bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ld creates shared libraries with garbage in the .dynsym section


From: Bruno Haible
Subject: ld creates shared libraries with garbage in the .dynsym section
Date: Mon, 1 Jul 2002 13:15:00 +0200 (CEST)

Hi,

Using binutils-2.12.90.0.7, when linking programs against glibc for
FreeBSD/i386, I got link errors mentioning strange versioned symbols.
A detailed look using "readelf" revealed that libc.so.6's .dynsym
section contained garbage symbols. In detail this section contained
  - 1 dummy symbol,
  - 64 section symbols,
  - 1858 regular symbols,
  - 26 section symbols again,
  - 34 garbage symbols:

  1949: 00010020   660 OBJECT  GLOBAL DEFAULT   12 getwchar@@GLIBC_2.1.2
  1950: 00009d04    52 FUNC    GLOBAL DEFAULT   10 48_r@@GLIBC_2.1.2
  1951: 0000a12c  1090 FUNC    GLOBAL DEFAULT   10 res@@GLIBC_2.1.2
  1952: 000065d4   680 FUNC    GLOBAL DEFAULT   10 har@@GLIBC_2.1.2
  1953: 000104a4     4 OBJECT  GLOBAL DEFAULT   15 core@@GLIBC_2.1.2
  1954: 0000943c   309 FUNC    GLOBAL DEFAULT   10 ntp_gettime@@GLIBC_2.1.2
  1957: 00005ff2   521 FUNC    GLOBAL DEFAULT   10 marker@@GLIBC_2.1.2
  1959: 000061fc   983 FUNC    GLOBAL DEFAULT   10 pread@@GLIBC_2.1.2
  1960: 000102c0     4 OBJECT  GLOBAL DEFAULT   12 hroot@@GLIBC_2.1.2
  1961: 00005d74   637 FUNC    GLOBAL DEFAULT   10 
_IO_wdefault_xsgetn@@GLIBC_2.1.2
  1963: 00009906     5 FUNC    GLOBAL DEFAULT   10 sym@@GLIBC_2.1.2
  1964: 00010000     4 OBJECT  GLOBAL DEFAULT   12 _link_in@@GLIBC_2.1.2
  1965: 00002ec8   277 FUNC    GLOBAL DEFAULT   10 __daylight@@GLIBC_2.1.2
  1967: 00000000     0 OBJECT  GLOBAL DEFAULT  ABS r@@GLIBC_2.1.2
  1969: 0000b2bc   141 FUNC    GLOBAL DEFAULT   10 @@GLIBC_2.1.2
  1970: 0000a640  2055 FUNC    GLOBAL DEFAULT   10 unsetenv@@GLIBC_2.1.2
  1971: 00007aa6  1098 FUNC    GLOBAL DEFAULT   10 tfsstat@@GLIBC_2.1.2
  1972: 00002e40   135 FUNC    GLOBAL DEFAULT   10 ate@@GLIBC_2.1.2
  1973: 00010004     4 OBJECT  GLOBAL DEFAULT   12 O_sputbackc@@GLIBC_2.1.2
  1974: 0000d800    14 OBJECT  GLOBAL DEFAULT   11 default_finish@@GLIBC_2.1.2
  1976: 0000498c  1950 FUNC    GLOBAL DEFAULT   10 longlong_t@@GLIBC_2.1.2
  1977: 00009070   410 FUNC    GLOBAL DEFAULT   10 @@GLIBC_2.1.2
  1979: 00009250   166 FUNC    GLOBAL DEFAULT   10 __isxdigit_l@@GLIBC_2.1.2
  1982: 0000808e  3377 FUNC    GLOBAL DEFAULT   10 t_morecore@@GLIBC_2.1.2

Where does the difference between the total number (1983) and the real number
(1923) of symbols come from? I added a printf statement in
elf_bfd_final_link (bfd/elflink.h:5914), right after the
bfd_set_section_contents call that copies the dynamic sections to their
output sections, and got this:

Filling up section .gnu.version_d, predicted 652 bytes, got 488 bytes.
Filling up section .gnu.version, predicted 3966 bytes, got 3846 bytes.
Filling up section .dynsym, predicted 31728 bytes, got 30768 bytes.
Filling up section .dynamic, predicted 368 bytes, got 192 bytes.
Filling up section .hash, predicted 12164 bytes, got 11768 bytes.

I.e. for these sections the initial _raw_size estimate made by
lang_size_sections_1() is higher than the final contents.

I made the appended patch, to clear the garbage memory region that will
later be written to the file. Would it be better to simply set
  o->output_section->_raw_size = o->_raw_size;  ?
Also, how to handle the other 4 sections where the same phenomenon occurs
but where clearing the memory makes things worse, not better?

Bruno

*** binutils-2.12.90.0.7/bfd/elflink.h.bak      Fri Apr  5 20:03:50 2002
--- binutils-2.12.90.0.7/bfd/elflink.h  Fri Jun 28 23:28:07 2002
***************
*** 5911,5916 ****
--- 5911,5936 ----
                                              (file_ptr) o->output_offset,
                                              o->_raw_size))
                goto error_return;
+             /* Sometimes the .dynsym section contains more room than
+                really needed.  (Example: libc.so, o->_raw_size = 1923 * 16,
+                o->output_section->_raw_size = 1983 * 16.)  We clear
+                the rest instead of leaving garbage there.  */
+             if (o->output_section->_raw_size < o->_raw_size)
+               abort ();
+             if (o->output_section->_raw_size > o->_raw_size)
+               if (strcmp (o->name, ".dynsym") == 0)
+                 {
+                   char *zerop = calloc (o->output_section->_raw_size - 
o->_raw_size, 1);
+                   if (!zerop)
+                     goto error_return;
+                   if (! bfd_set_section_contents (abfd, o->output_section,
+                                                   zerop,
+                                                   o->output_offset + 
o->_raw_size,
+                                                   
o->output_section->_raw_size - o->_raw_size))
+                     goto error_return;
+                   free (zerop);
+                   fprintf (stderr, "Filling up section %s, predicted %ld 
bytes, got %ld bytes.\n", o->name, o->output_section->_raw_size, o->_raw_size);
+                 }
            }
          else
            {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]