gcc符号表生成机制
符号表生成机制
我们以C语言的编译链接过程为例,详细讲解符号表(Symbol Table)的流程,涵盖编译和链接两个阶段。理解符号表是理解链接器如何解决符号引用(如函数、变量)的关键。
符号表分为两种:
- 目标文件(.o文件)中的符号表:由编译器生成,记录该文件内定义和引用的符号。
- 可执行文件或共享库中的符号表:由链接器生成,包含所有合并后的符号信息。
流程分为四个阶段:预处理、编译、汇编、链接。符号表主要在编译(生成汇编代码)和汇编(生成目标文件)阶段创建,在链接阶段被合并和解析。
1. 第一步:编译阶段(生成目标文件)
当我们编译一个源文件(如main.c)时:
gcc -c main.c -o main.o
编译器(如GCC)会进行以下操作:
- 语法分析、语义分析、中间代码生成、优化等。
- 生成汇编代码(main.s)。
- 汇编器将汇编代码翻译成机器指令(目标文件main.o)。
目标文件(main.o)的组成(以ELF格式为例):
名称 | 作用 |
---|---|
.text段 | 存放代码(函数体)。 |
.data段 | 存放已初始化的全局变量。 |
.bss段 | 存放未初始化的全局变量(预留位置,不占磁盘空间)。 |
.symtab | 符号表,记录本文件中定义和引用的符号信息。 |
符号表包含以下信息:
名称 | 作用 |
---|---|
符号名(name) | 符号的唯一标识 |
符号值(value) | 对于函数和变量,表示其在相应段内的偏移地址(暂时,在链接前是0或相对偏移)。 |
大小(size) | |
类型(type) | 例如数据(变量)、函数、未定义等。 |
绑定信息(binding) | 全局(global)或局部(local)。 |
所在段(section) | 符号属于哪个段(text/data/bss),未定义的符号标记为UND。 |
例如,假设main.c中有如下代码:
extern int external_var; // 声明外部变量
int global_var = 10; // 全局变量,初始化,位于.data段
static int static_var; // 静态变量,未初始化,位于.bss段,且是local符号
void external_func(); // 声明外部函数int main() {
static_var = 1;
external_func();
return 0;
}
那么main.o的符号表中会有以下重要条目:
- global_var:类型为数据(object),在.data段,全局(global),value为0(待重定位)。
- static_var:类型为数据,在.bss段,局部(local),value为0。
- main:类型为函数(FUNC),在.text段,全局(global),value为0。
- external_var:类型为未定义(UND),全局(global)。
- external_func:类型为未定义(UND),全局(global)。
2. 第二步:链接阶段
当我们链接多个目标文件(例如还有func.o)生成可执行文件时:
gcc main.o func.o -o program
链接器(ld)的工作:
- 合并所有目标文件中的段(.text合并到.text,.data合并到.data等)。
- 符号解析:将所有目标文件的符号表合并为一个全局符号表,并解决符号引用。
符号解析过程:
- 链接器扫描所有目标文件,构建一个全局符号表。
- 对于每个未定义的符号,在全局符号表中查找是否有定义。
- 如果找到,则将引用指向该定义(在合并段中的地址)。
- 如果找不到,则报错:undefined reference to …。
例如,假设func.c中有:
int external_var = 100; // 定义external_var
void external_func() { // 定义external_func
}
则func.o的符号表中有:
- external_var:全局,定义在.data段。
- external_func:全局,定义在.text段。
链接器在合并时会:
将main.o中未定义的external_var和external_func解析到func.o中的定义。
同时,在合并段后,重新计算每个符号在最终可执行文件中的地址(即重定位)。
3. 第三步:重定位
链接器在完成符号解析后,还要修改代码段和数据段中对这些符号的引用地址(因为在合并段后,符号的地址发生了变化)。这一步由重定位表(.rel.text, .rel.data)指导完成。
重定位表(在目标文件中)记录了哪些位置需要重定位(即引用了外部符号的位置)。例如,在main.o中,调用external_func()的汇编指令中有一个占位符(地址为0)。链接器根据重定位表将该位置修改为external_func在最终可执行文件中的实际地址。
4. 第四步:生成可执行文件
链接器输出一个可执行文件(如ELF格式),其中包含:
- 所有段(.text, .data等)的合并内容。
- 符号表(通常可执行文件中的符号表可以被去除以减小体积,但若使用-g选项则保留)。
- 其他信息(重定位信息在可执行文件中不再需要,因为地址已固定,但动态链接信息除外)。
动态链接的符号解析与静态链接不同:
- 静态链接在链接阶段完全解析符号(ld直接解析了)。
- 动态链接在运行时由动态链接器(ld-linux.so)完成解析。
例如,如果我们在程序中使用了动态库(如libc.so)中的函数,在链接阶段,链接器只记录该函数在动态库中的符号名,并不解析具体地址。在可执行文件中,这些符号被标记为动态符号(在.dynsym节中),并且需要重定位表(.rel.plt, .rel.dyn)在运行时进行重定位。
5. 总结:
符号表的流程:
- 编译阶段:每个源文件编译成目标文件,生成局部符号表。
- 链接阶段:
- 合并所有目标文件的段。
- 合并符号表,进行符号解析(将未定义的符号绑定到定义的地方)。
- 重定位:根据新的段布局修改符号引用的地址(利用重定位表)。
- 输出可执行文件或共享库。
通过这个流程,链接器确保了程序中的所有符号引用都有唯一的定义,并位于正确的地址。
符号检查工具
# 查看目标文件符号
nm target.o# 详细符号信息
readelf -s target.o# 检查未定义符号
nm -u target.o# 显示动态符号表
readelf --dyn-syms program# 查看符号版本
objdump -T libc.so.6 | grep memcpy# 详细链接日志
ld --verbose# 跟踪链接过程
LD_DEBUG=all ./program# 重定位表检查
readelf -r program.o
场景 | 示例错误信息 | 原因 |
---|---|---|
函数未定义 | undefined reference to ‘func()’ | 函数声明存在,但无实现代码 |
函数签名不匹配 | undefined reference to ‘func(int)’ | 声明与定义的参数类型/数量不一致 |
库文件未链接 | unresolved external symbol | 依赖的静态库未加入链接命令 |
C/C++ 混合编程未处理 | ?func@@YAHHH@Z(名称修饰不一致) | 未用 extern “C” 声明 C 函数 |
相关文章:
gcc符号表生成机制
符号表生成机制 我们以C语言的编译链接过程为例,详细讲解符号表(Symbol Table)的流程,涵盖编译和链接两个阶段。理解符号表是理解链接器如何解决符号引用(如函数、变量)的关键。 符号表分为两种ÿ…...

达梦数据库 Windows 系统安装教程
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
unix/linux source 命令,其基本概念、定义、性质、定理
从计算机科学的角度,特别是形式语言、操作系统和编程语言设计的角度来看,source (或 .) 命令虽然看似简单,但其背后也蕴含着一些核心的概念、定义、性质和可以类比的“定理”(或者说,更准确地是“设计原则”或“行为模式”)。 让我们尝试从一个更理论和结构化的视角来剖…...

【Java EE初阶】计算机是如何⼯作的
计算机是如何⼯作的 计算机发展史冯诺依曼体系(Von Neumann Architecture)CPU指令(Instruction)CPU 是如何执行指令的(重点) 操作系统(Operating System)进程(process) 进程 PCB 中的…...

RAG理论基础总结
目录 概念 流程 文档收集和切割 读取文档 转换文档 写入文档 向量转换和存储 搜索请求构建 向量存储工作原理 向量数据库 文档过滤和检索 检索前 检索 检索后 查询增强和关联 QuestionAnswerAdvisor查询增强 高级RAG架构 自纠错 RAG(C-RAG…...

列表推导式(Python)
[表达式 for 变量 in 列表] 注意:in后面不仅可以放列表,还可以放range ()可迭代对象 [表达式 for 变量 in 列表 if 条件]...
嵌入式RTC工作原理及应用场景
20ppm 是衡量 RTC(实时时钟)精度的关键指标,表示 每百万秒(约11.57天)的最大时间误差范围。以下是通俗易懂的解释: 1. ppm 的含义 ppm Parts Per Million(百万分之一) 1 ppm 1/1,…...

一天搞懂深度学习--李宏毅教程笔记
目录 1. Introduction of Deep Learning1.1. Neural Network - A Set of Function1.2. Learning Target - Define the goodness of a function1.3. Learn! - Pick the best functionLocal minimaBackpropagation 2. Tips for Training Deep Neural Network3. Variant of Neural…...
Go语言常见接口设计技巧-《Go语言实战指南》
在 Go 中,接口是连接代码组件的桥梁。合理设计接口可以大幅提升程序的可维护性、可扩展性和测试友好性。本章将分享 Go 开发中常见的接口设计技巧与最佳实践。 一、接口设计原则 1. 面向接口编程,而非面向实现编程 尽量使用接口类型作为函数参数或返回值…...

python打卡训练营打卡记录day43
复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 进阶:并拆分成多个文件 数据集来源:Flowers Recognition 选择该数据集原因: 中等规模:4242张图片 - 训练快速但足够展示效…...
Camera相机人脸识别系列专题分析之十一:人脸特征检测FFD算法之低功耗libvega_face.so人脸属性(年龄,性别,肤色,微笑,种族等)检测流程详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:Camera相机人脸识别系列专题分析之十:人脸特征检测FFD算法之低功耗libvega_face.so人脸识别检测流程详解 这一篇我们开始讲: Camera相机人脸识别系列专题分析之十一:人脸特征检测FFD算法之低功耗lib…...
解决:输入SSH后,仍无法通过网址登录以及紧接着的新问题Permission denied(publickey,password).
现象: 管理员: Windows PowerShell输入SSH后,仍无法通过网址登录 例如输入你的ssh命令:ssh -CNg -L xxxx:127.0.0.1:xxxx rootaaaaaaaaa.com -p yyyyy 得到终端提示:ssh无法识别为 cmdlet、函数、脚本文件或可运行程序的名称。 解…...

【QT控件】QWidget 常用核心属性介绍 -- 万字详解
目录 一、控件概述 二、QWidget 核心属性 2.1 核心属性概览 2.2 enabled 编辑 2.3 geometry 2.4 windowTitle 2.5 windowIcon 使用qrc文件管理资源 2.6 windowOpacity 2.7 cursor 2.8 font 编辑 2.9 toolTip 2.10 focusPolicy 2.11 styleSheet QT专栏&…...

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)
地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…...
HTTPS加密通信详解及在Spring Boot中的实现
HTTPS(Hyper Text Transfer Protocol Secure)是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护。 一、HTTPS核心原理 1.加密流程概述 客户端发起HTTPS请求(连接到服务器443端口)服务器返…...
如何让 Git 停止跟踪文件?停止后又如何恢复跟踪?
在使用 Git 管理代码时,有时我们希望某些文件不再被 Git 跟踪(比如本地配置文件、临时文件等),但保留这些文件在本地;过了一段时间,可能又需要恢复跟踪这些文件。本文将用通俗易懂的语言,教你如…...

【第16届蓝桥杯 | 软件赛】CB组省赛第二场
个人主页:Guiat 归属专栏:算法竞赛 文章目录 A. 密密摆放(5分填空题)B. 脉冲强度之和(5分填空题)C. 25 之和D. 旗帜E. 数列差分F. 树上寻宝G. 翻转硬币H. 破解信息 正文 总共8道题。 A. 密密摆放࿰…...
SQL进阶之旅 Day 10:执行计划解读与优化
【SQL进阶之旅 Day 10】执行计划解读与优化 开篇 今天是我们的"SQL进阶之旅"系列的第10天,我们将深入探讨SQL执行计划的解读与优化技巧。随着数据库规模的增长和业务复杂度的提升,理解SQL语句在数据库引擎中的执行过程变得至关重要。 执行计…...

AR/MR实时光照阴影开发教程
一、效果演示 1、PICO4 Ultra MR 发光的球 2、AR实时光照 二、实现原理 PICO4 Ultra MR开发时,通过空间网格能力扫描周围环境,然后将扫描到的环境网格材质替换为一个透明材质并停止扫描;基于Google ARCore XR Plugin和ARFoundation进行安卓手…...
Visual studio 中.sln/.vcxproj/.vcxproj.filters和.vcxproj.user文件的作用
在 Visual Studio (尤其是 C 项目) 中,.sln、.vcxproj、.vcxproj.filters 和 .vcxproj.user 文件各自承担着不同的关键角色。理解它们的作用对于项目管理和协作至关重要。 核心原则: .vcxproj 和 .sln 是项目/解决方案的核心定义文件,必须纳…...

【汽车电子入门】一文了解LIN总线
前言:LIN(Local Interconnect Network)总线,也就是局域互联网的意思,它的出现晚于CAN总线,于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发,其目的是提供一…...
JVM学习(七)--JVM性能监控
目录 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 2、JVM监控及诊断工具-GUI篇 3、JVM运行时参数 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 面试题: 1、你使用过Java虚拟机性能监控和故障处理工具吗? 2、怎么打出线程栈信息。 3、怎么获取 Jav…...
关于 java:5. Java IO 与文件操作
一、File 类(读取文件属性) 1.1 java.io.File 类概述 File 是 Java IO 中的核心类,用于表示文件或目录的路径名。 它是一个抽象路径名,可以表示实际存在或不存在的文件/文件夹。 File 类提供了创建、删除、重命名、判断属性、获…...

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)
📝 为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境) 🎯 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中,搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…...
【笔记】MLA矩阵吸收分析
文章目录 一、张量运算的计算量1. FLOPs定义2. 张量计算顺序对计算量的影响 二、MLA第一次矩阵吸收的计算量分析1. 原始注意力计算2. MLA源代码中的吸收方式3. 提前吸收4. 比较分析4.1 比较顺序1和顺序24.2 比较顺序2和顺序3 三、MLA第二次矩阵吸收的计算量分析1. 原始输出计算…...
600+纯CSS加载动画一键获取指南
CSS-Loaders.com 完整使用指南:600纯CSS加载动画库 🎯 什么是 CSS-Loaders.com? CSS-Loaders.com 是一个专门提供纯CSS加载动画的资源网站,拥有超过600个精美的单元素加载器。这个网站的最大特色是所有动画都只需要一个HTML元素…...
开源的JT1078转GB28181服务器
JT1078转GB28181流程 项目地址: JT1078转GB28181的流媒体服务器: https://github.com/lkmio/lkm JT1078转GB28181的信令服务器: https://github.com/lkmio/gb-cms 1. 创建GB28181 UA 调用接口: http://localhost:9000/api/v1/jt/device/add 请求体如下…...

智能守护电网安全:探秘输电线路测温装置的科技力量
在现代电力网络的庞大版图中,输电线路如同一条条 “电力血管”,日夜不息地输送着能量。然而,随着电网负荷不断增加,长期暴露在户外的线路,其线夹与导线在电流热效应影响下,极易出现温度异常。每年因线路过热…...
Java垃圾回收算法及GC触发条件
一、引言 在Java编程语言的发展历程中,内存管理一直是其核心特性之一。与C/C等需要手动管理内存的语言不同,Java通过自动垃圾回收(Garbage Collection,简称GC)机制,极大地减轻了开发人员的负担,…...

【Hot 100】118. 杨辉三角
目录 引言杨辉三角我的解题代码优化优化说明 🙋♂️ 作者:海码007📜 专栏:算法专栏💥 标题:【Hot 100】118. 杨辉三角❣️ 寄语:书到用时方恨少,事非经过不知难! 引言 …...