Home | History | Annotate | Download | only in processor
      1 // Copyright (c) 2006, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // basic_code_modules.cc: Contains all of the CodeModule objects that
     31 // were loaded into a single process.
     32 //
     33 // See basic_code_modules.h for documentation.
     34 //
     35 // Author: Mark Mentovai
     36 
     37 #include "processor/basic_code_modules.h"
     38 
     39 #include <assert.h>
     40 
     41 #include "google_breakpad/processor/code_module.h"
     42 #include "processor/linked_ptr.h"
     43 #include "processor/logging.h"
     44 #include "processor/range_map-inl.h"
     45 
     46 namespace google_breakpad {
     47 
     48 BasicCodeModules::BasicCodeModules(const CodeModules *that)
     49     : main_address_(0),
     50       map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
     51   BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires "
     52                             "|that|";
     53   assert(that);
     54 
     55   const CodeModule *main_module = that->GetMainModule();
     56   if (main_module)
     57     main_address_ = main_module->base_address();
     58 
     59   unsigned int count = that->module_count();
     60   for (unsigned int module_sequence = 0;
     61        module_sequence < count;
     62        ++module_sequence) {
     63     // Make a copy of the module and insert it into the map.  Use
     64     // GetModuleAtIndex because ordering is unimportant when slurping the
     65     // entire list, and GetModuleAtIndex may be faster than
     66     // GetModuleAtSequence.
     67     linked_ptr<const CodeModule> module(
     68         that->GetModuleAtIndex(module_sequence)->Copy());
     69     if (!map_->StoreRange(module->base_address(), module->size(), module)) {
     70       BPLOG(ERROR) << "Module " << module->code_file() <<
     71                       " could not be stored";
     72     }
     73   }
     74 }
     75 
     76 BasicCodeModules::BasicCodeModules()
     77   : main_address_(0),
     78     map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
     79 }
     80 
     81 BasicCodeModules::~BasicCodeModules() {
     82   delete map_;
     83 }
     84 
     85 unsigned int BasicCodeModules::module_count() const {
     86   return map_->GetCount();
     87 }
     88 
     89 const CodeModule* BasicCodeModules::GetModuleForAddress(
     90     uint64_t address) const {
     91   linked_ptr<const CodeModule> module;
     92   if (!map_->RetrieveRange(address, &module, NULL, NULL)) {
     93     BPLOG(INFO) << "No module at " << HexString(address);
     94     return NULL;
     95   }
     96 
     97   return module.get();
     98 }
     99 
    100 const CodeModule* BasicCodeModules::GetMainModule() const {
    101   return GetModuleForAddress(main_address_);
    102 }
    103 
    104 const CodeModule* BasicCodeModules::GetModuleAtSequence(
    105     unsigned int sequence) const {
    106   linked_ptr<const CodeModule> module;
    107   if (!map_->RetrieveRangeAtIndex(sequence, &module, NULL, NULL)) {
    108     BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence;
    109     return NULL;
    110   }
    111 
    112   return module.get();
    113 }
    114 
    115 const CodeModule* BasicCodeModules::GetModuleAtIndex(
    116     unsigned int index) const {
    117   // This class stores everything in a RangeMap, without any more-efficient
    118   // way to walk the list of CodeModule objects.  Implement GetModuleAtIndex
    119   // using GetModuleAtSequence, which meets all of the requirements, and
    120   // in addition, guarantees ordering.
    121   return GetModuleAtSequence(index);
    122 }
    123 
    124 const CodeModules* BasicCodeModules::Copy() const {
    125   return new BasicCodeModules(this);
    126 }
    127 
    128 }  // namespace google_breakpad
    129