diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 62 |
2 files changed, 68 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 316bcb6d..05b2522d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2021-10-20 John M Mellor-Crummey <johnmc@rice.edu> + + * readelf.c (print_debug_line_section): Try to read + debug_str_offset if available. Handle DW_LNE_NVIDIA_inlined_call + and DW_LNE_NVIDIA_set_function_name. + 2021-10-06 Mark Wielaard <mark@klomp.org> * elflint.c (check_sections): Don't dereference databits if bad. diff --git a/src/readelf.c b/src/readelf.c index 3a199068..c10038e3 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -8478,6 +8478,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, header_length = read_8ubyte_unaligned_inc (dbg, linep); } + const unsigned char *header_start = linep; + /* Next the minimum instruction length. */ if ((size_t) (lineendp - linep) < 1) goto invalid_data; @@ -8761,6 +8763,13 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, ++linep; } + unsigned int debug_str_offset = 0; + if (unlikely (linep == header_start + header_length - 4)) + { + /* CUBINs contain an unsigned 4-byte offset */ + debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep); + } + if (linep == lineendp) { puts (_("\nNo line number statements.")); @@ -8909,6 +8918,59 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, printf (_(" set discriminator to %u\n"), u128); break; + case DW_LNE_NVIDIA_inlined_call: + { + if (unlikely (linep >= lineendp)) + goto invalid_data; + + unsigned int context; + get_uleb128 (context, linep, lineendp); + + if (unlikely (linep >= lineendp)) + goto invalid_data; + + unsigned int function_name; + get_uleb128 (function_name, linep, lineendp); + function_name += debug_str_offset; + + Elf_Data *str_data = dbg->sectiondata[IDX_debug_str]; + char *function_str; + if (str_data == NULL || function_name >= str_data->d_size + || memchr (str_data->d_buf + function_name, '\0', + str_data->d_size - function_name) == NULL) + function_str = "???"; + else + function_str = (char *) str_data->d_buf + function_name; + + printf (_(" set inlined context %u," + " function name %s (0x%x)\n"), + context, function_str, function_name); + break; + } + + case DW_LNE_NVIDIA_set_function_name: + { + if (unlikely (linep >= lineendp)) + goto invalid_data; + + unsigned int function_name; + get_uleb128 (function_name, linep, lineendp); + function_name += debug_str_offset; + + Elf_Data *str_data = dbg->sectiondata[IDX_debug_str]; + char *function_str; + if (str_data == NULL || function_name >= str_data->d_size + || memchr (str_data->d_buf + function_name, '\0', + str_data->d_size - function_name) == NULL) + function_str = "???"; + else + function_str = (char *) str_data->d_buf + function_name; + + printf (_(" set function name %s (0x%x)\n"), + function_str, function_name); + } + break; + default: /* Unknown, ignore it. */ puts (_(" unknown opcode")); |