In r259574 I fixed some of the issues with the mach header symbols and DSO handles. This is the next issue whereby the __mh_execute_header has to not be dead stripped, and (to match ld64) should be dynamically referenced. The test here should also have been added in r259574 to make sure that we emit this symbol. But checking that it is not only emitted but also has the correct reference type is fine. llvm-svn: 259589
149 lines
4.5 KiB
C++
149 lines
4.5 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/Support/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;
|
|
bool noDeadStrip = false;
|
|
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;
|
|
noDeadStrip = true;
|
|
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, 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, false,
|
|
ArrayRef<uint8_t>(), DefinedAtom::Alignment(1)));
|
|
}
|
|
|
|
const AtomVector<DefinedAtom> &defined() const override {
|
|
return _definedAtoms;
|
|
}
|
|
const AtomVector<UndefinedAtom> &undefined() const override {
|
|
return _noUndefinedAtoms;
|
|
}
|
|
|
|
const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {
|
|
return _noSharedLibraryAtoms;
|
|
}
|
|
|
|
const AtomVector<AbsoluteAtom> &absolute() const override {
|
|
return _noAbsoluteAtoms;
|
|
}
|
|
|
|
|
|
private:
|
|
mutable AtomVector<DefinedAtom> _definedAtoms;
|
|
};
|
|
|
|
} // namespace mach_o
|
|
} // namespace lld
|
|
|
|
#endif // LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
|