Files
clang-p2996/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
Nick Kledzik 16cfa60cbd [mach-o] Support linker synthesized mach_header symbols.
On darwin in final linked images, the __TEXT segment covers that start of the
file.  That means in memory a process can see the mach_header (and load commands)
for every loaded image in a process.  There are APIs that take and return the
mach_header addresses as a way to specify a particular loaded image.

For completeness, any code can get the address of the mach_header of the image
it is in by using &__dso_handle.  In addition there are mach-o type specific
symbols like __mh_execute_header.

The linker needs to supply a definition for any of these symbols if used.  But
the address the symbol it resolves to is not in any section.  Instead it is the
address of the start of the __TEXT segment.

I needed to make a small change to SimpleFileNode to not override
resetNextIndex() because the Driver creates a SimpleFileNode to hold the
internal/implicit files that the context/writer can create. For some reason
SimpleFileNode overrode resetNextIndex() to do nothing instead of reseting
the index (which mach-o needs if the internal file is an archive).

llvm-svn: 221822
2014-11-12 22:21:56 +00:00

73 lines
2.4 KiB
C++

//===- lib/ReaderWriter/MachO/WriterMachO.cpp -----------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/Writer.h"
#include "ExecutableAtoms.hpp"
#include "MachONormalizedFile.h"
#include "lld/Core/File.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
using lld::mach_o::normalized::NormalizedFile;
namespace lld {
namespace mach_o {
class MachOWriter : public Writer {
public:
MachOWriter(const MachOLinkingContext &ctxt) : _context(ctxt) { }
std::error_code writeFile(const lld::File &file, StringRef path) override {
// Construct empty normalized file from atoms.
ErrorOr<std::unique_ptr<NormalizedFile>> nFile =
normalized::normalizedFromAtoms(file, _context);
if (std::error_code ec = nFile.getError())
return ec;
// For testing, write out yaml form of normalized file.
if (_context.printAtoms()) {
std::unique_ptr<Writer> yamlWriter = createWriterYAML(_context);
yamlWriter->writeFile(file, "-");
}
// Write normalized file as mach-o binary.
return writeBinary(*nFile->get(), path);
}
bool createImplicitFiles(std::vector<std::unique_ptr<File> > &r) override {
// When building main executables, add _main as required entry point.
if (_context.outputTypeHasEntry())
r.emplace_back(new CEntryFile(_context));
// If this can link with dylibs, need helper function (dyld_stub_binder).
if (_context.needsStubsPass())
r.emplace_back(new StubHelperFile(_context));
// Final linked images can access a symbol for their mach_header.
if (_context.outputMachOType() != llvm::MachO::MH_OBJECT)
r.emplace_back(new MachHeaderAliasFile(_context));
return true;
}
private:
const MachOLinkingContext &_context;
};
} // namespace mach_o
std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &context) {
return std::unique_ptr<Writer>(new lld::mach_o::MachOWriter(context));
}
} // namespace lld