| ... | ... | @@ -4797,7 +4797,11 @@ fn writeAtomsObject(self: *Elf) !void { |
| 4797 | 4797 | return error.Overflow; |
| 4798 | 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 | 4806 | // TODO decompress directly into provided buffer |
| 4803 | 4807 | const out_code = buffer[offset..][0..size]; |
| ... | ... | @@ -5048,6 +5052,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5048 | 5052 | if (!atom_ptr.flags.alive) continue; |
| 5049 | 5053 | try atom_ptr.writeRelocs(self, &relocs); |
| 5050 | 5054 | } |
| 5055 | assert(relocs.items.len == num_relocs); |
| 5051 | 5056 | |
| 5052 | 5057 | const SortRelocs = struct { |
| 5053 | 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 | 5063 | |
| 5059 | 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 | 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 | 5078 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5068 | 5079 | defer buffer.deinit(); |
| 5069 | 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 | 5086 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 5071 | 5087 | } |
| 5072 | 5088 | if (self.eh_frame_rela_section_index) |shndx| { |
| ... | ... | @@ -5075,6 +5091,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5075 | 5091 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5076 | 5092 | defer buffer.deinit(); |
| 5077 | 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 | 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 | 5112 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5092 | 5113 | defer buffer.deinit(); |
| 5093 | 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 | 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 | 5124 | fn writeShStrtab(self: *Elf) !void { |
| 5099 | 5125 | if (self.shstrtab_section_index) |index| { |
| 5100 | 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 | 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 | 5139 | }; |
| 5113 | 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 | 5152 | try self.symtab.resize(gpa, nsyms); |
| 5118 | 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 | 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 | 5223 | fn writeSectionSymbols(self: *Elf) void { |
| 5238 | 5224 | var ilocal: u32 = 1; |
| 5239 | 5225 | for (self.output_sections.keys()) |shndx| { |