Skip to content

Commit cc63893

Browse files
committed
[IRGen] Don't use GOTPCREL relocations for x86 ELF.
Unforunately, x86 ELF linkers like to optimize GOTPCREL relocations by replacing `mov` instructions that go via the GOT with `lea` instructions that do not. That would be fine, but they aren't very selective and will happily perform this transformation in non-code sections if they think that the bytes before a relocation look like a `mov` instruction. This corrupts our metadata. rdar://148168098
1 parent 6b3e2cd commit cc63893

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,13 +3736,15 @@ static llvm::GlobalVariable *createGOTEquivalent(IRGenModule &IGM,
37363736
llvm::GlobalValue::PrivateLinkage,
37373737
global,
37383738
llvm::Twine("got.") + globalName);
3739-
3739+
37403740
// rdar://problem/53836960: i386 ld64 also mis-links relative references
37413741
// to GOT entries.
37423742
// rdar://problem/59782487: issue with on-device JITd expressions.
37433743
// The JIT gets confused by private vars accessed across object files.
3744+
// rdar://148168098: ELF x86 GOTPCREL relaxation can break metadata.
37443745
if (!IGM.getOptions().UseJIT &&
3745-
(!IGM.Triple.isOSDarwin() || IGM.Triple.getArch() != llvm::Triple::x86)) {
3746+
(!IGM.Triple.isOSDarwin() || IGM.Triple.getArch() != llvm::Triple::x86) &&
3747+
(!IGM.Triple.isOSBinFormatELF() || !IGM.Triple.isX86())) {
37463748
gotEquivalent->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
37473749
} else {
37483750
ApplyIRLinkage(IRLinkage::InternalLinkOnceODR)

0 commit comments

Comments
 (0)