Я сталкиваюсь с подобной проблемой к этому сообщению:
Глобальный вызов конструктора не в разделе .init_array
Я буду повторно использовать его пример, но я думаю, что это проблема, специфичная для среды RISCV, поэтому я создаю новый пост.
class foobar
{
int i;
public:
foobar()
{
i = 100;
}
void inc()
{
i++;
}
};
foobar foo;
int main()
{
foo.inc();
for (;;);
}
Проблема в том, что конструктор для foo никогда не вызывается. На котором я ставлю точку останова на первом шаге, значение i равно 0, а не ожидаемым 100.
Вот вывод: riscv64-unknown-elf-objdump.exe -j .init_array -x objs / main.o
objs / main.o: формат файла elf32-littleriscv objs / main.o
архитектура: riscv: rv32, флаги 0x00000011: HAS_RELOC, HAS_SYMS start
адрес 0x00000000Разделы: Idx Имя Размер VMA LMA Файл выключен
Algn 8 .init_array 00000004 00000000 00000000 00000154 2 ** 2
СОДЕРЖАНИЕ, ALLOC, LOAD, RELOC, СИМВОЛ ДАННЫХ ТАБЛИЦА: 00000000 l d .init_array 00000000 .init_arrayЗАПИСИ ОТНОШЕНИЯ ДЛЯ [.init_array]: ЗНАЧЕНИЕ ТИПА СМЕЩЕНИЯ
00000000 R_RISCV_32 _GLOBAL__sub_I_foo
Что заставляет меня верить, что это надо называть? Я также протестировал стандартные переменные C, объявленные глобально, которые присваиваются, а также отображаются в .init_array.
Мой _init () выглядит так:
void _init(void)
{
copy_section(&__sdata_load, &__sdata_start, &__sdata_end);
copy_section(&__data_load, &__data_start, &__data_end);
zero_section(&__sbss_start, &__sbss_end);
zero_section(&__bss_start, &__bss_end);
exit(main());
}
Похоже, что другие проекты на основе RISCV также не используют примитивы инициализации libc (например, __libc_init_array ()), в качестве дополнительного вопроса мне было интересно, почему это так?
Я наконец собрал правильное решение этой проблемы, с которой столкнулся все эти месяцы назад. Вот что я в итоге положил в процессе инициализации. Это вызывается прямо перед main (). На это во многом повлияло решение, о котором говорилось в посте, на который я ссылался в своем первоначальном вопросе.
extern void (**__preinit_array_start)();
extern void (**__preinit_array_end)();
extern void (**__init_array_start)();
extern void (**__init_array_end)();
extern void (**__fini_array_start)();
extern void (**__fini_array_end)();
static void execute_array(void (** _start)(), void (** _end)())
{
size_t count;
size_t i;
count = _end - _start;
for (i = 0; i < count; i++)
{
(*_start[i])();
}
}
void _init(void)
{
execute_array(__preinit_array_start, __preinit_array_end);
execute_array(__init_array_start, __init_array_end);
main();
}
void _fini()
{
execute_array(__fini_array_start, __fini_array_end);
}
Других решений пока нет …