From 3815668af78371a0c779427800746a9b19c579fb Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Wed, 24 May 2006 17:10:02 +0000 Subject: [PATCH] 2006-05-24 Paul Brook bfd/ * elf-bfd.h (elf_backend_data): Add elf_backend_output_arch_local_syms * elf32-arm.c (output_arch_syminfo): Define. (elf32_arm_ouput_plt_map_sym, elf32_arm_output_plt_map, elf32_arm_output_arch_local_syms): New functions. (elf_backend_output_arch_local_syms): Define. * elflink.c (bfd_elf_final_link): Call elf_backend_output_arch_local_syms. * elfxx-target.h (elf_backend_output_arch_local_syms): Provide default definition. (elfNN_bed): Add elf_backend_output_arch_local_syms. ld/testsuite/ * ld-arm/arm-app-abs32.d: Update expected output. * ld-arm/arm-app.d: Ditto. * ld-arm/arm-lib-plt32.d: Ditto. * ld-arm/arm-lib.d: Ditto. * ld-arm/mixed-app-v5.d: Ditto. * ld-arm/mixed-app.d: Ditto. * ld-arm/mixed-lib.d: Ditto. --- bfd/ChangeLog | 13 +++ bfd/elf-bfd.h | 10 ++- bfd/elf32-arm.c | 170 ++++++++++++++++++++++++++++++++++++ bfd/elflink.c | 13 +++ bfd/elfxx-target.h | 4 + ld/testsuite/ChangeLog | 10 +++ ld/testsuite/ld-arm/arm-app-abs32.d | 2 +- ld/testsuite/ld-arm/arm-app.d | 4 +- ld/testsuite/ld-arm/arm-lib-plt32.d | 4 +- ld/testsuite/ld-arm/arm-lib.d | 4 +- ld/testsuite/ld-arm/mixed-app-v5.d | 4 +- ld/testsuite/ld-arm/mixed-app.d | 4 +- ld/testsuite/ld-arm/mixed-lib.d | 4 +- 13 files changed, 232 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 51f54483fd..79b6321160 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,18 @@ 2006-05-24 Paul Brook + * elf-bfd.h (elf_backend_data): Add elf_backend_output_arch_local_syms + * elf32-arm.c (output_arch_syminfo): Define. + (elf32_arm_ouput_plt_map_sym, elf32_arm_output_plt_map, + elf32_arm_output_arch_local_syms): New functions. + (elf_backend_output_arch_local_syms): Define. + * elflink.c (bfd_elf_final_link): Call + elf_backend_output_arch_local_syms. + * elfxx-target.h (elf_backend_output_arch_local_syms): Provide default + definition. + (elfNN_bed): Add elf_backend_output_arch_local_syms. + +2006-05-24 Paul Brook + * elf32-arm.c (put_arm_insn, put_thumb_insn): New functions. (elf32_thumb_to_arm_stub, elf32_arm_to_thumb_stub, elf32_arm_finish_dynamic_symbol): Use them. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 3fba1c228f..3a32fc447d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -865,8 +865,16 @@ struct elf_backend_data /* This function, if defined, is called after all local symbols and global symbols converted to locals are emitted into the symtab - section. It allows the backend to emit special global symbols + section. It allows the backend to emit special local symbols not handled in the hash table. */ + bfd_boolean (*elf_backend_output_arch_local_syms) + (bfd *, struct bfd_link_info *, void *, + bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, + struct elf_link_hash_entry *)); + + /* This function, if defined, is called after all symbols are emitted + into the symtab section. It allows the backend to emit special + global symbols not handled in the hash table. */ bfd_boolean (*elf_backend_output_arch_syms) (bfd *, struct bfd_link_info *, void *, bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 1288ac2998..e2beac7404 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -7950,6 +7950,174 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info, return TRUE; } +typedef struct +{ + void *finfo; + struct bfd_link_info *info; + int plt_shndx; + bfd_vma plt_offset; + bfd_boolean (*func) (void *, const char *, Elf_Internal_Sym *, + asection *, struct elf_link_hash_entry *); +} output_arch_syminfo; + +enum map_symbol_type +{ + ARM_MAP_ARM, + ARM_MAP_THUMB, + ARM_MAP_DATA +}; + + +/* Output a single PLT mapping symbol. */ + +static bfd_boolean +elf32_arm_ouput_plt_map_sym (output_arch_syminfo *osi, + enum map_symbol_type type, + bfd_vma offset) +{ + static const char *names[3] = {"$a", "$t", "$d"}; + struct elf32_arm_link_hash_table *htab; + Elf_Internal_Sym sym; + + htab = elf32_arm_hash_table (osi->info); + sym.st_value = osi->plt_offset + offset; + sym.st_size = 0; + sym.st_other = 0; + sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); + sym.st_shndx = osi->plt_shndx; + if (!osi->func (osi->finfo, names[type], &sym, htab->splt, NULL)) + return FALSE; + return TRUE; +} + + +/* Output mapping symbols for PLT entries associated with H. */ + +static bfd_boolean +elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf) +{ + output_arch_syminfo *osi = (output_arch_syminfo *) inf; + struct elf32_arm_link_hash_table *htab; + struct elf32_arm_link_hash_entry *eh; + bfd_vma addr; + + htab = elf32_arm_hash_table (osi->info); + + if (h->root.type == bfd_link_hash_indirect) + return TRUE; + + if (h->root.type == bfd_link_hash_warning) + /* When warning symbols are created, they **replace** the "real" + entry in the hash table, thus we never get to see the real + symbol in a hash traversal. So look at it now. */ + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->plt.offset == (bfd_vma) -1) + return TRUE; + + eh = (struct elf32_arm_link_hash_entry *) h; + addr = h->plt.offset; + if (htab->symbian_p) + { + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 4)) + return FALSE; + } + else if (htab->vxworks_p) + { + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 8)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr + 12)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 20)) + return FALSE; + } + else + { + bfd_boolean thumb_stub; + + thumb_stub = eh->plt_thumb_refcount > 0 && !htab->use_blx; + if (thumb_stub) + { + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_THUMB, addr - 4)) + return FALSE; + } +#ifdef FOUR_WORD_PLT + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 12)) + return FALSE; +#else + /* A three-word PLT with no Thumb thunk contains only Arm code, + so only need to output a mapping symbol for the first PLT entry and + entries with thumb thunks. */ + if (thumb_stub || addr == 20) + { + if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr)) + return FALSE; + } +#endif + } + + return TRUE; +} + + +/* Output mapping symbols for the PLT. */ + +static bfd_boolean +elf32_arm_output_arch_local_syms (bfd *output_bfd, + struct bfd_link_info *info, + void *finfo, bfd_boolean (*func) (void *, const char *, + Elf_Internal_Sym *, + asection *, + struct elf_link_hash_entry *)) +{ + output_arch_syminfo osi; + struct elf32_arm_link_hash_table *htab; + + htab = elf32_arm_hash_table (info); + if (!htab->splt || htab->splt->size == 0) + return TRUE; + + check_use_blx(htab); + osi.finfo = finfo; + osi.info = info; + osi.func = func; + osi.plt_shndx = _bfd_elf_section_from_bfd_section (output_bfd, + htab->splt->output_section); + osi.plt_offset = htab->splt->output_section->vma; + + /* Output mapping symbols for the plt header. SymbianOS does not have a + plt header. */ + if (htab->vxworks_p) + { + /* VxWorks shared libraries have no PLT header. */ + if (!info->shared) + { + if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0)) + return FALSE; + if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 12)) + return FALSE; + } + } + else if (!htab->symbian_p) + { + if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0)) + return FALSE; +#ifndef FOUR_WORD_PLT + if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 16)) + return FALSE; +#endif + } + + elf_link_hash_traverse (&htab->root, elf32_arm_output_plt_map, (void *) &osi); + return TRUE; +} + /* Allocate target specific section data. */ static bfd_boolean @@ -8280,6 +8448,8 @@ const struct elf_size_info elf32_arm_size_info = { #define elf_backend_modify_segment_map elf32_arm_modify_segment_map #define elf_backend_additional_program_headers \ elf32_arm_additional_program_headers +#define elf_backend_output_arch_local_syms \ + elf32_arm_output_arch_local_syms #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 diff --git a/bfd/elflink.c b/bfd/elflink.c index ff401f2c7d..df2b7e9fb7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8296,6 +8296,19 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (eoinfo.failed) return FALSE; + /* If backend needs to output some local symbols not present in the hash + table, do it now. */ + if (bed->elf_backend_output_arch_local_syms) + { + typedef bfd_boolean (*out_sym_func) + (void *, const char *, Elf_Internal_Sym *, asection *, + struct elf_link_hash_entry *); + + if (! ((*bed->elf_backend_output_arch_local_syms) + (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) + return FALSE; + } + /* That wrote out all the local symbols. Finish up the symbol table with the global symbols. Even if we want to strip everything we can, we still need to deal with those global symbols that got diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 14a693a420..5a5ca34899 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -413,6 +413,9 @@ #ifndef elf_backend_print_symbol_all #define elf_backend_print_symbol_all NULL #endif +#ifndef elf_backend_output_arch_local_syms +#define elf_backend_output_arch_local_syms NULL +#endif #ifndef elf_backend_output_arch_syms #define elf_backend_output_arch_syms NULL #endif @@ -600,6 +603,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_gc_sweep_hook, elf_backend_post_process_headers, elf_backend_print_symbol_all, + elf_backend_output_arch_local_syms, elf_backend_output_arch_syms, elf_backend_copy_indirect_symbol, elf_backend_hide_symbol, diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 33e4b94e41..ecabfa36ae 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2006-05-24 Paul Brook + + * ld-arm/arm-app-abs32.d: Update expected output. + * ld-arm/arm-app.d: Ditto. + * ld-arm/arm-lib-plt32.d: Ditto. + * ld-arm/arm-lib.d: Ditto. + * ld-arm/mixed-app-v5.d: Ditto. + * ld-arm/mixed-app.d: Ditto. + * ld-arm/mixed-lib.d: Ditto. + 2006-05-23 H.J. Lu PR ld/2655 diff --git a/ld/testsuite/ld-arm/arm-app-abs32.d b/ld/testsuite/ld-arm/arm-app-abs32.d index 9a4da22b33..c398169854 100644 --- a/ld/testsuite/ld-arm/arm-app-abs32.d +++ b/ld/testsuite/ld-arm/arm-app-abs32.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* <_start-0x10> + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* .* diff --git a/ld/testsuite/ld-arm/arm-app.d b/ld/testsuite/ld-arm/arm-app.d index 207961ea0f..0cb52a955b 100644 --- a/ld/testsuite/ld-arm/arm-app.d +++ b/ld/testsuite/ld-arm/arm-app.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* <_start-0x10> + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -27,7 +27,7 @@ Disassembly of section .text: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} - .*: ebfffff4 bl .* <_start-0xc> + .*: ebfffff4 bl .* <.text-0xc> .*: e89d6800 ldmia sp, {fp, sp, lr} .*: e12fff1e bx lr diff --git a/ld/testsuite/ld-arm/arm-lib-plt32.d b/ld/testsuite/ld-arm/arm-lib-plt32.d index 58206f4379..96beabc8a5 100644 --- a/ld/testsuite/ld-arm/arm-lib-plt32.d +++ b/ld/testsuite/ld-arm/arm-lib-plt32.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -20,7 +20,7 @@ Disassembly of section .text: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} - .*: ebfffff9 bl .* + .*: ebfffff9 bl .* <.text-0xc> .*: e89d6800 ldmia sp, {fp, sp, lr} .*: e12fff1e bx lr diff --git a/ld/testsuite/ld-arm/arm-lib.d b/ld/testsuite/ld-arm/arm-lib.d index e3257c9551..706a657241 100644 --- a/ld/testsuite/ld-arm/arm-lib.d +++ b/ld/testsuite/ld-arm/arm-lib.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -20,7 +20,7 @@ Disassembly of section .text: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} - .*: ebfffff9 bl .* + .*: ebfffff9 bl .* <.text-0xc> .*: e89d6800 ldmia sp, {fp, sp, lr} .*: e12fff1e bx lr diff --git a/ld/testsuite/ld-arm/mixed-app-v5.d b/ld/testsuite/ld-arm/mixed-app-v5.d index 9e8d4dd194..73fa9ec83b 100644 --- a/ld/testsuite/ld-arm/mixed-app-v5.d +++ b/ld/testsuite/ld-arm/mixed-app-v5.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* <_start-0x20> + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -48,7 +48,7 @@ Disassembly of section .text: .* : .*: b500 push {lr} - .*: f7ff efc. blx .* <_start-0x..> + .*: f7ff efc. blx .* <.text-0x..> .*: bd00 pop {pc} .*: 4770 bx lr .*: 46c0 nop \(mov r8, r8\) diff --git a/ld/testsuite/ld-arm/mixed-app.d b/ld/testsuite/ld-arm/mixed-app.d index 381222727e..7893a33d3d 100644 --- a/ld/testsuite/ld-arm/mixed-app.d +++ b/ld/testsuite/ld-arm/mixed-app.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* <_start-0x20> + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -49,7 +49,7 @@ Disassembly of section .text: .* : .*: b500 push {lr} - .*: f7ff ffc. bl .* <_start-0x..> + .*: f7ff ffc. bl .* <.text-0x..> .*: bd00 pop {pc} .*: 4770 bx lr .*: 46c0 nop \(mov r8, r8\) diff --git a/ld/testsuite/ld-arm/mixed-lib.d b/ld/testsuite/ld-arm/mixed-lib.d index b261c67fae..0c426f36c7 100644 --- a/ld/testsuite/ld-arm/mixed-lib.d +++ b/ld/testsuite/ld-arm/mixed-lib.d @@ -8,7 +8,7 @@ Disassembly of section .plt: .* <.plt>: .*: e52de004 str lr, \[sp, #-4\]! - .*: e59fe004 ldr lr, \[pc, #4\] ; .* + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <\.plt\+0x10> .*: e08fe00e add lr, pc, lr .*: e5bef008 ldr pc, \[lr, #8\]! .*: .* @@ -20,7 +20,7 @@ Disassembly of section .text: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} - .*: ebfffff. bl .* + .*: ebfffff. bl .* <.text-0x..> .*: e89d6800 ldmia sp, {fp, sp, lr} .*: e12fff1e bx lr .*: e1a00000 nop \(mov r0,r0\) -- 2.11.0