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