Я пытаюсь перенести проект c ++ на RISC-V. Проект уже был успешно скомпилирован для ARM с использованием IAR Toolchain и для Windows.
Для порта RISC-V я написал свой собственный файл CRT0.S, который выполняет всю инициализацию, а также мой собственный скрипт компоновщика.
С некоторыми небольшими демонстрационными проектами все работает отлично.
Я также могу успешно скомпилировать и связать проект. Проблема заключается в том, что когда я добавляю секцию .init_array в скрипт компоновщика, выходной файл увеличивается с 4 до более 100 КБ. Я добавил эти разделы в скрипт компоновщика:
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > ram
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array ))
PROVIDE_HIDDEN (__init_array_end = .);
} > ram
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array ))
PROVIDE_HIDDEN (__fini_array_end = .);
} > ram
Когда я сейчас пытаюсь загрузить этот файл ELF в GDB, я просто получаю сообщение об ошибке Нет регистров. Когда я удаляю разделы из компоновщика, я могу успешно запустить код, поскольку я не использую статические объекты, которые не загружены.
Есть ли объяснение этому поведению?
Я смог определить проблему. При добавлении раздела массива init также были добавлены некоторые статические объекты из стандартных библиотек. Библиотека использовала системные вызовы операционной системы (ebreak). Поскольку мы работаем над «голой железной» системой, звонки не были услышаны.
Решение состояло в том, чтобы исключить стандартную библиотеку и реализовать delete
оператор вручную. Сейчас работает отлично.
void operator delete(void *p) noexcept
{
free(p);
}
extern "C" void operator delete(void* p, unsigned long c) noexcept
{
operator delete(p); // Same as regular delete
}
Других решений пока нет …