Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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)
36 #include "processor/module_serializer.h"
38 #include <map>
39 #include <string>
41 #include "processor/basic_code_module.h"
42 #include "processor/logging.h"
44 namespace google_breakpad {
46 // Definition of static member variable in SimplerSerializer<Funcion>, which
47 // is declared in file "simple_serializer-inl.h"
48 RangeMapSerializer< MemAddr, linked_ptr<BasicSourceLineResolver::Line> >
49 SimpleSerializer<BasicSourceLineResolver::Function>::range_map_serializer_;
51 size_t ModuleSerializer::SizeOf(const BasicSourceLineResolver::Module &module) {
52 size_t total_size_alloc_ = 0;
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_);
67 // Header size.
68 total_size_alloc_ = kNumberMaps_ * sizeof(uint32_t);
70 for (int i = 0; i < kNumberMaps_; ++i)
71 total_size_alloc_ += map_sizes_[i];
73 // Extra one byte for null terminator for C-string copy safety.
74 ++total_size_alloc_;
76 return total_size_alloc_;
77 }
79 char *ModuleSerializer::Write(const BasicSourceLineResolver::Module &module,
80 char *dest) {
81 // Write header.
82 memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint32_t));
83 dest += kNumberMaps_ * sizeof(uint32_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 }
97 char* 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);
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 }
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 }
121 // Set size and return the start address of memory chunk.
122 if (size)
123 *size = size_to_alloc;
124 return serialized_data;
125 }
127 bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver(
128 const BasicSourceLineResolver::ModuleMap::const_iterator &iter,
129 FastSourceLineResolver *fast_resolver) {
130 BPLOG(INFO) << "Converting symbol " << iter->first.c_str();
132 // Cast SourceLineResolverBase::Module* to BasicSourceLineResolver::Module*.
133 BasicSourceLineResolver::Module* basic_module =
134 dynamic_cast<BasicSourceLineResolver::Module*>(iter->second);
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;
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();
150 scoped_ptr<CodeModule> code_module(
151 new BasicCodeModule(0, 0, iter->first, "", "", "", ""));
153 return fast_resolver->LoadModuleUsingMapBuffer(code_module.get(),
154 symbol_data_string);
155 }
157 void ModuleSerializer::ConvertAllModules(
158 const BasicSourceLineResolver *basic_resolver,
159 FastSourceLineResolver *fast_resolver) {
160 // Check for NULL pointer.
161 if (!basic_resolver || !fast_resolver)
162 return;
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 }
171 bool 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;
179 BasicSourceLineResolver::ModuleMap::const_iterator iter;
180 iter = basic_resolver->modules_->find(moduleid);
181 if (iter == basic_resolver->modules_->end())
182 return false;
184 return SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver);
185 }
187 char* 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 }
200 } // namespace google_breakpad