forked from KolibriOS/kolibrios
ktcc: added __attribute__((dllimport)) support
git-svn-id: svn://kolibrios.org@9782 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
3dddd1c687
commit
db785142be
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Версия расширения KX - 0.4.3
|
Версия расширения KX - 0.4.6
|
||||||
|
|
||||||
Обзор новых возможностей
|
Обзор новых возможностей
|
||||||
|
|
||||||
@ -19,9 +19,10 @@
|
|||||||
|
|
||||||
+ Уменьшенный размер образа
|
+ Уменьшенный размер образа
|
||||||
Поскольку загрузчик библиотек больше не нужно размещать в каждом
|
Поскольку загрузчик библиотек больше не нужно размещать в каждом
|
||||||
приложении, это уменьшает размер образа. Больше не нужен слой C
|
приложении, это уменьшает размер образа. Больше не нужна фукнция вызова
|
||||||
(C layer), все зависимые библиотеки загружаются, а также инициализируются
|
инициализации библиотек в C layer, все зависимые библиотеки загружаются,
|
||||||
автоматически. Также используется компактный формат таблицы импорта.
|
а также инициализируются автоматически. Кроме того используется компактные
|
||||||
|
формат таблицы импорта, а также вызовы функций из динамических библиотек.
|
||||||
|
|
||||||
+ Обратная совместимость
|
+ Обратная совместимость
|
||||||
Если Вы по каким то причинам не хотите, либо пока не готовы использовать
|
Если Вы по каким то причинам не хотите, либо пока не готовы использовать
|
||||||
|
@ -1,3 +1,16 @@
|
|||||||
|
0.4.6
|
||||||
|
+ Добавлена поддержка __attribute__((dllimport))
|
||||||
|
Новый способ вызова импортов дополнительно уменьшает размер приложений
|
||||||
|
+ Добавлена обработка ошибок линкера при неправильном использовании типов
|
||||||
|
вызовов функций импорта, в том числе для сторонних объектных файлов
|
||||||
|
В частности, вызов без префикса __attribute__((dllimport)) перед
|
||||||
|
импортируемой функцией в файле заголовка вызывает останов линкера
|
||||||
|
+ Добавлено отображение информации о номере версии расширения KX (опция -vv)
|
||||||
|
|
||||||
|
0.4.5
|
||||||
|
+ Добавлено подключение %ktcc_root%/include через файл tcc.conf
|
||||||
|
+
|
||||||
|
+
|
||||||
|
|
||||||
0.4.4
|
0.4.4
|
||||||
+ Исправлена ошибка при задании неиспользуемых библиотек
|
+ Исправлена ошибка при задании неиспользуемых библиотек
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
|
|
||||||
Быстрый старт
|
Быстрый старт
|
||||||
Для использования новых возможностей предоставляемых расширением KX
|
|
||||||
необходимо использовать файл конфигурации tcc.conf в папке где расположен tcc
|
|
||||||
|
|
||||||
Этот файл перенастраивает директорию %ktcc_root%\ на %ktcc_root%\kx.
|
|
||||||
|
|
||||||
В данной директории присутствует папка lib с файлами
|
tcc используется как обычно (см. справку tcc). Расширение KX использользует
|
||||||
*.def, crt.0 и libtcc.a
|
файлы определений символов (*.def) для динамических библиотек (файлы *.o,
|
||||||
|
не требуются, исключение - статические *.o, если они нужны для работы
|
||||||
|
программы).
|
||||||
|
|
||||||
|
Примеры по сборке см. в директории /samples
|
||||||
|
|
||||||
|
Примечание:
|
||||||
|
ключ -nobss был удален, так как он не имеет смысла (ранее генерировавшаяся
|
||||||
|
bss секция заполнялась нулями и занимала ненужное место в файле, эта секция
|
||||||
|
не должна содержаться в образе и ядро инициализирует эту часть нялями
|
||||||
|
автоматически при загрузке)
|
||||||
|
|
||||||
|
В директории /lib поставляются файлы *.def (определение символов динамических
|
||||||
|
библиотек), crt0.o (поддержка кода С) и *libtcc.a (вспомогательная библиотека
|
||||||
|
tcc), а также некоторые статические библиотеки *.a. Кроме того, имеется
|
||||||
|
библиотека tiny.o для возможности линковки приложений без поддержки кода С,
|
||||||
|
в том числе объектных файлов созданные сторонними компиляторами.
|
||||||
|
|
||||||
Во избежание конфликтов бибилиотек с использованием возможностей
|
Во избежание конфликтов бибилиотек с использованием возможностей
|
||||||
предоставляемых расширением KX рекомендуется использовать только одну
|
предоставляемых расширением KX рекомендуется использовать только одну
|
||||||
директорию с библиотеками. Если определено несколько директорий библиотек,
|
директорию с библиотеками [++, в которой не должно быть взаимоисключающих
|
||||||
|
библиотек]. Если определено несколько директорий библиотек,
|
||||||
в каждой из них не должно быть конфликтных библиотек. Например,
|
в каждой из них не должно быть конфликтных библиотек. Например,
|
||||||
при таком подключении библиотеки
|
при таком подключении библиотеки
|
||||||
|
|
||||||
@ -22,14 +35,8 @@
|
|||||||
работы приложения с расширением KX все динамические библиотеки должны быть
|
работы приложения с расширением KX все динамические библиотеки должны быть
|
||||||
обработаны только с *.def
|
обработаны только с *.def
|
||||||
|
|
||||||
В остальном tcc используется как обычно (см. справку tcc)
|
|
||||||
Примечание:
|
|
||||||
ключ -nobss был удален, так как он не имеет смысла (ранее генерировавшаяся
|
|
||||||
bss секция заполнялась нулями и занимала ненужное место в файле, эта секция
|
|
||||||
не должна содержаться в образе и ядро инициализирует эту часть нялями
|
|
||||||
автоматически при загрузке)
|
|
||||||
|
|
||||||
Файлы определения символов
|
Файлы определения символов
|
||||||
|
|
||||||
Расширение KX использует файлы определений символов (*.def). Файлы *.def
|
Расширение KX использует файлы определений символов (*.def). Файлы *.def
|
||||||
используют простой формат и могут создваться и редактироваться в любом
|
используют простой формат и могут создваться и редактироваться в любом
|
||||||
удобном текстовом редакторе. Структура файла *.def описана ниже.
|
удобном текстовом редакторе. Структура файла *.def описана ниже.
|
||||||
@ -53,13 +60,38 @@
|
|||||||
[libname_]entry2
|
[libname_]entry2
|
||||||
|
|
||||||
; все остальные символы библиотеки
|
; все остальные символы библиотеки
|
||||||
|
|
||||||
|
Заголовочные файлы динамических библиотек
|
||||||
|
Для импотируемых функций поддерживается два способа их объявления:
|
||||||
|
- с префиксом атрибута импорта (рекомендуется для новых бибилиотек).
|
||||||
|
Данный способ дополнительно уменьшает размер приложения.
|
||||||
|
|
||||||
|
__attribute__((dllimport)) void foo(int);
|
||||||
|
|
||||||
|
- внешняя функция с вызовом по указателю (устаревший способ, используется
|
||||||
|
для совместимости с имеющимися на данный момент заголовками)
|
||||||
|
|
||||||
|
extern int (*foo)(const char*);
|
||||||
|
|
||||||
|
ВНИМАНИЕ:
|
||||||
|
объявление импортируемой функции с вызовом по указателю без спецификатора
|
||||||
|
extern является ошибкой, которую tcc не может отследить, так как данная
|
||||||
|
конструкция является правильной с точки зрения языка С
|
||||||
|
|
||||||
|
int (*foo)(const char*); => ошибка!!!
|
||||||
|
|
||||||
|
Объявление импортируемых функций без __attribute__((dllimport))
|
||||||
|
не поддерживается и будет генерировать ошибку линкера
|
||||||
|
|
||||||
|
void foo(int); => ошибка!!!, останов линкера.
|
||||||
|
|
||||||
Проверка поддержки расширения KX
|
Проверка поддержки расширения KX
|
||||||
|
|
||||||
Для проверки, что tcc поддерживает расширение KX:
|
Для проверки, что tcc поддерживает расширение KX:
|
||||||
1. в командной строке наберите
|
1. в командной строке наберите
|
||||||
tcc -v
|
tcc -v
|
||||||
Строка ниже означает, что имеется поддерка расширения KX
|
Строка ниже означает, что имеется поддерка расширения KX
|
||||||
tcc version 0.9.26 (i386 KolibriOS/KX extension)
|
tcc version 0.9.26 (i386 KolibriOS/KX extension 0.4.6)
|
||||||
|
|
||||||
2. В коде для условной компиляции используйте директивы препроцессора
|
2. В коде для условной компиляции используйте директивы препроцессора
|
||||||
проверки предопределенного макроса __KX__, например
|
проверки предопределенного макроса __KX__, например
|
||||||
@ -74,25 +106,4 @@
|
|||||||
определен всегда, даже если Вы по каким то причинам не желаете
|
определен всегда, даже если Вы по каким то причинам не желаете
|
||||||
использовать новые преимущества. При использовании текущих
|
использовать новые преимущества. При использовании текущих
|
||||||
особенностей разделять код описанным в примере выше способом в
|
особенностей разделять код описанным в примере выше способом в
|
||||||
большинстве случаев не требуется.
|
большинстве случаев не требуется.
|
||||||
|
|
||||||
Обеспечение совместимости
|
|
||||||
Если для обеспечения совместимости необходимо отделить код, чтобы его можно
|
|
||||||
было использовать как с расширением KX, так и без него, Вы можете определить
|
|
||||||
дополнительный макрос и таким образом разделять код на нужные участки,
|
|
||||||
например. Настоятельно рекомендуется использовать только код с поддержкой
|
|
||||||
расширения KX.
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
#ifdef _C_LAYER
|
|
||||||
// Код который выполняется без поддержки расширения KX
|
|
||||||
/ использующий старый метод загрузки
|
|
||||||
if(!kolibri_libimg_init()){ // Загружаем libimg.obj
|
|
||||||
notify_show("Libimg.obj not loaded!' -E");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
@ -353,6 +353,14 @@ static void gen_static_call(int v)
|
|||||||
static void gcall_or_jmp(int is_jmp)
|
static void gcall_or_jmp(int is_jmp)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
if (vtop->type.t & VT_IMPORT) {
|
||||||
|
o(0x15ff);
|
||||||
|
greloc(cur_text_section, vtop->sym, ind, R_386_32);
|
||||||
|
gen_le32(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||||
/* constant case */
|
/* constant case */
|
||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
|
@ -660,7 +660,11 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
else
|
else
|
||||||
sh_num = section->sh_num;
|
sh_num = section->sh_num;
|
||||||
|
|
||||||
if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
|
if (((sym->type.t & VT_BTYPE) == VT_FUNC
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
) && ((vtop->type.t & VT_IMPORT) == 0
|
||||||
|
#endif
|
||||||
|
)) {
|
||||||
sym_type = STT_FUNC;
|
sym_type = STT_FUNC;
|
||||||
} else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
|
} else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
|
||||||
sym_type = STT_NOTYPE;
|
sym_type = STT_NOTYPE;
|
||||||
@ -859,11 +863,14 @@ PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
|
|||||||
PUB_FUNC void tcc_error(const char *fmt, ...)
|
PUB_FUNC void tcc_error(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
TCCState *s1 = tcc_state;
|
TCCState *s1 = tcc_state;
|
||||||
|
// { Edit by Coldy
|
||||||
|
if (fmt) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
error1(s1, 0, fmt, ap);
|
error1(s1, 0, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
} // }
|
||||||
/* better than nothing: in some cases, we accept to handle errors */
|
/* better than nothing: in some cases, we accept to handle errors */
|
||||||
if (s1->error_set_jmp_enabled) {
|
if (s1->error_set_jmp_enabled) {
|
||||||
longjmp(s1->error_jmp_buf, 1);
|
longjmp(s1->error_jmp_buf, 1);
|
||||||
|
@ -59,7 +59,8 @@ static void display_info(TCCState *s, int what)
|
|||||||
#elif defined TCC_TARGET_MEOS
|
#elif defined TCC_TARGET_MEOS
|
||||||
" KolibriOS"
|
" KolibriOS"
|
||||||
#ifdef TCC_TARGET_KX
|
#ifdef TCC_TARGET_KX
|
||||||
"/KX extension"
|
"/KX extension "
|
||||||
|
TCC_KX_VERSION_INFO
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
" Linux"
|
" Linux"
|
||||||
|
@ -1217,6 +1217,9 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
|
|||||||
#define realloc(p, s) use_tcc_realloc(p, s)
|
#define realloc(p, s) use_tcc_realloc(p, s)
|
||||||
#undef strdup
|
#undef strdup
|
||||||
#define strdup(s) use_tcc_strdup(s)
|
#define strdup(s) use_tcc_strdup(s)
|
||||||
|
// { Added by Coldy
|
||||||
|
#define tcc_abort() tcc_error(0)
|
||||||
|
// }
|
||||||
PUB_FUNC void tcc_memstats(int bench);
|
PUB_FUNC void tcc_memstats(int bench);
|
||||||
PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
|
PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
|
||||||
PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
|
PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
|
||||||
|
@ -6316,7 +6316,7 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
|
|
||||||
if (ad.a.weak)
|
if (ad.a.weak)
|
||||||
type.t |= VT_WEAK;
|
type.t |= VT_WEAK;
|
||||||
#ifdef TCC_TARGET_PE
|
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_KX)
|
||||||
if (ad.a.func_import)
|
if (ad.a.func_import)
|
||||||
type.t |= VT_IMPORT;
|
type.t |= VT_IMPORT;
|
||||||
if (ad.a.func_export)
|
if (ad.a.func_export)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* TCCKX.C - KolibriOS/KX file output for the TinyC Compiler
|
* TCCKX.C - KolibriOS/KX file output for the TinyC Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021 Coldy
|
* Copyright (c) 2021-2022 Coldy
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -17,6 +17,8 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define TCC_KX_VERSION_INFO "0.4.6"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char magic[4];
|
char magic[4];
|
||||||
@ -67,7 +69,7 @@ typedef struct {
|
|||||||
|
|
||||||
if (dynsym_index == 0) {
|
if (dynsym_index == 0) {
|
||||||
//if (strcmp(name, __kx_import_table_sym) != 0) {
|
//if (strcmp(name, __kx_import_table_sym) != 0) {
|
||||||
tcc_error/*_noabort*/("undefined symbol '%s'", name);
|
tcc_error/*_noabort*/("(kx) undefined symbol '%s'", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// KOS support 32 bit only
|
// KOS support 32 bit only
|
||||||
@ -314,7 +316,39 @@ typedef struct {
|
|||||||
tcc_free(imp);
|
tcc_free(imp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This routine is called from build_reloc to check the code for incorrect import calls
|
||||||
|
void kx_check_import_error(int reloc_type, const char* code_base, Elf32_Addr offset, const char* symbol_name) {
|
||||||
|
|
||||||
|
unsigned char fError = 0;
|
||||||
|
char* p = (char*)(offset + code_base);
|
||||||
|
|
||||||
|
// Hook for "[extern] rtype foo([?])" declaration
|
||||||
|
if (((unsigned char)*((char*)(p-1))) == 0xe8){
|
||||||
|
// call m32
|
||||||
|
tcc_error_noabort("import symbol '%s' has direct call (not supported),\n\t use __attribute__((dllimport)) prefix", symbol_name);
|
||||||
|
fError = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook for MSVC "__declspec(dllimport) rtype(*foo)([?])"
|
||||||
|
/*if ((((unsigned char)*(p + 4)) == 0xff) &&
|
||||||
|
(((unsigned char)*(p + 5)) == 0x10)) {*/
|
||||||
|
if (*((uint16_t*)(p + 4)) == 0x10ff) {
|
||||||
|
/*
|
||||||
|
(mov eax [m32])
|
||||||
|
call dword[eax]
|
||||||
|
*/
|
||||||
|
tcc_error_noabort("import symbol '%s' has unsupported call type", symbol_name);
|
||||||
|
fError = 1;
|
||||||
|
}
|
||||||
|
if (reloc_type == R_386_PC32) {
|
||||||
|
tcc_error_noabort("incorrect relocation type for import symbol '%s'", symbol_name);
|
||||||
|
fError = 1;
|
||||||
|
}
|
||||||
|
if (fError)
|
||||||
|
tcc_abort();
|
||||||
|
}
|
||||||
|
|
||||||
#if /*!*/defined(_DEBUG)// && !defined(_WIN32)
|
#if /*!*/defined(_DEBUG)// && !defined(_WIN32)
|
||||||
#define kx_debug_output printf
|
#define kx_debug_output printf
|
||||||
#else
|
#else
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler
|
* TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Andrey Khalyavin
|
* Copyright (c) 2006 Andrey Khalyavin
|
||||||
* Copyright (c) 2021 Coldy (KX extension)
|
* Copyright (c) 2021-2022 Coldy (KX extension)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -58,6 +58,7 @@ typedef struct {
|
|||||||
#ifdef TCC_TARGET_KX
|
#ifdef TCC_TARGET_KX
|
||||||
void kx_init(me_info* me);
|
void kx_init(me_info* me);
|
||||||
void kx_build_imports(me_info* me);
|
void kx_build_imports(me_info* me);
|
||||||
|
void kx_check_import_error(int reloc_type, const char* code_base, Elf32_Addr offset, const char* symbol_name);
|
||||||
long kx_get_header_length(me_info* me);
|
long kx_get_header_length(me_info* me);
|
||||||
void kx_write_header(me_info* me, FILE* f);
|
void kx_write_header(me_info* me, FILE* f);
|
||||||
void kx_write_imports(me_info* me, FILE* f);
|
void kx_write_imports(me_info* me, FILE* f);
|
||||||
@ -112,8 +113,11 @@ void build_reloc(me_info* me)
|
|||||||
rel=rel_;
|
rel=rel_;
|
||||||
int type = ELF32_R_TYPE(rel->r_info);
|
int type = ELF32_R_TYPE(rel->r_info);
|
||||||
rel_=rel+1;
|
rel_=rel+1;
|
||||||
if (type != R_386_PC32 && type != R_386_32)
|
if (type != R_386_PC32 && type != R_386_32) {
|
||||||
|
// gcc (and friends) object files is used?
|
||||||
|
tcc_error("unsupported relocation type %d", type);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
int sym = ELF32_R_SYM(rel->r_info);
|
int sym = ELF32_R_SYM(rel->r_info);
|
||||||
if (sym>symtab_section->data_offset/sizeof(Elf32_Sym))
|
if (sym>symtab_section->data_offset/sizeof(Elf32_Sym))
|
||||||
continue;
|
continue;
|
||||||
@ -121,34 +125,42 @@ void build_reloc(me_info* me)
|
|||||||
int sect=esym->st_shndx;
|
int sect=esym->st_shndx;
|
||||||
int sh_addr;
|
int sh_addr;
|
||||||
ss=findsection(me,sect);
|
ss=findsection(me,sect);
|
||||||
|
const char* sym_name = strtab_section->data + esym->st_name;
|
||||||
|
int sym_index;
|
||||||
|
Elf32_Sym* dyn_sym;
|
||||||
|
// Import has more less priority in relation to local symbols
|
||||||
if (ss==0)
|
if (ss==0)
|
||||||
{
|
{
|
||||||
const char *sym_name = strtab_section->data + esym->st_name;
|
|
||||||
#ifdef TCC_TARGET_KX
|
#ifdef TCC_TARGET_KX
|
||||||
int sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name);
|
sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name);
|
||||||
Elf32_Sym* dyn_sym;
|
|
||||||
if (sym_index == 0) {
|
if (sym_index == 0) {
|
||||||
#endif
|
#endif
|
||||||
tcc_error_noabort("undefined symbol '%s'", sym_name);
|
tcc_error_noabort("undefined import symbol '%s'", sym_name);
|
||||||
continue;
|
continue;
|
||||||
#ifdef TCC_TARGET_KX
|
#ifdef TCC_TARGET_KX
|
||||||
}
|
}
|
||||||
dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[sym_index];
|
dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[sym_index];
|
||||||
sh_addr = dyn_sym->st_value;
|
sh_addr = dyn_sym->st_value;
|
||||||
if (sh_addr == 0) {
|
if (sh_addr == 0) {
|
||||||
tcc_error_noabort("symbol '%s' has zero value", sym_name);
|
tcc_error_noabort("import symbol '%s' has zero value", sym_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop linking if incorrect import
|
||||||
|
kx_check_import_error(type, s->data, rel->r_offset, sym_name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
if (esym->st_shndx == SHN_UNDEF)
|
||||||
|
tcc_error("unresolved external symbol '%s'", sym_name);
|
||||||
sh_addr = ss->sh_addr;
|
sh_addr = ss->sh_addr;
|
||||||
|
}
|
||||||
if (rel->r_offset>s->data_size)
|
if (rel->r_offset>s->data_size)
|
||||||
continue;
|
continue;
|
||||||
if (type==R_386_PC32)
|
if (type==R_386_PC32)
|
||||||
*(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value-rel->r_offset-s->sh_addr;
|
*(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value-rel->r_offset-s->sh_addr;
|
||||||
else if (type==R_386_32)
|
else if (type==R_386_32)
|
||||||
*(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value;
|
*(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value;
|
||||||
}
|
}
|
||||||
rel=rel_;
|
rel=rel_;
|
||||||
s=s->next;
|
s=s->next;
|
||||||
|
Loading…
Reference in New Issue
Block a user