authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-23 02:37:46+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-23 03:10:58+01:00
logfc8a4c445d6f01ad0e0dab21129fa1594c55aae8
tree157e075d2b741a5eb45d4a1c5d3c169608fadc36
parentcc73d7ad749df8d53da442faa2e7af5d69357b33
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

gen_stubs: Require less manual intervention and produce better output.

The tool will now skip over undefined symbols. These can only occur as a result of building musl without compiler-rt, i.e. -rtlib=none. Thanks to this, it's no longer necessary to patch Zig's compiler-rt, nor is it necessary to maintain a symbol blacklist. See the updated instructions here: https://github.com/ziglang/zig/wiki/Updating-libc#updating-the-libcs-file Additionally, the tool now produces slightly more compact output by recognizing symbols that are defined for a single arch, for a family of arches, or only for arches using 32-bit or 64-bit time as their primary ABI. Finally, the tool now supports all architectures that we can emit code for, with the single exception of x86_64-linux-muslx32. (x32 currently fails with a ton of relocation errors, leading me to believe that it might be an LLVM or LLD bug.)

1 files changed, 236 insertions(+), 676 deletions(-)

tools/gen_stubs.zig+236-676
...@@ -2,23 +2,51 @@...@@ -2,23 +2,51 @@
2//! ./gen_stubs /path/to/musl/build-all >libc.S2//! ./gen_stubs /path/to/musl/build-all >libc.S
3//!3//!
4//! The directory 'build-all' is expected to contain these subdirectories:4//! The directory 'build-all' is expected to contain these subdirectories:
5//! arm x86 mips mips64 powerpc powerpc64 riscv32 riscv64 x86_64 loongarch645//!
6//! * aarch64
7//! * arm
8//! * i386
9//! * loongarch64
10//! * mips
11//! * mips64
12//! * mipsn32
13//! * powerpc
14//! * powerpc64
15//! * riscv32
16//! * riscv64
17//! * s390x
18//! * x32 (currently broken)
19//! * x86_64
6//!20//!
7//! ...each with 'lib/libc.so' inside of them.21//! ...each with 'lib/libc.so' inside of them.
8//!22//!
9//! When building the resulting libc.S file, these defines are required:23//! When building the resulting libc.S file, these defines are required:
10//! * `-DPTR64`: when the architecture is 64-bit24//! * `-DTIME32`: When the target's primary time ABI is 32-bit
25//! * `-DPTR64`: When the target has 64-bit pointers
11//! * One of the following, corresponding to the CPU architecture:26//! * One of the following, corresponding to the CPU architecture:
12//! - `-DARCH_riscv32`27//! - `-DARCH_aarch64`
13//! - `-DARCH_riscv64`28//! - `-DARCH_arm`
29//! - `-DARCH_i386`
30//! - `-DARCH_loongarch64`
14//! - `-DARCH_mips`31//! - `-DARCH_mips`
15//! - `-DARCH_mips64`32//! - `-DARCH_mips64`
16//! - `-DARCH_i386`33//! - `-DARCH_mipsn32`
17//! - `-DARCH_x86_64`
18//! - `-DARCH_powerpc`34//! - `-DARCH_powerpc`
19//! - `-DARCH_powerpc64`35//! - `-DARCH_powerpc64`
20//! - `-DARCH_aarch64`36//! - `-DARCH_riscv32`
21//! - `-DARCH_loongarch64`37//! - `-DARCH_riscv64`
38//! - `-DARCH_s390x`
39//! - `-DARCH_x32`
40//! - `-DARCH_x86_64`
41//! * One of the following, corresponding to the CPU architecture family:
42//! - `-DFAMILY_aarch64`
43//! - `-DFAMILY_arm`
44//! - `-DFAMILY_loongarch`
45//! - `-DFAMILY_mips`
46//! - `-DFAMILY_powerpc`
47//! - `-DFAMILY_riscv`
48//! - `-DFAMILY_s390x`
49//! - `-DFAMILY_x86`
2250
23// TODO: pick the best index to put them into instead of at the end51// TODO: pick the best index to put them into instead of at the end
24// - e.g. find a common previous symbol and put it after that one52// - e.g. find a common previous symbol and put it after that one
...@@ -29,24 +57,85 @@ const builtin = std.builtin;...@@ -29,24 +57,85 @@ const builtin = std.builtin;
29const mem = std.mem;57const mem = std.mem;
30const log = std.log;58const log = std.log;
31const elf = std.elf;59const elf = std.elf;
32const native_endian = @import("builtin").target.cpu.arch.endian();60const native_endian = @import("builtin").cpu.arch.endian();
3361
34const inputs = .{62const Arch = enum {
35 .riscv32,63 aarch64,
36 .riscv64,64 arm,
37 .loongarch64,65 i386,
38 .mips,66 loongarch64,
39 .mips64,67 mips,
40 .x86,68 mips64,
41 .x86_64,69 mipsn32,
42 .powerpc,70 powerpc,
43 .powerpc64,71 powerpc64,
44 .aarch64,72 riscv32,
73 riscv64,
74 s390x,
75 x86_64,
76
77 pub fn ptrSize(arch: Arch) u16 {
78 return switch (arch) {
79 .arm,
80 .i386,
81 .mips,
82 .mipsn32,
83 .powerpc,
84 .riscv32,
85 => 4,
86 .aarch64,
87 .loongarch64,
88 .mips64,
89 .powerpc64,
90 .riscv64,
91 .s390x,
92 .x86_64,
93 => 8,
94 };
95 }
96
97 pub fn isTime32(arch: Arch) bool {
98 return switch (arch) {
99 // This list will never grow; newer 32-bit ports will be time64 (e.g. riscv32).
100 .arm,
101 .i386,
102 .mips,
103 .mipsn32,
104 .powerpc,
105 => true,
106 else => false,
107 };
108 }
109
110 pub fn family(arch: Arch) Family {
111 return switch (arch) {
112 .aarch64 => .aarch64,
113 .arm => .arm,
114 .i386, .x86_64 => .x86,
115 .loongarch64 => .loongarch,
116 .mips, .mips64, .mipsn32 => .mips,
117 .powerpc, .powerpc64 => .powerpc,
118 .riscv32, .riscv64 => .riscv,
119 .s390x => .s390x,
120 };
121 }
122};
123
124const Family = enum {
125 aarch64,
126 arm,
127 loongarch,
128 mips,
129 powerpc,
130 riscv,
131 s390x,
132 x86,
45};133};
46134
47const arches: [inputs.len]std.Target.Cpu.Arch = blk: {135const arches: [@typeInfo(Arch).@"enum".fields.len]Arch = blk: {
48 var result: [inputs.len]std.Target.Cpu.Arch = undefined;136 var result: [@typeInfo(Arch).@"enum".fields.len]Arch = undefined;
49 for (inputs) |arch| {137 for (@typeInfo(Arch).@"enum".fields) |field| {
138 const arch: Arch = @enumFromInt(field.value);
50 result[archIndex(arch)] = arch;139 result[archIndex(arch)] = arch;
51 }140 }
52 break :blk result;141 break :blk result;
...@@ -60,6 +149,31 @@ const MultiSym = struct {...@@ -60,6 +149,31 @@ const MultiSym = struct {
60 ty: u4,149 ty: u4,
61 visib: elf.STV,150 visib: elf.STV,
62151
152 fn isSingleArch(ms: MultiSym) ?Arch {
153 var result: ?Arch = null;
154 inline for (@typeInfo(Arch).@"enum".fields) |field| {
155 const arch: Arch = @enumFromInt(field.value);
156 if (ms.present[archIndex(arch)]) {
157 if (result != null) return null;
158 result = arch;
159 }
160 }
161 return result;
162 }
163
164 fn isFamily(ms: MultiSym) ?Family {
165 var result: ?Family = null;
166 inline for (@typeInfo(Arch).@"enum".fields) |field| {
167 const arch: Arch = @enumFromInt(field.value);
168 if (ms.present[archIndex(arch)]) {
169 const family = arch.family();
170 if (result) |r| if (family != r) return null;
171 result = family;
172 }
173 }
174 return result;
175 }
176
63 fn allPresent(ms: MultiSym) bool {177 fn allPresent(ms: MultiSym) bool {
64 for (arches, 0..) |_, i| {178 for (arches, 0..) |_, i| {
65 if (!ms.present[i]) {179 if (!ms.present[i]) {
...@@ -69,17 +183,14 @@ const MultiSym = struct {...@@ -69,17 +183,14 @@ const MultiSym = struct {
69 return true;183 return true;
70 }184 }
71185
72 fn is32Only(ms: MultiSym) bool {186 fn isTime32Only(ms: MultiSym) bool {
73 return ms.present[archIndex(.riscv32)] == true and187 inline for (@typeInfo(Arch).@"enum".fields) |field| {
74 ms.present[archIndex(.riscv64)] == false and188 const arch: Arch = @enumFromInt(field.value);
75 ms.present[archIndex(.mips)] == true and189 if (ms.present[archIndex(arch)] != arch.isTime32()) {
76 ms.present[archIndex(.mips64)] == false and190 return false;
77 ms.present[archIndex(.x86)] == true and191 }
78 ms.present[archIndex(.x86_64)] == false and192 }
79 ms.present[archIndex(.powerpc)] == true and193 return true;
80 ms.present[archIndex(.powerpc64)] == false and
81 ms.present[archIndex(.aarch64)] == false and
82 ms.present[archIndex(.loongarch64)] == false;
83 }194 }
84195
85 fn commonSize(ms: MultiSym) ?u64 {196 fn commonSize(ms: MultiSym) ?u64 {
...@@ -112,71 +223,38 @@ const MultiSym = struct {...@@ -112,71 +223,38 @@ const MultiSym = struct {
112 return binding.?;223 return binding.?;
113 }224 }
114225
115 fn isPtrSize(ms: MultiSym) bool {226 fn isPtrSize(ms: MultiSym, mult: u16) bool {
116 const map = .{227 inline for (@typeInfo(Arch).@"enum".fields) |field| {
117 .{ .riscv32, 4 },228 const arch: Arch = @enumFromInt(field.value);
118 .{ .riscv64, 8 },
119 .{ .mips, 4 },
120 .{ .mips64, 8 },
121 .{ .x86, 4 },
122 .{ .x86_64, 8 },
123 .{ .powerpc, 4 },
124 .{ .powerpc64, 8 },
125 .{ .aarch64, 8 },
126 .{ .loongarch64, 8 },
127 };
128 inline for (map) |item| {
129 const arch = item[0];
130 const size = item[1];
131 const arch_index = archIndex(arch);229 const arch_index = archIndex(arch);
132 if (ms.present[arch_index] and ms.size[arch_index] != size) {230 if (ms.present[arch_index] and ms.size[arch_index] != arch.ptrSize() * mult) {
133 return false;231 return false;
134 }232 }
135 }233 }
136 return true;234 return true;
137 }235 }
138236
139 fn isPtr2Size(ms: MultiSym) bool {237 fn isWeak64(ms: MultiSym) bool {
140 const map = .{238 inline for (@typeInfo(Arch).@"enum".fields) |field| {
141 .{ .riscv32, 8 },239 const arch: Arch = @enumFromInt(field.value);
142 .{ .riscv64, 16 },
143 .{ .mips, 8 },
144 .{ .mips64, 16 },
145 .{ .x86, 8 },
146 .{ .x86_64, 16 },
147 .{ .powerpc, 8 },
148 .{ .powerpc64, 16 },
149 .{ .aarch64, 16 },
150 .{ .loongarch64, 16 },
151 };
152 inline for (map) |item| {
153 const arch = item[0];
154 const size = item[1];
155 const arch_index = archIndex(arch);240 const arch_index = archIndex(arch);
156 if (ms.present[arch_index] and ms.size[arch_index] != size) {241 const binding: u4 = switch (arch.ptrSize()) {
242 4 => std.elf.STB_GLOBAL,
243 8 => std.elf.STB_WEAK,
244 else => unreachable,
245 };
246 if (ms.present[arch_index] and ms.binding[arch_index] != binding) {
157 return false;247 return false;
158 }248 }
159 }249 }
160 return true;250 return true;
161 }251 }
162252
163 fn isWeak64(ms: MultiSym) bool {253 fn isWeakTime64(ms: MultiSym) bool {
164 const map = .{254 inline for (@typeInfo(Arch).@"enum".fields) |field| {
165 .{ .riscv32, 1 },255 const arch: Arch = @enumFromInt(field.value);
166 .{ .riscv64, 2 },
167 .{ .mips, 1 },
168 .{ .mips64, 2 },
169 .{ .x86, 1 },
170 .{ .x86_64, 2 },
171 .{ .powerpc, 1 },
172 .{ .powerpc64, 2 },
173 .{ .aarch64, 2 },
174 .{ .loongarch64, 2 },
175 };
176 inline for (map) |item| {
177 const arch = item[0];
178 const binding = item[1];
179 const arch_index = archIndex(arch);256 const arch_index = archIndex(arch);
257 const binding: u4 = if (arch.isTime32()) std.elf.STB_GLOBAL else std.elf.STB_WEAK;
180 if (ms.present[arch_index] and ms.binding[arch_index] != binding) {258 if (ms.present[arch_index] and ms.binding[arch_index] != binding) {
181 return false;259 return false;
182 }260 }
...@@ -189,10 +267,9 @@ const Parse = struct {...@@ -189,10 +267,9 @@ const Parse = struct {
189 arena: mem.Allocator,267 arena: mem.Allocator,
190 sym_table: *std.StringArrayHashMap(MultiSym),268 sym_table: *std.StringArrayHashMap(MultiSym),
191 sections: *std.StringArrayHashMap(void),269 sections: *std.StringArrayHashMap(void),
192 blacklist: std.StringArrayHashMap(void),
193 elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8,270 elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8,
194 header: elf.Header,271 header: elf.Header,
195 arch: std.Target.Cpu.Arch,272 arch: Arch,
196};273};
197274
198pub fn main() !void {275pub fn main() !void {
...@@ -207,16 +284,10 @@ pub fn main() !void {...@@ -207,16 +284,10 @@ pub fn main() !void {
207284
208 var sym_table = std.StringArrayHashMap(MultiSym).init(arena);285 var sym_table = std.StringArrayHashMap(MultiSym).init(arena);
209 var sections = std.StringArrayHashMap(void).init(arena);286 var sections = std.StringArrayHashMap(void).init(arena);
210 var blacklist = std.StringArrayHashMap(void).init(arena);
211
212 try blacklist.ensureUnusedCapacity(blacklisted_symbols.len);
213 for (blacklisted_symbols) |name| {
214 blacklist.putAssumeCapacityNoClobber(name, {});
215 }
216287
217 for (arches) |arch| {288 for (arches) |arch| {
218 const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{289 const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{
219 archMuslName(arch),290 @tagName(arch),
220 });291 });
221292
222 // Read the ELF header.293 // Read the ELF header.
...@@ -238,7 +309,6 @@ pub fn main() !void {...@@ -238,7 +309,6 @@ pub fn main() !void {
238 .arena = arena,309 .arena = arena,
239 .sym_table = &sym_table,310 .sym_table = &sym_table,
240 .sections = &sections,311 .sections = &sections,
241 .blacklist = blacklist,
242 .elf_bytes = elf_bytes,312 .elf_bytes = elf_bytes,
243 .header = header,313 .header = header,
244 .arch = arch,314 .arch = arch,
...@@ -268,6 +338,13 @@ pub fn main() !void {...@@ -268,6 +338,13 @@ pub fn main() !void {
268 \\#define PTR2_SIZE_BYTES 8338 \\#define PTR2_SIZE_BYTES 8
269 \\#endif339 \\#endif
270 \\340 \\
341 \\#ifdef TIME32
342 \\#define WEAKTIME64 .globl
343 \\#else
344 \\#define WEAKTIME64 .weak
345 \\#endif
346 \\
347 \\
271 );348 );
272349
273 // Sort the symbols for deterministic output and cleaner vcs diffs.350 // Sort the symbols for deterministic output and cleaner vcs diffs.
...@@ -301,7 +378,7 @@ pub fn main() !void {...@@ -301,7 +378,7 @@ pub fn main() !void {
301 sym_table.sort(SymTableSort{ .sym_table = &sym_table, .sections = &sections });378 sym_table.sort(SymTableSort{ .sym_table = &sym_table, .sections = &sections });
302379
303 var prev_section: u16 = std.math.maxInt(u16);380 var prev_section: u16 = std.math.maxInt(u16);
304 var prev_pp_state: enum { none, ptr32, special } = .none;381 var prev_pp_state: union(enum) { all, single: Arch, multi, family: Family, time32 } = .all;
305 for (sym_table.values(), 0..) |multi_sym, sym_index| {382 for (sym_table.values(), 0..) |multi_sym, sym_index| {
306 const name = sym_table.keys()[sym_index];383 const name = sym_table.keys()[sym_index];
307384
...@@ -313,32 +390,66 @@ pub fn main() !void {...@@ -313,32 +390,66 @@ pub fn main() !void {
313390
314 if (multi_sym.allPresent()) {391 if (multi_sym.allPresent()) {
315 switch (prev_pp_state) {392 switch (prev_pp_state) {
316 .none => {},393 .all => {},
317 .ptr32, .special => {394 .single, .multi, .family, .time32 => {
318 try stdout.writeAll("#endif\n");395 try stdout.writeAll("#endif\n");
319 prev_pp_state = .none;396 prev_pp_state = .all;
320 },397 },
321 }398 }
322 } else if (multi_sym.is32Only()) {399 } else if (multi_sym.isSingleArch()) |arch| {
323 switch (prev_pp_state) {400 switch (prev_pp_state) {
324 .none => {401 .all => {
325 try stdout.writeAll("#ifdef PTR32\n");402 try stdout.print("#ifdef ARCH_{s}\n", .{@tagName(arch)});
326 prev_pp_state = .ptr32;403 prev_pp_state = .{ .single = arch };
327 },404 },
328 .special => {405 .multi, .family, .time32 => {
329 try stdout.writeAll("#endif\n#ifdef PTR32\n");406 try stdout.print("#endif\n#ifdef ARCH_{s}\n", .{@tagName(arch)});
330 prev_pp_state = .ptr32;407 prev_pp_state = .{ .single = arch };
408 },
409 .single => |prev_arch| {
410 if (arch != prev_arch) {
411 try stdout.print("#endif\n#ifdef ARCH_{s}\n", .{@tagName(arch)});
412 prev_pp_state = .{ .single = arch };
413 }
331 },414 },
332 .ptr32 => {},415 }
416 } else if (multi_sym.isFamily()) |family| {
417 switch (prev_pp_state) {
418 .all => {
419 try stdout.print("#ifdef FAMILY_{s}\n", .{@tagName(family)});
420 prev_pp_state = .{ .family = family };
421 },
422 .single, .multi, .time32 => {
423 try stdout.print("#endif\n#ifdef FAMILY_{s}\n", .{@tagName(family)});
424 prev_pp_state = .{ .family = family };
425 },
426 .family => |prev_family| {
427 if (family != prev_family) {
428 try stdout.print("#endif\n#ifdef FAMILY_{s}\n", .{@tagName(family)});
429 prev_pp_state = .{ .family = family };
430 }
431 },
432 }
433 } else if (multi_sym.isTime32Only()) {
434 switch (prev_pp_state) {
435 .all => {
436 try stdout.writeAll("#ifdef TIME32\n");
437 prev_pp_state = .time32;
438 },
439 .single, .multi, .family => {
440 try stdout.writeAll("#endif\n#ifdef TIME32\n");
441 prev_pp_state = .time32;
442 },
443 .time32 => {},
333 }444 }
334 } else {445 } else {
335 switch (prev_pp_state) {446 switch (prev_pp_state) {
336 .none => {},447 .all => {},
337 .special, .ptr32 => {448 .single, .multi, .family, .time32 => {
338 try stdout.writeAll("#endif\n");449 try stdout.writeAll("#endif\n");
339 },450 },
340 }451 }
341 prev_pp_state = .special;452 prev_pp_state = .multi;
342453
343 var first = true;454 var first = true;
344 try stdout.writeAll("#if ");455 try stdout.writeAll("#if ");
...@@ -366,6 +477,8 @@ pub fn main() !void {...@@ -366,6 +477,8 @@ pub fn main() !void {
366 }477 }
367 } else if (multi_sym.isWeak64()) {478 } else if (multi_sym.isWeak64()) {
368 try stdout.print("WEAK64 {s}\n", .{name});479 try stdout.print("WEAK64 {s}\n", .{name});
480 } else if (multi_sym.isWeakTime64()) {
481 try stdout.print("WEAKTIME64 {s}\n", .{name});
369 } else {482 } else {
370 for (arches, 0..) |arch, i| {483 for (arches, 0..) |arch, i| {
371 log.info("symbol '{s}' binding on {s}: {d}", .{484 log.info("symbol '{s}' binding on {s}: {d}", .{
...@@ -384,9 +497,9 @@ pub fn main() !void {...@@ -384,9 +497,9 @@ pub fn main() !void {
384 try stdout.print(".type {s}, %object;\n", .{name});497 try stdout.print(".type {s}, %object;\n", .{name});
385 if (multi_sym.commonSize()) |size| {498 if (multi_sym.commonSize()) |size| {
386 try stdout.print(".size {s}, {d}\n", .{ name, size });499 try stdout.print(".size {s}, {d}\n", .{ name, size });
387 } else if (multi_sym.isPtrSize()) {500 } else if (multi_sym.isPtrSize(1)) {
388 try stdout.print(".size {s}, PTR_SIZE_BYTES\n", .{name});501 try stdout.print(".size {s}, PTR_SIZE_BYTES\n", .{name});
389 } else if (multi_sym.isPtr2Size()) {502 } else if (multi_sym.isPtrSize(2)) {
390 try stdout.print(".size {s}, PTR2_SIZE_BYTES\n", .{name});503 try stdout.print(".size {s}, PTR2_SIZE_BYTES\n", .{name});
391 } else {504 } else {
392 for (arches, 0..) |arch, i| {505 for (arches, 0..) |arch, i| {
...@@ -410,8 +523,8 @@ pub fn main() !void {...@@ -410,8 +523,8 @@ pub fn main() !void {
410 }523 }
411524
412 switch (prev_pp_state) {525 switch (prev_pp_state) {
413 .none => {},526 .all => {},
414 .ptr32, .special => try stdout.writeAll("#endif\n"),527 .single, .multi, .family, .time32 => try stdout.writeAll("#endif\n"),
415 }528 }
416}529}
417530
...@@ -487,12 +600,17 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)...@@ -487,12 +600,17 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)
487 const visib = @as(elf.STV, @enumFromInt(@as(u2, @truncate(sym.st_other))));600 const visib = @as(elf.STV, @enumFromInt(@as(u2, @truncate(sym.st_other))));
488 const size = s(sym.st_size);601 const size = s(sym.st_size);
489602
490 if (parse.blacklist.contains(name)) continue;
491
492 if (size == 0) {603 if (size == 0) {
493 log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name });604 log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name });
494 }605 }
495606
607 if (sym.st_shndx == elf.SHN_UNDEF) {
608 log.debug("{s}: skipping '{s}' due to it being undefined", .{
609 @tagName(parse.arch), name,
610 });
611 continue;
612 }
613
496 switch (binding) {614 switch (binding) {
497 elf.STB_GLOBAL, elf.STB_WEAK => {},615 elf.STB_GLOBAL, elf.STB_WEAK => {},
498 else => {616 else => {
...@@ -590,40 +708,8 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)...@@ -590,40 +708,8 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)
590 }708 }
591}709}
592710
593fn archIndex(arch: std.Target.Cpu.Arch) u8 {711fn archIndex(arch: Arch) u8 {
594 return switch (arch) {712 return @intFromEnum(arch);
595 // zig fmt: off
596 .riscv64 => 0,
597 .mips => 1,
598 .mips64 => 2,
599 .x86 => 3,
600 .x86_64 => 4,
601 .powerpc => 5,
602 .powerpc64 => 6,
603 .aarch64 => 7,
604 .riscv32 => 8,
605 .loongarch64 => 9,
606 else => unreachable,
607 // zig fmt: on
608 };
609}
610
611fn archMuslName(arch: std.Target.Cpu.Arch) []const u8 {
612 return switch (arch) {
613 // zig fmt: off
614 .riscv64 => "riscv64",
615 .mips => "mips",
616 .mips64 => "mips64",
617 .x86 => "i386",
618 .x86_64 => "x86_64",
619 .powerpc => "powerpc",
620 .powerpc64 => "powerpc64",
621 .aarch64 => "aarch64",
622 .riscv32 => "riscv32",
623 .loongarch64 => "loongarch64",
624 else => unreachable,
625 // zig fmt: on
626 };
627}713}
628714
629fn archSetName(arch_set: [arches.len]bool) []const u8 {715fn archSetName(arch_set: [arches.len]bool) []const u8 {
...@@ -639,529 +725,3 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn {...@@ -639,529 +725,3 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn {
639 log.err(format, args);725 log.err(format, args);
640 std.process.exit(1);726 std.process.exit(1);
641}727}
642
643const blacklisted_symbols = [_][]const u8{
644 "__absvdi2",
645 "__absvsi2",
646 "__absvti2",
647 "__adddf3",
648 "__addkf3",
649 "__addodi4",
650 "__addosi4",
651 "__addoti4",
652 "__addsf3",
653 "__addtf3",
654 "__addxf3",
655 "__ashldi3",
656 "__ashlsi3",
657 "__ashlti3",
658 "__ashrdi3",
659 "__ashrsi3",
660 "__ashrti3",
661 "__atomic_compare_exchange",
662 "__atomic_compare_exchange_1",
663 "__atomic_compare_exchange_2",
664 "__atomic_compare_exchange_4",
665 "__atomic_compare_exchange_8",
666 "__atomic_exchange",
667 "__atomic_exchange_1",
668 "__atomic_exchange_2",
669 "__atomic_exchange_4",
670 "__atomic_exchange_8",
671 "__atomic_fetch_add_1",
672 "__atomic_fetch_add_2",
673 "__atomic_fetch_add_4",
674 "__atomic_fetch_add_8",
675 "__atomic_fetch_and_1",
676 "__atomic_fetch_and_2",
677 "__atomic_fetch_and_4",
678 "__atomic_fetch_and_8",
679 "__atomic_fetch_nand_1",
680 "__atomic_fetch_nand_2",
681 "__atomic_fetch_nand_4",
682 "__atomic_fetch_nand_8",
683 "__atomic_fetch_or_1",
684 "__atomic_fetch_or_2",
685 "__atomic_fetch_or_4",
686 "__atomic_fetch_or_8",
687 "__atomic_fetch_sub_1",
688 "__atomic_fetch_sub_2",
689 "__atomic_fetch_sub_4",
690 "__atomic_fetch_sub_8",
691 "__atomic_fetch_xor_1",
692 "__atomic_fetch_xor_2",
693 "__atomic_fetch_xor_4",
694 "__atomic_fetch_xor_8",
695 "__atomic_load",
696 "__atomic_load_1",
697 "__atomic_load_2",
698 "__atomic_load_4",
699 "__atomic_load_8",
700 "__atomic_store",
701 "__atomic_store_1",
702 "__atomic_store_2",
703 "__atomic_store_4",
704 "__atomic_store_8",
705 "__bswapdi2",
706 "__bswapsi2",
707 "__bswapti2",
708 "__ceilh",
709 "__ceilx",
710 "__clear_cache",
711 "__clzdi2",
712 "__chk_fail",
713 "__clzsi2",
714 "__clzti2",
715 "__cmpdf2",
716 "__cmpdi2",
717 "__cmpsf2",
718 "__cmpsi2",
719 "__cmptf2",
720 "__cmpti2",
721 "__cosh",
722 "__cosx",
723 "__ctzdi2",
724 "__ctzsi2",
725 "__ctzti2",
726 "__divdf3",
727 "__divdi3",
728 "__divkf3",
729 "__divmoddi4",
730 "__divmodsi4",
731 "__divmodti4",
732 "__divsf3",
733 "__divsi3",
734 "__divtf3",
735 "__divti3",
736 "__divxf3",
737 "__dlstart",
738 "__eqdf2",
739 "__eqkf2",
740 "__eqsf2",
741 "__eqtf2",
742 "__eqxf2",
743 "__exp2h",
744 "__exp2x",
745 "__exph",
746 "__expx",
747 "__extenddfkf2",
748 "__extenddftf2",
749 "__extenddfxf2",
750 "__extendhfsf2",
751 "__extendhftf2",
752 "__extendhfxf2",
753 "__extendsfdf2",
754 "__extendsfkf2",
755 "__extendsftf2",
756 "__extendsfxf2",
757 "__extendxftf2",
758 "__fabsh",
759 "__fabsx",
760 "__ffsdi2",
761 "__ffssi2",
762 "__ffsti2",
763 "__fixdfdi",
764 "__fixdfsi",
765 "__fixdfti",
766 "__fixkfdi",
767 "__fixkfsi",
768 "__fixkfti",
769 "__fixsfdi",
770 "__fixsfsi",
771 "__fixsfti",
772 "__fixtfdi",
773 "__fixtfsi",
774 "__fixtfti",
775 "__fixunsdfdi",
776 "__fixunsdfsi",
777 "__fixunsdfti",
778 "__fixunskfdi",
779 "__fixunskfsi",
780 "__fixunskfti",
781 "__fixunssfdi",
782 "__fixunssfsi",
783 "__fixunssfti",
784 "__fixunstfdi",
785 "__fixunstfsi",
786 "__fixunstfti",
787 "__fixunsxfdi",
788 "__fixunsxfsi",
789 "__fixunsxfti",
790 "__fixxfdi",
791 "__fixxfsi",
792 "__fixxfti",
793 "__floatdidf",
794 "__floatdikf",
795 "__floatdisf",
796 "__floatditf",
797 "__floatdixf",
798 "__floatsidf",
799 "__floatsikf",
800 "__floatsisf",
801 "__floatsitf",
802 "__floatsixf",
803 "__floattidf",
804 "__floattikf",
805 "__floattisf",
806 "__floattitf",
807 "__floattixf",
808 "__floatundidf",
809 "__floatundikf",
810 "__floatundisf",
811 "__floatunditf",
812 "__floatundixf",
813 "__floatunsidf",
814 "__floatunsikf",
815 "__floatunsisf",
816 "__floatunsitf",
817 "__floatunsixf",
818 "__floatuntidf",
819 "__floatuntikf",
820 "__floatuntisf",
821 "__floatuntitf",
822 "__floatuntixf",
823 "__floorh",
824 "__floorx",
825 "__fmah",
826 "__fmax",
827 "__fmaxh",
828 "__fmaxx",
829 "__fminh",
830 "__fminx",
831 "__fmodh",
832 "__fmodx",
833 "__gedf2",
834 "__gekf2",
835 "__gesf2",
836 "__getf2",
837 "__gexf2",
838 "__gnu_f2h_ieee",
839 "__gnu_h2f_ieee",
840 "__gtdf2",
841 "__gtkf2",
842 "__gtsf2",
843 "__gttf2",
844 "__gtxf2",
845 "__ledf2",
846 "__lekf2",
847 "__lesf2",
848 "__letf2",
849 "__lexf2",
850 "__log10h",
851 "__log10x",
852 "__log2h",
853 "__log2x",
854 "__logh",
855 "__logx",
856 "__lshrdi3",
857 "__lshrsi3",
858 "__lshrti3",
859 "__ltdf2",
860 "__ltkf2",
861 "__ltsf2",
862 "__lttf2",
863 "__ltxf2",
864 "__memcpy_chk",
865 "__memmove_chk",
866 "__memset",
867 "__memset_chk",
868 "__moddi3",
869 "__modsi3",
870 "__modti3",
871 "__muldc3",
872 "__muldf3",
873 "__muldi3",
874 "__mulkc3",
875 "__mulkf3",
876 "__mulodi4",
877 "__mulosi4",
878 "__muloti4",
879 "__mulsc3",
880 "__mulsf3",
881 "__mulsi3",
882 "__multc3",
883 "__multf3",
884 "__multi3",
885 "__mulxc3",
886 "__mulxf3",
887 "__nedf2",
888 "__negdf2",
889 "__negdi2",
890 "__negsf2",
891 "__negsi2",
892 "__negti2",
893 "__negvdi2",
894 "__negvsi2",
895 "__negvti2",
896 "__nekf2",
897 "__nesf2",
898 "__netf2",
899 "__nexf2",
900 "__paritydi2",
901 "__paritysi2",
902 "__parityti2",
903 "__popcountdi2",
904 "__popcountsi2",
905 "__popcountti2",
906 "__powidf2",
907 "__powihf2",
908 "__powikf2",
909 "__powisf2",
910 "__powitf2",
911 "__powixf2",
912 "__roundh",
913 "__roundx",
914 "__sincosh",
915 "__sincosx",
916 "__sinh",
917 "__sinx",
918 "__sqrth",
919 "__sqrtx",
920 "__strcat_chk",
921 "__strcpy_chk",
922 "__strncat_chk",
923 "__strncpy_chk",
924 "__subdf3",
925 "__subkf3",
926 "__subodi4",
927 "__subosi4",
928 "__suboti4",
929 "__subsf3",
930 "__subtf3",
931 "__subxf3",
932 "__tanh",
933 "__tanx",
934 "__truncdfhf2",
935 "__truncdfsf2",
936 "__trunch",
937 "__trunckfdf2",
938 "__trunckfsf2",
939 "__truncsfhf2",
940 "__trunctfdf2",
941 "__trunctfhf2",
942 "__trunctfsf2",
943 "__trunctfxf2",
944 "__truncx",
945 "__truncxfdf2",
946 "__truncxfhf2",
947 "__truncxfsf2",
948 "__ucmpdi2",
949 "__ucmpsi2",
950 "__ucmpti2",
951 "__udivdi3",
952 "__udivei4",
953 "__udivmoddi4",
954 "__udivmodsi4",
955 "__udivmodti4",
956 "__udivsi3",
957 "__udivti3",
958 "__umoddi3",
959 "__umodei4",
960 "__umodsi3",
961 "__umodti3",
962 "__unorddf2",
963 "__unordkf2",
964 "__unordsf2",
965 "__unordtf2",
966 "__zig_probe_stack",
967 "ceilf128",
968 "ceilq",
969 "cosf128",
970 "cosq",
971 "exp2f128",
972 "exp2q",
973 "expf128",
974 "expq",
975 "fabsf128",
976 "fabsq",
977 "fabsq.2",
978 "fabsq.3",
979 "floorf128",
980 "floorq",
981 "fmaf128",
982 "fmaq",
983 "fmaxf128",
984 "fmaxq",
985 "fmaxq.2",
986 "fmaxq.3",
987 "fminf128",
988 "fminq",
989 "fmodf128",
990 "fmodq",
991 "log10f128",
992 "log10q",
993 "log2f128",
994 "log2q",
995 "logf128",
996 "logq",
997 "roundf128",
998 "roundq",
999 "sincosf128",
1000 "sincosq",
1001 "sinf128",
1002 "sinq",
1003 "sqrtf128",
1004 "sqrtq",
1005 "tanf128",
1006 "tanq",
1007 "truncf128",
1008 "truncq",
1009 "__aarch64_cas16_acq",
1010 "__aarch64_cas16_acq_rel",
1011 "__aarch64_cas16_rel",
1012 "__aarch64_cas16_relax",
1013 "__aarch64_cas1_acq",
1014 "__aarch64_cas1_acq_rel",
1015 "__aarch64_cas1_rel",
1016 "__aarch64_cas1_relax",
1017 "__aarch64_cas2_acq",
1018 "__aarch64_cas2_acq_rel",
1019 "__aarch64_cas2_rel",
1020 "__aarch64_cas2_relax",
1021 "__aarch64_cas4_acq",
1022 "__aarch64_cas4_acq_rel",
1023 "__aarch64_cas4_rel",
1024 "__aarch64_cas4_relax",
1025 "__aarch64_cas8_acq",
1026 "__aarch64_cas8_acq_rel",
1027 "__aarch64_cas8_rel",
1028 "__aarch64_cas8_relax",
1029 "__aarch64_ldadd1_acq",
1030 "__aarch64_ldadd1_acq_rel",
1031 "__aarch64_ldadd1_rel",
1032 "__aarch64_ldadd1_relax",
1033 "__aarch64_ldadd2_acq",
1034 "__aarch64_ldadd2_acq_rel",
1035 "__aarch64_ldadd2_rel",
1036 "__aarch64_ldadd2_relax",
1037 "__aarch64_ldadd4_acq",
1038 "__aarch64_ldadd4_acq_rel",
1039 "__aarch64_ldadd4_rel",
1040 "__aarch64_ldadd4_relax",
1041 "__aarch64_ldadd8_acq",
1042 "__aarch64_ldadd8_acq_rel",
1043 "__aarch64_ldadd8_rel",
1044 "__aarch64_ldadd8_relax",
1045 "__aarch64_ldclr1_acq",
1046 "__aarch64_ldclr1_acq_rel",
1047 "__aarch64_ldclr1_rel",
1048 "__aarch64_ldclr1_relax",
1049 "__aarch64_ldclr2_acq",
1050 "__aarch64_ldclr2_acq_rel",
1051 "__aarch64_ldclr2_rel",
1052 "__aarch64_ldclr2_relax",
1053 "__aarch64_ldclr4_acq",
1054 "__aarch64_ldclr4_acq_rel",
1055 "__aarch64_ldclr4_rel",
1056 "__aarch64_ldclr4_relax",
1057 "__aarch64_ldclr8_acq",
1058 "__aarch64_ldclr8_acq_rel",
1059 "__aarch64_ldclr8_rel",
1060 "__aarch64_ldclr8_relax",
1061 "__aarch64_ldeor1_acq",
1062 "__aarch64_ldeor1_acq_rel",
1063 "__aarch64_ldeor1_rel",
1064 "__aarch64_ldeor1_relax",
1065 "__aarch64_ldeor2_acq",
1066 "__aarch64_ldeor2_acq_rel",
1067 "__aarch64_ldeor2_rel",
1068 "__aarch64_ldeor2_relax",
1069 "__aarch64_ldeor4_acq",
1070 "__aarch64_ldeor4_acq_rel",
1071 "__aarch64_ldeor4_rel",
1072 "__aarch64_ldeor4_relax",
1073 "__aarch64_ldeor8_acq",
1074 "__aarch64_ldeor8_acq_rel",
1075 "__aarch64_ldeor8_rel",
1076 "__aarch64_ldeor8_relax",
1077 "__aarch64_ldset1_acq",
1078 "__aarch64_ldset1_acq_rel",
1079 "__aarch64_ldset1_rel",
1080 "__aarch64_ldset1_relax",
1081 "__aarch64_ldset2_acq",
1082 "__aarch64_ldset2_acq_rel",
1083 "__aarch64_ldset2_rel",
1084 "__aarch64_ldset2_relax",
1085 "__aarch64_ldset4_acq",
1086 "__aarch64_ldset4_acq_rel",
1087 "__aarch64_ldset4_rel",
1088 "__aarch64_ldset4_relax",
1089 "__aarch64_ldset8_acq",
1090 "__aarch64_ldset8_acq_rel",
1091 "__aarch64_ldset8_rel",
1092 "__aarch64_ldset8_relax",
1093 "__aarch64_swp1_acq",
1094 "__aarch64_swp1_acq_rel",
1095 "__aarch64_swp1_rel",
1096 "__aarch64_swp1_relax",
1097 "__aarch64_swp2_acq",
1098 "__aarch64_swp2_acq_rel",
1099 "__aarch64_swp2_rel",
1100 "__aarch64_swp2_relax",
1101 "__aarch64_swp4_acq",
1102 "__aarch64_swp4_acq_rel",
1103 "__aarch64_swp4_rel",
1104 "__aarch64_swp4_relax",
1105 "__aarch64_swp8_acq",
1106 "__aarch64_swp8_acq_rel",
1107 "__aarch64_swp8_rel",
1108 "__aarch64_swp8_relax",
1109 "__addhf3",
1110 "__atomic_compare_exchange_16",
1111 "__atomic_exchange_16",
1112 "__atomic_fetch_add_16",
1113 "__atomic_fetch_and_16",
1114 "__atomic_fetch_nand_16",
1115 "__atomic_fetch_or_16",
1116 "__atomic_fetch_sub_16",
1117 "__atomic_fetch_umax_1",
1118 "__atomic_fetch_umax_16",
1119 "__atomic_fetch_umax_2",
1120 "__atomic_fetch_umax_4",
1121 "__atomic_fetch_umax_8",
1122 "__atomic_fetch_umin_1",
1123 "__atomic_fetch_umin_16",
1124 "__atomic_fetch_umin_2",
1125 "__atomic_fetch_umin_4",
1126 "__atomic_fetch_umin_8",
1127 "__atomic_fetch_xor_16",
1128 "__atomic_load_16",
1129 "__atomic_store_16",
1130 "__cmphf2",
1131 "__cmpxf2",
1132 "__divdc3",
1133 "__divhc3",
1134 "__divhf3",
1135 "__divkc3",
1136 "__divsc3",
1137 "__divtc3",
1138 "__divxc3",
1139 "__eqhf2",
1140 "__extendhfdf2",
1141 "__fixhfdi",
1142 "__fixhfsi",
1143 "__fixhfti",
1144 "__fixunshfdi",
1145 "__fixunshfsi",
1146 "__fixunshfti",
1147 "__floatdihf",
1148 "__floatsihf",
1149 "__floattihf",
1150 "__floatundihf",
1151 "__floatunsihf",
1152 "__floatuntihf",
1153 "__gehf2",
1154 "__gthf2",
1155 "__lehf2",
1156 "__lthf2",
1157 "__mulhc3",
1158 "__mulhf3",
1159 "__neghf2",
1160 "__negkf2",
1161 "__negtf2",
1162 "__negxf2",
1163 "__nehf2",
1164 "__subhf3",
1165 "__unordhf2",
1166 "__unordxf2",
1167};