* cgraph.c (cgraph_node::get_untransformed_body): Pass compressed
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_stacktrace_printer.cc
blobbcc9de78ec1570e708ea2496c335240bcf7cb997
1 //===-- sanitizer_common.cc -----------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between sanitizers' run-time libraries.
9 //
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_stacktrace_printer.h"
14 namespace __sanitizer {
16 static const char *StripFunctionName(const char *function, const char *prefix) {
17 if (!function) return nullptr;
18 if (!prefix) return function;
19 uptr prefix_len = internal_strlen(prefix);
20 if (0 == internal_strncmp(function, prefix, prefix_len))
21 return function + prefix_len;
22 return function;
25 static const char kDefaultFormat[] = " #%n %p %F %L";
27 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
28 const AddressInfo &info, bool vs_style,
29 const char *strip_path_prefix, const char *strip_func_prefix) {
30 if (0 == internal_strcmp(format, "DEFAULT"))
31 format = kDefaultFormat;
32 for (const char *p = format; *p != '\0'; p++) {
33 if (*p != '%') {
34 buffer->append("%c", *p);
35 continue;
37 p++;
38 switch (*p) {
39 case '%':
40 buffer->append("%%");
41 break;
42 // Frame number and all fields of AddressInfo structure.
43 case 'n':
44 buffer->append("%zu", frame_no);
45 break;
46 case 'p':
47 buffer->append("0x%zx", info.address);
48 break;
49 case 'm':
50 buffer->append("%s", StripPathPrefix(info.module, strip_path_prefix));
51 break;
52 case 'o':
53 buffer->append("0x%zx", info.module_offset);
54 break;
55 case 'f':
56 buffer->append("%s", StripFunctionName(info.function, strip_func_prefix));
57 break;
58 case 'q':
59 buffer->append("0x%zx", info.function_offset != AddressInfo::kUnknown
60 ? info.function_offset
61 : 0x0);
62 break;
63 case 's':
64 buffer->append("%s", StripPathPrefix(info.file, strip_path_prefix));
65 break;
66 case 'l':
67 buffer->append("%d", info.line);
68 break;
69 case 'c':
70 buffer->append("%d", info.column);
71 break;
72 // Smarter special cases.
73 case 'F':
74 // Function name and offset, if file is unknown.
75 if (info.function) {
76 buffer->append("in %s",
77 StripFunctionName(info.function, strip_func_prefix));
78 if (!info.file && info.function_offset != AddressInfo::kUnknown)
79 buffer->append("+0x%zx", info.function_offset);
81 break;
82 case 'S':
83 // File/line information.
84 RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,
85 strip_path_prefix);
86 break;
87 case 'L':
88 // Source location, or module location.
89 if (info.file) {
90 RenderSourceLocation(buffer, info.file, info.line, info.column,
91 vs_style, strip_path_prefix);
92 } else if (info.module) {
93 RenderModuleLocation(buffer, info.module, info.module_offset,
94 strip_path_prefix);
95 } else {
96 buffer->append("(<unknown module>)");
98 break;
99 case 'M':
100 // Module basename and offset, or PC.
101 if (info.address & kExternalPCBit)
102 {} // There PCs are not meaningful.
103 else if (info.module)
104 buffer->append("(%s+%p)", StripModuleName(info.module),
105 (void *)info.module_offset);
106 else
107 buffer->append("(%p)", (void *)info.address);
108 break;
109 default:
110 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
111 *p);
112 Die();
117 void RenderSourceLocation(InternalScopedString *buffer, const char *file,
118 int line, int column, bool vs_style,
119 const char *strip_path_prefix) {
120 if (vs_style && line > 0) {
121 buffer->append("%s(%d", StripPathPrefix(file, strip_path_prefix), line);
122 if (column > 0)
123 buffer->append(",%d", column);
124 buffer->append(")");
125 return;
128 buffer->append("%s", StripPathPrefix(file, strip_path_prefix));
129 if (line > 0) {
130 buffer->append(":%d", line);
131 if (column > 0)
132 buffer->append(":%d", column);
136 void RenderModuleLocation(InternalScopedString *buffer, const char *module,
137 uptr offset, const char *strip_path_prefix) {
138 buffer->append("(%s+0x%zx)", StripPathPrefix(module, strip_path_prefix),
139 offset);
142 } // namespace __sanitizer