| author | |
| committer | |
| log | 60f2f3457dd73772e7cd60bf5d90358079361d11 |
| tree | d86ce4af1ccd7ecc12cfb59507e38900f046331e |
| parent | 662b5f7c6045ba857d0d9abd72350a82f0b7ddf3 |
| signature | Commit is signed but in an unrecognized format. |
* `std.Target.getStandardDynamicLinkerPath` =>
`std.Target.standardDynamicLinkerPath`
* it now takes a pointer to fixed size array rather than an allocator
* `std.zig.system.NativeTargetInfo.detect` now supports reading
PT_INTERP from /usr/bin/env3 files changed, 158 insertions(+), 113 deletions(-)
lib/std/target.zig+71-69| ... | ... | @@ -1084,65 +1084,59 @@ pub const Target = struct { |
| 1084 | 1084 | } |
| 1085 | 1085 | } |
| 1086 | 1086 | |
| 1087 | /// Caller owns returned memory. | |
| 1088 | pub fn getStandardDynamicLinkerPath( | |
| 1089 | self: Target, | |
| 1090 | allocator: *mem.Allocator, | |
| 1091 | ) error{ | |
| 1092 | OutOfMemory, | |
| 1093 | UnknownDynamicLinkerPath, | |
| 1094 | TargetHasNoDynamicLinker, | |
| 1095 | }![:0]u8 { | |
| 1096 | const a = allocator; | |
| 1087 | /// The result will be a slice of `buffer`, pointing at position 0. | |
| 1088 | /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. | |
| 1089 | pub fn standardDynamicLinkerPath(self: Target, buffer: *[255]u8) ?[]u8 { | |
| 1090 | const S = struct { | |
| 1091 | fn print(b: *[255]u8, comptime fmt: []const u8, args: var) []u8 { | |
| 1092 | return std.fmt.bufPrint(b, fmt, args) catch unreachable; | |
| 1093 | } | |
| 1094 | fn copy(b: *[255]u8, s: []const u8) []u8 { | |
| 1095 | mem.copy(u8, b, s); | |
| 1096 | return b[0..s.len]; | |
| 1097 | } | |
| 1098 | }; | |
| 1099 | const print = S.print; | |
| 1100 | const copy = S.copy; | |
| 1101 | ||
| 1097 | 1102 | if (self.isAndroid()) { |
| 1098 | return mem.dupeZ(a, u8, if (self.cpu.arch.ptrBitWidth() == 64) | |
| 1099 | "/system/bin/linker64" | |
| 1100 | else | |
| 1101 | "/system/bin/linker"); | |
| 1103 | const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; | |
| 1104 | return print(buffer, "/system/bin/linker{}", .{suffix}); | |
| 1102 | 1105 | } |
| 1103 | 1106 | |
| 1104 | 1107 | if (self.isMusl()) { |
| 1105 | var result = try std.Buffer.init(allocator, "/lib/ld-musl-"); | |
| 1106 | defer result.deinit(); | |
| 1107 | ||
| 1108 | var is_arm = false; | |
| 1109 | switch (self.cpu.arch) { | |
| 1110 | .arm, .thumb => { | |
| 1111 | try result.append("arm"); | |
| 1112 | is_arm = true; | |
| 1113 | }, | |
| 1114 | .armeb, .thumbeb => { | |
| 1115 | try result.append("armeb"); | |
| 1116 | is_arm = true; | |
| 1117 | }, | |
| 1118 | else => |arch| try result.append(@tagName(arch)), | |
| 1119 | } | |
| 1120 | if (is_arm and self.getFloatAbi() == .hard) { | |
| 1121 | try result.append("hf"); | |
| 1122 | } | |
| 1123 | try result.append(".so.1"); | |
| 1124 | return result.toOwnedSlice(); | |
| 1108 | const is_arm = switch (self.cpu.arch) { | |
| 1109 | .arm, .armeb, .thumb, .thumbeb => true, | |
| 1110 | else => false, | |
| 1111 | }; | |
| 1112 | const arch_part = switch (self.cpu.arch) { | |
| 1113 | .arm, .thumb => "arm", | |
| 1114 | .armeb, .thumbeb => "armeb", | |
| 1115 | else => |arch| @tagName(arch), | |
| 1116 | }; | |
| 1117 | const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; | |
| 1118 | return print(buffer, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); | |
| 1125 | 1119 | } |
| 1126 | 1120 | |
| 1127 | 1121 | switch (self.os.tag) { |
| 1128 | .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"), | |
| 1129 | .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"), | |
| 1130 | .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"), | |
| 1122 | .freebsd => return copy(buffer, "/libexec/ld-elf.so.1"), | |
| 1123 | .netbsd => return copy(buffer, "/libexec/ld.elf_so"), | |
| 1124 | .dragonfly => return copy(buffer, "/libexec/ld-elf.so.2"), | |
| 1131 | 1125 | .linux => switch (self.cpu.arch) { |
| 1132 | 1126 | .i386, |
| 1133 | 1127 | .sparc, |
| 1134 | 1128 | .sparcel, |
| 1135 | => return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"), | |
| 1129 | => return copy(buffer, "/lib/ld-linux.so.2"), | |
| 1136 | 1130 | |
| 1137 | .aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"), | |
| 1138 | .aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"), | |
| 1139 | .aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"), | |
| 1131 | .aarch64 => return copy(buffer, "/lib/ld-linux-aarch64.so.1"), | |
| 1132 | .aarch64_be => return copy(buffer, "/lib/ld-linux-aarch64_be.so.1"), | |
| 1133 | .aarch64_32 => return copy(buffer, "/lib/ld-linux-aarch64_32.so.1"), | |
| 1140 | 1134 | |
| 1141 | 1135 | .arm, |
| 1142 | 1136 | .armeb, |
| 1143 | 1137 | .thumb, |
| 1144 | 1138 | .thumbeb, |
| 1145 | => return mem.dupeZ(a, u8, switch (self.getFloatAbi()) { | |
| 1139 | => return copy(buffer, switch (self.getFloatAbi()) { | |
| 1146 | 1140 | .hard => "/lib/ld-linux-armhf.so.3", |
| 1147 | 1141 | else => "/lib/ld-linux.so.3", |
| 1148 | 1142 | }), |
| ... | ... | @@ -1159,29 +1153,35 @@ pub const Target = struct { |
| 1159 | 1153 | }; |
| 1160 | 1154 | const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); |
| 1161 | 1155 | const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; |
| 1162 | return std.fmt.allocPrint0(a, "/lib{}/{}", .{ lib_suffix, loader }); | |
| 1156 | return print(buffer, "/lib{}/{}", .{ lib_suffix, loader }); | |
| 1163 | 1157 | }, |
| 1164 | 1158 | |
| 1165 | .powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"), | |
| 1166 | .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"), | |
| 1167 | .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"), | |
| 1168 | .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"), | |
| 1169 | .x86_64 => return mem.dupeZ(a, u8, switch (self.abi) { | |
| 1159 | .powerpc => return copy(buffer, "/lib/ld.so.1"), | |
| 1160 | .powerpc64, .powerpc64le => return copy(buffer, "/lib64/ld64.so.2"), | |
| 1161 | .s390x => return copy(buffer, "/lib64/ld64.so.1"), | |
| 1162 | .sparcv9 => return copy(buffer, "/lib64/ld-linux.so.2"), | |
| 1163 | .x86_64 => return copy(buffer, switch (self.abi) { | |
| 1170 | 1164 | .gnux32 => "/libx32/ld-linux-x32.so.2", |
| 1171 | 1165 | else => "/lib64/ld-linux-x86-64.so.2", |
| 1172 | 1166 | }), |
| 1173 | 1167 | |
| 1174 | .riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"), | |
| 1175 | .riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"), | |
| 1168 | .riscv32 => return copy(buffer, "/lib/ld-linux-riscv32-ilp32.so.1"), | |
| 1169 | .riscv64 => return copy(buffer, "/lib/ld-linux-riscv64-lp64.so.1"), | |
| 1176 | 1170 | |
| 1171 | // Architectures in this list have been verified as not having a standard | |
| 1172 | // dynamic linker path. | |
| 1177 | 1173 | .wasm32, |
| 1178 | 1174 | .wasm64, |
| 1179 | => return error.TargetHasNoDynamicLinker, | |
| 1175 | .bpfel, | |
| 1176 | .bpfeb, | |
| 1177 | .nvptx, | |
| 1178 | .nvptx64, | |
| 1179 | => return null, | |
| 1180 | 1180 | |
| 1181 | // TODO go over each item in this list and either move it to the above list, or | |
| 1182 | // implement the standard dynamic linker path code for it. | |
| 1181 | 1183 | .arc, |
| 1182 | 1184 | .avr, |
| 1183 | .bpfel, | |
| 1184 | .bpfeb, | |
| 1185 | 1185 | .hexagon, |
| 1186 | 1186 | .msp430, |
| 1187 | 1187 | .r600, |
| ... | ... | @@ -1189,8 +1189,6 @@ pub const Target = struct { |
| 1189 | 1189 | .tce, |
| 1190 | 1190 | .tcele, |
| 1191 | 1191 | .xcore, |
| 1192 | .nvptx, | |
| 1193 | .nvptx64, | |
| 1194 | 1192 | .le32, |
| 1195 | 1193 | .le64, |
| 1196 | 1194 | .amdil, |
| ... | ... | @@ -1204,9 +1202,25 @@ pub const Target = struct { |
| 1204 | 1202 | .lanai, |
| 1205 | 1203 | .renderscript32, |
| 1206 | 1204 | .renderscript64, |
| 1207 | => return error.UnknownDynamicLinkerPath, | |
| 1205 | => return null, | |
| 1208 | 1206 | }, |
| 1209 | 1207 | |
| 1208 | // Operating systems in this list have been verified as not having a standard | |
| 1209 | // dynamic linker path. | |
| 1210 | .freestanding, | |
| 1211 | .ios, | |
| 1212 | .tvos, | |
| 1213 | .watchos, | |
| 1214 | .macosx, | |
| 1215 | .uefi, | |
| 1216 | .windows, | |
| 1217 | .emscripten, | |
| 1218 | .other, | |
| 1219 | .wasi, | |
| 1220 | => return null, | |
| 1221 | ||
| 1222 | // TODO go over each item in this list and either move it to the above list, or | |
| 1223 | // implement the standard dynamic linker path code for it. | |
| 1210 | 1224 | .ananas, |
| 1211 | 1225 | .cloudabi, |
| 1212 | 1226 | .fuchsia, |
| ... | ... | @@ -1230,19 +1244,7 @@ pub const Target = struct { |
| 1230 | 1244 | .amdpal, |
| 1231 | 1245 | .hermit, |
| 1232 | 1246 | .hurd, |
| 1233 | => return error.UnknownDynamicLinkerPath, | |
| 1234 | ||
| 1235 | .freestanding, | |
| 1236 | .ios, | |
| 1237 | .tvos, | |
| 1238 | .watchos, | |
| 1239 | .macosx, | |
| 1240 | .uefi, | |
| 1241 | .windows, | |
| 1242 | .emscripten, | |
| 1243 | .other, | |
| 1244 | .wasi, | |
| 1245 | => return error.TargetHasNoDynamicLinker, | |
| 1247 | => return null, | |
| 1246 | 1248 | } |
| 1247 | 1249 | } |
| 1248 | 1250 | }; |
lib/std/zig/system.zig+80-35| ... | ... | @@ -167,7 +167,15 @@ pub const NativePaths = struct { |
| 167 | 167 | |
| 168 | 168 | pub const NativeTargetInfo = struct { |
| 169 | 169 | target: Target, |
| 170 | dynamic_linker: ?[:0]u8, | |
| 170 | ||
| 171 | /// Contains the memory used to store the dynamic linker path. This field should | |
| 172 | /// not be used directly. See `dynamicLinker` and `setDynamicLinker`. This field | |
| 173 | /// exists so that this API requires no allocator. | |
| 174 | dynamic_linker_buffer: [255]u8 = undefined, | |
| 175 | ||
| 176 | /// Used to construct the dynamic linker path. This field should not be used | |
| 177 | /// directly. See `dynamicLinker` and `setDynamicLinker`. | |
| 178 | dynamic_linker_max: ?u8 = null, | |
| 171 | 179 | |
| 172 | 180 | pub const DetectError = error{ |
| 173 | 181 | OutOfMemory, |
| ... | ... | @@ -181,6 +189,7 @@ pub const NativeTargetInfo = struct { |
| 181 | 189 | |
| 182 | 190 | /// Detects the native CPU model & features, operating system & version, and C ABI & dynamic linker. |
| 183 | 191 | /// On Linux, this is additionally responsible for detecting the native glibc version when applicable. |
| 192 | /// TODO Remove the allocator requirement from this. | |
| 184 | 193 | pub fn detect(allocator: *Allocator) DetectError!NativeTargetInfo { |
| 185 | 194 | const arch = Target.current.cpu.arch; |
| 186 | 195 | const os_tag = Target.current.os.tag; |
| ... | ... | @@ -188,8 +197,7 @@ pub const NativeTargetInfo = struct { |
| 188 | 197 | // TODO Detect native CPU model & features. Until that is implemented we hard code baseline. |
| 189 | 198 | const cpu = Target.Cpu.baseline(arch); |
| 190 | 199 | |
| 191 | // TODO Detect native operating system version. Until that is implemented we use the minimum version | |
| 192 | // of the default range. | |
| 200 | // TODO Detect native operating system version. Until that is implemented we use the default range. | |
| 193 | 201 | const os = Target.Os.defaultVersionRange(os_tag); |
| 194 | 202 | |
| 195 | 203 | return detectAbiAndDynamicLinker(allocator, cpu, os); |
| ... | ... | @@ -201,6 +209,21 @@ pub const NativeTargetInfo = struct { |
| 201 | 209 | self.* = undefined; |
| 202 | 210 | } |
| 203 | 211 | |
| 212 | /// The returned memory has the same lifetime as the `NativeTargetInfo`. | |
| 213 | pub fn dynamicLinker(self: *const NativeTargetInfo) ?[]const u8 { | |
| 214 | const m = self.dynamic_linker_max orelse return null; | |
| 215 | return self.dynamic_linker_buffer[0 .. m + 1]; | |
| 216 | } | |
| 217 | ||
| 218 | pub fn setDynamicLinker(self: *NativeTargetInfo, dl_or_null: ?[]const u8) void { | |
| 219 | if (dl_or_null) |dl| { | |
| 220 | mem.copy(u8, &self.dynamic_linker_buffer, dl); | |
| 221 | self.dynamic_linker_max = @intCast(u8, dl.len - 1); | |
| 222 | } else { | |
| 223 | self.dynamic_linker_max = null; | |
| 224 | } | |
| 225 | } | |
| 226 | ||
| 204 | 227 | /// First we attempt to use the executable's own binary. If it is dynamically |
| 205 | 228 | /// linked, then it should answer both the C ABI question and the dynamic linker question. |
| 206 | 229 | /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then |
| ... | ... | @@ -245,10 +268,11 @@ pub const NativeTargetInfo = struct { |
| 245 | 268 | .os = os, |
| 246 | 269 | .abi = abi, |
| 247 | 270 | }; |
| 248 | const standard_ld_path = target.getStandardDynamicLinkerPath(allocator) catch |err| switch (err) { | |
| 249 | error.OutOfMemory => return error.OutOfMemory, | |
| 250 | error.UnknownDynamicLinkerPath, error.TargetHasNoDynamicLinker => continue, | |
| 251 | }; | |
| 271 | var buf: [255]u8 = undefined; | |
| 272 | const standard_ld_path = if (target.standardDynamicLinkerPath(&buf)) |s| | |
| 273 | try mem.dupe(allocator, u8, s) | |
| 274 | else | |
| 275 | continue; | |
| 252 | 276 | errdefer allocator.free(standard_ld_path); |
| 253 | 277 | try ld_info_list.append(.{ |
| 254 | 278 | .ld_path = standard_ld_path, |
| ... | ... | @@ -294,28 +318,29 @@ pub const NativeTargetInfo = struct { |
| 294 | 318 | } |
| 295 | 319 | } |
| 296 | 320 | |
| 297 | return NativeTargetInfo{ | |
| 321 | var result: NativeTargetInfo = .{ | |
| 298 | 322 | .target = .{ |
| 299 | 323 | .cpu = cpu, |
| 300 | 324 | .os = os_adjusted, |
| 301 | 325 | .abi = found_ld_info.abi, |
| 302 | 326 | }, |
| 303 | .dynamic_linker = try mem.dupeZ(allocator, u8, found_ld_path), | |
| 304 | 327 | }; |
| 328 | result.setDynamicLinker(found_ld_path); | |
| 329 | return result; | |
| 305 | 330 | } |
| 306 | 331 | |
| 307 | 332 | // If Zig is statically linked, such as via distributed binary static builds, the above |
| 308 | 333 | // trick won't work. The next thing we fall back to is the same thing, but for /usr/bin/env. |
| 309 | 334 | // Since that path is hard-coded into the shebang line of many portable scripts, it's a |
| 310 | 335 | // reasonably reliable path to check for. |
| 311 | return abiAndDynamicLinkerFromUsrBinEnv(allocator, cpu, os) catch |err| switch (err) { | |
| 312 | error.OutOfMemory => return error.OutOfMemory, | |
| 313 | error.FileSystem => return error.FileSystem, | |
| 314 | error.SystemResources => return error.SystemResources, | |
| 315 | error.SymLinkLoop => return error.SymLinkLoop, | |
| 316 | error.ProcessFdQuotaExceeded => return error.ProcessFdQuotaExceeded, | |
| 317 | error.SystemFdQuotaExceeded => return error.SystemFdQuotaExceeded, | |
| 318 | error.DeviceBusy => return error.DeviceBusy, | |
| 336 | return abiAndDynamicLinkerFromUsrBinEnv(cpu, os) catch |err| switch (err) { | |
| 337 | error.FileSystem, | |
| 338 | error.SystemResources, | |
| 339 | error.SymLinkLoop, | |
| 340 | error.ProcessFdQuotaExceeded, | |
| 341 | error.SystemFdQuotaExceeded, | |
| 342 | error.DeviceBusy, | |
| 343 | => |e| return e, | |
| 319 | 344 | |
| 320 | 345 | error.UnableToReadElfFile, |
| 321 | 346 | error.ElfNotADynamicExecutable, |
| ... | ... | @@ -327,6 +352,8 @@ pub const NativeTargetInfo = struct { |
| 327 | 352 | error.InvalidElfMagic, |
| 328 | 353 | error.UsrBinEnvNotAvailable, |
| 329 | 354 | error.Unexpected, |
| 355 | error.UnexpectedEndOfFile, | |
| 356 | error.NameTooLong, | |
| 330 | 357 | // Finally, we fall back on the standard path. |
| 331 | 358 | => defaultAbiAndDynamicLinker(allocator, cpu, os), |
| 332 | 359 | }; |
| ... | ... | @@ -362,11 +389,7 @@ pub const NativeTargetInfo = struct { |
| 362 | 389 | }; |
| 363 | 390 | } |
| 364 | 391 | |
| 365 | fn abiAndDynamicLinkerFromUsrBinEnv( | |
| 366 | allocator: *Allocator, | |
| 367 | cpu: Target.Cpu, | |
| 368 | os: Target.Os, | |
| 369 | ) !NativeTargetInfo { | |
| 392 | fn abiAndDynamicLinkerFromUsrBinEnv(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { | |
| 370 | 393 | const env_file = std.fs.openFileAbsoluteC("/usr/bin/env", .{}) catch |err| switch (err) { |
| 371 | 394 | error.NoSpaceLeft => unreachable, |
| 372 | 395 | error.NameTooLong => unreachable, |
| ... | ... | @@ -409,6 +432,14 @@ pub const NativeTargetInfo = struct { |
| 409 | 432 | const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum); |
| 410 | 433 | const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); |
| 411 | 434 | |
| 435 | var result: NativeTargetInfo = .{ | |
| 436 | .target = .{ | |
| 437 | .cpu = cpu, | |
| 438 | .os = os, | |
| 439 | .abi = Target.Abi.default(cpu.arch, os), | |
| 440 | }, | |
| 441 | }; | |
| 442 | ||
| 412 | 443 | const ph_total_size = std.math.mul(u32, phentsize, phnum) catch |err| switch (err) { |
| 413 | 444 | error.Overflow => return error.InvalidElfProgramHeaders, |
| 414 | 445 | }; |
| ... | ... | @@ -430,7 +461,22 @@ pub const NativeTargetInfo = struct { |
| 430 | 461 | const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type); |
| 431 | 462 | switch (p_type) { |
| 432 | 463 | elf.PT_INTERP => { |
| 433 | std.debug.warn("found PT_INTERP\n", .{}); | |
| 464 | const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); | |
| 465 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); | |
| 466 | var interp_buf: [255]u8 = undefined; | |
| 467 | if (p_filesz > interp_buf.len) return error.NameTooLong; | |
| 468 | var read_offset: usize = 0; | |
| 469 | while (true) { | |
| 470 | const len = try wrapRead(env_file.pread( | |
| 471 | interp_buf[read_offset .. p_filesz - read_offset], | |
| 472 | p_offset + read_offset, | |
| 473 | )); | |
| 474 | if (len == 0) return error.UnexpectedEndOfFile; | |
| 475 | read_offset += len; | |
| 476 | if (read_offset == p_filesz) break; | |
| 477 | } | |
| 478 | // PT_INTERP includes a null byte in p_filesz. | |
| 479 | result.setDynamicLinker(interp_buf[0 .. p_filesz - 1]); | |
| 434 | 480 | }, |
| 435 | 481 | elf.PT_DYNAMIC => { |
| 436 | 482 | std.debug.warn("found PT_DYNAMIC\n", .{}); |
| ... | ... | @@ -440,7 +486,7 @@ pub const NativeTargetInfo = struct { |
| 440 | 486 | } |
| 441 | 487 | } |
| 442 | 488 | |
| 443 | return error.OutOfMemory; // TODO | |
| 489 | return result; | |
| 444 | 490 | } |
| 445 | 491 | |
| 446 | 492 | fn wrapRead(res: std.os.ReadError!usize) !usize { |
| ... | ... | @@ -457,18 +503,17 @@ pub const NativeTargetInfo = struct { |
| 457 | 503 | } |
| 458 | 504 | |
| 459 | 505 | fn defaultAbiAndDynamicLinker(allocator: *Allocator, cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { |
| 460 | const target: Target = .{ | |
| 461 | .cpu = cpu, | |
| 462 | .os = os, | |
| 463 | .abi = Target.Abi.default(cpu.arch, os), | |
| 464 | }; | |
| 465 | return @as(NativeTargetInfo, .{ | |
| 466 | .target = target, | |
| 467 | .dynamic_linker = target.getStandardDynamicLinkerPath(allocator) catch |err| switch (err) { | |
| 468 | error.OutOfMemory => return error.OutOfMemory, | |
| 469 | error.UnknownDynamicLinkerPath, error.TargetHasNoDynamicLinker => null, | |
| 506 | var result: NativeTargetInfo = .{ | |
| 507 | .target = .{ | |
| 508 | .cpu = cpu, | |
| 509 | .os = os, | |
| 510 | .abi = Target.Abi.default(cpu.arch, os), | |
| 470 | 511 | }, |
| 471 | }); | |
| 512 | }; | |
| 513 | if (result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer)) |s| { | |
| 514 | result.dynamic_linker_max = @intCast(u8, s.len - 1); | |
| 515 | } | |
| 516 | return result; | |
| 472 | 517 | } |
| 473 | 518 | }; |
| 474 | 519 |
src-self-hosted/stage2.zig+7-9| ... | ... | @@ -1157,9 +1157,9 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) |
| 1157 | 1157 | if (cross_target.os_tag == null) { |
| 1158 | 1158 | adjusted_target.os = detected_info.target.os; |
| 1159 | 1159 | |
| 1160 | if (detected_info.dynamic_linker) |dl| { | |
| 1160 | if (detected_info.dynamicLinker()) |dl| { | |
| 1161 | 1161 | have_native_dl = true; |
| 1162 | dynamic_linker_ptr.* = dl.ptr; | |
| 1162 | dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); | |
| 1163 | 1163 | } |
| 1164 | 1164 | if (cross_target.abi == null) { |
| 1165 | 1165 | adjusted_target.abi = detected_info.target.abi; |
| ... | ... | @@ -1169,13 +1169,11 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) |
| 1169 | 1169 | } |
| 1170 | 1170 | } |
| 1171 | 1171 | if (!have_native_dl) { |
| 1172 | dynamic_linker_ptr.* = adjusted_target.getStandardDynamicLinkerPath( | |
| 1173 | std.heap.c_allocator, | |
| 1174 | ) catch |err| switch (err) { | |
| 1175 | error.TargetHasNoDynamicLinker => null, | |
| 1176 | error.UnknownDynamicLinkerPath => null, | |
| 1177 | else => |e| return e, | |
| 1178 | }; | |
| 1172 | var buf: [255]u8 = undefined; | |
| 1173 | dynamic_linker_ptr.* = if (adjusted_target.standardDynamicLinkerPath(&buf)) |s| | |
| 1174 | try mem.dupeZ(std.heap.c_allocator, u8, s) | |
| 1175 | else | |
| 1176 | null; | |
| 1179 | 1177 | } |
| 1180 | 1178 | return adjusted_target; |
| 1181 | 1179 | } |