aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2004-06-22 05:35:37 +0000
committerAlan Modra <amodra@gmail.com>2004-06-22 05:35:37 +0000
commitd1c6de6f1598529efe3f24af517aa94ae4de4d5d (patch)
tree36af76317ca17fa0c9cb214e7c6a456033aa7e37 /bfd/elf32-ppc.c
parentfb514b26fa9986c7690da8da9c030ef030145b35 (diff)
downloadgdb-d1c6de6f1598529efe3f24af517aa94ae4de4d5d.zip
gdb-d1c6de6f1598529efe3f24af517aa94ae4de4d5d.tar.gz
gdb-d1c6de6f1598529efe3f24af517aa94ae4de4d5d.tar.bz2
* elf32-ppc.c (ppc_elf_relax_section): Implement reference code
for handling SEC_MERGE symbols in relax_section. * coff-i386.c: Update copyright date.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r--bfd/elf32-ppc.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index be05270..c4b46f6 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -1723,6 +1723,7 @@ ppc_elf_relax_section (bfd *abfd,
bfd_vma max_branch_offset, val;
bfd_byte *hit_addr;
unsigned long t0;
+ unsigned char sym_type;
switch (r_type)
{
@@ -1770,6 +1771,7 @@ ppc_elf_relax_section (bfd *abfd,
tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
toff = isym->st_value;
+ sym_type = ELF_ST_TYPE (isym->st_info);
}
else
{
@@ -1799,6 +1801,8 @@ ppc_elf_relax_section (bfd *abfd,
}
else
continue;
+
+ sym_type = h->type;
}
/* If the branch and target are in the same section, you have
@@ -1807,11 +1811,41 @@ ppc_elf_relax_section (bfd *abfd,
if (tsec == isec)
continue;
- toff += irel->r_addend;
- if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
- toff = _bfd_merged_section_offset (abfd, &tsec,
- elf_section_data (tsec)->sec_info,
- toff);
+ /* There probably isn't any reason to handle symbols in
+ SEC_MERGE sections; SEC_MERGE doesn't seem a likely
+ attribute for a code section, and we are only looking at
+ branches. However, implement it correctly here as a
+ reference for other target relax_section functions. */
+ if (0 && tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
+ {
+ /* At this stage in linking, no SEC_MERGE symbol has been
+ adjusted, so all references to such symbols need to be
+ passed through _bfd_merged_section_offset. (Later, in
+ relocate_section, all SEC_MERGE symbols *except* for
+ section symbols have been adjusted.)
+
+ gas may reduce relocations against symbols in SEC_MERGE
+ sections to a relocation against the section symbol when
+ the original addend was zero. When the reloc is against
+ a section symbol we should include the addend in the
+ offset passed to _bfd_merged_section_offset, since the
+ location of interest is the original symbol. On the
+ other hand, an access to "sym+addend" where "sym" is not
+ a section symbol should not include the addend; Such an
+ access is presumed to be an offset from "sym"; The
+ location of interest is just "sym". */
+ if (sym_type == STT_SECTION)
+ toff += irel->r_addend;
+
+ toff = _bfd_merged_section_offset (abfd, &tsec,
+ elf_section_data (tsec)->sec_info,
+ toff);
+
+ if (sym_type != STT_SECTION)
+ toff += irel->r_addend;
+ }
+ else
+ toff += irel->r_addend;
symaddr = tsec->output_section->vma + tsec->output_offset + toff;