clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MinidumpTypes.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Process/minidump -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Process/minidump -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Process/minidump -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp -faddrsig
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | #include "MinidumpTypes.h" |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | using namespace lldb_private; |
18 | using namespace minidump; |
19 | |
20 | const MinidumpHeader *MinidumpHeader::Parse(llvm::ArrayRef<uint8_t> &data) { |
21 | const MinidumpHeader *header = nullptr; |
22 | Status error = consumeObject(data, header); |
23 | |
24 | const MinidumpHeaderConstants signature = |
25 | static_cast<const MinidumpHeaderConstants>( |
26 | static_cast<const uint32_t>(header->signature)); |
27 | const MinidumpHeaderConstants version = |
28 | static_cast<const MinidumpHeaderConstants>( |
29 | static_cast<const uint32_t>(header->version) & 0x0000ffff); |
30 | |
31 | |
32 | if (error.Fail() || signature != MinidumpHeaderConstants::Signature || |
33 | version != MinidumpHeaderConstants::Version) |
34 | return nullptr; |
35 | |
36 | return header; |
37 | } |
38 | |
39 | |
40 | llvm::Optional<std::string> |
41 | lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) { |
42 | std::string result; |
43 | |
44 | const uint32_t *source_length_ptr; |
45 | Status error = consumeObject(data, source_length_ptr); |
46 | |
47 | |
48 | uint32_t source_length; |
49 | std::memcpy(&source_length, source_length_ptr, sizeof(source_length)); |
50 | |
51 | if (error.Fail() || source_length > data.size() || source_length % 2 != 0) |
52 | return llvm::None; |
53 | |
54 | auto source_start = reinterpret_cast<const llvm::UTF16 *>(data.data()); |
55 | |
56 | |
57 | |
58 | const auto source_end = source_start + source_length / 2; |
59 | |
60 | result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT4 * source_length / 2); |
61 | auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]); |
62 | const auto result_end = result_start + result.size(); |
63 | llvm::ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, |
64 | llvm::strictConversion); |
65 | const auto result_size = |
66 | std::distance(reinterpret_cast<llvm::UTF8 *>(&result[0]), result_start); |
67 | result.resize(result_size); |
68 | |
69 | return result; |
70 | } |
71 | |
72 | |
73 | const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) { |
74 | const MinidumpThread *thread = nullptr; |
75 | Status error = consumeObject(data, thread); |
76 | if (error.Fail()) |
77 | return nullptr; |
78 | |
79 | return thread; |
80 | } |
81 | |
82 | llvm::ArrayRef<MinidumpThread> |
83 | MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) { |
84 | const auto orig_size = data.size(); |
85 | const llvm::support::ulittle32_t *thread_count; |
86 | Status error = consumeObject(data, thread_count); |
87 | if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size()) |
88 | return {}; |
89 | |
90 | |
91 | |
92 | if (4 + *thread_count * sizeof(MinidumpThread) < orig_size) |
93 | data = data.drop_front(4); |
94 | |
95 | return llvm::ArrayRef<MinidumpThread>( |
96 | reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count); |
97 | } |
98 | |
99 | |
100 | const MinidumpSystemInfo * |
101 | MinidumpSystemInfo::Parse(llvm::ArrayRef<uint8_t> &data) { |
102 | const MinidumpSystemInfo *system_info; |
103 | Status error = consumeObject(data, system_info); |
104 | if (error.Fail()) |
105 | return nullptr; |
106 | |
107 | return system_info; |
108 | } |
109 | |
110 | |
111 | const MinidumpMiscInfo *MinidumpMiscInfo::Parse(llvm::ArrayRef<uint8_t> &data) { |
112 | const MinidumpMiscInfo *misc_info; |
113 | Status error = consumeObject(data, misc_info); |
114 | if (error.Fail()) |
115 | return nullptr; |
116 | |
117 | return misc_info; |
118 | } |
119 | |
120 | llvm::Optional<lldb::pid_t> MinidumpMiscInfo::GetPid() const { |
121 | uint32_t pid_flag = |
122 | static_cast<const uint32_t>(MinidumpMiscInfoFlags::ProcessID); |
123 | if (flags1 & pid_flag) |
124 | return llvm::Optional<lldb::pid_t>(process_id); |
125 | |
126 | return llvm::None; |
127 | } |
128 | |
129 | |
130 | |
131 | llvm::Optional<LinuxProcStatus> |
132 | LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) { |
133 | LinuxProcStatus result; |
134 | result.proc_status = |
135 | llvm::StringRef(reinterpret_cast<const char *>(data.data()), data.size()); |
136 | data = data.drop_front(data.size()); |
137 | |
138 | llvm::SmallVector<llvm::StringRef, 0> lines; |
139 | result.proc_status.split(lines, '\n', 42); |
140 | |
141 | for (auto line : lines) { |
142 | if (line.consume_front("Pid:")) { |
143 | line = line.trim(); |
144 | if (!line.getAsInteger(10, result.pid)) |
145 | return result; |
146 | } |
147 | } |
148 | |
149 | return llvm::None; |
150 | } |
151 | |
152 | lldb::pid_t LinuxProcStatus::GetPid() const { return pid; } |
153 | |
154 | |
155 | const MinidumpModule *MinidumpModule::Parse(llvm::ArrayRef<uint8_t> &data) { |
156 | const MinidumpModule *module = nullptr; |
157 | Status error = consumeObject(data, module); |
158 | if (error.Fail()) |
159 | return nullptr; |
160 | |
161 | return module; |
162 | } |
163 | |
164 | llvm::ArrayRef<MinidumpModule> |
165 | MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) { |
166 | const auto orig_size = data.size(); |
167 | const llvm::support::ulittle32_t *modules_count; |
168 | Status error = consumeObject(data, modules_count); |
169 | if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size()) |
170 | return {}; |
171 | |
172 | |
173 | |
174 | if (4 + *modules_count * sizeof(MinidumpModule) < orig_size) |
175 | data = data.drop_front(4); |
176 | |
177 | return llvm::ArrayRef<MinidumpModule>( |
178 | reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count); |
179 | } |
180 | |
181 | |
182 | const MinidumpExceptionStream * |
183 | MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) { |
184 | const MinidumpExceptionStream *exception_stream = nullptr; |
185 | Status error = consumeObject(data, exception_stream); |
186 | if (error.Fail()) |
187 | return nullptr; |
188 | |
189 | return exception_stream; |
190 | } |
191 | |
192 | llvm::ArrayRef<MinidumpMemoryDescriptor> |
193 | MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) { |
194 | const auto orig_size = data.size(); |
195 | const llvm::support::ulittle32_t *mem_ranges_count; |
196 | Status error = consumeObject(data, mem_ranges_count); |
197 | if (error.Fail() || |
198 | *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size()) |
199 | return {}; |
200 | |
201 | |
202 | |
203 | if (4 + *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) < orig_size) |
204 | data = data.drop_front(4); |
205 | |
206 | return llvm::makeArrayRef( |
207 | reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()), |
208 | *mem_ranges_count); |
209 | } |
210 | |
211 | std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t> |
212 | MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) { |
213 | const llvm::support::ulittle64_t *mem_ranges_count; |
214 | Status error = consumeObject(data, mem_ranges_count); |
215 | if (error.Fail() || |
| 1 | Assuming the condition is false | |
|
| |
216 | *mem_ranges_count * sizeof(MinidumpMemoryDescriptor64) > data.size()) |
| 2 | | Assuming the condition is false | |
|
217 | return {}; |
218 | |
219 | const llvm::support::ulittle64_t *base_rva; |
220 | error = consumeObject(data, base_rva); |
221 | if (error.Fail()) |
| 4 | | Assuming the condition is false | |
|
| |
222 | return {}; |
223 | |
224 | return std::make_pair( |
| 6 | | 2nd function call argument is an uninitialized value |
|
225 | llvm::makeArrayRef( |
226 | reinterpret_cast<const MinidumpMemoryDescriptor64 *>(data.data()), |
227 | *mem_ranges_count), |
228 | *base_rva); |
229 | } |
230 | |
231 | std::vector<const MinidumpMemoryInfo *> |
232 | MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) { |
233 | const MinidumpMemoryInfoListHeader *header; |
234 | Status error = consumeObject(data, header); |
235 | if (error.Fail() || |
236 | header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) || |
237 | header->size_of_entry < sizeof(MinidumpMemoryInfo)) |
238 | return {}; |
239 | |
240 | data = data.drop_front(header->size_of_header - |
241 | sizeof(MinidumpMemoryInfoListHeader)); |
242 | |
243 | if (header->size_of_entry * header->num_of_entries > data.size()) |
244 | return {}; |
245 | |
246 | std::vector<const MinidumpMemoryInfo *> result; |
247 | for (uint64_t i = 0; i < header->num_of_entries; ++i) { |
248 | result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>( |
249 | data.data() + i * header->size_of_entry)); |
250 | } |
251 | |
252 | return result; |
253 | } |