Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 :
4 : // Copyright (c) 2010 Google Inc. All Rights Reserved.
5 : //
6 : // Redistribution and use in source and binary forms, with or without
7 : // modification, are permitted provided that the following conditions are
8 : // met:
9 : //
10 : // * Redistributions of source code must retain the above copyright
11 : // notice, this list of conditions and the following disclaimer.
12 : // * Redistributions in binary form must reproduce the above
13 : // copyright notice, this list of conditions and the following disclaimer
14 : // in the documentation and/or other materials provided with the
15 : // distribution.
16 : // * Neither the name of Google Inc. nor the names of its
17 : // contributors may be used to endorse or promote products derived from
18 : // this software without specific prior written permission.
19 : //
20 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 :
32 : // CFI reader author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
33 : // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
34 :
35 : // Implementation of dwarf2reader::LineInfo, dwarf2reader::CompilationUnit,
36 : // and dwarf2reader::CallFrameInfo. See dwarf2reader.h for details.
37 :
38 : // This file is derived from the following files in
39 : // toolkit/crashreporter/google-breakpad:
40 : // src/common/dwarf/bytereader.cc
41 : // src/common/dwarf/dwarf2reader.cc
42 : // src/common/dwarf_cfi_to_module.cc
43 :
44 : #include <stdint.h>
45 : #include <stdio.h>
46 : #include <string.h>
47 : #include <stdlib.h>
48 :
49 : #include <map>
50 : #include <stack>
51 : #include <string>
52 :
53 : #include "mozilla/Assertions.h"
54 : #include "mozilla/Sprintf.h"
55 :
56 : #include "LulCommonExt.h"
57 : #include "LulDwarfInt.h"
58 :
59 :
60 : // Set this to 1 for verbose logging
61 : #define DEBUG_DWARF 0
62 :
63 :
64 : namespace lul {
65 :
66 : using std::string;
67 :
68 0 : ByteReader::ByteReader(enum Endianness endian)
69 : :offset_reader_(NULL), address_reader_(NULL), endian_(endian),
70 : address_size_(0), offset_size_(0),
71 : have_section_base_(), have_text_base_(), have_data_base_(),
72 0 : have_function_base_() { }
73 :
74 0 : ByteReader::~ByteReader() { }
75 :
76 0 : void ByteReader::SetOffsetSize(uint8 size) {
77 0 : offset_size_ = size;
78 0 : MOZ_ASSERT(size == 4 || size == 8);
79 0 : if (size == 4) {
80 0 : this->offset_reader_ = &ByteReader::ReadFourBytes;
81 : } else {
82 0 : this->offset_reader_ = &ByteReader::ReadEightBytes;
83 : }
84 0 : }
85 :
86 0 : void ByteReader::SetAddressSize(uint8 size) {
87 0 : address_size_ = size;
88 0 : MOZ_ASSERT(size == 4 || size == 8);
89 0 : if (size == 4) {
90 0 : this->address_reader_ = &ByteReader::ReadFourBytes;
91 : } else {
92 0 : this->address_reader_ = &ByteReader::ReadEightBytes;
93 : }
94 0 : }
95 :
96 0 : uint64 ByteReader::ReadInitialLength(const char* start, size_t* len) {
97 0 : const uint64 initial_length = ReadFourBytes(start);
98 0 : start += 4;
99 :
100 : // In DWARF2/3, if the initial length is all 1 bits, then the offset
101 : // size is 8 and we need to read the next 8 bytes for the real length.
102 0 : if (initial_length == 0xffffffff) {
103 0 : SetOffsetSize(8);
104 0 : *len = 12;
105 0 : return ReadOffset(start);
106 : } else {
107 0 : SetOffsetSize(4);
108 0 : *len = 4;
109 : }
110 0 : return initial_length;
111 : }
112 :
113 0 : bool ByteReader::ValidEncoding(DwarfPointerEncoding encoding) const {
114 0 : if (encoding == DW_EH_PE_omit) return true;
115 0 : if (encoding == DW_EH_PE_aligned) return true;
116 0 : if ((encoding & 0x7) > DW_EH_PE_udata8)
117 0 : return false;
118 0 : if ((encoding & 0x70) > DW_EH_PE_funcrel)
119 0 : return false;
120 0 : return true;
121 : }
122 :
123 0 : bool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const {
124 0 : switch (encoding & 0x70) {
125 0 : case DW_EH_PE_absptr: return true;
126 0 : case DW_EH_PE_pcrel: return have_section_base_;
127 0 : case DW_EH_PE_textrel: return have_text_base_;
128 0 : case DW_EH_PE_datarel: return have_data_base_;
129 0 : case DW_EH_PE_funcrel: return have_function_base_;
130 0 : default: return false;
131 : }
132 : }
133 :
134 0 : uint64 ByteReader::ReadEncodedPointer(const char *buffer,
135 : DwarfPointerEncoding encoding,
136 : size_t *len) const {
137 : // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't
138 : // see it here.
139 0 : MOZ_ASSERT(encoding != DW_EH_PE_omit);
140 :
141 : // The Linux Standards Base 4.0 does not make this clear, but the
142 : // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c)
143 : // agree that aligned pointers are always absolute, machine-sized,
144 : // machine-signed pointers.
145 0 : if (encoding == DW_EH_PE_aligned) {
146 0 : MOZ_ASSERT(have_section_base_);
147 :
148 : // We don't need to align BUFFER in *our* address space. Rather, we
149 : // need to find the next position in our buffer that would be aligned
150 : // when the .eh_frame section the buffer contains is loaded into the
151 : // program's memory. So align assuming that buffer_base_ gets loaded at
152 : // address section_base_, where section_base_ itself may or may not be
153 : // aligned.
154 :
155 : // First, find the offset to START from the closest prior aligned
156 : // address.
157 0 : uint64 skew = section_base_ & (AddressSize() - 1);
158 : // Now find the offset from that aligned address to buffer.
159 0 : uint64 offset = skew + (buffer - buffer_base_);
160 : // Round up to the next boundary.
161 0 : uint64 aligned = (offset + AddressSize() - 1) & -AddressSize();
162 : // Convert back to a pointer.
163 0 : const char *aligned_buffer = buffer_base_ + (aligned - skew);
164 : // Finally, store the length and actually fetch the pointer.
165 0 : *len = aligned_buffer - buffer + AddressSize();
166 0 : return ReadAddress(aligned_buffer);
167 : }
168 :
169 : // Extract the value first, ignoring whether it's a pointer or an
170 : // offset relative to some base.
171 : uint64 offset;
172 0 : switch (encoding & 0x0f) {
173 : case DW_EH_PE_absptr:
174 : // DW_EH_PE_absptr is weird, as it is used as a meaningful value for
175 : // both the high and low nybble of encoding bytes. When it appears in
176 : // the high nybble, it means that the pointer is absolute, not an
177 : // offset from some base address. When it appears in the low nybble,
178 : // as here, it means that the pointer is stored as a normal
179 : // machine-sized and machine-signed address. A low nybble of
180 : // DW_EH_PE_absptr does not imply that the pointer is absolute; it is
181 : // correct for us to treat the value as an offset from a base address
182 : // if the upper nybble is not DW_EH_PE_absptr.
183 0 : offset = ReadAddress(buffer);
184 0 : *len = AddressSize();
185 0 : break;
186 :
187 : case DW_EH_PE_uleb128:
188 0 : offset = ReadUnsignedLEB128(buffer, len);
189 0 : break;
190 :
191 : case DW_EH_PE_udata2:
192 0 : offset = ReadTwoBytes(buffer);
193 0 : *len = 2;
194 0 : break;
195 :
196 : case DW_EH_PE_udata4:
197 0 : offset = ReadFourBytes(buffer);
198 0 : *len = 4;
199 0 : break;
200 :
201 : case DW_EH_PE_udata8:
202 0 : offset = ReadEightBytes(buffer);
203 0 : *len = 8;
204 0 : break;
205 :
206 : case DW_EH_PE_sleb128:
207 0 : offset = ReadSignedLEB128(buffer, len);
208 0 : break;
209 :
210 : case DW_EH_PE_sdata2:
211 0 : offset = ReadTwoBytes(buffer);
212 : // Sign-extend from 16 bits.
213 0 : offset = (offset ^ 0x8000) - 0x8000;
214 0 : *len = 2;
215 0 : break;
216 :
217 : case DW_EH_PE_sdata4:
218 0 : offset = ReadFourBytes(buffer);
219 : // Sign-extend from 32 bits.
220 0 : offset = (offset ^ 0x80000000ULL) - 0x80000000ULL;
221 0 : *len = 4;
222 0 : break;
223 :
224 : case DW_EH_PE_sdata8:
225 : // No need to sign-extend; this is the full width of our type.
226 0 : offset = ReadEightBytes(buffer);
227 0 : *len = 8;
228 0 : break;
229 :
230 : default:
231 0 : abort();
232 : }
233 :
234 : // Find the appropriate base address.
235 : uint64 base;
236 0 : switch (encoding & 0x70) {
237 : case DW_EH_PE_absptr:
238 0 : base = 0;
239 0 : break;
240 :
241 : case DW_EH_PE_pcrel:
242 0 : MOZ_ASSERT(have_section_base_);
243 0 : base = section_base_ + (buffer - buffer_base_);
244 0 : break;
245 :
246 : case DW_EH_PE_textrel:
247 0 : MOZ_ASSERT(have_text_base_);
248 0 : base = text_base_;
249 0 : break;
250 :
251 : case DW_EH_PE_datarel:
252 0 : MOZ_ASSERT(have_data_base_);
253 0 : base = data_base_;
254 0 : break;
255 :
256 : case DW_EH_PE_funcrel:
257 0 : MOZ_ASSERT(have_function_base_);
258 0 : base = function_base_;
259 0 : break;
260 :
261 : default:
262 0 : abort();
263 : }
264 :
265 0 : uint64 pointer = base + offset;
266 :
267 : // Remove inappropriate upper bits.
268 0 : if (AddressSize() == 4)
269 0 : pointer = pointer & 0xffffffff;
270 : else
271 0 : MOZ_ASSERT(AddressSize() == sizeof(uint64));
272 :
273 0 : return pointer;
274 : }
275 :
276 :
277 : // A DWARF rule for recovering the address or value of a register, or
278 : // computing the canonical frame address. There is one subclass of this for
279 : // each '*Rule' member function in CallFrameInfo::Handler.
280 : //
281 : // It's annoying that we have to handle Rules using pointers (because
282 : // the concrete instances can have an arbitrary size). They're small,
283 : // so it would be much nicer if we could just handle them by value
284 : // instead of fretting about ownership and destruction.
285 : //
286 : // It seems like all these could simply be instances of std::tr1::bind,
287 : // except that we need instances to be EqualityComparable, too.
288 : //
289 : // This could logically be nested within State, but then the qualified names
290 : // get horrendous.
291 0 : class CallFrameInfo::Rule {
292 : public:
293 0 : virtual ~Rule() { }
294 :
295 : // Tell HANDLER that, at ADDRESS in the program, REGISTER can be
296 : // recovered using this rule. If REGISTER is kCFARegister, then this rule
297 : // describes how to compute the canonical frame address. Return what the
298 : // HANDLER member function returned.
299 : virtual bool Handle(Handler *handler, uint64 address, int register) const = 0;
300 :
301 : // Equality on rules. We use these to decide which rules we need
302 : // to report after a DW_CFA_restore_state instruction.
303 : virtual bool operator==(const Rule &rhs) const = 0;
304 :
305 0 : bool operator!=(const Rule &rhs) const { return ! (*this == rhs); }
306 :
307 : // Return a pointer to a copy of this rule.
308 : virtual Rule *Copy() const = 0;
309 :
310 : // If this is a base+offset rule, change its base register to REG.
311 : // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.)
312 0 : virtual void SetBaseRegister(unsigned reg) { }
313 :
314 : // If this is a base+offset rule, change its offset to OFFSET. Otherwise,
315 : // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.)
316 0 : virtual void SetOffset(long long offset) { }
317 :
318 : // A RTTI workaround, to make it possible to implement equality
319 : // comparisons on classes derived from this one.
320 : enum CFIRTag {
321 : CFIR_UNDEFINED_RULE,
322 : CFIR_SAME_VALUE_RULE,
323 : CFIR_OFFSET_RULE,
324 : CFIR_VAL_OFFSET_RULE,
325 : CFIR_REGISTER_RULE,
326 : CFIR_EXPRESSION_RULE,
327 : CFIR_VAL_EXPRESSION_RULE
328 : };
329 :
330 : // Produce the tag that identifies the child class of this object.
331 : virtual CFIRTag getTag() const = 0;
332 : };
333 :
334 : // Rule: the value the register had in the caller cannot be recovered.
335 0 : class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
336 : public:
337 0 : UndefinedRule() { }
338 0 : ~UndefinedRule() { }
339 0 : CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; }
340 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
341 0 : return handler->UndefinedRule(address, reg);
342 : }
343 0 : bool operator==(const Rule &rhs) const {
344 0 : if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false;
345 0 : return true;
346 : }
347 0 : Rule *Copy() const { return new UndefinedRule(*this); }
348 : };
349 :
350 : // Rule: the register's value is the same as that it had in the caller.
351 0 : class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
352 : public:
353 0 : SameValueRule() { }
354 0 : ~SameValueRule() { }
355 0 : CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; }
356 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
357 0 : return handler->SameValueRule(address, reg);
358 : }
359 0 : bool operator==(const Rule &rhs) const {
360 0 : if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false;
361 0 : return true;
362 : }
363 0 : Rule *Copy() const { return new SameValueRule(*this); }
364 : };
365 :
366 : // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER
367 : // may be CallFrameInfo::Handler::kCFARegister.
368 0 : class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
369 : public:
370 0 : OffsetRule(int base_register, long offset)
371 0 : : base_register_(base_register), offset_(offset) { }
372 0 : ~OffsetRule() { }
373 0 : CFIRTag getTag() const { return CFIR_OFFSET_RULE; }
374 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
375 0 : return handler->OffsetRule(address, reg, base_register_, offset_);
376 : }
377 0 : bool operator==(const Rule &rhs) const {
378 0 : if (rhs.getTag() != CFIR_OFFSET_RULE) return false;
379 0 : const OffsetRule *our_rhs = static_cast<const OffsetRule *>(&rhs);
380 0 : return (base_register_ == our_rhs->base_register_ &&
381 0 : offset_ == our_rhs->offset_);
382 : }
383 0 : Rule *Copy() const { return new OffsetRule(*this); }
384 : // We don't actually need SetBaseRegister or SetOffset here, since they
385 : // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it
386 : // doesn't make sense to use OffsetRule for computing the CFA: it
387 : // computes the address at which a register is saved, not a value.
388 : private:
389 : int base_register_;
390 : long offset_;
391 : };
392 :
393 : // Rule: the value the register had in the caller is the value of
394 : // BASE_REGISTER plus offset. BASE_REGISTER may be
395 : // CallFrameInfo::Handler::kCFARegister.
396 0 : class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
397 : public:
398 0 : ValOffsetRule(int base_register, long offset)
399 0 : : base_register_(base_register), offset_(offset) { }
400 0 : ~ValOffsetRule() { }
401 0 : CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; }
402 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
403 0 : return handler->ValOffsetRule(address, reg, base_register_, offset_);
404 : }
405 0 : bool operator==(const Rule &rhs) const {
406 0 : if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false;
407 0 : const ValOffsetRule *our_rhs = static_cast<const ValOffsetRule *>(&rhs);
408 0 : return (base_register_ == our_rhs->base_register_ &&
409 0 : offset_ == our_rhs->offset_);
410 : }
411 0 : Rule *Copy() const { return new ValOffsetRule(*this); }
412 0 : void SetBaseRegister(unsigned reg) { base_register_ = reg; }
413 0 : void SetOffset(long long offset) { offset_ = offset; }
414 : private:
415 : int base_register_;
416 : long offset_;
417 : };
418 :
419 : // Rule: the register has been saved in another register REGISTER_NUMBER_.
420 0 : class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
421 : public:
422 0 : explicit RegisterRule(int register_number)
423 0 : : register_number_(register_number) { }
424 0 : ~RegisterRule() { }
425 0 : CFIRTag getTag() const { return CFIR_REGISTER_RULE; }
426 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
427 0 : return handler->RegisterRule(address, reg, register_number_);
428 : }
429 0 : bool operator==(const Rule &rhs) const {
430 0 : if (rhs.getTag() != CFIR_REGISTER_RULE) return false;
431 0 : const RegisterRule *our_rhs = static_cast<const RegisterRule *>(&rhs);
432 0 : return (register_number_ == our_rhs->register_number_);
433 : }
434 0 : Rule *Copy() const { return new RegisterRule(*this); }
435 : private:
436 : int register_number_;
437 : };
438 :
439 : // Rule: EXPRESSION evaluates to the address at which the register is saved.
440 0 : class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
441 : public:
442 0 : explicit ExpressionRule(const string &expression)
443 0 : : expression_(expression) { }
444 0 : ~ExpressionRule() { }
445 0 : CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; }
446 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
447 0 : return handler->ExpressionRule(address, reg, expression_);
448 : }
449 0 : bool operator==(const Rule &rhs) const {
450 0 : if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false;
451 0 : const ExpressionRule *our_rhs = static_cast<const ExpressionRule *>(&rhs);
452 0 : return (expression_ == our_rhs->expression_);
453 : }
454 0 : Rule *Copy() const { return new ExpressionRule(*this); }
455 : private:
456 : string expression_;
457 : };
458 :
459 : // Rule: EXPRESSION evaluates to the previous value of the register.
460 0 : class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
461 : public:
462 0 : explicit ValExpressionRule(const string &expression)
463 0 : : expression_(expression) { }
464 0 : ~ValExpressionRule() { }
465 0 : CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; }
466 0 : bool Handle(Handler *handler, uint64 address, int reg) const {
467 0 : return handler->ValExpressionRule(address, reg, expression_);
468 : }
469 0 : bool operator==(const Rule &rhs) const {
470 0 : if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false;
471 : const ValExpressionRule *our_rhs =
472 0 : static_cast<const ValExpressionRule *>(&rhs);
473 0 : return (expression_ == our_rhs->expression_);
474 : }
475 0 : Rule *Copy() const { return new ValExpressionRule(*this); }
476 : private:
477 : string expression_;
478 : };
479 :
480 : // A map from register numbers to rules.
481 : class CallFrameInfo::RuleMap {
482 : public:
483 0 : RuleMap() : cfa_rule_(NULL) { }
484 0 : RuleMap(const RuleMap &rhs) : cfa_rule_(NULL) { *this = rhs; }
485 0 : ~RuleMap() { Clear(); }
486 :
487 : RuleMap &operator=(const RuleMap &rhs);
488 :
489 : // Set the rule for computing the CFA to RULE. Take ownership of RULE.
490 0 : void SetCFARule(Rule *rule) { delete cfa_rule_; cfa_rule_ = rule; }
491 :
492 : // Return the current CFA rule. Unlike RegisterRule, this RuleMap retains
493 : // ownership of the rule. We use this for DW_CFA_def_cfa_offset and
494 : // DW_CFA_def_cfa_register, and for detecting references to the CFA before
495 : // a rule for it has been established.
496 0 : Rule *CFARule() const { return cfa_rule_; }
497 :
498 : // Return the rule for REG, or NULL if there is none. The caller takes
499 : // ownership of the result.
500 : Rule *RegisterRule(int reg) const;
501 :
502 : // Set the rule for computing REG to RULE. Take ownership of RULE.
503 : void SetRegisterRule(int reg, Rule *rule);
504 :
505 : // Make all the appropriate calls to HANDLER as if we were changing from
506 : // this RuleMap to NEW_RULES at ADDRESS. We use this to implement
507 : // DW_CFA_restore_state, where lots of rules can change simultaneously.
508 : // Return true if all handlers returned true; otherwise, return false.
509 : bool HandleTransitionTo(Handler *handler, uint64 address,
510 : const RuleMap &new_rules) const;
511 :
512 : private:
513 : // A map from register numbers to Rules.
514 : typedef std::map<int, Rule *> RuleByNumber;
515 :
516 : // Remove all register rules and clear cfa_rule_.
517 : void Clear();
518 :
519 : // The rule for computing the canonical frame address. This RuleMap owns
520 : // this rule.
521 : Rule *cfa_rule_;
522 :
523 : // A map from register numbers to postfix expressions to recover
524 : // their values. This RuleMap owns the Rules the map refers to.
525 : RuleByNumber registers_;
526 : };
527 :
528 0 : CallFrameInfo::RuleMap &CallFrameInfo::RuleMap::operator=(const RuleMap &rhs) {
529 0 : Clear();
530 : // Since each map owns the rules it refers to, assignment must copy them.
531 0 : if (rhs.cfa_rule_) cfa_rule_ = rhs.cfa_rule_->Copy();
532 0 : for (RuleByNumber::const_iterator it = rhs.registers_.begin();
533 0 : it != rhs.registers_.end(); it++)
534 0 : registers_[it->first] = it->second->Copy();
535 0 : return *this;
536 : }
537 :
538 0 : CallFrameInfo::Rule *CallFrameInfo::RuleMap::RegisterRule(int reg) const {
539 0 : MOZ_ASSERT(reg != Handler::kCFARegister);
540 0 : RuleByNumber::const_iterator it = registers_.find(reg);
541 0 : if (it != registers_.end())
542 0 : return it->second->Copy();
543 : else
544 0 : return NULL;
545 : }
546 :
547 0 : void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule *rule) {
548 0 : MOZ_ASSERT(reg != Handler::kCFARegister);
549 0 : MOZ_ASSERT(rule);
550 0 : Rule **slot = ®isters_[reg];
551 0 : delete *slot;
552 0 : *slot = rule;
553 0 : }
554 :
555 0 : bool CallFrameInfo::RuleMap::HandleTransitionTo(
556 : Handler *handler,
557 : uint64 address,
558 : const RuleMap &new_rules) const {
559 : // Transition from cfa_rule_ to new_rules.cfa_rule_.
560 0 : if (cfa_rule_ && new_rules.cfa_rule_) {
561 0 : if (*cfa_rule_ != *new_rules.cfa_rule_ &&
562 0 : !new_rules.cfa_rule_->Handle(handler, address, Handler::kCFARegister))
563 0 : return false;
564 0 : } else if (cfa_rule_) {
565 : // this RuleMap has a CFA rule but new_rules doesn't.
566 : // CallFrameInfo::Handler has no way to handle this --- and shouldn't;
567 : // it's garbage input. The instruction interpreter should have
568 : // detected this and warned, so take no action here.
569 0 : } else if (new_rules.cfa_rule_) {
570 : // This shouldn't be possible: NEW_RULES is some prior state, and
571 : // there's no way to remove entries.
572 0 : MOZ_ASSERT(0);
573 : } else {
574 : // Both CFA rules are empty. No action needed.
575 : }
576 :
577 : // Traverse the two maps in order by register number, and report
578 : // whatever differences we find.
579 0 : RuleByNumber::const_iterator old_it = registers_.begin();
580 0 : RuleByNumber::const_iterator new_it = new_rules.registers_.begin();
581 0 : while (old_it != registers_.end() && new_it != new_rules.registers_.end()) {
582 0 : if (old_it->first < new_it->first) {
583 : // This RuleMap has an entry for old_it->first, but NEW_RULES
584 : // doesn't.
585 : //
586 : // This isn't really the right thing to do, but since CFI generally
587 : // only mentions callee-saves registers, and GCC's convention for
588 : // callee-saves registers is that they are unchanged, it's a good
589 : // approximation.
590 0 : if (!handler->SameValueRule(address, old_it->first))
591 0 : return false;
592 0 : old_it++;
593 0 : } else if (old_it->first > new_it->first) {
594 : // NEW_RULES has entry for new_it->first, but this RuleMap
595 : // doesn't. This shouldn't be possible: NEW_RULES is some prior
596 : // state, and there's no way to remove entries.
597 0 : MOZ_ASSERT(0);
598 : } else {
599 : // Both maps have an entry for this register. Report the new
600 : // rule if it is different.
601 0 : if (*old_it->second != *new_it->second &&
602 0 : !new_it->second->Handle(handler, address, new_it->first))
603 0 : return false;
604 0 : new_it++; old_it++;
605 : }
606 : }
607 : // Finish off entries from this RuleMap with no counterparts in new_rules.
608 0 : while (old_it != registers_.end()) {
609 0 : if (!handler->SameValueRule(address, old_it->first))
610 0 : return false;
611 0 : old_it++;
612 : }
613 : // Since we only make transitions from a rule set to some previously
614 : // saved rule set, and we can only add rules to the map, NEW_RULES
615 : // must have fewer rules than *this.
616 0 : MOZ_ASSERT(new_it == new_rules.registers_.end());
617 :
618 0 : return true;
619 : }
620 :
621 : // Remove all register rules and clear cfa_rule_.
622 0 : void CallFrameInfo::RuleMap::Clear() {
623 0 : delete cfa_rule_;
624 0 : cfa_rule_ = NULL;
625 0 : for (RuleByNumber::iterator it = registers_.begin();
626 0 : it != registers_.end(); it++)
627 0 : delete it->second;
628 0 : registers_.clear();
629 0 : }
630 :
631 : // The state of the call frame information interpreter as it processes
632 : // instructions from a CIE and FDE.
633 : class CallFrameInfo::State {
634 : public:
635 : // Create a call frame information interpreter state with the given
636 : // reporter, reader, handler, and initial call frame info address.
637 0 : State(ByteReader *reader, Handler *handler, Reporter *reporter,
638 : uint64 address)
639 0 : : reader_(reader), handler_(handler), reporter_(reporter),
640 : address_(address), entry_(NULL), cursor_(NULL),
641 0 : saved_rules_(NULL) { }
642 :
643 0 : ~State() {
644 0 : if (saved_rules_)
645 0 : delete saved_rules_;
646 0 : }
647 :
648 : // Interpret instructions from CIE, save the resulting rule set for
649 : // DW_CFA_restore instructions, and return true. On error, report
650 : // the problem to reporter_ and return false.
651 : bool InterpretCIE(const CIE &cie);
652 :
653 : // Interpret instructions from FDE, and return true. On error,
654 : // report the problem to reporter_ and return false.
655 : bool InterpretFDE(const FDE &fde);
656 :
657 : private:
658 : // The operands of a CFI instruction, for ParseOperands.
659 0 : struct Operands {
660 : unsigned register_number; // A register number.
661 : uint64 offset; // An offset or address.
662 : long signed_offset; // A signed offset.
663 : string expression; // A DWARF expression.
664 : };
665 :
666 : // Parse CFI instruction operands from STATE's instruction stream as
667 : // described by FORMAT. On success, populate OPERANDS with the
668 : // results, and return true. On failure, report the problem and
669 : // return false.
670 : //
671 : // Each character of FORMAT should be one of the following:
672 : //
673 : // 'r' unsigned LEB128 register number (OPERANDS->register_number)
674 : // 'o' unsigned LEB128 offset (OPERANDS->offset)
675 : // 's' signed LEB128 offset (OPERANDS->signed_offset)
676 : // 'a' machine-size address (OPERANDS->offset)
677 : // (If the CIE has a 'z' augmentation string, 'a' uses the
678 : // encoding specified by the 'R' argument.)
679 : // '1' a one-byte offset (OPERANDS->offset)
680 : // '2' a two-byte offset (OPERANDS->offset)
681 : // '4' a four-byte offset (OPERANDS->offset)
682 : // '8' an eight-byte offset (OPERANDS->offset)
683 : // 'e' a DW_FORM_block holding a (OPERANDS->expression)
684 : // DWARF expression
685 : bool ParseOperands(const char *format, Operands *operands);
686 :
687 : // Interpret one CFI instruction from STATE's instruction stream, update
688 : // STATE, report any rule changes to handler_, and return true. On
689 : // failure, report the problem and return false.
690 : bool DoInstruction();
691 :
692 : // The following Do* member functions are subroutines of DoInstruction,
693 : // factoring out the actual work of operations that have several
694 : // different encodings.
695 :
696 : // Set the CFA rule to be the value of BASE_REGISTER plus OFFSET, and
697 : // return true. On failure, report and return false. (Used for
698 : // DW_CFA_def_cfa and DW_CFA_def_cfa_sf.)
699 : bool DoDefCFA(unsigned base_register, long offset);
700 :
701 : // Change the offset of the CFA rule to OFFSET, and return true. On
702 : // failure, report and return false. (Subroutine for
703 : // DW_CFA_def_cfa_offset and DW_CFA_def_cfa_offset_sf.)
704 : bool DoDefCFAOffset(long offset);
705 :
706 : // Specify that REG can be recovered using RULE, and return true. On
707 : // failure, report and return false.
708 : bool DoRule(unsigned reg, Rule *rule);
709 :
710 : // Specify that REG can be found at OFFSET from the CFA, and return true.
711 : // On failure, report and return false. (Subroutine for DW_CFA_offset,
712 : // DW_CFA_offset_extended, and DW_CFA_offset_extended_sf.)
713 : bool DoOffset(unsigned reg, long offset);
714 :
715 : // Specify that the caller's value for REG is the CFA plus OFFSET,
716 : // and return true. On failure, report and return false. (Subroutine
717 : // for DW_CFA_val_offset and DW_CFA_val_offset_sf.)
718 : bool DoValOffset(unsigned reg, long offset);
719 :
720 : // Restore REG to the rule established in the CIE, and return true. On
721 : // failure, report and return false. (Subroutine for DW_CFA_restore and
722 : // DW_CFA_restore_extended.)
723 : bool DoRestore(unsigned reg);
724 :
725 : // Return the section offset of the instruction at cursor. For use
726 : // in error messages.
727 0 : uint64 CursorOffset() { return entry_->offset + (cursor_ - entry_->start); }
728 :
729 : // Report that entry_ is incomplete, and return false. For brevity.
730 0 : bool ReportIncomplete() {
731 0 : reporter_->Incomplete(entry_->offset, entry_->kind);
732 0 : return false;
733 : }
734 :
735 : // For reading multi-byte values with the appropriate endianness.
736 : ByteReader *reader_;
737 :
738 : // The handler to which we should report the data we find.
739 : Handler *handler_;
740 :
741 : // For reporting problems in the info we're parsing.
742 : Reporter *reporter_;
743 :
744 : // The code address to which the next instruction in the stream applies.
745 : uint64 address_;
746 :
747 : // The entry whose instructions we are currently processing. This is
748 : // first a CIE, and then an FDE.
749 : const Entry *entry_;
750 :
751 : // The next instruction to process.
752 : const char *cursor_;
753 :
754 : // The current set of rules.
755 : RuleMap rules_;
756 :
757 : // The set of rules established by the CIE, used by DW_CFA_restore
758 : // and DW_CFA_restore_extended. We set this after interpreting the
759 : // CIE's instructions.
760 : RuleMap cie_rules_;
761 :
762 : // A stack of saved states, for DW_CFA_remember_state and
763 : // DW_CFA_restore_state.
764 : std::stack<RuleMap>* saved_rules_;
765 : };
766 :
767 0 : bool CallFrameInfo::State::InterpretCIE(const CIE &cie) {
768 0 : entry_ = &cie;
769 0 : cursor_ = entry_->instructions;
770 0 : while (cursor_ < entry_->end)
771 0 : if (!DoInstruction())
772 0 : return false;
773 : // Note the rules established by the CIE, for use by DW_CFA_restore
774 : // and DW_CFA_restore_extended.
775 0 : cie_rules_ = rules_;
776 0 : return true;
777 : }
778 :
779 0 : bool CallFrameInfo::State::InterpretFDE(const FDE &fde) {
780 0 : entry_ = &fde;
781 0 : cursor_ = entry_->instructions;
782 0 : while (cursor_ < entry_->end)
783 0 : if (!DoInstruction())
784 0 : return false;
785 0 : return true;
786 : }
787 :
788 0 : bool CallFrameInfo::State::ParseOperands(const char *format,
789 : Operands *operands) {
790 : size_t len;
791 : const char *operand;
792 :
793 0 : for (operand = format; *operand; operand++) {
794 0 : size_t bytes_left = entry_->end - cursor_;
795 0 : switch (*operand) {
796 : case 'r':
797 0 : operands->register_number = reader_->ReadUnsignedLEB128(cursor_, &len);
798 0 : if (len > bytes_left) return ReportIncomplete();
799 0 : cursor_ += len;
800 0 : break;
801 :
802 : case 'o':
803 0 : operands->offset = reader_->ReadUnsignedLEB128(cursor_, &len);
804 0 : if (len > bytes_left) return ReportIncomplete();
805 0 : cursor_ += len;
806 0 : break;
807 :
808 : case 's':
809 0 : operands->signed_offset = reader_->ReadSignedLEB128(cursor_, &len);
810 0 : if (len > bytes_left) return ReportIncomplete();
811 0 : cursor_ += len;
812 0 : break;
813 :
814 : case 'a':
815 0 : operands->offset =
816 0 : reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding,
817 : &len);
818 0 : if (len > bytes_left) return ReportIncomplete();
819 0 : cursor_ += len;
820 0 : break;
821 :
822 : case '1':
823 0 : if (1 > bytes_left) return ReportIncomplete();
824 0 : operands->offset = static_cast<unsigned char>(*cursor_++);
825 0 : break;
826 :
827 : case '2':
828 0 : if (2 > bytes_left) return ReportIncomplete();
829 0 : operands->offset = reader_->ReadTwoBytes(cursor_);
830 0 : cursor_ += 2;
831 0 : break;
832 :
833 : case '4':
834 0 : if (4 > bytes_left) return ReportIncomplete();
835 0 : operands->offset = reader_->ReadFourBytes(cursor_);
836 0 : cursor_ += 4;
837 0 : break;
838 :
839 : case '8':
840 0 : if (8 > bytes_left) return ReportIncomplete();
841 0 : operands->offset = reader_->ReadEightBytes(cursor_);
842 0 : cursor_ += 8;
843 0 : break;
844 :
845 : case 'e': {
846 0 : size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len);
847 0 : if (len > bytes_left || expression_length > bytes_left - len)
848 0 : return ReportIncomplete();
849 0 : cursor_ += len;
850 0 : operands->expression = string(cursor_, expression_length);
851 0 : cursor_ += expression_length;
852 0 : break;
853 : }
854 :
855 : default:
856 0 : MOZ_ASSERT(0);
857 : }
858 : }
859 :
860 0 : return true;
861 : }
862 :
863 0 : bool CallFrameInfo::State::DoInstruction() {
864 0 : CIE *cie = entry_->cie;
865 0 : Operands ops;
866 :
867 : // Our entry's kind should have been set by now.
868 0 : MOZ_ASSERT(entry_->kind != kUnknown);
869 :
870 : // We shouldn't have been invoked unless there were more
871 : // instructions to parse.
872 0 : MOZ_ASSERT(cursor_ < entry_->end);
873 :
874 0 : unsigned opcode = *cursor_++;
875 0 : if ((opcode & 0xc0) != 0) {
876 0 : switch (opcode & 0xc0) {
877 : // Advance the address.
878 : case DW_CFA_advance_loc: {
879 0 : size_t code_offset = opcode & 0x3f;
880 0 : address_ += code_offset * cie->code_alignment_factor;
881 0 : break;
882 : }
883 :
884 : // Find a register at an offset from the CFA.
885 : case DW_CFA_offset:
886 0 : if (!ParseOperands("o", &ops) ||
887 0 : !DoOffset(opcode & 0x3f, ops.offset * cie->data_alignment_factor))
888 0 : return false;
889 0 : break;
890 :
891 : // Restore the rule established for a register by the CIE.
892 : case DW_CFA_restore:
893 0 : if (!DoRestore(opcode & 0x3f)) return false;
894 0 : break;
895 :
896 : // The 'if' above should have excluded this possibility.
897 : default:
898 0 : MOZ_ASSERT(0);
899 : }
900 :
901 : // Return here, so the big switch below won't be indented.
902 0 : return true;
903 : }
904 :
905 0 : switch (opcode) {
906 : // Set the address.
907 : case DW_CFA_set_loc:
908 0 : if (!ParseOperands("a", &ops)) return false;
909 0 : address_ = ops.offset;
910 0 : break;
911 :
912 : // Advance the address.
913 : case DW_CFA_advance_loc1:
914 0 : if (!ParseOperands("1", &ops)) return false;
915 0 : address_ += ops.offset * cie->code_alignment_factor;
916 0 : break;
917 :
918 : // Advance the address.
919 : case DW_CFA_advance_loc2:
920 0 : if (!ParseOperands("2", &ops)) return false;
921 0 : address_ += ops.offset * cie->code_alignment_factor;
922 0 : break;
923 :
924 : // Advance the address.
925 : case DW_CFA_advance_loc4:
926 0 : if (!ParseOperands("4", &ops)) return false;
927 0 : address_ += ops.offset * cie->code_alignment_factor;
928 0 : break;
929 :
930 : // Advance the address.
931 : case DW_CFA_MIPS_advance_loc8:
932 0 : if (!ParseOperands("8", &ops)) return false;
933 0 : address_ += ops.offset * cie->code_alignment_factor;
934 0 : break;
935 :
936 : // Compute the CFA by adding an offset to a register.
937 : case DW_CFA_def_cfa:
938 0 : if (!ParseOperands("ro", &ops) ||
939 0 : !DoDefCFA(ops.register_number, ops.offset))
940 0 : return false;
941 0 : break;
942 :
943 : // Compute the CFA by adding an offset to a register.
944 : case DW_CFA_def_cfa_sf:
945 0 : if (!ParseOperands("rs", &ops) ||
946 0 : !DoDefCFA(ops.register_number,
947 0 : ops.signed_offset * cie->data_alignment_factor))
948 0 : return false;
949 0 : break;
950 :
951 : // Change the base register used to compute the CFA.
952 : case DW_CFA_def_cfa_register: {
953 0 : Rule *cfa_rule = rules_.CFARule();
954 0 : if (!cfa_rule) {
955 0 : reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
956 0 : return false;
957 : }
958 0 : if (!ParseOperands("r", &ops)) return false;
959 0 : cfa_rule->SetBaseRegister(ops.register_number);
960 0 : if (!cfa_rule->Handle(handler_, address_, Handler::kCFARegister))
961 0 : return false;
962 0 : break;
963 : }
964 :
965 : // Change the offset used to compute the CFA.
966 : case DW_CFA_def_cfa_offset:
967 0 : if (!ParseOperands("o", &ops) ||
968 0 : !DoDefCFAOffset(ops.offset))
969 0 : return false;
970 0 : break;
971 :
972 : // Change the offset used to compute the CFA.
973 : case DW_CFA_def_cfa_offset_sf:
974 0 : if (!ParseOperands("s", &ops) ||
975 0 : !DoDefCFAOffset(ops.signed_offset * cie->data_alignment_factor))
976 0 : return false;
977 0 : break;
978 :
979 : // Specify an expression whose value is the CFA.
980 : case DW_CFA_def_cfa_expression: {
981 0 : if (!ParseOperands("e", &ops))
982 0 : return false;
983 0 : Rule *rule = new ValExpressionRule(ops.expression);
984 0 : rules_.SetCFARule(rule);
985 0 : if (!rule->Handle(handler_, address_, Handler::kCFARegister))
986 0 : return false;
987 0 : break;
988 : }
989 :
990 : // The register's value cannot be recovered.
991 : case DW_CFA_undefined: {
992 0 : if (!ParseOperands("r", &ops) ||
993 0 : !DoRule(ops.register_number, new UndefinedRule()))
994 0 : return false;
995 0 : break;
996 : }
997 :
998 : // The register's value is unchanged from its value in the caller.
999 : case DW_CFA_same_value: {
1000 0 : if (!ParseOperands("r", &ops) ||
1001 0 : !DoRule(ops.register_number, new SameValueRule()))
1002 0 : return false;
1003 0 : break;
1004 : }
1005 :
1006 : // Find a register at an offset from the CFA.
1007 : case DW_CFA_offset_extended:
1008 0 : if (!ParseOperands("ro", &ops) ||
1009 0 : !DoOffset(ops.register_number,
1010 0 : ops.offset * cie->data_alignment_factor))
1011 0 : return false;
1012 0 : break;
1013 :
1014 : // The register is saved at an offset from the CFA.
1015 : case DW_CFA_offset_extended_sf:
1016 0 : if (!ParseOperands("rs", &ops) ||
1017 0 : !DoOffset(ops.register_number,
1018 0 : ops.signed_offset * cie->data_alignment_factor))
1019 0 : return false;
1020 0 : break;
1021 :
1022 : // The register is saved at an offset from the CFA.
1023 : case DW_CFA_GNU_negative_offset_extended:
1024 0 : if (!ParseOperands("ro", &ops) ||
1025 0 : !DoOffset(ops.register_number,
1026 0 : -ops.offset * cie->data_alignment_factor))
1027 0 : return false;
1028 0 : break;
1029 :
1030 : // The register's value is the sum of the CFA plus an offset.
1031 : case DW_CFA_val_offset:
1032 0 : if (!ParseOperands("ro", &ops) ||
1033 0 : !DoValOffset(ops.register_number,
1034 0 : ops.offset * cie->data_alignment_factor))
1035 0 : return false;
1036 0 : break;
1037 :
1038 : // The register's value is the sum of the CFA plus an offset.
1039 : case DW_CFA_val_offset_sf:
1040 0 : if (!ParseOperands("rs", &ops) ||
1041 0 : !DoValOffset(ops.register_number,
1042 0 : ops.signed_offset * cie->data_alignment_factor))
1043 0 : return false;
1044 0 : break;
1045 :
1046 : // The register has been saved in another register.
1047 : case DW_CFA_register: {
1048 0 : if (!ParseOperands("ro", &ops) ||
1049 0 : !DoRule(ops.register_number, new RegisterRule(ops.offset)))
1050 0 : return false;
1051 0 : break;
1052 : }
1053 :
1054 : // An expression yields the address at which the register is saved.
1055 : case DW_CFA_expression: {
1056 0 : if (!ParseOperands("re", &ops) ||
1057 0 : !DoRule(ops.register_number, new ExpressionRule(ops.expression)))
1058 0 : return false;
1059 0 : break;
1060 : }
1061 :
1062 : // An expression yields the caller's value for the register.
1063 : case DW_CFA_val_expression: {
1064 0 : if (!ParseOperands("re", &ops) ||
1065 0 : !DoRule(ops.register_number, new ValExpressionRule(ops.expression)))
1066 0 : return false;
1067 0 : break;
1068 : }
1069 :
1070 : // Restore the rule established for a register by the CIE.
1071 : case DW_CFA_restore_extended:
1072 0 : if (!ParseOperands("r", &ops) ||
1073 0 : !DoRestore( ops.register_number))
1074 0 : return false;
1075 0 : break;
1076 :
1077 : // Save the current set of rules on a stack.
1078 : case DW_CFA_remember_state:
1079 0 : if (!saved_rules_) {
1080 0 : saved_rules_ = new std::stack<RuleMap>();
1081 : }
1082 0 : saved_rules_->push(rules_);
1083 0 : break;
1084 :
1085 : // Pop the current set of rules off the stack.
1086 : case DW_CFA_restore_state: {
1087 0 : if (!saved_rules_ || saved_rules_->empty()) {
1088 0 : reporter_->EmptyStateStack(entry_->offset, entry_->kind,
1089 0 : CursorOffset());
1090 0 : return false;
1091 : }
1092 0 : const RuleMap &new_rules = saved_rules_->top();
1093 0 : if (rules_.CFARule() && !new_rules.CFARule()) {
1094 0 : reporter_->ClearingCFARule(entry_->offset, entry_->kind,
1095 0 : CursorOffset());
1096 0 : return false;
1097 : }
1098 0 : rules_.HandleTransitionTo(handler_, address_, new_rules);
1099 0 : rules_ = new_rules;
1100 0 : saved_rules_->pop();
1101 0 : break;
1102 : }
1103 :
1104 : // No operation. (Padding instruction.)
1105 : case DW_CFA_nop:
1106 0 : break;
1107 :
1108 : // A SPARC register window save: Registers 8 through 15 (%o0-%o7)
1109 : // are saved in registers 24 through 31 (%i0-%i7), and registers
1110 : // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets
1111 : // (0-15 * the register size). The register numbers must be
1112 : // hard-coded. A GNU extension, and not a pretty one.
1113 : case DW_CFA_GNU_window_save: {
1114 : // Save %o0-%o7 in %i0-%i7.
1115 0 : for (int i = 8; i < 16; i++)
1116 0 : if (!DoRule(i, new RegisterRule(i + 16)))
1117 0 : return false;
1118 : // Save %l0-%l7 and %i0-%i7 at the CFA.
1119 0 : for (int i = 16; i < 32; i++)
1120 : // Assume that the byte reader's address size is the same as
1121 : // the architecture's register size. !@#%*^ hilarious.
1122 0 : if (!DoRule(i, new OffsetRule(Handler::kCFARegister,
1123 0 : (i - 16) * reader_->AddressSize())))
1124 0 : return false;
1125 0 : break;
1126 : }
1127 :
1128 : // I'm not sure what this is. GDB doesn't use it for unwinding.
1129 : case DW_CFA_GNU_args_size:
1130 0 : if (!ParseOperands("o", &ops)) return false;
1131 0 : break;
1132 :
1133 : // An opcode we don't recognize.
1134 : default: {
1135 0 : reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset());
1136 0 : return false;
1137 : }
1138 : }
1139 :
1140 0 : return true;
1141 : }
1142 :
1143 0 : bool CallFrameInfo::State::DoDefCFA(unsigned base_register, long offset) {
1144 0 : Rule *rule = new ValOffsetRule(base_register, offset);
1145 0 : rules_.SetCFARule(rule);
1146 0 : return rule->Handle(handler_, address_, Handler::kCFARegister);
1147 : }
1148 :
1149 0 : bool CallFrameInfo::State::DoDefCFAOffset(long offset) {
1150 0 : Rule *cfa_rule = rules_.CFARule();
1151 0 : if (!cfa_rule) {
1152 0 : reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
1153 0 : return false;
1154 : }
1155 0 : cfa_rule->SetOffset(offset);
1156 0 : return cfa_rule->Handle(handler_, address_, Handler::kCFARegister);
1157 : }
1158 :
1159 0 : bool CallFrameInfo::State::DoRule(unsigned reg, Rule *rule) {
1160 0 : rules_.SetRegisterRule(reg, rule);
1161 0 : return rule->Handle(handler_, address_, reg);
1162 : }
1163 :
1164 0 : bool CallFrameInfo::State::DoOffset(unsigned reg, long offset) {
1165 0 : if (!rules_.CFARule()) {
1166 0 : reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
1167 0 : return false;
1168 : }
1169 : return DoRule(reg,
1170 0 : new OffsetRule(Handler::kCFARegister, offset));
1171 : }
1172 :
1173 0 : bool CallFrameInfo::State::DoValOffset(unsigned reg, long offset) {
1174 0 : if (!rules_.CFARule()) {
1175 0 : reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
1176 0 : return false;
1177 : }
1178 : return DoRule(reg,
1179 0 : new ValOffsetRule(Handler::kCFARegister, offset));
1180 : }
1181 :
1182 0 : bool CallFrameInfo::State::DoRestore(unsigned reg) {
1183 : // DW_CFA_restore and DW_CFA_restore_extended don't make sense in a CIE.
1184 0 : if (entry_->kind == kCIE) {
1185 0 : reporter_->RestoreInCIE(entry_->offset, CursorOffset());
1186 0 : return false;
1187 : }
1188 0 : Rule *rule = cie_rules_.RegisterRule(reg);
1189 0 : if (!rule) {
1190 : // This isn't really the right thing to do, but since CFI generally
1191 : // only mentions callee-saves registers, and GCC's convention for
1192 : // callee-saves registers is that they are unchanged, it's a good
1193 : // approximation.
1194 0 : rule = new SameValueRule();
1195 : }
1196 0 : return DoRule(reg, rule);
1197 : }
1198 :
1199 0 : bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) {
1200 0 : const char *buffer_end = buffer_ + buffer_length_;
1201 :
1202 : // Initialize enough of ENTRY for use in error reporting.
1203 0 : entry->offset = cursor - buffer_;
1204 0 : entry->start = cursor;
1205 0 : entry->kind = kUnknown;
1206 0 : entry->end = NULL;
1207 :
1208 : // Read the initial length. This sets reader_'s offset size.
1209 : size_t length_size;
1210 0 : uint64 length = reader_->ReadInitialLength(cursor, &length_size);
1211 0 : if (length_size > size_t(buffer_end - cursor))
1212 0 : return ReportIncomplete(entry);
1213 0 : cursor += length_size;
1214 :
1215 : // In a .eh_frame section, a length of zero marks the end of the series
1216 : // of entries.
1217 0 : if (length == 0 && eh_frame_) {
1218 0 : entry->kind = kTerminator;
1219 0 : entry->end = cursor;
1220 0 : return true;
1221 : }
1222 :
1223 : // Validate the length.
1224 0 : if (length > size_t(buffer_end - cursor))
1225 0 : return ReportIncomplete(entry);
1226 :
1227 : // The length is the number of bytes after the initial length field;
1228 : // we have that position handy at this point, so compute the end
1229 : // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine,
1230 : // and the length didn't fit in a size_t, we would have rejected it
1231 : // above.)
1232 0 : entry->end = cursor + length;
1233 :
1234 : // Parse the next field: either the offset of a CIE or a CIE id.
1235 0 : size_t offset_size = reader_->OffsetSize();
1236 0 : if (offset_size > size_t(entry->end - cursor)) return ReportIncomplete(entry);
1237 0 : entry->id = reader_->ReadOffset(cursor);
1238 :
1239 : // Don't advance cursor past id field yet; in .eh_frame data we need
1240 : // the id's position to compute the section offset of an FDE's CIE.
1241 :
1242 : // Now we can decide what kind of entry this is.
1243 0 : if (eh_frame_) {
1244 : // In .eh_frame data, an ID of zero marks the entry as a CIE, and
1245 : // anything else is an offset from the id field of the FDE to the start
1246 : // of the CIE.
1247 0 : if (entry->id == 0) {
1248 0 : entry->kind = kCIE;
1249 : } else {
1250 0 : entry->kind = kFDE;
1251 : // Turn the offset from the id into an offset from the buffer's start.
1252 0 : entry->id = (cursor - buffer_) - entry->id;
1253 : }
1254 : } else {
1255 : // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the
1256 : // offset size for the entry) marks the entry as a CIE, and anything
1257 : // else is the offset of the CIE from the beginning of the section.
1258 0 : if (offset_size == 4)
1259 0 : entry->kind = (entry->id == 0xffffffff) ? kCIE : kFDE;
1260 : else {
1261 0 : MOZ_ASSERT(offset_size == 8);
1262 0 : entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE;
1263 : }
1264 : }
1265 :
1266 : // Now advance cursor past the id.
1267 0 : cursor += offset_size;
1268 :
1269 : // The fields specific to this kind of entry start here.
1270 0 : entry->fields = cursor;
1271 :
1272 0 : entry->cie = NULL;
1273 :
1274 0 : return true;
1275 : }
1276 :
1277 0 : bool CallFrameInfo::ReadCIEFields(CIE *cie) {
1278 0 : const char *cursor = cie->fields;
1279 : size_t len;
1280 :
1281 0 : MOZ_ASSERT(cie->kind == kCIE);
1282 :
1283 : // Prepare for early exit.
1284 0 : cie->version = 0;
1285 0 : cie->augmentation.clear();
1286 0 : cie->code_alignment_factor = 0;
1287 0 : cie->data_alignment_factor = 0;
1288 0 : cie->return_address_register = 0;
1289 0 : cie->has_z_augmentation = false;
1290 0 : cie->pointer_encoding = DW_EH_PE_absptr;
1291 0 : cie->instructions = 0;
1292 :
1293 : // Parse the version number.
1294 0 : if (cie->end - cursor < 1)
1295 0 : return ReportIncomplete(cie);
1296 0 : cie->version = reader_->ReadOneByte(cursor);
1297 0 : cursor++;
1298 :
1299 : // If we don't recognize the version, we can't parse any more fields of the
1300 : // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a
1301 : // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well;
1302 : // the difference between those versions seems to be the same as for
1303 : // .debug_frame.
1304 0 : if (cie->version < 1 || cie->version > 3) {
1305 0 : reporter_->UnrecognizedVersion(cie->offset, cie->version);
1306 0 : return false;
1307 : }
1308 :
1309 0 : const char *augmentation_start = cursor;
1310 : const void *augmentation_end =
1311 0 : memchr(augmentation_start, '\0', cie->end - augmentation_start);
1312 0 : if (! augmentation_end) return ReportIncomplete(cie);
1313 0 : cursor = static_cast<const char *>(augmentation_end);
1314 0 : cie->augmentation = string(augmentation_start,
1315 0 : cursor - augmentation_start);
1316 : // Skip the terminating '\0'.
1317 0 : cursor++;
1318 :
1319 : // Is this CFI augmented?
1320 0 : if (!cie->augmentation.empty()) {
1321 : // Is it an augmentation we recognize?
1322 0 : if (cie->augmentation[0] == DW_Z_augmentation_start) {
1323 : // Linux C++ ABI 'z' augmentation, used for exception handling data.
1324 0 : cie->has_z_augmentation = true;
1325 : } else {
1326 : // Not an augmentation we recognize. Augmentations can have arbitrary
1327 : // effects on the form of rest of the content, so we have to give up.
1328 0 : reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
1329 0 : return false;
1330 : }
1331 : }
1332 :
1333 : // Parse the code alignment factor.
1334 0 : cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
1335 0 : if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1336 0 : cursor += len;
1337 :
1338 : // Parse the data alignment factor.
1339 0 : cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
1340 0 : if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1341 0 : cursor += len;
1342 :
1343 : // Parse the return address register. This is a ubyte in version 1, and
1344 : // a ULEB128 in version 3.
1345 0 : if (cie->version == 1) {
1346 0 : if (cursor >= cie->end) return ReportIncomplete(cie);
1347 0 : cie->return_address_register = uint8(*cursor++);
1348 : } else {
1349 0 : cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len);
1350 0 : if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1351 0 : cursor += len;
1352 : }
1353 :
1354 : // If we have a 'z' augmentation string, find the augmentation data and
1355 : // use the augmentation string to parse it.
1356 0 : if (cie->has_z_augmentation) {
1357 0 : uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len);
1358 0 : if (size_t(cie->end - cursor) < len + data_size)
1359 0 : return ReportIncomplete(cie);
1360 0 : cursor += len;
1361 0 : const char *data = cursor;
1362 0 : cursor += data_size;
1363 0 : const char *data_end = cursor;
1364 :
1365 0 : cie->has_z_lsda = false;
1366 0 : cie->has_z_personality = false;
1367 0 : cie->has_z_signal_frame = false;
1368 :
1369 : // Walk the augmentation string, and extract values from the
1370 : // augmentation data as the string directs.
1371 0 : for (size_t i = 1; i < cie->augmentation.size(); i++) {
1372 0 : switch (cie->augmentation[i]) {
1373 : case DW_Z_has_LSDA:
1374 : // The CIE's augmentation data holds the language-specific data
1375 : // area pointer's encoding, and the FDE's augmentation data holds
1376 : // the pointer itself.
1377 0 : cie->has_z_lsda = true;
1378 : // Fetch the LSDA encoding from the augmentation data.
1379 0 : if (data >= data_end) return ReportIncomplete(cie);
1380 0 : cie->lsda_encoding = DwarfPointerEncoding(*data++);
1381 0 : if (!reader_->ValidEncoding(cie->lsda_encoding)) {
1382 0 : reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding);
1383 0 : return false;
1384 : }
1385 : // Don't check if the encoding is usable here --- we haven't
1386 : // read the FDE's fields yet, so we're not prepared for
1387 : // DW_EH_PE_funcrel, although that's a fine encoding for the
1388 : // LSDA to use, since it appears in the FDE.
1389 0 : break;
1390 :
1391 : case DW_Z_has_personality_routine:
1392 : // The CIE's augmentation data holds the personality routine
1393 : // pointer's encoding, followed by the pointer itself.
1394 0 : cie->has_z_personality = true;
1395 : // Fetch the personality routine pointer's encoding from the
1396 : // augmentation data.
1397 0 : if (data >= data_end) return ReportIncomplete(cie);
1398 0 : cie->personality_encoding = DwarfPointerEncoding(*data++);
1399 0 : if (!reader_->ValidEncoding(cie->personality_encoding)) {
1400 0 : reporter_->InvalidPointerEncoding(cie->offset,
1401 0 : cie->personality_encoding);
1402 0 : return false;
1403 : }
1404 0 : if (!reader_->UsableEncoding(cie->personality_encoding)) {
1405 0 : reporter_->UnusablePointerEncoding(cie->offset,
1406 0 : cie->personality_encoding);
1407 0 : return false;
1408 : }
1409 : // Fetch the personality routine's pointer itself from the data.
1410 0 : cie->personality_address =
1411 0 : reader_->ReadEncodedPointer(data, cie->personality_encoding,
1412 : &len);
1413 0 : if (len > size_t(data_end - data))
1414 0 : return ReportIncomplete(cie);
1415 0 : data += len;
1416 0 : break;
1417 :
1418 : case DW_Z_has_FDE_address_encoding:
1419 : // The CIE's augmentation data holds the pointer encoding to use
1420 : // for addresses in the FDE.
1421 0 : if (data >= data_end) return ReportIncomplete(cie);
1422 0 : cie->pointer_encoding = DwarfPointerEncoding(*data++);
1423 0 : if (!reader_->ValidEncoding(cie->pointer_encoding)) {
1424 0 : reporter_->InvalidPointerEncoding(cie->offset,
1425 0 : cie->pointer_encoding);
1426 0 : return false;
1427 : }
1428 0 : if (!reader_->UsableEncoding(cie->pointer_encoding)) {
1429 0 : reporter_->UnusablePointerEncoding(cie->offset,
1430 0 : cie->pointer_encoding);
1431 0 : return false;
1432 : }
1433 0 : break;
1434 :
1435 : case DW_Z_is_signal_trampoline:
1436 : // Frames using this CIE are signal delivery frames.
1437 0 : cie->has_z_signal_frame = true;
1438 0 : break;
1439 :
1440 : default:
1441 : // An augmentation we don't recognize.
1442 0 : reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
1443 0 : return false;
1444 : }
1445 : }
1446 : }
1447 :
1448 : // The CIE's instructions start here.
1449 0 : cie->instructions = cursor;
1450 :
1451 0 : return true;
1452 : }
1453 :
1454 0 : bool CallFrameInfo::ReadFDEFields(FDE *fde) {
1455 0 : const char *cursor = fde->fields;
1456 : size_t size;
1457 :
1458 0 : fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
1459 : &size);
1460 0 : if (size > size_t(fde->end - cursor))
1461 0 : return ReportIncomplete(fde);
1462 0 : cursor += size;
1463 0 : reader_->SetFunctionBase(fde->address);
1464 :
1465 : // For the length, we strip off the upper nybble of the encoding used for
1466 : // the starting address.
1467 : DwarfPointerEncoding length_encoding =
1468 0 : DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f);
1469 0 : fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size);
1470 0 : if (size > size_t(fde->end - cursor))
1471 0 : return ReportIncomplete(fde);
1472 0 : cursor += size;
1473 :
1474 : // If the CIE has a 'z' augmentation string, then augmentation data
1475 : // appears here.
1476 0 : if (fde->cie->has_z_augmentation) {
1477 0 : uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size);
1478 0 : if (size_t(fde->end - cursor) < size + data_size)
1479 0 : return ReportIncomplete(fde);
1480 0 : cursor += size;
1481 :
1482 : // In the abstract, we should walk the augmentation string, and extract
1483 : // items from the FDE's augmentation data as we encounter augmentation
1484 : // string characters that specify their presence: the ordering of items
1485 : // in the augmentation string determines the arrangement of values in
1486 : // the augmentation data.
1487 : //
1488 : // In practice, there's only ever one value in FDE augmentation data
1489 : // that we support --- the LSDA pointer --- and we have to bail if we
1490 : // see any unrecognized augmentation string characters. So if there is
1491 : // anything here at all, we know what it is, and where it starts.
1492 0 : if (fde->cie->has_z_lsda) {
1493 : // Check whether the LSDA's pointer encoding is usable now: only once
1494 : // we've parsed the FDE's starting address do we call reader_->
1495 : // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes
1496 : // usable.
1497 0 : if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) {
1498 0 : reporter_->UnusablePointerEncoding(fde->cie->offset,
1499 0 : fde->cie->lsda_encoding);
1500 0 : return false;
1501 : }
1502 :
1503 0 : fde->lsda_address =
1504 0 : reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size);
1505 0 : if (size > data_size)
1506 0 : return ReportIncomplete(fde);
1507 : // Ideally, we would also complain here if there were unconsumed
1508 : // augmentation data.
1509 : }
1510 :
1511 0 : cursor += data_size;
1512 : }
1513 :
1514 : // The FDE's instructions start after those.
1515 0 : fde->instructions = cursor;
1516 :
1517 0 : return true;
1518 : }
1519 :
1520 0 : bool CallFrameInfo::Start() {
1521 0 : const char *buffer_end = buffer_ + buffer_length_;
1522 : const char *cursor;
1523 0 : bool all_ok = true;
1524 : const char *entry_end;
1525 : bool ok;
1526 :
1527 : // Traverse all the entries in buffer_, skipping CIEs and offering
1528 : // FDEs to the handler.
1529 0 : for (cursor = buffer_; cursor < buffer_end;
1530 0 : cursor = entry_end, all_ok = all_ok && ok) {
1531 : FDE fde;
1532 :
1533 : // Make it easy to skip this entry with 'continue': assume that
1534 : // things are not okay until we've checked all the data, and
1535 : // prepare the address of the next entry.
1536 0 : ok = false;
1537 :
1538 : // Read the entry's prologue.
1539 0 : if (!ReadEntryPrologue(cursor, &fde)) {
1540 0 : if (!fde.end) {
1541 : // If we couldn't even figure out this entry's extent, then we
1542 : // must stop processing entries altogether.
1543 0 : all_ok = false;
1544 0 : break;
1545 : }
1546 0 : entry_end = fde.end;
1547 0 : continue;
1548 : }
1549 :
1550 : // The next iteration picks up after this entry.
1551 0 : entry_end = fde.end;
1552 :
1553 : // Did we see an .eh_frame terminating mark?
1554 0 : if (fde.kind == kTerminator) {
1555 : // If there appears to be more data left in the section after the
1556 : // terminating mark, warn the user. But this is just a warning;
1557 : // we leave all_ok true.
1558 0 : if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset);
1559 0 : break;
1560 : }
1561 :
1562 : // In this loop, we skip CIEs. We only parse them fully when we
1563 : // parse an FDE that refers to them. This limits our memory
1564 : // consumption (beyond the buffer itself) to that needed to
1565 : // process the largest single entry.
1566 0 : if (fde.kind != kFDE) {
1567 0 : ok = true;
1568 0 : continue;
1569 : }
1570 :
1571 : // Validate the CIE pointer.
1572 0 : if (fde.id > buffer_length_) {
1573 0 : reporter_->CIEPointerOutOfRange(fde.offset, fde.id);
1574 0 : continue;
1575 : }
1576 :
1577 0 : CIE cie;
1578 :
1579 : // Parse this FDE's CIE header.
1580 0 : if (!ReadEntryPrologue(buffer_ + fde.id, &cie))
1581 0 : continue;
1582 : // This had better be an actual CIE.
1583 0 : if (cie.kind != kCIE) {
1584 0 : reporter_->BadCIEId(fde.offset, fde.id);
1585 0 : continue;
1586 : }
1587 0 : if (!ReadCIEFields(&cie))
1588 0 : continue;
1589 :
1590 : // We now have the values that govern both the CIE and the FDE.
1591 0 : cie.cie = &cie;
1592 0 : fde.cie = &cie;
1593 :
1594 : // Parse the FDE's header.
1595 0 : if (!ReadFDEFields(&fde))
1596 0 : continue;
1597 :
1598 : // Call Entry to ask the consumer if they're interested.
1599 0 : if (!handler_->Entry(fde.offset, fde.address, fde.size,
1600 0 : cie.version, cie.augmentation,
1601 0 : cie.return_address_register)) {
1602 : // The handler isn't interested in this entry. That's not an error.
1603 0 : ok = true;
1604 0 : continue;
1605 : }
1606 :
1607 0 : if (cie.has_z_augmentation) {
1608 : // Report the personality routine address, if we have one.
1609 0 : if (cie.has_z_personality) {
1610 0 : if (!handler_
1611 0 : ->PersonalityRoutine(cie.personality_address,
1612 0 : IsIndirectEncoding(cie.personality_encoding)))
1613 0 : continue;
1614 : }
1615 :
1616 : // Report the language-specific data area address, if we have one.
1617 0 : if (cie.has_z_lsda) {
1618 0 : if (!handler_
1619 0 : ->LanguageSpecificDataArea(fde.lsda_address,
1620 0 : IsIndirectEncoding(cie.lsda_encoding)))
1621 0 : continue;
1622 : }
1623 :
1624 : // If this is a signal-handling frame, report that.
1625 0 : if (cie.has_z_signal_frame) {
1626 0 : if (!handler_->SignalHandler())
1627 0 : continue;
1628 : }
1629 : }
1630 :
1631 : // Interpret the CIE's instructions, and then the FDE's instructions.
1632 0 : State state(reader_, handler_, reporter_, fde.address);
1633 0 : ok = state.InterpretCIE(cie) && state.InterpretFDE(fde);
1634 :
1635 : // Tell the ByteReader that the function start address from the
1636 : // FDE header is no longer valid.
1637 0 : reader_->ClearFunctionBase();
1638 :
1639 : // Report the end of the entry.
1640 0 : handler_->End();
1641 : }
1642 :
1643 0 : return all_ok;
1644 : }
1645 :
1646 0 : const char *CallFrameInfo::KindName(EntryKind kind) {
1647 0 : if (kind == CallFrameInfo::kUnknown)
1648 0 : return "entry";
1649 0 : else if (kind == CallFrameInfo::kCIE)
1650 0 : return "common information entry";
1651 0 : else if (kind == CallFrameInfo::kFDE)
1652 0 : return "frame description entry";
1653 : else {
1654 0 : MOZ_ASSERT (kind == CallFrameInfo::kTerminator);
1655 0 : return ".eh_frame sequence terminator";
1656 : }
1657 : }
1658 :
1659 0 : bool CallFrameInfo::ReportIncomplete(Entry *entry) {
1660 0 : reporter_->Incomplete(entry->offset, entry->kind);
1661 0 : return false;
1662 : }
1663 :
1664 0 : void CallFrameInfo::Reporter::Incomplete(uint64 offset,
1665 : CallFrameInfo::EntryKind kind) {
1666 : char buf[300];
1667 0 : SprintfLiteral(buf,
1668 : "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
1669 : filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1670 0 : section_.c_str());
1671 0 : log_(buf);
1672 0 : }
1673 :
1674 0 : void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) {
1675 : char buf[300];
1676 0 : SprintfLiteral(buf,
1677 : "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
1678 : " before end of section contents\n",
1679 0 : filename_.c_str(), offset, section_.c_str());
1680 0 : log_(buf);
1681 0 : }
1682 :
1683 0 : void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset,
1684 : uint64 cie_offset) {
1685 : char buf[300];
1686 0 : SprintfLiteral(buf,
1687 : "%s: CFI frame description entry at offset 0x%llx in '%s':"
1688 : " CIE pointer is out of range: 0x%llx\n",
1689 0 : filename_.c_str(), offset, section_.c_str(), cie_offset);
1690 0 : log_(buf);
1691 0 : }
1692 :
1693 0 : void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
1694 : char buf[300];
1695 0 : SprintfLiteral(buf,
1696 : "%s: CFI frame description entry at offset 0x%llx in '%s':"
1697 : " CIE pointer does not point to a CIE: 0x%llx\n",
1698 0 : filename_.c_str(), offset, section_.c_str(), cie_offset);
1699 0 : log_(buf);
1700 0 : }
1701 :
1702 0 : void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
1703 : char buf[300];
1704 0 : SprintfLiteral(buf,
1705 : "%s: CFI frame description entry at offset 0x%llx in '%s':"
1706 : " CIE specifies unrecognized version: %d\n",
1707 0 : filename_.c_str(), offset, section_.c_str(), version);
1708 0 : log_(buf);
1709 0 : }
1710 :
1711 0 : void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
1712 : const string &aug) {
1713 : char buf[300];
1714 0 : SprintfLiteral(buf,
1715 : "%s: CFI frame description entry at offset 0x%llx in '%s':"
1716 : " CIE specifies unrecognized augmentation: '%s'\n",
1717 0 : filename_.c_str(), offset, section_.c_str(), aug.c_str());
1718 0 : log_(buf);
1719 0 : }
1720 :
1721 0 : void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset,
1722 : uint8 encoding) {
1723 : char buf[300];
1724 0 : SprintfLiteral(buf,
1725 : "%s: CFI common information entry at offset 0x%llx in '%s':"
1726 : " 'z' augmentation specifies invalid pointer encoding: "
1727 : "0x%02x\n",
1728 0 : filename_.c_str(), offset, section_.c_str(), encoding);
1729 0 : log_(buf);
1730 0 : }
1731 :
1732 0 : void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset,
1733 : uint8 encoding) {
1734 : char buf[300];
1735 0 : SprintfLiteral(buf,
1736 : "%s: CFI common information entry at offset 0x%llx in '%s':"
1737 : " 'z' augmentation specifies a pointer encoding for which"
1738 : " we have no base address: 0x%02x\n",
1739 0 : filename_.c_str(), offset, section_.c_str(), encoding);
1740 0 : log_(buf);
1741 0 : }
1742 :
1743 0 : void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) {
1744 : char buf[300];
1745 0 : SprintfLiteral(buf,
1746 : "%s: CFI common information entry at offset 0x%llx in '%s':"
1747 : " the DW_CFA_restore instruction at offset 0x%llx"
1748 : " cannot be used in a common information entry\n",
1749 0 : filename_.c_str(), offset, section_.c_str(), insn_offset);
1750 0 : log_(buf);
1751 0 : }
1752 :
1753 0 : void CallFrameInfo::Reporter::BadInstruction(uint64 offset,
1754 : CallFrameInfo::EntryKind kind,
1755 : uint64 insn_offset) {
1756 : char buf[300];
1757 0 : SprintfLiteral(buf,
1758 : "%s: CFI %s at offset 0x%llx in section '%s':"
1759 : " the instruction at offset 0x%llx is unrecognized\n",
1760 : filename_.c_str(), CallFrameInfo::KindName(kind),
1761 0 : offset, section_.c_str(), insn_offset);
1762 0 : log_(buf);
1763 0 : }
1764 :
1765 0 : void CallFrameInfo::Reporter::NoCFARule(uint64 offset,
1766 : CallFrameInfo::EntryKind kind,
1767 : uint64 insn_offset) {
1768 : char buf[300];
1769 0 : SprintfLiteral(buf,
1770 : "%s: CFI %s at offset 0x%llx in section '%s':"
1771 : " the instruction at offset 0x%llx assumes that a CFA rule "
1772 : "has been set, but none has been set\n",
1773 : filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1774 0 : section_.c_str(), insn_offset);
1775 0 : log_(buf);
1776 0 : }
1777 :
1778 0 : void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset,
1779 : CallFrameInfo::EntryKind kind,
1780 : uint64 insn_offset) {
1781 : char buf[300];
1782 0 : SprintfLiteral(buf,
1783 : "%s: CFI %s at offset 0x%llx in section '%s':"
1784 : " the DW_CFA_restore_state instruction at offset 0x%llx"
1785 : " should pop a saved state from the stack, but the stack "
1786 : "is empty\n",
1787 : filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1788 0 : section_.c_str(), insn_offset);
1789 0 : log_(buf);
1790 0 : }
1791 :
1792 0 : void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset,
1793 : CallFrameInfo::EntryKind kind,
1794 : uint64 insn_offset) {
1795 : char buf[300];
1796 0 : SprintfLiteral(buf,
1797 : "%s: CFI %s at offset 0x%llx in section '%s':"
1798 : " the DW_CFA_restore_state instruction at offset 0x%llx"
1799 : " would clear the CFA rule in effect\n",
1800 : filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1801 0 : section_.c_str(), insn_offset);
1802 0 : log_(buf);
1803 0 : }
1804 :
1805 :
1806 0 : unsigned int DwarfCFIToModule::RegisterNames::I386() {
1807 : /*
1808 : 8 "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
1809 : 3 "$eip", "$eflags", "$unused1",
1810 : 8 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
1811 : 2 "$unused2", "$unused3",
1812 : 8 "$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
1813 : 8 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
1814 : 3 "$fcw", "$fsw", "$mxcsr",
1815 : 8 "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5",
1816 : 2 "$tr", "$ldtr"
1817 : */
1818 0 : return 8 + 3 + 8 + 2 + 8 + 8 + 3 + 8 + 2;
1819 : }
1820 :
1821 0 : unsigned int DwarfCFIToModule::RegisterNames::X86_64() {
1822 : /*
1823 : 8 "$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp",
1824 : 8 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
1825 : 1 "$rip",
1826 : 8 "$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
1827 : 8 "$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15",
1828 : 8 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
1829 : 8 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
1830 : 1 "$rflags",
1831 : 8 "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2",
1832 : 4 "$fs.base", "$gs.base", "$unused3", "$unused4",
1833 : 2 "$tr", "$ldtr",
1834 : 3 "$mxcsr", "$fcw", "$fsw"
1835 : */
1836 0 : return 8 + 8 + 1 + 8 + 8 + 8 + 8 + 1 + 8 + 4 + 2 + 3;
1837 : }
1838 :
1839 : // Per ARM IHI 0040A, section 3.1
1840 0 : unsigned int DwarfCFIToModule::RegisterNames::ARM() {
1841 : /*
1842 : 8 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1843 : 8 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
1844 : 8 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1845 : 8 "fps", "cpsr", "", "", "", "", "", "",
1846 : 8 "", "", "", "", "", "", "", "",
1847 : 8 "", "", "", "", "", "", "", "",
1848 : 8 "", "", "", "", "", "", "", "",
1849 : 8 "", "", "", "", "", "", "", "",
1850 : 8 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1851 : 8 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
1852 : 8 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
1853 : 8 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1854 : 8 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"
1855 : */
1856 0 : return 13 * 8;
1857 : }
1858 :
1859 : // See prototype for comments.
1860 0 : int32_t parseDwarfExpr(Summariser* summ, const ByteReader* reader,
1861 : string expr, bool debug,
1862 : bool pushCfaAtStart, bool derefAtEnd)
1863 : {
1864 0 : const char* cursor = expr.c_str();
1865 0 : const char* end1 = cursor + expr.length();
1866 :
1867 : char buf[100];
1868 0 : if (debug) {
1869 0 : SprintfLiteral(buf, "LUL.DW << DwarfExpr, len is %d\n",
1870 0 : (int)(end1 - cursor));
1871 0 : summ->Log(buf);
1872 : }
1873 :
1874 : // Add a marker for the start of this expression. In it, indicate
1875 : // whether or not the CFA should be pushed onto the stack prior to
1876 : // evaluation.
1877 : int32_t start_ix
1878 0 : = summ->AddPfxInstr(PfxInstr(PX_Start, pushCfaAtStart ? 1 : 0));
1879 0 : MOZ_ASSERT(start_ix >= 0);
1880 :
1881 0 : while (cursor < end1) {
1882 :
1883 0 : uint8 opc = reader->ReadOneByte(cursor);
1884 0 : cursor++;
1885 :
1886 0 : const char* nm = nullptr;
1887 0 : PfxExprOp pxop = PX_End;
1888 :
1889 0 : switch (opc) {
1890 :
1891 : case DW_OP_lit0 ... DW_OP_lit31: {
1892 0 : int32_t simm32 = (int32_t)(opc - DW_OP_lit0);
1893 0 : if (debug) {
1894 0 : SprintfLiteral(buf, "LUL.DW DW_OP_lit%d\n", (int)simm32);
1895 0 : summ->Log(buf);
1896 : }
1897 0 : (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, simm32));
1898 0 : break;
1899 : }
1900 :
1901 : case DW_OP_breg0 ... DW_OP_breg31: {
1902 : size_t len;
1903 0 : int64_t n = reader->ReadSignedLEB128(cursor, &len);
1904 0 : cursor += len;
1905 0 : DW_REG_NUMBER reg = (DW_REG_NUMBER)(opc - DW_OP_breg0);
1906 0 : if (debug) {
1907 : SprintfLiteral(buf, "LUL.DW DW_OP_breg%d %lld\n",
1908 0 : (int)reg, (long long int)n);
1909 0 : summ->Log(buf);
1910 : }
1911 : // PfxInstr only allows a 32 bit signed offset. So we
1912 : // must fail if the immediate is out of range.
1913 0 : if (n < INT32_MIN || INT32_MAX < n)
1914 : goto fail;
1915 0 : (void) summ->AddPfxInstr(PfxInstr(PX_DwReg, reg));
1916 0 : (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, (int32_t)n));
1917 0 : (void) summ->AddPfxInstr(PfxInstr(PX_Add));
1918 0 : break;
1919 : }
1920 :
1921 : case DW_OP_const4s: {
1922 0 : uint64_t u64 = reader->ReadFourBytes(cursor);
1923 0 : cursor += 4;
1924 : // u64 is guaranteed by |ReadFourBytes| to be in the
1925 : // range 0 .. FFFFFFFF inclusive. But to be safe:
1926 0 : uint32_t u32 = (uint32_t)(u64 & 0xFFFFFFFF);
1927 0 : int32_t s32 = (int32_t)u32;
1928 0 : if (debug) {
1929 0 : SprintfLiteral(buf, "LUL.DW DW_OP_const4s %d\n", (int)s32);
1930 0 : summ->Log(buf);
1931 : }
1932 0 : (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, s32));
1933 0 : break;
1934 : }
1935 :
1936 0 : case DW_OP_deref: nm = "deref"; pxop = PX_Deref; goto no_operands;
1937 0 : case DW_OP_and: nm = "and"; pxop = PX_And; goto no_operands;
1938 0 : case DW_OP_plus: nm = "plus"; pxop = PX_Add; goto no_operands;
1939 0 : case DW_OP_minus: nm = "minus"; pxop = PX_Sub; goto no_operands;
1940 0 : case DW_OP_shl: nm = "shl"; pxop = PX_Shl; goto no_operands;
1941 0 : case DW_OP_ge: nm = "ge"; pxop = PX_CmpGES; goto no_operands;
1942 : no_operands:
1943 0 : MOZ_ASSERT(nm && pxop != PX_End);
1944 0 : if (debug) {
1945 0 : SprintfLiteral(buf, "LUL.DW DW_OP_%s\n", nm);
1946 0 : summ->Log(buf);
1947 : }
1948 0 : (void) summ->AddPfxInstr(PfxInstr(pxop));
1949 0 : break;
1950 :
1951 : default:
1952 0 : if (debug) {
1953 0 : SprintfLiteral(buf, "LUL.DW unknown opc %d\n", (int)opc);
1954 0 : summ->Log(buf);
1955 : }
1956 0 : goto fail;
1957 :
1958 : } // switch (opc)
1959 :
1960 : } // while (cursor < end1)
1961 :
1962 0 : MOZ_ASSERT(cursor >= end1);
1963 :
1964 0 : if (cursor > end1) {
1965 : // We overran the Dwarf expression. Give up.
1966 0 : goto fail;
1967 : }
1968 :
1969 : // For DW_CFA_expression, what the expression denotes is the address
1970 : // of where the previous value is located. The caller of this routine
1971 : // may therefore request one last dereference before the end marker is
1972 : // inserted.
1973 0 : if (derefAtEnd) {
1974 0 : (void) summ->AddPfxInstr(PfxInstr(PX_Deref));
1975 : }
1976 :
1977 : // Insert an end marker, and declare success.
1978 0 : (void) summ->AddPfxInstr(PfxInstr(PX_End));
1979 0 : if (debug) {
1980 : SprintfLiteral(buf, "LUL.DW conversion of dwarf expression succeeded, "
1981 0 : "ix = %d\n", (int)start_ix);
1982 0 : summ->Log(buf);
1983 0 : summ->Log("LUL.DW >>\n");
1984 : }
1985 0 : return start_ix;
1986 :
1987 : fail:
1988 0 : if (debug) {
1989 0 : summ->Log("LUL.DW conversion of dwarf expression failed\n");
1990 0 : summ->Log("LUL.DW >>\n");
1991 : }
1992 0 : return -1;
1993 : }
1994 :
1995 :
1996 0 : bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length,
1997 : uint8 version, const string &augmentation,
1998 : unsigned return_address) {
1999 : if (DEBUG_DWARF) {
2000 : char buf[100];
2001 : SprintfLiteral(buf, "LUL.DW DwarfCFIToModule::Entry 0x%llx,+%lld\n",
2002 : address, length);
2003 : summ_->Log(buf);
2004 : }
2005 :
2006 0 : summ_->Entry(address, length);
2007 :
2008 : // If dwarf2reader::CallFrameInfo can handle this version and
2009 : // augmentation, then we should be okay with that, so there's no
2010 : // need to check them here.
2011 :
2012 : // Get ready to collect entries.
2013 0 : return_address_ = return_address;
2014 :
2015 : // Breakpad STACK CFI records must provide a .ra rule, but DWARF CFI
2016 : // may not establish any rule for .ra if the return address column
2017 : // is an ordinary register, and that register holds the return
2018 : // address on entry to the function. So establish an initial .ra
2019 : // rule citing the return address register.
2020 0 : if (return_address_ < num_dw_regs_) {
2021 0 : summ_->Rule(address, return_address_, NODEREF, return_address, 0);
2022 : }
2023 :
2024 0 : return true;
2025 : }
2026 :
2027 0 : const UniqueString* DwarfCFIToModule::RegisterName(int i) {
2028 0 : if (i < 0) {
2029 0 : MOZ_ASSERT(i == kCFARegister);
2030 0 : return usu_->ToUniqueString(".cfa");
2031 : }
2032 0 : unsigned reg = i;
2033 0 : if (reg == return_address_)
2034 0 : return usu_->ToUniqueString(".ra");
2035 :
2036 : char buf[30];
2037 0 : SprintfLiteral(buf, "dwarf_reg_%u", reg);
2038 0 : return usu_->ToUniqueString(buf);
2039 : }
2040 :
2041 0 : bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) {
2042 0 : reporter_->UndefinedNotSupported(entry_offset_, RegisterName(reg));
2043 : // Treat this as a non-fatal error.
2044 0 : return true;
2045 : }
2046 :
2047 0 : bool DwarfCFIToModule::SameValueRule(uint64 address, int reg) {
2048 : if (DEBUG_DWARF) {
2049 : char buf[100];
2050 : SprintfLiteral(buf, "LUL.DW 0x%llx: old r%d = Same\n", address, reg);
2051 : summ_->Log(buf);
2052 : }
2053 : // reg + 0
2054 0 : summ_->Rule(address, reg, NODEREF, reg, 0);
2055 0 : return true;
2056 : }
2057 :
2058 0 : bool DwarfCFIToModule::OffsetRule(uint64 address, int reg,
2059 : int base_register, long offset) {
2060 : if (DEBUG_DWARF) {
2061 : char buf[100];
2062 : SprintfLiteral(buf, "LUL.DW 0x%llx: old r%d = *(r%d + %ld)\n",
2063 : address, reg, base_register, offset);
2064 : summ_->Log(buf);
2065 : }
2066 : // *(base_register + offset)
2067 0 : summ_->Rule(address, reg, DEREF, base_register, offset);
2068 0 : return true;
2069 : }
2070 :
2071 0 : bool DwarfCFIToModule::ValOffsetRule(uint64 address, int reg,
2072 : int base_register, long offset) {
2073 : if (DEBUG_DWARF) {
2074 : char buf[100];
2075 : SprintfLiteral(buf, "LUL.DW 0x%llx: old r%d = r%d + %ld\n",
2076 : address, reg, base_register, offset);
2077 : summ_->Log(buf);
2078 : }
2079 : // base_register + offset
2080 0 : summ_->Rule(address, reg, NODEREF, base_register, offset);
2081 0 : return true;
2082 : }
2083 :
2084 0 : bool DwarfCFIToModule::RegisterRule(uint64 address, int reg,
2085 : int base_register) {
2086 : if (DEBUG_DWARF) {
2087 : char buf[100];
2088 : SprintfLiteral(buf, "LUL.DW 0x%llx: old r%d = r%d\n",
2089 : address, reg, base_register);
2090 : summ_->Log(buf);
2091 : }
2092 : // base_register + 0
2093 0 : summ_->Rule(address, reg, NODEREF, base_register, 0);
2094 0 : return true;
2095 : }
2096 :
2097 0 : bool DwarfCFIToModule::ExpressionRule(uint64 address, int reg,
2098 : const string &expression)
2099 : {
2100 0 : bool debug = !!DEBUG_DWARF;
2101 0 : int32_t start_ix = parseDwarfExpr(summ_, reader_, expression, debug,
2102 : true/*pushCfaAtStart*/,
2103 0 : true/*derefAtEnd*/);
2104 0 : if (start_ix >= 0) {
2105 0 : summ_->Rule(address, reg, PFXEXPR, 0, start_ix);
2106 : } else {
2107 : // Parsing of the Dwarf expression failed. Treat this as a
2108 : // non-fatal error, hence return |true| even on this path.
2109 0 : reporter_->ExpressionCouldNotBeSummarised(entry_offset_, RegisterName(reg));
2110 : }
2111 0 : return true;
2112 : }
2113 :
2114 0 : bool DwarfCFIToModule::ValExpressionRule(uint64 address, int reg,
2115 : const string &expression)
2116 : {
2117 0 : bool debug = !!DEBUG_DWARF;
2118 0 : int32_t start_ix = parseDwarfExpr(summ_, reader_, expression, debug,
2119 : true/*pushCfaAtStart*/,
2120 0 : false/*!derefAtEnd*/);
2121 0 : if (start_ix >= 0) {
2122 0 : summ_->Rule(address, reg, PFXEXPR, 0, start_ix);
2123 : } else {
2124 : // Parsing of the Dwarf expression failed. Treat this as a
2125 : // non-fatal error, hence return |true| even on this path.
2126 0 : reporter_->ExpressionCouldNotBeSummarised(entry_offset_, RegisterName(reg));
2127 : }
2128 0 : return true;
2129 : }
2130 :
2131 0 : bool DwarfCFIToModule::End() {
2132 : //module_->AddStackFrameEntry(entry_);
2133 : if (DEBUG_DWARF) {
2134 : summ_->Log("LUL.DW DwarfCFIToModule::End()\n");
2135 : }
2136 0 : summ_->End();
2137 0 : return true;
2138 : }
2139 :
2140 0 : void DwarfCFIToModule::Reporter::UndefinedNotSupported(
2141 : size_t offset,
2142 : const UniqueString* reg) {
2143 : char buf[300];
2144 0 : SprintfLiteral(buf, "DwarfCFIToModule::Reporter::UndefinedNotSupported()\n");
2145 0 : log_(buf);
2146 : //BPLOG(INFO) << file_ << ", section '" << section_
2147 : // << "': the call frame entry at offset 0x"
2148 : // << std::setbase(16) << offset << std::setbase(10)
2149 : // << " sets the rule for register '" << FromUniqueString(reg)
2150 : // << "' to 'undefined', but the Breakpad symbol file format cannot "
2151 : // << " express this";
2152 0 : }
2153 :
2154 : // FIXME: move this somewhere sensible
2155 0 : static bool is_power_of_2(uint64_t n)
2156 : {
2157 0 : int i, nSetBits = 0;
2158 0 : for (i = 0; i < 8*(int)sizeof(n); i++) {
2159 0 : if ((n & ((uint64_t)1) << i) != 0)
2160 0 : nSetBits++;
2161 : }
2162 0 : return nSetBits <= 1;
2163 : }
2164 :
2165 0 : void DwarfCFIToModule::Reporter::ExpressionCouldNotBeSummarised(
2166 : size_t offset,
2167 : const UniqueString* reg) {
2168 : static uint64_t n_complaints = 0; // This isn't threadsafe
2169 0 : n_complaints++;
2170 0 : if (!is_power_of_2(n_complaints))
2171 0 : return;
2172 : char buf[300];
2173 0 : SprintfLiteral(buf,
2174 : "DwarfCFIToModule::Reporter::"
2175 : "ExpressionCouldNotBeSummarised(shown %llu times)\n",
2176 0 : (unsigned long long int)n_complaints);
2177 0 : log_(buf);
2178 : }
2179 :
2180 : } // namespace lul
|