authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-27 17:20:40-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 14:51:55-05:00
logfd006c1c74a43827a6f1c32e289ba57cafa874be
tree0568223856214389c035304f0352fcc914d83414
parent60f2f3457dd73772e7cd60bf5d90358079361d11
signaturelock-open Commit is signed but in an unrecognized format.

std.zig.system.NativeTargetInfo.detect: almost no Allocator


4 files changed, 42 insertions(+), 40 deletions(-)

lib/std/process.zig+4
......@@ -609,6 +609,10 @@ pub fn getBaseAddress() usize {
609609}
610610
611611/// Caller owns the result value and each inner slice.
612/// TODO Remove the `Allocator` requirement from this API, which will remove the `Allocator`
613/// requirement from `std.zig.system.NativeTargetInfo.detect`. Most likely this will require
614/// introducing a new, lower-level function which takes a callback function, and then this
615/// function which takes an allocator can exist on top of it.
612616pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 {
613617 switch (builtin.link_mode) {
614618 .Static => return &[_][:0]u8{},
lib/std/target.zig+6-6
......@@ -1084,16 +1084,16 @@ pub const Target = struct {
10841084 }
10851085 }
10861086
1087 /// The result will be a slice of `buffer`, pointing at position 0.
1087 /// The result will be a byte index *pointing at the final byte*. In other words, length minus one.
10881088 /// 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 {
1089 pub fn standardDynamicLinkerPath(self: Target, buffer: *[255]u8) ?u8 {
10901090 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;
1091 fn print(b: *[255]u8, comptime fmt: []const u8, args: var) u8 {
1092 return @intCast(u8, (std.fmt.bufPrint(b, fmt, args) catch unreachable).len - 1);
10931093 }
1094 fn copy(b: *[255]u8, s: []const u8) []u8 {
1094 fn copy(b: *[255]u8, s: []const u8) u8 {
10951095 mem.copy(u8, b, s);
1096 return b[0..s.len];
1096 return @intCast(u8, s.len - 1);
10971097 }
10981098 };
10991099 const print = S.print;
lib/std/zig/system.zig+30-32
......@@ -189,7 +189,9 @@ pub const NativeTargetInfo = struct {
189189
190190 /// Detects the native CPU model & features, operating system & version, and C ABI & dynamic linker.
191191 /// On Linux, this is additionally responsible for detecting the native glibc version when applicable.
192 /// TODO Remove the allocator requirement from this.
192 /// Any resources this function allocates are released before returning, and so there is no
193 /// deinitialization method.
194 /// TODO Remove the Allocator requirement from this function.
193195 pub fn detect(allocator: *Allocator) DetectError!NativeTargetInfo {
194196 const arch = Target.current.cpu.arch;
195197 const os_tag = Target.current.os.tag;
......@@ -203,15 +205,9 @@ pub const NativeTargetInfo = struct {
203205 return detectAbiAndDynamicLinker(allocator, cpu, os);
204206 }
205207
206 /// Must be the same `Allocator` passed to `detect`.
207 pub fn deinit(self: *NativeTargetInfo, allocator: *Allocator) void {
208 if (self.dynamic_linker) |dl| allocator.free(dl);
209 self.* = undefined;
210 }
211
212208 /// The returned memory has the same lifetime as the `NativeTargetInfo`.
213209 pub fn dynamicLinker(self: *const NativeTargetInfo) ?[]const u8 {
214 const m = self.dynamic_linker_max orelse return null;
210 const m: usize = self.dynamic_linker_max orelse return null;
215211 return self.dynamic_linker_buffer[0 .. m + 1];
216212 }
217213
......@@ -228,13 +224,14 @@ pub const NativeTargetInfo = struct {
228224 /// linked, then it should answer both the C ABI question and the dynamic linker question.
229225 /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then
230226 /// we fall back to the defaults.
227 /// TODO Remove the Allocator requirement from this function.
231228 fn detectAbiAndDynamicLinker(
232229 allocator: *Allocator,
233230 cpu: Target.Cpu,
234231 os: Target.Os,
235232 ) DetectError!NativeTargetInfo {
236233 if (!comptime Target.current.hasDynamicLinker()) {
237 return defaultAbiAndDynamicLinker(allocator, cpu, os);
234 return defaultAbiAndDynamicLinker(cpu, os);
238235 }
239236 // The current target's ABI cannot be relied on for this. For example, we may build the zig
240237 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
......@@ -242,15 +239,15 @@ pub const NativeTargetInfo = struct {
242239 // and supported by Zig. But that means that we must detect the system ABI here rather than
243240 // relying on `Target.current`.
244241 const LdInfo = struct {
245 ld_path: []u8,
242 ld_path_buffer: [255]u8,
243 ld_path_max: u8,
246244 abi: Target.Abi,
247 };
248 var ld_info_list = std.ArrayList(LdInfo).init(allocator);
249 defer {
250 for (ld_info_list.toSlice()) |ld_info| allocator.free(ld_info.ld_path);
251 ld_info_list.deinit();
252 }
253245
246 pub fn ldPath(self: *const @This()) []const u8 {
247 const m: usize = self.ld_path_max;
248 return self.ld_path_buffer[0 .. m + 1];
249 }
250 };
254251 const all_abis = comptime blk: {
255252 assert(@enumToInt(Target.Abi.none) == 0);
256253 const fields = std.meta.fields(Target.Abi)[1..];
......@@ -260,6 +257,9 @@ pub const NativeTargetInfo = struct {
260257 }
261258 break :blk array;
262259 };
260 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
261 var ld_info_list_len: usize = 0;
262
263263 for (all_abis) |abi| {
264264 // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
265265 // skip adding it to `ld_info_list`.
......@@ -268,17 +268,17 @@ pub const NativeTargetInfo = struct {
268268 .os = os,
269269 .abi = abi,
270270 };
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;
276 errdefer allocator.free(standard_ld_path);
277 try ld_info_list.append(.{
278 .ld_path = standard_ld_path,
271 const ld_info = &ld_info_list_buffer[ld_info_list_len];
272 ld_info_list_len += 1;
273
274 ld_info.* = .{
275 .ld_path_buffer = undefined,
276 .ld_path_max = undefined,
279277 .abi = abi,
280 });
278 };
279 ld_info.ld_path_max = target.standardDynamicLinkerPath(&ld_info.ld_path_buffer) orelse continue;
281280 }
281 const ld_info_list = ld_info_list_buffer[0..ld_info_list_len];
282282
283283 // Best case scenario: the executable is dynamically linked, and we can iterate
284284 // over our own shared objects and find a dynamic linker.
......@@ -292,8 +292,8 @@ pub const NativeTargetInfo = struct {
292292 // Look for dynamic linker.
293293 // This is O(N^M) but typical case here is N=2 and M=10.
294294 find_ld: for (lib_paths) |lib_path| {
295 for (ld_info_list.toSlice()) |ld_info| {
296 const standard_ld_basename = fs.path.basename(ld_info.ld_path);
295 for (ld_info_list) |ld_info| {
296 const standard_ld_basename = fs.path.basename(ld_info.ldPath());
297297 if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) {
298298 found_ld_info = ld_info;
299299 found_ld_path = lib_path;
......@@ -355,7 +355,7 @@ pub const NativeTargetInfo = struct {
355355 error.UnexpectedEndOfFile,
356356 error.NameTooLong,
357357 // Finally, we fall back on the standard path.
358 => defaultAbiAndDynamicLinker(allocator, cpu, os),
358 => defaultAbiAndDynamicLinker(cpu, os),
359359 };
360360 }
361361
......@@ -502,7 +502,7 @@ pub const NativeTargetInfo = struct {
502502 };
503503 }
504504
505 fn defaultAbiAndDynamicLinker(allocator: *Allocator, cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo {
505 fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo {
506506 var result: NativeTargetInfo = .{
507507 .target = .{
508508 .cpu = cpu,
......@@ -510,9 +510,7 @@ pub const NativeTargetInfo = struct {
510510 .abi = Target.Abi.default(cpu.arch, os),
511511 },
512512 };
513 if (result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer)) |s| {
514 result.dynamic_linker_max = @intCast(u8, s.len - 1);
515 }
513 result.dynamic_linker_max = result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer);
516514 return result;
517515 }
518516};
src-self-hosted/stage2.zig+2-2
......@@ -1170,8 +1170,8 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8)
11701170 }
11711171 if (!have_native_dl) {
11721172 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)
1173 dynamic_linker_ptr.* = if (adjusted_target.standardDynamicLinkerPath(&buf)) |m|
1174 try mem.dupeZ(std.heap.c_allocator, u8, buf[0 .. @as(usize, m) + 1])
11751175 else
11761176 null;
11771177 }