| ... | @@ -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 | } |
| 499 | | 499 | |
| 500 | fn getString(self: *Elf, str_off: u32) []const u8 { | 500 | fn 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(); |
| 1017 | | 1017 | |
| | 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 |
| 1167 | | 1171 | |
| 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 |
| 1180 | | 1184 | |
| 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 section | 2814 | 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 { |
| 2857 | | 2878 | |
| 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); |
| 2864 | | 2886 | |
| 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); |
| 2883 | | 2906 | |
| 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 | |
| | 3222 | fn 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 | } |