From 9e051e365b689cb4e6ceae5910fb70fe6a7eb0f8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Jul 2021 23:59:36 +0200 Subject: [PATCH] zld: correctly estimate TextBlock's alignment with section's alignment serving as the maximum alignment that can be seen in this particular section. However, TextBlocks are still allowed to have at most that alignment. --- src/link/MachO/Object.zig | 10 ++++++++-- src/link/MachO/Zld.zig | 31 +++++++++++++++---------------- src/link/MachO/reloc.zig | 10 ++++++++-- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 6a801845b30a347ef54569d1a19dd95ba2e49d0c..c8c72e5ed49152866d95f34b28a7f8788fee630e 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -413,6 +413,12 @@ const TextBlockParser = struct { const code = self.code[start_addr..end_addr]; const size = code.len; + const max_align = self.section.@"align"; + const actual_align = if (senior_nlist.nlist.n_value > 0) + math.min(@ctz(u64, senior_nlist.nlist.n_value), max_align) + else + max_align; + const alias_only_indices = if (aliases.items.len > 0) blk: { var out = std.ArrayList(u32).init(self.allocator); try out.ensureTotalCapacity(aliases.items.len); @@ -435,7 +441,7 @@ const TextBlockParser = struct { block.aliases = alias_only_indices; block.code = try self.allocator.dupe(u8, code); block.size = size; - block.alignment = self.section.@"align"; + block.alignment = actual_align; const relocs = filterRelocs(self.relocs, start_addr, end_addr); if (relocs.len > 0) { @@ -524,7 +530,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { const reg = &sym.payload.regular; if (reg.file) |file| { if (file != self) { - log.debug("deduping definition of {s} in {s}", .{ sym.name, self.name.? }); + log.warn("deduping definition of {s} in {s}", .{ sym.name, self.name.? }); block.deinit(); self.allocator.destroy(block); continue; diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index cd8dcd6f8afe808f0927ca82abcde6bc4caad91e..017ebf3835c90c4928cf4ab93a59184d550e7e5c 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -320,15 +320,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg self.allocateLinkeditSegment(); try self.allocateTextBlocks(); - var it = self.blocks.iterator(); - while (it.next()) |entry| { - const seg = self.load_commands.items[entry.key_ptr.seg].Segment; - const sect = seg.sections.items[entry.key_ptr.sect]; + // var it = self.blocks.iterator(); + // while (it.next()) |entry| { + // const seg = self.load_commands.items[entry.key_ptr.seg].Segment; + // const sect = seg.sections.items[entry.key_ptr.sect]; - log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); - log.warn(" {}", .{sect}); - entry.value_ptr.*.print(self); - } + // log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); + // log.warn(" {}", .{sect}); + // entry.value_ptr.*.print(self); + // } try self.flush(); } @@ -1056,8 +1056,8 @@ fn allocateTextBlocks(self: *Zld) !void { var base_addr: u64 = sect.addr; - log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) }); - log.warn(" {}", .{sect}); + log.debug(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) }); + log.debug(" {}", .{sect}); while (true) { const block_alignment = try math.powi(u32, 2, block.alignment); @@ -1067,7 +1067,7 @@ fn allocateTextBlocks(self: *Zld) !void { assert(sym.payload == .regular); sym.payload.regular.address = base_addr; - log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ + log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ sym.name, base_addr, base_addr + block.size, @@ -1118,8 +1118,8 @@ fn writeTextBlocks(self: *Zld) !void { const sect = seg.sections.items[match.sect]; const sect_type = sectionType(sect); - log.warn(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) }); - log.warn(" {}", .{sect}); + log.debug(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) }); + log.debug(" {}", .{sect}); var code = try self.allocator.alloc(u8, sect.size); defer self.allocator.free(code); @@ -1134,7 +1134,7 @@ fn writeTextBlocks(self: *Zld) !void { const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment); const sym = self.locals.items[block.local_sym_index]; - log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ + log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ sym.name, aligned_base_off, aligned_base_off + block.size, @@ -1433,7 +1433,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { log.debug("resolving symbols in '{s}'", .{object.name}); - for (object.symtab.items) |sym, sym_id| { + for (object.symtab.items) |sym| { const sym_name = object.getString(sym.n_strx); if (Symbol.isStab(sym)) { @@ -2152,7 +2152,6 @@ fn writeRebaseInfoTable(self: *Zld) !void { if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable const seg = self.load_commands.items[match.seg].Segment; - const sect = seg.sections.items[match.sect]; while (true) { const sym = self.locals.items[block.local_sym_index]; diff --git a/src/link/MachO/reloc.zig b/src/link/MachO/reloc.zig index 87ccd89873aa4fbdf756a34815dd7ff3bbc2a31f..1799769db24f6e9e0e8e73330851a2628f7f5869 100644 --- a/src/link/MachO/reloc.zig +++ b/src/link/MachO/reloc.zig @@ -110,6 +110,7 @@ pub const Relocation = struct { } pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + _ = self; _ = fmt; _ = options; try std.fmt.format(writer, "Branch {{}}", .{}); @@ -179,7 +180,7 @@ pub const Relocation = struct { load, }; - pub fn resolve(self: PageOff, base: Relocation, source_addr: u64, target_addr: u64) !void { + pub fn resolve(self: PageOff, base: Relocation, _: u64, target_addr: u64) !void { switch (self.kind) { .page => { const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr; @@ -325,12 +326,13 @@ pub const Relocation = struct { }; pub const PointerToGot = struct { - pub fn resolve(self: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void { + pub fn resolve(_: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void { const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr)); mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @bitCast(u32, result)); } pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + _ = self; _ = fmt; _ = options; try std.fmt.format(writer, "PointerToGot {{}}", .{}); @@ -342,6 +344,10 @@ pub const Relocation = struct { correction: i4, pub fn resolve(self: Signed, base: Relocation, source_addr: u64, target_addr: u64) !void { + _ = self; + _ = base; + _ = source_addr; + _ = target_addr; // const target_addr = target_addr: { // if (signed.base.target == .section) { // const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4; -- 2.54.0