Какие команды сборки.seh_* выводит gcc?

Я использую 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 ответа

Решение

Это gasРеализация псевдообработки MASM для создания фреймов для секций.pdata и.xdata исполняемого файла (структурированная среда обработки исключений). Также проверьте Сырые Псевдо Операции. Очевидно, если ваш код может быть в стеке во время операции размотки 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 бита), Use-32-bit-инструкция (1 бит) и Exception-Handler-Exists (1 бит). Если значение FunctionLength равно нулю или бит Exception-Handler-Exists имеет значение true, блок DATA_EH помещается непосредственно перед вводом функции.

Третья версия имеет функциональный блок ввода BeginAddress (RVA), EndAddress (RVA) и UnwindData (RVA). Описание пролога, обработчика исключений и дополнительных данных SEH хранится в поле UNWIND_DATA в разделе xdata.

.seh_proc <имя_файла>
Это указывает, что блок SEH начинается для функции . Это верно для всех целей.

.seh_endprologue
Посредством этого псевдо-местоположения конечного адреса пролога (берется по текущему кодовому адресу появления этого псевдо-адреса). Действительно для всех целей.

.seh_handler <обработчик>[,<данные обработчика>]
Это псевдо указывает функцию-обработчик, которая будет использоваться. Для версии 2 поле данных обработчика указывает необязательный пользовательский блок данных. Для версии 3 поле данных обработчика может быть rva to user-data (для FHANDLER), если имя @unwind, генерируется блок размотки UHANDLER, и если это @except (или не указан вообще), блок исключений EHANDLER генерируется.

.seh_eh
Это псевдо используется для версии 2, чтобы указать расположение функции начала сборки. Здесь данные PDATA_EH могут быть сохранены в.

.seh_32 /.seh_no32
Эти псевдо только используются для версии 2 (см. Описание выше). На данный момент это значение по умолчанию no32, если не указано.

.seh_endproc
Этим псевдо указывается конец блока SEH.

.seh_setframe ,
Этим псевдо-регистром кадров и смещением (значение от 0 до 240 с 16-байтовым выравниванием) можно указать. Это просто используется в версии 3.

.seh_stackalloc <размер>
При этом выделение стека в коде описано для версии 3.

.seh_pushreg
Этим описывается общий ввод регистра в коде для версии 3.

.seh_savereg
Этим описывается общий регистр сохранения в памяти в коде для версии 3.

.seh_savemm <мм>
Этим регистр мм, сохраняемый в памяти в коде, описан для версии 3.

.seh_savexmm
Этим описывается сохранение регистра xmm в памяти в коде для версии 3.

.seh_pushframe
Этим информация о виде записи может быть описана для версии 3.

.seh_scope ,,,
Этим SCOPED могут быть указаны записи для размотки или исключения для версии 3. Это справедливо только для дескриптора xdata UHANDLE и EHANDLER, и должен быть указан глобальный обработчик. Для аргументов обработчика и перехода можно использовать имена @1,@0 и @null, и они указывают, что вместо rva должна использоваться константа.

Кроме того, по адресу https://sourceware.org/ml/binutils/2009-04/msg00181.html ведется обсуждение некоторых проблем.xdata и.pdata (вместе с кучей ссылок).

Я остановил их вывод с помощью:

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

так что я могу посмотреть это. Но я счастлив от того, что их больше не выводят.

Кажется, они связаны с обработкой исключений. Это все, что я мог найти.

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

Другие вопросы по тегам