1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include <sys/param.h>
28 #include "DbeSession.h"
29 #include "Experiment.h"
30 #include "DataObject.h"
33 #include "MetricList.h"
35 #include "ClassFile.h"
36 #include "LoadObject.h"
46 lang_code
= Sp_lang_unknown
;
49 openSourceFlag
= AE_NOTREAD
;
56 indexStabsLink
= NULL
;
58 functions
= new Vector
<Function
*>;
61 main_source
= dbeSession
->get_Unknown_Source ();
62 srcContext
= main_source
;
63 includes
= new Vector
<SourceFile
*>;
64 includes
->append (main_source
);
79 linkerStabName
= NULL
;
80 disMTime
= (time_t) 0;
81 stabsMTime
= (time_t) 0;
105 free (linkerStabName
);
113 // Remove a link to the current module
114 indexStabsLink
->indexStabsLink
= NULL
;
118 delete dot_o_file
->dbeFile
;
125 if (lang_code
!= Sp_lang_java
)
131 Module::openDebugInfo ()
134 objStabs
= loadobject
->openDebugInfo (disPath
);
139 Module::removeStabsTmp ()
141 // Remove temporary *.o (got from *.a) after reading Stabs
142 if (stabsTmp
!= NULL
)
156 Vec_loop (Function
*, functions
, index
, fp
)
164 Module::is_fortran ()
166 return Stabs::is_fortran (lang_code
);
170 Module::findSource (const char *fname
, bool create
)
172 SourceFile
*sf
= NULL
;
173 if (loadobject
&& loadobject
->firstExp
)
174 sf
= loadobject
->firstExp
->get_source (fname
);
176 sf
= dbeSession
->createSourceFile (fname
);
177 for (int i
= 0, sz
= includes
? includes
->size () : 0; i
< sz
; i
++)
179 SourceFile
*sf1
= includes
->fetch (i
);
185 if (includes
== NULL
)
186 includes
= new Vector
<SourceFile
*>;
187 includes
->append (sf
);
194 Module::setIncludeFile (char *includeFile
)
198 curr_inc
= findSource (includeFile
, true);
203 Module::anno_str (char *fnm
)
205 char timebuf1
[26], timebuf2
[26];
206 const time_t real_time
= (time_t) (unsigned int) real_timestamp
;
207 const time_t curr_time
= (time_t) (unsigned int) curr_timestamp
;
215 return dbe_sprintf (GTXT ("Source file `%s' not readable"),
216 fnm
? fnm
: file_name
);
218 if (lang_code
== Sp_lang_java
)
220 Emsg
*emsg
= get_error ();
223 char *s
= dbe_strdup (emsg
->get_msg ());
227 return dbe_sprintf (GTXT ("Object file `%s.class' not readable"),
230 return dbe_sprintf (GTXT ("Object file `%s' not readable"), get_name ());
232 if (lang_code
== Sp_lang_java
)
233 return dbe_sprintf (GTXT ("Object file `%s' not readable"),
234 dbeFile
? dbeFile
->get_name () : name
);
235 return dbe_sprintf (GTXT ("Object file `%s' not readable"), loadobject
->get_pathname ());
237 return dbe_sprintf (GTXT ("Error reading line-number information in object `%s'; source annotation not available"),
238 stabsPath
? stabsPath
: NTXT (""));
240 return dbe_sprintf (GTXT ("Error reading symbol table in object `%s'; disassembly annotation not available"),
241 disPath
? disPath
: NTXT (""));
243 return dbe_sprintf (GTXT ("Warning! Source file `%s' is newer than the experiment data"),
244 main_source
->dbeFile
->getResolvedPath ());
246 return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),
247 disName
? disName
: NTXT (""));
249 return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),
250 stabsName
? stabsName
: NTXT (""));
251 case AE_TIMESTABS_DIFF
:
252 snprintf (timebuf1
, sizeof (timebuf1
), NTXT ("%s"), ctime (&curr_time
));
253 snprintf (timebuf2
, sizeof (timebuf2
), NTXT ("%s"), ctime (&real_time
));
254 timebuf1
[24] = timebuf2
[24] = '\0';
255 return dbe_sprintf (GTXT ("Warning! Object file `%s' is not the same one that was linked into executable.\n"
256 "\tObject file: `%s'\n\tcompiled on: %s\n"
257 "\tExecutable contains object file compiled on: %s"),
258 getResolvedObjectPath (), getResolvedObjectPath (),
262 return dbe_strdup (GTXT ("Annotation computation error"));
267 Module::createLoadObject (const char *lo_name
)
269 LoadObject
*lo
= new LoadObject (lo_name
);
270 lo
->dbeFile
->filetype
|= DbeFile::F_DOT_O
;
275 tsIsNewer (time_t t1
, time_t t2
)
277 return t1
!= 0 && t2
!= 0 && t1
< t2
;
281 Module::checkTimeStamp (bool chkDis
)
283 /* Check the linked and the real object timestamps due to bug #4796329 */
284 if (real_timestamp
&& curr_timestamp
&& real_timestamp
!= curr_timestamp
)
285 return AE_TIMESTABS_DIFF
;
287 time_t srctime
= main_source
->getMTime ();
288 for (int index
= 0; index
< dbeSession
->nexps (); index
++)
290 time_t mtime
= dbeSession
->get_exp (index
)->get_mtime ();
291 if (tsIsNewer (mtime
, srctime
))
293 if (tsIsNewer (mtime
, stabsMTime
))
295 if (chkDis
&& tsIsNewer (mtime
, disMTime
))
302 get_ar_size (char *s
, size_t len
)
305 for (size_t i
= 0; i
< len
; i
++)
307 if (s
[i
] < '0' || s
[i
] > '9')
309 sz
= sz
* 10 + (s
[i
] - '0');
315 dump_hdr_field (char *nm
, char *s
, size_t len
)
317 Dprintf (DEBUG_READ_AR
, NTXT (" %s "), nm
);
318 for (size_t i
= 0; i
< len
; i
++)
319 Dprintf (DEBUG_READ_AR
, "%c", isprint (s
[i
]) ? s
[i
] : '?');
320 Dprintf (DEBUG_READ_AR
, NTXT (" "));
321 for (size_t i
= 0; i
< len
; i
++)
322 Dprintf (DEBUG_READ_AR
, NTXT (" %d"), s
[i
]);
323 Dprintf (DEBUG_READ_AR
, NTXT (" \n"));
327 dump_ar_hdr (int lineNum
, struct ar_hdr
*hdr
)
331 Dprintf (DEBUG_READ_AR
, NTXT ("Module::read_ar %d\n"), lineNum
);
332 dump_hdr_field (NTXT ("ar_name"), hdr
->ar_name
, sizeof (hdr
->ar_name
));
333 dump_hdr_field (NTXT ("ar_date"), hdr
->ar_date
, sizeof (hdr
->ar_date
));
334 dump_hdr_field (NTXT ("ar_uid"), hdr
->ar_uid
, sizeof (hdr
->ar_uid
));
335 dump_hdr_field (NTXT ("ar_gid"), hdr
->ar_gid
, sizeof (hdr
->ar_gid
));
336 dump_hdr_field (NTXT ("ar_mode"), hdr
->ar_mode
, sizeof (hdr
->ar_mode
));
337 dump_hdr_field (NTXT ("ar_size"), hdr
->ar_size
, sizeof (hdr
->ar_size
));
338 dump_hdr_field (NTXT ("ar_fmag"), hdr
->ar_fmag
, sizeof (hdr
->ar_fmag
));
343 Module::read_ar (int ar
, int obj
, char *obj_base
)
345 struct ar_hdr hdr
; // Archive header
346 char magic
[SARMAG
]; // Magic string from archive
347 Dprintf (DEBUG_READ_AR
, "Module::read_ar %d %p %s %s \n", __LINE__
,
348 this, STR (obj_base
), STR (get_name ()));
349 // Check the magic string
350 if ((read_from_file (ar
, magic
, SARMAG
) != SARMAG
)
351 || strncmp (magic
, ARMAG
, SARMAG
))
354 // Read and skip the first file in the archive (index file to ld)
355 if (read_from_file (ar
, &hdr
, sizeof (hdr
)) != sizeof (hdr
))
357 DEBUG_CODE
dump_ar_hdr (__LINE__
, &hdr
);
358 if (lseek (ar
, get_ar_size (hdr
.ar_size
, sizeof (hdr
.ar_size
)), SEEK_CUR
)
362 // Read the string file where it keeps long file names (if exist)
363 if (read_from_file (ar
, &hdr
, sizeof (hdr
)) != sizeof (hdr
))
365 DEBUG_CODE
dump_ar_hdr (__LINE__
, &hdr
);
366 char *longnames
= NULL
; // Area with names longer than ~13
367 size_t longnames_size
= 0;
368 if (!strncmp (hdr
.ar_name
, NTXT ("//"), 2))
370 longnames_size
= get_ar_size (hdr
.ar_size
, sizeof (hdr
.ar_size
));
371 longnames
= (char *) malloc (longnames_size
+ 1);
372 int64_t cnt
= read_from_file (ar
, longnames
, longnames_size
);
373 if (cnt
!= (int64_t) longnames_size
)
378 longnames
[longnames_size
] = 0;
381 // back out, no long file names
382 lseek (ar
, -(sizeof (hdr
)), SEEK_CUR
);
384 // Search the ar for the object file name
385 char ar_buf
[sizeof (hdr
.ar_name
) + 1];
386 ar_buf
[sizeof (hdr
.ar_name
)] = 0;
389 if (read_from_file (ar
, &hdr
, sizeof (hdr
)) != sizeof (hdr
))
391 DEBUG_CODE
dump_ar_hdr (__LINE__
, &hdr
);
393 if (hdr
.ar_name
[0] != '/')
394 { // Name is in the header
395 for (size_t i
= 0; i
< sizeof (hdr
.ar_name
); i
++)
397 if (hdr
.ar_name
[i
] == '/')
402 ar_buf
[i
] = hdr
.ar_name
[i
];
406 else if (hdr
.ar_name
[1] == ' ')
412 { // Name is in the string table
413 if (longnames
== NULL
)
415 size_t offset
= get_ar_size (hdr
.ar_name
+ 1,
416 sizeof (hdr
.ar_name
) - 1);
417 if (offset
>= longnames_size
)
419 for (size_t i
= offset
; i
< longnames_size
; i
++)
421 if (longnames
[i
] == '/')
427 ar_name
= longnames
+ offset
;
429 Dprintf (DEBUG_READ_AR
, "Module::read_ar %d ar_name=%s\n", __LINE__
,
432 if (streq (ar_name
, obj_base
))
433 { // create object file
435 for (size_t objsize
= get_ar_size (hdr
.ar_size
, sizeof (hdr
.ar_size
));
438 char buf
[MAXPATHLEN
];
439 size_t n
= objsize
< sizeof (buf
) ? objsize
: sizeof (buf
);
440 int64_t cnt
= read_from_file (ar
, buf
, n
);
441 if (cnt
!= (int64_t) n
)
443 cnt
= write (obj
, buf
, n
);
444 if (cnt
!= (int64_t) n
)
450 if (lseek (ar
, get_ar_size (hdr
.ar_size
, sizeof (hdr
.ar_size
)),
459 get_obj_name_from_lib (char *nm
)
461 char *base
= strrchr (nm
, '(');
464 size_t last
= strlen (base
) - 1;
465 if (base
[last
] == ')')
474 if ((loadobject
->flags
& SEG_FLAG_DYNAMIC
) != 0)
476 if ((loadobject
->dbeFile
->filetype
& DbeFile::F_FICTION
) != 0)
478 if ((flags
& MOD_FLAG_UNKNOWN
) != 0)
481 if (lang_code
== Sp_lang_java
)
483 if (dbeFile
->get_need_refind ())
485 char *fnm
= dbeFile
->get_location ();
486 stabsPath
= dbe_strdup (fnm
);
487 stabsName
= dbe_strdup (fnm
);
488 disPath
= dbe_strdup (fnm
);
489 disName
= dbe_strdup (fnm
);
490 stabsMTime
= dbeFile
->sbuf
.st_mtime
;
492 return dbeFile
->get_location () != NULL
;
497 char *objname
= get_obj_name_from_lib (name
);
500 // in the format of libpath(obj)
501 objname
= dbe_strdup (objname
+ 1);
502 size_t last
= strlen (objname
) - 1;
503 objname
[last
] = '\0';
505 dbeFile
= new DbeFile (objname
? objname
: name
);
507 dbeFile
->filetype
|= DbeFile::F_DOT_O
;
509 if (dbeFile
->get_need_refind ())
511 disMTime
= (time_t) 0;
512 stabsMTime
= (time_t) 0;
518 // Find the Executable/Shared-Object file of module
519 char *path
= loadobject
->dbeFile
->get_location ();
522 disPath
= strdup (path
);
523 disName
= strdup (path
);
524 disMTime
= loadobject
->dbeFile
->sbuf
.st_mtime
;
527 char *objname
= get_obj_name_from_lib (name
);
530 // in the format of libpath(obj)
531 char *namebuf
= dbe_strdup (name
);
532 char *base
= namebuf
+ (objname
- name
);
535 size_t last
= strlen (base
) - 1;
537 stabsTmp
= dbeSession
->get_tmp_file_name (base
, false);
538 dbeSession
->tmp_files
->append (strdup (stabsTmp
));
540 DbeFile
*dbf
= dbeSession
->getDbeFile (namebuf
,
541 DbeFile::F_DOT_A_LIB
| DbeFile::F_FILE
);
542 path
= dbf
->get_location ();
543 int ar
= -1, obj
= -1;
546 ar
= open64 (path
, O_RDONLY
| O_LARGEFILE
);
548 obj
= open64 (stabsTmp
, O_CREAT
| O_WRONLY
| O_LARGEFILE
, 0600);
550 if (ar
!= -1 && obj
!= -1 && read_ar (ar
, obj
, base
))
552 dbeFile
->set_location (stabsTmp
);
553 dbeFile
->check_access (stabsTmp
); // init 'sbuf'
554 dbeFile
->sbuf
.st_mtime
= 0; // Don't check timestamps
555 dbeFile
->container
= dbf
;
556 stabsPath
= strdup (stabsTmp
);
557 stabsName
= strdup (path
);
558 stabsMTime
= dbeFile
->sbuf
.st_mtime
;
573 path
= dbeFile
->get_location ();
576 stabsPath
= strdup (path
);
577 stabsName
= strdup (path
);
578 stabsMTime
= hasDwarf
? 0 : dbeFile
->sbuf
.st_mtime
;
582 // First, try to access the symbol table of the module itself
583 // If failed, access the symbol table of the executable
584 if (stabsPath
== NULL
)
588 stabsPath
= strdup (disPath
);
589 stabsName
= strdup (disName
);
590 stabsMTime
= disMTime
;
592 else if (disPath
== NULL
)
594 disPath
= strdup (stabsPath
);
595 disName
= strdup (stabsName
);
596 disMTime
= stabsMTime
;
599 return stabsPath
!= NULL
;
602 // openStabs -- open mappings from PCs to source lines
604 Module::openStabs (bool all
)
606 if ((loadobject
->flags
& SEG_FLAG_DYNAMIC
) != 0
607 || (flags
& MOD_FLAG_UNKNOWN
) != 0)
609 if (loadobject
->platform
== Java
)
611 setIncludeFile (NULL
);
613 return ( status
== AE_OK
);
619 int64_t Inode
= main_source
->getInode ();
620 char *fname
= strrchr (file_name
, (int) '/');
621 char *mname
= strrchr (main_source
->get_name (), (int) '/');
622 if (fname
&& mname
&& !streq (fname
, mname
))
624 SourceFile
*sf
= findSource (file_name
, false);
626 Inode
= sf
->getInode ();
629 comComs
= new Vector
<ComC
*>;
630 Stabs
*stabs
= openDebugInfo ();
633 int st
= stabs
->read_stabs (Inode
, this, comComs
, true);
634 if (!hasDwarf
&& hasStabs
&& !streq (stabsPath
, disPath
))
636 // Read stabs from .o file
637 if (dot_o_file
== NULL
)
639 if (dbeFile
->get_location ())
641 dot_o_file
= createLoadObject (dbeFile
->get_name ());
642 dot_o_file
->dbeFile
->set_location (dbeFile
->get_location ());
643 dot_o_file
->dbeFile
->sbuf
= dbeFile
->sbuf
;
644 dot_o_file
->dbeFile
->container
= dbeFile
->container
;
648 && dot_o_file
->sync_read_stabs () == LoadObject::ARCHIVE_SUCCESS
)
650 Stabs
*stabs_o
= dot_o_file
->objStabs
;
653 st
= stabs_o
->read_stabs (Inode
, this,
654 comComs
->size () > 0 ? NULL
: comComs
);
655 Elf
*elf_o
= stabs_o
->openElf (false);
657 stabs
->read_dwarf_from_dot_o (this);
662 read_hwcprof_info ();
665 return st
== Stabs::DBGD_ERR_NONE
;
669 Module::get_disasm (uint64_t inst_address
, uint64_t end_address
,
670 uint64_t start_address
, uint64_t address
, int64_t &inst_size
)
672 return disasm
->get_disasm (inst_address
, end_address
, start_address
,
677 Module::read_stabs (bool all
)
679 if (openSourceFlag
== AE_NOTREAD
)
681 openSourceFlag
= AE_OK
;
682 if (lang_code
== Sp_lang_java
)
684 char *clpath
= file_name
;
685 if (clpath
== NULL
|| strcmp (clpath
, "<Unknown>") == 0)
686 clpath
= ClassFile::get_java_file_name (name
, false);
687 main_source
= findSource (clpath
, true);
688 main_source
->dbeFile
->filetype
|= DbeFile::F_JAVA_SOURCE
;
689 if (clpath
!= file_name
)
693 main_source
= findSource (file_name
, true);
704 if (!(loadobject
->flags
& SEG_FLAG_DYNAMIC
) && loadobject
->platform
!= Java
)
706 // Read Stabs & Symbol tables
707 if (openDebugInfo () == NULL
)
709 if (!objStabs
->read_symbols (functions
))
712 disasm
= new Disasm (loadobject
->platform
, objStabs
);
717 static SourceFile
*cmpSrcContext
; // Use only for func_cmp
720 func_cmp (const void *a
, const void *b
)
722 Function
*fp1
= *((Function
**) a
);
723 Function
*fp2
= *((Function
**) b
);
724 return fp1
->func_cmp (fp2
, cmpSrcContext
);
728 Module::computeMetrics (DbeView
*dbev
, Function
*func
, MetricList
*metrics
,
729 Histable::Type type
, bool src_metric
,
730 bool func_scope
, SourceFile
*source
)
732 name_idx
= metrics
->get_listorder (NTXT ("name"), Metric::STATIC
);
735 metrics
->print_metric_list (stderr
,
736 GTXT ("Fatal: no name metric in Module::computeMetrics mlist:\n"),
741 // Now find the metrics for size and address, if present
742 size_index
= metrics
->get_listorder (NTXT ("size"), Metric::STATIC
);
743 addr_index
= metrics
->get_listorder (NTXT ("address"), Metric::STATIC
);
745 // free the old cached data for both src and disassembly
746 // If it's disassembly with visible source metrics, we use both
758 // ask the DbeView to generate new data to be cached
759 if (src_metric
|| type
== Histable::LINE
)
761 Histable
*obj
= (func_scope
) ? (Histable
*) func
: (Histable
*)this;
762 if (lang_code
== Sp_lang_java
)
763 obj
= func_scope
? (Histable
*) func
:
764 (source
&& source
->get_type () == Histable::SOURCEFILE
?
765 (Histable
*) source
: (Histable
*) this);
766 src_items
= dbev
->get_hist_data (metrics
, Histable::LINE
, 0,
767 Hist_data::MODL
, obj
, source
);
769 if (type
== Histable::INSTR
)
770 dis_items
= dbev
->get_hist_data (metrics
, Histable::INSTR
, 0,
772 func_scope
? (Histable
*) func
: (Histable
*) this,
775 Hist_data
*cur_hist_data
;
776 if (type
== Histable::INSTR
)
777 cur_hist_data
= dis_items
;
779 cur_hist_data
= src_items
;
781 Vector
<Metric
*> *items
= cur_hist_data
->get_metric_list ()->get_items ();
782 long sz
= items
->size ();
783 empty
= new TValue
[sz
];
784 memset (empty
, 0, sizeof (TValue
) * sz
);
785 for (long i
= 0; i
< sz
; i
++)
786 empty
[i
].tag
= items
->get (i
)->get_vtype ();
790 // Method to get annotated source or disassembly for the module
791 // or a function within it
793 Module::get_data (DbeView
*dbev
, MetricList
*mlist
, Histable::Type type
,
794 TValue
*ftotal
, SourceFile
*srcFile
, Function
*func
,
795 Vector
<int> *marks
, int threshold
, int vis_bits
,
796 int src_visible
, bool hex_vis
, bool func_scope
,
797 bool /*src_only*/, Vector
<int_pair_t
> *marks2d
,
798 Vector
<int_pair_t
> *marks2d_inc
)
801 srcContext
= srcFile
? srcFile
: main_source
;
804 dbev
->warning_msg
= NULL
;
805 dbev
->error_msg
= NULL
;
806 if (type
== Histable::LINE
)
808 if (!srcContext
->readSource ())
811 dbev
->error_msg
= anno_str (srcContext
->get_name ());
814 if (!computeMetrics (dbev
, func
, mlist
, type
, false, func_scope
, srcContext
))
817 dbev
->error_msg
= anno_str ();
820 status
= checkTimeStamp (false);
824 Anno_Errors src_status
= AE_OK
;
825 if (!srcContext
->readSource ())
827 src_status
= AE_NOSRC
;
828 dbev
->error_msg
= anno_str (srcContext
->get_name ());
835 src_status
= AE_NOSTABS
;
837 status
= AE_NOSYMTAB
;
841 dbev
->error_msg
= anno_str ();
844 if (src_status
!= AE_OK
&& func
!= NULL
)
846 if (loadobject
->platform
== Java
&& (func
->flags
& FUNC_FLAG_NATIVE
) != 0)
848 append_msg (CMSG_ERROR
,
849 GTXT ("`%s' is a native method; byte code not available\n"),
852 dbev
->error_msg
= anno_str ();
857 // get the disassembly-line metric data
858 if (!computeMetrics (dbev
, func
, mlist
, type
,
859 (src_visible
& SRC_METRIC
) != 0,
860 func_scope
, srcContext
))
863 dbev
->error_msg
= anno_str ();
866 status
= checkTimeStamp (true);
870 // initialize line number
873 // initialize data -- get duplicate metric list for the line texts
874 // pick up the metric list from the computed data
875 MetricList
*nmlist
= NULL
;
876 if (type
== Histable::INSTR
)
878 mlist
= dis_items
->get_metric_list ();
879 nmlist
= new MetricList (mlist
);
880 data_items
= new Hist_data (nmlist
, Histable::INSTR
, Hist_data::MODL
);
881 data_items
->set_status (dis_items
->get_status ());
882 set_dis_data (func
, vis_bits
, dbev
->get_cmpline_visible (),
883 src_visible
, hex_vis
, func_scope
,
884 dbev
->get_funcline_visible ());
888 mlist
= src_items
->get_metric_list ();
889 nmlist
= new MetricList (mlist
);
890 data_items
= new Hist_data (nmlist
, Histable::LINE
, Hist_data::MODL
);
891 data_items
->set_status (src_items
->get_status ());
892 set_src_data (func_scope
? func
: NULL
, vis_bits
,
893 dbev
->get_cmpline_visible (),
894 dbev
->get_funcline_visible ());
896 data_items
->compute_minmax ();
900 Hist_data::HistItem
*max_item
;
902 Hist_data::HistItem
*max_item_inc
;
904 double dthreshold
= threshold
/ 100.0;
906 int sz
= data_items
->get_metric_list ()->get_items ()->size ();
907 maximum
= new TValue
[sz
];
908 maximum_inc
= new TValue
[sz
];
909 memset (maximum
, 0, sizeof (TValue
) * sz
);
910 memset (maximum_inc
, 0, sizeof (TValue
) * sz
);
911 max_item
= data_items
->get_maximums ();
912 max_item_inc
= data_items
->get_maximums_inc ();
914 Vec_loop (Metric
*, data_items
->get_metric_list ()->get_items (), index
, mitem
)
916 maximum_inc
[index
].tag
= maximum
[index
].tag
= mitem
->get_vtype ();
918 if (mitem
->get_subtype () == Metric::STATIC
)
920 if (!mitem
->is_visible () && !mitem
->is_tvisible ()
921 && !mitem
->is_pvisible ())
924 value
= &max_item
->value
[index
];
925 value_inc
= &max_item_inc
->value
[index
];
928 if (mitem
->is_zeroThreshold () == true)
931 dthresh
= dthreshold
;
935 maximum
[index
].i
= (int) (dthresh
* (double) value
->i
);
936 maximum_inc
[index
].i
= (int) (dthresh
* (double) value_inc
->i
);
939 maximum
[index
].d
= dthresh
* value
->d
;
940 maximum_inc
[index
].d
= dthresh
* value_inc
->d
;
943 maximum
[index
].ll
= (unsigned long long) (dthresh
* (double) value
->ll
);
944 maximum_inc
[index
].ll
= (unsigned long long)
945 (dthresh
* (double) value_inc
->ll
);
948 maximum
[index
].ull
= (unsigned long long)
949 (dthresh
* (double) value
->ull
);
950 maximum_inc
[index
].ull
= (unsigned long long)
951 (dthresh
* (double) value_inc
->ull
);
954 // not needed for non-numerical metrics
959 // mark all high values
960 for (int index1
= 0; index1
< data_items
->size (); index1
++)
962 Hist_data::HistItem
*hi
= data_items
->fetch (index1
);
964 Vec_loop (Metric
*, nmlist
->get_items (), index2
, mitem
)
967 if (mitem
->get_subtype () == Metric::STATIC
)
969 if (!mitem
->is_visible () && !mitem
->is_tvisible ()
970 && !mitem
->is_pvisible ())
973 switch (hi
->value
[index2
].tag
)
976 if (nmlist
->get_type () == MET_SRCDIS
977 && data_items
->get_callsite_mark ()->get (hi
->obj
))
979 if (hi
->value
[index2
].d
> maximum_inc
[index2
].d
)
983 if (hi
->value
[index2
].d
> maximum
[index2
].d
)
987 if (nmlist
->get_type () == MET_SRCDIS
988 && data_items
->get_callsite_mark ()->get (hi
->obj
))
990 if (hi
->value
[index2
].i
> maximum_inc
[index2
].i
)
994 if (hi
->value
[index2
].i
> maximum
[index2
].i
)
998 if (nmlist
->get_type () == MET_SRCDIS
999 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1001 if (hi
->value
[index2
].ll
> maximum_inc
[index2
].ll
)
1005 if (hi
->value
[index2
].ll
> maximum
[index2
].ll
)
1009 if (nmlist
->get_type () == MET_SRCDIS
1010 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1012 if (hi
->value
[index2
].ull
> maximum_inc
[index2
].ull
)
1016 if (hi
->value
[index2
].ull
> maximum
[index2
].ull
)
1019 // ignoring the following cases (why?)
1030 marks
->append (index1
);
1036 // mark all high values to marks2d
1037 if (marks2d
!= NULL
&& marks2d_inc
!= NULL
)
1039 for (int index1
= 0; index1
< data_items
->size (); index1
++)
1041 Hist_data::HistItem
*hi
= data_items
->fetch (index1
);
1043 Vec_loop (Metric
*, nmlist
->get_items (), index2
, mitem
)
1045 Metric::SubType subType
= mitem
->get_subtype ();
1046 if (subType
== Metric::STATIC
)
1048 if (!mitem
->is_visible () && !mitem
->is_tvisible ()
1049 && !mitem
->is_pvisible ())
1051 switch (hi
->value
[index2
].tag
)
1054 if (nmlist
->get_type () == MET_SRCDIS
1055 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1057 if (hi
->value
[index2
].d
> maximum_inc
[index2
].d
)
1059 int_pair_t pair
= {index1
, index2
};
1060 marks2d_inc
->append (pair
);
1064 if (hi
->value
[index2
].d
> maximum
[index2
].d
)
1066 int_pair_t pair
= {index1
, index2
};
1067 marks2d
->append (pair
);
1071 if (nmlist
->get_type () == MET_SRCDIS
1072 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1074 if (hi
->value
[index2
].i
> maximum_inc
[index2
].i
)
1076 int_pair_t pair
= {index1
, index2
};
1077 marks2d_inc
->append (pair
);
1081 if (hi
->value
[index2
].i
> maximum
[index2
].i
)
1083 int_pair_t pair
= {index1
, index2
};
1084 marks2d
->append (pair
);
1088 if (nmlist
->get_type () == MET_SRCDIS
1089 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1091 if (hi
->value
[index2
].ll
> maximum_inc
[index2
].ll
)
1093 int_pair_t pair
= {index1
, index2
};
1094 marks2d_inc
->append (pair
);
1098 if (hi
->value
[index2
].ll
> maximum
[index2
].ll
)
1100 int_pair_t pair
= {index1
, index2
};
1101 marks2d
->append (pair
);
1105 if (nmlist
->get_type () == MET_SRCDIS
1106 && data_items
->get_callsite_mark ()->get (hi
->obj
))
1108 if (hi
->value
[index2
].ull
> maximum_inc
[index2
].ull
)
1110 int_pair_t pair
= {index1
, index2
};
1111 marks2d_inc
->append (pair
);
1115 if (hi
->value
[index2
].ull
> maximum
[index2
].ull
)
1117 int_pair_t pair
= {index1
, index2
};
1118 marks2d
->append (pair
);
1133 // free memory used by Computing & Printing metrics
1135 delete[] maximum_inc
;
1140 dbev
->warning_msg
= anno_str ();
1145 Module::getAddrs (Function
*func
)
1147 uint64_t start_address
= func
->img_offset
;
1148 uint64_t end_address
= start_address
+ func
->size
;
1149 int64_t inst_size
= 0;
1151 // initialize "disasm" if necessary
1155 Vector
<uint64_t> *addrs
= new Vector
<uint64_t>;
1156 for (uint64_t inst_address
= start_address
; inst_address
< end_address
;)
1158 char *s
= disasm
->get_disasm (inst_address
, end_address
, start_address
,
1159 func
->img_offset
, inst_size
);
1161 addrs
->append (inst_address
- start_address
);
1162 inst_address
+= inst_size
;
1170 Module::init_line ()
1172 // initialize the compiler commentary data
1174 if (comComs
!= NULL
&& comComs
->size () > 0)
1175 cline
= comComs
->fetch (cindex
)->line
;
1180 if (src_items
&& src_items
->size () > 0)
1181 sline
= ((DbeLine
*) src_items
->fetch (0)->obj
)->lineno
;
1188 if (dis_items
&& dis_items
->size () > 0)
1190 daddr
= (DbeInstr
*) dis_items
->fetch (0)->obj
;
1192 // After sorting all HistItems with PCLineFlag appear
1193 // at the end of the list. Find the first one.
1194 for (mindex
= dis_items
->size () - 1; mindex
>= 0; mindex
--)
1196 Hist_data::HistItem
*item
= dis_items
->fetch (mindex
);
1197 if (!(((DbeInstr
*) item
->obj
)->flags
& PCLineFlag
))
1199 mline
= (unsigned) (((DbeInstr
*) item
->obj
)->addr
);
1208 Module::set_src_data (Function
*func
, int vis_bits
, int cmpline_visible
,
1209 int funcline_visible
)
1211 Function
*curr_func
= NULL
;
1213 // start at the top of the file, and loop over all lines in the file (source context)
1214 for (curline
= 1; curline
<= srcContext
->getLineCount (); curline
++)
1216 // Before writing the line, see if there's compiler commentary to insert
1217 if (cline
== curline
)
1218 set_ComCom (vis_bits
);
1220 // Find out if we need to print zero metrics with the line
1221 DbeLine
*dbeline
= srcContext
->find_dbeline (NULL
, curline
);
1222 Anno_Types type
= AT_SRC_ONLY
;
1223 if (dbeline
->dbeline_func_next
)
1226 for (DbeLine
*dl
= dbeline
->dbeline_func_next
; dl
; dl
= dl
->dbeline_func_next
)
1228 if (dl
->func
== func
)
1238 if (funcline_visible
)
1240 // is there a function index line to insert?
1241 Function
*func_next
= NULL
;
1242 for (DbeLine
*dl
= dbeline
; dl
; dl
= dl
->dbeline_func_next
)
1244 Function
*f
= dl
->func
;
1245 if (f
&& f
->line_first
== curline
1246 && f
->getDefSrc () == srcContext
)
1248 if (lang_code
== Sp_lang_java
1249 && (f
->flags
& FUNC_FLAG_DYNAMIC
))
1251 if (cur_dbev
&& cur_dbev
->get_path_tree ()->get_func_nodeidx (f
))
1256 else if (func_next
== NULL
)
1260 if (func_next
&& curr_func
!= func_next
)
1262 curr_func
= func_next
;
1263 char *func_name
= curr_func
->get_name ();
1264 if (is_fortran () && streq (func_name
, NTXT ("MAIN_")))
1265 func_name
= curr_func
->get_match_name ();
1266 Hist_data::HistItem
*item
=
1267 src_items
->new_hist_item (curr_func
, AT_FUNC
, empty
);
1268 item
->value
[name_idx
].l
= dbe_sprintf (GTXT ("<Function: %s>"),
1270 data_items
->append_hist_item (item
);
1272 } // end of red line
1273 set_src (type
, dbeline
); // add the source line
1274 } // end of loop over source lines
1276 // See if compiler flags are set; if so, append them
1277 if (cmpline_visible
&& comp_flags
)
1279 Hist_data::HistItem
*item
= src_items
->new_hist_item (NULL
, AT_EMPTY
,
1281 item
->value
[name_idx
].l
= strdup (NTXT (""));
1282 data_items
->append_hist_item (item
);
1283 item
= src_items
->new_hist_item (NULL
, AT_COM
, empty
);
1284 item
->value
[name_idx
].l
= dbe_sprintf (GTXT ("Compile flags: %s"),
1286 data_items
->append_hist_item (item
);
1291 Module::set_dis_data (Function
*func
, int vis_bits
, int cmpline_visible
,
1292 int src_visible
, bool hex_vis
, bool func_scope
,
1293 int funcline_visible
)
1295 bool nextFile
= false;
1297 // initialize the source output, if any
1298 curline
= (srcContext
->getLineCount () > 0) ? 1 : -1;
1300 nextFile
= srcContext
!= func
->getDefSrc ();
1301 curr_inc
= srcContext
;
1303 bool src_code
= (src_visible
& SRC_CODE
);
1304 Anno_Types src_type
= (src_visible
& SRC_METRIC
) ? AT_SRC
: AT_SRC_ONLY
;
1306 char *img_fname
= func
? func
->img_fname
: NULL
;
1308 // Build a new Function list
1309 Vector
<Function
*> *FuncLst
= new Vector
<Function
*>;
1313 FuncLst
->append (func
);
1317 for (int i
= 0, sz
= functions
? functions
->size () : 0; i
< sz
; i
++)
1319 Function
*fitem
= functions
->fetch (i
);
1320 if (fitem
!= fitem
->cardinal ())
1322 if (img_fname
== NULL
)
1323 img_fname
= fitem
->img_fname
;
1324 if (fitem
->img_fname
== NULL
|| strcmp (fitem
->img_fname
, img_fname
))
1326 FuncLst
->append (fitem
);
1329 if (FuncLst
->size () == 0)
1330 { // no function is good
1334 cmpSrcContext
= srcContext
;
1335 FuncLst
->sort (func_cmp
);
1337 disasm
->set_hex_visible (hex_vis
);
1338 for (int index
= 0, sz
= FuncLst
->size (); index
< sz
; index
++)
1340 Function
*fitem
= FuncLst
->fetch (index
);
1341 uint64_t start_address
, end_address
;
1343 if (fitem
->getDefSrc () != srcContext
&& curline
> 0)
1345 // now flush the left source line, if available
1346 for (; curline
<= srcContext
->getLineCount (); curline
++)
1348 // see if there's a compiler comment line to dump
1349 if (cline
== curline
)
1350 set_ComCom (vis_bits
);
1352 set_src (src_type
, srcContext
->find_dbeline (curline
));
1358 // disassemble one function
1359 start_address
= objStabs
?
1360 objStabs
->mapOffsetToAddress (fitem
->img_offset
) : 0;
1361 end_address
= start_address
+ fitem
->size
;
1364 disasm
->set_addr_end (end_address
);
1365 if ((loadobject
->flags
& SEG_FLAG_DYNAMIC
)
1366 && loadobject
->platform
!= Java
)
1367 disasm
->set_img_name (img_fname
);
1369 for (uint64_t inst_address
= start_address
; inst_address
< end_address
;)
1371 uint64_t address
= inst_address
- start_address
;
1372 DbeInstr
*instr
= fitem
->find_dbeinstr (0, address
);
1373 DbeLine
*dbeline
= (DbeLine
*) (instr
->convertto (Histable::LINE
));
1374 if (instr
->lineno
== -1 && dbeline
&& dbeline
->lineno
> 0)
1375 instr
->lineno
= dbeline
->lineno
;
1377 // now write the unannotated source line, if available
1379 { // source is present
1380 int lineno
= curline
- 1;
1381 if (instr
->lineno
!= -1)
1383 if (dbeline
&& streq (dbeline
->sourceFile
->get_name (),
1384 srcContext
->get_name ()))
1385 lineno
= instr
->lineno
;
1387 else if (curr_inc
== NULL
&& srcContext
== fitem
->def_source
1388 && fitem
->line_first
> 0)
1389 lineno
= fitem
->line_first
;
1391 for (; curline
<= lineno
; curline
++)
1393 // see if there's a compiler comment line to dump
1394 if (cline
== curline
)
1395 set_ComCom (vis_bits
);
1396 if (mline
== curline
)
1399 set_src (src_type
, srcContext
->find_dbeline (curline
));
1400 if (curline
>= srcContext
->getLineCount ())
1408 if (funcline_visible
)
1410 if (!curr_inc
|| (dbeline
&& curr_inc
!= dbeline
->sourceFile
))
1412 Hist_data::HistItem
*item
= dis_items
->new_hist_item (dbeline
, AT_FUNC
, empty
);
1413 curr_inc
= dbeline
? dbeline
->sourceFile
: srcContext
;
1415 if (curr_inc
!= srcContext
)
1417 char *fileName
= curr_inc
->dbeFile
->getResolvedPath ();
1418 str
= dbe_sprintf (GTXT ("<Function: %s, instructions from source file %s>"),
1419 fitem
->get_name (), fileName
);
1422 str
= dbe_sprintf (GTXT ("<Function: %s>"),
1423 fitem
->get_name ());
1424 item
->value
[name_idx
].l
= str
;
1425 data_items
->append_hist_item (item
);
1429 char *dis_str
= get_disasm (inst_address
, end_address
, start_address
,
1430 fitem
->img_offset
, inst_size
);
1433 else if (instr
->size
== 0)
1434 instr
->size
= (unsigned int) inst_size
;
1435 inst_address
+= inst_size
;
1437 // stomp out control characters
1438 for (size_t i
= 0, len
= strlen (dis_str
); i
< len
; i
++)
1440 if (dis_str
[i
] == '\t')
1444 for (int i
= 0; i
< bTargets
.size (); i
++)
1446 target_info_t
*bTarget
= bTargets
.fetch (i
);
1447 if (bTarget
->offset
== fitem
->img_offset
+ address
)
1449 // insert a new line for the bTarget
1450 size_t colon
= strcspn (dis_str
, NTXT (":"));
1451 char *msg
= GTXT ("* <branch target>");
1452 size_t len
= colon
+ strlen (msg
);
1453 len
= (len
< 50) ? (50 - len
) : 1;
1454 char *new_dis_str
= dbe_sprintf ("%.*s%s%*c <===----<<<",
1455 (int) colon
, dis_str
, msg
,
1457 DbeInstr
*bt
= fitem
->find_dbeinstr (PCTrgtFlag
, address
);
1458 bt
->lineno
= instr
->lineno
;
1460 set_dis (bt
, AT_DIS
, nextFile
, new_dis_str
);
1465 // AnalyzerInfo/Datatype annotations
1466 if (infoList
!= NULL
)
1468 inst_info_t
*info
= NULL
;
1470 Vec_loop (inst_info_t
*, infoList
, pinfo
, info
)
1472 if (info
->offset
== fitem
->img_offset
+ address
) break;
1475 { // got a matching memop
1479 datatype_t
*dtype
= NULL
;
1480 Vec_loop (datatype_t
*, datatypes
, t
, dtype
)
1482 if (dtype
->datatype_id
== info
->memop
->datatype_id
)
1485 if (datatypes
!= NULL
)
1487 size_t len
= strlen (typetag
);
1488 if (dtype
== NULL
|| t
== datatypes
->size ())
1489 snprintf (typetag
+ len
, sizeof (typetag
) - len
, "%s",
1490 PTXT (DOBJ_UNSPECIFIED
));
1491 else if (dtype
->dobj
== NULL
)
1492 snprintf (typetag
+ len
, sizeof (typetag
) - len
, "%s",
1493 PTXT (DOBJ_UNDETERMINED
));
1495 snprintf (typetag
+ len
, sizeof (typetag
) - len
, "%s",
1496 dtype
->dobj
->get_name ());
1498 if (strlen (typetag
) > 1)
1501 new_dis_str
= dbe_sprintf ("%-50s %s", dis_str
, typetag
);
1503 dis_str
= new_dis_str
;
1507 set_dis (instr
, AT_DIS
, nextFile
, dis_str
);
1511 // now flush the left source line, if available
1513 { // source is present
1514 for (; curline
<= srcContext
->getLineCount (); curline
++)
1516 // see if there's a compiler comment line to dump
1517 if (cline
== curline
)
1518 set_ComCom (vis_bits
);
1521 set_src (src_type
, srcContext
->find_dbeline (curline
));
1525 // See if compiler flags are set; if so, append them
1526 if (cmpline_visible
&& comp_flags
)
1528 Hist_data::HistItem
*item
= dis_items
->new_hist_item (NULL
, AT_EMPTY
,
1530 item
->value
[name_idx
].l
= dbe_strdup (NTXT (""));
1531 data_items
->append_hist_item (item
);
1532 item
= dis_items
->new_hist_item (NULL
, AT_COM
, empty
);
1533 item
->value
[name_idx
].l
= dbe_sprintf (GTXT ("Compile flags: %s"),
1535 data_items
->append_hist_item (item
);
1540 // set_src -- inserts one or more lines into the growing data list
1542 Module::set_src (Anno_Types type
, DbeLine
*dbeline
)
1544 Hist_data::HistItem
*item
;
1546 // Flush items that are not represented in source
1547 while (sline
>= 0 && sline
< curline
)
1549 item
= src_items
->fetch (sindex
);
1550 if (((DbeLine
*) item
->obj
)->lineno
> 0)
1551 set_one (item
, AT_QUOTE
, item
->obj
->get_name ());
1553 if (++sindex
< src_items
->size ()) // get next line with metrics
1554 sline
= ((DbeLine
*) src_items
->fetch (sindex
)->obj
)->lineno
;
1559 // write values in the metric fields for the given source line
1560 if (curline
== sline
)
1561 { // got metrics for this line
1562 item
= src_items
->fetch (sindex
);
1563 if (((DbeLine
*) item
->obj
)->lineno
> 0)
1564 set_one (item
, AT_SRC
, srcContext
->getLine (curline
));
1566 if (++sindex
< src_items
->size ()) // get next line metric index
1567 sline
= ((DbeLine
*) src_items
->fetch (sindex
)->obj
)->lineno
;
1573 item
= data_items
->new_hist_item (dbeline
, type
, empty
);
1574 if (size_index
!= -1)
1575 item
->value
[size_index
].ll
= dbeline
->get_size ();
1576 if (addr_index
!= -1)
1577 item
->value
[addr_index
].ll
= dbeline
->get_addr ();
1578 item
->value
[name_idx
].l
= dbe_strdup (srcContext
->getLine (curline
));
1579 data_items
->append_hist_item (item
);
1584 Module::set_dis (DbeInstr
*instr
, Anno_Types type
, bool nextFile
, char *dis_str
)
1586 // Flush items that are not represented in disassembly
1587 while (daddr
&& daddr
->pc_cmp (instr
) < 0)
1590 set_one (dis_items
->fetch (dindex
), AT_QUOTE
, daddr
->get_name ());
1591 if (++dindex
< dis_items
->size ()) // get next line metric index
1592 daddr
= (DbeInstr
*) dis_items
->fetch (dindex
)->obj
;
1597 // Write values in the metric fields for the given pc index value
1598 if (instr
->inlinedInd
>= 0)
1601 sb
.append (dis_str
);
1602 instr
->add_inlined_info (&sb
);
1604 dis_str
= sb
.toString ();
1606 if (daddr
&& daddr
->pc_cmp (instr
) == 0)
1608 Hist_data::HistItem
*item
= data_items
->new_hist_item (instr
, type
,
1609 dis_items
->fetch (dindex
)->value
);
1610 item
->value
[name_idx
].tag
= VT_LABEL
;
1611 item
->value
[name_idx
].l
= dis_str
;
1612 data_items
->append_hist_item (item
);
1613 if (dis_items
->get_callsite_mark ()->get (dis_items
->fetch (dindex
)->obj
))
1614 data_items
->get_callsite_mark ()->put (item
->obj
, 1);
1616 if (++dindex
< dis_items
->size ()) // get next line metric index
1617 daddr
= (DbeInstr
*) dis_items
->fetch (dindex
)->obj
;
1623 // create a new item for this PC
1624 Hist_data::HistItem
*item
= dis_items
->new_hist_item (instr
, type
, empty
);
1625 if (size_index
!= -1)
1626 item
->value
[size_index
].ll
= instr
->size
;
1627 if (addr_index
!= -1)
1628 item
->value
[addr_index
].ll
= instr
->get_addr ();
1629 item
->value
[name_idx
].tag
= VT_LABEL
;
1630 item
->value
[name_idx
].l
= dis_str
;
1631 data_items
->append_hist_item (item
);
1636 Module::set_MPSlave ()
1638 Hist_data::HistItem
*item
;
1642 // write the inclusive metrics for slave threads
1643 while (mline
== curline
)
1645 item
= dis_items
->fetch (mindex
);
1646 DbeInstr
*instr
= (DbeInstr
*) item
->obj
;
1647 Vec_loop (Function
*, functions
, index
, fp
)
1649 if (fp
->derivedNode
== instr
)
1651 set_one (item
, AT_QUOTE
, (fp
->isOutlineFunction
) ?
1652 GTXT ("<inclusive metrics for outlined functions>") :
1653 GTXT ("<inclusive metrics for slave threads>"));
1659 if (mindex
< dis_items
->size ())
1660 mline
= (unsigned) ((DbeInstr
*) (dis_items
->fetch (mindex
)->obj
))->addr
;
1667 Module::set_one (Hist_data::HistItem
*org_item
, Anno_Types type
,
1670 if (org_item
== NULL
)
1672 Hist_data::HistItem
*item
= data_items
->new_hist_item (org_item
->obj
, type
,
1674 item
->value
[name_idx
].tag
= VT_LABEL
;
1675 item
->value
[name_idx
].l
= dbe_strdup (text
);
1676 data_items
->append_hist_item (item
);
1677 if (org_item
!= NULL
&& src_items
!= NULL
1678 && src_items
->get_callsite_mark ()->get (org_item
->obj
))
1679 data_items
->get_callsite_mark ()->put (item
->obj
, 1);
1683 Module::set_ComCom (int vis_bits
)
1685 Hist_data::HistItem
*item
;
1686 Function
*func
= dbeSession
->get_Unknown_Function ();
1690 // precede the compiler commentary with a blank line
1691 item
= data_items
->new_hist_item (func
, AT_EMPTY
, empty
);
1692 item
->value
[name_idx
].l
= dbe_strdup (NTXT (""));
1693 data_items
->append_hist_item (item
);
1695 while (cline
== curline
)
1697 ComC
*comm
= comComs
->fetch (cindex
);
1698 if (comm
->visible
& vis_bits
)
1700 // write the compiler commentary
1701 item
= data_items
->new_hist_item (func
, AT_COM
, empty
);
1702 item
->value
[name_idx
].l
= dbe_strdup (comm
->com_str
);
1703 data_items
->append_hist_item (item
);
1705 if (++cindex
< comComs
->size ())
1706 cline
= comComs
->fetch (cindex
)->line
;
1713 Module::dump_dataobjects (FILE *out
)
1717 Vec_loop (datatype_t
*, datatypes
, index
, dtype
)
1719 fprintf (out
, NTXT ("[0x%08X,%6lld] %4d %6d %s "), dtype
->datatype_id
,
1720 dtype
->dobj
? dtype
->dobj
->id
: 0LL,
1721 dtype
->memop_refs
, dtype
->event_data
,
1722 (dtype
->dobj
!= NULL
? (dtype
->dobj
->get_name () ?
1723 dtype
->dobj
->get_name () : "<NULL>") : "<no object>"));
1725 Histable
* scope
= dtype
->dobj
? dtype
->dobj
->get_scope () : NULL
;
1728 switch (scope
->get_type ())
1730 case Histable::LOADOBJECT
:
1731 case Histable::FUNCTION
:
1732 fprintf (out
, NTXT ("%s"), scope
->get_name ());
1734 case Histable::MODULE
:
1736 char *filename
= get_basename (scope
->get_name ());
1737 fprintf (out
, NTXT ("%s"), filename
);
1741 fprintf (out
, NTXT ("\tUnexpected scope %d:%s"),
1742 scope
->get_type (), scope
->get_name ());
1746 fprintf (out
, NTXT ("\n"));
1751 Module::set_name (char *str
)
1758 Module::read_hwcprof_info ()
1763 Stabs
*stabs
= openDebugInfo ();
1765 stabs
->read_hwcprof_info (this);
1770 Module::reset_datatypes ()
1772 for (int i
= 0, sz
= datatypes
? datatypes
->size () : -1; i
< sz
; i
++)
1774 datatype_t
*t
= datatypes
->fetch (i
);
1780 Module::get_dobj (uint32_t dtype_id
)
1782 read_hwcprof_info ();
1783 for (int i
= 0, sz
= datatypes
? datatypes
->size () : -1; i
< sz
; i
++)
1785 datatype_t
*t
= datatypes
->fetch (i
);
1786 if (t
->datatype_id
== dtype_id
)
1802 Module::get_comparable_objs ()
1804 update_comparable_objs ();
1805 if (comparable_objs
|| dbeSession
->expGroups
->size () <= 1 || loadobject
== NULL
)
1806 return comparable_objs
;
1807 Vector
<Histable
*> *comparableLoadObjs
= loadobject
->get_comparable_objs ();
1808 if (comparableLoadObjs
== NULL
)
1810 comparable_objs
= new Vector
<Histable
*>(comparableLoadObjs
->size ());
1811 for (int i
= 0, sz
= comparableLoadObjs
->size (); i
< sz
; i
++)
1814 LoadObject
*lo
= (LoadObject
*) comparableLoadObjs
->fetch (i
);
1817 mod
= lo
->get_comparable_Module (this);
1819 mod
->comparable_objs
= comparable_objs
;
1821 comparable_objs
->store (i
, mod
);
1823 dump_comparable_objs ();
1824 return comparable_objs
;
1828 Module::find_jmethod (const char *nm
, const char *sig
)
1830 // Vladimir: Probably we should not use linear search
1831 for (long i
= 0, sz
= VecSize (functions
); i
< sz
; i
++)
1833 JMethod
*jmthd
= (JMethod
*) functions
->get (i
);
1834 char *jmt_name
= jmthd
->get_name (Histable::SHORT
);
1835 if (strcmp (jmt_name
, nm
) == 0
1836 && strcmp (jmthd
->get_signature (), sig
) == 0)