| ... | @@ -1,15 +1,25 @@ | ... | @@ -1,15 +1,25 @@ |
| 1 | //! Example usage: | 1 | //! Example usage: |
| 2 | //! ./gen_stubs /path/to/musl/build-all | 2 | //! ./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 i386 mips mips64 powerpc powerpc64 riscv64 x86_64 | 5 | //! arm i386 mips mips64 powerpc powerpc64 riscv64 x86_64 |
| 6 | //! | 6 | //! |
| 7 | //! ...each with 'lib/libc.so' inside of them. | 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 | // TODO: pick the best index to put them into instead of at the end | 20 | // TODO: pick the best index to put them into instead of at the end |
| 10 | // - e.g. find a common previous symbol and put it after that one | 21 | // - e.g. find a common previous symbol and put it after that one |
| 11 | // - they definitely need to go into the correct section | 22 | // - they definitely need to go into the correct section |
| 12 | // TODO: emit MultiSyms to use the preprocessor | | |
| 13 | | 23 | |
| 14 | const std = @import("std"); | 24 | const std = @import("std"); |
| 15 | const builtin = std.builtin; | 25 | const builtin = std.builtin; |
| ... | @@ -18,9 +28,9 @@ const log = std.log; | ... | @@ -18,9 +28,9 @@ const log = std.log; |
| 18 | const elf = std.elf; | 28 | const elf = std.elf; |
| 19 | const native_endian = @import("builtin").target.cpu.arch.endian(); | 29 | const native_endian = @import("builtin").target.cpu.arch.endian(); |
| 20 | | 30 | |
| 21 | const arches: [6]std.Target.Cpu.Arch = blk: { | 31 | const arches: [7]std.Target.Cpu.Arch = blk: { |
| 22 | var result: [6]std.Target.Cpu.Arch = undefined; | 32 | var result: [7]std.Target.Cpu.Arch = undefined; |
| 23 | for (.{ .riscv64, .mips, .i386, .x86_64, .powerpc, .powerpc64 }) |arch| { | 33 | for (.{ .riscv64, .mips, .i386, .x86_64, .powerpc, .powerpc64, .aarch64 }) |arch| { |
| 24 | result[archIndex(arch)] = arch; | 34 | result[archIndex(arch)] = arch; |
| 25 | } | 35 | } |
| 26 | break :blk result; | 36 | break :blk result; |
| ... | @@ -29,16 +39,129 @@ const arches: [6]std.Target.Cpu.Arch = blk: { | ... | @@ -29,16 +39,129 @@ const arches: [6]std.Target.Cpu.Arch = blk: { |
| 29 | const MultiSym = struct { | 39 | const MultiSym = struct { |
| 30 | size: [arches.len]u64, | 40 | size: [arches.len]u64, |
| 31 | present: [arches.len]bool, | 41 | present: [arches.len]bool, |
| | 42 | binding: [arches.len]u4, |
| 32 | section: u16, | 43 | section: u16, |
| 33 | ty: u4, | 44 | ty: u4, |
| 34 | binding: u4, | | |
| 35 | visib: elf.STV, | 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 | const Parse = struct { | 160 | const Parse = struct { |
| 39 | arena: mem.Allocator, | 161 | arena: mem.Allocator, |
| 40 | sym_table: *std.StringArrayHashMap(MultiSym), | 162 | sym_table: *std.StringArrayHashMap(MultiSym), |
| 41 | sections: *std.StringArrayHashMap(void), | 163 | sections: *std.StringArrayHashMap(void), |
| | 164 | blacklist: std.StringArrayHashMap(void), |
| 42 | elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8, | 165 | elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8, |
| 43 | header: elf.Header, | 166 | header: elf.Header, |
| 44 | arch: std.Target.Cpu.Arch, | 167 | arch: std.Target.Cpu.Arch, |
| ... | @@ -54,6 +177,15 @@ pub fn main() !void { | ... | @@ -54,6 +177,15 @@ pub fn main() !void { |
| 54 | | 177 | |
| 55 | var build_all_dir = try std.fs.cwd().openDir(build_all_path, .{}); | 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 | for (arches) |arch| { | 189 | for (arches) |arch| { |
| 58 | const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{@tagName(arch)}); | 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,13 +200,11 @@ pub fn main() !void { |
| 68 | ); | 200 | ); |
| 69 | const header = try elf.Header.parse(elf_bytes[0..@sizeOf(elf.Elf64_Ehdr)]); | 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 | const parse: Parse = .{ | 203 | const parse: Parse = .{ |
| 75 | .arena = arena, | 204 | .arena = arena, |
| 76 | .sym_table = &sym_table, | 205 | .sym_table = &sym_table, |
| 77 | .sections = &sections, | 206 | .sections = &sections, |
| | 207 | .blacklist = blacklist, |
| 78 | .elf_bytes = elf_bytes, | 208 | .elf_bytes = elf_bytes, |
| 79 | .header = header, | 209 | .header = header, |
| 80 | .arch = arch, | 210 | .arch = arch, |
| ... | @@ -93,50 +223,132 @@ pub fn main() !void { | ... | @@ -93,50 +223,132 @@ pub fn main() !void { |
| 93 | } | 223 | } |
| 94 | | 224 | |
| 95 | const stdout = std.io.getStdOut().writer(); | 225 | const stdout = std.io.getStdOut().writer(); |
| 96 | _ = stdout; | 226 | try stdout.writeAll( |
| 97 | | 227 | \\#ifdef PTR64 |
| 98 | //var prev_section: u16 = 0; | 228 | \\#define WEAK64 .weak |
| 99 | //for (all_syms) |sym| { | 229 | \\#define PTR_SIZE_BYTES 8 |
| 100 | // const this_section = s(sym.st_shndx); | 230 | \\#define PTR2_SIZE_BYTES 16 |
| 101 | // if (this_section != prev_section) { | 231 | \\#else |
| 102 | // prev_section = this_section; | 232 | \\#define WEAK64 .globl |
| 103 | // const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); | 233 | \\#define PTR_SIZE_BYTES 4 |
| 104 | // try stdout.print("{s}\n", .{sh_name}); | 234 | \\#define PTR2_SIZE_BYTES 8 |
| 105 | // } | 235 | \\#endif |
| 106 | | 236 | \\ |
| 107 | // switch (binding) { | 237 | ); |
| 108 | // elf.STB_GLOBAL => { | 238 | |
| 109 | // try stdout.print(".globl {s}\n", .{name}); | 239 | var prev_section: u16 = std.math.maxInt(u16); |
| 110 | // }, | 240 | var prev_pp_state: enum { none, ptr32, special } = .none; |
| 111 | // elf.STB_WEAK => { | 241 | for (sym_table.values()) |multi_sym, sym_index| { |
| 112 | // try stdout.print(".weak {s}\n", .{name}); | 242 | const name = sym_table.keys()[sym_index]; |
| 113 | // }, | 243 | |
| 114 | // else => unreachable, | 244 | if (multi_sym.section != prev_section) { |
| 115 | // } | 245 | prev_section = multi_sym.section; |
| 116 | | 246 | const sh_name = sections.keys()[multi_sym.section]; |
| 117 | // switch (ty) { | 247 | try stdout.print("{s}\n", .{sh_name}); |
| 118 | // elf.STT_NOTYPE => {}, | 248 | } |
| 119 | // elf.STT_FUNC => { | 249 | |
| 120 | // try stdout.print(".type {s}, %function;\n", .{name}); | 250 | if (multi_sym.allPresent()) { |
| 121 | // // omitting the size is OK for functions | 251 | switch (prev_pp_state) { |
| 122 | // }, | 252 | .none => {}, |
| 123 | // elf.STT_OBJECT => { | 253 | .ptr32, .special => { |
| 124 | // try stdout.print(".type {s}, %object;\n", .{name}); | 254 | try stdout.writeAll("#endif\n"); |
| 125 | // if (size != 0) { | 255 | prev_pp_state = .none; |
| 126 | // try stdout.print(".size {s}, {d}\n", .{ name, size }); | 256 | }, |
| 127 | // } | 257 | } |
| 128 | // }, | 258 | } else if (multi_sym.is32Only()) { |
| 129 | // else => unreachable, | 259 | switch (prev_pp_state) { |
| 130 | // } | 260 | .none => { |
| 131 | | 261 | try stdout.writeAll("#ifdef PTR32\n"); |
| 132 | // switch (visib) { | 262 | prev_pp_state = .ptr32; |
| 133 | // .DEFAULT => {}, | 263 | }, |
| 134 | // .PROTECTED => try stdout.print(".protected {s}\n", .{name}), | 264 | .special => { |
| 135 | // .INTERNAL, .HIDDEN => unreachable, | 265 | try stdout.writeAll("#endif\n#ifdef PTR32\n"); |
| 136 | // } | 266 | prev_pp_state = .ptr32; |
| 137 | | 267 | }, |
| 138 | // try stdout.print("{s}:\n", .{name}); | 268 | .ptr32 => {}, |
| 139 | //} | 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 | fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) !void { | 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,9 +417,10 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 205 | const visib = @intToEnum(elf.STV, @truncate(u2, sym.st_other)); | 417 | const visib = @intToEnum(elf.STV, @truncate(u2, sym.st_other)); |
| 206 | const size = s(sym.st_size); | 418 | const size = s(sym.st_size); |
| 207 | | 419 | |
| | 420 | if (parse.blacklist.contains(name)) continue; |
| | 421 | |
| 208 | if (size == 0) { | 422 | if (size == 0) { |
| 209 | log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name }); | 423 | log.warn("{s}: symbol '{s}' has size 0", .{ @tagName(parse.arch), name }); |
| 210 | continue; | | |
| 211 | } | 424 | } |
| 212 | | 425 | |
| 213 | switch (binding) { | 426 | switch (binding) { |
| ... | @@ -245,26 +458,50 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) | ... | @@ -245,26 +458,50 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 245 | if (gop.value_ptr.section != section_index_map[this_section]) { | 458 | if (gop.value_ptr.section != section_index_map[this_section]) { |
| 246 | const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); | 459 | const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); |
| 247 | fatal("symbol '{s}' in arch {s} is in section {s} but in arch {s} is in section {s}", .{ | 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, | 461 | name, |
| 249 | archSetName(gop.value_ptr.present), parse.sections.keys()[gop.value_ptr.section], | 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 | fatal("symbol '{s}' in arch {s} has type {d} but in arch {s} has type {d}", .{ | 490 | fatal("symbol '{s}' in arch {s} has type {d} but in arch {s} has type {d}", .{ |
| 254 | name, @tagName(parse.arch), ty, | 491 | name, |
| 255 | archSetName(gop.value_ptr.present), gop.value_ptr.ty, | 492 | @tagName(parse.arch), |
| 256 | }); | 493 | ty, |
| 257 | } | 494 | archSetName(gop.value_ptr.present), |
| 258 | if (gop.value_ptr.binding != binding) { | 495 | gop.value_ptr.ty, |
| 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, | | |
| 262 | }); | 496 | }); |
| 263 | } | 497 | } |
| 264 | if (gop.value_ptr.visib != visib) { | 498 | if (gop.value_ptr.visib != visib) { |
| 265 | fatal("symbol '{s}' in arch {s} has visib {s} but in arch {s} has visib {s}", .{ | 499 | fatal("symbol '{s}' in arch {s} has visib {s} but in arch {s} has visib {s}", .{ |
| 266 | name, @tagName(parse.arch), @tagName(visib), | 500 | name, |
| 267 | archSetName(gop.value_ptr.present), @tagName(gop.value_ptr.visib), | 501 | @tagName(parse.arch), |
| | 502 | @tagName(visib), |
| | 503 | archSetName(gop.value_ptr.present), |
| | 504 | @tagName(gop.value_ptr.visib), |
| 268 | }); | 505 | }); |
| 269 | } | 506 | } |
| 270 | } else { | 507 | } else { |
| ... | @@ -272,13 +509,14 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) | ... | @@ -272,13 +509,14 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian) |
| 272 | .present = [1]bool{false} ** arches.len, | 509 | .present = [1]bool{false} ** arches.len, |
| 273 | .section = section_index_map[this_section], | 510 | .section = section_index_map[this_section], |
| 274 | .ty = ty, | 511 | .ty = ty, |
| 275 | .binding = binding, | 512 | .binding = [1]u4{0} ** arches.len, |
| 276 | .visib = visib, | 513 | .visib = visib, |
| 277 | .size = [1]u64{0} ** arches.len, | 514 | .size = [1]u64{0} ** arches.len, |
| 278 | }; | 515 | }; |
| 279 | } | 516 | } |
| 280 | gop.value_ptr.present[archIndex(parse.arch)] = true; | 517 | gop.value_ptr.present[archIndex(parse.arch)] = true; |
| 281 | gop.value_ptr.size[archIndex(parse.arch)] = size; | 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,6 +529,7 @@ fn archIndex(arch: std.Target.Cpu.Arch) u8 { |
| 291 | .x86_64 => 3, | 529 | .x86_64 => 3, |
| 292 | .powerpc => 4, | 530 | .powerpc => 4, |
| 293 | .powerpc64 => 5, | 531 | .powerpc64 => 5, |
| | 532 | .aarch64 => 6, |
| 294 | else => unreachable, | 533 | else => unreachable, |
| 295 | // zig fmt: on | 534 | // zig fmt: on |
| 296 | }; | 535 | }; |
| ... | @@ -309,3 +548,211 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn { | ... | @@ -309,3 +548,211 @@ fn fatal(comptime format: []const u8, args: anytype) noreturn { |
| 309 | log.err(format, args); | 548 | log.err(format, args); |
| 310 | std.process.exit(1); | 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 | }; |