| author | |
| committer | |
| log | 6a2425c38c2a776d2aafd68b25da8c4c1164f614 |
| tree | 418f27f237b06c20907434b90d99350a6f6a9787 |
| parent | 080022f6c670b0f74c39fe01096ebdbaafeda1b2 |
3 files changed, 57 insertions(+), 50 deletions(-)
lib/std/fs/file.zig+7-4| ... | @@ -527,19 +527,21 @@ pub const File = struct { | ... | @@ -527,19 +527,21 @@ pub const File = struct { |
| 527 | } | 527 | } |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | pub fn copyRange(in: File, in_offset: u64, out: File, out_offset: u64, len: usize) PWriteError!usize { | 530 | pub const CopyRangeError = PWriteError || PReadError; |
| 531 | |||
| 532 | pub fn copyRange(in: File, in_offset: u64, out: File, out_offset: u64, len: usize) CopyRangeError!usize { | ||
| 531 | // TODO take advantage of copy_file_range OS APIs | 533 | // TODO take advantage of copy_file_range OS APIs |
| 532 | var buf: [8 * 4096]u8 = undefined; | 534 | var buf: [8 * 4096]u8 = undefined; |
| 533 | const adjusted_count = math.min(buf.len, len); | 535 | const adjusted_count = math.min(buf.len, len); |
| 534 | const amt_read = try in.pread(buf[0..adjusted_count], in_offset); | 536 | const amt_read = try in.pread(buf[0..adjusted_count], in_offset); |
| 535 | if (amt_read == 0) return 0; | 537 | if (amt_read == 0) return @as(usize, 0); |
| 536 | return out.pwrite(buf[0..amt_read], out_offset); | 538 | return out.pwrite(buf[0..amt_read], out_offset); |
| 537 | } | 539 | } |
| 538 | 540 | ||
| 539 | /// Returns the number of bytes copied. If the number read is smaller than `buffer.len`, it | 541 | /// Returns the number of bytes copied. If the number read is smaller than `buffer.len`, it |
| 540 | /// means the in file reached the end. Reaching the end of a file is not an error condition. | 542 | /// means the in file reached the end. Reaching the end of a file is not an error condition. |
| 541 | pub fn copyRangeAll(in: File, in_offset: u64, out: File, out_offset: u64, len: usize) PWriteError!usize { | 543 | pub fn copyRangeAll(in: File, in_offset: u64, out: File, out_offset: u64, len: usize) CopyRangeError!usize { |
| 542 | var total_bytes_copied = 0; | 544 | var total_bytes_copied: usize = 0; |
| 543 | var in_off = in_offset; | 545 | var in_off = in_offset; |
| 544 | var out_off = out_offset; | 546 | var out_off = out_offset; |
| 545 | while (total_bytes_copied < len) { | 547 | while (total_bytes_copied < len) { |
| ... | @@ -549,6 +551,7 @@ pub const File = struct { | ... | @@ -549,6 +551,7 @@ pub const File = struct { |
| 549 | in_off += amt_copied; | 551 | in_off += amt_copied; |
| 550 | out_off += amt_copied; | 552 | out_off += amt_copied; |
| 551 | } | 553 | } |
| 554 | return total_bytes_copied; | ||
| 552 | } | 555 | } |
| 553 | 556 | ||
| 554 | pub const WriteFileOptions = struct { | 557 | pub const WriteFileOptions = struct { |
src-self-hosted/codegen.zig+24-23| ... | @@ -5,16 +5,17 @@ const ir = @import("ir.zig"); | ... | @@ -5,16 +5,17 @@ const ir = @import("ir.zig"); |
| 5 | const Type = @import("type.zig").Type; | 5 | const Type = @import("type.zig").Type; |
| 6 | const Value = @import("value.zig").Value; | 6 | const Value = @import("value.zig").Value; |
| 7 | const TypedValue = @import("TypedValue.zig"); | 7 | const TypedValue = @import("TypedValue.zig"); |
| 8 | const link = @import("link.zig"); | ||
| 8 | const Target = std.Target; | 9 | const Target = std.Target; |
| 9 | const Allocator = mem.Allocator; | 10 | const Allocator = mem.Allocator; |
| 10 | 11 | ||
| 11 | pub fn generateSymbol(typed_value: TypedValue, module: ir.Module, code: *std.ArrayList(u8)) !?*ir.ErrorMsg { | 12 | pub fn generateSymbol(bin_file: *link.ElfFile, typed_value: TypedValue, code: *std.ArrayList(u8)) !?*ir.ErrorMsg { |
| 12 | switch (typed_value.ty.zigTypeTag()) { | 13 | switch (typed_value.ty.zigTypeTag()) { |
| 13 | .Fn => { | 14 | .Fn => { |
| 14 | const module_fn = typed_value.val.cast(Value.Payload.Function).?.func; | 15 | const module_fn = typed_value.val.cast(Value.Payload.Function).?.func; |
| 15 | 16 | ||
| 16 | var function = Function{ | 17 | var function = Function{ |
| 17 | .module = &module, | 18 | .target = &bin_file.options.target, |
| 18 | .mod_fn = module_fn, | 19 | .mod_fn = module_fn, |
| 19 | .code = code, | 20 | .code = code, |
| 20 | .inst_table = std.AutoHashMap(*ir.Inst, Function.MCValue).init(code.allocator), | 21 | .inst_table = std.AutoHashMap(*ir.Inst, Function.MCValue).init(code.allocator), |
| ... | @@ -22,7 +23,7 @@ pub fn generateSymbol(typed_value: TypedValue, module: ir.Module, code: *std.Arr | ... | @@ -22,7 +23,7 @@ pub fn generateSymbol(typed_value: TypedValue, module: ir.Module, code: *std.Arr |
| 22 | }; | 23 | }; |
| 23 | defer function.inst_table.deinit(); | 24 | defer function.inst_table.deinit(); |
| 24 | 25 | ||
| 25 | for (module_fn.body.instructions) |inst| { | 26 | for (module_fn.analysis.success.instructions) |inst| { |
| 26 | const new_inst = function.genFuncInst(inst) catch |err| switch (err) { | 27 | const new_inst = function.genFuncInst(inst) catch |err| switch (err) { |
| 27 | error.CodegenFail => { | 28 | error.CodegenFail => { |
| 28 | assert(function.err_msg != null); | 29 | assert(function.err_msg != null); |
| ... | @@ -40,7 +41,7 @@ pub fn generateSymbol(typed_value: TypedValue, module: ir.Module, code: *std.Arr | ... | @@ -40,7 +41,7 @@ pub fn generateSymbol(typed_value: TypedValue, module: ir.Module, code: *std.Arr |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | const Function = struct { | 43 | const Function = struct { |
| 43 | module: *const ir.Module, | 44 | target: *const std.Target, |
| 44 | mod_fn: *const ir.Module.Fn, | 45 | mod_fn: *const ir.Module.Fn, |
| 45 | code: *std.ArrayList(u8), | 46 | code: *std.ArrayList(u8), |
| 46 | inst_table: std.AutoHashMap(*ir.Inst, MCValue), | 47 | inst_table: std.AutoHashMap(*ir.Inst, MCValue), |
| ... | @@ -76,60 +77,60 @@ const Function = struct { | ... | @@ -76,60 +77,60 @@ const Function = struct { |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | fn genBreakpoint(self: *Function, src: usize) !MCValue { | 79 | fn genBreakpoint(self: *Function, src: usize) !MCValue { |
| 79 | switch (self.module.target.cpu.arch) { | 80 | switch (self.target.cpu.arch) { |
| 80 | .i386, .x86_64 => { | 81 | .i386, .x86_64 => { |
| 81 | try self.code.append(0xcc); // int3 | 82 | try self.code.append(0xcc); // int3 |
| 82 | }, | 83 | }, |
| 83 | else => return self.fail(src, "TODO implement @breakpoint() for {}", .{self.module.target.cpu.arch}), | 84 | else => return self.fail(src, "TODO implement @breakpoint() for {}", .{self.target.cpu.arch}), |
| 84 | } | 85 | } |
| 85 | return .unreach; | 86 | return .unreach; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | fn genCall(self: *Function, inst: *ir.Inst.Call) !MCValue { | 89 | fn genCall(self: *Function, inst: *ir.Inst.Call) !MCValue { |
| 89 | switch (self.module.target.cpu.arch) { | 90 | switch (self.target.cpu.arch) { |
| 90 | else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.module.target.cpu.arch}), | 91 | else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}), |
| 91 | } | 92 | } |
| 92 | return .unreach; | 93 | return .unreach; |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | fn genRet(self: *Function, inst: *ir.Inst.Ret) !MCValue { | 96 | fn genRet(self: *Function, inst: *ir.Inst.Ret) !MCValue { |
| 96 | switch (self.module.target.cpu.arch) { | 97 | switch (self.target.cpu.arch) { |
| 97 | .i386, .x86_64 => { | 98 | .i386, .x86_64 => { |
| 98 | try self.code.append(0xc3); // ret | 99 | try self.code.append(0xc3); // ret |
| 99 | }, | 100 | }, |
| 100 | else => return self.fail(inst.base.src, "TODO implement return for {}", .{self.module.target.cpu.arch}), | 101 | else => return self.fail(inst.base.src, "TODO implement return for {}", .{self.target.cpu.arch}), |
| 101 | } | 102 | } |
| 102 | return .unreach; | 103 | return .unreach; |
| 103 | } | 104 | } |
| 104 | 105 | ||
| 105 | fn genCmp(self: *Function, inst: *ir.Inst.Cmp) !MCValue { | 106 | fn genCmp(self: *Function, inst: *ir.Inst.Cmp) !MCValue { |
| 106 | switch (self.module.target.cpu.arch) { | 107 | switch (self.target.cpu.arch) { |
| 107 | else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.module.target.cpu.arch}), | 108 | else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.target.cpu.arch}), |
| 108 | } | 109 | } |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | fn genCondBr(self: *Function, inst: *ir.Inst.CondBr) !MCValue { | 112 | fn genCondBr(self: *Function, inst: *ir.Inst.CondBr) !MCValue { |
| 112 | switch (self.module.target.cpu.arch) { | 113 | switch (self.target.cpu.arch) { |
| 113 | else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.module.target.cpu.arch}), | 114 | else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.target.cpu.arch}), |
| 114 | } | 115 | } |
| 115 | } | 116 | } |
| 116 | 117 | ||
| 117 | fn genIsNull(self: *Function, inst: *ir.Inst.IsNull) !MCValue { | 118 | fn genIsNull(self: *Function, inst: *ir.Inst.IsNull) !MCValue { |
| 118 | switch (self.module.target.cpu.arch) { | 119 | switch (self.target.cpu.arch) { |
| 119 | else => return self.fail(inst.base.src, "TODO implement isnull for {}", .{self.module.target.cpu.arch}), | 120 | else => return self.fail(inst.base.src, "TODO implement isnull for {}", .{self.target.cpu.arch}), |
| 120 | } | 121 | } |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | fn genIsNonNull(self: *Function, inst: *ir.Inst.IsNonNull) !MCValue { | 124 | fn genIsNonNull(self: *Function, inst: *ir.Inst.IsNonNull) !MCValue { |
| 124 | // Here you can specialize this instruction if it makes sense to, otherwise the default | 125 | // Here you can specialize this instruction if it makes sense to, otherwise the default |
| 125 | // will call genIsNull and invert the result. | 126 | // will call genIsNull and invert the result. |
| 126 | switch (self.module.target.cpu.arch) { | 127 | switch (self.target.cpu.arch) { |
| 127 | else => return self.fail(inst.base.src, "TODO call genIsNull and invert the result ", .{}), | 128 | else => return self.fail(inst.base.src, "TODO call genIsNull and invert the result ", .{}), |
| 128 | } | 129 | } |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | fn genRelativeFwdJump(self: *Function, src: usize, amount: u32) !void { | 132 | fn genRelativeFwdJump(self: *Function, src: usize, amount: u32) !void { |
| 132 | switch (self.module.target.cpu.arch) { | 133 | switch (self.target.cpu.arch) { |
| 133 | .i386, .x86_64 => { | 134 | .i386, .x86_64 => { |
| 134 | // TODO x86 treats the operands as signed | 135 | // TODO x86 treats the operands as signed |
| 135 | if (amount <= std.math.maxInt(u8)) { | 136 | if (amount <= std.math.maxInt(u8)) { |
| ... | @@ -143,13 +144,13 @@ const Function = struct { | ... | @@ -143,13 +144,13 @@ const Function = struct { |
| 143 | mem.writeIntLittle(u32, imm_ptr, amount); | 144 | mem.writeIntLittle(u32, imm_ptr, amount); |
| 144 | } | 145 | } |
| 145 | }, | 146 | }, |
| 146 | else => return self.fail(src, "TODO implement relative forward jump for {}", .{self.module.target.cpu.arch}), | 147 | else => return self.fail(src, "TODO implement relative forward jump for {}", .{self.target.cpu.arch}), |
| 147 | } | 148 | } |
| 148 | } | 149 | } |
| 149 | 150 | ||
| 150 | fn genAsm(self: *Function, inst: *ir.Inst.Assembly) !MCValue { | 151 | fn genAsm(self: *Function, inst: *ir.Inst.Assembly) !MCValue { |
| 151 | // TODO convert to inline function | 152 | // TODO convert to inline function |
| 152 | switch (self.module.target.cpu.arch) { | 153 | switch (self.target.cpu.arch) { |
| 153 | .arm => return self.genAsmArch(.arm, inst), | 154 | .arm => return self.genAsmArch(.arm, inst), |
| 154 | .armeb => return self.genAsmArch(.armeb, inst), | 155 | .armeb => return self.genAsmArch(.armeb, inst), |
| 155 | .aarch64 => return self.genAsmArch(.aarch64, inst), | 156 | .aarch64 => return self.genAsmArch(.aarch64, inst), |
| ... | @@ -388,7 +389,7 @@ const Function = struct { | ... | @@ -388,7 +389,7 @@ const Function = struct { |
| 388 | } | 389 | } |
| 389 | } | 390 | } |
| 390 | 391 | ||
| 391 | fn genTypedValue(self: *Function, src: usize, typed_value: ir.TypedValue) !MCValue { | 392 | fn genTypedValue(self: *Function, src: usize, typed_value: TypedValue) !MCValue { |
| 392 | switch (typed_value.ty.zigTypeTag()) { | 393 | switch (typed_value.ty.zigTypeTag()) { |
| 393 | .Pointer => { | 394 | .Pointer => { |
| 394 | const ptr_elem_type = typed_value.ty.elemType(); | 395 | const ptr_elem_type = typed_value.ty.elemType(); |
| ... | @@ -410,8 +411,8 @@ const Function = struct { | ... | @@ -410,8 +411,8 @@ const Function = struct { |
| 410 | } | 411 | } |
| 411 | }, | 412 | }, |
| 412 | .Int => { | 413 | .Int => { |
| 413 | const info = typed_value.ty.intInfo(self.module.target); | 414 | const info = typed_value.ty.intInfo(self.target.*); |
| 414 | const ptr_bits = self.module.target.cpu.arch.ptrBitWidth(); | 415 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 415 | if (info.bits > ptr_bits or info.signed) { | 416 | if (info.bits > ptr_bits or info.signed) { |
| 416 | return self.fail(src, "TODO const int bigger than ptr and signed int", .{}); | 417 | return self.fail(src, "TODO const int bigger than ptr and signed int", .{}); |
| 417 | } | 418 | } |
src-self-hosted/link.zig+26-23| ... | @@ -685,23 +685,20 @@ pub const ElfFile = struct { | ... | @@ -685,23 +685,20 @@ pub const ElfFile = struct { |
| 685 | // TODO Also detect virtual address collisions. | 685 | // TODO Also detect virtual address collisions. |
| 686 | const text_capacity = self.allocatedSize(shdr.sh_offset); | 686 | const text_capacity = self.allocatedSize(shdr.sh_offset); |
| 687 | // TODO instead of looping here, maintain a free list and a pointer to the end. | 687 | // TODO instead of looping here, maintain a free list and a pointer to the end. |
| 688 | const end_vaddr = blk: { | 688 | var last_start: u64 = 0; |
| 689 | var start: u64 = 0; | 689 | var last_size: u64 = 0; |
| 690 | var size: u64 = 0; | 690 | for (self.symbols.items) |sym| { |
| 691 | for (self.symbols.items) |sym| { | 691 | if (sym.st_value > last_start) { |
| 692 | if (sym.st_value > start) { | 692 | last_start = sym.st_value; |
| 693 | start = sm.st_value; | 693 | last_size = sym.st_size; |
| 694 | size = sym.st_size; | ||
| 695 | } | ||
| 696 | } | 694 | } |
| 697 | break :blk start + (size * alloc_num / alloc_den); | 695 | } |
| 698 | }; | 696 | const end_vaddr = last_start + (last_size * alloc_num / alloc_den); |
| 699 | 697 | const needed_size = (end_vaddr + new_block_size) - phdr.p_vaddr; | |
| 700 | const text_size = end_vaddr - phdr.p_vaddr; | ||
| 701 | const needed_size = text_size + new_block_size; | ||
| 702 | if (needed_size > text_capacity) { | 698 | if (needed_size > text_capacity) { |
| 703 | // Must move the entire text section. | 699 | // Must move the entire text section. |
| 704 | const new_offset = self.findFreeSpace(needed_size, 0x1000); | 700 | const new_offset = self.findFreeSpace(needed_size, 0x1000); |
| 701 | const text_size = (last_start + last_size) - phdr.p_vaddr; | ||
| 705 | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, text_size); | 702 | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, text_size); |
| 706 | if (amt != text_size) return error.InputOutput; | 703 | if (amt != text_size) return error.InputOutput; |
| 707 | shdr.sh_offset = new_offset; | 704 | shdr.sh_offset = new_offset; |
| ... | @@ -713,6 +710,12 @@ pub const ElfFile = struct { | ... | @@ -713,6 +710,12 @@ pub const ElfFile = struct { |
| 713 | 710 | ||
| 714 | self.phdr_table_dirty = true; // TODO look into making only the one program header dirty | 711 | self.phdr_table_dirty = true; // TODO look into making only the one program header dirty |
| 715 | self.shdr_table_dirty = true; // TODO look into making only the one section dirty | 712 | self.shdr_table_dirty = true; // TODO look into making only the one section dirty |
| 713 | |||
| 714 | return AllocatedBlock{ | ||
| 715 | .vaddr = end_vaddr, | ||
| 716 | .file_offset = shdr.sh_offset + (end_vaddr - phdr.p_vaddr), | ||
| 717 | .size_capacity = text_capacity - end_vaddr, | ||
| 718 | }; | ||
| 716 | } | 719 | } |
| 717 | 720 | ||
| 718 | fn findAllocatedTextBlock(self: *ElfFile, sym: elf.Elf64_Sym) AllocatedBlock { | 721 | fn findAllocatedTextBlock(self: *ElfFile, sym: elf.Elf64_Sym) AllocatedBlock { |
| ... | @@ -739,8 +742,8 @@ pub const ElfFile = struct { | ... | @@ -739,8 +742,8 @@ pub const ElfFile = struct { |
| 739 | defer code.deinit(); | 742 | defer code.deinit(); |
| 740 | 743 | ||
| 741 | const typed_value = decl.typed_value.most_recent.typed_value; | 744 | const typed_value = decl.typed_value.most_recent.typed_value; |
| 742 | const err_msg = try codegen.generateSymbol(typed_value, module.*, &code); | 745 | const err_msg = try codegen.generateSymbol(self, typed_value, &code); |
| 743 | if (err_msg != null) |em| { | 746 | if (err_msg) |em| { |
| 744 | decl.analysis = .codegen_failure; | 747 | decl.analysis = .codegen_failure; |
| 745 | _ = try module.failed_decls.put(decl, em); | 748 | _ = try module.failed_decls.put(decl, em); |
| 746 | return; | 749 | return; |
| ... | @@ -755,7 +758,7 @@ pub const ElfFile = struct { | ... | @@ -755,7 +758,7 @@ pub const ElfFile = struct { |
| 755 | 758 | ||
| 756 | if (decl.link.local_sym_index != 0) { | 759 | if (decl.link.local_sym_index != 0) { |
| 757 | const local_sym = &self.symbols.items[decl.link.local_sym_index]; | 760 | const local_sym = &self.symbols.items[decl.link.local_sym_index]; |
| 758 | const existing_block = self.findAllocatedTextBlock(local_sym); | 761 | const existing_block = self.findAllocatedTextBlock(local_sym.*); |
| 759 | const file_offset = if (code_size > existing_block.size_capacity) fo: { | 762 | const file_offset = if (code_size > existing_block.size_capacity) fo: { |
| 760 | const new_block = try self.allocateTextBlock(code_size); | 763 | const new_block = try self.allocateTextBlock(code_size); |
| 761 | local_sym.st_value = new_block.vaddr; | 764 | local_sym.st_value = new_block.vaddr; |
| ... | @@ -765,7 +768,7 @@ pub const ElfFile = struct { | ... | @@ -765,7 +768,7 @@ pub const ElfFile = struct { |
| 765 | 768 | ||
| 766 | break :fo new_block.file_offset; | 769 | break :fo new_block.file_offset; |
| 767 | } else existing_block.file_offset; | 770 | } else existing_block.file_offset; |
| 768 | local_sym.st_name = try self.updateString(local_sym.st_name, mem.spanZ(u8, decl.name)); | 771 | local_sym.st_name = try self.updateString(local_sym.st_name, mem.spanZ(decl.name)); |
| 769 | local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits; | 772 | local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits; |
| 770 | // TODO this write could be avoided if no fields of the symbol were changed. | 773 | // TODO this write could be avoided if no fields of the symbol were changed. |
| 771 | try self.writeSymbol(decl.link.local_sym_index); | 774 | try self.writeSymbol(decl.link.local_sym_index); |
| ... | @@ -773,7 +776,7 @@ pub const ElfFile = struct { | ... | @@ -773,7 +776,7 @@ pub const ElfFile = struct { |
| 773 | } else { | 776 | } else { |
| 774 | try self.symbols.ensureCapacity(self.allocator, self.symbols.items.len + 1); | 777 | try self.symbols.ensureCapacity(self.allocator, self.symbols.items.len + 1); |
| 775 | try self.offset_table.ensureCapacity(self.allocator, self.offset_table.items.len + 1); | 778 | try self.offset_table.ensureCapacity(self.allocator, self.offset_table.items.len + 1); |
| 776 | const decl_name = mem.spanZ(u8, decl.name); | 779 | const decl_name = mem.spanZ(decl.name); |
| 777 | const name_str_index = try self.makeString(decl_name); | 780 | const name_str_index = try self.makeString(decl_name); |
| 778 | const new_block = try self.allocateTextBlock(code_size); | 781 | const new_block = try self.allocateTextBlock(code_size); |
| 779 | const local_sym_index = self.symbols.items.len; | 782 | const local_sym_index = self.symbols.items.len; |
| ... | @@ -796,8 +799,8 @@ pub const ElfFile = struct { | ... | @@ -796,8 +799,8 @@ pub const ElfFile = struct { |
| 796 | self.symbol_count_dirty = true; | 799 | self.symbol_count_dirty = true; |
| 797 | self.offset_table_count_dirty = true; | 800 | self.offset_table_count_dirty = true; |
| 798 | decl.link = .{ | 801 | decl.link = .{ |
| 799 | .local_sym_index = local_sym_index, | 802 | .local_sym_index = @intCast(u32, local_sym_index), |
| 800 | .offset_table_index = offset_table_index, | 803 | .offset_table_index = @intCast(u32, offset_table_index), |
| 801 | }; | 804 | }; |
| 802 | 805 | ||
| 803 | break :blk new_block.file_offset; | 806 | break :blk new_block.file_offset; |
| ... | @@ -807,7 +810,7 @@ pub const ElfFile = struct { | ... | @@ -807,7 +810,7 @@ pub const ElfFile = struct { |
| 807 | try self.file.pwriteAll(code.items, file_offset); | 810 | try self.file.pwriteAll(code.items, file_offset); |
| 808 | 811 | ||
| 809 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. | 812 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. |
| 810 | const decl_exports = module.decl_exports.get(decl) orelse &[0]*ir.Module.Export{}; | 813 | const decl_exports = module.decl_exports.getValue(decl) orelse &[0]*ir.Module.Export{}; |
| 811 | return self.updateDeclExports(module, decl, decl_exports); | 814 | return self.updateDeclExports(module, decl, decl_exports); |
| 812 | } | 815 | } |
| 813 | 816 | ||
| ... | @@ -938,9 +941,9 @@ pub const ElfFile = struct { | ... | @@ -938,9 +941,9 @@ pub const ElfFile = struct { |
| 938 | const needed_size = self.symbols.items.len * shdr.sh_entsize; | 941 | const needed_size = self.symbols.items.len * shdr.sh_entsize; |
| 939 | if (needed_size > allocated_size) { | 942 | if (needed_size > allocated_size) { |
| 940 | // Must move the entire got section. | 943 | // Must move the entire got section. |
| 941 | const new_offset = self.findFreeSpace(needed_size, shdr.sh_entsize); | 944 | const new_offset = self.findFreeSpace(needed_size, @intCast(u16, shdr.sh_entsize)); |
| 942 | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, shdr.sh_size); | 945 | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, shdr.sh_size); |
| 943 | if (amt != text_size) return error.InputOutput; | 946 | if (amt != shdr.sh_size) return error.InputOutput; |
| 944 | shdr.sh_offset = new_offset; | 947 | shdr.sh_offset = new_offset; |
| 945 | } | 948 | } |
| 946 | shdr.sh_size = needed_size; | 949 | shdr.sh_size = needed_size; |