OSDN Git Service

Another try at correcting relocations against discarded
authorAlan Modra <amodra@bigpond.net.au>
Thu, 12 Oct 2000 03:44:51 +0000 (03:44 +0000)
committerAlan Modra <amodra@bigpond.net.au>
Thu, 12 Oct 2000 03:44:51 +0000 (03:44 +0000)
link-once section symbols.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elflink.h
bfd/section.c
ld/ChangeLog
ld/ldlang.c

index 95d885c..a3ca28a 100644 (file)
@@ -1,5 +1,17 @@
 2000-10-12  Alan Modra  <alan@linuxcare.com.au>
 
+       * section.c (struct sec): Add kept_section.
+       (struct bfd_comdat_info): Remove sec, we can use above.
+       (STD_SECTION): Add initializer.
+       (bfd_make_section_anyway): Init here too.
+
+       * bfd-in2.h: Regenerate.
+
+       * elflink.h (elf_link_add_object_symbols): Remove unnecessary
+       zeroing of `flags'.  
+       (elf_link_input_bfd): Set all asection->symbol->value's here, and
+       fudge values for discarded link-once section symbols.
+
        * elf64-hppa.c: Include alloca-conf.h
 
 2000-10-11  Alan Modra  <alan@linuxcare.com.au>
index 51c7043..64238ac 100644 (file)
@@ -913,10 +913,6 @@ struct bfd_comdat_info
      specific code; it is not an index into the list returned by
      bfd_canonicalize_symtab.  */
   long symbol;
-
-  /* If this section is being discarded, the linker uses this field
-     to point to the input section which is being kept.  */
-  struct sec *sec;
 };
 
 typedef struct sec
@@ -1219,6 +1215,10 @@ typedef struct sec
 
   struct bfd_comdat_info *comdat;
 
+  /* Points to the kept section if this section is a link-once section,
+     and is discarded.  */
+  struct sec *kept_section;
+
   /* When a section is being output, this value changes as more
      linenumbers are written out.  */
 
index 9e543a7..9a0f49a 100644 (file)
@@ -1371,8 +1371,6 @@ elf_link_add_object_symbols (abfd, info)
          if (sym.st_shndx != SHN_UNDEF
              && sym.st_shndx != SHN_COMMON)
            flags = BSF_GLOBAL;
-         else
-           flags = 0;
        }
       else if (bind == STB_WEAK)
        flags = BSF_WEAK;
@@ -5536,16 +5534,43 @@ elf_link_input_bfd (finfo, input_bfd)
       if (esym == external_syms)
        continue;
 
+      if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+       {
+         asection *ksec;
+
+         /* Save away all section symbol values.  */
+         if (isec != NULL)
+           isec->symbol->value = isym->st_value;
+
+         /* If this is a discarded link-once section symbol, update
+            it's value to that of the kept section symbol.  The
+            linker will keep the first of any matching link-once
+            sections, so we should have already seen it's section
+            symbol.  I trust no-one will have the bright idea of
+            re-ordering the bfd list...  */
+         if (isec != NULL
+             && (bfd_get_section_flags (input_bfd, isec) & SEC_LINK_ONCE) != 0
+             && (ksec = isec->kept_section) != NULL)
+           {
+             isym->st_value = ksec->symbol->value;
+
+             /* That put the value right, but the section info is all
+                wrong.  I hope this works.  */
+             isec->output_offset = ksec->output_offset;
+             isec->output_section = ksec->output_section;
+           }
+
+         /* We never output section symbols.  Instead, we use the
+            section symbol of the corresponding section in the output
+            file.  */
+         continue;
+       }
+
       /* If we are stripping all symbols, we don't want to output this
         one.  */
       if (finfo->info->strip == strip_all)
        continue;
 
-      /* We never output section symbols.  Instead, we use the section
-        symbol of the corresponding section in the output file.  */
-      if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
-       continue;
-
       /* If we are discarding all local symbols, we don't want to
         output this one.  If we are generating a relocateable output
         file, then some of the local symbols may be required by
index fc64b20..ef7a7e6 100644 (file)
@@ -165,10 +165,6 @@ CODE_FRAGMENT
 .     specific code; it is not an index into the list returned by
 .     bfd_canonicalize_symtab.  *}
 .  long symbol;
-.
-.  {* If this section is being discarded, the linker uses this field
-.     to point to the input section which is being kept.  *}
-.  struct sec *sec;
 .};
 .
 .typedef struct sec
@@ -471,6 +467,10 @@ CODE_FRAGMENT
 .
 .  struct bfd_comdat_info *comdat;
 .
+.  {* Points to the kept section if this section is a link-once section,
+.     and is discarded.  *}
+.  struct sec *kept_section;
+.
 .  {* When a section is being output, this value changes as more
 .     linenumbers are written out.  *}
 .
@@ -578,11 +578,11 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */        \
        0,            NULL,     NULL,     NULL,   0,                    \
                                                                        \
-    /* comdat, moving_line_filepos, target_index, used_by_bfd,       */        \
-       NULL,   0,                   0,            NULL,                        \
+    /* comdat, kept_section, moving_line_filepos, target_index,      */        \
+       NULL,   NULL,         0,                   0,                   \
                                                                        \
-    /* constructor_chain, owner,                                     */        \
-       NULL,              NULL,                                                \
+    /* used_by_bfd, constructor_chain, owner,                        */        \
+       NULL,        NULL,              NULL,                           \
                                                                        \
     /* symbol,                                                       */        \
        (struct symbol_cache_entry *) &global_syms[IDX],                        \
@@ -789,6 +789,7 @@ bfd_make_section_anyway (abfd, name)
   newsect->line_filepos = 0;
   newsect->owner = abfd;
   newsect->comdat = NULL;
+  newsect->kept_section = NULL;
 
   /* Create a symbol whos only job is to point to this section. This is
      useful for things like relocs which are relative to the base of a
index 0300d65..14fe197 100644 (file)
@@ -1,3 +1,8 @@
+2000-10-12  Alan Modra  <alan@linuxcare.com.au>
+
+       * ldlang.c (section_already_linked): Set kept_section instead of
+       sec->comdat->sec.
+
 2000-10-10  Kazu Hirata  <kazu@hxi.com>
 
        * deffile.h: Fix formatting.
index c57dd6d..d92ebbf 100644 (file)
@@ -995,8 +995,7 @@ section_already_linked (abfd, sec, data)
             discarded, we must retain a pointer to the section which
             we are really going to use.  */
          sec->output_section = bfd_abs_section_ptr;
-         if (sec->comdat != NULL)
-           sec->comdat->sec = l->sec;
+         sec->kept_section = l->sec;
 
          return;
        }