Как определить локальную статическую переменную в функции, не являющейся членом, с помощью dwarf

Я пытаюсь использовать dwarf для сравнения двух файлов C ++, но у меня возникают проблемы, когда я получаю локальные переменные в функциях, не являющихся членами. Рассмотрим следующий код —

int f(){
[static] int j=0;
return j;
}

Если я скомпилирую без static модификатор я получаю следующую информацию о гномах —

 <1><eb>: Abbrev Number: 13 (DW_TAG_subprogram)
<ec>   DW_AT_external    : 1
<ed>   DW_AT_name        : f
<ef>   DW_AT_decl_file   : 1
<f0>   DW_AT_decl_line   : 15
<f1>   DW_AT_MIPS_linkage_name: (indirect string, offset: 0x22): _Z1fv
<f5>   DW_AT_type        : <0xa8>
<f9>   DW_AT_low_pc      : 0x0
<101>   DW_AT_high_pc     : 0x10
<109>   DW_AT_frame_base  : 0x0     (location list)
<10d>   DW_AT_sibling     : <0x130>
<2><111>: Abbrev Number: 14 (DW_TAG_lexical_block)
<112>   DW_AT_low_pc      : 0x4
<11a>   DW_AT_high_pc     : 0xe
<3><122>: Abbrev Number: 15 (DW_TAG_variable)
<123>   DW_AT_name        : j
<125>   DW_AT_decl_file   : 1
<126>   DW_AT_decl_line   : 16
<127>   DW_AT_type        : <0xa8>
<12b>   DW_AT_location    : 2 byte block: 91 6c     (DW_OP_fbreg: -20)

но если я скомпилирую с static модификатор я получаю —

 <1><eb>: Abbrev Number: 13 (DW_TAG_subprogram)
<ec>   DW_AT_external    : 1
<ed>   DW_AT_name        : f
<ef>   DW_AT_decl_file   : 1
<f0>   DW_AT_decl_line   : 22
<f1>   DW_AT_MIPS_linkage_name: (indirect string, offset: 0x24): _Z1fv
<f5>   DW_AT_type        : <0xa8>
<f9>   DW_AT_low_pc      : 0x0
<101>   DW_AT_high_pc     : 0xc
<109>   DW_AT_frame_base  : 0x0     (location list)
<10d>   DW_AT_sibling     : <0x137>
<2><111>: Abbrev Number: 14 (DW_TAG_lexical_block)
<112>   DW_AT_low_pc      : 0x4
<11a>   DW_AT_high_pc     : 0xa
<3><122>: Abbrev Number: 15 (DW_TAG_variable)
<123>   DW_AT_name        : j
<125>   DW_AT_decl_file   : 1
<126>   DW_AT_decl_line   : 23
<127>   DW_AT_type        : <0xa8>
<12b>   DW_AT_location    : 9 byte block: 3 20 0 0 0 0 0 0 0        (DW_OP_addr: 20)

Теперь, насколько я могу судить, между этими файлами есть только одно реальное различие — размер байтового блока на DW_AT_location атрибуты для переменной j разные (вот почему DW_AT_sibling атрибуты в теге функции f различны, поэтому я не считаю это). Я предполагаю, что это как-то подразумевает статичность, но я не знаю как.

0

Решение

DWARF не пытается описать связь переменной, только ее тип, область действия и способ ее определения. И под «областью действия» я подразумеваю, когда код может видеть / получать доступ к значению, которое означает только в теле f()даже если это статично.

fbreg регистр, который является основой вашего стекового фрейма — чаще всего на x86_64, rbp, Локальные переменные содержатся в стеке внутри стекового фрейма функции (опять же в x86_64, обычно между rbp а также rsp). Стек растет вниз так rbp имеет более высокое значение, чем rsp,

Насколько DW_AT_location для вашего статического значения, равного 20, я предполагаю, что вы сбросили DWARF файла .o до того, как он был связан с исполняемым файлом. Когда это связано с окончательным исполняемым файлом, я ожидаю, что компоновщик обновит это DW_AT_location с фактическим адресом статического — прямо сейчас я держу пари, что это просто заполнитель перемещения.

Обычно отладчики используют имена символов в самом исполняемом файле, чтобы расширить свой список глобальных / статических переменных, потому что пользователи могут захотеть проверить f«s j переменная, даже если f() выходит за рамки Имя статики будет каким-то образом искажено (не обязательно в смысле искажения в C ++) (иначе будет другой функцией). g() который также имел static j будет конфликтовать), поэтому отладчик должен знать, как справиться с этим.

2

Другие решения

Я не эксперт по «DWARF», но я вижу очень четкую разницу между этими строками:

<12b>   DW_AT_location    : 2 byte block: 91 6c     (DW_OP_fbreg: -20)

<12b>   DW_AT_location    : 9 byte block: 3 20 0 0 0 0 0 0 0        (DW_OP_addr: 20)

Один из fbreg: -20 — так «regeister буфера кадра, смещение -20».

Другой, я полагаю, ссылается на абсолютный адрес (32 байта в сегменте DATA, возможно?)

0

По вопросам рекламы [email protected]