文本文件

源码文件就是文本类型

1➜  fashnv git:(main) ✗ file main.go     
2main.go: c program text, Unicode text, UTF-8 text

程序

  • 动态链接
  • 静态链接

静态链接

fashnv 是go build 出来的二进制文件,是静态链接程序

1➜  fashnv git:(main) ✗ file fashnv     
2fashnv: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=JrQ_Ix2QTqsthM88zctF/aiHR2VD1EEeCCeuMNU0y/Eu6eBh5w9k00OcFG0P3g/4QuehrTGvBerKD3G5lSq, stripped

cat a.c

1extern int x;
2int main(){
3	test(x);
4	return 0;
5
6}

cat b.c

1int x=300;
2
3int test(int v){
4	return v;
5}
1gcc -c a.c -o a.o
2gcc -c b.c -o b.o
3vagrant@ubuntu2204:/home/www/c/ld$ ld a.o b.o -e main -o ab
4vagrant@ubuntu2204:/home/www/c/ld$ ls
5ab  a.c  a.o  b.c  b.o
6vagrant@ubuntu2204:/home/www/c/ld$ ./ab
7Segmentation fault (core dumped)
8vagrant@ubuntu2204:/home/www/c/ld$ file ab
9ab: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

动态链接

打印helloworld的c 编译出来的就是个动态链接程序。

cat 001hello.c

1#include <stdio.h>
2
3int main(){
4  printf("hello world\n");
5  return 0;
6}
1vagrant@ubuntu2204:/home/www/c$ gcc 001hello.c
2vagrant@ubuntu2204:/home/www/c$ ls
3001hello.c   004char.c      007putchar_getchar.c  a.out
4002sizeof.c  005printf.c    008hermit_assign.c    ld
5003float.c   006constant.c  009qiang_change.c
6vagrant@ubuntu2204:/home/www/c$ ./a.out
7hello world
8vagrant@ubuntu2204:/home/www/c$ file a.out
9a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=aece32b89fbdd8d0537638709482075c68faa014, for GNU/Linux 3.2.0, not stripped
1vagrant@ubuntu2204:/home/www/c$ ldd a.out
2	linux-vdso.so.1 (0x00007ffc5a9e8000)
3	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa512bea000)
4	/lib64/ld-linux-x86-64.so.2 (0x00007fa512e20000)

go 程序本身就是动态链接程序

 1vagrant@ubuntu2204:/home/www/c/ld$ which  go
 2/home/vagrant/go/go1.16.2/bin/go
 3vagrant@ubuntu2204:/home/www/c/ld$ file /home/vagrant/go/go1.16.2/bin/go
 4/home/vagrant/go/go1.16.2/bin/go: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=nV9lqTh-ZPFAo5rg8-dC/4d10FD5jy4F2MisGCrf1/2za6_VbQMXgGb9TYGtgE/6BVF_bFleMlL2m8dnVls, not stripped
 5
 6vagrant@ubuntu2204:/home/www/c$ ldd /home/vagrant/go/go1.16.2/bin/go
 7linux-vdso.so.1 (0x00007ffc1458e000)
 8libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5b690b9000)
 9libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5b68e91000)
10/lib64/ld-linux-x86-64.so.2 (0x00007f5b690c7000)

ELF文件结构

elf文件大致由以下内容组成

  • ELF HEADER 头
  • 程序头 program header
  • 段表 section header
  • .text 代码段
  • .data 数据段
    • .bss
    • .rodata
  • 其他段
1readelf xxx

程序头表,只有可执行文件或动态库文件才有,目标文件(还没链接)是没有 程序头表,它决定了操作系统加载可执行文件的映射方法