[PATCH] D43952: [ELF][MIPS] Don't change every dynamic relocation into R_MIPS_REL32
Alexander Richardson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 2 06:55:34 PST 2018
arichardson planned changes to this revision.
arichardson added a comment.
Turns out we can't emit R_MIPS_64 absolute relocations that don't need the GOT since neither glibc nor FreeBSD handle a R_MIPS_64 dynamic relocations.
I wonder if we should emit a R_MIPS_GLOB_DAT for unresolved symbols since that will always look in the global part of the GOT.
Comment at: test/ELF/mips-32.s:51
# REL-NEXT: 0x20008 R_MIPS_REL32 - 0x0
-# REL-NEXT: 0x20004 R_MIPS_REL32 v2 0x0
+# REL-NEXT: 0x20004 R_MIPS_32 v2 0x0
# REL-NEXT: }
> I have not had a time for deep investigation yet, but both bfd and gold linker emit two R_MIPS_REL32 relocations for that test case. It looks like either a bug in GNU tools or problem in this fix.
It appears that while this fixes my issue it is not the actually correct fix. Emitting R_MIPS_REL32 is the correct thing because of the MIPS ABI:
R_MIPS_REL32 relocation depends on its r_symndx value. If the relocation r_symndx is less than DT_MIPS_GOTSYM, the value of EA is the symbol st_value plus displacement. Otherwise, the value of EA is the value in the GOT entry corresponding to the relocation entry r_symndx. The correspondence between the GOT and the dynamic symbol table is described in the "Global Offset Table" section in Chapter 5.
For some reason the `r_symndx` in my case ended up being less than DT_MIPS_GOTSYM even though it was referencing a preemptible symbol. Therefore it would only add the load address instead of the resolved value from the GOT. I will try to reduce my testcase (unfortunately it's libc.so, so it could take a while) to find out why I ended up getting the wrong value.
However, I don't really understand why we need to add a relocation in the GOT just to write an absolute data symbol. I believe emitting a R_MIPS_64 relocation should result in the same runtime value being stored but we don't need the additional GOT slot.
rLLD LLVM Linker
More information about the llvm-commits