forked from OSchip/llvm-project
156 lines
4.7 KiB
C++
156 lines
4.7 KiB
C++
//===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
|
|
//
|
|
// The LLVM Linker
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
|
|
#define LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
|
|
|
|
#include "Atoms.h"
|
|
#include "File.h"
|
|
|
|
#include "llvm/BinaryFormat/MachO.h"
|
|
|
|
#include "lld/Core/DefinedAtom.h"
|
|
#include "lld/Core/File.h"
|
|
#include "lld/Core/LinkingContext.h"
|
|
#include "lld/Core/Reference.h"
|
|
#include "lld/Core/Simple.h"
|
|
#include "lld/Core/UndefinedAtom.h"
|
|
#include "lld/ReaderWriter/MachOLinkingContext.h"
|
|
|
|
namespace lld {
|
|
namespace mach_o {
|
|
|
|
|
|
//
|
|
// CEntryFile adds an UndefinedAtom for "_main" so that the Resolving
|
|
// phase will fail if "_main" is undefined.
|
|
//
|
|
class CEntryFile : public SimpleFile {
|
|
public:
|
|
CEntryFile(const MachOLinkingContext &context)
|
|
: SimpleFile("C entry", kindCEntryObject),
|
|
_undefMain(*this, context.entrySymbolName()) {
|
|
this->addAtom(_undefMain);
|
|
}
|
|
|
|
private:
|
|
SimpleUndefinedAtom _undefMain;
|
|
};
|
|
|
|
|
|
//
|
|
// StubHelperFile adds an UndefinedAtom for "dyld_stub_binder" so that
|
|
// the Resolveing phase will fail if "dyld_stub_binder" is undefined.
|
|
//
|
|
class StubHelperFile : public SimpleFile {
|
|
public:
|
|
StubHelperFile(const MachOLinkingContext &context)
|
|
: SimpleFile("stub runtime", kindStubHelperObject),
|
|
_undefBinder(*this, context.binderSymbolName()) {
|
|
this->addAtom(_undefBinder);
|
|
}
|
|
|
|
private:
|
|
SimpleUndefinedAtom _undefBinder;
|
|
};
|
|
|
|
|
|
//
|
|
// MachHeaderAliasFile lazily instantiates the magic symbols that mark the start
|
|
// of the mach_header for final linked images.
|
|
//
|
|
class MachHeaderAliasFile : public SimpleFile {
|
|
public:
|
|
MachHeaderAliasFile(const MachOLinkingContext &context)
|
|
: SimpleFile("mach_header symbols", kindHeaderObject) {
|
|
StringRef machHeaderSymbolName;
|
|
DefinedAtom::Scope symbolScope = DefinedAtom::scopeLinkageUnit;
|
|
StringRef dsoHandleName;
|
|
switch (context.outputMachOType()) {
|
|
case llvm::MachO::MH_OBJECT:
|
|
machHeaderSymbolName = "__mh_object_header";
|
|
break;
|
|
case llvm::MachO::MH_EXECUTE:
|
|
machHeaderSymbolName = "__mh_execute_header";
|
|
symbolScope = DefinedAtom::scopeGlobal;
|
|
dsoHandleName = "___dso_handle";
|
|
break;
|
|
case llvm::MachO::MH_FVMLIB:
|
|
llvm_unreachable("no mach_header symbol for file type");
|
|
case llvm::MachO::MH_CORE:
|
|
llvm_unreachable("no mach_header symbol for file type");
|
|
case llvm::MachO::MH_PRELOAD:
|
|
llvm_unreachable("no mach_header symbol for file type");
|
|
case llvm::MachO::MH_DYLIB:
|
|
machHeaderSymbolName = "__mh_dylib_header";
|
|
dsoHandleName = "___dso_handle";
|
|
break;
|
|
case llvm::MachO::MH_DYLINKER:
|
|
machHeaderSymbolName = "__mh_dylinker_header";
|
|
dsoHandleName = "___dso_handle";
|
|
break;
|
|
case llvm::MachO::MH_BUNDLE:
|
|
machHeaderSymbolName = "__mh_bundle_header";
|
|
dsoHandleName = "___dso_handle";
|
|
break;
|
|
case llvm::MachO::MH_DYLIB_STUB:
|
|
llvm_unreachable("no mach_header symbol for file type");
|
|
case llvm::MachO::MH_DSYM:
|
|
llvm_unreachable("no mach_header symbol for file type");
|
|
case llvm::MachO::MH_KEXT_BUNDLE:
|
|
dsoHandleName = "___dso_handle";
|
|
break;
|
|
}
|
|
if (!machHeaderSymbolName.empty())
|
|
_definedAtoms.push_back(new (allocator()) MachODefinedAtom(
|
|
*this, machHeaderSymbolName, symbolScope,
|
|
DefinedAtom::typeMachHeader, DefinedAtom::mergeNo, false,
|
|
true /* noDeadStrip */,
|
|
ArrayRef<uint8_t>(), DefinedAtom::Alignment(4096)));
|
|
|
|
if (!dsoHandleName.empty())
|
|
_definedAtoms.push_back(new (allocator()) MachODefinedAtom(
|
|
*this, dsoHandleName, DefinedAtom::scopeLinkageUnit,
|
|
DefinedAtom::typeDSOHandle, DefinedAtom::mergeNo, false,
|
|
true /* noDeadStrip */,
|
|
ArrayRef<uint8_t>(), DefinedAtom::Alignment(1)));
|
|
}
|
|
|
|
const AtomRange<DefinedAtom> defined() const override {
|
|
return _definedAtoms;
|
|
}
|
|
const AtomRange<UndefinedAtom> undefined() const override {
|
|
return _noUndefinedAtoms;
|
|
}
|
|
|
|
const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
|
|
return _noSharedLibraryAtoms;
|
|
}
|
|
|
|
const AtomRange<AbsoluteAtom> absolute() const override {
|
|
return _noAbsoluteAtoms;
|
|
}
|
|
|
|
void clearAtoms() override {
|
|
_definedAtoms.clear();
|
|
_noUndefinedAtoms.clear();
|
|
_noSharedLibraryAtoms.clear();
|
|
_noAbsoluteAtoms.clear();
|
|
}
|
|
|
|
|
|
private:
|
|
mutable AtomVector<DefinedAtom> _definedAtoms;
|
|
};
|
|
|
|
} // namespace mach_o
|
|
} // namespace lld
|
|
|
|
#endif // LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
|