LLVM: lib/ExecutionEngine/JITLink/ELF_aarch32.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14

23

26

27#define DEBUG_TYPE "jitlink"

28

30

31namespace llvm {

33

34

35LLVM_ABI Expectedaarch32::EdgeKind\_aarch32

38 case ELF::R_ARM_ABS32:

40 case ELF::R_ARM_GOT_PREL:

42 case ELF::R_ARM_REL32:

44 case ELF::R_ARM_CALL:

46 case ELF::R_ARM_JUMP24:

48 case ELF::R_ARM_MOVW_ABS_NC:

50 case ELF::R_ARM_MOVT_ABS:

52 case ELF::R_ARM_NONE:

54 case ELF::R_ARM_PREL31:

56 case ELF::R_ARM_TARGET1:

59 case ELF::R_ARM_THM_CALL:

61 case ELF::R_ARM_THM_JUMP24:

63 case ELF::R_ARM_THM_MOVW_ABS_NC:

65 case ELF::R_ARM_THM_MOVT_ABS:

67 case ELF::R_ARM_THM_MOVW_PREL_NC:

69 case ELF::R_ARM_THM_MOVT_PREL:

71 }

72

74 "Unsupported aarch32 relocation " + formatv("{0:d}: ", ELFType) +

76}

77

78

82 return ELF::R_ARM_REL32;

84 return ELF::R_ARM_ABS32;

86 return ELF::R_ARM_PREL31;

88 return ELF::R_ARM_GOT_PREL;

90 return ELF::R_ARM_CALL;

92 return ELF::R_ARM_JUMP24;

94 return ELF::R_ARM_MOVW_ABS_NC;

96 return ELF::R_ARM_MOVT_ABS;

98 return ELF::R_ARM_THM_CALL;

100 return ELF::R_ARM_THM_JUMP24;

102 return ELF::R_ARM_THM_MOVW_ABS_NC;

104 return ELF::R_ARM_THM_MOVT_ABS;

106 return ELF::R_ARM_THM_MOVW_PREL_NC;

108 return ELF::R_ARM_THM_MOVT_PREL;

110 return ELF::R_ARM_NONE;

111 }

112

115}

116

117

122

125

126public:

132

133private:

135

138 }

139};

140

141template <llvm::endianness DataEndianness>

144private:

147

153 &Self::addSingleRelRelocation))

154 return Err;

155 }

157 }

158

159 Error addSingleRelRelocation(const typename ELFT::Rel &Rel,

160 const typename ELFT::Shdr &FixupSect,

161 Block &BlockToFix) {

162 uint32_t SymbolIndex = Rel.getSymbol(false);

164 if (!ObjSymbol)

165 return ObjSymbol.takeError();

166

168 if (!GraphSymbol)

170 formatv("Could not find symbol at given index, did you add it to "

171 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",

172 SymbolIndex, (*ObjSymbol)->st_shndx,

175

179 return Kind.takeError();

180

181 auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;

182 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();

183

186 if (!Addend)

188

191 dbgs() << " ";

193 dbgs() << "\n";

194 });

195

196 BlockToFix.addEdge(std::move(E));

198 }

199

201

202protected:

211

215 static constexpr uint64_t ThumbBit = 0x01;

217 return Sym.getValue() & ~ThumbBit;

219 }

220

221public:

224 std::shared_ptrorc::SymbolStringPool SSP,

228 std::move(Features), FileName,

230 ArmCfg(std::move(ArmCfg)) {}

231};

232

233template

236

237 StubsManagerType StubsManager;

241

243}

244

246 MemoryBufferRef ObjectBuffer, std::shared_ptrorc::SymbolStringPool SSP) {

248 dbgs() << "Building jitlink graph for new input "

250 });

251

253 if (!ELFObj)

254 return ELFObj.takeError();

255

256 auto Features = (*ELFObj)->getFeatures();

257 if (!Features)

258 return Features.takeError();

259

260

261 auto TT = (*ELFObj)->makeTriple();

263 if (AK == ARM::ArchKind::INVALID)

265 "Failed to build ELF link graph: Invalid ARM ArchKind");

266

267

268

269

272

273

274 switch (TT.getArch()) {

279 (*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,

280 std::move(*Features), ArmCfg)

282 }

287 (*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,

288 std::move(*Features), ArmCfg)

290 }

291 default:

293 "Failed to build ELF/aarch32 link graph: Invalid target triple " +

294 TT.getTriple());

295 }

296}

297

299 std::unique_ptr Ctx) {

300 const Triple &TT = G->getTargetTriple();

301

306

308 if (Ctx->shouldAddDefaultTargetPasses(TT)) {

309

310 if (auto MarkLive = Ctx->getMarkLivePass(TT))

311 PassCfg.PrePrunePasses.push_back(std::move(MarkLive));

312 else

314

315 switch (ArmCfg.Stubs) {

319 break;

323 break;

326 }

327 }

328

329 if (auto Err = Ctx->modifyPassConfig(*G, PassCfg))

330 return Ctx->notifyFailed(std::move(Err));

331

333 std::move(ArmCfg));

334}

335

336}

337}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

StringRef getBufferIdentifier() const

static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)

StringRef - Represent a constant reference to a string, i.e.

Manages the enabling and disabling of subtarget specific features.

Triple - Helper class for working with autoconf configuration names.

The instances of the Type class are immutable: once they are created, they are never changed.

orc::ExecutorAddr getAddress() const

An Addressable with content and edges.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

ELFJITLinker_aarch32(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassCfg, aarch32::ArmConfig ArmCfg)

Definition ELF_aarch32.cpp:127

std::unique_ptr< LinkGraph > G

Definition ELF_aarch32.cpp:143

TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) override

Definition ELF_aarch32.cpp:203

orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym, TargetFlagsType Flags) override

Definition ELF_aarch32.cpp:212

ELFLinkGraphBuilder_aarch32(StringRef FileName, const llvm::object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, aarch32::ArmConfig ArmCfg)

Definition ELF_aarch32.cpp:222

const ELFFile::Elf_Shdr * SymTabSec

Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func)

Traverse all matching ELFT::Rel relocation records in the given section.

virtual Error addRelocations()=0

ELFLinkGraphBuilder(const object::ELFFile< ELFType< DataEndianness, false > > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)

Expected< std::unique_ptr< LinkGraph > > buildGraph()

Attempt to construct and return the LinkGraph.

DenseMap< ELFSymbolIndex, Symbol * > GraphSymbols

ELFFile::Elf_Shdr_Range Sections

Symbol * getGraphSymbol(ELFSymbolIndex SymIndex)

Represents fixups and constraints in the LinkGraph.

static void link(ArgTs &&... Args)

Populate a Global Offset Table from edges that request it.

Represents an address in the executor process.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

LLVM_ABI ArchKind parseArch(StringRef Arch)

LLVM_ABI unsigned getArchAttr(ArchKind AK)

EdgeKind_aarch32

JITLink-internal AArch32 fixup kinds.

@ Data_RequestGOTAndTransformToDelta32

Create GOT entry and store offset.

@ Arm_MovtAbs

Write immediate value to the top halfword of the destination register.

@ Data_PRel31

Relative 31-bit value relocation that preserves the most-significant bit.

@ Data_Pointer32

Absolute 32-bit value relocation.

@ Arm_MovwAbsNC

Write immediate value to the lower halfword of the destination register.

@ Arm_Call

Write immediate value for unconditional PC-relative branch with link.

@ Thumb_MovtPrel

Write PC-relative immediate value to the top halfword of the destination register.

@ Thumb_Jump24

Write immediate value for PC-relative branch without link.

@ Arm_Jump24

Write immediate value for conditional PC-relative branch without link.

@ Thumb_MovwAbsNC

Write immediate value to the lower halfword of the destination register.

@ Data_Delta32

Relative 32-bit value relocation.

@ Thumb_Call

Write immediate value for unconditional PC-relative branch with link.

@ Thumb_MovtAbs

Write immediate value to the top halfword of the destination register.

@ Thumb_MovwPrelNC

Write PC-relative immediate value to the lower halfword of the destination register.

Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)

Apply fixup expression for edge to block content.

ArmConfig getArmConfigForCPUArch(ARMBuildAttrs::CPUArch CPUArch)

Obtain the sub-arch configuration for a given Arm CPU model.

LLVM_ABI const char * getEdgeKindName(Edge::Kind K)

Get a human-readable name for the given AArch32 edge kind.

Expected< int64_t > readAddend(LinkGraph &G, Block &B, Edge::OffsetT Offset, Edge::Kind Kind, const ArmConfig &ArmCfg)

Read the initial addend for a REL-type relocation.

LLVM_ABI Expected< uint32_t > getELFRelocationType(Edge::Kind Kind)

Translate from JITLink-internal edge kind back to ELF relocation type.

Definition ELF_aarch32.cpp:79

LLVM_ABI Expected< aarch32::EdgeKind_aarch32 > getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &ArmCfg)

Translate from ELF relocation type to JITLink-internal edge kind.

Definition ELF_aarch32.cpp:36

void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)

For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...

Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)

Create a LinkGraph from an ELF/arm relocatable object.

Definition ELF_aarch32.cpp:245

LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)

Marks all symbols in a graph live.

const char * getELFAArch32EdgeKindName(Edge::Kind R)

Get a human-readable name for the given ELF AArch32 edge kind.

Definition ELF_aarch32.cpp:118

uint8_t TargetFlagsType

Holds target-specific properties for a symbol.

Error buildTables_ELF_aarch32(LinkGraph &G)

Definition ELF_aarch32.cpp:234

LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)

void link_ELF_aarch32(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)

jit-link the given object buffer, which must be an ELF arm/thumb object file.

Definition ELF_aarch32.cpp:298

LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)

uint64_t ExecutorAddrDiff

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

Implement std::hash so that hash_code can be used in STL containers.

An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...

LinkGraphPassList PostPrunePasses

Post-prune passes.

LinkGraphPassList PrePrunePasses

Pre-prune passes.

JITLink sub-arch configuration for Arm CPU models.

Elf_Rel_Impl< ELFType< E, Is64 >, false > Rel

Elf_Shdr_Impl< ELFType< E, Is64 > > Shdr

Elf_Sym_Impl< ELFType< E, Is64 > > Sym

unsigned char getType() const

uint64_t getValue() const