11/// Non-zero for fat object files or archives
22offset : 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 ,
67file_handle : File.HandleIndex ,
78mtime : u64 ,
89index : File.Index ,
@@ -41,8 +42,8 @@ output_symtab_ctx: MachO.SymtabCtx = .{},
4142output_ar_state : Archive.ArState = .{},
4243
4344pub 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 );
4647 for (self .sections .items (.relocs ), self .sections .items (.subsections )) | * relocs , * sub | {
4748 relocs .deinit (allocator );
4849 sub .deinit (allocator );
@@ -1703,7 +1704,7 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
17031704pub fn writeAr (self : Object , ar_format : Archive.Format , macho_file : * MachO , writer : anytype ) ! void {
17041705 // Header
17051706 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 );
17071708 try Archive .writeHeader (basename , size , ar_format , writer );
17081709 // Data
17091710 const file = macho_file .getFileHandle (self .file_handle );
@@ -1756,12 +1757,7 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void {
17561757 self .calcStabsSize (macho_file );
17571758}
17581759
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 {
17651761 if (self .compile_unit ) | cu | {
17661762 const comp_dir = cu .getCompDir (self .* );
17671763 const tu_name = cu .getTuName (self .* );
@@ -1771,9 +1767,11 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) void {
17711767 self .output_symtab_ctx .strsize += @as (u32 , @intCast (tu_name .len + 1 )); // tu_name
17721768
17731769 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 );
17751772 } 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 );
17771775 }
17781776
17791777 for (self .symbols .items , 0.. ) | sym , i | {
@@ -2018,7 +2016,7 @@ pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) void {
20182016 self .writeStabs (n_strx , macho_file , ctx );
20192017}
20202018
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 {
20222020 const writeFuncStab = struct {
20232021 inline fn writeFuncStab (
20242022 n_strx : u32 ,
@@ -2103,38 +2101,20 @@ pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) v
21032101 };
21042102 index += 1 ;
21052103 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 ] = '(' ;
21242108 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 ;
21252113 } 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 );
21382118 }
21392119
21402120 for (self .symbols .items , 0.. ) | sym , i | {
@@ -2621,11 +2601,9 @@ pub fn fmtPath(self: Object) std.fmt.Alt(Object, formatPath) {
26212601
26222602fn formatPath (object : Object , w : * Writer ) Writer.Error ! void {
26232603 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 });
26272605 } else {
2628- try w .print ( "{f}" , .{ object .path } );
2606+ try w .writeAll ( object .path );
26292607 }
26302608}
26312609
@@ -2716,7 +2694,9 @@ const CompileUnit = struct {
27162694};
27172695
27182696const 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 ,
27202700 size : u32 ,
27212701};
27222702
@@ -3094,7 +3074,6 @@ const log = std.log.scoped(.link);
30943074const macho = std .macho ;
30953075const math = std .math ;
30963076const mem = std .mem ;
3097- const Path = std .Build .Cache .Path ;
30983077const Allocator = std .mem .Allocator ;
30993078const Writer = std .Io .Writer ;
31003079
0 commit comments