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 @@
22//! ./gen_stubs /path/to/musl/build-all >libc.S
33//!
44//! The directory 'build-all' is expected to contain these subdirectories:
5//! arm x86 mips mips64 powerpc powerpc64 riscv32 riscv64 x86_64 loongarch64
5//!
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
620//!
721//! ...each with 'lib/libc.so' inside of them.
822//!
923//! When building the resulting libc.S file, these defines are required:
10//! * `-DPTR64`: when the architecture is 64-bit
24//! * `-DTIME32`: When the target's primary time ABI is 32-bit
25//! * `-DPTR64`: When the target has 64-bit pointers
1126//! * One of the following, corresponding to the CPU architecture:
12//! - `-DARCH_riscv32`
13//! - `-DARCH_riscv64`
27//! - `-DARCH_aarch64`
28//! - `-DARCH_arm`
29//! - `-DARCH_i386`
30//! - `-DARCH_loongarch64`
1431//! - `-DARCH_mips`
1532//! - `-DARCH_mips64`
16//! - `-DARCH_i386`
17//! - `-DARCH_x86_64`
33//! - `-DARCH_mipsn32`
1834//! - `-DARCH_powerpc`
1935//! - `-DARCH_powerpc64`
20//! - `-DARCH_aarch64`
21//! - `-DARCH_loongarch64`
36//! - `-DARCH_riscv32`
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
2351// TODO: pick the best index to put them into instead of at the end
2452// - e.g. find a common previous symbol and put it after that one
......@@ -29,24 +57,85 @@ const builtin = std.builtin;
2957const mem = std.mem;
3058const log = std.log;
3159const elf = std.elf;
32const native_endian = @import("builtin").target.cpu.arch.endian();
33
34const inputs = .{
35 .riscv32,
36 .riscv64,
37 .loongarch64,
38 .mips,
39 .mips64,
40 .x86,
41 .x86_64,
42 .powerpc,
43 .powerpc64,
44 .aarch64,
60const native_endian = @import("builtin").cpu.arch.endian();
61
62const Arch = enum {
63 aarch64,
64 arm,
65 i386,
66 loongarch64,
67 mips,
68 mips64,
69 mipsn32,
70 powerpc,
71 powerpc64,
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,
45133};
46134
47const arches: [inputs.len]std.Target.Cpu.Arch = blk: {
48 var result: [inputs.len]std.Target.Cpu.Arch = undefined;
49 for (inputs) |arch| {
135const arches: [@typeInfo(Arch).@"enum".fields.len]Arch = blk: {
136 var result: [@typeInfo(Arch).@"enum".fields.len]Arch = undefined;
137 for (@typeInfo(Arch).@"enum".fields) |field| {
138 const arch: Arch = @enumFromInt(field.value);
50139 result[archIndex(arch)] = arch;
51140 }
52141 break :blk result;
......@@ -60,6 +149,31 @@ const MultiSym = struct {
60149 ty: u4,
61150 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
63177 fn allPresent(ms: MultiSym) bool {
64178 for (arches, 0..) |_, i| {
65179 if (!ms.present[i]) {
......@@ -69,17 +183,14 @@ const MultiSym = struct {
69183 return true;
70184 }
71185
72 fn is32Only(ms: MultiSym) bool {
73 return ms.present[archIndex(.riscv32)] == true and
74 ms.present[archIndex(.riscv64)] == false and
75 ms.present[archIndex(.mips)] == true and
76 ms.present[archIndex(.mips64)] == false and
77 ms.present[archIndex(.x86)] == true and
78 ms.present[archIndex(.x86_64)] == false and
79 ms.present[archIndex(.powerpc)] == true and
80 ms.present[archIndex(.powerpc64)] == false and
81 ms.present[archIndex(.aarch64)] == false and
82 ms.present[archIndex(.loongarch64)] == false;
186 fn isTime32Only(ms: MultiSym) bool {
187 inline for (@typeInfo(Arch).@"enum".fields) |field| {
188 const arch: Arch = @enumFromInt(field.value);
189 if (ms.present[archIndex(arch)] != arch.isTime32()) {
190 return false;
191 }
192 }
193 return true;
83194 }
84195
85196 fn commonSize(ms: MultiSym) ?u64 {
......@@ -112,71 +223,38 @@ const MultiSym = struct {
112223 return binding.?;
113224 }
114225
115 fn isPtrSize(ms: MultiSym) bool {
116 const map = .{
117 .{ .riscv32, 4 },
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];
226 fn isPtrSize(ms: MultiSym, mult: u16) bool {
227 inline for (@typeInfo(Arch).@"enum".fields) |field| {
228 const arch: Arch = @enumFromInt(field.value);
131229 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) {
133231 return false;
134232 }
135233 }
136234 return true;
137235 }
138236
139 fn isPtr2Size(ms: MultiSym) bool {
140 const map = .{
141 .{ .riscv32, 8 },
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];
237 fn isWeak64(ms: MultiSym) bool {
238 inline for (@typeInfo(Arch).@"enum".fields) |field| {
239 const arch: Arch = @enumFromInt(field.value);
155240 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) {
157247 return false;
158248 }
159249 }
160250 return true;
161251 }
162252
163 fn isWeak64(ms: MultiSym) bool {
164 const map = .{
165 .{ .riscv32, 1 },
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];
253 fn isWeakTime64(ms: MultiSym) bool {
254 inline for (@typeInfo(Arch).@"enum".fields) |field| {
255 const arch: Arch = @enumFromInt(field.value);
179256 const arch_index = archIndex(arch);
257 const binding: u4 = if (arch.isTime32()) std.elf.STB_GLOBAL else std.elf.STB_WEAK;
180258 if (ms.present[arch_index] and ms.binding[arch_index] != binding) {
181259 return false;
182260 }
......@@ -189,10 +267,9 @@ const Parse = struct {
189267 arena: mem.Allocator,
190268 sym_table: *std.StringArrayHashMap(MultiSym),
191269 sections: *std.StringArrayHashMap(void),
192 blacklist: std.StringArrayHashMap(void),
193270 elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8,
194271 header: elf.Header,
195 arch: std.Target.Cpu.Arch,
272 arch: Arch,
196273};
197274
198275pub fn main() !void {
......@@ -207,16 +284,10 @@ pub fn main() !void {
207284
208285 var sym_table = std.StringArrayHashMap(MultiSym).init(arena);
209286 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
217288 for (arches) |arch| {
218289 const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{
219 archMuslName(arch),
290 @tagName(arch),
220291 });
221292
222293 // Read the ELF header.
......@@ -238,7 +309,6 @@ pub fn main() !void {
238309 .arena = arena,
239310 .sym_table = &sym_table,
240311 .sections = &sections,
241 .blacklist = blacklist,
242312 .elf_bytes = elf_bytes,
243313 .header = header,
244314 .arch = arch,
......@@ -268,6 +338,13 @@ pub fn main() !void {
268338 \\#define PTR2_SIZE_BYTES 8
269339 \\#endif
270340 \\
341 \\#ifdef TIME32
342 \\#define WEAKTIME64 .globl
343 \\#else
344 \\#define WEAKTIME64 .weak
345 \\#endif
346 \\
347 \\
271348 );
272349
273350 // Sort the symbols for deterministic output and cleaner vcs diffs.
......@@ -301,7 +378,7 @@ pub fn main() !void {
301378 sym_table.sort(SymTableSort{ .sym_table = &sym_table, .sections = &sections });
302379
303380 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;
305382 for (sym_table.values(), 0..) |multi_sym, sym_index| {
306383 const name = sym_table.keys()[sym_index];
307384
......@@ -313,32 +390,66 @@ pub fn main() !void {
313390
314391 if (multi_sym.allPresent()) {
315392 switch (prev_pp_state) {
316 .none => {},
317 .ptr32, .special => {
393 .all => {},
394 .single, .multi, .family, .time32 => {
318395 try stdout.writeAll("#endif\n");
319 prev_pp_state = .none;
396 prev_pp_state = .all;
320397 },
321398 }
322 } else if (multi_sym.is32Only()) {
399 } else if (multi_sym.isSingleArch()) |arch| {
323400 switch (prev_pp_state) {
324 .none => {
325 try stdout.writeAll("#ifdef PTR32\n");
326 prev_pp_state = .ptr32;
401 .all => {
402 try stdout.print("#ifdef ARCH_{s}\n", .{@tagName(arch)});
403 prev_pp_state = .{ .single = arch };
327404 },
328 .special => {
329 try stdout.writeAll("#endif\n#ifdef PTR32\n");
330 prev_pp_state = .ptr32;
405 .multi, .family, .time32 => {
406 try stdout.print("#endif\n#ifdef ARCH_{s}\n", .{@tagName(arch)});
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 }
331414 },
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 => {},
333444 }
334445 } else {
335446 switch (prev_pp_state) {
336 .none => {},
337 .special, .ptr32 => {
447 .all => {},
448 .single, .multi, .family, .time32 => {
338449 try stdout.writeAll("#endif\n");
339450 },
340451 }
341 prev_pp_state = .special;
452 prev_pp_state = .multi;
342453
343454 var first = true;
344455 try stdout.writeAll("#if ");
......@@ -366,6 +477,8 @@ pub fn main() !void {
366477 }
367478 } else if (multi_sym.isWeak64()) {
368479 try stdout.print("WEAK64 {s}\n", .{name});
480 } else if (multi_sym.isWeakTime64()) {
481 try stdout.print("WEAKTIME64 {s}\n", .{name});
369482 } else {
370483 for (arches, 0..) |arch, i| {
371484 log.info("symbol '{s}' binding on {s}: {d}", .{
......@@ -384,9 +497,9 @@ pub fn main() !void {
384497 try stdout.print(".type {s}, %object;\n", .{name});
385498 if (multi_sym.commonSize()) |size| {
386499 try stdout.print(".size {s}, {d}\n", .{ name, size });
387 } else if (multi_sym.isPtrSize()) {
500 } else if (multi_sym.isPtrSize(1)) {
388501 try stdout.print(".size {s}, PTR_SIZE_BYTES\n", .{name});
389 } else if (multi_sym.isPtr2Size()) {
502 } else if (multi_sym.isPtrSize(2)) {
390503 try stdout.print(".size {s}, PTR2_SIZE_BYTES\n", .{name});
391504 } else {
392505 for (arches, 0..) |arch, i| {
......@@ -410,8 +523,8 @@ pub fn main() !void {
410523 }
411524
412525 switch (prev_pp_state) {
413 .none => {},
414 .ptr32, .special => try stdout.writeAll("#endif\n"),
526 .all => {},
527 .single, .multi, .family, .time32 => try stdout.writeAll("#endif\n"),
415528 }
416529}
417530
......@@ -487,12 +600,17 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)
487600 const visib = @as(elf.STV, @enumFromInt(@as(u2, @truncate(sym.st_other))));
488601 const size = s(sym.st_size);
489602
490 if (parse.blacklist.contains(name)) continue;
491
492603 if (size == 0) {
493604 log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name });
494605 }
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
496614 switch (binding) {
497615 elf.STB_GLOBAL, elf.STB_WEAK => {},
498616 else => {
......@@ -590,40 +708,8 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)
590708 }
591709}
592710
593fn archIndex(arch: std.Target.Cpu.Arch) u8 {
594 return switch (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 };
711fn archIndex(arch: Arch) u8 {
712 return @intFromEnum(arch);
627713}
628714
629715fn archSetName(arch_set: [arches.len]bool) []const u8 {
......@@ -639,529 +725,3 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn {
639725 log.err(format, args);
640726 std.process.exit(1);
641727}
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};