From 5649242025cd885a6a2f0607d96f54b1926b0a5a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 5 Jul 2021 07:39:49 +0200 Subject: [PATCH] zld: draft up final format of TextBlock --- src/link/MachO/Object.zig | 50 ++++++++++++++++++++++++++++++++++++++- src/link/MachO/Zld.zig | 25 ++++++++++++++++---- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 8e9a3075d5..43bfea67d5 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -343,7 +343,7 @@ pub fn parseSections(self: *Object) !void { } } -pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { +pub fn parseTextBlocks(self: *Object, zld: *Zld) !*TextBlock { const seg = self.load_commands.items[self.segment_cmd_index.?].Segment; log.warn("analysing {s}", .{self.name.?}); @@ -503,6 +503,54 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { } } +const SectionAsTextBlocksArgs = struct { + sect: macho.section_64, + code: []u8, + subsections_via_symbols: bool = false, + relocs: ?[]macho.relocation_info = null, + segment_id: u16 = 0, + section_id: u16 = 0, +}; + +fn sectionAsTextBlocks(self: *Object, args: SectionAsTextBlocksArgs) !*TextBlock { + const sect = args.sect; + + log.warn("putting section '{s},{s}' as a TextBlock", .{ segmentName(sect), sectionName(sect) }); + + // Section alignment will be the assumed alignment per symbol. + const alignment = sect.@"align"; + + const first_block: *TextBlock = blk: { + if (args.subsections_via_symbols) { + return error.TODO; + } else { + const block = try self.allocator.create(TextBlock); + errdefer self.allocator.destroy(block); + + block.* = .{ + .ref = .{ + .section = undefined, // Will be populated when we allocated final sections. + }, + .code = args.code, + .relocs = null, + .size = sect.size, + .alignment = alignment, + .segment_id = args.segment_id, + .section_id = args.section_id, + }; + + // TODO parse relocs + if (args.relocs) |relocs| { + block.relocs = try reloc.parse(self.allocator, self.arch.?, args.code, relocs, symbols); + } + + break :blk block; + } + }; + + return first_block; +} + pub fn parseInitializers(self: *Object) !void { const index = self.mod_init_func_section_index orelse return; const section = self.sections.items[index]; diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 2b7b905b89..9d7eea042a 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -135,13 +135,30 @@ const TlvOffset = struct { }; pub const TextBlock = struct { - local_sym_index: ?u32 = null, + allocator: *Allocator, + local_sym_index: u32, + aliases: std.ArrayList(u32), + references: std.ArrayList(u32), + code: []u8, + relocs: ?std.ArrayList(*Relocation) = null, size: u64, alignment: u32, - code: []u8, - relocs: []*Relocation, segment_id: u16, section_id: u16, + next: ?*TextBlock = null, + prev: ?*TextBlock = null, + + pub fn deinit(block: *TextBlock, allocator: *Allocator) void { + block.aliases.deinit(); + block.references.deinit(); + if (block.relocs) |relocs| { + for (relocs.items) |reloc| { + allocator.destroy(reloc); + } + relocs.deinit(); + } + allocator.free(code); + } }; /// Default path to dyld @@ -1669,7 +1686,7 @@ fn resolveSymbols(self: *Zld) !void { fn parseTextBlocks(self: *Zld) !void { for (self.objects.items) |object| { - try object.parseTextBlocks(self); + _ = try object.parseTextBlocks(self); } }