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

[Mach-O] wip

This commit is contained in:
Rui Ueyama 2021-11-07 23:57:33 +09:00
parent ea6d310576
commit 72587e643f
5 changed files with 61 additions and 13 deletions

View File

@ -113,9 +113,11 @@ static bool compare_chunks(const Chunk *a, const Chunk *b) {
static void create_synthetic_chunks(Context &ctx) {
for (ObjectFile *file : ctx.objs) {
for (std::unique_ptr<InputSection> &isec : file->sections) {
for (std::unique_ptr<Subsection> &subsec : isec->subsections)
isec->osec.add_subsec(subsec.get());
isec->osec.hdr.attr |= isec->hdr.attr;
if (isec) {
for (std::unique_ptr<Subsection> &subsec : isec->subsections)
isec->osec.add_subsec(subsec.get());
isec->osec.hdr.attr |= isec->hdr.attr;
}
}
}
@ -300,12 +302,16 @@ int main(int argc, char **argv) {
create_synthetic_chunks(ctx);
for (ObjectFile *file : ctx.objs)
file->check_duplicate_symbols(ctx);
for (i64 i = 0; i < ctx.segments.size(); i++)
ctx.segments[i]->seg_idx = i + 1;
for (ObjectFile *file : ctx.objs)
for (std::unique_ptr<InputSection> &sec : file->sections)
sec->scan_relocations(ctx);
for (std::unique_ptr<InputSection> &isec : file->sections)
if (isec)
isec->scan_relocations(ctx);
export_symbols(ctx);
i64 output_size = assign_offsets(ctx);

View File

@ -76,6 +76,7 @@ public:
void resolve_lazy_symbols(Context &ctx);
std::vector<ObjectFile *> mark_live_objects(Context &ctx);
void convert_common_symbols(Context &ctx);
void check_duplicate_symbols(Context &ctx);
Relocation read_reloc(Context &ctx, const MachSection &hdr, MachRel r);

View File

@ -40,10 +40,17 @@ void ObjectFile::parse(Context &ctx) {
if (mach_sec[i].get_segname() == "__LD" &&
mach_sec[i].get_sectname() == "__compact_unwind") {
unwind_sec = &mach_sec[i];
} else {
sections.push_back(
std::make_unique<InputSection>(ctx, *this, mach_sec[i]));
sections.push_back(nullptr);
continue;
}
if (mach_sec[i].attr & S_ATTR_DEBUG) {
sections.push_back(nullptr);
continue;
}
sections.push_back(
std::make_unique<InputSection>(ctx, *this, mach_sec[i]));
}
break;
}
@ -88,7 +95,8 @@ void ObjectFile::parse(Context &ctx) {
}
for (std::unique_ptr<InputSection> &sec : sections)
sec->parse_relocations(ctx);
if (sec)
sec->parse_relocations(ctx);
if (unwind_sec)
parse_compact_unwind(ctx, *unwind_sec);
@ -314,7 +322,17 @@ void ObjectFile::convert_common_symbols(Context &ctx) {
sym.value = 0;
sym.is_common = false;
}
}
}
}
void ObjectFile::check_duplicate_symbols(Context &ctx) {
for (i64 i = 0; i < syms.size(); 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;
}
}
InputSection *ObjectFile::get_common_sec(Context &ctx) {

View File

@ -911,10 +911,12 @@ void DataInCodeSection::compute_size(Context &ctx) {
std::span<DataInCodeEntry> entries = file->data_in_code_entries;
for (i64 i = 0; !entries.empty() && i < file->sections.size(); i++) {
InputSection &sec = *file->sections[i];
std::unique_ptr<InputSection> &isec = file->sections[i];
if (!isec)
continue;
for (i64 j = 0; !entries.empty() && j < sec.subsections.size(); j++) {
Subsection &subsec = *sec.subsections[j];
for (i64 j = 0; !entries.empty() && j < isec->subsections.size(); j++) {
Subsection &subsec = *isec->subsections[j];
DataInCodeEntry &ent = entries[0];
if (subsec.input_addr + subsec.input_size < ent.offset)

21
test/macho/duplicate-error.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -e
cd $(dirname $0)
mold=`pwd`/../../ld64.mold
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/../../out/test/macho/$(basename -s .sh $0)
mkdir -p $t
cat <<EOF | cc -o $t/a.o -c -xc -
void hello() {}
EOF
cat <<EOF | cc -o $t/b.o -c -xc -
void hello() {}
int main() {}
EOF
! clang -fuse-ld=$mold -o $t/exe $t/a.o $t/b.o 2> $t/log || false
grep -q 'duplicate symbol: .*/b.o: .*/a.o: _hello' $t/log
echo OK