| ... | ... | @@ -590,6 +590,17 @@ fn initSymbolStabs(self: *Object, nlists: anytype, macho_file: *MachO) !void { |
| 590 | 590 | const syms = self.symtab.items(.nlist); |
| 591 | 591 | const sym_lookup = SymbolLookup{ .ctx = self, .entries = nlists }; |
| 592 | 592 | |
| 593 | // We need to cache nlists by name so that we can properly resolve local N_GSYM stabs. |
| 594 | // What happens is `ld -r` will emit an N_GSYM stab for a symbol that may be either an |
| 595 | // external or private external. |
| 596 | var addr_lookup = std.StringHashMap(u64).init(gpa); |
| 597 | defer addr_lookup.deinit(); |
| 598 | for (syms) |sym| { |
| 599 | if (sym.sect() and (sym.ext() or sym.pext())) { |
| 600 | try addr_lookup.putNoClobber(self.getString(sym.n_strx), sym.n_value); |
| 601 | } |
| 602 | } |
| 603 | |
| 593 | 604 | var i: u32 = start; |
| 594 | 605 | while (i < end) : (i += 1) { |
| 595 | 606 | const open = syms[i]; |
| ... | ... | @@ -611,17 +622,17 @@ fn initSymbolStabs(self: *Object, nlists: anytype, macho_file: *MachO) !void { |
| 611 | 622 | var stab: StabFile.Stab = .{}; |
| 612 | 623 | switch (nlist.n_type) { |
| 613 | 624 | macho.N_BNSYM => { |
| 614 | | stab.tag = .func; |
| 625 | stab.is_func = true; |
| 615 | 626 | stab.symbol = sym_lookup.find(nlist.n_value); |
| 616 | 627 | // TODO validate |
| 617 | 628 | i += 3; |
| 618 | 629 | }, |
| 619 | 630 | macho.N_GSYM => { |
| 620 | | stab.tag = .global; |
| 621 | | stab.symbol = macho_file.getGlobalByName(self.getString(nlist.n_strx)); |
| 631 | stab.is_func = false; |
| 632 | stab.symbol = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?); |
| 622 | 633 | }, |
| 623 | 634 | macho.N_STSYM => { |
| 624 | | stab.tag = .static; |
| 635 | stab.is_func = false; |
| 625 | 636 | stab.symbol = sym_lookup.find(nlist.n_value); |
| 626 | 637 | }, |
| 627 | 638 | else => { |
| ... | ... | @@ -1421,11 +1432,7 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void { |
| 1421 | 1432 | const file = sym.getFile(macho_file).?; |
| 1422 | 1433 | if (file.getIndex() != self.index) continue; |
| 1423 | 1434 | if (!sym.flags.output_symtab) continue; |
| 1424 | | const nstabs: u32 = switch (stab.tag) { |
| 1425 | | .func => 4, // N_BNSYM, N_FUN, N_FUN, N_ENSYM |
| 1426 | | .global => 1, // N_GSYM |
| 1427 | | .static => 1, // N_STSYM |
| 1428 | | }; |
| 1435 | const nstabs: u32 = if (stab.is_func) 4 else 1; |
| 1429 | 1436 | self.output_symtab_ctx.nstabs += nstabs; |
| 1430 | 1437 | } |
| 1431 | 1438 | } |
| ... | ... | @@ -1654,31 +1661,27 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO, ctx: anytype) error{O |
| 1654 | 1661 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; |
| 1655 | 1662 | const sym_n_value = sym.getAddress(.{}, macho_file); |
| 1656 | 1663 | const sym_size = sym.getSize(macho_file); |
| 1657 | | switch (stab.tag) { |
| 1658 | | .func => { |
| 1659 | | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx); |
| 1660 | | index += 4; |
| 1661 | | }, |
| 1662 | | .global => { |
| 1663 | | ctx.symtab.items[index] = .{ |
| 1664 | | .n_strx = sym_n_strx, |
| 1665 | | .n_type = macho.N_GSYM, |
| 1666 | | .n_sect = sym_n_sect, |
| 1667 | | .n_desc = 0, |
| 1668 | | .n_value = 0, |
| 1669 | | }; |
| 1670 | | index += 1; |
| 1671 | | }, |
| 1672 | | .static => { |
| 1673 | | ctx.symtab.items[index] = .{ |
| 1674 | | .n_strx = sym_n_strx, |
| 1675 | | .n_type = macho.N_STSYM, |
| 1676 | | .n_sect = sym_n_sect, |
| 1677 | | .n_desc = 0, |
| 1678 | | .n_value = sym_n_value, |
| 1679 | | }; |
| 1680 | | index += 1; |
| 1681 | | }, |
| 1664 | if (stab.is_func) { |
| 1665 | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx); |
| 1666 | index += 4; |
| 1667 | } else if (sym.visibility == .global) { |
| 1668 | ctx.symtab.items[index] = .{ |
| 1669 | .n_strx = sym_n_strx, |
| 1670 | .n_type = macho.N_GSYM, |
| 1671 | .n_sect = sym_n_sect, |
| 1672 | .n_desc = 0, |
| 1673 | .n_value = 0, |
| 1674 | }; |
| 1675 | index += 1; |
| 1676 | } else { |
| 1677 | ctx.symtab.items[index] = .{ |
| 1678 | .n_strx = sym_n_strx, |
| 1679 | .n_type = macho.N_STSYM, |
| 1680 | .n_sect = sym_n_sect, |
| 1681 | .n_desc = 0, |
| 1682 | .n_value = sym_n_value, |
| 1683 | }; |
| 1684 | index += 1; |
| 1682 | 1685 | } |
| 1683 | 1686 | } |
| 1684 | 1687 | |
| ... | ... | @@ -1976,7 +1979,7 @@ const StabFile = struct { |
| 1976 | 1979 | } |
| 1977 | 1980 | |
| 1978 | 1981 | const Stab = struct { |
| 1979 | | tag: enum { func, global, static } = .func, |
| 1982 | is_func: bool = true, |
| 1980 | 1983 | symbol: ?Symbol.Index = null, |
| 1981 | 1984 | |
| 1982 | 1985 | fn getSymbol(stab: Stab, macho_file: *MachO) ?*Symbol { |