[Top][All Lists]
[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
{
- ld creates shared libraries with garbage in the .dynsym section,
Bruno Haible <=