| ... | ... | @@ -904,9 +904,11 @@ pub const Symbol = struct { |
| 904 | 904 | weak_external_strat: WeakExternalStrat, |
| 905 | 905 | _: u5 = 0, |
| 906 | 906 | }, |
| 907 | | /// Relocations contained within this symbol |
| 907 | /// The first index of the contiguous range of location relocs for this symbol. |
| 908 | /// The list is terminated by a reloc with a different .target than this symbol. |
| 909 | /// These are relocations that have a .loc that points to this symbol. |
| 908 | 910 | loc_relocs: Reloc.Index, |
| 909 | | /// Relocations targeting this symbol |
| 911 | /// The tail of a linked list of relocations with a .target that points to this symbol. |
| 910 | 912 | target_relocs: Reloc.Index, |
| 911 | 913 | section_number: SectionNumber, |
| 912 | 914 | gmi: Node.GlobalMapIndex, |
| ... | ... | @@ -998,8 +1000,20 @@ pub const Symbol = struct { |
| 998 | 1000 | }; |
| 999 | 1001 | } |
| 1000 | 1002 | |
| 1001 | | pub fn size(sym: *const Symbol) u32 { |
| 1002 | | return if (sym.flags.extra_tag == .size) sym.extra.size else 0; |
| 1003 | pub fn size(sym: *const Symbol, coff: *Coff) u32 { |
| 1004 | var size_sym = sym; |
| 1005 | while (size_sym.flags.extra_tag == .next_alias_si) |
| 1006 | size_sym = size_sym.extra.next_alias_si.get(coff); |
| 1007 | if (size_sym.flags.extra_tag != .size) return 0; |
| 1008 | return size_sym.extra.size; |
| 1009 | } |
| 1010 | |
| 1011 | pub fn setSize(sym: *Symbol, coff: *Coff, new_size: u32) void { |
| 1012 | var size_sym = sym; |
| 1013 | while (size_sym.flags.extra_tag == .next_alias_si) |
| 1014 | size_sym = size_sym.extra.next_alias_si.get(coff); |
| 1015 | assert(size_sym.flags.extra_tag == .size); |
| 1016 | size_sym.extra.size = new_size; |
| 1003 | 1017 | } |
| 1004 | 1018 | |
| 1005 | 1019 | pub const SectionNumber = enum(i16) { |
| ... | ... | @@ -1097,7 +1111,7 @@ pub const Symbol = struct { |
| 1097 | 1111 | assert(reloc.target == si); |
| 1098 | 1112 | if (reloc.sri.entry(coff, reloc.loc.get(coff).section_number)) |entry| |
| 1099 | 1113 | coff.targetStore(&entry.symbol_table_index, index); |
| 1100 | | ri = reloc.next; |
| 1114 | ri = reloc.prev; |
| 1101 | 1115 | } |
| 1102 | 1116 | } |
| 1103 | 1117 | |
| ... | ... | @@ -1126,7 +1140,7 @@ pub const Symbol = struct { |
| 1126 | 1140 | const reloc = ri.get(coff); |
| 1127 | 1141 | assert(reloc.target == si); |
| 1128 | 1142 | try reloc.apply(coff); |
| 1129 | | ri = reloc.next; |
| 1143 | ri = reloc.prev; |
| 1130 | 1144 | } |
| 1131 | 1145 | } |
| 1132 | 1146 | |
| ... | ... | @@ -1494,24 +1508,25 @@ pub const Reloc = extern struct { |
| 1494 | 1508 | } |
| 1495 | 1509 | |
| 1496 | 1510 | pub fn delete(reloc: *Reloc, coff: *Coff) void { |
| 1511 | log.debug("deleteReloc({d})", .{reloc - coff.relocs.items.ptr}); |
| 1497 | 1512 | if (reloc.sri != .none) { |
| 1498 | | // TODO: Need to remove this from the COFF relocation table (maybe removeswap?) |
| 1499 | | // TODO: If this was the last reloc causing something to be in the symbol table, we should remove |
| 1500 | | // the symbol table entry (and unset sti). That will require flushSymbolTableIndex on the |
| 1501 | | // swapped symbol if we exchange indices |
| 1502 | | @panic("TODO implement symbol table reloc deletions"); |
| 1513 | const loc_sym = reloc.loc.get(coff); |
| 1514 | const entry = reloc.sri.entry(coff, loc_sym.section_number).?; |
| 1515 | |
| 1516 | // On every supported architecture, a reloc type of 0 is .ABSOLUTE, and is a no-op |
| 1517 | @memset(std.mem.asBytes(entry), 0); |
| 1503 | 1518 | } |
| 1504 | 1519 | |
| 1505 | 1520 | switch (reloc.prev) { |
| 1521 | .none => {}, |
| 1522 | else => |prev| prev.get(coff).next = reloc.next, |
| 1523 | } |
| 1524 | switch (reloc.next) { |
| 1506 | 1525 | .none => { |
| 1507 | 1526 | const target = reloc.target.get(coff); |
| 1508 | 1527 | assert(target.target_relocs.get(coff) == reloc); |
| 1509 | | target.target_relocs = reloc.next; |
| 1528 | target.target_relocs = reloc.prev; |
| 1510 | 1529 | }, |
| 1511 | | else => |prev| prev.get(coff).next = reloc.next, |
| 1512 | | } |
| 1513 | | switch (reloc.next) { |
| 1514 | | .none => {}, |
| 1515 | 1530 | else => |next| next.get(coff).prev = reloc.prev, |
| 1516 | 1531 | } |
| 1517 | 1532 | |
| ... | ... | @@ -3264,7 +3279,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32) !void { |
| 3264 | 3279 | }; |
| 3265 | 3280 | |
| 3266 | 3281 | coff.targetStore(&entry.value, switch (sym.section_number) { |
| 3267 | | .UNDEFINED => if (entry.storage_class == .WEAK_EXTERNAL) 0 else sym.size(), |
| 3282 | .UNDEFINED => if (entry.storage_class == .WEAK_EXTERNAL) 0 else sym.size(coff), |
| 3268 | 3283 | .ABSOLUTE, |
| 3269 | 3284 | .DEBUG, |
| 3270 | 3285 | => unreachable, |
| ... | ... | @@ -3731,6 +3746,9 @@ fn addRelocAssumeCapacity( |
| 3731 | 3746 | } else .none; |
| 3732 | 3747 | |
| 3733 | 3748 | const sri: Section.RelocationIndex = blk: { |
| 3749 | // TODO: Once the API for using free relocs exist, if this is about to consume a |
| 3750 | // free reloc, then we can use the existing (cleared) .sri on the reloc |
| 3751 | |
| 3734 | 3752 | const section = loc_sn.section(coff); |
| 3735 | 3753 | const header = loc_sn.header(coff); |
| 3736 | 3754 | const old_num_relocations = coff.targetLoad(&header.number_of_relocations); |
| ... | ... | @@ -3770,8 +3788,8 @@ fn addRelocAssumeCapacity( |
| 3770 | 3788 | |
| 3771 | 3789 | coff.relocs.addOneAssumeCapacity().* = .{ |
| 3772 | 3790 | .type = @"type", |
| 3773 | | .prev = .none, |
| 3774 | | .next = target.target_relocs, |
| 3791 | .prev = target.target_relocs, |
| 3792 | .next = .none, |
| 3775 | 3793 | .loc = loc_si, |
| 3776 | 3794 | .target = target_si, |
| 3777 | 3795 | .sri = sri, |
| ... | ... | @@ -3784,7 +3802,7 @@ fn addRelocAssumeCapacity( |
| 3784 | 3802 | }; |
| 3785 | 3803 | switch (target.target_relocs) { |
| 3786 | 3804 | .none => {}, |
| 3787 | | else => |target_ri| target_ri.get(coff).prev = ri, |
| 3805 | else => |target_ri| target_ri.get(coff).next = ri, |
| 3788 | 3806 | } |
| 3789 | 3807 | target.target_relocs = ri; |
| 3790 | 3808 | } |
| ... | ... | @@ -4894,7 +4912,7 @@ fn loadObject( |
| 4894 | 4912 | symbol.si = global_gop.value_ptr.si; |
| 4895 | 4913 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { |
| 4896 | 4914 | const sym = symbol.si.get(coff); |
| 4897 | | sym.setExtra(.{ .size = @max(sym.size(), size) }); |
| 4915 | sym.setExtra(.{ .size = @max(sym.size(coff), size) }); |
| 4898 | 4916 | } |
| 4899 | 4917 | }, |
| 4900 | 4918 | else => unreachable, |
| ... | ... | @@ -5483,7 +5501,8 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5483 | 5501 | error.WriteFailed => return nw.err.?, |
| 5484 | 5502 | else => |e| return e, |
| 5485 | 5503 | }; |
| 5486 | | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 5504 | |
| 5505 | si.get(coff).setSize(coff, @intCast(nw.interface.end)); |
| 5487 | 5506 | try si.applyLocationRelocs(coff); |
| 5488 | 5507 | } |
| 5489 | 5508 | |
| ... | ... | @@ -5621,7 +5640,8 @@ fn updateFuncInner( |
| 5621 | 5640 | error.WriteFailed => return nw.err.?, |
| 5622 | 5641 | else => |e| return e, |
| 5623 | 5642 | }; |
| 5624 | | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 5643 | |
| 5644 | si.get(coff).setSize(coff, @intCast(nw.interface.end)); |
| 5625 | 5645 | try si.applyLocationRelocs(coff); |
| 5626 | 5646 | |
| 5627 | 5647 | // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs. |
| ... | ... | @@ -6214,7 +6234,8 @@ fn genUav( |
| 6214 | 6234 | error.WriteFailed => return nw.err.?, |
| 6215 | 6235 | else => |e| return e, |
| 6216 | 6236 | }; |
| 6217 | | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 6237 | |
| 6238 | si.get(coff).setSize(coff, @intCast(nw.interface.end)); |
| 6218 | 6239 | try si.applyLocationRelocs(coff); |
| 6219 | 6240 | } |
| 6220 | 6241 | |
| ... | ... | @@ -6238,18 +6259,19 @@ fn aliasGlobal(coff: *Coff, gmi: Node.GlobalMapIndex, alias_si: Symbol.Index) !v |
| 6238 | 6259 | const reloc = ri.get(coff); |
| 6239 | 6260 | assert(reloc.target == si); |
| 6240 | 6261 | reloc.target = alias_si; |
| 6241 | | if (reloc.next == .none) { |
| 6242 | | reloc.next = alias_sym.target_relocs; |
| 6262 | if (reloc.prev == .none) { |
| 6263 | reloc.prev = alias_sym.target_relocs; |
| 6243 | 6264 | if (alias_sym.target_relocs != .none) |
| 6244 | | alias_sym.target_relocs.get(coff).prev = ri; |
| 6265 | alias_sym.target_relocs.get(coff).next = ri; |
| 6245 | 6266 | break; |
| 6246 | 6267 | } |
| 6247 | | ri = reloc.next; |
| 6268 | ri = reloc.prev; |
| 6248 | 6269 | } |
| 6249 | 6270 | |
| 6250 | 6271 | const prev_target_relocs = alias_sym.target_relocs; |
| 6251 | 6272 | if (sym.target_relocs != .none) |
| 6252 | 6273 | alias_sym.target_relocs = sym.target_relocs; |
| 6274 | |
| 6253 | 6275 | sym.target_relocs = .none; |
| 6254 | 6276 | sym.gmi = alias_sym.gmi; |
| 6255 | 6277 | coff.globals.values()[gmi.unwrap().?].si = alias_si; |
| ... | ... | @@ -6844,7 +6866,8 @@ fn genLazyInner(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6844 | 6866 | error.WriteFailed => return nw.err.?, |
| 6845 | 6867 | else => |e| return e, |
| 6846 | 6868 | }; |
| 6847 | | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 6869 | |
| 6870 | si.get(coff).setSize(coff, @intCast(nw.interface.end)); |
| 6848 | 6871 | try si.applyLocationRelocs(coff); |
| 6849 | 6872 | } |
| 6850 | 6873 | |