c - 使用 gcc 理解共享库

标签 c linux gcc shared-libraries

我试图理解 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)
$

Machine Two

$ 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)
$

目前我还没有完全理解的几点:

  • 括号中给出的地址(例如,(0x002de000))是什么意思?

    即使对于同一台机器上的同一个库,这些地址也是不同的,这表明这些地址是这些库在内存中加载的位置的地址。但是,如果这是真的,为什么这些库会加载到内存中(我还没有执行程序,它们不应该只在运行时加载吗?)。

  • 为什么 two 根本不需要任何库?我用过-O3,汇编输出是

    $ 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
    $
    

    图书馆到底需要什么?

  • 在机器二上,为什么使用 /usr/lib/libcwait.so 而不是 linux-gate.so.1

    我认为这是因为机器二上的内核非常旧 (2.6.9) 并且库 linux-gate.so.1 不可用。是这个原因吗?

最佳答案

What does the address given in brackets (for example, (0x002de000)) mean?

它是加载库的(虚拟)内存地址。 最近的系统可以提供库加载位置的随机化,所以 该地址可能因调用而异。

shouldn't they be loaded only at runtime?

是的。 ldd 经历了很多与 is 相同的过程 虽然在运行时完成,以便能够弄清楚各种事情。

Why does two need any libraries at all?

libc.so.6 是标准的 C 库(和其他东西,比如内核接口(interface))并且总是默认链接。 gcc 有控制这个的选项,例如-nostdlib 标志

ld-linux.so 是一个动态加载程序,负责加载/重定位其他共享库并运行您的应用程序。 ld-linux.so 的联机帮助页为您提供了详细信息。

linux-gate.so.1是一个虚拟库,它只存在于内核内存中。它用于执行对内核的系统调用,并根据您的 CPU 找出最有效的方法。这可能比您的其他 2.6.9 内核机器晚添加到 linux。

我不知道/usr/lib/libcwait.so 是什么,但您可能可以通过执行 rpm -qif/usr/lib/libcwait.so 获得一些有关它的信息

关于c - 使用 gcc 理解共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3902091/

相关文章:

c - 用于 MSP430FR5969 的串口

regex - 如何在文件中查找恰好出现 35 次字符的行?

c - 编译 CUDA 时出错

C 程序使用 GCC 在 Linux 上仅提供 UTC 时间作为本地时间

gcc - 如何在 RHEL7 上将 GCC 从 4.8 更新到 8.2

iphone - 我可以安全地将 UInt32 存储到 NSInteger 吗?

java - 安卓 : calling Java class from C++ Native Activity

c++ - 如何避免标题耦合

linux - 在 Linux 中以编程方式设置自定义文件夹/目录图标

Linux Shell - 查找前 k 个进程