Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/tools/profiler/lul/LulDwarf.cpp
Line
Count
Source (jump to first uncovered line)
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
0
#define DEBUG_DWARF 0
62
63
64
namespace lul {
65
66
using std::string;
67
68
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
0
  } else {
82
0
    this->offset_reader_ = &ByteReader::ReadEightBytes;
83
0
  }
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
0
  } else {
92
0
    this->address_reader_ = &ByteReader::ReadEightBytes;
93
0
  }
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
0
100
0
  // In DWARF2/3, if the initial length is all 1 bits, then the offset
101
0
  // 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
0
  } else {
107
0
    SetOffsetSize(4);
108
0
    *len = 4;
109
0
  }
110
0
  return initial_length;
111
0
}
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
0
}
122
123
bool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const {
124
  switch (encoding & 0x70) {
125
    case DW_EH_PE_absptr:  return true;
126
    case DW_EH_PE_pcrel:   return have_section_base_;
127
    case DW_EH_PE_textrel: return have_text_base_;
128
    case DW_EH_PE_datarel: return have_data_base_;
129
    case DW_EH_PE_funcrel: return have_function_base_;
130
    default:               return false;
131
  }
132
}
133
134
uint64 ByteReader::ReadEncodedPointer(const char *buffer,
135
                                      DwarfPointerEncoding encoding,
136
0
                                      size_t *len) const {
137
0
  // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't
138
0
  // see it here.
139
0
  MOZ_ASSERT(encoding != DW_EH_PE_omit);
140
0
141
0
  // The Linux Standards Base 4.0 does not make this clear, but the
142
0
  // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c)
143
0
  // agree that aligned pointers are always absolute, machine-sized,
144
0
  // machine-signed pointers.
145
0
  if (encoding == DW_EH_PE_aligned) {
146
0
    MOZ_ASSERT(have_section_base_);
147
0
148
0
    // We don't need to align BUFFER in *our* address space. Rather, we
149
0
    // need to find the next position in our buffer that would be aligned
150
0
    // when the .eh_frame section the buffer contains is loaded into the
151
0
    // program's memory. So align assuming that buffer_base_ gets loaded at
152
0
    // address section_base_, where section_base_ itself may or may not be
153
0
    // aligned.
154
0
155
0
    // First, find the offset to START from the closest prior aligned
156
0
    // address.
157
0
    uint64 skew = section_base_ & (AddressSize() - 1);
158
0
    // Now find the offset from that aligned address to buffer.
159
0
    uint64 offset = skew + (buffer - buffer_base_);
160
0
    // Round up to the next boundary.
161
0
    uint64 aligned = (offset + AddressSize() - 1) & -AddressSize();
162
0
    // Convert back to a pointer.
163
0
    const char *aligned_buffer = buffer_base_ + (aligned - skew);
164
0
    // Finally, store the length and actually fetch the pointer.
165
0
    *len = aligned_buffer - buffer + AddressSize();
166
0
    return ReadAddress(aligned_buffer);
167
0
  }
168
0
169
0
  // Extract the value first, ignoring whether it's a pointer or an
170
0
  // offset relative to some base.
171
0
  uint64 offset;
172
0
  switch (encoding & 0x0f) {
173
0
    case DW_EH_PE_absptr:
174
0
      // DW_EH_PE_absptr is weird, as it is used as a meaningful value for
175
0
      // both the high and low nybble of encoding bytes. When it appears in
176
0
      // the high nybble, it means that the pointer is absolute, not an
177
0
      // offset from some base address. When it appears in the low nybble,
178
0
      // as here, it means that the pointer is stored as a normal
179
0
      // machine-sized and machine-signed address. A low nybble of
180
0
      // DW_EH_PE_absptr does not imply that the pointer is absolute; it is
181
0
      // correct for us to treat the value as an offset from a base address
182
0
      // if the upper nybble is not DW_EH_PE_absptr.
183
0
      offset = ReadAddress(buffer);
184
0
      *len = AddressSize();
185
0
      break;
186
0
187
0
    case DW_EH_PE_uleb128:
188
0
      offset = ReadUnsignedLEB128(buffer, len);
189
0
      break;
190
0
191
0
    case DW_EH_PE_udata2:
192
0
      offset = ReadTwoBytes(buffer);
193
0
      *len = 2;
194
0
      break;
195
0
196
0
    case DW_EH_PE_udata4:
197
0
      offset = ReadFourBytes(buffer);
198
0
      *len = 4;
199
0
      break;
200
0
201
0
    case DW_EH_PE_udata8:
202
0
      offset = ReadEightBytes(buffer);
203
0
      *len = 8;
204
0
      break;
205
0
206
0
    case DW_EH_PE_sleb128:
207
0
      offset = ReadSignedLEB128(buffer, len);
208
0
      break;
209
0
210
0
    case DW_EH_PE_sdata2:
211
0
      offset = ReadTwoBytes(buffer);
212
0
      // Sign-extend from 16 bits.
213
0
      offset = (offset ^ 0x8000) - 0x8000;
214
0
      *len = 2;
215
0
      break;
216
0
217
0
    case DW_EH_PE_sdata4:
218
0
      offset = ReadFourBytes(buffer);
219
0
      // Sign-extend from 32 bits.
220
0
      offset = (offset ^ 0x80000000ULL) - 0x80000000ULL;
221
0
      *len = 4;
222
0
      break;
223
0
224
0
    case DW_EH_PE_sdata8:
225
0
      // 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
0
230
0
    default:
231
0
      abort();
232
0
  }
233
0
234
0
  // Find the appropriate base address.
235
0
  uint64 base;
236
0
  switch (encoding & 0x70) {
237
0
    case DW_EH_PE_absptr:
238
0
      base = 0;
239
0
      break;
240
0
241
0
    case DW_EH_PE_pcrel:
242
0
      MOZ_ASSERT(have_section_base_);
243
0
      base = section_base_ + (buffer - buffer_base_);
244
0
      break;
245
0
246
0
    case DW_EH_PE_textrel:
247
0
      MOZ_ASSERT(have_text_base_);
248
0
      base = text_base_;
249
0
      break;
250
0
251
0
    case DW_EH_PE_datarel:
252
0
      MOZ_ASSERT(have_data_base_);
253
0
      base = data_base_;
254
0
      break;
255
0
256
0
    case DW_EH_PE_funcrel:
257
0
      MOZ_ASSERT(have_function_base_);
258
0
      base = function_base_;
259
0
      break;
260
0
261
0
    default:
262
0
      abort();
263
0
  }
264
0
265
0
  uint64 pointer = base + offset;
266
0
267
0
  // Remove inappropriate upper bits.
268
0
  if (AddressSize() == 4)
269
0
    pointer = pointer & 0xffffffff;
270
0
  else
271
0
    MOZ_ASSERT(AddressSize() == sizeof(uint64));
272
0
273
0
  return pointer;
274
0
}
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
class CallFrameInfo::Rule {
292
 public:
293
0
  virtual ~Rule() { }
294
295
  // Tell HANDLER that, at ADDRESS in the program, REG can be
296
  // recovered using this rule. If REG 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 reg) 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
class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
336
 public:
337
0
  UndefinedRule() { }
338
0
  ~UndefinedRule() { }
339
0
  CFIRTag getTag() const override { return CFIR_UNDEFINED_RULE; }
340
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
341
0
    return handler->UndefinedRule(address, reg);
342
0
  }
343
0
  bool operator==(const Rule &rhs) const override {
344
0
    if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false;
345
0
    return true;
346
0
  }
347
0
  Rule *Copy() const override { return new UndefinedRule(*this); }
348
};
349
350
// Rule: the register's value is the same as that it had in the caller.
351
class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
352
 public:
353
0
  SameValueRule() { }
354
0
  ~SameValueRule() { }
355
0
  CFIRTag getTag() const override { return CFIR_SAME_VALUE_RULE; }
356
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
357
0
    return handler->SameValueRule(address, reg);
358
0
  }
359
0
  bool operator==(const Rule &rhs) const override {
360
0
    if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false;
361
0
    return true;
362
0
  }
363
0
  Rule *Copy() const override { 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
class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
369
 public:
370
  OffsetRule(int base_register, long offset)
371
0
      : base_register_(base_register), offset_(offset) { }
372
0
  ~OffsetRule() { }
373
0
  CFIRTag getTag() const override { return CFIR_OFFSET_RULE; }
374
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
375
0
    return handler->OffsetRule(address, reg, base_register_, offset_);
376
0
  }
377
0
  bool operator==(const Rule &rhs) const override {
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
0
  }
383
0
  Rule *Copy() const override { 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
class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
397
 public:
398
  ValOffsetRule(int base_register, long offset)
399
0
      : base_register_(base_register), offset_(offset) { }
400
0
  ~ValOffsetRule() { }
401
0
  CFIRTag getTag() const override { return CFIR_VAL_OFFSET_RULE; }
402
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
403
0
    return handler->ValOffsetRule(address, reg, base_register_, offset_);
404
0
  }
405
0
  bool operator==(const Rule &rhs) const override {
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
0
  }
411
0
  Rule *Copy() const override { return new ValOffsetRule(*this); }
412
0
  void SetBaseRegister(unsigned reg) override { base_register_ = reg; }
413
0
  void SetOffset(long long offset) override { 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
class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
421
 public:
422
  explicit RegisterRule(int register_number)
423
0
      : register_number_(register_number) { }
424
0
  ~RegisterRule() { }
425
0
  CFIRTag getTag() const override { return CFIR_REGISTER_RULE; }
426
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
427
0
    return handler->RegisterRule(address, reg, register_number_);
428
0
  }
429
0
  bool operator==(const Rule &rhs) const override {
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
0
  }
434
0
  Rule *Copy() const override { 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
class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
441
 public:
442
  explicit ExpressionRule(const string &expression)
443
0
      : expression_(expression) { }
444
0
  ~ExpressionRule() { }
445
0
  CFIRTag getTag() const override { return CFIR_EXPRESSION_RULE; }
446
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
447
0
    return handler->ExpressionRule(address, reg, expression_);
448
0
  }
449
0
  bool operator==(const Rule &rhs) const override {
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
0
  }
454
0
  Rule *Copy() const override { return new ExpressionRule(*this); }
455
 private:
456
  string expression_;
457
};
458
459
// Rule: EXPRESSION evaluates to the previous value of the register.
460
class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
461
 public:
462
  explicit ValExpressionRule(const string &expression)
463
0
      : expression_(expression) { }
464
0
  ~ValExpressionRule() { }
465
0
  CFIRTag getTag() const override { return CFIR_VAL_EXPRESSION_RULE; }
466
0
  bool Handle(Handler *handler, uint64 address, int reg) const override {
467
0
    return handler->ValExpressionRule(address, reg, expression_);
468
0
  }
469
0
  bool operator==(const Rule &rhs) const override {
470
0
    if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false;
471
0
    const ValExpressionRule *our_rhs =
472
0
        static_cast<const ValExpressionRule *>(&rhs);
473
0
    return (expression_ == our_rhs->expression_);
474
0
  }
475
0
  Rule *Copy() const override { 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
0
  // 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
0
}
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
0
  else
544
0
    return NULL;
545
0
}
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 = &registers_[reg];
551
0
  delete *slot;
552
0
  *slot = rule;
553
0
}
554
555
bool CallFrameInfo::RuleMap::HandleTransitionTo(
556
    Handler *handler,
557
    uint64 address,
558
0
    const RuleMap &new_rules) const {
559
0
  // 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
0
    // this RuleMap has a CFA rule but new_rules doesn't.
566
0
    // CallFrameInfo::Handler has no way to handle this --- and shouldn't;
567
0
    // it's garbage input. The instruction interpreter should have
568
0
    // detected this and warned, so take no action here.
569
0
  } else if (new_rules.cfa_rule_) {
570
0
    // This shouldn't be possible: NEW_RULES is some prior state, and
571
0
    // there's no way to remove entries.
572
0
    MOZ_ASSERT(0);
573
0
  } else {
574
0
    // Both CFA rules are empty.  No action needed.
575
0
  }
576
0
577
0
  // Traverse the two maps in order by register number, and report
578
0
  // 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
0
      // This RuleMap has an entry for old_it->first, but NEW_RULES
584
0
      // doesn't.
585
0
      //
586
0
      // This isn't really the right thing to do, but since CFI generally
587
0
      // only mentions callee-saves registers, and GCC's convention for
588
0
      // callee-saves registers is that they are unchanged, it's a good
589
0
      // 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
0
      // NEW_RULES has entry for new_it->first, but this RuleMap
595
0
      // doesn't. This shouldn't be possible: NEW_RULES is some prior
596
0
      // state, and there's no way to remove entries.
597
0
      MOZ_ASSERT(0);
598
0
    } else {
599
0
      // Both maps have an entry for this register. Report the new
600
0
      // 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
0
    }
606
0
  }
607
0
  // 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
0
  }
613
0
  // Since we only make transitions from a rule set to some previously
614
0
  // saved rule set, and we can only add rules to the map, NEW_RULES
615
0
  // must have fewer rules than *this.
616
0
  MOZ_ASSERT(new_it == new_rules.registers_.end());
617
0
618
0
  return true;
619
0
}
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
  State(ByteReader *reader, Handler *handler, Reporter *reporter,
638
        uint64 address)
639
      : 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
  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
0
  }
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
0
  // Note the rules established by the CIE, for use by DW_CFA_restore
774
0
  // and DW_CFA_restore_extended.
775
0
  cie_rules_ = rules_;
776
0
  return true;
777
0
}
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
0
}
787
788
bool CallFrameInfo::State::ParseOperands(const char *format,
789
0
                                         Operands *operands) {
790
0
  size_t len;
791
0
  const char *operand;
792
0
793
0
  for (operand = format; *operand; operand++) {
794
0
    size_t bytes_left = entry_->end - cursor_;
795
0
    switch (*operand) {
796
0
      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
0
802
0
      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
0
808
0
      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
0
814
0
      case 'a':
815
0
        operands->offset =
816
0
          reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding,
817
0
                                      &len);
818
0
        if (len > bytes_left) return ReportIncomplete();
819
0
        cursor_ += len;
820
0
        break;
821
0
822
0
      case '1':
823
0
        if (1 > bytes_left) return ReportIncomplete();
824
0
        operands->offset = static_cast<unsigned char>(*cursor_++);
825
0
        break;
826
0
827
0
      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
0
833
0
      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
0
839
0
      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
0
845
0
      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
0
      }
854
0
855
0
      default:
856
0
        MOZ_ASSERT(0);
857
0
    }
858
0
  }
859
0
860
0
  return true;
861
0
}
862
863
0
bool CallFrameInfo::State::DoInstruction() {
864
0
  CIE *cie = entry_->cie;
865
0
  Operands ops;
866
0
867
0
  // Our entry's kind should have been set by now.
868
0
  MOZ_ASSERT(entry_->kind != kUnknown);
869
0
870
0
  // We shouldn't have been invoked unless there were more
871
0
  // instructions to parse.
872
0
  MOZ_ASSERT(cursor_ < entry_->end);
873
0
874
0
  unsigned opcode = *cursor_++;
875
0
  if ((opcode & 0xc0) != 0) {
876
0
    switch (opcode & 0xc0) {
877
0
      // Advance the address.
878
0
      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
0
      }
883
0
884
0
      // Find a register at an offset from the CFA.
885
0
      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
0
891
0
      // Restore the rule established for a register by the CIE.
892
0
      case DW_CFA_restore:
893
0
        if (!DoRestore(opcode & 0x3f)) return false;
894
0
        break;
895
0
896
0
      // The 'if' above should have excluded this possibility.
897
0
      default:
898
0
        MOZ_ASSERT(0);
899
0
    }
900
0
901
0
    // Return here, so the big switch below won't be indented.
902
0
    return true;
903
0
  }
904
0
905
0
  switch (opcode) {
906
0
    // Set the address.
907
0
    case DW_CFA_set_loc:
908
0
      if (!ParseOperands("a", &ops)) return false;
909
0
      address_ = ops.offset;
910
0
      break;
911
0
912
0
    // Advance the address.
913
0
    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
0
918
0
    // Advance the address.
919
0
    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
0
924
0
    // Advance the address.
925
0
    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
0
930
0
    // Advance the address.
931
0
    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
0
936
0
    // Compute the CFA by adding an offset to a register.
937
0
    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
0
943
0
    // Compute the CFA by adding an offset to a register.
944
0
    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
0
951
0
    // Change the base register used to compute the CFA.
952
0
    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
0
      }
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
0
    }
964
0
965
0
    // Change the offset used to compute the CFA.
966
0
    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
0
972
0
    // Change the offset used to compute the CFA.
973
0
    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
0
979
0
    // Specify an expression whose value is the CFA.
980
0
    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
0
    }
989
0
990
0
    // The register's value cannot be recovered.
991
0
    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
0
    }
997
0
998
0
    // The register's value is unchanged from its value in the caller.
999
0
    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
0
    }
1005
0
1006
0
    // Find a register at an offset from the CFA.
1007
0
    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
0
1014
0
    // The register is saved at an offset from the CFA.
1015
0
    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
0
1022
0
    // The register is saved at an offset from the CFA.
1023
0
    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
0
1030
0
    // The register's value is the sum of the CFA plus an offset.
1031
0
    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
0
1038
0
    // The register's value is the sum of the CFA plus an offset.
1039
0
    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
0
1046
0
    // The register has been saved in another register.
1047
0
    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
0
    }
1053
0
1054
0
    // An expression yields the address at which the register is saved.
1055
0
    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
0
    }
1061
0
1062
0
    // An expression yields the caller's value for the register.
1063
0
    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
0
    }
1069
0
1070
0
    // Restore the rule established for a register by the CIE.
1071
0
    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
0
1077
0
    // Save the current set of rules on a stack.
1078
0
    case DW_CFA_remember_state:
1079
0
      if (!saved_rules_) {
1080
0
        saved_rules_ = new std::stack<RuleMap>();
1081
0
      }
1082
0
      saved_rules_->push(rules_);
1083
0
      break;
1084
0
1085
0
    // Pop the current set of rules off the stack.
1086
0
    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
0
      }
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
0
      }
1098
0
      rules_.HandleTransitionTo(handler_, address_, new_rules);
1099
0
      rules_ = new_rules;
1100
0
      saved_rules_->pop();
1101
0
      break;
1102
0
    }
1103
0
1104
0
    // No operation.  (Padding instruction.)
1105
0
    case DW_CFA_nop:
1106
0
      break;
1107
0
1108
0
    // A SPARC register window save: Registers 8 through 15 (%o0-%o7)
1109
0
    // are saved in registers 24 through 31 (%i0-%i7), and registers
1110
0
    // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets
1111
0
    // (0-15 * the register size). The register numbers must be
1112
0
    // hard-coded. A GNU extension, and not a pretty one.
1113
0
    case DW_CFA_GNU_window_save: {
1114
0
      // 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
0
      // Save %l0-%l7 and %i0-%i7 at the CFA.
1119
0
      for (int i = 16; i < 32; i++)
1120
0
        // Assume that the byte reader's address size is the same as
1121
0
        // 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
0
    }
1127
0
1128
0
    // I'm not sure what this is. GDB doesn't use it for unwinding.
1129
0
    case DW_CFA_GNU_args_size:
1130
0
      if (!ParseOperands("o", &ops)) return false;
1131
0
      break;
1132
0
1133
0
    // An opcode we don't recognize.
1134
0
    default: {
1135
0
      reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset());
1136
0
      return false;
1137
0
    }
1138
0
  }
1139
0
1140
0
  return true;
1141
0
}
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
0
}
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
0
  }
1155
0
  cfa_rule->SetOffset(offset);
1156
0
  return cfa_rule->Handle(handler_, address_, Handler::kCFARegister);
1157
0
}
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
0
}
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
0
  }
1169
0
  return DoRule(reg,
1170
0
                new OffsetRule(Handler::kCFARegister, offset));
1171
0
}
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
0
  }
1178
0
  return DoRule(reg,
1179
0
                new ValOffsetRule(Handler::kCFARegister, offset));
1180
0
}
1181
1182
0
bool CallFrameInfo::State::DoRestore(unsigned reg) {
1183
0
  // 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
0
  }
1188
0
  Rule *rule = cie_rules_.RegisterRule(reg);
1189
0
  if (!rule) {
1190
0
    // This isn't really the right thing to do, but since CFI generally
1191
0
    // only mentions callee-saves registers, and GCC's convention for
1192
0
    // callee-saves registers is that they are unchanged, it's a good
1193
0
    // approximation.
1194
0
    rule = new SameValueRule();
1195
0
  }
1196
0
  return DoRule(reg, rule);
1197
0
}
1198
1199
0
bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) {
1200
0
  const char *buffer_end = buffer_ + buffer_length_;
1201
0
1202
0
  // 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
0
1208
0
  // Read the initial length. This sets reader_'s offset size.
1209
0
  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
0
1215
0
  // In a .eh_frame section, a length of zero marks the end of the series
1216
0
  // of entries.
1217
0
  if (length == 0 && eh_frame_) {
1218
0
    entry->kind = kTerminator;
1219
0
    entry->end = cursor;
1220
0
    return true;
1221
0
  }
1222
0
1223
0
  // Validate the length.
1224
0
  if (length > size_t(buffer_end - cursor))
1225
0
    return ReportIncomplete(entry);
1226
0
1227
0
  // The length is the number of bytes after the initial length field;
1228
0
  // we have that position handy at this point, so compute the end
1229
0
  // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine,
1230
0
  // and the length didn't fit in a size_t, we would have rejected it
1231
0
  // above.)
1232
0
  entry->end = cursor + length;
1233
0
1234
0
  // 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
0
1239
0
  // Don't advance cursor past id field yet; in .eh_frame data we need
1240
0
  // the id's position to compute the section offset of an FDE's CIE.
1241
0
1242
0
  // Now we can decide what kind of entry this is.
1243
0
  if (eh_frame_) {
1244
0
    // In .eh_frame data, an ID of zero marks the entry as a CIE, and
1245
0
    // anything else is an offset from the id field of the FDE to the start
1246
0
    // of the CIE.
1247
0
    if (entry->id == 0) {
1248
0
      entry->kind = kCIE;
1249
0
    } else {
1250
0
      entry->kind = kFDE;
1251
0
      // Turn the offset from the id into an offset from the buffer's start.
1252
0
      entry->id = (cursor - buffer_) - entry->id;
1253
0
    }
1254
0
  } else {
1255
0
    // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the
1256
0
    // offset size for the entry) marks the entry as a CIE, and anything
1257
0
    // 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
0
    else {
1261
0
      MOZ_ASSERT(offset_size == 8);
1262
0
      entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE;
1263
0
    }
1264
0
  }
1265
0
1266
0
  // Now advance cursor past the id.
1267
0
   cursor += offset_size;
1268
0
1269
0
  // The fields specific to this kind of entry start here.
1270
0
  entry->fields = cursor;
1271
0
1272
0
  entry->cie = NULL;
1273
0
1274
0
  return true;
1275
0
}
1276
1277
0
bool CallFrameInfo::ReadCIEFields(CIE *cie) {
1278
0
  const char *cursor = cie->fields;
1279
0
  size_t len;
1280
0
1281
0
  MOZ_ASSERT(cie->kind == kCIE);
1282
0
1283
0
  // 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
0
1293
0
  // 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
0
1299
0
  // If we don't recognize the version, we can't parse any more fields of the
1300
0
  // CIE. For DWARF CFI, we handle versions 1 through 4 (there was never a
1301
0
  // version 2 of CFI data). For .eh_frame, we handle versions 1 and 4 as well;
1302
0
  // the difference between those versions seems to be the same as for
1303
0
  // .debug_frame.
1304
0
  if (cie->version < 1 || cie->version > 4) {
1305
0
    reporter_->UnrecognizedVersion(cie->offset, cie->version);
1306
0
    return false;
1307
0
  }
1308
0
1309
0
  const char *augmentation_start = cursor;
1310
0
  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
0
  // Skip the terminating '\0'.
1317
0
  cursor++;
1318
0
1319
0
  // Is this CFI augmented?
1320
0
  if (!cie->augmentation.empty()) {
1321
0
    // Is it an augmentation we recognize?
1322
0
    if (cie->augmentation[0] == DW_Z_augmentation_start) {
1323
0
      // Linux C++ ABI 'z' augmentation, used for exception handling data.
1324
0
      cie->has_z_augmentation = true;
1325
0
    } else {
1326
0
      // Not an augmentation we recognize. Augmentations can have arbitrary
1327
0
      // 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
0
    }
1331
0
  }
1332
0
1333
0
  if (cie->version >= 4) {
1334
0
    // Check that the address_size and segment_size fields are plausible.
1335
0
    if (cie->end - cursor < 2) {
1336
0
      return ReportIncomplete(cie);
1337
0
    }
1338
0
    uint8_t address_size = reader_->ReadOneByte(cursor);
1339
0
    cursor++;
1340
0
    if (address_size != sizeof(void*)) {
1341
0
      // This is not per-se invalid CFI.  But we can reasonably expect to
1342
0
      // be running on a target of the same word size as the CFI is for,
1343
0
      // so we reject this case.
1344
0
      reporter_->InvalidDwarf4Artefact(cie->offset, "Invalid address_size");
1345
0
      return false;
1346
0
    }
1347
0
    uint8_t segment_size = reader_->ReadOneByte(cursor);
1348
0
    cursor++;
1349
0
    if (segment_size != 0) {
1350
0
      // This is also not per-se invalid CFI, but we don't currently handle
1351
0
      // the case of non-zero |segment_size|.
1352
0
      reporter_->InvalidDwarf4Artefact(cie->offset, "Invalid segment_size");
1353
0
      return false;
1354
0
    }
1355
0
    // We only continue parsing if |segment_size| is zero.  If this routine
1356
0
    // is ever changed to allow non-zero |segment_size|, then
1357
0
    // ReadFDEFields() below will have to be changed to match, per comments
1358
0
    // there.
1359
0
  }
1360
0
1361
0
  // Parse the code alignment factor.
1362
0
  cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
1363
0
  if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1364
0
  cursor += len;
1365
0
1366
0
  // Parse the data alignment factor.
1367
0
  cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
1368
0
  if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1369
0
  cursor += len;
1370
0
1371
0
  // Parse the return address register. This is a ubyte in version 1, and
1372
0
  // a ULEB128 in version 3.
1373
0
  if (cie->version == 1) {
1374
0
    if (cursor >= cie->end) return ReportIncomplete(cie);
1375
0
    cie->return_address_register = uint8(*cursor++);
1376
0
  } else {
1377
0
    cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len);
1378
0
    if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
1379
0
    cursor += len;
1380
0
  }
1381
0
1382
0
  // If we have a 'z' augmentation string, find the augmentation data and
1383
0
  // use the augmentation string to parse it.
1384
0
  if (cie->has_z_augmentation) {
1385
0
    uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len);
1386
0
    if (size_t(cie->end - cursor) < len + data_size)
1387
0
      return ReportIncomplete(cie);
1388
0
    cursor += len;
1389
0
    const char *data = cursor;
1390
0
    cursor += data_size;
1391
0
    const char *data_end = cursor;
1392
0
1393
0
    cie->has_z_lsda = false;
1394
0
    cie->has_z_personality = false;
1395
0
    cie->has_z_signal_frame = false;
1396
0
1397
0
    // Walk the augmentation string, and extract values from the
1398
0
    // augmentation data as the string directs.
1399
0
    for (size_t i = 1; i < cie->augmentation.size(); i++) {
1400
0
      switch (cie->augmentation[i]) {
1401
0
        case DW_Z_has_LSDA:
1402
0
          // The CIE's augmentation data holds the language-specific data
1403
0
          // area pointer's encoding, and the FDE's augmentation data holds
1404
0
          // the pointer itself.
1405
0
          cie->has_z_lsda = true;
1406
0
          // Fetch the LSDA encoding from the augmentation data.
1407
0
          if (data >= data_end) return ReportIncomplete(cie);
1408
0
          cie->lsda_encoding = DwarfPointerEncoding(*data++);
1409
0
          if (!reader_->ValidEncoding(cie->lsda_encoding)) {
1410
0
            reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding);
1411
0
            return false;
1412
0
          }
1413
0
          // Don't check if the encoding is usable here --- we haven't
1414
0
          // read the FDE's fields yet, so we're not prepared for
1415
0
          // DW_EH_PE_funcrel, although that's a fine encoding for the
1416
0
          // LSDA to use, since it appears in the FDE.
1417
0
          break;
1418
0
1419
0
        case DW_Z_has_personality_routine:
1420
0
          // The CIE's augmentation data holds the personality routine
1421
0
          // pointer's encoding, followed by the pointer itself.
1422
0
          cie->has_z_personality = true;
1423
0
          // Fetch the personality routine pointer's encoding from the
1424
0
          // augmentation data.
1425
0
          if (data >= data_end) return ReportIncomplete(cie);
1426
0
          cie->personality_encoding = DwarfPointerEncoding(*data++);
1427
0
          if (!reader_->ValidEncoding(cie->personality_encoding)) {
1428
0
            reporter_->InvalidPointerEncoding(cie->offset,
1429
0
                                              cie->personality_encoding);
1430
0
            return false;
1431
0
          }
1432
0
          if (!reader_->UsableEncoding(cie->personality_encoding)) {
1433
0
            reporter_->UnusablePointerEncoding(cie->offset,
1434
0
                                               cie->personality_encoding);
1435
0
            return false;
1436
0
          }
1437
0
          // Fetch the personality routine's pointer itself from the data.
1438
0
          cie->personality_address =
1439
0
            reader_->ReadEncodedPointer(data, cie->personality_encoding,
1440
0
                                        &len);
1441
0
          if (len > size_t(data_end - data))
1442
0
            return ReportIncomplete(cie);
1443
0
          data += len;
1444
0
          break;
1445
0
1446
0
        case DW_Z_has_FDE_address_encoding:
1447
0
          // The CIE's augmentation data holds the pointer encoding to use
1448
0
          // for addresses in the FDE.
1449
0
          if (data >= data_end) return ReportIncomplete(cie);
1450
0
          cie->pointer_encoding = DwarfPointerEncoding(*data++);
1451
0
          if (!reader_->ValidEncoding(cie->pointer_encoding)) {
1452
0
            reporter_->InvalidPointerEncoding(cie->offset,
1453
0
                                              cie->pointer_encoding);
1454
0
            return false;
1455
0
          }
1456
0
          if (!reader_->UsableEncoding(cie->pointer_encoding)) {
1457
0
            reporter_->UnusablePointerEncoding(cie->offset,
1458
0
                                               cie->pointer_encoding);
1459
0
            return false;
1460
0
          }
1461
0
          break;
1462
0
1463
0
        case DW_Z_is_signal_trampoline:
1464
0
          // Frames using this CIE are signal delivery frames.
1465
0
          cie->has_z_signal_frame = true;
1466
0
          break;
1467
0
1468
0
        default:
1469
0
          // An augmentation we don't recognize.
1470
0
          reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
1471
0
          return false;
1472
0
      }
1473
0
    }
1474
0
  }
1475
0
1476
0
  // The CIE's instructions start here.
1477
0
  cie->instructions = cursor;
1478
0
1479
0
  return true;
1480
0
}
1481
1482
0
bool CallFrameInfo::ReadFDEFields(FDE *fde) {
1483
0
  const char *cursor = fde->fields;
1484
0
  size_t size;
1485
0
1486
0
  // At this point, for Dwarf 4 and above, we are assuming that the
1487
0
  // associated CIE has its |segment_size| field equal to zero.  This is
1488
0
  // checked for in ReadCIEFields() above.  If ReadCIEFields() is ever
1489
0
  // changed to allow non-zero |segment_size| CIEs then we will have to read
1490
0
  // the segment_selector value at this point.
1491
0
1492
0
  fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
1493
0
                                             &size);
1494
0
  if (size > size_t(fde->end - cursor))
1495
0
    return ReportIncomplete(fde);
1496
0
  cursor += size;
1497
0
  reader_->SetFunctionBase(fde->address);
1498
0
1499
0
  // For the length, we strip off the upper nybble of the encoding used for
1500
0
  // the starting address.
1501
0
  DwarfPointerEncoding length_encoding =
1502
0
    DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f);
1503
0
  fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size);
1504
0
  if (size > size_t(fde->end - cursor))
1505
0
    return ReportIncomplete(fde);
1506
0
  cursor += size;
1507
0
1508
0
  // If the CIE has a 'z' augmentation string, then augmentation data
1509
0
  // appears here.
1510
0
  if (fde->cie->has_z_augmentation) {
1511
0
    uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size);
1512
0
    if (size_t(fde->end - cursor) < size + data_size)
1513
0
      return ReportIncomplete(fde);
1514
0
    cursor += size;
1515
0
1516
0
    // In the abstract, we should walk the augmentation string, and extract
1517
0
    // items from the FDE's augmentation data as we encounter augmentation
1518
0
    // string characters that specify their presence: the ordering of items
1519
0
    // in the augmentation string determines the arrangement of values in
1520
0
    // the augmentation data.
1521
0
    //
1522
0
    // In practice, there's only ever one value in FDE augmentation data
1523
0
    // that we support --- the LSDA pointer --- and we have to bail if we
1524
0
    // see any unrecognized augmentation string characters. So if there is
1525
0
    // anything here at all, we know what it is, and where it starts.
1526
0
    if (fde->cie->has_z_lsda) {
1527
0
      // Check whether the LSDA's pointer encoding is usable now: only once
1528
0
      // we've parsed the FDE's starting address do we call reader_->
1529
0
      // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes
1530
0
      // usable.
1531
0
      if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) {
1532
0
        reporter_->UnusablePointerEncoding(fde->cie->offset,
1533
0
                                           fde->cie->lsda_encoding);
1534
0
        return false;
1535
0
      }
1536
0
1537
0
      fde->lsda_address =
1538
0
        reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size);
1539
0
      if (size > data_size)
1540
0
        return ReportIncomplete(fde);
1541
0
      // Ideally, we would also complain here if there were unconsumed
1542
0
      // augmentation data.
1543
0
    }
1544
0
1545
0
    cursor += data_size;
1546
0
  }
1547
0
1548
0
  // The FDE's instructions start after those.
1549
0
  fde->instructions = cursor;
1550
0
1551
0
  return true;
1552
0
}
1553
1554
0
bool CallFrameInfo::Start() {
1555
0
  const char *buffer_end = buffer_ + buffer_length_;
1556
0
  const char *cursor;
1557
0
  bool all_ok = true;
1558
0
  const char *entry_end;
1559
0
  bool ok;
1560
0
1561
0
  // Traverse all the entries in buffer_, skipping CIEs and offering
1562
0
  // FDEs to the handler.
1563
0
  for (cursor = buffer_; cursor < buffer_end;
1564
0
       cursor = entry_end, all_ok = all_ok && ok) {
1565
0
    FDE fde;
1566
0
1567
0
    // Make it easy to skip this entry with 'continue': assume that
1568
0
    // things are not okay until we've checked all the data, and
1569
0
    // prepare the address of the next entry.
1570
0
    ok = false;
1571
0
1572
0
    // Read the entry's prologue.
1573
0
    if (!ReadEntryPrologue(cursor, &fde)) {
1574
0
      if (!fde.end) {
1575
0
        // If we couldn't even figure out this entry's extent, then we
1576
0
        // must stop processing entries altogether.
1577
0
        all_ok = false;
1578
0
        break;
1579
0
      }
1580
0
      entry_end = fde.end;
1581
0
      continue;
1582
0
    }
1583
0
1584
0
    // The next iteration picks up after this entry.
1585
0
    entry_end = fde.end;
1586
0
1587
0
    // Did we see an .eh_frame terminating mark?
1588
0
    if (fde.kind == kTerminator) {
1589
0
      // If there appears to be more data left in the section after the
1590
0
      // terminating mark, warn the user. But this is just a warning;
1591
0
      // we leave all_ok true.
1592
0
      if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset);
1593
0
      break;
1594
0
    }
1595
0
1596
0
    // In this loop, we skip CIEs. We only parse them fully when we
1597
0
    // parse an FDE that refers to them. This limits our memory
1598
0
    // consumption (beyond the buffer itself) to that needed to
1599
0
    // process the largest single entry.
1600
0
    if (fde.kind != kFDE) {
1601
0
      ok = true;
1602
0
      continue;
1603
0
    }
1604
0
1605
0
    // Validate the CIE pointer.
1606
0
    if (fde.id > buffer_length_) {
1607
0
      reporter_->CIEPointerOutOfRange(fde.offset, fde.id);
1608
0
      continue;
1609
0
    }
1610
0
1611
0
    CIE cie;
1612
0
1613
0
    // Parse this FDE's CIE header.
1614
0
    if (!ReadEntryPrologue(buffer_ + fde.id, &cie))
1615
0
      continue;
1616
0
    // This had better be an actual CIE.
1617
0
    if (cie.kind != kCIE) {
1618
0
      reporter_->BadCIEId(fde.offset, fde.id);
1619
0
      continue;
1620
0
    }
1621
0
    if (!ReadCIEFields(&cie))
1622
0
      continue;
1623
0
1624
0
    // We now have the values that govern both the CIE and the FDE.
1625
0
    cie.cie = &cie;
1626
0
    fde.cie = &cie;
1627
0
1628
0
    // Parse the FDE's header.
1629
0
    if (!ReadFDEFields(&fde))
1630
0
      continue;
1631
0
1632
0
    // Call Entry to ask the consumer if they're interested.
1633
0
    if (!handler_->Entry(fde.offset, fde.address, fde.size,
1634
0
                         cie.version, cie.augmentation,
1635
0
                         cie.return_address_register)) {
1636
0
      // The handler isn't interested in this entry. That's not an error.
1637
0
      ok = true;
1638
0
      continue;
1639
0
    }
1640
0
1641
0
    if (cie.has_z_augmentation) {
1642
0
      // Report the personality routine address, if we have one.
1643
0
      if (cie.has_z_personality) {
1644
0
        if (!handler_
1645
0
            ->PersonalityRoutine(cie.personality_address,
1646
0
                                 IsIndirectEncoding(cie.personality_encoding)))
1647
0
          continue;
1648
0
      }
1649
0
1650
0
      // Report the language-specific data area address, if we have one.
1651
0
      if (cie.has_z_lsda) {
1652
0
        if (!handler_
1653
0
            ->LanguageSpecificDataArea(fde.lsda_address,
1654
0
                                       IsIndirectEncoding(cie.lsda_encoding)))
1655
0
          continue;
1656
0
      }
1657
0
1658
0
      // If this is a signal-handling frame, report that.
1659
0
      if (cie.has_z_signal_frame) {
1660
0
        if (!handler_->SignalHandler())
1661
0
          continue;
1662
0
      }
1663
0
    }
1664
0
1665
0
    // Interpret the CIE's instructions, and then the FDE's instructions.
1666
0
    State state(reader_, handler_, reporter_, fde.address);
1667
0
    ok = state.InterpretCIE(cie) && state.InterpretFDE(fde);
1668
0
1669
0
    // Tell the ByteReader that the function start address from the
1670
0
    // FDE header is no longer valid.
1671
0
    reader_->ClearFunctionBase();
1672
0
1673
0
    // Report the end of the entry.
1674
0
    handler_->End();
1675
0
  }
1676
0
1677
0
  return all_ok;
1678
0
}
1679
1680
0
const char *CallFrameInfo::KindName(EntryKind kind) {
1681
0
  if (kind == CallFrameInfo::kUnknown)
1682
0
    return "entry";
1683
0
  else if (kind == CallFrameInfo::kCIE)
1684
0
    return "common information entry";
1685
0
  else if (kind == CallFrameInfo::kFDE)
1686
0
    return "frame description entry";
1687
0
  else {
1688
0
    MOZ_ASSERT (kind == CallFrameInfo::kTerminator);
1689
0
    return ".eh_frame sequence terminator";
1690
0
  }
1691
0
}
1692
1693
0
bool CallFrameInfo::ReportIncomplete(Entry *entry) {
1694
0
  reporter_->Incomplete(entry->offset, entry->kind);
1695
0
  return false;
1696
0
}
1697
1698
void CallFrameInfo::Reporter::Incomplete(uint64 offset,
1699
0
                                         CallFrameInfo::EntryKind kind) {
1700
0
  char buf[300];
1701
0
  SprintfLiteral(buf,
1702
0
                 "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
1703
0
                 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1704
0
                 section_.c_str());
1705
0
  log_(buf);
1706
0
}
1707
1708
0
void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) {
1709
0
  char buf[300];
1710
0
  SprintfLiteral(buf,
1711
0
                 "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
1712
0
                 " before end of section contents\n",
1713
0
                 filename_.c_str(), offset, section_.c_str());
1714
0
  log_(buf);
1715
0
}
1716
1717
void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset,
1718
0
                                                   uint64 cie_offset) {
1719
0
  char buf[300];
1720
0
  SprintfLiteral(buf,
1721
0
                 "%s: CFI frame description entry at offset 0x%llx in '%s':"
1722
0
                 " CIE pointer is out of range: 0x%llx\n",
1723
0
                 filename_.c_str(), offset, section_.c_str(), cie_offset);
1724
0
  log_(buf);
1725
0
}
1726
1727
0
void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
1728
0
  char buf[300];
1729
0
  SprintfLiteral(buf,
1730
0
                 "%s: CFI frame description entry at offset 0x%llx in '%s':"
1731
0
                 " CIE pointer does not point to a CIE: 0x%llx\n",
1732
0
                 filename_.c_str(), offset, section_.c_str(), cie_offset);
1733
0
  log_(buf);
1734
0
}
1735
1736
0
void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
1737
0
  char buf[300];
1738
0
  SprintfLiteral(buf,
1739
0
                 "%s: CFI frame description entry at offset 0x%llx in '%s':"
1740
0
                 " CIE specifies unrecognized version: %d\n",
1741
0
                 filename_.c_str(), offset, section_.c_str(), version);
1742
0
  log_(buf);
1743
0
}
1744
1745
void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
1746
0
                                                       const string &aug) {
1747
0
  char buf[300];
1748
0
  SprintfLiteral(buf,
1749
0
                 "%s: CFI frame description entry at offset 0x%llx in '%s':"
1750
0
                 " CIE specifies unrecognized augmentation: '%s'\n",
1751
0
                 filename_.c_str(), offset, section_.c_str(), aug.c_str());
1752
0
  log_(buf);
1753
0
}
1754
1755
void CallFrameInfo::Reporter::InvalidDwarf4Artefact(uint64 offset,
1756
0
                                                    const char* what) {
1757
0
  char* what_safe = strndup(what, 100);
1758
0
  char buf[300];
1759
0
  SprintfLiteral(buf,
1760
0
                 "%s: CFI frame description entry at offset 0x%llx in '%s':"
1761
0
                 " CIE specifies invalid Dwarf4 artefact: %s\n",
1762
0
                 filename_.c_str(), offset, section_.c_str(), what_safe);
1763
0
  log_(buf);
1764
0
  free(what_safe);
1765
0
}
1766
1767
void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset,
1768
0
                                                     uint8 encoding) {
1769
0
  char buf[300];
1770
0
  SprintfLiteral(buf,
1771
0
                 "%s: CFI common information entry at offset 0x%llx in '%s':"
1772
0
                 " 'z' augmentation specifies invalid pointer encoding: "
1773
0
                 "0x%02x\n",
1774
0
                 filename_.c_str(), offset, section_.c_str(), encoding);
1775
0
  log_(buf);
1776
0
}
1777
1778
void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset,
1779
0
                                                      uint8 encoding) {
1780
0
  char buf[300];
1781
0
  SprintfLiteral(buf,
1782
0
                 "%s: CFI common information entry at offset 0x%llx in '%s':"
1783
0
                 " 'z' augmentation specifies a pointer encoding for which"
1784
0
                 " we have no base address: 0x%02x\n",
1785
0
                 filename_.c_str(), offset, section_.c_str(), encoding);
1786
0
  log_(buf);
1787
0
}
1788
1789
0
void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) {
1790
0
  char buf[300];
1791
0
  SprintfLiteral(buf,
1792
0
                 "%s: CFI common information entry at offset 0x%llx in '%s':"
1793
0
                 " the DW_CFA_restore instruction at offset 0x%llx"
1794
0
                 " cannot be used in a common information entry\n",
1795
0
                 filename_.c_str(), offset, section_.c_str(), insn_offset);
1796
0
  log_(buf);
1797
0
}
1798
1799
void CallFrameInfo::Reporter::BadInstruction(uint64 offset,
1800
                                             CallFrameInfo::EntryKind kind,
1801
0
                                             uint64 insn_offset) {
1802
0
  char buf[300];
1803
0
  SprintfLiteral(buf,
1804
0
                 "%s: CFI %s at offset 0x%llx in section '%s':"
1805
0
                 " the instruction at offset 0x%llx is unrecognized\n",
1806
0
                 filename_.c_str(), CallFrameInfo::KindName(kind),
1807
0
                 offset, section_.c_str(), insn_offset);
1808
0
  log_(buf);
1809
0
}
1810
1811
void CallFrameInfo::Reporter::NoCFARule(uint64 offset,
1812
                                        CallFrameInfo::EntryKind kind,
1813
0
                                        uint64 insn_offset) {
1814
0
  char buf[300];
1815
0
  SprintfLiteral(buf,
1816
0
                 "%s: CFI %s at offset 0x%llx in section '%s':"
1817
0
                 " the instruction at offset 0x%llx assumes that a CFA rule "
1818
0
                 "has been set, but none has been set\n",
1819
0
                 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1820
0
                 section_.c_str(), insn_offset);
1821
0
  log_(buf);
1822
0
}
1823
1824
void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset,
1825
                                              CallFrameInfo::EntryKind kind,
1826
0
                                              uint64 insn_offset) {
1827
0
  char buf[300];
1828
0
  SprintfLiteral(buf,
1829
0
                 "%s: CFI %s at offset 0x%llx in section '%s':"
1830
0
                 " the DW_CFA_restore_state instruction at offset 0x%llx"
1831
0
                 " should pop a saved state from the stack, but the stack "
1832
0
                 "is empty\n",
1833
0
                 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1834
0
                 section_.c_str(), insn_offset);
1835
0
  log_(buf);
1836
0
}
1837
1838
void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset,
1839
                                              CallFrameInfo::EntryKind kind,
1840
0
                                              uint64 insn_offset) {
1841
0
  char buf[300];
1842
0
  SprintfLiteral(buf,
1843
0
                 "%s: CFI %s at offset 0x%llx in section '%s':"
1844
0
                 " the DW_CFA_restore_state instruction at offset 0x%llx"
1845
0
                 " would clear the CFA rule in effect\n",
1846
0
                 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
1847
0
                 section_.c_str(), insn_offset);
1848
0
  log_(buf);
1849
0
}
1850
1851
1852
0
unsigned int DwarfCFIToModule::RegisterNames::I386() {
1853
0
  /*
1854
0
   8 "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
1855
0
   3 "$eip", "$eflags", "$unused1",
1856
0
   8 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
1857
0
   2 "$unused2", "$unused3",
1858
0
   8 "$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
1859
0
   8 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
1860
0
   3 "$fcw", "$fsw", "$mxcsr",
1861
0
   8 "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5",
1862
0
   2 "$tr", "$ldtr"
1863
0
  */
1864
0
  return 8 + 3 + 8 + 2 + 8 + 8 + 3 + 8 + 2;
1865
0
}
1866
1867
0
unsigned int DwarfCFIToModule::RegisterNames::X86_64() {
1868
0
  /*
1869
0
   8 "$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp",
1870
0
   8 "$r8",  "$r9",  "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
1871
0
   1 "$rip",
1872
0
   8 "$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
1873
0
   8 "$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15",
1874
0
   8 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
1875
0
   8 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
1876
0
   1 "$rflags",
1877
0
   8 "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2",
1878
0
   4 "$fs.base", "$gs.base", "$unused3", "$unused4",
1879
0
   2 "$tr", "$ldtr",
1880
0
   3 "$mxcsr", "$fcw", "$fsw"
1881
0
  */
1882
0
  return 8 + 8 + 1 + 8 + 8 + 8 + 8 + 1 + 8 + 4 + 2 + 3;
1883
0
}
1884
1885
// Per ARM IHI 0040A, section 3.1
1886
0
unsigned int DwarfCFIToModule::RegisterNames::ARM() {
1887
0
  /*
1888
0
   8 "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
1889
0
   8 "r8",  "r9",  "r10", "r11", "r12", "sp",  "lr",  "pc",
1890
0
   8 "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1891
0
   8 "fps", "cpsr", "",   "",    "",    "",    "",    "",
1892
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1893
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1894
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1895
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1896
0
   8 "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",
1897
0
   8 "s8",  "s9",  "s10", "s11", "s12", "s13", "s14", "s15",
1898
0
   8 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
1899
0
   8 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1900
0
   8 "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7"
1901
0
  */
1902
0
  return 13 * 8;
1903
0
}
1904
1905
// Per ARM IHI 0057A, section 3.1
1906
0
unsigned int DwarfCFIToModule::RegisterNames::ARM64() {
1907
0
  /*
1908
0
   8 "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
1909
0
   8 "x8",  "x9",  "x10", "x11", "x12", "x13", "x14", "x15",
1910
0
   8 "x16"  "x17", "x18", "x19", "x20", "x21", "x22", "x23",
1911
0
   8 "x24", "x25", "x26", "x27", "x28", "x29",  "x30","sp",
1912
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1913
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1914
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1915
0
   8 "",    "",    "",    "",    "",    "",    "",    "",
1916
0
   8 "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
1917
0
   8 "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
1918
0
   8 "v16", "v17", "v18", "v19", "v20", "v21", "v22,  "v23",
1919
0
   8 "v24", "x25", "x26,  "x27", "v28", "v29", "v30", "v31",
1920
0
  */
1921
0
  return 12 * 8;
1922
0
}
1923
1924
0
unsigned int DwarfCFIToModule::RegisterNames::MIPS() {
1925
0
  /*
1926
0
   8 "$zero", "$at",  "$v0",  "$v1",  "$a0",   "$a1",  "$a2",  "$a3",
1927
0
   8 "$t0",   "$t1",  "$t2",  "$t3",  "$t4",   "$t5",  "$t6",  "$t7",
1928
0
   8 "$s0",   "$s1",  "$s2",  "$s3",  "$s4",   "$s5",  "$s6",  "$s7",
1929
0
   8 "$t8",   "$t9",  "$k0",  "$k1",  "$gp",   "$sp",  "$fp",  "$ra",
1930
0
   9 "$lo",   "$hi",  "$pc",  "$f0",  "$f1",   "$f2",  "$f3",  "$f4",  "$f5",
1931
0
   8 "$f6",   "$f7",  "$f8",  "$f9",  "$f10",  "$f11", "$f12", "$f13",
1932
0
   7 "$f14",  "$f15", "$f16", "$f17", "$f18",  "$f19", "$f20",
1933
0
   7 "$f21",  "$f22", "$f23", "$f24", "$f25",  "$f26", "$f27",
1934
0
   6 "$f28",  "$f29", "$f30", "$f31", "$fcsr", "$fir"
1935
0
  */
1936
0
  return 8 + 8 + 8 + 8 + 9 + 8 + 7 + 7 + 6;
1937
0
}
1938
1939
// See prototype for comments.
1940
int32_t parseDwarfExpr(Summariser* summ, const ByteReader* reader,
1941
                       string expr, bool debug,
1942
                       bool pushCfaAtStart, bool derefAtEnd)
1943
0
{
1944
0
  const char* cursor = expr.c_str();
1945
0
  const char* end1   = cursor + expr.length();
1946
0
1947
0
  char buf[100];
1948
0
  if (debug) {
1949
0
    SprintfLiteral(buf, "LUL.DW  << DwarfExpr, len is %d\n",
1950
0
                   (int)(end1 - cursor));
1951
0
    summ->Log(buf);
1952
0
  }
1953
0
1954
0
  // Add a marker for the start of this expression.  In it, indicate
1955
0
  // whether or not the CFA should be pushed onto the stack prior to
1956
0
  // evaluation.
1957
0
  int32_t start_ix
1958
0
    = summ->AddPfxInstr(PfxInstr(PX_Start, pushCfaAtStart ? 1 : 0));
1959
0
  MOZ_ASSERT(start_ix >= 0);
1960
0
1961
0
  while (cursor < end1) {
1962
0
1963
0
    uint8 opc = reader->ReadOneByte(cursor);
1964
0
    cursor++;
1965
0
1966
0
    const char* nm   = nullptr;
1967
0
    PfxExprOp   pxop = PX_End;
1968
0
1969
0
    switch (opc) {
1970
0
1971
0
      case DW_OP_lit0 ... DW_OP_lit31: {
1972
0
        int32_t simm32 = (int32_t)(opc - DW_OP_lit0);
1973
0
        if (debug) {
1974
0
          SprintfLiteral(buf, "LUL.DW   DW_OP_lit%d\n", (int)simm32);
1975
0
          summ->Log(buf);
1976
0
        }
1977
0
        (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, simm32));
1978
0
        break;
1979
0
      }
1980
0
1981
0
      case DW_OP_breg0 ... DW_OP_breg31: {
1982
0
        size_t len;
1983
0
        int64_t n = reader->ReadSignedLEB128(cursor, &len);
1984
0
        cursor += len;
1985
0
        DW_REG_NUMBER reg = (DW_REG_NUMBER)(opc - DW_OP_breg0);
1986
0
        if (debug) {
1987
0
          SprintfLiteral(buf, "LUL.DW   DW_OP_breg%d %lld\n",
1988
0
                         (int)reg, (long long int)n);
1989
0
          summ->Log(buf);
1990
0
        }
1991
0
        // PfxInstr only allows a 32 bit signed offset.  So we
1992
0
        // must fail if the immediate is out of range.
1993
0
        if (n < INT32_MIN || INT32_MAX < n)
1994
0
          goto fail;
1995
0
        (void) summ->AddPfxInstr(PfxInstr(PX_DwReg, reg));
1996
0
        (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, (int32_t)n));
1997
0
        (void) summ->AddPfxInstr(PfxInstr(PX_Add));
1998
0
        break;
1999
0
      }
2000
0
2001
0
      case DW_OP_const4s: {
2002
0
        uint64_t u64 = reader->ReadFourBytes(cursor);
2003
0
        cursor += 4;
2004
0
        // u64 is guaranteed by |ReadFourBytes| to be in the
2005
0
        // range 0 .. FFFFFFFF inclusive.  But to be safe:
2006
0
        uint32_t u32 = (uint32_t)(u64 & 0xFFFFFFFF);
2007
0
        int32_t  s32 = (int32_t)u32;
2008
0
        if (debug) {
2009
0
          SprintfLiteral(buf, "LUL.DW   DW_OP_const4s %d\n", (int)s32);
2010
0
          summ->Log(buf);
2011
0
        }
2012
0
        (void) summ->AddPfxInstr(PfxInstr(PX_SImm32, s32));
2013
0
        break;
2014
0
      }
2015
0
2016
0
      case DW_OP_deref: nm = "deref"; pxop = PX_Deref;  goto no_operands;
2017
0
      case DW_OP_and:   nm = "and";   pxop = PX_And;    goto no_operands;
2018
0
      case DW_OP_plus:  nm = "plus";  pxop = PX_Add;    goto no_operands;
2019
0
      case DW_OP_minus: nm = "minus"; pxop = PX_Sub;    goto no_operands;
2020
0
      case DW_OP_shl:   nm = "shl";   pxop = PX_Shl;    goto no_operands;
2021
0
      case DW_OP_ge:    nm = "ge";    pxop = PX_CmpGES; goto no_operands;
2022
0
      no_operands:
2023
0
        MOZ_ASSERT(nm && pxop != PX_End);
2024
0
        if (debug) {
2025
0
          SprintfLiteral(buf, "LUL.DW   DW_OP_%s\n", nm);
2026
0
          summ->Log(buf);
2027
0
        }
2028
0
        (void) summ->AddPfxInstr(PfxInstr(pxop));
2029
0
        break;
2030
0
2031
0
      default:
2032
0
        if (debug) {
2033
0
          SprintfLiteral(buf, "LUL.DW   unknown opc %d\n", (int)opc);
2034
0
          summ->Log(buf);
2035
0
        }
2036
0
        goto fail;
2037
0
2038
0
    } // switch (opc)
2039
0
2040
0
  } // while (cursor < end1)
2041
0
2042
0
  MOZ_ASSERT(cursor >= end1);
2043
0
2044
0
  if (cursor > end1) {
2045
0
    // We overran the Dwarf expression.  Give up.
2046
0
    goto fail;
2047
0
  }
2048
0
2049
0
  // For DW_CFA_expression, what the expression denotes is the address
2050
0
  // of where the previous value is located.  The caller of this routine
2051
0
  // may therefore request one last dereference before the end marker is
2052
0
  // inserted.
2053
0
  if (derefAtEnd) {
2054
0
    (void) summ->AddPfxInstr(PfxInstr(PX_Deref));
2055
0
  }
2056
0
2057
0
  // Insert an end marker, and declare success.
2058
0
  (void) summ->AddPfxInstr(PfxInstr(PX_End));
2059
0
  if (debug) {
2060
0
    SprintfLiteral(buf, "LUL.DW   conversion of dwarf expression succeeded, "
2061
0
                        "ix = %d\n", (int)start_ix);
2062
0
    summ->Log(buf);
2063
0
    summ->Log("LUL.DW  >>\n");
2064
0
  }
2065
0
  return start_ix;
2066
0
2067
0
 fail:
2068
0
  if (debug) {
2069
0
    summ->Log("LUL.DW   conversion of dwarf expression failed\n");
2070
0
    summ->Log("LUL.DW  >>\n");
2071
0
  }
2072
0
  return -1;
2073
0
}
2074
2075
2076
bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length,
2077
                             uint8 version, const string &augmentation,
2078
0
                             unsigned return_address) {
2079
0
  if (DEBUG_DWARF) {
2080
0
    char buf[100];
2081
0
    SprintfLiteral(buf, "LUL.DW DwarfCFIToModule::Entry 0x%llx,+%lld\n",
2082
0
                   address, length);
2083
0
    summ_->Log(buf);
2084
0
  }
2085
0
2086
0
  summ_->Entry(address, length);
2087
0
2088
0
  // If dwarf2reader::CallFrameInfo can handle this version and
2089
0
  // augmentation, then we should be okay with that, so there's no
2090
0
  // need to check them here.
2091
0
2092
0
  // Get ready to collect entries.
2093
0
  return_address_ = return_address;
2094
0
2095
0
  // Breakpad STACK CFI records must provide a .ra rule, but DWARF CFI
2096
0
  // may not establish any rule for .ra if the return address column
2097
0
  // is an ordinary register, and that register holds the return
2098
0
  // address on entry to the function. So establish an initial .ra
2099
0
  // rule citing the return address register.
2100
0
  if (return_address_ < num_dw_regs_) {
2101
0
    summ_->Rule(address, return_address_, NODEREF, return_address, 0);
2102
0
  }
2103
0
2104
0
  return true;
2105
0
}
2106
2107
0
const UniqueString* DwarfCFIToModule::RegisterName(int i) {
2108
0
  if (i < 0) {
2109
0
    MOZ_ASSERT(i == kCFARegister);
2110
0
    return usu_->ToUniqueString(".cfa");
2111
0
  }
2112
0
  unsigned reg = i;
2113
0
  if (reg == return_address_)
2114
0
    return usu_->ToUniqueString(".ra");
2115
0
2116
0
  char buf[30];
2117
0
  SprintfLiteral(buf, "dwarf_reg_%u", reg);
2118
0
  return usu_->ToUniqueString(buf);
2119
0
}
2120
2121
0
bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) {
2122
0
  reporter_->UndefinedNotSupported(entry_offset_, RegisterName(reg));
2123
0
  // Treat this as a non-fatal error.
2124
0
  return true;
2125
0
}
2126
2127
0
bool DwarfCFIToModule::SameValueRule(uint64 address, int reg) {
2128
0
  if (DEBUG_DWARF) {
2129
0
    char buf[100];
2130
0
    SprintfLiteral(buf, "LUL.DW  0x%llx: old r%d = Same\n", address, reg);
2131
0
    summ_->Log(buf);
2132
0
  }
2133
0
  // reg + 0
2134
0
  summ_->Rule(address, reg, NODEREF, reg, 0);
2135
0
  return true;
2136
0
}
2137
2138
bool DwarfCFIToModule::OffsetRule(uint64 address, int reg,
2139
0
                                  int base_register, long offset) {
2140
0
  if (DEBUG_DWARF) {
2141
0
    char buf[100];
2142
0
    SprintfLiteral(buf, "LUL.DW  0x%llx: old r%d = *(r%d + %ld)\n",
2143
0
                   address, reg, base_register, offset);
2144
0
    summ_->Log(buf);
2145
0
  }
2146
0
  // *(base_register + offset)
2147
0
  summ_->Rule(address, reg, DEREF, base_register, offset);
2148
0
  return true;
2149
0
}
2150
2151
bool DwarfCFIToModule::ValOffsetRule(uint64 address, int reg,
2152
0
                                     int base_register, long offset) {
2153
0
  if (DEBUG_DWARF) {
2154
0
    char buf[100];
2155
0
    SprintfLiteral(buf, "LUL.DW  0x%llx: old r%d = r%d + %ld\n",
2156
0
                   address, reg, base_register, offset);
2157
0
    summ_->Log(buf);
2158
0
  }
2159
0
  // base_register + offset
2160
0
  summ_->Rule(address, reg, NODEREF, base_register, offset);
2161
0
  return true;
2162
0
}
2163
2164
bool DwarfCFIToModule::RegisterRule(uint64 address, int reg,
2165
0
                                    int base_register) {
2166
0
  if (DEBUG_DWARF) {
2167
0
    char buf[100];
2168
0
    SprintfLiteral(buf, "LUL.DW  0x%llx: old r%d = r%d\n",
2169
0
                   address, reg, base_register);
2170
0
    summ_->Log(buf);
2171
0
  }
2172
0
  // base_register + 0
2173
0
  summ_->Rule(address, reg, NODEREF, base_register, 0);
2174
0
  return true;
2175
0
}
2176
2177
bool DwarfCFIToModule::ExpressionRule(uint64 address, int reg,
2178
                                      const string &expression)
2179
0
{
2180
0
  bool debug = !!DEBUG_DWARF;
2181
0
  int32_t start_ix = parseDwarfExpr(summ_, reader_, expression, debug,
2182
0
                                    true/*pushCfaAtStart*/,
2183
0
                                    true/*derefAtEnd*/);
2184
0
  if (start_ix >= 0) {
2185
0
    summ_->Rule(address, reg, PFXEXPR, 0, start_ix);
2186
0
  } else {
2187
0
    // Parsing of the Dwarf expression failed.  Treat this as a
2188
0
    // non-fatal error, hence return |true| even on this path.
2189
0
    reporter_->ExpressionCouldNotBeSummarised(entry_offset_, RegisterName(reg));
2190
0
  }
2191
0
  return true;
2192
0
}
2193
2194
bool DwarfCFIToModule::ValExpressionRule(uint64 address, int reg,
2195
                                         const string &expression)
2196
0
{
2197
0
  bool debug = !!DEBUG_DWARF;
2198
0
  int32_t start_ix = parseDwarfExpr(summ_, reader_, expression, debug,
2199
0
                                    true/*pushCfaAtStart*/,
2200
0
                                    false/*!derefAtEnd*/);
2201
0
  if (start_ix >= 0) {
2202
0
    summ_->Rule(address, reg, PFXEXPR, 0, start_ix);
2203
0
  } else {
2204
0
    // Parsing of the Dwarf expression failed.  Treat this as a
2205
0
    // non-fatal error, hence return |true| even on this path.
2206
0
    reporter_->ExpressionCouldNotBeSummarised(entry_offset_, RegisterName(reg));
2207
0
  }
2208
0
  return true;
2209
0
}
2210
2211
0
bool DwarfCFIToModule::End() {
2212
0
  //module_->AddStackFrameEntry(entry_);
2213
0
  if (DEBUG_DWARF) {
2214
0
    summ_->Log("LUL.DW DwarfCFIToModule::End()\n");
2215
0
  }
2216
0
  summ_->End();
2217
0
  return true;
2218
0
}
2219
2220
void DwarfCFIToModule::Reporter::UndefinedNotSupported(
2221
    size_t offset,
2222
0
    const UniqueString* reg) {
2223
0
  char buf[300];
2224
0
  SprintfLiteral(buf, "DwarfCFIToModule::Reporter::UndefinedNotSupported()\n");
2225
0
  log_(buf);
2226
0
  //BPLOG(INFO) << file_ << ", section '" << section_
2227
0
  //  << "': the call frame entry at offset 0x"
2228
0
  //  << std::setbase(16) << offset << std::setbase(10)
2229
0
  //  << " sets the rule for register '" << FromUniqueString(reg)
2230
0
  //  << "' to 'undefined', but the Breakpad symbol file format cannot "
2231
0
  //  << " express this";
2232
0
}
2233
2234
// FIXME: move this somewhere sensible
2235
static bool is_power_of_2(uint64_t n)
2236
0
{
2237
0
  int i, nSetBits = 0;
2238
0
  for (i = 0; i < 8*(int)sizeof(n); i++) {
2239
0
    if ((n & ((uint64_t)1) << i) != 0)
2240
0
      nSetBits++;
2241
0
  }
2242
0
  return nSetBits <= 1;
2243
0
}
2244
2245
void DwarfCFIToModule::Reporter::ExpressionCouldNotBeSummarised(
2246
    size_t offset,
2247
0
    const UniqueString* reg) {
2248
0
  static uint64_t n_complaints = 0; // This isn't threadsafe
2249
0
  n_complaints++;
2250
0
  if (!is_power_of_2(n_complaints))
2251
0
    return;
2252
0
  char buf[300];
2253
0
  SprintfLiteral(buf,
2254
0
                 "DwarfCFIToModule::Reporter::"
2255
0
                 "ExpressionCouldNotBeSummarised(shown %llu times)\n",
2256
0
                 (unsigned long long int)n_complaints);
2257
0
  log_(buf);
2258
0
}
2259
2260
} // namespace lul