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
0 commit comments