| ... | ... | @@ -21,14 +21,7 @@ const Allocator = std.mem.Allocator; |
| 21 | 21 | const log = std.log.scoped(.link); |
| 22 | 22 | const assert = std.debug.assert; |
| 23 | 23 | |
| 24 | | const FnDeclOutput = struct { |
| 25 | | /// this code is modified when relocated so it is mutable |
| 26 | | code: []u8, |
| 27 | | /// this might have to be modified in the linker, so thats why its mutable |
| 28 | | lineinfo: []u8, |
| 29 | | start_line: u32, |
| 30 | | end_line: u32, |
| 31 | | }; |
| 24 | pub const base_tag = .plan9; |
| 32 | 25 | |
| 33 | 26 | base: link.File, |
| 34 | 27 | sixtyfour_bit: bool, |
| ... | ... | @@ -101,6 +94,9 @@ got_index_free_list: std.ArrayListUnmanaged(usize) = .{}, |
| 101 | 94 | |
| 102 | 95 | syms_index_free_list: std.ArrayListUnmanaged(usize) = .{}, |
| 103 | 96 | |
| 97 | decl_blocks: std.ArrayListUnmanaged(DeclBlock) = .{}, |
| 98 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 99 | |
| 104 | 100 | const Reloc = struct { |
| 105 | 101 | target: Module.Decl.Index, |
| 106 | 102 | offset: u64, |
| ... | ... | @@ -115,6 +111,42 @@ const Bases = struct { |
| 115 | 111 | |
| 116 | 112 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(struct { info: DeclBlock, code: []const u8 })); |
| 117 | 113 | |
| 114 | pub const PtrWidth = enum { p32, p64 }; |
| 115 | |
| 116 | pub const DeclBlock = struct { |
| 117 | type: aout.Sym.Type, |
| 118 | /// offset in the text or data sects |
| 119 | offset: ?u64, |
| 120 | /// offset into syms |
| 121 | sym_index: ?usize, |
| 122 | /// offset into got |
| 123 | got_index: ?usize, |
| 124 | |
| 125 | pub const Index = u32; |
| 126 | }; |
| 127 | |
| 128 | const DeclMetadata = struct { |
| 129 | index: DeclBlock.Index, |
| 130 | exports: std.ArrayListUnmanaged(usize) = .{}, |
| 131 | |
| 132 | fn getExport(m: DeclMetadata, p9: *const Plan9, name: []const u8) ?usize { |
| 133 | for (m.exports.items) |exp| { |
| 134 | const sym = p9.syms.items[exp]; |
| 135 | if (mem.eql(u8, name, sym.name)) return exp; |
| 136 | } |
| 137 | return null; |
| 138 | } |
| 139 | }; |
| 140 | |
| 141 | const FnDeclOutput = struct { |
| 142 | /// this code is modified when relocated so it is mutable |
| 143 | code: []u8, |
| 144 | /// this might have to be modified in the linker, so thats why its mutable |
| 145 | lineinfo: []u8, |
| 146 | start_line: u32, |
| 147 | end_line: u32, |
| 148 | }; |
| 149 | |
| 118 | 150 | fn getAddr(self: Plan9, addr: u64, t: aout.Sym.Type) u64 { |
| 119 | 151 | return addr + switch (t) { |
| 120 | 152 | .T, .t, .l, .L => self.bases.text, |
| ... | ... | @@ -127,22 +159,6 @@ fn getSymAddr(self: Plan9, s: aout.Sym) u64 { |
| 127 | 159 | return self.getAddr(s.value, s.type); |
| 128 | 160 | } |
| 129 | 161 | |
| 130 | | pub const DeclBlock = struct { |
| 131 | | type: aout.Sym.Type, |
| 132 | | /// offset in the text or data sects |
| 133 | | offset: ?u64, |
| 134 | | /// offset into syms |
| 135 | | sym_index: ?usize, |
| 136 | | /// offset into got |
| 137 | | got_index: ?usize, |
| 138 | | pub const empty = DeclBlock{ |
| 139 | | .type = .t, |
| 140 | | .offset = null, |
| 141 | | .sym_index = null, |
| 142 | | .got_index = null, |
| 143 | | }; |
| 144 | | }; |
| 145 | | |
| 146 | 162 | pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { |
| 147 | 163 | return switch (arch) { |
| 148 | 164 | .x86_64 => .{ |
| ... | ... | @@ -164,8 +180,6 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { |
| 164 | 180 | }; |
| 165 | 181 | } |
| 166 | 182 | |
| 167 | | pub const PtrWidth = enum { p32, p64 }; |
| 168 | | |
| 169 | 183 | pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 { |
| 170 | 184 | if (options.use_llvm) |
| 171 | 185 | return error.LLVMBackendDoesNotSupportPlan9; |
| ... | ... | @@ -271,7 +285,7 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv |
| 271 | 285 | const decl = module.declPtr(decl_index); |
| 272 | 286 | self.freeUnnamedConsts(decl_index); |
| 273 | 287 | |
| 274 | | try self.seeDecl(decl_index); |
| 288 | _ = try self.seeDecl(decl_index); |
| 275 | 289 | log.debug("codegen decl {*} ({s})", .{ decl, decl.name }); |
| 276 | 290 | |
| 277 | 291 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| ... | ... | @@ -313,11 +327,11 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv |
| 313 | 327 | .end_line = end_line, |
| 314 | 328 | }; |
| 315 | 329 | try self.putFn(decl_index, out); |
| 316 | | return self.updateFinish(decl); |
| 330 | return self.updateFinish(decl_index); |
| 317 | 331 | } |
| 318 | 332 | |
| 319 | 333 | pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.Index) !u32 { |
| 320 | | try self.seeDecl(decl_index); |
| 334 | _ = try self.seeDecl(decl_index); |
| 321 | 335 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 322 | 336 | defer code_buffer.deinit(); |
| 323 | 337 | |
| ... | ... | @@ -387,7 +401,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index) |
| 387 | 401 | } |
| 388 | 402 | } |
| 389 | 403 | |
| 390 | | try self.seeDecl(decl_index); |
| 404 | _ = try self.seeDecl(decl_index); |
| 391 | 405 | |
| 392 | 406 | log.debug("codegen decl {*} ({s}) ({d})", .{ decl, decl.name, decl_index }); |
| 393 | 407 | |
| ... | ... | @@ -414,28 +428,31 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index) |
| 414 | 428 | if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| { |
| 415 | 429 | self.base.allocator.free(old_entry.value); |
| 416 | 430 | } |
| 417 | | return self.updateFinish(decl); |
| 431 | return self.updateFinish(decl_index); |
| 418 | 432 | } |
| 419 | 433 | /// called at the end of update{Decl,Func} |
| 420 | | fn updateFinish(self: *Plan9, decl: *Module.Decl) !void { |
| 434 | fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void { |
| 435 | const decl = self.base.options.module.?.declPtr(decl_index); |
| 421 | 436 | const is_fn = (decl.ty.zigTypeTag() == .Fn); |
| 422 | 437 | log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name }); |
| 423 | 438 | const sym_t: aout.Sym.Type = if (is_fn) .t else .d; |
| 439 | |
| 440 | const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index); |
| 424 | 441 | // write the internal linker metadata |
| 425 | | decl.link.plan9.type = sym_t; |
| 442 | decl_block.type = sym_t; |
| 426 | 443 | // write the symbol |
| 427 | 444 | // we already have the got index |
| 428 | 445 | const sym: aout.Sym = .{ |
| 429 | 446 | .value = undefined, // the value of stuff gets filled in in flushModule |
| 430 | | .type = decl.link.plan9.type, |
| 447 | .type = decl_block.type, |
| 431 | 448 | .name = mem.span(decl.name), |
| 432 | 449 | }; |
| 433 | 450 | |
| 434 | | if (decl.link.plan9.sym_index) |s| { |
| 451 | if (decl_block.sym_index) |s| { |
| 435 | 452 | self.syms.items[s] = sym; |
| 436 | 453 | } else { |
| 437 | 454 | const s = try self.allocateSymbolIndex(); |
| 438 | | decl.link.plan9.sym_index = s; |
| 455 | decl_block.sym_index = s; |
| 439 | 456 | self.syms.items[s] = sym; |
| 440 | 457 | } |
| 441 | 458 | } |
| ... | ... | @@ -550,6 +567,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 550 | 567 | while (it.next()) |entry| { |
| 551 | 568 | const decl_index = entry.key_ptr.*; |
| 552 | 569 | const decl = mod.declPtr(decl_index); |
| 570 | const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index); |
| 553 | 571 | const out = entry.value_ptr.*; |
| 554 | 572 | log.debug("write text decl {*} ({s}), lines {d} to {d}", .{ decl, decl.name, out.start_line + 1, out.end_line }); |
| 555 | 573 | { |
| ... | ... | @@ -568,16 +586,16 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 568 | 586 | iovecs_i += 1; |
| 569 | 587 | const off = self.getAddr(text_i, .t); |
| 570 | 588 | text_i += out.code.len; |
| 571 | | decl.link.plan9.offset = off; |
| 589 | decl_block.offset = off; |
| 572 | 590 | if (!self.sixtyfour_bit) { |
| 573 | | mem.writeIntNative(u32, got_table[decl.link.plan9.got_index.? * 4 ..][0..4], @intCast(u32, off)); |
| 574 | | mem.writeInt(u32, got_table[decl.link.plan9.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian()); |
| 591 | mem.writeIntNative(u32, got_table[decl_block.got_index.? * 4 ..][0..4], @intCast(u32, off)); |
| 592 | mem.writeInt(u32, got_table[decl_block.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian()); |
| 575 | 593 | } else { |
| 576 | | mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); |
| 594 | mem.writeInt(u64, got_table[decl_block.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); |
| 577 | 595 | } |
| 578 | | self.syms.items[decl.link.plan9.sym_index.?].value = off; |
| 596 | self.syms.items[decl_block.sym_index.?].value = off; |
| 579 | 597 | if (mod.decl_exports.get(decl_index)) |exports| { |
| 580 | | try self.addDeclExports(mod, decl, exports.items); |
| 598 | try self.addDeclExports(mod, decl_index, exports.items); |
| 581 | 599 | } |
| 582 | 600 | } |
| 583 | 601 | } |
| ... | ... | @@ -598,6 +616,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 598 | 616 | while (it.next()) |entry| { |
| 599 | 617 | const decl_index = entry.key_ptr.*; |
| 600 | 618 | const decl = mod.declPtr(decl_index); |
| 619 | const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index); |
| 601 | 620 | const code = entry.value_ptr.*; |
| 602 | 621 | log.debug("write data decl {*} ({s})", .{ decl, decl.name }); |
| 603 | 622 | |
| ... | ... | @@ -606,15 +625,15 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 606 | 625 | iovecs_i += 1; |
| 607 | 626 | const off = self.getAddr(data_i, .d); |
| 608 | 627 | data_i += code.len; |
| 609 | | decl.link.plan9.offset = off; |
| 628 | decl_block.offset = off; |
| 610 | 629 | if (!self.sixtyfour_bit) { |
| 611 | | mem.writeInt(u32, got_table[decl.link.plan9.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian()); |
| 630 | mem.writeInt(u32, got_table[decl_block.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian()); |
| 612 | 631 | } else { |
| 613 | | mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); |
| 632 | mem.writeInt(u64, got_table[decl_block.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); |
| 614 | 633 | } |
| 615 | | self.syms.items[decl.link.plan9.sym_index.?].value = off; |
| 634 | self.syms.items[decl_block.sym_index.?].value = off; |
| 616 | 635 | if (mod.decl_exports.get(decl_index)) |exports| { |
| 617 | | try self.addDeclExports(mod, decl, exports.items); |
| 636 | try self.addDeclExports(mod, decl_index, exports.items); |
| 618 | 637 | } |
| 619 | 638 | } |
| 620 | 639 | // write the unnamed constants after the other data decls |
| ... | ... | @@ -676,7 +695,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 676 | 695 | for (kv.value_ptr.items) |reloc| { |
| 677 | 696 | const target_decl_index = reloc.target; |
| 678 | 697 | const target_decl = mod.declPtr(target_decl_index); |
| 679 | | const target_decl_offset = target_decl.link.plan9.offset.?; |
| 698 | const target_decl_block = self.getDeclBlock(self.decls.get(target_decl_index).?.index); |
| 699 | const target_decl_offset = target_decl_block.offset.?; |
| 680 | 700 | |
| 681 | 701 | const offset = reloc.offset; |
| 682 | 702 | const addend = reloc.addend; |
| ... | ... | @@ -709,28 +729,36 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 709 | 729 | fn addDeclExports( |
| 710 | 730 | self: *Plan9, |
| 711 | 731 | module: *Module, |
| 712 | | decl: *Module.Decl, |
| 732 | decl_index: Module.Decl.Index, |
| 713 | 733 | exports: []const *Module.Export, |
| 714 | 734 | ) !void { |
| 735 | const metadata = self.decls.getPtr(decl_index).?; |
| 736 | const decl_block = self.getDeclBlock(metadata.index); |
| 737 | |
| 715 | 738 | for (exports) |exp| { |
| 716 | 739 | // plan9 does not support custom sections |
| 717 | 740 | if (exp.options.section) |section_name| { |
| 718 | 741 | if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) { |
| 719 | | try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "plan9 does not support extra sections", .{})); |
| 742 | try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create( |
| 743 | self.base.allocator, |
| 744 | module.declPtr(decl_index).srcLoc(), |
| 745 | "plan9 does not support extra sections", |
| 746 | .{}, |
| 747 | )); |
| 720 | 748 | break; |
| 721 | 749 | } |
| 722 | 750 | } |
| 723 | 751 | const sym = .{ |
| 724 | | .value = decl.link.plan9.offset.?, |
| 725 | | .type = decl.link.plan9.type.toGlobal(), |
| 752 | .value = decl_block.offset.?, |
| 753 | .type = decl_block.type.toGlobal(), |
| 726 | 754 | .name = exp.options.name, |
| 727 | 755 | }; |
| 728 | 756 | |
| 729 | | if (exp.link.plan9) |i| { |
| 757 | if (metadata.getExport(self, exp.options.name)) |i| { |
| 730 | 758 | self.syms.items[i] = sym; |
| 731 | 759 | } else { |
| 732 | 760 | try self.syms.append(self.base.allocator, sym); |
| 733 | | exp.link.plan9 = self.syms.items.len - 1; |
| 761 | try metadata.exports.append(self.base.allocator, self.syms.items.len - 1); |
| 734 | 762 | } |
| 735 | 763 | } |
| 736 | 764 | } |
| ... | ... | @@ -760,13 +788,18 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void { |
| 760 | 788 | self.base.allocator.free(removed_entry.value); |
| 761 | 789 | } |
| 762 | 790 | } |
| 763 | | if (decl.link.plan9.got_index) |i| { |
| 764 | | // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length |
| 765 | | self.got_index_free_list.append(self.base.allocator, i) catch {}; |
| 766 | | } |
| 767 | | if (decl.link.plan9.sym_index) |i| { |
| 768 | | self.syms_index_free_list.append(self.base.allocator, i) catch {}; |
| 769 | | self.syms.items[i] = aout.Sym.undefined_symbol; |
| 791 | if (self.decls.fetchRemove(decl_index)) |const_kv| { |
| 792 | var kv = const_kv; |
| 793 | const decl_block = self.getDeclBlock(kv.value.index); |
| 794 | if (decl_block.got_index) |i| { |
| 795 | // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length |
| 796 | self.got_index_free_list.append(self.base.allocator, i) catch {}; |
| 797 | } |
| 798 | if (decl_block.sym_index) |i| { |
| 799 | self.syms_index_free_list.append(self.base.allocator, i) catch {}; |
| 800 | self.syms.items[i] = aout.Sym.undefined_symbol; |
| 801 | } |
| 802 | kv.value.exports.deinit(self.base.allocator); |
| 770 | 803 | } |
| 771 | 804 | self.freeUnnamedConsts(decl_index); |
| 772 | 805 | { |
| ... | ... | @@ -786,12 +819,30 @@ fn freeUnnamedConsts(self: *Plan9, decl_index: Module.Decl.Index) void { |
| 786 | 819 | unnamed_consts.clearAndFree(self.base.allocator); |
| 787 | 820 | } |
| 788 | 821 | |
| 789 | | pub fn seeDecl(self: *Plan9, decl_index: Module.Decl.Index) !void { |
| 790 | | const mod = self.base.options.module.?; |
| 791 | | const decl = mod.declPtr(decl_index); |
| 792 | | if (decl.link.plan9.got_index == null) { |
| 793 | | decl.link.plan9.got_index = self.allocateGotIndex(); |
| 822 | fn createDeclBlock(self: *Plan9) !DeclBlock.Index { |
| 823 | const gpa = self.base.allocator; |
| 824 | const index = @intCast(DeclBlock.Index, self.decl_blocks.items.len); |
| 825 | const decl_block = try self.decl_blocks.addOne(gpa); |
| 826 | decl_block.* = .{ |
| 827 | .type = .t, |
| 828 | .offset = null, |
| 829 | .sym_index = null, |
| 830 | .got_index = null, |
| 831 | }; |
| 832 | return index; |
| 833 | } |
| 834 | |
| 835 | pub fn seeDecl(self: *Plan9, decl_index: Module.Decl.Index) !DeclBlock.Index { |
| 836 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 837 | if (!gop.found_existing) { |
| 838 | const index = try self.createDeclBlock(); |
| 839 | self.getDeclBlockPtr(index).got_index = self.allocateGotIndex(); |
| 840 | gop.value_ptr.* = .{ |
| 841 | .index = index, |
| 842 | .exports = .{}, |
| 843 | }; |
| 794 | 844 | } |
| 845 | return gop.value_ptr.index; |
| 795 | 846 | } |
| 796 | 847 | |
| 797 | 848 | pub fn updateDeclExports( |
| ... | ... | @@ -800,7 +851,7 @@ pub fn updateDeclExports( |
| 800 | 851 | decl_index: Module.Decl.Index, |
| 801 | 852 | exports: []const *Module.Export, |
| 802 | 853 | ) !void { |
| 803 | | try self.seeDecl(decl_index); |
| 854 | _ = try self.seeDecl(decl_index); |
| 804 | 855 | // we do all the things in flush |
| 805 | 856 | _ = module; |
| 806 | 857 | _ = exports; |
| ... | ... | @@ -842,10 +893,17 @@ pub fn deinit(self: *Plan9) void { |
| 842 | 893 | self.syms_index_free_list.deinit(gpa); |
| 843 | 894 | self.file_segments.deinit(gpa); |
| 844 | 895 | self.path_arena.deinit(); |
| 896 | self.decl_blocks.deinit(gpa); |
| 897 | |
| 898 | { |
| 899 | var it = self.decls.iterator(); |
| 900 | while (it.next()) |entry| { |
| 901 | entry.value_ptr.exports.deinit(gpa); |
| 902 | } |
| 903 | self.decls.deinit(gpa); |
| 904 | } |
| 845 | 905 | } |
| 846 | 906 | |
| 847 | | pub const Export = ?usize; |
| 848 | | pub const base_tag = .plan9; |
| 849 | 907 | pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 { |
| 850 | 908 | if (options.use_llvm) |
| 851 | 909 | return error.LLVMBackendDoesNotSupportPlan9; |
| ... | ... | @@ -911,20 +969,19 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 911 | 969 | } |
| 912 | 970 | } |
| 913 | 971 | |
| 914 | | const mod = self.base.options.module.?; |
| 915 | | |
| 916 | 972 | // write the data symbols |
| 917 | 973 | { |
| 918 | 974 | var it = self.data_decl_table.iterator(); |
| 919 | 975 | while (it.next()) |entry| { |
| 920 | 976 | const decl_index = entry.key_ptr.*; |
| 921 | | const decl = mod.declPtr(decl_index); |
| 922 | | const sym = self.syms.items[decl.link.plan9.sym_index.?]; |
| 977 | const decl_metadata = self.decls.get(decl_index).?; |
| 978 | const decl_block = self.getDeclBlock(decl_metadata.index); |
| 979 | const sym = self.syms.items[decl_block.sym_index.?]; |
| 923 | 980 | try self.writeSym(writer, sym); |
| 924 | 981 | if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| { |
| 925 | | for (exports.items) |e| { |
| 926 | | try self.writeSym(writer, self.syms.items[e.link.plan9.?]); |
| 927 | | } |
| 982 | for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| { |
| 983 | try self.writeSym(writer, self.syms.items[exp_i]); |
| 984 | }; |
| 928 | 985 | } |
| 929 | 986 | } |
| 930 | 987 | } |
| ... | ... | @@ -943,16 +1000,17 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 943 | 1000 | var submap_it = symidx_and_submap.functions.iterator(); |
| 944 | 1001 | while (submap_it.next()) |entry| { |
| 945 | 1002 | const decl_index = entry.key_ptr.*; |
| 946 | | const decl = mod.declPtr(decl_index); |
| 947 | | const sym = self.syms.items[decl.link.plan9.sym_index.?]; |
| 1003 | const decl_metadata = self.decls.get(decl_index).?; |
| 1004 | const decl_block = self.getDeclBlock(decl_metadata.index); |
| 1005 | const sym = self.syms.items[decl_block.sym_index.?]; |
| 948 | 1006 | try self.writeSym(writer, sym); |
| 949 | 1007 | if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| { |
| 950 | | for (exports.items) |e| { |
| 951 | | const s = self.syms.items[e.link.plan9.?]; |
| 1008 | for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| { |
| 1009 | const s = self.syms.items[exp_i]; |
| 952 | 1010 | if (mem.eql(u8, s.name, "_start")) |
| 953 | 1011 | self.entry_val = s.value; |
| 954 | 1012 | try self.writeSym(writer, s); |
| 955 | | } |
| 1013 | }; |
| 956 | 1014 | } |
| 957 | 1015 | } |
| 958 | 1016 | } |
| ... | ... | @@ -1004,3 +1062,11 @@ pub fn getDeclVAddr( |
| 1004 | 1062 | }); |
| 1005 | 1063 | return undefined; |
| 1006 | 1064 | } |
| 1065 | |
| 1066 | pub fn getDeclBlock(self: *const Plan9, index: DeclBlock.Index) DeclBlock { |
| 1067 | return self.decl_blocks.items[index]; |
| 1068 | } |
| 1069 | |
| 1070 | fn getDeclBlockPtr(self: *Plan9, index: DeclBlock.Index) *DeclBlock { |
| 1071 | return &self.decl_blocks.items[index]; |
| 1072 | } |