Understanding shared libraries using gcc

I am trying to understand the following behavior of shared libraries in C

Machine one

$ cat one.c #include<stdio.h> int main() { printf ("%d", 45); } $ gcc one.c -o one -O3 $ ldd one linux-gate.so.1 => (0x00331000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc2000) /lib/ld-linux.so.2 (0x006dc000) $ cat two.c int main() { int i = 0; } $ gcc two.c -o two -O3 $ ldd two linux-gate.so.1 => (0x006f7000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000) /lib/ld-linux.so.2 (0x00eb0000) $ 

Second car

 $ cat three.c #include<stdio.h> int main() { printf ("%d", 45); } $ gcc three.c -o three -O3 $ ldd three /usr/lib/libcwait.so (0xb7ffd000) libc.so.6 => /lib/tls/i686/nosegneg/libc.so.6 (0x002de000) /lib/ld-linux.so.2 (0x002bf000) $ 

A few things that I currently do not fully understand:

  • What does the address indicated in parentheses mean (for example, (0x002de000) )?

    These addresses are different even for the same library on the same computer, which indicates that these are addresses of places in the memory where these libraries are loaded. But, if so, why are these libraries loaded into memory at all (I haven't run programs yet, shouldn't they only load at run time?).

  • Why do two need any libraries at all? I used -O3 and the assembler output is

     $ gcc two.c -S -O3 $ cat two.s .file "two.c" .text .p2align 4,,15 .globl main .type main, @function main: pushl %ebp movl %esp, %ebp popl %ebp ret .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits $ 

    What do any libraries need?

  • On machine two, why is /usr/lib/libcwait.so used instead of linux-gate.so.1 ?

    I think this is due to the fact that the kernel on Machine Two is very old (2.6.9), and the linux-gate.so.1 not available. This is the reason?

+4
source share
3 answers

What does the address indicated in parentheses mean (for example, (0x002de000))?

This is the (virtual) memory address into which the library is loaded. A recent system can randomize where libraries are loaded, so this address may vary between calls.

shouldn't they only load at run time?

Yes they are. ldd goes through most of the same procedure as at run time to understand various things.

Why do two need any libraries?

libc.so.6 is the standard C library (and other things, such as the kernel interface) and is always bundled by default. gcc has options to control this, for example, the -nostdlib flag

ld-linux.so is a dynamic bootloader, and it is responsible for loading / moving other shared libraries and launching your application. The man page for ld-linux.so gives you detailed information.

linux-gate.so.1 is a virtual library, it exists only in memory in the kernel. It was used to make kernel system calls, and figure out the most efficient way to do this based on your processor. This was probably added in linux later than your other 2.6.9 kernel machine.

I don't know what /usr/lib/libcwait.so is, but most likely you can get some information about this by running rpm -qif / usr / lib / libcwait.so

+5
source

Addresses are mostly random numbers. Before secure implementations were developed, ldd will sequentially indicate the memory addresses where the program sections were loaded. Since about five years ago, many varieties of Linux have now deliberately randomized download addresses to disrupt potential virus writers, etc. I compiled one.c (like tc) and re-executed ldd:

 [ wally@zenetfedora .bin]$ cat tc #include <stdio.h> int main() { printf ("%d", 45); } [ wally@zenetfedora .bin]$ gcc -ot tc -O3 [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x009e5000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00b8d000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00238000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x002a0000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00f93000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00c7a000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00d1a000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) [ wally@zenetfedora .bin]$ ldd t linux-gate.so.1 => (0x00d12000) libc.so.6 => /lib/libc.so.6 (0x002e4000) /lib/ld-linux.so.2 (0x002c2000) 

The crtl and ld-linux load addresses are consistent, but linux-gate is randomized.

Libraries are needed because it is necessary to start the initialization and completion of C. Of course, they can be greatly optimized, since stdin , stdout , stderr , etc. Etc. No need to initialize. However, crtl is a way to call main() .

Different Linux variants and versions have differences. The evolution of glib has taken many turns. Some things have been transferred to other libraries. It's almost the same as your local grocery store moving things around. It does not really matter.

+2
source

A number is the memory address where the library loads when the executable is launched. It is detected at connection time and is usually randomized in order to make errors in library functions unpredictable and therefore more difficult to use in exploits. The default C library is linked by GCC by default. libcwait is probably another default library, possibly used by older versions of GCC.

+1
source

All Articles