libgcc_s.so.1是什么
The GCC
low-level runtime library
会在有需要的时候自动启动的C
运行时库,可以替代某些机器完成整数、浮点运算,还有一些其他的功能。
运行时库
应用程序和操作系统之间的桥梁,对操作系统硬件的抽象,包括对IO
操作、程序启动和程序退出、栈等的实现。不同的操作系统对应不同的运行时库,但提供的接口基本一致,比如windows
和linux 的运行时库,都提供fread 功能,但是其实现应该是不一样的,fread
就包括在运行时库中。
编译参数顺序
LINKFLAGS_AFTER_LIBS(False)决定cxxflags、ldflags(编译参数和链接参数)是放在库前还是库后,对cmake
和bcloud 而言有用,对gcc
而言没有所谓这些参数之分,都是编译参数,链接的库名也都是编译参数,但是编译参数之间的顺序可能会影响能否编译成功
libc.so
/usr/lib/aarch64-linux-gnu/libc.so
是个链接脚本,表示在链接时去链哪个库,可以根据需要选择动态库还是静态库
符号集版本
func@GLIBC_2.31
GLIBC_2.31表示符号集版本,向下兼容,即如果需要func@GLIBC_2.29时也没问题
强符号和若符号
符号表中的 STRONG 和 WEAK
强符号:全局且初始化的参数和默认的函数,都属于强符号,强符号全局只能唯一,找不到直接报
undefined reference
弱符号:全局且未初始化的参数,也可以在代码中来指定。弱符号在链接时候找不到可以暂时用0地址代替,链接时不会报
undefined,作为插件接口或用户自定义接口使用更加方便。
gcc 安装
https://wenku.baidu.com/view/b73c43055a0102020740be1e650e52ea5418ce77.html?wkts=1676342805235
wget https://mirrors.ustc.edu.cn/gnu/gcc/gcc-7.5.0
Note: gcc 安装后 c 和 c++ 的标准库还是原来的版本
添加系统头文件搜索路径
https://blog.csdn.net/yjk13703623757/article/details/83154578
gcc的环境变量CPLUS_INCLUDE_PATH(C程序使用的是C_INCLUDE_PATH)
gcc 低版本问题
gcc4 gcc5 不支持直接使用enum 作为map 的键指,需要自己指定hash
方法。
/lib/ld-linux-aarch64.so.1
作用
其是 aarch64平台上的动态链接器,ld-linux-aarch64.so.1 是ld-2.31.so
的软链接
linux man
手册介绍:https://man7.org/linux/man-pages/man8/ld.so.8.html
可执行的 ELF 程序中,将使用的动态链接器路径存储在 .interp section
中,或者也可以手动执行命令
/lib/ld-linux.so.* [OPTIONS] [PROGRAM [ARGUMENTS]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| $ readelf -l /bin/ls
Elf file type is DYN (Shared object file) Entry point 0x67d0 There are 13 program headers, starting at offset 64
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000002d8 0x00000000000002d8 R 0x8 INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 0x000000000000001c 0x000000000000001c R 0x1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x00000000000036a8 0x00000000000036a8 R 0x1000 LOAD 0x0000000000004000 0x0000000000004000 0x0000000000004000 0x0000000000013581 0x0000000000013581 R E 0x1000 LOAD 0x0000000000018000 0x0000000000018000 0x0000000000018000 0x0000000000008b50 0x0000000000008b50 R 0x1000 LOAD 0x0000000000021010 0x0000000000022010 0x0000000000022010 0x0000000000001258 0x0000000000002548 RW 0x1000 DYNAMIC 0x0000000000021a58 0x0000000000022a58 0x0000000000022a58 0x0000000000000200 0x0000000000000200 RW 0x8 NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8 NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358 0x0000000000000044 0x0000000000000044 R 0x4 GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8 GNU_EH_FRAME 0x000000000001d24c 0x000000000001d24c 0x000000000001d24c 0x000000000000092c 0x000000000000092c R 0x4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10 GNU_RELRO 0x0000000000021010 0x0000000000022010 0x0000000000022010 0x0000000000000ff0 0x0000000000000ff0 R 0x1
|
当误删掉 ld-linux-aarch64.so.1, 可执行程序凭借 .interp section
找不到正确的动态链接器,因此什么命令也无法执行,但是还可以通过
/lib/ld-2.31.so /bin/ln 命令对原本的软链接做还原。
参考: https://www.zhihu.com/question/385135873/answer/1139858267