Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ld.lld: error: relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC #58377

Closed
wzssyqa opened this issue Oct 15, 2022 · 5 comments · Fixed by #91291
Closed
Labels
llvm:codegen mc Machine (object) code

Comments

@wzssyqa
Copy link
Contributor

wzssyqa commented Oct 15, 2022

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)
@wzssyqa
Copy link
Contributor Author

wzssyqa commented Oct 15, 2022

ld.bfd works well.

@llvmbot
Copy link
Member

llvmbot commented Oct 15, 2022

@llvm/issue-subscribers-backend-mips

@llvmbot
Copy link
Member

llvmbot commented Oct 15, 2022

@llvm/issue-subscribers-lld-elf

@MaskRay
Copy link
Member

MaskRay commented Oct 20, 2022

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.

@atanasyan
Copy link
Collaborator

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.

wzssyqa added a commit to wzssyqa/llvm-project that referenced this issue May 7, 2024
Gas uses encoding DW_EH_PE_absptr for PIC, and gnu ld converts it
to DW_EH_PE_sdata4|DW_EH_PE_pcrel.
LLD doesn't have this workarounding, thus complains
```
  relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC
  relocation R_MIPS_64 cannot be used against local symbol; recompile with -fPIC
```

So, let's generates asm/obj files with `DW_EH_PE_sdata4|DW_EH_PE_pcrel`
encoding. In fact, GNU ld supports such OBJs well.

For N64, maybe we should use sdata8, while GNU ld doesn't support it well,
and in fact sdata4 is enough now.

Fixes: llvm#58377.
wzssyqa added a commit to wzssyqa/llvm-project that referenced this issue May 7, 2024
Gas uses encoding DW_EH_PE_absptr for PIC, and gnu ld converts it
to DW_EH_PE_sdata4|DW_EH_PE_pcrel.
LLD doesn't have this workarounding, thus complains
```
  relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC
  relocation R_MIPS_64 cannot be used against local symbol; recompile with -fPIC
```

So, let's generates asm/obj files with `DW_EH_PE_sdata4|DW_EH_PE_pcrel`
encoding. In fact, GNU ld supports such OBJs well.

For N64, maybe we should use sdata8, while GNU ld doesn't support it well,
and in fact sdata4 is enough now. So we just ignore the `Large` for
`MCObjectFileInfo::initELFMCObjectFileInfo`. Maybe we should switch
back to sdata8 once GNU LD supports it well.

Fixes: llvm#58377.
wzssyqa added a commit that referenced this issue May 8, 2024
Gas uses encoding DW_EH_PE_absptr for PIC, and gnu ld converts it to
DW_EH_PE_sdata4|DW_EH_PE_pcrel.
LLD doesn't have this workarounding, thus complains
```
  relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC
  relocation R_MIPS_64 cannot be used against local symbol; recompile with -fPIC
```

So, let's generates asm/obj files with `DW_EH_PE_sdata4|DW_EH_PE_pcrel`
encoding. In fact, GNU ld supports such OBJs well.

For N64, maybe we should use sdata8, while GNU ld doesn't support it
well, and in fact sdata4 is enough now. So we just ignore the `Large`
for `MCObjectFileInfo::initELFMCObjectFileInfo`. Maybe we should switch
back to sdata8 once GNU LD supports it well.

Fixes: #58377.
@EugeneZelenko EugeneZelenko added llvm:codegen mc Machine (object) code and removed backend:MIPS lld:ELF labels May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:codegen mc Machine (object) code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants