mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #11804 from ziglang/elf-dwarf-unions
dwarf: fix incorrect type relocations for union payloads
This commit is contained in:
commit
920f1dcd27
@ -3187,7 +3187,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {
|
||||
.macho => unreachable,
|
||||
else => unreachable,
|
||||
};
|
||||
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
||||
@ -754,7 +754,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
|
||||
.macho => unreachable,
|
||||
else => unreachable,
|
||||
};
|
||||
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
||||
@ -1550,7 +1550,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
|
||||
.elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,
|
||||
else => unreachable,
|
||||
};
|
||||
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
@ -1050,7 +1050,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
|
||||
const index = dbg_info.items.len;
|
||||
try dbg_info.resize(index + 4);
|
||||
const atom = &self.decl.link.wasm.dbg_info_atom;
|
||||
try dwarf.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
try dwarf.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
|
||||
},
|
||||
.plan9 => unreachable,
|
||||
.none => {},
|
||||
|
||||
@ -4371,7 +4371,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
|
||||
.macho => &fn_owner_decl.link.macho.dbg_info_atom,
|
||||
else => unreachable,
|
||||
};
|
||||
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
||||
@ -110,13 +110,22 @@ pub const DeclState = struct {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn addTypeReloc(
|
||||
self: *DeclState,
|
||||
atom: *const Atom,
|
||||
ty: Type,
|
||||
offset: u32,
|
||||
addend: ?u32,
|
||||
) !void {
|
||||
/// Adds local type relocation of the form: @offset => @this + addend
|
||||
/// @this signifies the offset within the .debug_abbrev section of the containing atom.
|
||||
pub fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
|
||||
log.debug("{x}: @this + {x}", .{ offset, addend });
|
||||
try self.abbrev_relocs.append(self.gpa, .{
|
||||
.target = null,
|
||||
.atom = atom,
|
||||
.offset = offset,
|
||||
.addend = addend,
|
||||
});
|
||||
}
|
||||
|
||||
/// Adds global type relocation of the form: @offset => @symbol + 0
|
||||
/// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
|
||||
/// which we use as our target of the relocation.
|
||||
pub fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
|
||||
const resolv = self.abbrev_resolver.getContext(ty, .{
|
||||
.mod = self.mod,
|
||||
}) orelse blk: {
|
||||
@ -134,14 +143,12 @@ pub const DeclState = struct {
|
||||
.mod = self.mod,
|
||||
}).?;
|
||||
};
|
||||
const add: u32 = addend orelse 0;
|
||||
|
||||
log.debug("{x}: @{d} + {x}", .{ offset, resolv, add });
|
||||
log.debug("{x}: @{d} + 0", .{ offset, resolv });
|
||||
try self.abbrev_relocs.append(self.gpa, .{
|
||||
.target = resolv,
|
||||
.atom = atom,
|
||||
.offset = offset,
|
||||
.addend = add,
|
||||
.addend = 0,
|
||||
});
|
||||
}
|
||||
|
||||
@ -213,7 +220,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
var index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, Type.bool, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, Type.bool, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try dbg_info_buffer.ensureUnusedCapacity(6);
|
||||
dbg_info_buffer.appendAssumeCapacity(0);
|
||||
@ -225,7 +232,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, payload_ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
const offset = abi_size - payload_ty.abiSize(target);
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
|
||||
@ -254,7 +261,7 @@ pub const DeclState = struct {
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
|
||||
const ptr_ty = ty.slicePtrFieldType(buf);
|
||||
try self.addTypeReloc(atom, ptr_ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, ptr_ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try dbg_info_buffer.ensureUnusedCapacity(6);
|
||||
dbg_info_buffer.appendAssumeCapacity(0);
|
||||
@ -266,7 +273,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, Type.usize, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try dbg_info_buffer.ensureUnusedCapacity(2);
|
||||
dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));
|
||||
@ -278,7 +285,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
const index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, ty.childType(), @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
|
||||
}
|
||||
},
|
||||
.Array => {
|
||||
@ -289,13 +296,13 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
var index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, ty.childType(), @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
|
||||
// DW.AT.subrange_type
|
||||
try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim));
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, Type.usize, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
|
||||
// DW.AT.count, DW.FORM.udata
|
||||
const len = ty.arrayLenIncludingSentinel();
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), len);
|
||||
@ -323,7 +330,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
var index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, field, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, field, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
const field_off = ty.structFieldOffset(field_index, target);
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
|
||||
@ -354,7 +361,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
var index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, field.ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
const field_off = ty.structFieldOffset(field_index, target);
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
|
||||
@ -434,7 +441,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
const inner_union_index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(inner_union_index + 4);
|
||||
try self.addTypeReloc(atom, ty, @intCast(u32, inner_union_index), 5);
|
||||
try self.addTypeRelocLocal(atom, @intCast(u32, inner_union_index), 5);
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset);
|
||||
}
|
||||
@ -461,7 +468,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
const index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, field.ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try dbg_info_buffer.append(0);
|
||||
}
|
||||
@ -478,7 +485,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
const index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, union_obj.tag_ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, union_obj.tag_ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset);
|
||||
|
||||
@ -521,7 +528,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
var index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, payload_ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off);
|
||||
|
||||
@ -534,7 +541,7 @@ pub const DeclState = struct {
|
||||
// DW.AT.type, DW.FORM.ref4
|
||||
index = dbg_info_buffer.items.len;
|
||||
try dbg_info_buffer.resize(index + 4);
|
||||
try self.addTypeReloc(atom, error_ty, @intCast(u32, index), null);
|
||||
try self.addTypeRelocGlobal(atom, error_ty, @intCast(u32, index));
|
||||
// DW.AT.data_member_location, DW.FORM.sdata
|
||||
try leb128.writeULEB128(dbg_info_buffer.writer(), error_off);
|
||||
|
||||
@ -556,7 +563,9 @@ pub const AbbrevEntry = struct {
|
||||
};
|
||||
|
||||
pub const AbbrevRelocation = struct {
|
||||
target: u32,
|
||||
/// If target is null, we deal with a local relocation that is based on simple offset + addend
|
||||
/// only.
|
||||
target: ?u32,
|
||||
atom: *const Atom,
|
||||
offset: u32,
|
||||
addend: u32,
|
||||
@ -740,12 +749,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState
|
||||
.wasm => &decl.link.wasm.dbg_info_atom,
|
||||
else => unreachable,
|
||||
};
|
||||
try decl_state.addTypeReloc(
|
||||
atom,
|
||||
fn_ret_type,
|
||||
@intCast(u32, dbg_info_buffer.items.len),
|
||||
null,
|
||||
);
|
||||
try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
|
||||
dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
|
||||
}
|
||||
|
||||
@ -1036,30 +1040,39 @@ pub fn commitDeclState(
|
||||
try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));
|
||||
|
||||
while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
|
||||
const symbol = decl_state.abbrev_table.items[reloc.target];
|
||||
const ty = symbol.@"type";
|
||||
const deferred: bool = blk: {
|
||||
if (ty.isAnyError()) break :blk true;
|
||||
switch (ty.tag()) {
|
||||
.error_set_inferred => {
|
||||
if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
|
||||
},
|
||||
else => {},
|
||||
if (reloc.target) |target| {
|
||||
const symbol = decl_state.abbrev_table.items[target];
|
||||
const ty = symbol.@"type";
|
||||
const deferred: bool = blk: {
|
||||
if (ty.isAnyError()) break :blk true;
|
||||
switch (ty.tag()) {
|
||||
.error_set_inferred => {
|
||||
if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
break :blk false;
|
||||
};
|
||||
if (deferred) {
|
||||
try self.global_abbrev_relocs.append(gpa, .{
|
||||
.target = null,
|
||||
.offset = reloc.offset,
|
||||
.atom = reloc.atom,
|
||||
.addend = reloc.addend,
|
||||
});
|
||||
} else {
|
||||
mem.writeInt(
|
||||
u32,
|
||||
dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
|
||||
symbol.atom.off + symbol.offset + reloc.addend,
|
||||
target_endian,
|
||||
);
|
||||
}
|
||||
break :blk false;
|
||||
};
|
||||
if (deferred) {
|
||||
try self.global_abbrev_relocs.append(gpa, .{
|
||||
.target = undefined,
|
||||
.offset = reloc.offset,
|
||||
.atom = reloc.atom,
|
||||
.addend = reloc.addend,
|
||||
});
|
||||
} else {
|
||||
mem.writeInt(
|
||||
u32,
|
||||
dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
|
||||
symbol.atom.off + symbol.offset + reloc.addend,
|
||||
reloc.atom.off + reloc.offset + reloc.addend,
|
||||
target_endian,
|
||||
);
|
||||
}
|
||||
|
||||
@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user