diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-09-05 09:25:47 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-09-07 22:42:57 +0200 |
| commit | f1bdf3f62f05388b75d6816b65c9cc5caec71cd9 (patch) | |
| tree | a87f6f1c2f3a06eb0a7939f099436e1754dbeb82 /src | |
| parent | 467d69c68aac0459b6a0c2876083d7295e43134d (diff) | |
| download | zig-f1bdf3f62f05388b75d6816b65c9cc5caec71cd9.tar.gz zig-f1bdf3f62f05388b75d6816b65c9cc5caec71cd9.zip | |
coff: fix writing strtab to PE image file
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Coff.zig | 50 | ||||
| -rw-r--r-- | src/link/strtab.zig | 4 |
2 files changed, 39 insertions, 15 deletions
diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 74d6ce372e..a85f8c3396 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -324,6 +324,19 @@ fn populateMissingMetadata(self: *Coff) !void { assert(self.llvm_object == null); const gpa = self.base.allocator; + try self.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32)); + self.strtab.buffer.appendNTimesAssumeCapacity(0, @sizeOf(u32)); + + // Index 0 is always a null symbol. + try self.locals.append(gpa, .{ + .name = [_]u8{0} ** 8, + .value = 0, + .section_number = .UNDEFINED, + .@"type" = .{ .base_type = .NULL, .complex_type = .NULL }, + .storage_class = .NULL, + .number_of_aux_symbols = 0, + }); + if (self.text_section_index == null) { self.text_section_index = @intCast(u16, self.sections.slice().len); const file_size = @intCast(u32, self.base.options.program_code_size_hint); @@ -472,21 +485,11 @@ fn populateMissingMetadata(self: *Coff) !void { } if (self.strtab_offset == null) { - try self.strtab.buffer.append(gpa, 0); - self.strtab_offset = self.findFreeSpace(@intCast(u32, self.strtab.len()), 1); - log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + self.strtab.len() }); + const file_size = @intCast(u32, self.strtab.len()); + self.strtab_offset = self.findFreeSpace(file_size, @alignOf(u32)); // 4bytes aligned seems like a good idea here + log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + file_size }); } - // Index 0 is always a null symbol. - try self.locals.append(gpa, .{ - .name = [_]u8{0} ** 8, - .value = 0, - .section_number = .UNDEFINED, - .@"type" = .{ .base_type = .NULL, .complex_type = .NULL }, - .storage_class = .NULL, - .number_of_aux_symbols = 0, - }); - { // We need to find out what the max file offset is according to section headers. // 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 { if (needed_size > allocated_size) { self.strtab_offset = null; - self.strtab_offset = @intCast(u32, self.findFreeSpace(needed_size, 1)); + self.strtab_offset = @intCast(u32, self.findFreeSpace(needed_size, @alignOf(u32))); } log.debug("writing strtab from 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + needed_size }); - try self.base.file.?.pwriteAll(self.strtab.buffer.items, self.strtab_offset.?); + + var buffer = std.ArrayList(u8).init(self.base.allocator); + defer buffer.deinit(); + try buffer.ensureTotalCapacityPrecise(needed_size); + buffer.appendSliceAssumeCapacity(self.strtab.items()); + // Here, we do a trick in that we do not commit the size of the strtab to strtab buffer, instead + // we write the length of the strtab to a temporary buffer that goes to file. + mem.writeIntLittle(u32, buffer.items[0..4], @intCast(u32, self.strtab.len())); + + try self.base.file.?.pwriteAll(buffer.items, self.strtab_offset.?); } fn writeSectionHeaders(self: *Coff) !void { @@ -1984,6 +1996,14 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v mem.set(u8, header.name[name_offset.len..], 0); } +fn getSectionName(self: *const Coff, header: *const coff.SectionHeader) []const u8 { + if (header.getName()) |name| { + return name; + } + const offset = header.getNameOffset().?; + return self.strtab.get(offset).?; +} + fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { if (name.len <= 8) { mem.copy(u8, &symbol.name, name); diff --git a/src/link/strtab.zig b/src/link/strtab.zig index 8e314f189f..abb58defef 100644 --- a/src/link/strtab.zig +++ b/src/link/strtab.zig @@ -110,6 +110,10 @@ pub fn StringTable(comptime log_scope: @Type(.EnumLiteral)) type { return self.get(off) orelse unreachable; } + pub fn items(self: Self) []const u8 { + return self.buffer.items; + } + pub fn len(self: Self) usize { return self.buffer.items.len; } |
