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

[Mach-O] Add -no_function_starts

This commit is contained in:
Rui Ueyama 2022-07-29 10:47:32 +08:00
parent 4ed7d72372
commit b2b16e66b4
5 changed files with 42 additions and 4 deletions

View File

@ -74,6 +74,7 @@ Options:
-needed-framework <NAME>[,<SUFFIX>]
Search for a given framework
-no_deduplicate Ignored
-no_function_starts Do not generate an LC_FUNCTION_STARTS load command
-no_uuid Do not generate an LC_UUID load command
-o <FILE> Set output filename
-objc_abi_version <VERSION> Ignored
@ -408,6 +409,8 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
remaining.push_back("-needed_framework");
remaining.push_back(std::string(arg));
} else if (read_flag("-no_deduplicate")) {
} else if (read_flag("-no_function_starts")) {
ctx.arg.function_starts = false;
} else if (read_flag("-no_uuid")) {
ctx.arg.uuid = UUID_NONE;
} else if (read_arg("-o")) {

View File

@ -324,6 +324,10 @@ static void create_synthetic_chunks(Context<E> &ctx) {
// Create a __DATA,__objc_imageinfo section.
ctx.image_info = ObjcImageInfoSection<E>::create(ctx);
// Create a __LINKEDIT,__func_starts section.
if (ctx.arg.function_starts)
ctx.function_starts.reset(new FunctionStartsSection(ctx));
// Handle -sectcreate
for (SectCreateOption arg : ctx.arg.sectcreate) {
MappedFile<Context<E>> *mf =

View File

@ -876,6 +876,7 @@ struct Context {
bool dynamic = true;
bool export_dynamic = false;
bool fatal_warnings = false;
bool function_starts = true;
bool ignore_optimization_hints = false;
bool mark_dead_strippable_dylib = false;
bool noinhibit_exec = false;
@ -974,10 +975,10 @@ struct Context {
BindSection<E> bind{*this};
LazyBindSection<E> lazy_bind{*this};
ExportSection<E> export_{*this};
FunctionStartsSection<E> function_starts{*this};
SymtabSection<E> symtab{*this};
StrtabSection<E> strtab{*this};
std::unique_ptr<FunctionStartsSection<E>> function_starts;
std::unique_ptr<ObjcImageInfoSection<E>> image_info;
std::unique_ptr<CodeSignatureSection<E>> code_sig;

View File

@ -191,8 +191,8 @@ static std::vector<u8> create_function_starts_cmd(Context<E> &ctx) {
cmd.cmd = LC_FUNCTION_STARTS;
cmd.cmdsize = buf.size();
cmd.dataoff = ctx.function_starts.hdr.offset;
cmd.datasize = ctx.function_starts.hdr.size;
cmd.dataoff = ctx.function_starts->hdr.offset;
cmd.datasize = ctx.function_starts->hdr.size;
return buf;
}
@ -275,7 +275,8 @@ static std::vector<std::vector<u8>> create_load_commands(Context<E> &ctx) {
vec.push_back(create_uuid_cmd(ctx));
vec.push_back(create_build_version_cmd(ctx));
vec.push_back(create_source_version_cmd(ctx));
vec.push_back(create_function_starts_cmd(ctx));
if (ctx.arg.function_starts)
vec.push_back(create_function_starts_cmd(ctx));
for (DylibFile<E> *file : ctx.dylibs)
if (file->dylib_idx != BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE)
@ -971,6 +972,9 @@ void ExportSection<E>::copy_buf(Context<E> &ctx) {
enc.write_trie(buf, enc.root);
}
// LC_FUNCTION_STARTS contains function start addresses encoded in
// ULEB128. I don't know what tools consume this table, but we create
// it anyway by default for the sake of compatibility.
template <typename E>
void FunctionStartsSection<E>::compute_size(Context<E> &ctx) {
std::vector<std::vector<u64>> vec(ctx.objs.size());

View File

@ -0,0 +1,26 @@
#!/bin/bash
export LC_ALL=C
set -e
CC="${TEST_CC:-cc}"
CXX="${TEST_CXX:-c++}"
GCC="${TEST_GCC:-gcc}"
GXX="${TEST_GXX:-g++}"
OBJDUMP="${OBJDUMP:-objdump}"
MACHINE="${MACHINE:-$(uname -m)}"
testname=$(basename "$0" .sh)
echo -n "Testing $testname ... "
t=out/test/macho/$MACHINE/$testname
mkdir -p $t
cat <<EOF | $CC -o $t/a.o -c -xc -
int main() {}
EOF
clang --ld-path=./ld64 -o $t/exe1 $t/a.o
otool -l $t/exe1 | grep -q LC_FUNCTION_STARTS
clang --ld-path=./ld64 -o $t/exe2 $t/a.o -Wl,-no_function_starts
otool -l $t/exe2 > $t/log
! grep -q LC_FUNCTION_STARTS $t/log || false
echo OK