As discussed in a previous checking to support the .localentry
directive on PowerPC, we need to inspect the actual target symbol
in needsRelocateWithSymbol to make the appropriate decision based
on that symbol's st_other bits.
Currently, needsRelocateWithSymbol does not get the target symbol.
However, it is directly available to its sole caller. This patch
therefore simply extends the needsRelocateWithSymbol by a new
parameter "const MCSymbolData &SD", passes in the target symbol,
and updates all derived implementations.
In particular, in the PowerPC implementation, this patch removes
the FIXME added by the previous checkin.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213487
91177308-0d34-0410-b5e6-
96231b3b80d8
class MCObjectWriter;
class MCSectionData;
class MCSymbol;
+class MCSymbolData;
class MCValue;
class MCELFObjectTargetWriter {
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const = 0;
- virtual bool needsRelocateWithSymbol(unsigned Type) const;
+ virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const;
/// @name Accessors
/// @{
if (Asm.isThumbFunc(&Sym))
return true;
- if (TargetObjectWriter->needsRelocateWithSymbol(Type))
+ if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type))
return true;
return false;
}
IsN64(IsN64_){
}
-bool MCELFObjectTargetWriter::needsRelocateWithSymbol(unsigned Type) const {
+bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
return false;
}
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const override;
- bool needsRelocateWithSymbol(unsigned Type) const override;
+ bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const override;
};
}
ARMELFObjectWriter::~ARMELFObjectWriter() {}
-bool ARMELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const {
+bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
// FIXME: This is extremelly conservative. This really needs to use a
// whitelist with a clear explanation for why each realocation needs to
// point to the symbol, not to the section.
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const override;
- bool needsRelocateWithSymbol(unsigned Type) const override;
+ bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const override;
};
}
}
bool
-MipsELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const {
+MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
// FIXME: This is extremelly conservative. This really needs to use a
// whitelist with a clear explanation for why each realocation needs to
// point to the symbol, not to the section.
#include "MCTargetDesc/PPCFixupKinds.h"
#include "MCTargetDesc/PPCMCExpr.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const override;
- bool needsRelocateWithSymbol(unsigned Type) const override;
+ bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const override;
};
}
return getRelocTypeInner(Target, Fixup, IsPCRel);
}
-bool PPCELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const {
+bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
switch (Type) {
default:
return false;
case ELF::R_PPC_REL24:
- // FIXME: We only need to keep the target symbol of the relocation
- // if the symbol uses a local entry point. Unfortunately, we do not
- // have access to the symbol here ...
- return true;
+ // If the target symbol has a local entry point, we must keep the
+ // target symbol to preserve that information for the linker.
+ // The "other" values are stored in the last 6 bits of the second byte.
+ // The traditional defines for STO values assume the full byte and thus
+ // the shift to pack it.
+ unsigned Other = MCELF::getOther(SD) << 2;
+ return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
}
}
nop
.size caller, .-caller
+ .section .text.other
+caller_other:
+ bl callee1
+ nop
+ bl callee2
+ nop
+ .size caller_other, .-caller_other
+
# Verify that use of .localentry implies ABI version 2
# CHECK: ElfHeader {
# CHECK: Flags [ (0x2)
# CHECK-NEXT: R_PPC64_REL24 callee1
# CHECK-NEXT: }
# CHECK-NOT: R_PPC64_REL24 callee2
+# CHECK: Section ({{[0-9]*}}) .rela.text.other {
+# CHECK-NEXT: R_PPC64_REL24 callee1
+# CHECK-NEXT: R_PPC64_REL24 .text
+# CHECK-NEXT: }
# Verify that .localentry is encoded in the Other field.
# CHECK: Symbols [