diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-10-10 00:41:58 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-10-10 14:21:52 -0700 |
| commit | 14c8e270bb47c4e10ee3392661d4c62ab5c2f89d (patch) | |
| tree | c74fe79e74d3fc6bff7dd61f372153906e29e040 /src/link/MachO/Object.zig | |
| parent | 58349b2c8ebc57718bbfbf939c30b586d5c85466 (diff) | |
| download | zig-14c8e270bb47c4e10ee3392661d4c62ab5c2f89d.tar.gz zig-14c8e270bb47c4e10ee3392661d4c62ab5c2f89d.zip | |
link: fix false positive crtbegin/crtend detection
Embrace the Path abstraction, doing more operations based on directory
handles rather than absolute file paths. Most of the diff noise here
comes from this one.
Fix sorting of crtbegin/crtend atoms. Previously it would look at all
path components for those strings.
Make the C runtime path detection partially a pure function, and move
some logic to glibc.zig where it belongs.
Diffstat (limited to 'src/link/MachO/Object.zig')
| -rw-r--r-- | src/link/MachO/Object.zig | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 81f28de65a..9181112f2a 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -1,6 +1,8 @@ /// Non-zero for fat object files or archives offset: u64, -path: []const u8, +/// Archive files cannot contain subdirectories, so only the basename is needed +/// for output. However, the full path is kept for error reporting. +path: Path, file_handle: File.HandleIndex, mtime: u64, index: File.Index, @@ -39,8 +41,8 @@ output_symtab_ctx: MachO.SymtabCtx = .{}, output_ar_state: Archive.ArState = .{}, pub fn deinit(self: *Object, allocator: Allocator) void { - if (self.in_archive) |*ar| allocator.free(ar.path); - allocator.free(self.path); + if (self.in_archive) |*ar| allocator.free(ar.path.sub_path); + allocator.free(self.path.sub_path); for (self.sections.items(.relocs), self.sections.items(.subsections)) |*relocs, *sub| { relocs.deinit(allocator); sub.deinit(allocator); @@ -1723,7 +1725,8 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void { pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void { // Header const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; - try Archive.writeHeader(self.path, size, ar_format, writer); + const basename = std.fs.path.basename(self.path.sub_path); + try Archive.writeHeader(basename, size, ar_format, writer); // Data const file = macho_file.getFileHandle(self.file_handle); // TODO try using copyRangeAll @@ -1774,6 +1777,11 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void { self.calcStabsSize(macho_file); } +fn pathLen(path: Path) usize { + // +1 for the path separator + return (if (path.root_dir.path) |p| p.len + @intFromBool(path.sub_path.len != 0) else 0) + path.sub_path.len; +} + pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { if (self.compile_unit) |cu| { const comp_dir = cu.getCompDir(self.*); @@ -1784,9 +1792,9 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { self.output_symtab_ctx.strsize += @as(u32, @intCast(tu_name.len + 1)); // tu_name if (self.in_archive) |ar| { - self.output_symtab_ctx.strsize += @as(u32, @intCast(ar.path.len + 1 + self.path.len + 1 + 1)); + self.output_symtab_ctx.strsize += @intCast(pathLen(ar.path) + 1 + self.path.basename().len + 1 + 1); } else { - self.output_symtab_ctx.strsize += @as(u32, @intCast(self.path.len + 1)); + self.output_symtab_ctx.strsize += @intCast(pathLen(self.path) + 1); } for (self.symbols.items, 0..) |sym, i| { @@ -2118,19 +2126,36 @@ pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) v }; index += 1; if (self.in_archive) |ar| { - @memcpy(ctx.strtab.items[n_strx..][0..ar.path.len], ar.path); - n_strx += @intCast(ar.path.len); + if (ar.path.root_dir.path) |p| { + @memcpy(ctx.strtab.items[n_strx..][0..p.len], p); + n_strx += @intCast(p.len); + if (ar.path.sub_path.len != 0) { + ctx.strtab.items[n_strx] = '/'; + n_strx += 1; + } + } + @memcpy(ctx.strtab.items[n_strx..][0..ar.path.sub_path.len], ar.path.sub_path); + n_strx += @intCast(ar.path.sub_path.len); ctx.strtab.items[n_strx] = '('; n_strx += 1; - @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path); - n_strx += @intCast(self.path.len); + const basename = self.path.basename(); + @memcpy(ctx.strtab.items[n_strx..][0..basename.len], basename); + n_strx += @intCast(basename.len); ctx.strtab.items[n_strx] = ')'; n_strx += 1; ctx.strtab.items[n_strx] = 0; n_strx += 1; } else { - @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path); - n_strx += @intCast(self.path.len); + if (self.path.root_dir.path) |p| { + @memcpy(ctx.strtab.items[n_strx..][0..p.len], p); + n_strx += @intCast(p.len); + if (self.path.sub_path.len != 0) { + ctx.strtab.items[n_strx] = '/'; + n_strx += 1; + } + } + @memcpy(ctx.strtab.items[n_strx..][0..self.path.sub_path.len], self.path.sub_path); + n_strx += @intCast(self.path.sub_path.len); ctx.strtab.items[n_strx] = 0; n_strx += 1; } @@ -2666,11 +2691,12 @@ fn formatPath( _ = unused_fmt_string; _ = options; if (object.in_archive) |ar| { - try writer.writeAll(ar.path); - try writer.writeByte('('); - try writer.writeAll(object.path); - try writer.writeByte(')'); - } else try writer.writeAll(object.path); + try writer.print("{}({s})", .{ + @as(Path, ar.path), object.path.basename(), + }); + } else { + try writer.print("{}", .{@as(Path, object.path)}); + } } const Section = struct { @@ -2777,7 +2803,7 @@ const CompileUnit = struct { }; const InArchive = struct { - path: []const u8, + path: Path, size: u32, }; @@ -3170,6 +3196,7 @@ const math = std.math; const mem = std.mem; const trace = @import("../../tracy.zig").trace; const std = @import("std"); +const Path = std.Build.Cache.Path; const Allocator = mem.Allocator; const Archive = @import("Archive.zig"); |
