69 #include <sys/types.h> 101 #define DEBUG_RAW_LINE_MAP 0 102 #define DEBUG_FULL_LINE_MAP 0 113 Dwarf_Signed file_count;
114 Dwarf_Error dw_error;
118 ret = dwarf_srclines(dw_die, &linebuf, &count, &dw_error);
119 if (ret != DW_DLV_OK) {
124 ret = dwarf_srcfiles(dw_die, &file_names, &file_count, &dw_error);
125 if (ret != DW_DLV_OK) {
131 vector <uint> fileVec;
132 fileVec.resize(file_count);
134 for (n = 0; n < file_count; n++) {
135 fileVec[
n] = m_str_tab.str2index(file_names[n]);
139 Dwarf_Unsigned ufile_count = (Dwarf_Unsigned) file_count;
141 for (n = 0; n < count; n++) {
143 Dwarf_Unsigned lineno = 0;
144 Dwarf_Unsigned fileno;
145 Dwarf_Bool is_end = 0;
146 uint file_index = m_empty_index;
149 ret = dwarf_lineaddr(linebuf[n], &addr, &dw_error);
150 if (ret != DW_DLV_OK) {
154 ret = dwarf_lineno(linebuf[n], &lineno, &dw_error);
155 if (ret != DW_DLV_OK) {
159 ret = dwarf_line_srcfileno(linebuf[n], &fileno, &dw_error);
160 if (ret != DW_DLV_OK) {
164 if (fileno > 0 && fileno <= ufile_count && lineno > 0) {
165 file_index = fileVec[fileno - 1];
168 ret = dwarf_lineendsequence(linebuf[n], &is_end, &dw_error);
169 if (ret != DW_DLV_OK) {
173 #if DEBUG_RAW_LINE_MAP 174 cout <<
"0x" << hex << addr << dec;
179 cout <<
" " << setw(6) << lineno
180 <<
" " << m_str_tab.index2str(file_index) <<
"\n";
184 if (n == count - 1) {
188 if (lineno > 0 && ! is_end) {
194 auto it = m_line_map.find(addr);
195 if (it == m_line_map.end()) {
202 for (n = 0; n < file_count; n++) {
203 dwarf_dealloc(dw_dbg, file_names[n], DW_DLA_STRING);
205 dwarf_dealloc(dw_dbg, file_names, DW_DLA_LIST);
206 dwarf_srclines_dealloc(dw_dbg, linebuf, count);
215 Dwarf_Error dw_error;
218 ret = dwarf_siblingof_b(dw_dbg,
NULL, 1, &dw_die, &dw_error);
220 if (ret == DW_DLV_OK) {
221 do_line_map(dw_dbg, dw_die);
222 dwarf_dealloc(dw_dbg, dw_die, DW_DLA_DIE);
232 Dwarf_Error dw_error;
233 Dwarf_Unsigned cu_hdr_len;
235 Dwarf_Unsigned cu_hdr_off;
238 ret = dwarf_elf_init(elfFile->
getElf(), DW_DLC_READ,
NULL,
NULL, &dw_dbg, &dw_error);
239 if (ret == DW_DLV_NO_ENTRY) {
240 errx(1,
"no debug section in file: %s", elfFile->
getFileName().c_str());
242 else if (ret != DW_DLV_OK) {
243 errx(1,
"dwarf_init failed");
247 for (num = 0;; num++) {
248 ret = dwarf_next_cu_header_d(dw_dbg, 1, &cu_hdr_len, &cu_vers, NULL, NULL,
249 NULL, NULL, NULL, NULL, &cu_hdr_off, NULL, &dw_error);
251 if (ret == DW_DLV_NO_ENTRY) {
254 else if (ret != DW_DLV_OK) {
255 errx(1,
"dwarf_next_cu_header_d failed");
258 #if DEBUG_RAW_LINE_MAP 259 cout <<
"\ncomp unit # " << num <<
":\n";
262 do_comp_unit(dw_dbg, num, cu_vers, cu_hdr_len, cu_hdr_off);
265 ret = dwarf_finish(dw_dbg, &dw_error);
266 if (ret != DW_DLV_OK) {
279 m_empty_index = m_str_tab.str2index(
"");
292 #if DEBUG_FULL_LINE_MAP 293 cout <<
"\nfull line map:\n\n";
295 for (
auto it = m_line_map.begin(); it != m_line_map.end(); ++it) {
296 cout <<
"0x" << hex << it->first << dec
297 <<
" " << setw(6) << it->second.line
298 <<
" " << m_str_tab.index2str(it->second.file) <<
"\n";
311 auto it = m_line_map.upper_bound(vma);
314 lr.
start = it->first;
315 lr.
filenm = m_str_tab.index2str(it->second.file).c_str();
316 lr.
lineno = it->second.line;
void do_line_map(Dwarf_Debug, Dwarf_Die)
void do_comp_unit(Dwarf_Debug, int, int, long, long)
void getLineRange(VMA, LineRange &)
void readFile(ElfFile *elf)
std::string getFileName()
void do_dwarf(ElfFile *elf)
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n