1*9880d681SAndroid Build Coastguard Worker //===-- X86TargetObjectFile.cpp - X86 Object Info -------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "X86TargetObjectFile.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Operator.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionCOFF.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCValue.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/COFF.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker using namespace dwarf;
25*9880d681SAndroid Build Coastguard Worker
getTTypeGlobalReference(const GlobalValue * GV,unsigned Encoding,Mangler & Mang,const TargetMachine & TM,MachineModuleInfo * MMI,MCStreamer & Streamer) const26*9880d681SAndroid Build Coastguard Worker const MCExpr *X86_64MachoTargetObjectFile::getTTypeGlobalReference(
27*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
28*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM, MachineModuleInfo *MMI,
29*9880d681SAndroid Build Coastguard Worker MCStreamer &Streamer) const {
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker // On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
32*9880d681SAndroid Build Coastguard Worker // is an indirect pc-relative reference.
33*9880d681SAndroid Build Coastguard Worker if ((Encoding & DW_EH_PE_indirect) && (Encoding & DW_EH_PE_pcrel)) {
34*9880d681SAndroid Build Coastguard Worker const MCSymbol *Sym = TM.getSymbol(GV, Mang);
35*9880d681SAndroid Build Coastguard Worker const MCExpr *Res =
36*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext());
37*9880d681SAndroid Build Coastguard Worker const MCExpr *Four = MCConstantExpr::create(4, getContext());
38*9880d681SAndroid Build Coastguard Worker return MCBinaryExpr::createAdd(Res, Four, getContext());
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker return TargetLoweringObjectFileMachO::getTTypeGlobalReference(
42*9880d681SAndroid Build Coastguard Worker GV, Encoding, Mang, TM, MMI, Streamer);
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker
getCFIPersonalitySymbol(const GlobalValue * GV,Mangler & Mang,const TargetMachine & TM,MachineModuleInfo * MMI) const45*9880d681SAndroid Build Coastguard Worker MCSymbol *X86_64MachoTargetObjectFile::getCFIPersonalitySymbol(
46*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
47*9880d681SAndroid Build Coastguard Worker MachineModuleInfo *MMI) const {
48*9880d681SAndroid Build Coastguard Worker return TM.getSymbol(GV, Mang);
49*9880d681SAndroid Build Coastguard Worker }
50*9880d681SAndroid Build Coastguard Worker
getIndirectSymViaGOTPCRel(const MCSymbol * Sym,const MCValue & MV,int64_t Offset,MachineModuleInfo * MMI,MCStreamer & Streamer) const51*9880d681SAndroid Build Coastguard Worker const MCExpr *X86_64MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
52*9880d681SAndroid Build Coastguard Worker const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
53*9880d681SAndroid Build Coastguard Worker MachineModuleInfo *MMI, MCStreamer &Streamer) const {
54*9880d681SAndroid Build Coastguard Worker // On Darwin/X86-64, we need to use foo@GOTPCREL+4 to access the got entry
55*9880d681SAndroid Build Coastguard Worker // from a data section. In case there's an additional offset, then use
56*9880d681SAndroid Build Coastguard Worker // foo@GOTPCREL+4+<offset>.
57*9880d681SAndroid Build Coastguard Worker unsigned FinalOff = Offset+MV.getConstant()+4;
58*9880d681SAndroid Build Coastguard Worker const MCExpr *Res =
59*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext());
60*9880d681SAndroid Build Coastguard Worker const MCExpr *Off = MCConstantExpr::create(FinalOff, getContext());
61*9880d681SAndroid Build Coastguard Worker return MCBinaryExpr::createAdd(Res, Off, getContext());
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
getDebugThreadLocalSymbol(const MCSymbol * Sym) const64*9880d681SAndroid Build Coastguard Worker const MCExpr *X86ELFTargetObjectFile::getDebugThreadLocalSymbol(
65*9880d681SAndroid Build Coastguard Worker const MCSymbol *Sym) const {
66*9880d681SAndroid Build Coastguard Worker return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext());
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker void
Initialize(MCContext & Ctx,const TargetMachine & TM)70*9880d681SAndroid Build Coastguard Worker X86LinuxNaClTargetObjectFile::Initialize(MCContext &Ctx,
71*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM) {
72*9880d681SAndroid Build Coastguard Worker TargetLoweringObjectFileELF::Initialize(Ctx, TM);
73*9880d681SAndroid Build Coastguard Worker InitializeELF(TM.Options.UseInitArray);
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,Mangler & Mang,const TargetMachine & TM) const76*9880d681SAndroid Build Coastguard Worker const MCExpr *X86WindowsTargetObjectFile::lowerRelativeReference(
77*9880d681SAndroid Build Coastguard Worker const GlobalValue *LHS, const GlobalValue *RHS, Mangler &Mang,
78*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM) const {
79*9880d681SAndroid Build Coastguard Worker // Our symbols should exist in address space zero, cowardly no-op if
80*9880d681SAndroid Build Coastguard Worker // otherwise.
81*9880d681SAndroid Build Coastguard Worker if (LHS->getType()->getPointerAddressSpace() != 0 ||
82*9880d681SAndroid Build Coastguard Worker RHS->getType()->getPointerAddressSpace() != 0)
83*9880d681SAndroid Build Coastguard Worker return nullptr;
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker // Both ptrtoint instructions must wrap global objects:
86*9880d681SAndroid Build Coastguard Worker // - Only global variables are eligible for image relative relocations.
87*9880d681SAndroid Build Coastguard Worker // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable.
88*9880d681SAndroid Build Coastguard Worker // We expect __ImageBase to be a global variable without a section, externally
89*9880d681SAndroid Build Coastguard Worker // defined.
90*9880d681SAndroid Build Coastguard Worker //
91*9880d681SAndroid Build Coastguard Worker // It should look something like this: @__ImageBase = external constant i8
92*9880d681SAndroid Build Coastguard Worker if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) ||
93*9880d681SAndroid Build Coastguard Worker LHS->isThreadLocal() || RHS->isThreadLocal() ||
94*9880d681SAndroid Build Coastguard Worker RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||
95*9880d681SAndroid Build Coastguard Worker cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())
96*9880d681SAndroid Build Coastguard Worker return nullptr;
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker return MCSymbolRefExpr::create(
99*9880d681SAndroid Build Coastguard Worker TM.getSymbol(LHS, Mang), MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
APIntToHexString(const APInt & AI)102*9880d681SAndroid Build Coastguard Worker static std::string APIntToHexString(const APInt &AI) {
103*9880d681SAndroid Build Coastguard Worker unsigned Width = (AI.getBitWidth() / 8) * 2;
104*9880d681SAndroid Build Coastguard Worker std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true);
105*9880d681SAndroid Build Coastguard Worker unsigned Size = HexString.size();
106*9880d681SAndroid Build Coastguard Worker assert(Width >= Size && "hex string is too large!");
107*9880d681SAndroid Build Coastguard Worker HexString.insert(HexString.begin(), Width - Size, '0');
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker return HexString;
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker
scalarConstantToHexString(const Constant * C)112*9880d681SAndroid Build Coastguard Worker static std::string scalarConstantToHexString(const Constant *C) {
113*9880d681SAndroid Build Coastguard Worker Type *Ty = C->getType();
114*9880d681SAndroid Build Coastguard Worker if (isa<UndefValue>(C)) {
115*9880d681SAndroid Build Coastguard Worker return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits()));
116*9880d681SAndroid Build Coastguard Worker } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
117*9880d681SAndroid Build Coastguard Worker return APIntToHexString(CFP->getValueAPF().bitcastToAPInt());
118*9880d681SAndroid Build Coastguard Worker } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
119*9880d681SAndroid Build Coastguard Worker return APIntToHexString(CI->getValue());
120*9880d681SAndroid Build Coastguard Worker } else {
121*9880d681SAndroid Build Coastguard Worker unsigned NumElements;
122*9880d681SAndroid Build Coastguard Worker if (isa<VectorType>(Ty))
123*9880d681SAndroid Build Coastguard Worker NumElements = Ty->getVectorNumElements();
124*9880d681SAndroid Build Coastguard Worker else
125*9880d681SAndroid Build Coastguard Worker NumElements = Ty->getArrayNumElements();
126*9880d681SAndroid Build Coastguard Worker std::string HexString;
127*9880d681SAndroid Build Coastguard Worker for (int I = NumElements - 1, E = -1; I != E; --I)
128*9880d681SAndroid Build Coastguard Worker HexString += scalarConstantToHexString(C->getAggregateElement(I));
129*9880d681SAndroid Build Coastguard Worker return HexString;
130*9880d681SAndroid Build Coastguard Worker }
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,unsigned & Align) const133*9880d681SAndroid Build Coastguard Worker MCSection *X86WindowsTargetObjectFile::getSectionForConstant(
134*9880d681SAndroid Build Coastguard Worker const DataLayout &DL, SectionKind Kind, const Constant *C,
135*9880d681SAndroid Build Coastguard Worker unsigned &Align) const {
136*9880d681SAndroid Build Coastguard Worker if (Kind.isMergeableConst() && C) {
137*9880d681SAndroid Build Coastguard Worker const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
138*9880d681SAndroid Build Coastguard Worker COFF::IMAGE_SCN_MEM_READ |
139*9880d681SAndroid Build Coastguard Worker COFF::IMAGE_SCN_LNK_COMDAT;
140*9880d681SAndroid Build Coastguard Worker std::string COMDATSymName;
141*9880d681SAndroid Build Coastguard Worker if (Kind.isMergeableConst4()) {
142*9880d681SAndroid Build Coastguard Worker if (Align <= 4) {
143*9880d681SAndroid Build Coastguard Worker COMDATSymName = "__real@" + scalarConstantToHexString(C);
144*9880d681SAndroid Build Coastguard Worker Align = 4;
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker } else if (Kind.isMergeableConst8()) {
147*9880d681SAndroid Build Coastguard Worker if (Align <= 8) {
148*9880d681SAndroid Build Coastguard Worker COMDATSymName = "__real@" + scalarConstantToHexString(C);
149*9880d681SAndroid Build Coastguard Worker Align = 8;
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker } else if (Kind.isMergeableConst16()) {
152*9880d681SAndroid Build Coastguard Worker if (Align <= 16) {
153*9880d681SAndroid Build Coastguard Worker COMDATSymName = "__xmm@" + scalarConstantToHexString(C);
154*9880d681SAndroid Build Coastguard Worker Align = 16;
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker } else if (Kind.isMergeableConst32()) {
157*9880d681SAndroid Build Coastguard Worker if (Align <= 32) {
158*9880d681SAndroid Build Coastguard Worker COMDATSymName = "__ymm@" + scalarConstantToHexString(C);
159*9880d681SAndroid Build Coastguard Worker Align = 32;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker if (!COMDATSymName.empty())
164*9880d681SAndroid Build Coastguard Worker return getContext().getCOFFSection(".rdata", Characteristics, Kind,
165*9880d681SAndroid Build Coastguard Worker COMDATSymName,
166*9880d681SAndroid Build Coastguard Worker COFF::IMAGE_COMDAT_SELECT_ANY);
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align);
170*9880d681SAndroid Build Coastguard Worker }
171