Commit 342a274948

LemonBoy <thatlemon@gmail.com>
2020-02-20 20:18:51
tidy interface, const correctness
1 parent ce2efbd
Changed files (2)
lib/std/debug.zig
@@ -838,9 +838,13 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
     }
 }
 
-fn openCoffDebugInfo(allocator: *mem.Allocator, self_file: fs.File) !ObjectDebugInfo {
+/// TODO resources https://github.com/ziglang/zig/issues/4353
+fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ObjectDebugInfo {
+    const coff_file = try std.fs.openFileAbsoluteW(coff_file_path.ptr, .{});
+    errdefer coff_file.close();
+
     const coff_obj = try allocator.create(coff.Coff);
-    coff_obj.* = coff.Coff.init(allocator, self_file);
+    coff_obj.* = coff.Coff.init(allocator, coff_file);
 
     var di = ObjectDebugInfo{
         .base_address = undefined,
@@ -1007,14 +1011,6 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
     return list.toOwnedSlice();
 }
 
-fn findDwarfSectionFromElf(elf_file: *elf.Elf, name: []const u8) !?DW.DwarfInfo.Section {
-    const elf_header = (try elf_file.findSection(name)) orelse return null;
-    return DW.DwarfInfo.Section{
-        .offset = elf_header.sh_offset,
-        .size = elf_header.sh_size,
-    };
-}
-
 fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
     const start = try math.cast(usize, offset);
     const end = start + try math.cast(usize, size);
@@ -1022,11 +1018,10 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
 }
 
 /// TODO resources https://github.com/ziglang/zig/issues/4353
-pub fn openElfDebugInfo(
-    allocator: *mem.Allocator,
-    data: []const u8,
-) !DW.DwarfInfo {
-    var seekable_stream = io.SliceSeekableInStream.init(data);
+pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ObjectDebugInfo {
+    const mapped_mem = mapWholeFile(elf_file_path) catch |_| return error.InvalidDebugInfo;
+
+    var seekable_stream = io.SliceSeekableInStream.init(mapped_mem);
     var efile = try elf.Elf.openStream(
         allocator,
         @ptrCast(*DW.DwarfSeekableStream, &seekable_stream.seekable_stream),
@@ -1046,26 +1041,32 @@ pub fn openElfDebugInfo(
 
     var di = DW.DwarfInfo{
         .endian = efile.endian,
-        .debug_info = try chopSlice(data, debug_info.sh_offset, debug_info.sh_size),
-        .debug_abbrev = try chopSlice(data, debug_abbrev.sh_offset, debug_abbrev.sh_size),
-        .debug_str = try chopSlice(data, debug_str.sh_offset, debug_str.sh_size),
-        .debug_line = try chopSlice(data, debug_line.sh_offset, debug_line.sh_size),
+        .debug_info = try chopSlice(mapped_mem, debug_info.sh_offset, debug_info.sh_size),
+        .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.sh_offset, debug_abbrev.sh_size),
+        .debug_str = try chopSlice(mapped_mem, debug_str.sh_offset, debug_str.sh_size),
+        .debug_line = try chopSlice(mapped_mem, debug_line.sh_offset, debug_line.sh_size),
         .debug_ranges = if (opt_debug_ranges) |debug_ranges|
-            try chopSlice(data, debug_ranges.sh_offset, debug_ranges.sh_size)
+            try chopSlice(mapped_mem, debug_ranges.sh_offset, debug_ranges.sh_size)
         else
             null,
     };
 
     try DW.openDwarfDebugInfo(&di, allocator);
-    return di;
+
+    return ObjectDebugInfo{
+        .base_address = undefined,
+        .dwarf = di,
+        .mapped_memory = mapped_mem,
+    };
 }
 
 /// TODO resources https://github.com/ziglang/zig/issues/4353
-fn openMachODebugInfo(allocator: *mem.Allocator, memmo: []const u8) !ObjectDebugInfo {
-    // const hdr = &std.c._mh_execute_header;
+fn openMachODebugInfo(allocator: *mem.Allocator, macho_file_path: []const u8) !ObjectDebugInfo {
+    const mapped_mem = mapWholeFile(macho_file_path) catch |_| return error.InvalidDebugInfo;
+
     const hdr = @ptrCast(
         *const macho.mach_header_64,
-        @alignCast(@alignOf(macho.mach_header_64), memmo.ptr),
+        @alignCast(@alignOf(macho.mach_header_64), mapped_mem.ptr),
     );
     assert(hdr.magic == std.macho.MH_MAGIC_64);
 
@@ -1137,7 +1138,7 @@ fn openMachODebugInfo(allocator: *mem.Allocator, memmo: []const u8) !ObjectDebug
 
     return ObjectDebugInfo{
         .base_address = undefined,
-        .mapped_memory = undefined,
+        .mapped_memory = mapped_mem,
         .ofiles = ObjectDebugInfo.OFileTable.init(allocator),
         .symbols = symbols,
         .strings = strings,
@@ -1191,6 +1192,24 @@ const MachoSymbol = struct {
     }
 };
 
+fn mapWholeFile(path: []const u8) ![]const u8 {
+    const file = try fs.openFileAbsolute(path, .{});
+    defer file.close();
+
+    const file_len = try math.cast(usize, try file.getEndPos());
+    const mapped_mem = try os.mmap(
+        null,
+        file_len,
+        os.PROT_READ,
+        os.MAP_SHARED,
+        file.handle,
+        0,
+    );
+    errdefer os.munmap(mapped_mem);
+
+    return mapped_mem;
+}
+
 pub const DebugInfo = struct {
     allocator: *mem.Allocator,
     address_map: std.AutoHashMap(usize, *ObjectDebugInfo),
@@ -1253,30 +1272,14 @@ pub const DebugInfo = struct {
                         return obj_di;
                     }
 
-                    const image_name = std.c._dyld_get_image_name(i);
-                    const exe_file = try fs.openFileAbsoluteC(image_name, .{});
-                    errdefer exe_file.close();
-
-                    const exe_len = math.cast(usize, try exe_file.getEndPos()) catch
-                        return error.DebugInfoTooLarge;
-                    const exe_mmap = try os.mmap(
-                        null,
-                        exe_len,
-                        os.PROT_READ,
-                        os.MAP_SHARED,
-                        exe_file.handle,
-                        0,
-                    );
-                    errdefer os.munmap(exe_mmap);
-
                     const obj_di = try self.allocator.create(ObjectDebugInfo);
                     errdefer self.allocator.destroy(obj_di);
 
                     try self.address_map.putNoClobber(base_address, obj_di);
 
-                    obj_di.* = try openMachODebugInfo(self.allocator, exe_mmap);
+                    const macho_path = mem.toSliceConst(u8, std.c._dyld_get_image_name(i));
+                    obj_di.* = try openMachODebugInfo(self.allocator, macho_path);
                     obj_di.base_address = base_address;
-                    obj_di.mapped_memory = exe_mmap;
 
                     return obj_di;
                 }
@@ -1348,18 +1351,12 @@ pub const DebugInfo = struct {
                 );
                 assert(len > 0);
 
-                // The compiler segfaults if the slicing is done as a parameter
-                // (#4423)
-                const tmp = name_buffer[0..:0];
-                const file_obj = try fs.openFileAbsoluteW(tmp, .{});
-                errdefer file_obj.close();
-
                 const obj_di = try self.allocator.create(ObjectDebugInfo);
                 errdefer self.allocator.destroy(obj_di);
 
                 try self.address_map.putNoClobber(seg_start, obj_di);
 
-                obj_di.* = try openCoffDebugInfo(self.allocator, file_obj);
+                obj_di.* = try openCoffDebugInfo(self.allocator, name_buffer[0..:0]);
                 obj_di.base_address = seg_start;
 
                 return obj_di;
@@ -1407,45 +1404,29 @@ pub const DebugInfo = struct {
             }
         }.callback)) {
             return error.DebugInfoNotFound;
-        } else |err| {
-            switch (err) {
-                error.Found => {},
-                else => return error.DebugInfoNotFound,
-            }
+        } else |err| switch (err) {
+            error.Found => {},
+            else => return error.DebugInfoNotFound,
         }
 
         if (self.address_map.getValue(ctx.base_address)) |obj_di| {
             return obj_di;
         }
 
-        const exe_file = if (ctx.name.len > 0)
-            try fs.openFileAbsolute(ctx.name, .{})
-        else
-            try fs.openSelfExe();
-        defer exe_file.close();
-
-        const exe_len = math.cast(usize, try exe_file.getEndPos()) catch
-            return error.DebugInfoTooLarge;
-        const exe_mmap = try os.mmap(
-            null,
-            exe_len,
-            os.PROT_READ,
-            os.MAP_SHARED,
-            exe_file.handle,
-            0,
-        );
-        errdefer os.munmap(exe_mmap);
+        const elf_path = if (ctx.name.len > 0)
+            ctx.name
+        else blk: {
+            var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
+            break :blk try fs.selfExePath(&buf);
+        };
 
         const obj_di = try self.allocator.create(ObjectDebugInfo);
         errdefer self.allocator.destroy(obj_di);
 
         try self.address_map.putNoClobber(ctx.base_address, obj_di);
 
-        obj_di.* = .{
-            .dwarf = try openElfDebugInfo(self.allocator, exe_mmap),
-            .mapped_memory = exe_mmap,
-            .base_address = ctx.base_address,
-        };
+        obj_di.* = try openElfDebugInfo(self.allocator, elf_path);
+        obj_di.base_address = ctx.base_address;
 
         return obj_di;
     }
@@ -1454,7 +1435,7 @@ pub const DebugInfo = struct {
 pub const ObjectDebugInfo = switch (builtin.os) {
     .macosx, .ios, .watchos, .tvos => struct {
         base_address: usize,
-        mapped_memory: []u8,
+        mapped_memory: []const u8,
         symbols: []const MachoSymbol,
         strings: []const u8,
         ofiles: OFileTable,
@@ -1480,7 +1461,7 @@ pub const ObjectDebugInfo = switch (builtin.os) {
     .linux, .freebsd => struct {
         base_address: usize,
         dwarf: DW.DwarfInfo,
-        mapped_memory: []u8,
+        mapped_memory: []const u8,
     },
     else => DW.DwarfInfo,
 };
lib/std/dwarf.zig
@@ -21,7 +21,7 @@ const PcRange = struct {
 
 const Func = struct {
     pc_range: ?PcRange,
-    name: ?[]u8,
+    name: ?[]const u8,
 };
 
 const CompileUnit = struct {
@@ -60,7 +60,7 @@ const FormValue = union(enum) {
     SecOffset: u64,
     Ref: u64,
     RefAddr: u64,
-    String: []u8,
+    String: []const u8,
     StrPtr: u64,
 };
 
@@ -124,7 +124,7 @@ const Die = struct {
         };
     }
 
-    fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]u8 {
+    fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
         const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
         return switch (form_value.*) {
             FormValue.String => |value| value,
@@ -740,7 +740,7 @@ pub const DwarfInfo = struct {
             }
         }
 
-        var include_directories = ArrayList([]u8).init(di.allocator());
+        var include_directories = ArrayList([]const u8).init(di.allocator());
         try include_directories.append(compile_unit_cwd);
         while (true) {
             const dir = try s.stream.readUntilDelimiterAlloc(di.allocator(), 0, math.maxInt(usize));
@@ -861,7 +861,7 @@ pub const DwarfInfo = struct {
         return error.MissingDebugInfo;
     }
 
-    fn getString(di: *DwarfInfo, offset: u64) ![]u8 {
+    fn getString(di: *DwarfInfo, offset: u64) ![]const u8 {
         if (offset > di.debug_str.len)
             return error.InvalidDebugInfo;
         const casted_offset = math.cast(usize, offset) catch