| ... | @@ -1100,132 +1100,132 @@ pub const Coff = struct { | ... | @@ -1100,132 +1100,132 @@ pub const Coff = struct { |
| 1100 | mem.copy(u8, out_buff, self.data[sec.pointer_to_raw_data..][0..sec.virtual_size]); | 1100 | mem.copy(u8, out_buff, self.data[sec.pointer_to_raw_data..][0..sec.virtual_size]); |
| 1101 | return out_buff; | 1101 | return out_buff; |
| 1102 | } | 1102 | } |
| | 1103 | }; |
| 1103 | | 1104 | |
| 1104 | pub const Symtab = struct { | 1105 | pub const Symtab = struct { |
| 1105 | buffer: []const u8, | 1106 | buffer: []const u8, |
| 1106 | | | |
| 1107 | fn len(self: Symtab) usize { | | |
| 1108 | return @divExact(self.buffer.len, Symbol.sizeOf()); | | |
| 1109 | } | | |
| 1110 | | | |
| 1111 | const Tag = enum { | | |
| 1112 | symbol, | | |
| 1113 | func_def, | | |
| 1114 | debug_info, | | |
| 1115 | weak_ext, | | |
| 1116 | file_def, | | |
| 1117 | sect_def, | | |
| 1118 | }; | | |
| 1119 | | 1107 | |
| 1120 | const Record = union(Tag) { | 1108 | pub fn len(self: Symtab) usize { |
| 1121 | symbol: Symbol, | 1109 | return @divExact(self.buffer.len, Symbol.sizeOf()); |
| 1122 | debug_info: DebugInfoDefinition, | 1110 | } |
| 1123 | func_def: FunctionDefinition, | | |
| 1124 | weak_ext: WeakExternalDefinition, | | |
| 1125 | file_def: FileDefinition, | | |
| 1126 | sect_def: SectionDefinition, | | |
| 1127 | }; | | |
| 1128 | | 1111 | |
| 1129 | /// Lives as long as Symtab instance. | 1112 | pub const Tag = enum { |
| 1130 | fn at(self: Symtab, index: usize, tag: Tag) Record { | 1113 | symbol, |
| 1131 | const offset = index * Symbol.sizeOf(); | 1114 | func_def, |
| 1132 | const raw = self.buffer[offset..][0..Symbol.sizeOf()]; | 1115 | debug_info, |
| 1133 | return switch (tag) { | 1116 | weak_ext, |
| 1134 | .symbol => .{ .symbol = asSymbol(raw) }, | 1117 | file_def, |
| 1135 | .debug_info => .{ .debug_info = asDebugInfo(raw) }, | 1118 | sect_def, |
| 1136 | .func_def => .{ .func_def = asFuncDef(raw) }, | 1119 | }; |
| 1137 | .weak_ext => .{ .weak_ext = asWeakExtDef(raw) }, | | |
| 1138 | .file_def => .{ .file_def = asFileDef(raw) }, | | |
| 1139 | .sect_def => .{ .sect_def = asSectDef(raw) }, | | |
| 1140 | }; | | |
| 1141 | } | | |
| 1142 | | 1120 | |
| 1143 | fn asSymbol(raw: []const u8) Symbol { | 1121 | pub const Record = union(Tag) { |
| 1144 | return .{ | 1122 | symbol: Symbol, |
| 1145 | .name = raw[0..8].*, | 1123 | debug_info: DebugInfoDefinition, |
| 1146 | .value = mem.readIntLittle(u32, raw[8..12]), | 1124 | func_def: FunctionDefinition, |
| 1147 | .section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])), | 1125 | weak_ext: WeakExternalDefinition, |
| 1148 | .@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])), | 1126 | file_def: FileDefinition, |
| 1149 | .storage_class = @intToEnum(StorageClass, raw[16]), | 1127 | sect_def: SectionDefinition, |
| 1150 | .number_of_aux_symbols = raw[17], | 1128 | }; |
| 1151 | }; | | |
| 1152 | } | | |
| 1153 | | 1129 | |
| 1154 | fn asDebugInfo(raw: []const u8) DebugInfoDefinition { | 1130 | /// Lives as long as Symtab instance. |
| 1155 | return .{ | 1131 | pub fn at(self: Symtab, index: usize, tag: Tag) Record { |
| 1156 | .unused_1 = raw[0..4].*, | 1132 | const offset = index * Symbol.sizeOf(); |
| 1157 | .linenumber = mem.readIntLittle(u16, raw[4..6]), | 1133 | const raw = self.buffer[offset..][0..Symbol.sizeOf()]; |
| 1158 | .unused_2 = raw[6..12].*, | 1134 | return switch (tag) { |
| 1159 | .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]), | 1135 | .symbol => .{ .symbol = asSymbol(raw) }, |
| 1160 | .unused_3 = raw[16..18].*, | 1136 | .debug_info => .{ .debug_info = asDebugInfo(raw) }, |
| 1161 | }; | 1137 | .func_def => .{ .func_def = asFuncDef(raw) }, |
| 1162 | } | 1138 | .weak_ext => .{ .weak_ext = asWeakExtDef(raw) }, |
| | 1139 | .file_def => .{ .file_def = asFileDef(raw) }, |
| | 1140 | .sect_def => .{ .sect_def = asSectDef(raw) }, |
| | 1141 | }; |
| | 1142 | } |
| 1163 | | 1143 | |
| 1164 | fn asFuncDef(raw: []const u8) FunctionDefinition { | 1144 | fn asSymbol(raw: []const u8) Symbol { |
| 1165 | return .{ | 1145 | return .{ |
| 1166 | .tag_index = mem.readIntLittle(u32, raw[0..4]), | 1146 | .name = raw[0..8].*, |
| 1167 | .total_size = mem.readIntLittle(u32, raw[4..8]), | 1147 | .value = mem.readIntLittle(u32, raw[8..12]), |
| 1168 | .pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]), | 1148 | .section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])), |
| 1169 | .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]), | 1149 | .@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])), |
| 1170 | .unused = raw[16..18].*, | 1150 | .storage_class = @intToEnum(StorageClass, raw[16]), |
| 1171 | }; | 1151 | .number_of_aux_symbols = raw[17], |
| 1172 | } | 1152 | }; |
| | 1153 | } |
| 1173 | | 1154 | |
| 1174 | fn asWeakExtDef(raw: []const u8) WeakExternalDefinition { | 1155 | fn asDebugInfo(raw: []const u8) DebugInfoDefinition { |
| 1175 | return .{ | 1156 | return .{ |
| 1176 | .tag_index = mem.readIntLittle(u32, raw[0..4]), | 1157 | .unused_1 = raw[0..4].*, |
| 1177 | .flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])), | 1158 | .linenumber = mem.readIntLittle(u16, raw[4..6]), |
| 1178 | .unused = raw[8..18].*, | 1159 | .unused_2 = raw[6..12].*, |
| 1179 | }; | 1160 | .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]), |
| 1180 | } | 1161 | .unused_3 = raw[16..18].*, |
| | 1162 | }; |
| | 1163 | } |
| 1181 | | 1164 | |
| 1182 | fn asFileDef(raw: []const u8) FileDefinition { | 1165 | fn asFuncDef(raw: []const u8) FunctionDefinition { |
| 1183 | return .{ | 1166 | return .{ |
| 1184 | .file_name = raw[0..18].*, | 1167 | .tag_index = mem.readIntLittle(u32, raw[0..4]), |
| 1185 | }; | 1168 | .total_size = mem.readIntLittle(u32, raw[4..8]), |
| 1186 | } | 1169 | .pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]), |
| | 1170 | .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]), |
| | 1171 | .unused = raw[16..18].*, |
| | 1172 | }; |
| | 1173 | } |
| 1187 | | 1174 | |
| 1188 | fn asSectDef(raw: []const u8) SectionDefinition { | 1175 | fn asWeakExtDef(raw: []const u8) WeakExternalDefinition { |
| 1189 | return .{ | 1176 | return .{ |
| 1190 | .length = mem.readIntLittle(u32, raw[0..4]), | 1177 | .tag_index = mem.readIntLittle(u32, raw[0..4]), |
| 1191 | .number_of_relocations = mem.readIntLittle(u16, raw[4..6]), | 1178 | .flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])), |
| 1192 | .number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]), | 1179 | .unused = raw[8..18].*, |
| 1193 | .checksum = mem.readIntLittle(u32, raw[8..12]), | 1180 | }; |
| 1194 | .number = mem.readIntLittle(u16, raw[12..14]), | 1181 | } |
| 1195 | .selection = @intToEnum(ComdatSelection, raw[14]), | | |
| 1196 | .unused = raw[15..18].*, | | |
| 1197 | }; | | |
| 1198 | } | | |
| 1199 | | 1182 | |
| 1200 | const Slice = struct { | 1183 | fn asFileDef(raw: []const u8) FileDefinition { |
| 1201 | buffer: []const u8, | 1184 | return .{ |
| 1202 | num: usize, | 1185 | .file_name = raw[0..18].*, |
| 1203 | count: usize = 0, | | |
| 1204 | | | |
| 1205 | /// Lives as long as Symtab instance. | | |
| 1206 | fn next(self: *Slice) ?Symbol { | | |
| 1207 | if (self.count >= self.num) return null; | | |
| 1208 | const sym = asSymbol(self.buffer[0..Symbol.sizeOf()]); | | |
| 1209 | self.count += 1; | | |
| 1210 | self.buffer = self.buffer[Symbol.sizeOf()..]; | | |
| 1211 | return sym; | | |
| 1212 | } | | |
| 1213 | }; | 1186 | }; |
| | 1187 | } |
| 1214 | | 1188 | |
| 1215 | fn slice(self: Symtab, start: usize, end: ?usize) Slice { | 1189 | fn asSectDef(raw: []const u8) SectionDefinition { |
| 1216 | const offset = start * Symbol.sizeOf(); | 1190 | return .{ |
| 1217 | const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len; | 1191 | .length = mem.readIntLittle(u32, raw[0..4]), |
| 1218 | const num = @divExact(llen - offset, Symbol.sizeOf()); | 1192 | .number_of_relocations = mem.readIntLittle(u16, raw[4..6]), |
| 1219 | return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num }; | 1193 | .number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]), |
| 1220 | } | 1194 | .checksum = mem.readIntLittle(u32, raw[8..12]), |
| 1221 | }; | 1195 | .number = mem.readIntLittle(u16, raw[12..14]), |
| | 1196 | .selection = @intToEnum(ComdatSelection, raw[14]), |
| | 1197 | .unused = raw[15..18].*, |
| | 1198 | }; |
| | 1199 | } |
| 1222 | | 1200 | |
| 1223 | pub const Strtab = struct { | 1201 | pub const Slice = struct { |
| 1224 | buffer: []const u8, | 1202 | buffer: []const u8, |
| | 1203 | num: usize, |
| | 1204 | count: usize = 0, |
| 1225 | | 1205 | |
| 1226 | fn get(self: Strtab, off: u32) []const u8 { | 1206 | /// Lives as long as Symtab instance. |
| 1227 | assert(off < self.buffer.len); | 1207 | pub fn next(self: *Slice) ?Symbol { |
| 1228 | return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0); | 1208 | if (self.count >= self.num) return null; |
| | 1209 | const sym = asSymbol(self.buffer[0..Symbol.sizeOf()]); |
| | 1210 | self.count += 1; |
| | 1211 | self.buffer = self.buffer[Symbol.sizeOf()..]; |
| | 1212 | return sym; |
| 1229 | } | 1213 | } |
| 1230 | }; | 1214 | }; |
| | 1215 | |
| | 1216 | pub fn slice(self: Symtab, start: usize, end: ?usize) Slice { |
| | 1217 | const offset = start * Symbol.sizeOf(); |
| | 1218 | const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len; |
| | 1219 | const num = @divExact(llen - offset, Symbol.sizeOf()); |
| | 1220 | return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num }; |
| | 1221 | } |
| | 1222 | }; |
| | 1223 | |
| | 1224 | pub const Strtab = struct { |
| | 1225 | buffer: []const u8, |
| | 1226 | |
| | 1227 | pub fn get(self: Strtab, off: u32) []const u8 { |
| | 1228 | assert(off < self.buffer.len); |
| | 1229 | return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0); |
| | 1230 | } |
| 1231 | }; | 1231 | }; |