存档

文章标签 ‘elf’

坑爹的COFF格式

2011年8月4日 没有评论

最近在研究 TI 的 DSP, 有一件很坑爹的事情令我很恼火. 研究过 TI DSP 的人都知道, TI DSP 的开发主要分为三个部分, 一个是纯算法的开发, 一个是把算法整合成 DSP 可以执行, 并且可以和 ARM 的可执行文件通行的文件的开发, 最后一个是 ARM 程序的开发. 其中对于使用 TI DSP 的厂商来说, 他们开发的重点是 ARM 程序的开发, 对于第一和第二, 则由数量众多的第三方厂商来提供支持. 并且第一个(算法)一般是闭源的算法库.

坑爹的事情是这样的, 公司现在在基于 TI 最新的 DSP C674 系列的开发. 技术部门向 TI 申请到了一个 G.729 的编解码库. 我拿过来一看文件名后缀是 .a64P的, 明显是 C64 系列格式的 编解码库. 让公司的技术人员和他们交涉, 申请符合 C674 的 编解码库. TI 中国的分公司的工程师是这样说的, 674 和 64 系列的软件完全兼容.

好吧, 既然得到这样的答复, 我只好建立在相信对方的基础上去工作了. 对方提供的 Codec Engine的编译方式编译不过(TI 提供的 SDK叫EZSDK, 搞得人模鬼样的SDK, 用我最讨厌的javascript, java等等, 好像还有 cpp, 来自动生成代码), 于是我在花了几周的时间去了解底层 SDK 实现的细节. 直到把所有这些编译方式翻译成我所熟悉的 GNU Makefile + GCC的方式以后, 才发现, 对方给的库有问题, 用 EZSDK 根本编译不过, 然后看了一下编解码库的 readme 的时间(2008年), 再比较了一下 EZSDK 的发行时间(2011年6月). 心马上亮了半截. 然后去 TI的论坛 上去搜索 EZSDK 问题. 果然那边一堆骂娘的, 最后 TI 的工程师给了一句. 最新的 SDK(也就是 EZSDK)不支持 COFF 格式, 只支持 ELF格式, 而原来的SDK(DVSDK, 好吧我疯了)编译的库几乎都是 COFF 格式的, 包括我们申请到的 G.729 库. 我把 TI 的论坛上的答复发给了 TI 中国的工程师以后, 对方莫名其妙的给了我一句, 这个库不支持你们的平台, 新的库我们正在找人编译, 不要浪费时间在这个库上.

我 ……

下面是我这几天在 google 上找到的关于可执行文件格式的简单介绍:

a.out

UNIX 上最早的可执行文件格式, 特点是格式简单, 比较难实现共享库. 目前几乎被抛弃了.

COFF

COFF 比 a.out 是一种进步, 他在 a.out 的基础上增加了一个节段表, 比 a.out 更灵活. 但是默认情况下对动态连接和C++程序的支持仍然比较困难, 所以不同的操作系统做了不同的扩展, 比如 Microsoft 设计了名为 PE (Portable Executable) 的文件格式, 在 COFF 文件头部之上增加了一些专用头部.

ELF

这是现在 Linux 使用的文件格式, 一般我们用 file 指令查看一个可执行文件格式(比如 /bin/ls)的时候, 会有这样的信息:

# file `which ls`
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped

说明 ls 是一个 ELF 格式的可执行文件.

简单来说, ELF 格式更好的支持动态链接技术. 具有一下特点:

  • 链接库是内存位置无关的. 可以把动态库加载到内存的任何位置都没有影响. a.out 是内存地址有关的, 必须加载到相应的内存地址才行.
  • 动态加载. 比如一个程序需要用到某个动态库, 在没有调用到这个动态库的函数, 是不会把这个动态库加载到程序中的(也就是内存映射).
  • 动态解析. 要调用的函数被调用的时候, 才会去把这个函数在虚拟内存空间的起始地址解析出来, 再写到专门在调用模块中的储存地址内, 有点像 linux 的 COW(copy on write).

分类: dsp, linux 标签: , ,