| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | /// Non-zero for fat object files or archives | 1 | /// Non-zero for fat object files or archives |
| 2 | offset: u64, | 2 | offset: u64, |
| 3 | /// Archive files cannot contain subdirectories, so only the basename is needed | 3 | /// If `in_archive` is not `null`, this is the basename of the object in the archive. Otherwise, |
| 4 | /// for output. However, the full path is kept for error reporting. | 4 | /// this is a fully-resolved absolute path, because that is the path we need to embed in stabs to |
| 5 | path: Path, | 5 | /// ensure the output does not depend on its cwd. |
| | 6 | path: []u8, |
| 6 | file_handle: File.HandleIndex, | 7 | file_handle: File.HandleIndex, |
| 7 | mtime: u64, | 8 | mtime: u64, |
| 8 | index: File.Index, | 9 | index: File.Index, |
| ... | @@ -41,8 +42,8 @@ output_symtab_ctx: MachO.SymtabCtx = .{}, | ... | @@ -41,8 +42,8 @@ output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 41 | output_ar_state: Archive.ArState = .{}, | 42 | output_ar_state: Archive.ArState = .{}, |
| 42 | | 43 | |
| 43 | pub fn deinit(self: *Object, allocator: Allocator) void { | 44 | pub fn deinit(self: *Object, allocator: Allocator) void { |
| 44 | if (self.in_archive) |*ar| allocator.free(ar.path.sub_path); | 45 | if (self.in_archive) |*ar| allocator.free(ar.path); |
| 45 | allocator.free(self.path.sub_path); | 46 | allocator.free(self.path); |
| 46 | for (self.sections.items(.relocs), self.sections.items(.subsections)) |*relocs, *sub| { | 47 | for (self.sections.items(.relocs), self.sections.items(.subsections)) |*relocs, *sub| { |
| 47 | relocs.deinit(allocator); | 48 | relocs.deinit(allocator); |
| 48 | sub.deinit(allocator); | 49 | sub.deinit(allocator); |
| ... | @@ -1703,7 +1704,7 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void { | ... | @@ -1703,7 +1704,7 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void { |
| 1703 | pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void { | 1704 | pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void { |
| 1704 | // Header | 1705 | // Header |
| 1705 | const size = try macho_file.cast(usize, self.output_ar_state.size); | 1706 | const size = try macho_file.cast(usize, self.output_ar_state.size); |
| 1706 | const basename = std.fs.path.basename(self.path.sub_path); | 1707 | const basename = std.fs.path.basename(self.path); |
| 1707 | try Archive.writeHeader(basename, size, ar_format, writer); | 1708 | try Archive.writeHeader(basename, size, ar_format, writer); |
| 1708 | // Data | 1709 | // Data |
| 1709 | const file = macho_file.getFileHandle(self.file_handle); | 1710 | const file = macho_file.getFileHandle(self.file_handle); |
| ... | @@ -1756,12 +1757,7 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void { | ... | @@ -1756,12 +1757,7 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void { |
| 1756 | self.calcStabsSize(macho_file); | 1757 | self.calcStabsSize(macho_file); |
| 1757 | } | 1758 | } |
| 1758 | | 1759 | |
| 1759 | fn pathLen(path: Path) usize { | 1760 | fn calcStabsSize(self: *Object, macho_file: *MachO) void { |
| 1760 | // +1 for the path separator | | |
| 1761 | return (if (path.root_dir.path) |p| p.len + @intFromBool(path.sub_path.len != 0) else 0) + path.sub_path.len; | | |
| 1762 | } | | |
| 1763 | | | |
| 1764 | pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { | | |
| 1765 | if (self.compile_unit) |cu| { | 1761 | if (self.compile_unit) |cu| { |
| 1766 | const comp_dir = cu.getCompDir(self.*); | 1762 | const comp_dir = cu.getCompDir(self.*); |
| 1767 | const tu_name = cu.getTuName(self.*); | 1763 | const tu_name = cu.getTuName(self.*); |
| ... | @@ -1771,9 +1767,11 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { | ... | @@ -1771,9 +1767,11 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { |
| 1771 | self.output_symtab_ctx.strsize += @as(u32, @intCast(tu_name.len + 1)); // tu_name | 1767 | self.output_symtab_ctx.strsize += @as(u32, @intCast(tu_name.len + 1)); // tu_name |
| 1772 | | 1768 | |
| 1773 | if (self.in_archive) |ar| { | 1769 | if (self.in_archive) |ar| { |
| 1774 | self.output_symtab_ctx.strsize += @intCast(pathLen(ar.path) + 1 + self.path.basename().len + 1 + 1); | 1770 | // "/path/to/archive.a(object.o)\x00" |
| | 1771 | self.output_symtab_ctx.strsize += @intCast(ar.path.len + self.path.len + 3); |
| 1775 | } else { | 1772 | } else { |
| 1776 | self.output_symtab_ctx.strsize += @intCast(pathLen(self.path) + 1); | 1773 | // "/path/to/object.o\x00" |
| | 1774 | self.output_symtab_ctx.strsize += @intCast(self.path.len + 1); |
| 1777 | } | 1775 | } |
| 1778 | | 1776 | |
| 1779 | for (self.symbols.items, 0..) |sym, i| { | 1777 | for (self.symbols.items, 0..) |sym, i| { |
| ... | @@ -2018,7 +2016,7 @@ pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) void { | ... | @@ -2018,7 +2016,7 @@ pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) void { |
| 2018 | self.writeStabs(n_strx, macho_file, ctx); | 2016 | self.writeStabs(n_strx, macho_file, ctx); |
| 2019 | } | 2017 | } |
| 2020 | | 2018 | |
| 2021 | pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) void { | 2019 | fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) void { |
| 2022 | const writeFuncStab = struct { | 2020 | const writeFuncStab = struct { |
| 2023 | inline fn writeFuncStab( | 2021 | inline fn writeFuncStab( |
| 2024 | n_strx: u32, | 2022 | n_strx: u32, |
| ... | @@ -2103,38 +2101,20 @@ pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) v | ... | @@ -2103,38 +2101,20 @@ pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) v |
| 2103 | }; | 2101 | }; |
| 2104 | index += 1; | 2102 | index += 1; |
| 2105 | if (self.in_archive) |ar| { | 2103 | if (self.in_archive) |ar| { |
| 2106 | if (ar.path.root_dir.path) |p| { | 2104 | // "/path/to/archive.a(object.o)\x00" |
| 2107 | @memcpy(ctx.strtab.items[n_strx..][0..p.len], p); | 2105 | @memcpy(ctx.strtab.items[n_strx..][0..ar.path.len], ar.path); |
| 2108 | n_strx += @intCast(p.len); | 2106 | n_strx += @intCast(ar.path.len); |
| 2109 | if (ar.path.sub_path.len != 0) { | 2107 | ctx.strtab.items[n_strx..][0] = '('; |
| 2110 | ctx.strtab.items[n_strx] = '/'; | | |
| 2111 | n_strx += 1; | | |
| 2112 | } | | |
| 2113 | } | | |
| 2114 | @memcpy(ctx.strtab.items[n_strx..][0..ar.path.sub_path.len], ar.path.sub_path); | | |
| 2115 | n_strx += @intCast(ar.path.sub_path.len); | | |
| 2116 | ctx.strtab.items[n_strx] = '('; | | |
| 2117 | n_strx += 1; | | |
| 2118 | const basename = self.path.basename(); | | |
| 2119 | @memcpy(ctx.strtab.items[n_strx..][0..basename.len], basename); | | |
| 2120 | n_strx += @intCast(basename.len); | | |
| 2121 | ctx.strtab.items[n_strx] = ')'; | | |
| 2122 | n_strx += 1; | | |
| 2123 | ctx.strtab.items[n_strx] = 0; | | |
| 2124 | n_strx += 1; | 2108 | n_strx += 1; |
| | 2109 | @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path); |
| | 2110 | n_strx += @intCast(self.path.len); |
| | 2111 | ctx.strtab.items[n_strx..][0..2].* = ")\x00".*; |
| | 2112 | n_strx += 2; |
| 2125 | } else { | 2113 | } else { |
| 2126 | if (self.path.root_dir.path) |p| { | 2114 | // "/path/to/object.o\x00" |
| 2127 | @memcpy(ctx.strtab.items[n_strx..][0..p.len], p); | 2115 | @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path); |
| 2128 | n_strx += @intCast(p.len); | 2116 | ctx.strtab.items[n_strx..][self.path.len] = 0; |
| 2129 | if (self.path.sub_path.len != 0) { | 2117 | n_strx += @intCast(self.path.len + 1); |
| 2130 | ctx.strtab.items[n_strx] = '/'; | | |
| 2131 | n_strx += 1; | | |
| 2132 | } | | |
| 2133 | } | | |
| 2134 | @memcpy(ctx.strtab.items[n_strx..][0..self.path.sub_path.len], self.path.sub_path); | | |
| 2135 | n_strx += @intCast(self.path.sub_path.len); | | |
| 2136 | ctx.strtab.items[n_strx] = 0; | | |
| 2137 | n_strx += 1; | | |
| 2138 | } | 2118 | } |
| 2139 | | 2119 | |
| 2140 | for (self.symbols.items, 0..) |sym, i| { | 2120 | for (self.symbols.items, 0..) |sym, i| { |
| ... | @@ -2621,11 +2601,9 @@ pub fn fmtPath(self: Object) std.fmt.Alt(Object, formatPath) { | ... | @@ -2621,11 +2601,9 @@ pub fn fmtPath(self: Object) std.fmt.Alt(Object, formatPath) { |
| 2621 | | 2601 | |
| 2622 | fn formatPath(object: Object, w: *Writer) Writer.Error!void { | 2602 | fn formatPath(object: Object, w: *Writer) Writer.Error!void { |
| 2623 | if (object.in_archive) |ar| { | 2603 | if (object.in_archive) |ar| { |
| 2624 | try w.print("{f}({s})", .{ | 2604 | try w.print("{s}({s})", .{ ar.path, object.path }); |
| 2625 | ar.path, object.path.basename(), | | |
| 2626 | }); | | |
| 2627 | } else { | 2605 | } else { |
| 2628 | try w.print("{f}", .{object.path}); | 2606 | try w.writeAll(object.path); |
| 2629 | } | 2607 | } |
| 2630 | } | 2608 | } |
| 2631 | | 2609 | |
| ... | @@ -2716,7 +2694,9 @@ const CompileUnit = struct { | ... | @@ -2716,7 +2694,9 @@ const CompileUnit = struct { |
| 2716 | }; | 2694 | }; |
| 2717 | | 2695 | |
| 2718 | const InArchive = struct { | 2696 | const InArchive = struct { |
| 2719 | path: Path, | 2697 | /// This is a fully-resolved absolute path, because that is the path we need to embed in stabs |
| | 2698 | /// to ensure the output does not depend on its cwd. |
| | 2699 | path: []u8, |
| 2720 | size: u32, | 2700 | size: u32, |
| 2721 | }; | 2701 | }; |
| 2722 | | 2702 | |
| ... | @@ -3094,7 +3074,6 @@ const log = std.log.scoped(.link); | ... | @@ -3094,7 +3074,6 @@ const log = std.log.scoped(.link); |
| 3094 | const macho = std.macho; | 3074 | const macho = std.macho; |
| 3095 | const math = std.math; | 3075 | const math = std.math; |
| 3096 | const mem = std.mem; | 3076 | const mem = std.mem; |
| 3097 | const Path = std.Build.Cache.Path; | | |
| 3098 | const Allocator = std.mem.Allocator; | 3077 | const Allocator = std.mem.Allocator; |
| 3099 | const Writer = std.Io.Writer; | 3078 | const Writer = std.Io.Writer; |
| 3100 | | 3079 | |