[PATCH] Change how MachOLinkingContext initializes defaults
Joe Ranieri
joe at alacatialabs.com
Fri Dec 6 22:38:22 PST 2013
On Mon, Dec 2, 2013 at 7:12 PM, Nick Kledzik <kledzik at apple.com> wrote:
> Joe,
>
> It is a little odd to have some setXXX() methods be called before initialize() and some after. I’d rather get rid of:
> setOS()
> setArch()
> setOutputFileType()
>
> And instead have just:
> configure(HeaderFileType type, OS os, StringRef minOSVersion);
> which sets those values then does what your initialize() function does.
Fixed.
-- Joe Ranieri
-------------- next part --------------
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index a26ddc1..971dcd4 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -30,6 +30,27 @@ public:
MachOLinkingContext();
~MachOLinkingContext();
+ enum Arch {
+ arch_unknown,
+ arch_ppc,
+ arch_x86,
+ arch_x86_64,
+ arch_armv6,
+ arch_armv7,
+ arch_armv7s,
+ };
+
+ enum class OS {
+ unknown,
+ macOSX,
+ iOS,
+ iOS_simulator
+ };
+
+ /// Initializes the context to sane default values given the specified output
+ /// file type, arch, os, and minimum os version.
+ void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion);
+
virtual void addPasses(PassManager &pm);
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
@@ -50,26 +71,9 @@ public:
HeaderFileType outputFileType() const { return _outputFileType; }
- enum Arch {
- arch_unknown,
- arch_ppc,
- arch_x86,
- arch_x86_64,
- arch_armv6,
- arch_armv7,
- arch_armv7s,
- };
-
- enum class OS {
- unknown, macOSX, iOS, iOS_simulator
- };
-
Arch arch() const { return _arch; }
OS os() const { return _os; }
- void setOutputFileType(HeaderFileType type) { _outputFileType = type; }
- void setArch(Arch arch) { _arch = arch; }
- bool setOS(OS os, StringRef minOSVersion);
bool minOS(StringRef mac, StringRef iOS) const;
void setDoNothing(bool value) { _doNothing = value; }
bool doNothing() const { return _doNothing; }
@@ -147,7 +151,6 @@ private:
};
static ArchInfo _s_archInfos[];
- static const uint64_t unspecifiedPageZeroSize = UINT64_MAX;
HeaderFileType _outputFileType; // e.g MH_EXECUTE
bool _outputFileTypeStatic; // Disambiguate static vs dynamic prog
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index c6c7c81..8ac9903 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -104,30 +104,79 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
}
// Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
+ llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
if ( llvm::opt::Arg *kind = parsedArgs->getLastArg(OPT_dylib, OPT_relocatable,
OPT_bundle, OPT_static, OPT_preload)) {
switch (kind->getOption().getID()) {
case OPT_dylib:
- ctx.setOutputFileType(llvm::MachO::MH_DYLIB);
- ctx.setGlobalsAreDeadStripRoots(true);
+ fileType = llvm::MachO::MH_DYLIB;
break;
case OPT_relocatable:
- ctx.setPrintRemainingUndefines(false);
- ctx.setAllowRemainingUndefines(true);
- ctx.setOutputFileType(llvm::MachO::MH_OBJECT);
+ fileType = llvm::MachO::MH_OBJECT;
break;
case OPT_bundle:
- ctx.setOutputFileType(llvm::MachO::MH_BUNDLE);
+ fileType = llvm::MachO::MH_BUNDLE;
break;
case OPT_static:
- ctx.setOutputFileType(llvm::MachO::MH_EXECUTE);
+ fileType = llvm::MachO::MH_EXECUTE;
break;
case OPT_preload:
- ctx.setOutputFileType(llvm::MachO::MH_PRELOAD);
+ fileType = llvm::MachO::MH_PRELOAD;
break;
}
}
+ // Handle -arch xxx
+ MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
+ if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
+ arch = MachOLinkingContext::archFromName(archStr->getValue());
+ if (arch == MachOLinkingContext::arch_unknown) {
+ diagnostics << "error: unknown arch named '" << archStr->getValue()
+ << "'\n";
+ return false;
+ }
+ }
+
+ // Handle -macosx_version_min or -ios_version_min
+ MachOLinkingContext::OS os = MachOLinkingContext::OS::macOSX;
+ uint32_t minOSVersion = 0;
+ if (llvm::opt::Arg *minOS =
+ parsedArgs->getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
+ OPT_ios_simulator_version_min)) {
+ switch (minOS->getOption().getID()) {
+ case OPT_macosx_version_min:
+ os = MachOLinkingContext::OS::macOSX;
+ if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+ minOSVersion)) {
+ diagnostics << "error: malformed macosx_version_min value\n";
+ return false;
+ }
+ break;
+ case OPT_ios_version_min:
+ os = MachOLinkingContext::OS::iOS;
+ if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+ minOSVersion)) {
+ diagnostics << "error: malformed ios_version_min value\n";
+ return false;
+ }
+ break;
+ case OPT_ios_simulator_version_min:
+ os = MachOLinkingContext::OS::iOS_simulator;
+ if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+ minOSVersion)) {
+ diagnostics << "error: malformed ios_simulator_version_min value\n";
+ return false;
+ }
+ break;
+ }
+ } else {
+ // No min-os version on command line, check environment variables
+ }
+
+ // Now that there's enough information parsed in, let the linking context
+ // set up default values.
+ ctx.configure(fileType, arch, os, minOSVersion);
+
// Handle -e xxx
if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
ctx.setEntrySymbolName(entry->getValue());
@@ -185,47 +234,6 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
if (llvm::opt::Arg *loader = parsedArgs->getLastArg(OPT_bundle_loader))
ctx.setBundleLoader(loader->getValue());
- // Handle -arch xxx
- if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
- ctx.setArch(MachOLinkingContext::archFromName(archStr->getValue()));
- if (ctx.arch() == MachOLinkingContext::arch_unknown) {
- diagnostics << "error: unknown arch named '" << archStr->getValue()
- << "'\n";
- return false;
- }
- }
-
- // Handle -macosx_version_min or -ios_version_min
- if (llvm::opt::Arg *minOS = parsedArgs->getLastArg(
- OPT_macosx_version_min,
- OPT_ios_version_min,
- OPT_ios_simulator_version_min)) {
- switch (minOS->getOption().getID()) {
- case OPT_macosx_version_min:
- if (ctx.setOS(MachOLinkingContext::OS::macOSX, minOS->getValue())) {
- diagnostics << "error: malformed macosx_version_min value\n";
- return false;
- }
- break;
- case OPT_ios_version_min:
- if (ctx.setOS(MachOLinkingContext::OS::iOS, minOS->getValue())) {
- diagnostics << "error: malformed ios_version_min value\n";
- return false;
- }
- break;
- case OPT_ios_simulator_version_min:
- if (ctx.setOS(MachOLinkingContext::OS::iOS_simulator,
- minOS->getValue())) {
- diagnostics << "error: malformed ios_simulator_version_min value\n";
- return false;
- }
- break;
- }
- }
- else {
- // No min-os version on command line, check environment variables
- }
-
// Handle -help
if (parsedArgs->getLastArg(OPT_help)) {
table.PrintHelp(llvm::outs(), argv[0], "LLVM Darwin Linker", false);
diff --git a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index f5dc5c7..474bc03 100644
--- a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -114,13 +114,50 @@ uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
MachOLinkingContext::MachOLinkingContext()
: _outputFileType(MH_EXECUTE), _outputFileTypeStatic(false),
_doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
- _pageZeroSize(unspecifiedPageZeroSize),
- _pageSize(4096),
- _compatibilityVersion(0), _currentVersion(0),
- _deadStrippableDylib(false), _kindHandler(nullptr) {}
+ _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
+ _currentVersion(0), _deadStrippableDylib(false), _kindHandler(nullptr) {}
MachOLinkingContext::~MachOLinkingContext() {}
+void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
+ uint32_t minOSVersion) {
+ _outputFileType = type;
+ _arch = arch;
+ _os = os;
+ _osMinVersion = minOSVersion;
+
+ switch (_outputFileType) {
+ case llvm::MachO::MH_EXECUTE:
+ // If targeting newer OS, use _main
+ if (minOS("10.8", "6.0")) {
+ _entrySymbolName = "_main";
+ } else {
+ // If targeting older OS, use start (in crt1.o)
+ _entrySymbolName = "start";
+ }
+
+ // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
+ // support) and 4KB on 32-bit.
+ if (is64Bit(_arch)) {
+ _pageZeroSize = 0x100000000;
+ } else {
+ _pageZeroSize = 0x1000;
+ }
+
+ break;
+ case llvm::MachO::MH_DYLIB:
+ _globalsAreDeadStripRoots = true;
+ break;
+ case llvm::MachO::MH_BUNDLE:
+ break;
+ case llvm::MachO::MH_OBJECT:
+ _printRemainingUndefines = false;
+ _allowRemainingUndefines = true;
+ default:
+ break;
+ }
+}
+
uint32_t MachOLinkingContext::getCPUType() const {
return cpuTypeFromArch(_arch);
}
@@ -218,29 +255,8 @@ bool MachOLinkingContext::addUnixThreadLoadCommand() const {
}
bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
- if ((_outputFileType == MH_EXECUTE) && _entrySymbolName.empty()){
- if (_outputFileTypeStatic) {
- _entrySymbolName = "start";
- } else if (addUnixThreadLoadCommand()) {
- // If targeting older OS, use start (in crt1.o)
- _entrySymbolName = "start";
- } else if (addEntryPointLoadCommand()) {
- // If targeting newer OS, use _main
- _entrySymbolName = "_main";
- }
- }
-
// TODO: if -arch not specified, look at arch of first .o file.
- // Set default __PAGEZERO for main executables
- if ((_outputFileType == MH_EXECUTE) && !_outputFileTypeStatic
- && (_pageZeroSize == unspecifiedPageZeroSize)) {
- if (is64Bit(_arch))
- _pageZeroSize = 0x100000000;
- else
- _pageZeroSize = 0x00010000;
- }
-
if (_currentVersion && _outputFileType != MH_DYLIB) {
diagnostics << "error: -current_version can only be used with dylibs\n";
return false;
@@ -267,11 +283,6 @@ bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
return true;
}
-bool MachOLinkingContext::setOS(OS os, StringRef minOSVersion) {
- _os = os;
- return parsePackedVersion(minOSVersion, _osMinVersion);
-}
-
void MachOLinkingContext::addPasses(PassManager &pm) {
if (outputFileType() != MH_OBJECT) {
pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
More information about the llvm-commits
mailing list