authorgravatar for matt.chudleigh@gmail.comMatt Chudleigh <matt.chudleigh@gmail.com> 2021-06-18 11:36:28-07:00
committergravatar for matt.chudleigh@gmail.comMatt Chudleigh <matt.chudleigh@gmail.com> 2021-06-18 16:19:20-07:00
log2dcdaa76688cfb287432905fce6a097a53c6704d
tree028c595d957c465415cd9b19b2b6b82f6c0729bf
parentfac0c6f25d936c556c240fdb599ed14ce06cb02d

Support long section names in COFF files


1 files changed, 35 insertions(+), 3 deletions(-)

lib/std/coff.zig+35-3
......@@ -98,6 +98,7 @@ pub const CoffError = error{
9898 InvalidPEHeader,
9999 InvalidMachine,
100100 MissingCoffSection,
101 MissingStringTable,
101102};
102103
103104// Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
......@@ -162,6 +163,25 @@ pub const Coff = struct {
162163 try self.loadOptionalHeader();
163164 }
164165
166 fn readStringFromTable(self: *Coff, offset: usize, buf: []u8) ![]const u8 {
167 if (self.coff_header.pointer_to_symbol_table == 0) {
168 // No symbol table therefore no string table
169 return error.MissingStringTable;
170 }
171 // The string table is at the end of the symbol table and symbols are 18 bytes long
172 const string_table_offset = self.coff_header.pointer_to_symbol_table + (self.coff_header.number_of_symbols * 18) + offset;
173 const in = self.in_file.reader();
174 const old_pos = try self.in_file.getPos();
175
176 try self.in_file.seekTo(string_table_offset);
177 defer {
178 self.in_file.seekTo(old_pos) catch unreachable;
179 }
180
181 const str = try in.readUntilDelimiterOrEof(buf, 0);
182 return str orelse "";
183 }
184
165185 fn loadOptionalHeader(self: *Coff) !void {
166186 const in = self.in_file.reader();
167187 self.pe_header.magic = try in.readIntLittle(u16);
......@@ -258,11 +278,23 @@ pub const Coff = struct {
258278
259279 const in = self.in_file.reader();
260280
261 var name: [8]u8 = undefined;
281 var name: [32]u8 = undefined;
262282
263283 var i: u16 = 0;
264284 while (i < self.coff_header.number_of_sections) : (i += 1) {
265 try in.readNoEof(name[0..]);
285 try in.readNoEof(name[0..8]);
286
287 if (name[0] == '/') {
288 // This is a long name and stored in the string table
289 const offset_len = mem.indexOfScalar(u8, name[1..], 0) orelse 7;
290
291 const str_offset = try std.fmt.parseInt(u32, name[1 .. offset_len + 1], 10);
292 const str = try self.readStringFromTable(str_offset, &name);
293 std.mem.set(u8, name[str.len..], 0);
294 } else {
295 std.mem.set(u8, name[8..], 0);
296 }
297
266298 try self.sections.append(Section{
267299 .header = SectionHeader{
268300 .name = name,
......@@ -331,7 +363,7 @@ const SectionHeader = struct {
331363 virtual_size: u32,
332364 };
333365
334 name: [8]u8,
366 name: [32]u8,
335367 misc: Misc,
336368 virtual_address: u32,
337369 size_of_raw_data: u32,