In ARM backend, move hooks for ltrace_elf and library to plt.c
authorPetr Machata <pmachata@redhat.com>
Tue, 5 Nov 2013 03:48:38 +0000 (22:48 -0500)
committerChanho Park <chanho61.park@samsung.com>
Fri, 22 Aug 2014 11:38:23 +0000 (20:38 +0900)
- That's the customary location for backend hooks.

sysdeps/linux-gnu/arm/fetch.c
sysdeps/linux-gnu/arm/plt.c

index 5081d78..b500448 100644 (file)
 #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.  */
index d1bf7ca..649f73a 100644 (file)
  */
 
 #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;
+}