aboutsummaryrefslogtreecommitdiff
path: root/gprofng
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng')
-rwxr-xr-xgprofng/configure20
-rw-r--r--gprofng/doc/version.texi8
-rwxr-xr-xgprofng/libcollector/configure20
-rw-r--r--gprofng/src/Disasm.cc2
-rw-r--r--gprofng/src/Dwarf.cc23
-rw-r--r--gprofng/src/Dwarf.h1
-rw-r--r--gprofng/src/DwarfLib.cc19
-rw-r--r--gprofng/src/Elf.cc118
-rw-r--r--gprofng/src/Elf.h12
-rw-r--r--gprofng/src/Experiment.cc3
-rw-r--r--gprofng/src/Experiment.h4
-rw-r--r--gprofng/src/LoadObject.cc80
-rw-r--r--gprofng/src/LoadObject.h10
-rw-r--r--gprofng/src/Module.cc2
-rw-r--r--gprofng/src/Stabs.cc123
-rw-r--r--gprofng/src/Stabs.h3
-rw-r--r--gprofng/src/gp-archive.cc65
-rw-r--r--gprofng/src/gp-archive.h1
18 files changed, 304 insertions, 210 deletions
diff --git a/gprofng/configure b/gprofng/configure
index 2f4e18c..9ad1def 100755
--- a/gprofng/configure
+++ b/gprofng/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gprofng 2.44.50.
+# Generated by GNU Autoconf 2.69 for gprofng 2.45.50.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gprofng'
PACKAGE_TARNAME='gprofng'
-PACKAGE_VERSION='2.44.50'
-PACKAGE_STRING='gprofng 2.44.50'
+PACKAGE_VERSION='2.45.50'
+PACKAGE_STRING='gprofng 2.45.50'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1362,7 +1362,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gprofng 2.44.50 to adapt to many kinds of systems.
+\`configure' configures gprofng 2.45.50 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1433,7 +1433,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gprofng 2.44.50:";;
+ short | recursive ) echo "Configuration of gprofng 2.45.50:";;
esac
cat <<\_ACEOF
@@ -1547,7 +1547,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-gprofng configure 2.44.50
+gprofng configure 2.45.50
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2079,7 +2079,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gprofng $as_me 2.44.50, which was
+It was created by gprofng $as_me 2.45.50, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3052,7 +3052,7 @@ fi
# Define the identity of the package.
PACKAGE='gprofng'
- VERSION='2.44.50'
+ VERSION='2.45.50'
cat >>confdefs.h <<_ACEOF
@@ -17802,7 +17802,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by gprofng $as_me 2.44.50, which was
+This file was extended by gprofng $as_me 2.45.50, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -17868,7 +17868,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-gprofng config.status 2.44.50
+gprofng config.status 2.45.50
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/gprofng/doc/version.texi b/gprofng/doc/version.texi
index 720791e..477472d 100644
--- a/gprofng/doc/version.texi
+++ b/gprofng/doc/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 6 January 2025
-@set UPDATED-MONTH January 2025
-@set EDITION 2.44.50
-@set VERSION 2.44.50
+@set UPDATED 22 April 2025
+@set UPDATED-MONTH April 2025
+@set EDITION 2.45.50
+@set VERSION 2.45.50
diff --git a/gprofng/libcollector/configure b/gprofng/libcollector/configure
index 0baad7c..ecd1542 100755
--- a/gprofng/libcollector/configure
+++ b/gprofng/libcollector/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gprofng 2.44.50.
+# Generated by GNU Autoconf 2.69 for gprofng 2.45.50.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gprofng'
PACKAGE_TARNAME='gprofng'
-PACKAGE_VERSION='2.44.50'
-PACKAGE_STRING='gprofng 2.44.50'
+PACKAGE_VERSION='2.45.50'
+PACKAGE_STRING='gprofng 2.45.50'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1324,7 +1324,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gprofng 2.44.50 to adapt to many kinds of systems.
+\`configure' configures gprofng 2.45.50 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1395,7 +1395,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gprofng 2.44.50:";;
+ short | recursive ) echo "Configuration of gprofng 2.45.50:";;
esac
cat <<\_ACEOF
@@ -1504,7 +1504,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-gprofng configure 2.44.50
+gprofng configure 2.45.50
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1990,7 +1990,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gprofng $as_me 2.44.50, which was
+It was created by gprofng $as_me 2.45.50, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2967,7 +2967,7 @@ fi
# Define the identity of the package.
PACKAGE='gprofng'
- VERSION='2.44.50'
+ VERSION='2.45.50'
cat >>confdefs.h <<_ACEOF
@@ -16136,7 +16136,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by gprofng $as_me 2.44.50, which was
+This file was extended by gprofng $as_me 2.45.50, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -16202,7 +16202,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-gprofng config.status 2.44.50
+gprofng config.status 2.45.50
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/gprofng/src/Disasm.cc b/gprofng/src/Disasm.cc
index 348718b..3ee50d7 100644
--- a/gprofng/src/Disasm.cc
+++ b/gprofng/src/Disasm.cc
@@ -355,7 +355,7 @@ Disasm::get_funcname_in_plt (uint64_t pc)
{
if (stabs)
{
- Elf *elf = stabs->openElf (true);
+ Elf *elf = stabs->openElf (false);
if (elf)
return elf->get_funcname_in_plt (pc);
}
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index a54cdb1..934ae44 100644
--- a/gprofng/src/Dwarf.cc
+++ b/gprofng/src/Dwarf.cc
@@ -368,6 +368,7 @@ Dwarf::Dwarf (Stabs *_stabs)
debug_infoSec = NULL;
debug_abbrevSec = NULL;
debug_strSec = NULL;
+ debug_alt_strSec = NULL;
debug_lineSec = NULL;
debug_line_strSec = NULL;
debug_rangesSec = NULL;
@@ -384,6 +385,8 @@ Dwarf::Dwarf (Stabs *_stabs)
debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
debug_line_strSec = dwrGetSec (".debug_line_str");
debug_rnglists = NULL;
+ if (elf->gnu_debugalt_file)
+ debug_alt_strSec = elf->gnu_debugalt_file->get_dwr_section (".debug_str");
if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
{
@@ -394,27 +397,16 @@ Dwarf::Dwarf (Stabs *_stabs)
Dwarf::~Dwarf ()
{
- delete debug_infoSec;
- delete debug_abbrevSec;
- delete debug_strSec;
- delete debug_lineSec;
- delete debug_rangesSec;
Destroy (dwrCUs);
}
DwrSec *
Dwarf::dwrGetSec (const char *sec_name)
{
- int secN = elf->elf_get_sec_num (sec_name);
- if (secN > 0)
- {
- Elf_Data *elfData = elf->elf_getdata (secN);
- if (elfData)
- return new DwrSec ((unsigned char *) elfData->d_buf, elfData->d_size,
- elf->need_swap_endian,
- elf->elf_getclass () == ELFCLASS32);
- }
- return NULL;
+ DwrSec *p = elf->get_dwr_section (sec_name);
+ if (p)
+ p->offset = 0;
+ return p;
}
uint64_t
@@ -1182,7 +1174,6 @@ Dwarf::get_debug_rnglists ()
debug_rnglistsSec->size = debug_rnglistsSec->sizeSec;
debug_rnglistsSec->offset = length;
}
- delete debug_rnglistsSec;
debug_rnglists->dump ("Dwarf::get_debug_rnglists");
return debug_rnglists;
}
diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h
index bf8ffb4..14d9878 100644
--- a/gprofng/src/Dwarf.h
+++ b/gprofng/src/Dwarf.h
@@ -78,6 +78,7 @@ public:
DwrSec *debug_infoSec;
DwrSec *debug_abbrevSec;
DwrSec *debug_strSec;
+ DwrSec *debug_alt_strSec;
DwrSec *debug_lineSec;
DwrSec *debug_line_strSec;
DwrSec *debug_rangesSec;
diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index 9e11658..4720ef1 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -53,6 +53,7 @@ extended_opcode2str (int opcode)
CASE_S (DW_LNE_end_sequence);
CASE_S (DW_LNE_set_address);
CASE_S (DW_LNE_define_file);
+ CASE_S (DW_LNS_set_file);
default:
snprintf (buf, sizeof (buf), NTXT ("??? (%d)"), opcode);
buf[sizeof (buf) - 1] = 0;
@@ -141,7 +142,6 @@ get_string (DwrSec *sec, uint64_t off)
return NULL;
}
-
DwrLocation *
DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp)
{
@@ -684,6 +684,8 @@ DwrCU::form2str (int tag)
CASE_S (DW_FORM_strp);
CASE_S (DW_FORM_udata);
CASE_S (DW_FORM_ref_addr);
+ CASE_S (DW_FORM_GNU_ref_alt);
+ CASE_S (DW_FORM_GNU_strp_alt);
CASE_S (DW_FORM_ref1);
CASE_S (DW_FORM_ref2);
CASE_S (DW_FORM_ref4);
@@ -741,6 +743,7 @@ Dwr_Tag::dump ()
case DW_FORM_strp:
case DW_FORM_string:
case DW_FORM_line_strp:
+ case DW_FORM_GNU_strp_alt:
case DW_FORM_strp_sup:
case DW_FORM_strx1:
case DW_FORM_strx2:
@@ -781,6 +784,7 @@ Dwr_Tag::dump ()
case DW_FORM_ref_udata:
case DW_FORM_indirect:
case DW_FORM_sec_offset:
+ case DW_FORM_GNU_ref_alt:
case DW_FORM_exprloc:
case DW_FORM_ref_sig8:
case DW_FORM_flag_present:
@@ -1021,6 +1025,7 @@ DwrSec::get_value (int dw_form)
case DW_FORM_line_strp:
case DW_FORM_strp:
case DW_FORM_strp_sup:
+ case DW_FORM_GNU_strp_alt:
return GetRef ();
case DW_FORM_data1:
return Get_8 ();
@@ -1284,6 +1289,8 @@ DwrLineRegs::read_file_names_dwarf5 ()
nm = get_string (dwarf->debug_line_strSec, off);
else if (efmt[k].form_code == DW_FORM_strp)
nm = get_string (dwarf->debug_strSec, off);
+ else if (efmt[k].form_code == DW_FORM_GNU_strp_alt)
+ nm = get_string (dwarf->debug_alt_strSec, off);
}
break;
case DW_LNCT_directory_index:
@@ -1581,7 +1588,7 @@ DwrCU::DwrCU (Dwarf *_dwarf)
if (DUMP_DWARFLIB)
{
Dprintf (DUMP_DWARFLIB,
- "CU_HEADER: header_offset = 0x%08llx %lld"
+ "File: %s\nCU_HEADER: header_offset = 0x%08llx %lld"
" next_header_offset=0x%08llx %lld\n"
" abbrev_offset = 0x%08llx %lld\n"
" unit_length = %lld\n"
@@ -1589,6 +1596,7 @@ DwrCU::DwrCU (Dwarf *_dwarf)
" address_size = %d\n"
" fmt64 = %s\n"
"debug_info: need_swap_endian=%s fmt64=%s addr32=%s\n",
+ dwarf->elf->get_location (),
(long long) cu_offset, (long long) cu_offset,
(long long) next_cu_offset, (long long) next_cu_offset,
(long long) debug_abbrev_offset, (long long) debug_abbrev_offset,
@@ -1788,6 +1796,9 @@ DwrCU::set_die (Dwarf_Die die)
else
atf->u.offset = debug_infoSec->GetADDR ();
break;
+ case DW_FORM_GNU_ref_alt:
+ atf->u.offset = debug_infoSec->GetRef ();
+ break;
case DW_FORM_sec_offset:
atf->u.offset = debug_infoSec->GetRef ();
break;
@@ -1811,6 +1822,10 @@ DwrCU::set_die (Dwarf_Die die)
case DW_FORM_rnglistx:
atf->u.offset = debug_infoSec->GetULEB128 ();
break;
+ case DW_FORM_GNU_strp_alt:
+ atf->u.offset = debug_infoSec->GetRef ();
+ atf->u.str = get_string (dwarf->debug_alt_strSec, atf->u.offset);
+ break;
case DW_FORM_strx:
atf->u.offset = debug_infoSec->GetULEB128 ();
atf->u.str = get_string (dwarf->debug_strSec, atf->u.offset);
diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc
index b90ad29..e63e3c3 100644
--- a/gprofng/src/Elf.cc
+++ b/gprofng/src/Elf.cc
@@ -29,6 +29,7 @@
#include "StringBuilder.h"
#include "DbeFile.h"
#include "DbeSession.h"
+#include "Dwarf.h"
typedef uint32_t Elf32_Word;
typedef uint32_t Elf64_Word;
@@ -84,6 +85,31 @@ struct S_Elf64_Dyn
} d_un;
};
+#ifndef DEBUGDIR
+#define DEBUGDIR "/lib/debug"
+#endif
+#ifndef EXTRA_DEBUG_ROOT1
+#define EXTRA_DEBUG_ROOT1 "/usr/lib/debug"
+#endif
+#ifndef EXTRA_DEBUG_ROOT2
+#define EXTRA_DEBUG_ROOT2 "/usr/lib/debug/usr"
+#endif
+
+static const char *debug_dirs[] = {
+ DEBUGDIR, EXTRA_DEBUG_ROOT1, EXTRA_DEBUG_ROOT2, "."
+};
+
+template<> void Vector<asymbol *>::dump (const char *msg)
+{
+ Dprintf (1, NTXT ("\nFile: %s Vector<asymbol *> [%ld]\n"),
+ msg ? msg : "NULL", (long) size ());
+ for (long i = 0, sz = size (); i < sz; i++)
+ {
+ asymbol *sym = get (i);
+ Dprintf (1, " %3ld %s\n", i, sym->name);
+ }
+}
+
int Elf::bfd_status = -1;
void
@@ -100,6 +126,8 @@ Elf::Elf (char *filename) : DbeMessages (), Data_window (filename)
ancillary_files = NULL;
elfSymbols = NULL;
gnu_debug_file = NULL;
+ gnu_debugalt_file = NULL;
+ sections = NULL;
dbeFile = NULL;
abfd = NULL;
bfd_symcnt = -1;
@@ -209,6 +237,12 @@ Elf::~Elf ()
}
free (data);
}
+ if (sections)
+ {
+ for (int i = 0; i < (int) ehdrp->e_shnum; i++)
+ delete sections[i];
+ free (sections);
+ }
if (ancillary_files)
{
ancillary_files->destroy ();
@@ -216,6 +250,7 @@ Elf::~Elf ()
}
delete elfSymbols;
delete gnu_debug_file;
+ delete gnu_debugalt_file;
delete dbeFile;
delete synthsym;
free (bfd_sym);
@@ -338,9 +373,36 @@ Elf::get_sec_name (unsigned int sec)
return elf_strptr (ehdrp->e_shstrndx, shdr->sh_name);
}
+DwrSec *
+Elf::get_dwr_section (const char *sec_name)
+{
+ int sec_num = elf_get_sec_num (sec_name);
+ if (sec_num > 0)
+ {
+ if (sections == NULL)
+ {
+ sections = (DwrSec **) xmalloc (ehdrp->e_shnum * sizeof (DwrSec *));
+ for (int i = 0; i < (int) ehdrp->e_shnum; i++)
+ sections[i] = NULL;
+ }
+ if (sections[sec_num] == NULL)
+ {
+ Elf_Data *elfData = elf_getdata (sec_num);
+ if (elfData)
+ sections[sec_num] = new DwrSec ((unsigned char *) elfData->d_buf,
+ elfData->d_size, need_swap_endian,
+ elf_getclass () == ELFCLASS32);
+ }
+ return sections[sec_num];
+ }
+ return NULL;
+}
+
Elf_Data *
Elf::elf_getdata (unsigned int sec)
{
+ if (sec == 0)
+ return NULL;
if (data == NULL)
{
data = (Elf_Data **) xmalloc (ehdrp->e_shnum * sizeof (Elf_Data *));
@@ -565,25 +627,54 @@ Elf::get_related_file (const char *lo_name, const char *nm)
return NULL;
}
-Elf *
-Elf::find_ancillary_files (char *lo_name)
+static char *
+find_file (char *(bfd_func) (bfd *, const char *), bfd *abfd)
{
- // read the .gnu_debuglink and .SUNW_ancillary seections
- if (gnu_debug_file)
- return gnu_debug_file;
- unsigned int sec = elf_get_sec_num (NTXT (".gnu_debuglink"));
- if (sec > 0)
+ char *fnm = NULL;
+ for (size_t i = 0; i < ARR_SIZE (debug_dirs); i++)
+ {
+ fnm = bfd_func (abfd, debug_dirs[i]);
+ if (fnm)
+ break;
+ }
+ Dprintf (DUMP_DWARFLIB, "FOUND: gnu_debug_file: %s --> %s\n",
+ abfd->filename, fnm);
+ return fnm;
+}
+
+void
+Elf::find_gnu_debug_files ()
+{
+ char *fnm;
+ if (gnu_debug_file == NULL)
{
- Elf_Data *dp = elf_getdata (sec);
- if (dp)
+ fnm = find_file (bfd_follow_gnu_debuglink, abfd);
+ if (fnm)
{
- gnu_debug_file = get_related_file (lo_name, (char *) (dp->d_buf));
+ gnu_debug_file = Elf::elf_begin (fnm);
+ free (fnm);
if (gnu_debug_file)
- return gnu_debug_file;
+ gnu_debug_file->find_gnu_debug_files ();
}
}
+ if (gnu_debugalt_file == NULL)
+ {
+ fnm = find_file (bfd_follow_gnu_debugaltlink, abfd);
+ if (fnm)
+ {
+ gnu_debugalt_file = Elf::elf_begin (fnm);
+ free (fnm);
+ }
+ }
+}
- sec = elf_get_sec_num (NTXT (".SUNW_ancillary"));
+void
+Elf::find_ancillary_files (const char *lo_name)
+{
+ // read the .SUNW_ancillary section
+ if (ancillary_files != NULL)
+ return;
+ unsigned int sec = elf_get_sec_num (".SUNW_ancillary");
if (sec > 0)
{
Elf_Internal_Shdr *shdr = get_shdr (sec);
@@ -644,7 +735,6 @@ Elf::find_ancillary_files (char *lo_name)
}
}
}
- return NULL;
}
void
@@ -717,6 +807,8 @@ Elf::get_funcname_in_plt (uint64_t pc)
for (long i = 0; i < bfd_synthcnt; i++)
synthsym->append (bfd_synthsym + i);
synthsym->sort (cmp_sym_addr);
+ if (DUMP_ELF_SYM)
+ synthsym->dump (get_location ());
}
asymbol sym, *symp = &sym;
diff --git a/gprofng/src/Elf.h b/gprofng/src/Elf.h
index 6667670..2d227f7 100644
--- a/gprofng/src/Elf.h
+++ b/gprofng/src/Elf.h
@@ -32,6 +32,7 @@
class Symbol;
class DbeFile;
+class DwrSec;
template <class ITEM> class Vector;
template <typename Key_t, typename Value_t> class Map;
@@ -93,7 +94,14 @@ public:
long elf_getSymCount (bool is_dynamic);
asymbol *elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic);
Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
- Elf *find_ancillary_files (char *lo_name); // read the .gnu_debuglink and .SUNW_ancillary seections
+
+ // read the .SUNW_ancillary section
+ void find_ancillary_files (const char *lo_name);
+
+ // read the .gnu_debuglink and .gnu_debugaltlink sections
+ void find_gnu_debug_files ();
+
+ DwrSec *get_dwr_section (const char *sec_name); // Used in Dwarf reader
const char *get_funcname_in_plt (uint64_t pc);
char *get_location ();
char *dump ();
@@ -126,6 +134,7 @@ public:
Elf_status status;
Vector<Elf*> *ancillary_files;
Elf *gnu_debug_file;
+ Elf *gnu_debugalt_file; // if the .gun_debugaltlink section presents
DbeFile *dbeFile;
Map<const char*, Symbol*> *elfSymbols;
unsigned int analyzerInfo, stab, stabStr;
@@ -139,6 +148,7 @@ protected:
int elf_datatype;
Elf_Internal_Ehdr *ehdrp;
Elf_Data **data;
+ DwrSec **sections;
bfd *abfd;
static int bfd_status;
long bfd_symcnt;
diff --git a/gprofng/src/Experiment.cc b/gprofng/src/Experiment.cc
index 4cbb7f6..2768927 100644
--- a/gprofng/src/Experiment.cc
+++ b/gprofng/src/Experiment.cc
@@ -6811,7 +6811,8 @@ Experiment::copy_file_to_common_archive (const char *name, const char *aname,
* @return 0 - success
*/
int
-Experiment::copy_file (char *name, char *aname, int hide_msg, char *common_archive, int relative_path)
+Experiment::copy_file (const char *name, const char *aname, int hide_msg,
+ const char *common_archive, int relative_path)
{
if (common_archive)
{
diff --git a/gprofng/src/Experiment.h b/gprofng/src/Experiment.h
index c85aadd..9a3d226 100644
--- a/gprofng/src/Experiment.h
+++ b/gprofng/src/Experiment.h
@@ -267,8 +267,8 @@ public:
static int copy_file_to_archive (const char *name, const char *aname, int hide_msg);
static int copy_file_to_common_archive (const char *name, const char *aname,
int hide_msg, const char *common_archive, int relative_path = 0);
- static int copy_file (char *name, char *aname, int hide_msg,
- char *common_archive = NULL, int relative_path = 0);
+ static int copy_file (const char *name, const char *aname, int hide_msg,
+ const char *common_archive = NULL, int relative_path = 0);
// get_raw_events()
// action: get unfiltered packets, loading them if required
diff --git a/gprofng/src/LoadObject.cc b/gprofng/src/LoadObject.cc
index bf49e9d..7b4bef2 100644
--- a/gprofng/src/LoadObject.cc
+++ b/gprofng/src/LoadObject.cc
@@ -102,7 +102,6 @@ LoadObject::LoadObject (const char *loname)
noname = dbeSession->createUnknownModule (this);
modules->put (noname->get_name (), noname);
pathname = NULL;
- arch_name = NULL;
runTimePath = NULL;
objStabs = NULL;
firstExp = NULL;
@@ -135,7 +134,6 @@ LoadObject::~LoadObject ()
delete modules;
delete elf_lo;
free (pathname);
- free (arch_name);
free (runTimePath);
delete objStabs;
delete warnq;
@@ -167,45 +165,66 @@ LoadObject::get_elf ()
{
case Elf::ELF_ERR_CANT_OPEN_FILE:
append_msg (CMSG_ERROR, GTXT ("Cannot open ELF file `%s'"), fnm);
- break;
+ return NULL;
case Elf::ELF_ERR_BAD_ELF_FORMAT:
default:
append_msg (CMSG_ERROR, GTXT ("Cannot read ELF header of `%s'"),
fnm);
- break;
+ return NULL;
}
+ if (dbeFile->inArchive)
+ {
+ // Try to find gnu_debug and gnu debug_alt files in archive
+ char *nm = dbe_sprintf ("%s_debug", fnm);
+ elf_lo->gnu_debug_file = Elf::elf_begin (nm);
+ free (nm);
+ if (elf_lo->gnu_debug_file)
+ {
+ nm = dbe_sprintf ("%s_debug_alt", fnm);
+ elf_lo->gnu_debug_file->gnu_debugalt_file = Elf::elf_begin (nm);
+ free (nm);
+ }
+ nm = dbe_sprintf ("%s_alt", fnm);
+ elf_lo->gnu_debugalt_file = Elf::elf_begin (nm);
+ free (nm);
+ }
+ else if (checksum != 0 && elf_lo->elf_checksum () != 0 &&
+ checksum != elf_lo->elf_checksum ())
+ {
+ char *msg = dbe_sprintf (GTXT ("%s has an unexpected checksum value;"
+ "perhaps it was rebuilt. File ignored"),
+ dbeFile->get_location ());
+ commentq->append (new Emsg (CMSG_ERROR, msg));
+ delete msg;
+ delete elf_lo;
+ elf_lo = NULL;
+ return NULL;
+ }
+ elf_lo->find_gnu_debug_files ();
+ elf_lo->find_ancillary_files (get_pathname ());
}
return elf_lo;
}
Stabs *
-LoadObject::openDebugInfo (char *fname, Stabs::Stab_status *stp)
+LoadObject::openDebugInfo (Stabs::Stab_status *stp)
{
if (objStabs == NULL)
{
- if (fname == NULL)
- return NULL;
- objStabs = new Stabs (fname, get_pathname ());
- Stabs::Stab_status st = objStabs->get_status ();
- if ((st == Stabs::DBGD_ERR_NONE) && (checksum != 0))
+ Stabs::Stab_status st = Stabs::DBGD_ERR_BAD_ELF_LIB;
+ Elf *elf = get_elf ();
+ if (elf)
{
- Elf *elf = get_elf ();
- if (elf && (checksum != elf->elf_checksum ()))
+ objStabs = new Stabs (elf, get_pathname ());
+ st = objStabs->get_status ();
+ if (st != Stabs::DBGD_ERR_NONE)
{
- char *buf = dbe_sprintf (GTXT ("*** Note: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored"),
- fname);
- commentq->append (new Emsg (CMSG_ERROR, buf));
- delete buf;
- st = Stabs::DBGD_ERR_CHK_SUM;
+ delete objStabs;
+ objStabs = NULL;
}
}
if (stp)
*stp = st;
- if (st != Stabs::DBGD_ERR_NONE)
- {
- delete objStabs;
- objStabs = NULL;
- }
}
return objStabs;
}
@@ -560,7 +579,7 @@ fixFuncAlias (Vector<Function*> *SymLst)
void
LoadObject::post_process_functions ()
{
- if (flags & SEG_FLAG_DYNAMIC || platform == Java)
+ if ((flags & SEG_FLAG_DYNAMIC) != 0 || platform == Java)
return;
char *msg = GTXT ("Processing Load Object Data");
@@ -726,21 +745,8 @@ LoadObject::read_stabs ()
delete msg;
return ARCHIVE_ERR_OPEN;
}
- else if (checksum != 0 && checksum != elf->elf_checksum ())
- {
- char *msg = dbe_sprintf (GTXT ("%s has an unexpected checksum value;"
- "perhaps it was rebuilt. File ignored"),
- dbeFile->get_location ());
- commentq->append (new Emsg (CMSG_ERROR, msg));
- delete msg;
- return ARCHIVE_ERR_OPEN;
- }
Stabs::Stab_status status = Stabs::DBGD_ERR_CANT_OPEN_FILE;
- char *location = dbeFile->get_location (true);
- if (location == NULL)
- return ARCHIVE_ERR_OPEN;
-
- if (openDebugInfo (location, &status))
+ if (openDebugInfo (&status))
{
status = objStabs->read_archive (this);
isRelocatable = objStabs->is_relocatable ();
diff --git a/gprofng/src/LoadObject.h b/gprofng/src/LoadObject.h
index dd40ea0..c93594b 100644
--- a/gprofng/src/LoadObject.h
+++ b/gprofng/src/LoadObject.h
@@ -117,13 +117,6 @@ public:
return pathname;
}
- void
- set_archname (char *aname)
- {
- free (arch_name);
- arch_name = aname;
- }
-
bool
is_relocatable ()
{
@@ -144,7 +137,7 @@ public:
Module *get_comparable_Module (Module *mod);
void append_module (Module *mod);
Elf *get_elf ();
- Stabs *openDebugInfo (char *fname, Stabs::Stab_status *stp = NULL);
+ Stabs *openDebugInfo (Stabs::Stab_status *stp = NULL);
Arch_status read_stabs ();
Arch_status sync_read_stabs ();
void post_process_functions ();
@@ -192,7 +185,6 @@ private:
char *pathname; // User name of object file
ino64_t inode; // inode number of segment file
bool isRelocatable; // is relocatable .o
- char *arch_name; // .archive name
Emsgqueue *warnq;
Emsgqueue *commentq;
Function **funcHTable; // hash table for functions
diff --git a/gprofng/src/Module.cc b/gprofng/src/Module.cc
index a62d3e8..55091ad 100644
--- a/gprofng/src/Module.cc
+++ b/gprofng/src/Module.cc
@@ -131,7 +131,7 @@ Stabs *
Module::openDebugInfo ()
{
setFile ();
- objStabs = loadobject->openDebugInfo (disPath);
+ objStabs = loadobject->openDebugInfo ();
return objStabs;
}
diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc
index 53f7ef1..20bdf8b 100644
--- a/gprofng/src/Stabs.cc
+++ b/gprofng/src/Stabs.cc
@@ -163,9 +163,11 @@ Stabs::removeDupSyms ()
SymLst->truncate (last);
}
-Stabs::Stabs (char *_path, char *_lo_name)
+Stabs::Stabs (Elf *elf, char *_lo_name)
{
- path = dbe_strdup (_path);
+ elfDis = elf;
+ elfDbg = elf->gnu_debug_file ? elf->gnu_debug_file : elf;
+ path = dbe_strdup (elf->get_location ());
lo_name = dbe_strdup (_lo_name);
SymLstByName = NULL;
pltSym = NULL;
@@ -175,16 +177,12 @@ Stabs::Stabs (char *_path, char *_lo_name)
LocalFileIdx = new Vector<int>;
last_PC_to_sym = NULL;
dwarf = NULL;
- elfDbg = NULL;
- elfDis = NULL;
stabsModules = NULL;
textsz = 0;
wsize = Wnone;
st_check_symtab = false;
status = DBGD_ERR_NONE;
- if (openElf (false) == NULL)
- return;
switch (elfDis->elf_getclass ())
{
case ELFCLASS32:
@@ -194,6 +192,31 @@ Stabs::Stabs (char *_path, char *_lo_name)
wsize = W64;
break;
}
+ switch (elfDis->elf_getehdr ()->e_machine)
+ {
+ case EM_SPARC:
+ platform = Sparc;
+ break;
+ case EM_SPARC32PLUS:
+ platform = Sparcv8plus;
+ break;
+ case EM_SPARCV9:
+ platform = Sparcv9;
+ break;
+ case EM_386:
+ // case EM_486:
+ platform = Intel;
+ break;
+ case EM_X86_64:
+ platform = Amd64;
+ break;
+ case EM_AARCH64:
+ platform = Aarch64;
+ break;
+ default:
+ platform = Unknown;
+ break;
+ }
isRelocatable = elfDis->elf_getehdr ()->e_type == ET_REL;
for (unsigned int pnum = 0; pnum < elfDis->elf_getehdr ()->e_phnum; pnum++)
{
@@ -216,7 +239,6 @@ Stabs::~Stabs ()
delete SymLstByName;
Destroy (SymLst);
Destroy (LocalFile);
- delete elfDis;
delete dwarf;
delete LocalLst;
delete LocalFileIdx;
@@ -226,90 +248,11 @@ Stabs::~Stabs ()
}
Elf *
-Stabs::openElf (char *fname, Stab_status &st)
-{
- Elf::Elf_status elf_status;
- Elf *elf = Elf::elf_begin (fname, &elf_status);
- if (elf == NULL)
- {
- switch (elf_status)
- {
- case Elf::ELF_ERR_CANT_OPEN_FILE:
- case Elf::ELF_ERR_CANT_MMAP:
- case Elf::ELF_ERR_BIG_FILE:
- st = DBGD_ERR_CANT_OPEN_FILE;
- break;
- case Elf::ELF_ERR_BAD_ELF_FORMAT:
- default:
- st = DBGD_ERR_BAD_ELF_FORMAT;
- break;
- }
- return NULL;
- }
- if (elf->elf_version (EV_CURRENT) == EV_NONE)
- {
- // ELF library out of date
- delete elf;
- st = DBGD_ERR_BAD_ELF_LIB;
- return NULL;
- }
-
- Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr ();
- if (ehdrp == NULL)
- {
- // check machine
- delete elf;
- st = DBGD_ERR_BAD_ELF_FORMAT;
- return NULL;
- }
- switch (ehdrp->e_machine)
- {
- case EM_SPARC:
- platform = Sparc;
- break;
- case EM_SPARC32PLUS:
- platform = Sparcv8plus;
- break;
- case EM_SPARCV9:
- platform = Sparcv9;
- break;
- case EM_386:
- // case EM_486:
- platform = Intel;
- break;
- case EM_X86_64:
- platform = Amd64;
- break;
- case EM_AARCH64:
- platform = Aarch64;
- break;
- default:
- platform = Unknown;
- break;
- }
- return elf;
-}
-
-Elf *
Stabs::openElf (bool dbg_info)
{
- if (status != DBGD_ERR_NONE)
- return NULL;
- if (elfDis == NULL)
- {
- elfDis = openElf (path, status);
- if (elfDis == NULL)
- return NULL;
- }
- if (!dbg_info)
- return elfDis;
- if (elfDbg == NULL)
- {
- elfDbg = elfDis->find_ancillary_files (lo_name);
- if (elfDbg == NULL)
- elfDbg = elfDis;
- }
- return elfDbg;
+ if (dbg_info)
+ return elfDbg;
+ return elfDis;
}
bool
@@ -1603,7 +1546,7 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic)
switch (GELF_ST_TYPE (Sym.st_info))
{
case STT_FUNC:
- if (Sym.st_size == 0 || ELF_ST_BIND (Sym.st_info) == STB_WEAK)
+ if (Sym.st_size == 0)
break;
if (Sym.st_shndx == 0)
{
diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h
index f0e162b..cd10c25 100644
--- a/gprofng/src/Stabs.h
+++ b/gprofng/src/Stabs.h
@@ -76,7 +76,7 @@ class Stabs {
DBGD_ERR_CHK_SUM
};
- Stabs(char *_path, char *_lo_name);
+ Stabs(Elf *elf, char *_lo_name);
~Stabs();
bool is_relocatable(){ return isRelocatable; }
@@ -136,7 +136,6 @@ class Stabs {
Vector<char*> *LocalFile; // list of local files
Vector<int> *LocalFileIdx; // start index in LocalLst
- Elf *openElf(char *fname, Stab_status &st);
Map<const char*, Symbol*> *get_elf_symbols();
Dwarf *dwarf;
diff --git a/gprofng/src/gp-archive.cc b/gprofng/src/gp-archive.cc
index ee9f917..2c15da8 100644
--- a/gprofng/src/gp-archive.cc
+++ b/gprofng/src/gp-archive.cc
@@ -357,25 +357,59 @@ er_archive::start (int argc, char *argv[])
}
lo->sync_read_stabs ();
Elf *elf = lo->get_elf ();
- if (elf && (lo->checksum != 0) && (lo->checksum != elf->elf_checksum ()))
+ if (elf == NULL)
{
if (!quiet)
- fprintf (stderr, GTXT ("gp-archive: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored\n"),
+ fprintf (stderr, GTXT ("gp-archive: Cannot open \"%s\"\n"),
df->get_location ());
+ Dprintf (DEBUG_ARCHIVE,
+ " loadObjs[%ld]: not found '%s'\n", i, df->get_location ());
+ continue;
+ }
+ else if (df->inArchive)
+ {
+ Dprintf (DEBUG_ARCHIVE,
+ " loadObjs[%ld]: inArchive=1 '%s'\n", i, df->get_name ());
continue;
}
- copy_files->append (df);
- if (elf)
+ else if (!mask_is_on (df->get_name ()))
+ {
+ Dprintf (DEBUG_ARCHIVE,
+ " loadObjs[%ld]: mask_is_on=0 '%s'\n", i, df->get_name ());
+ continue;
+ }
+ char *fnm = elf->get_location ();
+ char *anm = founder_exp->getNameInArchive (fnm);
+ archive_file (fnm, anm);
+
+ // archive gnu_debug and gnu_debugalt files
+ if (elf->gnu_debug_file)
{
- Elf *f = elf->find_ancillary_files (lo->get_pathname ());
- if (f)
- copy_files->append (f->dbeFile);
- for (long i1 = 0, sz1 = VecSize(elf->ancillary_files); i1 < sz1; i1++)
+ char *arch_nm = dbe_sprintf ("%s_debug", anm);
+ archive_file (elf->gnu_debug_file->get_location (), arch_nm);
+ free (arch_nm);
+ if (elf->gnu_debug_file->gnu_debugalt_file)
{
- Elf *ancElf = elf->ancillary_files->get (i1);
- copy_files->append (ancElf->dbeFile);
+ arch_nm = dbe_sprintf ("%s_debug_alt", anm);
+ archive_file (elf->gnu_debug_file->gnu_debugalt_file->get_location (), arch_nm);
+ free (arch_nm);
}
}
+ if (elf->gnu_debugalt_file)
+ {
+ char *arch_nm = dbe_sprintf ("%s_alt", anm);
+ archive_file (elf->gnu_debugalt_file->get_location (), arch_nm);
+ free (arch_nm);
+ }
+ free (anm);
+
+ elf->find_ancillary_files (lo->get_pathname ());
+ for (long i1 = 0, sz1 = VecSize (elf->ancillary_files); i1 < sz1; i1++)
+ {
+ Elf *ancElf = elf->ancillary_files->get (i1);
+ copy_files->append (ancElf->dbeFile);
+ }
+
Vector<Module*> *modules = lo->seg_modules;
for (long i1 = 0, sz1 = VecSize(modules); i1 < sz1; i1++)
{
@@ -469,7 +503,7 @@ er_archive::start (int argc, char *argv[])
int res = founder_exp->copy_file (fnm, anm, quiet, common_archive_dir, use_relative_path);
if (0 == res) // file successfully archived
df->inArchive = 1;
- delete anm;
+ free (anm);
}
delete copy_files;
@@ -490,6 +524,15 @@ er_archive::start (int argc, char *argv[])
}
int
+er_archive::archive_file (const char *from, const char *to)
+{
+ if (force)
+ unlink (to);
+ return Experiment::copy_file (from, to, quiet, common_archive_dir,
+ use_relative_path);
+}
+
+int
er_archive::check_args (int argc, char *argv[])
{
int opt;
diff --git a/gprofng/src/gp-archive.h b/gprofng/src/gp-archive.h
index 41fb4b2..3b9d0ee 100644
--- a/gprofng/src/gp-archive.h
+++ b/gprofng/src/gp-archive.h
@@ -47,6 +47,7 @@ public:
private:
void usage ();
int check_args (int argc, char *argv[]);
+ int archive_file (const char *from, const char *to);
int clean_old_archive (char *expname, ArchiveExp *founder_exp);
int mask_is_on (const char *str);
void check_env_var ();