怎样才能去除可执行文件中的.eh_frame数据?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq446252221/article/details/80962143

用mingw gcc各个版本编译出来的exe文件,都比VS编译的大一点。

分析文件发现是每个exe文件都包含一个叫作".eh_frame"的节,然而却没有找到去除这个数据节的办法!!!

测试方法:

编译一个空的main.c文件,如下内容:

#include <stdio.h>
void main(void)
{
    printf("hello\n");
}

1.使用命令#gcc main.c 得到a.exe,这时包含调试信息,再用#strip a.exe去除调试信息。

发现a.exe里面也有.eh_frame章节。

2.使用命令#gcc -s main.c得到a.exe

这时a.exe还有是.eh_fram章节,注意与上面的a.exe有区别。

3.使用strip -R .eh_frame 强制去除这个数据节,结果程序不能正常运行了。


网上找了半天资料,试过加上如下各种参数:

-fno-exceptions

-fno-unwind-tables

-fno-asynchronous-unwind-tables

依然没能解决问题。

----------------------------------------------------------------

24小时后......

终于找到原因了,换了另外一个版本的gcc,编译出来的a.exe竟然没有.eh_frame段,而且体积会小2KB.

经过比较区别就是这个版本的gcc没有使用dwarf的异常模型!

使用gcc -v查看GCC的版本,会提示这个GCC的configure,如果带有--with-dwarf则说明是支持dwarf异常。

还记得Mingw-W64下载GCC的时候会选择线程模型(win32/posix)和异常模型(sjlj/dwarf)吗?

下载sjls异常的GCC编译出来的exe就没有.eh_frame!!!

之所以有这两种区别都是C++的事,只是没想到会影响我这个纯C开发者。


25小时后............

事情好像不是我想像中的那样,似乎与异常模型没有关系???

因为我交换了两个版本GCC自带的win32 library之后,原本出现.eh_frame的GCC竟然没有出现!

进一步研究,好像是CRT库搞的鬼。具体就是crt1.o和crt2.o这两个文件!

使用ojbdump查看crt1.o,这是自带.eh_frame的那个版本:

$../bin/objdump.exe -h crt1.o

crt1.o:     file format pe-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000500  00000000  00000000  00000294  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000004  00000000  00000000  00000794  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000001c  00000000  00000000  00000000  2**2
                  ALLOC
  3 .text.unlikely 00000000  00000000  00000000  00000000  2**2
                  ALLOC, LOAD, READONLY, CODE
  4 .CRT$XCAA     00000004  00000000  00000000  00000798  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  5 .CRT$XIAA     00000004  00000000  00000000  0000079c  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  6 .drectve      00000054  00000000  00000000  000007a0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .debug_info   00002203  00000000  00000000  000007f4  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  8 .debug_abbrev 00000441  00000000  00000000  000029f7  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_loc    000002e3  00000000  00000000  00002e38  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
 10 .debug_aranges 00000020  00000000  00000000  0000311b  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
 11 .debug_ranges 00000088  00000000  00000000  0000313b  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_line   0000031c  00000000  00000000  000031c3  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
 13 .debug_str    000002f0  00000000  00000000  000034df  2**0
                  CONTENTS, READONLY, DEBUGGING
 14 .rdata$zzz    0000002c  00000000  00000000  000037cf  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame     000000c8  00000000  00000000  000037fb  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

下面是不带.eh_frame的版本

$../bin/objdump.exe -h crt1.o

crt1.o:     file format pe-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000500  00000000  00000000  0000026c  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000004  00000000  00000000  0000076c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000020  00000000  00000000  00000000  2**2
                  ALLOC
  3 .CRT$XCAA     00000004  00000000  00000000  00000770  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  4 .CRT$XIAA     00000004  00000000  00000000  00000774  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  5 .drectve      00000054  00000000  00000000  00000778  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  6 .debug_info   000023b4  00000000  00000000  000007cc  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  7 .debug_abbrev 0000046f  00000000  00000000  00002b80  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_loc    000002e3  00000000  00000000  00002fef  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  9 .debug_aranges 00000020  00000000  00000000  000032d2  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
 10 .debug_ranges 00000088  00000000  00000000  000032f2  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   00000361  00000000  00000000  0000337a  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
 12 .debug_str    00000235  00000000  00000000  000036db  2**0
                  CONTENTS, READONLY, DEBUGGING
 13 .rdata$zzz    00000014  00000000  00000000  00003910  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .debug_frame  000000c0  00000000  00000000  00003924  2**2
                  CONTENTS, RELOC, READONLY, DEBUGGING

可以看出来,那个去不掉的.eh_frame竟然来自crt,暂时不知道如何生成这种版本的crt.o,待研究。。。

顺便记录一下,在这期间用到了几个有用的编译选项:

--pipe 不创建临时文件,加快编译速度
-s 编译后自动执行strip
-Os 优化目标文件体积
-fomit-frame-pointer
-march=i686
-Wl,--xxxx 设置链接参数

猜你喜欢

转载自blog.csdn.net/qq446252221/article/details/80962143