authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-02 20:22:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-02 20:22:41-07:00
log42d331b58aa874420d2515071e94f046adaf0689
tree2a3ad58a20fa4d97d2ba07ea04b58f818be0383c
parent1ce6e201aa818b05f6637438d1c0b460ea817e3f

.debug_line: avoid DW_FORM_strp to work around readelf/gdb

These tools do not support DWARFv5 yet apparently.

1 files changed, 27 insertions(+), 11 deletions(-)

src-self-hosted/link.zig+27-11
......@@ -1264,27 +1264,37 @@ pub const File = struct {
12641264 1, // `DW.LNS_set_isa`
12651265
12661266 1, // directory_entry_format_count
1267 DW.LNCT_path, DW.FORM_strp, // directory_entry_format
1267 DW.LNCT_path, DW.FORM_string, // directory_entry_format
12681268
12691269 // For now we only support one compilation unit, which has one directory.
12701270 1, // directories_count (this is a ULEB128)
12711271 });
1272 const comp_dir_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_dir_path);
1273 self.writeDwarfAddrAssumeCapacity(&di_buf, comp_dir_strp);
1272 // Empirically, some tools do not understand DW.FORM_strp yet. readelf 2.31.1 gives the bogus
1273 // error <no .debug_str section> and gdb 8.3.1 crashes. Both programs seem to work fine with
1274 // DW.FORM_string however.
1275 di_buf.appendSliceAssumeCapacity(self.base.options.root_pkg.root_src_dir_path);
1276 di_buf.appendAssumeCapacity(0);
12741277
12751278 di_buf.appendSliceAssumeCapacity(&[_]u8{
12761279 2, // file_name_entry_format_count
1277 DW.LNCT_path, DW.FORM_strp, // file_name_entry_format[0]
1280 DW.LNCT_path, DW.FORM_string, // file_name_entry_format[0]
12781281 DW.LNCT_directory_index, DW.FORM_data1, // file_name_entry_format[1]
12791282 // TODO Look into adding the file size here. Maybe even the mtime and MD5.
12801283 //DW.LNCT_size, DW.FORM_udata, // file_name_entry_format[2]
12811284
12821285 // For now we only put the root file name here. Once more source files
12831286 // are supported, this will need to be improved.
1284 1, // file_names_count (this is a ULEB128)
1287 2, // file_names_count (this is a ULEB128)
12851288 });
1286 const root_src_file_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_path);
1287 self.writeDwarfAddrAssumeCapacity(&di_buf, root_src_file_strp); // DW.LNCT_path, DW.FORM_strp
1289 // See note above with directories about why we use DW.FORM_string here.
1290 di_buf.appendSliceAssumeCapacity(self.base.options.root_pkg.root_src_path);
1291 di_buf.appendAssumeCapacity(0);
1292 di_buf.appendAssumeCapacity(0); // LNCT_directory_index, FORM_data1
1293
1294 // We add the root file twice because according to DWARF, the state machine
1295 // starts out with file index 1.
1296 di_buf.appendSliceAssumeCapacity(self.base.options.root_pkg.root_src_path);
1297 di_buf.appendAssumeCapacity(0);
12881298 di_buf.appendAssumeCapacity(0); // LNCT_directory_index, FORM_data1
12891299
12901300 const header_len = di_buf.items.len - after_header_len;
......@@ -2140,8 +2150,9 @@ pub const File = struct {
21402150 {
21412151 var header: [dbg_line_file_header_len]u8 = undefined;
21422152 header[0] = DW.LNS_set_file;
2143 // Once we support more than one source file, this will have the ability to be non-zero.
2144 const file_index = 0;
2153 // Once we support more than one source file, this will have the ability to be more
2154 // than one possible value.
2155 const file_index = 1;
21452156 leb128.writeUnsignedFixed(4, header[1..5], file_index);
21462157 try self.file.?.pwriteAll(&header, header_off);
21472158 }
......@@ -2384,8 +2395,13 @@ pub const File = struct {
23842395 const file_name_entry_format_count = 1;
23852396 const directory_count = 1;
23862397 const file_name_count = 1;
2387 return 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
2388 directory_count * 8 + file_name_count * 8;
2398 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
2399 directory_count * 8 + file_name_count * 8 +
2400 // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like
2401 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
2402 self.base.options.root_pkg.root_src_dir_path.len +
2403 self.base.options.root_pkg.root_src_path.len * 2);
2404
23892405 }
23902406 };
23912407};