|
From: | Pajak, Lukas |
Subject: | Address shift when adjusting vma and using interleave while exporting as verilog (and padding problems with empty sections) |
Date: | Mon, 25 Nov 2024 10:02:46 +0000 |
Hey all,
first of all, I'm not quite sure if those are bugs or a wished behavior, but if it's the latter, I'm curious what the use case might be.
I have a valid main.elf
and need to write its .text
and
.rodata
sections to two 16-bit ROMs by exporting the binary to Intel hex and Verilog. The addresses should start at 0x0 though, and I also need to fill the rest of the ROMs with 0x0.
My arguments for riscv32-unknown-elf-objcopy
are
--adjust-vma -0xffffc000
To make the binary at address 0x0 --only-section .text --only-section .rodata --pad-to=0x1000
To fill in the 0x0, --only-section is needed because the padding is appended after the last section and while .rodata is the last section to be exported, the --pad-to does not respect
that --interleave-width 2 --interleave=4 --byte [0|2]
Interleave to get either the lower or upper 16 bits.
--output-format [ihex|verilog] [--verilog-data-width 2]
Output as Intel Hex or Verilog with 16 bit data width
In my example the elf has the following structure (readelf -S
):
There are 11 section headers, starting at offset 0x2bcc:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS ffffc000 001000 000a50 00 AX 0 0 4
[ 2] .rodata PROGBITS ffffca50 001a50 0001ec 00 A 0 0 4
[ 3] .data PROGBITS 80000000 001c3c 000000 00 WA 0 0 4
[ 4] .bss NOBITS 80000000 002000 000008 00 WA 0 0 4
[ 5] .heap PROGBITS 80000008 001c3c 000000 00 W 0 0 4
[ 6] .comment PROGBITS 00000000 001c3c 00001b 01 MS 0 0 1
[ 7] .riscv.attributes RISCV_ATTRIBUTE 00000000 001c57 000035 00 0 0 1
[ 8] .symtab SYMTAB 00000000 001c8c 000910 10 9 117 4
[ 9] .strtab STRTAB 00000000 00259c 0005db 00 0 0 1
[10] .shstrtab STRTAB 00000000 002b77 000055 00 0 0 1
@00000000
20B7 0000 8093 8000 9073 3000 0097 0000
8093 0E40 9073 3050 1073 3040 4217 8000
[…]
2423 C000 2623 C000 F7B7 FFFF 8793 5007
A703 0007 4EE3 FE07 0793 0000 80E7 0007
@00000528
0A07 5245 5F52 0000 450A 5252 455F 4358
0020 0000 7741 6961 6974 676E 6E20 6F65
[…]
5845 0045 5300 5A49 0045 4843 534B 4600
534C 0048 5754 0049 0000 0000
@0000061E
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
[…]
So the part after @00000528
is the .rodata
section and
the address 0x528 is right after the .text section.
Now for the unexpected behavior: the Verilog file sets the start address of the .rodata section too low when using interleaving.
@00000000
20B7 8093 9073 0097 8093 9073 1073 4217
0213 7113 4197 8193 0293 0313 0393 0413
[…]
0513 F0EF F0EF 0663 2423 2623 F7B7 8793
A703 4EE3 0793 80E7
@0000014A
0A07 5F52 450A 455F 0020 7741 6974 6E20
7672 655F 622E 2E2E 0000 6F4C 6E69 7266
[…]
3130 3534 3938 6463 5845 5300 0045 534B
534C 5754 0000
@000001C5
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
[…]
So the part after @00000528
is the .rodata
section and
the address 0x14A
is in the middle of the previous .text
section. So I miss the
.text
data after address 0x14A
. This does not seem to be the case with the Intel hex files.
I expect this address to be the exact half of the non-interleaved one, so
0x294
.
Versions
GNU objcopy (GNU Binutils) 2.43.1
riscv32-unknown-elf-gcc (g04696df0963) 14.2.0
Elf, Intel Hex and Verilog files: riscv-toolchain-issue-address-shift.zip
I first build a Intel Hex file with --adjust-vma -0xffffc000 --only-section .text --only-section .rodata --pad-to=0x2000 --output-format ihex
and then split.
--output-format ihex --interleave-width 2 --interleave=4 --byte [0|2] path/to_intel.hex
--reverse-bytes=2 --output-format verilog --verilog-data-width 2 --interleave-width 2 --interleave=4 path/to_intel.hex
The reverse-bytes is to interpret the byte order correctly. It surprises me a bit that this is necessary, but at least it
works now.
Even with the workaround I got a new Problem: I might have a .data
section as well. If I just add the
.data
to the --only-section
commands, the 0x00 padding with
--pad-to=0x2000
only works when the .data
section is not empty. Otherwise no padding will happen. I also had the situation where objcopy wrote a gigabyte big file with 0x00 but I cannot reproduce it currently.
Test if .data
section is empty or not.
As I do have the workarounds I don't expect any bugfixes and unforutantelly I don't have the time to look at the source code myself, but I just want to let you know :)
[Prev in Thread] | Current Thread | [Next in Thread] |