authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 20:18:51+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 20:18:51+01:00
log342a2749487d9952cf2afd6f8fb3e9534d4a210a
tree84126141f2bcfe8acf7ad0545243f1d94dfc95ab
parentce2efbdca6f1bf8a1ac01c379cb90990a2ea4e78

tidy interface, const correctness


2 files changed, 65 insertions(+), 84 deletions(-)

lib/std/debug.zig+60-79
...@@ -838,9 +838,13 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {...@@ -838,9 +838,13 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
838 }838 }
839}839}
840840
841fn openCoffDebugInfo(allocator: *mem.Allocator, self_file: fs.File) !ObjectDebugInfo {841/// TODO resources https://github.com/ziglang/zig/issues/4353
842fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ObjectDebugInfo {
843 const coff_file = try std.fs.openFileAbsoluteW(coff_file_path.ptr, .{});
844 errdefer coff_file.close();
845
842 const coff_obj = try allocator.create(coff.Coff);846 const coff_obj = try allocator.create(coff.Coff);
843 coff_obj.* = coff.Coff.init(allocator, self_file);847 coff_obj.* = coff.Coff.init(allocator, coff_file);
844848
845 var di = ObjectDebugInfo{849 var di = ObjectDebugInfo{
846 .base_address = undefined,850 .base_address = undefined,
...@@ -1007,14 +1011,6 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {...@@ -1007,14 +1011,6 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
1007 return list.toOwnedSlice();1011 return list.toOwnedSlice();
1008}1012}
10091013
1010fn findDwarfSectionFromElf(elf_file: *elf.Elf, name: []const u8) !?DW.DwarfInfo.Section {
1011 const elf_header = (try elf_file.findSection(name)) orelse return null;
1012 return DW.DwarfInfo.Section{
1013 .offset = elf_header.sh_offset,
1014 .size = elf_header.sh_size,
1015 };
1016}
1017
1018fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {1014fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
1019 const start = try math.cast(usize, offset);1015 const start = try math.cast(usize, offset);
1020 const end = start + try math.cast(usize, size);1016 const end = start + try math.cast(usize, size);
...@@ -1022,11 +1018,10 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {...@@ -1022,11 +1018,10 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
1022}1018}
10231019
1024/// TODO resources https://github.com/ziglang/zig/issues/43531020/// TODO resources https://github.com/ziglang/zig/issues/4353
1025pub fn openElfDebugInfo(1021pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ObjectDebugInfo {
1026 allocator: *mem.Allocator,1022 const mapped_mem = mapWholeFile(elf_file_path) catch |_| return error.InvalidDebugInfo;
1027 data: []const u8,1023
1028) !DW.DwarfInfo {1024 var seekable_stream = io.SliceSeekableInStream.init(mapped_mem);
1029 var seekable_stream = io.SliceSeekableInStream.init(data);
1030 var efile = try elf.Elf.openStream(1025 var efile = try elf.Elf.openStream(
1031 allocator,1026 allocator,
1032 @ptrCast(*DW.DwarfSeekableStream, &seekable_stream.seekable_stream),1027 @ptrCast(*DW.DwarfSeekableStream, &seekable_stream.seekable_stream),
...@@ -1046,26 +1041,32 @@ pub fn openElfDebugInfo(...@@ -1046,26 +1041,32 @@ pub fn openElfDebugInfo(
10461041
1047 var di = DW.DwarfInfo{1042 var di = DW.DwarfInfo{
1048 .endian = efile.endian,1043 .endian = efile.endian,
1049 .debug_info = try chopSlice(data, debug_info.sh_offset, debug_info.sh_size),1044 .debug_info = try chopSlice(mapped_mem, debug_info.sh_offset, debug_info.sh_size),
1050 .debug_abbrev = try chopSlice(data, debug_abbrev.sh_offset, debug_abbrev.sh_size),1045 .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.sh_offset, debug_abbrev.sh_size),
1051 .debug_str = try chopSlice(data, debug_str.sh_offset, debug_str.sh_size),1046 .debug_str = try chopSlice(mapped_mem, debug_str.sh_offset, debug_str.sh_size),
1052 .debug_line = try chopSlice(data, debug_line.sh_offset, debug_line.sh_size),1047 .debug_line = try chopSlice(mapped_mem, debug_line.sh_offset, debug_line.sh_size),
1053 .debug_ranges = if (opt_debug_ranges) |debug_ranges|1048 .debug_ranges = if (opt_debug_ranges) |debug_ranges|
1054 try chopSlice(data, debug_ranges.sh_offset, debug_ranges.sh_size)1049 try chopSlice(mapped_mem, debug_ranges.sh_offset, debug_ranges.sh_size)
1055 else1050 else
1056 null,1051 null,
1057 };1052 };
10581053
1059 try DW.openDwarfDebugInfo(&di, allocator);1054 try DW.openDwarfDebugInfo(&di, allocator);
1060 return di;1055
1056 return ObjectDebugInfo{
1057 .base_address = undefined,
1058 .dwarf = di,
1059 .mapped_memory = mapped_mem,
1060 };
1061}1061}
10621062
1063/// TODO resources https://github.com/ziglang/zig/issues/43531063/// TODO resources https://github.com/ziglang/zig/issues/4353
1064fn openMachODebugInfo(allocator: *mem.Allocator, memmo: []const u8) !ObjectDebugInfo {1064fn openMachODebugInfo(allocator: *mem.Allocator, macho_file_path: []const u8) !ObjectDebugInfo {
1065 // const hdr = &std.c._mh_execute_header;1065 const mapped_mem = mapWholeFile(macho_file_path) catch |_| return error.InvalidDebugInfo;
1066
1066 const hdr = @ptrCast(1067 const hdr = @ptrCast(
1067 *const macho.mach_header_64,1068 *const macho.mach_header_64,
1068 @alignCast(@alignOf(macho.mach_header_64), memmo.ptr),1069 @alignCast(@alignOf(macho.mach_header_64), mapped_mem.ptr),
1069 );1070 );
1070 assert(hdr.magic == std.macho.MH_MAGIC_64);1071 assert(hdr.magic == std.macho.MH_MAGIC_64);
10711072
...@@ -1137,7 +1138,7 @@ fn openMachODebugInfo(allocator: *mem.Allocator, memmo: []const u8) !ObjectDebug...@@ -1137,7 +1138,7 @@ fn openMachODebugInfo(allocator: *mem.Allocator, memmo: []const u8) !ObjectDebug
11371138
1138 return ObjectDebugInfo{1139 return ObjectDebugInfo{
1139 .base_address = undefined,1140 .base_address = undefined,
1140 .mapped_memory = undefined,1141 .mapped_memory = mapped_mem,
1141 .ofiles = ObjectDebugInfo.OFileTable.init(allocator),1142 .ofiles = ObjectDebugInfo.OFileTable.init(allocator),
1142 .symbols = symbols,1143 .symbols = symbols,
1143 .strings = strings,1144 .strings = strings,
...@@ -1191,6 +1192,24 @@ const MachoSymbol = struct {...@@ -1191,6 +1192,24 @@ const MachoSymbol = struct {
1191 }1192 }
1192};1193};
11931194
1195fn mapWholeFile(path: []const u8) ![]const u8 {
1196 const file = try fs.openFileAbsolute(path, .{});
1197 defer file.close();
1198
1199 const file_len = try math.cast(usize, try file.getEndPos());
1200 const mapped_mem = try os.mmap(
1201 null,
1202 file_len,
1203 os.PROT_READ,
1204 os.MAP_SHARED,
1205 file.handle,
1206 0,
1207 );
1208 errdefer os.munmap(mapped_mem);
1209
1210 return mapped_mem;
1211}
1212
1194pub const DebugInfo = struct {1213pub const DebugInfo = struct {
1195 allocator: *mem.Allocator,1214 allocator: *mem.Allocator,
1196 address_map: std.AutoHashMap(usize, *ObjectDebugInfo),1215 address_map: std.AutoHashMap(usize, *ObjectDebugInfo),
...@@ -1253,30 +1272,14 @@ pub const DebugInfo = struct {...@@ -1253,30 +1272,14 @@ pub const DebugInfo = struct {
1253 return obj_di;1272 return obj_di;
1254 }1273 }
12551274
1256 const image_name = std.c._dyld_get_image_name(i);
1257 const exe_file = try fs.openFileAbsoluteC(image_name, .{});
1258 errdefer exe_file.close();
1259
1260 const exe_len = math.cast(usize, try exe_file.getEndPos()) catch
1261 return error.DebugInfoTooLarge;
1262 const exe_mmap = try os.mmap(
1263 null,
1264 exe_len,
1265 os.PROT_READ,
1266 os.MAP_SHARED,
1267 exe_file.handle,
1268 0,
1269 );
1270 errdefer os.munmap(exe_mmap);
1271
1272 const obj_di = try self.allocator.create(ObjectDebugInfo);1275 const obj_di = try self.allocator.create(ObjectDebugInfo);
1273 errdefer self.allocator.destroy(obj_di);1276 errdefer self.allocator.destroy(obj_di);
12741277
1275 try self.address_map.putNoClobber(base_address, obj_di);1278 try self.address_map.putNoClobber(base_address, obj_di);
12761279
1277 obj_di.* = try openMachODebugInfo(self.allocator, exe_mmap);1280 const macho_path = mem.toSliceConst(u8, std.c._dyld_get_image_name(i));
1281 obj_di.* = try openMachODebugInfo(self.allocator, macho_path);
1278 obj_di.base_address = base_address;1282 obj_di.base_address = base_address;
1279 obj_di.mapped_memory = exe_mmap;
12801283
1281 return obj_di;1284 return obj_di;
1282 }1285 }
...@@ -1348,18 +1351,12 @@ pub const DebugInfo = struct {...@@ -1348,18 +1351,12 @@ pub const DebugInfo = struct {
1348 );1351 );
1349 assert(len > 0);1352 assert(len > 0);
13501353
1351 // The compiler segfaults if the slicing is done as a parameter
1352 // (#4423)
1353 const tmp = name_buffer[0..:0];
1354 const file_obj = try fs.openFileAbsoluteW(tmp, .{});
1355 errdefer file_obj.close();
1356
1357 const obj_di = try self.allocator.create(ObjectDebugInfo);1354 const obj_di = try self.allocator.create(ObjectDebugInfo);
1358 errdefer self.allocator.destroy(obj_di);1355 errdefer self.allocator.destroy(obj_di);
13591356
1360 try self.address_map.putNoClobber(seg_start, obj_di);1357 try self.address_map.putNoClobber(seg_start, obj_di);
13611358
1362 obj_di.* = try openCoffDebugInfo(self.allocator, file_obj);1359 obj_di.* = try openCoffDebugInfo(self.allocator, name_buffer[0..:0]);
1363 obj_di.base_address = seg_start;1360 obj_di.base_address = seg_start;
13641361
1365 return obj_di;1362 return obj_di;
...@@ -1407,45 +1404,29 @@ pub const DebugInfo = struct {...@@ -1407,45 +1404,29 @@ pub const DebugInfo = struct {
1407 }1404 }
1408 }.callback)) {1405 }.callback)) {
1409 return error.DebugInfoNotFound;1406 return error.DebugInfoNotFound;
1410 } else |err| {1407 } else |err| switch (err) {
1411 switch (err) {1408 error.Found => {},
1412 error.Found => {},1409 else => return error.DebugInfoNotFound,
1413 else => return error.DebugInfoNotFound,
1414 }
1415 }1410 }
14161411
1417 if (self.address_map.getValue(ctx.base_address)) |obj_di| {1412 if (self.address_map.getValue(ctx.base_address)) |obj_di| {
1418 return obj_di;1413 return obj_di;
1419 }1414 }
14201415
1421 const exe_file = if (ctx.name.len > 0)1416 const elf_path = if (ctx.name.len > 0)
1422 try fs.openFileAbsolute(ctx.name, .{})1417 ctx.name
1423 else1418 else blk: {
1424 try fs.openSelfExe();1419 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
1425 defer exe_file.close();1420 break :blk try fs.selfExePath(&buf);
14261421 };
1427 const exe_len = math.cast(usize, try exe_file.getEndPos()) catch
1428 return error.DebugInfoTooLarge;
1429 const exe_mmap = try os.mmap(
1430 null,
1431 exe_len,
1432 os.PROT_READ,
1433 os.MAP_SHARED,
1434 exe_file.handle,
1435 0,
1436 );
1437 errdefer os.munmap(exe_mmap);
14381422
1439 const obj_di = try self.allocator.create(ObjectDebugInfo);1423 const obj_di = try self.allocator.create(ObjectDebugInfo);
1440 errdefer self.allocator.destroy(obj_di);1424 errdefer self.allocator.destroy(obj_di);
14411425
1442 try self.address_map.putNoClobber(ctx.base_address, obj_di);1426 try self.address_map.putNoClobber(ctx.base_address, obj_di);
14431427
1444 obj_di.* = .{1428 obj_di.* = try openElfDebugInfo(self.allocator, elf_path);
1445 .dwarf = try openElfDebugInfo(self.allocator, exe_mmap),1429 obj_di.base_address = ctx.base_address;
1446 .mapped_memory = exe_mmap,
1447 .base_address = ctx.base_address,
1448 };
14491430
1450 return obj_di;1431 return obj_di;
1451 }1432 }
...@@ -1454,7 +1435,7 @@ pub const DebugInfo = struct {...@@ -1454,7 +1435,7 @@ pub const DebugInfo = struct {
1454pub const ObjectDebugInfo = switch (builtin.os) {1435pub const ObjectDebugInfo = switch (builtin.os) {
1455 .macosx, .ios, .watchos, .tvos => struct {1436 .macosx, .ios, .watchos, .tvos => struct {
1456 base_address: usize,1437 base_address: usize,
1457 mapped_memory: []u8,1438 mapped_memory: []const u8,
1458 symbols: []const MachoSymbol,1439 symbols: []const MachoSymbol,
1459 strings: []const u8,1440 strings: []const u8,
1460 ofiles: OFileTable,1441 ofiles: OFileTable,
...@@ -1480,7 +1461,7 @@ pub const ObjectDebugInfo = switch (builtin.os) {...@@ -1480,7 +1461,7 @@ pub const ObjectDebugInfo = switch (builtin.os) {
1480 .linux, .freebsd => struct {1461 .linux, .freebsd => struct {
1481 base_address: usize,1462 base_address: usize,
1482 dwarf: DW.DwarfInfo,1463 dwarf: DW.DwarfInfo,
1483 mapped_memory: []u8,1464 mapped_memory: []const u8,
1484 },1465 },
1485 else => DW.DwarfInfo,1466 else => DW.DwarfInfo,
1486};1467};
lib/std/dwarf.zig+5-5
...@@ -21,7 +21,7 @@ const PcRange = struct {...@@ -21,7 +21,7 @@ const PcRange = struct {
2121
22const Func = struct {22const Func = struct {
23 pc_range: ?PcRange,23 pc_range: ?PcRange,
24 name: ?[]u8,24 name: ?[]const u8,
25};25};
2626
27const CompileUnit = struct {27const CompileUnit = struct {
...@@ -60,7 +60,7 @@ const FormValue = union(enum) {...@@ -60,7 +60,7 @@ const FormValue = union(enum) {
60 SecOffset: u64,60 SecOffset: u64,
61 Ref: u64,61 Ref: u64,
62 RefAddr: u64,62 RefAddr: u64,
63 String: []u8,63 String: []const u8,
64 StrPtr: u64,64 StrPtr: u64,
65};65};
6666
...@@ -124,7 +124,7 @@ const Die = struct {...@@ -124,7 +124,7 @@ const Die = struct {
124 };124 };
125 }125 }
126126
127 fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]u8 {127 fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
128 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;128 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
129 return switch (form_value.*) {129 return switch (form_value.*) {
130 FormValue.String => |value| value,130 FormValue.String => |value| value,
...@@ -740,7 +740,7 @@ pub const DwarfInfo = struct {...@@ -740,7 +740,7 @@ pub const DwarfInfo = struct {
740 }740 }
741 }741 }
742742
743 var include_directories = ArrayList([]u8).init(di.allocator());743 var include_directories = ArrayList([]const u8).init(di.allocator());
744 try include_directories.append(compile_unit_cwd);744 try include_directories.append(compile_unit_cwd);
745 while (true) {745 while (true) {
746 const dir = try s.stream.readUntilDelimiterAlloc(di.allocator(), 0, math.maxInt(usize));746 const dir = try s.stream.readUntilDelimiterAlloc(di.allocator(), 0, math.maxInt(usize));
...@@ -861,7 +861,7 @@ pub const DwarfInfo = struct {...@@ -861,7 +861,7 @@ pub const DwarfInfo = struct {
861 return error.MissingDebugInfo;861 return error.MissingDebugInfo;
862 }862 }
863863
864 fn getString(di: *DwarfInfo, offset: u64) ![]u8 {864 fn getString(di: *DwarfInfo, offset: u64) ![]const u8 {
865 if (offset > di.debug_str.len)865 if (offset > di.debug_str.len)
866 return error.InvalidDebugInfo;866 return error.InvalidDebugInfo;
867 const casted_offset = math.cast(usize, offset) catch867 const casted_offset = math.cast(usize, offset) catch