为啥 Windows gcc (cygwin) 不写 ELF 标头?

Posted

技术标签:

【中文标题】为啥 Windows gcc (cygwin) 不写 ELF 标头?【英文标题】:Why Windows gcc (cygwin) do not write ELF header?为什么 Windows gcc (cygwin) 不写 ELF 标头? 【发布时间】:2016-09-13 16:44:10 【问题描述】:

在linux机器上,我们编译的时候,比如下面这段代码:

b.cc:

typedef struct sTeste 
    int campo1;
    char campo2;
    int campo3;


 T_TESTE;


void m1(T_TESTE *p) 


使用命令:

gcc -gdwarf-2 -c b.cc -o b.o

我们得到 ELF 标头

root@marceloaleks:~# hd b.o |head 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.......| 00000020 00 00 00 00 00 00 00 00 a8 03 00 00 00 00 00 00 |......| 00000030 00 00 00 00 40 00 00 00 00 00 40 00 14 00 11 00 |....@.....@.....| 00000040 55 48 89 e5 48 89 7d f8 5d c3 00 00 b1 00 00 00 |UH..H..]........| 00000050 02 00 00 00 00 00 08 01 00 00 00 00 04 00 00 00 |......| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......| 00000070 00 00 00 00 00 00 00 00 00 02 00 00 00 00 0c 01 |......| 00000080 01 64 00 00 00 03 00 00 00 00 01 02 64 00 00 00 |.d......d....| 00000090 02 23 00 03 00 00 00 00 01 03 6b 00 00 00 02 23 |.#........k....#|

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|

但是,当我们在 Windows 上执行相同操作时,结果是:

C:\Aleks-IOT\Code\Dev\JAVA\nbdwarfdumplib>xxd b.o |head 00000000: 6486 0d00 0000 0000 ae05 0000 1c00 0000 d....... 00000010:0000 0400 2e74 6578 7400 0000 0000 0000 .....文本...... 00000020: 0000 0000 1000 0000 1c02 0000 0000 0000 ...... 00000030: 0000 0000 0000 0000 2000 5060 2e64 6174 ........ .P`.dat 00000040: 6100 0000 0000 0000 0000 0000 0000 0000 ......

我真正的问题是我只想从一个简单的编译单元(在本例中为 b.cc)提取 dwarf 调试数据。

有什么线索吗?

谢谢

【问题讨论】:

你有 Windows 10 64 位吗?您可以尝试Ubuntu on Windows,它可以让您在 Windows cmd 或 powershell 窗口中构建和运行 ELF 二进制文件。这是预览质量 - 我只使用 apt-get 得到了 BSOD - 但它有效。 我试试 【参考方案1】:

因为 Windows 不使用 ELF。 Windows 使用 PE (https://en.wikipedia.org/wiki/Portable_Executable)。如果您想在 Windows 中使用 ELF,只需获取 GCC 源代码并在 ./configure 阶段使用 elf 目标自行构建它。

但是,您将无法在 Windows 中运行输出。

在 PE 中,调试信息作为符号存储在 COFF 符号表中。您可以通过 Windows API 访问它:

https://msdn.microsoft.com/en-us/library/ms809762.aspx

有很多免费工具可以使用它来查看 PE 文件。例如:https://sourceforge.net/projects/nktspeview/

【讨论】:

是的,但是如果没有生成可执行文件,我无法在 Windows 中获取 dwarf 数据。谢谢你。 dwarfdump 在 Linux 中完美运行!你知道如何为一个来源获得 PE 吗? 我添加了一些细节。您可能想要对 PE 文件查看器进行网络搜索。我不知道哪个最好。我已经很久没有在这个领域工作了。 我不想使用 PE 格式,因为它只存在于 windows 世界中,而且我的应用程序也需要在 Linux 和 MACOS 中运行。但是您谈到了生成 gcc 来获取 elf;这是个好主意,我会试试的。 我认为您需要重新构建应用程序才能在 Linux 和 Mac 上运行。即使它们都是 ELF,系统调用也不兼容。为什么不在 Linux 机器上构建呢?否则,您必须在 Windows 中设置交叉编译工具链,这可以,但是您将无法通过运行它来测试您的应用程序(在 Windows 上)。 gcc 可以选择在单独的文件中输出 dwarf 数据。也许你想这样做。【参考方案2】:

我不知道你使用的是什么版本。在 Linux 中 gcc 可以是: - GCC 标准(编译 C) - GCC-elf (用 Elf 编译 C)

在 Windows 中也是如此,但拥有 Elf 比较困难

【讨论】:

以上是关于为啥 Windows gcc (cygwin) 不写 ELF 标头?的主要内容,如果未能解决你的问题,请参考以下文章

win10下安装Cygwin配置gcc编译环境

在windows配置 cygwin 和 gcc

windows下安装cygwin环境并配置gcc环境

在 Cygwin/GCC C++ 程序中嵌入 Windows Python

Windows 上的 Matlab:将“mex”默认编译器更改为 Cygwin 的 GCC [重复]

cygwin 中如何安装arm-linux-gcc交叉编译器