aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-09-06 20:55:23 +0000
committerMark Mitchell <mark@codesourcery.com>2004-09-06 20:55:23 +0000
commit229fcec57051103b79422353f53b6053fc5fc4b4 (patch)
treee9620d5259158d88238cd849061f454202b01dca /bfd
parentd597aff735ca792afe4d7508fe83e7891e50e5e9 (diff)
downloadgdb-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/ChangeLog15
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c43
-rw-r--r--bfd/elf32-arm.h121
-rw-r--r--bfd/elfarm-nabi.c18
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);
diff --git a/bfd/elf.c b/bfd/elf.c
index f9e2235..b317d7e 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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"