This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: BZ/175: Fix dynamic string offset
On Sun, Jun 06, 2004 at 10:15:29AM +0930, Alan Modra wrote:
> On Fri, Jun 04, 2004 at 01:04:56PM -0700, H. J. Lu wrote:
> > Here is a patch. It uses _bfd_elf_rela_local_sym to compute the offset
> > of local symbol.
>
> No, this isn't correct. I think the following is right, but I haven't
> tested it yet since I'm still away from home. Hopefully the comments
> I've added will make things clear.
>
This is the version for ia64.
H.J.
----
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.
--- bfd/elfxx-ia64.c.merge 2004-06-21 18:24:27.976350621 -0700
+++ bfd/elfxx-ia64.c 2004-06-21 18:47:22.599377664 -0700
@@ -799,6 +799,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
bfd_size_type amt;
bfd_boolean is_branch;
struct elfNN_ia64_dyn_sym_info *dyn_i;
+ char symtype;
switch (r_type)
{
@@ -874,6 +875,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
toff = isym->st_value;
dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
+ symtype = ELF_ST_TYPE (isym->st_info);
}
else
{
@@ -918,12 +920,38 @@ elfNN_ia64_relax_section (abfd, sec, lin
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;