/ src / processor / simple_serializer-inl.h
simple_serializer-inl.h
  1  // Copyright 2010 Google LLC
  2  //
  3  // Redistribution and use in source and binary forms, with or without
  4  // modification, are permitted provided that the following conditions are
  5  // met:
  6  //
  7  //     * Redistributions of source code must retain the above copyright
  8  // notice, this list of conditions and the following disclaimer.
  9  //     * Redistributions in binary form must reproduce the above
 10  // copyright notice, this list of conditions and the following disclaimer
 11  // in the documentation and/or other materials provided with the
 12  // distribution.
 13  //     * Neither the name of Google LLC nor the names of its
 14  // contributors may be used to endorse or promote products derived from
 15  // this software without specific prior written permission.
 16  //
 17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28  //
 29  // simple_serializer-inl.h: template specializations for following types:
 30  // bool, const char *(C-string), string,
 31  // Line, Function, PublicSymbol, WindowsFrameInfo and their linked pointers.
 32  //
 33  // See simple_serializer.h for moredocumentation.
 34  //
 35  // Author: Siyang Xie (lambxsy@google.com)
 36  
 37  #ifndef PROCESSOR_SIMPLE_SERIALIZER_INL_H__
 38  #define PROCESSOR_SIMPLE_SERIALIZER_INL_H__
 39  
 40  #include "processor/simple_serializer.h"
 41  
 42  #include <cstdint>
 43  #include <string>
 44  
 45  #include "google_breakpad/processor/basic_source_line_resolver.h"
 46  #include "processor/basic_source_line_resolver_types.h"
 47  #include "processor/linked_ptr.h"
 48  #include "processor/map_serializers-inl.h"
 49  #include "processor/windows_frame_info.h"
 50  
 51  namespace google_breakpad {
 52  
 53  // Specializations of SimpleSerializer: bool
 54  template<>
 55  class SimpleSerializer<bool> {
 56   public:
 57    static size_t SizeOf(bool boolean) { return 1; }
 58  
 59    static char* Write(bool boolean, char* dest) {
 60      *dest = static_cast<char>(boolean? 255 : 0);
 61      return ++dest;
 62    }
 63  
 64    static const char* Read(const char* source, bool* value) {
 65      *value = ((*source) == 0 ? false : true);
 66      return ++source;
 67    }
 68  };
 69  
 70  // Specializations of SimpleSerializer: string
 71  template<>
 72  class SimpleSerializer<string> {
 73   public:
 74    static size_t SizeOf(const string& str) { return str.size() + 1; }
 75  
 76    static char* Write(const string& str, char* dest) {
 77      strcpy(dest, str.c_str());
 78      return dest + SizeOf(str);
 79    }
 80  };
 81  
 82  // Specializations of SimpleSerializer: C-string
 83  template<>
 84  class SimpleSerializer<const char*> {
 85   public:
 86    static size_t SizeOf(const char* cstring) {
 87      return strlen(cstring) + 1;
 88    }
 89  
 90    static char* Write(const char* cstring, char* dest) {
 91      strcpy(dest, cstring);
 92      return dest + SizeOf(cstring);
 93    }
 94  };
 95  
 96  // Specializations of SimpleSerializer: Line
 97  template<>
 98  class SimpleSerializer<BasicSourceLineResolver::Line> {
 99    typedef BasicSourceLineResolver::Line Line;
100   public:
101    static size_t SizeOf(const Line& line) {
102      return SimpleSerializer<MemAddr>::SizeOf(line.address)
103           + SimpleSerializer<MemAddr>::SizeOf(line.size)
104           + SimpleSerializer<int32_t>::SizeOf(line.source_file_id)
105           + SimpleSerializer<int32_t>::SizeOf(line.line);
106    }
107    static char* Write(const Line& line, char* dest) {
108      dest = SimpleSerializer<MemAddr>::Write(line.address, dest);
109      dest = SimpleSerializer<MemAddr>::Write(line.size, dest);
110      dest = SimpleSerializer<int32_t>::Write(line.source_file_id, dest);
111      dest = SimpleSerializer<int32_t>::Write(line.line, dest);
112      return dest;
113    }
114  };
115  
116  // Specializations of SimpleSerializer: InlineOrigin
117  template <>
118  class SimpleSerializer<BasicSourceLineResolver::InlineOrigin> {
119    typedef BasicSourceLineResolver::InlineOrigin InlineOrigin;
120  
121   public:
122    static size_t SizeOf(const InlineOrigin& origin) {
123      return SimpleSerializer<bool>::SizeOf(origin.has_file_id) +
124             SimpleSerializer<int32_t>::SizeOf(origin.source_file_id) +
125             SimpleSerializer<string>::SizeOf(origin.name);
126    }
127    static char* Write(const InlineOrigin& origin, char* dest) {
128      dest = SimpleSerializer<bool>::Write(origin.has_file_id, dest);
129      dest = SimpleSerializer<int32_t>::Write(origin.source_file_id, dest);
130      dest = SimpleSerializer<string>::Write(origin.name, dest);
131      return dest;
132    }
133  };
134  
135  // Specializations of SimpleSerializer: PublicSymbol
136  template<>
137  class SimpleSerializer<BasicSourceLineResolver::PublicSymbol> {
138    typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
139   public:
140    static size_t SizeOf(const PublicSymbol& pubsymbol) {
141      return SimpleSerializer<string>::SizeOf(pubsymbol.name)
142           + SimpleSerializer<MemAddr>::SizeOf(pubsymbol.address)
143           + SimpleSerializer<int32_t>::SizeOf(pubsymbol.parameter_size)
144           + SimpleSerializer<bool>::SizeOf(pubsymbol.is_multiple);
145    }
146    static char* Write(const PublicSymbol& pubsymbol, char* dest) {
147      dest = SimpleSerializer<string>::Write(pubsymbol.name, dest);
148      dest = SimpleSerializer<MemAddr>::Write(pubsymbol.address, dest);
149      dest = SimpleSerializer<int32_t>::Write(pubsymbol.parameter_size, dest);
150      dest = SimpleSerializer<bool>::Write(pubsymbol.is_multiple, dest);
151      return dest;
152    }
153  };
154  
155  // Specializations of SimpleSerializer: WindowsFrameInfo
156  template<>
157  class SimpleSerializer<WindowsFrameInfo> {
158   public:
159    static size_t SizeOf(const WindowsFrameInfo& wfi) {
160      unsigned int size = 0;
161      size += sizeof(int32_t);  // wfi.type_
162      size += SimpleSerializer<int32_t>::SizeOf(wfi.valid);
163      size += SimpleSerializer<uint32_t>::SizeOf(wfi.prolog_size);
164      size += SimpleSerializer<uint32_t>::SizeOf(wfi.epilog_size);
165      size += SimpleSerializer<uint32_t>::SizeOf(wfi.parameter_size);
166      size += SimpleSerializer<uint32_t>::SizeOf(wfi.saved_register_size);
167      size += SimpleSerializer<uint32_t>::SizeOf(wfi.local_size);
168      size += SimpleSerializer<uint32_t>::SizeOf(wfi.max_stack_size);
169      size += SimpleSerializer<bool>::SizeOf(wfi.allocates_base_pointer);
170      size += SimpleSerializer<string>::SizeOf(wfi.program_string);
171      return size;
172    }
173    static char* Write(const WindowsFrameInfo& wfi, char* dest) {
174      dest = SimpleSerializer<int32_t>::Write(
175          static_cast<const int32_t>(wfi.type_), dest);
176      dest = SimpleSerializer<int32_t>::Write(wfi.valid, dest);
177      dest = SimpleSerializer<uint32_t>::Write(wfi.prolog_size, dest);
178      dest = SimpleSerializer<uint32_t>::Write(wfi.epilog_size, dest);
179      dest = SimpleSerializer<uint32_t>::Write(wfi.parameter_size, dest);
180      dest = SimpleSerializer<uint32_t>::Write(wfi.saved_register_size, dest);
181      dest = SimpleSerializer<uint32_t>::Write(wfi.local_size, dest);
182      dest = SimpleSerializer<uint32_t>::Write(wfi.max_stack_size, dest);
183      dest = SimpleSerializer<bool>::Write(wfi.allocates_base_pointer, dest);
184      return SimpleSerializer<string>::Write(wfi.program_string, dest);
185    }
186  };
187  
188  // Specializations of SimpleSerializer: Linked_ptr version of
189  // Line, InlineOrigin, Inline, Function, PublicSymbol, WindowsFrameInfo.
190  template<>
191  class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Line> > {
192    typedef BasicSourceLineResolver::Line Line;
193   public:
194    static size_t SizeOf(const linked_ptr<Line>& lineptr) {
195      if (lineptr.get() == NULL) return 0;
196      return SimpleSerializer<Line>::SizeOf(*(lineptr.get()));
197    }
198    static char* Write(const linked_ptr<Line>& lineptr, char* dest) {
199      if (lineptr.get())
200        dest = SimpleSerializer<Line>::Write(*(lineptr.get()), dest);
201      return dest;
202    }
203  };
204  
205  template <>
206  class SimpleSerializer<linked_ptr<BasicSourceLineResolver::InlineOrigin>> {
207    typedef BasicSourceLineResolver::InlineOrigin InlineOrigin;
208  
209   public:
210    static size_t SizeOf(const linked_ptr<InlineOrigin>& origin_ptr) {
211      if (origin_ptr.get() == NULL)
212        return 0;
213      return SimpleSerializer<InlineOrigin>::SizeOf(*(origin_ptr.get()));
214    }
215    static char* Write(const linked_ptr<InlineOrigin>& origin_ptr, char* dest) {
216      if (origin_ptr.get())
217        dest = SimpleSerializer<InlineOrigin>::Write(*(origin_ptr.get()), dest);
218      return dest;
219    }
220  };
221  
222  // Specializations of SimpleSerializer: Inline
223  template <>
224  class SimpleSerializer<linked_ptr<BasicSourceLineResolver::Inline>>;
225  template <>
226  class SimpleSerializer<BasicSourceLineResolver::Inline> {
227    typedef BasicSourceLineResolver::Inline Inline;
228  
229   public:
230    inline static size_t SizeOf(const Inline& in);
231    inline static char* Write(const Inline& in, char* dest);
232  };
233  
234  template <>
235  class SimpleSerializer<linked_ptr<BasicSourceLineResolver::Inline>> {
236    typedef BasicSourceLineResolver::Inline Inline;
237  
238   public:
239    static size_t SizeOf(const linked_ptr<Inline>& inline_ptr) {
240      if (inline_ptr.get() == NULL)
241        return 0;
242      return SimpleSerializer<Inline>::SizeOf(*(inline_ptr.get()));
243    }
244    static char* Write(const linked_ptr<Inline>& inline_ptr, char* dest) {
245      if (inline_ptr.get())
246        dest = SimpleSerializer<Inline>::Write(*(inline_ptr.get()), dest);
247      return dest;
248    }
249  };
250  
251  size_t SimpleSerializer<BasicSourceLineResolver::Inline>::SizeOf(
252      const Inline& in) {
253    return SimpleSerializer<bool>::SizeOf(in.has_call_site_file_id) +
254           SimpleSerializer<int32_t>::SizeOf(in.inline_nest_level) +
255           SimpleSerializer<int32_t>::SizeOf(in.call_site_line) +
256           SimpleSerializer<int32_t>::SizeOf(in.call_site_file_id) +
257           SimpleSerializer<int32_t>::SizeOf(in.origin_id) +
258           sizeof(uint32_t) +  // This is to store the size of inline_ranges.
259           (in.inline_ranges.size() * sizeof(MemAddr) * 2);
260  }
261  
262  char* SimpleSerializer<BasicSourceLineResolver::Inline>::Write(const Inline& in,
263                                                                 char* dest) {
264    dest = SimpleSerializer<bool>::Write(in.has_call_site_file_id, dest);
265    dest = SimpleSerializer<int32_t>::Write(in.inline_nest_level, dest);
266    dest = SimpleSerializer<int32_t>::Write(in.call_site_line, dest);
267    dest = SimpleSerializer<int32_t>::Write(in.call_site_file_id, dest);
268    dest = SimpleSerializer<int32_t>::Write(in.origin_id, dest);
269    // Write the size of inline_ranges.
270    dest = SimpleSerializer<int32_t>::Write(in.inline_ranges.size(), dest);
271    for (const std::pair<MemAddr, MemAddr>& range : in.inline_ranges) {
272      dest = SimpleSerializer<MemAddr>::Write(range.first, dest);
273      dest = SimpleSerializer<MemAddr>::Write(range.second, dest);
274    }
275    return dest;
276  }
277  
278  template<>
279  class SimpleSerializer<BasicSourceLineResolver::Function> {
280    // Convenient type names.
281    typedef BasicSourceLineResolver::Function Function;
282    typedef BasicSourceLineResolver::Line Line;
283    typedef BasicSourceLineResolver::Inline Inline;
284  
285   public:
286    static size_t SizeOf(const Function& func) {
287      unsigned int size = 0;
288      size += SimpleSerializer<string>::SizeOf(func.name);
289      size += SimpleSerializer<MemAddr>::SizeOf(func.address);
290      size += SimpleSerializer<MemAddr>::SizeOf(func.size);
291      size += SimpleSerializer<int32_t>::SizeOf(func.parameter_size);
292      size += SimpleSerializer<bool>::SizeOf(func.is_multiple);
293      // This extra size is used to store the size of serialized func.inlines, so
294      // we know where to start de-serialize func.lines.
295      size += sizeof(int32_t);
296      size += inline_range_map_serializer_.SizeOf(&func.inlines);
297      size += range_map_serializer_.SizeOf(func.lines);
298      return size;
299    }
300  
301    static char* Write(const Function& func, char* dest) {
302      dest = SimpleSerializer<string>::Write(func.name, dest);
303      dest = SimpleSerializer<MemAddr>::Write(func.address, dest);
304      dest = SimpleSerializer<MemAddr>::Write(func.size, dest);
305      dest = SimpleSerializer<int32_t>::Write(func.parameter_size, dest);
306      dest = SimpleSerializer<bool>::Write(func.is_multiple, dest);
307      char* old_dest = dest;
308      dest += sizeof(int32_t);
309      dest = inline_range_map_serializer_.Write(&func.inlines, dest);
310      // Write the size of serialized func.inlines. The size doesn't include size
311      // field itself.
312      SimpleSerializer<MemAddr>::Write(dest - old_dest - sizeof(int32_t),
313                                       old_dest);
314      dest = range_map_serializer_.Write(func.lines, dest);
315      return dest;
316    }
317   private:
318    // This static member is defined in module_serializer.cc.
319    static RangeMapSerializer<MemAddr, linked_ptr<Line>> range_map_serializer_;
320    static ContainedRangeMapSerializer<MemAddr, linked_ptr<Inline>>
321        inline_range_map_serializer_;
322  };
323  
324  template<>
325  class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Function> > {
326    typedef BasicSourceLineResolver::Function Function;
327   public:
328    static size_t SizeOf(const linked_ptr<Function>& func) {
329      if (!func.get()) return 0;
330      return SimpleSerializer<Function>::SizeOf(*(func.get()));
331    }
332  
333    static char* Write(const linked_ptr<Function>& func, char* dest) {
334      if (func.get())
335        dest = SimpleSerializer<Function>::Write(*(func.get()), dest);
336      return dest;
337    }
338  };
339  
340  template<>
341  class SimpleSerializer< linked_ptr<BasicSourceLineResolver::PublicSymbol> > {
342    typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
343   public:
344    static size_t SizeOf(const linked_ptr<PublicSymbol>& pubsymbol) {
345      if (pubsymbol.get() == NULL) return 0;
346      return SimpleSerializer<PublicSymbol>::SizeOf(*(pubsymbol.get()));
347    }
348    static char* Write(const linked_ptr<PublicSymbol>& pubsymbol, char* dest) {
349      if (pubsymbol.get())
350        dest = SimpleSerializer<PublicSymbol>::Write(*(pubsymbol.get()), dest);
351      return dest;
352    }
353  };
354  
355  template<>
356  class SimpleSerializer< linked_ptr<WindowsFrameInfo> > {
357   public:
358    static size_t SizeOf(const linked_ptr<WindowsFrameInfo>& wfi) {
359      if (wfi.get() == NULL) return 0;
360      return SimpleSerializer<WindowsFrameInfo>::SizeOf(*(wfi.get()));
361    }
362    static char* Write(const linked_ptr<WindowsFrameInfo>& wfi, char* dest) {
363      if (wfi.get())
364        dest = SimpleSerializer<WindowsFrameInfo>::Write(*(wfi.get()), dest);
365      return dest;
366    }
367  };
368  
369  }  // namespace google_breakpad
370  
371  #endif  // PROCESSOR_SIMPLE_SERIALIZER_INL_H__