1*9880d681SAndroid Build Coastguard Worker //===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===//
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 // This file implements the Link Time Optimization library. This library is
11*9880d681SAndroid Build Coastguard Worker // intended to be used by linker to optimize code at link time.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/LTO/legacy/LTOModule.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Analysis.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticPrinter.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Metadata.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCAsmParser.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCTargetAsmParser.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/SubtargetFeature.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/IRObjectFile.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetSelect.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLoweringObjectFile.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/GlobalStatus.h"
48*9880d681SAndroid Build Coastguard Worker #include <system_error>
49*9880d681SAndroid Build Coastguard Worker using namespace llvm;
50*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
51*9880d681SAndroid Build Coastguard Worker
LTOModule(std::unique_ptr<object::IRObjectFile> Obj,llvm::TargetMachine * TM)52*9880d681SAndroid Build Coastguard Worker LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
53*9880d681SAndroid Build Coastguard Worker llvm::TargetMachine *TM)
54*9880d681SAndroid Build Coastguard Worker : IRFile(std::move(Obj)), _target(TM) {}
55*9880d681SAndroid Build Coastguard Worker
~LTOModule()56*9880d681SAndroid Build Coastguard Worker LTOModule::~LTOModule() {}
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
59*9880d681SAndroid Build Coastguard Worker /// bitcode.
isBitcodeFile(const void * Mem,size_t Length)60*9880d681SAndroid Build Coastguard Worker bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) {
61*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
62*9880d681SAndroid Build Coastguard Worker MemoryBufferRef(StringRef((const char *)Mem, Length), "<mem>"));
63*9880d681SAndroid Build Coastguard Worker return bool(BCData);
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
isBitcodeFile(const char * Path)66*9880d681SAndroid Build Coastguard Worker bool LTOModule::isBitcodeFile(const char *Path) {
67*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
68*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getFile(Path);
69*9880d681SAndroid Build Coastguard Worker if (!BufferOrErr)
70*9880d681SAndroid Build Coastguard Worker return false;
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
73*9880d681SAndroid Build Coastguard Worker BufferOrErr.get()->getMemBufferRef());
74*9880d681SAndroid Build Coastguard Worker return bool(BCData);
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker
isThinLTO()77*9880d681SAndroid Build Coastguard Worker bool LTOModule::isThinLTO() {
78*9880d681SAndroid Build Coastguard Worker // Right now the detection is only based on the summary presence. We may want
79*9880d681SAndroid Build Coastguard Worker // to add a dedicated flag at some point.
80*9880d681SAndroid Build Coastguard Worker return hasGlobalValueSummary(IRFile->getMemoryBufferRef(),
81*9880d681SAndroid Build Coastguard Worker [](const DiagnosticInfo &DI) {
82*9880d681SAndroid Build Coastguard Worker DiagnosticPrinterRawOStream DP(errs());
83*9880d681SAndroid Build Coastguard Worker DI.print(DP);
84*9880d681SAndroid Build Coastguard Worker errs() << '\n';
85*9880d681SAndroid Build Coastguard Worker return;
86*9880d681SAndroid Build Coastguard Worker });
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker
isBitcodeForTarget(MemoryBuffer * Buffer,StringRef TriplePrefix)89*9880d681SAndroid Build Coastguard Worker bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer,
90*9880d681SAndroid Build Coastguard Worker StringRef TriplePrefix) {
91*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCOrErr =
92*9880d681SAndroid Build Coastguard Worker IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
93*9880d681SAndroid Build Coastguard Worker if (!BCOrErr)
94*9880d681SAndroid Build Coastguard Worker return false;
95*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
96*9880d681SAndroid Build Coastguard Worker std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context);
97*9880d681SAndroid Build Coastguard Worker return StringRef(Triple).startswith(TriplePrefix);
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker
getProducerString(MemoryBuffer * Buffer)100*9880d681SAndroid Build Coastguard Worker std::string LTOModule::getProducerString(MemoryBuffer *Buffer) {
101*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCOrErr =
102*9880d681SAndroid Build Coastguard Worker IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
103*9880d681SAndroid Build Coastguard Worker if (!BCOrErr)
104*9880d681SAndroid Build Coastguard Worker return "";
105*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
106*9880d681SAndroid Build Coastguard Worker return getBitcodeProducerString(*BCOrErr, Context);
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
createFromFile(LLVMContext & Context,const char * path,const TargetOptions & options)110*9880d681SAndroid Build Coastguard Worker LTOModule::createFromFile(LLVMContext &Context, const char *path,
111*9880d681SAndroid Build Coastguard Worker const TargetOptions &options) {
112*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
113*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getFile(path);
114*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = BufferOrErr.getError()) {
115*9880d681SAndroid Build Coastguard Worker Context.emitError(EC.message());
116*9880d681SAndroid Build Coastguard Worker return EC;
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
119*9880d681SAndroid Build Coastguard Worker return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
120*9880d681SAndroid Build Coastguard Worker /* ShouldBeLazy*/ false);
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
createFromOpenFile(LLVMContext & Context,int fd,const char * path,size_t size,const TargetOptions & options)124*9880d681SAndroid Build Coastguard Worker LTOModule::createFromOpenFile(LLVMContext &Context, int fd, const char *path,
125*9880d681SAndroid Build Coastguard Worker size_t size, const TargetOptions &options) {
126*9880d681SAndroid Build Coastguard Worker return createFromOpenFileSlice(Context, fd, path, size, 0, options);
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
createFromOpenFileSlice(LLVMContext & Context,int fd,const char * path,size_t map_size,off_t offset,const TargetOptions & options)130*9880d681SAndroid Build Coastguard Worker LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd,
131*9880d681SAndroid Build Coastguard Worker const char *path, size_t map_size,
132*9880d681SAndroid Build Coastguard Worker off_t offset, const TargetOptions &options) {
133*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
134*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset);
135*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = BufferOrErr.getError()) {
136*9880d681SAndroid Build Coastguard Worker Context.emitError(EC.message());
137*9880d681SAndroid Build Coastguard Worker return EC;
138*9880d681SAndroid Build Coastguard Worker }
139*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
140*9880d681SAndroid Build Coastguard Worker return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
141*9880d681SAndroid Build Coastguard Worker /* ShouldBeLazy */ false);
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
createFromBuffer(LLVMContext & Context,const void * mem,size_t length,const TargetOptions & options,StringRef path)145*9880d681SAndroid Build Coastguard Worker LTOModule::createFromBuffer(LLVMContext &Context, const void *mem,
146*9880d681SAndroid Build Coastguard Worker size_t length, const TargetOptions &options,
147*9880d681SAndroid Build Coastguard Worker StringRef path) {
148*9880d681SAndroid Build Coastguard Worker StringRef Data((const char *)mem, length);
149*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Buffer(Data, path);
150*9880d681SAndroid Build Coastguard Worker return makeLTOModule(Buffer, options, Context, /* ShouldBeLazy */ false);
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
createInLocalContext(std::unique_ptr<LLVMContext> Context,const void * mem,size_t length,const TargetOptions & options,StringRef path)154*9880d681SAndroid Build Coastguard Worker LTOModule::createInLocalContext(std::unique_ptr<LLVMContext> Context,
155*9880d681SAndroid Build Coastguard Worker const void *mem, size_t length,
156*9880d681SAndroid Build Coastguard Worker const TargetOptions &options, StringRef path) {
157*9880d681SAndroid Build Coastguard Worker StringRef Data((const char *)mem, length);
158*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Buffer(Data, path);
159*9880d681SAndroid Build Coastguard Worker // If we own a context, we know this is being used only for symbol extraction,
160*9880d681SAndroid Build Coastguard Worker // not linking. Be lazy in that case.
161*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>> Ret =
162*9880d681SAndroid Build Coastguard Worker makeLTOModule(Buffer, options, *Context, /* ShouldBeLazy */ true);
163*9880d681SAndroid Build Coastguard Worker if (Ret)
164*9880d681SAndroid Build Coastguard Worker (*Ret)->OwnedContext = std::move(Context);
165*9880d681SAndroid Build Coastguard Worker return Ret;
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker static ErrorOr<std::unique_ptr<Module>>
parseBitcodeFileImpl(MemoryBufferRef Buffer,LLVMContext & Context,bool ShouldBeLazy)169*9880d681SAndroid Build Coastguard Worker parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context,
170*9880d681SAndroid Build Coastguard Worker bool ShouldBeLazy) {
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker // Find the buffer.
173*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> MBOrErr =
174*9880d681SAndroid Build Coastguard Worker IRObjectFile::findBitcodeInMemBuffer(Buffer);
175*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = MBOrErr.getError()) {
176*9880d681SAndroid Build Coastguard Worker Context.emitError(EC.message());
177*9880d681SAndroid Build Coastguard Worker return EC;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker if (!ShouldBeLazy) {
181*9880d681SAndroid Build Coastguard Worker // Parse the full file.
182*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> M = parseBitcodeFile(*MBOrErr, Context);
183*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = M.getError())
184*9880d681SAndroid Build Coastguard Worker return EC;
185*9880d681SAndroid Build Coastguard Worker return std::move(*M);
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker // Parse lazily.
189*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> LightweightBuf =
190*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getMemBuffer(*MBOrErr, false);
191*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> M = getLazyBitcodeModule(
192*9880d681SAndroid Build Coastguard Worker std::move(LightweightBuf), Context, true /*ShouldLazyLoadMetadata*/);
193*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = M.getError())
194*9880d681SAndroid Build Coastguard Worker return EC;
195*9880d681SAndroid Build Coastguard Worker return std::move(*M);
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<LTOModule>>
makeLTOModule(MemoryBufferRef Buffer,const TargetOptions & options,LLVMContext & Context,bool ShouldBeLazy)199*9880d681SAndroid Build Coastguard Worker LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options,
200*9880d681SAndroid Build Coastguard Worker LLVMContext &Context, bool ShouldBeLazy) {
201*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> MOrErr =
202*9880d681SAndroid Build Coastguard Worker parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy);
203*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = MOrErr.getError())
204*9880d681SAndroid Build Coastguard Worker return EC;
205*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> &M = *MOrErr;
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker std::string TripleStr = M->getTargetTriple();
208*9880d681SAndroid Build Coastguard Worker if (TripleStr.empty())
209*9880d681SAndroid Build Coastguard Worker TripleStr = sys::getDefaultTargetTriple();
210*9880d681SAndroid Build Coastguard Worker llvm::Triple Triple(TripleStr);
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker // find machine architecture for this module
213*9880d681SAndroid Build Coastguard Worker std::string errMsg;
214*9880d681SAndroid Build Coastguard Worker const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
215*9880d681SAndroid Build Coastguard Worker if (!march)
216*9880d681SAndroid Build Coastguard Worker return std::unique_ptr<LTOModule>(nullptr);
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker // construct LTOModule, hand over ownership of module and target
219*9880d681SAndroid Build Coastguard Worker SubtargetFeatures Features;
220*9880d681SAndroid Build Coastguard Worker Features.getDefaultSubtargetFeatures(Triple);
221*9880d681SAndroid Build Coastguard Worker std::string FeatureStr = Features.getString();
222*9880d681SAndroid Build Coastguard Worker // Set a default CPU for Darwin triples.
223*9880d681SAndroid Build Coastguard Worker std::string CPU;
224*9880d681SAndroid Build Coastguard Worker if (Triple.isOSDarwin()) {
225*9880d681SAndroid Build Coastguard Worker if (Triple.getArch() == llvm::Triple::x86_64)
226*9880d681SAndroid Build Coastguard Worker CPU = "core2";
227*9880d681SAndroid Build Coastguard Worker else if (Triple.getArch() == llvm::Triple::x86)
228*9880d681SAndroid Build Coastguard Worker CPU = "yonah";
229*9880d681SAndroid Build Coastguard Worker else if (Triple.getArch() == llvm::Triple::aarch64)
230*9880d681SAndroid Build Coastguard Worker CPU = "cyclone";
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker TargetMachine *target =
234*9880d681SAndroid Build Coastguard Worker march->createTargetMachine(TripleStr, CPU, FeatureStr, options, None);
235*9880d681SAndroid Build Coastguard Worker M->setDataLayout(target->createDataLayout());
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker std::unique_ptr<object::IRObjectFile> IRObj(
238*9880d681SAndroid Build Coastguard Worker new object::IRObjectFile(Buffer, std::move(M)));
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker std::unique_ptr<LTOModule> Ret(new LTOModule(std::move(IRObj), target));
241*9880d681SAndroid Build Coastguard Worker Ret->parseSymbols();
242*9880d681SAndroid Build Coastguard Worker Ret->parseMetadata();
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker return std::move(Ret);
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker /// Create a MemoryBuffer from a memory range with an optional name.
248*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer>
makeBuffer(const void * mem,size_t length,StringRef name)249*9880d681SAndroid Build Coastguard Worker LTOModule::makeBuffer(const void *mem, size_t length, StringRef name) {
250*9880d681SAndroid Build Coastguard Worker const char *startPtr = (const char*)mem;
251*9880d681SAndroid Build Coastguard Worker return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false);
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker /// objcClassNameFromExpression - Get string that the data pointer points to.
255*9880d681SAndroid Build Coastguard Worker bool
objcClassNameFromExpression(const Constant * c,std::string & name)256*9880d681SAndroid Build Coastguard Worker LTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) {
257*9880d681SAndroid Build Coastguard Worker if (const ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) {
258*9880d681SAndroid Build Coastguard Worker Constant *op = ce->getOperand(0);
259*9880d681SAndroid Build Coastguard Worker if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) {
260*9880d681SAndroid Build Coastguard Worker Constant *cn = gvn->getInitializer();
261*9880d681SAndroid Build Coastguard Worker if (ConstantDataArray *ca = dyn_cast<ConstantDataArray>(cn)) {
262*9880d681SAndroid Build Coastguard Worker if (ca->isCString()) {
263*9880d681SAndroid Build Coastguard Worker name = (".objc_class_name_" + ca->getAsCString()).str();
264*9880d681SAndroid Build Coastguard Worker return true;
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker return false;
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker /// addObjCClass - Parse i386/ppc ObjC class data structure.
addObjCClass(const GlobalVariable * clgv)273*9880d681SAndroid Build Coastguard Worker void LTOModule::addObjCClass(const GlobalVariable *clgv) {
274*9880d681SAndroid Build Coastguard Worker const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
275*9880d681SAndroid Build Coastguard Worker if (!c) return;
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker // second slot in __OBJC,__class is pointer to superclass name
278*9880d681SAndroid Build Coastguard Worker std::string superclassName;
279*9880d681SAndroid Build Coastguard Worker if (objcClassNameFromExpression(c->getOperand(1), superclassName)) {
280*9880d681SAndroid Build Coastguard Worker auto IterBool =
281*9880d681SAndroid Build Coastguard Worker _undefines.insert(std::make_pair(superclassName, NameAndAttributes()));
282*9880d681SAndroid Build Coastguard Worker if (IterBool.second) {
283*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = IterBool.first->second;
284*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
285*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
286*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
287*9880d681SAndroid Build Coastguard Worker info.symbol = clgv;
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker // third slot in __OBJC,__class is pointer to class name
292*9880d681SAndroid Build Coastguard Worker std::string className;
293*9880d681SAndroid Build Coastguard Worker if (objcClassNameFromExpression(c->getOperand(2), className)) {
294*9880d681SAndroid Build Coastguard Worker auto Iter = _defines.insert(className).first;
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker NameAndAttributes info;
297*9880d681SAndroid Build Coastguard Worker info.name = Iter->first().data();
298*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_PERMISSIONS_DATA |
299*9880d681SAndroid Build Coastguard Worker LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT;
300*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
301*9880d681SAndroid Build Coastguard Worker info.symbol = clgv;
302*9880d681SAndroid Build Coastguard Worker _symbols.push_back(info);
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker /// addObjCCategory - Parse i386/ppc ObjC category data structure.
addObjCCategory(const GlobalVariable * clgv)307*9880d681SAndroid Build Coastguard Worker void LTOModule::addObjCCategory(const GlobalVariable *clgv) {
308*9880d681SAndroid Build Coastguard Worker const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
309*9880d681SAndroid Build Coastguard Worker if (!c) return;
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker // second slot in __OBJC,__category is pointer to target class name
312*9880d681SAndroid Build Coastguard Worker std::string targetclassName;
313*9880d681SAndroid Build Coastguard Worker if (!objcClassNameFromExpression(c->getOperand(1), targetclassName))
314*9880d681SAndroid Build Coastguard Worker return;
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker auto IterBool =
317*9880d681SAndroid Build Coastguard Worker _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker if (!IterBool.second)
320*9880d681SAndroid Build Coastguard Worker return;
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = IterBool.first->second;
323*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
324*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
325*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
326*9880d681SAndroid Build Coastguard Worker info.symbol = clgv;
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker /// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
addObjCClassRef(const GlobalVariable * clgv)330*9880d681SAndroid Build Coastguard Worker void LTOModule::addObjCClassRef(const GlobalVariable *clgv) {
331*9880d681SAndroid Build Coastguard Worker std::string targetclassName;
332*9880d681SAndroid Build Coastguard Worker if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
333*9880d681SAndroid Build Coastguard Worker return;
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker auto IterBool =
336*9880d681SAndroid Build Coastguard Worker _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker if (!IterBool.second)
339*9880d681SAndroid Build Coastguard Worker return;
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = IterBool.first->second;
342*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
343*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
344*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
345*9880d681SAndroid Build Coastguard Worker info.symbol = clgv;
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker
addDefinedDataSymbol(const object::BasicSymbolRef & Sym)348*9880d681SAndroid Build Coastguard Worker void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) {
349*9880d681SAndroid Build Coastguard Worker SmallString<64> Buffer;
350*9880d681SAndroid Build Coastguard Worker {
351*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(Buffer);
352*9880d681SAndroid Build Coastguard Worker Sym.printName(OS);
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker const GlobalValue *V = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
356*9880d681SAndroid Build Coastguard Worker addDefinedDataSymbol(Buffer.c_str(), V);
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker
addDefinedDataSymbol(const char * Name,const GlobalValue * v)359*9880d681SAndroid Build Coastguard Worker void LTOModule::addDefinedDataSymbol(const char *Name, const GlobalValue *v) {
360*9880d681SAndroid Build Coastguard Worker // Add to list of defined symbols.
361*9880d681SAndroid Build Coastguard Worker addDefinedSymbol(Name, v, false);
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker if (!v->hasSection() /* || !isTargetDarwin */)
364*9880d681SAndroid Build Coastguard Worker return;
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker // Special case i386/ppc ObjC data structures in magic sections:
367*9880d681SAndroid Build Coastguard Worker // The issue is that the old ObjC object format did some strange
368*9880d681SAndroid Build Coastguard Worker // contortions to avoid real linker symbols. For instance, the
369*9880d681SAndroid Build Coastguard Worker // ObjC class data structure is allocated statically in the executable
370*9880d681SAndroid Build Coastguard Worker // that defines that class. That data structures contains a pointer to
371*9880d681SAndroid Build Coastguard Worker // its superclass. But instead of just initializing that part of the
372*9880d681SAndroid Build Coastguard Worker // struct to the address of its superclass, and letting the static and
373*9880d681SAndroid Build Coastguard Worker // dynamic linkers do the rest, the runtime works by having that field
374*9880d681SAndroid Build Coastguard Worker // instead point to a C-string that is the name of the superclass.
375*9880d681SAndroid Build Coastguard Worker // At runtime the objc initialization updates that pointer and sets
376*9880d681SAndroid Build Coastguard Worker // it to point to the actual super class. As far as the linker
377*9880d681SAndroid Build Coastguard Worker // knows it is just a pointer to a string. But then someone wanted the
378*9880d681SAndroid Build Coastguard Worker // linker to issue errors at build time if the superclass was not found.
379*9880d681SAndroid Build Coastguard Worker // So they figured out a way in mach-o object format to use an absolute
380*9880d681SAndroid Build Coastguard Worker // symbols (.objc_class_name_Foo = 0) and a floating reference
381*9880d681SAndroid Build Coastguard Worker // (.reference .objc_class_name_Bar) to cause the linker into erroring when
382*9880d681SAndroid Build Coastguard Worker // a class was missing.
383*9880d681SAndroid Build Coastguard Worker // The following synthesizes the implicit .objc_* symbols for the linker
384*9880d681SAndroid Build Coastguard Worker // from the ObjC data structures generated by the front end.
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker // special case if this data blob is an ObjC class definition
387*9880d681SAndroid Build Coastguard Worker std::string Section = v->getSection();
388*9880d681SAndroid Build Coastguard Worker if (Section.compare(0, 15, "__OBJC,__class,") == 0) {
389*9880d681SAndroid Build Coastguard Worker if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
390*9880d681SAndroid Build Coastguard Worker addObjCClass(gv);
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker // special case if this data blob is an ObjC category definition
395*9880d681SAndroid Build Coastguard Worker else if (Section.compare(0, 18, "__OBJC,__category,") == 0) {
396*9880d681SAndroid Build Coastguard Worker if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
397*9880d681SAndroid Build Coastguard Worker addObjCCategory(gv);
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker // special case if this data blob is the list of referenced classes
402*9880d681SAndroid Build Coastguard Worker else if (Section.compare(0, 18, "__OBJC,__cls_refs,") == 0) {
403*9880d681SAndroid Build Coastguard Worker if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
404*9880d681SAndroid Build Coastguard Worker addObjCClassRef(gv);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker }
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker
addDefinedFunctionSymbol(const object::BasicSymbolRef & Sym)409*9880d681SAndroid Build Coastguard Worker void LTOModule::addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym) {
410*9880d681SAndroid Build Coastguard Worker SmallString<64> Buffer;
411*9880d681SAndroid Build Coastguard Worker {
412*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(Buffer);
413*9880d681SAndroid Build Coastguard Worker Sym.printName(OS);
414*9880d681SAndroid Build Coastguard Worker }
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Worker const Function *F =
417*9880d681SAndroid Build Coastguard Worker cast<Function>(IRFile->getSymbolGV(Sym.getRawDataRefImpl()));
418*9880d681SAndroid Build Coastguard Worker addDefinedFunctionSymbol(Buffer.c_str(), F);
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker
addDefinedFunctionSymbol(const char * Name,const Function * F)421*9880d681SAndroid Build Coastguard Worker void LTOModule::addDefinedFunctionSymbol(const char *Name, const Function *F) {
422*9880d681SAndroid Build Coastguard Worker // add to list of defined symbols
423*9880d681SAndroid Build Coastguard Worker addDefinedSymbol(Name, F, true);
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker
addDefinedSymbol(const char * Name,const GlobalValue * def,bool isFunction)426*9880d681SAndroid Build Coastguard Worker void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
427*9880d681SAndroid Build Coastguard Worker bool isFunction) {
428*9880d681SAndroid Build Coastguard Worker // set alignment part log2() can have rounding errors
429*9880d681SAndroid Build Coastguard Worker uint32_t align = def->getAlignment();
430*9880d681SAndroid Build Coastguard Worker uint32_t attr = align ? countTrailingZeros(align) : 0;
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker // set permissions part
433*9880d681SAndroid Build Coastguard Worker if (isFunction) {
434*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_PERMISSIONS_CODE;
435*9880d681SAndroid Build Coastguard Worker } else {
436*9880d681SAndroid Build Coastguard Worker const GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
437*9880d681SAndroid Build Coastguard Worker if (gv && gv->isConstant())
438*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
439*9880d681SAndroid Build Coastguard Worker else
440*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_PERMISSIONS_DATA;
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker // set definition part
444*9880d681SAndroid Build Coastguard Worker if (def->hasWeakLinkage() || def->hasLinkOnceLinkage())
445*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_DEFINITION_WEAK;
446*9880d681SAndroid Build Coastguard Worker else if (def->hasCommonLinkage())
447*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
448*9880d681SAndroid Build Coastguard Worker else
449*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_DEFINITION_REGULAR;
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker // set scope part
452*9880d681SAndroid Build Coastguard Worker if (def->hasLocalLinkage())
453*9880d681SAndroid Build Coastguard Worker // Ignore visibility if linkage is local.
454*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_INTERNAL;
455*9880d681SAndroid Build Coastguard Worker else if (def->hasHiddenVisibility())
456*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_HIDDEN;
457*9880d681SAndroid Build Coastguard Worker else if (def->hasProtectedVisibility())
458*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_PROTECTED;
459*9880d681SAndroid Build Coastguard Worker else if (canBeOmittedFromSymbolTable(def))
460*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
461*9880d681SAndroid Build Coastguard Worker else
462*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_DEFAULT;
463*9880d681SAndroid Build Coastguard Worker
464*9880d681SAndroid Build Coastguard Worker if (def->hasComdat())
465*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_COMDAT;
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker if (isa<GlobalAlias>(def))
468*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_ALIAS;
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker auto Iter = _defines.insert(Name).first;
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker // fill information structure
473*9880d681SAndroid Build Coastguard Worker NameAndAttributes info;
474*9880d681SAndroid Build Coastguard Worker StringRef NameRef = Iter->first();
475*9880d681SAndroid Build Coastguard Worker info.name = NameRef.data();
476*9880d681SAndroid Build Coastguard Worker assert(info.name[NameRef.size()] == '\0');
477*9880d681SAndroid Build Coastguard Worker info.attributes = attr;
478*9880d681SAndroid Build Coastguard Worker info.isFunction = isFunction;
479*9880d681SAndroid Build Coastguard Worker info.symbol = def;
480*9880d681SAndroid Build Coastguard Worker
481*9880d681SAndroid Build Coastguard Worker // add to table of symbols
482*9880d681SAndroid Build Coastguard Worker _symbols.push_back(info);
483*9880d681SAndroid Build Coastguard Worker }
484*9880d681SAndroid Build Coastguard Worker
485*9880d681SAndroid Build Coastguard Worker /// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
486*9880d681SAndroid Build Coastguard Worker /// defined list.
addAsmGlobalSymbol(const char * name,lto_symbol_attributes scope)487*9880d681SAndroid Build Coastguard Worker void LTOModule::addAsmGlobalSymbol(const char *name,
488*9880d681SAndroid Build Coastguard Worker lto_symbol_attributes scope) {
489*9880d681SAndroid Build Coastguard Worker auto IterBool = _defines.insert(name);
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Worker // only add new define if not already defined
492*9880d681SAndroid Build Coastguard Worker if (!IterBool.second)
493*9880d681SAndroid Build Coastguard Worker return;
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = _undefines[IterBool.first->first().data()];
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker if (info.symbol == nullptr) {
498*9880d681SAndroid Build Coastguard Worker // FIXME: This is trying to take care of module ASM like this:
499*9880d681SAndroid Build Coastguard Worker //
500*9880d681SAndroid Build Coastguard Worker // module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0"
501*9880d681SAndroid Build Coastguard Worker //
502*9880d681SAndroid Build Coastguard Worker // but is gross and its mother dresses it funny. Have the ASM parser give us
503*9880d681SAndroid Build Coastguard Worker // more details for this type of situation so that we're not guessing so
504*9880d681SAndroid Build Coastguard Worker // much.
505*9880d681SAndroid Build Coastguard Worker
506*9880d681SAndroid Build Coastguard Worker // fill information structure
507*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
508*9880d681SAndroid Build Coastguard Worker info.attributes =
509*9880d681SAndroid Build Coastguard Worker LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope;
510*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
511*9880d681SAndroid Build Coastguard Worker info.symbol = nullptr;
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker // add to table of symbols
514*9880d681SAndroid Build Coastguard Worker _symbols.push_back(info);
515*9880d681SAndroid Build Coastguard Worker return;
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker if (info.isFunction)
519*9880d681SAndroid Build Coastguard Worker addDefinedFunctionSymbol(info.name, cast<Function>(info.symbol));
520*9880d681SAndroid Build Coastguard Worker else
521*9880d681SAndroid Build Coastguard Worker addDefinedDataSymbol(info.name, info.symbol);
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
524*9880d681SAndroid Build Coastguard Worker _symbols.back().attributes |= scope;
525*9880d681SAndroid Build Coastguard Worker }
526*9880d681SAndroid Build Coastguard Worker
527*9880d681SAndroid Build Coastguard Worker /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the
528*9880d681SAndroid Build Coastguard Worker /// undefined list.
addAsmGlobalSymbolUndef(const char * name)529*9880d681SAndroid Build Coastguard Worker void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
530*9880d681SAndroid Build Coastguard Worker auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker _asm_undefines.push_back(IterBool.first->first().data());
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker // we already have the symbol
535*9880d681SAndroid Build Coastguard Worker if (!IterBool.second)
536*9880d681SAndroid Build Coastguard Worker return;
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;
539*9880d681SAndroid Build Coastguard Worker attr |= LTO_SYMBOL_SCOPE_DEFAULT;
540*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = IterBool.first->second;
541*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
542*9880d681SAndroid Build Coastguard Worker info.attributes = attr;
543*9880d681SAndroid Build Coastguard Worker info.isFunction = false;
544*9880d681SAndroid Build Coastguard Worker info.symbol = nullptr;
545*9880d681SAndroid Build Coastguard Worker }
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker /// Add a symbol which isn't defined just yet to a list to be resolved later.
addPotentialUndefinedSymbol(const object::BasicSymbolRef & Sym,bool isFunc)548*9880d681SAndroid Build Coastguard Worker void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
549*9880d681SAndroid Build Coastguard Worker bool isFunc) {
550*9880d681SAndroid Build Coastguard Worker SmallString<64> name;
551*9880d681SAndroid Build Coastguard Worker {
552*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(name);
553*9880d681SAndroid Build Coastguard Worker Sym.printName(OS);
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker // we already have the symbol
559*9880d681SAndroid Build Coastguard Worker if (!IterBool.second)
560*9880d681SAndroid Build Coastguard Worker return;
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker NameAndAttributes &info = IterBool.first->second;
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker info.name = IterBool.first->first().data();
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker const GlobalValue *decl = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Worker if (decl->hasExternalWeakLinkage())
569*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
570*9880d681SAndroid Build Coastguard Worker else
571*9880d681SAndroid Build Coastguard Worker info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker info.isFunction = isFunc;
574*9880d681SAndroid Build Coastguard Worker info.symbol = decl;
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker
parseSymbols()577*9880d681SAndroid Build Coastguard Worker void LTOModule::parseSymbols() {
578*9880d681SAndroid Build Coastguard Worker for (auto &Sym : IRFile->symbols()) {
579*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
580*9880d681SAndroid Build Coastguard Worker uint32_t Flags = Sym.getFlags();
581*9880d681SAndroid Build Coastguard Worker if (Flags & object::BasicSymbolRef::SF_FormatSpecific)
582*9880d681SAndroid Build Coastguard Worker continue;
583*9880d681SAndroid Build Coastguard Worker
584*9880d681SAndroid Build Coastguard Worker bool IsUndefined = Flags & object::BasicSymbolRef::SF_Undefined;
585*9880d681SAndroid Build Coastguard Worker
586*9880d681SAndroid Build Coastguard Worker if (!GV) {
587*9880d681SAndroid Build Coastguard Worker SmallString<64> Buffer;
588*9880d681SAndroid Build Coastguard Worker {
589*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(Buffer);
590*9880d681SAndroid Build Coastguard Worker Sym.printName(OS);
591*9880d681SAndroid Build Coastguard Worker }
592*9880d681SAndroid Build Coastguard Worker const char *Name = Buffer.c_str();
593*9880d681SAndroid Build Coastguard Worker
594*9880d681SAndroid Build Coastguard Worker if (IsUndefined)
595*9880d681SAndroid Build Coastguard Worker addAsmGlobalSymbolUndef(Name);
596*9880d681SAndroid Build Coastguard Worker else if (Flags & object::BasicSymbolRef::SF_Global)
597*9880d681SAndroid Build Coastguard Worker addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_DEFAULT);
598*9880d681SAndroid Build Coastguard Worker else
599*9880d681SAndroid Build Coastguard Worker addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_INTERNAL);
600*9880d681SAndroid Build Coastguard Worker continue;
601*9880d681SAndroid Build Coastguard Worker }
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker auto *F = dyn_cast<Function>(GV);
604*9880d681SAndroid Build Coastguard Worker if (IsUndefined) {
605*9880d681SAndroid Build Coastguard Worker addPotentialUndefinedSymbol(Sym, F != nullptr);
606*9880d681SAndroid Build Coastguard Worker continue;
607*9880d681SAndroid Build Coastguard Worker }
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker if (F) {
610*9880d681SAndroid Build Coastguard Worker addDefinedFunctionSymbol(Sym);
611*9880d681SAndroid Build Coastguard Worker continue;
612*9880d681SAndroid Build Coastguard Worker }
613*9880d681SAndroid Build Coastguard Worker
614*9880d681SAndroid Build Coastguard Worker if (isa<GlobalVariable>(GV)) {
615*9880d681SAndroid Build Coastguard Worker addDefinedDataSymbol(Sym);
616*9880d681SAndroid Build Coastguard Worker continue;
617*9880d681SAndroid Build Coastguard Worker }
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker assert(isa<GlobalAlias>(GV));
620*9880d681SAndroid Build Coastguard Worker addDefinedDataSymbol(Sym);
621*9880d681SAndroid Build Coastguard Worker }
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker // make symbols for all undefines
624*9880d681SAndroid Build Coastguard Worker for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
625*9880d681SAndroid Build Coastguard Worker e = _undefines.end(); u != e; ++u) {
626*9880d681SAndroid Build Coastguard Worker // If this symbol also has a definition, then don't make an undefine because
627*9880d681SAndroid Build Coastguard Worker // it is a tentative definition.
628*9880d681SAndroid Build Coastguard Worker if (_defines.count(u->getKey())) continue;
629*9880d681SAndroid Build Coastguard Worker NameAndAttributes info = u->getValue();
630*9880d681SAndroid Build Coastguard Worker _symbols.push_back(info);
631*9880d681SAndroid Build Coastguard Worker }
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker
634*9880d681SAndroid Build Coastguard Worker /// parseMetadata - Parse metadata from the module
parseMetadata()635*9880d681SAndroid Build Coastguard Worker void LTOModule::parseMetadata() {
636*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(LinkerOpts);
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker // Linker Options
639*9880d681SAndroid Build Coastguard Worker if (Metadata *Val = getModule().getModuleFlag("Linker Options")) {
640*9880d681SAndroid Build Coastguard Worker MDNode *LinkerOptions = cast<MDNode>(Val);
641*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
642*9880d681SAndroid Build Coastguard Worker MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
643*9880d681SAndroid Build Coastguard Worker for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
644*9880d681SAndroid Build Coastguard Worker MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
645*9880d681SAndroid Build Coastguard Worker OS << " " << MDOption->getString();
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker // Globals
651*9880d681SAndroid Build Coastguard Worker Mangler Mang;
652*9880d681SAndroid Build Coastguard Worker for (const NameAndAttributes &Sym : _symbols) {
653*9880d681SAndroid Build Coastguard Worker if (!Sym.symbol)
654*9880d681SAndroid Build Coastguard Worker continue;
655*9880d681SAndroid Build Coastguard Worker _target->getObjFileLowering()->emitLinkerFlagsForGlobal(OS, Sym.symbol,
656*9880d681SAndroid Build Coastguard Worker Mang);
657*9880d681SAndroid Build Coastguard Worker }
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker // Add other interesting metadata here.
660*9880d681SAndroid Build Coastguard Worker }
661