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__