Включение раздела .init_array в скрипт компоновщика приводит к непригодному выводу - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь перенести проект 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, я просто получаю сообщение об ошибке Нет регистров .Когда я удаляю разделы из компоновщика, я могу успешно запустить код, если не использую статические объекты, которые не загружены.

Есть ли какое-либо объяснение этому поведению?

1 Ответ

0 голосов
/ 07 июня 2018

Мне удалось выявить проблему.При добавлении раздела массива 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
}
...