| ... | ... | @@ -1,15 +1,25 @@ |
| 1 | 1 | //! Example usage: |
| 2 | | //! ./gen_stubs /path/to/musl/build-all |
| 2 | //! ./gen_stubs /path/to/musl/build-all >libc.S |
| 3 | 3 | //! |
| 4 | 4 | //! The directory 'build-all' is expected to contain these subdirectories: |
| 5 | 5 | //! arm i386 mips mips64 powerpc powerpc64 riscv64 x86_64 |
| 6 | 6 | //! |
| 7 | 7 | //! ...each with 'lib/libc.so' inside of them. |
| 8 | //! |
| 9 | //! When building the resulting libc.S file, these defines are required: |
| 10 | //! * `-DPTR64`: when the architecture is 64-bit |
| 11 | //! * One of the following, corresponding to the CPU architecture: |
| 12 | //! - `-DARCH_riscv64` |
| 13 | //! - `-DARCH_mips` |
| 14 | //! - `-DARCH_i386` |
| 15 | //! - `-DARCH_x86_64` |
| 16 | //! - `-DARCH_powerpc` |
| 17 | //! - `-DARCH_powerpc64` |
| 18 | //! - `-DARCH_aarch64` |
| 8 | 19 | |
| 9 | 20 | // TODO: pick the best index to put them into instead of at the end |
| 10 | 21 | // - e.g. find a common previous symbol and put it after that one |
| 11 | 22 | // - they definitely need to go into the correct section |
| 12 | | // TODO: emit MultiSyms to use the preprocessor |
| 13 | 23 | |
| 14 | 24 | const std = @import("std"); |
| 15 | 25 | const builtin = std.builtin; |
| ... | ... | @@ -18,9 +28,9 @@ const log = std.log; |
| 18 | 28 | const elf = std.elf; |
| 19 | 29 | const native_endian = @import("builtin").target.cpu.arch.endian(); |
| 20 | 30 | |
| 21 | | const arches: [6]std.Target.Cpu.Arch = blk: { |
| 22 | | var result: [6]std.Target.Cpu.Arch = undefined; |
| 23 | | for (.{ .riscv64, .mips, .i386, .x86_64, .powerpc, .powerpc64 }) |arch| { |
| 31 | const arches: [7]std.Target.Cpu.Arch = blk: { |
| 32 | var result: [7]std.Target.Cpu.Arch = undefined; |
| 33 | for (.{ .riscv64, .mips, .i386, .x86_64, .powerpc, .powerpc64, .aarch64 }) |arch| { |
| 24 | 34 | result[archIndex(arch)] = arch; |
| 25 | 35 | } |
| 26 | 36 | break :blk result; |
| ... | ... | @@ -29,16 +39,129 @@ const arches: [6]std.Target.Cpu.Arch = blk: { |
| 29 | 39 | const MultiSym = struct { |
| 30 | 40 | size: [arches.len]u64, |
| 31 | 41 | present: [arches.len]bool, |
| 42 | binding: [arches.len]u4, |
| 32 | 43 | section: u16, |
| 33 | 44 | ty: u4, |
| 34 | | binding: u4, |
| 35 | 45 | visib: elf.STV, |
| 46 | |
| 47 | fn allPresent(ms: MultiSym) bool { |
| 48 | for (arches) |_, i| { |
| 49 | if (!ms.present[i]) { |
| 50 | return false; |
| 51 | } |
| 52 | } |
| 53 | return true; |
| 54 | } |
| 55 | |
| 56 | fn is32Only(ms: MultiSym) bool { |
| 57 | return ms.present[archIndex(.riscv64)] == false and |
| 58 | ms.present[archIndex(.mips)] == true and |
| 59 | ms.present[archIndex(.i386)] == true and |
| 60 | ms.present[archIndex(.x86_64)] == false and |
| 61 | ms.present[archIndex(.powerpc)] == true and |
| 62 | ms.present[archIndex(.powerpc64)] == false and |
| 63 | ms.present[archIndex(.aarch64)] == false; |
| 64 | } |
| 65 | |
| 66 | fn commonSize(ms: MultiSym) ?u64 { |
| 67 | var size: ?u64 = null; |
| 68 | for (arches) |_, i| { |
| 69 | if (!ms.present[i]) continue; |
| 70 | if (size) |s| { |
| 71 | if (ms.size[i] != s) { |
| 72 | return null; |
| 73 | } |
| 74 | } else { |
| 75 | size = ms.size[i]; |
| 76 | } |
| 77 | } |
| 78 | return size.?; |
| 79 | } |
| 80 | |
| 81 | fn commonBinding(ms: MultiSym) ?u4 { |
| 82 | var binding: ?u4 = null; |
| 83 | for (arches) |_, i| { |
| 84 | if (!ms.present[i]) continue; |
| 85 | if (binding) |b| { |
| 86 | if (ms.binding[i] != b) { |
| 87 | return null; |
| 88 | } |
| 89 | } else { |
| 90 | binding = ms.binding[i]; |
| 91 | } |
| 92 | } |
| 93 | return binding.?; |
| 94 | } |
| 95 | |
| 96 | fn isPtrSize(ms: MultiSym) bool { |
| 97 | const map = .{ |
| 98 | .{ .riscv64, 8 }, |
| 99 | .{ .mips, 4 }, |
| 100 | .{ .i386, 4 }, |
| 101 | .{ .x86_64, 8 }, |
| 102 | .{ .powerpc, 4 }, |
| 103 | .{ .powerpc64, 8 }, |
| 104 | .{ .aarch64, 8 }, |
| 105 | }; |
| 106 | inline for (map) |item| { |
| 107 | const arch = item[0]; |
| 108 | const size = item[1]; |
| 109 | const arch_index = archIndex(arch); |
| 110 | if (ms.present[arch_index] and ms.size[arch_index] != size) { |
| 111 | return false; |
| 112 | } |
| 113 | } |
| 114 | return true; |
| 115 | } |
| 116 | |
| 117 | fn isPtr2Size(ms: MultiSym) bool { |
| 118 | const map = .{ |
| 119 | .{ .riscv64, 16 }, |
| 120 | .{ .mips, 8 }, |
| 121 | .{ .i386, 8 }, |
| 122 | .{ .x86_64, 16 }, |
| 123 | .{ .powerpc, 8 }, |
| 124 | .{ .powerpc64, 16 }, |
| 125 | .{ .aarch64, 16 }, |
| 126 | }; |
| 127 | inline for (map) |item| { |
| 128 | const arch = item[0]; |
| 129 | const size = item[1]; |
| 130 | const arch_index = archIndex(arch); |
| 131 | if (ms.present[arch_index] and ms.size[arch_index] != size) { |
| 132 | return false; |
| 133 | } |
| 134 | } |
| 135 | return true; |
| 136 | } |
| 137 | |
| 138 | fn isWeak64(ms: MultiSym) bool { |
| 139 | const map = .{ |
| 140 | .{ .riscv64, 2 }, |
| 141 | .{ .mips, 1 }, |
| 142 | .{ .i386, 1 }, |
| 143 | .{ .x86_64, 2 }, |
| 144 | .{ .powerpc, 1 }, |
| 145 | .{ .powerpc64, 2 }, |
| 146 | .{ .aarch64, 2 }, |
| 147 | }; |
| 148 | inline for (map) |item| { |
| 149 | const arch = item[0]; |
| 150 | const binding = item[1]; |
| 151 | const arch_index = archIndex(arch); |
| 152 | if (ms.present[arch_index] and ms.binding[arch_index] != binding) { |
| 153 | return false; |
| 154 | } |
| 155 | } |
| 156 | return true; |
| 157 | } |
| 36 | 158 | }; |
| 37 | 159 | |
| 38 | 160 | const Parse = struct { |
| 39 | 161 | arena: mem.Allocator, |
| 40 | 162 | sym_table: *std.StringArrayHashMap(MultiSym), |
| 41 | 163 | sections: *std.StringArrayHashMap(void), |
| 164 | blacklist: std.StringArrayHashMap(void), |
| 42 | 165 | elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8, |
| 43 | 166 | header: elf.Header, |
| 44 | 167 | arch: std.Target.Cpu.Arch, |
| ... | ... | @@ -54,6 +177,15 @@ pub fn main() !void { |
| 54 | 177 | |
| 55 | 178 | var build_all_dir = try std.fs.cwd().openDir(build_all_path, .{}); |
| 56 | 179 | |
| 180 | var sym_table = std.StringArrayHashMap(MultiSym).init(arena); |
| 181 | var sections = std.StringArrayHashMap(void).init(arena); |
| 182 | var blacklist = std.StringArrayHashMap(void).init(arena); |
| 183 | |
| 184 | try blacklist.ensureUnusedCapacity(blacklisted_symbols.len); |
| 185 | for (blacklisted_symbols) |name| { |
| 186 | blacklist.putAssumeCapacityNoClobber(name, {}); |
| 187 | } |
| 188 | |
| 57 | 189 | for (arches) |arch| { |
| 58 | 190 | const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{@tagName(arch)}); |
| 59 | 191 | |
| ... | ... | @@ -68,13 +200,11 @@ pub fn main() !void { |
| 68 | 200 | ); |
| 69 | 201 | const header = try elf.Header.parse(elf_bytes[0..@sizeOf(elf.Elf64_Ehdr)]); |
| 70 | 202 | |
| 71 | | var sym_table = std.StringArrayHashMap(MultiSym).init(arena); |
| 72 | | var sections = std.StringArrayHashMap(void).init(arena); |
| 73 | | |
| 74 | 203 | const parse: Parse = .{ |
| 75 | 204 | .arena = arena, |
| 76 | 205 | .sym_table = &sym_table, |
| 77 | 206 | .sections = &sections, |
| 207 | .blacklist = blacklist, |
| 78 | 208 | .elf_bytes = elf_bytes, |
| 79 | 209 | .header = header, |
| 80 | 210 | .arch = arch, |
| ... | ... | @@ -93,50 +223,132 @@ pub fn main() !void { |
| 93 | 223 | } |
| 94 | 224 | |
| 95 | 225 | const stdout = std.io.getStdOut().writer(); |
| 96 | | _ = stdout; |
| 97 | | |
| 98 | | //var prev_section: u16 = 0; |
| 99 | | //for (all_syms) |sym| { |
| 100 | | // const this_section = s(sym.st_shndx); |
| 101 | | // if (this_section != prev_section) { |
| 102 | | // prev_section = this_section; |
| 103 | | // const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); |
| 104 | | // try stdout.print("{s}\n", .{sh_name}); |
| 105 | | // } |
| 106 | | |
| 107 | | // switch (binding) { |
| 108 | | // elf.STB_GLOBAL => { |
| 109 | | // try stdout.print(".globl {s}\n", .{name}); |
| 110 | | // }, |
| 111 | | // elf.STB_WEAK => { |
| 112 | | // try stdout.print(".weak {s}\n", .{name}); |
| 113 | | // }, |
| 114 | | // else => unreachable, |
| 115 | | // } |
| 116 | | |
| 117 | | // switch (ty) { |
| 118 | | // elf.STT_NOTYPE => {}, |
| 119 | | // elf.STT_FUNC => { |
| 120 | | // try stdout.print(".type {s}, %function;\n", .{name}); |
| 121 | | // // omitting the size is OK for functions |
| 122 | | // }, |
| 123 | | // elf.STT_OBJECT => { |
| 124 | | // try stdout.print(".type {s}, %object;\n", .{name}); |
| 125 | | // if (size != 0) { |
| 126 | | // try stdout.print(".size {s}, {d}\n", .{ name, size }); |
| 127 | | // } |
| 128 | | // }, |
| 129 | | // else => unreachable, |
| 130 | | // } |
| 131 | | |
| 132 | | // switch (visib) { |
| 133 | | // .DEFAULT => {}, |
| 134 | | // .PROTECTED => try stdout.print(".protected {s}\n", .{name}), |
| 135 | | // .INTERNAL, .HIDDEN => unreachable, |
| 136 | | // } |
| 137 | | |
| 138 | | // try stdout.print("{s}:\n", .{name}); |
| 139 | | //} |
| 226 | try stdout.writeAll( |
| 227 | \\#ifdef PTR64 |
| 228 | \\#define WEAK64 .weak |
| 229 | \\#define PTR_SIZE_BYTES 8 |
| 230 | \\#define PTR2_SIZE_BYTES 16 |
| 231 | \\#else |
| 232 | \\#define WEAK64 .globl |
| 233 | \\#define PTR_SIZE_BYTES 4 |
| 234 | \\#define PTR2_SIZE_BYTES 8 |
| 235 | \\#endif |
| 236 | \\ |
| 237 | ); |
| 238 | |
| 239 | var prev_section: u16 = std.math.maxInt(u16); |
| 240 | var prev_pp_state: enum { none, ptr32, special } = .none; |
| 241 | for (sym_table.values()) |multi_sym, sym_index| { |
| 242 | const name = sym_table.keys()[sym_index]; |
| 243 | |
| 244 | if (multi_sym.section != prev_section) { |
| 245 | prev_section = multi_sym.section; |
| 246 | const sh_name = sections.keys()[multi_sym.section]; |
| 247 | try stdout.print("{s}\n", .{sh_name}); |
| 248 | } |
| 249 | |
| 250 | if (multi_sym.allPresent()) { |
| 251 | switch (prev_pp_state) { |
| 252 | .none => {}, |
| 253 | .ptr32, .special => { |
| 254 | try stdout.writeAll("#endif\n"); |
| 255 | prev_pp_state = .none; |
| 256 | }, |
| 257 | } |
| 258 | } else if (multi_sym.is32Only()) { |
| 259 | switch (prev_pp_state) { |
| 260 | .none => { |
| 261 | try stdout.writeAll("#ifdef PTR32\n"); |
| 262 | prev_pp_state = .ptr32; |
| 263 | }, |
| 264 | .special => { |
| 265 | try stdout.writeAll("#endif\n#ifdef PTR32\n"); |
| 266 | prev_pp_state = .ptr32; |
| 267 | }, |
| 268 | .ptr32 => {}, |
| 269 | } |
| 270 | } else { |
| 271 | switch (prev_pp_state) { |
| 272 | .none => {}, |
| 273 | .special, .ptr32 => { |
| 274 | try stdout.writeAll("#endif\n"); |
| 275 | }, |
| 276 | } |
| 277 | prev_pp_state = .special; |
| 278 | |
| 279 | var first = true; |
| 280 | try stdout.writeAll("#if "); |
| 281 | |
| 282 | for (arches) |arch, i| { |
| 283 | if (multi_sym.present[i]) continue; |
| 284 | |
| 285 | if (!first) try stdout.writeAll(" && "); |
| 286 | first = false; |
| 287 | try stdout.print("!defined(ARCH_{s})", .{@tagName(arch)}); |
| 288 | } |
| 289 | |
| 290 | try stdout.writeAll("\n"); |
| 291 | } |
| 292 | |
| 293 | if (multi_sym.commonBinding()) |binding| { |
| 294 | switch (binding) { |
| 295 | elf.STB_GLOBAL => { |
| 296 | try stdout.print(".globl {s}\n", .{name}); |
| 297 | }, |
| 298 | elf.STB_WEAK => { |
| 299 | try stdout.print(".weak {s}\n", .{name}); |
| 300 | }, |
| 301 | else => unreachable, |
| 302 | } |
| 303 | } else if (multi_sym.isWeak64()) { |
| 304 | try stdout.print("WEAK64 {s}\n", .{name}); |
| 305 | } else { |
| 306 | for (arches) |arch, i| { |
| 307 | log.info("symbol '{s}' binding on {s}: {d}", .{ |
| 308 | name, @tagName(arch), multi_sym.binding[i], |
| 309 | }); |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | switch (multi_sym.ty) { |
| 314 | elf.STT_NOTYPE => {}, |
| 315 | elf.STT_FUNC => { |
| 316 | try stdout.print(".type {s}, %function;\n", .{name}); |
| 317 | // omitting the size is OK for functions |
| 318 | }, |
| 319 | elf.STT_OBJECT => { |
| 320 | try stdout.print(".type {s}, %object;\n", .{name}); |
| 321 | if (multi_sym.commonSize()) |size| { |
| 322 | try stdout.print(".size {s}, {d}\n", .{ name, size }); |
| 323 | } else if (multi_sym.isPtrSize()) { |
| 324 | try stdout.print(".size {s}, PTR_SIZE_BYTES\n", .{name}); |
| 325 | } else if (multi_sym.isPtr2Size()) { |
| 326 | try stdout.print(".size {s}, PTR2_SIZE_BYTES\n", .{name}); |
| 327 | } else { |
| 328 | for (arches) |arch, i| { |
| 329 | log.info("symbol '{s}' size on {s}: {d}", .{ |
| 330 | name, @tagName(arch), multi_sym.size[i], |
| 331 | }); |
| 332 | } |
| 333 | //try stdout.print(".size {s}, {d}\n", .{ name, size }); |
| 334 | } |
| 335 | }, |
| 336 | else => unreachable, |
| 337 | } |
| 338 | |
| 339 | switch (multi_sym.visib) { |
| 340 | .DEFAULT => {}, |
| 341 | .PROTECTED => try stdout.print(".protected {s}\n", .{name}), |
| 342 | .INTERNAL, .HIDDEN => unreachable, |
| 343 | } |
| 344 | |
| 345 | try stdout.print("{s}:\n", .{name}); |
| 346 | } |
| 347 | |
| 348 | switch (prev_pp_state) { |
| 349 | .none => {}, |
| 350 | .ptr32, .special => try stdout.writeAll("#endif\n"), |
| 351 | } |
| 140 | 352 | } |
| 141 | 353 | |
| 142 | 354 | fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) !void { |
| ... | ... | @@ -205,9 +417,10 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 205 | 417 | const visib = @intToEnum(elf.STV, @truncate(u2, sym.st_other)); |
| 206 | 418 | const size = s(sym.st_size); |
| 207 | 419 | |
| 420 | if (parse.blacklist.contains(name)) continue; |
| 421 | |
| 208 | 422 | if (size == 0) { |
| 209 | 423 | log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name }); |
| 210 | | continue; |
| 211 | 424 | } |
| 212 | 425 | |
| 213 | 426 | switch (binding) { |
| ... | ... | @@ -245,26 +458,50 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 245 | 458 | if (gop.value_ptr.section != section_index_map[this_section]) { |
| 246 | 459 | const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); |
| 247 | 460 | fatal("symbol '{s}' in arch {s} is in section {s} but in arch {s} is in section {s}", .{ |
| 248 | | name, @tagName(parse.arch), sh_name, |
| 249 | | archSetName(gop.value_ptr.present), parse.sections.keys()[gop.value_ptr.section], |
| 461 | name, |
| 462 | @tagName(parse.arch), |
| 463 | sh_name, |
| 464 | archSetName(gop.value_ptr.present), |
| 465 | parse.sections.keys()[gop.value_ptr.section], |
| 250 | 466 | }); |
| 251 | 467 | } |
| 252 | | if (gop.value_ptr.ty != ty) { |
| 468 | if (gop.value_ptr.ty != ty) blk: { |
| 469 | if (ty == elf.STT_NOTYPE) { |
| 470 | log.warn("symbol '{s}' in arch {s} has type {d} but in arch {s} has type {d}. going with the one that is not STT_NOTYPE", .{ |
| 471 | name, |
| 472 | @tagName(parse.arch), |
| 473 | ty, |
| 474 | archSetName(gop.value_ptr.present), |
| 475 | gop.value_ptr.ty, |
| 476 | }); |
| 477 | break :blk; |
| 478 | } |
| 479 | if (gop.value_ptr.ty == elf.STT_NOTYPE) { |
| 480 | log.warn("symbol '{s}' in arch {s} has type {d} but in arch {s} has type {d}. going with the one that is not STT_NOTYPE", .{ |
| 481 | name, |
| 482 | @tagName(parse.arch), |
| 483 | ty, |
| 484 | archSetName(gop.value_ptr.present), |
| 485 | gop.value_ptr.ty, |
| 486 | }); |
| 487 | gop.value_ptr.ty = ty; |
| 488 | break :blk; |
| 489 | } |
| 253 | 490 | fatal("symbol '{s}' in arch {s} has type {d} but in arch {s} has type {d}", .{ |
| 254 | | name, @tagName(parse.arch), ty, |
| 255 | | archSetName(gop.value_ptr.present), gop.value_ptr.ty, |
| 256 | | }); |
| 257 | | } |
| 258 | | if (gop.value_ptr.binding != binding) { |
| 259 | | fatal("symbol '{s}' in arch {s} has binding {d} but in arch {s} has binding {d}", .{ |
| 260 | | name, @tagName(parse.arch), binding, |
| 261 | | archSetName(gop.value_ptr.present), gop.value_ptr.binding, |
| 491 | name, |
| 492 | @tagName(parse.arch), |
| 493 | ty, |
| 494 | archSetName(gop.value_ptr.present), |
| 495 | gop.value_ptr.ty, |
| 262 | 496 | }); |
| 263 | 497 | } |
| 264 | 498 | if (gop.value_ptr.visib != visib) { |
| 265 | 499 | fatal("symbol '{s}' in arch {s} has visib {s} but in arch {s} has visib {s}", .{ |
| 266 | | name, @tagName(parse.arch), @tagName(visib), |
| 267 | | archSetName(gop.value_ptr.present), @tagName(gop.value_ptr.visib), |
| 500 | name, |
| 501 | @tagName(parse.arch), |
| 502 | @tagName(visib), |
| 503 | archSetName(gop.value_ptr.present), |
| 504 | @tagName(gop.value_ptr.visib), |
| 268 | 505 | }); |
| 269 | 506 | } |
| 270 | 507 | } else { |
| ... | ... | @@ -272,13 +509,14 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 272 | 509 | .present = [1]bool{false} ** arches.len, |
| 273 | 510 | .section = section_index_map[this_section], |
| 274 | 511 | .ty = ty, |
| 275 | | .binding = binding, |
| 512 | .binding = [1]u4{0} ** arches.len, |
| 276 | 513 | .visib = visib, |
| 277 | 514 | .size = [1]u64{0} ** arches.len, |
| 278 | 515 | }; |
| 279 | 516 | } |
| 280 | 517 | gop.value_ptr.present[archIndex(parse.arch)] = true; |
| 281 | 518 | gop.value_ptr.size[archIndex(parse.arch)] = size; |
| 519 | gop.value_ptr.binding[archIndex(parse.arch)] = binding; |
| 282 | 520 | } |
| 283 | 521 | } |
| 284 | 522 | |
| ... | ... | @@ -291,6 +529,7 @@ fn archIndex(arch: std.Target.Cpu.Arch) u8 { |
| 291 | 529 | .x86_64 => 3, |
| 292 | 530 | .powerpc => 4, |
| 293 | 531 | .powerpc64 => 5, |
| 532 | .aarch64 => 6, |
| 294 | 533 | else => unreachable, |
| 295 | 534 | // zig fmt: on |
| 296 | 535 | }; |
| ... | ... | @@ -309,3 +548,211 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn { |
| 309 | 548 | log.err(format, args); |
| 310 | 549 | std.process.exit(1); |
| 311 | 550 | } |
| 551 | |
| 552 | const blacklisted_symbols = [_][]const u8{ |
| 553 | "__adddf3", |
| 554 | "__addkf3", |
| 555 | "__addsf3", |
| 556 | "__addtf3", |
| 557 | "__ashldi3", |
| 558 | "__ashlti3", |
| 559 | "__ashrdi3", |
| 560 | "__ashrti3", |
| 561 | "__atomic_compare_exchange", |
| 562 | "__atomic_compare_exchange_1", |
| 563 | "__atomic_compare_exchange_2", |
| 564 | "__atomic_compare_exchange_4", |
| 565 | "__atomic_compare_exchange_8", |
| 566 | "__atomic_exchange", |
| 567 | "__atomic_exchange_1", |
| 568 | "__atomic_exchange_2", |
| 569 | "__atomic_exchange_4", |
| 570 | "__atomic_exchange_8", |
| 571 | "__atomic_fetch_add_1", |
| 572 | "__atomic_fetch_add_2", |
| 573 | "__atomic_fetch_add_4", |
| 574 | "__atomic_fetch_add_8", |
| 575 | "__atomic_fetch_and_1", |
| 576 | "__atomic_fetch_and_2", |
| 577 | "__atomic_fetch_and_4", |
| 578 | "__atomic_fetch_and_8", |
| 579 | "__atomic_fetch_nand_1", |
| 580 | "__atomic_fetch_nand_2", |
| 581 | "__atomic_fetch_nand_4", |
| 582 | "__atomic_fetch_nand_8", |
| 583 | "__atomic_fetch_or_1", |
| 584 | "__atomic_fetch_or_2", |
| 585 | "__atomic_fetch_or_4", |
| 586 | "__atomic_fetch_or_8", |
| 587 | "__atomic_fetch_sub_1", |
| 588 | "__atomic_fetch_sub_2", |
| 589 | "__atomic_fetch_sub_4", |
| 590 | "__atomic_fetch_sub_8", |
| 591 | "__atomic_fetch_xor_1", |
| 592 | "__atomic_fetch_xor_2", |
| 593 | "__atomic_fetch_xor_4", |
| 594 | "__atomic_fetch_xor_8", |
| 595 | "__atomic_load", |
| 596 | "__atomic_load_1", |
| 597 | "__atomic_load_2", |
| 598 | "__atomic_load_4", |
| 599 | "__atomic_load_8", |
| 600 | "__atomic_store", |
| 601 | "__atomic_store_1", |
| 602 | "__atomic_store_2", |
| 603 | "__atomic_store_4", |
| 604 | "__atomic_store_8", |
| 605 | "__clear_cache", |
| 606 | "__clzdi2", |
| 607 | "__clzsi2", |
| 608 | "__clzti2", |
| 609 | "__cmpdf2", |
| 610 | "__cmpsf2", |
| 611 | "__cmptf2", |
| 612 | "__ctzdi2", |
| 613 | "__ctzsi2", |
| 614 | "__ctzti2", |
| 615 | "__divdf3", |
| 616 | "__divdi3", |
| 617 | "__divkf3", |
| 618 | "__divmoddi4", |
| 619 | "__divmodsi4", |
| 620 | "__divsf3", |
| 621 | "__divsi3", |
| 622 | "__divtf3", |
| 623 | "__divti3", |
| 624 | "__dlstart", |
| 625 | "__eqdf2", |
| 626 | "__eqkf2", |
| 627 | "__eqsf2", |
| 628 | "__eqtf2", |
| 629 | "__extenddfkf2", |
| 630 | "__extenddftf2", |
| 631 | "__extendhfsf2", |
| 632 | "__extendhftf2", |
| 633 | "__extendsfdf2", |
| 634 | "__extendsfkf2", |
| 635 | "__extendsftf2", |
| 636 | "__ffsdi2", |
| 637 | "__ffssi2", |
| 638 | "__ffsti2", |
| 639 | "__fixdfdi", |
| 640 | "__fixdfsi", |
| 641 | "__fixdfti", |
| 642 | "__fixkfdi", |
| 643 | "__fixkfsi", |
| 644 | "__fixsfdi", |
| 645 | "__fixsfsi", |
| 646 | "__fixsfti", |
| 647 | "__fixtfdi", |
| 648 | "__fixtfsi", |
| 649 | "__fixtfti", |
| 650 | "__fixunsdfdi", |
| 651 | "__fixunsdfsi", |
| 652 | "__fixunsdfti", |
| 653 | "__fixunskfdi", |
| 654 | "__fixunskfsi", |
| 655 | "__fixunssfdi", |
| 656 | "__fixunssfsi", |
| 657 | "__fixunssfti", |
| 658 | "__fixunstfdi", |
| 659 | "__fixunstfsi", |
| 660 | "__fixunstfti", |
| 661 | "__floatdidf", |
| 662 | "__floatdikf", |
| 663 | "__floatdisf", |
| 664 | "__floatditf", |
| 665 | "__floatsidf", |
| 666 | "__floatsikf", |
| 667 | "__floatsisf", |
| 668 | "__floatsitf", |
| 669 | "__floattidf", |
| 670 | "__floattisf", |
| 671 | "__floattitf", |
| 672 | "__floatundidf", |
| 673 | "__floatundikf", |
| 674 | "__floatundisf", |
| 675 | "__floatunditf", |
| 676 | "__floatunsidf", |
| 677 | "__floatunsikf", |
| 678 | "__floatunsisf", |
| 679 | "__floatunsitf", |
| 680 | "__floatuntidf", |
| 681 | "__floatuntisf", |
| 682 | "__floatuntitf", |
| 683 | "__gedf2", |
| 684 | "__gekf2", |
| 685 | "__gesf2", |
| 686 | "__getf2", |
| 687 | "__gnu_f2h_ieee", |
| 688 | "__gnu_h2f_ieee", |
| 689 | "__gtdf2", |
| 690 | "__gtkf2", |
| 691 | "__gtsf2", |
| 692 | "__gttf2", |
| 693 | "__ledf2", |
| 694 | "__lekf2", |
| 695 | "__lesf2", |
| 696 | "__letf2", |
| 697 | "__lshrdi3", |
| 698 | "__lshrti3", |
| 699 | "__ltdf2", |
| 700 | "__ltkf2", |
| 701 | "__ltsf2", |
| 702 | "__lttf2", |
| 703 | "__moddi3", |
| 704 | "__modsi3", |
| 705 | "__modti3", |
| 706 | "__muldc3", |
| 707 | "__muldf3", |
| 708 | "__muldi3", |
| 709 | "__mulkf3", |
| 710 | "__mulodi4", |
| 711 | "__muloti4", |
| 712 | "__mulsc3", |
| 713 | "__mulsf3", |
| 714 | "__mulsi3", |
| 715 | "__multc3", |
| 716 | "__multf3", |
| 717 | "__multi3", |
| 718 | "__mulxc3", |
| 719 | "__nedf2", |
| 720 | "__negdf2", |
| 721 | "__negsf2", |
| 722 | "__nekf2", |
| 723 | "__nesf2", |
| 724 | "__netf2", |
| 725 | "__paritydi2", |
| 726 | "__paritysi2", |
| 727 | "__parityti2", |
| 728 | "__popcountdi2", |
| 729 | "__popcountsi2", |
| 730 | "__popcountti2", |
| 731 | "__subdf3", |
| 732 | "__subkf3", |
| 733 | "__subsf3", |
| 734 | "__subtf3", |
| 735 | "__truncdfhf2", |
| 736 | "__truncdfsf2", |
| 737 | "__trunckfdf2", |
| 738 | "__trunckfsf2", |
| 739 | "__truncsfhf2", |
| 740 | "__trunctfdf2", |
| 741 | "__trunctfhf2", |
| 742 | "__trunctfsf2", |
| 743 | "__udivdi3", |
| 744 | "__udivmoddi4", |
| 745 | "__udivmodsi4", |
| 746 | "__udivmodti4", |
| 747 | "__udivsi3", |
| 748 | "__udivti3", |
| 749 | "__umoddi3", |
| 750 | "__umodsi3", |
| 751 | "__umodti3", |
| 752 | "__unorddf2", |
| 753 | "__unordkf2", |
| 754 | "__unordsf2", |
| 755 | "__unordtf2", |
| 756 | "__zig_probe_stack", |
| 757 | "fmaq", |
| 758 | }; |