authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-06 09:43:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-06 19:58:47+02:00
log0cab01adbf8ba495f214f948d34a3e6bd133bbc4
tree1ca552b985182c1a6f52092d300c5bcf51845bb0
parent33826a6a2e035d2a2be65314ed80a6b7abaf7f12

elf: refactor and enhance logging symtab


1 files changed, 61 insertions(+), 26 deletions(-)

src/link/Elf.zig+61-26
...@@ -497,7 +497,7 @@ fn makeString(self: *Elf, bytes: []const u8) !u32 {...@@ -497,7 +497,7 @@ fn makeString(self: *Elf, bytes: []const u8) !u32 {
497 return @intCast(u32, result);497 return @intCast(u32, result);
498}498}
499499
500fn getString(self: *Elf, str_off: u32) []const u8 {500fn getString(self: Elf, str_off: u32) []const u8 {
501 assert(str_off < self.shstrtab.items.len);501 assert(str_off < self.shstrtab.items.len);
502 return mem.sliceTo(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off), 0);502 return mem.sliceTo(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off), 0);
503}503}
...@@ -1015,6 +1015,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1015,6 +1015,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1015 // mixing local and global symbols within a symbol table.1015 // mixing local and global symbols within a symbol table.
1016 try self.writeAllGlobalSymbols();1016 try self.writeAllGlobalSymbols();
10171017
1018 if (build_options.enable_logging) {
1019 self.logSymtab();
1020 }
1021
1018 if (self.dwarf) |*dw| {1022 if (self.dwarf) |*dw| {
1019 if (self.debug_abbrev_section_dirty) {1023 if (self.debug_abbrev_section_dirty) {
1020 try dw.writeDbgAbbrev(&self.base);1024 try dw.writeDbgAbbrev(&self.base);
...@@ -1167,7 +1171,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1167,7 +1171,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11671171
1168 for (buf) |*shdr, i| {1172 for (buf) |*shdr, i| {
1169 shdr.* = sectHeaderTo32(self.sections.items[i]);1173 shdr.* = sectHeaderTo32(self.sections.items[i]);
1170 log.debug("writing section {}", .{shdr.*});1174 log.debug("writing section {s}: {}", .{ self.getString(shdr.sh_name), shdr.* });
1171 if (foreign_endian) {1175 if (foreign_endian) {
1172 mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);1176 mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);
1173 }1177 }
...@@ -1180,7 +1184,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1180,7 +1184,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11801184
1181 for (buf) |*shdr, i| {1185 for (buf) |*shdr, i| {
1182 shdr.* = self.sections.items[i];1186 shdr.* = self.sections.items[i];
1183 log.debug("writing section {}", .{shdr.*});1187 log.debug("writing section {s}: {}", .{ self.getString(shdr.sh_name), shdr.* });
1184 if (foreign_endian) {1188 if (foreign_endian) {
1185 mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);1189 mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);
1186 }1190 }
...@@ -2794,8 +2798,14 @@ fn writeSymbol(self: *Elf, index: usize) !void {...@@ -2794,8 +2798,14 @@ fn writeSymbol(self: *Elf, index: usize) !void {
2794 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {2798 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {
2795 // Move all the symbols to a new file location.2799 // Move all the symbols to a new file location.
2796 const new_offset = self.findFreeSpace(needed_size, sym_align);2800 const new_offset = self.findFreeSpace(needed_size, sym_align);
2801 log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
2797 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;2802 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
2798 const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size);2803 const amt = try self.base.file.?.copyRangeAll(
2804 syms_sect.sh_offset,
2805 self.base.file.?,
2806 new_offset,
2807 existing_size,
2808 );
2799 if (amt != existing_size) return error.InputOutput;2809 if (amt != existing_size) return error.InputOutput;
2800 syms_sect.sh_offset = new_offset;2810 syms_sect.sh_offset = new_offset;
2801 }2811 }
...@@ -2804,30 +2814,35 @@ fn writeSymbol(self: *Elf, index: usize) !void {...@@ -2804,30 +2814,35 @@ fn writeSymbol(self: *Elf, index: usize) !void {
2804 self.shdr_table_dirty = true; // TODO look into only writing one section2814 self.shdr_table_dirty = true; // TODO look into only writing one section
2805 }2815 }
2806 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();2816 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
2817 const off = switch (self.ptr_width) {
2818 .p32 => syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index,
2819 .p64 => syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index,
2820 };
2821 const local = self.local_symbols.items[index];
2822 log.debug("writing symbol {d}, '{s}' at 0x{x}", .{ index, self.getString(local.st_name), off });
2823 log.debug(" ({})", .{local});
2807 switch (self.ptr_width) {2824 switch (self.ptr_width) {
2808 .p32 => {2825 .p32 => {
2809 var sym = [1]elf.Elf32_Sym{2826 var sym = [1]elf.Elf32_Sym{
2810 .{2827 .{
2811 .st_name = self.local_symbols.items[index].st_name,2828 .st_name = local.st_name,
2812 .st_value = @intCast(u32, self.local_symbols.items[index].st_value),2829 .st_value = @intCast(u32, local.st_value),
2813 .st_size = @intCast(u32, self.local_symbols.items[index].st_size),2830 .st_size = @intCast(u32, local.st_size),
2814 .st_info = self.local_symbols.items[index].st_info,2831 .st_info = local.st_info,
2815 .st_other = self.local_symbols.items[index].st_other,2832 .st_other = local.st_other,
2816 .st_shndx = self.local_symbols.items[index].st_shndx,2833 .st_shndx = local.st_shndx,
2817 },2834 },
2818 };2835 };
2819 if (foreign_endian) {2836 if (foreign_endian) {
2820 mem.byteSwapAllFields(elf.Elf32_Sym, &sym[0]);2837 mem.byteSwapAllFields(elf.Elf32_Sym, &sym[0]);
2821 }2838 }
2822 const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;
2823 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2839 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
2824 },2840 },
2825 .p64 => {2841 .p64 => {
2826 var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};2842 var sym = [1]elf.Elf64_Sym{local};
2827 if (foreign_endian) {2843 if (foreign_endian) {
2828 mem.byteSwapAllFields(elf.Elf64_Sym, &sym[0]);2844 mem.byteSwapAllFields(elf.Elf64_Sym, &sym[0]);
2829 }2845 }
2830 const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;
2831 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2846 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
2832 },2847 },
2833 }2848 }
...@@ -2847,8 +2862,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2847,8 +2862,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
2847 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {2862 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {
2848 // Move all the symbols to a new file location.2863 // Move all the symbols to a new file location.
2849 const new_offset = self.findFreeSpace(needed_size, sym_align);2864 const new_offset = self.findFreeSpace(needed_size, sym_align);
2865 log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
2850 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;2866 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
2851 const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size);2867 const amt = try self.base.file.?.copyRangeAll(
2868 syms_sect.sh_offset,
2869 self.base.file.?,
2870 new_offset,
2871 existing_size,
2872 );
2852 if (amt != existing_size) return error.InputOutput;2873 if (amt != existing_size) return error.InputOutput;
2853 syms_sect.sh_offset = new_offset;2874 syms_sect.sh_offset = new_offset;
2854 }2875 }
...@@ -2857,19 +2878,21 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2857,19 +2878,21 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
28572878
2858 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();2879 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
2859 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;2880 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;
2881 log.debug("writing {d} global symbols at 0x{x}", .{ self.global_symbols.items.len, global_syms_off });
2860 switch (self.ptr_width) {2882 switch (self.ptr_width) {
2861 .p32 => {2883 .p32 => {
2862 const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len);2884 const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len);
2863 defer self.base.allocator.free(buf);2885 defer self.base.allocator.free(buf);
28642886
2865 for (buf) |*sym, i| {2887 for (buf) |*sym, i| {
2888 const global = self.global_symbols.items[i];
2866 sym.* = .{2889 sym.* = .{
2867 .st_name = self.global_symbols.items[i].st_name,2890 .st_name = global.st_name,
2868 .st_value = @intCast(u32, self.global_symbols.items[i].st_value),2891 .st_value = @intCast(u32, global.st_value),
2869 .st_size = @intCast(u32, self.global_symbols.items[i].st_size),2892 .st_size = @intCast(u32, global.st_size),
2870 .st_info = self.global_symbols.items[i].st_info,2893 .st_info = global.st_info,
2871 .st_other = self.global_symbols.items[i].st_other,2894 .st_other = global.st_other,
2872 .st_shndx = self.global_symbols.items[i].st_shndx,2895 .st_shndx = global.st_shndx,
2873 };2896 };
2874 if (foreign_endian) {2897 if (foreign_endian) {
2875 mem.byteSwapAllFields(elf.Elf32_Sym, sym);2898 mem.byteSwapAllFields(elf.Elf32_Sym, sym);
...@@ -2882,13 +2905,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2882,13 +2905,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
2882 defer self.base.allocator.free(buf);2905 defer self.base.allocator.free(buf);
28832906
2884 for (buf) |*sym, i| {2907 for (buf) |*sym, i| {
2908 const global = self.global_symbols.items[i];
2885 sym.* = .{2909 sym.* = .{
2886 .st_name = self.global_symbols.items[i].st_name,2910 .st_name = global.st_name,
2887 .st_value = self.global_symbols.items[i].st_value,2911 .st_value = global.st_value,
2888 .st_size = self.global_symbols.items[i].st_size,2912 .st_size = global.st_size,
2889 .st_info = self.global_symbols.items[i].st_info,2913 .st_info = global.st_info,
2890 .st_other = self.global_symbols.items[i].st_other,2914 .st_other = global.st_other,
2891 .st_shndx = self.global_symbols.items[i].st_shndx,2915 .st_shndx = global.st_shndx,
2892 };2916 };
2893 if (foreign_endian) {2917 if (foreign_endian) {
2894 mem.byteSwapAllFields(elf.Elf64_Sym, sym);2918 mem.byteSwapAllFields(elf.Elf64_Sym, sym);
...@@ -3194,3 +3218,14 @@ const CsuObjects = struct {...@@ -3194,3 +3218,14 @@ const CsuObjects = struct {
3194 self.crtn = crtn;3218 self.crtn = crtn;
3195 }3219 }
3196};3220};
3221
3222fn logSymtab(self: Elf) void {
3223 log.debug("locals:", .{});
3224 for (self.local_symbols.items) |sym, id| {
3225 log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.st_name), sym.st_value, sym.st_shndx });
3226 }
3227 log.debug("globals:", .{});
3228 for (self.global_symbols.items) |sym, id| {
3229 log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.st_name), sym.st_value, sym.st_shndx });
3230 }
3231}