Skip to content

Commit 85f065a

Browse files
authored
Merge pull request #9676 from ziglang/zld-incr
MachO: merges stage1 with self-hosted codepath
2 parents d1908c9 + 05763f4 commit 85f065a

File tree

10 files changed

+3661
-4629
lines changed

10 files changed

+3661
-4629
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,11 @@ set(ZIG_STAGE2_SOURCES
574574
"${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"
575575
"${CMAKE_SOURCE_DIR}/src/link/MachO.zig"
576576
"${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig"
577+
"${CMAKE_SOURCE_DIR}/src/link/MachO/Atom.zig"
577578
"${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig"
578579
"${CMAKE_SOURCE_DIR}/src/link/MachO/DebugSymbols.zig"
579580
"${CMAKE_SOURCE_DIR}/src/link/MachO/Dylib.zig"
580581
"${CMAKE_SOURCE_DIR}/src/link/MachO/Object.zig"
581-
"${CMAKE_SOURCE_DIR}/src/link/MachO/TextBlock.zig"
582582
"${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"
583583
"${CMAKE_SOURCE_DIR}/src/link/MachO/bind.zig"
584584
"${CMAKE_SOURCE_DIR}/src/link/MachO/commands.zig"

lib/std/macho.zig

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -601,35 +601,35 @@ pub const segment_command = extern struct {
601601
/// command and their size is reflected in cmdsize.
602602
pub const segment_command_64 = extern struct {
603603
/// LC_SEGMENT_64
604-
cmd: u32,
604+
cmd: u32 = LC_SEGMENT_64,
605605

606606
/// includes sizeof section_64 structs
607-
cmdsize: u32,
607+
cmdsize: u32 = @sizeOf(segment_command_64),
608608

609609
/// segment name
610610
segname: [16]u8,
611611

612612
/// memory address of this segment
613-
vmaddr: u64,
613+
vmaddr: u64 = 0,
614614

615615
/// memory size of this segment
616-
vmsize: u64,
616+
vmsize: u64 = 0,
617617

618618
/// file offset of this segment
619-
fileoff: u64,
619+
fileoff: u64 = 0,
620620

621621
/// amount to map from the file
622-
filesize: u64,
622+
filesize: u64 = 0,
623623

624624
/// maximum VM protection
625-
maxprot: vm_prot_t,
625+
maxprot: vm_prot_t = VM_PROT_NONE,
626626

627627
/// initial VM protection
628-
initprot: vm_prot_t,
628+
initprot: vm_prot_t = VM_PROT_NONE,
629629

630630
/// number of sections in segment
631-
nsects: u32,
632-
flags: u32,
631+
nsects: u32 = 0,
632+
flags: u32 = 0,
633633
};
634634

635635
/// A segment is made up of zero or more sections. Non-MH_OBJECT files have
@@ -700,34 +700,34 @@ pub const section_64 = extern struct {
700700
segname: [16]u8,
701701

702702
/// memory address of this section
703-
addr: u64,
703+
addr: u64 = 0,
704704

705705
/// size in bytes of this section
706-
size: u64,
706+
size: u64 = 0,
707707

708708
/// file offset of this section
709-
offset: u32,
709+
offset: u32 = 0,
710710

711711
/// section alignment (power of 2)
712-
@"align": u32,
712+
@"align": u32 = 0,
713713

714714
/// file offset of relocation entries
715-
reloff: u32,
715+
reloff: u32 = 0,
716716

717717
/// number of relocation entries
718-
nreloc: u32,
718+
nreloc: u32 = 0,
719719

720720
/// flags (section type and attributes
721-
flags: u32,
721+
flags: u32 = S_REGULAR,
722722

723723
/// reserved (for offset or index)
724-
reserved1: u32,
724+
reserved1: u32 = 0,
725725

726726
/// reserved (for count or sizeof)
727-
reserved2: u32,
727+
reserved2: u32 = 0,
728728

729729
/// reserved
730-
reserved3: u32,
730+
reserved3: u32 = 0,
731731
};
732732

733733
pub const nlist = extern struct {

src/codegen.zig

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,24 +2816,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28162816
if (self.air.value(callee)) |func_value| {
28172817
if (func_value.castTag(.function)) |func_payload| {
28182818
const func = func_payload.data;
2819-
const got_addr = blk: {
2820-
const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
2821-
const got = seg.sections.items[macho_file.got_section_index.?];
2822-
const got_index = macho_file.got_entries_map.get(.{
2823-
.where = .local,
2824-
.where_index = func.owner_decl.link.macho.local_sym_index,
2825-
}) orelse unreachable;
2826-
break :blk got.addr + got_index * @sizeOf(u64);
2827-
};
2819+
// TODO I'm hacking my way through here by repurposing .memory for storing
2820+
// index to the GOT target symbol index.
28282821
switch (arch) {
28292822
.x86_64 => {
2830-
try self.genSetReg(Type.initTag(.u64), .rax, .{ .memory = got_addr });
2823+
try self.genSetReg(Type.initTag(.u64), .rax, .{
2824+
.memory = func.owner_decl.link.macho.local_sym_index,
2825+
});
28312826
// callq *%rax
28322827
try self.code.ensureCapacity(self.code.items.len + 2);
28332828
self.code.appendSliceAssumeCapacity(&[2]u8{ 0xff, 0xd0 });
28342829
},
28352830
.aarch64 => {
2836-
try self.genSetReg(Type.initTag(.u64), .x30, .{ .memory = got_addr });
2831+
try self.genSetReg(Type.initTag(.u64), .x30, .{
2832+
.memory = func.owner_decl.link.macho.local_sym_index,
2833+
});
28372834
// blr x30
28382835
writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
28392836
},
@@ -4345,29 +4342,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
43454342
}).toU32());
43464343

43474344
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4348-
// TODO this is super awkward. We are reversing the address of the GOT entry here.
4349-
// We should probably have it cached or move the reloc adding somewhere else.
4350-
const got_addr = blk: {
4351-
const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
4352-
const got = seg.sections.items[macho_file.got_section_index.?];
4353-
break :blk got.addr;
4354-
};
4355-
const where_index = blk: for (macho_file.got_entries.items) |key, id| {
4356-
if (got_addr + id * @sizeOf(u64) == addr) break :blk key.where_index;
4357-
} else unreachable;
4345+
// TODO I think the reloc might be in the wrong place.
43584346
const decl = macho_file.active_decl.?;
43594347
// Page reloc for adrp instruction.
43604348
try decl.link.macho.relocs.append(self.bin_file.allocator, .{
43614349
.offset = offset,
43624350
.where = .local,
4363-
.where_index = where_index,
4351+
.where_index = @intCast(u32, addr),
43644352
.payload = .{ .page = .{ .kind = .got } },
43654353
});
43664354
// Pageoff reloc for adrp instruction.
43674355
try decl.link.macho.relocs.append(self.bin_file.allocator, .{
43684356
.offset = offset + 4,
43694357
.where = .local,
4370-
.where_index = where_index,
4358+
.where_index = @intCast(u32, addr),
43714359
.payload = .{ .page_off = .{ .kind = .got } },
43724360
});
43734361
} else {
@@ -4628,22 +4616,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
46284616
const offset = @intCast(u32, self.code.items.len);
46294617

46304618
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4631-
// TODO this is super awkward. We are reversing the address of the GOT entry here.
4632-
// We should probably have it cached or move the reloc adding somewhere else.
4633-
const got_addr = blk: {
4634-
const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
4635-
const got = seg.sections.items[macho_file.got_section_index.?];
4636-
break :blk got.addr;
4637-
};
4638-
const where_index = blk: for (macho_file.got_entries.items) |key, id| {
4639-
if (got_addr + id * @sizeOf(u64) == x) break :blk key.where_index;
4640-
} else unreachable;
4619+
// TODO I think the reloc might be in the wrong place.
46414620
const decl = macho_file.active_decl.?;
46424621
// Load reloc for LEA instruction.
46434622
try decl.link.macho.relocs.append(self.bin_file.allocator, .{
46444623
.offset = offset - 4,
46454624
.where = .local,
4646-
.where_index = where_index,
4625+
.where_index = @intCast(u32, x),
46474626
.payload = .{ .load = .{ .kind = .got } },
46484627
});
46494628
} else {
@@ -4869,17 +4848,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
48694848
const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
48704849
const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
48714850
return MCValue{ .memory = got_addr };
4872-
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4873-
const got_addr = blk: {
4874-
const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
4875-
const got = seg.sections.items[macho_file.got_section_index.?];
4876-
const got_index = macho_file.got_entries_map.get(.{
4877-
.where = .local,
4878-
.where_index = decl.link.macho.local_sym_index,
4879-
}) orelse unreachable;
4880-
break :blk got.addr + got_index * ptr_bytes;
4881-
};
4882-
return MCValue{ .memory = got_addr };
4851+
} else if (self.bin_file.cast(link.File.MachO)) |_| {
4852+
// TODO I'm hacking my way through here by repurposing .memory for storing
4853+
// index to the GOT target symbol index.
4854+
return MCValue{ .memory = decl.link.macho.local_sym_index };
48834855
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
48844856
const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
48854857
return MCValue{ .memory = got_addr };

0 commit comments

Comments
 (0)