Skip to content

Commit

Permalink
[Mach-O] Add -sectcreate
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed May 21, 2022
1 parent 7f84e42 commit e293d56
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 9 deletions.
15 changes: 9 additions & 6 deletions macho/cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ static const char helpmsg[] = R"(
Set platform, platform version and SDK version
-random_uuid Generate a random LC_UUID load command
-rpath <PATH> Add PATH to the runpath search path list
-search_dylibs_first
-search_paths_first
-sectcreate <SEGNAME> <SECTNAME> <FILE>
-stack_size <SIZE>
-syslibroot <DIR> Prepend DIR to library search paths
-search_paths_first
-search_dylibs_first
-t Print out each file the linker loads
-v Report version information)";

Expand Down Expand Up @@ -300,14 +301,16 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.uuid = UUID_RANDOM;
} else if (read_arg("-rpath")) {
ctx.arg.rpath.push_back(std::string(arg));
} else if (read_hex("-stack_size")) {
ctx.arg.stack_size = hex_arg;
} else if (read_arg("-syslibroot")) {
ctx.arg.syslibroot.push_back(std::string(arg));
} else if (read_flag("-search_paths_first")) {
ctx.arg.search_paths_first = true;
} else if (read_flag("-search_dylibs_first")) {
ctx.arg.search_paths_first = false;
} else if (read_arg3("-sectcreate")) {
ctx.arg.sectcreate.push_back({arg, arg2, arg3});
} else if (read_hex("-stack_size")) {
ctx.arg.stack_size = hex_arg;
} else if (read_arg("-syslibroot")) {
ctx.arg.syslibroot.push_back(std::string(arg));
} else if (read_flag("-t")) {
ctx.arg.trace = true;
} else if (read_flag("-v")) {
Expand Down
9 changes: 9 additions & 0 deletions macho/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,15 @@ static int do_main(int argc, char **argv) {
Fatal(ctx) << "unknown cputype: " << ctx.arg.arch;
}

// Handle -sectcreate
for (SectCreateOption arg : ctx.arg.sectcreate) {
MappedFile<Context<E>> *mf =
MappedFile<Context<E>>::must_open(ctx, std::string(arg.filename));
SectCreateSection<E> *sec =
new SectCreateSection<E>(ctx, arg.segname, arg.sectname, mf->get_contents());
ctx.chunk_pool.emplace_back(sec);
}

read_input_files(ctx, file_args);

for (ObjectFile<E> *file : ctx.objs)
Expand Down
23 changes: 22 additions & 1 deletion macho/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,20 @@ class ThreadPtrsSection : public Chunk<E> {
std::vector<Symbol<E> *> syms;
};

template <typename E>
class SectCreateSection : public Chunk<E> {
public:
SectCreateSection(Context<E> &ctx, std::string_view seg, std::string_view sect,
std::string_view contents)
: Chunk<E>(ctx, seg, sect), contents(contents) {
this->hdr.size = contents.size();
}

void copy_buf(Context<E> &ctx) override;

std::string_view contents;
};

//
// mapfile.cc
//
Expand Down Expand Up @@ -754,6 +768,12 @@ void do_lto(Context<E> &ctx);

enum UuidKind { UUID_NONE, UUID_HASH, UUID_RANDOM };

struct SectCreateOption {
std::string_view segname;
std::string_view sectname;
std::string_view filename;
};

template <typename E>
struct Context {
Context() {
Expand Down Expand Up @@ -820,6 +840,7 @@ struct Context {
std::vector<std::string> mllvm;
std::vector<std::string> rpath;
std::vector<std::string> syslibroot;
std::vector<SectCreateOption> sectcreate;
} arg;

std::vector<std::string_view> cmdline_args;
Expand All @@ -846,7 +867,7 @@ struct Context {
tbb::concurrent_vector<std::unique_ptr<DylibFile<E>>> dylib_pool;
tbb::concurrent_vector<std::unique_ptr<u8[]>> string_pool;
tbb::concurrent_vector<std::unique_ptr<MappedFile<Context<E>>>> mf_pool;
std::vector<std::unique_ptr<OutputSection<E>>> osec_pool;
std::vector<std::unique_ptr<Chunk<E>>> chunk_pool;

tbb::concurrent_vector<std::unique_ptr<TimerRecord>> timer_records;

Expand Down
10 changes: 8 additions & 2 deletions macho/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ OutputSection<E>::get_instance(Context<E> &ctx, std::string_view segname,
return osec;

OutputSection<E> *osec = new OutputSection<E>(ctx, segname, sectname);
ctx.osec_pool.emplace_back(osec);
ctx.chunk_pool.emplace_back(osec);
return osec;
}

Expand Down Expand Up @@ -1335,6 +1335,11 @@ void ThreadPtrsSection<E>::copy_buf(Context<E> &ctx) {
buf[i] = sym.get_addr(ctx);
}

template <typename E>
void SectCreateSection<E>::copy_buf(Context<E> &ctx) {
write_string(ctx.buf + this->hdr.offset, contents);
}

#define INSTANTIATE(E) \
template class OutputSegment<E>; \
template class OutputMachHeader<E>; \
Expand All @@ -1354,7 +1359,8 @@ void ThreadPtrsSection<E>::copy_buf(Context<E> &ctx) {
template class UnwindInfoSection<E>; \
template class GotSection<E>; \
template class LazySymbolPtrSection<E>; \
template class ThreadPtrsSection<E>
template class ThreadPtrsSection<E>; \
template class SectCreateSection<E>

INSTANTIATE_ALL;

Expand Down
29 changes: 29 additions & 0 deletions test/macho/sectcreate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/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 ... "
cd "$(dirname "$0")"/../..
t=out/test/macho/$testname
mkdir -p $t

cat <<EOF | $CC -o $t/a.o -c -xc -
int main() {}
EOF

echo 'foobar' > $t/contents

clang --ld-path=./ld64 -o $t/exe $t/a.o -Wl,-sectcreate,__TEXT,__foo,$t/contents

otool -l $t/exe | grep -A3 'sectname __foo' > $t/log
grep -q 'segname __TEXT' $t/log
grep -q 'segname __TEXT' $t/log
grep -q 'size 0x0*7$' $t/log

echo OK

0 comments on commit e293d56

Please sign in to comment.