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