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