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:
parent
4ed7d72372
commit
b2b16e66b4
@ -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")) {
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
26
test/macho/no-function-starts.sh
Executable file
26
test/macho/no-function-starts.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user