1
2 /* libunwind - a platform-independent unwind library
3 Copyright 2011 Linaro Limited
4
5 This file is part of libunwind.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
26 // Copyright (c) 2010 Google Inc.
27 // All rights reserved.
28 //
29 // Redistribution and use in source and binary forms, with or without
30 // modification, are permitted provided that the following conditions are
31 // met:
32 //
33 // * Redistributions of source code must retain the above copyright
34 // notice, this list of conditions and the following disclaimer.
35 // * Redistributions in binary form must reproduce the above
36 // copyright notice, this list of conditions and the following disclaimer
37 // in the documentation and/or other materials provided with the
38 // distribution.
39 // * Neither the name of Google Inc. nor the names of its
40 // contributors may be used to endorse or promote products derived from
41 // this software without specific prior written permission.
42 //
43 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54
55
56 // Derived from libunwind, with extensive modifications.
57
58
59 #include "common/arm_ex_reader.h"
60
61 #include <assert.h>
62 #include <stdio.h>
63
64 // This file, in conjunction with arm_ex_to_module.cc, translates
65 // EXIDX unwind information into the same format that Breakpad uses
66 // for CFI information. Hence Breakpad's CFI unwinding abilities
67 // also become usable for EXIDX.
68 //
69 // See: "Exception Handling ABI for the ARM Architecture", ARM IHI 0038A
70 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
71
72 // EXIDX data is presented in two parts:
73 //
74 // * an index table. This contains two words per routine,
75 // the first of which identifies the routine, and the second
76 // of which is a reference to the unwind bytecode. If the
77 // bytecode is very compact -- 3 bytes or less -- it can be
78 // stored directly in the second word.
79 //
80 // * an area containing the unwind bytecodes.
81
82 // General flow is: ExceptionTableInfo::Start iterates over all
83 // of the index table entries (pairs). For each entry, it:
84 //
85 // * calls ExceptionTableInfo::ExtabEntryExtract to copy the bytecode
86 // out into an intermediate buffer.
87
88 // * uses ExceptionTableInfo::ExtabEntryDecode to parse the intermediate
89 // buffer. Each bytecode instruction is bundled into a
90 // arm_ex_to_module::extab_data structure, and handed to ..
91 //
92 // * .. ARMExToModule::ImproveStackFrame, which in turn hands it to
93 // ARMExToModule::TranslateCmd, and that generates the pseudo-CFI
94 // records that Breakpad stores.
95
96 #define ARM_EXIDX_CANT_UNWIND 0x00000001
97 #define ARM_EXIDX_COMPACT 0x80000000
98 #define ARM_EXTBL_OP_FINISH 0xb0
99 #define ARM_EXIDX_TABLE_LIMIT (255*4)
100
101 namespace arm_ex_reader {
102
103 using arm_ex_to_module::ARM_EXIDX_CMD_FINISH;
104 using arm_ex_to_module::ARM_EXIDX_CMD_SUB_FROM_VSP;
105 using arm_ex_to_module::ARM_EXIDX_CMD_ADD_TO_VSP;
106 using arm_ex_to_module::ARM_EXIDX_CMD_REG_POP;
107 using arm_ex_to_module::ARM_EXIDX_CMD_REG_TO_SP;
108 using arm_ex_to_module::ARM_EXIDX_CMD_VFP_POP;
109 using arm_ex_to_module::ARM_EXIDX_CMD_WREG_POP;
110 using arm_ex_to_module::ARM_EXIDX_CMD_WCGR_POP;
111 using arm_ex_to_module::ARM_EXIDX_CMD_RESERVED;
112 using arm_ex_to_module::ARM_EXIDX_CMD_REFUSED;
113 using arm_ex_to_module::exidx_entry;
114 using arm_ex_to_module::ARM_EXIDX_VFP_SHIFT_16;
115 using arm_ex_to_module::ARM_EXIDX_VFP_FSTMD;
116 using google_breakpad::MemoryRange;
117
118
Prel31ToAddr(const void * addr)119 static void* Prel31ToAddr(const void* addr) {
120 uint32_t offset32 = *reinterpret_cast<const uint32_t*>(addr);
121 // sign extend offset32[30:0] to 64 bits -- copy bit 30 to positions
122 // 63:31 inclusive.
123 uint64_t offset64 = offset32;
124 if (offset64 & (1ULL << 30))
125 offset64 |= 0xFFFFFFFF80000000ULL;
126 else
127 offset64 &= 0x000000007FFFFFFFULL;
128 return ((char*)addr) + (uintptr_t)offset64;
129 }
130
131
132 // Extract unwind bytecode for the function denoted by |entry| into |buf|,
133 // and return the number of bytes of |buf| written, along with a code
134 // indicating the outcome.
135
ExtabEntryExtract(const struct exidx_entry * entry,uint8_t * buf,size_t buf_size,size_t * buf_used)136 ExceptionTableInfo::ExExtractResult ExceptionTableInfo::ExtabEntryExtract(
137 const struct exidx_entry* entry,
138 uint8_t* buf, size_t buf_size,
139 size_t* buf_used) {
140 MemoryRange mr_out(buf, buf_size);
141
142 *buf_used = 0;
143
144 # define PUT_BUF_U8(_byte) \
145 do { if (!mr_out.Covers(*buf_used, 1)) return ExOutBufOverflow; \
146 buf[(*buf_used)++] = (_byte); } while (0)
147
148 # define GET_EX_U32(_lval, _addr, _sec_mr) \
149 do { if (!(_sec_mr).Covers(reinterpret_cast<const uint8_t*>(_addr) \
150 - (_sec_mr).data(), 4)) \
151 return ExInBufOverflow; \
152 (_lval) = *(reinterpret_cast<const uint32_t*>(_addr)); } while (0)
153
154 # define GET_EXIDX_U32(_lval, _addr) \
155 GET_EX_U32(_lval, _addr, mr_exidx_)
156 # define GET_EXTAB_U32(_lval, _addr) \
157 GET_EX_U32(_lval, _addr, mr_extab_)
158
159 uint32_t data;
160 GET_EXIDX_U32(data, &entry->data);
161
162 // A function can be marked CANT_UNWIND if (eg) it is known to be
163 // at the bottom of the stack.
164 if (data == ARM_EXIDX_CANT_UNWIND)
165 return ExCantUnwind;
166
167 uint32_t pers; // personality number
168 uint32_t extra; // number of extra data words required
169 uint32_t extra_allowed; // number of extra data words allowed
170 uint32_t* extbl_data; // the handler entry, if not inlined
171
172 if (data & ARM_EXIDX_COMPACT) {
173 // The handler table entry has been inlined into the index table entry.
174 // In this case it can only be an ARM-defined compact model, since
175 // bit 31 is 1. Only personalities 0, 1 and 2 are defined for the
176 // ARM compact model, but 1 and 2 are "Long format" and may require
177 // extra data words. Hence the allowable personalities here are:
178 // personality 0, in which case 'extra' has no meaning
179 // personality 1, with zero extra words
180 // personality 2, with zero extra words
181 extbl_data = NULL;
182 pers = (data >> 24) & 0x0F;
183 extra = (data >> 16) & 0xFF;
184 extra_allowed = 0;
185 }
186 else {
187 // The index table entry is a pointer to the handler entry. Note
188 // that Prel31ToAddr will read the given address, but we already
189 // range-checked above.
190 extbl_data = reinterpret_cast<uint32_t*>(Prel31ToAddr(&entry->data));
191 GET_EXTAB_U32(data, extbl_data);
192 if (!(data & ARM_EXIDX_COMPACT)) {
193 // This denotes a "generic model" handler. That will involve
194 // executing arbitary machine code, which is something we
195 // can't represent here; hence reject it.
196 return ExCantRepresent;
197 }
198 // So we have a compact model representation. Again, 3 possible
199 // personalities, but this time up to 255 allowable extra words.
200 pers = (data >> 24) & 0x0F;
201 extra = (data >> 16) & 0xFF;
202 extra_allowed = 255;
203 extbl_data++;
204 }
205
206 // Now look at the the handler table entry. The first word is
207 // |data| and subsequent words start at |*extbl_data|. The number
208 // of extra words to use is |extra|, provided that the personality
209 // allows extra words. Even if it does, none may be available --
210 // extra_allowed is the maximum number of extra words allowed. */
211 if (pers == 0) {
212 // "Su16" in the documentation -- 3 unwinding insn bytes
213 // |extra| has no meaning here; instead that byte is an unwind-info byte
214 PUT_BUF_U8(data >> 16);
215 PUT_BUF_U8(data >> 8);
216 PUT_BUF_U8(data);
217 }
218 else if ((pers == 1 || pers == 2) && extra <= extra_allowed) {
219 // "Lu16" or "Lu32" respectively -- 2 unwinding insn bytes,
220 // and up to 255 extra words.
221 PUT_BUF_U8(data >> 8);
222 PUT_BUF_U8(data);
223 for (uint32_t j = 0; j < extra; j++) {
224 GET_EXTAB_U32(data, extbl_data);
225 extbl_data++;
226 PUT_BUF_U8(data >> 24);
227 PUT_BUF_U8(data >> 16);
228 PUT_BUF_U8(data >> 8);
229 PUT_BUF_U8(data >> 0);
230 }
231 }
232 else {
233 // The entry is invalid.
234 return ExInvalid;
235 }
236
237 // Make sure the entry is terminated with "FINISH"
238 if (*buf_used > 0 && buf[(*buf_used) - 1] != ARM_EXTBL_OP_FINISH)
239 PUT_BUF_U8(ARM_EXTBL_OP_FINISH);
240
241 return ExSuccess;
242
243 # undef GET_EXTAB_U32
244 # undef GET_EXIDX_U32
245 # undef GET_U32
246 # undef PUT_BUF_U8
247 }
248
249
250 // Take the unwind information extracted by ExtabEntryExtract
251 // and parse it into frame-unwind instructions. These are as
252 // specified in "Table 4, ARM-defined frame-unwinding instructions"
253 // in the specification document detailed in comments at the top
254 // of this file.
255 //
256 // This reads from |buf[0, +data_size)|. It checks for overruns of
257 // the input buffer and returns a negative value if that happens, or
258 // for any other failure cases. It returns zero in case of success.
ExtabEntryDecode(const uint8_t * buf,size_t buf_size)259 int ExceptionTableInfo::ExtabEntryDecode(const uint8_t* buf, size_t buf_size) {
260 if (buf == NULL || buf_size == 0)
261 return -1;
262
263 MemoryRange mr_in(buf, buf_size);
264 const uint8_t* buf_initially = buf;
265
266 # define GET_BUF_U8(_lval) \
267 do { if (!mr_in.Covers(buf - buf_initially, 1)) return -1; \
268 (_lval) = *(buf++); } while (0)
269
270 const uint8_t* end = buf + buf_size;
271
272 while (buf < end) {
273 struct arm_ex_to_module::extab_data edata;
274 memset(&edata, 0, sizeof(edata));
275
276 uint8_t op;
277 GET_BUF_U8(op);
278 if ((op & 0xc0) == 0x00) {
279 // vsp = vsp + (xxxxxx << 2) + 4
280 edata.cmd = ARM_EXIDX_CMD_ADD_TO_VSP;
281 edata.data = (((int)op & 0x3f) << 2) + 4;
282 } else if ((op & 0xc0) == 0x40) {
283 // vsp = vsp - (xxxxxx << 2) - 4
284 edata.cmd = ARM_EXIDX_CMD_SUB_FROM_VSP;
285 edata.data = (((int)op & 0x3f) << 2) + 4;
286 } else if ((op & 0xf0) == 0x80) {
287 uint8_t op2;
288 GET_BUF_U8(op2);
289 if (op == 0x80 && op2 == 0x00) {
290 // Refuse to unwind
291 edata.cmd = ARM_EXIDX_CMD_REFUSED;
292 } else {
293 // Pop up to 12 integer registers under masks {r15-r12},{r11-r4}
294 edata.cmd = ARM_EXIDX_CMD_REG_POP;
295 edata.data = ((op & 0xf) << 8) | op2;
296 edata.data = edata.data << 4;
297 }
298 } else if ((op & 0xf0) == 0x90) {
299 if (op == 0x9d || op == 0x9f) {
300 // 9d: Reserved as prefix for ARM register to register moves
301 // 9f: Reserved as perfix for Intel Wireless MMX reg to reg moves
302 edata.cmd = ARM_EXIDX_CMD_RESERVED;
303 } else {
304 // Set vsp = r[nnnn]
305 edata.cmd = ARM_EXIDX_CMD_REG_TO_SP;
306 edata.data = op & 0x0f;
307 }
308 } else if ((op & 0xf0) == 0xa0) {
309 // Pop r4 to r[4+nnn], or
310 // Pop r4 to r[4+nnn] and r14 or
311 unsigned end = (op & 0x07);
312 edata.data = (1 << (end + 1)) - 1;
313 edata.data = edata.data << 4;
314 if (op & 0x08) edata.data |= 1 << 14;
315 edata.cmd = ARM_EXIDX_CMD_REG_POP;
316 } else if (op == ARM_EXTBL_OP_FINISH) {
317 // Finish
318 edata.cmd = ARM_EXIDX_CMD_FINISH;
319 buf = end;
320 } else if (op == 0xb1) {
321 uint8_t op2;
322 GET_BUF_U8(op2);
323 if (op2 == 0 || (op2 & 0xf0)) {
324 // Spare
325 edata.cmd = ARM_EXIDX_CMD_RESERVED;
326 } else {
327 // Pop integer registers under mask {r3,r2,r1,r0}
328 edata.cmd = ARM_EXIDX_CMD_REG_POP;
329 edata.data = op2 & 0x0f;
330 }
331 } else if (op == 0xb2) {
332 // vsp = vsp + 0x204 + (uleb128 << 2)
333 uint64_t offset = 0;
334 uint8_t byte, shift = 0;
335 do {
336 GET_BUF_U8(byte);
337 offset |= (byte & 0x7f) << shift;
338 shift += 7;
339 } while ((byte & 0x80) && buf < end);
340 edata.data = offset * 4 + 0x204;
341 edata.cmd = ARM_EXIDX_CMD_ADD_TO_VSP;
342 } else if (op == 0xb3 || op == 0xc8 || op == 0xc9) {
343 // b3: Pop VFP regs D[ssss] to D[ssss+cccc], FSTMFDX-ishly
344 // c8: Pop VFP regs D[16+ssss] to D[16+ssss+cccc], FSTMFDD-ishly
345 // c9: Pop VFP regs D[ssss] to D[ssss+cccc], FSTMFDD-ishly
346 edata.cmd = ARM_EXIDX_CMD_VFP_POP;
347 GET_BUF_U8(edata.data);
348 if (op == 0xc8) edata.data |= ARM_EXIDX_VFP_SHIFT_16;
349 if (op != 0xb3) edata.data |= ARM_EXIDX_VFP_FSTMD;
350 } else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) {
351 // b8: Pop VFP regs D[8] to D[8+nnn], FSTMFDX-ishly
352 // d0: Pop VFP regs D[8] to D[8+nnn], FSTMFDD-ishly
353 edata.cmd = ARM_EXIDX_CMD_VFP_POP;
354 edata.data = 0x80 | (op & 0x07);
355 if ((op & 0xf8) == 0xd0) edata.data |= ARM_EXIDX_VFP_FSTMD;
356 } else if (op >= 0xc0 && op <= 0xc5) {
357 // Intel Wireless MMX pop wR[10]-wr[10+nnn], nnn != 6,7
358 edata.cmd = ARM_EXIDX_CMD_WREG_POP;
359 edata.data = 0xa0 | (op & 0x07);
360 } else if (op == 0xc6) {
361 // Intel Wireless MMX pop wR[ssss] to wR[ssss+cccc]
362 edata.cmd = ARM_EXIDX_CMD_WREG_POP;
363 GET_BUF_U8(edata.data);
364 } else if (op == 0xc7) {
365 uint8_t op2;
366 GET_BUF_U8(op2);
367 if (op2 == 0 || (op2 & 0xf0)) {
368 // Spare
369 edata.cmd = ARM_EXIDX_CMD_RESERVED;
370 } else {
371 // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}
372 edata.cmd = ARM_EXIDX_CMD_WCGR_POP;
373 edata.data = op2 & 0x0f;
374 }
375 } else {
376 // Spare
377 edata.cmd = ARM_EXIDX_CMD_RESERVED;
378 }
379
380 int ret = handler_->ImproveStackFrame(&edata);
381 if (ret < 0)
382 return ret;
383 }
384 return 0;
385
386 # undef GET_BUF_U8
387 }
388
Start()389 void ExceptionTableInfo::Start() {
390 const struct exidx_entry* start
391 = reinterpret_cast<const struct exidx_entry*>(mr_exidx_.data());
392 const struct exidx_entry* end
393 = reinterpret_cast<const struct exidx_entry*>(mr_exidx_.data()
394 + mr_exidx_.length());
395
396 // Iterate over each of the EXIDX entries (pairs of 32-bit words).
397 // These occupy the entire .exidx section.
398 for (const struct exidx_entry* entry = start; entry < end; ++entry) {
399 // Figure out the code address range that this table entry is
400 // associated with.
401 uint32_t addr = (reinterpret_cast<char*>(Prel31ToAddr(&entry->addr))
402 - mapping_addr_ + loading_addr_) & 0x7fffffff;
403 uint32_t next_addr;
404 if (entry < end - 1) {
405 next_addr = (reinterpret_cast<char*>(Prel31ToAddr(&((entry + 1)->addr)))
406 - mapping_addr_ + loading_addr_) & 0x7fffffff;
407 } else {
408 // This is the last EXIDX entry in the sequence, so we don't
409 // have an address for the start of the next function, to limit
410 // this one. Instead use the address of the last byte of the
411 // text section associated with this .exidx section, that we
412 // have been given. So as to avoid junking up the CFI unwind
413 // tables with absurdly large address ranges in the case where
414 // text_last_svma_ is wrong, only use the value if it is nonzero
415 // and within one page of |addr|. Otherwise assume a length of 1.
416 //
417 // In some cases, gcc has been observed to finish the exidx
418 // section with an entry of length 1 marked CANT_UNWIND,
419 // presumably exactly for the purpose of giving a definite
420 // length for the last real entry, without having to look at
421 // text segment boundaries.
422 bool plausible = false;
423 next_addr = addr + 1;
424 if (text_last_svma_ != 0) {
425 uint32_t maybe_next_addr = text_last_svma_ + 1;
426 if (maybe_next_addr > addr && maybe_next_addr - addr <= 4096) {
427 next_addr = maybe_next_addr;
428 plausible = true;
429 }
430 }
431 if (!plausible) {
432 fprintf(stderr, "ExceptionTableInfo: implausible EXIDX last entry size "
433 "%d, using 1 instead.", (int32_t)(text_last_svma_ - addr));
434 }
435 }
436
437 // Extract the unwind info into |buf|. This might fail for
438 // various reasons. It involves reading both the .exidx and
439 // .extab sections. All accesses to those sections are
440 // bounds-checked.
441 uint8_t buf[ARM_EXIDX_TABLE_LIMIT];
442 size_t buf_used = 0;
443 ExExtractResult res = ExtabEntryExtract(entry, buf, sizeof(buf), &buf_used);
444 if (res != ExSuccess) {
445 // Couldn't extract the unwind info, for some reason. Move on.
446 switch (res) {
447 case ExInBufOverflow:
448 fprintf(stderr, "ExtabEntryExtract: .exidx/.extab section overrun");
449 break;
450 case ExOutBufOverflow:
451 fprintf(stderr, "ExtabEntryExtract: bytecode buffer overflow");
452 break;
453 case ExCantUnwind:
454 fprintf(stderr, "ExtabEntryExtract: function is marked CANT_UNWIND");
455 break;
456 case ExCantRepresent:
457 fprintf(stderr, "ExtabEntryExtract: bytecode can't be represented");
458 break;
459 case ExInvalid:
460 fprintf(stderr, "ExtabEntryExtract: index table entry is invalid");
461 break;
462 default:
463 fprintf(stderr, "ExtabEntryExtract: unknown error: %d", (int)res);
464 break;
465 }
466 continue;
467 }
468
469 // Finally, work through the unwind instructions in |buf| and
470 // create CFI entries that Breakpad can use. This can also fail.
471 // First, add a new stack frame entry, into which ExtabEntryDecode
472 // will write the CFI entries.
473 if (!handler_->HasStackFrame(addr, next_addr - addr)) {
474 handler_->AddStackFrame(addr, next_addr - addr);
475 int ret = ExtabEntryDecode(buf, buf_used);
476 if (ret < 0) {
477 handler_->DeleteStackFrame();
478 fprintf(stderr, "ExtabEntryDecode: failed with error code: %d", ret);
479 continue;
480 }
481 handler_->SubmitStackFrame();
482 }
483
484 } /* iterating over .exidx */
485 }
486
487 } // namespace arm_ex_reader
488