Reputation: 22906
The following RISC-V assembly code (RV32) is used to show the problem.
start: jal end
end: jal start
I invoke the assembler using the following simple command...
riscv32-unknown-elf-as -m32 example.s -o example.o
To check the generated code I disassemble it...
riscv32-unknown-eft-objdump -D example.o
Which gives the following output...
00000000 <start>:
0: 004000ef jal 4 <end>
00000004 <end>
4: ffdff0ef jal 0 <start>
The first 'jal' has correctly indicated that it needs to add 4 to the PC in order to jump to the following line, which is address 4. (Note: the odd layout of the immediate value for the jal instruction means the actual value instruction encodes 2 which is then multiplied at the CPU by 2 to get the actual offset of 4). The second 'jal' has -2 as the offset. Again, with the CPU multiplying by 2 we can -4 as the offset.
I actually want to generate a raw output file that contains no ELF information and is made up of just 8 bytes, the 8 bytes that make up the two instructions. I am running directly against a microcontroller and that microcontroller is not running an operating system. I want the output to be flashed to non-volatile RAM which then executes at reset.
So I use the following linker command to generate the binary output...
riscv32-unknown-elf-ld --oformat=binary example.o -o example
But this seems to have lost the relative addressing values because using the following command to look at the generate output bytes...
xxd example
...gives the following result...
00000000: ef00 0000 eff0 ffff
Taking into account it is little endian it means that each set of four bytes is in reverse order compared to the disassembly seen earlier. We can can see the first jump '000000ef' has lost its jump offset. The second jump 'fffff0ef' is also different from before and after applying twos compliment we get -1, which is definitely wrong!
Any ideas how the jump offsets have been corrupted? Is there some extra option I need to specify to the linker to handle offsets correctly? I cannot find anything obvious and as a beginner to Linux and GNU I am stuck.
Upvotes: 2
Views: 838
Reputation: 22906
Turns out there is a bug in the linker and the workaround is to use...
riscv32-unknown-elf-objcopy -O binary example.o example
Upvotes: 1