| ... | @@ -4797,7 +4797,11 @@ fn writeAtomsObject(self: *Elf) !void { | ... | @@ -4797,7 +4797,11 @@ fn writeAtomsObject(self: *Elf) !void { |
| 4797 | return error.Overflow; | 4797 | return error.Overflow; |
| 4798 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; | 4798 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 4799 | | 4799 | |
| 4800 | log.debug("writing atom({d}) at 0x{x}", .{ atom_index, sh_offset + offset }); | 4800 | log.debug("writing atom({d}) from 0x{x} to 0x{x}", .{ |
| | 4801 | atom_index, |
| | 4802 | sh_offset + offset, |
| | 4803 | sh_offset + offset + size, |
| | 4804 | }); |
| 4801 | | 4805 | |
| 4802 | // TODO decompress directly into provided buffer | 4806 | // TODO decompress directly into provided buffer |
| 4803 | const out_code = buffer[offset..][0..size]; | 4807 | const out_code = buffer[offset..][0..size]; |
| ... | @@ -5048,6 +5052,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -5048,6 +5052,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5048 | if (!atom_ptr.flags.alive) continue; | 5052 | if (!atom_ptr.flags.alive) continue; |
| 5049 | try atom_ptr.writeRelocs(self, &relocs); | 5053 | try atom_ptr.writeRelocs(self, &relocs); |
| 5050 | } | 5054 | } |
| | 5055 | assert(relocs.items.len == num_relocs); |
| 5051 | | 5056 | |
| 5052 | const SortRelocs = struct { | 5057 | const SortRelocs = struct { |
| 5053 | pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool { | 5058 | pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool { |
| ... | @@ -5058,6 +5063,12 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -5058,6 +5063,12 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5058 | | 5063 | |
| 5059 | mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan); | 5064 | mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan); |
| 5060 | | 5065 | |
| | 5066 | log.debug("writing {s} from 0x{x} to 0x{x}", .{ |
| | 5067 | self.getShString(shdr.sh_name), |
| | 5068 | shdr.sh_offset, |
| | 5069 | shdr.sh_offset + shdr.sh_size, |
| | 5070 | }); |
| | 5071 | |
| 5061 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); | 5072 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); |
| 5062 | } | 5073 | } |
| 5063 | | 5074 | |
| ... | @@ -5067,6 +5078,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -5067,6 +5078,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5067 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 5078 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5068 | defer buffer.deinit(); | 5079 | defer buffer.deinit(); |
| 5069 | try eh_frame.writeEhFrameObject(self, buffer.writer()); | 5080 | try eh_frame.writeEhFrameObject(self, buffer.writer()); |
| | 5081 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ |
| | 5082 | shdr.sh_offset, |
| | 5083 | shdr.sh_offset + shdr.sh_size, |
| | 5084 | }); |
| | 5085 | assert(buffer.items.len == sh_size); |
| 5070 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 5086 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 5071 | } | 5087 | } |
| 5072 | if (self.eh_frame_rela_section_index) |shndx| { | 5088 | if (self.eh_frame_rela_section_index) |shndx| { |
| ... | @@ -5075,6 +5091,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -5075,6 +5091,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5075 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 5091 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5076 | defer buffer.deinit(); | 5092 | defer buffer.deinit(); |
| 5077 | try eh_frame.writeEhFrameRelocs(self, buffer.writer()); | 5093 | try eh_frame.writeEhFrameRelocs(self, buffer.writer()); |
| | 5094 | assert(buffer.items.len == sh_size); |
| | 5095 | log.debug("writing .rela.eh_frame from 0x{x} to 0x{x}", .{ |
| | 5096 | shdr.sh_offset, |
| | 5097 | shdr.sh_offset + shdr.sh_size, |
| | 5098 | }); |
| 5078 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 5099 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 5079 | } | 5100 | } |
| 5080 | | 5101 | |
| ... | @@ -5091,6 +5112,11 @@ fn writeComdatGroups(self: *Elf) !void { | ... | @@ -5091,6 +5112,11 @@ fn writeComdatGroups(self: *Elf) !void { |
| 5091 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 5112 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5092 | defer buffer.deinit(); | 5113 | defer buffer.deinit(); |
| 5093 | try cgs.write(self, buffer.writer()); | 5114 | try cgs.write(self, buffer.writer()); |
| | 5115 | assert(buffer.items.len == sh_size); |
| | 5116 | log.debug("writing COMDAT group from 0x{x} to 0x{x}", .{ |
| | 5117 | shdr.sh_offset, |
| | 5118 | shdr.sh_offset + shdr.sh_size, |
| | 5119 | }); |
| 5094 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 5120 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 5095 | } | 5121 | } |
| 5096 | } | 5122 | } |
| ... | @@ -5098,6 +5124,7 @@ fn writeComdatGroups(self: *Elf) !void { | ... | @@ -5098,6 +5124,7 @@ fn writeComdatGroups(self: *Elf) !void { |
| 5098 | fn writeShStrtab(self: *Elf) !void { | 5124 | fn writeShStrtab(self: *Elf) !void { |
| 5099 | if (self.shstrtab_section_index) |index| { | 5125 | if (self.shstrtab_section_index) |index| { |
| 5100 | const shdr = self.shdrs.items[index]; | 5126 | const shdr = self.shdrs.items[index]; |
| | 5127 | log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size }); |
| 5101 | try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset); | 5128 | try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset); |
| 5102 | } | 5129 | } |
| 5103 | } | 5130 | } |
| ... | @@ -5112,7 +5139,15 @@ fn writeSymtab(self: *Elf) !void { | ... | @@ -5112,7 +5139,15 @@ fn writeSymtab(self: *Elf) !void { |
| 5112 | }; | 5139 | }; |
| 5113 | const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow; | 5140 | const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow; |
| 5114 | | 5141 | |
| 5115 | log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset }); | 5142 | log.debug("writing {d} symbols in .symtab from 0x{x} to 0x{x}", .{ |
| | 5143 | nsyms, |
| | 5144 | symtab_shdr.sh_offset, |
| | 5145 | symtab_shdr.sh_offset + symtab_shdr.sh_size, |
| | 5146 | }); |
| | 5147 | log.debug("writing .strtab from 0x{x} to 0x{x}", .{ |
| | 5148 | strtab_shdr.sh_offset, |
| | 5149 | strtab_shdr.sh_offset + strtab_shdr.sh_size, |
| | 5150 | }); |
| 5116 | | 5151 | |
| 5117 | try self.symtab.resize(gpa, nsyms); | 5152 | try self.symtab.resize(gpa, nsyms); |
| 5118 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; | 5153 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| ... | @@ -5185,55 +5220,6 @@ fn writeSymtab(self: *Elf) !void { | ... | @@ -5185,55 +5220,6 @@ fn writeSymtab(self: *Elf) !void { |
| 5185 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); | 5220 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); |
| 5186 | } | 5221 | } |
| 5187 | | 5222 | |
| 5188 | fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { | | |
| 5189 | const gpa = self.base.allocator; | | |
| 5190 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; | | |
| 5191 | const strtab_shdr = self.shdrs.items[self.strtab_section_index.?]; | | |
| 5192 | const sym_size: u64 = switch (self.ptr_width) { | | |
| 5193 | .p32 => @sizeOf(elf.Elf32_Sym), | | |
| 5194 | .p64 => @sizeOf(elf.Elf64_Sym), | | |
| 5195 | }; | | |
| 5196 | const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow; | | |
| 5197 | | | |
| 5198 | log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset }); | | |
| 5199 | | | |
| 5200 | try self.symtab.resize(gpa, nsyms); | | |
| 5201 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; | | |
| 5202 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); | | |
| 5203 | | | |
| 5204 | self.writeSectionSymbols(); | | |
| 5205 | zig_object.asFile().writeSymtab(self); | | |
| 5206 | | | |
| 5207 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); | | |
| 5208 | switch (self.ptr_width) { | | |
| 5209 | .p32 => { | | |
| 5210 | const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len); | | |
| 5211 | defer gpa.free(buf); | | |
| 5212 | | | |
| 5213 | for (buf, self.symtab.items) |*out, sym| { | | |
| 5214 | out.* = .{ | | |
| 5215 | .st_name = sym.st_name, | | |
| 5216 | .st_info = sym.st_info, | | |
| 5217 | .st_other = sym.st_other, | | |
| 5218 | .st_shndx = sym.st_shndx, | | |
| 5219 | .st_value = @as(u32, @intCast(sym.st_value)), | | |
| 5220 | .st_size = @as(u32, @intCast(sym.st_size)), | | |
| 5221 | }; | | |
| 5222 | if (foreign_endian) mem.byteSwapAllFields(elf.Elf32_Sym, out); | | |
| 5223 | } | | |
| 5224 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), symtab_shdr.sh_offset); | | |
| 5225 | }, | | |
| 5226 | .p64 => { | | |
| 5227 | if (foreign_endian) { | | |
| 5228 | for (self.symtab.items) |*sym| mem.byteSwapAllFields(elf.Elf64_Sym, sym); | | |
| 5229 | } | | |
| 5230 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), symtab_shdr.sh_offset); | | |
| 5231 | }, | | |
| 5232 | } | | |
| 5233 | | | |
| 5234 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); | | |
| 5235 | } | | |
| 5236 | | | |
| 5237 | fn writeSectionSymbols(self: *Elf) void { | 5223 | fn writeSectionSymbols(self: *Elf) void { |
| 5238 | var ilocal: u32 = 1; | 5224 | var ilocal: u32 = 1; |
| 5239 | for (self.output_sections.keys()) |shndx| { | 5225 | for (self.output_sections.keys()) |shndx| { |