xref: /llvm-project/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp (revision 2ccf7ed277df28651b94bbee9fccefdf22fb074f)
15c1d160cSStefan Gränitz //===----- ELF_aarch32.cpp - JIT linker implementation for arm/thumb ------===//
25c1d160cSStefan Gränitz //
35c1d160cSStefan Gränitz // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45c1d160cSStefan Gränitz // See https://llvm.org/LICENSE.txt for license information.
55c1d160cSStefan Gränitz // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65c1d160cSStefan Gränitz //
75c1d160cSStefan Gränitz //===----------------------------------------------------------------------===//
85c1d160cSStefan Gränitz //
95c1d160cSStefan Gränitz // ELF/aarch32 jit-link implementation.
105c1d160cSStefan Gränitz //
115c1d160cSStefan Gränitz //===----------------------------------------------------------------------===//
125c1d160cSStefan Gränitz 
135c1d160cSStefan Gränitz #include "llvm/ExecutionEngine/JITLink/ELF_aarch32.h"
145c1d160cSStefan Gränitz 
155c1d160cSStefan Gränitz #include "llvm/BinaryFormat/ELF.h"
165c1d160cSStefan Gränitz #include "llvm/ExecutionEngine/JITLink/JITLink.h"
175c1d160cSStefan Gränitz #include "llvm/ExecutionEngine/JITLink/aarch32.h"
185c1d160cSStefan Gränitz #include "llvm/Object/ELF.h"
195c1d160cSStefan Gränitz #include "llvm/Object/ELFObjectFile.h"
205c1d160cSStefan Gränitz #include "llvm/Support/ErrorHandling.h"
215c1d160cSStefan Gränitz #include "llvm/TargetParser/ARMTargetParser.h"
225c1d160cSStefan Gränitz 
235c1d160cSStefan Gränitz #include "ELFLinkGraphBuilder.h"
245c1d160cSStefan Gränitz #include "JITLinkGeneric.h"
255c1d160cSStefan Gränitz 
265c1d160cSStefan Gränitz #define DEBUG_TYPE "jitlink"
275c1d160cSStefan Gränitz 
285c1d160cSStefan Gränitz using namespace llvm::object;
295c1d160cSStefan Gränitz 
305c1d160cSStefan Gränitz namespace llvm {
315c1d160cSStefan Gränitz namespace jitlink {
325c1d160cSStefan Gränitz 
335c1d160cSStefan Gränitz /// Translate from ELF relocation type to JITLink-internal edge kind.
34bfb09326SStefan Gränitz Expected<aarch32::EdgeKind_aarch32>
35bfb09326SStefan Gränitz getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &ArmCfg) {
365c1d160cSStefan Gränitz   switch (ELFType) {
37a05a98a2SStefan Gränitz   case ELF::R_ARM_ABS32:
38a05a98a2SStefan Gränitz     return aarch32::Data_Pointer32;
39c4fc563bSStefan Gränitz   case ELF::R_ARM_GOT_PREL:
40c4fc563bSStefan Gränitz     return aarch32::Data_RequestGOTAndTransformToDelta32;
415c1d160cSStefan Gränitz   case ELF::R_ARM_REL32:
425c1d160cSStefan Gränitz     return aarch32::Data_Delta32;
435c1d160cSStefan Gränitz   case ELF::R_ARM_CALL:
445c1d160cSStefan Gränitz     return aarch32::Arm_Call;
4562f793ecSEymen Ünay   case ELF::R_ARM_JUMP24:
4662f793ecSEymen Ünay     return aarch32::Arm_Jump24;
47e575b7cbSEymen Ünay   case ELF::R_ARM_MOVW_ABS_NC:
48e575b7cbSEymen Ünay     return aarch32::Arm_MovwAbsNC;
49e575b7cbSEymen Ünay   case ELF::R_ARM_MOVT_ABS:
50e575b7cbSEymen Ünay     return aarch32::Arm_MovtAbs;
51565470edSStefan Gränitz   case ELF::R_ARM_NONE:
52565470edSStefan Gränitz     return aarch32::None;
539577806bSStefan Gränitz   case ELF::R_ARM_PREL31:
549577806bSStefan Gränitz     return aarch32::Data_PRel31;
55bfb09326SStefan Gränitz   case ELF::R_ARM_TARGET1:
56bfb09326SStefan Gränitz     return (ArmCfg.Target1Rel) ? aarch32::Data_Delta32
57bfb09326SStefan Gränitz                                : aarch32::Data_Pointer32;
585c1d160cSStefan Gränitz   case ELF::R_ARM_THM_CALL:
595c1d160cSStefan Gränitz     return aarch32::Thumb_Call;
605c1d160cSStefan Gränitz   case ELF::R_ARM_THM_JUMP24:
615c1d160cSStefan Gränitz     return aarch32::Thumb_Jump24;
625c1d160cSStefan Gränitz   case ELF::R_ARM_THM_MOVW_ABS_NC:
635c1d160cSStefan Gränitz     return aarch32::Thumb_MovwAbsNC;
645c1d160cSStefan Gränitz   case ELF::R_ARM_THM_MOVT_ABS:
655c1d160cSStefan Gränitz     return aarch32::Thumb_MovtAbs;
6687081f1cSEymen Ünay   case ELF::R_ARM_THM_MOVW_PREL_NC:
6787081f1cSEymen Ünay     return aarch32::Thumb_MovwPrelNC;
6887081f1cSEymen Ünay   case ELF::R_ARM_THM_MOVT_PREL:
6987081f1cSEymen Ünay     return aarch32::Thumb_MovtPrel;
705c1d160cSStefan Gränitz   }
715c1d160cSStefan Gränitz 
725c1d160cSStefan Gränitz   return make_error<JITLinkError>(
735c1d160cSStefan Gränitz       "Unsupported aarch32 relocation " + formatv("{0:d}: ", ELFType) +
745c1d160cSStefan Gränitz       object::getELFRelocationTypeName(ELF::EM_ARM, ELFType));
755c1d160cSStefan Gränitz }
765c1d160cSStefan Gränitz 
775c1d160cSStefan Gränitz /// Translate from JITLink-internal edge kind back to ELF relocation type.
785c1d160cSStefan Gränitz Expected<uint32_t> getELFRelocationType(Edge::Kind Kind) {
795c1d160cSStefan Gränitz   switch (static_cast<aarch32::EdgeKind_aarch32>(Kind)) {
805c1d160cSStefan Gränitz   case aarch32::Data_Delta32:
815c1d160cSStefan Gränitz     return ELF::R_ARM_REL32;
82a05a98a2SStefan Gränitz   case aarch32::Data_Pointer32:
83a05a98a2SStefan Gränitz     return ELF::R_ARM_ABS32;
849577806bSStefan Gränitz   case aarch32::Data_PRel31:
859577806bSStefan Gränitz     return ELF::R_ARM_PREL31;
86c4fc563bSStefan Gränitz   case aarch32::Data_RequestGOTAndTransformToDelta32:
87c4fc563bSStefan Gränitz     return ELF::R_ARM_GOT_PREL;
885c1d160cSStefan Gränitz   case aarch32::Arm_Call:
895c1d160cSStefan Gränitz     return ELF::R_ARM_CALL;
9062f793ecSEymen Ünay   case aarch32::Arm_Jump24:
9162f793ecSEymen Ünay     return ELF::R_ARM_JUMP24;
92e575b7cbSEymen Ünay   case aarch32::Arm_MovwAbsNC:
93e575b7cbSEymen Ünay     return ELF::R_ARM_MOVW_ABS_NC;
94e575b7cbSEymen Ünay   case aarch32::Arm_MovtAbs:
95e575b7cbSEymen Ünay     return ELF::R_ARM_MOVT_ABS;
965c1d160cSStefan Gränitz   case aarch32::Thumb_Call:
975c1d160cSStefan Gränitz     return ELF::R_ARM_THM_CALL;
985c1d160cSStefan Gränitz   case aarch32::Thumb_Jump24:
995c1d160cSStefan Gränitz     return ELF::R_ARM_THM_JUMP24;
1005c1d160cSStefan Gränitz   case aarch32::Thumb_MovwAbsNC:
1015c1d160cSStefan Gränitz     return ELF::R_ARM_THM_MOVW_ABS_NC;
1025c1d160cSStefan Gränitz   case aarch32::Thumb_MovtAbs:
1035c1d160cSStefan Gränitz     return ELF::R_ARM_THM_MOVT_ABS;
10487081f1cSEymen Ünay   case aarch32::Thumb_MovwPrelNC:
10587081f1cSEymen Ünay     return ELF::R_ARM_THM_MOVW_PREL_NC;
10687081f1cSEymen Ünay   case aarch32::Thumb_MovtPrel:
10787081f1cSEymen Ünay     return ELF::R_ARM_THM_MOVT_PREL;
108565470edSStefan Gränitz   case aarch32::None:
109565470edSStefan Gränitz     return ELF::R_ARM_NONE;
1105c1d160cSStefan Gränitz   }
1115c1d160cSStefan Gränitz 
1125c1d160cSStefan Gränitz   return make_error<JITLinkError>(formatv("Invalid aarch32 edge {0:d}: ",
1135c1d160cSStefan Gränitz                                           Kind));
1145c1d160cSStefan Gränitz }
1155c1d160cSStefan Gränitz 
1165c1d160cSStefan Gränitz /// Get a human-readable name for the given ELF AArch32 edge kind.
1175c1d160cSStefan Gränitz const char *getELFAArch32EdgeKindName(Edge::Kind R) {
1185c1d160cSStefan Gränitz   // No ELF-specific edge kinds yet
1195c1d160cSStefan Gränitz   return aarch32::getEdgeKindName(R);
1205c1d160cSStefan Gränitz }
1215c1d160cSStefan Gränitz 
1225c1d160cSStefan Gränitz class ELFJITLinker_aarch32 : public JITLinker<ELFJITLinker_aarch32> {
1235c1d160cSStefan Gränitz   friend class JITLinker<ELFJITLinker_aarch32>;
1245c1d160cSStefan Gränitz 
1255c1d160cSStefan Gränitz public:
1265c1d160cSStefan Gränitz   ELFJITLinker_aarch32(std::unique_ptr<JITLinkContext> Ctx,
1275c1d160cSStefan Gränitz                        std::unique_ptr<LinkGraph> G, PassConfiguration PassCfg,
1285c1d160cSStefan Gränitz                        aarch32::ArmConfig ArmCfg)
1295c1d160cSStefan Gränitz       : JITLinker(std::move(Ctx), std::move(G), std::move(PassCfg)),
1305c1d160cSStefan Gränitz         ArmCfg(std::move(ArmCfg)) {}
1315c1d160cSStefan Gränitz 
1325c1d160cSStefan Gränitz private:
1335c1d160cSStefan Gränitz   aarch32::ArmConfig ArmCfg;
1345c1d160cSStefan Gränitz 
1355c1d160cSStefan Gränitz   Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
1365c1d160cSStefan Gränitz     return aarch32::applyFixup(G, B, E, ArmCfg);
1375c1d160cSStefan Gränitz   }
1385c1d160cSStefan Gränitz };
1395c1d160cSStefan Gränitz 
140a9d50568SKazu Hirata template <llvm::endianness DataEndianness>
1415c1d160cSStefan Gränitz class ELFLinkGraphBuilder_aarch32
1425c1d160cSStefan Gränitz     : public ELFLinkGraphBuilder<ELFType<DataEndianness, false>> {
1435c1d160cSStefan Gränitz private:
1445c1d160cSStefan Gränitz   using ELFT = ELFType<DataEndianness, false>;
1455c1d160cSStefan Gränitz   using Base = ELFLinkGraphBuilder<ELFT>;
1465c1d160cSStefan Gränitz 
1475c1d160cSStefan Gränitz   Error addRelocations() override {
1485c1d160cSStefan Gränitz     LLVM_DEBUG(dbgs() << "Processing relocations:\n");
1495c1d160cSStefan Gränitz     using Self = ELFLinkGraphBuilder_aarch32<DataEndianness>;
1505c1d160cSStefan Gränitz     for (const auto &RelSect : Base::Sections) {
1515c1d160cSStefan Gränitz       if (Error Err = Base::forEachRelRelocation(RelSect, this,
1525c1d160cSStefan Gränitz                                                  &Self::addSingleRelRelocation))
1535c1d160cSStefan Gränitz         return Err;
1545c1d160cSStefan Gränitz     }
1555c1d160cSStefan Gränitz     return Error::success();
1565c1d160cSStefan Gränitz   }
1575c1d160cSStefan Gränitz 
1585c1d160cSStefan Gränitz   Error addSingleRelRelocation(const typename ELFT::Rel &Rel,
1595c1d160cSStefan Gränitz                                const typename ELFT::Shdr &FixupSect,
1605c1d160cSStefan Gränitz                                Block &BlockToFix) {
1615c1d160cSStefan Gränitz     uint32_t SymbolIndex = Rel.getSymbol(false);
1625c1d160cSStefan Gränitz     auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
1635c1d160cSStefan Gränitz     if (!ObjSymbol)
1645c1d160cSStefan Gränitz       return ObjSymbol.takeError();
1655c1d160cSStefan Gränitz 
1665c1d160cSStefan Gränitz     Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
1675c1d160cSStefan Gränitz     if (!GraphSymbol)
1685c1d160cSStefan Gränitz       return make_error<StringError>(
1695c1d160cSStefan Gränitz           formatv("Could not find symbol at given index, did you add it to "
1705c1d160cSStefan Gränitz                   "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
1715c1d160cSStefan Gränitz                   SymbolIndex, (*ObjSymbol)->st_shndx,
1725c1d160cSStefan Gränitz                   Base::GraphSymbols.size()),
1735c1d160cSStefan Gränitz           inconvertibleErrorCode());
1745c1d160cSStefan Gränitz 
1755c1d160cSStefan Gränitz     uint32_t Type = Rel.getType(false);
176bfb09326SStefan Gränitz     Expected<aarch32::EdgeKind_aarch32> Kind = getJITLinkEdgeKind(Type, ArmCfg);
1775c1d160cSStefan Gränitz     if (!Kind)
1785c1d160cSStefan Gränitz       return Kind.takeError();
1795c1d160cSStefan Gränitz 
1805c1d160cSStefan Gränitz     auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
1815c1d160cSStefan Gränitz     Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
1825c1d160cSStefan Gränitz 
1835c1d160cSStefan Gränitz     Expected<int64_t> Addend =
184808caa9dSStefan Gränitz         aarch32::readAddend(*Base::G, BlockToFix, Offset, *Kind, ArmCfg);
1855c1d160cSStefan Gränitz     if (!Addend)
1865c1d160cSStefan Gränitz       return Addend.takeError();
1875c1d160cSStefan Gränitz 
188808caa9dSStefan Gränitz     Edge E(*Kind, Offset, *GraphSymbol, *Addend);
1895c1d160cSStefan Gränitz     LLVM_DEBUG({
1905c1d160cSStefan Gränitz       dbgs() << "    ";
1915c1d160cSStefan Gränitz       printEdge(dbgs(), BlockToFix, E, getELFAArch32EdgeKindName(*Kind));
1925c1d160cSStefan Gränitz       dbgs() << "\n";
1935c1d160cSStefan Gränitz     });
1945c1d160cSStefan Gränitz 
1955c1d160cSStefan Gränitz     BlockToFix.addEdge(std::move(E));
1965c1d160cSStefan Gränitz     return Error::success();
1975c1d160cSStefan Gränitz   }
1985c1d160cSStefan Gränitz 
1995c1d160cSStefan Gränitz   aarch32::ArmConfig ArmCfg;
2005c1d160cSStefan Gränitz 
2015c1d160cSStefan Gränitz protected:
2025c1d160cSStefan Gränitz   TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) override {
203cd0f8910SEymen Ünay     // Only emit target flag for callable symbols
204cd0f8910SEymen Ünay     if (Sym.getType() != ELF::STT_FUNC)
205cd0f8910SEymen Ünay       return TargetFlagsType{};
2065c1d160cSStefan Gränitz     if (Sym.getValue() & 0x01)
2075c1d160cSStefan Gränitz       return aarch32::ThumbSymbol;
2085c1d160cSStefan Gränitz     return TargetFlagsType{};
2095c1d160cSStefan Gränitz   }
2105c1d160cSStefan Gränitz 
2115c1d160cSStefan Gränitz   orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
2125c1d160cSStefan Gränitz                                      TargetFlagsType Flags) override {
2135c1d160cSStefan Gränitz     assert((makeTargetFlags(Sym) & Flags) == Flags);
2145c1d160cSStefan Gränitz     static constexpr uint64_t ThumbBit = 0x01;
215cd0f8910SEymen Ünay     if (Sym.getType() == ELF::STT_FUNC)
2165c1d160cSStefan Gränitz       return Sym.getValue() & ~ThumbBit;
217cd0f8910SEymen Ünay     return Sym.getValue();
2185c1d160cSStefan Gränitz   }
2195c1d160cSStefan Gränitz 
2205c1d160cSStefan Gränitz public:
221a35e4d2cSStefan Gränitz   ELFLinkGraphBuilder_aarch32(StringRef FileName,
222*2ccf7ed2SJared Wyles                               const llvm::object::ELFFile<ELFT> &Obj,
223*2ccf7ed2SJared Wyles                               std::shared_ptr<orc::SymbolStringPool> SSP,
224*2ccf7ed2SJared Wyles                               Triple TT, SubtargetFeatures Features,
225a35e4d2cSStefan Gränitz                               aarch32::ArmConfig ArmCfg)
226*2ccf7ed2SJared Wyles       : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
227*2ccf7ed2SJared Wyles                                   std::move(Features), FileName,
228*2ccf7ed2SJared Wyles                                   getELFAArch32EdgeKindName),
2295c1d160cSStefan Gränitz         ArmCfg(std::move(ArmCfg)) {}
2305c1d160cSStefan Gränitz };
2315c1d160cSStefan Gränitz 
2329c607e77SStefan Gränitz template <typename StubsManagerType>
2335c1d160cSStefan Gränitz Error buildTables_ELF_aarch32(LinkGraph &G) {
2345c1d160cSStefan Gränitz   LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
2355c1d160cSStefan Gränitz 
2369c607e77SStefan Gränitz   StubsManagerType StubsManager;
2379c607e77SStefan Gränitz   visitExistingEdges(G, StubsManager);
238c4fc563bSStefan Gränitz   aarch32::GOTBuilder GOT;
239c4fc563bSStefan Gränitz   visitExistingEdges(G, GOT);
240c4fc563bSStefan Gränitz 
2415c1d160cSStefan Gränitz   return Error::success();
2425c1d160cSStefan Gränitz }
2435c1d160cSStefan Gränitz 
244*2ccf7ed2SJared Wyles Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch32(
245*2ccf7ed2SJared Wyles     MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
2465c1d160cSStefan Gränitz   LLVM_DEBUG({
2475c1d160cSStefan Gränitz     dbgs() << "Building jitlink graph for new input "
2485c1d160cSStefan Gränitz            << ObjectBuffer.getBufferIdentifier() << "...\n";
2495c1d160cSStefan Gränitz   });
2505c1d160cSStefan Gränitz 
2515c1d160cSStefan Gränitz   auto ELFObj = ObjectFile::createELFObjectFile(ObjectBuffer);
2525c1d160cSStefan Gränitz   if (!ELFObj)
2535c1d160cSStefan Gränitz     return ELFObj.takeError();
2545c1d160cSStefan Gränitz 
255348d0a6bSJob Noorman   auto Features = (*ELFObj)->getFeatures();
256348d0a6bSJob Noorman   if (!Features)
257348d0a6bSJob Noorman     return Features.takeError();
258348d0a6bSJob Noorman 
2595c1d160cSStefan Gränitz   // Find out what exact AArch32 instruction set and features we target.
2605c1d160cSStefan Gränitz   auto TT = (*ELFObj)->makeTriple();
2615c1d160cSStefan Gränitz   ARM::ArchKind AK = ARM::parseArch(TT.getArchName());
2625c1d160cSStefan Gränitz   if (AK == ARM::ArchKind::INVALID)
2635c1d160cSStefan Gränitz     return make_error<JITLinkError>(
2645c1d160cSStefan Gränitz         "Failed to build ELF link graph: Invalid ARM ArchKind");
2655c1d160cSStefan Gränitz 
2665c1d160cSStefan Gränitz   // Resolve our internal configuration for the target. If at some point the
2675c1d160cSStefan Gränitz   // CPUArch alone becomes too unprecise, we can find more details in the
2685c1d160cSStefan Gränitz   // Tag_CPU_arch_profile.
26955929cd6SStefan Gränitz   auto Arch = static_cast<ARMBuildAttrs::CPUArch>(ARM::getArchAttr(AK));
27055929cd6SStefan Gränitz   aarch32::ArmConfig ArmCfg = aarch32::getArmConfigForCPUArch(Arch);
2715c1d160cSStefan Gränitz 
2725c1d160cSStefan Gränitz   // Populate the link-graph.
2735c1d160cSStefan Gränitz   switch (TT.getArch()) {
2745c1d160cSStefan Gränitz   case Triple::arm:
2755c1d160cSStefan Gränitz   case Triple::thumb: {
2765c1d160cSStefan Gränitz     auto &ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
2774a0ccfa8SKazu Hirata     return ELFLinkGraphBuilder_aarch32<llvm::endianness::little>(
278*2ccf7ed2SJared Wyles                (*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,
279*2ccf7ed2SJared Wyles                std::move(*Features), ArmCfg)
2805c1d160cSStefan Gränitz         .buildGraph();
2815c1d160cSStefan Gränitz   }
2825c1d160cSStefan Gränitz   case Triple::armeb:
2835c1d160cSStefan Gränitz   case Triple::thumbeb: {
2845c1d160cSStefan Gränitz     auto &ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
2854a0ccfa8SKazu Hirata     return ELFLinkGraphBuilder_aarch32<llvm::endianness::big>(
286*2ccf7ed2SJared Wyles                (*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,
287*2ccf7ed2SJared Wyles                std::move(*Features), ArmCfg)
2885c1d160cSStefan Gränitz         .buildGraph();
2895c1d160cSStefan Gränitz   }
2905c1d160cSStefan Gränitz   default:
2915c1d160cSStefan Gränitz     return make_error<JITLinkError>(
2925c1d160cSStefan Gränitz         "Failed to build ELF/aarch32 link graph: Invalid target triple " +
2935c1d160cSStefan Gränitz         TT.getTriple());
2945c1d160cSStefan Gränitz   }
2955c1d160cSStefan Gränitz }
2965c1d160cSStefan Gränitz 
2975c1d160cSStefan Gränitz void link_ELF_aarch32(std::unique_ptr<LinkGraph> G,
2985c1d160cSStefan Gränitz                       std::unique_ptr<JITLinkContext> Ctx) {
2995c1d160cSStefan Gränitz   const Triple &TT = G->getTargetTriple();
3005c1d160cSStefan Gränitz 
3015c1d160cSStefan Gränitz   using namespace ARMBuildAttrs;
3025c1d160cSStefan Gränitz   ARM::ArchKind AK = ARM::parseArch(TT.getArchName());
3035c1d160cSStefan Gränitz   auto CPU = static_cast<CPUArch>(ARM::getArchAttr(AK));
3045c1d160cSStefan Gränitz   aarch32::ArmConfig ArmCfg = aarch32::getArmConfigForCPUArch(CPU);
3055c1d160cSStefan Gränitz 
3065c1d160cSStefan Gränitz   PassConfiguration PassCfg;
3075c1d160cSStefan Gränitz   if (Ctx->shouldAddDefaultTargetPasses(TT)) {
3085c1d160cSStefan Gränitz     // Add a mark-live pass.
3095c1d160cSStefan Gränitz     if (auto MarkLive = Ctx->getMarkLivePass(TT))
3105c1d160cSStefan Gränitz       PassCfg.PrePrunePasses.push_back(std::move(MarkLive));
3115c1d160cSStefan Gränitz     else
3125c1d160cSStefan Gränitz       PassCfg.PrePrunePasses.push_back(markAllSymbolsLive);
3135c1d160cSStefan Gränitz 
3145c1d160cSStefan Gränitz     switch (ArmCfg.Stubs) {
31555929cd6SStefan Gränitz     case aarch32::StubsFlavor::pre_v7:
31655929cd6SStefan Gränitz       PassCfg.PostPrunePasses.push_back(
31755929cd6SStefan Gränitz           buildTables_ELF_aarch32<aarch32::StubsManager_prev7>);
31855929cd6SStefan Gränitz       break;
319a979797dSStefan Gränitz     case aarch32::StubsFlavor::v7:
3205c1d160cSStefan Gränitz       PassCfg.PostPrunePasses.push_back(
3219c607e77SStefan Gränitz           buildTables_ELF_aarch32<aarch32::StubsManager_v7>);
3225c1d160cSStefan Gränitz       break;
32355929cd6SStefan Gränitz     case aarch32::StubsFlavor::Undefined:
3245c1d160cSStefan Gränitz       llvm_unreachable("Check before building graph");
3255c1d160cSStefan Gränitz     }
3265c1d160cSStefan Gränitz   }
3275c1d160cSStefan Gränitz 
3285c1d160cSStefan Gränitz   if (auto Err = Ctx->modifyPassConfig(*G, PassCfg))
3295c1d160cSStefan Gränitz     return Ctx->notifyFailed(std::move(Err));
3305c1d160cSStefan Gränitz 
3315c1d160cSStefan Gränitz   ELFJITLinker_aarch32::link(std::move(Ctx), std::move(G), std::move(PassCfg),
3325c1d160cSStefan Gränitz                              std::move(ArmCfg));
3335c1d160cSStefan Gränitz }
3345c1d160cSStefan Gränitz 
3355c1d160cSStefan Gränitz } // namespace jitlink
3365c1d160cSStefan Gränitz } // namespace llvm
337