LLVM 23.0.0git
ELF_hexagon.cpp
Go to the documentation of this file.
1//===------ ELF_hexagon.cpp - JIT linker for ELF/hexagon ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// ELF/hexagon jit-link implementation.
10//
11//===----------------------------------------------------------------------===//
12
14#include "ELFLinkGraphBuilder.h"
15#include "JITLinkGeneric.h"
19
20#define DEBUG_TYPE "jitlink"
21
22using namespace llvm;
23using namespace llvm::jitlink;
24
25namespace {
26
27class ELFJITLinker_hexagon : public JITLinker<ELFJITLinker_hexagon> {
28 friend class JITLinker<ELFJITLinker_hexagon>;
29
30public:
31 ELFJITLinker_hexagon(std::unique_ptr<JITLinkContext> Ctx,
32 std::unique_ptr<LinkGraph> G,
33 PassConfiguration PassConfig)
34 : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
35
36private:
37 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
38 return hexagon::applyFixup(G, B, E);
39 }
40};
41
42class ELFLinkGraphBuilder_hexagon
43 : public ELFLinkGraphBuilder<object::ELF32LE> {
44private:
45 using ELFT = object::ELF32LE;
46
47 Expected<hexagon::EdgeKind_hexagon> getRelocationKind(const uint32_t Type) {
48 switch (Type) {
49 case ELF::R_HEX_32:
50 return hexagon::Pointer32;
51 case ELF::R_HEX_32_PCREL:
52 return hexagon::PCRel32;
53 case ELF::R_HEX_B22_PCREL:
54 case ELF::R_HEX_PLT_B22_PCREL:
55 // PLT and GD_PLT variants are mapped to plain branch edges since JITLink
56 // resolves all symbols directly within contiguous JIT memory. When the
57 // GOT/PLT stubs builder is added (see TODO in link_ELF_hexagon), these
58 // should map to a distinct edge kind that triggers stub generation.
59 // GD_PLT does not handle TLS __tls_get_addr calls.
60 case ELF::R_HEX_GD_PLT_B22_PCREL:
61 return hexagon::B22_PCREL;
62 case ELF::R_HEX_B15_PCREL:
63 return hexagon::B15_PCREL;
64 case ELF::R_HEX_B13_PCREL:
65 return hexagon::B13_PCREL;
66 case ELF::R_HEX_B9_PCREL:
67 return hexagon::B9_PCREL;
68 case ELF::R_HEX_B7_PCREL:
69 return hexagon::B7_PCREL;
70 case ELF::R_HEX_HI16:
71 return hexagon::HI16;
72 case ELF::R_HEX_LO16:
73 return hexagon::LO16;
74 case ELF::R_HEX_32_6_X:
76 case ELF::R_HEX_B32_PCREL_X:
77 case ELF::R_HEX_GD_PLT_B32_PCREL_X: // See PLT/GD_PLT note above.
79 case ELF::R_HEX_B22_PCREL_X:
80 case ELF::R_HEX_GD_PLT_B22_PCREL_X: // See PLT/GD_PLT note above.
82 case ELF::R_HEX_B15_PCREL_X:
84 case ELF::R_HEX_B13_PCREL_X:
86 case ELF::R_HEX_B9_PCREL_X:
88 case ELF::R_HEX_B7_PCREL_X:
90 case ELF::R_HEX_6_X:
91 return hexagon::Word6_X;
92 case ELF::R_HEX_6_PCREL_X:
94 case ELF::R_HEX_8_X:
95 return hexagon::Word8_X;
96 case ELF::R_HEX_9_X:
97 return hexagon::Word9_X;
98 case ELF::R_HEX_10_X:
99 return hexagon::Word10_X;
100 case ELF::R_HEX_11_X:
101 return hexagon::Word11_X;
102 case ELF::R_HEX_12_X:
103 return hexagon::Word12_X;
104 case ELF::R_HEX_16_X:
105 return hexagon::Word16_X;
106 }
107
109 "In " + G->getName() + ": Unsupported Hexagon relocation type " +
111 }
112
113 Error addRelocations() override {
114 LLVM_DEBUG(dbgs() << "Adding relocations\n");
116 using Self = ELFLinkGraphBuilder_hexagon;
117
118 for (const auto &RelSect : Base::Sections) {
119 // Hexagon uses SHT_RELA.
120 if (RelSect.sh_type == ELF::SHT_REL)
122 "Unexpected SHT_REL section in Hexagon ELF object",
124
125 if (Error Err = Base::forEachRelaRelocation(RelSect, this,
126 &Self::addSingleRelocation))
127 return Err;
128 }
129
130 return Error::success();
131 }
132
133 Error addSingleRelocation(const typename ELFT::Rela &Rel,
134 const typename ELFT::Shdr &FixupSection,
135 Block &BlockToFix) {
137
138 auto ELFReloc = Rel.getType(false);
139
140 if (LLVM_UNLIKELY(ELFReloc == ELF::R_HEX_NONE))
141 return Error::success();
142
143 uint32_t SymbolIndex = Rel.getSymbol(false);
144 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
145 if (!ObjSymbol)
146 return ObjSymbol.takeError();
147
148 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
149 if (!GraphSymbol)
151 formatv("Could not find symbol at given index, did you add it to "
152 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
153 SymbolIndex, (*ObjSymbol)->st_shndx,
154 Base::GraphSymbols.size()),
156
157 Expected<hexagon::EdgeKind_hexagon> Kind = getRelocationKind(ELFReloc);
158 if (!Kind)
159 return Kind.takeError();
160
161 auto FixupAddress = orc::ExecutorAddr(FixupSection.sh_addr) + Rel.r_offset;
162 int64_t Addend = Rel.r_addend;
163
164 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
165 Edge GE(*Kind, Offset, *GraphSymbol, Addend);
166 LLVM_DEBUG({
167 dbgs() << " ";
168 printEdge(dbgs(), BlockToFix, GE, hexagon::getEdgeKindName(*Kind));
169 dbgs() << "\n";
170 });
171
172 BlockToFix.addEdge(std::move(GE));
173 return Error::success();
174 }
175
176public:
177 ELFLinkGraphBuilder_hexagon(StringRef FileName,
178 const object::ELFFile<ELFT> &Obj,
179 std::shared_ptr<orc::SymbolStringPool> SSP,
180 Triple TT, SubtargetFeatures Features)
181 : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
182 std::move(Features), FileName,
184};
185
186} // anonymous namespace
187
188namespace llvm::jitlink {
189
191 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
192 LLVM_DEBUG({
193 dbgs() << "Building jitlink graph for new input "
194 << ObjectBuffer.getBufferIdentifier() << "...\n";
195 });
196
197 auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);
198 if (!ELFObj)
199 return ELFObj.takeError();
200
201 auto Features = (*ELFObj)->getFeatures();
202 if (!Features)
203 return Features.takeError();
204
205 assert((*ELFObj)->getArch() == Triple::hexagon &&
206 "Only Hexagon is supported");
207
208 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
209
210 return ELFLinkGraphBuilder_hexagon(
211 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
212 (*ELFObj)->makeTriple(), std::move(*Features))
213 .buildGraph();
214}
215
216void link_ELF_hexagon(std::unique_ptr<LinkGraph> G,
217 std::unique_ptr<JITLinkContext> Ctx) {
218 PassConfiguration Config;
219 const Triple &TT = G->getTargetTriple();
220 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
221 // TODO: Add GOT/PLT stubs builder when external symbol support is needed.
222 // TODO: Add eh-frame passes when exception handling support is needed.
223 if (auto MarkLive = Ctx->getMarkLivePass(TT))
224 Config.PrePrunePasses.push_back(std::move(MarkLive));
225 else
226 Config.PrePrunePasses.push_back(markAllSymbolsLive);
227 }
228 if (auto Err = Ctx->modifyPassConfig(*G, Config))
229 return Ctx->notifyFailed(std::move(Err));
230
231 ELFJITLinker_hexagon::link(std::move(Ctx), std::move(G), std::move(Config));
232}
233
234} // namespace llvm::jitlink
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")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
#define G(x, y, z)
Definition MD5.cpp:55
#define LLVM_DEBUG(...)
Definition Debug.h:114
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
StringRef getBufferIdentifier() const
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Represents an address in the executor process.
@ EM_HEXAGON
Definition ELF.h:262
@ SHT_REL
Definition ELF.h:1156
LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition ELF.cpp:25
ELFType< llvm::endianness::little, false > ELF32LE
Definition ELFTypes.h:110
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
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.
Definition Debug.cpp:207
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Elf_Rel_Impl< ELFType< E, Is64 >, true > Rela
Definition ELFTypes.h:78
Elf_Shdr_Impl< ELFType< E, Is64 > > Shdr
Definition ELFTypes.h:73