This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: --gc-sections not working?


2012/1/13 Ulrich Drepper <drepper@gmail.com>:
> The linker is not complete.  Problems are expected.

ok, I think I fixed it for my simple use case. See the attached patch.
It skips the sections in archives that define only new symbols (ie. do
not satisfy any old unresolved symbols).
Still, for stand-alone objects files it links-in all their sections. I
think this will have to do for now...

Take it or leave it. Problems are expected ;)

Jara

-- 
Space--the final frontier!
diff --git a/src/ldgeneric.c b/src/ldgeneric.c
index 1f0af19..a58ead8 100644
--- a/src/ldgeneric.c
+++ b/src/ldgeneric.c
@@ -588,6 +588,7 @@ Warning: size of `%s' changed from %" PRIu64 " in %s to %" PRIu64 " in %s"),
 }
 
 
+/* Note: this bitch has side effects!! */
 static int
 check_definition (const XElf_Sym *sym, size_t shndx, size_t symidx,
 		  struct usedfiles *fileinfo, struct symbol *oldp)
@@ -916,6 +917,25 @@ mark_section_used (struct scninfo *scninfo, Elf32_Word shndx,
   /* We need this section.  */
   scninfo->used = true;
 
+  if (1) {
+    char *sectname = NULL;
+    if (!scninfo)
+        sectname = "<scninfo==NULL>";
+    else if (!scninfo->fileinfo)
+        sectname = "<fileinfo==NULL>";
+    else if (!&SCNINFO_SHDR(scninfo->shdr))
+        sectname = "<shdr==NULL>";
+    else 
+        sectname = elf_strptr (scninfo->fileinfo->elf, 
+                                 scninfo->fileinfo->shstrndx, 
+                                 SCNINFO_SHDR(scninfo->shdr).sh_name);
+    printf("  mark_section_used: file:%s, section:'%s'\n", 
+           (scninfo->fileinfo ? scninfo->fileinfo->fname : "<fileinfo==NULL>"),
+           (sectname ? : "<corrupt>"));
+//     if (sectname && strcmp(".text.my_unused_a", sectname) == 0)
+//         abort();
+  }
+  
   /* Make sure the section header has been read from the file.  */
   XElf_Shdr *shdr = &SCNINFO_SHDR (scninfo->shdr);
 #if NATIVE_ELF
@@ -980,7 +1000,7 @@ add_section (struct usedfiles *fileinfo, struct scninfo *scninfo)
      dependency analysis should work.  Should the entry point be
      the root?  What if it is a numeric value?  */
   if (!scninfo->used
-      && (ld_state.strip == strip_none
+      && (ld_state.strip == strip_none        // JSY: IMHO 'strip' has nothing to do with this (??)
 	  || (shdr->sh_flags & SHF_ALLOC) != 0
 	  || shdr->sh_type == SHT_NOTE
 	  || (shdr->sh_type == SHT_PROGBITS
@@ -1092,6 +1112,13 @@ add_section (struct usedfiles *fileinfo, struct scninfo *scninfo)
 }
 
 
+/* Called from file_process2() to go through the sections and add them in.
+ * We have already determined that there are symbols in the object file
+ * that satisfy currently unresolved symbols.
+ * Note: secttype is SHT_SYMTAB in the ET_REL case, or SHT_DYNSYM when ET_EXEC.
+ * First we go over all the sections in the file and look at them;
+ * we call add_section() on the non-special sections (.text, .bss, .rel, ...).
+ */
 static int
 add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
 {
@@ -1537,9 +1564,11 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
 	  struct symbol *oldp = ld_symbol_tab_find (&ld_state.symbol_tab,
 						    hval, &search);
 	  struct symbol *newp;
+          bool is_new_symb = false;
 	  if (likely (oldp == NULL))
 	    {
 	      /* No symbol of this name known.  Add it.  */
+              is_new_symb = true;
 	      newp = (struct symbol *) obstack_alloc (&ld_state.smem,
 						      sizeof (*newp));
 	      newp->name = search.name;
@@ -1600,7 +1629,7 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
 		ld_state.fini_symbol = newp;
 	    }
 	  else if (unlikely (check_definition (sym, shndx, cnt, fileinfo, oldp)
-			     != 0))
+			     != 0))     // WARNING: SIDE EFFECTS!!
 	    /* A fatal error (multiple definition of a symbol)
 	       occurred, no need to continue.  */
 	    return 1;
@@ -1621,8 +1650,19 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
 	      assert (shndx < shnum);
 #endif
 
+//               printf("  add_relocatable_file: file:%s, section:'%s', symb:'%s', isnew:%d\n", 
+//                     (fileinfo ? fileinfo->fname : "<fileinfo==NULL>"),
+//                     elf_strptr (fileinfo->elf, 
+//                                  fileinfo->shstrndx, 
+//                                  SCNINFO_SHDR(fileinfo->scninfo[shndx].shdr).sh_name),
+//                     newp->name, is_new_symb
+//                     );
 	      /* Mark section (and all dependencies) as used.  */
-	      mark_section_used (&fileinfo->scninfo[shndx], shndx, &ignore);
+              // JSY: do not mark as used when in_archive and --gc-sections given and it is a new symbol
+              if (fileinfo->status != in_archive
+                  || !ld_state.gc_sections
+                  || !is_new_symb)
+                mark_section_used (&fileinfo->scninfo[shndx], shndx, &ignore);
 
 	      /* Check whether the section is merge-able.  In this case we
 		 have to record the symbol.  */
@@ -1868,6 +1908,10 @@ add_whole_archive (struct usedfiles *fileinfo)
 }
 
 
+/* Determine any object files in the archive that define
+ * currently unresolved symbols. The object files are then
+ * added using the file_process2() function.
+ */
 static int
 extract_from_archive (struct usedfiles *fileinfo)
 {
@@ -1913,6 +1957,7 @@ extract_from_archive (struct usedfiles *fileinfo)
       any_used = false;
 
       size_t cnt;
+      /* Loop over all the symbols received from the archive symbol table (syms[nsyms]) */
       for (cnt = 0; cnt < nsyms; ++cnt)
 	{
 	  struct symbol search = { .name = syms[cnt].as_name };
@@ -1978,6 +2023,11 @@ extract_from_archive (struct usedfiles *fileinfo)
 }
 
 
+/* Process object file - a standalone elf file or an archive member.
+ * If this is called from extract_from_archive(), we have already determined
+ * that the object file (archive member in this case) contains some currently
+ * unresolved symbol. In that case we'll likely end up calling add_relocatable_file().
+ */
 static int
 file_process2 (struct usedfiles *fileinfo)
 {
@@ -4395,7 +4445,8 @@ ld_generic_create_outfile (struct ld_state *statep)
     }
   else
     {
-      assert (ld_state.need_dynsym);
+      assert (ld_state.need_dynsym
+                && "Some symbol section is required (try removing -s)");         // JSY 2012-01-16
 
       /* First create the symbol table.  We need the symbol section itself
 	 and the string table for it.  */
@@ -4440,10 +4491,13 @@ ld_generic_create_outfile (struct ld_state *statep)
       XElf_Off offset;
       Elf32_Word xndx;
 
+      printf("  ld_generic_create_outfile: section '%s'\n", head->name);
       /* Don't handle unused sections at all.  */
-      if (!head->used)
+      if (!head->used) {
+        printf("  ld_generic_create_outfile: unused section '%s'\n", head->name);
 	continue;
-
+      }
+      
       /* Get the section handle.  */
       scn = elf_getscn (ld_state.outelf, head->scnidx);
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]