У меня есть функция original_fun
, определенная в одном файле (original_fun.c
), и мне нужно сослаться на нее как global_alias
в файле use_alias.c
. Я попытался следующие:Как установить символ .globl в GAS?
# set_alias.s
.globl global_alias
.set global_alias, original_fun
// original_fun.c
#include <stdio.h>
void original_fun(int x)
{
printf("original_fun(%d)\n", x);
}
// use_alias.c
extern void global_alias(int x);
int main()
{
global_alias(42);
return 0;
}
Но символ global_alias
не экспортируется:
$ as set_alias.s -o set_alias.o
$ clang original_fun.c -c -o original_fun.o
$ clang use_alias.c -c -o use_alias.o
$ clang set_alias.o original_fun.o use_alias.o -o result
use_alias.o: In function `main':
use_alias.c:(.text+0x1d): undefined reference to `global_alias'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
И objdump
отчеты:
$ objdump -rt set_alias.o
set_alias.o: file format elf32-i386
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 *UND* 00000000 original_fun
(Движущей примером является то, что original_fun
это имя подогнаны C++ , и я хотел бы экспортировать его под более чистым именем, чтобы его можно было легко использовать с ассемблера.)
ГАЗА руководство (https://sourceware.org/binutils/docs/as/Set.html) говорится следующее:
Если вы .set глобальный символ, значение, хранящееся в файле объекта последнее значение, сохраненное в него.
Это может быть связано с моей проблемой, но я не уверен, что правильно понимаю это.
Мой ответ: используйте «extern» C «или переосмыслите свой дизайн. Зачем вам нужно вызвать функцию из сборки? Не будет ли перегрузка решить проблему? Является ли это единственной перегрузкой, которая будет объявлена 'extern 'C"?? Не могли бы вы использовать функцию ввода, которая объявлена 'extern 'C"?? Если для функции требуются данные, которые вы генерируете с помощью сборки, почему это не в автономной процедуре сборки, которая может быть вызвана из 'original_fun', а не наоборот, как вы пытаетесь сделать? –
Мне нужно вызвать функции (и обратиться к константам) из сборки, потому что ассемблер выводится из компилятора, а C++ - это язык библиотеки времени выполнения. Имена функций искажаются, даже если нет перегрузки, поскольку компилятор никогда не может быть уверен, что больше не будет перегрузок позже или в другом файле. –