2004-06-21 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 22 Jun 2004 06:03:07 +0000 (06:03 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 22 Jun 2004 06:03:07 +0000 (06:03 +0000)
* elfxx-ia64.c (elfNN_ia64_relax_section): Add addend when
calling _bfd_merged_section_offset only for section symbols.

bfd/ChangeLog
bfd/elfxx-ia64.c

index 130466142cea66437a35053a764ed312da5093ea..5b145c363beae4a10e48ea24129fadaa26f95fdb 100644 (file)
@@ -1,3 +1,8 @@
+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.
+
 2004-06-22  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-ppc.c (ppc_elf_relax_section): Implement reference code
index 26b2e455488740767bf8e3f9a3976f73fa6b2732..e5a6214c452289ad8e557a6ae5bf92848cbb2512 100644 (file)
@@ -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;