-
Notifications
You must be signed in to change notification settings - Fork 82
Description
Sometimes, GAS will produce incorrect instructions for %hi directives. I'm unsure of the exact cause,
but it seems there have been numerous relocation bugs addressed in future releases of GCC
(e.g. https://sourceware.org/legacy-ml/binutils/2006-11/msg00055.html for problems with global offsets).
Removing other relocations may fix the problem or cause new problems on different lines.
I've attached an input file which generates incorrect results for a couple %hi directives.
On line 399526, operation "lui $v0, %hi(dword_647648)" (dword_647648 being a symbol which is
located at address 0x647648 after assembly) will produce "lui $v0, 0x65" (located at 117800h in output).
The corresponding %lo operation, "sw $a0, %lo(dword_647648)($v0)", is assembled correctly ("sw $a0, 0x7648($v0)").
On line 400157, operation "lui $v0, %hi(byte_64764D)" (byte_64764D being a symbol which is located at address 0x64764D after assembly) will produce "lui $v0, 0x65" (located at 117F40h in output).
The corresponding %lo operation, "sb $zero, %lo(byte_64764D)($v0)", is assembled correctly ("sb $zero, 0x764D($v0)").
Notice that on lines 400152 and 400156, the hi bits of symbols immediately before and after
byte_64764D are loaded; however, these are accurately assembled as lui instructions with the immediate 0x64.
I'm assembling the file with the command "ee-gcc -o output.elf input.s &> output.txt -nostartfiles -nostdlib".