diff options
Diffstat (limited to 'gprofng/src')
-rw-r--r-- | gprofng/src/Disasm.cc | 17 | ||||
-rw-r--r-- | gprofng/src/Disasm.h | 3 | ||||
-rw-r--r-- | gprofng/src/Dwarf.cc | 30 | ||||
-rw-r--r-- | gprofng/src/Dwarf.h | 1 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.cc | 285 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.h | 3 | ||||
-rw-r--r-- | gprofng/src/Elf.cc | 225 | ||||
-rw-r--r-- | gprofng/src/Elf.h | 42 | ||||
-rw-r--r-- | gprofng/src/Experiment.cc | 3 | ||||
-rw-r--r-- | gprofng/src/Experiment.h | 4 | ||||
-rw-r--r-- | gprofng/src/LoadObject.cc | 80 | ||||
-rw-r--r-- | gprofng/src/LoadObject.h | 10 | ||||
-rw-r--r-- | gprofng/src/Module.cc | 2 | ||||
-rw-r--r-- | gprofng/src/Stabs.cc | 184 | ||||
-rw-r--r-- | gprofng/src/Stabs.h | 5 | ||||
-rw-r--r-- | gprofng/src/gp-archive.cc | 65 | ||||
-rw-r--r-- | gprofng/src/gp-archive.h | 1 |
17 files changed, 281 insertions, 679 deletions
diff --git a/gprofng/src/Disasm.cc b/gprofng/src/Disasm.cc index 42fb777..3ee50d7 100644 --- a/gprofng/src/Disasm.cc +++ b/gprofng/src/Disasm.cc @@ -50,19 +50,6 @@ struct DisContext static const int MAX_DISASM_STR = 2048; -Disasm::Disasm (char *fname) -{ - dwin = NULL; - dis_str = NULL; - need_swap_endian = false; - my_stabs = Stabs::NewStabs (fname, fname); - if (my_stabs == NULL) - return; - stabs = my_stabs; - platform = stabs->get_platform (); - disasm_open (); -} - Disasm::Disasm (Platform_t _platform, Stabs *_stabs) { dwin = NULL; @@ -70,7 +57,6 @@ Disasm::Disasm (Platform_t _platform, Stabs *_stabs) need_swap_endian = false; stabs = _stabs; platform = _platform; - my_stabs = NULL; disasm_open (); } @@ -263,7 +249,6 @@ Disasm::disasm_open () Disasm::~Disasm () { - delete my_stabs; delete dwin; delete dis_str; } @@ -370,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/Disasm.h b/gprofng/src/Disasm.h index 0326b5c..3d7159d 100644 --- a/gprofng/src/Disasm.h +++ b/gprofng/src/Disasm.h @@ -31,7 +31,6 @@ enum Platform_t; class Disasm { public: - Disasm (char *fname); Disasm (Platform_t _platform, Stabs *_stabs); ~Disasm (); void remove_disasm_hndl (void *hndl); @@ -59,7 +58,7 @@ private: disassemble_info dis_info; Data_window *dwin; - Stabs *stabs, *my_stabs; + Stabs *stabs; Platform_t platform; char addr_fmt[32]; int hex_visible; diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index 85891099..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; @@ -378,19 +379,14 @@ Dwarf::Dwarf (Stabs *_stabs) return; } debug_infoSec = dwrGetSec (NTXT (".debug_info")); - if (debug_infoSec) - { - debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL); - debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc); - if (debug_infoSec->reloc) - debug_infoSec->reloc->dump (); - } debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev")); debug_strSec = dwrGetSec (NTXT (".debug_str")); debug_lineSec = dwrGetSec (NTXT (".debug_line")); 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)) { @@ -401,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 @@ -1189,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 79be8cf..4720ef1 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -35,31 +35,6 @@ #define CASE_S(x) case x: s = (char *) #x; break static char * -gelf_st_type2str (int type) -{ - static char buf[128]; - char *s; - switch (type) - { - CASE_S (STT_NOTYPE); - CASE_S (STT_OBJECT); - CASE_S (STT_FUNC); - CASE_S (STT_SECTION); - CASE_S (STT_FILE); - CASE_S (STT_COMMON); - CASE_S (STT_TLS); - // CASE_S(STT_NUM); - CASE_S (STT_LOPROC); - CASE_S (STT_HIPROC); - default: s = NTXT ("???"); - break; - } - snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type); - buf[sizeof (buf) - 1] = 0; - return buf; -} - -static char * special_opcode2str (int opcode) { static char buf[128]; @@ -78,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; @@ -166,234 +142,6 @@ get_string (DwrSec *sec, uint64_t off) return NULL; } - -////////////////////////////////////////////////////////// -// class ElfReloc - -ElfReloc::ElfReloc (Elf *_elf) -{ - elf = _elf; - reloc = NULL; - cur_reloc_ind = 0; -} - -ElfReloc::~ElfReloc () -{ - if (reloc) - { - reloc->destroy (); - delete reloc; - } -} - -void -ElfReloc::dump_rela_debug_sec (int sec) -{ - if (!DUMP_RELA_SEC) - return; - Elf_Internal_Shdr *shdr = elf->get_shdr (sec); - if (shdr == NULL) - return; - - Elf_Data *data = elf->elf_getdata (sec); - if (data == NULL) - return; - - uint64_t ScnSize = data->d_size; - uint64_t EntSize = shdr->sh_entsize; - if (ScnSize == 0 || EntSize == 0) - return; - - Elf_Internal_Rela rela; - int n, cnt = (int) (ScnSize / EntSize); - - char *sec_name = elf->get_sec_name (sec); - if (sec_name == NULL) // It can not be, but let's check - return; - Dprintf (DUMP_RELA_SEC, - "======= DwarfLib::dump_rela_debug_sec Section:%2d '%s'\n", - sec, sec_name); - Dprintf (DUMP_RELA_SEC, - " N |addend| offset | r_info | stt_type |\n"); - for (n = 0; n < cnt; n++) - { - if (strncmp (sec_name, NTXT (".rela."), 6) == 0) - elf->elf_getrela (data, n, &rela); - else - { - elf->elf_getrel (data, n, &rela); - rela.r_addend = 0; - } - int ndx = (int) GELF_R_SYM (rela.r_info); - Elf_Internal_Shdr *secHdr; - Elf_Internal_Sym sym; - asymbol *asym; - asym = elf->elf_getsym (ndx, &sym, false); - Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"), - n, (int) rela.r_addend, - (long long) rela.r_offset, (long long) rela.r_info, - gelf_st_type2str ((int) GELF_ST_TYPE (sym.st_info))); - switch (GELF_ST_TYPE (sym.st_info)) - { - case STT_FUNC: - case STT_OBJECT: - case STT_NOTYPE: - Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"), - (long long) (bfd_asymbol_value (asym))); - Dprintf (DUMP_RELA_SEC, NTXT (" %s"), bfd_asymbol_name (asym)); - break; - case STT_SECTION: - secHdr = elf->get_shdr (sym.st_shndx); - if (secHdr) - { - Dprintf (DUMP_RELA_SEC, NTXT (" value=0x%016llx (%lld)"), - (long long) (secHdr->sh_offset + rela.r_addend), - (long long) (secHdr->sh_offset + rela.r_addend)); - } - break; - default: - break; - } - Dprintf (DUMP_RELA_SEC, NTXT ("\n")); - } - Dprintf (DUMP_RELA_SEC, NTXT ("\n")); -} - -void -ElfReloc::dump () -{ - if (!DUMP_ELF_RELOC || (reloc == NULL) || (reloc->size () == 0)) - return; - Dprintf (DUMP_ELF_RELOC, NTXT ("======= ElfReloc::dump\n")); - Dprintf (DUMP_ELF_RELOC, NTXT (" N | offset | value | STT_TYPE\n")); - for (int i = 0; i < reloc->size (); i++) - { - Sreloc *srlc = reloc->fetch (i); - Dprintf (DUMP_ELF_RELOC, NTXT ("%3d:%11lld |%11lld | %s\n"), - i, (long long) srlc->offset, (long long) srlc->value, - gelf_st_type2str (srlc->stt_type)); - } - Dprintf (DUMP_ELF_RELOC, NTXT ("\n")); -} - -static int -DwrRelocOffsetCmp (const void *a, const void *b) -{ - ElfReloc::Sreloc *item1 = *((ElfReloc::Sreloc **) a); - ElfReloc::Sreloc *item2 = *((ElfReloc::Sreloc **) b); - return item1->offset < item2->offset ? -1 : - item1->offset == item2->offset ? 0 : 1; -} - -ElfReloc * -ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc) -{ - int et = elfp->elf_getehdr ()->e_type; - if (et == ET_EXEC || et == ET_DYN) - return rlc; - int sec = elfp->elf_get_sec_num (sec_name); - if (sec == 0) - return rlc; - Elf_Internal_Shdr *shdr = elfp->get_shdr (sec); - if (shdr == NULL || shdr->sh_entsize == 0) - return rlc; - - Elf_Data *data = elfp->elf_getdata (sec); - if (data == NULL || data->d_size == 0) - return rlc; - - int cnt = (int) (data->d_size / shdr->sh_entsize); - Vector<Sreloc *> *vp = NULL; - - for (int n = 0; n < cnt; n++) - { - Elf_Internal_Shdr *secHdr; - Sreloc *srlc; - Elf_Internal_Rela rela; - if (strncmp (sec_name, NTXT (".rela."), 6) == 0) - elfp->elf_getrela (data, n, &rela); - else - { - elfp->elf_getrel (data, n, &rela); - rela.r_addend = 0; - } - int ndx = (int) GELF_R_SYM (rela.r_info); - Elf_Internal_Sym sym; - elfp->elf_getsym (ndx, &sym, false); - - srlc = new Sreloc; - srlc->offset = rela.r_offset; - srlc->value = 0; - srlc->stt_type = (int) GELF_ST_TYPE (sym.st_info); - switch (GELF_ST_TYPE (sym.st_info)) - { - case STT_FUNC: - secHdr = elfp->get_shdr (sym.st_shndx); - if (secHdr) - srlc->value = secHdr->sh_offset + sym.st_value; - break; - case STT_OBJECT: - case STT_NOTYPE: - secHdr = elfp->get_shdr (shdr->sh_info); - if (secHdr) - { - srlc->offset = rela.r_info; - srlc->value = secHdr->sh_offset + rela.r_addend; - } - break; - case STT_SECTION: - secHdr = elfp->get_shdr (sym.st_shndx); - if (secHdr) - srlc->value = rela.r_addend; - break; - default: - srlc->value = 0; - break; - } - if (rlc == NULL) - { - rlc = new ElfReloc (elfp); - vp = rlc->reloc; - } - if (vp == NULL) - { - vp = new Vector<Sreloc*>; - rlc->reloc = vp; - } - vp->append (srlc); - } - if (vp) - vp->sort (DwrRelocOffsetCmp); - if (rlc) - { - rlc->dump_rela_debug_sec (sec); - rlc->dump (); - } - return rlc; -} - -long long -ElfReloc::get_reloc_addr (long long offset) -{ - Sreloc *srlc; - int i = cur_reloc_ind - 1; - if (i >= 0 && i < reloc->size ()) - { - srlc = reloc->fetch (i); - if (srlc->offset > offset) // need to reset - cur_reloc_ind = 0; - } - for (; cur_reloc_ind < reloc->size (); cur_reloc_ind++) - { - srlc = reloc->fetch (cur_reloc_ind); - if (srlc->offset == offset) - return srlc->value; - if (srlc->offset > offset) - return 0; - } - return 0; -} - DwrLocation * DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp) { @@ -936,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); @@ -993,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: @@ -1033,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: @@ -1058,34 +810,28 @@ Dwr_Tag::dump () DwrSec::DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32) { - isCopy = false; data = _data; sizeSec = _size; size = (data ? _size : 0); offset = 0; fmt64 = false; - reloc = NULL; need_swap_endian = _need_swap_endian; addr32 = _addr32; } DwrSec::DwrSec (DwrSec *secp, uint64_t _offset) { - isCopy = true; data = secp->data; sizeSec = secp->sizeSec; size = secp->size; offset = _offset; fmt64 = secp->fmt64; - reloc = secp->reloc; need_swap_endian = secp->need_swap_endian; addr32 = secp->addr32; } DwrSec::~DwrSec () { - if (!isCopy) - delete reloc; } bool @@ -1213,17 +959,13 @@ DwrSec::GetLong () uint64_t DwrSec::GetADDR_32 () { - uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0; - res += Get_32 (); - return res; + return Get_32 (); } uint64_t DwrSec::GetADDR_64 () { - uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0; - res += Get_64 (); - return res; + return Get_64 (); } uint64_t @@ -1283,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 (); @@ -1546,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: @@ -1843,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" @@ -1851,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, @@ -2050,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; @@ -2073,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/DwarfLib.h b/gprofng/src/DwarfLib.h index 06b19b8..49ecb41 100644 --- a/gprofng/src/DwarfLib.h +++ b/gprofng/src/DwarfLib.h @@ -23,7 +23,6 @@ #include "dwarf2.h" -class ElfReloc; class Dwr_type; class Function; class Range; @@ -76,7 +75,6 @@ public: return (uint32_t) GetULEB128 (); } - ElfReloc *reloc; uint64_t sizeSec; uint64_t size; uint64_t offset; @@ -87,7 +85,6 @@ public: int segment_selector_size; // DWARF 5 private: - bool isCopy; unsigned char *data; bool bounds_violation (uint64_t sz); }; diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc index f0fd121..e63e3c3 100644 --- a/gprofng/src/Elf.cc +++ b/gprofng/src/Elf.cc @@ -28,6 +28,8 @@ #include "Map.h" #include "StringBuilder.h" #include "DbeFile.h" +#include "DbeSession.h" +#include "Dwarf.h" typedef uint32_t Elf32_Word; typedef uint32_t Elf64_Word; @@ -83,55 +85,30 @@ 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 -// Symbol table -typedef struct -{ - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; /* bind, type: ELF_32_ST_... */ - unsigned char st_other; - Elf32_Half st_shndx; /* SHN_... */ -} Elf32_Sym; - -typedef struct -{ - Elf64_Word st_name; - unsigned char st_info; /* bind, type: ELF_64_ST_... */ - unsigned char st_other; - Elf64_Half st_shndx; /* SHN_... */ - Elf64_Addr st_value; - Elf64_Xword st_size; -} Elf64_Sym; - - -// Relocation -typedef struct -{ - Elf32_Addr r_offset; - Elf32_Word r_info; /* sym, type: ELF32_R_... */ -} Elf32_Rel; - -typedef struct -{ - Elf32_Addr r_offset; - Elf32_Word r_info; /* sym, type: ELF32_R_... */ - Elf32_Sword r_addend; -} Elf32_Rela; - -typedef struct -{ - Elf64_Addr r_offset; - Elf64_Xword r_info; /* sym, type: ELF64_R_... */ -} Elf64_Rel; +static const char *debug_dirs[] = { + DEBUGDIR, EXTRA_DEBUG_ROOT1, EXTRA_DEBUG_ROOT2, "." +}; -typedef struct +template<> void Vector<asymbol *>::dump (const char *msg) { - Elf64_Addr r_offset; - Elf64_Xword r_info; /* sym, type: ELF64_R_... */ - Elf64_Sxword r_addend; -} Elf64_Rela; + 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; @@ -149,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; @@ -196,23 +175,13 @@ Elf::Elf (char *filename) : DbeMessages (), Data_window (filename) } status = ELF_ERR_NONE; -#if ARCH(SPARC) - need_swap_endian = is_Intel (); -#else - need_swap_endian = !is_Intel (); -#endif - + need_swap_endian = DbeSession::is_bigendian () != bfd_big_endian (abfd); analyzerInfo = 0; - SUNW_ldynsym = 0; - gnuLink = 0; stab = 0; - stabStr = 0; stabIndex = 0; stabIndexStr = 0; stabExcl = 0; stabExclStr = 0; - symtab = 0; - dynsym = 0; info = 0; plt = 0; dwarf = false; @@ -234,20 +203,12 @@ Elf::Elf (char *filename) : DbeMessages (), Data_window (filename) stabExcl = sec; else if (streq (name, NTXT (".stab.exclstr"))) stabExclStr = sec; - else if (streq (name, NTXT (".gnu_debuglink"))) - gnuLink = sec; else if (streq (name, NTXT (".__analyzer_info"))) analyzerInfo = sec; else if (streq (name, NTXT (".info"))) info = true; else if (streq (name, NTXT (".plt"))) plt = sec; - else if (streq (name, NTXT (".SUNW_ldynsym"))) - SUNW_ldynsym = sec; - else if (streq (name, NTXT (".dynsym"))) - dynsym = sec; - else if (streq (name, NTXT (".symtab"))) - symtab = sec; else if (strncmp (name, NTXT (".debug"), 6) == 0) dwarf = true; } @@ -276,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 (); @@ -283,6 +250,7 @@ Elf::~Elf () } delete elfSymbols; delete gnu_debug_file; + delete gnu_debugalt_file; delete dbeFile; delete synthsym; free (bfd_sym); @@ -405,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 *)); @@ -572,50 +567,6 @@ Elf::elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic) return asym; } -Elf_Internal_Rela * -Elf::elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst) -{ - if (dst == NULL || edta == NULL || edta->d_buf == NULL) - return NULL; - if (elf_getclass () == ELFCLASS32) - { - Elf32_Rel *rel = ((Elf32_Rel *) edta->d_buf) + ndx; - dst->r_offset = decode (rel->r_offset); - dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rel->r_info)), - ELF32_R_TYPE (decode (rel->r_info))); - } - else - { - Elf64_Rel *rel = ((Elf64_Rel *) edta->d_buf) + ndx; - dst->r_offset = decode (rel->r_offset); - dst->r_info = decode (rel->r_info); - } - return dst; -} - -Elf_Internal_Rela * -Elf::elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst) -{ - if (dst == NULL || edta == NULL || edta->d_buf == NULL) - return NULL; - if (elf_getclass () == ELFCLASS32) - { - Elf32_Rela *rela = ((Elf32_Rela *) edta->d_buf) + ndx; - dst->r_offset = decode (rela->r_offset); - dst->r_addend = decode (rela->r_addend); - dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rela->r_info)), - ELF32_R_TYPE (decode (rela->r_info))); - } - else - { - Elf64_Rela *rela = ((Elf64_Rela *) edta->d_buf) + ndx; - dst->r_offset = decode (rela->r_offset); - dst->r_addend = decode (rela->r_addend); - dst->r_info = decode (rela->r_info); - } - return dst; -} - Elf64_Ancillary * Elf::elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst) { @@ -676,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); @@ -755,7 +735,6 @@ Elf::find_ancillary_files (char *lo_name) } } } - return NULL; } void @@ -828,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 b324c39..2d227f7 100644 --- a/gprofng/src/Elf.h +++ b/gprofng/src/Elf.h @@ -32,13 +32,12 @@ class Symbol; class DbeFile; +class DwrSec; template <class ITEM> class Vector; template <typename Key_t, typename Value_t> class Map; -#define GELF_R_SYM(info) ((info)>>32) #define GELF_ST_TYPE(info) ((info) & 0xf) #define GELF_ST_BIND(info) ((info) >> 4) -#define GELF_R_TYPE(info) ((((uint64_t)(info))<<56)>>56) #define SHF_SUNW_ABSENT 0x00200000 /* section data not present */ #define SEC_DECOMPRESSED 0x00400000 /* bfd allocated this memory */ @@ -94,10 +93,15 @@ public: char *elf_strptr (unsigned int sec, uint64_t off); long elf_getSymCount (bool is_dynamic); asymbol *elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic); - Elf_Internal_Rela *elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst); - Elf_Internal_Rela *elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst); 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 (); @@ -130,9 +134,10 @@ 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 gnuLink, analyzerInfo, SUNW_ldynsym, stab, stabStr, symtab, dynsym; + unsigned int analyzerInfo, stab, stabStr; unsigned int stabIndex, stabIndexStr, stabExcl, stabExclStr, info, plt; bool dwarf; @@ -143,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; @@ -154,28 +160,4 @@ protected: Vector <asymbol *> *synthsym; }; - -class ElfReloc -{ -public: - struct Sreloc - { - long long offset; - long long value; - int stt_type; - }; - - static ElfReloc *get_elf_reloc (Elf *elf, char *sec_name, ElfReloc *rlc); - ElfReloc (Elf *_elf); - ~ElfReloc (); - long long get_reloc_addr (long long offset); - void dump (); - void dump_rela_debug_sec (int sec); - -private: - Elf *elf; - Vector<Sreloc *> *reloc; - int cur_reloc_ind; -}; - #endif 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 c6d6473..116316e 100644 --- a/gprofng/src/Stabs.cc +++ b/gprofng/src/Stabs.cc @@ -163,21 +163,11 @@ Stabs::removeDupSyms () SymLst->truncate (last); } -Stabs * -Stabs::NewStabs (char *_path, char *lo_name) +Stabs::Stabs (Elf *elf, char *_lo_name) { - Stabs *stabs = new Stabs (_path, lo_name); - if (stabs->status != Stabs::DBGD_ERR_NONE) - { - delete stabs; - return NULL; - } - return stabs; -} - -Stabs::Stabs (char *_path, 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; @@ -187,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: @@ -206,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++) { @@ -228,7 +239,6 @@ Stabs::~Stabs () delete SymLstByName; Destroy (SymLst); Destroy (LocalFile); - delete elfDis; delete dwarf; delete LocalLst; delete LocalFileIdx; @@ -238,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 @@ -2131,57 +2062,6 @@ Stabs::append_Function (Module *module, char *fname) return func; } -Function * -Stabs::append_Function (Module *module, char *linkerName, uint64_t pc) -{ - Dprintf (DEBUG_STABS, NTXT ("Stabs::append_Function: module=%s linkerName=%s pc=0x%llx\n"), - STR (module->get_name ()), STR (linkerName), (unsigned long long) pc); - long i; - Symbol *sitem = NULL, *sp; - Function *func; - sp = new Symbol; - if (pc) - { - sp->value = pc; - i = SymLst->bisearch (0, -1, &sp, SymFindCmp); - if (i != -1) - sitem = SymLst->fetch (i); - } - - if (!sitem && linkerName) - { - if (SymLstByName == NULL) - { - SymLstByName = SymLst->copy (); - SymLstByName->sort (SymNameCmp); - } - sp->name = linkerName; - i = SymLstByName->bisearch (0, -1, &sp, SymNameCmp); - sp->name = NULL; - if (i != -1) - sitem = SymLstByName->fetch (i); - } - delete sp; - - if (!sitem) - return NULL; - if (sitem->alias) - sitem = sitem->alias; - if (sitem->func) - return sitem->func; - - sitem->func = func = dbeSession->createFunction (); - func->img_fname = path; - func->img_offset = sitem->img_offset; - func->save_addr = sitem->save; - func->size = sitem->size; - func->module = module; - func->set_name (sitem->name); //XXXX ?? Now call it to set obj->name - module->functions->append (func); - module->loadobject->functions->append (func); - return func; -}// Stabs::append_Function - Dwarf * Stabs::openDwarf () { diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h index c8da278..cd10c25 100644 --- a/gprofng/src/Stabs.h +++ b/gprofng/src/Stabs.h @@ -76,8 +76,7 @@ class Stabs { DBGD_ERR_CHK_SUM }; - static Stabs *NewStabs(char *_path, char *lo_name); - Stabs(char *_path, char *_lo_name); + Stabs(Elf *elf, char *_lo_name); ~Stabs(); bool is_relocatable(){ return isRelocatable; } @@ -100,7 +99,6 @@ class Stabs { static Function *find_func(char *fname, Vector<Function*> *functions, bool fortran, bool inner_names=false); Module *append_Module(LoadObject *lo, char *name, int lastMod = 0); Function *append_Function(Module *module, char *fname); - Function *append_Function(Module *module, char *linkerName, uint64_t pc); Function *map_PC_to_func(uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions); char *path; // path to the object file char *lo_name; // User name of load object @@ -138,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 (); |