llvm-project
llvm-project copied to clipboard
ld.lld: error: relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC
t.cpp
#include <stdio.h>
#include "t.h"
TT::TT(const int a)
: n(a)
{
printf("{%s}[%s](%d) : %d\n", __FILE__, __func__, __LINE__, n);
}
m.cpp
#include <stdio.h>
#include "t.h"
int main()
{
int c = 100;
printf("{%s}[%s](%d) : %d\n", __FILE__, __func__, __LINE__, c);
TT *a = new TT(c);
printf("{%s}[%s](%d) : %p\n", __FILE__, __func__, __LINE__, a);
return 0;
}
t.h
class TT {
public:
//explicit TT(const int a);
TT(const int a);
~TT() {};
private:
int n {};
};
$ ../build/bin/clang++ -fPIC -mabi=32 -fuse-ld=lld -O3 -o a.out t.cpp m.cpp
ld.lld: error: relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC
>>> defined in /tmp/m-dc13fe.o
>>> referenced by m.cpp
>>> /tmp/m-dc13fe.o:(.eh_frame+0x2D)
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
$ ../build/bin/clang++ -fPIC -L/lib64 -mabi=64 -fuse-ld=lld -O3 -o a.out t.cpp m.cpp
ld.lld: error: relocation R_MIPS_64 cannot be used against local symbol; recompile with -fPIC
>>> defined in /tmp/m-627e22.o
>>> referenced by m.cpp
>>> /tmp/m-627e22.o:(.eh_frame+0x31)
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
ld.bfd works well.
@llvm/issue-subscribers-backend-mips
@llvm/issue-subscribers-lld-elf
This is a MIPS ABI bug or compiler bug.
One relocatable file has .eh_frame
referencing DW.ref.__gxx_personality
using the encoding DW_EH_PE_absptr
.
This encoding is wrong for PIC.
However, GNU ld works around the bug by converting this into DW_EH_PE_sdata4|DW_EH_PE_pcrel
.
ld.lld does not implement the hack, hence the error.
GCC and Clang should use DW_EH_PE_sdata4|DW_EH_PE_pcrel
to reference the personality symbol.
This is an incomplete solution for the problem - https://reviews.llvm.org/D80392. It solves the but but probably we need an option to turn on/off this feature.