Commit 453c16d8ac
Changed files (2)
src
link
MachO
src/link/MachO/Object.zig
@@ -15,6 +15,7 @@ const Allocator = mem.Allocator;
const Arch = std.Target.Cpu.Arch;
const Relocation = reloc.Relocation;
const Symbol = @import("Symbol.zig");
+const TextBlock = @import("Zld.zig").TextBlock;
usingnamespace @import("commands.zig");
@@ -271,6 +272,7 @@ pub fn parse(self: *Object) !void {
try self.parseSymtab();
try self.parseDataInCode();
try self.parseInitializers();
+ try self.parseDummy();
}
pub fn readLoadCommands(self: *Object, reader: anytype) !void {
@@ -379,6 +381,110 @@ pub fn parseSections(self: *Object) !void {
}
}
+fn cmpNlist(_: void, lhs: macho.nlist_64, rhs: macho.nlist_64) bool {
+ return lhs.n_value < rhs.n_value;
+}
+
+fn filterSymsInSection(symbols: []macho.nlist_64, sect_id: u8) []macho.nlist_64 {
+ var start: usize = 0;
+ var end: usize = symbols.len;
+
+ while (true) {
+ var change = false;
+ if (symbols[start].n_sect != sect_id) {
+ start += 1;
+ change = true;
+ }
+ if (symbols[end - 1].n_sect != sect_id) {
+ end -= 1;
+ change = true;
+ }
+
+ if (start == end) break;
+ if (!change) break;
+ }
+
+ return symbols[start..end];
+}
+
+pub fn parseDummy(self: *Object) !void {
+ const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
+
+ log.warn("analysing {s}", .{self.name.?});
+
+ const dysymtab = self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
+
+ var sorted_syms = std.ArrayList(macho.nlist_64).init(self.allocator);
+ defer sorted_syms.deinit();
+ try sorted_syms.appendSlice(self.symtab.items[dysymtab.ilocalsym..dysymtab.iundefsym]);
+
+ std.sort.sort(macho.nlist_64, sorted_syms.items, {}, cmpNlist);
+
+ for (seg.sections.items) |sect, sect_id| {
+ log.warn("section {s},{s}", .{ parseName(§.segname), parseName(§.sectname) });
+ // Read code
+ var code = try self.allocator.alloc(u8, @intCast(usize, sect.size));
+ defer self.allocator.free(code);
+ _ = try self.file.?.preadAll(code, sect.offset);
+
+ // Read and parse relocs
+ const raw_relocs = try self.allocator.alloc(u8, @sizeOf(macho.relocation_info) * sect.nreloc);
+ defer self.allocator.free(raw_relocs);
+ _ = try self.file.?.preadAll(raw_relocs, sect.reloff);
+
+ const relocs = try reloc.parse(
+ self.allocator,
+ self.arch.?,
+ code,
+ mem.bytesAsSlice(macho.relocation_info, raw_relocs),
+ );
+
+ if (self.header.?.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0) {
+ const syms = filterSymsInSection(sorted_syms.items, @intCast(u8, sect_id + 1));
+
+ var indices = std.ArrayList(u32).init(self.allocator);
+ defer indices.deinit();
+
+ var i: u32 = 0;
+ while (i < syms.len) : (i += 1) {
+ const curr = syms[i];
+ try indices.append(i);
+
+ const next: ?macho.nlist_64 = if (i + 1 < syms.len)
+ syms[i + 1]
+ else
+ null;
+
+ if (next) |n| {
+ if (curr.n_value == n.n_value) {
+ continue;
+ }
+ }
+
+ const start_addr = curr.n_value - sect.addr;
+ const end_addr = if (next) |n| n.n_value - sect.addr else sect.size;
+ const alignment = sect.@"align";
+
+ const tb_code = code[start_addr..end_addr];
+ const size = tb_code.len;
+
+ log.warn("TextBlock", .{});
+ for (indices.items) |id| {
+ log.warn(" | symbol {s}", .{self.getString(syms[id].n_strx)});
+ }
+ log.warn(" | start_addr = 0x{x}", .{start_addr});
+ log.warn(" | end_addr = 0x{x}", .{end_addr});
+ log.warn(" | size = {}", .{size});
+ log.warn(" | alignment = 0x{x}", .{alignment});
+
+ indices.clearRetainingCapacity();
+ }
+ } else {
+ return error.TODOOneLargeTextBlock;
+ }
+ }
+}
+
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
@@ -17,6 +17,7 @@ const Archive = @import("Archive.zig");
const CodeSignature = @import("CodeSignature.zig");
const Dylib = @import("Dylib.zig");
const Object = @import("Object.zig");
+const Relocation = reloc.Relocation;
const StringTable = @import("StringTable.zig");
const Symbol = @import("Symbol.zig");
const Trie = @import("Trie.zig");
@@ -133,6 +134,16 @@ const TlvOffset = struct {
}
};
+pub const TextBlock = struct {
+ local_sym_index: ?u32 = null,
+ size: u64,
+ alignment: u32,
+ code: []u8,
+ relocs: []*Relocation,
+ segment_id: u16,
+ section_id: u16,
+};
+
/// Default path to dyld
const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld";
@@ -236,19 +247,6 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
try self.allocateSymbols();
try self.allocateTentativeSymbols();
try self.allocateProxyBindAddresses();
-
- // log.warn("globals", .{});
- // for (self.globals.values()) |value| {
- // log.warn(" | {s}: {}", .{ value.name, value.payload });
- // }
-
- // for (self.objects.items) |object| {
- // log.warn("object {s}", .{object.name.?});
- // for (object.symbols.items) |sym| {
- // log.warn(" | {s}: {}", .{ sym.name, sym.payload });
- // }
- // }
-
try self.flush();
}