CMS 3D CMS Logo

IgProfSymCache.cc

Go to the documentation of this file.
00001 #include "IgTools/IgProf/src/IgProfSymCache.h"
00002 #include "IgTools/IgHook/interface/IgHookTrace.h"
00003 #include <memory.h>
00004 
00006 IgProfSymCache::IgProfSymCache(void)
00007 {
00008   memset(bintable_, 0, sizeof(bintable_));
00009   memset(symtable_, 0, sizeof(symtable_));
00010   memset(symcache_, 0, sizeof(symcache_));
00011 }
00012 
00014 IgProfSymCache::~IgProfSymCache(void)
00015 {}
00016 
00018 IgProfSymCache::Symbol *
00019 IgProfSymCache::symbolForAddress(void *address)
00020 {
00021   Symbol *sym = symtable_[hash((uintptr_t) address) & (SYMBOL_HASH-1)];
00022   while (sym)
00023   {
00024     if (sym->address == address)
00025       return sym;
00026     if ((char *) sym->address > (char *) address)
00027       return 0;
00028     sym = sym->next;
00029   }
00030 
00031   return 0;
00032 }
00033 
00034 void *
00035 IgProfSymCache::roundAddressToSymbol(void *address)
00036 {
00037   // Look up the address in call address to symbol address cache.
00038   void     *symaddr = address;
00039   SymCache **sclink = &symcache_[hash((uintptr_t) address) & (SYMBOL_HASH-1)];
00040   SymCache *cached;
00041   while (cached = *sclink)
00042   {
00043     // If we found it, return the saved address.
00044     if (cached->calladdr == address)
00045       return cached->symaddr;
00046     if ((char *) cached->calladdr > (char *) address)
00047       break;
00048     sclink = &cached->next;
00049   }
00050 
00051   // If we didn't find it, convert the call address to a symbol
00052   // address.  Then look up the symbol in the symbol table, and
00053   // if not present add to the symbol cache, symbol table and
00054   // the library hashes.
00055   const char *binary;
00056   Symbol     sym = { 0, address, 0, 0, 0, 0, -1 };
00057   Symbol     *s;
00058   if (IgHookTrace::symbol(address, sym.name, binary, sym.symoffset, sym.binoffset))
00059     sym.address = symaddr = (void *) ((uintptr_t) address - sym.symoffset);
00060 
00061   // Hook up the cache entry to sort order in the hash list.
00062   SymCache *next = *sclink;
00063   cached = *sclink = allocate<SymCache>();
00064   cached->next = next;
00065   cached->calladdr = address;
00066   cached->symaddr = symaddr;
00067 
00068   // Look up in the symbol table.
00069   bool found = false;
00070   Symbol **slink = &symtable_[hash((uintptr_t) symaddr) & (SYMBOL_HASH-1)];
00071   while (s = *slink)
00072   {
00073     if (s->address == sym.address)
00074     {
00075       found = true;
00076       break;
00077     }
00078     else if ((char *) s->address > (char *) sym.address)
00079       break;
00080 
00081     slink = &s->next;
00082   }
00083 
00084   // If not found, hook up
00085   if (! found)
00086   {
00087     // Hook up the symbol into sorted hash list order.
00088     sym.next = *slink;
00089     s = *slink = allocate<Symbol>();
00090     *s = sym;
00091 
00092     // Find and if necessary create the binary and hook into the symbol.
00093     Binary **blink = &bintable_[hash((uintptr_t) binary) & (BINARY_HASH-1)];
00094     while (Binary *binobj = *blink)
00095     {
00096       if (binobj->name == binary)
00097       {
00098         s->binary = *blink;
00099         break;
00100       }
00101       blink = &binobj->next;
00102     }
00103 
00104     if (! s->binary)
00105     {
00106       Binary *binobj = *blink = s->binary = allocate<Binary>();
00107       binobj->name = binary;
00108       binobj->next = 0;
00109       binobj->id = -1;
00110     }
00111   }
00112 
00113   // Return the new symbol address.
00114   return cached->symaddr;
00115 }
00116 
00118 IgProfSymCache::Symbol *
00119 IgProfSymCache::get(void *address)
00120 {
00121   return symbolForAddress(roundAddressToSymbol(address));
00122 }

Generated on Tue Jun 9 17:38:08 2009 for CMSSW by  doxygen 1.5.4