1 //===-- llvm/Target/ARMTargetObjectFile.cpp - ARM Object Info Impl --------===//
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
7 //===----------------------------------------------------------------------===//
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"
25 using namespace dwarf
;
27 //===----------------------------------------------------------------------===//
29 //===----------------------------------------------------------------------===//
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
;
36 ARM_TM
.getMCSubtargetInfo()->hasFeature(ARM::FeatureExecuteOnly
);
38 TargetLoweringObjectFileELF::Initialize(Ctx
, TM
);
39 InitializeELF(isAAPCS_ABI
);
42 LSDASection
= nullptr;
45 // Make code section unreadable when in execute-only mode
47 unsigned Type
= ELF::SHT_PROGBITS
;
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
54 Ctx
.getELFSection(".text", Type
, Flags
, 0, "", false, 0U, nullptr);
58 MCRegister
ARMElfTargetObjectFile::getStaticBase() const { return ARM::R9
; }
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 Sym
, MCSymbolRefExpr::VK_ARM_GOT_PREL
, getContext());
66 const MCExpr
*Off
= MCConstantExpr::create(FinalOffset
, getContext());
67 return MCBinaryExpr::createAdd(Res
, Off
, getContext());
70 const MCExpr
*ARMElfTargetObjectFile::
71 getIndirectSymViaRWPI(const MCSymbol
*Sym
) const {
72 return MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_ARM_SBREL
,
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
);
83 assert(Encoding
== DW_EH_PE_absptr
&& "Can handle absptr encoding only");
85 return MCSymbolRefExpr::create(TM
.getSymbol(GV
),
86 MCSymbolRefExpr::VK_ARM_TARGET2
, getContext());
89 const MCExpr
*ARMElfTargetObjectFile::
90 getDebugThreadLocalSymbol(const MCSymbol
*Sym
) const {
91 return MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_ARM_TLSLDO
,
95 static bool isExecuteOnlyFunction(const GlobalObject
*GO
, SectionKind SK
,
96 const TargetMachine
&TM
) {
97 if (const Function
*F
= dyn_cast
<Function
>(GO
))
98 if (TM
.getSubtarget
<ARMSubtarget
>(*F
).genExecuteOnly() && SK
.isText())
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();
109 return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO
, SK
, TM
);
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();
118 return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO
, SK
, TM
);