展开全部

主编推荐语

多维度讲解多任务操作系统中编译、链接、装载与库的内幕与技术细节。

内容简介

本书深入浅出地讲解了构建过程(编译、链接)中的细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码重用和系统集成的软件架构设计方法,同时展示了系统开发过程中疑难问题的解决方案。

本书也是一本C和C二进制文件方面的软件工程指南,涵盖中级和专家级程序员所需的各方面内容和信息。

目录

  • 版权信息
  • The Translator's Words 译者序
  • 前言 Preface
  • Chapter 1 第1章 多任务操作系统基础
  • 1.1 一些有用的抽象概念
  • 1.2 存储器层次结构与缓存策略
  • 1.3 虚拟内存
  • 1.4 虚拟地址
  • 1.5 进程的内存划分方案
  • 1.6 二进制文件、编译器、链接器与装载器的作用
  • 1.7 小结
  • Chapter 2 第2章 程序生命周期阶段基础
  • 2.1 基本假设
  • 2.2 编写代码
  • 2.3 编译阶段
  • 2.3.1 基本概念
  • 2.3.2 相关概念
  • 2.3.3 编译的各个阶段
  • 2.3.4 目标文件属性
  • 2.3.5 编译过程的局限性
  • 2.4 链接
  • 2.4.1 链接阶段
  • 2.4.2 链接器视角
  • 2.5 可执行文件属性
  • 2.5.1 各种节的类型
  • 2.5.2 各种符号类型
  • Chapter 3 第3章 加载程序执行阶段
  • 3.1 shell的重要性
  • 3.2 内核的作用
  • 3.3 装载器的作用
  • 3.3.1 装载器视角下的二进制文件(节与段)
  • 3.3.2 程序加载阶段
  • 3.4 程序执行入口点
  • 3.4.1 装载器查找入口点
  • 3.4.2 _start()函数的作用
  • 3.4.3 __libc_start_main()函数的作用
  • 3.4.4 栈和调用惯例
  • Chapter 4 第4章 重用概念的作用
  • 4.1 静态库
  • 4.2 动态库
  • 4.2.1 动态库和共享库
  • 4.2.2 动态链接详解
  • 4.2.3 Windows平台中动态链接的特点
  • 4.2.4 动态库的特点
  • 4.2.5 应用程序二进制接口
  • 4.3 静态库和动态库对比
  • 4.3.1 导入选择条件的差异
  • 4.3.2 部署难题
  • 4.4 一些有用的类比
  • 4.5 结论:二进制重用概念所产生的影响
  • Chapter 5 第5章 使用静态库
  • 5.1 创建静态库
  • 5.1.1 创建Linux静态库
  • 5.1.2 创建Windows静态库
  • 5.2 静态库的使用场合
  • 5.3 静态库设计技巧
  • 5.3.1 丢失符号可见性和唯一性的可能性
  • 5.3.2 静态库使用禁忌
  • 5.3.3 静态库链接的具体规则
  • 5.3.4 将静态库转换成动态库
  • 5.3.5 静态库在64位Linux平台上的问题
  • Chapter 6 第6章 动态库的设计:基础篇
  • 6.1 创建动态库
  • 6.1.1 在Linux中创建动态库
  • 6.1.2 在Windows中创建动态库
  • 6.2 设计动态库
  • 6.2.1 设计二进制接口
  • 6.2.2 设计应用程序的二进制接口
  • 6.2.3 控制动态库符号的可见性
  • 6.2.4 完成链接需要满足的条件
  • 6.3 动态链接模式
  • 6.3.1 加载时动态链接
  • 6.3.2 运行时动态链接
  • 6.3.3 比较两种动态链接模式
  • Chapter 7 第7章 定位库文件
  • 7.1 典型用例场景
  • 7.1.1 开发用例场景
  • 7.1.2 用户运行时用例场景
  • 7.2 构建过程中库文件的定位规则
  • 7.2.1 Linux构建过程中的库文件定位规则
  • 7.2.2 Windows构建过程中的库文件定位规则
  • 7.3 运行时动态库文件的定位规则
  • 7.3.1 Linux运行时动态库文件的定位规则
  • 7.3.2 Windows运行时动态库文件的定位规则
  • 7.4 示例:Linux构建时与运行时的库文件定位
  • Chapter 8 第8章 动态库的设计:进阶篇
  • 8.1 解析内存地址的必要性
  • 8.2 引用解析中的常见问题
  • 8.3 地址转换引发的问题
  • 8.3.1 情景1:客户二进制文件需要知道动态库符号地址
  • 8.3.2 情景2:被装载的库不需要知道其自身符号地址
  • 8.4 链接器-装载器协作
  • 8.4.1 总体策略
  • 8.4.2 具体技术
  • 8.4.3 链接器重定位提示概述
  • 8.5 链接器-装载器协作实现技术
  • 8.5.1 装载时重定位
  • 8.5.2 位置无关代码
  • Chapter 9 第9章 动态链接时的重复符号处理
  • 9.1 重复符号的定义
  • 9.2 重复符号的默认处理
  • 9.3 在动态库链接过程中处理重复符号
  • 9.3.1 处理重复符号问题的一般策略
  • 9.3.2 链接器解析动态库重复符号的模糊算法准则
  • 9.4 特定重复名称案例分析
  • 9.4.1 案例1:客户二进制文件符号与动态库ABI函数冲突
  • 9.4.2 案例2:不同动态库的ABI符号冲突
  • 9.4.3 案例3:动态库ABI符号和另一个动态库局部符号冲突
  • 9.4.4 案例4:两个未导出的动态库符号冲突
  • 9.5 小提示:链接并不提供任何类型的命名空间继承
  • Chapter 10 第10章 动态库的版本控制
  • 10.1 主次版本号与向后兼容性
  • 10.1.1 主版本号变更
  • 10.1.2 次版本号变更
  • 10.1.3 修订版本号
  • 10.2 Linux动态库版本控制方案
  • 10.2.1 基于soname的版本控制方案
  • 10.2.2 基于符号的版本控制方案
  • 10.3 Windows动态库版本控制
  • 10.3.1 DLL版本信息
  • 10.3.2 指定DLL版本信息
  • 10.3.3 查询并获取DLL版本信息
  • Chapter 11 第11章 动态库:其他主题
  • 11.1 插件
  • 11.1.1 导出规则
  • 11.1.2 一些流行的插件架构
  • 11.2 提示和技巧
  • 11.2.1 使用动态库的实际意义
  • 11.2.2 其他主题
  • Chapter 12 第12章 Linux工具集
  • 12.1 快速查看工具
  • 12.1.1 file实用程序
  • 12.1.2 size实用程序
  • 12.2 详细信息分析工具
  • 12.2.1 ldd
  • 12.2.2 nm
  • 12.2.3 objdump
  • 12.2.4 readelf
  • 12.3 部署阶段工具
  • 12.3.1 chrpath
  • 12.3.2 patchelf
  • 12.3.3 strip
  • 12.3.4 ldconfig
  • 12.4 运行时分析工具
  • 12.4.1 strace
  • 12.4.2 addr2line
  • 12.4.3 gdb
  • 12.5 静态库工具
  • Chapter 13 第13章 平台实践
  • 13.1 链接过程调试
  • 13.2 确定二进制文件类型
  • 13.3 确定二进制文件入口点
  • 13.3.1 获取可执行文件入口点
  • 13.3.2 获取动态库入口点
  • 13.4 列出符号信息
  • 13.5 查看节的信息
  • 13.5.1 列出所有节的信息
  • 13.5.2 查看节的信息
  • 13.6 查看段的信息
  • 13.7 反汇编代码
  • 13.7.1 反汇编二进制文件
  • 13.7.2 反汇编正在运行的进程
  • 13.8 判断是否为调试构建
  • 13.9 查看加载时依赖项
  • 13.10 查看装载器可以找到的库文件
  • 13.11 查看运行时动态链接的库文件
  • 13.11.1 strace实用程序
  • 13.11.2 LD_DEBUG环境变量
  • 13.11.3 /proc/<PID>/maps文件
  • 13.11.4 lsof实用程序
  • 13.11.5 通过编程方式查看
  • 13.12 创建和维护静态库
  • Chapter 14 第14章 Windows工具集
  • 14.1 库管理器lib.exe
  • 14.1.1 使用lib.exe处理静态库
  • 14.1.2 使用lib.exe处理动态库
  • 14.2 dumpbin实用程序
  • 14.2.1 确定二进制文件类型
  • 14.2.2 查看DLL的导出符号
  • 14.2.3 查看节的信息
  • 14.2.4 反汇编代码
  • 14.2.5 确定是否使用了调试模式构建
  • 14.2.6 查看加载时依赖项
  • 14.3 Dependency Walker工具
展开全部

评分及书评

评分不足
2个评分
  • 用户头像
    给这本书评了
    5.0
    解释清楚了动态库的链接、加载与运行时的一些机制

    在多个进程共用同一个库时,一般会将该库链接成动态库,节省磁盘空间。运行时,再将该库映射到各进程的内存空间。看起来很合理,没毛病,但是,再细想一下问题就来了:1. 链接动态库时,函数的地址是从 0 开始的,装载到进程空间后,地址需要变更为实际装载的地址,这个动作是在哪里完成的?2. 如果是在装载时,由装载器修改了代码段中的地址,可以解决单进程的问题。多个进程要复用该动态库,不就做不到了么?3. 解决办法:引入位置无关代码(pic) 的思想,讲导出函数做成函数指针,不同进程修改少量的几个函数指针值就可以了下一个问题,函数命名冲突。不同动态库可能存在相同的函数签名,链接,运行也可能不报错,但是执行结果不是预期中的原因:如果存在命名冲突,动态库加载会按一定的优先级来决定采用哪一个实现,带来的副作用就是未被选中的实现,不知道自己被忽略了解决方法:采用命名空间,从源头上解决命名冲突问题再下一个问题,动态库的版本更新,如何保证使用新老版本的两个程序都能正常工作?基本思想:1. 约定主版本(api 有修改)、次版本(api 有新增)、修订版本(api 无变化)的更新原则 2. 链接动态库时,通过版本控制脚本来设置不同版本动态库对外可见哪些 api3. 链接可执行文件时,写入链接时的动态库的主、次版本 4. 运行时,不同进程看到的动态库就不一样了

      转发
      评论

    出版方

    机械工业出版社

    机械工业出版社是全国优秀出版社,自1952年成立以来,坚持为科技、为教育服务,以向行业、向学校提供优质、权威的精神产品为宗旨,以“服务社会和人民群众需求,传播社会主义先进文化”为己任,产业结构不断完善,已由传统的图书出版向着图书、期刊、电子出版物、音像制品、电子商务一体化延伸,现已发展为多领域、多学科的大型综合性出版社,涉及机械、电工电子、汽车、计算机、经济管理、建筑、ELT、科普以及教材、教辅等领域。