我看到了/ Gy选项,我想知道为什么要使用它?http://msdn.microsoft.com/en-us/library/xsa71f43.aspx
是否可以在UNIX上运行COFF可执行文件或在Windows上运行ELF可执行文件?在Windows和UNIX上运行任一文件类型的步骤是什么?我只是好奇.
通过查看问题标题不要误解我 - 我知道它们是什么(可移植可执行文件的格式).但我的兴趣范围略有不同
我的困惑
我参与了重新托管/重新定位最初来自第三方的应用程序.问题是,有时目标代码的格式也是.elf,.COFF格式,仍然说"可执行和可链接".
我主要是Windows用户,并且知道在编译和汇编C/C++代码时,会得到类似于.o或.obj的东西.这是不可执行的(好吧,我从来没有尝试过执行它们).但是,当您完成链接静态和动态库并完成构建时,将显示可执行文件.我的理解是,您可以继续并链接该可执行文件,或者在必要时使用某种形式的脚本"bash"测试它.
但是,在Linux(或类UNIX系统)中,在编译和汇编C/C++代码之后会有.o文件.一旦链接完成,可执行文件就是a.out格式(至少在Linux的Ubuntu发行版中).在其他一些分销商中很可能是.elf.在我的快速网络搜索中,没有任何消息来源提到任何关于.o文件作为可执行文件.
质询
因此我的问题变成了以下几点:
可移植可执行文件和目标代码的真正定义是什么?
Windows和UNIX平台如何涵盖相同文件格式(.COFF,.elf)下的可执行文件和目标代码.
我误解了"可链接"吗?我对"可链接"的解释是编译目标代码,然后可以"链接"到其他静态/动态链接库.这是一个愚蠢的想法吗?
根据问题1.(可能还有2个)我是否需要使用符号表(例如.LUM或.MAP文件)和目标代码?调试符号中的符号,并在重新托管不同计算机上的可执行文件/目标文件时使用它们.
在此先感谢正确的推动.同时,如有必要,我会继续挖掘和更新问题.
UPDATE
我已经设法从某个地方挖出这个 :(似乎很多东西要吞下我.
最近我一直在维护一个用VC++ 6.0编写的遗留项目.代码使用了这个编译器的许多独特特性,将它移植到更新的标准编译器已被证明是一项艰巨的任务.
在项目的数千行代码中,有四个汇编程序文件.由于某种原因,我不明白,MASM615和TASM也无法编译它们(它们发送错误),但我有目标文件.但是,当我链接库时,我收到一条消息
警告LNK4033:将对象格式从OMF转换为COFF
该库按预期工作,但我一直想知道这些二进制格式之间的差异是什么,或者我是否应该期望这种转换有些丑陋.
我只知道2:
我的意思是可以在Win32和Linux i386中运行单个二进制文件吗?
我正在尝试生成16位DOS可执行文件,但使用gcc编译器.所以我使用古老的gcc-4.3 ia16端口.我制作了我的构建的Docker镜像:https://registry.hub.docker.com/u/ysangkok/ia16-gcc-rask
这是我正在尝试的:
host $ mkdir results
host $ docker run -v $PWD/results:/results -it ysangkok/ia16-gcc-rask
container $ cd results
Run Code Online (Sandbox Code Playgroud)
我没有包含头文件,导致gcc无法使用OpenWatcom的libc头文件.
container $ echo 'main() { printf("lol"); }' > test.c
Run Code Online (Sandbox Code Playgroud)
我没有链接因为我没有16位binutils可用.如果我构建一个目标文件,它没有正确标记为16位.
container $ /trunk/build-ia16-master/prefix/bin/ia16-unknown-elf-gcc -S test.c
Run Code Online (Sandbox Code Playgroud)
现在我有这个汇编文件:
.arch i8086,jumps
.code16
.att_syntax prefix
#NO_APP
.section .rodata
.LC0:
.string "lol"
.text
.p2align 1
.global main
.type main, @function
main:
pushw %bp
movw %sp, %bp
subw $4, %sp
call __main
movw $.LC0, %ax
pushw %ax
call printf
addw $2, %sp
movw …Run Code Online (Sandbox Code Playgroud) 我有一个使用microsoft visual studio生成的地图文件.它包含一个名为__NULL_IMPORT_DESCRIPTOR的相对较大的区域.这有什么用?它与链接的dll有关,但我无法弄清楚它的确切目的.
这是我偶尔遇到的情况:
对于不使用虚拟寻址的嵌入式系统,我有一个可执行文件,它是用C或C++代码编译的,包含调试信息.它通常在COFF或ELF/DWARF(我得到那两个混合)格式.
在运行时,在PC上,我想确定给定名称的变量的地址.(例如"foo.bar [7] .baz")这允许我在嵌入式系统上读/写变量的值(给定一个超出本问题范围的调试协议).显然,任何基于堆栈或基于堆的变量都没有,因为它们没有静态地址.
我之前在C++中已经完成了这项工作,用于解析TI编译器为其2800系列DSP编写的COFF文件,这有点痛苦.我想知道是否有一个Java库已经做了这种事情,因为我面对着一个或两个其他处理器的可执行文件.
更新:(11/18/2009)一个有希望的线索!
有没有人使用Eclipse CDT ELF解析器?
(见http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.cdt.doc.isv/reference/api/org/eclipse/cdt/core/model/IBinary.html一的javadoc pgs)
TI的Code Composer 4(基于Eclipse)似乎使用了这个,所以似乎我可以弄清楚文档的位置,也许我可以用它来解决我的问题.
在创建最终图像之前,链接器在解析目标文件中的重定位时会采取哪些步骤?更具体地说,链接器如何处理已经存储在重定位站点的值?它总是将它添加到最终的VA/RVA中,还是有时会被忽略(例如某些重定位类型)?
我在MS PE/COFF Specfication中找不到清晰的解释,经过谷歌搜索和实验一段时间后,我所能发现的是:
您能否指出我的任何(相关)文档,它解释了链接器如何处理重定位?