| ... | @@ -100,11 +100,23 @@ syms_index_free_list: std.ArrayListUnmanaged(usize) = .{}, | ... | @@ -100,11 +100,23 @@ syms_index_free_list: std.ArrayListUnmanaged(usize) = .{}, |
| 100 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 100 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 101 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, | 101 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 102 | | 102 | |
| | 103 | /// Indices of the three "special" symbols into atoms |
| | 104 | etext_edata_end_atom_indices: [3]?Atom.Index = .{ null, null, null }, |
| | 105 | |
| 103 | const Reloc = struct { | 106 | const Reloc = struct { |
| 104 | target: Atom.Index, | 107 | target: Atom.Index, |
| 105 | offset: u64, | 108 | offset: u64, |
| 106 | addend: u32, | 109 | addend: u32, |
| 107 | pcrel: bool = false, | 110 | type: enum { |
| | 111 | pcrel, |
| | 112 | nonpcrel, |
| | 113 | // for getting the value of the etext symbol; we ignore target |
| | 114 | special_etext, |
| | 115 | // for getting the value of the edata symbol; we ignore target |
| | 116 | special_edata, |
| | 117 | // for getting the value of the end symbol; we ignore target |
| | 118 | special_end, |
| | 119 | } = .nonpcrel, |
| 108 | }; | 120 | }; |
| 109 | | 121 | |
| 110 | const Bases = struct { | 122 | const Bases = struct { |
| ... | @@ -467,15 +479,10 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I | ... | @@ -467,15 +479,10 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I |
| 467 | pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !void { | 479 | pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !void { |
| 468 | const decl = mod.declPtr(decl_index); | 480 | const decl = mod.declPtr(decl_index); |
| 469 | | 481 | |
| 470 | if (decl.val.getExternFunc(mod)) |_| { | 482 | if (decl.isExtern(mod)) { |
| 471 | return; // TODO Should we do more when front-end analyzed extern decl? | 483 | log.debug("found extern decl: {s}", .{mod.intern_pool.stringToSlice(decl.name)}); |
| 472 | } | 484 | return; |
| 473 | if (decl.val.getVariable(mod)) |variable| { | | |
| 474 | if (variable.is_extern) { | | |
| 475 | return; // TODO Should we do more when front-end analyzed extern decl? | | |
| 476 | } | | |
| 477 | } | 485 | } |
| 478 | | | |
| 479 | const atom_idx = try self.seeDecl(decl_index); | 486 | const atom_idx = try self.seeDecl(decl_index); |
| 480 | | 487 | |
| 481 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 488 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| ... | @@ -574,6 +581,13 @@ pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { | ... | @@ -574,6 +581,13 @@ pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| 574 | } | 581 | } |
| 575 | } | 582 | } |
| 576 | | 583 | |
| | 584 | fn externCount(self: *Plan9) usize { |
| | 585 | var extern_atom_count: usize = 0; |
| | 586 | for (self.etext_edata_end_atom_indices) |idx| { |
| | 587 | if (idx != null) extern_atom_count += 1; |
| | 588 | } |
| | 589 | return extern_atom_count; |
| | 590 | } |
| 577 | // counts decls, unnamed consts, and lazy syms | 591 | // counts decls, unnamed consts, and lazy syms |
| 578 | fn atomCount(self: *Plan9) usize { | 592 | fn atomCount(self: *Plan9) usize { |
| 579 | var fn_decl_count: usize = 0; | 593 | var fn_decl_count: usize = 0; |
| ... | @@ -594,7 +608,8 @@ fn atomCount(self: *Plan9) usize { | ... | @@ -594,7 +608,8 @@ fn atomCount(self: *Plan9) usize { |
| 594 | while (it_lazy.next()) |kv| { | 608 | while (it_lazy.next()) |kv| { |
| 595 | lazy_atom_count += kv.value_ptr.numberOfAtoms(); | 609 | lazy_atom_count += kv.value_ptr.numberOfAtoms(); |
| 596 | } | 610 | } |
| 597 | return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count; | 611 | const extern_atom_count = self.externCount(); |
| | 612 | return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count; |
| 598 | } | 613 | } |
| 599 | | 614 | |
| 600 | pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | 615 | pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| ... | @@ -647,7 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -647,7 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 647 | defer self.base.allocator.free(got_table); | 662 | defer self.base.allocator.free(got_table); |
| 648 | | 663 | |
| 649 | // + 4 for header, got, symbols, linecountinfo | 664 | // + 4 for header, got, symbols, linecountinfo |
| 650 | var iovecs = try self.base.allocator.alloc(std.os.iovec_const, self.atomCount() + 4); | 665 | var iovecs = try self.base.allocator.alloc(std.os.iovec_const, self.atomCount() + 4 - self.externCount()); |
| 651 | defer self.base.allocator.free(iovecs); | 666 | defer self.base.allocator.free(iovecs); |
| 652 | | 667 | |
| 653 | const file = self.base.file.?; | 668 | const file = self.base.file.?; |
| ... | @@ -729,8 +744,17 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -729,8 +744,17 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 729 | self.syms.items[text_atom.sym_index.?].value = off; | 744 | self.syms.items[text_atom.sym_index.?].value = off; |
| 730 | } | 745 | } |
| 731 | } | 746 | } |
| 732 | // etext symbol | 747 | // fix the sym for etext |
| 733 | self.syms.items[2].value = self.getAddr(text_i, .t); | 748 | if (self.etext_edata_end_atom_indices[0]) |etext_atom_idx| { |
| | 749 | const etext_atom = self.getAtom(etext_atom_idx); |
| | 750 | const val = self.getAddr(text_i, .t); |
| | 751 | self.syms.items[etext_atom.sym_index.?].value = val; |
| | 752 | if (!self.sixtyfour_bit) { |
| | 753 | mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); |
| | 754 | } else { |
| | 755 | mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); |
| | 756 | } |
| | 757 | } |
| 734 | // global offset table is in data | 758 | // global offset table is in data |
| 735 | iovecs[iovecs_i] = .{ .iov_base = got_table.ptr, .iov_len = got_table.len }; | 759 | iovecs[iovecs_i] = .{ .iov_base = got_table.ptr, .iov_len = got_table.len }; |
| 736 | iovecs_i += 1; | 760 | iovecs_i += 1; |
| ... | @@ -800,15 +824,34 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -800,15 +824,34 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 800 | self.syms.items[data_atom.sym_index.?].value = off; | 824 | self.syms.items[data_atom.sym_index.?].value = off; |
| 801 | } | 825 | } |
| 802 | // edata symbol | 826 | // edata symbol |
| 803 | self.syms.items[0].value = self.getAddr(data_i, .b); | 827 | if (self.etext_edata_end_atom_indices[1]) |edata_atom_idx| { |
| 804 | // end | 828 | const edata_atom = self.getAtom(edata_atom_idx); |
| 805 | self.syms.items[1].value = self.getAddr(data_i, .b); | 829 | const val = self.getAddr(data_i, .b); |
| | 830 | self.syms.items[edata_atom.sym_index.?].value = val; |
| | 831 | if (!self.sixtyfour_bit) { |
| | 832 | mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); |
| | 833 | } else { |
| | 834 | mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); |
| | 835 | } |
| | 836 | } |
| | 837 | // end symbol (same as edata because native backends don't do .bss yet) |
| | 838 | if (self.etext_edata_end_atom_indices[2]) |end_atom_idx| { |
| | 839 | const end_atom = self.getAtom(end_atom_idx); |
| | 840 | const val = self.getAddr(data_i, .b); |
| | 841 | self.syms.items[end_atom.sym_index.?].value = val; |
| | 842 | if (!self.sixtyfour_bit) { |
| | 843 | mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); |
| | 844 | } else { |
| | 845 | log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val }); |
| | 846 | mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); |
| | 847 | } |
| | 848 | } |
| 806 | } | 849 | } |
| 807 | var sym_buf = std.ArrayList(u8).init(self.base.allocator); | 850 | var sym_buf = std.ArrayList(u8).init(self.base.allocator); |
| 808 | try self.writeSyms(&sym_buf); | 851 | try self.writeSyms(&sym_buf); |
| 809 | const syms = try sym_buf.toOwnedSlice(); | 852 | const syms = try sym_buf.toOwnedSlice(); |
| 810 | defer self.base.allocator.free(syms); | 853 | defer self.base.allocator.free(syms); |
| 811 | assert(2 + self.atomCount() == iovecs_i); // we didn't write all the decls | 854 | assert(2 + self.atomCount() - self.externCount() == iovecs_i); // we didn't write all the decls |
| 812 | iovecs[iovecs_i] = .{ .iov_base = syms.ptr, .iov_len = syms.len }; | 855 | iovecs[iovecs_i] = .{ .iov_base = syms.ptr, .iov_len = syms.len }; |
| 813 | iovecs_i += 1; | 856 | iovecs_i += 1; |
| 814 | iovecs[iovecs_i] = .{ .iov_base = linecountinfo.items.ptr, .iov_len = linecountinfo.items.len }; | 857 | iovecs[iovecs_i] = .{ .iov_base = linecountinfo.items.ptr, .iov_len = linecountinfo.items.len }; |
| ... | @@ -836,28 +879,46 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -836,28 +879,46 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 836 | const source_atom_index = kv.key_ptr.*; | 879 | const source_atom_index = kv.key_ptr.*; |
| 837 | const source_atom = self.getAtom(source_atom_index); | 880 | const source_atom = self.getAtom(source_atom_index); |
| 838 | const source_atom_symbol = self.syms.items[source_atom.sym_index.?]; | 881 | const source_atom_symbol = self.syms.items[source_atom.sym_index.?]; |
| | 882 | const code = source_atom.code.getCode(self); |
| | 883 | const endian = self.base.options.target.cpu.arch.endian(); |
| 839 | for (kv.value_ptr.items) |reloc| { | 884 | for (kv.value_ptr.items) |reloc| { |
| 840 | const target_atom_index = reloc.target; | | |
| 841 | const target_atom = self.getAtomPtr(target_atom_index); | | |
| 842 | const target_symbol = self.syms.items[target_atom.sym_index.?]; | | |
| 843 | const target_offset = target_atom.offset.?; | | |
| 844 | | | |
| 845 | const offset = reloc.offset; | 885 | const offset = reloc.offset; |
| 846 | const addend = reloc.addend; | 886 | const addend = reloc.addend; |
| 847 | | 887 | if (reloc.type == .pcrel or reloc.type == .nonpcrel) { |
| 848 | const code = source_atom.code.getCode(self); | 888 | const target_atom_index = reloc.target; |
| 849 | | 889 | const target_atom = self.getAtomPtr(target_atom_index); |
| 850 | if (reloc.pcrel) { | 890 | const target_symbol = self.syms.items[target_atom.sym_index.?]; |
| 851 | const disp = @as(i32, @intCast(target_offset)) - @as(i32, @intCast(source_atom.offset.?)) - 4 - @as(i32, @intCast(offset)); | 891 | const target_offset = target_atom.offset.?; |
| 852 | mem.writeInt(i32, code[@as(usize, @intCast(offset))..][0..4], @as(i32, @intCast(disp)), self.base.options.target.cpu.arch.endian()); | 892 | |
| | 893 | switch (reloc.type) { |
| | 894 | .pcrel => { |
| | 895 | const disp = @as(i32, @intCast(target_offset)) - @as(i32, @intCast(source_atom.offset.?)) - 4 - @as(i32, @intCast(offset)); |
| | 896 | mem.writeInt(i32, code[@as(usize, @intCast(offset))..][0..4], @as(i32, @intCast(disp)), endian); |
| | 897 | }, |
| | 898 | .nonpcrel => { |
| | 899 | if (!self.sixtyfour_bit) { |
| | 900 | mem.writeInt(u32, code[@intCast(offset)..][0..4], @as(u32, @intCast(target_offset + addend)), endian); |
| | 901 | } else { |
| | 902 | mem.writeInt(u64, code[@intCast(offset)..][0..8], target_offset + addend, endian); |
| | 903 | } |
| | 904 | }, |
| | 905 | else => unreachable, |
| | 906 | } |
| | 907 | log.debug("relocating the address of '{s}' + {d} into '{s}' + {d} (({s}[{d}] = 0x{x} + 0x{x})", .{ target_symbol.name, addend, source_atom_symbol.name, offset, source_atom_symbol.name, offset, target_offset, addend }); |
| 853 | } else { | 908 | } else { |
| | 909 | const addr = switch (reloc.type) { |
| | 910 | .special_etext => self.syms.items[self.getAtom(self.etext_edata_end_atom_indices[0].?).sym_index.?].value, |
| | 911 | .special_edata => self.syms.items[self.getAtom(self.etext_edata_end_atom_indices[1].?).sym_index.?].value, |
| | 912 | .special_end => self.syms.items[self.getAtom(self.etext_edata_end_atom_indices[2].?).sym_index.?].value, |
| | 913 | else => unreachable, |
| | 914 | }; |
| 854 | if (!self.sixtyfour_bit) { | 915 | if (!self.sixtyfour_bit) { |
| 855 | mem.writeInt(u32, code[@as(usize, @intCast(offset))..][0..4], @as(u32, @intCast(target_offset + addend)), self.base.options.target.cpu.arch.endian()); | 916 | mem.writeInt(u32, code[@intCast(offset)..][0..4], @as(u32, @intCast(addr + addend)), endian); |
| 856 | } else { | 917 | } else { |
| 857 | mem.writeInt(u64, code[@as(usize, @intCast(offset))..][0..8], target_offset + addend, self.base.options.target.cpu.arch.endian()); | 918 | mem.writeInt(u64, code[@intCast(offset)..][0..8], addr + addend, endian); |
| 858 | } | 919 | } |
| | 920 | log.debug("relocating the address of '{s}' + {d} into '{s}' + {d} (({s}[{d}] = 0x{x} + 0x{x})", .{ @tagName(reloc.type), addend, source_atom_symbol.name, offset, source_atom_symbol.name, offset, addr, addend }); |
| 859 | } | 921 | } |
| 860 | log.debug("relocating the address of '{s}' + {d} into '{s}' + {d} (({s}[{d}] = 0x{x} + 0x{x})", .{ target_symbol.name, addend, source_atom_symbol.name, offset, source_atom_symbol.name, offset, target_offset, addend }); | | |
| 861 | } | 922 | } |
| 862 | } | 923 | } |
| 863 | } | 924 | } |
| ... | @@ -983,7 +1044,24 @@ pub fn seeDecl(self: *Plan9, decl_index: Module.Decl.Index) !Atom.Index { | ... | @@ -983,7 +1044,24 @@ pub fn seeDecl(self: *Plan9, decl_index: Module.Decl.Index) !Atom.Index { |
| 983 | .exports = .{}, | 1044 | .exports = .{}, |
| 984 | }; | 1045 | }; |
| 985 | } | 1046 | } |
| 986 | return gop.value_ptr.index; | 1047 | const atom_idx = gop.value_ptr.index; |
| | 1048 | // handle externs here because they might not get updateDecl called on them |
| | 1049 | const mod = self.base.options.module.?; |
| | 1050 | const decl = mod.declPtr(decl_index); |
| | 1051 | const name = mod.intern_pool.stringToSlice(decl.name); |
| | 1052 | if (decl.isExtern(mod)) { |
| | 1053 | // this is a "phantom atom" - it is never actually written to disk, just convenient for us to store stuff about externs |
| | 1054 | if (std.mem.eql(u8, name, "etext")) { |
| | 1055 | self.etext_edata_end_atom_indices[0] = atom_idx; |
| | 1056 | } else if (std.mem.eql(u8, name, "edata")) { |
| | 1057 | self.etext_edata_end_atom_indices[1] = atom_idx; |
| | 1058 | } else if (std.mem.eql(u8, name, "end")) { |
| | 1059 | self.etext_edata_end_atom_indices[2] = atom_idx; |
| | 1060 | } |
| | 1061 | try self.updateFinish(decl_index); |
| | 1062 | log.debug("seeDecl(extern) for {s} (got_addr=0x{x})", .{ name, self.getAtom(atom_idx).getOffsetTableAddress(self) }); |
| | 1063 | } else log.debug("seeDecl for {s}", .{name}); |
| | 1064 | return atom_idx; |
| 987 | } | 1065 | } |
| 988 | | 1066 | |
| 989 | pub fn updateDeclExports( | 1067 | pub fn updateDeclExports( |
| ... | @@ -1157,23 +1235,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option | ... | @@ -1157,23 +1235,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 1157 | | 1235 | |
| 1158 | self.bases = defaultBaseAddrs(options.target.cpu.arch); | 1236 | self.bases = defaultBaseAddrs(options.target.cpu.arch); |
| 1159 | | 1237 | |
| 1160 | // first 4 symbols in our table are edata, end, etext, and got | | |
| 1161 | try self.syms.appendSlice(self.base.allocator, &.{ | 1238 | try self.syms.appendSlice(self.base.allocator, &.{ |
| 1162 | .{ | | |
| 1163 | .value = 0xcafebabe, | | |
| 1164 | .type = .B, | | |
| 1165 | .name = "edata", | | |
| 1166 | }, | | |
| 1167 | .{ | | |
| 1168 | .value = 0xcafebabe, | | |
| 1169 | .type = .B, | | |
| 1170 | .name = "end", | | |
| 1171 | }, | | |
| 1172 | .{ | | |
| 1173 | .value = 0xcafebabe, | | |
| 1174 | .type = .T, | | |
| 1175 | .name = "etext", | | |
| 1176 | }, | | |
| 1177 | // we include the global offset table to make it easier for debugging | 1239 | // we include the global offset table to make it easier for debugging |
| 1178 | .{ | 1240 | .{ |
| 1179 | .value = self.getAddr(0, .d), // the global offset table starts at 0 | 1241 | .value = self.getAddr(0, .d), // the global offset table starts at 0 |
| ... | @@ -1202,11 +1264,8 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { | ... | @@ -1202,11 +1264,8 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1202 | const mod = self.base.options.module.?; | 1264 | const mod = self.base.options.module.?; |
| 1203 | const ip = &mod.intern_pool; | 1265 | const ip = &mod.intern_pool; |
| 1204 | const writer = buf.writer(); | 1266 | const writer = buf.writer(); |
| 1205 | // write the first four symbols (edata, etext, end, __GOT) | 1267 | // write __GOT |
| 1206 | try self.writeSym(writer, self.syms.items[0]); | 1268 | try self.writeSym(writer, self.syms.items[0]); |
| 1207 | try self.writeSym(writer, self.syms.items[1]); | | |
| 1208 | try self.writeSym(writer, self.syms.items[2]); | | |
| 1209 | try self.writeSym(writer, self.syms.items[3]); | | |
| 1210 | // write the f symbols | 1269 | // write the f symbols |
| 1211 | { | 1270 | { |
| 1212 | var it = self.file_segments.iterator(); | 1271 | var it = self.file_segments.iterator(); |
| ... | @@ -1296,6 +1355,14 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { | ... | @@ -1296,6 +1355,14 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1296 | } | 1355 | } |
| 1297 | } | 1356 | } |
| 1298 | } | 1357 | } |
| | 1358 | // special symbols |
| | 1359 | for (self.etext_edata_end_atom_indices) |idx| { |
| | 1360 | if (idx) |atom_idx| { |
| | 1361 | const atom = self.getAtom(atom_idx); |
| | 1362 | const sym = self.syms.items[atom.sym_index.?]; |
| | 1363 | try self.writeSym(writer, sym); |
| | 1364 | } |
| | 1365 | } |
| 1299 | } | 1366 | } |
| 1300 | | 1367 | |
| 1301 | /// Must be called only after a successful call to `updateDecl`. | 1368 | /// Must be called only after a successful call to `updateDecl`. |
| ... | @@ -1312,6 +1379,34 @@ pub fn getDeclVAddr( | ... | @@ -1312,6 +1379,34 @@ pub fn getDeclVAddr( |
| 1312 | ) !u64 { | 1379 | ) !u64 { |
| 1313 | const mod = self.base.options.module.?; | 1380 | const mod = self.base.options.module.?; |
| 1314 | const decl = mod.declPtr(decl_index); | 1381 | const decl = mod.declPtr(decl_index); |
| | 1382 | log.debug("getDeclVAddr for {s}", .{mod.intern_pool.stringToSlice(decl.name)}); |
| | 1383 | if (decl.isExtern(mod)) { |
| | 1384 | const extern_name = mod.intern_pool.stringToSlice(decl.name); |
| | 1385 | if (std.mem.eql(u8, extern_name, "etext")) { |
| | 1386 | try self.addReloc(reloc_info.parent_atom_index, .{ |
| | 1387 | .target = undefined, |
| | 1388 | .offset = reloc_info.offset, |
| | 1389 | .addend = reloc_info.addend, |
| | 1390 | .type = .special_etext, |
| | 1391 | }); |
| | 1392 | } else if (std.mem.eql(u8, extern_name, "edata")) { |
| | 1393 | try self.addReloc(reloc_info.parent_atom_index, .{ |
| | 1394 | .target = undefined, |
| | 1395 | .offset = reloc_info.offset, |
| | 1396 | .addend = reloc_info.addend, |
| | 1397 | .type = .special_edata, |
| | 1398 | }); |
| | 1399 | } else if (std.mem.eql(u8, extern_name, "end")) { |
| | 1400 | try self.addReloc(reloc_info.parent_atom_index, .{ |
| | 1401 | .target = undefined, |
| | 1402 | .offset = reloc_info.offset, |
| | 1403 | .addend = reloc_info.addend, |
| | 1404 | .type = .special_end, |
| | 1405 | }); |
| | 1406 | } |
| | 1407 | // TODO handle other extern variables and functions |
| | 1408 | return undefined; |
| | 1409 | } |
| 1315 | // we might already know the vaddr | 1410 | // we might already know the vaddr |
| 1316 | if (decl.ty.zigTypeTag(mod) == .Fn) { | 1411 | if (decl.ty.zigTypeTag(mod) == .Fn) { |
| 1317 | var start = self.bases.text; | 1412 | var start = self.bases.text; |
| ... | @@ -1339,7 +1434,7 @@ pub fn getDeclVAddr( | ... | @@ -1339,7 +1434,7 @@ pub fn getDeclVAddr( |
| 1339 | .offset = reloc_info.offset, | 1434 | .offset = reloc_info.offset, |
| 1340 | .addend = reloc_info.addend, | 1435 | .addend = reloc_info.addend, |
| 1341 | }); | 1436 | }); |
| 1342 | return 0xcafebabe; | 1437 | return undefined; |
| 1343 | } | 1438 | } |
| 1344 | | 1439 | |
| 1345 | pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void { | 1440 | pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void { |