This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


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

[PATCH] Fix place_orphan


Hi!

I was wondering why some glibc shared libraries have .interp sections placed
in between non-alloced sections, like for libBrokenLocale.so.1:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .note.ABI-tag     NOTE            000000f4 0000f4 000020 00   A  0   0  4
  [ 2] .hash             HASH            00000114 000114 0000c8 04   A  3   0  4
  [ 3] .dynsym           DYNSYM          000001dc 0001dc 000230 10   A  4  1c  4
  [ 4] .dynstr           STRTAB          0000040c 00040c 00010b 00   A  0   0  1
  [ 5] .gnu.version      VERSYM          00000518 000518 000046 02   A  3   0  2
  [ 6] .gnu.version_d    VERDEF          00000560 000560 000038 00   A  4   2  4
  [ 7] .gnu.version_r    VERNEED         00000598 000598 000030 00   A  4   1  4
  [ 8] .rel.data         REL             000005c8 0005c8 000010 08   A  3   f  4
  [ 9] .rel.got          REL             000005d8 0005d8 000030 08   A  3  13  4
  [10] .rel.plt          REL             00000608 000608 000018 08   A  3   c  4
  [11] .init             PROGBITS        00000620 000620 000018 00  AX  0   0  4
  [12] .plt              PROGBITS        00000638 000638 000040 04  AX  0   0  4
  [13] .text             PROGBITS        00000680 000680 0001b0 00  AX  0   0 16
  [14] .fini             PROGBITS        00000830 000830 00001e 00  AX  0   0  4
  [15] .data             PROGBITS        00001864 000864 000028 00  WA  0   0  4
  [16] .eh_frame         PROGBITS        0000188c 00088c 000004 00  WA  0   0  4
  [17] .ctors            PROGBITS        00001890 000890 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        00001898 000898 000008 00  WA  0   0  4
  [19] .got              PROGBITS        000018a0 0008a0 000030 04  WA  0   0  4
  [20] .dynamic          DYNAMIC         000018d0 0008d0 0000e0 08  WA  4   0  4
  [21] .sbss             PROGBITS        000019b0 0009b0 000000 00   W  0   0  1
  [22] .bss              NOBITS          000019b0 0009b0 000018 00  WA  0   0  4
  [23] .stab             PROGBITS        00000000 0009b0 0012c0 0c     24   0  4
  [24] .stabstr          STRTAB          00000000 001c70 004ca8 00      0   0  1
  [25] .comment          PROGBITS        00000000 006918 000144 00      0   0  1
  [26] .note             NOTE            00000000 006a5c 000078 00      0   0  1
  [27] .interp           PROGBITS        0000084e 00084e 000013 00   A  0   0  1
  [28] .shstrtab         STRTAB          00000000 006ad4 0000fa 00      0   0  1
  [29] .symtab           SYMTAB          00000000 0070a8 0004b0 10     30  44  4
  [30] .strtab           STRTAB          00000000 007558 000236 00      0   0  1

(see section [27]). Turns out this is because this library lacks .rodata section.
It is not hard to place it into the expected place though, see following patch.
Minimal testcase is:
cat > test.s <<EOF
.section .interp,"a",@progbits
.string "/lib/ld-linux.so.2"
EOF
gcc -shared -o test.so test.s
The patch basically, if place->os->bfd_section is NULL, looks through
output_section list and finds last non-NULL bfd_section which preceedes it
(in libBrokenLocale.so.1 case that would be e.g. .fini).
Ok to commit? Tested on i386-redhat-linux.

2001-07-12  Jakub Jelinek  <jakub@redhat.com>

	* emultempl/elf32.em (output_prev_sec_find): New.
	(place_orphan): Use it.

--- ld/emultempl/elf32.em.jj	Wed Jul 11 15:48:53 2001
+++ ld/emultempl/elf32.em	Thu Jul 12 21:04:56 2001
@@ -1006,6 +1006,35 @@ EOF
 if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
+/* Find the last output section before given output statement.
+   Used by place_orphan.  */
+
+static asection *
+output_prev_sec_find (os)
+     lang_output_section_statement_type *os;
+{
+  asection *s = (asection *) NULL;
+  lang_statement_union_type *u;
+  lang_output_section_statement_type *lookup;
+
+  for (u = lang_output_section_statement.head;
+       u != (lang_statement_union_type *) NULL;
+       u = lookup->next)
+    {
+      lookup = &u->output_section_statement;
+      if (lookup == os)
+	break;
+      if (lookup->bfd_section != NULL)
+	s = lookup->bfd_section;
+    }
+
+  if (u == NULL)
+    return NULL;
+
+  return s;
+}
+
+
 /* Place an orphan section.  We use this to put random SHF_ALLOC
    sections in the right segment.  */
 
@@ -1192,12 +1221,16 @@ gld${EMULATION_NAME}_place_orphan (file,
 
   if (place != NULL)
     {
-      asection *snew, **pps;
+      asection *snew, **pps, *bfd_section;
 
       snew = os->bfd_section;
+      bfd_section = place->os->bfd_section;
+      if (place->section == NULL && bfd_section == NULL)
+	bfd_section = output_prev_sec_find (place->os);
+
       if (place->section != NULL
-	  || (place->os->bfd_section != NULL
-	      && place->os->bfd_section != snew))
+	  || (bfd_section != NULL
+	      && bfd_section != snew))
 	{
 	  /* Shuffle the section to make the output file look neater.
 	     This is really only cosmetic.  */
@@ -1206,15 +1239,15 @@ gld${EMULATION_NAME}_place_orphan (file,
 #if 0
 	      /* Finding the end of the list is a little tricky.  We
 		 make a wild stab at it by comparing section flags.  */
-	      flagword first_flags = place->os->bfd_section->flags;
-	      for (pps = &place->os->bfd_section->next;
+	      flagword first_flags = bfd_section->flags;
+	      for (pps = &bfd_section->next;
 		   *pps != NULL && (*pps)->flags == first_flags;
 		   pps = &(*pps)->next)
 		;
 	      place->section = pps;
 #else
 	      /* Put orphans after the first section on the list.  */
-	      place->section = &place->os->bfd_section->next;
+	      place->section = &bfd_section->next;
 #endif
 	    }
 

	Jakub


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