1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-10 00:59:38 +03:00
mold/macho/cmdline.cc

264 lines
8.8 KiB
C++
Raw Normal View History

2021-10-03 11:49:33 +03:00
#include "mold.h"
#include "../cmdline.h"
2021-10-03 11:49:33 +03:00
#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-11-27 13:57:38 +03:00
-F<PATH> Add DIR to framework search path
2021-10-22 09:34:16 +03:00
-L<PATH> Add DIR to library search path
2021-11-28 03:58:25 +03:00
-Z Do not search the standard directories when
searching for libraries and frameworks
2021-11-21 13:54:47 +03:00
-ObjC Load all static archive members that implement
an Objective-C class or category
2021-11-02 09:23:06 +03:00
-adhoc_codesign Add ad-hoc code signature to the output file
-no_adhoc_codesign
2021-10-22 09:34:16 +03:00
-arch <ARCH_NAME> Specify target architecture
2021-11-12 13:28:55 +03:00
-dead_strip Remove unreachable functions and data
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-11-12 13:00:49 +03:00
-e <SYMBOL> Specify the entry point of a main executable
2021-11-20 13:26:29 +03:00
-filelist <FILE>[,<DIR>] Specify the list of input file names
2021-11-27 13:57:38 +03:00
-framework <NAME>,[,<SUFFIX>]
Search for a given framework
2021-10-25 14:14:47 +03:00
-headerpad <SIZE> Allocate the size of padding after load commands
2021-10-21 16:57:25 +03:00
-help Report usage information
2021-10-22 09:38:00 +03:00
-l<LIB> Search for a given library
2021-10-22 09:34:16 +03:00
-lto_library <FILE> Ignored
2021-11-05 08:14:59 +03:00
-map <FILE> Write map file to a given file
2021-10-27 15:15:29 +03:00
-no_deduplicate Ignored
2021-11-05 08:14:59 +03:00
-o <FILE> Set output filename
2021-11-14 08:22:31 +03:00
-pagezero_size <SIZE> Specify the size of the __PAGEZERO segment
2021-10-22 09:34:16 +03:00
-platform_version <PLATFORM> <MIN_VERSION> <SDK_VERSION>
2021-10-21 17:48:08 +03:00
Set platform, platform version and SDK version
2021-11-20 13:01:18 +03:00
-rpath <PATH> Add PATH to the runpath search path list
2021-10-22 09:34:16 +03:00
-syslibroot <DIR> Prepend DIR to library search paths
2021-11-05 12:40:59 +03:00
-t Print out each file the linker loads
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) {
2021-10-23 10:49:06 +03:00
static std::regex re(R"((\d+)(?:\.(\d+))?(?:\.(\d+))?)",
2021-10-21 17:48:08 +03:00
std::regex_constants::ECMAScript);
std::cmatch m;
if (!std::regex_match(arg.begin(), arg.end(), m, re))
Fatal(ctx) << "malformed version number: " << arg;
2021-10-23 10:49:06 +03:00
i64 major = (m[1].length() == 0) ? 0 : stoi(m[1]);
i64 minor = (m[2].length() == 0) ? 0 : stoi(m[2]);
i64 patch = (m[3].length() == 0) ? 0 : stoi(m[3]);
return (major << 16) | (minor << 8) | patch;
2021-10-21 17:48:08 +03:00
}
2021-10-03 11:49:33 +03:00
void parse_nonpositional_args(Context &ctx,
2021-10-22 09:38:00 +03:00
std::vector<std::string> &remaining) {
std::vector<std::string_view> &args = ctx.cmdline_args;
i64 i = 1;
2021-10-03 11:49:33 +03:00
2021-11-27 13:57:38 +03:00
std::vector<std::string> framework_paths;
std::vector<std::string> library_paths;
2021-11-28 03:58:25 +03:00
bool nostdlib = false;
2021-11-27 13:57:38 +03:00
while (i < args.size()) {
2021-10-03 11:49:33 +03:00
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[i] == name) {
if (args.size() <= i + 1)
2021-10-03 11:49:33 +03:00
Fatal(ctx) << "option -" << name << ": argument missing";
arg = args[i + 1];
i += 2;
2021-10-03 11:49:33 +03:00
return true;
}
return false;
};
2021-10-21 17:48:08 +03:00
auto read_arg3 = [&](std::string name) {
if (args[i] == name) {
if (args.size() <= i + 3)
2021-10-21 17:48:08 +03:00
Fatal(ctx) << "option -" << name << ": argument missing";
arg = args[i + 1];
arg2 = args[i + 2];
arg3 = args[i + 3];
i += 4;
2021-10-21 17:48:08 +03:00
return true;
}
return false;
};
2021-10-22 09:38:00 +03:00
auto read_joined = [&](std::string name) {
if (read_arg(name))
return true;
if (args[i].starts_with(name)) {
arg = args[i].substr(2);
i++;
2021-10-22 09:38:00 +03:00
return true;
}
return false;
};
2021-10-03 11:49:33 +03:00
auto read_flag = [&](std::string name) {
if (args[i] == name) {
i++;
2021-10-03 11:49:33 +03:00
return true;
}
return false;
};
if (args[i].starts_with('@')) {
std::vector<std::string_view> vec =
read_response_file(ctx, args[i].substr(1));
args.erase(args.begin() + i);
args.insert(args.begin() + i, vec.begin(), vec.end());
continue;
}
2021-10-03 11:49:33 +03:00
if (read_flag("-help") || read_flag("--help")) {
SyncOut(ctx) << "Usage: " << ctx.cmdline_args[i]
2021-10-03 11:49:33 +03:00
<< " [options] file...\n" << helpmsg;
exit(0);
}
2021-11-27 13:57:38 +03:00
if (read_joined("-F")) {
framework_paths.push_back(std::string(arg));
} else if (read_joined("-L")) {
library_paths.push_back(std::string(arg));
2021-11-28 03:58:25 +03:00
} else if (read_flag("-Z")) {
nostdlib = true;
2021-11-21 13:54:47 +03:00
} else if (read_flag("-ObjC")) {
ctx.arg.ObjC = true;
2021-11-02 09:23:06 +03:00
} else if (read_flag("-adhoc_codesign")) {
ctx.arg.adhoc_codesign = true;
} else if (read_flag("-no_adhoc_codesign")) {
ctx.arg.adhoc_codesign = false;
2021-10-22 09:34:16 +03:00
} else if (read_arg("-arch")) {
2021-10-21 17:18:15 +03:00
if (arg != "x86_64")
Fatal(ctx) << "unknown -arch: " << arg;
2021-11-21 09:32:36 +03:00
} else if (read_flag("-color-diagnostics") ||
read_flag("--color-diagnostics")) {
2021-11-12 13:28:55 +03:00
} else if (read_flag("-dead_strip")) {
ctx.arg.dead_strip = true;
2021-10-21 17:18:15 +03:00
} else if (read_flag("-demangle")) {
2021-10-21 16:57:25 +03:00
ctx.arg.demangle = true;
2021-10-25 14:14:47 +03:00
} else if (read_arg("-headerpad")) {
size_t pos;
ctx.arg.headerpad = std::stoi(std::string(arg), &pos, 16);
if (pos != arg.size())
Fatal(ctx) << "malformed -headerpad: " << arg;
2021-10-21 17:11:29 +03:00
} else if (read_flag("-dynamic")) {
ctx.arg.dynamic = true;
2021-11-12 13:00:49 +03:00
} else if (read_arg("-e")) {
ctx.arg.entry = arg;
2021-11-21 09:31:23 +03:00
} else if (read_arg("-fatal_warnings")) {
2021-11-20 13:26:29 +03:00
} else if (read_arg("-filelist")) {
remaining.push_back("-filelist");
remaining.push_back(std::string(arg));
2021-11-27 13:57:38 +03:00
} else if (read_arg("-framework")) {
remaining.push_back("-framework");
remaining.push_back(std::string(arg));
2021-10-23 11:06:36 +03:00
} else if (read_arg("-lto_library")) {
2021-10-22 09:38:00 +03:00
} else if (read_joined("-l")) {
remaining.push_back("-l" + std::string(arg));
2021-11-05 08:14:59 +03:00
} else if (read_arg("-map")) {
ctx.arg.map = arg;
2021-10-27 15:15:29 +03:00
} else if (read_flag("-no_deduplicate")) {
2021-10-03 11:49:33 +03:00
} else if (read_arg("-o")) {
ctx.arg.output = arg;
2021-11-14 08:22:31 +03:00
} else if (read_arg("-pagezero_size")) {
size_t pos;
ctx.arg.pagezero_size = std::stoi(std::string(arg), &pos, 16);
if (pos != arg.size())
Fatal(ctx) << "malformed -pagezero_size: " << 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-11-20 13:01:18 +03:00
} else if (read_arg("-rpath")) {
ctx.arg.rpath.push_back(std::string(arg));
2021-10-22 09:34:16 +03:00
} else if (read_arg("-syslibroot")) {
2021-11-03 16:07:50 +03:00
ctx.arg.syslibroot.push_back(std::string(arg));
2021-11-05 12:40:59 +03:00
} else if (read_flag("-t")) {
ctx.arg.trace = true;
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 {
2021-11-22 09:36:31 +03:00
if (args[i][0] == '-')
Fatal(ctx) << "unknown command line option: " << args[i];
remaining.push_back(std::string(args[i]));
i++;
2021-10-03 11:49:33 +03:00
}
}
2021-11-27 13:57:38 +03:00
auto add_library_path = [&](std::string path) {
if (!path.starts_with('/') || ctx.arg.syslibroot.empty()) {
ctx.arg.library_paths.push_back(path);
} else {
for (std::string &dir : ctx.arg.syslibroot)
ctx.arg.library_paths.push_back(path_clean(dir + "/" + path));
}
};
2021-11-03 16:07:50 +03:00
2021-11-27 13:57:38 +03:00
for (std::string &path : library_paths)
add_library_path(path);
2021-11-28 03:58:25 +03:00
if (!nostdlib) {
add_library_path("/usr/lib");
add_library_path("/usr/local/lib");
}
2021-11-03 16:07:50 +03:00
2021-11-27 13:57:38 +03:00
auto add_framework_path = [&](std::string path) {
if (!path.starts_with('/') || ctx.arg.syslibroot.empty()) {
ctx.arg.framework_paths.push_back(path);
} else {
for (std::string &dir : ctx.arg.syslibroot)
ctx.arg.framework_paths.push_back(path_clean(dir + "/" + path));
2021-11-03 16:07:50 +03:00
}
2021-11-27 13:57:38 +03:00
};
2021-11-03 16:07:50 +03:00
2021-11-27 13:57:38 +03:00
for (std::string &path : framework_paths)
add_framework_path(path);
2021-11-28 03:58:25 +03:00
if (!nostdlib) {
add_framework_path("/Library/Frameworks");
add_framework_path("/System/Library/Frameworks");
}
2021-10-03 11:49:33 +03:00
}
} // namespace mold::macho