PageRenderTime 17ms CodeModel.GetById 1ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/processor/module_serializer.cc

http://github.com/tomahawk-player/tomahawk
C++ | 200 lines | 117 code | 29 blank | 54 comment | 18 complexity | d58cff81d5381b8b8cebe13056957fda MD5 | raw file
  1// Copyright (c) 2010, 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// module_serializer.cc: ModuleSerializer implementation.
 31//
 32// See module_serializer.h for documentation.
 33//
 34// Author: Siyang Xie (lambxsy@google.com)
 35
 36#include "processor/module_serializer.h"
 37
 38#include <map>
 39#include <string>
 40
 41#include "processor/basic_code_module.h"
 42#include "processor/logging.h"
 43
 44namespace google_breakpad {
 45
 46// Definition of static member variable in SimplerSerializer<Funcion>, which
 47// is declared in file "simple_serializer-inl.h"
 48RangeMapSerializer< MemAddr, linked_ptr<BasicSourceLineResolver::Line> >
 49SimpleSerializer<BasicSourceLineResolver::Function>::range_map_serializer_;
 50
 51size_t ModuleSerializer::SizeOf(const BasicSourceLineResolver::Module &module) {
 52  size_t total_size_alloc_ = 0;
 53
 54  // Compute memory size for each map component in Module class.
 55  int map_index = 0;
 56  map_sizes_[map_index++] = files_serializer_.SizeOf(module.files_);
 57  map_sizes_[map_index++] = functions_serializer_.SizeOf(module.functions_);
 58  map_sizes_[map_index++] = pubsym_serializer_.SizeOf(module.public_symbols_);
 59  for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
 60   map_sizes_[map_index++] =
 61       wfi_serializer_.SizeOf(&(module.windows_frame_info_[i]));
 62  map_sizes_[map_index++] = cfi_init_rules_serializer_.SizeOf(
 63     module.cfi_initial_rules_);
 64  map_sizes_[map_index++] = cfi_delta_rules_serializer_.SizeOf(
 65     module.cfi_delta_rules_);
 66
 67  // Header size.
 68  total_size_alloc_ = kNumberMaps_ * sizeof(u_int32_t);
 69
 70  for (int i = 0; i < kNumberMaps_; ++i)
 71   total_size_alloc_ += map_sizes_[i];
 72
 73  // Extra one byte for null terminator for C-string copy safety.
 74  ++total_size_alloc_;
 75
 76  return total_size_alloc_;
 77}
 78
 79char *ModuleSerializer::Write(const BasicSourceLineResolver::Module &module,
 80                              char *dest) {
 81  // Write header.
 82  memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(u_int32_t));
 83  dest += kNumberMaps_ * sizeof(u_int32_t);
 84  // Write each map.
 85  dest = files_serializer_.Write(module.files_, dest);
 86  dest = functions_serializer_.Write(module.functions_, dest);
 87  dest = pubsym_serializer_.Write(module.public_symbols_, dest);
 88  for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
 89    dest = wfi_serializer_.Write(&(module.windows_frame_info_[i]), dest);
 90  dest = cfi_init_rules_serializer_.Write(module.cfi_initial_rules_, dest);
 91  dest = cfi_delta_rules_serializer_.Write(module.cfi_delta_rules_, dest);
 92  // Write a null terminator.
 93  dest = SimpleSerializer<char>::Write(0, dest);
 94  return dest;
 95}
 96
 97char* ModuleSerializer::Serialize(
 98    const BasicSourceLineResolver::Module &module, unsigned int *size) {
 99  // Compute size of memory to allocate.
100  unsigned int size_to_alloc = SizeOf(module);
101
102  // Allocate memory for serialized data.
103  char *serialized_data = new char[size_to_alloc];
104  if (!serialized_data) {
105    BPLOG(ERROR) << "ModuleSerializer: memory allocation failed, "
106                 << "size to alloc: " << size_to_alloc;
107    if (size) *size = 0;
108    return NULL;
109  }
110
111  // Write serialized data to allocated memory chunk.
112  char *end_address = Write(module, serialized_data);
113  // Verify the allocated memory size is equal to the size of data been written.
114  unsigned int size_written =
115      static_cast<unsigned int>(end_address - serialized_data);
116  if (size_to_alloc != size_written) {
117    BPLOG(ERROR) << "size_to_alloc differs from size_written: "
118                   << size_to_alloc << " vs " << size_written;
119  }
120
121  // Set size and return the start address of memory chunk.
122  if (size)
123    *size = size_to_alloc;
124  return serialized_data;
125}
126
127bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver(
128    const BasicSourceLineResolver::ModuleMap::const_iterator &iter,
129    FastSourceLineResolver *fast_resolver) {
130  BPLOG(INFO) << "Converting symbol " << iter->first.c_str();
131
132  // Cast SourceLineResolverBase::Module* to BasicSourceLineResolver::Module*.
133  BasicSourceLineResolver::Module* basic_module =
134      dynamic_cast<BasicSourceLineResolver::Module*>(iter->second);
135
136  unsigned int size = 0;
137  scoped_array<char> symbol_data(Serialize(*basic_module, &size));
138  if (!symbol_data.get()) {
139    BPLOG(ERROR) << "Serialization failed for module: " << basic_module->name_;
140    return false;
141  }
142  BPLOG(INFO) << "Serialized Symbol Size " << size;
143
144  // Copy the data into string.
145  // Must pass string to LoadModuleUsingMapBuffer(), instead of passing char* to
146  // LoadModuleUsingMemoryBuffer(), becaused of data ownership/lifetime issue.
147  string symbol_data_string(symbol_data.get(), size);
148  symbol_data.reset();
149
150  scoped_ptr<CodeModule> code_module(
151      new BasicCodeModule(0, 0, iter->first, "", "", "", ""));
152
153  return fast_resolver->LoadModuleUsingMapBuffer(code_module.get(),
154                                                 symbol_data_string);
155}
156
157void ModuleSerializer::ConvertAllModules(
158    const BasicSourceLineResolver *basic_resolver,
159    FastSourceLineResolver *fast_resolver) {
160  // Check for NULL pointer.
161  if (!basic_resolver || !fast_resolver)
162    return;
163
164  // Traverse module list in basic resolver.
165  BasicSourceLineResolver::ModuleMap::const_iterator iter;
166  iter = basic_resolver->modules_->begin();
167  for (; iter != basic_resolver->modules_->end(); ++iter)
168    SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver);
169}
170
171bool ModuleSerializer::ConvertOneModule(
172    const string &moduleid,
173    const BasicSourceLineResolver *basic_resolver,
174    FastSourceLineResolver *fast_resolver) {
175  // Check for NULL pointer.
176  if (!basic_resolver || !fast_resolver)
177    return false;
178
179  BasicSourceLineResolver::ModuleMap::const_iterator iter;
180  iter = basic_resolver->modules_->find(moduleid);
181  if (iter == basic_resolver->modules_->end())
182    return false;
183
184  return SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver);
185}
186
187char* ModuleSerializer::SerializeSymbolFileData(
188    const string &symbol_data, unsigned int *size) {
189  scoped_ptr<BasicSourceLineResolver::Module> module(
190      new BasicSourceLineResolver::Module("no name"));
191  scoped_array<char> buffer(new char[symbol_data.size() + 1]);
192  strcpy(buffer.get(), symbol_data.c_str());
193  if (!module->LoadMapFromMemory(buffer.get())) {
194    return NULL;
195  }
196  buffer.reset(NULL);
197  return Serialize(*(module.get()), size);
198}
199
200}  // namespace google_breakpad