Commit 5649242025

Jakub Konka <kubkon@jakubkonka.com>
2021-07-05 07:39:49
zld: draft up final format of TextBlock
1 parent 5b3c469
Changed files (2)
src
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];
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);
     }
 }