xref: /aosp_15_r20/external/google-breakpad/src/processor/module_serializer.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle //     * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle //     * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle //     * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle //
29*9712c20fSFrederick Mayle // module_serializer.cc: ModuleSerializer implementation.
30*9712c20fSFrederick Mayle //
31*9712c20fSFrederick Mayle // See module_serializer.h for documentation.
32*9712c20fSFrederick Mayle //
33*9712c20fSFrederick Mayle // Author: Siyang Xie ([email protected])
34*9712c20fSFrederick Mayle 
35*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
36*9712c20fSFrederick Mayle #include <config.h>  // Must come first
37*9712c20fSFrederick Mayle #endif
38*9712c20fSFrederick Mayle 
39*9712c20fSFrederick Mayle #include "processor/module_serializer.h"
40*9712c20fSFrederick Mayle 
41*9712c20fSFrederick Mayle #include <map>
42*9712c20fSFrederick Mayle #include <string>
43*9712c20fSFrederick Mayle 
44*9712c20fSFrederick Mayle #include "processor/basic_code_module.h"
45*9712c20fSFrederick Mayle #include "processor/logging.h"
46*9712c20fSFrederick Mayle 
47*9712c20fSFrederick Mayle namespace google_breakpad {
48*9712c20fSFrederick Mayle 
49*9712c20fSFrederick Mayle // Definition of static member variables in SimplerSerializer<Funcion> and
50*9712c20fSFrederick Mayle // SimplerSerializer<Inline>, which are declared in file
51*9712c20fSFrederick Mayle // "simple_serializer-inl.h"
52*9712c20fSFrederick Mayle RangeMapSerializer<MemAddr, linked_ptr<BasicSourceLineResolver::Line>>
53*9712c20fSFrederick Mayle     SimpleSerializer<BasicSourceLineResolver::Function>::range_map_serializer_;
54*9712c20fSFrederick Mayle ContainedRangeMapSerializer<MemAddr,
55*9712c20fSFrederick Mayle                             linked_ptr<BasicSourceLineResolver::Inline>>
56*9712c20fSFrederick Mayle     SimpleSerializer<
57*9712c20fSFrederick Mayle         BasicSourceLineResolver::Function>::inline_range_map_serializer_;
58*9712c20fSFrederick Mayle 
SizeOf(const BasicSourceLineResolver::Module & module)59*9712c20fSFrederick Mayle size_t ModuleSerializer::SizeOf(const BasicSourceLineResolver::Module& module) {
60*9712c20fSFrederick Mayle   size_t total_size_alloc_ = 0;
61*9712c20fSFrederick Mayle 
62*9712c20fSFrederick Mayle   // Size of the "is_corrupt" flag.
63*9712c20fSFrederick Mayle   total_size_alloc_ += SimpleSerializer<bool>::SizeOf(module.is_corrupt_);
64*9712c20fSFrederick Mayle 
65*9712c20fSFrederick Mayle   // Compute memory size for each map component in Module class.
66*9712c20fSFrederick Mayle   int map_index = 0;
67*9712c20fSFrederick Mayle   map_sizes_[map_index++] = files_serializer_.SizeOf(module.files_);
68*9712c20fSFrederick Mayle   map_sizes_[map_index++] = functions_serializer_.SizeOf(module.functions_);
69*9712c20fSFrederick Mayle   map_sizes_[map_index++] = pubsym_serializer_.SizeOf(module.public_symbols_);
70*9712c20fSFrederick Mayle   for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
71*9712c20fSFrederick Mayle    map_sizes_[map_index++] =
72*9712c20fSFrederick Mayle        wfi_serializer_.SizeOf(&(module.windows_frame_info_[i]));
73*9712c20fSFrederick Mayle   map_sizes_[map_index++] = cfi_init_rules_serializer_.SizeOf(
74*9712c20fSFrederick Mayle      module.cfi_initial_rules_);
75*9712c20fSFrederick Mayle   map_sizes_[map_index++] = cfi_delta_rules_serializer_.SizeOf(
76*9712c20fSFrederick Mayle      module.cfi_delta_rules_);
77*9712c20fSFrederick Mayle   map_sizes_[map_index++] =
78*9712c20fSFrederick Mayle       inline_origin_serializer_.SizeOf(module.inline_origins_);
79*9712c20fSFrederick Mayle 
80*9712c20fSFrederick Mayle   // Header size.
81*9712c20fSFrederick Mayle   total_size_alloc_ += kNumberMaps_ * sizeof(uint32_t);
82*9712c20fSFrederick Mayle 
83*9712c20fSFrederick Mayle   for (int i = 0; i < kNumberMaps_; ++i) {
84*9712c20fSFrederick Mayle     total_size_alloc_ += map_sizes_[i];
85*9712c20fSFrederick Mayle   }
86*9712c20fSFrederick Mayle 
87*9712c20fSFrederick Mayle   // Extra one byte for null terminator for C-string copy safety.
88*9712c20fSFrederick Mayle   total_size_alloc_ += SimpleSerializer<char>::SizeOf(0);
89*9712c20fSFrederick Mayle 
90*9712c20fSFrederick Mayle   return total_size_alloc_;
91*9712c20fSFrederick Mayle }
92*9712c20fSFrederick Mayle 
Write(const BasicSourceLineResolver::Module & module,char * dest)93*9712c20fSFrederick Mayle char* ModuleSerializer::Write(const BasicSourceLineResolver::Module& module,
94*9712c20fSFrederick Mayle                               char* dest) {
95*9712c20fSFrederick Mayle   // Write the is_corrupt flag.
96*9712c20fSFrederick Mayle   dest = SimpleSerializer<bool>::Write(module.is_corrupt_, dest);
97*9712c20fSFrederick Mayle   // Write header.
98*9712c20fSFrederick Mayle   memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint32_t));
99*9712c20fSFrederick Mayle   dest += kNumberMaps_ * sizeof(uint32_t);
100*9712c20fSFrederick Mayle   // Write each map.
101*9712c20fSFrederick Mayle   dest = files_serializer_.Write(module.files_, dest);
102*9712c20fSFrederick Mayle   dest = functions_serializer_.Write(module.functions_, dest);
103*9712c20fSFrederick Mayle   dest = pubsym_serializer_.Write(module.public_symbols_, dest);
104*9712c20fSFrederick Mayle   for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
105*9712c20fSFrederick Mayle     dest = wfi_serializer_.Write(&(module.windows_frame_info_[i]), dest);
106*9712c20fSFrederick Mayle   dest = cfi_init_rules_serializer_.Write(module.cfi_initial_rules_, dest);
107*9712c20fSFrederick Mayle   dest = cfi_delta_rules_serializer_.Write(module.cfi_delta_rules_, dest);
108*9712c20fSFrederick Mayle   dest = inline_origin_serializer_.Write(module.inline_origins_, dest);
109*9712c20fSFrederick Mayle   // Write a null terminator.
110*9712c20fSFrederick Mayle   dest = SimpleSerializer<char>::Write(0, dest);
111*9712c20fSFrederick Mayle   return dest;
112*9712c20fSFrederick Mayle }
113*9712c20fSFrederick Mayle 
Serialize(const BasicSourceLineResolver::Module & module,size_t * size)114*9712c20fSFrederick Mayle char* ModuleSerializer::Serialize(const BasicSourceLineResolver::Module& module,
115*9712c20fSFrederick Mayle                                   size_t* size) {
116*9712c20fSFrederick Mayle   // Compute size of memory to allocate.
117*9712c20fSFrederick Mayle   const size_t size_to_alloc = SizeOf(module);
118*9712c20fSFrederick Mayle 
119*9712c20fSFrederick Mayle   // Allocate memory for serialized data.
120*9712c20fSFrederick Mayle   char* serialized_data = new char[size_to_alloc];
121*9712c20fSFrederick Mayle   if (!serialized_data) {
122*9712c20fSFrederick Mayle     BPLOG(ERROR) << "ModuleSerializer: memory allocation failed, "
123*9712c20fSFrederick Mayle                  << "size to alloc: " << size_to_alloc;
124*9712c20fSFrederick Mayle     if (size) *size = 0;
125*9712c20fSFrederick Mayle     return NULL;
126*9712c20fSFrederick Mayle   }
127*9712c20fSFrederick Mayle 
128*9712c20fSFrederick Mayle   // Write serialized data to allocated memory chunk.
129*9712c20fSFrederick Mayle   char* end_address = Write(module, serialized_data);
130*9712c20fSFrederick Mayle   // Verify the allocated memory size is equal to the size of data been written.
131*9712c20fSFrederick Mayle   const size_t size_written =
132*9712c20fSFrederick Mayle       static_cast<size_t>(end_address - serialized_data);
133*9712c20fSFrederick Mayle   if (size_to_alloc != size_written) {
134*9712c20fSFrederick Mayle     BPLOG(ERROR) << "size_to_alloc differs from size_written: "
135*9712c20fSFrederick Mayle                    << size_to_alloc << " vs " << size_written;
136*9712c20fSFrederick Mayle   }
137*9712c20fSFrederick Mayle 
138*9712c20fSFrederick Mayle   // Set size and return the start address of memory chunk.
139*9712c20fSFrederick Mayle   if (size)
140*9712c20fSFrederick Mayle     *size = size_to_alloc;
141*9712c20fSFrederick Mayle 
142*9712c20fSFrederick Mayle   return serialized_data;
143*9712c20fSFrederick Mayle }
144*9712c20fSFrederick Mayle 
SerializeModuleAndLoadIntoFastResolver(const BasicSourceLineResolver::ModuleMap::const_iterator & iter,FastSourceLineResolver * fast_resolver)145*9712c20fSFrederick Mayle bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver(
146*9712c20fSFrederick Mayle     const BasicSourceLineResolver::ModuleMap::const_iterator& iter,
147*9712c20fSFrederick Mayle     FastSourceLineResolver* fast_resolver) {
148*9712c20fSFrederick Mayle   BPLOG(INFO) << "Converting symbol " << iter->first.c_str();
149*9712c20fSFrederick Mayle 
150*9712c20fSFrederick Mayle   // Cast SourceLineResolverBase::Module* to BasicSourceLineResolver::Module*.
151*9712c20fSFrederick Mayle   BasicSourceLineResolver::Module* basic_module =
152*9712c20fSFrederick Mayle       dynamic_cast<BasicSourceLineResolver::Module*>(iter->second);
153*9712c20fSFrederick Mayle 
154*9712c20fSFrederick Mayle   size_t size = 0;
155*9712c20fSFrederick Mayle   scoped_array<char> symbol_data(Serialize(*basic_module, &size));
156*9712c20fSFrederick Mayle   if (!symbol_data.get()) {
157*9712c20fSFrederick Mayle     BPLOG(ERROR) << "Serialization failed for module: " << basic_module->name_;
158*9712c20fSFrederick Mayle     return false;
159*9712c20fSFrederick Mayle   }
160*9712c20fSFrederick Mayle   BPLOG(INFO) << "Serialized Symbol Size " << size;
161*9712c20fSFrederick Mayle 
162*9712c20fSFrederick Mayle   // Copy the data into string.
163*9712c20fSFrederick Mayle   // Must pass string to LoadModuleUsingMapBuffer(), instead of passing char* to
164*9712c20fSFrederick Mayle   // LoadModuleUsingMemoryBuffer(), becaused of data ownership/lifetime issue.
165*9712c20fSFrederick Mayle   string symbol_data_string(symbol_data.get(), size);
166*9712c20fSFrederick Mayle   symbol_data.reset();
167*9712c20fSFrederick Mayle 
168*9712c20fSFrederick Mayle   scoped_ptr<CodeModule> code_module(
169*9712c20fSFrederick Mayle       new BasicCodeModule(0, 0, iter->first, "", "", "", ""));
170*9712c20fSFrederick Mayle 
171*9712c20fSFrederick Mayle   return fast_resolver->LoadModuleUsingMapBuffer(code_module.get(),
172*9712c20fSFrederick Mayle                                                  symbol_data_string);
173*9712c20fSFrederick Mayle }
174*9712c20fSFrederick Mayle 
ConvertAllModules(const BasicSourceLineResolver * basic_resolver,FastSourceLineResolver * fast_resolver)175*9712c20fSFrederick Mayle void ModuleSerializer::ConvertAllModules(
176*9712c20fSFrederick Mayle     const BasicSourceLineResolver* basic_resolver,
177*9712c20fSFrederick Mayle     FastSourceLineResolver* fast_resolver) {
178*9712c20fSFrederick Mayle   // Check for NULL pointer.
179*9712c20fSFrederick Mayle   if (!basic_resolver || !fast_resolver)
180*9712c20fSFrederick Mayle     return;
181*9712c20fSFrederick Mayle 
182*9712c20fSFrederick Mayle   // Traverse module list in basic resolver.
183*9712c20fSFrederick Mayle   BasicSourceLineResolver::ModuleMap::const_iterator iter;
184*9712c20fSFrederick Mayle   iter = basic_resolver->modules_->begin();
185*9712c20fSFrederick Mayle   for (; iter != basic_resolver->modules_->end(); ++iter)
186*9712c20fSFrederick Mayle     SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver);
187*9712c20fSFrederick Mayle }
188*9712c20fSFrederick Mayle 
ConvertOneModule(const string & moduleid,const BasicSourceLineResolver * basic_resolver,FastSourceLineResolver * fast_resolver)189*9712c20fSFrederick Mayle bool ModuleSerializer::ConvertOneModule(
190*9712c20fSFrederick Mayle     const string& moduleid,
191*9712c20fSFrederick Mayle     const BasicSourceLineResolver* basic_resolver,
192*9712c20fSFrederick Mayle     FastSourceLineResolver* fast_resolver) {
193*9712c20fSFrederick Mayle   // Check for NULL pointer.
194*9712c20fSFrederick Mayle   if (!basic_resolver || !fast_resolver)
195*9712c20fSFrederick Mayle     return false;
196*9712c20fSFrederick Mayle 
197*9712c20fSFrederick Mayle   BasicSourceLineResolver::ModuleMap::const_iterator iter;
198*9712c20fSFrederick Mayle   iter = basic_resolver->modules_->find(moduleid);
199*9712c20fSFrederick Mayle   if (iter == basic_resolver->modules_->end())
200*9712c20fSFrederick Mayle     return false;
201*9712c20fSFrederick Mayle 
202*9712c20fSFrederick Mayle   return SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver);
203*9712c20fSFrederick Mayle }
204*9712c20fSFrederick Mayle 
SerializeSymbolFileData(const string & symbol_data,size_t * size)205*9712c20fSFrederick Mayle char* ModuleSerializer::SerializeSymbolFileData(const string& symbol_data,
206*9712c20fSFrederick Mayle                                                 size_t* size) {
207*9712c20fSFrederick Mayle   scoped_ptr<BasicSourceLineResolver::Module> module(
208*9712c20fSFrederick Mayle       new BasicSourceLineResolver::Module("no name"));
209*9712c20fSFrederick Mayle   scoped_array<char> buffer(new char[symbol_data.size() + 1]);
210*9712c20fSFrederick Mayle   memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size());
211*9712c20fSFrederick Mayle   buffer.get()[symbol_data.size()] = '\0';
212*9712c20fSFrederick Mayle   if (!module->LoadMapFromMemory(buffer.get(), symbol_data.size() + 1)) {
213*9712c20fSFrederick Mayle     return NULL;
214*9712c20fSFrederick Mayle   }
215*9712c20fSFrederick Mayle   buffer.reset(NULL);
216*9712c20fSFrederick Mayle   return Serialize(*(module.get()), size);
217*9712c20fSFrederick Mayle }
218*9712c20fSFrederick Mayle 
219*9712c20fSFrederick Mayle }  // namespace google_breakpad
220