[mach-o]: implement -image_base option on Darwin.
As suggested by Nick, this will make __unwind_info implementation more natural, and it'd have to be done at some point anyway. llvm-svn: 217486
This commit is contained in:
parent
75ee6b4302
commit
af3075b93f
|
@ -108,6 +108,9 @@ public:
|
|||
bool PIE() const { return _pie; }
|
||||
void setPIE(bool pie) { _pie = pie; }
|
||||
|
||||
uint64_t baseAddress() const { return _baseAddress; }
|
||||
void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; }
|
||||
|
||||
/// \brief Checks whether a given path on the filesystem exists.
|
||||
///
|
||||
/// When running in -test_file_usage mode, this method consults an
|
||||
|
@ -275,6 +278,7 @@ private:
|
|||
uint32_t _osMinVersion;
|
||||
uint64_t _pageZeroSize;
|
||||
uint64_t _pageSize;
|
||||
uint64_t _baseAddress;
|
||||
uint32_t _compatibilityVersion;
|
||||
uint32_t _currentVersion;
|
||||
StringRef _installName;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "llvm/Support/Signals.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace lld;
|
||||
|
||||
|
@ -312,6 +313,20 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
|
|||
else
|
||||
ctx.setOutputPath("a.out");
|
||||
|
||||
if (llvm::opt::Arg *imageBase = parsedArgs->getLastArg(OPT_image_base)) {
|
||||
char *endPtr;
|
||||
uint64_t baseAddress = strtoull(imageBase->getValue(), &endPtr, 16);
|
||||
if (*endPtr != 0) {
|
||||
diagnostics << "error: image_base expects a hex number\n";
|
||||
return false;
|
||||
} else if (baseAddress < ctx.pageZeroSize()) {
|
||||
diagnostics << "error: image_base overlaps with __PAGEZERO\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx.setBaseAddress(baseAddress);
|
||||
}
|
||||
|
||||
// Handle -dead_strip
|
||||
if (parsedArgs->getLastArg(OPT_dead_strip))
|
||||
ctx.setDeadStripping(true);
|
||||
|
|
|
@ -142,6 +142,7 @@ def arch : Separate<["-"], "arch">,
|
|||
def sectalign : MultiArg<["-"], "sectalign", 3>,
|
||||
MetaVarName<"<segname> <sectname> <alignment>">,
|
||||
HelpText<"alignment for segment/section">;
|
||||
def image_base : Separate<["-"], "image_base">;
|
||||
def t : Flag<["-"], "t">,
|
||||
HelpText<"Print the names of the input files as ld processes them">;
|
||||
def v : Flag<["-"], "v">,
|
||||
|
|
|
@ -133,11 +133,10 @@ bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
|
|||
|
||||
MachOLinkingContext::MachOLinkingContext()
|
||||
: _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
|
||||
_doNothing(false), _pie(false),
|
||||
_arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
|
||||
_pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
|
||||
_currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
|
||||
_testingFileUsage(false), _keepPrivateExterns(false),
|
||||
_doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
|
||||
_osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
|
||||
_compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
|
||||
_printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
|
||||
_archHandler(nullptr), _exportMode(ExportMode::globals) {}
|
||||
|
||||
MachOLinkingContext::~MachOLinkingContext() {}
|
||||
|
|
|
@ -95,8 +95,8 @@ SegmentInfo::SegmentInfo(StringRef n)
|
|||
|
||||
class Util {
|
||||
public:
|
||||
Util(const MachOLinkingContext &ctxt) : _context(ctxt),
|
||||
_archHandler(ctxt.archHandler()), _entryAtom(nullptr) {}
|
||||
Util(const MachOLinkingContext &ctxt)
|
||||
: _context(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr) {}
|
||||
|
||||
void assignAtomsToSections(const lld::File &atomFile);
|
||||
void organizeSections();
|
||||
|
@ -468,16 +468,19 @@ void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
|
|||
|
||||
void Util::assignAddressesToSections(const NormalizedFile &file) {
|
||||
size_t hlcSize = headerAndLoadCommandsSize(file);
|
||||
uint64_t address = 0; // FIXME
|
||||
uint64_t address = 0;
|
||||
if (_context.outputMachOType() != llvm::MachO::MH_OBJECT) {
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
if (seg->name.equals("__PAGEZERO")) {
|
||||
seg->size = _context.pageZeroSize();
|
||||
address += seg->size;
|
||||
}
|
||||
else if (seg->name.equals("__TEXT"))
|
||||
else if (seg->name.equals("__TEXT")) {
|
||||
// _context.baseAddress() == 0 implies it was either unspecified or
|
||||
// pageZeroSize is also 0. In either case resetting address is safe.
|
||||
address = _context.baseAddress() ? _context.baseAddress() : address;
|
||||
layoutSectionsInTextSegment(hlcSize, seg, address);
|
||||
else
|
||||
} else
|
||||
layoutSectionsInSegment(seg, address);
|
||||
|
||||
address = llvm::RoundUpToAlignment(address, _context.pageSize());
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t -image_base 31415926530 %p/Inputs/libSystem.yaml
|
||||
# RUN: macho-dump %t | FileCheck %s
|
||||
|
||||
--- !native
|
||||
defined-atoms:
|
||||
- name: _main
|
||||
scope: global
|
||||
content: []
|
||||
|
||||
# Unfortunately, llvm-objdump and llvm-readobj are too generic and don't give
|
||||
# us easy access to the MachO segment model, so we have to check the uglier
|
||||
# macho-dump output.
|
||||
# CHECK: 'segment_name', '__TEXT
|
||||
# CHECK-NEXT: 'vm_addr', 3384796144944
|
Loading…
Reference in New Issue