2021-09-08 13:02:38 +03:00
|
|
|
#include "mold.h"
|
|
|
|
|
2021-09-13 12:15:34 +03:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <fcntl.h>
|
2021-09-14 07:12:43 +03:00
|
|
|
#include <iomanip>
|
2021-09-08 13:15:12 +03:00
|
|
|
#include <iostream>
|
2021-09-13 12:15:34 +03:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2021-09-08 13:15:12 +03:00
|
|
|
|
2021-09-08 13:02:38 +03:00
|
|
|
namespace mold::macho {
|
|
|
|
|
2021-09-20 16:04:41 +03:00
|
|
|
static void create_synthetic_sections(Context &ctx) {
|
2021-09-21 08:53:38 +03:00
|
|
|
ctx.segments.push_back(&ctx.text_seg);
|
|
|
|
ctx.segments.push_back(&ctx.data_const_seg);
|
|
|
|
ctx.segments.push_back(&ctx.data_seg);
|
|
|
|
ctx.segments.push_back(&ctx.linkedit_seg);
|
|
|
|
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.mach_hdr);
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.load_cmd);
|
2021-09-21 09:57:23 +03:00
|
|
|
ctx.text_seg.sections.push_back(&ctx.text);
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.stubs);
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.stub_helper);
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.cstring);
|
|
|
|
ctx.text_seg.sections.push_back(&ctx.unwind_info);
|
2021-09-21 08:53:38 +03:00
|
|
|
|
2021-09-21 09:57:23 +03:00
|
|
|
ctx.data_const_seg.sections.push_back(&ctx.got);
|
2021-09-21 08:53:38 +03:00
|
|
|
|
2021-09-21 09:57:23 +03:00
|
|
|
ctx.data_seg.sections.push_back(&ctx.lazy_symbol_ptr);
|
|
|
|
ctx.data_seg.sections.push_back(&ctx.data);
|
2021-09-21 08:53:38 +03:00
|
|
|
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.rebase);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.bind);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.lazy_bind);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.export_);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.function_starts);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.symtab);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.indir_symtab);
|
|
|
|
ctx.linkedit_seg.sections.push_back(&ctx.strtab);
|
2021-09-15 15:00:14 +03:00
|
|
|
}
|
2021-09-13 15:59:20 +03:00
|
|
|
|
2021-09-20 16:04:41 +03:00
|
|
|
static void fill_symtab(Context &ctx) {
|
2021-09-21 08:51:29 +03:00
|
|
|
ctx.symtab.add(ctx, "__dyld_private", N_SECT, false, 8, 0x0, 0x100008008);
|
|
|
|
ctx.symtab.add(ctx, "__mh_execute_header", N_SECT, true, 1, 0x10, 0x100000000);
|
|
|
|
ctx.symtab.add(ctx, "_hello", N_SECT, true, 1, 0x0, 0x100003f50);
|
|
|
|
ctx.symtab.add(ctx, "_main", N_SECT, true, 1, 0x0, 0x100003f70);
|
|
|
|
ctx.symtab.add(ctx, "_printf", N_UNDF, true, 0, 0x100, 0x0);
|
|
|
|
ctx.symtab.add(ctx, "dyld_stub_binder", N_UNDF, true, 0, 0x100, 0x0);
|
|
|
|
|
|
|
|
ctx.strtab.hdr.size = align_to(ctx.strtab.hdr.size, 8);
|
2021-09-20 16:04:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static i64 assign_offsets(Context &ctx) {
|
2021-09-15 15:00:14 +03:00
|
|
|
i64 fileoff = 0;
|
2021-09-17 14:09:50 +03:00
|
|
|
i64 vmaddr = PAGE_ZERO_SIZE;
|
2021-09-16 16:23:18 +03:00
|
|
|
|
2021-09-17 14:09:50 +03:00
|
|
|
for (OutputSegment *seg : ctx.segments) {
|
2021-09-20 13:41:03 +03:00
|
|
|
seg->set_offset(ctx, fileoff, vmaddr);
|
2021-09-18 09:05:46 +03:00
|
|
|
fileoff += seg->cmd.filesize;
|
2021-09-17 14:09:50 +03:00
|
|
|
vmaddr += seg->cmd.vmsize;
|
2021-09-16 16:23:18 +03:00
|
|
|
}
|
2021-09-16 10:21:18 +03:00
|
|
|
return fileoff;
|
2021-09-13 15:59:20 +03:00
|
|
|
}
|
|
|
|
|
2021-09-08 14:15:03 +03:00
|
|
|
int main(int argc, char **argv) {
|
2021-09-15 11:25:06 +03:00
|
|
|
Context ctx;
|
|
|
|
|
2021-09-15 15:00:14 +03:00
|
|
|
// Parse command line arguments
|
2021-09-13 12:15:34 +03:00
|
|
|
if (argc == 1) {
|
2021-09-15 11:25:06 +03:00
|
|
|
SyncOut(ctx) << "mold macho stub\n";
|
2021-09-13 12:15:34 +03:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2021-09-15 11:25:06 +03:00
|
|
|
if (std::string_view(argv[1]) == "-dump") {
|
|
|
|
if (argc != 3)
|
|
|
|
Fatal(ctx) << "usage: ld64.mold -dump <executable-name>\n";
|
|
|
|
dump_file(argv[2]);
|
|
|
|
exit(0);
|
2021-09-13 12:15:34 +03:00
|
|
|
}
|
|
|
|
|
2021-09-15 15:00:14 +03:00
|
|
|
if (std::string_view(argv[1]) == "-out") {
|
|
|
|
if (argc != 3)
|
|
|
|
Fatal(ctx) << "usage: ld64.mold -out <output-file>\n";
|
|
|
|
ctx.arg.output = argv[2];
|
|
|
|
|
|
|
|
create_synthetic_sections(ctx);
|
2021-09-20 16:04:41 +03:00
|
|
|
fill_symtab(ctx);
|
2021-09-21 08:51:29 +03:00
|
|
|
ctx.load_cmd.compute_size(ctx);
|
2021-09-16 16:23:18 +03:00
|
|
|
i64 output_size = assign_offsets(ctx);
|
2021-09-13 13:07:15 +03:00
|
|
|
|
2021-09-15 15:00:14 +03:00
|
|
|
ctx.output_file =
|
2021-09-16 10:21:18 +03:00
|
|
|
std::make_unique<OutputFile>(ctx, ctx.arg.output, output_size, 0777);
|
2021-09-15 15:00:14 +03:00
|
|
|
ctx.buf = ctx.output_file->buf;
|
2021-09-13 13:07:15 +03:00
|
|
|
|
2021-09-17 14:09:50 +03:00
|
|
|
for (OutputSegment *seg : ctx.segments)
|
|
|
|
seg->copy_buf(ctx);
|
2021-09-15 06:40:27 +03:00
|
|
|
|
2021-09-15 15:00:14 +03:00
|
|
|
ctx.output_file->close(ctx);
|
|
|
|
exit(0);
|
|
|
|
}
|
2021-09-13 13:07:15 +03:00
|
|
|
|
2021-09-15 15:00:14 +03:00
|
|
|
Fatal(ctx) << "usage: ld64.mold\n";
|
2021-09-08 13:02:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|