Почему программа и все ее статически определенные системы, построенные с помощью набора инструментов RISC-V, должны соответствовать диапазону адресов 2 ГБ?

#linux #gcc #operating-system #elf #riscv

#линукс #gcc #операционная система #эльф #рискв

Вопрос:

Я пытаюсь создать 64-разрядный исполняемый файл RISC-V ELF, используя набор инструментов RISC-V с newlib и сценарием компоновщика, который помещает раздел текста в 0x100, а раздел данных начинается с 0x100000000 (больше, чем ограничение в 2 ГБ). Однако я получаю следующую ошибку:

 relocation truncated to fit: R_RISCV_HI20 against symbol `__global_pointer

Я заметил, что параметры RISC-V указывают эти два параметра --mcmodel:

 -mcmodel=medlow  Generate code for the medium-low code model. The program and its statically defined symbols must lie within a single 2 GiB address range and must lie between absolute addresses -2 GiB and  2 GiB. Programs can be statically or dynamically linked. This is the default code model.  -mcmodel=medany  Generate code for the medium-any code model. The program and its statically defined symbols must be within any single 2 GiB address range. Programs can be statically or dynamically linked.  

Однако я не понимаю, почему даже при использовании 64-разрядных регистров я не могу использовать все 64-разрядное адресное пространство в моем исполняемом файле. Любые разъяснения будут весьма признательны.

Ответ №1:

Аналогичные ситуации наблюдаются и на других 64-разрядных платформах, таких как x86-64 и ARM64.

Обычный способ загрузки статического адреса-это 32-разрядный немедленный, абсолютный или относительный для ПК. Это более эффективно, чем требовать 64-разрядной оперативной памяти при каждом использовании адреса, для чего, как правило, требуется более длинная и медленная последовательность инструкций. Но это означает, что весь статический код и данные должны поместиться в 2 ГБ.

Вы можете использовать гораздо больше 64-разрядного адресного пространства для динамически выделяемых объектов, поскольку им не нужно, чтобы их адреса были закодированы в двоичном формате. Это ограничение действует только для статического кода и данных. Кроме того, я не уверен в RISC-V, но я полагаю, что на других платформах ограничение в 2 ГБ применяется отдельно к каждой общей библиотеке, поэтому действительно огромное приложение все равно можно написать, разделив части на общие библиотеки.

На x86-64 и ARM64 GCC поддерживает модель "большого" кода, в которой все статические адреса загружаются как 64-разрядные, с соответствующим снижением производительности. Похоже, что в настоящее время это не поддерживается для RISC-V.

defined in .sdata section in a.out collect2: error: ld returned 1 exit status Я заметил, что параметры RISC-V указывают эти два параметра —mcmodel:


Однако я не понимаю, почему даже при использовании 64-разрядных регистров я не могу использовать все 64-разрядное адресное пространство в моем исполняемом файле. Любые разъяснения будут весьма признательны.

Ответ №1:

Аналогичные ситуации наблюдаются и на других 64-разрядных платформах, таких как x86-64 и ARM64.

Обычный способ загрузки статического адреса-это 32-разрядный немедленный, абсолютный или относительный для ПК. Это более эффективно, чем требовать 64-разрядной оперативной памяти при каждом использовании адреса, для чего, как правило, требуется более длинная и медленная последовательность инструкций. Но это означает, что весь статический код и данные должны поместиться в 2 ГБ.

Вы можете использовать гораздо больше 64-разрядного адресного пространства для динамически выделяемых объектов, поскольку им не нужно, чтобы их адреса были закодированы в двоичном формате. Это ограничение действует только для статического кода и данных. Кроме того, я не уверен в RISC-V, но я полагаю, что на других платформах ограничение в 2 ГБ применяется отдельно к каждой общей библиотеке, поэтому действительно огромное приложение все равно можно написать, разделив части на общие библиотеки.

На x86-64 и ARM64 GCC поддерживает модель «большого» кода, в которой все статические адреса загружаются как 64-разрядные, с соответствующим снижением производительности. Похоже, что в настоящее время это не поддерживается для RISC-V.