gprofng: read Dwarf 5

gprofng reads Dwarf to find function names, sources, and line numbers.
gprofng skips other debug information.
I fixed three places in gprofng Dwarf reader:
 - parsing the compilation unit header.
 - parsing the line number table header.
 - parsing new DW_FORMs.

Tested on aarch64-linux/x86_64-linux.

gprofng/ChangeLog
2023-03-05  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>

	PR gprofng/30195
	gprofng/src/Dwarf.cc: Support Dwarf-5.
	gprofng/src/DwarfLib.cc: Likewise.
	gprofng/src/Dwarf.h: Likewise.
	gprofng/src/DwarfLib.h: Likewise.
	gprofng/src/collctrl.cc: Don't read freed memory.
This commit is contained in:
Vladimir Mezentsev
2023-03-05 17:35:53 -08:00
parent 5fc6b6d44c
commit 74f1d7f4a3
5 changed files with 381 additions and 104 deletions

View File

@ -369,6 +369,7 @@ Dwarf::Dwarf (Stabs *_stabs)
debug_abbrevSec = NULL;
debug_strSec = NULL;
debug_lineSec = NULL;
debug_line_strSec = NULL;
debug_rangesSec = NULL;
elf = stabs->openElf (true);
if (elf == NULL)
@ -388,6 +389,7 @@ Dwarf::Dwarf (Stabs *_stabs)
debug_strSec = dwrGetSec (NTXT (".debug_str"));
debug_lineSec = dwrGetSec (NTXT (".debug_line"));
debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
debug_line_strSec = dwrGetSec (".debug_line_str");
if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
{
@ -610,9 +612,9 @@ Dwarf::archive_Dwarf (LoadObject *lo)
dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
{
char *fname = lineReg->getPath (i + 1);
SourceFile *sf = mod->findSource (fname, true);
dwrCU->srcFiles->append (sf);
char *fname = lineReg->getPath (i);
if (fname)
dwrCU->srcFiles->append (mod->findSource (fname, true));
}
}
@ -988,7 +990,7 @@ DwrCU::append_Function (Dwarf_cnt *ctx)
if (lineno > 0)
{
func->setLineFirst (lineno);
int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1;
int fileno = ((int) Dwarf_data (DW_AT_decl_file));
SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno)
: module->getMainSrc ();
func->setDefSrc (sf);

View File

@ -76,6 +76,7 @@ public:
DwrSec *debug_abbrevSec;
DwrSec *debug_strSec;
DwrSec *debug_lineSec;
DwrSec *debug_line_strSec;
DwrSec *debug_rangesSec;
Elf *elf;
Stabs *stabs;

View File

@ -140,6 +140,33 @@ template<> void Vector<DwrLine *>
Dprintf (1, NTXT ("\n\n"));
}
template<> void Vector<DwrFileName *>
::dump (const char *msg)
{
Dprintf (1, "\n%s Vector<DwrFileName *> [%lld]: [dir_ind tstamp fsize]\n",
msg ? msg : NTXT (""), (long long) size ());
for (long i = 0, sz = size (); i < sz; i++)
{
DwrFileName *fnp = get (i);
Dprintf (1, " %2ld %3lld %8lld %8lld %s\n", i, (long long) fnp->dir_index,
(long long) fnp->timestamp, (long long) fnp->file_size,
STR (fnp->fname));
}
Dprintf (1, "\n");
}
static char *
get_string (DwrSec *sec, uint64_t off)
{
if (sec)
{
sec->offset = off;
return sec->GetString ();
}
return NULL;
}
//////////////////////////////////////////////////////////
// class ElfReloc
@ -687,6 +714,16 @@ DwrCU::tag2str (int tag)
CASE_S (DW_TAG_SUN_memop_info);
CASE_S (DW_TAG_hi_user);
CASE_S (DW_TAG_icc_compile_unit);
CASE_S (DW_TAG_rvalue_reference_type);
CASE_S (DW_TAG_coarray_type);
CASE_S (DW_TAG_generic_subrange);
CASE_S (DW_TAG_dynamic_type);
CASE_S (DW_TAG_atomic_type);
CASE_S (DW_TAG_call_site);
CASE_S (DW_TAG_call_site_parameter);
CASE_S (DW_TAG_skeleton_unit);
CASE_S (DW_TAG_immutable_type);
CASE_S (0);
default: s = NTXT ("???");
break;
}
@ -833,6 +870,8 @@ DwrCU::at2str (int tag)
CASE_S (DW_AT_GNU_all_tail_call_sites);
CASE_S (DW_AT_GNU_all_call_sites);
CASE_S (DW_AT_GNU_all_source_call_sites);
CASE_S (DW_AT_GNU_locviews);
CASE_S (DW_AT_GNU_entry_view);
CASE_S (DW_AT_SUN_command_line);
CASE_S (DW_AT_SUN_func_offsets);
CASE_S (DW_AT_SUN_cf_kind);
@ -846,6 +885,36 @@ DwrCU::at2str (int tag)
CASE_S (DW_AT_SUN_link_name);
CASE_S (DW_AT_hi_user);
CASE_S (DW_AT_icc_flags);
CASE_S (DW_AT_string_length_bit_size);
CASE_S (DW_AT_string_length_byte_size);
CASE_S (DW_AT_rank);
CASE_S (DW_AT_str_offsets_base);
CASE_S (DW_AT_addr_base);
CASE_S (DW_AT_rnglists_base);
CASE_S (DW_AT_dwo_name);
CASE_S (DW_AT_reference);
CASE_S (DW_AT_rvalue_reference);
CASE_S (DW_AT_macros);
CASE_S (DW_AT_call_all_calls);
CASE_S (DW_AT_call_all_source_calls);
CASE_S (DW_AT_call_all_tail_calls);
CASE_S (DW_AT_call_return_pc);
CASE_S (DW_AT_call_value);
CASE_S (DW_AT_call_origin);
CASE_S (DW_AT_call_parameter);
CASE_S (DW_AT_call_pc);
CASE_S (DW_AT_call_tail_call);
CASE_S (DW_AT_call_target);
CASE_S (DW_AT_call_target_clobbered);
CASE_S (DW_AT_call_data_location);
CASE_S (DW_AT_call_data_value);
CASE_S (DW_AT_noreturn);
CASE_S (DW_AT_alignment);
CASE_S (DW_AT_export_symbols);
CASE_S (DW_AT_deleted);
CASE_S (DW_AT_defaulted);
CASE_S (DW_AT_loclists_base);
default: s = NTXT ("???");
break;
}
@ -867,6 +936,9 @@ DwrCU::form2str (int tag)
CASE_S (DW_FORM_data2);
CASE_S (DW_FORM_data4);
CASE_S (DW_FORM_data8);
CASE_S (DW_FORM_data16);
CASE_S (DW_FORM_line_strp);
CASE_S (DW_FORM_implicit_const);
CASE_S (DW_FORM_string);
CASE_S (DW_FORM_block);
CASE_S (DW_FORM_block1);
@ -894,6 +966,28 @@ DwrCU::form2str (int tag)
return buf;
}
char *
DwrCU::lnct2str (int ty)
{
static char buf[128];
char *s;
switch (ty)
{
CASE_S (DW_LNCT_path);
CASE_S (DW_LNCT_directory_index);
CASE_S (DW_LNCT_timestamp);
CASE_S (DW_LNCT_size);
CASE_S (DW_LNCT_MD5);
CASE_S (DW_LNCT_lo_user);
CASE_S (DW_LNCT_hi_user);
default: s = NTXT ("???");
break;
}
snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, ty);
buf[sizeof (buf) - 1] = 0;
return buf;
}
void
Dwr_Tag::dump ()
{
@ -910,14 +1004,16 @@ Dwr_Tag::dump ()
{
case DW_FORM_strp:
case DW_FORM_string:
Dprintf (DUMP_DWARFLIB, " \"%s\" len=%ld",
atrp->u.str ? atrp->u.str : NTXT ("<NULL>"),
(long) atrp->len);
case DW_FORM_line_strp:
case DW_FORM_strp_sup:
case DW_FORM_implicit_const:
Dprintf (DUMP_DWARFLIB, " \"%s\"", atrp->u.str ? atrp->u.str : "<NULL>");
break;
case DW_FORM_block:
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_data16:
Dprintf (DUMP_DWARFLIB, " len=%3ld %p", (long) atrp->len,
atrp->u.str);
break;
@ -1041,6 +1137,19 @@ DwrSec::Get_16 ()
return n;
}
uint32_t
DwrSec::Get_24 ()
{
uint32_t n = 0;
if (bounds_violation (3))
return n;
memcpy ((char *) &n, data + offset, 3);
offset += 3;
if (need_swap_endian)
SWAP_ENDIAN (n);
return n;
}
uint32_t
DwrSec::Get_32 ()
{
@ -1078,27 +1187,17 @@ DwrSec::GetData (uint64_t len)
}
char *
DwrSec::GetString (uint64_t *lenp)
DwrSec::GetString ()
{
if (offset < size)
{
uint64_t len = 0;
for (char *s = ((char *) data) + offset; offset + len < size; len++)
{
if (s[len] == 0)
{ // '\0' is inside section
offset += len + 1;
if (len == 0)
return NULL;
if (lenp)
*lenp = len + 1;
return s;
}
}
offset += len;
return NULL; // The section is not '\0' terminated
}
return NULL;
uint64_t off = offset;
while (offset < size)
if (data[offset++] == 0)
{ // '\0' is inside section
if (off + 1 == offset)
return NULL;
return ((char *) data) + off;
}
return NULL; // The section is not '\0' terminated
}
uint64_t
@ -1173,6 +1272,37 @@ DwrSec::GetSLEB128 ()
return (SLEB128) res;
}
uint64_t
DwrSec::get_value (int dw_form)
{
uint64_t v;
switch (dw_form)
{
case DW_FORM_line_strp:
case DW_FORM_strp:
case DW_FORM_strp_sup:
return GetRef ();
case DW_FORM_data1:
return Get_8 ();
case DW_FORM_data2:
return Get_16 ();
case DW_FORM_data4:
return Get_32 ();
case DW_FORM_data8:
return Get_64 ();
case DW_FORM_udata:
return GetULEB128 ();
case DW_FORM_data16:
offset += 16;
return offset - 16;
case DW_FORM_block:
v = GetULEB128 ();
offset += v;
return offset - v;
}
return 0;
}
static void
fillBuf (unsigned char *s, int len, int col, unsigned char *buf)
{
@ -1229,7 +1359,7 @@ DwrSec::dump (char *msg)
DwrFileName::DwrFileName (char *_fname)
{
path = NULL;
fname = _fname;
fname = dbe_strdup (_fname);
dir_index = 0;
timestamp = 0;
file_size = 0;
@ -1267,8 +1397,13 @@ LineRegsCmp (const void *a, const void *b)
item1->address > item2->address ? 1 : -1;
}
DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
DwrLineRegs::DwrLineRegs (Dwarf *_dwarf, DwrSec *secp, char *dirName)
{
dwarf = _dwarf;
dir_names = NULL;
file_names = NULL;
lines = NULL;
fname = NULL;
// `dwarfdump -vv -l` shows a line section (.debug_line)
debug_lineSec = secp;
uint64_t stmt_offset = debug_lineSec->offset;
@ -1276,11 +1411,16 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
uint64_t header_offset = debug_lineSec->offset;
debug_lineSec->size = next_cu_offset;
version = debug_lineSec->Get_16 ();
if (version == 5)
{
debug_lineSec->address_size = debug_lineSec->Get_8();
debug_lineSec->segment_selector_size = debug_lineSec->Get_8();
}
header_length = debug_lineSec->GetLong ();
opcode_start = debug_lineSec->offset + header_length;
minimum_instruction_length = debug_lineSec->Get_8 ();
op_index_register = 0;
if (version == 4)
if (version >= 4)
maximum_operations_per_instruction = debug_lineSec->Get_8 ();
else
maximum_operations_per_instruction = 1;
@ -1295,9 +1435,9 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
{
Dprintf (DUMP_DWR_LINE_REGS,
"\n.debug_line version=%d stmt_offset=0x%llx"
"header_offset=0x%llx size=%lld dirname='%s'\n"
" header_offset=0x%llx size=%lld dirname='%s'\n"
" header_length=0x%llx opcode_start=0x%llx"
"minimum_instruction_length=%d default_is_stmt=%d\n"
" minimum_instruction_length=%d default_is_stmt=%d\n"
" line_base=%d line_range=%d opcode_base=%d\n",
(int) version, (long long) stmt_offset,
(long long) header_offset,
@ -1313,40 +1453,122 @@ DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
(int) standard_opcode_length[i]);
}
include_directories = new Vector<char *>;
include_directories->append (dirName);
while (true)
if (version == 5)
{
char *s = debug_lineSec->GetString (NULL);
if (s == NULL)
break;
include_directories->append (s);
dir_names = read_file_names_dwarf5 ();
file_names = read_file_names_dwarf5 ();
}
else
{
dir_names = new Vector<DwrFileName *>;
dir_names->append (new DwrFileName (dirName));
while (true)
{
char *s = debug_lineSec->GetString ();
if (s == NULL)
break;
dir_names->append (new DwrFileName (s));
}
file_names = new Vector<DwrFileName *>;
while (true)
{
char *s = debug_lineSec->GetString (NULL);
if (s == NULL)
break;
DwrFileName *fnp = new DwrFileName (s);
fnp->path = NULL;
fnp->fname = s;
fnp->dir_index = debug_lineSec->GetULEB128_32 ();
fnp->timestamp = debug_lineSec->GetULEB128 ();
fnp->file_size = debug_lineSec->GetULEB128 ();
file_names->append (fnp);
file_names = new Vector<DwrFileName *>;
file_names->append (new DwrFileName (dirName));
while (true)
{
char *s = debug_lineSec->GetString ();
if (s == NULL)
break;
DwrFileName *fnp = new DwrFileName (s);
fnp->dir_index = debug_lineSec->GetULEB128_32 ();
fnp->timestamp = debug_lineSec->GetULEB128 ();
fnp->file_size = debug_lineSec->GetULEB128 ();
file_names->append (fnp);
}
}
lines = NULL;
dump ();
}
DwrLineRegs::~DwrLineRegs ()
{
Destroy (dir_names);
Destroy (file_names);
Destroy (lines);
delete debug_lineSec;
delete include_directories;
}
Vector <DwrFileName *> *
DwrLineRegs::read_file_names_dwarf5 ()
{
typedef struct
{
int type_code;
int form_code;
} t_entry_fmt;
int efmt_cnt = debug_lineSec->Get_8 ();
Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx entry_fmt_cnt=%d\n",
(long long) debug_lineSec->offset, efmt_cnt);
if (efmt_cnt == 0)
return NULL;
t_entry_fmt *efmt = (t_entry_fmt *) malloc (sizeof (t_entry_fmt) * efmt_cnt);
for (int i = 0; i < efmt_cnt; i++)
{
efmt[i].type_code = debug_lineSec->GetULEB128 ();
efmt[i].form_code = debug_lineSec->GetULEB128 ();
Dprintf (DUMP_DWR_LINE_REGS, " %2d %20s %s\n", i,
DwrCU::lnct2str (efmt[i].type_code),
DwrCU::form2str (efmt[i].form_code));
}
int cnt = debug_lineSec->GetULEB128_32 ();
Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx names_cnt=%d\n",
(long long) debug_lineSec->offset, cnt);
Vector<DwrFileName *> *fnames = new Vector<DwrFileName *> (cnt);
for (int i = 0; i < cnt; i++)
{
int ind = 0;
uint64_t off = 0;
uint64_t tstamp = 0;
uint64_t fsize = 0;
char *nm = NULL;
for (int k = 0; k < efmt_cnt; k++)
switch (efmt[k].type_code)
{
case DW_LNCT_path:
if (efmt[k].form_code == DW_FORM_string)
nm = debug_lineSec->GetString ();
else
{
off = debug_lineSec->get_value (efmt[k].form_code);
if (efmt[k].form_code == DW_FORM_line_strp)
nm = get_string (dwarf->debug_line_strSec, off);
else if (efmt[k].form_code == DW_FORM_strp)
nm = get_string (dwarf->debug_strSec, off);
}
break;
case DW_LNCT_directory_index:
ind = debug_lineSec->get_value (efmt[k].form_code);
break;
case DW_LNCT_timestamp:
tstamp = debug_lineSec->get_value (efmt[k].form_code);
break;
case DW_LNCT_size:
fsize = debug_lineSec->get_value (efmt[k].form_code);
break;
case DW_LNCT_MD5:
(void) debug_lineSec->get_value (efmt[k].form_code);
break;
}
Dprintf (DUMP_DWR_LINE_REGS, " %3d ind=%d off=0x%08llx %s\n",
i, ind, (long long) off, STR (nm));
DwrFileName *fnp = new DwrFileName (nm);
fnp->dir_index = ind;
fnp->timestamp = tstamp;
fnp->file_size = fsize;
fnames->append (fnp);
}
free (efmt);
return fnames;
}
void
@ -1354,12 +1576,10 @@ DwrLineRegs::dump ()
{
if (!DUMP_DWR_LINE_REGS)
return;
Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\ninclude_directories size=%lld\n"), (long long) VecSize (include_directories));
for (long i = 0, sz = VecSize (include_directories); i < sz; i++)
{
char *s = include_directories->get (i);
Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %s\n"), (long long) i, STR (s));
}
if (dir_names)
dir_names->dump ("dir_names");
if (file_names)
file_names->dump ("file_names");
Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\nfile_names size=%lld\n"), (long long) VecSize (file_names));
for (long i = 0, sz = VecSize (file_names); i < sz; i++)
@ -1396,7 +1616,7 @@ DwrLineRegs::DoExtendedOpcode ()
break;
case DW_LNE_define_file:
// TODO, add file to file list
fname = debug_lineSec->GetString (NULL);
fname = debug_lineSec->GetString ();
dir_index = debug_lineSec->GetULEB128 ();
timestamp = debug_lineSec->GetULEB128 ();
file_size = debug_lineSec->GetULEB128 ();
@ -1467,7 +1687,7 @@ DwrLineRegs::reset ()
timestamp = 0;
file_size = 0;
address = 0;
file = 1;
file = 0;
line = 1;
column = 0;
is_stmt = (default_is_stmt != 0);
@ -1535,39 +1755,31 @@ DwrLineRegs::get_lines ()
char *
DwrLineRegs::getPath (int fn)
{
fn--;
if ((fn >= VecSize (file_names)) || (fn < 0))
if (fn >= VecSize (file_names) || fn < 0)
{
Dprintf (DEBUG_ERR_MSG, NTXT ("DwrLineRegs::getPath: fn=0x%lld file_names->size()=%lld\n"),
(long long) fn, (long long) VecSize (file_names));
return NULL;
}
DwrFileName *fnp = file_names->fetch (fn);
if (fnp->fname == NULL)
return NULL;
if (fnp->path)
return fnp->path;
char *dir = fnp->dir_index < include_directories->size () ?
include_directories->fetch (fnp->dir_index) : NULL;
if ((fnp->fname[0] == '/') || (dir == NULL) || (*dir == 0))
{
fnp->path = fnp->fname;
return fnp->path;
}
fnp->path = fnp->fname;
if (fnp->fname[0] == '/')
return fnp->path;
StringBuilder sb;
if (*dir != '/')
{ // not absolute
char *s = include_directories->fetch (0);
if (s != NULL && *s != 0)
{
sb.append (s);
sb.append ('/');
}
char *dir = NULL;
if (dir_names)
{
if (fnp->dir_index < dir_names->size () && fnp->dir_index >= 0)
dir = dir_names->get (fnp->dir_index)->fname;
}
sb.append (dir);
sb.append ('/');
sb.append (fnp->fname);
fnp->path = canonical_path (sb.toString ());
if (dir == NULL || *dir == 0)
return fnp->path;
fnp->path = canonical_path (dbe_sprintf ("%s/%s", dir, fnp->fname));
return fnp->path;
}
@ -1586,8 +1798,18 @@ DwrCU::DwrCU (Dwarf *_dwarf)
}
debug_infoSec->size = next_cu_offset;
version = debug_infoSec->Get_16 ();
debug_abbrev_offset = debug_infoSec->GetLong ();
address_size = debug_infoSec->Get_8 ();
if (version == 5)
{
unit_type = debug_infoSec->Get_8 ();
address_size = debug_infoSec->Get_8 ();
debug_abbrev_offset = debug_infoSec->GetLong ();
}
else
{
unit_type = DW_UT_compile;
debug_abbrev_offset = debug_infoSec->GetLong ();
address_size = debug_infoSec->Get_8 ();
}
cu_header_offset = debug_infoSec->offset;
comp_dir = NULL;
module = NULL;
@ -1606,7 +1828,7 @@ DwrCU::DwrCU (Dwarf *_dwarf)
{
Dprintf (DUMP_DWARFLIB,
"CU_HEADER: header_offset = 0x%08llx %lld"
"next_header_offset=0x%08llx %lld\n"
" next_header_offset=0x%08llx %lld\n"
" abbrev_offset = 0x%08llx %lld\n"
" unit_length = %lld\n"
" version = %d\n"
@ -1685,10 +1907,18 @@ DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
while (debug_abbrevSec->offset < debug_abbrevSec->size)
{
Dwr_Attr atf;
atf.len = 0;
atf.u.str = NULL;
atf.at_name = debug_abbrevSec->GetULEB128_32 ();
atf.at_form = debug_abbrevSec->GetULEB128_32 ();
if (atf.at_name == 0 && atf.at_form == 0)
break;
switch (atf.at_form)
{
case DW_FORM_implicit_const:
atf.len = debug_abbrevSec->GetSLEB128 ();
break;
}
abbrevAtForm->append (atf);
}
abbTbl.lastAtForm = abbrevAtForm->size ();
@ -1782,20 +2012,12 @@ DwrCU::set_die (Dwarf_Die die)
atf->u.offset = debug_infoSec->Get_64 ();
break;
case DW_FORM_string:
atf->u.str = debug_infoSec->GetString (&atf->len);
atf->u.offset = debug_infoSec->offset;
atf->u.str = debug_infoSec->GetString ();
break;
case DW_FORM_strp:
atf->u.offset = debug_infoSec->GetRef ();
if (dwarf->debug_strSec == NULL)
{
atf->u.str = NULL;
atf->len = 0;
}
else
{
dwarf->debug_strSec->offset = atf->u.offset;
atf->u.str = dwarf->debug_strSec->GetString (&atf->len);
}
atf->u.str = get_string (dwarf->debug_strSec, atf->u.offset);
break;
case DW_FORM_sdata:
atf->u.val = debug_infoSec->GetSLEB128 ();
@ -1819,6 +2041,49 @@ DwrCU::set_die (Dwarf_Die die)
case DW_FORM_ref_sig8:
atf->u.offset = debug_infoSec->GetADDR_64 ();
break;
case DW_FORM_data16: // we never use this data. Skip 16 bytes
atf->len = 16;
(void) debug_infoSec->Get_64 ();
(void) debug_infoSec->Get_64 ();
break;
case DW_FORM_addrx:
case DW_FORM_strx:
case DW_FORM_loclistx:
case DW_FORM_rnglistx:
atf->u.offset = debug_infoSec->GetULEB128 ();
break;
case DW_FORM_addrx1:
case DW_FORM_strx1:
atf->u.offset = debug_infoSec->Get_8 ();
break;
case DW_FORM_addrx2:
case DW_FORM_strx2:
atf->u.offset = debug_infoSec->Get_16 ();
break;
case DW_FORM_addrx3:
case DW_FORM_strx3:
atf->u.offset = debug_infoSec->Get_24 ();
break;
case DW_FORM_addrx4:
case DW_FORM_strx4:
case DW_FORM_ref_sup4:
atf->u.offset = debug_infoSec->Get_32 ();
break;
case DW_FORM_ref_sup8:
atf->u.offset = debug_infoSec->Get_64 ();
break;
case DW_FORM_line_strp:
atf->u.offset = debug_infoSec->GetRef ();
atf->u.str = get_string (dwarf->debug_line_strSec, atf->u.offset);
break;
case DW_FORM_strp_sup:
atf->u.offset = debug_infoSec->GetRef ();
atf->u.str = NULL;
atf->len = 0;
break;
case DW_FORM_implicit_const:
atf->u.str = NULL;
break;
default:
DEBUG_CODE
{
@ -1974,6 +2239,7 @@ DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
case DW_FORM_data2:
case DW_FORM_data4:
case DW_FORM_data8:
case DW_FORM_data16:
case DW_FORM_udata:
case DW_FORM_sec_offset:
*retVal = dwrAttr->u.val;
@ -2132,7 +2398,7 @@ DwrLineRegs *
DwrCU::get_dwrLineReg ()
{
if (dwrLineReg == NULL && stmt_list_offset != NO_STMT_LIST)
dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
dwrLineReg = new DwrLineRegs (dwarf, new DwrSec (dwarf->debug_lineSec,
stmt_list_offset), comp_dir);
return dwrLineReg;
}

View File

@ -61,8 +61,10 @@ public:
uint64_t ReadLength ();
SLEB128 GetSLEB128 ();
ULEB128 GetULEB128 ();
char *GetString (uint64_t *lenp);
char *GetString ();
char *GetData (uint64_t len);
uint32_t Get_24 ();
uint64_t get_value (int dw_form);
void dump (char *msg);
inline uint32_t
@ -84,6 +86,8 @@ public:
bool fmt64;
bool addr32;
bool need_swap_endian;
int address_size;
int segment_selector_size; // DWARF 5
private:
bool isCopy;
@ -132,7 +136,7 @@ public:
class DwrLineRegs
{
public:
DwrLineRegs (DwrSec *_secp, char *dirName);
DwrLineRegs (Dwarf *_dwarf, DwrSec *_secp, char *dirName);
~DwrLineRegs ();
char *getPath (int fn);
Vector<DwrLine *> *get_lines ();
@ -146,7 +150,9 @@ private:
void DoSpecialOpcode (int opcode);
void EmitLine ();
void reset ();
Vector <DwrFileName *> *read_file_names_dwarf5 ();
Dwarf *dwarf;
char *fname;
uint64_t dir_index;
uint64_t timestamp;
@ -167,7 +173,7 @@ private:
bool basic_block;
bool end_sequence;
Vector<DwrLine *> *lines;
Vector<char *> *include_directories;
Vector<DwrFileName *> *dir_names;
Dwarf_Small *standard_opcode_length;
DwrSec *debug_lineSec;
uint64_t header_length;
@ -269,6 +275,7 @@ public:
static char *at2str (int tag);
static char *form2str (int tag);
static char *tag2str (int tag);
static char *lnct2str (int ty);
uint64_t cu_header_offset;
uint64_t cu_offset;
@ -302,6 +309,7 @@ private:
uint64_t stmt_list_offset; // offset in .debug_line section (DW_AT_stmt_list)
char *comp_dir; // compilation directory (DW_AT_comp_dir)
Module *module;
int unit_type;
Dwarf_Half version;
Dwarf_Small address_size;
Dwr_Tag dwrTag;

View File

@ -114,7 +114,6 @@ Coll_Ctrl::Coll_Ctrl (int _interactive, bool _defHWC, bool _kernelHWC)
#elif defined(__aarch64__)
asm volatile("mrs %0, cntfrq_el0" : "=r" (cpu_clk_freq));
dbe_write (2, GTXT ("CPU clock frequency: %d\n"), cpu_clk_freq);
#else
FILE *procf = fopen ("/proc/cpuinfo", "r");
@ -1079,15 +1078,16 @@ Coll_Ctrl::set_synctrace (const char *string)
/* the remaining string should be a number >= 0 */
char *endchar = NULL;
int tval = (int) strtol (val, &endchar, 0);
free (val);
if (*endchar != 0 || tval < 0)
{
free (val);
/* invalid setting */
/* restore the comma, if it was zeroed out */
if (comma_p != NULL)
*comma_p = ',';
return dbe_sprintf (GTXT ("Unrecognized synchronization tracing threshold `%s'\n"), string);
}
free (val);
synctrace_thresh = tval;
synctrace_enabled = 1;
return NULL;