authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-10 23:59:36+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:47+02:00
log9e051e365b689cb4e6ceae5910fb70fe6a7eb0f8
tree5957aa92c9688a99c13bf384bcb5c9970266d761
parent95aeb09b9b36874645eae648324e21cb2f89337a

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.

3 files changed, 31 insertions(+), 20 deletions(-)

src/link/MachO/Object.zig+8-2
......@@ -413,6 +413,12 @@ const TextBlockParser = struct {
413413 const code = self.code[start_addr..end_addr];
414414 const size = code.len;
415415
416 const max_align = self.section.@"align";
417 const actual_align = if (senior_nlist.nlist.n_value > 0)
418 math.min(@ctz(u64, senior_nlist.nlist.n_value), max_align)
419 else
420 max_align;
421
416422 const alias_only_indices = if (aliases.items.len > 0) blk: {
417423 var out = std.ArrayList(u32).init(self.allocator);
418424 try out.ensureTotalCapacity(aliases.items.len);
......@@ -435,7 +441,7 @@ const TextBlockParser = struct {
435441 block.aliases = alias_only_indices;
436442 block.code = try self.allocator.dupe(u8, code);
437443 block.size = size;
438 block.alignment = self.section.@"align";
444 block.alignment = actual_align;
439445
440446 const relocs = filterRelocs(self.relocs, start_addr, end_addr);
441447 if (relocs.len > 0) {
......@@ -524,7 +530,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
524530 const reg = &sym.payload.regular;
525531 if (reg.file) |file| {
526532 if (file != self) {
527 log.debug("deduping definition of {s} in {s}", .{ sym.name, self.name.? });
533 log.warn("deduping definition of {s} in {s}", .{ sym.name, self.name.? });
528534 block.deinit();
529535 self.allocator.destroy(block);
530536 continue;
src/link/MachO/Zld.zig+15-16
......@@ -320,15 +320,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
320320 self.allocateLinkeditSegment();
321321 try self.allocateTextBlocks();
322322
323 var it = self.blocks.iterator();
324 while (it.next()) |entry| {
325 const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
326 const sect = seg.sections.items[entry.key_ptr.sect];
323 // var it = self.blocks.iterator();
324 // while (it.next()) |entry| {
325 // const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
326 // const sect = seg.sections.items[entry.key_ptr.sect];
327327
328 log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
329 log.warn(" {}", .{sect});
330 entry.value_ptr.*.print(self);
331 }
328 // log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
329 // log.warn(" {}", .{sect});
330 // entry.value_ptr.*.print(self);
331 // }
332332
333333 try self.flush();
334334}
......@@ -1056,8 +1056,8 @@ fn allocateTextBlocks(self: *Zld) !void {
10561056
10571057 var base_addr: u64 = sect.addr;
10581058
1059 log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1060 log.warn(" {}", .{sect});
1059 log.debug(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1060 log.debug(" {}", .{sect});
10611061
10621062 while (true) {
10631063 const block_alignment = try math.powi(u32, 2, block.alignment);
......@@ -1067,7 +1067,7 @@ fn allocateTextBlocks(self: *Zld) !void {
10671067 assert(sym.payload == .regular);
10681068 sym.payload.regular.address = base_addr;
10691069
1070 log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1070 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
10711071 sym.name,
10721072 base_addr,
10731073 base_addr + block.size,
......@@ -1118,8 +1118,8 @@ fn writeTextBlocks(self: *Zld) !void {
11181118 const sect = seg.sections.items[match.sect];
11191119 const sect_type = sectionType(sect);
11201120
1121 log.warn(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1122 log.warn(" {}", .{sect});
1121 log.debug(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1122 log.debug(" {}", .{sect});
11231123
11241124 var code = try self.allocator.alloc(u8, sect.size);
11251125 defer self.allocator.free(code);
......@@ -1134,7 +1134,7 @@ fn writeTextBlocks(self: *Zld) !void {
11341134 const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);
11351135
11361136 const sym = self.locals.items[block.local_sym_index];
1137 log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1137 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
11381138 sym.name,
11391139 aligned_base_off,
11401140 aligned_base_off + block.size,
......@@ -1433,7 +1433,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void {
14331433fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
14341434 log.debug("resolving symbols in '{s}'", .{object.name});
14351435
1436 for (object.symtab.items) |sym, sym_id| {
1436 for (object.symtab.items) |sym| {
14371437 const sym_name = object.getString(sym.n_strx);
14381438
14391439 if (Symbol.isStab(sym)) {
......@@ -2152,7 +2152,6 @@ fn writeRebaseInfoTable(self: *Zld) !void {
21522152 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
21532153
21542154 const seg = self.load_commands.items[match.seg].Segment;
2155 const sect = seg.sections.items[match.sect];
21562155
21572156 while (true) {
21582157 const sym = self.locals.items[block.local_sym_index];
src/link/MachO/reloc.zig+8-2
......@@ -110,6 +110,7 @@ pub const Relocation = struct {
110110 }
111111
112112 pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
113 _ = self;
113114 _ = fmt;
114115 _ = options;
115116 try std.fmt.format(writer, "Branch {{}}", .{});
......@@ -179,7 +180,7 @@ pub const Relocation = struct {
179180 load,
180181 };
181182
182 pub fn resolve(self: PageOff, base: Relocation, source_addr: u64, target_addr: u64) !void {
183 pub fn resolve(self: PageOff, base: Relocation, _: u64, target_addr: u64) !void {
183184 switch (self.kind) {
184185 .page => {
185186 const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr;
......@@ -325,12 +326,13 @@ pub const Relocation = struct {
325326 };
326327
327328 pub const PointerToGot = struct {
328 pub fn resolve(self: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void {
329 pub fn resolve(_: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void {
329330 const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));
330331 mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @bitCast(u32, result));
331332 }
332333
333334 pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
335 _ = self;
334336 _ = fmt;
335337 _ = options;
336338 try std.fmt.format(writer, "PointerToGot {{}}", .{});
......@@ -342,6 +344,10 @@ pub const Relocation = struct {
342344 correction: i4,
343345
344346 pub fn resolve(self: Signed, base: Relocation, source_addr: u64, target_addr: u64) !void {
347 _ = self;
348 _ = base;
349 _ = source_addr;
350 _ = target_addr;
345351 // const target_addr = target_addr: {
346352 // if (signed.base.target == .section) {
347353 // const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4;