Changeset View
Changeset View
Standalone View
Standalone View
lld/MachO/Writer.cpp
Show All 15 Lines | |||||
#include "SymbolTable.h" | #include "SymbolTable.h" | ||||
#include "Symbols.h" | #include "Symbols.h" | ||||
#include "SyntheticSections.h" | #include "SyntheticSections.h" | ||||
#include "Target.h" | #include "Target.h" | ||||
#include "lld/Common/ErrorHandler.h" | #include "lld/Common/ErrorHandler.h" | ||||
#include "lld/Common/Memory.h" | #include "lld/Common/Memory.h" | ||||
#include "llvm/BinaryFormat/MachO.h" | #include "llvm/BinaryFormat/MachO.h" | ||||
#include "llvm/Config/llvm-config.h" | |||||
#include "llvm/Support/LEB128.h" | #include "llvm/Support/LEB128.h" | ||||
#include "llvm/Support/MathExtras.h" | #include "llvm/Support/MathExtras.h" | ||||
#include "llvm/Support/Path.h" | #include "llvm/Support/Path.h" | ||||
using namespace llvm; | using namespace llvm; | ||||
using namespace llvm::MachO; | using namespace llvm::MachO; | ||||
using namespace lld; | using namespace lld; | ||||
using namespace lld::macho; | using namespace lld::macho; | ||||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | |||||
private: | private: | ||||
// Recent versions of Darwin won't run any binary that has dyld at a | // Recent versions of Darwin won't run any binary that has dyld at a | ||||
// different location. | // different location. | ||||
const StringRef path = "/usr/lib/dyld"; | const StringRef path = "/usr/lib/dyld"; | ||||
}; | }; | ||||
class LCRPath : public LoadCommand { | class LCRPath : public LoadCommand { | ||||
public: | public: | ||||
LCRPath(StringRef path) : path(path) {} | LCRPath(StringRef path) : path(path) {} | ||||
int3: nit: const ref | |||||
uint32_t getSize() const override { | uint32_t getSize() const override { | ||||
Not Done ReplyInline ActionsNit: can this and platform be private? smeenai: Nit: can this and `platform` be private? | |||||
return alignTo(sizeof(rpath_command) + path.size() + 1, WordSize); | return alignTo(sizeof(rpath_command) + path.size() + 1, WordSize); | ||||
} | } | ||||
void writeTo(uint8_t *buf) const override { | void writeTo(uint8_t *buf) const override { | ||||
auto *c = reinterpret_cast<rpath_command *>(buf); | auto *c = reinterpret_cast<rpath_command *>(buf); | ||||
buf += sizeof(rpath_command); | buf += sizeof(rpath_command); | ||||
c->cmd = LC_RPATH; | c->cmd = LC_RPATH; | ||||
c->cmdsize = getSize(); | c->cmdsize = getSize(); | ||||
c->path = sizeof(rpath_command); | c->path = sizeof(rpath_command); | ||||
memcpy(buf, path.data(), path.size()); | memcpy(buf, path.data(), path.size()); | ||||
buf[path.size()] = '\0'; | buf[path.size()] = '\0'; | ||||
} | } | ||||
private: | private: | ||||
StringRef path; | StringRef path; | ||||
}; | }; | ||||
class LCBuildVersion : public LoadCommand { | |||||
public: | |||||
LCBuildVersion(const PlatformInfo &platform) : platform(platform) {} | |||||
const int ntools = 1; | |||||
Not Done ReplyInline Actionscodebase convention is not to prefix member variables int3: codebase convention is not to prefix member variables | |||||
Not Done ReplyInline Actionsconst ref int3: const ref | |||||
uint32_t getSize() const override { | |||||
return sizeof(build_version_command) + ntools * sizeof(build_tool_version); | |||||
} | |||||
void writeTo(uint8_t *buf) const override { | |||||
auto *c = reinterpret_cast<build_version_command *>(buf); | |||||
c->cmd = LC_BUILD_VERSION; | |||||
c->cmdsize = getSize(); | |||||
c->platform = static_cast<uint32_t>(platform.kind); | |||||
c->minos = ((platform.minimum.getMajor() << 020) | | |||||
(platform.minimum.getMinor().getValueOr(0) << 010) | | |||||
platform.minimum.getSubminor().getValueOr(0)); | |||||
c->sdk = ((platform.sdk.getMajor() << 020) | | |||||
(platform.sdk.getMinor().getValueOr(0) << 010) | | |||||
platform.sdk.getSubminor().getValueOr(0)); | |||||
c->ntools = ntools; | |||||
auto *t = reinterpret_cast<build_tool_version *>(&c[1]); | |||||
t->tool = TOOL_LD; | |||||
t->version = (LLVM_VERSION_MAJOR << 020) | (LLVM_VERSION_MINOR << 010) | | |||||
LLVM_VERSION_PATCH; | |||||
} | |||||
const PlatformInfo &platform; | |||||
}; | |||||
} // namespace | } // namespace | ||||
void Writer::scanRelocations() { | void Writer::scanRelocations() { | ||||
for (InputSection *isec : inputSections) { | for (InputSection *isec : inputSections) { | ||||
for (Reloc &r : isec->relocs) { | for (Reloc &r : isec->relocs) { | ||||
if (auto *s = r.target.dyn_cast<lld::macho::Symbol *>()) { | if (auto *s = r.target.dyn_cast<lld::macho::Symbol *>()) { | ||||
if (isa<Undefined>(s)) | if (isa<Undefined>(s)) | ||||
error("undefined symbol " + s->getName() + ", referenced from " + | error("undefined symbol " + s->getName() + ", referenced from " + | ||||
Show All 20 Lines | case MH_EXECUTE: | ||||
break; | break; | ||||
case MH_DYLIB: | case MH_DYLIB: | ||||
in.header->addLoadCommand(make<LCDylib>(LC_ID_DYLIB, config->installName)); | in.header->addLoadCommand(make<LCDylib>(LC_ID_DYLIB, config->installName)); | ||||
break; | break; | ||||
default: | default: | ||||
llvm_unreachable("unhandled output file type"); | llvm_unreachable("unhandled output file type"); | ||||
} | } | ||||
in.header->addLoadCommand(make<LCBuildVersion>(config->platform)); | |||||
uint8_t segIndex = 0; | uint8_t segIndex = 0; | ||||
for (OutputSegment *seg : outputSegments) { | for (OutputSegment *seg : outputSegments) { | ||||
in.header->addLoadCommand(make<LCSegment>(seg->name, seg)); | in.header->addLoadCommand(make<LCSegment>(seg->name, seg)); | ||||
seg->index = segIndex++; | seg->index = segIndex++; | ||||
} | } | ||||
uint64_t dylibOrdinal = 1; | uint64_t dylibOrdinal = 1; | ||||
for (InputFile *file : inputFiles) { | for (InputFile *file : inputFiles) { | ||||
▲ Show 20 Lines • Show All 257 Lines • Show Last 20 Lines |
nit: const ref