diff options
author | Petr Machata <pmachata@redhat.com> | 2013-11-04 22:48:38 -0500 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:38:23 +0900 |
commit | bf95c098bba38573ee9b3f8918b0cdca30e6d5fc (patch) | |
tree | 5d81ee11f77db95b3a0a0d58be3c5d126efa8e2a /sysdeps/linux-gnu | |
parent | 391db0f031d2c15ae2eef1b3edab76e80d5c0979 (diff) | |
download | ltrace-bf95c098bba38573ee9b3f8918b0cdca30e6d5fc.tar.gz ltrace-bf95c098bba38573ee9b3f8918b0cdca30e6d5fc.tar.bz2 ltrace-bf95c098bba38573ee9b3f8918b0cdca30e6d5fc.zip |
In ARM backend, move hooks for ltrace_elf and library to plt.c
- That's the customary location for backend hooks.
Diffstat (limited to 'sysdeps/linux-gnu')
-rw-r--r-- | sysdeps/linux-gnu/arm/fetch.c | 188 | ||||
-rw-r--r-- | sysdeps/linux-gnu/arm/plt.c | 194 |
2 files changed, 192 insertions, 190 deletions
diff --git a/sysdeps/linux-gnu/arm/fetch.c b/sysdeps/linux-gnu/arm/fetch.c index 5081d78..b500448 100644 --- a/sysdeps/linux-gnu/arm/fetch.c +++ b/sysdeps/linux-gnu/arm/fetch.c @@ -32,200 +32,12 @@ #include "backend.h" #include "fetch.h" #include "library.h" -#include "ltrace-elf.h" #include "proc.h" #include "ptrace.h" #include "regs.h" #include "type.h" #include "value.h" -static int -get_hardfp(uint64_t abi_vfp_args) -{ - if (abi_vfp_args == 2) - fprintf(stderr, - "Tag_ABI_VFP_args value 2 (tool chain-specific " - "conventions) not supported.\n"); - return abi_vfp_args == 1; -} - -int -arch_elf_init(struct ltelf *lte, struct library *lib) -{ - /* Nothing in this section is strictly critical. It's not - * that much of a deal if we fail to guess right whether the - * ABI is softfp or hardfp. */ - unsigned hardfp = 0; - - Elf_Scn *scn; - Elf_Data *data; - GElf_Shdr shdr; - if (elf_get_section_type(lte, SHT_ARM_ATTRIBUTES, &scn, &shdr) < 0 - || (scn != NULL && (data = elf_loaddata(scn, &shdr)) == NULL)) { - fprintf(stderr, - "Error when obtaining ARM attribute section: %s\n", - elf_errmsg(-1)); - goto done; - - } else if (scn != NULL && data != NULL) { - GElf_Xword offset = 0; - uint8_t version; - if (elf_read_next_u8(data, &offset, &version) < 0) { - goto done; - } else if (version != 'A') { - fprintf(stderr, "Unsupported ARM attribute section " - "version %d ('%c').\n", version, version); - goto done; - } - - do { - const char signature[] = "aeabi"; - /* N.B. LEN is including the length field - * itself. */ - uint32_t sec_len; - if (elf_read_u32(data, offset, &sec_len) < 0 - || !elf_can_read_next(data, offset, sec_len)) { - goto done; - } - const GElf_Xword next_offset = offset + sec_len; - offset += 4; - - if (sec_len < 4 + sizeof signature - || strcmp(signature, data->d_buf + offset) != 0) - goto skip; - offset += sizeof signature; - - const GElf_Xword offset0 = offset; - uint64_t tag; - uint32_t sub_len; - if (elf_read_next_uleb128(data, &offset, &tag) < 0 - || elf_read_next_u32(data, &offset, &sub_len) < 0 - || !elf_can_read_next(data, offset0, sub_len)) - goto done; - - if (tag != 1) - /* IHI0045D_ABI_addenda: "section and - * symbol attributes are deprecated - * [...] consumers are permitted to - * ignore them." */ - goto skip; - - while (offset < offset0 + sub_len) { - if (elf_read_next_uleb128(data, - &offset, &tag) < 0) - goto done; - - switch (tag) { - uint64_t v; - case 6: /* Tag_CPU_arch */ - case 7: /* Tag_CPU_arch_profile */ - case 8: /* Tag_ARM_ISA_use */ - case 9: /* Tag_THUMB_ISA_use */ - case 10: /* Tag_FP_arch */ - case 11: /* Tag_WMMX_arch */ - case 12: /* Tag_Advanced_SIMD_arch */ - case 13: /* Tag_PCS_config */ - case 14: /* Tag_ABI_PCS_R9_use */ - case 15: /* Tag_ABI_PCS_RW_data */ - case 16: /* Tag_ABI_PCS_RO_data */ - case 17: /* Tag_ABI_PCS_GOT_use */ - case 18: /* Tag_ABI_PCS_wchar_t */ - case 19: /* Tag_ABI_FP_rounding */ - case 20: /* Tag_ABI_FP_denormal */ - case 21: /* Tag_ABI_FP_exceptions */ - case 22: /* Tag_ABI_FP_user_exceptions */ - case 23: /* Tag_ABI_FP_number_model */ - case 24: /* Tag_ABI_align_needed */ - case 25: /* Tag_ABI_align_preserved */ - case 26: /* Tag_ABI_enum_size */ - case 27: /* Tag_ABI_HardFP_use */ - case 28: /* Tag_ABI_VFP_args */ - case 29: /* Tag_ABI_WMMX_args */ - case 30: /* Tag_ABI_optimization_goals */ - case 31: /* Tag_ABI_FP_optimization_goals */ - case 32: /* Tag_compatibility */ - case 34: /* Tag_CPU_unaligned_access */ - case 36: /* Tag_FP_HP_extension */ - case 38: /* Tag_ABI_FP_16bit_format */ - case 42: /* Tag_MPextension_use */ - case 70: /* Tag_MPextension_use as well */ - case 44: /* Tag_DIV_use */ - case 64: /* Tag_nodefaults */ - case 66: /* Tag_T2EE_use */ - case 68: /* Tag_Virtualization_use */ - uleb128: - if (elf_read_next_uleb128 - (data, &offset, &v) < 0) - goto done; - if (tag == 28) - hardfp = get_hardfp(v); - if (tag != 32) - continue; - - /* Tag 32 has two arguments, - * fall through. */ - - case 4: /* Tag_CPU_raw_name */ - case 5: /* Tag_CPU_name */ - case 65: /* Tag_also_compatible_with */ - case 67: /* Tag_conformance */ - ntbs: - offset += strlen(data->d_buf - + offset) + 1; - continue; - } - - /* Handle unknown tags in a generic - * manner, if possible. */ - if (tag <= 32) { - fprintf(stderr, - "Unknown tag %lld " - "at offset %#llx " - "of ARM attribute section.", - tag, offset); - goto skip; - } else if (tag % 2 == 0) { - goto uleb128; - } else { - goto ntbs; - } - } - - skip: - offset = next_offset; - - } while (elf_can_read_next(data, offset, 1)); - - } - -done: - lib->arch.hardfp = hardfp; - return 0; -} - -void -arch_elf_destroy(struct ltelf *lte) -{ -} - -int -arch_library_init(struct library *lib) -{ - return 0; -} - -void -arch_library_destroy(struct library *lib) -{ -} - -int -arch_library_clone(struct library *retp, struct library *lib) -{ - retp->arch = lib->arch; - return 0; -} - enum { /* How many (double) VFP registers the AAPCS uses for * parameter passing. */ diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c index d1bf7ca..649f73a 100644 --- a/sysdeps/linux-gnu/arm/plt.c +++ b/sysdeps/linux-gnu/arm/plt.c @@ -20,20 +20,192 @@ */ #include <gelf.h> +#include <stdio.h> +#include <string.h> #include "proc.h" #include "library.h" #include "ltrace-elf.h" static int +get_hardfp(uint64_t abi_vfp_args) +{ + if (abi_vfp_args == 2) + fprintf(stderr, + "Tag_ABI_VFP_args value 2 (tool chain-specific " + "conventions) not supported.\n"); + return abi_vfp_args == 1; +} + +int +arch_elf_init(struct ltelf *lte, struct library *lib) +{ + /* Nothing in this section is strictly critical. It's not + * that much of a deal if we fail to guess right whether the + * ABI is softfp or hardfp. */ + unsigned hardfp = 0; + + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + if (elf_get_section_type(lte, SHT_ARM_ATTRIBUTES, &scn, &shdr) < 0 + || (scn != NULL && (data = elf_loaddata(scn, &shdr)) == NULL)) { + fprintf(stderr, + "Error when obtaining ARM attribute section: %s\n", + elf_errmsg(-1)); + goto done; + + } else if (scn != NULL && data != NULL) { + GElf_Xword offset = 0; + uint8_t version; + if (elf_read_next_u8(data, &offset, &version) < 0) { + goto done; + } else if (version != 'A') { + fprintf(stderr, "Unsupported ARM attribute section " + "version %d ('%c').\n", version, version); + goto done; + } + + do { + const char signature[] = "aeabi"; + /* N.B. LEN is including the length field + * itself. */ + uint32_t sec_len; + if (elf_read_u32(data, offset, &sec_len) < 0 + || !elf_can_read_next(data, offset, sec_len)) { + goto done; + } + const GElf_Xword next_offset = offset + sec_len; + offset += 4; + + if (sec_len < 4 + sizeof signature + || strcmp(signature, data->d_buf + offset) != 0) + goto skip; + offset += sizeof signature; + + const GElf_Xword offset0 = offset; + uint64_t tag; + uint32_t sub_len; + if (elf_read_next_uleb128(data, &offset, &tag) < 0 + || elf_read_next_u32(data, &offset, &sub_len) < 0 + || !elf_can_read_next(data, offset0, sub_len)) + goto done; + + if (tag != 1) + /* IHI0045D_ABI_addenda: "section and + * symbol attributes are deprecated + * [...] consumers are permitted to + * ignore them." */ + goto skip; + + while (offset < offset0 + sub_len) { + if (elf_read_next_uleb128(data, + &offset, &tag) < 0) + goto done; + + switch (tag) { + uint64_t v; + case 6: /* Tag_CPU_arch */ + case 7: /* Tag_CPU_arch_profile */ + case 8: /* Tag_ARM_ISA_use */ + case 9: /* Tag_THUMB_ISA_use */ + case 10: /* Tag_FP_arch */ + case 11: /* Tag_WMMX_arch */ + case 12: /* Tag_Advanced_SIMD_arch */ + case 13: /* Tag_PCS_config */ + case 14: /* Tag_ABI_PCS_R9_use */ + case 15: /* Tag_ABI_PCS_RW_data */ + case 16: /* Tag_ABI_PCS_RO_data */ + case 17: /* Tag_ABI_PCS_GOT_use */ + case 18: /* Tag_ABI_PCS_wchar_t */ + case 19: /* Tag_ABI_FP_rounding */ + case 20: /* Tag_ABI_FP_denormal */ + case 21: /* Tag_ABI_FP_exceptions */ + case 22: /* Tag_ABI_FP_user_exceptions */ + case 23: /* Tag_ABI_FP_number_model */ + case 24: /* Tag_ABI_align_needed */ + case 25: /* Tag_ABI_align_preserved */ + case 26: /* Tag_ABI_enum_size */ + case 27: /* Tag_ABI_HardFP_use */ + case 28: /* Tag_ABI_VFP_args */ + case 29: /* Tag_ABI_WMMX_args */ + case 30: /* Tag_ABI_optimization_goals */ + case 31: /* Tag_ABI_FP_optimization_goals */ + case 32: /* Tag_compatibility */ + case 34: /* Tag_CPU_unaligned_access */ + case 36: /* Tag_FP_HP_extension */ + case 38: /* Tag_ABI_FP_16bit_format */ + case 42: /* Tag_MPextension_use */ + case 70: /* Tag_MPextension_use as well */ + case 44: /* Tag_DIV_use */ + case 64: /* Tag_nodefaults */ + case 66: /* Tag_T2EE_use */ + case 68: /* Tag_Virtualization_use */ + uleb128: + if (elf_read_next_uleb128 + (data, &offset, &v) < 0) + goto done; + if (tag == 28) + hardfp = get_hardfp(v); + if (tag != 32) + continue; + + /* Tag 32 has two arguments, + * fall through. */ + + case 4: /* Tag_CPU_raw_name */ + case 5: /* Tag_CPU_name */ + case 65: /* Tag_also_compatible_with */ + case 67: /* Tag_conformance */ + ntbs: + offset += strlen(data->d_buf + + offset) + 1; + continue; + } + + /* Handle unknown tags in a generic + * manner, if possible. */ + if (tag <= 32) { + fprintf(stderr, + "Unknown tag %lld " + "at offset %#llx " + "of ARM attribute section.", + tag, offset); + goto skip; + } else if (tag % 2 == 0) { + goto uleb128; + } else { + goto ntbs; + } + } + + skip: + offset = next_offset; + + } while (elf_can_read_next(data, offset, 1)); + + } + +done: + lib->arch.hardfp = hardfp; + return 0; +} + +void +arch_elf_destroy(struct ltelf *lte) +{ +} + +static int arch_plt_entry_has_stub(struct ltelf *lte, size_t off) { - uint16_t op = *(uint16_t *)((char *)lte->relplt->d_buf + off); + char *buf = (char *) lte->arch.jmprel_data->d_buf; + uint16_t op = *(uint16_t *) (buf + off); return op == 0x4778; } GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - size_t start = lte->relplt->d_size + 12; + size_t start = lte->arch.jmprel_data->d_size + 12; size_t off = start + 20, i; for (i = 0; i < ndx; i++) off += arch_plt_entry_has_stub(lte, off) ? 16 : 12; @@ -47,3 +219,21 @@ sym2addr(struct process *proc, struct library_symbol *sym) { return sym->enter_addr; } + +int +arch_library_init(struct library *lib) +{ + return 0; +} + +void +arch_library_destroy(struct library *lib) +{ +} + +int +arch_library_clone(struct library *retp, struct library *lib) +{ + retp->arch = lib->arch; + return 0; +} |