Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is /usr/lib64/libc.so generated?

Tags:

linux

glibc

ld

[root@xx test]# cat /usr/lib64/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

Anyone knows how this kind of stuff is generated?

like image 981
compile-fan Avatar asked Apr 07 '11 14:04

compile-fan


1 Answers

This is generated when glibc is compiled using Make utility.

There is a rule (started by make install) in glibc's Makefile, which does just echo needed lines into some temporary file [email protected]:

(echo '/* GNU ld script';\
 echo '   Use the shared library, but some functions are only in';\
 echo '   the static library, so try that secondarily.  */';\
 cat $<; \
 echo 'GROUP ( $(slibdir)/libc.so$(libc.so-version)' \
      '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
      ' AS_NEEDED (' $(slibdir)/$(rtld-installed-name) ') )' \
) > [email protected]

And then this file is renamed to libc.so

mv -f [email protected] $@

Here is a comment from Makefile, which explains a bit:

# What we install as libc.so for programs to link against is in fact a
# link script.  It contains references for the various libraries we need.
# The libc.so object is not complete since some functions are only defined
# in libc_nonshared.a.
# We need to use absolute paths since otherwise local copies (if they exist)
# of the files are taken by the linker.

I understand this as: libc.so.6 is not complete and needs something, which can't be stored in shared library. So, glibc developers moved this something to static part of glibc - libc_nonshared.a. To force always linking both libc.so.6 and libc_nonstared.a, they created a special linking script which instructs ld linker to use both when it is asked for -lc (libc)

What is in the nonshared part? Let's check:

$ objdump -t /usr/lib/libc_nonshared.a |grep " F "|grep -v __
00000000 g     F .text  00000058 .hidden atexit
00000000  w    F .text  00000050 .hidden stat
00000000  w    F .text  00000050 .hidden fstat
00000000  w    F .text  00000050 .hidden lstat
00000000 g     F .text  00000050 .hidden stat64
00000000 g     F .text  00000050 .hidden fstat64
00000000 g     F .text  00000050 .hidden lstat64
00000000 g     F .text  00000050 .hidden fstatat
00000000 g     F .text  00000050 .hidden fstatat64
00000000  w    F .text  00000058 .hidden mknod
00000000 g     F .text  00000050 .hidden mknodat
00000000 l     F .text  00000001 nop

There are atexit(), *stat*(), mknod functions. Why? Don't know really, but it is a fact of glibc.

Here is some long explaination http://giraffe-data.com/~bryanh/giraffehome/d/note/proglib and I cite beginning of it:

The stat() family of functions and mknod() are special.  Their
interfaces are tied so tightly to the underlying operating system that
they change occasionally. 
like image 87
osgx Avatar answered Oct 01 '22 18:10

osgx