aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Elf.zig71
-rw-r--r--src/link/MachO.zig6
-rw-r--r--src/link/MachO/DebugSymbols.zig3
3 files changed, 60 insertions, 20 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index a7ce8d0783..2b88458bc9 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -783,8 +783,9 @@ pub const abbrev_compile_unit = 1;
pub const abbrev_subprogram = 2;
pub const abbrev_subprogram_retvoid = 3;
pub const abbrev_base_type = 4;
-pub const abbrev_pad1 = 5;
-pub const abbrev_parameter = 6;
+pub const abbrev_ptr_type = 5;
+pub const abbrev_pad1 = 6;
+pub const abbrev_parameter = 7;
pub fn flush(self: *Elf, comp: *Compilation) !void {
if (self.base.options.emit == null) {
@@ -871,9 +872,21 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
DW.AT.byte_size,
DW.FORM.data1,
DW.AT.name,
- DW.FORM.string, 0, 0, // table sentinel
- abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
- 0, 0, // table sentinel
+ DW.FORM.string,
+ 0,
+ 0, // table sentinel
+ abbrev_ptr_type,
+ DW.TAG.pointer_type,
+ DW.CHILDREN.no, // header
+ DW.AT.type,
+ DW.FORM.ref4,
+ 0,
+ 0, // table sentinel
+ abbrev_pad1,
+ DW.TAG.unspecified_type,
+ DW.CHILDREN.no, // header
+ 0,
+ 0, // table sentinel
abbrev_parameter,
DW.TAG.formal_parameter, DW.CHILDREN.no, // header
DW.AT.location, DW.FORM.exprloc,
@@ -2309,8 +2322,7 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
}
fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void {
- var it = table.valueIterator();
- while (it.next()) |value| {
+ for (table.values()) |*value| {
value.relocs.deinit(gpa);
}
table.deinit(gpa);
@@ -2387,10 +2399,12 @@ fn finishUpdateDecl(
// the buffer, so we have to do it before computing the offset, and we can't perform the actual
// relocations yet.
{
- var it = dbg_info_type_relocs.iterator();
- while (it.next()) |entry| {
- entry.value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);
- try self.addDbgInfoType(entry.key_ptr.*, dbg_info_buffer);
+ var it: usize = 0;
+ while (it < dbg_info_type_relocs.count()) : (it += 1) {
+ const ty = dbg_info_type_relocs.keys()[it];
+ const value_ptr = dbg_info_type_relocs.getPtr(ty).?;
+ value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);
+ try self.addDbgInfoType(ty, dbg_info_buffer, dbg_info_type_relocs);
}
}
@@ -2401,8 +2415,7 @@ fn finishUpdateDecl(
{
// Now that we have the offset assigned we can finally perform type relocations.
- var it = dbg_info_type_relocs.valueIterator();
- while (it.next()) |value| {
+ for (dbg_info_type_relocs.values()) |value| {
for (value.relocs.items) |off| {
mem.writeInt(
u32,
@@ -2706,7 +2719,14 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
}
/// Asserts the type has codegen bits.
-fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !void {
+fn addDbgInfoType(
+ self: *Elf,
+ ty: Type,
+ dbg_info_buffer: *std.ArrayList(u8),
+ dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable,
+) error{OutOfMemory}!void {
+ var reloc: ?struct { ty: Type, reloc: u32 } = null;
+
switch (ty.zigTypeTag()) {
.Void => unreachable,
.NoReturn => unreachable,
@@ -2747,11 +2767,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo
try dbg_info_buffer.append(abbrev_pad1);
}
},
+ .Pointer => blk: {
+ if (ty.isSlice()) {
+ log.debug("TODO implement .debug_info for type '{}'", .{ty});
+ try dbg_info_buffer.append(abbrev_pad1);
+ break :blk;
+ }
+ try dbg_info_buffer.ensureUnusedCapacity(5);
+ dbg_info_buffer.appendAssumeCapacity(abbrev_ptr_type);
+ const index = dbg_info_buffer.items.len;
+ try dbg_info_buffer.resize(index + 4); // DW.AT.type, DW.FORM.ref4
+ reloc = .{ .ty = ty.childType(), .reloc = @intCast(u32, index) };
+ },
else => {
log.debug("TODO implement .debug_info for type '{}'", .{ty});
try dbg_info_buffer.append(abbrev_pad1);
},
}
+
+ if (reloc) |rel| {
+ const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, rel.ty);
+ if (!gop.found_existing) {
+ gop.value_ptr.* = .{
+ .off = undefined,
+ .relocs = .{},
+ };
+ }
+ try gop.value_ptr.relocs.append(self.base.allocator, rel.reloc);
+ }
}
fn updateDeclDebugInfoAllocation(self: *Elf, text_block: *TextBlock, len: u32) !void {
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index d7385f1f33..cd1d197010 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -3578,8 +3578,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
if (debug_buffers) |dbg| {
dbg.dbg_line_buffer.deinit();
dbg.dbg_info_buffer.deinit();
- var it = dbg.dbg_info_type_relocs.valueIterator();
- while (it.next()) |value| {
+ for (dbg.dbg_info_type_relocs.values()) |*value| {
value.relocs.deinit(self.base.allocator);
}
dbg.dbg_info_type_relocs.deinit(self.base.allocator);
@@ -3659,8 +3658,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
if (debug_buffers) |dbg| {
dbg.dbg_line_buffer.deinit();
dbg.dbg_info_buffer.deinit();
- var it = dbg.dbg_info_type_relocs.valueIterator();
- while (it.next()) |value| {
+ for (dbg.dbg_info_type_relocs.values()) |*value| {
value.relocs.deinit(self.base.allocator);
}
dbg.dbg_info_type_relocs.deinit(self.base.allocator);
diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig
index 88a27ea48f..beef0b6b2c 100644
--- a/src/link/MachO/DebugSymbols.zig
+++ b/src/link/MachO/DebugSymbols.zig
@@ -1112,8 +1112,7 @@ pub fn commitDeclDebugInfo(
{
// Now that we have the offset assigned we can finally perform type relocations.
- var it = dbg_info_type_relocs.valueIterator();
- while (it.next()) |value| {
+ for (dbg_info_type_relocs.values()) |value| {
for (value.relocs.items) |off| {
mem.writeIntLittle(
u32,