1
1
mirror of https://github.com/rui314/mold.git synced 2024-10-04 16:48:04 +03:00

[ELF] Deduce emulation from input files if -m is not given

This commit is contained in:
Rui Ueyama 2022-01-05 19:54:34 +09:00
parent 31a6a1164e
commit be49d673a5
3 changed files with 38 additions and 1 deletions

View File

@ -103,6 +103,7 @@ void read_file(Context<E> &ctx, MappedFile<Context<E>> *mf) {
template <typename E>
static i64 get_machine_type(Context<E> &ctx, MappedFile<Context<E>> *mf) {
switch (get_file_type(mf)) {
case FileType::ELF_OBJ:
case FileType::ELF_DSO:
return ((ElfEhdr<E> *)mf->data)->e_machine;
case FileType::AR:
@ -122,6 +123,17 @@ static i64 get_machine_type(Context<E> &ctx, MappedFile<Context<E>> *mf) {
}
}
template <typename E>
static i64
deduce_machine_type(Context<E> &ctx, std::span<std::string_view> args) {
for (std::string_view arg : args)
if (!arg.starts_with('-'))
if (auto *mf = MappedFile<Context<E>>::open(ctx, std::string(arg)))
if (i64 type = get_machine_type(ctx, mf); type != -1)
return type;
Fatal(ctx) << "-m option is missing";
}
template <typename E>
static MappedFile<Context<E>> *open_library(Context<E> &ctx, std::string path) {
MappedFile<Context<E>> *mf = MappedFile<Context<E>>::open(ctx, path);
@ -341,6 +353,10 @@ static int elf_main(int argc, char **argv) {
std::vector<std::string_view> file_args;
parse_nonpositional_args(ctx, file_args);
// If no -m option is given, deduce it from input files.
if (ctx.arg.emulation == -1)
ctx.arg.emulation = deduce_machine_type(ctx, file_args);
// Redo if -m is not x86-64.
if (ctx.arg.emulation != E::e_machine) {
switch (ctx.arg.emulation) {

View File

@ -1264,7 +1264,7 @@ struct Context {
bool z_relro = true;
bool z_text = false;
u16 default_version = VER_NDX_GLOBAL;
i64 emulation = EM_X86_64;
i64 emulation = -1;
i64 filler = -1;
i64 spare_dynamic_tags = 5;
i64 thread_count = 0;

21
test/elf/emulation-deduction.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
export LANG=
set -e
testname=$(basename -s .sh "$0")
echo -n "Testing $testname ... "
cd "$(dirname "$0")"/../..
mold="$(pwd)/mold"
t="$(pwd)/out/test/elf/$testname"
mkdir -p "$t"
# Skip if target is not x86-64
[ "$(uname -m)" = x86_64 ] || { echo skipped; exit; }
cat <<EOF | cc -o "$t"/a.o -c -xc -
void _start() {}
EOF
"$mold" -o "$t"/exe "$t"/a.o
readelf --file-header "$t"/exe | grep -qi x86-64
echo OK