78 #include <include/hpctoolkit-config.h> 101 #define DBG_BLD_PROC_MAP 0 103 #define NORETURNS_DISABLE 0 104 #define NORETURNS_DEBUG 0 105 #define NORETURNS_RESULT_NOISY 0 106 #define NORETURNS_LOOKUP_NOISY 0 107 #define NORETURNS_LOOKUP_LOCAL_NOISY 0 130 int result = strcmp(s1,s2);
131 return result < 0 ? true :
false;
136 class name_set :
public std::set<const char*, cstring_compare> {
146 for(name_set::iterator i = this->begin();
147 i != this->end(); i++) {
148 std::cout << *i << std::endl;
165 #if NORETURNS_RESULT_NOISY 166 printf(
"-------- dyn sym noreturn functions ------ \n");
181 asymbol *symbol = syms;
182 for (
long i = 0; i < symcount; i++, symbol++) {
186 char *name = strdup(bfd_asymbol_name(symbol));
188 char *index = strchr(name,
'@');
191 unsigned long addr = bfd_asymbol_value(symbol);
197 #if NORETURNS_LOOKUP_NOISY 198 std::cout <<
"looking up " << name <<
" @ " << std::hex <<
"0x" << addr << std::endl;
200 addIfNoReturn(name, addr);
209 #if NORETURNS_RESULT_NOISY 210 printf(
"-------- sym noreturn functions ------ \n");
219 asymbol **symbol = syms;
220 if (symbol && symcount > 0) {
221 for (
long i = 0; symbol[i]; i++) {
222 const char *name = bfd_asymbol_name(symbol[i]);
223 if (symbol[i]->flags & (BSF_FUNCTION)) {
224 unsigned long addr = bfd_asymbol_value(symbol[i]);
225 #if NORETURNS_LOOKUP_NOISY 226 std::cout <<
"looking up " << name <<
" @ " << std::hex <<
"0x" 227 << addr << std::endl;
230 addIfNoReturn(name, addr);
232 }
else if (symbol[i]->flags == BSF_LOCAL) {
235 #if NORETURNS_LOOKUP_LOCAL_NOISY 236 unsigned long laddr = bfd_asymbol_value(symbol[i]);
237 std::cout <<
"looking up local symbol " << name << std::hex <<
"0x" 238 << laddr << std::endl;
240 if (strstr(name,
"long_branch_r2off")) {
241 unsigned long addr = bfd_asymbol_value(symbol[i]);
243 char *dname = strdup(name);
244 char *index = strchr(dname,
'+');
251 char *name_suffix = strrchr(dname,
'.');
253 name = name_suffix + 1;
255 #if NORETURNS_LOOKUP_NOISY 256 std::cout <<
"looking up " << name <<
" @ " << std::hex <<
"0x" 257 << addr << std::endl;
259 addIfNoReturn(name, addr);
262 }
else if (strstr(name,
"plt_call")) {
263 unsigned long addr = bfd_asymbol_value(symbol[i]);
265 char *dname = strdup(name);
266 char *index = strchr(dname,
'@');
272 char *name_suffix = strrchr(dname,
'.');
274 name = name_suffix + 1;
276 #if NORETURNS_LOOKUP_NOISY 277 std::cout <<
"looking up " << name <<
" @ " << std::hex <<
"0x" 278 << addr << std::endl;
280 addIfNoReturn(name, addr);
300 if (noreturn_fn_names.find(name) != noreturn_fn_names.end()) {
302 #if NORETURNS_RESULT_NOISY 303 std::cout << name <<
" @ " << std::hex <<
"0x" << addr << std::endl;
311 std::cout <<
"noreturns (addresses of functions that don't return)" 313 for(std::set<VMA>::iterator i = this->begin(); i != this->end(); i++) {
314 std::cout << std::hex <<
"0x" << *i << std::endl;
326 dumpSymFlag(std::ostream& o, asymbol* sym,
int flag,
const char* txt,
bool& hasPrinted);
341 : m_type(TypeNULL), m_readFlags(ReadFlg_NULL),
342 m_txtBeg(0), m_txtEnd(0), m_begVMA(0),
343 m_textBegReloc(0), m_unrelocDelta(0),
345 m_bfdDynSymTab(
NULL), m_bfdSynthTab(
NULL),
346 m_bfdSymTabSort(
NULL), m_bfdSymTabSz(0), m_bfdDynSymTabSz(0),
347 m_bfdSymTabSortSz(0), m_bfdSynthTabSz(0), m_noreturns(0),
348 m_realpathMgr(
RealPathMgr::singleton()), m_useBinutils(useBinutils),
398 "Cannot open a different file!");
411 m_bfd = bfd_openr(filenm,
"default");
413 BINUTIL_Throw(
"'" << filenm <<
"': " << bfd_errmsg(bfd_get_error()));
419 if (!bfd_check_format(
m_bfd, bfd_object)) {
420 BINUTIL_Throw(
"'" << filenm <<
"': not an object or executable");
432 flagword flags = bfd_get_file_flags(
m_bfd);
433 if (flags & EXEC_P) {
436 else if (flags & DYNAMIC) {
463 DIAG_Assert(!
m_name.empty(),
"Must call LM::Open first");
489 DIAG_Assert(
m_txtBeg != 0,
"LM::Relocate not supported!");
510 minsn = insn->
bits();
538 asection* bfdSeg =
NULL;
543 bfdSeg = bfd_get_section_by_name(
m_bfd, seg->
name().c_str());
544 base = bfd_section_vma(
m_bfd, bfdSeg);
552 const char *bfd_func =
NULL, *bfd_file =
NULL;
556 opVMA - base, &bfd_file, &bfd_func, &bfd_line);
577 string& func,
string& file,
583 begLine = endLine = 0;
588 if (! (begOpVMA <= endOpVMA) ) {
592 ushort tmpOpIdx = bOpIndex;
598 string func1, func2, file1, file2;
601 STATUS = (call1 && call2);
604 if (!func1.empty() && !func2.empty()) {
606 if (func1 != func2) {
610 else if (!func1.empty() && func2.empty()) {
613 else if (func1.empty() && !func2.empty()) {
618 if (!file1.empty() && !file2.empty()) {
620 if (file1 != file2) {
625 else if (!file1.empty() && file2.empty()) {
628 else if (file1.empty() && !file2.empty()) {
640 && begLine > endLine) {
654 bool isfound =
false;
664 Proc* proc = it->second;
669 << ival.
toString() <<
" = " << line);
683 Seg* seg = it->second;
685 if (!(sml_begVMA || lg_endVMA)) {
686 sml_begVMA = seg->
begVMA();
687 lg_endVMA = seg->
endVMA();
690 curr_begVMA = seg->
begVMA();
691 curr_endVMA = seg->
endVMA();
692 if (curr_begVMA < sml_begVMA)
693 sml_begVMA = curr_begVMA;
694 if (curr_endVMA > lg_endVMA)
695 lg_endVMA = curr_endVMA;
700 *begVMA = sml_begVMA;
708 std::ostringstream os;
709 dump(os, flags, pre);
719 string p2 = p1 +
" ";
721 o << p <<
"==================== Load Module Dump ====================\n";
723 o << p1 <<
"BFD version: ";
725 o << BFD_VERSION << endl;
727 o <<
"-unknown-" << endl;
731 o << p1 <<
"Load Module Information:\n";
734 o << p1 <<
"Load Module Contents:\n";
742 o << p2 <<
"Sections (" <<
numSegs() <<
"):\n";
744 Seg* seg = it->second;
745 seg->
dump(o, flags, p2.c_str());
753 dump(std::cerr, code);
771 os << it->first.toString() <<
" --> " << std::hex <<
"Ox" << it->second
774 os << it->second->toString();
791 asymbol *a = (asymbol *)s1;
792 asymbol *b = (asymbol *)s2;
795 if (bfd_asymbol_value(a) < bfd_asymbol_value(b)) {
798 else if (bfd_asymbol_value(a) > bfd_asymbol_value(b)) {
813 long bytesNeeded = bfd_get_symtab_upper_bound(
m_bfd);
815 if (bytesNeeded > 0) {
816 m_bfdSymTab =
new asymbol*[bytesNeeded /
sizeof(asymbol*)];
819 if (m_bfdSymTabSz == 0) {
822 DIAG_Msg(2,
"'" <<
name() <<
"': No regular symbols found.");
830 bytesNeeded = bfd_get_dynamic_symtab_upper_bound(
m_bfd);
832 if (bytesNeeded > 0) {
838 DIAG_Msg(2,
"'" <<
name() <<
"': No dynamic symbols found.");
859 DIAG_Msg(2,
"'" <<
name() <<
"': No synthetic symbols found.");
888 for (asection* sec =
m_bfd->sections; (sec); sec = sec->next) {
891 string segnm(bfd_section_name(
m_bfd, sec));
892 bfd_vma segBeg = bfd_section_vma(
m_bfd, sec);
893 uint64_t segSz = bfd_section_size(
m_bfd, sec) / bfd_octets_per_byte(
m_bfd);
894 bfd_vma segEnd = segBeg + segSz;
898 if (sec->flags & SEC_CODE) {
899 seg =
new TextSeg(
this, segnm, segBeg, segEnd, segSz);
906 DIAG_WMsg(3,
"Overlapping segment: " << segnm <<
": " 907 << std::hex << segBeg <<
" " << segEnd << std::dec);
940 o << p <<
"Name: `" <<
name() <<
"'\n";
942 o << p <<
"Format: `" << bfd_get_target(
m_bfd) <<
"'" << endl;
948 o <<
"Unknown load module type'\n";
951 o <<
"Executable (fully linked except for possible DSOs)'\n";
954 o <<
"Dynamically Shared Library'\n";
960 o << p <<
"Load VMA: " << std::hex <<
m_begVMA << std::dec <<
"\n";
962 o << p <<
"Text(beg,end): " 963 << std::hex <<
textBeg() <<
", " <<
textEnd() << std::dec <<
"\n";
965 o << p <<
"Endianness: `" 966 << ( (bfd_big_endian(
m_bfd)) ?
"Big'\n" :
"Little'\n" );
968 o << p <<
"Architecture: `";
969 switch (bfd_get_arch(
m_bfd)) {
970 case bfd_arch_alpha: o <<
"Alpha'\n";
break;
971 case bfd_arch_mips: o <<
"MIPS'\n";
break;
972 case bfd_arch_powerpc: o <<
"POWER'\n";
break;
973 case bfd_arch_sparc: o <<
"SPARC'\n";
break;
974 case bfd_arch_i386: o <<
"x86'\n";
break;
975 case bfd_arch_ia64: o <<
"IA-64'\n";
break;
977 case bfd_arch_k1om: o <<
"K1OM'\n";
break;
979 default:
DIAG_Die(
"Unknown bfd arch: " << bfd_get_arch(
m_bfd));
982 o << p <<
"Architectural implementation: `";
983 switch (bfd_get_arch(
m_bfd)) {
985 switch (bfd_get_mach(
m_bfd)) {
986 case bfd_mach_alpha_ev4: o <<
"EV4'\n";
break;
987 case bfd_mach_alpha_ev5: o <<
"EV5'\n";
break;
988 case bfd_mach_alpha_ev6: o <<
"EV6'\n";
break;
989 default: o <<
"-unknown Alpha-'\n";
break;
993 switch (bfd_get_mach(
m_bfd)) {
994 case bfd_mach_mips3000: o <<
"R3000'\n";
break;
995 case bfd_mach_mips4000: o <<
"R4000'\n";
break;
996 case bfd_mach_mips6000: o <<
"R6000'\n";
break;
997 case bfd_mach_mips8000: o <<
"R8000'\n";
break;
998 case bfd_mach_mips10000: o <<
"R10000'\n";
break;
999 case bfd_mach_mips12000: o <<
"R12000'\n";
break;
1000 default: o <<
"-unknown MIPS-'\n";
1003 case bfd_arch_powerpc:
1004 switch (bfd_get_mach(
m_bfd)) {
1005 case bfd_mach_ppc: o <<
"PPC'\n";
break;
1006 case bfd_mach_ppc64: o <<
"PPC-64'\n";
break;
1007 default: o <<
"-unknown POWER-'\n";
1010 case bfd_arch_sparc:
1011 switch (bfd_get_mach(
m_bfd)) {
1012 case bfd_mach_sparc_sparclet: o <<
"let'\n";
break;
1013 case bfd_mach_sparc_sparclite: o <<
"lite'\n";
break;
1014 case bfd_mach_sparc_sparclite_le: o <<
"lite_le'\n";
break;
1015 case bfd_mach_sparc_v8plus: o <<
"v8plus'\n";
break;
1016 case bfd_mach_sparc_v8plusa: o <<
"v8plusa'\n";
break;
1017 case bfd_mach_sparc_v8plusb: o <<
"v8plusb'\n";
break;
1018 case bfd_mach_sparc_v9: o <<
"v9'\n";
break;
1019 case bfd_mach_sparc_v9a: o <<
"v9a'\n";
break;
1020 case bfd_mach_sparc_v9b: o <<
"v9b'\n";
break;
1021 default: o <<
"-unknown Sparc-'\n";
1025 switch (bfd_get_mach(
m_bfd)) {
1026 case bfd_mach_i386_i386: o <<
"x86'\n";
break;
1027 case bfd_mach_i386_i8086: o <<
"x86 (8086)'\n";
break;
1028 case bfd_mach_x86_64: o <<
"x86_64'\n";
break;
1029 default: o <<
"-unknown x86-'\n";
1035 #ifdef bfd_mach_k1om 1044 o << p <<
"Bits per byte: " << bfd_arch_bits_per_byte(
m_bfd) << endl;
1045 o << p <<
"Bits per address: " << bfd_arch_bits_per_address(
m_bfd) << endl;
1046 o << p <<
"Bits per word: " <<
m_bfd->arch_info->bits_per_word << endl;
1054 o << p1 << std::hex << std::setw(16)
1055 << (bfd_vma)bfd_asymbol_value(sym) <<
": " << std::setw(0) << std::dec
1056 << bfd_asymbol_name(sym)
1057 <<
" [sec: " << sym->section->name <<
"] ";
1060 o <<
"[flg: " << std::hex << sym->flags << std::dec <<
" ";
1061 bool hasPrintedFlag =
false;
1062 dumpSymFlag(o, sym, BSF_LOCAL,
"LCL", hasPrintedFlag);
1063 dumpSymFlag(o, sym, BSF_GLOBAL,
"GBL", hasPrintedFlag);
1064 dumpSymFlag(o, sym, BSF_FUNCTION,
"FUNC", hasPrintedFlag);
1065 dumpSymFlag(o, sym, BSF_WEAK,
"WEAK", hasPrintedFlag);
1066 dumpSymFlag(o, sym, BSF_SECTION_SYM,
"SEC", hasPrintedFlag);
1067 dumpSymFlag(o, sym, BSF_FILE,
"FILE", hasPrintedFlag);
1068 dumpSymFlag(o, sym, BSF_DYNAMIC,
"DYN", hasPrintedFlag);
1069 dumpSymFlag(o, sym, BSF_OBJECT,
"OBJ", hasPrintedFlag);
1070 dumpSymFlag(o, sym, BSF_THREAD_LOCAL,
"THR_LCL", hasPrintedFlag);
1085 string p1 = p +
" ";
1087 o << p <<
"--------------- Symbol Table Dump (Unsorted) --------------\n";
1095 o << p <<
"--------------- Symbol Table Dump (Synthetic) -------------\n";
1103 o << p <<
"-----------------------------------------------------------\n";
1110 asymbol* sym,
int flag,
const char* txt,
bool& hasPrinted)
1112 if ((sym->flags & flag)) {
1117 hasPrinted =
true; \
1159 o << pre <<
"Program start address: " << std::hex <<
getStartVMA()
1160 << std::dec << endl;
std::string toString(int flags=DUMP_Short, const char *pre="") const
virtual VMA convertVMAToOpVMA(VMA vma, ushort GCC_ATTR_UNUSED opIndex) const
bool findProcSrcCodeInfo(VMA vma, ushort opIndex, SrcFile::ln &line) const
void MONITOR_EXT_WRAP_NAME() free(void *ptr)
static void dumpASymbol(std::ostream &o, asymbol *sym, string p1)
int find(char s1[], char s2[])
void textBegEndVMA(VMA *begVMA, VMA *endVMA)
void ddumpProcMap(unsigned flag) const
SrcFile::ln begLine() const
bool isValid(SrcFile::ln line)
void Sort(const int minEntryIndex, const int maxEntryIndex)
void relocate(VMA textBegReloc)
virtual void read(const std::set< std::string > &directorySet, ReadFlg readflg)
void addSymEntries(asymbol **syms, long symcount)
void ddump(int code=DUMP_Long_decode) const
bool insertSeg(VMAInterval ival, Seg *seg)
bool functionNeverReturns(VMA addr)
void addSynSymEntries(asymbol *syms, long symcount)
BinUtil::Dbg::LM m_dbgInfo
MachInsn * findMachInsn(VMA vma, ushort &size) const
name_set noreturn_fn_names
virtual void open(const char *filenm)
#define DIAG_MsgIf(ifexpr,...)
const std::string & name() const
asymbol ** m_bfdDynSymTab
bool operator()(const char *s1, const char *s2) const
const std::string & name() const
unsigned short int ushort
bool realpath(std::string &pathNm) const
virtual MachInsn * bits() const
#define NORETURNS_DISABLE
static void dumpSymFlag(std::ostream &o, asymbol *sym, int flag, const char *txt, bool &hasPrinted)
virtual bool parse(const std::set< std::string > &directorySet, const char *pathname)=0
RealPathMgr & m_realpathMgr
virtual ushort size() const =0
virtual void dumpProcMap(std::ostream &o=std::cerr, unsigned flag=0, const char *pre="") const
static const char * noreturn_table[]
asymbol ** m_bfdSymTabSort
SimpleSymbolsFactories simpleSymbolsFactories
SimpleSymbolsFactory * find(const char *pathname)
void addIfNoReturn(const char *name, uint64_t addr)
void dumpModuleInfo(std::ostream &o=std::cerr, const char *pre="") const
My_t::const_iterator const_iterator
#define DIAG_Msg(level,...)
virtual void dumpme(std::ostream &o=std::cerr, const char *pre="") const
static int cmpBFDSymByVMA(const void *s1, const void *s2)
virtual void dump(std::ostream &o=std::cerr, int flags=LM::DUMP_Short, const char *pre="") const
void Create(void **UserArrayPtr, const EntryCompareFunctPtr _CompareFunct)
virtual void dump(std::ostream &o=std::cerr, int flags=DUMP_Short, const char *pre="") const
void dumpSymTab(std::ostream &o=std::cerr, const char *pre="") const
VMA unrelocate(VMA relocVMA) const
void read(bfd *abfd, asymbol **bfdSymTab)
Seg * findSeg(VMA vma) const
virtual void dump(std::ostream &o=std::cerr, int flags=DUMP_Short, const char *pre="") const
bool isNoReturn(VMA addr)
static bool isProcBFDSym(asymbol *sym)
std::string toString() const
#define BINUTIL_Throw(streamArgs)
Insn * findInsn(VMA vma, ushort opIndex) const
iterator find(const key_type &toFind)
bool findSrcCodeInfo(VMA vma, ushort opIndex, std::string &func, std::string &file, SrcFile::ln &line)
bool findEnclosingFunction(uint64_t vma, std::string &fnName)
bool implies(bool p, bool q)
virtual void dumpme(std::ostream &o=std::cerr, const char *pre="") const
LM(bool useBinutils=false)
SimpleSymbols * m_simpleSymbols
virtual void open(const char *filenm)
virtual SimpleSymbols * create()=0