Commit 0cab01adbf

Jakub Konka <kubkon@jakubkonka.com>
2022-06-06 09:43:05
elf: refactor and enhance logging symtab
1 parent 33826a6
Changed files (1)
src
link
src/link/Elf.zig
@@ -497,7 +497,7 @@ fn makeString(self: *Elf, bytes: []const u8) !u32 {
     return @intCast(u32, result);
 }
 
-fn getString(self: *Elf, str_off: u32) []const u8 {
+fn getString(self: Elf, str_off: u32) []const u8 {
     assert(str_off < self.shstrtab.items.len);
     return mem.sliceTo(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off), 0);
 }
@@ -1015,6 +1015,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
     // mixing local and global symbols within a symbol table.
     try self.writeAllGlobalSymbols();
 
+    if (build_options.enable_logging) {
+        self.logSymtab();
+    }
+
     if (self.dwarf) |*dw| {
         if (self.debug_abbrev_section_dirty) {
             try dw.writeDbgAbbrev(&self.base);
@@ -1167,7 +1171,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
 
                 for (buf) |*shdr, i| {
                     shdr.* = sectHeaderTo32(self.sections.items[i]);
-                    log.debug("writing section {}", .{shdr.*});
+                    log.debug("writing section {s}: {}", .{ self.getString(shdr.sh_name), shdr.* });
                     if (foreign_endian) {
                         mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);
                     }
@@ -1180,7 +1184,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
 
                 for (buf) |*shdr, i| {
                     shdr.* = self.sections.items[i];
-                    log.debug("writing section {}", .{shdr.*});
+                    log.debug("writing section {s}: {}", .{ self.getString(shdr.sh_name), shdr.* });
                     if (foreign_endian) {
                         mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);
                     }
@@ -2794,8 +2798,14 @@ fn writeSymbol(self: *Elf, index: usize) !void {
         if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {
             // Move all the symbols to a new file location.
             const new_offset = self.findFreeSpace(needed_size, sym_align);
+            log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
             const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
-            const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size);
+            const amt = try self.base.file.?.copyRangeAll(
+                syms_sect.sh_offset,
+                self.base.file.?,
+                new_offset,
+                existing_size,
+            );
             if (amt != existing_size) return error.InputOutput;
             syms_sect.sh_offset = new_offset;
         }
@@ -2804,30 +2814,35 @@ fn writeSymbol(self: *Elf, index: usize) !void {
         self.shdr_table_dirty = true; // TODO look into only writing one section
     }
     const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
+    const off = switch (self.ptr_width) {
+        .p32 => syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index,
+        .p64 => syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index,
+    };
+    const local = self.local_symbols.items[index];
+    log.debug("writing symbol {d}, '{s}' at 0x{x}", .{ index, self.getString(local.st_name), off });
+    log.debug("  ({})", .{local});
     switch (self.ptr_width) {
         .p32 => {
             var sym = [1]elf.Elf32_Sym{
                 .{
-                    .st_name = self.local_symbols.items[index].st_name,
-                    .st_value = @intCast(u32, self.local_symbols.items[index].st_value),
-                    .st_size = @intCast(u32, self.local_symbols.items[index].st_size),
-                    .st_info = self.local_symbols.items[index].st_info,
-                    .st_other = self.local_symbols.items[index].st_other,
-                    .st_shndx = self.local_symbols.items[index].st_shndx,
+                    .st_name = local.st_name,
+                    .st_value = @intCast(u32, local.st_value),
+                    .st_size = @intCast(u32, local.st_size),
+                    .st_info = local.st_info,
+                    .st_other = local.st_other,
+                    .st_shndx = local.st_shndx,
                 },
             };
             if (foreign_endian) {
                 mem.byteSwapAllFields(elf.Elf32_Sym, &sym[0]);
             }
-            const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;
             try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
         },
         .p64 => {
-            var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};
+            var sym = [1]elf.Elf64_Sym{local};
             if (foreign_endian) {
                 mem.byteSwapAllFields(elf.Elf64_Sym, &sym[0]);
             }
-            const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;
             try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
         },
     }
@@ -2847,8 +2862,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
     if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {
         // Move all the symbols to a new file location.
         const new_offset = self.findFreeSpace(needed_size, sym_align);
+        log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
         const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
-        const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size);
+        const amt = try self.base.file.?.copyRangeAll(
+            syms_sect.sh_offset,
+            self.base.file.?,
+            new_offset,
+            existing_size,
+        );
         if (amt != existing_size) return error.InputOutput;
         syms_sect.sh_offset = new_offset;
     }
@@ -2857,19 +2878,21 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
 
     const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
     const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;
+    log.debug("writing {d} global symbols at 0x{x}", .{ self.global_symbols.items.len, global_syms_off });
     switch (self.ptr_width) {
         .p32 => {
             const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len);
             defer self.base.allocator.free(buf);
 
             for (buf) |*sym, i| {
+                const global = self.global_symbols.items[i];
                 sym.* = .{
-                    .st_name = self.global_symbols.items[i].st_name,
-                    .st_value = @intCast(u32, self.global_symbols.items[i].st_value),
-                    .st_size = @intCast(u32, self.global_symbols.items[i].st_size),
-                    .st_info = self.global_symbols.items[i].st_info,
-                    .st_other = self.global_symbols.items[i].st_other,
-                    .st_shndx = self.global_symbols.items[i].st_shndx,
+                    .st_name = global.st_name,
+                    .st_value = @intCast(u32, global.st_value),
+                    .st_size = @intCast(u32, global.st_size),
+                    .st_info = global.st_info,
+                    .st_other = global.st_other,
+                    .st_shndx = global.st_shndx,
                 };
                 if (foreign_endian) {
                     mem.byteSwapAllFields(elf.Elf32_Sym, sym);
@@ -2882,13 +2905,14 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
             defer self.base.allocator.free(buf);
 
             for (buf) |*sym, i| {
+                const global = self.global_symbols.items[i];
                 sym.* = .{
-                    .st_name = self.global_symbols.items[i].st_name,
-                    .st_value = self.global_symbols.items[i].st_value,
-                    .st_size = self.global_symbols.items[i].st_size,
-                    .st_info = self.global_symbols.items[i].st_info,
-                    .st_other = self.global_symbols.items[i].st_other,
-                    .st_shndx = self.global_symbols.items[i].st_shndx,
+                    .st_name = global.st_name,
+                    .st_value = global.st_value,
+                    .st_size = global.st_size,
+                    .st_info = global.st_info,
+                    .st_other = global.st_other,
+                    .st_shndx = global.st_shndx,
                 };
                 if (foreign_endian) {
                     mem.byteSwapAllFields(elf.Elf64_Sym, sym);
@@ -3194,3 +3218,14 @@ const CsuObjects = struct {
         self.crtn = crtn;
     }
 };
+
+fn logSymtab(self: Elf) void {
+    log.debug("locals:", .{});
+    for (self.local_symbols.items) |sym, id| {
+        log.debug("  {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.st_name), sym.st_value, sym.st_shndx });
+    }
+    log.debug("globals:", .{});
+    for (self.global_symbols.items) |sym, id| {
+        log.debug("  {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.st_name), sym.st_value, sym.st_shndx });
+    }
+}