AArch32 branch offsets explicitly encode the target instruction subset (Arm/Thumb) in their least significant bit. We want this bit set (or clear) in addreses we hand out, but the addresses in the LinkGraph should be the real/physical addresses.
This patch allows ELFLinkGraphBuilder's to set target-specific flags in jitlink::Symbol and prepares ObjectLinkingLayer to account for them.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D146641
// must end with a zero, and contain no zeros before the end.
bool isCStringBlock(Block &B);
-/// Describes symbol linkage. This can be used to make resolve definition
-/// clashes.
+/// Describes symbol linkage. This can be used to resolve definition clashes.
enum class Linkage : uint8_t {
Strong,
Weak,
};
+/// Holds target-specific properties for a symbol.
+using TargetFlagsType = uint8_t;
+
/// For errors and debugging output.
const char *getLinkageName(Linkage L);
this->S = static_cast<uint8_t>(S);
}
+ /// Check wehther the given target flags are set for this Symbol.
+ bool hasTargetFlags(TargetFlagsType Flags) const {
+ return static_cast<TargetFlagsType>(TargetFlags) & Flags;
+ }
+
+ /// Set the target flags for this Symbol.
+ void setTargetFlags(TargetFlagsType Flags) {
+ assert(Flags <= 1 && "Add more bits to store more than single flag");
+ TargetFlags = Flags;
+ }
+
/// Returns true if this is a weakly referenced external symbol.
/// This method may only be called on external symbols.
bool isWeaklyReferenced() const {
// FIXME: A char* or SymbolStringPtr may pack better.
StringRef Name;
Addressable *Base = nullptr;
- uint64_t Offset : 58;
+ uint64_t Offset : 57;
uint64_t L : 1;
uint64_t S : 2;
uint64_t IsLive : 1;
uint64_t IsCallable : 1;
uint64_t WeakRef : 1;
+ uint64_t TargetFlags : 1;
size_t Size = 0;
};
Expected<std::pair<Linkage, Scope>>
getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
+ /// Set the target flags on the given Symbol.
+ virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
+ return TargetFlagsType{};
+ }
+
+ /// Get the physical offset of the symbol on the target platform.
+ virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
+ TargetFlagsType Flags) {
+ return Sym.getValue();
+ }
+
Error prepare();
Error graphifySections();
Error graphifySymbols();
<< "\"\n";
});
+ TargetFlagsType Flags = makeTargetFlags(Sym);
+ orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
+
// In RISCV, temporary symbols (Used to generate dwarf, eh_frame
// sections...) will appear in object code's symbol table, and LLVM does
// not use names on these temporary symbols (RISCV gnu toolchain uses
// anonymous symbol.
auto &GSym =
Name->empty()
- ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
+ ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
false, false)
- : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
- S, Sym.getType() == ELF::STT_FUNC, false);
+ : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
+ S, Sym.getType() == ELF::STT_FUNC,
+ false);
+
+ GSym.setTargetFlags(Flags);
setGraphSymbol(SymIndex, GSym);
}
} else if (Sym.isUndefined() && Sym.isExternal()) {
return false;
}
+JITTargetAddress getJITSymbolPtrForSymbol(Symbol &Sym) {
+ return Sym.getAddress().getValue();
+}
+
JITSymbolFlags getJITSymbolFlagsForSymbol(Symbol &Sym) {
JITSymbolFlags Flags;
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && Sym->getScope() != Scope::Local) {
auto InternedName = ES.intern(Sym->getName());
+ auto Ptr = getJITSymbolPtrForSymbol(*Sym);
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
-
- InternedResult[InternedName] =
- JITEvaluatedSymbol(Sym->getAddress().getValue(), Flags);
+ InternedResult[InternedName] = JITEvaluatedSymbol(Ptr, Flags);
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
"Duplicate symbol to claim?");
for (auto *Sym : G.absolute_symbols())
if (Sym->hasName() && Sym->getScope() != Scope::Local) {
auto InternedName = ES.intern(Sym->getName());
+ auto Ptr = getJITSymbolPtrForSymbol(*Sym);
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
- InternedResult[InternedName] =
- JITEvaluatedSymbol(Sym->getAddress().getValue(), Flags);
+ InternedResult[InternedName] = JITEvaluatedSymbol(Ptr, Flags);
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
"Duplicate symbol to claim?");