diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2004-06-22 06:03:07 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2004-06-22 06:03:07 +0000 |
commit | bf8b15af149f2508101cf02c171fa817325230bf (patch) | |
tree | 204ce9ecb85f621cc11914bd6ae81535ce8156a2 /bfd/elfxx-ia64.c | |
parent | d1c6de6f1598529efe3f24af517aa94ae4de4d5d (diff) | |
download | ppe42-binutils-bf8b15af149f2508101cf02c171fa817325230bf.tar.gz ppe42-binutils-bf8b15af149f2508101cf02c171fa817325230bf.zip |
2004-06-21 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-ia64.c (elfNN_ia64_relax_section): Add addend when
calling _bfd_merged_section_offset only for section symbols.
Diffstat (limited to 'bfd/elfxx-ia64.c')
-rw-r--r-- | bfd/elfxx-ia64.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 26b2e45548..e5a6214c45 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -789,6 +789,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) bfd_size_type amt; bfd_boolean is_branch; struct elfNN_ia64_dyn_sym_info *dyn_i; + char symtype; switch (r_type) { @@ -864,6 +865,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) toff = isym->st_value; dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE); + symtype = ELF_ST_TYPE (isym->st_info); } else { @@ -908,12 +910,38 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) tsec = h->root.u.def.section; toff = h->root.u.def.value; } + + symtype = h->type; } if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE) - toff = _bfd_merged_section_offset (abfd, &tsec, - elf_section_data (tsec)->sec_info, - toff + irel->r_addend); + { + /* 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 (symtype == STT_SECTION) + toff += irel->r_addend; + + toff = _bfd_merged_section_offset (abfd, &tsec, + elf_section_data (tsec)->sec_info, + toff); + + if (symtype != STT_SECTION) + toff += irel->r_addend; + } else toff += irel->r_addend; |