什么是.seh_ * gcc输出的汇编命令?

时间:2013-12-28 22:12:31

标签: gcc assembly x86-64

我使用gcc -S作为hello world程序。什么是5 .seh_命令?当我搜索时,我似乎无法找到关于它们的更多信息。

    .file   "hi.c"
    .def    __main; .scl    2;  .type   32; .endef
    .section .rdata,"dr"
.LC0:
    .ascii "Hello World\0"
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc 32
    .seh_endprologue
    call    __main
    leaq    .LC0(%rip), %rcx
    call    puts
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (rubenvb-4.8.0) 4.8.0"
    .def    puts;   .scl    2;  .type   32; .endef

3 个答案:

答案 0 :(得分:8)

这些是gas对MASM frame handling pseudos的实施,用于生成可执行文件的.pdata和.xdata部分(结构化异常处理内容)。另请查看Raw Pseudo Operations。显然,如果您的代码在SEH展开操作期间可能在堆栈中,您应该使用这些代码。

我在https://sourceware.org/ml/binutils/2009-08/msg00193.html找到了略微的更多信息。此线程似乎是gas的原始签到,以添加对所有.set_ *伪操作的支持。

  

我想展示.pdata和.xdata生成的补丁   pe-coff通过天然气进行目标,并获得一些反馈。这个补丁   包括对arm,ppc,arm,sh(3& 4),mips和x64的支持。至于   x86没有操作系统支持运行时功能信息,我幸免   这部分。它只会增加x86 PE的可执行文件大小   这个目标并没有真正的好处。

     

简短概述:
  目前有三种不同的功能输入格式预设。

     

第一个是MIPS版。第二个版本适用于ARM,PPC,SH3,   和SH4主要用于Windows CE。第三个是IA64和x64版本。   注意,IA64尚未实现,但要查找有关的信息   请参阅关于IA64的规格   http://download.intel.com/design/Itanium/Downloads/245358.pdf档案。

     

第一个版本只包含pdata部分中的条目:BeginAddress,   EndAddress,ExceptionHandler,HandlerData和PrologueEndAddress。   每个值都是指向相应数据的指针,大小为4   字节。

     

第二个变体在pdata部分中包含以下条目。   BeginAddress,PrologueLength(8位),EndAddress(22位),   使用-32位指令(1位)和Exception-Handler-Exists(1位)。   如果FunctionLength为零,或者Exception-Handler-Exists位为   如果是,则在函数输入之前直接放置DATA_EH块。

     

第三个版本有一个BeginAddress(RVA)的函数入口块,   EndAddress(RVA)和UnwindData(RVA)。的描述   prologue,excepetion-handler和其他SEH数据存储在其中   xdata部分中的UNWIND_DATA字段。

     

.seh_proc< fct_name>
  这指定SEH块开始用于函数< fct_name>。这对所有人都有效   目标

     

<强> .seh_endprologue
  通过这个伪的序言结束地址的位置(由当前代码地址的外观采取   这个伪)。适用于所有目标。

     

.seh_handler&lt; handler&gt; [,&lt; handler-data&gt;]
  此伪指定要使用的处理函数。对于版本2   handler-data字段指定用户可选数据块。对于版本   3 handler-data字段可以是rva到用户数据(对于FHANDLER),如果   名称是@unwind,生成UHANDLER展开块,如果是的话   是@except(或根本没有指定)EHANDLER异常块是   生成。

     

<强> .seh_eh
  此伪用于版本2以指示函数在汇编中开始的位置。这里的PDATA_EH数据是   可以存储到。

     

<强> .seh_32 / .seh_no32
  这个伪仅用于版本2(参见上面的描述)。目前它默认为no32,如果没有   指定。

     

<强> .seh_endproc
  通过这个伪指定SEH块的末尾。

     

.seh_setframe&lt; reg&gt;,&lt; offset&gt;
  通过这个伪帧的寄存器和偏移量(0-240之间的值与16字节   对齐)可以指定。这只是版本3使用。

     

.seh_stackalloc&lt; size&gt;
  通过这种方式,代码中的堆栈分配是针对版本3进行描述的。

     

.seh_pushreg&lt; reg&gt;
  通过这种方式,对于版本3描述了通用寄存器推入代码。

     

.seh_savereg&lt; reg&gt;
  通过这种方式,在版本3中描述了代码中的通用寄存器保存到存储器。

     

.seh_savemm&lt; mm&gt;
  通过这种方式,版本3中描述了代码中的mm寄存器保存到存储器。

     

<强> .seh_savexmm
  通过这个,在版本3中描述了代码中的xmm寄存器保存到存储器。

     

<强> .seh_pushframe
  有关条目类型的信息可以在版本3中进行描述。

     

.seh_scope&lt; begin&gt;,&lt; end&gt;,&lt; handler&gt;,&lt; jump&gt;
  通过此SCOPED条目可以指定展开或异常   版本3.这对UHANDLE和EHANDLER xdata有效   必须指定描述符和全局处理程序。对于处理程序和   可以使用跳转参数,@ 1,@ 0和@null的名称,它们是   指定必须使用常量而不是rva。

https://sourceware.org/ml/binutils/2009-04/msg00181.html还有一些关于.xdata和.pdata(以及一堆链接)的核心讨论。

答案 1 :(得分:5)

我使用以下方法阻止他们输出:

gcc -S -fno-asynchronous-unwind-tables hi.c

所以我可以看一下。但我很高兴再也没有让它们输出了。

答案 2 :(得分:2)

它们似乎与异常处理有关。这就是我能找到的全部。

http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/external/gpl3/binutils/dist/gas/config/obj-coff-seh.h