diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-09-06 20:55:23 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 2004-09-06 20:55:23 +0000 |
commit | 229fcec57051103b79422353f53b6053fc5fc4b4 (patch) | |
tree | e9620d5259158d88238cd849061f454202b01dca /bfd | |
parent | d597aff735ca792afe4d7508fe83e7891e50e5e9 (diff) | |
download | gdb-229fcec57051103b79422353f53b6053fc5fc4b4.zip gdb-229fcec57051103b79422353f53b6053fc5fc4b4.tar.gz gdb-229fcec57051103b79422353f53b6053fc5fc4b4.tar.bz2 |
* elf-bfd.h (_bfd_elf_make_dynamic_segment): Declare it.
* elf.c (_bfd_elf_make_dynamic_segment): New function, split out
from ...
(map_sections_to_segments): ... here. Use it. Assign a file
position to the .dynamic section if it is not loadable, but part
of the PT_DYNAMIC segment.
* elf32-arm.h (elf32_arm_finish_dynamic_sections): Use file
offsets, not VMAs, for the BPABI. Do not fill in the header in
the .got.plt section for the BPABI.
* elfarm-nabi.c (elf32_arm_symbian_modify_segment_map): Add a
PT_DYNAMIC segment.
(elf_backend_want_got_plt): Define to zero for Symbian OS.
* emulparams/armsymbian.sh: Use armbpabi script.
* scripttempl/armbpabi.sc: New script.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 4 | ||||
-rw-r--r-- | bfd/elf.c | 43 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 121 | ||||
-rw-r--r-- | bfd/elfarm-nabi.c | 18 |
5 files changed, 167 insertions, 34 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 60c0069..e6a3777 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2004-09-06 Mark Mitchell <mark@codesourcery.com> + + * elf-bfd.h (_bfd_elf_make_dynamic_segment): Declare it. + * elf.c (_bfd_elf_make_dynamic_segment): New function, split out + from ... + (map_sections_to_segments): ... here. Use it. Assign a file + position to the .dynamic section if it is not loadable, but part + of the PT_DYNAMIC segment. + * elf32-arm.h (elf32_arm_finish_dynamic_sections): Use file + offsets, not VMAs, for the BPABI. Do not fill in the header in + the .got.plt section for the BPABI. + * elfarm-nabi.c (elf32_arm_symbian_modify_segment_map): Add a + PT_DYNAMIC segment. + (elf_backend_want_got_plt): Define to zero for Symbian OS. + 2004-09-06 Nick Clifton <nickc@redhat.com> * elflink.c (elf_link_add_object_symbols): Set the error code to diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index dfc18de..5565e49 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1734,6 +1734,10 @@ extern bfd_boolean bfd_elf_gc_common_final_link extern bfd_boolean bfd_elf_reloc_symbol_deleted_p (bfd_vma, void *); +extern struct elf_segment_map * +_bfd_elf_make_dynamic_segment + (bfd *, asection *); + /* Exported interface for writing elf corefile notes. */ extern char *elfcore_write_note (bfd *, char *, int *, const char *, int, const void *, int); @@ -3329,6 +3329,25 @@ make_mapping (bfd *abfd, return m; } +/* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL + on failure. */ + +struct elf_segment_map * +_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec) +{ + struct elf_segment_map *m; + + m = bfd_zalloc (abfd, sizeof (struct elf_segment_map)); + if (m == NULL) + return NULL; + m->next = NULL; + m->p_type = PT_DYNAMIC; + m->count = 1; + m->sections[0] = dynsec; + + return m; +} + /* Set up a mapping from BFD sections to program segments. */ static bfd_boolean @@ -3566,15 +3585,9 @@ map_sections_to_segments (bfd *abfd) /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */ if (dynsec != NULL) { - amt = sizeof (struct elf_segment_map); - m = bfd_zalloc (abfd, amt); + m = _bfd_elf_make_dynamic_segment (abfd, dynsec); if (m == NULL) goto error_return; - m->next = NULL; - m->p_type = PT_DYNAMIC; - m->count = 1; - m->sections[0] = dynsec; - *pm = m; pm = &m->next; } @@ -4215,6 +4228,22 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a if (p->p_type != PT_LOAD && m->count > 0) { BFD_ASSERT (! m->includes_filehdr && ! m->includes_phdrs); + /* If the section has not yet been assigned a file position, + do so now. The ARM BPABI requires that .dynamic section + not be marked SEC_ALLOC because it is not part of any + PT_LOAD segment, so it will not be processed above. */ + if (p->p_type == PT_DYNAMIC && m->sections[0]->filepos == 0) + { + unsigned int i; + Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); + + i = 1; + while (i_shdrpp[i]->bfd_section != m->sections[0]) + ++i; + off = (_bfd_elf_assign_file_position_for_section + (i_shdrpp[i], off, TRUE)); + p->p_filesz = m->sections[0]->size; + } p->p_offset = m->sections[0]->filepos; } if (m->count == 0) diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index e60ea38..656a822 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -3861,14 +3861,16 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info dynobj = elf_hash_table (info)->dynobj; sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); + BFD_ASSERT (elf32_arm_hash_table (info)->symbian_p || sgot != NULL); sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); if (elf_hash_table (info)->dynamic_sections_created) { asection *splt; Elf32_External_Dyn *dyncon, *dynconend; + struct elf32_arm_link_hash_table *htab; + htab = elf32_arm_hash_table (info); splt = bfd_get_section_by_name (dynobj, ".plt"); BFD_ASSERT (splt != NULL && sdyn != NULL); @@ -3885,9 +3887,21 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info switch (dyn.d_tag) { + unsigned int type; + default: break; + case DT_HASH: + name = ".hash"; + goto get_vma_if_bpabi; + case DT_STRTAB: + name = ".dynstr"; + goto get_vma_if_bpabi; + case DT_SYMTAB: + name = ".dynsym"; + goto get_vma_if_bpabi; + case DT_PLTGOT: name = ".got"; goto get_vma; @@ -3896,31 +3910,81 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info get_vma: s = bfd_get_section_by_name (output_bfd, name); BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; + if (!htab->symbian_p) + dyn.d_un.d_ptr = s->vma; + else + /* In the BPABI, tags in the PT_DYNAMIC section point + at the file offset, not the memory address, for the + convenience of the post linker. */ + dyn.d_un.d_ptr = s->filepos; bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; + get_vma_if_bpabi: + if (htab->symbian_p) + goto get_vma; + break; + case DT_PLTRELSZ: s = bfd_get_section_by_name (output_bfd, ".rel.plt"); BFD_ASSERT (s != NULL); dyn.d_un.d_val = s->size; bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; - + case DT_RELSZ: - /* My reading of the SVR4 ABI indicates that the - procedure linkage table relocs (DT_JMPREL) should be - included in the overall relocs (DT_REL). This is - what Solaris does. However, UnixWare can not handle - that case. Therefore, we override the DT_RELSZ entry - here to make it not include the JMPREL relocs. Since - the linker script arranges for .rel.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_REL entry. */ - s = bfd_get_section_by_name (output_bfd, ".rel.plt"); - if (s != NULL) - dyn.d_un.d_val -= s->size; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + if (!htab->symbian_p) + { + /* My reading of the SVR4 ABI indicates that the + procedure linkage table relocs (DT_JMPREL) should be + included in the overall relocs (DT_REL). This is + what Solaris does. However, UnixWare can not handle + that case. Therefore, we override the DT_RELSZ entry + here to make it not include the JMPREL relocs. Since + the linker script arranges for .rel.plt to follow all + other relocation sections, we don't have to worry + about changing the DT_REL entry. */ + s = bfd_get_section_by_name (output_bfd, ".rel.plt"); + if (s != NULL) + dyn.d_un.d_val -= s->size; + bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + break; + } + /* Fall through */ + + case DT_REL: + case DT_RELA: + case DT_RELASZ: + /* In the BPABI, the DT_REL tag must point at the file + offset, not the VMA, of the first relocation + section. So, we use code similar to that in + elflink.c, but do not check for SHF_ALLOC on the + relcoation section, since relocations sections are + never allocated under the BPABI. The comments above + about Unixware notwithstanding, we include all of the + relocations here. */ + if (htab->symbian_p) + { + unsigned int i; + type = ((dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) + ? SHT_REL : SHT_RELA); + dyn.d_un.d_val = 0; + for (i = 1; i < elf_numsections (output_bfd); i++) + { + Elf_Internal_Shdr *hdr + = elf_elfsections (output_bfd)[i]; + if (hdr->sh_type == type) + { + if (dyn.d_tag == DT_RELSZ + || dyn.d_tag == DT_RELASZ) + dyn.d_un.d_val += hdr->sh_size; + else if (dyn.d_un.d_val == 0 + || hdr->sh_offset < dyn.d_un.d_val) + dyn.d_un.d_val = hdr->sh_offset; + } + } + bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + } break; /* Set the bottom bit of DT_INIT/FINI if the @@ -3981,19 +4045,22 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info } /* Fill in the first three entries in the global offset table. */ - if (sgot->size > 0) + if (sgot) { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } + if (sgot->size > 0) + { + if (sdyn == NULL) + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); + else + bfd_put_32 (output_bfd, + sdyn->output_section->vma + sdyn->output_offset, + sgot->contents); + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); + } - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; + elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; + } return TRUE; } diff --git a/bfd/elfarm-nabi.c b/bfd/elfarm-nabi.c index 7c6e7c2..6644578 100644 --- a/bfd/elfarm-nabi.c +++ b/bfd/elfarm-nabi.c @@ -936,6 +936,7 @@ elf32_arm_symbian_modify_segment_map (abfd, info) struct bfd_link_info *info ATTRIBUTE_UNUSED; { struct elf_segment_map *m; + asection *dynsec; /* The first PT_LOAD segment will have the program headers and file headers in it by default -- but BPABI object files should not @@ -946,6 +947,19 @@ elf32_arm_symbian_modify_segment_map (abfd, info) m->includes_filehdr = 0; m->includes_phdrs = 0; } + + /* BPABI shared libraries and executables should have a PT_DYNAMIC + segment. However, because the .dynamic section is not marked + with SEC_LOAD, the generic ELF code will not create such a + segment. */ + dynsec = bfd_get_section_by_name (abfd, ".dynamic"); + if (dynsec) + { + m = _bfd_elf_make_dynamic_segment (abfd, dynsec); + m->next = elf_tdata (abfd)->segment_map; + elf_tdata (abfd)->segment_map = m; + } + return TRUE; } @@ -970,5 +984,9 @@ elf32_arm_symbian_modify_segment_map (abfd, info) #undef elf_backend_got_header_size #define elf_backend_got_header_size 0 +/* Similarly, there is no .got.plt section. */ +#undef elf_backend_want_got_plt +#define elf_backend_want_got_plt 0 + #include "elf32-target.h" |