1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-21 01:47:11 +03:00

[Mach-O] Implement -dead_strip

This commit is contained in:
Rui Ueyama 2021-11-13 15:21:52 +09:00
parent d0138a404d
commit 433666a470
7 changed files with 73 additions and 14 deletions

View File

@ -2,7 +2,58 @@
namespace mold::macho {
static std::vector<Subsection *> collect_root_set(Context &ctx) {
std::vector<Subsection *> rootset;
if (Symbol *sym = intern(ctx, ctx.arg.entry))
if (sym->subsec)
rootset.push_back(sym->subsec);
for (ObjectFile *file : ctx.objs)
for (std::unique_ptr<Subsection> &subsec : file->subsections)
if (subsec->isec.hdr.match("__TEXT", "__eh_frame") ||
subsec->isec.hdr.match("__TEXT", "__gcc_except_tab"))
rootset.push_back(subsec.get());
return rootset;
}
static void visit(Context &ctx, Subsection &subsec) {
if (subsec.is_visited.exchange(true))
return;
for (Relocation &rel : subsec.get_rels()) {
if (rel.sym) {
if (rel.sym->subsec)
visit(ctx, *rel.sym->subsec);
} else {
visit(ctx, *rel.subsec);
}
}
}
static void mark(Context &ctx, std::span<Subsection *> rootset) {
for (Subsection *subsec : rootset)
visit(ctx, *subsec);
}
static void sweep(Context &ctx) {
for (ObjectFile *file : ctx.objs) {
erase(file->subsections, [](const std::unique_ptr<Subsection> &subsec) {
return !subsec->is_visited;
});
}
for (ObjectFile *file : ctx.objs)
for (Symbol *&sym : file->syms)
if (sym->file == file && sym->subsec && !sym->subsec->is_visited)
sym = nullptr;
}
void dead_strip(Context &ctx) {
std::vector<Subsection *> rootset = collect_root_set(ctx);
mark(ctx, rootset);
sweep(ctx);
}
} // namespace mold::macho

View File

@ -379,7 +379,7 @@ struct MachSection {
return {sectname, strnlen(sectname, sizeof(sectname))};
}
bool match(std::string_view segname, std::string_view sectname) {
bool match(std::string_view segname, std::string_view sectname) const {
return get_segname() == segname && get_sectname() == sectname;
}

View File

@ -140,7 +140,7 @@ static void export_symbols(Context &ctx) {
for (ObjectFile *file : ctx.objs) {
for (Symbol *sym : file->syms) {
if (sym->file == file) {
if (sym && sym->file == file) {
if (sym->flags & NEEDS_GOT)
ctx.got.add(ctx, sym);
if (sym->flags & NEEDS_THREAD_PTR)
@ -151,6 +151,9 @@ static void export_symbols(Context &ctx) {
for (DylibFile *file : ctx.dylibs) {
for (Symbol *sym : file->syms) {
if (!sym)
continue;
if (sym->file == file)
if (sym->flags & NEEDS_STUB)
ctx.stubs.add(ctx, sym);

View File

@ -177,6 +177,7 @@ public:
u32 nunwind = 0;
u32 raddr = -1;
u16 p2align = 0;
std::atomic_bool is_visited = false;
};
//

View File

@ -443,11 +443,11 @@ void ObjectFile::convert_common_symbols(Context &ctx) {
void ObjectFile::check_duplicate_symbols(Context &ctx) {
for (i64 i = 0; i < syms.size(); i++) {
Symbol &sym = *syms[i];
Symbol *sym = syms[i];
MachSym &msym = mach_syms[i];
if (!msym.is_undef() && !msym.is_common() && sym.file != this)
Error(ctx) << "duplicate symbol: " << *this << ": " << *sym.file
<< ": " << sym;
if (sym && !msym.is_undef() && !msym.is_common() && sym->file != this)
Error(ctx) << "duplicate symbol: " << *this << ": " << *sym->file
<< ": " << *sym;
}
}

View File

@ -723,7 +723,7 @@ void ExportEncoder::write_trie(u8 *start, TrieNode &node) {
void OutputExportSection::compute_size(Context &ctx) {
for (ObjectFile *file : ctx.objs)
for (Symbol *sym : file->syms)
if (sym->is_extern && sym->file == file)
if (sym && sym->is_extern && sym->file == file)
enc.add(sym->name, 0, sym->get_addr(ctx) - PAGE_ZERO_SIZE);
hdr.size = align_to(enc.finish(), 8);
@ -736,9 +736,10 @@ void OutputExportSection::copy_buf(Context &ctx) {
void OutputFunctionStartsSection::compute_size(Context &ctx) {
std::vector<u64> addrs;
for (ObjectFile *obj : ctx.objs)
for (Symbol *sym : obj->syms)
if (sym->file == obj && sym->subsec && &sym->subsec->isec.osec == ctx.text)
for (ObjectFile *file : ctx.objs)
for (Symbol *sym : file->syms)
if (sym && sym->file == file && sym->subsec &&
&sym->subsec->isec.osec == ctx.text)
addrs.push_back(sym->get_addr(ctx));
std::sort(addrs.begin(), addrs.end());
@ -762,16 +763,16 @@ void OutputFunctionStartsSection::copy_buf(Context &ctx) {
}
void OutputSymtabSection::compute_size(Context &ctx) {
for (ObjectFile *obj : ctx.objs)
for (Symbol *sym : obj->syms)
if (sym->file == obj)
for (ObjectFile *file : ctx.objs)
for (Symbol *sym : file->syms)
if (sym && sym->file == file)
globals.push_back({sym, ctx.strtab.add_string(sym->name)});
i64 idx = globals.size();
for (DylibFile *dylib : ctx.dylibs) {
for (Symbol *sym : dylib->syms) {
if (sym->file == dylib) {
if (sym && sym->file == dylib) {
if (sym->stub_idx != -1 || sym->got_idx != -1) {
undefs.push_back({sym, ctx.strtab.add_string(sym->name)});

View File

@ -27,5 +27,8 @@ EOF
clang -fuse-ld=$mold -o $t/exe $t/a.o -Wl,-dead_strip
$t/exe | grep -q 'Hello world'
otool -tVj $t/exe > $t/log
grep -q 'hello:' $t/log
! grep -q 'howdy:' $t/log || false
echo OK