菜单开关

周梦康 发表于 2019-08-25 761 次浏览
#include <stdio.h>

int main() {

    int a = 3;
    int b = 5;
    int c = 7;

    printf("%d",(a + b) * c);
    return 0;
}

把上面程序使用gcc编译之后,默认得到的文件名为a.out

[vagrant@10 04]$ ldd a.out
    linux-vdso.so.1 =>  (0x00007ffe6d5f8000)
    libc.so.6 => /usr/lib64/libc.so.6 (0x00007f476d62d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f476d9fa000)

ldd模拟运行一遍程序,在运行过程中做动态链接,从而得知这个可执行文件依赖于哪些共享库,每个共享库都在什么路径下,加载到进程地址空间的什么地址。也就是说我们使用gcc编译器编译的时候规定动态链接的是/usr/lib64/libc.so.6

[vagrant@10 04]$ readelf -h /usr/lib64/libc.so.6
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              DYN (共享目标文件)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  入口点地址:              0x224e0
  程序头起点:              64 (bytes into file)
  Start of section headers:          2146808 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       56 (字节)
  Number of program headers:         10
  节头大小:         64 (字节)
  节头数量:         76
  字符串表索引节头: 75

可以看到该共享库支持的操作系统(OS)是UNIX,应用程序二进制接口(ABI)是GNU。所以我们去看下gnuprintf的源码实现

gun libc 源码在 http://mirrors.kernel.org/gnu/glibc/

找了个最老的版本,看了下,太复杂。。

linux 比较老的源码下载,推荐0.11 https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/old-versions/

/*
 *  linux/lib/write.c
 *
 *  (C) 1991  Linus Torvalds
 */

#define __LIBRARY__
#include <unistd.h>

_syscall3(int,write,int,fd,const char *,buf,off_t,count)
// 路径在 include/unistd.h

#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
type name(atype a,btype b,ctype c) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
if (__res>=0) \
    return (type) __res; \
errno=-__res; \
return -1; \
}

疑惑点

lib不是内核的代码吗,不应该在进入内核前中断么,怎么是先进入的内核然后才触发中断呢?
原来lib目录本身也有Makefile会生成一个静态库。

评论列表