From d1c6de6f1598529efe3f24af517aa94ae4de4d5d Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 22 Jun 2004 05:35:37 +0000 Subject: [PATCH] * elf32-ppc.c (ppc_elf_relax_section): Implement reference code for handling SEC_MERGE symbols in relax_section. * coff-i386.c: Update copyright date. --- bfd/ChangeLog | 5 +++++ bfd/coff-i386.c | 2 +- bfd/elf32-ppc.c | 44 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2bcd7bd..1304661 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2004-06-22 Alan Modra + + * elf32-ppc.c (ppc_elf_relax_section): Implement reference code + for handling SEC_MERGE symbols in relax_section. + 2004-06-21 Alexandre Oliva 2003-05-15 Richard Sandiford diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index e2bf860..65700b6 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -1,6 +1,6 @@ /* BFD back-end for Intel 386 COFF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003 + 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Written by Cygnus Support. 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; -- 2.7.4