authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-14 21:44:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-14 21:44:44-07:00
log5da013e39c8687afa78ea64ed6d0e8d39f28e4f4
tree52ad3ec7d9cf7fdcd87cd2cbb921c28e59a1054f
parent20328e976fe3aea206fbd7a82090c1b61298398a

remove tools/update_glibc.zig

It has been replaced by https://github.com/ziglang/glibc-abi-tool/ and should have been removed in 1442aa7dc039fd77c483862e37b099fe6d43f369.

1 files changed, 0 insertions(+), 343 deletions(-)

tools/update_glibc.zig deleted-343
......@@ -1,343 +0,0 @@
1const std = @import("std");
2const fs = std.fs;
3const fmt = std.fmt;
4const assert = std.debug.assert;
5
6// Example abilist path:
7// ./sysdeps/unix/sysv/linux/aarch64/libc.abilist
8const AbiList = struct {
9 targets: []const ZigTarget,
10 path: []const u8,
11};
12const ZigTarget = struct {
13 arch: std.Target.Cpu.Arch,
14 abi: std.Target.Abi,
15};
16
17const lib_names = [_][]const u8{
18 "c",
19 "dl",
20 "m",
21 "pthread",
22 "rt",
23 "ld",
24 "util",
25};
26
27// fpu/nofpu are hardcoded elsewhere, based on .gnueabi/.gnueabihf with an exception for .arm
28// n64/n32 are hardcoded elsewhere, based on .gnuabi64/.gnuabin32
29const abi_lists = [_]AbiList{
30 AbiList{
31 .targets = &[_]ZigTarget{
32 ZigTarget{ .arch = .aarch64, .abi = .gnu },
33 ZigTarget{ .arch = .aarch64_be, .abi = .gnu },
34 },
35 .path = "aarch64",
36 },
37 AbiList{
38 .targets = &[_]ZigTarget{ZigTarget{ .arch = .s390x, .abi = .gnu }},
39 .path = "s390/s390-64",
40 },
41 AbiList{
42 .targets = &[_]ZigTarget{
43 ZigTarget{ .arch = .arm, .abi = .gnueabi },
44 ZigTarget{ .arch = .armeb, .abi = .gnueabi },
45 ZigTarget{ .arch = .arm, .abi = .gnueabihf },
46 ZigTarget{ .arch = .armeb, .abi = .gnueabihf },
47 },
48 .path = "arm",
49 },
50 AbiList{
51 .targets = &[_]ZigTarget{
52 ZigTarget{ .arch = .sparc, .abi = .gnu },
53 ZigTarget{ .arch = .sparcel, .abi = .gnu },
54 },
55 .path = "sparc/sparc32",
56 },
57 AbiList{
58 .targets = &[_]ZigTarget{ZigTarget{ .arch = .sparcv9, .abi = .gnu }},
59 .path = "sparc/sparc64",
60 },
61 AbiList{
62 .targets = &[_]ZigTarget{
63 ZigTarget{ .arch = .mips64el, .abi = .gnuabi64 },
64 ZigTarget{ .arch = .mips64, .abi = .gnuabi64 },
65 },
66 .path = "mips/mips64",
67 },
68 AbiList{
69 .targets = &[_]ZigTarget{
70 ZigTarget{ .arch = .mips64el, .abi = .gnuabin32 },
71 ZigTarget{ .arch = .mips64, .abi = .gnuabin32 },
72 },
73 .path = "mips/mips64",
74 },
75 AbiList{
76 .targets = &[_]ZigTarget{
77 ZigTarget{ .arch = .mipsel, .abi = .gnueabihf },
78 ZigTarget{ .arch = .mips, .abi = .gnueabihf },
79 },
80 .path = "mips/mips32",
81 },
82 AbiList{
83 .targets = &[_]ZigTarget{
84 ZigTarget{ .arch = .mipsel, .abi = .gnueabi },
85 ZigTarget{ .arch = .mips, .abi = .gnueabi },
86 },
87 .path = "mips/mips32",
88 },
89 AbiList{
90 .targets = &[_]ZigTarget{ZigTarget{ .arch = .x86_64, .abi = .gnu }},
91 .path = "x86_64/64",
92 },
93 AbiList{
94 .targets = &[_]ZigTarget{ZigTarget{ .arch = .x86_64, .abi = .gnux32 }},
95 .path = "x86_64/x32",
96 },
97 AbiList{
98 .targets = &[_]ZigTarget{ZigTarget{ .arch = .i386, .abi = .gnu }},
99 .path = "i386",
100 },
101 AbiList{
102 .targets = &[_]ZigTarget{ZigTarget{ .arch = .powerpc64le, .abi = .gnu }},
103 .path = "powerpc/powerpc64/le",
104 },
105 AbiList{
106 .targets = &[_]ZigTarget{ZigTarget{ .arch = .powerpc64, .abi = .gnu }},
107 .path = "powerpc/powerpc64/be",
108 },
109 AbiList{
110 .targets = &[_]ZigTarget{
111 ZigTarget{ .arch = .powerpc, .abi = .gnueabi },
112 ZigTarget{ .arch = .powerpc, .abi = .gnueabihf },
113 },
114 .path = "powerpc/powerpc32",
115 },
116};
117
118const FunctionSet = struct {
119 list: std.ArrayList(VersionedFn),
120 fn_vers_list: FnVersionList,
121};
122const FnVersionList = std.StringHashMap(std.ArrayList(usize));
123
124const VersionedFn = struct {
125 ver: []const u8, // example: "GLIBC_2.15"
126 name: []const u8, // example: "puts"
127};
128const Function = struct {
129 name: []const u8, // example: "puts"
130 lib: []const u8, // example: "c"
131 index: usize,
132};
133
134pub fn main() !void {
135 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
136 const allocator = arena.allocator();
137 const args = try std.process.argsAlloc(allocator);
138 const in_glibc_dir = args[1]; // path to the unzipped tarball of glibc, e.g. ~/downloads/glibc-2.25
139 const zig_src_dir = args[2]; // path to the source checkout of zig, lib dir, e.g. ~/zig-src/lib
140
141 const prefix = try fs.path.join(allocator, &[_][]const u8{ in_glibc_dir, "sysdeps", "unix", "sysv", "linux" });
142 const glibc_out_dir = try fs.path.join(allocator, &[_][]const u8{ zig_src_dir, "libc", "glibc" });
143
144 var global_fn_set = std.StringHashMap(Function).init(allocator);
145 var global_ver_set = std.StringHashMap(usize).init(allocator);
146 var target_functions = std.AutoHashMap(usize, FunctionSet).init(allocator);
147
148 for (abi_lists) |*abi_list| {
149 const target_funcs_gop = try target_functions.getOrPut(@ptrToInt(abi_list));
150 if (!target_funcs_gop.found_existing) {
151 target_funcs_gop.value_ptr.* = FunctionSet{
152 .list = std.ArrayList(VersionedFn).init(allocator),
153 .fn_vers_list = FnVersionList.init(allocator),
154 };
155 }
156 const fn_set = &target_funcs_gop.value_ptr.list;
157
158 for (lib_names) |lib_name| {
159 const lib_prefix = if (std.mem.eql(u8, lib_name, "ld")) "" else "lib";
160 const basename = try fmt.allocPrint(allocator, "{s}{s}.abilist", .{ lib_prefix, lib_name });
161 const abi_list_filename = blk: {
162 const is_c = std.mem.eql(u8, lib_name, "c");
163 const is_m = std.mem.eql(u8, lib_name, "m");
164 const is_ld = std.mem.eql(u8, lib_name, "ld");
165 if (abi_list.targets[0].abi == .gnuabi64 and (is_c or is_ld)) {
166 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "n64", basename });
167 } else if (abi_list.targets[0].abi == .gnuabin32 and (is_c or is_ld)) {
168 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "n32", basename });
169 } else if (abi_list.targets[0].arch != .arm and
170 abi_list.targets[0].abi == .gnueabihf and
171 (is_c or (is_m and abi_list.targets[0].arch == .powerpc)))
172 {
173 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "fpu", basename });
174 } else if (abi_list.targets[0].arch != .arm and
175 abi_list.targets[0].abi == .gnueabi and
176 (is_c or (is_m and abi_list.targets[0].arch == .powerpc)))
177 {
178 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "nofpu", basename });
179 } else if (abi_list.targets[0].arch == .arm) {
180 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "le", basename });
181 } else if (abi_list.targets[0].arch == .armeb) {
182 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, "be", basename });
183 }
184 break :blk try fs.path.join(allocator, &[_][]const u8{ prefix, abi_list.path, basename });
185 };
186 const max_bytes = 10 * 1024 * 1024;
187 const contents = std.fs.cwd().readFileAlloc(allocator, abi_list_filename, max_bytes) catch |err| {
188 std.debug.print("unable to open {s}: {}\n", .{ abi_list_filename, err });
189 std.process.exit(1);
190 };
191 var lines_it = std.mem.tokenize(u8, contents, "\n");
192 while (lines_it.next()) |line| {
193 var tok_it = std.mem.tokenize(u8, line, " ");
194 const ver = tok_it.next().?;
195 const name = tok_it.next().?;
196 const category = tok_it.next().?;
197 if (!std.mem.eql(u8, category, "F") and
198 !std.mem.eql(u8, category, "D"))
199 {
200 continue;
201 }
202 if (std.mem.startsWith(u8, ver, "GCC_")) continue;
203 try global_ver_set.put(ver, undefined);
204 const gop = try global_fn_set.getOrPut(name);
205 if (gop.found_existing) {
206 if (!std.mem.eql(u8, gop.value_ptr.lib, "c")) {
207 gop.value_ptr.lib = lib_name;
208 }
209 } else {
210 gop.value_ptr.* = Function{
211 .name = name,
212 .lib = lib_name,
213 .index = undefined,
214 };
215 }
216 try fn_set.append(VersionedFn{
217 .ver = ver,
218 .name = name,
219 });
220 }
221 }
222 }
223
224 const global_fn_list = blk: {
225 var list = std.ArrayList([]const u8).init(allocator);
226 var it = global_fn_set.keyIterator();
227 while (it.next()) |key| try list.append(key.*);
228 std.sort.sort([]const u8, list.items, {}, strCmpLessThan);
229 break :blk list.items;
230 };
231 const global_ver_list = blk: {
232 var list = std.ArrayList([]const u8).init(allocator);
233 var it = global_ver_set.keyIterator();
234 while (it.next()) |key| try list.append(key.*);
235 std.sort.sort([]const u8, list.items, {}, versionLessThan);
236 break :blk list.items;
237 };
238 {
239 const vers_txt_path = try fs.path.join(allocator, &[_][]const u8{ glibc_out_dir, "vers.txt" });
240 const vers_txt_file = try fs.cwd().createFile(vers_txt_path, .{});
241 defer vers_txt_file.close();
242 var buffered = std.io.bufferedWriter(vers_txt_file.writer());
243 const vers_txt = buffered.writer();
244 for (global_ver_list) |name, i| {
245 global_ver_set.put(name, i) catch unreachable;
246 try vers_txt.print("{s}\n", .{name});
247 }
248 try buffered.flush();
249 }
250 {
251 const fns_txt_path = try fs.path.join(allocator, &[_][]const u8{ glibc_out_dir, "fns.txt" });
252 const fns_txt_file = try fs.cwd().createFile(fns_txt_path, .{});
253 defer fns_txt_file.close();
254 var buffered = std.io.bufferedWriter(fns_txt_file.writer());
255 const fns_txt = buffered.writer();
256 for (global_fn_list) |name, i| {
257 const value = global_fn_set.getPtr(name).?;
258 value.index = i;
259 try fns_txt.print("{s} {s}\n", .{ name, value.lib });
260 }
261 try buffered.flush();
262 }
263
264 // Now the mapping of version and function to integer index is complete.
265 // Here we create a mapping of function name to list of versions.
266 for (abi_lists) |*abi_list| {
267 const value = target_functions.getPtr(@ptrToInt(abi_list)).?;
268 const fn_vers_list = &value.fn_vers_list;
269 for (value.list.items) |*ver_fn| {
270 const gop = try fn_vers_list.getOrPut(ver_fn.name);
271 if (!gop.found_existing) {
272 gop.value_ptr.* = std.ArrayList(usize).init(allocator);
273 }
274 const ver_index = global_ver_set.get(ver_fn.ver).?;
275 if (std.mem.indexOfScalar(usize, gop.value_ptr.items, ver_index) == null) {
276 try gop.value_ptr.append(ver_index);
277 }
278 }
279 }
280
281 {
282 const abilist_txt_path = try fs.path.join(allocator, &[_][]const u8{ glibc_out_dir, "abi.txt" });
283 const abilist_txt_file = try fs.cwd().createFile(abilist_txt_path, .{});
284 defer abilist_txt_file.close();
285 var buffered = std.io.bufferedWriter(abilist_txt_file.writer());
286 const abilist_txt = buffered.writer();
287
288 // first iterate over the abi lists
289 for (abi_lists) |*abi_list| {
290 const fn_vers_list = &target_functions.getPtr(@ptrToInt(abi_list)).?.fn_vers_list;
291 for (abi_list.targets) |target, it_i| {
292 if (it_i != 0) try abilist_txt.writeByte(' ');
293 try abilist_txt.print("{s}-linux-{s}", .{ @tagName(target.arch), @tagName(target.abi) });
294 }
295 try abilist_txt.writeByte('\n');
296 // next, each line implicitly corresponds to a function
297 for (global_fn_list) |name| {
298 const value = fn_vers_list.getPtr(name) orelse {
299 try abilist_txt.writeByte('\n');
300 continue;
301 };
302 for (value.items) |ver_index, it_i| {
303 if (it_i != 0) try abilist_txt.writeByte(' ');
304 try abilist_txt.print("{d}", .{ver_index});
305 }
306 try abilist_txt.writeByte('\n');
307 }
308 }
309
310 try buffered.flush();
311 }
312}
313
314pub fn strCmpLessThan(context: void, a: []const u8, b: []const u8) bool {
315 _ = context;
316 return std.mem.order(u8, a, b) == .lt;
317}
318
319pub fn versionLessThan(context: void, a: []const u8, b: []const u8) bool {
320 _ = context;
321 const sep_chars = "GLIBC_.";
322 var a_tokens = std.mem.tokenize(u8, a, sep_chars);
323 var b_tokens = std.mem.tokenize(u8, b, sep_chars);
324
325 while (true) {
326 const a_next = a_tokens.next();
327 const b_next = b_tokens.next();
328 if (a_next == null and b_next == null) {
329 return false; // equal means not less than
330 } else if (a_next == null) {
331 return true;
332 } else if (b_next == null) {
333 return false;
334 }
335 const a_int = fmt.parseInt(u64, a_next.?, 10) catch unreachable;
336 const b_int = fmt.parseInt(u64, b_next.?, 10) catch unreachable;
337 if (a_int < b_int) {
338 return true;
339 } else if (a_int > b_int) {
340 return false;
341 }
342 }
343}