LEFT | RIGHT |
1 //===-- sanitizer_symbolizer.cc -------------------------------------------===// | 1 //===-- sanitizer_symbolizer.cc -------------------------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This is a stub for LLVM-based symbolizer. | 10 // This is a stub for LLVM-based symbolizer. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 if (name == 0) { | 46 if (name == 0) { |
47 name = full_name; | 47 name = full_name; |
48 } else { | 48 } else { |
49 name++; | 49 name++; |
50 } | 50 } |
51 } | 51 } |
52 }; | 52 }; |
53 | 53 |
54 class Symbolizer { | 54 class Symbolizer { |
55 public: | 55 public: |
56 Symbolizer() { | 56 void GetModuleDescriptions() { |
57 modules_ = 0; | |
58 ProcessMaps proc_maps; | 57 ProcessMaps proc_maps; |
59 uptr start, end, offset; | 58 uptr start, end, offset; |
60 char *module_name = (char*)InternalAlloc(kMaxModuleNameLength); | 59 char *module_name = (char*)InternalAlloc(kMaxModuleNameLength); |
61 ModuleDesc *prev_module = 0; | 60 ModuleDesc *prev_module = 0; |
62 while (proc_maps.Next(&start, &end, &offset, module_name, | 61 while (proc_maps.Next(&start, &end, &offset, module_name, |
63 kMaxModuleNameLength)) { | 62 kMaxModuleNameLength)) { |
64 void *mem = InternalAlloc(sizeof(ModuleDesc)); | 63 void *mem = InternalAlloc(sizeof(ModuleDesc)); |
65 ModuleDesc *cur_module = new(mem) ModuleDesc(start, end, offset, | 64 ModuleDesc *cur_module = new(mem) ModuleDesc(start, end, offset, |
66 module_name); | 65 module_name); |
67 if (!prev_module) { | 66 if (!prev_module) { |
68 modules_ = cur_module; | 67 modules_ = cur_module; |
69 } else { | 68 } else { |
70 prev_module->next = cur_module; | 69 prev_module->next = cur_module; |
71 } | 70 } |
72 prev_module = cur_module; | 71 prev_module = cur_module; |
73 } | 72 } |
74 InternalFree(module_name); | 73 InternalFree(module_name); |
75 } | 74 } |
76 | 75 |
77 bool FillAddressInfo(uptr addr, AddressInfo *info) { | 76 uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) { |
| 77 if (max_frames == 0) |
| 78 return 0; |
| 79 AddressInfo *info = &frames[0]; |
78 info->Clear(); | 80 info->Clear(); |
79 info->address = addr; | 81 info->address = addr; |
| 82 if (modules_ == 0) { |
| 83 GetModuleDescriptions(); |
| 84 } |
80 bool first = true; | 85 bool first = true; |
81 for (ModuleDesc *module = modules_; module; module = module->next) { | 86 for (ModuleDesc *module = modules_; module; module = module->next) { |
82 if (addr >= module->start && addr < module->end) { | 87 if (addr >= module->start && addr < module->end) { |
83 info->module = internal_strdup(module->full_name); | 88 info->module = internal_strdup(module->full_name); |
84 // Don't subtract 'start' for the first entry. Don't ask me why. | 89 // Don't subtract 'start' for the first entry: |
| 90 // * If a binary is compiled w/o -pie, then the first entry in |
| 91 // process maps is likely the binary itself (all dynamic libs |
| 92 // are mapped higher in address space). For such a binary, |
| 93 // instruction offset in binary coincides with the actual |
| 94 // instruction address in virtual memory (as code section |
| 95 // is mapped to a fixed memory range). |
| 96 // * If a binary is compiled with -pie, all the modules are |
| 97 // mapped high at address space (in particular, higher than |
| 98 // shadow memory of the tool), so the module can't be the |
| 99 // first entry. |
85 info->module_offset = (addr - (first ? 0 : module->start)) + | 100 info->module_offset = (addr - (first ? 0 : module->start)) + |
86 module->offset; | 101 module->offset; |
87 // FIXME: Fill other fields here as well: create debug | 102 // FIXME: Fill other fields here as well: create debug |
88 // context for a given module and fetch file/line info from it. | 103 // context for a given module and fetch file/line info from it. |
89 info->function = 0; | 104 info->function = 0; |
90 info->file = 0; | 105 info->file = 0; |
91 info->line = 0; | 106 info->line = 0; |
92 info->column = 0; | 107 info->column = 0; |
93 return true; | 108 return 1; |
94 } | 109 } |
95 first = false; | 110 first = false; |
96 } | 111 } |
97 return false; | 112 return 0; |
98 } | 113 } |
99 | 114 |
100 private: | 115 private: |
101 ModuleDesc *modules_; // List of module descriptions is leaked. | 116 ModuleDesc *modules_; // List of module descriptions is leaked. |
102 }; | 117 }; |
103 | 118 |
104 static Symbolizer *symbolizer; | 119 static Symbolizer symbolizer; |
105 | |
106 static Symbolizer *GetSymbolizer() { | |
107 if (!symbolizer) { | |
108 void *mem = InternalAlloc(sizeof(Symbolizer)); | |
109 symbolizer = new(mem) Symbolizer(); | |
110 } | |
111 return symbolizer; | |
112 } | |
113 | 120 |
114 uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames) { | 121 uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames) { |
115 if (max_frames == 0) | 122 return symbolizer.SymbolizeCode(address, frames, max_frames); |
116 return 0; | |
117 return GetSymbolizer()->FillAddressInfo(address, &frames[0]); | |
118 } | 123 } |
119 | 124 |
120 } // namespace __sanitizer | 125 } // namespace __sanitizer |
LEFT | RIGHT |