| ... | @@ -324,6 +324,19 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -324,6 +324,19 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 324 | assert(self.llvm_object == null); | 324 | assert(self.llvm_object == null); |
| 325 | const gpa = self.base.allocator; | 325 | const gpa = self.base.allocator; |
| 326 | | 326 | |
| | 327 | try self.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32)); |
| | 328 | self.strtab.buffer.appendNTimesAssumeCapacity(0, @sizeOf(u32)); |
| | 329 | |
| | 330 | // Index 0 is always a null symbol. |
| | 331 | try self.locals.append(gpa, .{ |
| | 332 | .name = [_]u8{0} ** 8, |
| | 333 | .value = 0, |
| | 334 | .section_number = .UNDEFINED, |
| | 335 | .@"type" = .{ .base_type = .NULL, .complex_type = .NULL }, |
| | 336 | .storage_class = .NULL, |
| | 337 | .number_of_aux_symbols = 0, |
| | 338 | }); |
| | 339 | |
| 327 | if (self.text_section_index == null) { | 340 | if (self.text_section_index == null) { |
| 328 | self.text_section_index = @intCast(u16, self.sections.slice().len); | 341 | self.text_section_index = @intCast(u16, self.sections.slice().len); |
| 329 | const file_size = @intCast(u32, self.base.options.program_code_size_hint); | 342 | const file_size = @intCast(u32, self.base.options.program_code_size_hint); |
| ... | @@ -472,21 +485,11 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -472,21 +485,11 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 472 | } | 485 | } |
| 473 | | 486 | |
| 474 | if (self.strtab_offset == null) { | 487 | if (self.strtab_offset == null) { |
| 475 | try self.strtab.buffer.append(gpa, 0); | 488 | const file_size = @intCast(u32, self.strtab.len()); |
| 476 | self.strtab_offset = self.findFreeSpace(@intCast(u32, self.strtab.len()), 1); | 489 | self.strtab_offset = self.findFreeSpace(file_size, @alignOf(u32)); // 4bytes aligned seems like a good idea here |
| 477 | log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + self.strtab.len() }); | 490 | log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + file_size }); |
| 478 | } | 491 | } |
| 479 | | 492 | |
| 480 | // Index 0 is always a null symbol. | | |
| 481 | try self.locals.append(gpa, .{ | | |
| 482 | .name = [_]u8{0} ** 8, | | |
| 483 | .value = 0, | | |
| 484 | .section_number = .UNDEFINED, | | |
| 485 | .@"type" = .{ .base_type = .NULL, .complex_type = .NULL }, | | |
| 486 | .storage_class = .NULL, | | |
| 487 | .number_of_aux_symbols = 0, | | |
| 488 | }); | | |
| 489 | | | |
| 490 | { | 493 | { |
| 491 | // We need to find out what the max file offset is according to section headers. | 494 | // We need to find out what the max file offset is according to section headers. |
| 492 | // Otherwise, we may end up with an COFF binary with file size not matching the final section's | 495 | // Otherwise, we may end up with an COFF binary with file size not matching the final section's |
| ... | @@ -1672,11 +1675,20 @@ fn writeStrtab(self: *Coff) !void { | ... | @@ -1672,11 +1675,20 @@ fn writeStrtab(self: *Coff) !void { |
| 1672 | | 1675 | |
| 1673 | if (needed_size > allocated_size) { | 1676 | if (needed_size > allocated_size) { |
| 1674 | self.strtab_offset = null; | 1677 | self.strtab_offset = null; |
| 1675 | self.strtab_offset = @intCast(u32, self.findFreeSpace(needed_size, 1)); | 1678 | self.strtab_offset = @intCast(u32, self.findFreeSpace(needed_size, @alignOf(u32))); |
| 1676 | } | 1679 | } |
| 1677 | | 1680 | |
| 1678 | log.debug("writing strtab from 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + needed_size }); | 1681 | log.debug("writing strtab from 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + needed_size }); |
| 1679 | try self.base.file.?.pwriteAll(self.strtab.buffer.items, self.strtab_offset.?); | 1682 | |
| | 1683 | var buffer = std.ArrayList(u8).init(self.base.allocator); |
| | 1684 | defer buffer.deinit(); |
| | 1685 | try buffer.ensureTotalCapacityPrecise(needed_size); |
| | 1686 | buffer.appendSliceAssumeCapacity(self.strtab.items()); |
| | 1687 | // Here, we do a trick in that we do not commit the size of the strtab to strtab buffer, instead |
| | 1688 | // we write the length of the strtab to a temporary buffer that goes to file. |
| | 1689 | mem.writeIntLittle(u32, buffer.items[0..4], @intCast(u32, self.strtab.len())); |
| | 1690 | |
| | 1691 | try self.base.file.?.pwriteAll(buffer.items, self.strtab_offset.?); |
| 1680 | } | 1692 | } |
| 1681 | | 1693 | |
| 1682 | fn writeSectionHeaders(self: *Coff) !void { | 1694 | fn writeSectionHeaders(self: *Coff) !void { |
| ... | @@ -1984,6 +1996,14 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v | ... | @@ -1984,6 +1996,14 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v |
| 1984 | mem.set(u8, header.name[name_offset.len..], 0); | 1996 | mem.set(u8, header.name[name_offset.len..], 0); |
| 1985 | } | 1997 | } |
| 1986 | | 1998 | |
| | 1999 | fn getSectionName(self: *const Coff, header: *const coff.SectionHeader) []const u8 { |
| | 2000 | if (header.getName()) |name| { |
| | 2001 | return name; |
| | 2002 | } |
| | 2003 | const offset = header.getNameOffset().?; |
| | 2004 | return self.strtab.get(offset).?; |
| | 2005 | } |
| | 2006 | |
| 1987 | fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { | 2007 | fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { |
| 1988 | if (name.len <= 8) { | 2008 | if (name.len <= 8) { |
| 1989 | mem.copy(u8, &symbol.name, name); | 2009 | mem.copy(u8, &symbol.name, name); |