x86平台下64位设备,默认情况下编译的是elf64,比如简单的helloworld代码如下,使用readelf查看elf头部信息,格式为ELF64。
➜ cat helloworld.c
#include <stdio.h>int main()
{printf("hello!!!\n");return 0;
}➜ gcc -Wall helloworld.c -g -o helloworld
➜ readelf -h helloworld
ELF 头:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00类别: ELF64数据: 2 补码,小端序 (little endian)Version: 1 (current)OS/ABI: UNIX - System VABI 版本: 0类型: DYN (Position-Independent Executable file)系统架构: Advanced Micro Devices X86-64版本: 0x1入口点地址: 0x1040程序头起点: 64 (bytes into file)Start of section headers: 14080 (bytes into file)标志: 0x0Size of this header: 64 (bytes)Size of program headers: 56 (bytes)Number of program headers: 13Size of section headers: 64 (bytes)Number of section headers: 36Section header string table index: 35
➜ gcc -Wall -m32 helloworld.c -g -o helloworld
➜ readelf -h helloworld
ELF 头:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00类别: ELF32数据: 2 补码,小端序 (little endian)Version: 1 (current)OS/ABI: UNIX - System VABI 版本: 0类型: DYN (Position-Independent Executable file)系统架构: Intel 80386版本: 0x1入口点地址: 0x1060程序头起点: 52 (bytes into file)Start of section headers: 13996 (bytes into file)标志: 0x0Size of this header: 52 (bytes)Size of program headers: 32 (bytes)Number of program headers: 12Size of section headers: 40 (bytes)Number of section headers: 36Section header string table index: 35
我的设备是MANJARO发行版本,通过包管理器安装了risc-v编译工具链riscv64-linux-gnu-gcc
➜ uname -a
Linux mt-pc 5.10.202-1-MANJARO #1 SMP PREEMPT Tue Nov 28 19:17:16 UTC 2023 x86_64 GNU/Linux
➜ pacman -Q riscv64-linux-gnu-gcc
riscv64-linux-gnu-gcc 12.2.0-1
对于riscv汇编程序,默认生成elf64二进制。
➜ cat test.s
# Add
# Format:
# ADD RD, RS1, RS2
# Description:
# The contents of RS1 is added to the contents of RS2 and the result is
# placed in RD..text # Define beginning of text section.global _start # Define entry _start_start:li x6, 1 # x6 = 1li x7, 2 # x7 = 2add x5, x6, x7 # x5 = x6 + x7stop:j stop # Infinite loop to stop execution.end # End of file➜ riscv64-linux-gnu-gcc -nostdlib -fno-builtin -g -Wall test.s -o test
➜ riscv64-linux-gnu-readelf -h test
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: DYN (Position-Independent Executable file)Machine: RISC-VVersion: 0x1Entry point address: 0x29aStart of program headers: 64 (bytes into file)Start of section headers: 5536 (bytes into file)Flags: 0x5, RVC, double-float ABISize of this header: 64 (bytes)Size of program headers: 56 (bytes)Number of program headers: 8Size of section headers: 64 (bytes)Number of section headers: 19Section header string table index: 18
参照x86下的方式,使用 -m 32 发现没这个选项。查看github官方说明文档,发现–print-multi-lib可以打印出支持的架构,执行发现啥也没打印出来。
➜ riscv64-linux-gnu-gcc --print-multi-lib
.;
继续看文档,发现有个 -march/-mabi 选项,继续搜查之。发现gnu官方文档-march gnu官方文档-mabi有关于这两个选项的说明。 查看默认情况下这两个选项的值为 ‘-march=rv64gc’ ‘-mabi=lp64d’。使用readelf查看header信息,生成的是elf64。
➜ riscv64-linux-gnu-gcc -v -nostdlib -fno-builtin -g -Wall test.s -o test
...
COLLECT_GCC_OPTIONS='-v' '-nostdlib' '-fno-builtin' '-g' '-Wall' '-o' 'test' '-march=rv64gc' '-mabi=lp64d' '-misa-spec=20191213' '-march=rv64imafdc_zicsr_zifencei' '-dumpdir' 'test.'
...➜ tmp riscv64-linux-gnu-readelf -h test
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: DYN (Position-Independent Executable file)Machine: RISC-VVersion: 0x1Entry point address: 0x29aStart of program headers: 64 (bytes into file)Start of section headers: 5536 (bytes into file)Flags: 0x5, RVC, double-float ABISize of this header: 64 (bytes)Size of program headers: 56 (bytes)Number of program headers: 8Size of section headers: 64 (bytes)Number of section headers: 19Section header string table index: 18
基于以上信息,生成32二进制选项可设置为 “-march=rv32ima -mabi=ilp32”。
➜ riscv64-linux-gnu-gcc -nostdlib -fno-builtin -march=rv32ima -mabi=ilp32 -g -Wall test.s -o test
➜ riscv64-linux-gnu-readelf -h test
ELF Header:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00Class: ELF32Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: DYN (Position-Independent Executable file)Machine: RISC-VVersion: 0x1Entry point address: 0x1b8Start of program headers: 52 (bytes into file)Start of section headers: 5220 (bytes into file)Flags: 0x0Size of this header: 52 (bytes)Size of program headers: 32 (bytes)Number of program headers: 8Size of section headers: 40 (bytes)Number of section headers: 19Section header string table index: 18