@@ -1061,65 +1061,55 @@ pub const CoffError = error{
1061
1061
1062
1062
// Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
1063
1063
pub const Coff = struct {
1064
- allocator : mem.Allocator ,
1065
- data : []const u8 = undefined ,
1066
- is_image : bool = false ,
1067
- coff_header_offset : usize = 0 ,
1064
+ data : []const u8 ,
1065
+ is_image : bool ,
1066
+ coff_header_offset : usize ,
1068
1067
1069
1068
guid : [16 ]u8 = undefined ,
1070
1069
age : u32 = undefined ,
1071
1070
1072
- pub fn deinit (self : * Coff ) void {
1073
- self .allocator .free (self .data );
1074
- }
1075
-
1076
- /// Takes ownership of `data`.
1077
- pub fn parse (self : * Coff , data : []const u8 ) ! void {
1078
- self .data = data ;
1079
-
1071
+ // The lifetime of `data` must be longer than the lifetime of the returned Coff
1072
+ pub fn init (data : []const u8 ) ! Coff {
1080
1073
const pe_pointer_offset = 0x3C ;
1081
1074
const pe_magic = "PE\x00\x00 " ;
1082
1075
1083
- var stream = std .io .fixedBufferStream (self . data );
1076
+ var stream = std .io .fixedBufferStream (data );
1084
1077
const reader = stream .reader ();
1085
1078
try stream .seekTo (pe_pointer_offset );
1086
- const coff_header_offset = try reader .readIntLittle (u32 );
1079
+ var coff_header_offset = try reader .readIntLittle (u32 );
1087
1080
try stream .seekTo (coff_header_offset );
1088
1081
var buf : [4 ]u8 = undefined ;
1089
1082
try reader .readNoEof (& buf );
1090
- self .is_image = mem .eql (u8 , pe_magic , & buf );
1083
+ const is_image = mem .eql (u8 , pe_magic , & buf );
1084
+
1085
+ var coff = @This (){
1086
+ .data = data ,
1087
+ .is_image = is_image ,
1088
+ .coff_header_offset = coff_header_offset ,
1089
+ };
1091
1090
1092
1091
// Do some basic validation upfront
1093
- if (self . is_image ) {
1094
- self .coff_header_offset = coff_header_offset + 4 ;
1095
- const coff_header = self .getCoffHeader ();
1092
+ if (is_image ) {
1093
+ coff .coff_header_offset = coff . coff_header_offset + 4 ;
1094
+ const coff_header = coff .getCoffHeader ();
1096
1095
if (coff_header .size_of_optional_header == 0 ) return error .MissingPEHeader ;
1097
1096
}
1098
1097
1099
1098
// JK: we used to check for architecture here and throw an error if not x86 or derivative.
1100
1099
// However I am willing to take a leap of faith and let aarch64 have a shot also.
1100
+
1101
+ return coff ;
1101
1102
}
1102
1103
1103
1104
pub fn getPdbPath (self : * Coff , buffer : []u8 ) ! usize {
1104
1105
assert (self .is_image );
1105
1106
1106
- const header = blk : {
1107
- if (self .getSectionByName (".buildid" )) | hdr | {
1108
- break :blk hdr ;
1109
- } else if (self .getSectionByName (".rdata" )) | hdr | {
1110
- break :blk hdr ;
1111
- } else {
1112
- return error .MissingCoffSection ;
1113
- }
1114
- };
1115
-
1116
1107
const data_dirs = self .getDataDirectories ();
1117
1108
const debug_dir = data_dirs [@enumToInt (DirectoryEntry .DEBUG )];
1118
- const file_offset = debug_dir .virtual_address - header .virtual_address + header .pointer_to_raw_data ;
1119
1109
1120
1110
var stream = std .io .fixedBufferStream (self .data );
1121
1111
const reader = stream .reader ();
1122
- try stream .seekTo (file_offset );
1112
+ try stream .seekTo (debug_dir . virtual_address );
1123
1113
1124
1114
// Find the correct DebugDirectoryEntry, and where its data is stored.
1125
1115
// It can be in any section.
@@ -1128,16 +1118,8 @@ pub const Coff = struct {
1128
1118
blk : while (i < debug_dir_entry_count ) : (i += 1 ) {
1129
1119
const debug_dir_entry = try reader .readStruct (DebugDirectoryEntry );
1130
1120
if (debug_dir_entry .type == .CODEVIEW ) {
1131
- for (self .getSectionHeaders ()) | * section | {
1132
- const section_start = section .virtual_address ;
1133
- const section_size = section .virtual_size ;
1134
- const rva = debug_dir_entry .address_of_raw_data ;
1135
- const offset = rva - section_start ;
1136
- if (section_start <= rva and offset < section_size and debug_dir_entry .size_of_data <= section_size - offset ) {
1137
- try stream .seekTo (section .pointer_to_raw_data + offset );
1138
- break :blk ;
1139
- }
1140
- }
1121
+ try stream .seekTo (debug_dir_entry .address_of_raw_data );
1122
+ break :blk ;
1141
1123
}
1142
1124
}
1143
1125
@@ -1238,6 +1220,16 @@ pub const Coff = struct {
1238
1220
return @ptrCast ([* ]align (1 ) const SectionHeader , self .data .ptr + offset )[0.. coff_header .number_of_sections ];
1239
1221
}
1240
1222
1223
+ pub fn getSectionHeadersAlloc (self : * const Coff , allocator : mem.Allocator ) ! []SectionHeader {
1224
+ const section_headers = self .getSectionHeaders ();
1225
+ const out_buff = try allocator .alloc (SectionHeader , section_headers .len );
1226
+ for (out_buff ) | * section_header , i | {
1227
+ section_header .* = section_headers [i ];
1228
+ }
1229
+
1230
+ return out_buff ;
1231
+ }
1232
+
1241
1233
pub fn getSectionName (self : * const Coff , sect_hdr : * align (1 ) const SectionHeader ) []const u8 {
1242
1234
const name = sect_hdr .getName () orelse blk : {
1243
1235
const strtab = self .getStrtab ().? ;
@@ -1256,12 +1248,15 @@ pub const Coff = struct {
1256
1248
return null ;
1257
1249
}
1258
1250
1251
+ pub fn getSectionData (self : * const Coff , comptime name : []const u8 ) ! []const u8 {
1252
+ const sec = self .getSectionByName (name ) orelse return error .MissingCoffSection ;
1253
+ return self .data [sec .pointer_to_raw_data .. ][0.. sec .virtual_size ];
1254
+ }
1255
+
1259
1256
// Return an owned slice full of the section data
1260
1257
pub fn getSectionDataAlloc (self : * const Coff , comptime name : []const u8 , allocator : mem.Allocator ) ! []u8 {
1261
- const sec = self .getSectionByName (name ) orelse return error .MissingCoffSection ;
1262
- const out_buff = try allocator .alloc (u8 , sec .virtual_size );
1263
- mem .copy (u8 , out_buff , self .data [sec .pointer_to_raw_data .. ][0.. sec .virtual_size ]);
1264
- return out_buff ;
1258
+ const section_data = try self .getSectionData (name );
1259
+ return allocator .dupe (u8 , section_data );
1265
1260
}
1266
1261
};
1267
1262
0 commit comments