Hi All,
On lld “LLD 14.0.5 (compatible with GNU linkers)” target 32-bit mips freebsd, when creating relocatable object using -r, lld assigns wrong offset when placing .o on certain position between other .o files. Issue doesnt exist if gnu linker is used for it.
/llvm-project/build/bin/ld.lld -o test.co -r <list of .o> problem.o <list of .o>
problem.c
static foo()
{ … }
bar()
{
// Assign foo to function pointer
fnptr = foo;
}
In problem.o the offset was fine
000001a4 foo:
000002b8 bar:
2e0: 3c 02 00 00 lui $2, 0
2e4: 24 42 01 a4 addiu $2, $2, 420
2e8: af a2 00 40 sw $2, 64($sp)
(gdb) p/x 420
$1 = 0x1a4
But after creating relocatable with -r and checking on the disassembly of test.co
000180f4 foo:
xxxxxxxx bar:
181cc: 3c 02 00 01 lui $2, 1
181d0: 24 42 80 f4 addiu $2, $2, -32524
(gdb) p/x 0x10000 -32524
$1 = 0x80f4 <<< It assigned 0x80f4 instead of 0x000180f4 and hence a calculation mistake
But if we move the position of problem.o little before or after. The calculation becomes correct.
e.g.,
00017764 foo:
xxxxxxxx bar:
178a0: 3c 02 00 01 lui $2, 1
178a4: 24 42 77 64 addiu $2, $2, 30564
(gdb) p/x 0x10000 + 30564
$1 = 0x17764
The problem is bit difficult to reproduce with sample test. Can someone please point out where could be the issue or where these offset fixup are performed during partial linking.
Thanks,
Karan