Home | History | Annotate | Download | only in qtools
      1 // Copyright 2006 The Android Open Source Project
      2 
      3 #ifndef TRACE_READER_H
      4 #define TRACE_READER_H
      5 
      6 #include <string.h>
      7 #include <inttypes.h>
      8 #include <elf.h>
      9 #include <assert.h>
     10 #include <cxxabi.h>
     11 #include "read_elf.h"
     12 #include "trace_reader_base.h"
     13 #include "hash_table.h"
     14 
     15 struct TraceReaderEmptyStruct {
     16 };
     17 
     18 template <class T = TraceReaderEmptyStruct>
     19 class TraceReader : public TraceReaderBase {
     20   public:
     21 
     22     struct region_entry;
     23     typedef struct symbol_entry : public T {
     24         typedef region_entry region_type;
     25 
     26         // Define flag values
     27         static const uint32_t kIsPlt = 0x01;
     28         static const uint32_t kIsVectorStart = 0x02;
     29         static const uint32_t kIsVectorTable = (kIsPlt | kIsVectorStart);
     30         static const uint32_t kIsInterpreter = 0x04;
     31         static const uint32_t kIsMethod = 0x08;
     32 
     33         uint32_t        addr;
     34 
     35         // This may hold the name of the interpreted method instead of
     36         // the name of the native function if the native function is a
     37         // virtual machine interpreter.
     38         const char      *name;
     39 
     40         // The symbol for the virtual machine interpreter, or NULL
     41         symbol_entry    *vm_sym;
     42         region_type     *region;
     43         uint32_t        flags;
     44     } symbol_type;
     45 
     46     typedef struct region_entry {
     47         // Define flag values
     48         static const uint32_t kIsKernelRegion           = 0x01;
     49         static const uint32_t kSharedSymbols            = 0x02;
     50         static const uint32_t kIsLibraryRegion          = 0x04;
     51         static const uint32_t kIsUserMappedRegion       = 0x08;
     52 
     53         region_entry() : refs(0), path(NULL), vstart(0), vend(0), base_addr(0),
     54                          file_offset(0), flags(0), nsymbols(0), symbols(NULL) {}
     55 
     56         symbol_type    *LookupFunctionByName(char *name) {
     57             // Just do a linear search
     58             for (int ii = 0; ii < nsymbols; ++ii) {
     59                 if (strcmp(symbols[ii].name, name) == 0)
     60                     return &symbols[ii];
     61             }
     62             return NULL;
     63         }
     64 
     65         region_entry   *MakePrivateCopy(region_entry *dest) {
     66             dest->refs = 0;
     67             dest->path = Strdup(path);
     68             dest->vstart = vstart;
     69             dest->vend = vend;
     70             dest->base_addr = base_addr;
     71             dest->file_offset = file_offset;
     72             dest->flags = flags;
     73             dest->nsymbols = nsymbols;
     74             dest->symbols = symbols;
     75             return dest;
     76         }
     77 
     78         int             refs;        // reference count
     79         char            *path;
     80         uint32_t        vstart;
     81         uint32_t        vend;
     82         uint32_t        base_addr;
     83         uint32_t        file_offset;
     84         uint32_t        flags;
     85         int             nsymbols;
     86         symbol_type     *symbols;
     87     } region_type;
     88 
     89     typedef typename HashTable<region_type*>::entry_type hash_entry_type;
     90 
     91     class ProcessState {
     92       public:
     93 
     94         // The "regions" array below is a pointer to array of pointers to
     95         // regions.  The size of the pointer array is kInitialNumRegions,
     96         // but grows if needed.  There is a separate region for each mmap
     97         // call which includes shared libraries as well as .dex and .jar
     98         // files.  In addition, there is a region for the main executable
     99         // for this process, as well as a few regions for the kernel.
    100         //
    101         // If a child process is a clone of a parent process, the
    102         // regions array is unused.  Instead, the "addr_manager" pointer is
    103         // used to find the process that is the address space manager for
    104         // both the parent and child processes.
    105         static const int kInitialNumRegions = 10;
    106 
    107         static const int kMaxMethodStackSize = 1000;
    108 
    109         // Define values for the ProcessState flag bits
    110         static const int kCalledExec            = 0x01;
    111         static const int kCalledExit            = 0x02;
    112         static const int kIsClone               = 0x04;
    113         static const int kHasKernelRegion       = 0x08;
    114         static const int kHasFirstMmap          = 0x10;
    115 
    116         struct methodFrame {
    117             uint32_t    addr;
    118             bool        isNative;
    119         };
    120 
    121         ProcessState() {
    122             cpu_time = 0;
    123             tgid = 0;
    124             pid = 0;
    125             parent_pid = 0;
    126             exit_val = 0;
    127             flags = 0;
    128             argc = 0;
    129             argv = NULL;
    130             name = NULL;
    131             nregions = 0;
    132             max_regions = 0;
    133             // Don't allocate space yet until we know if we are a clone.
    134             regions = NULL;
    135             parent = NULL;
    136             addr_manager = this;
    137             next = NULL;
    138             current_method_sym = NULL;
    139             method_stack_top = 0;
    140         }
    141 
    142         ~ProcessState() {
    143             delete[] name;
    144             if ((flags & kIsClone) != 0) {
    145                 return;
    146             }
    147 
    148             // Free the regions.  We must be careful not to free the symbols
    149             // within each region because the symbols are sometimes shared
    150             // between multiple regions.  The TraceReader class has a hash
    151             // table containing all the unique regions and it will free the
    152             // region symbols in its destructor.  We need to free only the
    153             // regions and the array of region pointers.
    154             //
    155             // Each region is also reference-counted.  The count is zero
    156             // if no other processes are sharing this region.
    157             for (int ii = 0; ii < nregions; ii++) {
    158                 if (regions[ii]->refs > 0) {
    159                     regions[ii]->refs -= 1;
    160                     continue;
    161                 }
    162 
    163                 delete regions[ii];
    164             }
    165 
    166             delete[] regions;
    167 
    168             for (int ii = 0; ii < argc; ++ii)
    169                 delete[] argv[ii];
    170             delete[] argv;
    171         }
    172 
    173         // Dumps the stack contents to standard output.  For debugging.
    174         void            DumpStack(FILE *stream);
    175 
    176         uint64_t        cpu_time;
    177         uint64_t        start_time;
    178         uint64_t        end_time;
    179         int             tgid;
    180         int             pid;
    181         int             parent_pid;
    182         int             exit_val;
    183         uint32_t        flags;
    184         int             argc;
    185         char            **argv;
    186         const char      *name;
    187         int             nregions;        // num regions in use
    188         int             max_regions;     // max regions allocated
    189         region_type     **regions;
    190         ProcessState    *parent;
    191         ProcessState    *addr_manager;   // the address space manager process
    192         ProcessState    *next;
    193         int             method_stack_top;
    194         methodFrame     method_stack[kMaxMethodStackSize];
    195         symbol_type     *current_method_sym;
    196     };
    197 
    198     TraceReader();
    199     ~TraceReader();
    200 
    201     void                ReadKernelSymbols(const char *kernel_file);
    202     void                CopyKernelRegion(ProcessState *pstate);
    203     void                ClearRegions(ProcessState *pstate);
    204     void                CopyRegions(ProcessState *parent, ProcessState *child);
    205     void                DumpRegions(FILE *stream, ProcessState *pstate);
    206     symbol_type         *LookupFunction(int pid, uint32_t addr, uint64_t time);
    207     symbol_type         *GetSymbols(int *num_syms);
    208     ProcessState        *GetCurrentProcess()            { return current_; }
    209     ProcessState        *GetProcesses(int *num_procs);
    210     ProcessState        *GetNextProcess();
    211     const char          *GetProcessName(int pid);
    212     void                SetRoot(const char *root)       { root_ = root; }
    213     void                SetDemangle(bool demangle)      { demangle_ = demangle; }
    214     bool                ReadMethodSymbol(MethodRec *method_record,
    215                                          symbol_type **psym,
    216                                          ProcessState **pproc);
    217 
    218   protected:
    219     virtual int FindCurrentPid(uint64_t time);
    220 
    221   private:
    222 
    223     static const int kNumPids = 32768;
    224     static const uint32_t kIncludeLocalSymbols = 0x1;
    225 
    226     void                AddPredefinedRegion(region_type *region, const char *path,
    227                                             uint32_t vstart, uint32_t vend,
    228                                             uint32_t base);
    229     void                InitRegionSymbols(region_type *region, int nsymbols);
    230     void                AddRegionSymbol(region_type *region, int idx,
    231                                         uint32_t addr, const char *name,
    232                                         uint32_t flags);
    233     void                AddPredefinedRegions(ProcessState *pstate);
    234     void                demangle_names(int nfuncs, symbol_type *functions);
    235     bool                ReadElfSymbols(region_type *region, uint32_t flags);
    236     void                AddRegion(ProcessState *pstate, region_type *region);
    237     region_type         *FindRegion(uint32_t addr, int nregions,
    238                                     region_type **regions);
    239     int                 FindRegionIndex(uint32_t addr, int nregions,
    240                                          region_type **regions);
    241     void                FindAndRemoveRegion(ProcessState *pstate,
    242                                             uint32_t vstart, uint32_t vend);
    243     symbol_type         *FindFunction(uint32_t addr, int nsyms,
    244                                       symbol_type *symbols, bool exact_match);
    245     symbol_type         *FindCurrentMethod(int pid, uint64_t time);
    246     void                PopulateSymbolsFromDexFile(const DexFileList *dexfile,
    247                                                    region_type *region);
    248     void                HandlePidEvent(PidEvent *event);
    249     void                HandleMethodRecord(ProcessState *pstate,
    250                                            MethodRec *method_rec);
    251 
    252     int                 cached_pid_;
    253     symbol_type         *cached_func_;
    254     symbol_type         unknown_;
    255     int                 next_pid_;
    256 
    257     PidEvent            next_pid_event_;
    258     ProcessState        *processes_[kNumPids];
    259     ProcessState        *current_;
    260     MethodRec           next_method_;
    261     uint64_t            function_start_time_;
    262     const char          *root_;
    263     HashTable<region_type*> *hash_;
    264     bool                demangle_;
    265 };
    266 
    267 template<class T>
    268 TraceReader<T>::TraceReader()
    269 {
    270     static PidEvent event_no_action;
    271 
    272     cached_pid_ = -1;
    273     cached_func_ = NULL;
    274 
    275     memset(&unknown_, 0, sizeof(symbol_type));
    276     unknown_.name = "(unknown)";
    277     next_pid_ = 0;
    278 
    279     memset(&event_no_action, 0, sizeof(PidEvent));
    280     event_no_action.rec_type = kPidNoAction;
    281     next_pid_event_ = event_no_action;
    282     for (int ii = 1; ii < kNumPids; ++ii)
    283         processes_[ii] = NULL;
    284     current_ = new ProcessState;
    285     processes_[0] = current_;
    286     next_method_.time = 0;
    287     next_method_.addr = 0;
    288     next_method_.flags = 0;
    289     function_start_time_ = 0;
    290     root_ = "";
    291     hash_ = new HashTable<region_type*>(512);
    292     AddPredefinedRegions(current_);
    293     demangle_ = true;
    294 }
    295 
    296 template<class T>
    297 TraceReader<T>::~TraceReader()
    298 {
    299     hash_entry_type *ptr;
    300     for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
    301         region_type *region = ptr->value;
    302         // If the symbols are not shared with another region, then delete them.
    303         if ((region->flags & region_type::kSharedSymbols) == 0) {
    304             int nsymbols = region->nsymbols;
    305             for (int ii = 0; ii < nsymbols; ii++) {
    306                 delete[] region->symbols[ii].name;
    307             }
    308             delete[] region->symbols;
    309         }
    310         delete[] region->path;
    311 
    312         // Do not delete the region itself here.  Each region
    313         // is reference-counted and deleted by the ProcessState
    314         // object that owns it.
    315     }
    316     delete hash_;
    317 
    318     // Delete the ProcessState objects after the region symbols in
    319     // the hash table above so that we still have valid region pointers
    320     // when deleting the region symbols.
    321     for (int ii = 0; ii < kNumPids; ++ii) {
    322         delete processes_[ii];
    323     }
    324 }
    325 
    326 // This function is used by the qsort() routine to sort symbols
    327 // into increasing address order.
    328 template<class T>
    329 int cmp_symbol_addr(const void *a, const void *b) {
    330     typedef typename TraceReader<T>::symbol_type stype;
    331 
    332     const stype *syma = static_cast<stype const *>(a);
    333     const stype *symb = static_cast<stype const *>(b);
    334     uint32_t addr1 = syma->addr;
    335     uint32_t addr2 = symb->addr;
    336     if (addr1 < addr2)
    337         return -1;
    338     if (addr1 > addr2)
    339         return 1;
    340 
    341     // The addresses are the same, sort the symbols into
    342     // increasing alphabetical order.  But put symbols that
    343     // that start with "_" last.
    344     if (syma->name[0] == '_' || symb->name[0] == '_') {
    345         // Count the number of leading underscores and sort the
    346         // symbol with the most underscores last.
    347         int aCount = 0;
    348         while (syma->name[aCount] == '_')
    349             aCount += 1;
    350         int bCount = 0;
    351         while (symb->name[bCount] == '_')
    352             bCount += 1;
    353         if (aCount < bCount) {
    354             return -1;
    355         }
    356         if (aCount > bCount) {
    357             return 1;
    358         }
    359         // If the symbols have the same number of underscores, then
    360         // fall through and sort by the whole name.
    361     }
    362     return strcmp(syma->name, symb->name);
    363 }
    364 
    365 // This function is used by the qsort() routine to sort region entries
    366 // into increasing address order.
    367 template<class T>
    368 int cmp_region_addr(const void *a, const void *b) {
    369     typedef typename TraceReader<T>::region_type rtype;
    370 
    371     const rtype *ma = *static_cast<rtype* const *>(a);
    372     const rtype *mb = *static_cast<rtype* const *>(b);
    373     uint32_t addr1 = ma->vstart;
    374     uint32_t addr2 = mb->vstart;
    375     if (addr1 < addr2)
    376         return -1;
    377     if (addr1 == addr2)
    378         return 0;
    379     return 1;
    380 }
    381 
    382 // This routine returns a new array containing all the symbols.
    383 template<class T>
    384 typename TraceReader<T>::symbol_type*
    385 TraceReader<T>::GetSymbols(int *num_syms)
    386 {
    387     // Count the symbols
    388     int nsyms = 0;
    389     for (hash_entry_type *ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
    390         region_type *region = ptr->value;
    391         nsyms += region->nsymbols;
    392     }
    393     *num_syms = nsyms;
    394 
    395     // Allocate space
    396     symbol_type *syms = new symbol_type[nsyms];
    397     symbol_type *next_sym = syms;
    398 
    399     // Copy the symbols
    400     for (hash_entry_type *ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
    401         region_type *region = ptr->value;
    402         memcpy(next_sym, region->symbols, region->nsymbols * sizeof(symbol_type));
    403         next_sym += region->nsymbols;
    404     }
    405 
    406     return syms;
    407 }
    408 
    409 // This routine returns all the valid processes.
    410 template<class T>
    411 typename TraceReader<T>::ProcessState*
    412 TraceReader<T>::GetProcesses(int *num_procs)
    413 {
    414     // Count the valid processes
    415     int nprocs = 0;
    416     for (int ii = 0; ii < kNumPids; ++ii) {
    417         if (processes_[ii])
    418             nprocs += 1;
    419     }
    420 
    421     // Allocate a new array to hold the valid processes.
    422     ProcessState *procs = new ProcessState[nprocs];
    423 
    424     // Copy the processes to the new array.
    425     ProcessState *pstate = procs;
    426     for (int ii = 0; ii < kNumPids; ++ii) {
    427         if (processes_[ii])
    428             memcpy(pstate++, processes_[ii], sizeof(ProcessState));
    429     }
    430 
    431     *num_procs = nprocs;
    432     return procs;
    433 }
    434 
    435 // This routine returns the next valid process, or NULL if there are no
    436 // more valid processes.
    437 template<class T>
    438 typename TraceReader<T>::ProcessState*
    439 TraceReader<T>::GetNextProcess()
    440 {
    441     while (next_pid_ < kNumPids) {
    442         if (processes_[next_pid_])
    443             return processes_[next_pid_++];
    444         next_pid_ += 1;
    445     }
    446     next_pid_ = 0;
    447     return NULL;
    448 }
    449 
    450 template<class T>
    451 const char* TraceReader<T>::GetProcessName(int pid)
    452 {
    453     if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
    454         return "(unknown)";
    455     return processes_[pid]->name;
    456 }
    457 
    458 template<class T>
    459 void TraceReader<T>::AddPredefinedRegion(region_type *region, const char *path,
    460                                          uint32_t vstart, uint32_t vend,
    461                                          uint32_t base)
    462 {
    463     // Copy the path to make it easy to delete later.
    464     int len = strlen(path);
    465     region->path = new char[len + 1];
    466     strcpy(region->path, path);
    467     region->vstart = vstart;
    468     region->vend = vend;
    469     region->base_addr = base;
    470     region->flags = region_type::kIsKernelRegion;
    471 }
    472 
    473 template<class T>
    474 void TraceReader<T>::InitRegionSymbols(region_type *region, int nsymbols)
    475 {
    476     region->nsymbols = nsymbols;
    477     region->symbols = new symbol_type[nsymbols];
    478     memset(region->symbols, 0, nsymbols * sizeof(symbol_type));
    479 }
    480 
    481 template<class T>
    482 void TraceReader<T>::AddRegionSymbol(region_type *region, int idx,
    483                                      uint32_t addr, const char *name,
    484                                      uint32_t flags)
    485 {
    486     region->symbols[idx].addr = addr;
    487     region->symbols[idx].name = Strdup(name);
    488     region->symbols[idx].vm_sym = NULL;
    489     region->symbols[idx].region = region;
    490     region->symbols[idx].flags = flags;
    491 }
    492 
    493 template<class T>
    494 void TraceReader<T>::AddPredefinedRegions(ProcessState *pstate)
    495 {
    496     region_type *region = new region_type;
    497     AddPredefinedRegion(region, "(bootloader)", 0, 0x14, 0);
    498     InitRegionSymbols(region, 2);
    499     AddRegionSymbol(region, 0, 0, "(bootloader_start)", 0);
    500     AddRegionSymbol(region, 1, 0x14, "(bootloader_end)", 0);
    501     AddRegion(pstate, region);
    502     hash_->Update(region->path, region);
    503 
    504     region = new region_type;
    505     AddPredefinedRegion(region, "(exception vectors)", 0xffff0000, 0xffff0500,
    506                         0xffff0000);
    507     InitRegionSymbols(region, 2);
    508     AddRegionSymbol(region, 0, 0x0, "(vector_start)",
    509                     symbol_type::kIsVectorStart);
    510     AddRegionSymbol(region, 1, 0x500, "(vector_end)", 0);
    511     AddRegion(pstate, region);
    512     hash_->Update(region->path, region);
    513 
    514     region = new region_type;
    515     AddPredefinedRegion(region, "(atomic ops)", 0xffff0f80, 0xffff1000,
    516                         0xffff0f80);
    517     // Mark this region as also being mapped in user-space.
    518     // This isn't used anywhere in this code but client code can test for
    519     // this flag and decide whether to treat this as kernel or user code.
    520     region->flags |= region_type::kIsUserMappedRegion;
    521 
    522     InitRegionSymbols(region, 4);
    523     AddRegionSymbol(region, 0, 0x0, "(kuser_atomic_inc)", 0);
    524     AddRegionSymbol(region, 1, 0x20, "(kuser_atomic_dec)", 0);
    525     AddRegionSymbol(region, 2, 0x40, "(kuser_cmpxchg)", 0);
    526     AddRegionSymbol(region, 3, 0x80, "(kuser_end)", 0);
    527     AddRegion(pstate, region);
    528     hash_->Update(region->path, region);
    529 }
    530 
    531 template<class T>
    532 void TraceReader<T>::ReadKernelSymbols(const char *kernel_file)
    533 {
    534     region_type *region = new region_type;
    535     // Copy the path to make it easy to delete later.
    536     int len = strlen(kernel_file);
    537     region->path = new char[len + 1];
    538     strcpy(region->path, kernel_file);
    539     region->flags = region_type::kIsKernelRegion;
    540     ReadElfSymbols(region, kIncludeLocalSymbols);
    541     region->vend = 0xffff0000;
    542     AddRegion(processes_[0], region);
    543     processes_[0]->flags |= ProcessState::kHasKernelRegion;
    544     hash_->Update(region->path, region);
    545 }
    546 
    547 template<class T>
    548 void TraceReader<T>::demangle_names(int nfuncs, symbol_type *functions)
    549 {
    550     char *demangled;
    551     int status;
    552 
    553     for (int ii = 0; ii < nfuncs; ++ii) {
    554         demangled = NULL;
    555         int len = strlen(functions[ii].name);
    556 
    557         // If we don't check for "len > 1" then the demangler will incorrectly
    558         // expand 1-letter function names.  For example, "b" becomes "bool",
    559         // "c" becomes "char" and "d" becomes "double".  Also check that the
    560         // first character is an underscore.  Otherwise, on some strings
    561         // the demangler will try to read past the end of the string (because
    562         // the string is not really a C++ mangled name) and valgrind will
    563         // complain.
    564         if (demangle_ && len > 1 && functions[ii].name[0] == '_') {
    565             demangled = abi::__cxa_demangle(functions[ii].name, 0, NULL,
    566                                             &status);
    567         }
    568 
    569         if (demangled != NULL) {
    570             delete[] functions[ii].name;
    571             functions[ii].name = Strdup(demangled);
    572             free(demangled);
    573         }
    574     }
    575 }
    576 
    577 // Adds the symbols from the given ELF file to the given process.
    578 // Returns false if the file was not an ELF file or if there was an
    579 // error trying to read the sections of the ELF file.
    580 template<class T>
    581 bool TraceReader<T>::ReadElfSymbols(region_type *region, uint32_t flags)
    582 {
    583     static char full_path[4096];
    584     Elf32_Shdr  *symtab, *symstr;
    585     Elf32_Ehdr  *hdr;
    586     Elf32_Shdr  *shdr;
    587 
    588     full_path[0] = 0;
    589     if (root_ && strcmp(root_, "/")) {
    590         strcpy(full_path, root_);
    591     }
    592     strcat(full_path, region->path);
    593     FILE *fobj = fopen(full_path, "r");
    594     if(fobj == NULL) {
    595     EmptyRegion:
    596         // we need to create an (unknown) symbol with address 0, otherwise some
    597         // other parts of the trace reader will simply crash when dealing with
    598         // an empty region
    599         region->vstart = 0;
    600         region->nsymbols = 1;
    601         region->symbols  = new symbol_type[1];
    602         memset(region->symbols, 0, sizeof(symbol_type));
    603 
    604         region->symbols[0].addr   = 0;
    605         region->symbols[0].name   = Strdup("(unknown)");
    606         region->symbols[0].vm_sym = NULL;
    607         region->symbols[0].region = region;
    608         region->symbols[0].flags  = 0;
    609 
    610         if (fobj != NULL)
    611             fclose(fobj);
    612         return false;
    613     }
    614 
    615     hdr = ReadElfHeader(fobj);
    616     if (hdr == NULL) {
    617         fprintf(stderr, "Cannot read ELF header from '%s'\n", full_path);
    618         goto EmptyRegion;
    619     }
    620 
    621     shdr = ReadSectionHeaders(hdr, fobj);
    622     if(shdr == NULL) {
    623         fprintf(stderr, "Can't read section headers from executable\n");
    624         goto EmptyRegion;
    625     }
    626     char *section_names = ReadStringTable(hdr, shdr, fobj);
    627 
    628     // Get the symbol table section
    629     symtab = FindSymbolTableSection(hdr, shdr, section_names);
    630     if (symtab == NULL || symtab->sh_size == 0) {
    631         fprintf(stderr, "Can't read symbol table from '%s'\n", full_path);
    632         goto EmptyRegion;
    633     }
    634 
    635     // Get the symbol string table section
    636     symstr = FindSymbolStringTableSection(hdr, shdr, section_names);
    637     if (symstr == NULL || symstr->sh_size == 0) {
    638         fprintf(stderr, "Can't read symbol string table from '%s'\n", full_path);
    639         goto EmptyRegion;
    640     }
    641 
    642     // Load the symbol string table data
    643     char *symbol_names = new char[symstr->sh_size];
    644     ReadSection(symstr, symbol_names, fobj);
    645 
    646     int num_entries = symtab->sh_size / symtab->sh_entsize;
    647     Elf32_Sym *elf_symbols = new Elf32_Sym[num_entries];
    648     ReadSection(symtab, elf_symbols, fobj);
    649     AdjustElfSymbols(hdr, elf_symbols, num_entries);
    650 #if 0
    651     printf("size: %d, ent_size: %d, num_entries: %d\n",
    652            symtab->sh_size, symtab->sh_entsize, num_entries);
    653 #endif
    654     int nfuncs = 0;
    655 
    656     // Allocate space for all of the symbols for now.  We will
    657     // reallocate space for just the function symbols after we
    658     // know how many there are.  Also, make sure there is room
    659     // for some extra symbols, including the text section names.
    660     int num_alloc = num_entries + hdr->e_shnum + 1;
    661     symbol_type *func_symbols = new symbol_type[num_alloc];
    662     memset(func_symbols, 0, num_alloc * sizeof(symbol_type));
    663 
    664     // If this is the shared library for a virtual machine, then
    665     // set the IsInterpreter flag for all symbols in that shared library.
    666     // This will allow us to replace the symbol names with the name of
    667     // the currently executing method on the virtual machine.
    668     int symbol_flags = 0;
    669     char *cp = strrchr(region->path, '/');
    670     if (cp != NULL) {
    671         // Move past the '/'
    672         cp += 1;
    673     } else {
    674         // There was no '/', so use the whole path
    675         cp = region->path;
    676     }
    677     if (strcmp(cp, "libdvm.so") == 0) {
    678         symbol_flags = symbol_type::kIsInterpreter;
    679     }
    680 
    681     bool zero_found = false;
    682     for (int ii = 1; ii < num_entries; ++ii) {
    683         int idx = elf_symbols[ii].st_name;
    684 
    685         // If the symbol does not have a name, or if the name starts with a
    686         // dollar sign ($), then skip it.
    687         if (idx == 0 || symbol_names[idx] == 0 || symbol_names[idx] == '$')
    688             continue;
    689 
    690         // If the section index is not executable, then skip it.
    691         uint32_t section = elf_symbols[ii].st_shndx;
    692         if (section == 0 || section >= hdr->e_shnum)
    693             continue;
    694         if ((shdr[section].sh_flags & SHF_EXECINSTR) == 0)
    695             continue;
    696 
    697         uint8_t sym_type = ELF32_ST_TYPE(elf_symbols[ii].st_info);
    698         uint8_t sym_bind = ELF32_ST_BIND(elf_symbols[ii].st_info);
    699 
    700         // Allow the caller to decide if we want local non-function
    701         // symbols to be included.  We currently include these symbols
    702         // only for the kernel, where it is useful because the kernel
    703         // has lots of assembly language labels that have meaningful names.
    704         if ((flags & kIncludeLocalSymbols) == 0 && sym_bind == STB_LOCAL
    705             && sym_type != STT_FUNC) {
    706             continue;
    707         }
    708 #if 0
    709         printf("%08x %x %x %s\n",
    710                elf_symbols[ii].st_value,
    711                sym_bind,
    712                sym_type,
    713                &symbol_names[idx]);
    714 #endif
    715         if (sym_type != STT_FUNC && sym_type != STT_NOTYPE)
    716             continue;
    717 
    718         if (elf_symbols[ii].st_value == 0)
    719             zero_found = true;
    720 
    721         // The address of thumb functions seem to have the low bit set,
    722         // even though the instructions are really at an even address.
    723         uint32_t addr = elf_symbols[ii].st_value & ~0x1;
    724         func_symbols[nfuncs].addr = addr;
    725         func_symbols[nfuncs].name = Strdup(&symbol_names[idx]);
    726         func_symbols[nfuncs].flags = symbol_flags;
    727 
    728         nfuncs += 1;
    729     }
    730 
    731     // Add a [0, "(unknown)"] symbol pair if there is not already a
    732     // symbol with the address zero.  We don't need to reallocate space
    733     // because we already have more than we need.
    734     if (!zero_found) {
    735         func_symbols[nfuncs].addr = 0;
    736         func_symbols[nfuncs].name = Strdup("(0 unknown)");
    737         nfuncs += 1;
    738     }
    739 
    740     // Add another entry at the end
    741     func_symbols[nfuncs].addr = 0xffffffff;
    742     func_symbols[nfuncs].name = Strdup("(end)");
    743     nfuncs += 1;
    744 
    745     // Add in the names of the text sections, but only if there
    746     // are no symbols with that address already.
    747     for (int section = 0; section < hdr->e_shnum; ++section) {
    748         if ((shdr[section].sh_flags & SHF_EXECINSTR) == 0)
    749             continue;
    750 
    751         uint32_t addr = shdr[section].sh_addr;
    752         // Search for a symbol with a matching address.  The symbols aren't
    753         // sorted yet so we just search the whole list.
    754         int ii;
    755         for (ii = 0; ii < nfuncs; ++ii) {
    756             if (addr == func_symbols[ii].addr)
    757                 break;
    758         }
    759         if (ii == nfuncs) {
    760             // Symbol at address "addr" does not exist, so add the text
    761             // section name.  This will usually add the ".plt" section
    762             // (procedure linkage table).
    763             int idx = shdr[section].sh_name;
    764             func_symbols[nfuncs].addr = addr;
    765             func_symbols[nfuncs].name = Strdup(&section_names[idx]);
    766             if (strcmp(func_symbols[nfuncs].name, ".plt") == 0) {
    767                 func_symbols[nfuncs].flags |= symbol_type::kIsPlt;
    768                 // Change the name of the symbol to include the
    769                 // name of the library.  Otherwise we will have lots
    770                 // of ".plt" symbols.
    771                 int len = strlen(region->path);
    772                 len += strlen(":.plt");
    773                 char *name = new char[len + 1];
    774                 strcpy(name, region->path);
    775                 strcat(name, ":.plt");
    776                 delete[] func_symbols[nfuncs].name;
    777                 func_symbols[nfuncs].name = name;
    778 
    779                 // Check if this is part of the virtual machine interpreter
    780                 char *cp = strrchr(region->path, '/');
    781                 if (cp != NULL) {
    782                     // Move past the '/'
    783                     cp += 1;
    784                 } else {
    785                     // There was no '/', so use the whole path
    786                     cp = region->path;
    787                 }
    788                 if (strcmp(cp, "libdvm.so") == 0) {
    789                     func_symbols[nfuncs].flags |= symbol_type::kIsInterpreter;
    790                 }
    791             }
    792             nfuncs += 1;
    793         }
    794     }
    795 
    796     // Allocate just the space we need now that we know exactly
    797     // how many symbols we have.
    798     symbol_type *functions = new symbol_type[nfuncs];
    799 
    800     // Copy the symbols to the functions array
    801     memcpy(functions, func_symbols, nfuncs * sizeof(symbol_type));
    802     delete[] func_symbols;
    803 
    804     // Assign the region pointers
    805     for (int ii = 0; ii < nfuncs; ++ii) {
    806         functions[ii].region = region;
    807     }
    808 
    809     // Sort the symbols into increasing address order
    810     qsort(functions, nfuncs, sizeof(symbol_type), cmp_symbol_addr<T>);
    811 
    812     // If there are multiple symbols with the same address, then remove
    813     // the duplicates.  First, count the number of duplicates.
    814     uint32_t prev_addr = ~0;
    815     int num_duplicates = 0;
    816     for (int ii = 0; ii < nfuncs; ++ii) {
    817         if (prev_addr == functions[ii].addr)
    818             num_duplicates += 1;
    819         prev_addr = functions[ii].addr;
    820     }
    821 
    822     if (num_duplicates > 0) {
    823         int num_uniq = nfuncs - num_duplicates;
    824 
    825         // Allocate space for the unique functions
    826         symbol_type *uniq_functions = new symbol_type[num_uniq];
    827 
    828         // Copy the unique functions
    829         prev_addr = ~0;
    830         int next_uniq = 0;
    831         for (int ii = 0; ii < nfuncs; ++ii) {
    832             if (prev_addr == functions[ii].addr) {
    833                 delete[] functions[ii].name;
    834                 continue;
    835             }
    836             memcpy(&uniq_functions[next_uniq++], &functions[ii],
    837                    sizeof(symbol_type));
    838             prev_addr = functions[ii].addr;
    839         }
    840         assert(next_uniq == num_uniq);
    841 
    842         delete[] functions;
    843         functions = uniq_functions;
    844         nfuncs = num_uniq;
    845     }
    846 
    847     // Finally, demangle all of the symbol names
    848     demangle_names(nfuncs, functions);
    849 
    850     uint32_t min_addr = 0;
    851     if (!zero_found)
    852         min_addr = functions[1].addr;
    853     if (region->vstart == 0)
    854         region->vstart = min_addr;
    855     region->nsymbols = nfuncs;
    856     region->symbols = functions;
    857 
    858 #if 0
    859     printf("%s num symbols: %d min_addr: 0x%x\n", region->path, nfuncs, min_addr);
    860     for (int ii = 0; ii < nfuncs; ++ii) {
    861         printf("0x%08x %s\n", functions[ii].addr, functions[ii].name);
    862     }
    863 #endif
    864     delete[] elf_symbols;
    865     delete[] symbol_names;
    866     delete[] section_names;
    867     delete[] shdr;
    868     delete hdr;
    869     fclose(fobj);
    870 
    871     return true;
    872 }
    873 
    874 template<class T>
    875 void TraceReader<T>::CopyKernelRegion(ProcessState *pstate)
    876 {
    877     ProcessState *manager = pstate->addr_manager;
    878     if (manager->flags & ProcessState::kHasKernelRegion)
    879         return;
    880 
    881     int nregions = processes_[0]->nregions;
    882     region_type **regions = processes_[0]->regions;
    883     for (int ii = 0; ii < nregions; ii++) {
    884         if (regions[ii]->flags & region_type::kIsKernelRegion) {
    885             AddRegion(manager, regions[ii]);
    886             regions[ii]->refs += 1;
    887         }
    888     }
    889     manager->flags |= ProcessState::kHasKernelRegion;
    890 }
    891 
    892 template<class T>
    893 void TraceReader<T>::ClearRegions(ProcessState *pstate)
    894 {
    895     assert(pstate->pid != 0);
    896     int nregions = pstate->nregions;
    897     region_type **regions = pstate->regions;
    898 
    899     // Decrement the reference count on all the regions
    900     for (int ii = 0; ii < nregions; ii++) {
    901         if (regions[ii]->refs > 0) {
    902             regions[ii]->refs -= 1;
    903             continue;
    904         }
    905 
    906         delete regions[ii];
    907     }
    908     delete[] pstate->regions;
    909     pstate->regions = NULL;
    910     pstate->nregions = 0;
    911     pstate->max_regions = 0;
    912     pstate->addr_manager = pstate;
    913     pstate->flags &= ~ProcessState::kIsClone;
    914     pstate->flags &= ~ProcessState::kHasKernelRegion;
    915     CopyKernelRegion(pstate);
    916 }
    917 
    918 template<class T>
    919 void TraceReader<T>::AddRegion(ProcessState *pstate, region_type *region)
    920 {
    921     ProcessState *manager = pstate->addr_manager;
    922     if (manager->regions == NULL) {
    923         manager->max_regions = ProcessState::kInitialNumRegions;
    924         manager->regions = new region_type*[manager->max_regions];
    925         manager->nregions = 0;
    926     }
    927 
    928     // Check if we need to grow the array
    929     int nregions = manager->nregions;
    930     int max_regions = manager->max_regions;
    931     if (nregions >= max_regions) {
    932         max_regions <<= 1;
    933         manager->max_regions = max_regions;
    934         region_type **regions = new region_type*[max_regions];
    935         for (int ii = 0; ii < nregions; ii++) {
    936             regions[ii] = manager->regions[ii];
    937         }
    938         delete[] manager->regions;
    939         manager->regions = regions;
    940     }
    941 
    942     // Add the new region to the end of the array and resort
    943     manager->regions[nregions] = region;
    944     nregions += 1;
    945     manager->nregions = nregions;
    946 
    947     // Resort the regions into increasing start address
    948     qsort(manager->regions, nregions, sizeof(region_type*), cmp_region_addr<T>);
    949 }
    950 
    951 template<class T>
    952 void TraceReader<T>::FindAndRemoveRegion(ProcessState *pstate, uint32_t vstart,
    953                                          uint32_t vend)
    954 {
    955     ProcessState *manager = pstate->addr_manager;
    956     int nregions = manager->nregions;
    957     int index = FindRegionIndex(vstart, nregions, manager->regions);
    958     region_type *region = manager->regions[index];
    959 
    960     // If the region does not contain [vstart,vend], then return.
    961     if (vstart < region->vstart || vend > region->vend)
    962         return;
    963 
    964     // If the existing region exactly matches the address range [vstart,vend]
    965     // then remove the whole region.
    966     if (vstart == region->vstart && vend == region->vend) {
    967         // The regions are reference-counted.
    968         if (region->refs == 0) {
    969             // Free the region
    970             hash_->Remove(region->path);
    971             delete region;
    972         } else {
    973             region->refs -= 1;
    974         }
    975 
    976         if (nregions > 1) {
    977             // Assign the region at the end of the array to this empty slot
    978             manager->regions[index] = manager->regions[nregions - 1];
    979 
    980             // Resort the regions into increasing start address
    981             qsort(manager->regions, nregions - 1, sizeof(region_type*),
    982                   cmp_region_addr<T>);
    983         }
    984         manager->nregions = nregions - 1;
    985         return;
    986     }
    987 
    988     // If the existing region contains the given range and ends at the
    989     // end of the given range (a common case for some reason), then
    990     // truncate the existing region so that it ends at vstart (because
    991     // we are deleting the range [vstart,vend]).
    992     if (vstart > region->vstart && vend == region->vend) {
    993         region_type *truncated;
    994 
    995         if (region->refs == 0) {
    996             // This region is not shared, so truncate it directly
    997             truncated = region;
    998         } else {
    999             // This region is shared, so make a copy that we can truncate
   1000             region->refs -= 1;
   1001             truncated = region->MakePrivateCopy(new region_type);
   1002         }
   1003         truncated->vend = vstart;
   1004         manager->regions[index] = truncated;
   1005     }
   1006 }
   1007 
   1008 template<class T>
   1009 void TraceReader<T>::CopyRegions(ProcessState *parent, ProcessState *child)
   1010 {
   1011     // Copy the parent's address space
   1012     ProcessState *manager = parent->addr_manager;
   1013     int nregions = manager->nregions;
   1014     child->nregions = nregions;
   1015     child->max_regions = manager->max_regions;
   1016     region_type **regions = new region_type*[manager->max_regions];
   1017     child->regions = regions;
   1018     memcpy(regions, manager->regions, nregions * sizeof(region_type*));
   1019 
   1020     // Increment the reference count on all the regions
   1021     for (int ii = 0; ii < nregions; ii++) {
   1022         regions[ii]->refs += 1;
   1023     }
   1024 }
   1025 
   1026 template<class T>
   1027 void TraceReader<T>::DumpRegions(FILE *stream, ProcessState *pstate) {
   1028     ProcessState *manager = pstate->addr_manager;
   1029     for (int ii = 0; ii < manager->nregions; ++ii) {
   1030         fprintf(stream, "  %08x - %08x offset: %5x  nsyms: %4d refs: %d %s\n",
   1031                 manager->regions[ii]->vstart,
   1032                 manager->regions[ii]->vend,
   1033                 manager->regions[ii]->file_offset,
   1034                 manager->regions[ii]->nsymbols,
   1035                 manager->regions[ii]->refs,
   1036                 manager->regions[ii]->path);
   1037     }
   1038 }
   1039 
   1040 template<class T>
   1041 typename TraceReader<T>::region_type *
   1042 TraceReader<T>::FindRegion(uint32_t addr, int nregions, region_type **regions)
   1043 {
   1044     int high = nregions;
   1045     int low = -1;
   1046     while (low + 1 < high) {
   1047         int middle = (high + low) / 2;
   1048         uint32_t middle_addr = regions[middle]->vstart;
   1049         if (middle_addr == addr)
   1050             return regions[middle];
   1051         if (middle_addr > addr)
   1052             high = middle;
   1053         else
   1054             low = middle;
   1055     }
   1056 
   1057     // If we get here then we did not find an exact address match.  So use
   1058     // the closest region address that is less than the given address.
   1059     if (low < 0)
   1060         low = 0;
   1061     return regions[low];
   1062 }
   1063 
   1064 template<class T>
   1065 int TraceReader<T>::FindRegionIndex(uint32_t addr, int nregions,
   1066                                     region_type **regions)
   1067 {
   1068     int high = nregions;
   1069     int low = -1;
   1070     while (low + 1 < high) {
   1071         int middle = (high + low) / 2;
   1072         uint32_t middle_addr = regions[middle]->vstart;
   1073         if (middle_addr == addr)
   1074             return middle;
   1075         if (middle_addr > addr)
   1076             high = middle;
   1077         else
   1078             low = middle;
   1079     }
   1080 
   1081     // If we get here then we did not find an exact address match.  So use
   1082     // the closest region address that is less than the given address.
   1083     if (low < 0)
   1084         low = 0;
   1085     return low;
   1086 }
   1087 
   1088 template<class T>
   1089 typename TraceReader<T>::symbol_type *
   1090 TraceReader<T>::FindFunction(uint32_t addr, int nsyms, symbol_type *symbols,
   1091                              bool exact_match)
   1092 {
   1093     int high = nsyms;
   1094     int low = -1;
   1095     while (low + 1 < high) {
   1096         int middle = (high + low) / 2;
   1097         uint32_t middle_addr = symbols[middle].addr;
   1098         if (middle_addr == addr)
   1099             return &symbols[middle];
   1100         if (middle_addr > addr)
   1101             high = middle;
   1102         else
   1103             low = middle;
   1104     }
   1105 
   1106     // If we get here then we did not find an exact address match.  So use
   1107     // the closest function address that is less than the given address.
   1108     // We added a symbol with address zero so if there is no known
   1109     // function containing the given address, then we will return the
   1110     // "(unknown)" symbol.
   1111     if (low >= 0 && !exact_match)
   1112         return &symbols[low];
   1113     return NULL;
   1114 }
   1115 
   1116 template<class T>
   1117 typename TraceReader<T>::symbol_type *
   1118 TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
   1119 {
   1120     // Check if the previous match is still a good match.
   1121     if (cached_pid_ == pid) {
   1122         uint32_t vstart = cached_func_->region->vstart;
   1123         uint32_t vend = cached_func_->region->vend;
   1124         if (addr >= vstart && addr < vend) {
   1125             uint32_t sym_addr = addr - cached_func_->region->base_addr;
   1126             if (sym_addr >= cached_func_->addr
   1127                 && sym_addr < (cached_func_ + 1)->addr) {
   1128 
   1129                 // Check if there is a Java method on the method trace.
   1130                 symbol_type *sym = FindCurrentMethod(pid, time);
   1131                 if (sym != NULL) {
   1132                     sym->vm_sym = cached_func_;
   1133                     return sym;
   1134                 }
   1135                 return cached_func_;
   1136             }
   1137         }
   1138     }
   1139 
   1140     ProcessState *pstate = processes_[pid];
   1141     if (pstate == NULL) {
   1142         // There is no process state for the specified pid.
   1143         // This should never happen.
   1144         cached_pid_ = -1;
   1145         cached_func_ = NULL;
   1146         return NULL;
   1147     }
   1148     ProcessState *manager = pstate->addr_manager;
   1149     cached_pid_ = pid;
   1150     region_type *region = FindRegion(addr, manager->nregions, manager->regions);
   1151     uint32_t sym_addr = addr - region->base_addr;
   1152 
   1153     cached_func_ = FindFunction(sym_addr, region->nsymbols, region->symbols,
   1154                                 false /* no exact match */);
   1155     if (cached_func_ != NULL) {
   1156         cached_func_->region = region;
   1157 
   1158         // Check if there is a Java method on the method trace.
   1159         symbol_type *sym = FindCurrentMethod(pid, time);
   1160         if (sym != NULL) {
   1161             sym->vm_sym = cached_func_;
   1162             return sym;
   1163         }
   1164     }
   1165 
   1166     return cached_func_;
   1167 }
   1168 
   1169 template <class T>
   1170 void TraceReader<T>::HandlePidEvent(PidEvent *event)
   1171 {
   1172     switch (event->rec_type) {
   1173     case kPidFork:
   1174     case kPidClone:
   1175         // event->pid is the process id of the child
   1176         if (event->pid >= kNumPids) {
   1177             fprintf(stderr, "Error: pid (%d) too large\n", event->pid);
   1178             exit(1);
   1179         }
   1180         // Create a new ProcessState struct for the child
   1181         // and link it in at the front of the list for that
   1182         // pid.
   1183         {
   1184             ProcessState *child = new ProcessState;
   1185             processes_[event->pid] = child;
   1186             child->pid = event->pid;
   1187             child->tgid = event->tgid;
   1188 
   1189             // Link the new child at the front of the list (only needed if
   1190             // pids wrap around, which will probably never happen when
   1191             // tracing because it would take so long).
   1192             child->next = processes_[event->pid];
   1193             child->parent_pid = current_->pid;
   1194             child->parent = current_;
   1195             child->start_time = event->time;
   1196             child->name = Strdup(current_->name);
   1197             if (event->rec_type == kPidFork) {
   1198                 CopyRegions(current_, child);
   1199             } else {
   1200                 // Share the parent's address space
   1201                 child->flags |= ProcessState::kIsClone;
   1202 
   1203                 // The address space manager for the clone is the same
   1204                 // as the address space manager for the parent.  This works
   1205                 // even if the child later clones itself.
   1206                 child->addr_manager = current_->addr_manager;
   1207             }
   1208         }
   1209         break;
   1210     case kPidSwitch:
   1211         // event->pid is the process id of the process we are
   1212         // switching to.
   1213         {
   1214             uint64_t elapsed = event->time - function_start_time_;
   1215             function_start_time_ = event->time;
   1216             current_->cpu_time += elapsed;
   1217         }
   1218         if (current_->flags & ProcessState::kCalledExit)
   1219             current_->end_time = event->time;
   1220 
   1221         if (event->pid >= kNumPids) {
   1222             fprintf(stderr, "Error: pid (%d) too large\n", event->pid);
   1223             exit(1);
   1224         }
   1225 
   1226         // If the process we are switching to does not exist, then
   1227         // create one.  This can happen because the tracing code does
   1228         // not start tracing from the very beginning of the kernel.
   1229         current_ = processes_[event->pid];
   1230         if (current_ == NULL) {
   1231             current_ = new ProcessState;
   1232             processes_[event->pid] = current_;
   1233             current_->pid = event->pid;
   1234             current_->start_time = event->time;
   1235             CopyKernelRegion(current_);
   1236         }
   1237 #if 0
   1238         {
   1239             printf("switching to p%d\n", current_->pid);
   1240             ProcessState *manager = current_->addr_manager;
   1241             for (int ii = 0; ii < manager->nregions; ++ii) {
   1242                 printf("  %08x - %08x offset: %d nsyms: %4d %s\n",
   1243                        manager->regions[ii]->vstart,
   1244                        manager->regions[ii]->vend,
   1245                        manager->regions[ii]->file_offset,
   1246                        manager->regions[ii]->nsymbols,
   1247                        manager->regions[ii]->path);
   1248             }
   1249         }
   1250 #endif
   1251         break;
   1252     case kPidExit:
   1253         current_->exit_val = event->pid;
   1254         current_->flags |= ProcessState::kCalledExit;
   1255         break;
   1256     case kPidMunmap:
   1257         FindAndRemoveRegion(current_, event->vstart, event->vend);
   1258         break;
   1259     case kPidMmap:
   1260         {
   1261             region_type *region;
   1262             region_type *existing_region = hash_->Find(event->path);
   1263             if (existing_region == NULL
   1264                 || existing_region->vstart != event->vstart
   1265                 || existing_region->vend != event->vend
   1266                 || existing_region->file_offset != event->offset) {
   1267                 // Create a new region and add it to the current process'
   1268                 // address space.
   1269                 region = new region_type;
   1270 
   1271                 // The event->path is allocated by ReadPidEvent() and owned
   1272                 // by us.
   1273                 region->path = event->path;
   1274                 region->vstart = event->vstart;
   1275                 region->vend = event->vend;
   1276                 region->file_offset = event->offset;
   1277                 if (existing_region == NULL) {
   1278                     DexFileList *dexfile = dex_hash_->Find(event->path);
   1279                     if (dexfile != NULL) {
   1280                         PopulateSymbolsFromDexFile(dexfile, region);
   1281                     } else {
   1282                         ReadElfSymbols(region, 0);
   1283                     }
   1284                     hash_->Update(region->path, region);
   1285                 } else {
   1286                     region->nsymbols = existing_region->nsymbols;
   1287                     region->symbols = existing_region->symbols;
   1288                     region->flags |= region_type::kSharedSymbols;
   1289                 }
   1290 
   1291                 // The base_addr is subtracted from an address before the
   1292                 // symbol name lookup and is either zero or event->vstart.
   1293                 // HACK: Determine if base_addr is non-zero by looking at the
   1294                 // second symbol address (skip the first symbol because that is
   1295                 // the special symbol "(unknown)" with an address of zero).
   1296                 if (region->nsymbols > 2 && region->symbols[1].addr < event->vstart)
   1297                     region->base_addr = event->vstart;
   1298 
   1299                 // Treat all mmapped regions after the first as "libraries".
   1300                 // Profiling tools can test for this property.
   1301                 if (current_->flags & ProcessState::kHasFirstMmap)
   1302                     region->flags |= region_type::kIsLibraryRegion;
   1303                 else
   1304                     current_->flags |= ProcessState::kHasFirstMmap;
   1305 #if 0
   1306                 printf("%s vstart: 0x%x vend: 0x%x offset: 0x%x\n",
   1307                        region->path, region->vstart, region->vend, region->file_offset);
   1308 #endif
   1309             } else {
   1310                 region = existing_region;
   1311                 region->refs += 1;
   1312                 delete[] event->path;
   1313             }
   1314             AddRegion(current_, region);
   1315         }
   1316         break;
   1317     case kPidExec:
   1318         if (current_->argc > 0) {
   1319             for (int ii = 0; ii < current_->argc; ii++) {
   1320                 delete[] current_->argv[ii];
   1321             }
   1322             delete[] current_->argv;
   1323         }
   1324         delete[] current_->name;
   1325 
   1326         current_->argc = event->argc;
   1327         current_->argv = event->argv;
   1328         current_->name = Strdup(current_->argv[0]);
   1329         current_->flags |= ProcessState::kCalledExec;
   1330         ClearRegions(current_);
   1331         break;
   1332     case kPidName:
   1333     case kPidKthreadName:
   1334         {
   1335             ProcessState *pstate = processes_[event->pid];
   1336             if (pstate == NULL) {
   1337                 pstate = new ProcessState;
   1338                 if (event->rec_type == kPidKthreadName) {
   1339                     pstate->tgid = event->tgid;
   1340                 }
   1341                 pstate->pid = event->pid;
   1342                 pstate->start_time = event->time;
   1343                 processes_[event->pid] = pstate;
   1344                 CopyKernelRegion(pstate);
   1345             } else {
   1346                 delete[] pstate->name;
   1347             }
   1348             pstate->name = event->path;
   1349         }
   1350         break;
   1351     case kPidNoAction:
   1352         break;
   1353     case kPidSymbolAdd:
   1354         delete[] event->path;
   1355         break;
   1356     case kPidSymbolRemove:
   1357         break;
   1358     }
   1359 }
   1360 
   1361 // Finds the current pid for the given time.  This routine reads the pid
   1362 // trace file and assumes that the "time" parameter is monotonically
   1363 // increasing.
   1364 template <class T>
   1365 int TraceReader<T>::FindCurrentPid(uint64_t time)
   1366 {
   1367     if (time < next_pid_event_.time)
   1368         return current_->pid;
   1369 
   1370     while (1) {
   1371         HandlePidEvent(&next_pid_event_);
   1372 
   1373         if (internal_pid_reader_->ReadPidEvent(&next_pid_event_)) {
   1374             next_pid_event_.time = ~0ull;
   1375             break;
   1376         }
   1377         if (next_pid_event_.time > time)
   1378             break;
   1379     }
   1380     return current_->pid;
   1381 }
   1382 
   1383 template <class T>
   1384 void TraceReader<T>::ProcessState::DumpStack(FILE *stream)
   1385 {
   1386     const char *native;
   1387     for (int ii = 0; ii < method_stack_top; ii++) {
   1388         native = method_stack[ii].isNative ? "n" : " ";
   1389         fprintf(stream, "%2d: %s 0x%08x\n", ii, native, method_stack[ii].addr);
   1390     }
   1391 }
   1392 
   1393 template <class T>
   1394 void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
   1395                                         MethodRec *method_rec)
   1396 {
   1397     uint32_t addr;
   1398     int top = pstate->method_stack_top;
   1399     int flags = method_rec->flags;
   1400     bool isNative;
   1401     if (flags == kMethodEnter || flags == kNativeEnter) {
   1402         // Push this method on the stack
   1403         if (top >= pstate->kMaxMethodStackSize) {
   1404             fprintf(stderr, "Stack overflow at time %llu\n", method_rec->time);
   1405             exit(1);
   1406         }
   1407         pstate->method_stack[top].addr = method_rec->addr;
   1408         isNative = (flags == kNativeEnter);
   1409         pstate->method_stack[top].isNative = isNative;
   1410         pstate->method_stack_top = top + 1;
   1411         addr = method_rec->addr;
   1412     } else {
   1413         if (top <= 0) {
   1414             // If the stack underflows, then set the current method to NULL.
   1415             pstate->current_method_sym = NULL;
   1416             return;
   1417         }
   1418         top -= 1;
   1419         addr = pstate->method_stack[top].addr;
   1420 
   1421         // If this is a non-native method then the address we are popping should
   1422         // match the top-of-stack address.  Native pops don't always match the
   1423         // address of the native push for some reason.
   1424         if (addr != method_rec->addr && !pstate->method_stack[top].isNative) {
   1425             fprintf(stderr,
   1426                     "Stack method (0x%x) at index %d does not match trace record (0x%x) at time %llu\n",
   1427                     addr, top, method_rec->addr, method_rec->time);
   1428             pstate->DumpStack(stderr);
   1429             exit(1);
   1430         }
   1431 
   1432         // If we are popping a native method, then the top-of-stack should also
   1433         // be a native method.
   1434         bool poppingNative = (flags == kNativeExit) || (flags == kNativeException);
   1435         if (poppingNative != pstate->method_stack[top].isNative) {
   1436             fprintf(stderr,
   1437                     "Popping native vs. non-native mismatch at index %d time %llu\n",
   1438                     top, method_rec->time);
   1439             pstate->DumpStack(stderr);
   1440             exit(1);
   1441         }
   1442 
   1443         pstate->method_stack_top = top;
   1444         if (top == 0) {
   1445             // When we empty the stack, set the current method to NULL
   1446             pstate->current_method_sym = NULL;
   1447             return;
   1448         }
   1449         addr = pstate->method_stack[top - 1].addr;
   1450         isNative = pstate->method_stack[top - 1].isNative;
   1451     }
   1452 
   1453     // If the top-of-stack is a native method, then set the current method
   1454     // to NULL.
   1455     if (isNative) {
   1456         pstate->current_method_sym = NULL;
   1457         return;
   1458     }
   1459 
   1460     ProcessState *manager = pstate->addr_manager;
   1461     region_type *region = FindRegion(addr, manager->nregions, manager->regions);
   1462     uint32_t sym_addr = addr - region->base_addr;
   1463     symbol_type *sym = FindFunction(sym_addr, region->nsymbols,
   1464                                     region->symbols, true /* exact match */);
   1465 
   1466     pstate->current_method_sym = sym;
   1467     if (sym != NULL) {
   1468         sym->region = region;
   1469     }
   1470 }
   1471 
   1472 // Returns the current top-of-stack Java method, if any, for the given pid
   1473 // at the given time. The "time" parameter must be monotonically increasing
   1474 // across successive calls to this method.
   1475 // If the Java method stack is empty or if a native JNI method is on the
   1476 // top of the stack, then this method returns NULL.
   1477 template <class T>
   1478 typename TraceReader<T>::symbol_type*
   1479 TraceReader<T>::FindCurrentMethod(int pid, uint64_t time)
   1480 {
   1481     ProcessState *procState = processes_[pid];
   1482 
   1483     if (time < next_method_.time) {
   1484         return procState->current_method_sym;
   1485     }
   1486 
   1487     while (1) {
   1488         if (next_method_.time != 0) {
   1489             // We may have to process methods from a different pid so use
   1490             // a local variable here so that we don't overwrite procState.
   1491             ProcessState *pState = processes_[next_method_.pid];
   1492             HandleMethodRecord(pState, &next_method_);
   1493         }
   1494 
   1495         if (internal_method_reader_->ReadMethod(&next_method_)) {
   1496             next_method_.time = ~0ull;
   1497             break;
   1498         }
   1499         if (next_method_.time > time)
   1500             break;
   1501     }
   1502     return procState->current_method_sym;
   1503 }
   1504 
   1505 template <class T>
   1506 void TraceReader<T>::PopulateSymbolsFromDexFile(const DexFileList *dexfile,
   1507                                                 region_type *region)
   1508 
   1509 {
   1510     int nsymbols = dexfile->nsymbols;
   1511     DexSym *dexsyms = dexfile->symbols;
   1512     region->nsymbols = nsymbols + 1;
   1513     symbol_type *symbols = new symbol_type[nsymbols + 1];
   1514     memset(symbols, 0, (nsymbols + 1) * sizeof(symbol_type));
   1515     region->symbols = symbols;
   1516     for (int ii = 0; ii < nsymbols; ii++) {
   1517         symbols[ii].addr = dexsyms[ii].addr;
   1518         symbols[ii].name = Strdup(dexsyms[ii].name);
   1519         symbols[ii].vm_sym = NULL;
   1520         symbols[ii].region = region;
   1521         symbols[ii].flags = symbol_type::kIsMethod;
   1522     }
   1523 
   1524     // Add an entry at the end with an address of 0xffffffff.  This
   1525     // is required for LookupFunction() to work.
   1526     symbol_type *symbol = &symbols[nsymbols];
   1527     symbol->addr = 0xffffffff;
   1528     symbol->name = Strdup("(end)");
   1529     symbol->vm_sym = NULL;
   1530     symbol->region = region;
   1531     symbol->flags = symbol_type::kIsMethod;
   1532 }
   1533 
   1534 template <class T>
   1535 bool TraceReader<T>::ReadMethodSymbol(MethodRec *method_record,
   1536                                       symbol_type **psym,
   1537                                       ProcessState **pproc)
   1538 {
   1539     if (internal_method_reader_->ReadMethod(&next_method_)) {
   1540         return true;
   1541     }
   1542 
   1543     // Copy the whole MethodRec struct
   1544     *method_record = next_method_;
   1545 
   1546     uint64_t time = next_method_.time;
   1547 
   1548     // Read the pid trace file up to this point to make sure the
   1549     // process state is valid.
   1550     FindCurrentPid(time);
   1551 
   1552     ProcessState *pstate = processes_[next_method_.pid];
   1553     *pproc = pstate;
   1554     HandleMethodRecord(pstate, &next_method_);
   1555     *psym = pstate->current_method_sym;
   1556     return false;
   1557 }
   1558 
   1559 #endif /* TRACE_READER_H */
   1560