* RFA: Support for Thumb in dynamic objects @ 2004-11-16 23:39 Daniel Jacobowitz 2004-11-17 0:22 ` Paul Brook ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-16 23:39 UTC (permalink / raw) To: binutils This patch adds limited support for Thumb in dynamic objects. It causes the glue stubs not to be exported from the object, and uses a prefix to the PLT entry to change mode instead of a glue stub off somewhere else. It also fixes objdump to display thumb functions using the STT_ARM_TFUNC type as functions. It's easy to stop using STT_ARM_TFUNC and start using an odd symbol value for dynamic objects; but I didn't want to mix it with this patch. So that's a TODO. Other TODOs are: - some kind of mappng symbols in the .plt section so that the disassembler knows what to do (we can't easily generate new local symbols from the backend, but I'm sure there's a way around it); this is very important for GDB. - Related, synthetic named symbols for the .plt as implemented for other architectures. - BLX support. The only reason I didn't do this is that there's no easy way to tell if using BLX is OK; i.e. whether we can assume the presence of ARM v5t. OK? Comments? -- Daniel Jacobowitz 2004-11-16 Daniel Jacobowitz <dan@codesourcery.com> * elf32-arm.c (PLT_THUMB_STUB_SIZE): Define. (elf32_arm_plt_thumb_stub): New. (struct elf32_arm_link_hash_entry): Add plt_thumb_refcount and plt_got_offset. (elf32_arm_link_hash_traverse): Fix typo. (elf32_arm_link_hash_table): Add obfd. (elf32_arm_link_hash_newfunc): Initialize new fields. (elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount. (elf32_arm_link_hash_table_create): Initialize obfd. (record_arm_to_thumb_glue): Mark the glue as a local ARM function. (record_thumb_to_arm_glue): Mark the glue as a local Thumb function. (bfd_elf32_arm_get_bfd_for_interworking): Verify that the interworking BFD is not dynamic. (bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32. Do not emit glue for PLT references. (elf32_arm_final_link_relocate): Handle Thumb functions. Do not emit glue for PLT references. Support the Thumb PLT prefix. (elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and plt_thumb_refcount. (elf32_arm_check_relocs): Likewise. (elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and plt_thumb_refcount. (allocate_dynrelocs): Handle Thumb PLT references. (elf32_arm_finish_dynamic_symbol): Likewise. (elf32_arm_symbol_processing): New function. (elf_backend_symbol_processing): Define. 2004-11-16 Daniel Jacobowitz <dan@codesourcery.com> * gas/arm/mapping.d: Expect F markers for Thumb code. 2004-11-16 Daniel Jacobowitz <dan@codesourcery.com> * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use a dynamic object for stubs. 2004-11-16 Daniel Jacobowitz <dan@codesourcery.com> * ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s, ld-arm/mixed-app.sym, ld-arm/mixed-lib.d, ld-arm/mixed-lib.r, ld-arm/mixed-lib.s, ld-arm/mixed-lib.sym: New files. * ld-arm/arm-elf.exp: Run them. Index: bfd/elf32-arm.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/bfd/elf32-arm.c,v retrieving revision 1.7 diff -u -p -r1.7 elf32-arm.c --- bfd/elf32-arm.c 13 Nov 2004 13:38:15 -0000 1.7 +++ bfd/elf32-arm.c 16 Nov 2004 21:13:20 -0000 @@ -1063,6 +1063,13 @@ static const bfd_vma elf32_arm_plt_entry #endif +/* An initial stub used if the PLT entry is referenced from Thumb code. */ +#define PLT_THUMB_STUB_SIZE 4 +static const bfd_vma elf32_arm_plt_thumb_stub [1] = + { + 0x46c04778 /* bx pc; nop (in Thumb mode) */ + }; + /* The entries in a PLT when using a DLL-based target with multiple address spaces. */ static const bfd_vma elf32_arm_symbian_plt_entry [] = @@ -1116,13 +1123,22 @@ struct elf32_arm_link_hash_entry /* Number of PC relative relocs copied for this symbol. */ struct elf32_arm_relocs_copied * relocs_copied; + + /* We reference count Thumb references to a PLT entry separately, + so that we can emit the Thumb trampoline only if needed. */ + bfd_signed_vma plt_thumb_refcount; + + /* Since PLT entries have variable size if the Thumb prologue is + used, we need to record the index into .got.plt instead of + recomputing it from the PLT offset. */ + bfd_signed_vma plt_got_offset; }; /* Traverse an arm ELF linker hash table. */ #define elf32_arm_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (bfd_boolean (*) (struct elf_link_hash_entry *, void *))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) /* Get the ARM elf linker hash table from a link_info structure. */ @@ -1178,6 +1194,9 @@ struct elf32_arm_link_hash_table /* Small local sym to section mapping cache. */ struct sym_sec_cache sym_sec; + + /* For convenience in allocate_dynrelocs. */ + bfd * obfd; }; /* Create an entry in an ARM ELF linker hash table. */ @@ -1202,7 +1221,11 @@ elf32_arm_link_hash_newfunc (struct bfd_ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); if (ret != NULL) - ret->relocs_copied = NULL; + { + ret->relocs_copied = NULL; + ret->plt_thumb_refcount = 0; + ret->plt_got_offset = -1; + } return (struct bfd_hash_entry *) ret; } @@ -1315,6 +1338,17 @@ elf32_arm_copy_indirect_symbol (const st eind->relocs_copied = NULL; } + /* If the direct symbol already has an associated PLT entry, the + indirect symbol should not. If it doesn't, swap refcount information + from the indirect symbol. */ + if (edir->plt_thumb_refcount == 0) + { + edir->plt_thumb_refcount = eind->plt_thumb_refcount; + eind->plt_thumb_refcount = 0; + } + else + BFD_ASSERT (eind->plt_thumb_refcount == 0); + _bfd_elf_link_hash_copy_indirect (bed, dir, ind); } @@ -1360,6 +1394,7 @@ elf32_arm_link_hash_table_create (bfd *a #endif ret->symbian_p = 0; ret->sym_sec.abfd = NULL; + ret->obfd = abfd; return &ret->root.root; } @@ -1559,6 +1594,10 @@ record_arm_to_thumb_glue (struct bfd_lin tmp_name, BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh); + myh = (struct elf_link_hash_entry *) bh; + myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC); + myh->forced_local = 1; + free (tmp_name); globals->arm_glue_size += ARM2THUMB_GLUE_SIZE; @@ -1576,7 +1615,6 @@ record_thumb_to_arm_glue (struct bfd_lin struct elf_link_hash_entry *myh; struct bfd_link_hash_entry *bh; struct elf32_arm_link_hash_table *hash_table; - char bind; bfd_vma val; hash_table = elf32_arm_hash_table (link_info); @@ -1614,8 +1652,8 @@ record_thumb_to_arm_glue (struct bfd_lin /* If we mark it 'Thumb', the disassembler will do a better job. */ myh = (struct elf_link_hash_entry *) bh; - bind = ELF_ST_BIND (myh->type); - myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC); + myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC); + myh->forced_local = 1; free (tmp_name); @@ -1713,6 +1751,9 @@ bfd_elf32_arm_get_bfd_for_interworking ( if (info->relocatable) return TRUE; + /* Make sure we don't attach the glue sections to a dynamic object. */ + BFD_ASSERT (!(abfd->flags & DYNAMIC)); + globals = elf32_arm_hash_table (info); BFD_ASSERT (globals != NULL); @@ -1796,6 +1837,7 @@ bfd_elf32_arm_process_before_allocation /* These are the only relocation types we care about. */ if ( r_type != R_ARM_PC24 + && r_type != R_ARM_PLT32 #ifndef OLD_ARM_ABI && r_type != R_ARM_CALL && r_type != R_ARM_JUMP24 @@ -1834,6 +1876,11 @@ bfd_elf32_arm_process_before_allocation if (h == NULL) continue; + /* If the call will go through a PLT entry then we do not need + glue. */ + if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1) + continue; + switch (r_type) { case R_ARM_PC24: @@ -2374,6 +2421,8 @@ elf32_arm_final_link_relocate (reloc_how /* This symbol is local, or marked to become local. */ relocate = TRUE; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; if (globals->symbian_p) { /* On Symbian OS, the data segment and text segement @@ -2652,8 +2701,11 @@ elf32_arm_final_link_relocate (reloc_how { /* If it is not a call to Thumb, assume call to Arm. If it is a call relative to a section name, then it is not a - function call at all, but rather a long jump. */ - if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION) + function call at all, but rather a long jump. Calls through + the PLT do not require stubs. */ + if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION + && (h == NULL || splt == NULL + || h->plt.offset == (bfd_vma) -1)) { if (elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section, @@ -2664,6 +2716,16 @@ elf32_arm_final_link_relocate (reloc_how } } + /* Handle calls via the PLT. */ + if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1) + { + value = (splt->output_section->vma + + splt->output_offset + + h->plt.offset); + /* Target the Thumb stub before the ARM PLT entry. */ + value -= 4; + } + relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -2911,6 +2973,13 @@ elf32_arm_final_link_relocate (reloc_how off &= ~1; else { + /* If we are addressing a Thumb function, we need to + adjust the address by one, so that attempts to + call the function pointer will correctly + interpret it as Thumb code. */ + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + bfd_put_32 (output_bfd, value, sgot->contents + off); if (info->shared) @@ -3873,6 +3942,9 @@ elf32_arm_gc_sweep_hook (bfd * case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be here also? */ + r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx >= symtab_hdr->sh_info) { @@ -3881,15 +3953,18 @@ elf32_arm_gc_sweep_hook (bfd * struct elf32_arm_relocs_copied *p; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.refcount > 0) - h->plt.refcount -= 1; + { + h->plt.refcount -= 1; + if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22) + eh->plt_thumb_refcount--; + } if (r_type == R_ARM_ABS32 || r_type == R_ARM_REL32) { - eh = (struct elf32_arm_link_hash_entry *) h; - for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next) if (p->section == sec) @@ -3948,6 +4023,7 @@ elf32_arm_check_relocs (bfd *abfd, struc for (rel = relocs; rel < rel_end; rel++) { struct elf_link_hash_entry *h; + struct elf32_arm_link_hash_entry *eh; unsigned long r_symndx; int r_type; @@ -3961,6 +4037,8 @@ elf32_arm_check_relocs (bfd *abfd, struc else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; + switch (r_type) { case R_ARM_GOT32: @@ -4015,6 +4093,8 @@ elf32_arm_check_relocs (bfd *abfd, struc case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be listed here? */ if (h != NULL) { /* If this reloc is in a read-only section, we might @@ -4036,12 +4116,16 @@ elf32_arm_check_relocs (bfd *abfd, struc || r_type == R_ARM_JUMP24 || r_type == R_ARM_PREL31 #endif - || r_type == R_ARM_PLT32) + || r_type == R_ARM_PLT32 + || r_type == R_ARM_THM_PC22) h->needs_plt = 1; /* If we create a PLT entry, this relocation will reference it, even if it's an ABS32 relocation. */ h->plt.refcount += 1; + + if (r_type == R_ARM_THM_PC22) + eh->plt_thumb_refcount += 1; } /* If we are creating a shared library, and this is a reloc @@ -4065,7 +4149,8 @@ elf32_arm_check_relocs (bfd *abfd, struc && r_type != R_ARM_JUMP24 && r_type != R_ARM_PREL31 #endif - && r_type != R_ARM_REL32) + && r_type != R_ARM_REL32 + && r_type != R_ARM_THM_PC22) || (h != NULL && (! info->symbolic || !h->def_regular)))) @@ -4314,6 +4399,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd * dynobj; asection * s; unsigned int power_of_two; + struct elf32_arm_link_hash_entry * eh; dynobj = elf_hash_table (info)->dynobj; @@ -4325,10 +4411,12 @@ elf32_arm_adjust_dynamic_symbol (struct && h->ref_regular && !h->def_regular))); + eh = (struct elf32_arm_link_hash_entry *) h; + /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC || h->needs_plt) { if (h->plt.refcount <= 0 @@ -4342,18 +4430,22 @@ elf32_arm_adjust_dynamic_symbol (struct such a case, we don't actually need to build a procedure linkage table, and we can just do a PC24 reloc instead. */ h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; h->needs_plt = 0; } return TRUE; } else - /* It's possible that we incorrectly decided a .plt reloc was - needed for an R_ARM_PC24 or similar reloc to a non-function sym - in check_relocs. We can't decide accurately between function - and non-function syms in check-relocs; Objects loaded later in - the link may change h->type. So fix it now. */ - h->plt.offset = (bfd_vma) -1; + { + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_ARM_PC24 or similar reloc to a non-function sym + in check_relocs. We can't decide accurately between function + and non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ + h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; + } /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the @@ -4438,6 +4530,8 @@ allocate_dynrelocs (struct elf_link_hash struct elf32_arm_link_hash_entry *eh; struct elf32_arm_relocs_copied *p; + eh = (struct elf32_arm_link_hash_entry *) h; + if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -4474,6 +4568,14 @@ allocate_dynrelocs (struct elf_link_hash h->plt.offset = s->size; + /* If we will insert a Thumb trampoline before this PLT, leave room + for it. */ + if (!htab->symbian_p && eh->plt_thumb_refcount > 0) + { + h->plt.offset += PLT_THUMB_STUB_SIZE; + s->size += PLT_THUMB_STUB_SIZE; + } + /* If this symbol is not defined in a regular file, and we are not generating a shared library, then set the symbol to this location in the .plt. This is required to make function @@ -4484,15 +4586,24 @@ allocate_dynrelocs (struct elf_link_hash { h->root.u.def.section = s; h->root.u.def.value = h->plt.offset; + + /* Make sure the function is not marked as Thumb, in case + it is the target of an ABS32 relocation, which will + point to the PLT entry. */ + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) + h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); } /* Make room for this entry. */ s->size += htab->plt_entry_size; if (!htab->symbian_p) - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - htab->sgotplt->size += 4; + { + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + eh->plt_got_offset = htab->sgotplt->size; + htab->sgotplt->size += 4; + } /* We also need to make an entry in the .rel.plt section. */ htab->srelplt->size += sizeof (Elf32_External_Rel); @@ -4539,7 +4650,6 @@ allocate_dynrelocs (struct elf_link_hash else h->got.offset = (bfd_vma) -1; - eh = (struct elf32_arm_link_hash_entry *) h; if (eh->relocs_copied == NULL) return TRUE; @@ -4864,9 +4974,11 @@ elf32_arm_finish_dynamic_symbol (bfd * o { bfd * dynobj; struct elf32_arm_link_hash_table *htab; + struct elf32_arm_link_hash_entry *eh; dynobj = elf_hash_table (info)->dynobj; htab = elf32_arm_hash_table (info); + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.offset != (bfd_vma) -1) { @@ -4885,13 +4997,6 @@ elf32_arm_finish_dynamic_symbol (bfd * o srel = bfd_get_section_by_name (dynobj, ".rel.plt"); BFD_ASSERT (splt != NULL && srel != NULL); - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = ((h->plt.offset - htab->plt_header_size) - / htab->plt_entry_size); - /* Fill in the entry in the procedure linkage table. */ if (htab->symbian_p) { @@ -4906,6 +5011,13 @@ elf32_arm_finish_dynamic_symbol (bfd * o + splt->output_offset + h->plt.offset + 4 * (i - 1)); rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT); + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first entry in the procedure linkage table is reserved. */ + plt_index = ((h->plt.offset - htab->plt_header_size) + / htab->plt_entry_size); } else { @@ -4916,13 +5028,21 @@ elf32_arm_finish_dynamic_symbol (bfd * o sgot = bfd_get_section_by_name (dynobj, ".got.plt"); BFD_ASSERT (sgot != NULL); - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; + /* Get the offset into the .got.plt table of the entry that + corresponds to this function. */ + got_offset = eh->plt_got_offset; + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first three entries in .got.plt are reserved; after that + symbols appear in the same order as in .plt. */ + plt_index = (got_offset - 12) / 4; /* Calculate the displacement between the PLT slot and the - entry in the GOT. */ + entry in the GOT. The eight-byte offset accounts for the + value produced by adding to pc in the first instruction + of the PLT stub. */ got_displacement = (sgot->output_section->vma + sgot->output_offset + got_offset @@ -4933,6 +5053,10 @@ elf32_arm_finish_dynamic_symbol (bfd * o BFD_ASSERT ((got_displacement & 0xf0000000) == 0); + if (eh->plt_thumb_refcount > 0) + bfd_put_32 (output_bfd, elf32_arm_plt_thumb_stub[0], + splt->contents + h->plt.offset - 4); + bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20), splt->contents + h->plt.offset + 0); bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12), @@ -5518,6 +5642,18 @@ elf32_arm_write_section (bfd *output_bfd return FALSE; } +/* Display STT_ARM_TFUNC symbols as functions. */ + +static void +elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym; + + if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_ARM_TFUNC) + elfsym->symbol.flags |= BSF_FUNCTION; +} + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #ifdef __QNXTARGET__ @@ -5556,6 +5692,7 @@ elf32_arm_write_section (bfd *output_bfd #define elf_backend_section_from_shdr elf32_arm_section_from_shdr #define elf_backend_final_write_processing elf32_arm_final_write_processing #define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol +#define elf_backend_symbol_processing elf32_arm_symbol_processing #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 @@ -5688,4 +5825,3 @@ elf32_arm_symbian_modify_segment_map (bf #define elf_backend_want_got_plt 0 #include "elf32-target.h" - Index: gas/testsuite/gas/arm/mapping.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/mapping.d,v retrieving revision 1.2 diff -u -p -r1.2 mapping.d --- gas/testsuite/gas/arm/mapping.d 14 Oct 2004 16:04:09 -0000 1.2 +++ gas/testsuite/gas/arm/mapping.d 16 Nov 2004 21:15:21 -0000 @@ -10,9 +10,9 @@ SYMBOL TABLE: 0+00 l d .data 0+0 0+00 l d .bss 0+0 0+00 l F .text 0+0 \$a -0+08 l .text 0+0 \$t +0+08 l F .text 0+0 \$t 0+00 l O .data 0+0 \$d 0+00 l d foo 0+0 -0+00 l foo 0+0 \$t +0+00 l F foo 0+0 \$t 0+00 g .text 0+0 mapping -0+08 g .text 0+0 thumb_mapping +0+08 g F .text 0+0 thumb_mapping Index: ld/emultempl/armelf.em =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/emultempl/armelf.em,v retrieving revision 1.40 diff -u -p -r1.40 armelf.em --- ld/emultempl/armelf.em 17 Sep 2004 12:18:18 -0000 1.40 +++ ld/emultempl/armelf.em 16 Nov 2004 20:52:24 -0000 @@ -78,8 +78,11 @@ arm_elf_set_bfd_for_interworking (lang_s ASSERT (output_section->owner == output_bfd); + /* Don't attach the interworking stubs to a dynamic object, to + an empty section, etc. */ if ((output_section->flags & SEC_HAS_CONTENTS) != 0 && (i->flags & SEC_NEVER_LOAD) == 0 + && ! (i->owner->flags & DYNAMIC) && ! i->owner->output_has_begun) { bfd_for_interwork = i->owner; Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.5 diff -u -p -r1.5 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 30 Sep 2004 17:03:52 -0000 1.5 +++ ld/testsuite/ld-arm/arm-elf.exp 16 Nov 2004 22:32:55 -0000 @@ -47,6 +47,15 @@ set armelftests { {"Non-pcrel function reference" "tmpdir/arm-lib.so" "" {arm-app-abs32.s} {{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}} "arm-app-abs32"} + {"Mixed ARM/Thumb shared library" "-shared" "" {mixed-lib.s} + {{objdump -fdw mixed-lib.d} {objdump -Rw mixed-lib.r} + {readelf -Ds mixed-lib.sym}} + "mixed-lib.so"} + {"Mixed ARM/Thumb dynamic application" "tmpdir/mixed-lib.so" "" + {mixed-app.s} + {{objdump -fdw mixed-app.d} {objdump -Rw mixed-app.r} + {readelf -Ds mixed-app.sym}} + "mixed-app"} {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s} {{objdump -s arm-target1-abs.d}} "arm-target1-abs"} Index: ld/testsuite/ld-arm/mixed-app.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.d diff -N ld/testsuite/ld-arm/mixed-app.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.d 16 Nov 2004 22:29:37 -0000 @@ -0,0 +1,57 @@ + +tmpdir/mixed-app: file format elf32-littlearm +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <.plt\+0x10> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: 46c04778 undefined + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <_start>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: eb000004 bl .* <app_func> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebffffef bl .* <.text-0x14> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func2>: + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_tfunc>: + .*: b500 push {lr} + .*: ffc3f7ff bl .* <.text-0x24> + .*: bd00 pop {pc} + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-app.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.r diff -N ld/testsuite/ld-arm/mixed-app.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.r 16 Nov 2004 22:29:52 -0000 @@ -0,0 +1,10 @@ + +tmpdir/mixed-app: file format elf32-littlearm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_COPY data_obj +.* R_ARM_JUMP_SLOT lib_func2 +.* R_ARM_JUMP_SLOT lib_func1 + + Index: ld/testsuite/ld-arm/mixed-app.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.s diff -N ld/testsuite/ld-arm/mixed-app.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.s 16 Nov 2004 22:33:55 -0000 @@ -0,0 +1,39 @@ + .text + .p2align 4 + .globl _start +_start: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func + .type app_func,%function +app_func: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl lib_func1 + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func2 + .type app_func2,%function +app_func2: + bx lr + + .p2align 4 + .globl app_tfunc + .type app_tfunc,%function + .thumb_func + .code 16 +app_tfunc: + push {lr} + bl lib_func2 + pop {pc} + bx lr + + .data + .long data_obj Index: ld/testsuite/ld-arm/mixed-app.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.sym diff -N ld/testsuite/ld-arm/mixed-app.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.sym 16 Nov 2004 22:32:02 -0000 @@ -0,0 +1,16 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + 11 0: .* 0 NOTYPE GLOBAL DEFAULT ABS _edata + 3 0: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + 12 1: .* 0 NOTYPE GLOBAL DEFAULT ABS _end + 10 1: .* 4 OBJECT GLOBAL DEFAULT 12 data_obj + 7 1: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + 5 1: 0*[^0]*.* 20 FUNC GLOBAL DEFAULT UND lib_func1 + 1 1: .* 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + 13 2: .* 0 NOTYPE GLOBAL DEFAULT 11 __data_start + 9 2: .* 0 NOTYPE GLOBAL DEFAULT ABS __end__ + 8 2: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + 6 2: .* 0 FUNC GLOBAL DEFAULT 8 app_func2 + 4 2: 0*[^0]*.* 2 FUNC GLOBAL DEFAULT UND lib_func2 + 2 2: .* 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ Index: ld/testsuite/ld-arm/mixed-lib.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.d diff -N ld/testsuite/ld-arm/mixed-lib.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.d 16 Nov 2004 21:49:33 -0000 @@ -0,0 +1,38 @@ + +tmpdir/mixed-lib.so: file format elf32-littlearm +architecture: arm, flags 0x00000150: +HAS_SYMS, DYNAMIC, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <lib_func1-0x1c> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <lib_func1>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebfffff6 bl .* <lib_func1-0x18> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <lib_func2>: + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-lib.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.r diff -N ld/testsuite/ld-arm/mixed-lib.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.r 16 Nov 2004 21:34:59 -0000 @@ -0,0 +1,8 @@ + +tmpdir/mixed-lib.so: file format elf32-littlearm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_JUMP_SLOT app_func2 + + Index: ld/testsuite/ld-arm/mixed-lib.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.s diff -N ld/testsuite/ld-arm/mixed-lib.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.s 16 Nov 2004 21:45:17 -0000 @@ -0,0 +1,28 @@ + .text + + .p2align 4 + .globl lib_func1 + .type lib_func1, %function +lib_func1: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func2 + ldmia sp, {r11, sp, lr} + bx lr + .size lib_func1, . - lib_func1 + + .p2align 4 + .globl lib_func2 + .type lib_func2, %function + .thumb_func + .code 16 +lib_func2: + bx lr + .size lib_func2, . - lib_func2 + + .data + .globl data_obj + .type data_obj, %object +data_obj: + .long 0 + .size data_obj, . - data_obj Index: ld/testsuite/ld-arm/mixed-lib.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.sym diff -N ld/testsuite/ld-arm/mixed-lib.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.sym 16 Nov 2004 21:44:37 -0000 @@ -0,0 +1,16 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + 14 1: .* 0 NOTYPE GLOBAL DEFAULT ABS _edata + 8 1: .*0 20 FUNC GLOBAL DEFAULT 6 lib_func1 + 7 2: .*0 2 THUMB_FUNC GLOBAL DEFAULT 6 lib_func2 + 5 2: .* 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ + 4 4: .* 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + 10 5: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + 13 10: .* 4 OBJECT GLOBAL DEFAULT 9 data_obj + 6 10: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + 11 11: .* 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + 15 13: .* 0 NOTYPE GLOBAL DEFAULT ABS _end + 9 13: 00000000 0 NOTYPE GLOBAL DEFAULT UND app_func2 + 16 14: .* 0 NOTYPE GLOBAL DEFAULT 9 __data_start + 12 14: .* 0 NOTYPE GLOBAL DEFAULT ABS __end__ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-16 23:39 RFA: Support for Thumb in dynamic objects Daniel Jacobowitz @ 2004-11-17 0:22 ` Paul Brook 2004-11-17 0:37 ` Daniel Jacobowitz 2004-11-17 1:37 ` Ian Lance Taylor 2004-11-17 13:48 ` Richard Earnshaw 2 siblings, 1 reply; 13+ messages in thread From: Paul Brook @ 2004-11-17 0:22 UTC (permalink / raw) To: binutils; +Cc: Daniel Jacobowitz On Tuesday 16 November 2004 23:39, Daniel Jacobowitz wrote: > +/* An initial stub used if the PLT entry is referenced from Thumb code. > */ +#define PLT_THUMB_STUB_SIZE 4 > +static const bfd_vma elf32_arm_plt_thumb_stub [1] = > + { > + 0x46c04778 /* bx pc; nop (in Thumb mode) */ > + }; Does this DTRT on big-endian targets? Paul ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 0:22 ` Paul Brook @ 2004-11-17 0:37 ` Daniel Jacobowitz 0 siblings, 0 replies; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-17 0:37 UTC (permalink / raw) To: Paul Brook; +Cc: binutils On Wed, Nov 17, 2004 at 12:22:20AM +0000, Paul Brook wrote: > On Tuesday 16 November 2004 23:39, Daniel Jacobowitz wrote: > > +/* An initial stub used if the PLT entry is referenced from Thumb code. > > Â */ +#define PLT_THUMB_STUB_SIZE 4 > > +static const bfd_vma elf32_arm_plt_thumb_stub [1] = > > + Â { > > + Â Â 0x46c04778Â Â Â Â Â Â Â Â Â /* bx pc; nop (in Thumb mode) */ > > + Â }; > > Does this DTRT on big-endian targets? Probably not; I'd have to use 0x46c0, 0x4778 and two bfd_put16's. Thanks for catching that. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-16 23:39 RFA: Support for Thumb in dynamic objects Daniel Jacobowitz 2004-11-17 0:22 ` Paul Brook @ 2004-11-17 1:37 ` Ian Lance Taylor 2004-11-17 3:02 ` Daniel Jacobowitz 2004-11-17 13:48 ` Richard Earnshaw 2 siblings, 1 reply; 13+ messages in thread From: Ian Lance Taylor @ 2004-11-17 1:37 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils Daniel Jacobowitz <drow@false.org> writes: > This patch adds limited support for Thumb in dynamic objects. It causes the > glue stubs not to be exported from the object, and uses a prefix to the PLT > entry to change mode instead of a glue stub off somewhere else. It also > fixes objdump to display thumb functions using the STT_ARM_TFUNC type as > functions. > > It's easy to stop using STT_ARM_TFUNC and start using an odd symbol value > for dynamic objects; but I didn't want to mix it with this patch. So that's > a TODO. Other TODOs are: > - some kind of mappng symbols in the .plt section so that the disassembler > knows what to do (we can't easily generate new local symbols from the > backend, but I'm sure there's a way around it); this is very important > for GDB. > - Related, synthetic named symbols for the .plt as implemented for other > architectures. > - BLX support. The only reason I didn't do this is that there's no easy > way to tell if using BLX is OK; i.e. whether we can assume the presence > of ARM v5t. > > OK? Comments? My main comment is that I've done similar work, but I had the luxury of simply assuming ARMv5t. You can do so much better in that case that I do think we need to let the linker make that assumption when possible. The easy way to do it automatically would be to say that if any input .o file is marked for a processor supporting ARMv5t or above, we can assume that the output will be too, and we can use ARMv5t in the PLT support, etc. There is, of course, a second related issue, which is whether the other objects involved in the dynamic link are compiled with interworking support. In my case I could not assume that. So while my linker doesn't add a stub for each R_ARM_THM_PC22 reloc--it just changes those to blx when appropriate--it does automatically add a stub for ABS32 and GOT32 references to Thumb code. I don't have a good automatic solution here--perhaps the new new ABI, which I gather requires interworking support, will take the issue off the table. Along similar lines it is quite easy for the linker to generate stubs for all functions potentially referenced by non-interworking code, so the need for the -mcallee-super-interworking option goes away. Ian ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 1:37 ` Ian Lance Taylor @ 2004-11-17 3:02 ` Daniel Jacobowitz 2004-11-17 3:42 ` Ian Lance Taylor 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-17 3:02 UTC (permalink / raw) To: binutils On Tue, Nov 16, 2004 at 08:37:31PM -0500, Ian Lance Taylor wrote: > My main comment is that I've done similar work, but I had the luxury > of simply assuming ARMv5t. You can do so much better in that case > that I do think we need to let the linker make that assumption when > possible. The easy way to do it automatically would be to say that if > any input .o file is marked for a processor supporting ARMv5t or > above, we can assume that the output will be too, and we can use > ARMv5t in the PLT support, etc. That's what I've done in the past - a previous version of this patch used this to select v4t interworking capable PLT entries. But - none of that is EABI compliant. I don't know whether the EABI has got anything to say on this subject yet; I know it was discussed. But the way the GNU tools use ELF header flags is noncompliant, so I've been trying not to introduce more uses. So I just punted on the issue. > There is, of course, a second related issue, which is whether the > other objects involved in the dynamic link are compiled with > interworking support. In my case I could not assume that. So while > my linker doesn't add a stub for each R_ARM_THM_PC22 reloc--it just > changes those to blx when appropriate--it does automatically add a > stub for ABS32 and GOT32 references to Thumb code. I don't have a > good automatic solution here--perhaps the new new ABI, which I gather > requires interworking support, will take the issue off the table. > > Along similar lines it is quite easy for the linker to generate stubs > for all functions potentially referenced by non-interworking code, so > the need for the -mcallee-super-interworking option goes away. I haven't done any work on the linker equivalents of super interworking, since I didn't need them at the time. If you'd like to contribute it, of course... :-) -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 3:02 ` Daniel Jacobowitz @ 2004-11-17 3:42 ` Ian Lance Taylor 0 siblings, 0 replies; 13+ messages in thread From: Ian Lance Taylor @ 2004-11-17 3:42 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils Daniel Jacobowitz <drow@false.org> writes: > > There is, of course, a second related issue, which is whether the > > other objects involved in the dynamic link are compiled with > > interworking support. In my case I could not assume that. So while > > my linker doesn't add a stub for each R_ARM_THM_PC22 reloc--it just > > changes those to blx when appropriate--it does automatically add a > > stub for ABS32 and GOT32 references to Thumb code. I don't have a > > good automatic solution here--perhaps the new new ABI, which I gather > > requires interworking support, will take the issue off the table. > > > > Along similar lines it is quite easy for the linker to generate stubs > > for all functions potentially referenced by non-interworking code, so > > the need for the -mcallee-super-interworking option goes away. > > I haven't done any work on the linker equivalents of super > interworking, since I didn't need them at the time. If you'd like to > contribute it, of course... :-) Of course, before I can contribute them, we have to work out the issues of when you can use ARMv5T and when you can't assume the code supports interworking.... (Of course the linker can only handle -mcallee-super-interworking. -mcaller-super-interworking requires compiler support. That was unfortunately broken since it was written; I implemented my own version, only to discover that it has been fixed in the current compiler anyhow. (Although I do wonder what happens with the current compiler when using a shared libgcc and making a caller-super-interworking call via ip.)) Ian ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-16 23:39 RFA: Support for Thumb in dynamic objects Daniel Jacobowitz 2004-11-17 0:22 ` Paul Brook 2004-11-17 1:37 ` Ian Lance Taylor @ 2004-11-17 13:48 ` Richard Earnshaw 2004-11-17 16:49 ` Daniel Jacobowitz 2 siblings, 1 reply; 13+ messages in thread From: Richard Earnshaw @ 2004-11-17 13:48 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils On Tue, 2004-11-16 at 23:39, Daniel Jacobowitz wrote: > This patch adds limited support for Thumb in dynamic objects. It causes the > glue stubs not to be exported from the object, and uses a prefix to the PLT > entry to change mode instead of a glue stub off somewhere else. It also > fixes objdump to display thumb functions using the STT_ARM_TFUNC type as > functions. > > It's easy to stop using STT_ARM_TFUNC and start using an odd symbol value > for dynamic objects; but I didn't want to mix it with this patch. So that's > a TODO. Other TODOs are: > - some kind of mappng symbols in the .plt section so that the disassembler > knows what to do (we can't easily generate new local symbols from the > backend, but I'm sure there's a way around it); this is very important > for GDB. This is also essential for BE-8 support. Without it we can't byte-swap correctly (though if byte-swapping were to be integrated into the linker it could be fudged some other way). > - Related, synthetic named symbols for the .plt as implemented for other > architectures. > - BLX support. The only reason I didn't do this is that there's no easy > way to tell if using BLX is OK; i.e. whether we can assume the presence > of ARM v5t. Not withstanding the need to invent some suitable way of describing the input object files, ld needs to start handling the -mcpu and -march flags that we currently pass to the compiler and the linker. There are times when building objects that can run on multiple ARM machines where we can't safely determine that because one object file uses (for example) v5t, that it is safe to use v5t instructions everywhere. > > OK? Comments? This is OK once you've addressed the point Paul raised. You might also have to look at the tests when run in big-endian mode too. R. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 13:48 ` Richard Earnshaw @ 2004-11-17 16:49 ` Daniel Jacobowitz 2004-11-17 17:00 ` Richard Earnshaw 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-17 16:49 UTC (permalink / raw) To: Richard Earnshaw; +Cc: binutils, Paul Brook On Wed, Nov 17, 2004 at 01:48:06PM +0000, Richard Earnshaw wrote: > > OK? Comments? > > This is OK once you've addressed the point Paul raised. You might also > have to look at the tests when run in big-endian mode too. I missed some arm-elf vs arm-linux issues, and some big vs little endian issues; no one's run the testsuite in big-endian in a while. I'm reposting for review. There are two changes in the patch that I would like someone else to look at: - I fixed a big-endian Thumb disassembly bug. It would read past the end of the section. - I updated the patterns in the gas unwind tables test. There's some funny byte and nibble swapping going on, so I'd appreciate it if someone (Paul?) could tell me whether the big-endian pattern is correct; it matches gas's output now. Passes the testsuite on arm-elf, armeb-elf, and arm-linux. -- Daniel Jacobowitz 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * elf32-arm.c (PLT_THUMB_STUB_SIZE): Define. (elf32_arm_plt_thumb_stub): New. (struct elf32_arm_link_hash_entry): Add plt_thumb_refcount and plt_got_offset. (elf32_arm_link_hash_traverse): Fix typo. (elf32_arm_link_hash_table): Add obfd. (elf32_arm_link_hash_newfunc): Initialize new fields. (elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount. (elf32_arm_link_hash_table_create): Initialize obfd. (record_arm_to_thumb_glue): Mark the glue as a local ARM function. (record_thumb_to_arm_glue): Mark the glue as a local Thumb function. (bfd_elf32_arm_get_bfd_for_interworking): Verify that the interworking BFD is not dynamic. (bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32. Do not emit glue for PLT references. (elf32_arm_final_link_relocate): Handle Thumb functions. Do not emit glue for PLT references. Support the Thumb PLT prefix. (elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and plt_thumb_refcount. (elf32_arm_check_relocs): Likewise. (elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and plt_thumb_refcount. (allocate_dynrelocs): Handle Thumb PLT references. (elf32_arm_finish_dynamic_symbol): Likewise. (elf32_arm_symbol_processing): New function. (elf_backend_symbol_processing): Define. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * arm-dis.c (print_insn): Correct big-endian end-of-section handling. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * gas/arm/mapping.d: Expect F markers for Thumb code. * gas/arm/unwind.d: Update big-endian pattern. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use a dynamic object for stubs. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s, ld-arm/mixed-app.sym, ld-arm/mixed-lib.d, ld-arm/mixed-lib.r, ld-arm/mixed-lib.s, ld-arm/mixed-lib.sym, ld-arm/arm-dyn.ld, ld-arm/arm-lib.ld: New files. * ld-arm/arm-app-abs32.d, ld-arm/arm-app-abs32.r, ld-arm/arm-app.d, ld-arm/arm-app.r, ld-arm/arm-lib-plt32.d, ld-arm/arm-lib-plt32.r, ld-arm/arm-lib.d, ld-arm/arm-lib.r, ld-arm/arm-static-app.d, ld-arm/arm-static-app.r: Update for big-endian. * ld-arm/arm-elf.exp: Run the new tests. Index: bfd/elf32-arm.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/bfd/elf32-arm.c,v retrieving revision 1.7 diff -u -p -r1.7 elf32-arm.c --- bfd/elf32-arm.c 13 Nov 2004 13:38:15 -0000 1.7 +++ bfd/elf32-arm.c 17 Nov 2004 15:20:34 -0000 @@ -1063,6 +1063,14 @@ static const bfd_vma elf32_arm_plt_entry #endif +/* An initial stub used if the PLT entry is referenced from Thumb code. */ +#define PLT_THUMB_STUB_SIZE 4 +static const bfd_vma elf32_arm_plt_thumb_stub [] = + { + 0x4778, /* bx pc */ + 0x46c0 /* nop */ + }; + /* The entries in a PLT when using a DLL-based target with multiple address spaces. */ static const bfd_vma elf32_arm_symbian_plt_entry [] = @@ -1116,13 +1124,22 @@ struct elf32_arm_link_hash_entry /* Number of PC relative relocs copied for this symbol. */ struct elf32_arm_relocs_copied * relocs_copied; + + /* We reference count Thumb references to a PLT entry separately, + so that we can emit the Thumb trampoline only if needed. */ + bfd_signed_vma plt_thumb_refcount; + + /* Since PLT entries have variable size if the Thumb prologue is + used, we need to record the index into .got.plt instead of + recomputing it from the PLT offset. */ + bfd_signed_vma plt_got_offset; }; /* Traverse an arm ELF linker hash table. */ #define elf32_arm_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (bfd_boolean (*) (struct elf_link_hash_entry *, void *))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) /* Get the ARM elf linker hash table from a link_info structure. */ @@ -1178,6 +1195,9 @@ struct elf32_arm_link_hash_table /* Small local sym to section mapping cache. */ struct sym_sec_cache sym_sec; + + /* For convenience in allocate_dynrelocs. */ + bfd * obfd; }; /* Create an entry in an ARM ELF linker hash table. */ @@ -1202,7 +1222,11 @@ elf32_arm_link_hash_newfunc (struct bfd_ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); if (ret != NULL) - ret->relocs_copied = NULL; + { + ret->relocs_copied = NULL; + ret->plt_thumb_refcount = 0; + ret->plt_got_offset = -1; + } return (struct bfd_hash_entry *) ret; } @@ -1315,6 +1339,17 @@ elf32_arm_copy_indirect_symbol (const st eind->relocs_copied = NULL; } + /* If the direct symbol already has an associated PLT entry, the + indirect symbol should not. If it doesn't, swap refcount information + from the indirect symbol. */ + if (edir->plt_thumb_refcount == 0) + { + edir->plt_thumb_refcount = eind->plt_thumb_refcount; + eind->plt_thumb_refcount = 0; + } + else + BFD_ASSERT (eind->plt_thumb_refcount == 0); + _bfd_elf_link_hash_copy_indirect (bed, dir, ind); } @@ -1360,6 +1395,7 @@ elf32_arm_link_hash_table_create (bfd *a #endif ret->symbian_p = 0; ret->sym_sec.abfd = NULL; + ret->obfd = abfd; return &ret->root.root; } @@ -1559,6 +1595,10 @@ record_arm_to_thumb_glue (struct bfd_lin tmp_name, BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh); + myh = (struct elf_link_hash_entry *) bh; + myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC); + myh->forced_local = 1; + free (tmp_name); globals->arm_glue_size += ARM2THUMB_GLUE_SIZE; @@ -1576,7 +1616,6 @@ record_thumb_to_arm_glue (struct bfd_lin struct elf_link_hash_entry *myh; struct bfd_link_hash_entry *bh; struct elf32_arm_link_hash_table *hash_table; - char bind; bfd_vma val; hash_table = elf32_arm_hash_table (link_info); @@ -1614,8 +1653,8 @@ record_thumb_to_arm_glue (struct bfd_lin /* If we mark it 'Thumb', the disassembler will do a better job. */ myh = (struct elf_link_hash_entry *) bh; - bind = ELF_ST_BIND (myh->type); - myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC); + myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC); + myh->forced_local = 1; free (tmp_name); @@ -1713,6 +1752,9 @@ bfd_elf32_arm_get_bfd_for_interworking ( if (info->relocatable) return TRUE; + /* Make sure we don't attach the glue sections to a dynamic object. */ + BFD_ASSERT (!(abfd->flags & DYNAMIC)); + globals = elf32_arm_hash_table (info); BFD_ASSERT (globals != NULL); @@ -1796,6 +1838,7 @@ bfd_elf32_arm_process_before_allocation /* These are the only relocation types we care about. */ if ( r_type != R_ARM_PC24 + && r_type != R_ARM_PLT32 #ifndef OLD_ARM_ABI && r_type != R_ARM_CALL && r_type != R_ARM_JUMP24 @@ -1834,6 +1877,11 @@ bfd_elf32_arm_process_before_allocation if (h == NULL) continue; + /* If the call will go through a PLT entry then we do not need + glue. */ + if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1) + continue; + switch (r_type) { case R_ARM_PC24: @@ -2374,6 +2422,8 @@ elf32_arm_final_link_relocate (reloc_how /* This symbol is local, or marked to become local. */ relocate = TRUE; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; if (globals->symbian_p) { /* On Symbian OS, the data segment and text segement @@ -2652,8 +2702,11 @@ elf32_arm_final_link_relocate (reloc_how { /* If it is not a call to Thumb, assume call to Arm. If it is a call relative to a section name, then it is not a - function call at all, but rather a long jump. */ - if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION) + function call at all, but rather a long jump. Calls through + the PLT do not require stubs. */ + if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION + && (h == NULL || splt == NULL + || h->plt.offset == (bfd_vma) -1)) { if (elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section, @@ -2664,6 +2717,16 @@ elf32_arm_final_link_relocate (reloc_how } } + /* Handle calls via the PLT. */ + if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1) + { + value = (splt->output_section->vma + + splt->output_offset + + h->plt.offset); + /* Target the Thumb stub before the ARM PLT entry. */ + value -= 4; + } + relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -2911,6 +2974,13 @@ elf32_arm_final_link_relocate (reloc_how off &= ~1; else { + /* If we are addressing a Thumb function, we need to + adjust the address by one, so that attempts to + call the function pointer will correctly + interpret it as Thumb code. */ + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + bfd_put_32 (output_bfd, value, sgot->contents + off); if (info->shared) @@ -3873,6 +3943,9 @@ elf32_arm_gc_sweep_hook (bfd * case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be here also? */ + r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx >= symtab_hdr->sh_info) { @@ -3881,15 +3954,18 @@ elf32_arm_gc_sweep_hook (bfd * struct elf32_arm_relocs_copied *p; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.refcount > 0) - h->plt.refcount -= 1; + { + h->plt.refcount -= 1; + if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22) + eh->plt_thumb_refcount--; + } if (r_type == R_ARM_ABS32 || r_type == R_ARM_REL32) { - eh = (struct elf32_arm_link_hash_entry *) h; - for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next) if (p->section == sec) @@ -3948,6 +4024,7 @@ elf32_arm_check_relocs (bfd *abfd, struc for (rel = relocs; rel < rel_end; rel++) { struct elf_link_hash_entry *h; + struct elf32_arm_link_hash_entry *eh; unsigned long r_symndx; int r_type; @@ -3961,6 +4038,8 @@ elf32_arm_check_relocs (bfd *abfd, struc else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; + switch (r_type) { case R_ARM_GOT32: @@ -4015,6 +4094,8 @@ elf32_arm_check_relocs (bfd *abfd, struc case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be listed here? */ if (h != NULL) { /* If this reloc is in a read-only section, we might @@ -4036,12 +4117,16 @@ elf32_arm_check_relocs (bfd *abfd, struc || r_type == R_ARM_JUMP24 || r_type == R_ARM_PREL31 #endif - || r_type == R_ARM_PLT32) + || r_type == R_ARM_PLT32 + || r_type == R_ARM_THM_PC22) h->needs_plt = 1; /* If we create a PLT entry, this relocation will reference it, even if it's an ABS32 relocation. */ h->plt.refcount += 1; + + if (r_type == R_ARM_THM_PC22) + eh->plt_thumb_refcount += 1; } /* If we are creating a shared library, and this is a reloc @@ -4065,7 +4150,8 @@ elf32_arm_check_relocs (bfd *abfd, struc && r_type != R_ARM_JUMP24 && r_type != R_ARM_PREL31 #endif - && r_type != R_ARM_REL32) + && r_type != R_ARM_REL32 + && r_type != R_ARM_THM_PC22) || (h != NULL && (! info->symbolic || !h->def_regular)))) @@ -4314,6 +4400,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd * dynobj; asection * s; unsigned int power_of_two; + struct elf32_arm_link_hash_entry * eh; dynobj = elf_hash_table (info)->dynobj; @@ -4325,10 +4412,12 @@ elf32_arm_adjust_dynamic_symbol (struct && h->ref_regular && !h->def_regular))); + eh = (struct elf32_arm_link_hash_entry *) h; + /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC || h->needs_plt) { if (h->plt.refcount <= 0 @@ -4342,18 +4431,22 @@ elf32_arm_adjust_dynamic_symbol (struct such a case, we don't actually need to build a procedure linkage table, and we can just do a PC24 reloc instead. */ h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; h->needs_plt = 0; } return TRUE; } else - /* It's possible that we incorrectly decided a .plt reloc was - needed for an R_ARM_PC24 or similar reloc to a non-function sym - in check_relocs. We can't decide accurately between function - and non-function syms in check-relocs; Objects loaded later in - the link may change h->type. So fix it now. */ - h->plt.offset = (bfd_vma) -1; + { + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_ARM_PC24 or similar reloc to a non-function sym + in check_relocs. We can't decide accurately between function + and non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ + h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; + } /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the @@ -4438,6 +4531,8 @@ allocate_dynrelocs (struct elf_link_hash struct elf32_arm_link_hash_entry *eh; struct elf32_arm_relocs_copied *p; + eh = (struct elf32_arm_link_hash_entry *) h; + if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -4474,6 +4569,14 @@ allocate_dynrelocs (struct elf_link_hash h->plt.offset = s->size; + /* If we will insert a Thumb trampoline before this PLT, leave room + for it. */ + if (!htab->symbian_p && eh->plt_thumb_refcount > 0) + { + h->plt.offset += PLT_THUMB_STUB_SIZE; + s->size += PLT_THUMB_STUB_SIZE; + } + /* If this symbol is not defined in a regular file, and we are not generating a shared library, then set the symbol to this location in the .plt. This is required to make function @@ -4484,15 +4587,24 @@ allocate_dynrelocs (struct elf_link_hash { h->root.u.def.section = s; h->root.u.def.value = h->plt.offset; + + /* Make sure the function is not marked as Thumb, in case + it is the target of an ABS32 relocation, which will + point to the PLT entry. */ + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) + h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); } /* Make room for this entry. */ s->size += htab->plt_entry_size; if (!htab->symbian_p) - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - htab->sgotplt->size += 4; + { + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + eh->plt_got_offset = htab->sgotplt->size; + htab->sgotplt->size += 4; + } /* We also need to make an entry in the .rel.plt section. */ htab->srelplt->size += sizeof (Elf32_External_Rel); @@ -4539,7 +4651,6 @@ allocate_dynrelocs (struct elf_link_hash else h->got.offset = (bfd_vma) -1; - eh = (struct elf32_arm_link_hash_entry *) h; if (eh->relocs_copied == NULL) return TRUE; @@ -4864,9 +4975,11 @@ elf32_arm_finish_dynamic_symbol (bfd * o { bfd * dynobj; struct elf32_arm_link_hash_table *htab; + struct elf32_arm_link_hash_entry *eh; dynobj = elf_hash_table (info)->dynobj; htab = elf32_arm_hash_table (info); + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.offset != (bfd_vma) -1) { @@ -4885,13 +4998,6 @@ elf32_arm_finish_dynamic_symbol (bfd * o srel = bfd_get_section_by_name (dynobj, ".rel.plt"); BFD_ASSERT (splt != NULL && srel != NULL); - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = ((h->plt.offset - htab->plt_header_size) - / htab->plt_entry_size); - /* Fill in the entry in the procedure linkage table. */ if (htab->symbian_p) { @@ -4906,6 +5012,13 @@ elf32_arm_finish_dynamic_symbol (bfd * o + splt->output_offset + h->plt.offset + 4 * (i - 1)); rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT); + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first entry in the procedure linkage table is reserved. */ + plt_index = ((h->plt.offset - htab->plt_header_size) + / htab->plt_entry_size); } else { @@ -4916,13 +5029,21 @@ elf32_arm_finish_dynamic_symbol (bfd * o sgot = bfd_get_section_by_name (dynobj, ".got.plt"); BFD_ASSERT (sgot != NULL); - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; + /* Get the offset into the .got.plt table of the entry that + corresponds to this function. */ + got_offset = eh->plt_got_offset; + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first three entries in .got.plt are reserved; after that + symbols appear in the same order as in .plt. */ + plt_index = (got_offset - 12) / 4; /* Calculate the displacement between the PLT slot and the - entry in the GOT. */ + entry in the GOT. The eight-byte offset accounts for the + value produced by adding to pc in the first instruction + of the PLT stub. */ got_displacement = (sgot->output_section->vma + sgot->output_offset + got_offset @@ -4933,6 +5054,14 @@ elf32_arm_finish_dynamic_symbol (bfd * o BFD_ASSERT ((got_displacement & 0xf0000000) == 0); + if (eh->plt_thumb_refcount > 0) + { + bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0], + splt->contents + h->plt.offset - 4); + bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1], + splt->contents + h->plt.offset - 2); + } + bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20), splt->contents + h->plt.offset + 0); bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12), @@ -5518,6 +5647,18 @@ elf32_arm_write_section (bfd *output_bfd return FALSE; } +/* Display STT_ARM_TFUNC symbols as functions. */ + +static void +elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym; + + if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_ARM_TFUNC) + elfsym->symbol.flags |= BSF_FUNCTION; +} + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #ifdef __QNXTARGET__ @@ -5556,6 +5697,7 @@ elf32_arm_write_section (bfd *output_bfd #define elf_backend_section_from_shdr elf32_arm_section_from_shdr #define elf_backend_final_write_processing elf32_arm_final_write_processing #define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol +#define elf_backend_symbol_processing elf32_arm_symbol_processing #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 @@ -5688,4 +5830,3 @@ elf32_arm_symbian_modify_segment_map (bf #define elf_backend_want_got_plt 0 #include "elf32-target.h" - Index: gas/testsuite/gas/arm/mapping.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/mapping.d,v retrieving revision 1.2 diff -u -p -r1.2 mapping.d --- gas/testsuite/gas/arm/mapping.d 14 Oct 2004 16:04:09 -0000 1.2 +++ gas/testsuite/gas/arm/mapping.d 16 Nov 2004 21:15:21 -0000 @@ -10,9 +10,9 @@ SYMBOL TABLE: 0+00 l d .data 0+0 0+00 l d .bss 0+0 0+00 l F .text 0+0 \$a -0+08 l .text 0+0 \$t +0+08 l F .text 0+0 \$t 0+00 l O .data 0+0 \$d 0+00 l d foo 0+0 -0+00 l foo 0+0 \$t +0+00 l F foo 0+0 \$t 0+00 g .text 0+0 mapping -0+08 g .text 0+0 thumb_mapping +0+08 g F .text 0+0 thumb_mapping Index: gas/testsuite/gas/arm/unwind.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/unwind.d,v retrieving revision 1.1 diff -u -p -r1.1 unwind.d --- gas/testsuite/gas/arm/unwind.d 5 Oct 2004 13:51:40 -0000 1.1 +++ gas/testsuite/gas/arm/unwind.d 17 Nov 2004 16:32:36 -0000 @@ -21,13 +21,13 @@ OFFSET TYPE VALUE Contents of section .text: - 0000 (0000a0e3 0100a0e3 0200a0e3 0300a0e3|e3a00000 a0e30001 e3a00002 e3a00003) .* + 0000 (0000a0e3 0100a0e3 0200a0e3 0300a0e3|e3a00000 e3a00001 e3a00002 e3a00003) .* 0010 (0420|2004) .* Contents of section .ARM.extab: 0000 (449b0181 b0b08086|81019b44 8680b0b0) 00000000 00000000 .* - 0010 (8402b101 b0b0b005 2a000000 00c60181|01b10284 05b0b0b0 000000a2 8101c600) .* + 0010 (8402b101 b0b0b005 2a000000 00c60181|01b10284 05b0b0b0 0000002a 8101c600) .* 0020 (b0b0c1c1|c1c1b0b0) 00000000 .* Contents of section .ARM.exidx: 0000 00000000 (b0b0a880 04000000|80a8b0b0 00000004) 00000000 .* 0010 (08000000 0c000000 0c000000 1c000000|00000008 0000000c 0000000c 0000001c) .* - 0020 (10000000 08849780|00000010 80978480) .* + 0020 (10000000 08849780|00000010 80978408) .* Index: ld/emultempl/armelf.em =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/emultempl/armelf.em,v retrieving revision 1.40 diff -u -p -r1.40 armelf.em --- ld/emultempl/armelf.em 17 Sep 2004 12:18:18 -0000 1.40 +++ ld/emultempl/armelf.em 16 Nov 2004 20:52:24 -0000 @@ -78,8 +78,11 @@ arm_elf_set_bfd_for_interworking (lang_s ASSERT (output_section->owner == output_bfd); + /* Don't attach the interworking stubs to a dynamic object, to + an empty section, etc. */ if ((output_section->flags & SEC_HAS_CONTENTS) != 0 && (i->flags & SEC_NEVER_LOAD) == 0 + && ! (i->owner->flags & DYNAMIC) && ! i->owner->output_has_begun) { bfd_for_interwork = i->owner; Index: ld/testsuite/ld-arm/arm-app-abs32.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app-abs32.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-app-abs32.d --- ld/testsuite/ld-arm/arm-app-abs32.d 23 Jan 2004 16:51:39 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app-abs32.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app-abs32: file format elf32-littlearm +tmpdir/arm-app-abs32: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address .* Index: ld/testsuite/ld-arm/arm-app-abs32.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app-abs32.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-app-abs32.r --- ld/testsuite/ld-arm/arm-app-abs32.r 23 Jan 2004 16:51:39 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app-abs32.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app-abs32: file format elf32-littlearm +tmpdir/arm-app-abs32: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-app.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-app.d --- ld/testsuite/ld-arm/arm-app.d 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app: file format elf32-littlearm +tmpdir/arm-app: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-app.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-app.r --- ld/testsuite/ld-arm/arm-app.r 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app: file format elf32-littlearm +tmpdir/arm-app: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-dyn.ld =================================================================== RCS file: ld/testsuite/ld-arm/arm-dyn.ld diff -N ld/testsuite/ld-arm/arm-dyn.ld --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/arm-dyn.ld 17 Nov 2004 16:03:09 -0000 @@ -0,0 +1,199 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_ARCH(arm) +ENTRY(_start) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x8000); . = 0x8000; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(256) + (. & (256 - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { KEEP (*(.preinit_array)) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } + PROVIDE (__fini_array_end = .); + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.got) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) } +} + + Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.5 diff -u -p -r1.5 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 30 Sep 2004 17:03:52 -0000 1.5 +++ ld/testsuite/ld-arm/arm-elf.exp 17 Nov 2004 15:55:06 -0000 @@ -47,6 +47,16 @@ set armelftests { {"Non-pcrel function reference" "tmpdir/arm-lib.so" "" {arm-app-abs32.s} {{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}} "arm-app-abs32"} + {"Mixed ARM/Thumb shared library" "-shared -T arm-lib.ld" "" + {mixed-lib.s} + {{objdump -fdw mixed-lib.d} {objdump -Rw mixed-lib.r} + {readelf -Ds mixed-lib.sym}} + "mixed-lib.so"} + {"Mixed ARM/Thumb dynamic application" "tmpdir/mixed-lib.so -T arm-dyn.ld" "" + {mixed-app.s} + {{objdump -fdw mixed-app.d} {objdump -Rw mixed-app.r} + {readelf -Ds mixed-app.sym}} + "mixed-app"} {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s} {{objdump -s arm-target1-abs.d}} "arm-target1-abs"} Index: ld/testsuite/ld-arm/arm-lib-plt32.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib-plt32.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-lib-plt32.d --- ld/testsuite/ld-arm/arm-lib-plt32.d 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-lib-plt32.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib-plt32.so: file format elf32-littlearm +tmpdir/arm-lib-plt32.so: file format elf32-(little|big)arm architecture: arm, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-lib-plt32.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib-plt32.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-lib-plt32.r --- ld/testsuite/ld-arm/arm-lib-plt32.r 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-lib-plt32.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib-plt32.so: file format elf32-littlearm +tmpdir/arm-lib-plt32.so: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-lib.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib.d,v retrieving revision 1.2 diff -u -p -r1.2 arm-lib.d --- ld/testsuite/ld-arm/arm-lib.d 9 Jan 2004 16:53:10 -0000 1.2 +++ ld/testsuite/ld-arm/arm-lib.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib.so: file format elf32-littlearm +tmpdir/arm-lib.so: file format elf32-(little|big)arm architecture: arm, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-lib.ld =================================================================== RCS file: ld/testsuite/ld-arm/arm-lib.ld diff -N ld/testsuite/ld-arm/arm-lib.ld --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/arm-lib.ld 17 Nov 2004 16:03:09 -0000 @@ -0,0 +1,192 @@ +/* Script for --shared -z combreloc: shared library, combine & sort relocs */ +OUTPUT_ARCH(arm) +ENTRY(_start) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0 + SIZEOF_HEADERS; + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(256) + (. & (256 - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + .preinit_array : { KEEP (*(.preinit_array)) } + .init_array : { KEEP (*(.init_array)) } + .fini_array : { KEEP (*(.fini_array)) } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.got) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) } +} + + Index: ld/testsuite/ld-arm/arm-lib.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib.r,v retrieving revision 1.2 diff -u -p -r1.2 arm-lib.r --- ld/testsuite/ld-arm/arm-lib.r 9 Jan 2004 16:53:10 -0000 1.2 +++ ld/testsuite/ld-arm/arm-lib.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib.so: file format elf32-littlearm +tmpdir/arm-lib.so: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-static-app.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-static-app.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-static-app.d --- ld/testsuite/ld-arm/arm-static-app.d 13 Jan 2004 21:09:18 -0000 1.1 +++ ld/testsuite/ld-arm/arm-static-app.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-static-app: file format elf32-littlearm +tmpdir/arm-static-app: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-static-app.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-static-app.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-static-app.r --- ld/testsuite/ld-arm/arm-static-app.r 13 Jan 2004 21:09:18 -0000 1.1 +++ ld/testsuite/ld-arm/arm-static-app.r 17 Nov 2004 16:29:22 -0000 @@ -1,3 +1,3 @@ -tmpdir/arm-static-app: file format elf32-littlearm +tmpdir/arm-static-app: file format elf32-(little|big)arm Index: ld/testsuite/ld-arm/mixed-app.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.d diff -N ld/testsuite/ld-arm/mixed-app.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.d 17 Nov 2004 16:12:25 -0000 @@ -0,0 +1,57 @@ + +tmpdir/mixed-app: file format elf32-(little|big)arm +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <.plt\+0x10> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: (46c04778 undefined|477846c0 ldrmib r4, \[r8, -r0, asr #13\]!) + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <_start>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: eb000004 bl .* <app_func> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebffffe. bl .* <.text-0x..> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func2>: + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_tfunc>: + .*: b500 push {lr} + .*: (ffc.f7ff|f7ffffc.) bl .* <.text-0x..> + .*: bd00 pop {pc} + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-app.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.r diff -N ld/testsuite/ld-arm/mixed-app.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.r 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,10 @@ + +tmpdir/mixed-app: file format elf32-(little|big)arm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_COPY data_obj +.* R_ARM_JUMP_SLOT lib_func2 +.* R_ARM_JUMP_SLOT lib_func1 + + Index: ld/testsuite/ld-arm/mixed-app.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.s diff -N ld/testsuite/ld-arm/mixed-app.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.s 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,39 @@ + .text + .p2align 4 + .globl _start +_start: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func + .type app_func,%function +app_func: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl lib_func1 + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func2 + .type app_func2,%function +app_func2: + bx lr + + .p2align 4 + .globl app_tfunc + .type app_tfunc,%function + .thumb_func + .code 16 +app_tfunc: + push {lr} + bl lib_func2 + pop {pc} + bx lr + + .data + .long data_obj Index: ld/testsuite/ld-arm/mixed-app.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.sym diff -N ld/testsuite/ld-arm/mixed-app.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.sym 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,19 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _edata + .. ..: 0*[^0]*.* 20 FUNC GLOBAL DEFAULT UND lib_func1 + .. ..: 0*[^0]*.* 2 FUNC GLOBAL DEFAULT UND lib_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ + .. ..: ........ 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 13 _stack + .. ..: ........ 4 OBJECT GLOBAL DEFAULT 12 data_obj + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _end + .. ..: .......0 0 FUNC GLOBAL DEFAULT 8 app_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 11 __data_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start Index: ld/testsuite/ld-arm/mixed-lib.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.d diff -N ld/testsuite/ld-arm/mixed-lib.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.d 17 Nov 2004 16:10:57 -0000 @@ -0,0 +1,38 @@ + +tmpdir/mixed-lib.so: file format elf32-(little|big)arm +architecture: arm, flags 0x00000150: +HAS_SYMS, DYNAMIC, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <lib_func1-0x1.> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <lib_func1>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebfffff. bl .* <lib_func1-0x..> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <lib_func2>: + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-lib.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.r diff -N ld/testsuite/ld-arm/mixed-lib.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.r 17 Nov 2004 16:10:53 -0000 @@ -0,0 +1,8 @@ + +tmpdir/mixed-lib.so: file format elf32-(little|big)arm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_JUMP_SLOT app_func2 + + Index: ld/testsuite/ld-arm/mixed-lib.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.s diff -N ld/testsuite/ld-arm/mixed-lib.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.s 17 Nov 2004 16:10:54 -0000 @@ -0,0 +1,28 @@ + .text + + .p2align 4 + .globl lib_func1 + .type lib_func1, %function +lib_func1: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func2 + ldmia sp, {r11, sp, lr} + bx lr + .size lib_func1, . - lib_func1 + + .p2align 4 + .globl lib_func2 + .type lib_func2, %function + .thumb_func + .code 16 +lib_func2: + bx lr + .size lib_func2, . - lib_func2 + + .data + .globl data_obj + .type data_obj, %object +data_obj: + .long 0 + .size data_obj, . - data_obj Index: ld/testsuite/ld-arm/mixed-lib.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.sym diff -N ld/testsuite/ld-arm/mixed-lib.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.sym 17 Nov 2004 16:10:55 -0000 @@ -0,0 +1,19 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _edata + .. ..: .......0 20 FUNC GLOBAL DEFAULT 6 lib_func1 + .. ..: .......0 2 THUMB_FUNC GLOBAL DEFAULT 6 lib_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ + .. ..: ........ 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 11 _stack + .. ..: ........ 4 OBJECT GLOBAL DEFAULT 9 data_obj + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _end + .. ..: 00000000 0 NOTYPE GLOBAL DEFAULT UND app_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 9 __data_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start Index: opcodes/arm-dis.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/opcodes/arm-dis.c,v retrieving revision 1.38 diff -u -p -r1.38 arm-dis.c --- opcodes/arm-dis.c 30 Sep 2004 16:21:43 -0000 1.38 +++ opcodes/arm-dis.c 17 Nov 2004 16:28:01 -0000 @@ -1253,7 +1253,7 @@ print_insn (pc, info, little) unsigned char b[4]; long given; int status; - int is_thumb; + int is_thumb, second_half_valid = 1; if (info->disassembler_options) { @@ -1299,6 +1299,7 @@ print_insn (pc, info, little) if (status != 0 && is_thumb) { info->bytes_per_chunk = 2; + second_half_valid = 0; status = info->read_memory_func (pc, (bfd_byte *) b, 2, info); b[3] = b[2] = 0; @@ -1318,7 +1319,7 @@ print_insn (pc, info, little) (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info); if (status != 0) { - info->memory_error_func (status, pc, info); + info->memory_error_func (status, pc & ~ 0x3, info); return -1; } @@ -1331,12 +1332,9 @@ print_insn (pc, info, little) status = info->read_memory_func ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info); if (status != 0) - { - info->memory_error_func (status, pc + 4, info); - return -1; - } - - given |= (b[0] << 24) | (b[1] << 16); + second_half_valid = 0; + else + given |= (b[0] << 24) | (b[1] << 16); } else given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16); @@ -1358,6 +1356,12 @@ print_insn (pc, info, little) else status = print_insn_arm (pc, info, given); + if (is_thumb && status == 4 && second_half_valid == 0) + { + info->memory_error_func (status, (pc + 4) & ~ 0x3, info); + return -1; + } + return status; } ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 16:49 ` Daniel Jacobowitz @ 2004-11-17 17:00 ` Richard Earnshaw 2004-11-17 17:05 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Richard Earnshaw @ 2004-11-17 17:00 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils, Paul Brook On Wed, 2004-11-17 at 16:48, Daniel Jacobowitz wrote: > On Wed, Nov 17, 2004 at 01:48:06PM +0000, Richard Earnshaw wrote: > > > OK? Comments? > > > > This is OK once you've addressed the point Paul raised. You might also > > have to look at the tests when run in big-endian mode too. > > I missed some arm-elf vs arm-linux issues, and some big vs little > endian issues; no one's run the testsuite in big-endian in a while. > I'm reposting for review. There are two changes in the patch that I > would like someone else to look at: > > - I fixed a big-endian Thumb disassembly bug. It would read past > the end of the section. Can you use a macro rather than ~0x3? > - I updated the patterns in the gas unwind tables test. There's some > funny byte and nibble swapping going on, so I'd appreciate it if > someone (Paul?) could tell me whether the big-endian pattern is correct; > it matches gas's output now. > This is clearly OK, the values in the big-endian side of the table should clearly be the byte-swapped versions of the little-endian side. > Passes the testsuite on arm-elf, armeb-elf, and arm-linux. Other than that, OK. R. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 17:00 ` Richard Earnshaw @ 2004-11-17 17:05 ` Daniel Jacobowitz 2004-11-17 17:12 ` Richard Earnshaw 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-17 17:05 UTC (permalink / raw) To: Richard Earnshaw; +Cc: binutils, Paul Brook On Wed, Nov 17, 2004 at 04:59:10PM +0000, Richard Earnshaw wrote: > On Wed, 2004-11-17 at 16:48, Daniel Jacobowitz wrote: > > On Wed, Nov 17, 2004 at 01:48:06PM +0000, Richard Earnshaw wrote: > > > > OK? Comments? > > > > > > This is OK once you've addressed the point Paul raised. You might also > > > have to look at the tests when run in big-endian mode too. > > > > I missed some arm-elf vs arm-linux issues, and some big vs little > > endian issues; no one's run the testsuite in big-endian in a while. > > I'm reposting for review. There are two changes in the patch that I > > would like someone else to look at: > > > > - I fixed a big-endian Thumb disassembly bug. It would read past > > the end of the section. > > Can you use a macro rather than ~0x3? I just copied it from a couple of lines up. How about: ROUND_DOWN (pc + 4, 4) instead? -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 17:05 ` Daniel Jacobowitz @ 2004-11-17 17:12 ` Richard Earnshaw 2004-11-17 17:36 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Richard Earnshaw @ 2004-11-17 17:12 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils, Paul Brook On Wed, 2004-11-17 at 17:05, Daniel Jacobowitz wrote: > On Wed, Nov 17, 2004 at 04:59:10PM +0000, Richard Earnshaw wrote: > > On Wed, 2004-11-17 at 16:48, Daniel Jacobowitz wrote: > > > On Wed, Nov 17, 2004 at 01:48:06PM +0000, Richard Earnshaw wrote: > > > > > OK? Comments? > > > > > > > > This is OK once you've addressed the point Paul raised. You might also > > > > have to look at the tests when run in big-endian mode too. > > > > > > I missed some arm-elf vs arm-linux issues, and some big vs little > > > endian issues; no one's run the testsuite in big-endian in a while. > > > I'm reposting for review. There are two changes in the patch that I > > > would like someone else to look at: > > > > > > - I fixed a big-endian Thumb disassembly bug. It would read past > > > the end of the section. > > > > Can you use a macro rather than ~0x3? > > I just copied it from a couple of lines up. How about: > ROUND_DOWN (pc + 4, 4) > instead? It would certainly be better than the direct manipulation, but I was really thinking 'why are we doing the masking at this point?' Could it be because we want an ARM instruction address? If it's a Thumb insn address why isn't it ~1? A suitably named macro would convey that information directly... R. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 17:12 ` Richard Earnshaw @ 2004-11-17 17:36 ` Daniel Jacobowitz 2004-11-17 17:39 ` Richard Earnshaw 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2004-11-17 17:36 UTC (permalink / raw) To: Richard Earnshaw; +Cc: binutils, Paul Brook On Wed, Nov 17, 2004 at 05:11:20PM +0000, Richard Earnshaw wrote: > On Wed, 2004-11-17 at 17:05, Daniel Jacobowitz wrote: > > On Wed, Nov 17, 2004 at 04:59:10PM +0000, Richard Earnshaw wrote: > > > On Wed, 2004-11-17 at 16:48, Daniel Jacobowitz wrote: > > > > On Wed, Nov 17, 2004 at 01:48:06PM +0000, Richard Earnshaw wrote: > > > > > > OK? Comments? > > > > > > > > > > This is OK once you've addressed the point Paul raised. You might also > > > > > have to look at the tests when run in big-endian mode too. > > > > > > > > I missed some arm-elf vs arm-linux issues, and some big vs little > > > > endian issues; no one's run the testsuite in big-endian in a while. > > > > I'm reposting for review. There are two changes in the patch that I > > > > would like someone else to look at: > > > > > > > > - I fixed a big-endian Thumb disassembly bug. It would read past > > > > the end of the section. > > > > > > Can you use a macro rather than ~0x3? > > > > I just copied it from a couple of lines up. How about: > > ROUND_DOWN (pc + 4, 4) > > instead? > > It would certainly be better than the direct manipulation, but I was > really thinking 'why are we doing the masking at this point?' Could it > be because we want an ARM instruction address? If it's a Thumb insn > address why isn't it ~1? A suitably named macro would convey that > information directly... It's hard to come up with a good name for manipulation that's basically unnecessary. It's trying to do two 32-bit reads if possible instead of a bunch of smaller reads; we could leave this to the client instead. This patch calls it WORD_ADDRESS, since that descrbes the use. It could be throttled down to read 2-byte pieces for Thumb, and to do the read later (i.e. when we see a bl/blx); I'll leave that for another day. OK? -- Daniel Jacobowitz 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * elf32-arm.c (PLT_THUMB_STUB_SIZE): Define. (elf32_arm_plt_thumb_stub): New. (struct elf32_arm_link_hash_entry): Add plt_thumb_refcount and plt_got_offset. (elf32_arm_link_hash_traverse): Fix typo. (elf32_arm_link_hash_table): Add obfd. (elf32_arm_link_hash_newfunc): Initialize new fields. (elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount. (elf32_arm_link_hash_table_create): Initialize obfd. (record_arm_to_thumb_glue): Mark the glue as a local ARM function. (record_thumb_to_arm_glue): Mark the glue as a local Thumb function. (bfd_elf32_arm_get_bfd_for_interworking): Verify that the interworking BFD is not dynamic. (bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32. Do not emit glue for PLT references. (elf32_arm_final_link_relocate): Handle Thumb functions. Do not emit glue for PLT references. Support the Thumb PLT prefix. (elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and plt_thumb_refcount. (elf32_arm_check_relocs): Likewise. (elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and plt_thumb_refcount. (allocate_dynrelocs): Handle Thumb PLT references. (elf32_arm_finish_dynamic_symbol): Likewise. (elf32_arm_symbol_processing): New function. (elf_backend_symbol_processing): Define. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * arm-dis.c (WORD_ADDRESS): Define. (print_insn): Use it. Correct big-endian end-of-section handling. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * gas/arm/mapping.d: Expect F markers for Thumb code. * gas/arm/unwind.d: Update big-endian pattern. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use a dynamic object for stubs. 2004-11-17 Daniel Jacobowitz <dan@codesourcery.com> * ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s, ld-arm/mixed-app.sym, ld-arm/mixed-lib.d, ld-arm/mixed-lib.r, ld-arm/mixed-lib.s, ld-arm/mixed-lib.sym, ld-arm/arm-dyn.ld, ld-arm/arm-lib.ld: New files. * ld-arm/arm-app-abs32.d, ld-arm/arm-app-abs32.r, ld-arm/arm-app.d, ld-arm/arm-app.r, ld-arm/arm-lib-plt32.d, ld-arm/arm-lib-plt32.r, ld-arm/arm-lib.d, ld-arm/arm-lib.r, ld-arm/arm-static-app.d, ld-arm/arm-static-app.r: Update for big-endian. * ld-arm/arm-elf.exp: Run the new tests. Index: bfd/elf32-arm.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/bfd/elf32-arm.c,v retrieving revision 1.7 diff -u -p -r1.7 elf32-arm.c --- bfd/elf32-arm.c 13 Nov 2004 13:38:15 -0000 1.7 +++ bfd/elf32-arm.c 17 Nov 2004 15:20:34 -0000 @@ -1063,6 +1063,14 @@ static const bfd_vma elf32_arm_plt_entry #endif +/* An initial stub used if the PLT entry is referenced from Thumb code. */ +#define PLT_THUMB_STUB_SIZE 4 +static const bfd_vma elf32_arm_plt_thumb_stub [] = + { + 0x4778, /* bx pc */ + 0x46c0 /* nop */ + }; + /* The entries in a PLT when using a DLL-based target with multiple address spaces. */ static const bfd_vma elf32_arm_symbian_plt_entry [] = @@ -1116,13 +1124,22 @@ struct elf32_arm_link_hash_entry /* Number of PC relative relocs copied for this symbol. */ struct elf32_arm_relocs_copied * relocs_copied; + + /* We reference count Thumb references to a PLT entry separately, + so that we can emit the Thumb trampoline only if needed. */ + bfd_signed_vma plt_thumb_refcount; + + /* Since PLT entries have variable size if the Thumb prologue is + used, we need to record the index into .got.plt instead of + recomputing it from the PLT offset. */ + bfd_signed_vma plt_got_offset; }; /* Traverse an arm ELF linker hash table. */ #define elf32_arm_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (bfd_boolean (*) (struct elf_link_hash_entry *, void *))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) /* Get the ARM elf linker hash table from a link_info structure. */ @@ -1178,6 +1195,9 @@ struct elf32_arm_link_hash_table /* Small local sym to section mapping cache. */ struct sym_sec_cache sym_sec; + + /* For convenience in allocate_dynrelocs. */ + bfd * obfd; }; /* Create an entry in an ARM ELF linker hash table. */ @@ -1202,7 +1222,11 @@ elf32_arm_link_hash_newfunc (struct bfd_ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); if (ret != NULL) - ret->relocs_copied = NULL; + { + ret->relocs_copied = NULL; + ret->plt_thumb_refcount = 0; + ret->plt_got_offset = -1; + } return (struct bfd_hash_entry *) ret; } @@ -1315,6 +1339,17 @@ elf32_arm_copy_indirect_symbol (const st eind->relocs_copied = NULL; } + /* If the direct symbol already has an associated PLT entry, the + indirect symbol should not. If it doesn't, swap refcount information + from the indirect symbol. */ + if (edir->plt_thumb_refcount == 0) + { + edir->plt_thumb_refcount = eind->plt_thumb_refcount; + eind->plt_thumb_refcount = 0; + } + else + BFD_ASSERT (eind->plt_thumb_refcount == 0); + _bfd_elf_link_hash_copy_indirect (bed, dir, ind); } @@ -1360,6 +1395,7 @@ elf32_arm_link_hash_table_create (bfd *a #endif ret->symbian_p = 0; ret->sym_sec.abfd = NULL; + ret->obfd = abfd; return &ret->root.root; } @@ -1559,6 +1595,10 @@ record_arm_to_thumb_glue (struct bfd_lin tmp_name, BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh); + myh = (struct elf_link_hash_entry *) bh; + myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC); + myh->forced_local = 1; + free (tmp_name); globals->arm_glue_size += ARM2THUMB_GLUE_SIZE; @@ -1576,7 +1616,6 @@ record_thumb_to_arm_glue (struct bfd_lin struct elf_link_hash_entry *myh; struct bfd_link_hash_entry *bh; struct elf32_arm_link_hash_table *hash_table; - char bind; bfd_vma val; hash_table = elf32_arm_hash_table (link_info); @@ -1614,8 +1653,8 @@ record_thumb_to_arm_glue (struct bfd_lin /* If we mark it 'Thumb', the disassembler will do a better job. */ myh = (struct elf_link_hash_entry *) bh; - bind = ELF_ST_BIND (myh->type); - myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC); + myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC); + myh->forced_local = 1; free (tmp_name); @@ -1713,6 +1752,9 @@ bfd_elf32_arm_get_bfd_for_interworking ( if (info->relocatable) return TRUE; + /* Make sure we don't attach the glue sections to a dynamic object. */ + BFD_ASSERT (!(abfd->flags & DYNAMIC)); + globals = elf32_arm_hash_table (info); BFD_ASSERT (globals != NULL); @@ -1796,6 +1838,7 @@ bfd_elf32_arm_process_before_allocation /* These are the only relocation types we care about. */ if ( r_type != R_ARM_PC24 + && r_type != R_ARM_PLT32 #ifndef OLD_ARM_ABI && r_type != R_ARM_CALL && r_type != R_ARM_JUMP24 @@ -1834,6 +1877,11 @@ bfd_elf32_arm_process_before_allocation if (h == NULL) continue; + /* If the call will go through a PLT entry then we do not need + glue. */ + if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1) + continue; + switch (r_type) { case R_ARM_PC24: @@ -2374,6 +2422,8 @@ elf32_arm_final_link_relocate (reloc_how /* This symbol is local, or marked to become local. */ relocate = TRUE; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; if (globals->symbian_p) { /* On Symbian OS, the data segment and text segement @@ -2652,8 +2702,11 @@ elf32_arm_final_link_relocate (reloc_how { /* If it is not a call to Thumb, assume call to Arm. If it is a call relative to a section name, then it is not a - function call at all, but rather a long jump. */ - if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION) + function call at all, but rather a long jump. Calls through + the PLT do not require stubs. */ + if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION + && (h == NULL || splt == NULL + || h->plt.offset == (bfd_vma) -1)) { if (elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section, @@ -2664,6 +2717,16 @@ elf32_arm_final_link_relocate (reloc_how } } + /* Handle calls via the PLT. */ + if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1) + { + value = (splt->output_section->vma + + splt->output_offset + + h->plt.offset); + /* Target the Thumb stub before the ARM PLT entry. */ + value -= 4; + } + relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -2911,6 +2974,13 @@ elf32_arm_final_link_relocate (reloc_how off &= ~1; else { + /* If we are addressing a Thumb function, we need to + adjust the address by one, so that attempts to + call the function pointer will correctly + interpret it as Thumb code. */ + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + bfd_put_32 (output_bfd, value, sgot->contents + off); if (info->shared) @@ -3873,6 +3943,9 @@ elf32_arm_gc_sweep_hook (bfd * case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be here also? */ + r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx >= symtab_hdr->sh_info) { @@ -3881,15 +3954,18 @@ elf32_arm_gc_sweep_hook (bfd * struct elf32_arm_relocs_copied *p; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.refcount > 0) - h->plt.refcount -= 1; + { + h->plt.refcount -= 1; + if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22) + eh->plt_thumb_refcount--; + } if (r_type == R_ARM_ABS32 || r_type == R_ARM_REL32) { - eh = (struct elf32_arm_link_hash_entry *) h; - for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next) if (p->section == sec) @@ -3948,6 +4024,7 @@ elf32_arm_check_relocs (bfd *abfd, struc for (rel = relocs; rel < rel_end; rel++) { struct elf_link_hash_entry *h; + struct elf32_arm_link_hash_entry *eh; unsigned long r_symndx; int r_type; @@ -3961,6 +4038,8 @@ elf32_arm_check_relocs (bfd *abfd, struc else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + eh = (struct elf32_arm_link_hash_entry *) h; + switch (r_type) { case R_ARM_GOT32: @@ -4015,6 +4094,8 @@ elf32_arm_check_relocs (bfd *abfd, struc case R_ARM_JUMP24: case R_ARM_PREL31: #endif + case R_ARM_THM_PC22: + /* Should the interworking branches be listed here? */ if (h != NULL) { /* If this reloc is in a read-only section, we might @@ -4036,12 +4117,16 @@ elf32_arm_check_relocs (bfd *abfd, struc || r_type == R_ARM_JUMP24 || r_type == R_ARM_PREL31 #endif - || r_type == R_ARM_PLT32) + || r_type == R_ARM_PLT32 + || r_type == R_ARM_THM_PC22) h->needs_plt = 1; /* If we create a PLT entry, this relocation will reference it, even if it's an ABS32 relocation. */ h->plt.refcount += 1; + + if (r_type == R_ARM_THM_PC22) + eh->plt_thumb_refcount += 1; } /* If we are creating a shared library, and this is a reloc @@ -4065,7 +4150,8 @@ elf32_arm_check_relocs (bfd *abfd, struc && r_type != R_ARM_JUMP24 && r_type != R_ARM_PREL31 #endif - && r_type != R_ARM_REL32) + && r_type != R_ARM_REL32 + && r_type != R_ARM_THM_PC22) || (h != NULL && (! info->symbolic || !h->def_regular)))) @@ -4314,6 +4400,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd * dynobj; asection * s; unsigned int power_of_two; + struct elf32_arm_link_hash_entry * eh; dynobj = elf_hash_table (info)->dynobj; @@ -4325,10 +4412,12 @@ elf32_arm_adjust_dynamic_symbol (struct && h->ref_regular && !h->def_regular))); + eh = (struct elf32_arm_link_hash_entry *) h; + /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC || h->needs_plt) { if (h->plt.refcount <= 0 @@ -4342,18 +4431,22 @@ elf32_arm_adjust_dynamic_symbol (struct such a case, we don't actually need to build a procedure linkage table, and we can just do a PC24 reloc instead. */ h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; h->needs_plt = 0; } return TRUE; } else - /* It's possible that we incorrectly decided a .plt reloc was - needed for an R_ARM_PC24 or similar reloc to a non-function sym - in check_relocs. We can't decide accurately between function - and non-function syms in check-relocs; Objects loaded later in - the link may change h->type. So fix it now. */ - h->plt.offset = (bfd_vma) -1; + { + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_ARM_PC24 or similar reloc to a non-function sym + in check_relocs. We can't decide accurately between function + and non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ + h->plt.offset = (bfd_vma) -1; + eh->plt_thumb_refcount = 0; + } /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the @@ -4438,6 +4531,8 @@ allocate_dynrelocs (struct elf_link_hash struct elf32_arm_link_hash_entry *eh; struct elf32_arm_relocs_copied *p; + eh = (struct elf32_arm_link_hash_entry *) h; + if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -4474,6 +4569,14 @@ allocate_dynrelocs (struct elf_link_hash h->plt.offset = s->size; + /* If we will insert a Thumb trampoline before this PLT, leave room + for it. */ + if (!htab->symbian_p && eh->plt_thumb_refcount > 0) + { + h->plt.offset += PLT_THUMB_STUB_SIZE; + s->size += PLT_THUMB_STUB_SIZE; + } + /* If this symbol is not defined in a regular file, and we are not generating a shared library, then set the symbol to this location in the .plt. This is required to make function @@ -4484,15 +4587,24 @@ allocate_dynrelocs (struct elf_link_hash { h->root.u.def.section = s; h->root.u.def.value = h->plt.offset; + + /* Make sure the function is not marked as Thumb, in case + it is the target of an ABS32 relocation, which will + point to the PLT entry. */ + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) + h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); } /* Make room for this entry. */ s->size += htab->plt_entry_size; if (!htab->symbian_p) - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - htab->sgotplt->size += 4; + { + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + eh->plt_got_offset = htab->sgotplt->size; + htab->sgotplt->size += 4; + } /* We also need to make an entry in the .rel.plt section. */ htab->srelplt->size += sizeof (Elf32_External_Rel); @@ -4539,7 +4651,6 @@ allocate_dynrelocs (struct elf_link_hash else h->got.offset = (bfd_vma) -1; - eh = (struct elf32_arm_link_hash_entry *) h; if (eh->relocs_copied == NULL) return TRUE; @@ -4864,9 +4975,11 @@ elf32_arm_finish_dynamic_symbol (bfd * o { bfd * dynobj; struct elf32_arm_link_hash_table *htab; + struct elf32_arm_link_hash_entry *eh; dynobj = elf_hash_table (info)->dynobj; htab = elf32_arm_hash_table (info); + eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.offset != (bfd_vma) -1) { @@ -4885,13 +4998,6 @@ elf32_arm_finish_dynamic_symbol (bfd * o srel = bfd_get_section_by_name (dynobj, ".rel.plt"); BFD_ASSERT (splt != NULL && srel != NULL); - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = ((h->plt.offset - htab->plt_header_size) - / htab->plt_entry_size); - /* Fill in the entry in the procedure linkage table. */ if (htab->symbian_p) { @@ -4906,6 +5012,13 @@ elf32_arm_finish_dynamic_symbol (bfd * o + splt->output_offset + h->plt.offset + 4 * (i - 1)); rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT); + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first entry in the procedure linkage table is reserved. */ + plt_index = ((h->plt.offset - htab->plt_header_size) + / htab->plt_entry_size); } else { @@ -4916,13 +5029,21 @@ elf32_arm_finish_dynamic_symbol (bfd * o sgot = bfd_get_section_by_name (dynobj, ".got.plt"); BFD_ASSERT (sgot != NULL); - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; + /* Get the offset into the .got.plt table of the entry that + corresponds to this function. */ + got_offset = eh->plt_got_offset; + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first three entries in .got.plt are reserved; after that + symbols appear in the same order as in .plt. */ + plt_index = (got_offset - 12) / 4; /* Calculate the displacement between the PLT slot and the - entry in the GOT. */ + entry in the GOT. The eight-byte offset accounts for the + value produced by adding to pc in the first instruction + of the PLT stub. */ got_displacement = (sgot->output_section->vma + sgot->output_offset + got_offset @@ -4933,6 +5054,14 @@ elf32_arm_finish_dynamic_symbol (bfd * o BFD_ASSERT ((got_displacement & 0xf0000000) == 0); + if (eh->plt_thumb_refcount > 0) + { + bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0], + splt->contents + h->plt.offset - 4); + bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1], + splt->contents + h->plt.offset - 2); + } + bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20), splt->contents + h->plt.offset + 0); bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12), @@ -5518,6 +5647,18 @@ elf32_arm_write_section (bfd *output_bfd return FALSE; } +/* Display STT_ARM_TFUNC symbols as functions. */ + +static void +elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym; + + if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_ARM_TFUNC) + elfsym->symbol.flags |= BSF_FUNCTION; +} + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #ifdef __QNXTARGET__ @@ -5556,6 +5697,7 @@ elf32_arm_write_section (bfd *output_bfd #define elf_backend_section_from_shdr elf32_arm_section_from_shdr #define elf_backend_final_write_processing elf32_arm_final_write_processing #define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol +#define elf_backend_symbol_processing elf32_arm_symbol_processing #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 @@ -5688,4 +5830,3 @@ elf32_arm_symbian_modify_segment_map (bf #define elf_backend_want_got_plt 0 #include "elf32-target.h" - Index: gas/testsuite/gas/arm/mapping.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/mapping.d,v retrieving revision 1.2 diff -u -p -r1.2 mapping.d --- gas/testsuite/gas/arm/mapping.d 14 Oct 2004 16:04:09 -0000 1.2 +++ gas/testsuite/gas/arm/mapping.d 16 Nov 2004 21:15:21 -0000 @@ -10,9 +10,9 @@ SYMBOL TABLE: 0+00 l d .data 0+0 0+00 l d .bss 0+0 0+00 l F .text 0+0 \$a -0+08 l .text 0+0 \$t +0+08 l F .text 0+0 \$t 0+00 l O .data 0+0 \$d 0+00 l d foo 0+0 -0+00 l foo 0+0 \$t +0+00 l F foo 0+0 \$t 0+00 g .text 0+0 mapping -0+08 g .text 0+0 thumb_mapping +0+08 g F .text 0+0 thumb_mapping Index: gas/testsuite/gas/arm/unwind.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/unwind.d,v retrieving revision 1.1 diff -u -p -r1.1 unwind.d --- gas/testsuite/gas/arm/unwind.d 5 Oct 2004 13:51:40 -0000 1.1 +++ gas/testsuite/gas/arm/unwind.d 17 Nov 2004 16:32:36 -0000 @@ -21,13 +21,13 @@ OFFSET TYPE VALUE Contents of section .text: - 0000 (0000a0e3 0100a0e3 0200a0e3 0300a0e3|e3a00000 a0e30001 e3a00002 e3a00003) .* + 0000 (0000a0e3 0100a0e3 0200a0e3 0300a0e3|e3a00000 e3a00001 e3a00002 e3a00003) .* 0010 (0420|2004) .* Contents of section .ARM.extab: 0000 (449b0181 b0b08086|81019b44 8680b0b0) 00000000 00000000 .* - 0010 (8402b101 b0b0b005 2a000000 00c60181|01b10284 05b0b0b0 000000a2 8101c600) .* + 0010 (8402b101 b0b0b005 2a000000 00c60181|01b10284 05b0b0b0 0000002a 8101c600) .* 0020 (b0b0c1c1|c1c1b0b0) 00000000 .* Contents of section .ARM.exidx: 0000 00000000 (b0b0a880 04000000|80a8b0b0 00000004) 00000000 .* 0010 (08000000 0c000000 0c000000 1c000000|00000008 0000000c 0000000c 0000001c) .* - 0020 (10000000 08849780|00000010 80978480) .* + 0020 (10000000 08849780|00000010 80978408) .* Index: ld/emultempl/armelf.em =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/emultempl/armelf.em,v retrieving revision 1.40 diff -u -p -r1.40 armelf.em --- ld/emultempl/armelf.em 17 Sep 2004 12:18:18 -0000 1.40 +++ ld/emultempl/armelf.em 16 Nov 2004 20:52:24 -0000 @@ -78,8 +78,11 @@ arm_elf_set_bfd_for_interworking (lang_s ASSERT (output_section->owner == output_bfd); + /* Don't attach the interworking stubs to a dynamic object, to + an empty section, etc. */ if ((output_section->flags & SEC_HAS_CONTENTS) != 0 && (i->flags & SEC_NEVER_LOAD) == 0 + && ! (i->owner->flags & DYNAMIC) && ! i->owner->output_has_begun) { bfd_for_interwork = i->owner; Index: ld/testsuite/ld-arm/arm-app-abs32.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app-abs32.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-app-abs32.d --- ld/testsuite/ld-arm/arm-app-abs32.d 23 Jan 2004 16:51:39 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app-abs32.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app-abs32: file format elf32-littlearm +tmpdir/arm-app-abs32: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address .* Index: ld/testsuite/ld-arm/arm-app-abs32.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app-abs32.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-app-abs32.r --- ld/testsuite/ld-arm/arm-app-abs32.r 23 Jan 2004 16:51:39 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app-abs32.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app-abs32: file format elf32-littlearm +tmpdir/arm-app-abs32: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-app.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-app.d --- ld/testsuite/ld-arm/arm-app.d 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app: file format elf32-littlearm +tmpdir/arm-app: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-app.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-app.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-app.r --- ld/testsuite/ld-arm/arm-app.r 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-app.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-app: file format elf32-littlearm +tmpdir/arm-app: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-dyn.ld =================================================================== RCS file: ld/testsuite/ld-arm/arm-dyn.ld diff -N ld/testsuite/ld-arm/arm-dyn.ld --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/arm-dyn.ld 17 Nov 2004 16:03:09 -0000 @@ -0,0 +1,199 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_ARCH(arm) +ENTRY(_start) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x8000); . = 0x8000; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(256) + (. & (256 - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { KEEP (*(.preinit_array)) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } + PROVIDE (__fini_array_end = .); + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.got) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) } +} + + Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.5 diff -u -p -r1.5 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 30 Sep 2004 17:03:52 -0000 1.5 +++ ld/testsuite/ld-arm/arm-elf.exp 17 Nov 2004 15:55:06 -0000 @@ -47,6 +47,16 @@ set armelftests { {"Non-pcrel function reference" "tmpdir/arm-lib.so" "" {arm-app-abs32.s} {{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}} "arm-app-abs32"} + {"Mixed ARM/Thumb shared library" "-shared -T arm-lib.ld" "" + {mixed-lib.s} + {{objdump -fdw mixed-lib.d} {objdump -Rw mixed-lib.r} + {readelf -Ds mixed-lib.sym}} + "mixed-lib.so"} + {"Mixed ARM/Thumb dynamic application" "tmpdir/mixed-lib.so -T arm-dyn.ld" "" + {mixed-app.s} + {{objdump -fdw mixed-app.d} {objdump -Rw mixed-app.r} + {readelf -Ds mixed-app.sym}} + "mixed-app"} {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s} {{objdump -s arm-target1-abs.d}} "arm-target1-abs"} Index: ld/testsuite/ld-arm/arm-lib-plt32.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib-plt32.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-lib-plt32.d --- ld/testsuite/ld-arm/arm-lib-plt32.d 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-lib-plt32.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib-plt32.so: file format elf32-littlearm +tmpdir/arm-lib-plt32.so: file format elf32-(little|big)arm architecture: arm, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-lib-plt32.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib-plt32.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-lib-plt32.r --- ld/testsuite/ld-arm/arm-lib-plt32.r 6 Jan 2004 21:47:38 -0000 1.1 +++ ld/testsuite/ld-arm/arm-lib-plt32.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib-plt32.so: file format elf32-littlearm +tmpdir/arm-lib-plt32.so: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-lib.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib.d,v retrieving revision 1.2 diff -u -p -r1.2 arm-lib.d --- ld/testsuite/ld-arm/arm-lib.d 9 Jan 2004 16:53:10 -0000 1.2 +++ ld/testsuite/ld-arm/arm-lib.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib.so: file format elf32-littlearm +tmpdir/arm-lib.so: file format elf32-(little|big)arm architecture: arm, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-lib.ld =================================================================== RCS file: ld/testsuite/ld-arm/arm-lib.ld diff -N ld/testsuite/ld-arm/arm-lib.ld --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/arm-lib.ld 17 Nov 2004 16:03:09 -0000 @@ -0,0 +1,192 @@ +/* Script for --shared -z combreloc: shared library, combine & sort relocs */ +OUTPUT_ARCH(arm) +ENTRY(_start) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0 + SIZEOF_HEADERS; + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(256) + (. & (256 - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + .preinit_array : { KEEP (*(.preinit_array)) } + .init_array : { KEEP (*(.init_array)) } + .fini_array : { KEEP (*(.fini_array)) } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.got) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) } +} + + Index: ld/testsuite/ld-arm/arm-lib.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-lib.r,v retrieving revision 1.2 diff -u -p -r1.2 arm-lib.r --- ld/testsuite/ld-arm/arm-lib.r 9 Jan 2004 16:53:10 -0000 1.2 +++ ld/testsuite/ld-arm/arm-lib.r 17 Nov 2004 16:29:22 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-lib.so: file format elf32-littlearm +tmpdir/arm-lib.so: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE Index: ld/testsuite/ld-arm/arm-static-app.d =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-static-app.d,v retrieving revision 1.1 diff -u -p -r1.1 arm-static-app.d --- ld/testsuite/ld-arm/arm-static-app.d 13 Jan 2004 21:09:18 -0000 1.1 +++ ld/testsuite/ld-arm/arm-static-app.d 17 Nov 2004 16:29:26 -0000 @@ -1,5 +1,5 @@ -tmpdir/arm-static-app: file format elf32-littlearm +tmpdir/arm-static-app: file format elf32-(little|big)arm architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x.* Index: ld/testsuite/ld-arm/arm-static-app.r =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-static-app.r,v retrieving revision 1.1 diff -u -p -r1.1 arm-static-app.r --- ld/testsuite/ld-arm/arm-static-app.r 13 Jan 2004 21:09:18 -0000 1.1 +++ ld/testsuite/ld-arm/arm-static-app.r 17 Nov 2004 16:29:22 -0000 @@ -1,3 +1,3 @@ -tmpdir/arm-static-app: file format elf32-littlearm +tmpdir/arm-static-app: file format elf32-(little|big)arm Index: ld/testsuite/ld-arm/mixed-app.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.d diff -N ld/testsuite/ld-arm/mixed-app.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.d 17 Nov 2004 16:12:25 -0000 @@ -0,0 +1,57 @@ + +tmpdir/mixed-app: file format elf32-(little|big)arm +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <.plt\+0x10> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: (46c04778 undefined|477846c0 ldrmib r4, \[r8, -r0, asr #13\]!) + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <_start>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: eb000004 bl .* <app_func> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebffffe. bl .* <.text-0x..> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_func2>: + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <app_tfunc>: + .*: b500 push {lr} + .*: (ffc.f7ff|f7ffffc.) bl .* <.text-0x..> + .*: bd00 pop {pc} + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-app.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.r diff -N ld/testsuite/ld-arm/mixed-app.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.r 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,10 @@ + +tmpdir/mixed-app: file format elf32-(little|big)arm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_COPY data_obj +.* R_ARM_JUMP_SLOT lib_func2 +.* R_ARM_JUMP_SLOT lib_func1 + + Index: ld/testsuite/ld-arm/mixed-app.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.s diff -N ld/testsuite/ld-arm/mixed-app.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.s 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,39 @@ + .text + .p2align 4 + .globl _start +_start: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func + .type app_func,%function +app_func: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl lib_func1 + ldmia sp, {r11, sp, lr} + bx lr + + .p2align 4 + .globl app_func2 + .type app_func2,%function +app_func2: + bx lr + + .p2align 4 + .globl app_tfunc + .type app_tfunc,%function + .thumb_func + .code 16 +app_tfunc: + push {lr} + bl lib_func2 + pop {pc} + bx lr + + .data + .long data_obj Index: ld/testsuite/ld-arm/mixed-app.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-app.sym diff -N ld/testsuite/ld-arm/mixed-app.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-app.sym 17 Nov 2004 16:10:56 -0000 @@ -0,0 +1,19 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _edata + .. ..: 0*[^0]*.* 20 FUNC GLOBAL DEFAULT UND lib_func1 + .. ..: 0*[^0]*.* 2 FUNC GLOBAL DEFAULT UND lib_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ + .. ..: ........ 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 13 _stack + .. ..: ........ 4 OBJECT GLOBAL DEFAULT 12 data_obj + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _end + .. ..: .......0 0 FUNC GLOBAL DEFAULT 8 app_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 11 __data_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start Index: ld/testsuite/ld-arm/mixed-lib.d =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.d diff -N ld/testsuite/ld-arm/mixed-lib.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.d 17 Nov 2004 16:10:57 -0000 @@ -0,0 +1,38 @@ + +tmpdir/mixed-lib.so: file format elf32-(little|big)arm +architecture: arm, flags 0x00000150: +HAS_SYMS, DYNAMIC, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <lib_func1-0x1.> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <lib_func1>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebfffff. bl .* <lib_func1-0x..> + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* <lib_func2>: + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) Index: ld/testsuite/ld-arm/mixed-lib.r =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.r diff -N ld/testsuite/ld-arm/mixed-lib.r --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.r 17 Nov 2004 16:10:53 -0000 @@ -0,0 +1,8 @@ + +tmpdir/mixed-lib.so: file format elf32-(little|big)arm + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +.* R_ARM_JUMP_SLOT app_func2 + + Index: ld/testsuite/ld-arm/mixed-lib.s =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.s diff -N ld/testsuite/ld-arm/mixed-lib.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.s 17 Nov 2004 16:10:54 -0000 @@ -0,0 +1,28 @@ + .text + + .p2align 4 + .globl lib_func1 + .type lib_func1, %function +lib_func1: + mov ip, sp + stmdb sp!, {r11, ip, lr, pc} + bl app_func2 + ldmia sp, {r11, sp, lr} + bx lr + .size lib_func1, . - lib_func1 + + .p2align 4 + .globl lib_func2 + .type lib_func2, %function + .thumb_func + .code 16 +lib_func2: + bx lr + .size lib_func2, . - lib_func2 + + .data + .globl data_obj + .type data_obj, %object +data_obj: + .long 0 + .size data_obj, . - data_obj Index: ld/testsuite/ld-arm/mixed-lib.sym =================================================================== RCS file: ld/testsuite/ld-arm/mixed-lib.sym diff -N ld/testsuite/ld-arm/mixed-lib.sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-arm/mixed-lib.sym 17 Nov 2004 16:10:55 -0000 @@ -0,0 +1,19 @@ + +Symbol table for image: + Num Buc: Value Size Type Bind Vis Ndx Name + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _edata + .. ..: .......0 20 FUNC GLOBAL DEFAULT 6 lib_func1 + .. ..: .......0 2 THUMB_FUNC GLOBAL DEFAULT 6 lib_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ + .. ..: ........ 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 11 _stack + .. ..: ........ 4 OBJECT GLOBAL DEFAULT 9 data_obj + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __bss_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS _end + .. ..: 00000000 0 NOTYPE GLOBAL DEFAULT UND app_func2 + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT 9 __data_start + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __end__ + .. ..: ........ 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start Index: opcodes/arm-dis.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/opcodes/arm-dis.c,v retrieving revision 1.38 diff -u -p -r1.38 arm-dis.c --- opcodes/arm-dis.c 30 Sep 2004 16:21:43 -0000 1.38 +++ opcodes/arm-dis.c 17 Nov 2004 17:23:57 -0000 @@ -46,6 +46,8 @@ #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) #endif +#define WORD_ADDRESS(pc) ((pc) & ~0x3) + static char * arm_conditional[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "nv"}; @@ -1253,7 +1255,7 @@ print_insn (pc, info, little) unsigned char b[4]; long given; int status; - int is_thumb; + int is_thumb, second_half_valid = 1; if (info->disassembler_options) { @@ -1299,6 +1301,7 @@ print_insn (pc, info, little) if (status != 0 && is_thumb) { info->bytes_per_chunk = 2; + second_half_valid = 0; status = info->read_memory_func (pc, (bfd_byte *) b, 2, info); b[3] = b[2] = 0; @@ -1315,10 +1318,10 @@ print_insn (pc, info, little) else { status = info->read_memory_func - (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info); + (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info); if (status != 0) { - info->memory_error_func (status, pc, info); + info->memory_error_func (status, WORD_ADDRESS (pc), info); return -1; } @@ -1329,14 +1332,11 @@ print_insn (pc, info, little) given = (b[2] << 8) | b[3]; status = info->read_memory_func - ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info); + (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info); if (status != 0) - { - info->memory_error_func (status, pc + 4, info); - return -1; - } - - given |= (b[0] << 24) | (b[1] << 16); + second_half_valid = 0; + else + given |= (b[0] << 24) | (b[1] << 16); } else given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16); @@ -1358,6 +1358,12 @@ print_insn (pc, info, little) else status = print_insn_arm (pc, info, given); + if (is_thumb && status == 4 && second_half_valid == 0) + { + info->memory_error_func (status, WORD_ADDRESS (pc + 4), info); + return -1; + } + return status; } ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: RFA: Support for Thumb in dynamic objects 2004-11-17 17:36 ` Daniel Jacobowitz @ 2004-11-17 17:39 ` Richard Earnshaw 0 siblings, 0 replies; 13+ messages in thread From: Richard Earnshaw @ 2004-11-17 17:39 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils, Paul Brook On Wed, 2004-11-17 at 17:33, Daniel Jacobowitz wrote: > It's hard to come up with a good name for manipulation that's basically > unnecessary. It's trying to do two 32-bit reads if possible instead of > a bunch of smaller reads; we could leave this to the client instead. > > This patch calls it WORD_ADDRESS, since that descrbes the use. It > could be throttled down to read 2-byte pieces for Thumb, and to do the > read later (i.e. when we see a bl/blx); I'll leave that for another > day. OK? Yes, thanks. R. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2004-11-17 17:39 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-11-16 23:39 RFA: Support for Thumb in dynamic objects Daniel Jacobowitz 2004-11-17 0:22 ` Paul Brook 2004-11-17 0:37 ` Daniel Jacobowitz 2004-11-17 1:37 ` Ian Lance Taylor 2004-11-17 3:02 ` Daniel Jacobowitz 2004-11-17 3:42 ` Ian Lance Taylor 2004-11-17 13:48 ` Richard Earnshaw 2004-11-17 16:49 ` Daniel Jacobowitz 2004-11-17 17:00 ` Richard Earnshaw 2004-11-17 17:05 ` Daniel Jacobowitz 2004-11-17 17:12 ` Richard Earnshaw 2004-11-17 17:36 ` Daniel Jacobowitz 2004-11-17 17:39 ` Richard Earnshaw
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).