Как мне найти код сборки для моей функции в (выпускной) сборке Rust? - PullRequest
0 голосов
/ 25 мая 2020

Compiler Explorer кажется, может надежно найти ассемблерный код, соответствующий функции. Как я могу сделать это сам, предполагая набор инструментов x86_64-unknown-linux-gnu, обычную (без атрибутов) функцию и без дополнительных инструментов, таких как cargo-asm?

Я знаю, что для создания сборки я могу использовать ржавчина c s --emit asm флаг . Кто-то может подумать, что найти функцию так же просто, как найти ее имя в файле .s, но я обнаружил, что это не так.

Например, файл .s часто даже не упоминает имя функции, в этом случае помогает добавление #[inline(never)] к функции. Во-вторых, как определить, где заканчивается функция, найдя метку с именем функции? В моем тестовом ящике я обнаружил второе упоминание имени функции в директиве .size ниже - может быть, это означает конец функции? Или это может быть первая retq после запуска функции?

Если эта цель достижима, я надеюсь узнать:

  • Каковы наиболее надежные способы найти начало и конец функции?
  • Каковы предварительные условия для получения подходящих файлов сборки для этого?

1 Ответ

1 голос
/ 03 июня 2020

Поскольку ответа не было, я провел небольшое исследование, и это должно помочь:

  1. Убедитесь, что функция используется main() в случае бинарного ящика, или функцией pub в случае контейнера библиотеки (или самим pub).
  2. Чтобы компилятор не встраивал ваш тест, отметьте его #[inline(never)]
  3. Поиск функции имя, которое должно найти начало, которое выглядит так:
    .type   <mangled_name>,@function
<mangled_name>:
    .cfi_startproc
Найдите конец функции, который отмечен:
.Lfunc_end<number>:
    .size   <mangled_name>, .Lfunc_end<number>-<mangled_name>
    .cfi_endproc

Иногда ему может предшествовать retq, но ненадежно.

Те Строки, которые начинаются с точки и заканчиваются не двоеточием, например .type, являются директивами. Директивы, которые понимает ассемблер GNU, задокументированы здесь , и вывод --emit asm должен быть допустимым вводом для ассемблера GNU.

Compiler Explorer и cargo-asm

Кажется, что Compiler Explorer фактически хранит весь файл и не ищет функции, он просто отфильтровывает определенные строки. По крайней мере, это то, что, по-видимому, делает исходный код .

cargo-asm, по-видимому, специально ищет .cfi_endproc на Linux и Ma c, и .seh_endproc на Windows.

...