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. */
22 #include <sys/param.h>
27 #include "DbeSession.h"
28 #include "Experiment.h"
31 #include "LoadObject.h"
36 #include "StringBuilder.h"
39 Experiment::mrec_insert (MapRecord
*mrec
)
41 int sz
= mrecs
->size ();
42 MapRecord
*tmp
= sz
> 0 ? mrecs
->fetch (sz
- 1) : NULL
;
44 // The following should work in most cases
45 if (tmp
== NULL
|| tmp
->ts
<= mrec
->ts
)
56 int md
= (lo
+ hi
) / 2;
57 tmp
= mrecs
->fetch (md
);
58 if (tmp
->ts
< mrec
->ts
)
63 mrecs
->insert (lo
, mrec
);
67 Experiment::process_arglist_cmd (char *, char *arglist
)
71 // find argv[0], and extract its basename
72 if (strcmp (uarglist
, NTXT ("(fork)")) == 0)
73 return 0; // leaving target name NULL
81 if (*p
== ' ' || *p
== 0)
90 utargname
= dbe_sprintf (NTXT ("%.*s"), (int) len
, pp
);
95 Experiment::process_desc_start_cmd (char *, hrtime_t ts
, char *flavor
,
96 char *nexp
, int follow
, char *txt
)
102 str
= dbe_sprintf (GTXT ("Starting %s %ld.%09ld, exp %s.er, \"%s\""),
103 flavor
, (long) (ts
/ NANOSEC
), (long) (ts
% NANOSEC
),
106 str
= dbe_sprintf (GTXT ("Starting %s %ld.%09ld, no experiment, \"%s\""),
107 flavor
, (long) (ts
/ NANOSEC
), (long) (ts
% NANOSEC
),
109 m
= new Emsg (CMSG_COMMENT
, str
);
120 Experiment::process_desc_started_cmd (char *, hrtime_t ts
, char *flavor
,
121 char *nexp
, int follow
, char *txt
)
127 str
= dbe_sprintf (GTXT ("Started %s %ld.%09ld, exp %s.er, \"%s\""),
128 flavor
, (long) (ts
/ NANOSEC
), (long) (ts
% NANOSEC
),
131 str
= dbe_sprintf (GTXT ("Started %s %ld.%09ld, no experiment, \"%s\""),
132 flavor
, (long) (ts
/ NANOSEC
), (long) (ts
% NANOSEC
),
134 m
= new Emsg (CMSG_COMMENT
, str
);
144 Experiment::get_dynfunc_lo (const char *loName
)
146 LoadObject
*lo
= loadObjMap
->get (loName
);
149 lo
= createLoadObject (loName
, expIdx
);// DYNFUNC_SEGMENT is always unique
150 lo
->dbeFile
->filetype
|= DbeFile::F_FICTION
;
151 lo
->flags
|= SEG_FLAG_DYNAMIC
;
152 lo
->type
= LoadObject::SEG_TEXT
;
153 lo
->set_platform (platform
, wsize
);
160 Experiment::create_dynfunc (Module
*mod
, char *fname
, int64_t vaddr
,
163 Function
*f
= dbeSession
->createFunction ();
165 f
->flags
|= FUNC_FLAG_DYNAMIC
;
167 f
->img_offset
= vaddr
;
169 mod
->functions
->append (f
);
170 mod
->loadobject
->functions
->append (f
);
175 func_cmp (const void *a
, const void *b
)
177 Function
*fp1
= *((Function
**) a
);
178 Function
*fp2
= *((Function
**) b
);
179 uint64_t i1
= fp1
->img_offset
;
180 uint64_t i2
= fp2
->img_offset
;
181 return i1
< i2
? -1 : i1
== i2
? 0 : 1;
185 Experiment::process_fn_load_cmd (Module
*mod
, char *fname
, Vaddr vaddr
,
186 int fsize
, hrtime_t ts
)
189 "process_fn_load_cmd:%s (%s) vaddr=0x%llx msize=%lld ts=%lld\n",
190 STR (mod
? mod
->get_name () : NULL
), STR (fname
),
191 (unsigned long long) vaddr
, (long long) fsize
, (long long) ts
);
194 mod
->functions
->sort (func_cmp
);
195 uint64_t lastVaddr
= vaddr
;
196 for (int i
= 0, sz
= mod
->functions
->size (); i
< sz
; i
++)
198 Function
*f
= mod
->functions
->fetch (i
);
199 if (lastVaddr
< f
->img_offset
)
201 char *fnm
= dbe_sprintf (GTXT ("<static>@0x%llx (%s)"),
202 (unsigned long long) lastVaddr
, fname
);
203 create_dynfunc (mod
, fnm
, lastVaddr
, f
->img_offset
- lastVaddr
);
206 lastVaddr
= f
->img_offset
+ f
->size
;
208 if (lastVaddr
< vaddr
+ fsize
)
210 char *fnm
= dbe_sprintf (GTXT ("<static>@0x%llx (%s)"),
211 (unsigned long long) lastVaddr
, fname
);
212 create_dynfunc (mod
, fnm
, lastVaddr
, vaddr
+ fsize
- lastVaddr
);
215 mod
->functions
->sort (func_cmp
);
216 for (int i
= 0, sz
= mod
->functions
->size (); i
< sz
; i
++)
218 Function
*f
= mod
->functions
->fetch (i
);
219 MapRecord
*mrec
= new MapRecord
;
220 mrec
->kind
= MapRecord::LOAD
;
222 mrec
->base
= f
->img_offset
;
223 mrec
->size
= f
->size
;
231 LoadObject
*ds
= get_dynfunc_lo (DYNFUNC_SEGMENT
);
232 Function
*dfunc
= create_dynfunc (ds
->noname
, fname
, vaddr
, fsize
);
234 // check for special functions, USER, IDLE, TRUNC to disable offsets in disassembly
235 // XXX -- check based on name now
236 // Optimization: use pre-initialized localized strings
237 static const char * localized_USER_MODE
= NULL
;
238 static const char * localized_IDLE
= NULL
;
239 static const char * localized_TRUNCATED_STACK
= NULL
;
240 if (localized_USER_MODE
== NULL
)
242 localized_USER_MODE
= GTXT ("<USER_MODE>");
243 localized_IDLE
= GTXT ("<IDLE>");
244 localized_TRUNCATED_STACK
= GTXT ("<TRUNCATED_STACK>");
246 if (strcmp (fname
, localized_USER_MODE
) == 0
247 || strcmp (fname
, localized_IDLE
) == 0
248 || strcmp (fname
, localized_TRUNCATED_STACK
) == 0)
249 dfunc
->flags
|= FUNC_FLAG_NO_OFFSET
;
251 MapRecord
*mrec
= new MapRecord
;
252 mrec
->kind
= MapRecord::LOAD
;
263 Experiment::process_fn_unload_cmd (char *, Vaddr vaddr
, hrtime_t ts
)
265 MapRecord
*mrec
= new MapRecord
;
266 mrec
->kind
= MapRecord::UNLOAD
;
274 Experiment::register_metric (Metric::Type type
)
276 BaseMetric
*mtr
= dbeSession
->register_metric (type
);
277 metrics
->append (mtr
);
281 Experiment::register_metric (Hwcentry
*ctr
, const char* aux
, const char* uname
)
283 BaseMetric
*mtr
= dbeSession
->register_metric (ctr
, aux
, uname
);
284 metrics
->append (mtr
);
285 if (mtr
->get_dependent_bm ())
286 metrics
->append (mtr
->get_dependent_bm ());
290 Experiment::process_hwcounter_cmd (char *, int cpuver
, char *counter
,
291 char * int_name
, int interval
, int tag
,
292 int i_tpc
, char *modstr
)
297 ABST_type tpc
= (ABST_type
) i_tpc
;
299 // Use previously ignored tag to associate counter packets.
300 if (tag
< 0 || tag
>= MAX_HWCOUNT
)
302 // invalid tag specified, warn user
303 str
= dbe_sprintf (GTXT ("*** Error: HW counter tag %d out of range [%d - %d]; ignored"),
304 tag
, 0, MAX_HWCOUNT
- 1);
305 m
= new Emsg (CMSG_ERROR
, str
);
311 if (coll_params
.hw_aux_name
[tag
])
313 // duplicate tag used, warn user
314 str
= dbe_sprintf (GTXT ("*** Error: Duplicate HW counter tag %d specified; ignored"),
316 m
= new Emsg (CMSG_ERROR
, str
);
324 // map it to a machinemodel string
325 if (hw_cpuver
!= CPUVER_UNDEFINED
)
328 if (hw_cpuver
== 1104)
329 machinemodel
= dbe_strdup (NTXT ("t4"));
330 else if (hw_cpuver
== 1110)
331 machinemodel
= dbe_strdup (NTXT ("t5"));
332 else if (hw_cpuver
== 1204)
333 machinemodel
= dbe_strdup (NTXT ("m4"));
334 else if (hw_cpuver
== 1210)
335 machinemodel
= dbe_strdup (NTXT ("m5"));
336 else if (hw_cpuver
== 1220)
337 machinemodel
= dbe_strdup (NTXT ("m6"));
338 else if (hw_cpuver
== 1230)
339 machinemodel
= dbe_strdup (NTXT ("m7"));
341 machinemodel
= dbe_strdup (NTXT ("generic"));
344 // Find the entry in the machine table, and dup it
346 dbeSession
->append (ctr
);
347 hwc_post_lookup (ctr
, counter
, int_name
, cpuver
);
348 ctr
->sort_order
= tag
;
351 // Check if HWC name is to be modified
355 ctr
->name
= dbe_sprintf (NTXT ("%s%s"), modstr
, s
);
357 ctr
->int_name
= dbe_sprintf (NTXT ("%s%s"), modstr
, s
);
360 ctr
->metric
= dbe_sprintf (NTXT ("%s%s"), modstr
, s
);
363 char * cname
= dbe_strdup (ctr
->name
);
364 char * uname
= dbe_strdup (hwc_i18n_metric (ctr
));
365 coll_params
.hw_aux_name
[tag
] = cname
;
366 coll_params
.hw_username
[tag
] = uname
;
367 coll_params
.hw_interval
[tag
] = interval
;
368 coll_params
.hw_tpc
[tag
] = tpc
;
369 coll_params
.hw_cpu_ver
[tag
] = cpuver
;
371 // set hw_mode and xhw_mode?
372 coll_params
.hw_mode
= 1;
373 if (ABST_MEMSPACE_ENABLED (tpc
))
375 // yes, dataspace data available
376 coll_params
.xhw_mode
= 1;
378 // set dataspace available
379 dataspaceavail
= true;
381 register_metric (ctr
, cname
, uname
);
389 Experiment::process_hwsimctr_cmd (char *, int cpuver
, char *nm
, char *int_name
,
390 char *metric
, int reg
,
391 int interval
, int timecvt
, int i_tpc
, int tag
)
396 ABST_type tpc
= (ABST_type
) i_tpc
;
398 // Use previously ignored tag to associate counter packets.
399 if (tag
< 0 || tag
>= MAX_HWCOUNT
)
401 // invalid tag specified, warn user
402 str
= dbe_sprintf (GTXT ("*** Error: HW counter tag %d out of range [%d - %d]; ignored"),
403 tag
, 0, MAX_HWCOUNT
- 1);
404 m
= new Emsg (CMSG_ERROR
, str
);
413 if (coll_params
.hw_aux_name
[tag
])
415 // duplicate tag used, warn user
416 str
= dbe_sprintf (GTXT ("*** Error: Duplicate HW counter tag %d specified; ignored"),
418 m
= new Emsg (CMSG_ERROR
, str
);
429 static Hwcentry empty
;
433 ctr
->int_name
= int_name
;
434 ctr
->metric
= metric
;
437 ctr
->timecvt
= timecvt
;
439 ctr
->sort_order
= tag
;
441 char *cname
= dbe_strdup (ctr
->name
);
442 char *uname
= dbe_strdup (hwc_i18n_metric (ctr
));
444 coll_params
.hw_aux_name
[tag
] = cname
;
445 coll_params
.hw_username
[tag
] = uname
;
446 coll_params
.hw_interval
[tag
] = interval
;
447 coll_params
.hw_tpc
[tag
] = tpc
;
448 coll_params
.hw_cpu_ver
[tag
] = cpuver
;
450 // set hw_mode and xhw_mode?
451 coll_params
.hw_mode
= 1;
452 if (ABST_MEMSPACE_ENABLED (tpc
))
454 coll_params
.xhw_mode
= 1;
455 // set dataspace available
456 if (getenv ("ANALYZER_DATASPACE_COUNT") != 0)
457 dataspaceavail
= true;
460 register_metric (ctr
, cname
, uname
);
465 Experiment::process_jcm_load_cmd (char *, Vaddr mid
, Vaddr vaddr
,
466 int msize
, hrtime_t ts
)
471 JMethod
*jfunc
= (JMethod
*) jmaps
->locate_exact_match (mid
, ts
);
472 if (jfunc
== NULL
|| jfunc
->get_type () != Histable::FUNCTION
)
475 LoadObject
*ds
= get_dynfunc_lo (JAVA_COMPILED_METHODS
);
476 Module
*jmodule
= jfunc
->module
;
477 Module
*dmodule
= ds
->noname
;
480 dmodule
= dbeSession
->createModule (ds
, jmodule
->get_name ());
481 dmodule
->lang_code
= Sp_lang_java
;
482 dmodule
->set_file_name (dbe_strdup (jmodule
->file_name
));
485 JMethod
*dfunc
= dbeSession
->createJMethod ();
486 dfunc
->flags
|= FUNC_FLAG_DYNAMIC
;
488 dfunc
->module
= dmodule
;
489 dfunc
->usrfunc
= jfunc
;
490 dfunc
->set_addr (vaddr
);
491 dfunc
->set_mid (mid
);
492 dfunc
->set_signature (jfunc
->get_signature ());
493 dfunc
->set_name (jfunc
->get_mangled_name ());
494 ds
->functions
->append (dfunc
);
495 dmodule
->functions
->append (dfunc
);
496 MapRecord
*mrec
= new MapRecord
;
497 mrec
->kind
= MapRecord::LOAD
;
508 Experiment::process_jcm_unload_cmd (char *, Vaddr
/*mid*/, hrtime_t
/*ts*/)
513 // We are ignoring this record because of the flaw in
514 // JVMPI desing that doesn't distinguish between two or more
515 // compiled instances of a method when an unload event is
517 // JVMPI_COMPILED_METHOD_LOAD( mid, addr1, ... )
518 // JVMPI_COMPILED_METHOD_LOAD( mid, addr2, ... )
519 // JVMPI_COMPILED_METHOD_UNLOAD( mid ) -- which one?
520 // We rely on the ability of the PRBTree algorithms to
521 // perform mapping appropriately based on timestamps.
526 Experiment::process_jthr_end_cmd (char *, uint64_t tid64
, Vaddr jthr
,
527 Vaddr jenv
, hrtime_t ts
)
530 int rt
= jthreads_idx
->size () - 1;
531 uint32_t ttid
= mapTagValue (PROP_THRID
, tid64
);
534 int md
= (lt
+ rt
) / 2;
535 JThread
*jthread
= jthreads_idx
->fetch (md
);
536 if (jthread
->tid
< ttid
)
538 else if (jthread
->tid
> ttid
)
542 for (; jthread
; jthread
= jthread
->next
)
544 if (jthread
->jenv
== jenv
)
553 JThread
*jthread
= new JThread
;
554 jthread
->tid
= mapTagValue (PROP_THRID
, tid64
);
555 jthread
->jthr
= jthr
;
556 jthread
->jenv
= jenv
;
557 jthread
->jthr_id
= jthreads
->size ();
558 jthread
->start
= ZERO_TIME
;
560 jthread
->next
= NULL
;
561 jthreads
->append (jthread
);
562 if (lt
== jthreads_idx
->size ())
563 jthreads_idx
->append (jthread
);
565 jthreads_idx
->insert (lt
, jthread
);
570 Experiment::process_jthr_start_cmd (char *, char *thread_name
, char *group_name
,
571 char *parent_name
, uint64_t tid64
,
572 Vaddr jthr
, Vaddr jenv
, hrtime_t ts
)
574 JThread
*jthread
= new JThread
;
575 jthread
->name
= thread_name
;
576 jthread
->group_name
= group_name
;
577 jthread
->parent_name
= parent_name
;
578 jthread
->tid
= mapTagValue (PROP_THRID
, tid64
);
579 jthread
->jthr
= jthr
;
580 jthread
->jenv
= jenv
;
581 jthread
->jthr_id
= jthreads
->size ();
583 jthread
->end
= MAX_TIME
;
584 jthread
->next
= NULL
;
586 jthreads
->append (jthread
);
589 int rt
= jthreads_idx
->size () - 1;
592 int md
= (lt
+ rt
) / 2;
593 JThread
*jtmp
= jthreads_idx
->fetch (md
);
594 if (jtmp
->tid
< jthread
->tid
)
596 else if (jtmp
->tid
> jthread
->tid
)
600 jthread
->next
= jtmp
;
601 jthreads_idx
->store (md
, jthread
);
605 if (lt
== jthreads_idx
->size ())
606 jthreads_idx
->append (jthread
);
608 jthreads_idx
->insert (lt
, jthread
);
613 Experiment::process_gc_end_cmd (
616 if (gcevents
->size () == 0)
618 GCEvent
*gcevent
= new GCEvent
;
619 gcevent
->start
= ZERO_TIME
;
621 gcevent
->id
= gcevents
->size () + 1;
622 gcevents
->append (gcevent
);
625 GCEvent
*gcevent
= gcevents
->fetch (gcevents
->size () - 1);
626 if (gcevent
->end
== MAX_TIME
)
629 // Weird: gc_end followed by another gc_end
630 gcevent
->end
= ts
; // extend the previous event
635 Experiment::process_gc_start_cmd (
638 if (gcevents
->size () != 0)
640 GCEvent
*gcevent
= gcevents
->fetch (gcevents
->size () - 1);
641 // Weird: gc_start followed by another gc_start
642 if (gcevent
->end
== MAX_TIME
)
643 return 0; // ignore nested gc_starts
645 GCEvent
*gcevent
= new GCEvent
;
647 gcevent
->end
= MAX_TIME
;
648 gcevent
->id
= gcevents
->size () + 1;
649 gcevents
->append (gcevent
);
654 Experiment::process_sample_cmd (char */
*cmd*/
, hrtime_t
/*log_xml_time*/,
655 int sample_number
, char *label
)
657 // sample 0 is not a sample but the starting point
658 if (sample_number
== 0)
660 first_sample_label
= label
;
663 Sample
*prev_sample
= samples
->size () > 0 ?
664 samples
->fetch (samples
->size () - 1) : NULL
;
665 char *start_lable
= prev_sample
?
666 prev_sample
->end_label
: first_sample_label
;
667 Sample
*sample
= new Sample (sample_number
);
668 sample
->start_label
= dbe_strdup (start_lable
);
669 sample
->end_label
= label
;
670 samples
->append (sample
);
675 Experiment::process_sample_sig_cmd (char *, int sig
)
679 str
= dbe_sprintf (GTXT ("Sample signal %d"), sig
);
680 m
= new Emsg (CMSG_COMMENT
, str
);
687 Experiment::process_seg_map_cmd (char */
*cmd*/
, hrtime_t ts
, Vaddr vaddr
,
688 int mapsize
, int /*pagesize*/, int64_t offset
,
689 int64_t modeflags
, int64_t chk
, char *nm
)
692 strncmp (nm
+ 1, SP_MAP_UNRESOLVABLE
, strlen (SP_MAP_UNRESOLVABLE
)) == 0)
695 LoadObject
*lo
= loadObjMap
->get (nm
);
700 char *archName
= checkFileInArchive (nm
, false);
703 Elf
*elf
= new Elf (archName
);
704 if (elf
->status
== Elf::ELF_ERR_NONE
)
706 chk
= elf
->elf_checksum ();
712 lo
= dbeSession
->find_lobj_by_name (nm
, chk
);
715 // Skip non-text segments
716 if (modeflags
!= (PROT_READ
| PROT_EXEC
))
719 lo
= createLoadObject (nm
, chk
);
720 if (strstr (nm
, NTXT ("libjvm.so")))
722 lo
->flags
|= SEG_FLAG_JVM
;
723 // Make sure <JVM-System> is created
724 (void) dbeSession
->get_jvm_Function ();
726 else if (strstr (nm
, NTXT ("libmtsk.so")))
728 lo
->flags
|= SEG_FLAG_OMP
;
729 // Make sure all pseudo functions are created
730 for (int i
= 0; i
< OMP_LAST_STATE
; i
++)
731 (void) dbeSession
->get_OMP_Function (i
);
733 else if (dbe_strcmp (utargname
, get_basename (nm
)) == 0)
735 lo
->flags
|= SEG_FLAG_EXE
;
736 (void) dbeSession
->comp_lobjs
->get ((char *) COMP_EXE_NAME
, lo
);
739 // This is the default segment type
740 lo
->type
= LoadObject::SEG_TEXT
;
741 lo
->flags
= lo
->flags
| SEG_FLAG_REORDER
;
742 lo
->set_platform (platform
, wsize
);
744 if (lo
->dbeFile
->get_location (false) == NULL
)
746 char *archName
= checkFileInArchive (nm
, false);
749 lo
->dbeFile
->set_location (archName
);
750 lo
->dbeFile
->inArchive
= true;
751 lo
->dbeFile
->check_access (archName
); // init 'sbuf'
752 lo
->dbeFile
->sbuf
.st_mtime
= 0; // Don't check timestamps
757 archName
= checkFileInArchive (nm
, true);
760 lo
->set_archname (archName
);
761 lo
->need_swap_endian
= need_swap_endian
;
764 if (!dbeSession
->archive_mode
)
765 lo
->sync_read_stabs ();
771 MapRecord
*mrec
= new MapRecord
;
772 mrec
->kind
= MapRecord::LOAD
;
775 mrec
->size
= mapsize
;
783 Experiment::process_seg_unmap_cmd (char */
*cmd*/
, hrtime_t ts
, Vaddr vaddr
)
785 MapRecord
*mrec
= new MapRecord
;
786 mrec
->kind
= MapRecord::UNLOAD
;
794 strstarts (const char *var
, const char *x
)
796 return strncmp (var
, x
, strlen (x
)) == 0;
800 Experiment::process_Linux_kernel_cmd (hrtime_t ts
)
802 LoadObject
*lo
= createLoadObject ("LinuxKernel");
803 lo
->flags
|= SEG_FLAG_EXE
;
804 lo
->type
= LoadObject::SEG_TEXT
;
805 lo
->set_platform (platform
, wsize
);
807 long long unsigned lo_min
= (long long unsigned) (-1);
808 long long unsigned lo_max
= 0;
809 Module
*mod
= dbeSession
->createModule (lo
, "LinuxKernel");
811 * XXX need to review mod initialization
812 * A specific issue is mod->file_name. Options include:
814 * This leads to seg faults in, e.g., Timeline view.
815 * *) "/lib/modules/$(uname -r)/kernel/kernel/ctf/ctf.ko"
816 * This leads to garbage in the Source view.
817 * *) "/boot/vmlinuz-$(uname -r)"
818 * This cannot be parsed for DWARF and is sometimes not found,
819 * but the Analyzer seems to handle such problems.
821 * This is not a proper file name,
822 * but again Analyzer handles the case of not finding the file or not reading DWARF from it.
824 mod
->set_file_name (dbe_strdup ("LinuxKernel"));
825 char kallmodsyms_copy
[MAXPATHLEN
];
826 snprintf (kallmodsyms_copy
, sizeof (kallmodsyms_copy
), "%s/kallmodsyms",
828 FILE *fd
= fopen (kallmodsyms_copy
, "r");
831 char *s
= dbe_sprintf (GTXT ("*** Error: Cannot find kernel module symbols file %s; ignored"),
833 Emsg
*m
= new Emsg (CMSG_ERROR
, s
);
842 while (getline (&line
, &line_n
, fd
) > 0)
844 long long unsigned sym_addr
;
845 long long unsigned sym_size
;
849 char mod_name
[256] = "vmlinux]"; /* note trailing ] */
850 sscanf (line
, "%llx %llx %c %s [%s", &sym_addr
, &sym_size
, &sym_type
,
852 if (line
[0] == '\n' || line
[0] == 0)
854 sym_text
= (sym_type
== 't' || sym_type
== 'T');
855 mod_name
[strlen (mod_name
) - 1] = '\0'; /* chop trailing ] */
856 if (strcmp (mod_name
, "ctf") == 0)
857 strcpy (mod_name
, "shared_ctf");
859 if (strcmp (sym_name
, "__per_cpu_start") == 0
860 || strcmp (sym_name
, "__per_cpu_end") == 0
861 || strstarts (sym_name
, "__crc_")
862 || strstarts (sym_name
, "__ksymtab_")
863 || strstarts (sym_name
, "__kcrctab_")
864 || strstarts (sym_name
, "__kstrtab_")
865 || strstarts (sym_name
, "__param_")
866 || strstarts (sym_name
, "__syscall_meta__")
867 || strstarts (sym_name
, "__p_syscall_meta__")
868 || strstarts (sym_name
, "__event_")
869 || strstarts (sym_name
, "event_")
870 || strstarts (sym_name
, "ftrace_event_")
871 || strstarts (sym_name
, "types__")
872 || strstarts (sym_name
, "args__")
873 || strstarts (sym_name
, "__tracepoint_")
874 || strstarts (sym_name
, "__tpstrtab_")
875 || strstarts (sym_name
, "__tpstrtab__")
876 || strstarts (sym_name
, "__initcall_")
877 || strstarts (sym_name
, "__setup_")
878 || strstarts (sym_name
, "__pci_fixup_")
879 || strstarts (sym_name
, "__dta_")
880 || strstarts (sym_name
, "__dtrace_probe_")
881 || (strstr (sym_name
, ".") != NULL
882 && strstr (sym_name
, ".clone.") == NULL
))
888 sb
.appendf ("%s`%s", mod_name
, sym_name
);
889 char *fname
= sb
.toString ();
890 Function
*func
= dbeSession
->createFunction ();
891 func
->set_name (fname
);
893 func
->size
= sym_size
;
894 func
->img_offset
= sym_addr
;
896 lo
->functions
->append (func
);
897 mod
->functions
->append (func
);
898 if (lo_min
> sym_addr
)
900 if (lo_max
< sym_addr
+ sym_size
)
901 lo_max
= sym_addr
+ sym_size
;
908 lo
->functions
->sort (func_cmp
);
909 mod
->functions
->sort (func_cmp
);
911 MapRecord
*mrec
= new MapRecord
;
912 mrec
->kind
= MapRecord::LOAD
;
915 mrec
->size
= lo_max
- lo_min
;