1 | //===-- llvm/Target/ARMTargetObjectFile.cpp - ARM Object Info Impl --------===// |
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 | #include "ARMTargetObjectFile.h" |
10 | #include "ARMSubtarget.h" |
11 | #include "ARMTargetMachine.h" |
12 | #include "llvm/BinaryFormat/Dwarf.h" |
13 | #include "llvm/BinaryFormat/ELF.h" |
14 | #include "llvm/MC/MCAsmInfo.h" |
15 | #include "llvm/MC/MCContext.h" |
16 | #include "llvm/MC/MCExpr.h" |
17 | #include "llvm/MC/MCSectionELF.h" |
18 | #include "llvm/MC/MCTargetOptions.h" |
19 | #include "llvm/MC/MCValue.h" |
20 | #include "llvm/MC/SectionKind.h" |
21 | #include "llvm/Target/TargetMachine.h" |
22 | #include <cassert> |
23 | |
24 | using namespace llvm; |
25 | using namespace dwarf; |
26 | |
27 | //===----------------------------------------------------------------------===// |
28 | // ELF Target |
29 | //===----------------------------------------------------------------------===// |
30 | |
31 | void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, |
32 | const TargetMachine &TM) { |
33 | const ARMBaseTargetMachine &ARM_TM = static_cast<const ARMBaseTargetMachine &>(TM); |
34 | bool isAAPCS_ABI = ARM_TM.TargetABI == ARMBaseTargetMachine::ARMABI::ARM_ABI_AAPCS; |
35 | bool genExecuteOnly = |
36 | ARM_TM.getMCSubtargetInfo()->hasFeature(Feature: ARM::FeatureExecuteOnly); |
37 | |
38 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
39 | InitializeELF(UseInitArray_: isAAPCS_ABI); |
40 | |
41 | if (isAAPCS_ABI) { |
42 | LSDASection = nullptr; |
43 | } |
44 | |
45 | // Make code section unreadable when in execute-only mode |
46 | if (genExecuteOnly) { |
47 | unsigned Type = ELF::SHT_PROGBITS; |
48 | unsigned Flags = |
49 | ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_ARM_PURECODE; |
50 | // Since we cannot modify flags for an existing section, we create a new |
51 | // section with the right flags, and use 0 as the unique ID for |
52 | // execute-only text |
53 | TextSection = |
54 | Ctx.getELFSection(Section: ".text" , Type, Flags, EntrySize: 0, Group: "" , IsComdat: false, UniqueID: 0U, LinkedToSym: nullptr); |
55 | } |
56 | } |
57 | |
58 | MCRegister ARMElfTargetObjectFile::getStaticBase() const { return ARM::R9; } |
59 | |
60 | const MCExpr *ARMElfTargetObjectFile::getIndirectSymViaGOTPCRel( |
61 | const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, |
62 | int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
63 | int64_t FinalOffset = Offset + MV.getConstant(); |
64 | const MCExpr *Res = MCSymbolRefExpr::create( |
65 | Symbol: Sym, Kind: MCSymbolRefExpr::VK_ARM_GOT_PREL, Ctx&: getContext()); |
66 | const MCExpr *Off = MCConstantExpr::create(Value: FinalOffset, Ctx&: getContext()); |
67 | return MCBinaryExpr::createAdd(LHS: Res, RHS: Off, Ctx&: getContext()); |
68 | } |
69 | |
70 | const MCExpr *ARMElfTargetObjectFile:: |
71 | getIndirectSymViaRWPI(const MCSymbol *Sym) const { |
72 | return MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_ARM_SBREL, |
73 | Ctx&: getContext()); |
74 | } |
75 | |
76 | const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference( |
77 | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
78 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
79 | if (TM.getMCAsmInfo()->getExceptionHandlingType() != ExceptionHandling::ARM) |
80 | return TargetLoweringObjectFileELF::getTTypeGlobalReference( |
81 | GV, Encoding, TM, MMI, Streamer); |
82 | |
83 | assert(Encoding == DW_EH_PE_absptr && "Can handle absptr encoding only" ); |
84 | |
85 | return MCSymbolRefExpr::create(Symbol: TM.getSymbol(GV), |
86 | Kind: MCSymbolRefExpr::VK_ARM_TARGET2, Ctx&: getContext()); |
87 | } |
88 | |
89 | const MCExpr *ARMElfTargetObjectFile:: |
90 | getDebugThreadLocalSymbol(const MCSymbol *Sym) const { |
91 | return MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_ARM_TLSLDO, |
92 | Ctx&: getContext()); |
93 | } |
94 | |
95 | static bool isExecuteOnlyFunction(const GlobalObject *GO, SectionKind SK, |
96 | const TargetMachine &TM) { |
97 | if (const Function *F = dyn_cast<Function>(Val: GO)) |
98 | if (TM.getSubtarget<ARMSubtarget>(F: *F).genExecuteOnly() && SK.isText()) |
99 | return true; |
100 | return false; |
101 | } |
102 | |
103 | MCSection *ARMElfTargetObjectFile::getExplicitSectionGlobal( |
104 | const GlobalObject *GO, SectionKind SK, const TargetMachine &TM) const { |
105 | // Set execute-only access for the explicit section |
106 | if (isExecuteOnlyFunction(GO, SK, TM)) |
107 | SK = SectionKind::getExecuteOnly(); |
108 | |
109 | return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, Kind: SK, TM); |
110 | } |
111 | |
112 | MCSection *ARMElfTargetObjectFile::SelectSectionForGlobal( |
113 | const GlobalObject *GO, SectionKind SK, const TargetMachine &TM) const { |
114 | // Place the global in the execute-only text section |
115 | if (isExecuteOnlyFunction(GO, SK, TM)) |
116 | SK = SectionKind::getExecuteOnly(); |
117 | |
118 | return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind: SK, TM); |
119 | } |
120 | |