2021-10-03 11:49:33 +03:00
|
|
|
#include "mold.h"
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2021-10-21 17:48:08 +03:00
|
|
|
#include <regex>
|
2021-10-03 11:49:33 +03:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <unordered_set>
|
|
|
|
|
|
|
|
namespace mold::macho {
|
|
|
|
|
|
|
|
static const char helpmsg[] = R"(
|
|
|
|
Options:
|
2021-10-21 17:18:15 +03:00
|
|
|
-arch ARCH_NAME Specify target architecture
|
2021-10-21 16:57:25 +03:00
|
|
|
-demangle Demangle C++ symbols in log messages (default)
|
2021-10-21 17:11:29 +03:00
|
|
|
-dynamic Link against dylibs (default)
|
2021-10-21 16:57:25 +03:00
|
|
|
-help Report usage information
|
2021-10-21 17:11:29 +03:00
|
|
|
-lto_library FILE Ignored
|
2021-10-21 16:57:25 +03:00
|
|
|
-o FILE Set output filename
|
2021-10-21 17:48:08 +03:00
|
|
|
-platform_version PLATFORM MIN_VERSION SDK_VERSION
|
|
|
|
Set platform, platform version and SDK version
|
2021-10-21 16:57:25 +03:00
|
|
|
-v Report version information)";
|
2021-10-03 11:49:33 +03:00
|
|
|
|
2021-10-21 17:48:08 +03:00
|
|
|
static i64 parse_platform(Context &ctx, std::string_view arg) {
|
|
|
|
static std::regex re(R"(\d+)", std::regex_constants::ECMAScript);
|
|
|
|
if (std::regex_match(arg.begin(), arg.end(), re))
|
|
|
|
return stoi(std::string(arg));
|
|
|
|
|
|
|
|
if (arg == "macos")
|
|
|
|
return PLATFORM_MACOS;
|
|
|
|
if (arg == "ios")
|
|
|
|
return PLATFORM_IOS;
|
|
|
|
if (arg == "tvos")
|
|
|
|
return PLATFORM_TVOS;
|
|
|
|
if (arg == "watchos")
|
|
|
|
return PLATFORM_WATCHOS;
|
|
|
|
if (arg == "bridgeos")
|
|
|
|
return PLATFORM_BRIDGEOS;
|
|
|
|
if (arg == "mac-catalyst")
|
|
|
|
return PLATFORM_MACCATALYST;
|
|
|
|
if (arg == "ios-simulator")
|
|
|
|
return PLATFORM_IOSSIMULATOR;
|
|
|
|
if (arg == "tvos-simulator")
|
|
|
|
return PLATFORM_TVOSSIMULATOR;
|
|
|
|
if (arg == "watchos-simulator")
|
|
|
|
return PLATFORM_WATCHOSSIMULATOR;
|
|
|
|
if (arg == "driverkit")
|
|
|
|
return PLATFORM_DRIVERKIT;
|
|
|
|
Fatal(ctx) << "unknown -platform_version name: " << arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static i64 parse_version(Context &ctx, std::string_view arg) {
|
|
|
|
static std::regex re(R"(\d+(?:\.\d+(?:\.\d+)))",
|
|
|
|
std::regex_constants::ECMAScript);
|
|
|
|
std::cmatch m;
|
|
|
|
if (!std::regex_match(arg.begin(), arg.end(), m, re))
|
|
|
|
Fatal(ctx) << "malformed version number: " << arg;
|
|
|
|
return (stoi(m[1]) << 16) | (stoi(m[2]) << 8) | stoi(m[3]);
|
|
|
|
}
|
|
|
|
|
2021-10-03 11:49:33 +03:00
|
|
|
void parse_nonpositional_args(Context &ctx,
|
|
|
|
std::vector<std::string_view> &remaining) {
|
|
|
|
std::span<std::string_view> args = ctx.cmdline_args;
|
|
|
|
args = args.subspan(1);
|
|
|
|
|
|
|
|
bool version_shown = false;
|
|
|
|
|
|
|
|
while (!args.empty()) {
|
|
|
|
std::string_view arg;
|
2021-10-21 17:48:08 +03:00
|
|
|
std::string_view arg2;
|
|
|
|
std::string_view arg3;
|
2021-10-03 11:49:33 +03:00
|
|
|
|
|
|
|
auto read_arg = [&](std::string name) {
|
|
|
|
if (args[0] == name) {
|
|
|
|
if (args.size() == 1)
|
|
|
|
Fatal(ctx) << "option -" << name << ": argument missing";
|
|
|
|
arg = args[1];
|
|
|
|
args = args.subspan(2);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2021-10-21 17:48:08 +03:00
|
|
|
auto read_arg3 = [&](std::string name) {
|
|
|
|
if (args[0] == name) {
|
|
|
|
if (args.size() == 3)
|
|
|
|
Fatal(ctx) << "option -" << name << ": argument missing";
|
|
|
|
arg = args[1];
|
|
|
|
arg2 = args[2];
|
|
|
|
arg3 = args[3];
|
|
|
|
args = args.subspan(4);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2021-10-03 11:49:33 +03:00
|
|
|
auto read_flag = [&](std::string name) {
|
|
|
|
if (args[0] == name) {
|
|
|
|
args = args.subspan(1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (read_flag("-help") || read_flag("--help")) {
|
|
|
|
SyncOut(ctx) << "Usage: " << ctx.cmdline_args[0]
|
|
|
|
<< " [options] file...\n" << helpmsg;
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2021-10-21 17:18:15 +03:00
|
|
|
if (read_arg("-arch")) {
|
|
|
|
if (arg != "x86_64")
|
|
|
|
Fatal(ctx) << "unknown -arch: " << arg;
|
|
|
|
} else if (read_flag("-demangle")) {
|
2021-10-21 16:57:25 +03:00
|
|
|
ctx.arg.demangle = true;
|
2021-10-21 17:11:29 +03:00
|
|
|
} else if (read_flag("-dynamic")) {
|
|
|
|
ctx.arg.dynamic = true;
|
|
|
|
} else if (read_flag("-lto_library")) {
|
2021-10-03 11:49:33 +03:00
|
|
|
} else if (read_arg("-o")) {
|
|
|
|
ctx.arg.output = arg;
|
2021-10-21 17:48:08 +03:00
|
|
|
} else if (read_arg3("-platform_version")) {
|
|
|
|
ctx.arg.platform = parse_platform(ctx, arg);
|
|
|
|
ctx.arg.platform_min_version = parse_version(ctx, arg2);
|
|
|
|
ctx.arg.platform_sdk_version = parse_version(ctx, arg3);
|
2021-10-21 16:57:25 +03:00
|
|
|
} else if (read_flag("-v")) {
|
|
|
|
SyncOut(ctx) << mold_version;
|
2021-10-03 11:49:33 +03:00
|
|
|
} else {
|
|
|
|
if (args[0][0] == '-')
|
|
|
|
Fatal(ctx) << "unknown command line option: " << args[0];
|
|
|
|
remaining.push_back(args[0]);
|
|
|
|
args = args.subspan(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx.arg.output.empty())
|
|
|
|
ctx.arg.output = "a.out";
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mold::macho
|