1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-22 10:27:48 +03:00
This commit is contained in:
Rui Ueyama 2021-03-05 19:38:37 +09:00
parent 5af16edfcf
commit 6a34935cc9
4 changed files with 105 additions and 130 deletions

View File

@ -143,50 +143,9 @@ static i64 parse_number(std::string opt, std::string_view value) {
return std::stol(std::string(value));
}
static std::vector<std::string_view> get_input_files(std::span<std::string_view> args) {
static std::unordered_set<std::string_view> needs_arg({
"o", "dynamic-linker", "e", "entry", "y", "trace-symbol",
"filler", "sysroot", "thread-count", "z", "hash-style", "m",
"rpath", "rpath-link", "version-script",
});
std::vector<std::string_view> vec;
std::vector<std::string> library_paths;
while (args.empty()) {
if (needs_arg.contains(args[0])) {
if (args.size() == 1)
Fatal() << args[0] << ": missing argument";
args = args.subspan(2);
continue;
}
std::string_view arg;
if (read_arg(args, arg, "L") || read_arg(args, arg, "library-path")) {
library_paths.push_back(std::string(arg));
}
if (read_arg(args, arg, "l")) {
vec.push_back(arg);
continue;
}
if (args[0].starts_with("-")) {
args = args.subspan(1);
continue;
}
vec.push_back(args[0]);
args = args.subspan(1);
}
return vec;
}
Config parse_nonpositional_args(std::span<std::string_view> args,
std::vector<std::string_view> &remaining) {
Config conf;
conf.thread_count =
void parse_nonpositional_args(std::span<std::string_view> args,
std::vector<std::string_view> &remaining) {
config.thread_count =
tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism);
while (!args.empty()) {
@ -198,149 +157,149 @@ Config parse_nonpositional_args(std::span<std::string_view> args,
}
if (read_arg(args, arg, "o")) {
conf.output = arg;
config.output = arg;
} else if (read_arg(args, arg, "dynamic-linker")) {
conf.dynamic_linker = arg;
config.dynamic_linker = arg;
} else if (read_flag(args, "export-dynamic") || read_flag(args, "E")) {
conf.export_dynamic = true;
config.export_dynamic = true;
} else if (read_flag(args, "no-export-dynamic")) {
conf.export_dynamic = false;
config.export_dynamic = false;
} else if (read_flag(args, "Bsymbolic")) {
conf.Bsymbolic = true;
config.Bsymbolic = true;
} else if (read_flag(args, "Bsymbolic-functions")) {
conf.Bsymbolic_functions = true;
config.Bsymbolic_functions = true;
} else if (read_arg(args, arg, "e") || read_arg(args, arg, "entry")) {
conf.entry = arg;
config.entry = arg;
} else if (read_flag(args, "print-map")) {
conf.print_map = true;
config.print_map = true;
} else if (read_flag(args, "static")) {
conf.is_static = true;
config.is_static = true;
} else if (read_flag(args, "shared") || read_flag(args, "Bshareable")) {
conf.shared = true;
config.shared = true;
} else if (read_flag(args, "demangle")) {
conf.demangle = true;
config.demangle = true;
} else if (read_flag(args, "no-demangle")) {
conf.demangle = false;
config.demangle = false;
} else if (read_arg(args, arg, "y") || read_arg(args, arg, "trace-symbol")) {
conf.trace_symbol.push_back(arg);
config.trace_symbol.push_back(arg);
} else if (read_arg(args, arg, "filler")) {
conf.filler = parse_hex("filler", arg);
config.filler = parse_hex("filler", arg);
} else if (read_arg(args, arg, "L") || read_arg(args, arg, "library-path")) {
conf.library_paths.push_back(arg);
config.library_paths.push_back(arg);
} else if (read_arg(args, arg, "sysroot")) {
conf.sysroot = arg;
config.sysroot = arg;
} else if (read_arg(args, arg, "u") || read_arg(args, arg, "undefined")) {
conf.undefined.push_back(arg);
config.undefined.push_back(arg);
} else if (read_arg(args, arg, "init")) {
conf.init = arg;
config.init = arg;
} else if (read_arg(args, arg, "fini")) {
conf.fini = arg;
config.fini = arg;
} else if (read_arg(args, arg, "soname") || read_arg(args, arg, "h")) {
conf.soname = arg;
config.soname = arg;
} else if (read_arg(args, arg, "hash-style")) {
if (arg == "sysv") {
conf.hash_style_sysv = true;
conf.hash_style_gnu = false;
config.hash_style_sysv = true;
config.hash_style_gnu = false;
} else if (arg == "gnu") {
conf.hash_style_sysv = false;
conf.hash_style_gnu = true;
config.hash_style_sysv = false;
config.hash_style_gnu = true;
} else if (arg == "both") {
conf.hash_style_sysv = true;
conf.hash_style_gnu = true;
config.hash_style_sysv = true;
config.hash_style_gnu = true;
} else {
Fatal() << "invalid --hash-style argument: " << arg;
}
} else if (read_flag(args, "allow-multiple-definition")) {
conf.allow_multiple_definition = true;
config.allow_multiple_definition = true;
} else if (read_flag(args, "trace")) {
conf.trace = true;
config.trace = true;
} else if (read_flag(args, "eh-frame-hdr")) {
conf.eh_frame_hdr = true;
config.eh_frame_hdr = true;
} else if (read_flag(args, "no-eh-frame-hdr")) {
conf.eh_frame_hdr = false;
config.eh_frame_hdr = false;
} else if (read_flag(args, "pie") || read_flag(args, "pic-executable")) {
conf.pic = true;
conf.pie = true;
config.pic = true;
config.pie = true;
} else if (read_flag(args, "no-pie") || read_flag(args, "no-pic-executable")) {
conf.pic = false;
conf.pie = false;
config.pic = false;
config.pie = false;
} else if (read_flag(args, "relax")) {
conf.relax = true;
config.relax = true;
} else if (read_flag(args, "no-relax")) {
conf.relax = false;
config.relax = false;
} else if (read_flag(args, "print-perf")) {
conf.print_perf = true;
config.print_perf = true;
} else if (read_flag(args, "print-stats")) {
conf.print_stats = true;
config.print_stats = true;
} else if (read_z_flag(args, "now")) {
conf.z_now = true;
config.z_now = true;
} else if (read_flag(args, "fork")) {
conf.fork = true;
config.fork = true;
} else if (read_flag(args, "no-fork")) {
conf.fork = false;
config.fork = false;
} else if (read_flag(args, "gc-sections")) {
conf.gc_sections = true;
config.gc_sections = true;
} else if (read_flag(args, "no-gc-sections")) {
conf.gc_sections = false;
config.gc_sections = false;
} else if (read_flag(args, "print-gc-sections")) {
conf.print_gc_sections = true;
config.print_gc_sections = true;
} else if (read_flag(args, "no-print-gc-sections")) {
conf.print_gc_sections = false;
config.print_gc_sections = false;
} else if (read_flag(args, "icf")) {
conf.icf = true;
config.icf = true;
} else if (read_flag(args, "no-icf")) {
conf.icf = false;
config.icf = false;
} else if (read_flag(args, "quick-exit")) {
conf.quick_exit = true;
config.quick_exit = true;
} else if (read_flag(args, "no-quick-exit")) {
conf.quick_exit = false;
config.quick_exit = false;
} else if (read_flag(args, "print-icf-sections")) {
conf.print_icf_sections = true;
config.print_icf_sections = true;
} else if (read_flag(args, "no-print-icf-sections")) {
conf.print_icf_sections = false;
config.print_icf_sections = false;
} else if (read_flag(args, "quick-exit")) {
conf.quick_exit = true;
config.quick_exit = true;
} else if (read_flag(args, "no-quick-exit")) {
conf.quick_exit = false;
config.quick_exit = false;
} else if (read_arg(args, arg, "thread-count")) {
conf.thread_count = parse_number("thread-count", arg);
config.thread_count = parse_number("thread-count", arg);
} else if (read_flag(args, "no-threads")) {
conf.thread_count = 1;
config.thread_count = 1;
} else if (read_flag(args, "discard-all") || read_flag(args, "x")) {
conf.discard_all = true;
config.discard_all = true;
} else if (read_flag(args, "discard-locals") || read_flag(args, "X")) {
conf.discard_locals = true;
config.discard_locals = true;
} else if (read_flag(args, "strip-all") || read_flag(args, "s")) {
conf.strip_all = true;
config.strip_all = true;
} else if (read_arg(args, arg, "rpath")) {
if (!conf.rpaths.empty())
conf.rpaths += ":";
conf.rpaths += arg;
if (!config.rpaths.empty())
config.rpaths += ":";
config.rpaths += arg;
} else if (read_arg(args, arg, "version-script")) {
conf.version_script.push_back(arg);
parse_version_script(std::string(arg));
} else if (read_flag(args, "build-id")) {
conf.build_id = BuildIdKind::HASH;
conf.build_id_size = 20;
config.build_id = BuildIdKind::HASH;
config.build_id_size = 20;
} else if (read_arg(args, arg, "build-id")) {
if (arg == "none") {
conf.build_id = BuildIdKind::NONE;
config.build_id = BuildIdKind::NONE;
} else if (arg == "uuid") {
conf.build_id = BuildIdKind::UUID;
conf.build_id_size = 16;
config.build_id = BuildIdKind::UUID;
config.build_id_size = 16;
} else if (arg == "md5") {
conf.build_id = BuildIdKind::HASH;
conf.build_id_size = 16;
config.build_id = BuildIdKind::HASH;
config.build_id_size = 16;
} else if (arg == "sha1") {
conf.build_id = BuildIdKind::HASH;
conf.build_id_size = 20;
config.build_id = BuildIdKind::HASH;
config.build_id_size = 20;
} else if (arg == "sha256") {
conf.build_id = BuildIdKind::HASH;
conf.build_id_size = 32;
config.build_id = BuildIdKind::HASH;
config.build_id_size = 32;
} else {
Fatal() << "invalid --build-id argument: " << arg;
}
} else if (read_flag(args, "preload")) {
conf.preload = true;
config.preload = true;
} else if (read_arg(args, arg, "z")) {
} else if (read_arg(args, arg, "O")) {
} else if (read_flag(args, "O0")) {
@ -376,11 +335,9 @@ Config parse_nonpositional_args(std::span<std::string_view> args,
}
}
if (conf.shared) {
conf.pic = true;
conf.dynamic_linker = "";
if (config.shared) {
config.pic = true;
config.dynamic_linker = "";
}
return conf;
}

View File

@ -793,7 +793,7 @@ int main(int argc, char **argv) {
// Parse non-positional command line options
std::vector<std::string_view> arg_vector = expand_response_files(argv + 1);
std::vector<std::string_view> file_args;
config = parse_nonpositional_args(arg_vector, file_args);
parse_nonpositional_args(arg_vector, file_args);
if (config.output == "")
Fatal() << "-o option is missing";
@ -827,9 +827,6 @@ int main(int argc, char **argv) {
for (std::string_view arg : config.trace_symbol)
Symbol::intern(arg)->traced = true;
for (std::string_view arg : config.version_script)
parse_version_script(std::string(arg));
// Parse input files
{
Timer t("parse");

5
mold.h
View File

@ -100,7 +100,6 @@ struct Config {
std::vector<std::string_view> library_paths;
std::vector<std::string_view> trace_symbol;
std::vector<std::string_view> undefined;
std::vector<std::string_view> version_script;
u64 image_base = 0x200000;
};
@ -1170,8 +1169,8 @@ bool read_flag(std::span<std::string_view> &args, std::string name);
bool read_arg(std::span<std::string_view> &args, std::string_view &arg,
std::string name);
Config parse_nonpositional_args(std::span<std::string_view> args,
std::vector<std::string_view> &remaining);
void parse_nonpositional_args(std::span<std::string_view> args,
std::vector<std::string_view> &remaining);
//
// main.cc

22
test/version-script.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
set -e
cd $(dirname $0)
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/tmp/$(basename -s .sh $0)
mkdir -p $t
echo 'ver_x { global: *; };' > $t/a.ver
cat <<EOF > $t/b.s
.globl foo, bar, baz
foo:
nop
bar:
nop
baz:
nop
EOF
clang -fuse-ld=`pwd`/../mold -shared -o $t/c.so -Wl,-version-script,$t/a.ver $t/b.s
echo OK