diff options
-rw-r--r-- | bfd/version.h | 2 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 13 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/fixed_points.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb | 7 | ||||
-rw-r--r-- | gprofng/common/gp-experiment.h | 62 | ||||
-rw-r--r-- | gprofng/libcollector/collector.c | 48 | ||||
-rw-r--r-- | gprofng/libcollector/descendants.h | 14 | ||||
-rw-r--r-- | gprofng/libcollector/envmgmt.c | 3 | ||||
-rw-r--r-- | gprofng/libcollector/linetrace.c | 4 | ||||
-rw-r--r-- | gprofng/src/Dwarf.cc | 205 | ||||
-rw-r--r-- | gprofng/src/Dwarf.h | 2 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.cc | 79 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.h | 15 | ||||
-rw-r--r-- | gprofng/src/LoadObject.cc | 18 | ||||
-rw-r--r-- | gprofng/src/Makefile.am | 1 | ||||
-rw-r--r-- | gprofng/src/Makefile.in | 4 | ||||
-rw-r--r-- | gprofng/src/Stabs.cc | 166 | ||||
-rw-r--r-- | gprofng/src/Stabs.h | 5 | ||||
-rw-r--r-- | gprofng/src/Symbol.cc | 226 | ||||
-rw-r--r-- | gprofng/src/Symbol.h | 80 | ||||
-rw-r--r-- | gprofng/src/collect.h | 1 | ||||
-rw-r--r-- | gprofng/src/envsets.cc | 10 | ||||
-rw-r--r-- | gprofng/src/gp-collect-app.cc | 2 | ||||
-rw-r--r-- | gprofng/src/ipcio.cc | 5 |
24 files changed, 629 insertions, 347 deletions
diff --git a/bfd/version.h b/bfd/version.h index d8c882e..a28cdf3 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250504 +#define BFD_VERSION_DATE 20250506 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 6848f63..f90b227 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -13165,7 +13165,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu) a given gmp_mpz given an attribute. */ static void -get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) +get_mpz_for_rational (dwarf2_cu *cu, gdb_mpz *value, attribute *attr) { /* GCC will sometimes emit a 16-byte constant value as a DWARF location expression that pushes an implicit value. */ @@ -13199,10 +13199,11 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE, true); } - else if (attr->form_is_strictly_unsigned ()) - *value = gdb_mpz (attr->as_unsigned ()); else - *value = gdb_mpz (attr->signed_constant ().value_or (1)); + { + /* Rational constants for Ada are always unsigned. */ + *value = gdb_mpz (attr->unsigned_constant ().value_or (1)); + } } /* Assuming DIE is a rational DW_TAG_constant, read the DIE's @@ -13231,8 +13232,8 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu, if (num_attr == nullptr || denom_attr == nullptr) return; - get_mpz (cu, numerator, num_attr); - get_mpz (cu, denominator, denom_attr); + get_mpz_for_rational (cu, numerator, num_attr); + get_mpz_for_rational (cu, denominator, denom_attr); } /* Same as get_dwarf2_rational_constant, but extracting an unsigned diff --git a/gdb/testsuite/gdb.ada/fixed_points.exp b/gdb/testsuite/gdb.ada/fixed_points.exp index 8bb9e10..0e65004 100644 --- a/gdb/testsuite/gdb.ada/fixed_points.exp +++ b/gdb/testsuite/gdb.ada/fixed_points.exp @@ -90,6 +90,10 @@ foreach_gnat_encoding scenario flags {all minimal} { # This only started working in GCC 11. if {$scenario == "minimal" && [gnat_version_compare >= 11]} { gdb_test "print fp5_var" " = 3e-19" + + gdb_test "print Float(Object_Fixed) = Float(Semicircle_Delta * 5)" \ + " = true" \ + "examine object_fixed" } # This failed before GCC 10. diff --git a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb index adab614..94a41b9 100644 --- a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb +++ b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb @@ -64,6 +64,12 @@ procedure Fixed_Points is for Another_Type'size use 64; Another_Fixed : Another_Type := Another_Delta * 5; + Semicircle_Delta : constant := 1.0/(2**31); + type Semicircle_Type is delta Semicircle_Delta range -1.0 .. (1.0 - Semicircle_Delta); + for Semicircle_Type'small use Semicircle_Delta; + for Semicircle_Type'size use 32; + Object_Fixed : Semicircle_Type := Semicircle_Delta * 5; + begin Base_Object := 1.0/16.0; -- Set breakpoint here Subtype_Object := 1.0/16.0; @@ -75,4 +81,5 @@ begin Do_Nothing (FP4_Var'Address); Do_Nothing (FP5_Var'Address); Do_Nothing (Another_Fixed'Address); + Do_Nothing (Object_Fixed'Address); end Fixed_Points; diff --git a/gprofng/common/gp-experiment.h b/gprofng/common/gp-experiment.h index fab08f1..7abccdf 100644 --- a/gprofng/common/gp-experiment.h +++ b/gprofng/common/gp-experiment.h @@ -39,6 +39,23 @@ #define IS_DESC_EXPT(exptname) (strstr(exptname,DESCENDANT_EXPT_KEY) != NULL) #define IS_FNDR_EXPT(exptname) (strstr(exptname,DESCENDANT_EXPT_KEY) == NULL) +// environment variables that must be forwarded to libcollector +#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" +#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" +#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" +#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" +#define SP_PRELOAD_STRINGS "SP_COLLECTOR_PRELOAD" +#define LD_PRELOAD_STRINGS "LD_PRELOAD" +#define SP_LIBPATH_STRINGS "SP_COLLECTOR_LIBRARY_PATH" +#define LD_LIBPATH_STRINGS "LD_LIBRARY_PATH" +#define JAVA_TOOL_OPTIONS "JAVA_TOOL_OPTIONS" +#define COLLECTOR_JVMTI_OPTION "-agentlib:gp-collector" +#define LIBGP_COLLECTOR "libgp-collector.so" +#define GPROFNG_PRELOAD_LIBDIRS "GPROFNG_PRELOAD_LIBDIRS" +#define SP_COLLECTOR_ORIGIN_COLLECT "SP_COLLECTOR_ORIGIN_COLLECT" +#define SP_COLLECTOR_DEBUG "SP_COLLECTOR_DEBUG" +#define SP_COLLECTOR_TRACELEVEL "SP_COLLECTOR_TRACELEVEL" + /* File name definitions */ #define SP_ARCHIVES_DIR "archives" #define SP_ARCHIVE_LOG_FILE "archive.log" @@ -86,70 +103,31 @@ /* records for log and loadobjects files */ /* note that these are in alphabetical order */ -#define SP_JCMD_ARCH "architecture" #define SP_JCMD_ARCHIVE "archive_run" -#define SP_JCMD_ARGLIST "arglist" #define SP_JCMD_BLKSZ "blksz" #define SP_JCMD_CERROR "cerror" -#define SP_JCMD_CLASS_LOAD "class_load" -#define SP_JCMD_CLASS_UNLOAD "class_unload" #define SP_JCMD_COLLENV "collenv" #define SP_JCMD_COMMENT "comment" -#define SP_JCMD_CPUID "cpuid" #define SP_JCMD_CWARN "cwarn" -#define SP_JCMD_CWD "cwd" -#define SP_JCMD_CVERSION "cversion" -#define SP_JCMD_DATARACE "datarace" -#define SP_JCMD_DEADLOCK "deadlock" #define SP_JCMD_DELAYSTART "delay_start" #define SP_JCMD_DESC_START "desc_start" #define SP_JCMD_DESC_STARTED "desc_started" -#define SP_JCMD_DVERSION "dversion" #define SP_JCMD_EXEC_START "exec_start" #define SP_JCMD_EXEC_ERROR "exec_error" #define SP_JCMD_EXIT "exit" -#define SP_JCMD_EXPT_DURATION "exp_duration" #define SP_JCMD_FAKETIME "faketime" -#define SP_JCMD_FN_LOAD "fn_load" -#define SP_JCMD_FN_UNLOAD "fn_unload" -#define SP_JCMD_FUN_MAP "fun_map" -#define SP_JCMD_FUN_UNMAP "fun_unmap" #define SP_JCMD_HEAPTRACE "heaptrace" -#define SP_JCMD_HOSTNAME "hostname" #define SP_JCMD_HWC_DEFAULT "hwc_default" #define SP_JCMD_HW_COUNTER "hwcounter" -#define SP_JCMD_HW_SIM_CTR "hwsimctr" #define SP_JCMD_IOTRACE "iotrace" -#define SP_JCMD_JCM_LOAD "jcm_load" -#define SP_JCMD_JCM_UNLOAD "jcm_unload" -#define SP_JCMD_JCM_MAP "jcm_map" -#define SP_JCMD_JCM_UNMAP "jcm_unmap" #define SP_JCMD_JTHREND "jthread_end" #define SP_JCMD_JTHRSTART "jthread_start" #define SP_JCMD_GCEND "gc_end" #define SP_JCMD_GCSTART "gc_start" #define SP_JCMD_JVERSION "jversion" -//#define SP_JCMD_KPROFILE "kprofile" /* TBR */ #define SP_JCMD_LIMIT "limit" #define SP_JCMD_LINETRACE "linetrace" -#define SP_JCMD_LO_OPEN "lo_open" -#define SP_JCMD_LO_CLOSE "lo_close" -#define SP_JCMD_MOD_OPEN "mod_open" -#define SP_JCMD_MPIEXP "MPIexperiment" -#define SP_JCMD_MPI_NO_TRACE "MPI_no_trace" -#define SP_JCMD_MPIOMPVER "mpi_openmpi_version" -#define SP_JCMD_MPITRACEVER "mpi_trace_version" -#define SP_JCMD_MPIPP "mpipp" -#define SP_JCMD_MPIPPERR "mpipp_err" -#define SP_JCMD_MPIPPWARN "mpipp_warn" -#define SP_JCMD_MPISTATE "mpistate" -#define SP_JCMD_MPITRACE "mpitrace" /* backwards compat only */ -#define SP_JCMD_MPVIEW "mpview" -#define SP_JCMD_MSGTRACE "msgtrace" #define SP_JCMD_NOIDLE "noidle" -#define SP_JCMD_OMPTRACE "omptrace" -#define SP_JCMD_OS "os" -#define SP_JCMD_PAGESIZE "pagesize" #define SP_JCMD_PAUSE "pause" #define SP_JCMD_PAUSE_SIG "pause_signal" #define SP_JCMD_PROFILE "profile" @@ -158,21 +136,15 @@ #define SP_JCMD_SAMPLE "sample" #define SP_JCMD_SAMPLE_PERIOD "sample_period" #define SP_JCMD_SAMPLE_SIG "sample_signal" -#define SP_JCMD_SEGMENT_MAP "seg_map" -#define SP_JCMD_SEGMENT_UNMAP "seg_unmap" #define SP_JCMD_SRCHPATH "search_path" #define SP_JCMD_STACKBASE "stackbase" -#define SP_JCMD_SUNPERF "sunperf" #define SP_JCMD_SYNCTRACE "synctrace" #define SP_JCMD_TERMINATE "terminate" #define SP_JCMD_THREAD_PAUSE "thread_pause" #define SP_JCMD_THREAD_RESUME "thread_resume" -#define SP_JCMD_USERNAME "username" #define SP_JCMD_VERSION "version" -#define SP_JCMD_WSIZE "wsize" /* strings naming memory-segments */ -#define SP_MAP_ANON "Anon" #define SP_MAP_HEAP "Heap" #define SP_MAP_STACK "Stack" #define SP_MAP_SHMEM "SHMid" diff --git a/gprofng/libcollector/collector.c b/gprofng/libcollector/collector.c index 8d978a6..c5fa3cb 100644 --- a/gprofng/libcollector/collector.c +++ b/gprofng/libcollector/collector.c @@ -182,11 +182,12 @@ static void init_tracelevel () { #if DEBUG - char *s = CALL_UTIL (getenv)("SP_COLLECTOR_TRACELEVEL"); + char *s = CALL_UTIL (getenv)(SP_COLLECTOR_TRACELEVEL); if (s != NULL) __collector_tracelevel = CALL_UTIL (atoi)(s); - TprintfT (DBG_LT0, "collector: SP_COLLECTOR_TRACELEVEL=%d\n", __collector_tracelevel); - s = CALL_UTIL (getenv)("SP_COLLECTOR_DEBUG"); + TprintfT (DBG_LT0, "collector: %s=%d\n", SP_COLLECTOR_TRACELEVEL, + __collector_tracelevel); + s = CALL_UTIL (getenv)(SP_COLLECTOR_DEBUG); if (s != NULL) collector_debug_opt = CALL_UTIL (atoi)(s) & ~(SP_DUMP_TIME | SP_DUMP_FLAG); #endif @@ -239,21 +240,24 @@ collector_init () collector_module_init (get_collector_interface ()); /* determine experiment name */ - char *exp = CALL_UTIL (getenv)("SP_COLLECTOR_EXPNAME"); + char *exp = CALL_UTIL (getenv)(SP_COLLECTOR_EXPNAME); if ((exp == NULL) || (CALL_UTIL (strlen)(exp) == 0)) { - TprintfT (DBG_LT0, "collector_init: SP_COLLECTOR_EXPNAME undefined - no experiment to start\n"); + TprintfT (DBG_LT0, "collector_init: %s undefined. no experiment to start\n", + SP_COLLECTOR_EXPNAME); /* not set -- no experiment to run */ return; } else - TprintfT (DBG_LT1, "collector_init: found SP_COLLECTOR_EXPNAME = %s\n", exp); + TprintfT (DBG_LT1, "collector_init: found %s = %s\n", + SP_COLLECTOR_EXPNAME, exp); /* determine the data descriptor for the experiment */ - char *params = CALL_UTIL (getenv)("SP_COLLECTOR_PARAMS"); + char *params = CALL_UTIL (getenv)(SP_COLLECTOR_PARAMS); if (params == NULL) { - TprintfT (0, "collector_init: SP_COLLECTOR_PARAMS undefined - no experiment to start\n"); + TprintfT (0, "collector_init: %s undefined - no experiment to start\n", + SP_COLLECTOR_EXPNAME); return; } @@ -494,7 +498,8 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or return COL_ERROR_EXPOPEN; } __collector_start_time = collector_interface.getHiResTime (); - TprintfT (DBG_LT1, "\n\t\t__collector_open_experiment(SP_COLLECTOR_EXPNAME=%s, params=%s, origin=%d); setting start_time\n", + TprintfT (DBG_LT1, "\n\t\t__collector_open_experiment(%s=%s, params=%s, " + "origin=%d); setting start_time\n", SP_COLLECTOR_EXPNAME, exp, params, origin); if (environ) __collector_env_printall ("__collector_open_experiment", environ); @@ -548,23 +553,20 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or is_founder = getpid (); if (origin != SP_ORIGIN_DBX_ATTACH) { - envar = CALL_UTIL (getenv)("SP_COLLECTOR_FOUNDER"); + envar = CALL_UTIL (getenv)(SP_COLLECTOR_FOUNDER); if (envar) is_founder = CALL_UTIL (atoi)(envar); if (is_founder != 0) { if (is_founder != getpid ()) { - TprintfT (0, "__collector_open_experiment SP_COLLECTOR_FOUNDER=%d != pid(%d)\n", - is_founder, getpid ()); - //CALL_UTIL(fprintf)(stderr, "__collector_open_experiment SP_COLLECTOR_FOUNDER=%d != pid(%d); not recording experiment\n", - //is_founder, getpid() ); - //return COL_ERROR_UNEXP_FOUNDER; + TprintfT (0, "__collector_open_experiment %s=%d != pid(%d)\n", + SP_COLLECTOR_FOUNDER, is_founder, getpid ()); is_founder = 0; // Special case (CR 22917352) } /* clear FOUNDER for descendant experiments */ - TprintfT (0, "__collector_open_experiment setting SP_COLLECTOR_FOUNDER=0\n"); - CALL_UTIL (strlcpy)(buffer, "SP_COLLECTOR_FOUNDER=0", sizeof (buffer)); + TprintfT (0, "__collector_open_experiment setting %s=0\n", SP_COLLECTOR_FOUNDER); + CALL_UTIL (snprintf)(buffer, sizeof (buffer), "%s=0", SP_COLLECTOR_FOUNDER); CALL_UTIL (putenv)(buffer); } } @@ -617,8 +619,10 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or return COL_ERROR_BADDIR; } static char exp_name_env[MAXPATHLEN + 1]; - TprintfT (DBG_LT1, "collector_open_experiment: setting SP_COLLECTOR_EXPNAME to %s\n", __collector_exp_dir_name); - CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "SP_COLLECTOR_EXPNAME=%s", __collector_exp_dir_name); + TprintfT (DBG_LT1, "collector_open_experiment: setting %s to %s\n", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); + CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "%s=%s", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); CALL_UTIL (putenv)(exp_name_env); } /* Check that the name is that of a directory (new structure) */ @@ -1049,8 +1053,10 @@ collector_tail_init (const char *parent_exp_name) if (collector_exp_dir_append_x (linenum, parent_exp_name) != 0) return COL_ERROR_BADDIR; static char exp_name_env[MAXPATHLEN + 1]; - CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "SP_COLLECTOR_EXPNAME=%s", __collector_exp_dir_name); - TprintfT (DBG_LT1, "collector_tail_init: setting SP_COLLECTOR_EXPNAME to %s\n", __collector_exp_dir_name); + CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "%s=%s", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); + TprintfT (DBG_LT1, "collector_tail_init: setting %s to %s\n", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); CALL_UTIL (putenv)(exp_name_env); } /* initialize the segments map and mmap interposition */ diff --git a/gprofng/libcollector/descendants.h b/gprofng/libcollector/descendants.h index 0148410..7d594b3 100644 --- a/gprofng/libcollector/descendants.h +++ b/gprofng/libcollector/descendants.h @@ -44,7 +44,6 @@ typedef enum LM_TRACK_LINEAGE = 1, /* env vars preserved, recording */ } line_mode_t; -extern line_mode_t line_mode; extern int user_follow_mode; extern int java_mode; extern int dbg_current_mode; /* for debug only */ @@ -56,19 +55,6 @@ extern char **sp_env_backup; #define PUSH_REENTRANCE(x) ((*(x))++) #define POP_REENTRANCE(x) ((*(x))--) -/* environment variables that must be forwarded to descendents */ -#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" -#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" -#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" -#define SP_PRELOAD_STRINGS "SP_COLLECTOR_PRELOAD" -#define LD_PRELOAD_STRINGS "LD_PRELOAD" -#define SP_LIBPATH_STRINGS "SP_COLLECTOR_LIBRARY_PATH" -#define LD_LIBPATH_STRINGS "LD_LIBRARY_PATH" -#define JAVA_TOOL_OPTIONS "JAVA_TOOL_OPTIONS" -#define COLLECTOR_JVMTI_OPTION "-agentlib:gp-collector" - -extern int __collector_linetrace_shutdown_hwcs_6830763_XXXX; extern void __collector_env_unset (char *envp[]); extern void __collector_env_save_preloads (); extern char ** __collector_env_backup (); diff --git a/gprofng/libcollector/envmgmt.c b/gprofng/libcollector/envmgmt.c index 0c3bea1..0a2add9 100644 --- a/gprofng/libcollector/envmgmt.c +++ b/gprofng/libcollector/envmgmt.c @@ -285,9 +285,6 @@ env_ld_preload_strip (char *envv) for (int v = 0; SP_PRELOAD[v]; v++) if (env_strip (envv, sp_preloads[v])) return 0; - if (line_mode != LM_CLOSED) - TprintfT (DBG_LT2, "env_ld_preload_strip(): WARNING - could not strip SP_PRELOADS from '%s'\n", - envv); return -2; } diff --git a/gprofng/libcollector/linetrace.c b/gprofng/libcollector/linetrace.c index 86d9955..0e3e7cd 100644 --- a/gprofng/libcollector/linetrace.c +++ b/gprofng/libcollector/linetrace.c @@ -37,10 +37,10 @@ #define LT_MAXNAMELEN 1024 #define LT_MAXPATHLEN 1024 -int __collector_linetrace_shutdown_hwcs_6830763_XXXX = 0; +static int __collector_linetrace_shutdown_hwcs_6830763_XXXX = 0; int dbg_current_mode = FOLLOW_NONE; /* for debug only */ unsigned line_key = COLLECTOR_TSD_INVALID_KEY; -line_mode_t line_mode = LM_DORMANT; +static line_mode_t line_mode = LM_DORMANT; int user_follow_mode = FOLLOW_ON; int java_mode = 0; diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index 3b3fd63..23ac5b9 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -29,6 +29,7 @@ #include "LoadObject.h" #include "Module.h" #include "DefaultMap.h" +#include "Symbol.h" static int datatypeCmp (const void *a, const void *b) @@ -46,7 +47,6 @@ targetOffsetCmp (const void *a, const void *b) return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1); } - ////////////////////////////////////////////////////////// // class Dwr_type class Dwr_type @@ -441,7 +441,12 @@ DwrCU::get_linkage_name () nm = Dwarf_string (DW_AT_SUN_link_name); if (nm != NULL) return nm; - return Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + nm = Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + return Dwarf_string (DW_AT_name); } void @@ -490,8 +495,10 @@ DwrCU::parseChild (Dwarf_cnt *ctx) } break; case DW_TAG_subprogram: + { if (dwrTag.get_attr (DW_AT_abstract_origin)) break; + Symbol *sym = NULL; if (dwrTag.get_attr (DW_AT_declaration)) { // Only declaration @@ -499,26 +506,71 @@ DwrCU::parseChild (Dwarf_cnt *ctx) { char *link_name = Dwarf_string (DW_AT_name); if (link_name && streq (link_name, NTXT ("MAIN"))) - ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true); - } - break; + ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), + ctx->module->functions, true, true); + } + sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + break; } - func = append_Function (ctx); - if (func) + + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification); + if (dwrAttr) { - if (Stabs::is_fortran (ctx->module->lang_code) && - streq (func->get_match_name (), NTXT ("MAIN"))) - ctx->fortranMAIN = func; - old_name = ctx->name; - Function *old_func = ctx->func; - ctx->name = func->get_match_name (); - ctx->func = func; - parseChild (ctx); - hasChild = 0; - ctx->name = old_name; - ctx->func = old_func; + // Find previous declaration to inherit settings. + sym = find_declaration (dwrAttr->u.offset); + if (sym == NULL) + break; + func = sym->func; + if (func == NULL) + break; + set_source (func); + + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector<Symbol *> *syms = Symbol::find_symbols (symbols, ranges); + Destroy (ranges); + for (int i = 0, sz = VecSize (syms); i < sz; i++) + { + Symbol *sp = syms->get (i); + if (sp->alias) + sp = sp->alias; + Function *f = sp->func; + if (f == NULL) + f = sp->createFunction (func->module); + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + delete (syms); + } + break; } + + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + if (Stabs::is_fortran (ctx->module->lang_code) && + streq (func->get_match_name (), "MAIN")) + ctx->fortranMAIN = func; + set_source (func); + + old_name = ctx->name; + Function *old_func = ctx->func; + ctx->name = func->get_match_name (); + ctx->func = func; + parseChild (ctx); + hasChild = 0; + ctx->name = old_name; + ctx->func = old_func; break; + } case DW_TAG_module: old_name = ctx->name; ctx->name = Dwarf_string (DW_AT_SUN_link_name); @@ -631,6 +683,21 @@ Dwarf::archive_Dwarf (LoadObject *lo) STR (lo_name), STR (mod->get_name ())); dwrCU->dwrInlinedSubrs->dump (msg); } + for (int i = 0, sz = VecSize (dwrCU->symbols); i < sz; i++) + { + Symbol *sp = dwrCU->symbols->get (i); + Function *f = sp->func; + if (f == NULL) + { + f = sp->createFunction (mod); + if (sp->alias && sp->alias->func) + { + Function *func = sp->alias->func; + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + } + } } } return true; @@ -645,6 +712,38 @@ Dwarf::srcline_Dwarf (Module *module) dwrCU->map_dwarf_lines (module); } +static int +rangeCmp (const void *a, const void *b) +{ + Range *item1 = *((Range **) a); + Range *item2 = *((Range **) b); + return item1->low < item2->low ? -1 : (item1->low == item2->low ? 0 : 1); +} + +Vector<Range *> * +Dwarf::get_ranges (uint64_t offset) +{ + if (debug_rangesSec == NULL) + return NULL; + if (offset >= debug_rangesSec->size) + { + Dprintf (DUMP_DWARFLIB, "ERROR: Dwarf::get_ranges(0x%llx). size=0x%llx\n", + (long long) offset, (long long) debug_rangesSec->size); + return NULL; + } + Vector<Range*> *ranges = new Vector<Range*>(); + debug_rangesSec->offset = offset; + for (;;) + { + uint64_t low_pc = debug_rangesSec->GetADDR (); + uint64_t high_pc = debug_rangesSec->GetADDR (); + if (low_pc == 0 || low_pc > high_pc) + break; + ranges->append (new Range (low_pc, high_pc)); + } + ranges->sort (rangeCmp); + return ranges; +} // parse hwcprof info for given module in loadobject @@ -797,11 +896,17 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) case DW_TAG_subprogram: { Function *old_func = ctx->func; - if (dwrTag.get_attr (DW_AT_abstract_origin) - || dwrTag.get_attr (DW_AT_declaration)) - ctx->func = NULL; - else - ctx->func = append_Function (ctx); + ctx->func = NULL; + if (dwrTag.get_attr (DW_AT_abstract_origin) == NULL + && dwrTag.get_attr (DW_AT_declaration) == NULL) + { + Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym != NULL) + ctx->func = sym->func; + } read_hwcprof_info (ctx); ctx->func = old_func; break; @@ -955,49 +1060,31 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) // Append function to module Function * -DwrCU::append_Function (Dwarf_cnt *ctx) +DwrCU::append_Function (Symbol *sym, const char *outerName) { - char *outerName = ctx->name, *name, tmpname[2048]; - Function *func; + if (sym->func != NULL) + return sym->func; + Function *func = sym->createFunction (module); + char *fname = Dwarf_string (DW_AT_name); - if (fname && outerName && !strchr (fname, '.')) + if (fname) { - size_t outerlen = strlen (outerName); - if (outerlen > 0 && outerName[outerlen - 1] == '_') + if (outerName && !strchr (fname, '.')) { - outerlen--; - snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName); - snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname); + char *tmpname; + int outerlen = (int) strlen (outerName); + if (outerlen > 0 && outerName[outerlen - 1] == '_') + tmpname = dbe_sprintf ("%.*s.%s_", outerlen - 1, outerName, fname); + else + tmpname = dbe_sprintf ("%s.%s", outerName, fname); + func->set_match_name (tmpname); + Dprintf (DUMP_DWARFLIB, "Generated innerfunc name %s\n", tmpname); + free(tmpname); } else - snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname); - name = tmpname; - Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name); - } - else - name = fname; - - char *link_name = get_linkage_name (); - if (link_name == NULL) - link_name = name; - - uint64_t pc = get_low_pc (); - func = dwarf->stabs->append_Function (module, link_name, pc); - if (func != NULL) - { - int lineno = (int) Dwarf_data (DW_AT_decl_line); - func->set_match_name (name); - if (lineno > 0) - { - func->setLineFirst (lineno); - int fileno = ((int) Dwarf_data (DW_AT_decl_file)); - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) - : module->getMainSrc (); - func->setDefSrc (sf); - func->pushSrcFile (func->def_source, 0); - func->popSrcFile (); - } + func->set_match_name (fname); } + set_source (func); return func; } diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h index 8e3ee7a..f46ad3f 100644 --- a/gprofng/src/Dwarf.h +++ b/gprofng/src/Dwarf.h @@ -60,6 +60,7 @@ class LoadObject; class Module; class DwrCU; class DwrSec; +class Range; class Dwarf { @@ -69,6 +70,7 @@ public: bool archive_Dwarf (LoadObject *lo); void srcline_Dwarf (Module *module); void read_hwcprof_info (Module *module); + Vector<Range *> *get_ranges (uint64_t offset); Stabs::Stab_status status; Vector<DwrCU *> *dwrCUs; diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index 3594c2f..9f55ab3 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -27,9 +27,9 @@ #include "Elf.h" #include "Function.h" #include "Module.h" -#include "StringBuilder.h" #include "DbeArray.h" #include "DbeSession.h" +#include "Symbol.h" #define NO_STMT_LIST ((uint64_t) -1) #define CASE_S(x) case x: s = (char *) #x; break @@ -1795,6 +1795,8 @@ DwrLineRegs::getPath (int fn) DwrCU::DwrCU (Dwarf *_dwarf) { dwarf = _dwarf; + symbols = NULL; + symbols_sorted_by_name = NULL; cu_offset = dwarf->debug_infoSec->offset; debug_infoSec = new DwrSec (dwarf->debug_infoSec, cu_offset); next_cu_offset = debug_infoSec->ReadLength (); @@ -1883,6 +1885,8 @@ DwrCU::~DwrCU () Destroy (dwrInlinedSubrs); delete srcFiles; delete dwrLineReg; + delete symbols; + delete symbols_sorted_by_name; free (comp_dir); } @@ -2187,9 +2191,80 @@ DwrCU::parse_cu_header (LoadObject *lo) else path = dbe_strdup (dwarf->stabs->path); module->set_name (path); + + // create a list of functions in this CU + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector <Symbol *> *syms = dwarf->stabs->get_symbols (); + symbols = Symbol::find_symbols (syms, ranges); + symbols_sorted_by_name = Symbol::sort_by_name (syms); + Destroy (ranges); + } return module; } +Vector <Range *> * +DwrCU::get_ranges () +{ + Vector <Range *> *ranges = NULL; + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges); + if (dwrAttr) + { + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n", + (long long) dwrAttr->u.offset); + ranges = dwarf->get_ranges (dwrAttr->u.offset); + } + else + { + uint64_t low_pc = Dwarf_addr (DW_AT_low_pc); + if (low_pc > 0) + { + uint64_t high_pc = get_high_pc (low_pc); + ranges = new Vector <Range *> (1); + ranges->append (new Range (low_pc, high_pc)); + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: pc=0x%llx\n", + (long long) low_pc); + } + } + if (ranges && DUMP_DWARFLIB) + ranges->dump (" "); + return ranges; +} + +void +DwrCU::set_source (Function *func) +{ + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); +} + +Symbol * +DwrCU::find_declaration (int64_t offset) +{ + int64_t old_offset = dwrTag.offset; + Symbol *sym = NULL; + if (set_die (offset) == DW_DLV_OK) + { + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym && sym->func == NULL) + { + Function *func = sym->createFunction (module); + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); + } + } + set_die (old_offset); + return sym; +} + Dwr_Attr * Dwr_Tag::get_attr (Dwarf_Half attr) { @@ -2357,7 +2432,7 @@ DwrCU::map_dwarf_lines (Module *mod) InlinedSubr *p = func->inlinedSubr + func->inlinedSubrCnt; func->inlinedSubrCnt++; int fileno = inlinedSubr->file - 1; - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? + SourceFile *sf = ((fileno > 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) : dbeSession->get_Unknown_Source (); p->dbeLine = sf->find_dbeline (inlinedSubr->line); p->high_pc = inlinedSubr->high_pc - low_pc; diff --git a/gprofng/src/DwarfLib.h b/gprofng/src/DwarfLib.h index 178801d..230e551 100644 --- a/gprofng/src/DwarfLib.h +++ b/gprofng/src/DwarfLib.h @@ -25,6 +25,8 @@ class ElfReloc; class Dwr_type; +class Function; +class Range; class SourceFile; template <class ITEM> class Vector; @@ -73,12 +75,6 @@ public: return (uint32_t) GetULEB128 (); } - bool - inRange (uint64_t left, uint64_t right) - { - return (offset >= left) && (offset < right); - }; - ElfReloc *reloc; uint64_t sizeSec; uint64_t size; @@ -280,6 +276,8 @@ public: uint64_t cu_header_offset; uint64_t cu_offset; uint64_t next_cu_offset; + Vector<Symbol*> *symbols; // all symbols in this CU are sorted by pc + Vector<Symbol*> *symbols_sorted_by_name; Vector<DwrInlinedSubr*> *dwrInlinedSubrs; Vector<SourceFile *> *srcFiles; bool isMemop; @@ -287,7 +285,10 @@ public: private: void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset); - Function *append_Function (Dwarf_cnt *ctx); + Function *append_Function (Symbol *sym, const char *outerName); + Symbol *find_declaration(int64_t offset); + Vector <Range *> *get_ranges(); + void set_source (Function *func); void parse_inlined_subroutine (Dwarf_cnt *ctx); uint64_t get_low_pc (); uint64_t get_high_pc (uint64_t low_pc); diff --git a/gprofng/src/LoadObject.cc b/gprofng/src/LoadObject.cc index 1ca6ab6..be7ad3a 100644 --- a/gprofng/src/LoadObject.cc +++ b/gprofng/src/LoadObject.cc @@ -20,6 +20,7 @@ #include "config.h" #include <errno.h> +#include <libgen.h> #include "util.h" #include "StringBuilder.h" @@ -303,13 +304,16 @@ LoadObject::dump_functions (FILE *out) { mname = fitem->module ? fitem->module->file_name : noname->file_name; sname = fitem->getDefSrcName (); - fprintf (out, - "id %6llu, @0x%llx - 0x%llx [save 0x%llx] o-%lld sz-%lld %s (module = %s)", - (ull_t) fitem->id, (ull_t) fitem->img_offset, - (ull_t) (fitem->img_offset + fitem->size), - (ull_t) fitem->save_addr, (ull_t) fitem->img_offset, - (ll_t) fitem->size, fitem->get_name (), mname); - if (sname && !streq (sname, mname)) + fprintf (out, "id %6llu, @0x%llx-0x%llx sz-%lld", (ull_t) fitem->id, + (ull_t) fitem->img_offset, + (ull_t) (fitem->img_offset + fitem->size), + (ll_t) fitem->size); + if (fitem->save_addr != 0) + fprintf (out, " [save 0x%llx]", (ull_t) fitem->save_addr); + if (strcmp (fitem->get_mangled_name (), fitem->get_name ()) != 0) + fprintf (out, " [%s]", fitem->get_mangled_name ()); + fprintf (out, " %s (module = %s)", fitem->get_name (), mname); + if (sname && strcmp (basename (sname), basename (mname)) != 0) fprintf (out, " (Source = %s)", sname); fprintf (out, "\n"); } diff --git a/gprofng/src/Makefile.am b/gprofng/src/Makefile.am index 0465cdb..f6d3f5d 100644 --- a/gprofng/src/Makefile.am +++ b/gprofng/src/Makefile.am @@ -78,6 +78,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ diff --git a/gprofng/src/Makefile.in b/gprofng/src/Makefile.in index 9f07986..0cdd444 100644 --- a/gprofng/src/Makefile.in +++ b/gprofng/src/Makefile.in @@ -174,7 +174,7 @@ am__objects_1 = Application.lo BaseMetric.lo BaseMetricTreeNode.lo \ MemorySpace.lo Metric.lo MetricList.lo Module.lo Ovw_data.lo \ PRBTree.lo PathTree.lo PreviewExp.lo Print.lo \ SAXParserFactory.lo Sample.lo Settings.lo SourceFile.lo \ - Stabs.lo Stats_data.lo StringBuilder.lo Table.lo \ + Stabs.lo Stats_data.lo StringBuilder.lo Symbol.lo Table.lo \ QLParser.tab.lo dbe_collctrl.lo i18n.lo parse.lo UserLabel.lo \ util.lo Dbe.lo am__objects_2 = dbe_hwcdrv.lo dbe_hwcfuncs.lo dbe_hwctable.lo \ @@ -505,6 +505,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ @@ -777,6 +778,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stabs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stats_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringBuilder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Symbol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserLabel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checks.Po@am__quote@ diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc index b98ac28..ff83949 100644 --- a/gprofng/src/Stabs.cc +++ b/gprofng/src/Stabs.cc @@ -35,10 +35,7 @@ #include "StringBuilder.h" #include "DbeFile.h" #include "StringMap.h" - -#define DISASM_REL_NONE 0 /* symtab search only */ -#define DISASM_REL_ONLY 1 /* relocation search only */ -#define DISASM_REL_TARG 2 /* relocatoin then symtab */ +#include "Symbol.h" /////////////////////////////////////////////////////////////////////////////// // class StabReader @@ -62,105 +59,6 @@ private: int StabEntSize; }; -/////////////////////////////////////////////////////////////////////////////// -// class Symbol - -class Symbol -{ -public: - Symbol (Vector<Symbol*> *vec = NULL); - - ~Symbol () - { - free (name); - } - - inline Symbol * - cardinal () - { - return alias ? alias : this; - } - - static void dump (Vector<Symbol*> *vec, char*msg); - - Function *func; - Sp_lang_code lang_code; - uint64_t value; // st_value used in sym_name() - uint64_t save; - int64_t size; - uint64_t img_offset; // image offset in the ELF file - char *name; - Symbol *alias; - int local_ind; - int flags; - bool defined; -}; - -Symbol::Symbol (Vector<Symbol*> *vec) -{ - func = NULL; - lang_code = Sp_lang_unknown; - value = 0; - save = 0; - size = 0; - img_offset = 0; - name = NULL; - alias = NULL; - local_ind = -1; - flags = 0; - defined = false; - if (vec) - vec->append (this); -} - -void -Symbol::dump (Vector<Symbol*> *vec, char*msg) -{ - if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0) - return; - printf (NTXT ("======= Symbol::dump: %s =========\n" - " value | img_offset | flags|local_ind|\n"), msg); - for (int i = 0; i < vec->size (); i++) - { - Symbol *sp = vec->fetch (i); - printf (NTXT (" %3d %8lld |0x%016llx |%5d |%8d |%s\n"), - i, (long long) sp->value, (long long) sp->img_offset, sp->flags, - sp->local_ind, sp->name ? sp->name : NTXT ("NULL")); - } - printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg); -} - -// end of class Symbol -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// class Reloc -class Reloc -{ -public: - Reloc (); - ~Reloc (); - uint64_t type; - uint64_t value; - uint64_t addend; - char *name; -}; - -Reloc::Reloc () -{ - type = 0; - value = 0; - addend = 0; - name = NULL; -} - -Reloc::~Reloc () -{ - free (name); -} -// end of class Reloc -/////////////////////////////////////////////////////////////////////////////// - enum { SYM_PLT = 1 << 0, @@ -232,15 +130,6 @@ SymImgOffsetCmp (const void *a, const void *b) (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1; } -static int -RelValueCmp (const void *a, const void *b) -{ - Reloc *item1 = *((Reloc **) a); - Reloc *item2 = *((Reloc **) b); - return (item1->value > item2->value) ? 1 : - (item1->value == item2->value) ? 0 : -1; -} - /* Remove all duplicate symbols which can be in SymLst. The duplication is due to processing of both static and dynamic symbols. This function is called before computing symbol @@ -252,7 +141,6 @@ Stabs::removeDupSyms () long ind, i, last; Symbol *symA, *symB; SymLst->sort (SymImgOffsetCmp); - dump (); last = 0; ind = SymLst->size (); @@ -294,8 +182,6 @@ Stabs::Stabs (char *_path, char *_lo_name) SymLstByName = NULL; pltSym = NULL; SymLst = new Vector<Symbol*>; - RelLst = new Vector<Reloc*>; - RelPLTLst = new Vector<Reloc*>; LocalLst = new Vector<Symbol*>; LocalFile = new Vector<char*>; LocalFileIdx = new Vector<int>; @@ -341,8 +227,6 @@ Stabs::~Stabs () { delete SymLstByName; Destroy (SymLst); - Destroy (RelLst); - Destroy (RelPLTLst); Destroy (LocalFile); delete elfDis; delete dwarf; @@ -458,42 +342,6 @@ Stabs::read_symbols (Vector<Function*> *functions) return true; } -char * -Stabs::sym_name (uint64_t target, uint64_t instr, int flag) -{ - long index; - if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG) - { - Reloc *relptr = new Reloc; - relptr->value = instr; - index = RelLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelLst->fetch (index)->name; - } - if (!is_relocatable ()) - { - relptr->value = target; - index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelPLTLst->fetch (index)->name; - } - } - delete relptr; - } - if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ()) - { - Symbol *sptr; - sptr = map_PC_to_sym (target); - if (sptr && sptr->value == target) - return sptr->name; - } - return NULL; -} - Symbol * Stabs::map_PC_to_sym (uint64_t pc) { @@ -1761,10 +1609,12 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) if (asym == NULL) break; const char *st_name = bfd_asymbol_name (asym); + if (st_name == NULL) + continue; switch (GELF_ST_TYPE (Sym.st_info)) { case STT_FUNC: - if (Sym.st_size == 0) + if (Sym.st_size == 0 || ELF_ST_BIND (Sym.st_info) == STB_WEAK) break; if (Sym.st_shndx == 0) { @@ -1839,8 +1689,7 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) fixSymtabAlias (); SymLst->sort (SymValueCmp); get_save_addr (elf->need_swap_endian); - dump (); -}//check_Symtab +} void Stabs::get_save_addr (bool need_swap_endian) @@ -2339,6 +2188,7 @@ Stabs::openDwarf () { dwarf = new Dwarf (this); check_Symtab (); + dump(); } return dwarf; } @@ -2363,8 +2213,8 @@ Stabs::dump () printf (" %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i), LocalFile->fetch (i)); } - Symbol::dump (SymLst, NTXT ("SymLst")); - Symbol::dump (LocalLst, NTXT ("LocalLst")); + SymLst->dump ("SymLst"); + LocalLst->dump ("LocalLst"); printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"), path ? path : NTXT ("NULL")); } diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h index d34741f..c8da278 100644 --- a/gprofng/src/Stabs.h +++ b/gprofng/src/Stabs.h @@ -40,7 +40,6 @@ class ComC; class Elf; class Dwarf; class Symbol; -class Reloc; struct cpf_stabs_t; class SourceFile; template <typename Key_t, typename Value_t> class Map; @@ -86,12 +85,12 @@ class Stabs { Platform_t get_platform() { return platform; } WSize_t get_class() { return wsize;} Stab_status get_status() { return status;} + Vector<Symbol *> *get_symbols() { return SymLst; } Stab_status read_stabs(ino64_t srcInode, Module *module, Vector<ComC*> *comComs, bool readDwarf = false); Stab_status read_archive(LoadObject *lo); bool read_symbols(Vector<Function*> *functions); uint64_t mapOffsetToAddress(uint64_t img_offset); - char *sym_name(uint64_t target, uint64_t instr, int flag); Elf *openElf (bool dbg_info = false); void read_hwcprof_info(Module *module); void dump(); @@ -135,8 +134,6 @@ class Stabs { Symbol *pltSym; Vector<Symbol*> *SymLst; // list of func symbols Vector<Symbol*> *SymLstByName; // list of func symbols sorted by Name - Vector<Reloc*> *RelLst; // list of text relocations - Vector<Reloc*> *RelPLTLst; // list of PLT relocations Vector<Symbol*> *LocalLst; // list of local func symbols Vector<char*> *LocalFile; // list of local files Vector<int> *LocalFileIdx; // start index in LocalLst diff --git a/gprofng/src/Symbol.cc b/gprofng/src/Symbol.cc new file mode 100644 index 0000000..82fe788 --- /dev/null +++ b/gprofng/src/Symbol.cc @@ -0,0 +1,226 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" + +#include "DbeSession.h" +#include "Function.h" +#include "LoadObject.h" +#include "Module.h" +#include "Symbol.h" + + +template<> void Vector<Symbol *>::dump (const char *msg) +{ + if (msg == NULL) + msg = "#"; + Dprintf (1, NTXT ("\n%s Vector<Symbol *> [%lld]\n"), msg, (long long) size ()); + if (size () > 0) + Dprintf (1, " value | img_offset | size | flags|local_ind|\n"); + for (long i = 0, sz = size (); i < sz; i++) + { + Symbol *sp = get (i); + Dprintf (1, " %3ld ", i); + sp->dump (); + } + if (size () > 0) + Dprintf (1, "===== END of Symbol::dump: %s =========\n\n", msg); +} + +void +Symbol::dump (const char *msg) +{ + if (msg) + Dprintf (1, "%s\n", msg); + Dprintf (1, "%8lld |%11lld |%6d |%5d |%8d |%s\n", (long long) value, + (long long) img_offset, (int) size, flags, local_ind, + name ? name : "NULL"); +} + +Symbol::Symbol (Vector<Symbol*> *vec) +{ + func = NULL; + lang_code = Sp_lang_unknown; + value = 0; + save = 0; + size = 0; + img_offset = 0; + name = NULL; + alias = NULL; + local_ind = -1; + flags = 0; + defined = false; + if (vec) + vec->append (this); +} + +Symbol::~Symbol () +{ + free (name); +} + +static int +cmpSym (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return (item1->value > item2->value) ? 1 : + (item1->value == item2->value) ? 0 : -1; +} + +static int +cmpSymName (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return strcmp (item1->name, item2->name); +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, uint64_t pc) +{ + if (syms != NULL && pc != 0) + { + Symbol *sp = new Symbol; + sp->value = pc; + long i = syms->bisearch (0, -1, &sp, cmpSym); + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, char *linker_name) +{ + if (syms != NULL && linker_name != NULL) + { + Symbol *sp = new Symbol; + sp->name = linker_name; + long i = syms->bisearch (0, -1, &sp, cmpSymName); + sp->name = NULL; + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Vector<Symbol *> * +Symbol::sort_by_name (Vector<Symbol *> *syms) +{ + if (VecSize (syms) == 0) + return NULL; + Vector<Symbol *> *symbols = syms->copy (); + symbols->sort (cmpSymName); + return symbols; +} + +Vector<Symbol *> * +Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges) +{ + // 'syms' and 'ranges' must already be sorted. + // return symbols matched by 'ranges' + if (VecSize (syms) == 0 || VecSize (ranges) == 0) + return NULL; + Vector<Symbol *> *symbols = new Vector<Symbol*> (); + + // Use binary search to find a suitable index in 'syms' + int ind = 0; + uint64_t addr = ranges->get (0)->low; + for (int lo = 0, hi = syms->size (); lo < hi;) + { + int mid = (hi + lo) >> 1; + Symbol *sym = syms->get (mid); + if (sym->value == addr) + { + ind = mid; + break; + } + else if (sym->value > addr) + hi = mid - 1; + else + { + ind = mid; + lo = mid + 1; + } + } + + for (int i = 0, r_sz = ranges->size (), sz = syms->size (); ind < sz; ind++) + { + Symbol *sym = syms->get (ind); + while (i < r_sz) + { + Range *r = ranges->get (i); + if (sym->value < r->low) + break; + if (sym->value <= r->high) + { + symbols->append (sym); + break; + } + i++; + } + if (i >= r_sz) + break; + } + if (DUMP_ELF_SYM) + { + syms->dump ( "Symbol::find_symbols: syms"); + symbols->dump ("Symbol::find_symbols: symbols"); + } + if (symbols->size () != 0) + return symbols; + delete symbols; + return NULL; +} + +/* Create and append a new function to the 'module'. + * Copy attributes (size, name, etc) from Simbol, */ +Function * +Symbol::createFunction (Module *module) +{ + if (func) + return func; + func = dbeSession->createFunction (); + func->img_fname = module->file_name; + func->img_offset = img_offset; + func->save_addr = save; + func->size = size; + func->module = module; + func->set_name (name); + module->functions->append (func); + module->loadobject->functions->append (func); + return func; +} + +template<> void Vector<Range *>::dump (const char *msg) +{ + Dprintf (1, NTXT ("%s Vector<Range *> [%lld]\n"), + msg ? msg : "#", (long long) size ()); + for (long i = 0, sz = size (); i < sz; i++) + { + Range *p = get (i); + Dprintf (1, "%3ld 0x%08llx 0x%08llx (%lld - %lld)\n", i, + (long long) p->low, (long long) p->high, + (long long) p->low, (long long) p->high); + } +}
\ No newline at end of file diff --git a/gprofng/src/Symbol.h b/gprofng/src/Symbol.h new file mode 100644 index 0000000..25cceca --- /dev/null +++ b/gprofng/src/Symbol.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +class Function; +class Module; + +class Range +{ +public: + Range (uint64_t _low, uint64_t _high) + { + low = _low; + high = _high; + } + + inline bool + inside (uint64_t val) + { + return val >= low && val < high; + }; + + uint64_t low; + uint64_t high; +}; + +class Symbol +{ +public: + Symbol (Vector<Symbol *> *vec = NULL); + ~Symbol (); + + Symbol * + cardinal () + { + return alias ? alias : this; + } + + // Find symbols in 'syms' matched by 'ranges'. + static Vector<Symbol *> *find_symbols (Vector<Symbol *> *syms, + Vector<Range *> *ranges); + static Vector<Symbol *> *sort_by_name (Vector<Symbol *> *syms); + + // Find symbol in CU corresponding to pc or linker_name. + static Symbol *get_symbol (Vector<Symbol *> *syms, uint64_t pc); + static Symbol *get_symbol (Vector<Symbol *> *syms, char *linker_name); + + // Create and append a new function to the 'module'. + // Copy attributes (size, name, etc) from Simbol, + Function *createFunction(Module *module); + void dump (const char *msg = NULL); + + Function *func; + Sp_lang_code lang_code; + uint64_t value; + uint64_t save; + int64_t size; + uint64_t img_offset; // image offset in the ELF file + char *name; + Symbol *alias; + int local_ind; + int flags; + bool defined; +};
\ No newline at end of file diff --git a/gprofng/src/collect.h b/gprofng/src/collect.h index 18ab564..3ce6b28 100644 --- a/gprofng/src/collect.h +++ b/gprofng/src/collect.h @@ -32,7 +32,6 @@ class Coll_Ctrl; class Elf; #define MAXLABELS 10 /* maximum number of -C arguments */ -#define STDEBUFSIZE 24000 enum { MAX_LD_PRELOAD_TYPES = 3 }; diff --git a/gprofng/src/envsets.cc b/gprofng/src/envsets.cc index 30803aa..e92c017 100644 --- a/gprofng/src/envsets.cc +++ b/gprofng/src/envsets.cc @@ -31,16 +31,6 @@ #include "StringBuilder.h" #include "Settings.h" -#define STDEBUFSIZE 24000 - -#define LIBGP_COLLECTOR "libgp-collector.so" -#define GPROFNG_PRELOAD_LIBDIRS "GPROFNG_PRELOAD_LIBDIRS" -#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" -#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" -#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" -#define SP_COLLECTOR_ORIGIN_COLLECT "SP_COLLECTOR_ORIGIN_COLLECT" - static const char *LD_AUDIT[] = { // "LD_AUDIT", Do not set LD_AUDIT on Linux NULL diff --git a/gprofng/src/gp-collect-app.cc b/gprofng/src/gp-collect-app.cc index b94f410..695c4af 100644 --- a/gprofng/src/gp-collect-app.cc +++ b/gprofng/src/gp-collect-app.cc @@ -44,8 +44,6 @@ #include "collect.h" #include "StringBuilder.h" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" - extern char **environ; static volatile int interrupt = 0; diff --git a/gprofng/src/ipcio.cc b/gprofng/src/ipcio.cc index 36d2ba5..2890c6a 100644 --- a/gprofng/src/ipcio.cc +++ b/gprofng/src/ipcio.cc @@ -23,10 +23,7 @@ #include <stdlib.h> #include <signal.h> #include <unistd.h> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <queue> + #include "vec.h" #include "util.h" #include "ipcio.h" |