core-v-verif
core-v-verif copied to clipboard
ELF vs HEX mismatch
ELF vs HEX mismatch
Type
- Discrepancy between how binutils and the ISS determines which regions that are to be loaded into memory
- Possibly a linker bug, causing incorrect program header in elf-file
- If linker behavior is correct (TBD), then parsing the program header table is not sufficient to determine what parts of the binary to be loaded into system memory for a bare metal system. (indicated by objcopy behavior outlined below)
Background
ISS mismatches observed with attempts to read from memory 0x90f4 in a random simulations. The values being read by the ISS from the region 0x90xx appears to match the contents of the ELF header, while RTL reads zero (expected behavior)
Inspecting the program and section header tables (see below) indicates that extra space is allocated to the program header entry with the lowest address (+0x1000), with a start offset at 0x0 (start of file - which is always the elf header). Cutter disassembly also confirms that address 0x9000 is marked as loadable, and pointing to the header itself. consequently, ISS parses the program headers in the elf file to determine which parts of the elf file to load into memory, including file offset 0x0-0xFFF into offset 0x9000-0x9FFF, prior to loading the actual code that starts at address 0xA000.
This behavior is only observed in cases where the binary does not start at address 0x0000_0000.
In core-v-verif, the binutils <riscv-toolchain>_objcopy -O verilog command is used to generate the memory image (hex file) used by verilog simulators; this hex is generated as expected and does not contain the elf header, thus there is a discrepancy between how objcopy and the ISS determines which regions to load into memory.
Steps to Reproduce
-
branch: cv32e40x/dev
-
hash: bf064fc0b11b88bb6483ac10766f3ab02abee01f
-
Generate source code and linker scripts:
make comp_corev-dv gen_corev-dv TEST=corev_rand_fencei CV_CORE=cv32e40x CFG=pma_test_cfg_3 SIMULATOR=xrun USE_ISS=NO SEED=819033859 -
Build and run (This performs the necessary step to generate the output binaries):
make test TEST=corev_rand_fencei CV_CORE=cv32e40x CFG=pma_test_cfg_3 SIMULATOR=xrun USE_ISS=NO SEED=969359103 -
This does not get flagged as an error with these steps, but visual inspection of the output files confirm that the issue is present
Readelf output:
This snippet from the program headers is the culprit, "load 0x11000 bytes from elf file offset 0x0 into cpu memory at offset 0x9000", elf header is by spec always at file offset 0x0. Loading the elf header itself into bare metal cpu memory makes absolutely no sense, and is probably why objcopy discards it:
| Type | Offset | VirtAddr | PhysAddr | FileSiz | MemSiz | Flg | Align |
|---|---|---|---|---|---|---|---|
| LOAD | 0x000000 | 0x00009000 | 0x00009000 | 0x11000 | 0x11000 | RW | 0x1000 |
Program Headers:
| Type | Offset | VirtAddr | PhysAddr | FileSiz | MemSiz | Flg | Align |
|---|---|---|---|---|---|---|---|
| RISCV_ATTRIBUT | 0x15affe | 0x00000000 | 0x00000000 | 0x00044 | 0x00000 | R | 0x1 |
| LOAD | 0x000000 | 0x00009000 | 0x00009000 | 0x11000 | 0x11000 | RW | 0x1000 |
| LOAD | 0x011000 | 0x02000000 | 0x02000000 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x0210f0 | 0x100000f0 | 0x100000f0 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x031a54 | 0x13acaa54 | 0x13acaa54 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x042800 | 0x1a110800 | 0x1a110800 | 0x00802 | 0x00890 | RWE | 0x1000 |
| LOAD | 0x043008 | 0x23400008 | 0x23400008 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x054000 | 0x2a000000 | 0x2a000000 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x064ca8 | 0x3100fca8 | 0x3100fca8 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x075854 | 0x3420c854 | 0x3420c854 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x086000 | 0x3600a000 | 0x3600a000 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x096000 | 0x3ace0000 | 0x3ace0000 | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x0a6000 | 0x48000000 | 0x48000000 | 0x00080 | 0x00080 | R E | 0x1000 |
| LOAD | 0x0a6080 | 0x48000080 | 0x48000080 | 0x32e88 | 0x11ff80 | RWE | 0x1000 |
| LOAD | 0x000f10 | 0x48032f10 | 0x48032f10 | 0x00000 | 0xed0f0 | RW | 0x1000 |
| LOAD | 0x0d8ffc | 0x4bfffffc | 0x4bfffffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x0e8ffc | 0x4f99fffc | 0x4f99fffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x0f9bfc | 0x5000abfc | 0x5000abfc | 0x010c8 | 0x010c8 | RW | 0x1000 |
| LOAD | 0x0faffc | 0x52fffffc | 0x52fffffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x10affc | 0x56fffffc | 0x56fffffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x11affc | 0x63fffffc | 0x63fffffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x12affc | 0x7ffffffc | 0x7ffffffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x13affc | 0x8459fffc | 0x8459fffc | 0x10000 | 0x10000 | RW | 0x1000 |
| LOAD | 0x14affc | 0xeffffffc | 0xeffffffc | 0x10000 | 0x10000 | RW | 0x1000 |
Section to Segment mapping:
| Segment | Sections... |
|---|---|
| 00 | .riscv.attributes |
| 01 | .region_28 |
| 02 | .region_26 |
| 03 | .region_22 |
| 04 | .region_20 |
| 05 | .debugger .debugger_exception .debugger_stack |
| 06 | .region_16 |
| 07 | .region_14 |
| 08 | .region_8 |
| 09 | .region_6 |
| 10 | .region_4 |
| 11 | .region_3 |
| 12 | .mtvec_handler |
| 13 | .init .text .data .region_0 .user_stack .kernel_stack .heap .stack |
| 14 | .heap .stack |
| 15 | .region_5 |
| 16 | .region_7 |
| 17 | .region_9 |
| 18 | .region_15 |
| 19 | .region_17 |
| 20 | .region_21 |
| 21 | .region_23 |
| 22 | .region_27 |
| 23 | .region_29 |
Section Headers:
| [Nr] Name | Type | Addr | Off | Size | ES | Flg | Lk | Inf | Al |
|---|---|---|---|---|---|---|---|---|---|
| [ 0] | NULL | 00000000 | 000000 | 000000 | 00 | 0 | 0 | 0 | |
| [ 1] .debugger | PROGBITS | 1a110800 | 042800 | 000004 | 00 | AX | 0 | 0 | 1 |
| [ 2] .debugger_ex[...] | PROGBITS | 1a111000 | 043000 | 000002 | 00 | AX | 0 | 0 | 1 |
| [ 3] .debugger_stack | NOBITS | 1a111010 | 043002 | 000080 | 00 | WA | 0 | 0 | 16 |
| [ 4] .region_3 | PROGBITS | 3ace0000 | 096000 | 010000 | 00 | WA | 0 | 0 | 1 |
| [ 5] .region_4 | PROGBITS | 3600a000 | 086000 | 010000 | 00 | WA | 0 | 0 | 1 |
| [ 6] .region_5 | PROGBITS | 4bfffffc | 0d8ffc | 010000 | 00 | WA | 0 | 0 | 1 |
| [ 7] .region_6 | PROGBITS | 3420c854 | 075854 | 010000 | 00 | WA | 0 | 0 | 1 |
| [ 8] .region_7 | PROGBITS | 4f99fffc | 0e8ffc | 010000 | 00 | WA | 0 | 0 | 1 |
| [ 9] .region_8 | PROGBITS | 3100fca8 | 064ca8 | 010000 | 00 | WA | 0 | 0 | 1 |
| [10] .region_9 | PROGBITS | 5000abfc | 0f9bfc | 0010c8 | 00 | WA | 0 | 0 | 1 |
| [11] .region_14 | PROGBITS | 2a000000 | 054000 | 010000 | 00 | WA | 0 | 0 | 1 |
| [12] .region_15 | PROGBITS | 52fffffc | 0faffc | 010000 | 00 | WA | 0 | 0 | 1 |
| [13] .region_16 | PROGBITS | 23400008 | 043008 | 010000 | 00 | WA | 0 | 0 | 1 |
| [14] .region_17 | PROGBITS | 56fffffc | 10affc | 010000 | 00 | WA | 0 | 0 | 1 |
| [15] .region_20 | PROGBITS | 13acaa54 | 031a54 | 010000 | 00 | WA | 0 | 0 | 1 |
| [16] .region_21 | PROGBITS | 63fffffc | 11affc | 010000 | 00 | WA | 0 | 0 | 1 |
| [17] .region_22 | PROGBITS | 100000f0 | 0210f0 | 010000 | 00 | WA | 0 | 0 | 1 |
| [18] .region_23 | PROGBITS | 7ffffffc | 12affc | 010000 | 00 | WA | 0 | 0 | 1 |
| [19] .region_26 | PROGBITS | 02000000 | 011000 | 010000 | 00 | WA | 0 | 0 | 1 |
| [20] .region_27 | PROGBITS | 8459fffc | 13affc | 010000 | 00 | WA | 0 | 0 | 1 |
| [21] .region_28 | PROGBITS | 0000a000 | 001000 | 010000 | 00 | WA | 0 | 0 | 1 |
| [22] .region_29 | PROGBITS | effffffc | 14affc | 010000 | 00 | WA | 0 | 0 | 1 |
| [23] .mtvec_handler | PROGBITS | 48000000 | 0a6000 | 000080 | 00 | AX | 0 | 0 | 1 |
| [24] .init | PROGBITS | 48000080 | 0a6080 | 000004 | 00 | AX | 0 | 0 | 1 |
| [25] .text | PROGBITS | 48000100 | 0a6100 | 0152aa | 00 | AX | 0 | 0 | 256 |
| [26] .data | PROGBITS | 480153c0 | 0bb3c0 | 000088 | 00 | WA | 0 | 0 | 64 |
| [27] .region_0 | PROGBITS | 48015448 | 0bb448 | 010000 | 00 | WA | 0 | 0 | 1 |
| [28] .user_stack | PROGBITS | 48025448 | 0cb448 | 009c40 | 00 | WA | 0 | 0 | 4 |
| [29] .kernel_stack | PROGBITS | 4802f088 | 0d5088 | 003e80 | 00 | WA | 0 | 0 | 4 |
| [30] .heap | NOBITS | 48032f10 | 0d8f08 | 0ed0f0 | 00 | WA | 0 | 0 | 16 |
| [31] .stack | NOBITS | 48032f10 | 0d8f10 | 0ed0f0 | 00 | WA | 0 | 0 | 16 |
| [32] text | PROGBITS | 00000000 | 15affc | 000002 | 00 | 0 | 0 | 1 | |
| [33] .riscv.attributes | RISCV_ATTRIBUTE | 00000000 | 15affe | 000044 | 00 | 0 | 0 | 1 | |
| [34] .debug_aranges | PROGBITS | 00000000 | 15b048 | 000040 | 00 | 0 | 0 | 8 | |
| [35] .debug_info | PROGBITS | 00000000 | 15b088 | 000023 | 00 | 0 | 0 | 1 | |
| [36] .debug_abbrev | PROGBITS | 00000000 | 15b0ab | 000012 | 00 | 0 | 0 | 1 | |
| [37] .debug_line | PROGBITS | 00000000 | 15b0bd | 021422 | 00 | 0 | 0 | 1 | |
| [38] .debug_str | PROGBITS | 00000000 | 17c4df | 00005b | 01 | MS | 0 | 0 | 1 |
| [39] .debug_line_str | PROGBITS | 00000000 | 17c53a | 0000a3 | 01 | MS | 0 | 0 | 1 |
| [40] .debug_rnglists | PROGBITS | 00000000 | 17c5dd | 00002e | 00 | 0 | 0 | 1 | |
| [41] .symtab | SYMTAB | 00000000 | 17c60c | 0023a0 | 10 | 42 | 551 | 4 | |
| [42] .strtab | STRTAB | 00000000 | 17e9ac | 002fea | 00 | 0 | 0 | 1 | |
| [43] .shstrtab | STRTAB | 00000000 | 181996 | 0001d7 | 00 | 0 | 0 | 1 |
Map output:
| Name | Origin | Length | Attributes |
|---|---|---|---|
| dbg | 0x000000001a110800 | 0x0000000000001000 | axrwl |
| region_0 | 0x0000000048000000 | 0x0000000000120000 | axrwl |
| region_1 | 0x0000000044000000 | 0x0000000000120000 | !l |
| region_2 | 0x0000000049fffffc | 0x0000000000120000 | !l |
| region_3 | 0x000000003ace0000 | 0x0000000000120000 | axrwl |
| region_4 | 0x000000003600a000 | 0x0000000000120000 | axrwl |
| region_5 | 0x000000004bfffffc | 0x0000000000120000 | axrwl |
| region_6 | 0x000000003420c854 | 0x0000000000120000 | axrwl |
| region_7 | 0x000000004f99fffc | 0x0000000000120000 | axrwl |
| region_8 | 0x000000003100fca8 | 0x0000000000120000 | axrwl |
| region_9 | 0x000000005000abfc | 0x00000000000010c8 | axrwl |
| region_10 | 0x0000000030001350 | 0x0000000000120000 | !l |
| region_11 | 0x000000005000bcc8 | 0x0000000000120000 | !l |
| region_12 | 0x000000002c5a3200 | 0x0000000000120000 | !l |
| region_13 | 0x000000005140fffc | 0x0000000000120000 | !l |
| region_14 | 0x000000002a000000 | 0x0000000000120000 | axrwl |
| region_15 | 0x0000000052fffffc | 0x0000000000120000 | axrwl |
| region_16 | 0x0000000023400008 | 0x0000000000120000 | axrwl |
| region_17 | 0x0000000056fffffc | 0x0000000000120000 | axrwl |
| region_18 | 0x0000000020000000 | 0x0000000000120000 | !l |
| region_19 | 0x00000000600ffffc | 0x0000000000120000 | !l |
| region_20 | 0x0000000013acaa54 | 0x0000000000120000 | axrwl |
| region_21 | 0x0000000063fffffc | 0x0000000000120000 | axrwl |
| region_22 | 0x00000000100000f0 | 0x0000000000120000 | axrwl |
| region_23 | 0x000000007ffffffc | 0x0000000000120000 | axrwl |
| region_24 | 0x0000000005000000 | 0x0000000000120000 | !l |
| region_25 | 0x0000000082fffffc | 0x0000000000120000 | !l |
| region_26 | 0x0000000002000000 | 0x0000000000120000 | axrwl |
| region_27 | 0x000000008459fffc | 0x0000000000120000 | axrwl |
| region_28 | 0x000000000000a000 | 0x0000000000120000 | axrwl |
| region_29 | 0x00000000effffffc | 0x0000000000120000 | axrwl |
| default | 0x0000000000000000 | 0xffffffffffffffff |
hi @silabs-hfegran Would you be able to create a smaller reproducer that doesn't depend on EDA tooling, and I will take a look.
hi @silabs-hfegran Would you be able to create a smaller reproducer that doesn't depend on EDA tooling, and I will take a look.
Thanks for looking into this, @jeremybennett, I will try to create a small, self-contained example
@jeremybennett here is an example that only requires the compiler suite set up: make sure CV_SW_TOOLCHAIN points to your toolchain installation, check the makefile for details:
https://github.com/silabs-hfegran/debug/tree/elf_issue_1391
This issue can be worked around with the -nmagic flag to the linker.