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 {...@@ -413,6 +413,12 @@ const TextBlockParser = struct {
413 const code = self.code[start_addr..end_addr];413 const code = self.code[start_addr..end_addr];
414 const size = code.len;414 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
416 const alias_only_indices = if (aliases.items.len > 0) blk: {422 const alias_only_indices = if (aliases.items.len > 0) blk: {
417 var out = std.ArrayList(u32).init(self.allocator);423 var out = std.ArrayList(u32).init(self.allocator);
418 try out.ensureTotalCapacity(aliases.items.len);424 try out.ensureTotalCapacity(aliases.items.len);
...@@ -435,7 +441,7 @@ const TextBlockParser = struct {...@@ -435,7 +441,7 @@ const TextBlockParser = struct {
435 block.aliases = alias_only_indices;441 block.aliases = alias_only_indices;
436 block.code = try self.allocator.dupe(u8, code);442 block.code = try self.allocator.dupe(u8, code);
437 block.size = size;443 block.size = size;
438 block.alignment = self.section.@"align";444 block.alignment = actual_align;
439445
440 const relocs = filterRelocs(self.relocs, start_addr, end_addr);446 const relocs = filterRelocs(self.relocs, start_addr, end_addr);
441 if (relocs.len > 0) {447 if (relocs.len > 0) {
...@@ -524,7 +530,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {...@@ -524,7 +530,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
524 const reg = &sym.payload.regular;530 const reg = &sym.payload.regular;
525 if (reg.file) |file| {531 if (reg.file) |file| {
526 if (file != self) {532 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.? });
528 block.deinit();534 block.deinit();
529 self.allocator.destroy(block);535 self.allocator.destroy(block);
530 continue;536 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...@@ -320,15 +320,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
320 self.allocateLinkeditSegment();320 self.allocateLinkeditSegment();
321 try self.allocateTextBlocks();321 try self.allocateTextBlocks();
322322
323 var it = self.blocks.iterator();323 // var it = self.blocks.iterator();
324 while (it.next()) |entry| {324 // while (it.next()) |entry| {
325 const seg = self.load_commands.items[entry.key_ptr.seg].Segment;325 // const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
326 const sect = seg.sections.items[entry.key_ptr.sect];326 // const sect = seg.sections.items[entry.key_ptr.sect];
327327
328 log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });328 // log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
329 log.warn(" {}", .{sect});329 // log.warn(" {}", .{sect});
330 entry.value_ptr.*.print(self);330 // entry.value_ptr.*.print(self);
331 }331 // }
332332
333 try self.flush();333 try self.flush();
334}334}
...@@ -1056,8 +1056,8 @@ fn allocateTextBlocks(self: *Zld) !void {...@@ -1056,8 +1056,8 @@ fn allocateTextBlocks(self: *Zld) !void {
10561056
1057 var base_addr: u64 = sect.addr;1057 var base_addr: u64 = sect.addr;
10581058
1059 log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });1059 log.debug(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1060 log.warn(" {}", .{sect});1060 log.debug(" {}", .{sect});
10611061
1062 while (true) {1062 while (true) {
1063 const block_alignment = try math.powi(u32, 2, block.alignment);1063 const block_alignment = try math.powi(u32, 2, block.alignment);
...@@ -1067,7 +1067,7 @@ fn allocateTextBlocks(self: *Zld) !void {...@@ -1067,7 +1067,7 @@ fn allocateTextBlocks(self: *Zld) !void {
1067 assert(sym.payload == .regular);1067 assert(sym.payload == .regular);
1068 sym.payload.regular.address = base_addr;1068 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={}", .{
1071 sym.name,1071 sym.name,
1072 base_addr,1072 base_addr,
1073 base_addr + block.size,1073 base_addr + block.size,
...@@ -1118,8 +1118,8 @@ fn writeTextBlocks(self: *Zld) !void {...@@ -1118,8 +1118,8 @@ fn writeTextBlocks(self: *Zld) !void {
1118 const sect = seg.sections.items[match.sect];1118 const sect = seg.sections.items[match.sect];
1119 const sect_type = sectionType(sect);1119 const sect_type = sectionType(sect);
11201120
1121 log.warn(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });1121 log.debug(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1122 log.warn(" {}", .{sect});1122 log.debug(" {}", .{sect});
11231123
1124 var code = try self.allocator.alloc(u8, sect.size);1124 var code = try self.allocator.alloc(u8, sect.size);
1125 defer self.allocator.free(code);1125 defer self.allocator.free(code);
...@@ -1134,7 +1134,7 @@ fn writeTextBlocks(self: *Zld) !void {...@@ -1134,7 +1134,7 @@ fn writeTextBlocks(self: *Zld) !void {
1134 const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);1134 const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);
11351135
1136 const sym = self.locals.items[block.local_sym_index];1136 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={}", .{
1138 sym.name,1138 sym.name,
1139 aligned_base_off,1139 aligned_base_off,
1140 aligned_base_off + block.size,1140 aligned_base_off + block.size,
...@@ -1433,7 +1433,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void {...@@ -1433,7 +1433,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void {
1433fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {1433fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
1434 log.debug("resolving symbols in '{s}'", .{object.name});1434 log.debug("resolving symbols in '{s}'", .{object.name});
14351435
1436 for (object.symtab.items) |sym, sym_id| {1436 for (object.symtab.items) |sym| {
1437 const sym_name = object.getString(sym.n_strx);1437 const sym_name = object.getString(sym.n_strx);
14381438
1439 if (Symbol.isStab(sym)) {1439 if (Symbol.isStab(sym)) {
...@@ -2152,7 +2152,6 @@ fn writeRebaseInfoTable(self: *Zld) !void {...@@ -2152,7 +2152,6 @@ fn writeRebaseInfoTable(self: *Zld) !void {
2152 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable2152 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
21532153
2154 const seg = self.load_commands.items[match.seg].Segment;2154 const seg = self.load_commands.items[match.seg].Segment;
2155 const sect = seg.sections.items[match.sect];
21562155
2157 while (true) {2156 while (true) {
2158 const sym = self.locals.items[block.local_sym_index];2157 const sym = self.locals.items[block.local_sym_index];
src/link/MachO/reloc.zig+8-2
...@@ -110,6 +110,7 @@ pub const Relocation = struct {...@@ -110,6 +110,7 @@ pub const Relocation = struct {
110 }110 }
111111
112 pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {112 pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
113 _ = self;
113 _ = fmt;114 _ = fmt;
114 _ = options;115 _ = options;
115 try std.fmt.format(writer, "Branch {{}}", .{});116 try std.fmt.format(writer, "Branch {{}}", .{});
...@@ -179,7 +180,7 @@ pub const Relocation = struct {...@@ -179,7 +180,7 @@ pub const Relocation = struct {
179 load,180 load,
180 };181 };
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 {
183 switch (self.kind) {184 switch (self.kind) {
184 .page => {185 .page => {
185 const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr;186 const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr;
...@@ -325,12 +326,13 @@ pub const Relocation = struct {...@@ -325,12 +326,13 @@ pub const Relocation = struct {
325 };326 };
326327
327 pub const PointerToGot = struct {328 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 {
329 const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));330 const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));
330 mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @bitCast(u32, result));331 mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @bitCast(u32, result));
331 }332 }
332333
333 pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {334 pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
335 _ = self;
334 _ = fmt;336 _ = fmt;
335 _ = options;337 _ = options;
336 try std.fmt.format(writer, "PointerToGot {{}}", .{});338 try std.fmt.format(writer, "PointerToGot {{}}", .{});
...@@ -342,6 +344,10 @@ pub const Relocation = struct {...@@ -342,6 +344,10 @@ pub const Relocation = struct {
342 correction: i4,344 correction: i4,
343345
344 pub fn resolve(self: Signed, base: Relocation, source_addr: u64, target_addr: u64) !void {346 pub fn resolve(self: Signed, base: Relocation, source_addr: u64, target_addr: u64) !void {
347 _ = self;
348 _ = base;
349 _ = source_addr;
350 _ = target_addr;
345 // const target_addr = target_addr: {351 // const target_addr = target_addr: {
346 // if (signed.base.target == .section) {352 // if (signed.base.target == .section) {
347 // const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4;353 // const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4;