1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // CFI reader author: Jim Blandy <[email protected]> <[email protected]>
30*9712c20fSFrederick Mayle
31*9712c20fSFrederick Mayle // Implementation of LineInfo, CompilationUnit,
32*9712c20fSFrederick Mayle // and CallFrameInfo. See dwarf2reader.h for details.
33*9712c20fSFrederick Mayle
34*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
35*9712c20fSFrederick Mayle #include <config.h> // Must come first
36*9712c20fSFrederick Mayle #endif
37*9712c20fSFrederick Mayle
38*9712c20fSFrederick Mayle #include "common/dwarf/dwarf2reader.h"
39*9712c20fSFrederick Mayle
40*9712c20fSFrederick Mayle #include <stdint.h>
41*9712c20fSFrederick Mayle #include <stdio.h>
42*9712c20fSFrederick Mayle #include <string.h>
43*9712c20fSFrederick Mayle
44*9712c20fSFrederick Mayle #include <algorithm>
45*9712c20fSFrederick Mayle #include <map>
46*9712c20fSFrederick Mayle #include <memory>
47*9712c20fSFrederick Mayle #include <stack>
48*9712c20fSFrederick Mayle #include <string>
49*9712c20fSFrederick Mayle #include <utility>
50*9712c20fSFrederick Mayle
51*9712c20fSFrederick Mayle #include <sys/stat.h>
52*9712c20fSFrederick Mayle
53*9712c20fSFrederick Mayle #include "common/dwarf/bytereader-inl.h"
54*9712c20fSFrederick Mayle #include "common/dwarf/bytereader.h"
55*9712c20fSFrederick Mayle #include "common/dwarf/line_state_machine.h"
56*9712c20fSFrederick Mayle #include "common/using_std_string.h"
57*9712c20fSFrederick Mayle #include "google_breakpad/common/breakpad_types.h"
58*9712c20fSFrederick Mayle
59*9712c20fSFrederick Mayle namespace google_breakpad {
60*9712c20fSFrederick Mayle
GetSectionByName(const SectionMap & sections,const char * name)61*9712c20fSFrederick Mayle const SectionMap::const_iterator GetSectionByName(const SectionMap&
62*9712c20fSFrederick Mayle sections, const char *name) {
63*9712c20fSFrederick Mayle assert(name[0] == '.');
64*9712c20fSFrederick Mayle auto iter = sections.find(name);
65*9712c20fSFrederick Mayle if (iter != sections.end())
66*9712c20fSFrederick Mayle return iter;
67*9712c20fSFrederick Mayle std::string macho_name("__");
68*9712c20fSFrederick Mayle macho_name += name + 1;
69*9712c20fSFrederick Mayle iter = sections.find(macho_name);
70*9712c20fSFrederick Mayle return iter;
71*9712c20fSFrederick Mayle }
72*9712c20fSFrederick Mayle
CompilationUnit(const string & path,const SectionMap & sections,uint64_t offset,ByteReader * reader,Dwarf2Handler * handler)73*9712c20fSFrederick Mayle CompilationUnit::CompilationUnit(const string& path,
74*9712c20fSFrederick Mayle const SectionMap& sections, uint64_t offset,
75*9712c20fSFrederick Mayle ByteReader* reader, Dwarf2Handler* handler)
76*9712c20fSFrederick Mayle : path_(path), offset_from_section_start_(offset), reader_(reader),
77*9712c20fSFrederick Mayle sections_(sections), handler_(handler), abbrevs_(),
78*9712c20fSFrederick Mayle string_buffer_(NULL), string_buffer_length_(0),
79*9712c20fSFrederick Mayle line_string_buffer_(NULL), line_string_buffer_length_(0),
80*9712c20fSFrederick Mayle str_offsets_buffer_(NULL), str_offsets_buffer_length_(0),
81*9712c20fSFrederick Mayle addr_buffer_(NULL), addr_buffer_length_(0),
82*9712c20fSFrederick Mayle is_split_dwarf_(false), is_type_unit_(false), dwo_id_(0), dwo_name_(),
83*9712c20fSFrederick Mayle skeleton_dwo_id_(0), addr_base_(0),
84*9712c20fSFrederick Mayle str_offsets_base_(0), have_checked_for_dwp_(false),
85*9712c20fSFrederick Mayle should_process_split_dwarf_(false), low_pc_(0),
86*9712c20fSFrederick Mayle has_source_line_info_(false), source_line_offset_(0) {}
87*9712c20fSFrederick Mayle
88*9712c20fSFrederick Mayle // Initialize a compilation unit from a .dwo or .dwp file.
89*9712c20fSFrederick Mayle // In this case, we need the .debug_addr section from the
90*9712c20fSFrederick Mayle // executable file that contains the corresponding skeleton
91*9712c20fSFrederick Mayle // compilation unit. We also inherit the Dwarf2Handler from
92*9712c20fSFrederick Mayle // the executable file, and call it as if we were still
93*9712c20fSFrederick Mayle // processing the original compilation unit.
94*9712c20fSFrederick Mayle
SetSplitDwarf(uint64_t addr_base,uint64_t dwo_id)95*9712c20fSFrederick Mayle void CompilationUnit::SetSplitDwarf(uint64_t addr_base,
96*9712c20fSFrederick Mayle uint64_t dwo_id) {
97*9712c20fSFrederick Mayle is_split_dwarf_ = true;
98*9712c20fSFrederick Mayle addr_base_ = addr_base;
99*9712c20fSFrederick Mayle skeleton_dwo_id_ = dwo_id;
100*9712c20fSFrederick Mayle }
101*9712c20fSFrederick Mayle
102*9712c20fSFrederick Mayle // Read a DWARF2/3 abbreviation section.
103*9712c20fSFrederick Mayle // Each abbrev consists of a abbreviation number, a tag, a byte
104*9712c20fSFrederick Mayle // specifying whether the tag has children, and a list of
105*9712c20fSFrederick Mayle // attribute/form pairs.
106*9712c20fSFrederick Mayle // The list of forms is terminated by a 0 for the attribute, and a
107*9712c20fSFrederick Mayle // zero for the form. The entire abbreviation section is terminated
108*9712c20fSFrederick Mayle // by a zero for the code.
109*9712c20fSFrederick Mayle
ReadAbbrevs()110*9712c20fSFrederick Mayle void CompilationUnit::ReadAbbrevs() {
111*9712c20fSFrederick Mayle if (abbrevs_)
112*9712c20fSFrederick Mayle return;
113*9712c20fSFrederick Mayle
114*9712c20fSFrederick Mayle // First get the debug_abbrev section.
115*9712c20fSFrederick Mayle SectionMap::const_iterator iter =
116*9712c20fSFrederick Mayle GetSectionByName(sections_, ".debug_abbrev");
117*9712c20fSFrederick Mayle assert(iter != sections_.end());
118*9712c20fSFrederick Mayle
119*9712c20fSFrederick Mayle abbrevs_ = new std::vector<Abbrev>;
120*9712c20fSFrederick Mayle abbrevs_->resize(1);
121*9712c20fSFrederick Mayle
122*9712c20fSFrederick Mayle // The only way to check whether we are reading over the end of the
123*9712c20fSFrederick Mayle // buffer would be to first compute the size of the leb128 data by
124*9712c20fSFrederick Mayle // reading it, then go back and read it again.
125*9712c20fSFrederick Mayle const uint8_t* abbrev_start = iter->second.first +
126*9712c20fSFrederick Mayle header_.abbrev_offset;
127*9712c20fSFrederick Mayle const uint8_t* abbrevptr = abbrev_start;
128*9712c20fSFrederick Mayle #ifndef NDEBUG
129*9712c20fSFrederick Mayle const uint64_t abbrev_length = iter->second.second - header_.abbrev_offset;
130*9712c20fSFrederick Mayle #endif
131*9712c20fSFrederick Mayle
132*9712c20fSFrederick Mayle uint64_t highest_number = 0;
133*9712c20fSFrederick Mayle
134*9712c20fSFrederick Mayle while (1) {
135*9712c20fSFrederick Mayle CompilationUnit::Abbrev abbrev;
136*9712c20fSFrederick Mayle size_t len;
137*9712c20fSFrederick Mayle const uint64_t number = reader_->ReadUnsignedLEB128(abbrevptr, &len);
138*9712c20fSFrederick Mayle highest_number = std::max(highest_number, number);
139*9712c20fSFrederick Mayle
140*9712c20fSFrederick Mayle if (number == 0)
141*9712c20fSFrederick Mayle break;
142*9712c20fSFrederick Mayle abbrev.number = number;
143*9712c20fSFrederick Mayle abbrevptr += len;
144*9712c20fSFrederick Mayle
145*9712c20fSFrederick Mayle assert(abbrevptr < abbrev_start + abbrev_length);
146*9712c20fSFrederick Mayle const uint64_t tag = reader_->ReadUnsignedLEB128(abbrevptr, &len);
147*9712c20fSFrederick Mayle abbrevptr += len;
148*9712c20fSFrederick Mayle abbrev.tag = static_cast<enum DwarfTag>(tag);
149*9712c20fSFrederick Mayle
150*9712c20fSFrederick Mayle assert(abbrevptr < abbrev_start + abbrev_length);
151*9712c20fSFrederick Mayle abbrev.has_children = reader_->ReadOneByte(abbrevptr);
152*9712c20fSFrederick Mayle abbrevptr += 1;
153*9712c20fSFrederick Mayle
154*9712c20fSFrederick Mayle assert(abbrevptr < abbrev_start + abbrev_length);
155*9712c20fSFrederick Mayle
156*9712c20fSFrederick Mayle while (1) {
157*9712c20fSFrederick Mayle const uint64_t nametemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
158*9712c20fSFrederick Mayle abbrevptr += len;
159*9712c20fSFrederick Mayle
160*9712c20fSFrederick Mayle assert(abbrevptr < abbrev_start + abbrev_length);
161*9712c20fSFrederick Mayle const uint64_t formtemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
162*9712c20fSFrederick Mayle abbrevptr += len;
163*9712c20fSFrederick Mayle if (nametemp == 0 && formtemp == 0)
164*9712c20fSFrederick Mayle break;
165*9712c20fSFrederick Mayle
166*9712c20fSFrederick Mayle uint64_t value = 0;
167*9712c20fSFrederick Mayle if (formtemp == DW_FORM_implicit_const) {
168*9712c20fSFrederick Mayle value = reader_->ReadUnsignedLEB128(abbrevptr, &len);
169*9712c20fSFrederick Mayle abbrevptr += len;
170*9712c20fSFrederick Mayle }
171*9712c20fSFrederick Mayle AttrForm abbrev_attr(static_cast<enum DwarfAttribute>(nametemp),
172*9712c20fSFrederick Mayle static_cast<enum DwarfForm>(formtemp),
173*9712c20fSFrederick Mayle value);
174*9712c20fSFrederick Mayle abbrev.attributes.push_back(abbrev_attr);
175*9712c20fSFrederick Mayle }
176*9712c20fSFrederick Mayle abbrevs_->push_back(abbrev);
177*9712c20fSFrederick Mayle }
178*9712c20fSFrederick Mayle
179*9712c20fSFrederick Mayle // Account of cases where entries are out of order.
180*9712c20fSFrederick Mayle std::sort(abbrevs_->begin(), abbrevs_->end(),
181*9712c20fSFrederick Mayle [](const CompilationUnit::Abbrev& lhs, const CompilationUnit::Abbrev& rhs) {
182*9712c20fSFrederick Mayle return lhs.number < rhs.number;
183*9712c20fSFrederick Mayle });
184*9712c20fSFrederick Mayle
185*9712c20fSFrederick Mayle // Ensure that there are no missing sections.
186*9712c20fSFrederick Mayle assert(abbrevs_->size() == highest_number + 1);
187*9712c20fSFrederick Mayle }
188*9712c20fSFrederick Mayle
189*9712c20fSFrederick Mayle // Skips a single DIE's attributes.
SkipDIE(const uint8_t * start,const Abbrev & abbrev)190*9712c20fSFrederick Mayle const uint8_t* CompilationUnit::SkipDIE(const uint8_t* start,
191*9712c20fSFrederick Mayle const Abbrev& abbrev) {
192*9712c20fSFrederick Mayle for (AttributeList::const_iterator i = abbrev.attributes.begin();
193*9712c20fSFrederick Mayle i != abbrev.attributes.end();
194*9712c20fSFrederick Mayle i++) {
195*9712c20fSFrederick Mayle start = SkipAttribute(start, i->form_);
196*9712c20fSFrederick Mayle }
197*9712c20fSFrederick Mayle return start;
198*9712c20fSFrederick Mayle }
199*9712c20fSFrederick Mayle
200*9712c20fSFrederick Mayle // Skips a single attribute form's data.
SkipAttribute(const uint8_t * start,enum DwarfForm form)201*9712c20fSFrederick Mayle const uint8_t* CompilationUnit::SkipAttribute(const uint8_t* start,
202*9712c20fSFrederick Mayle enum DwarfForm form) {
203*9712c20fSFrederick Mayle size_t len;
204*9712c20fSFrederick Mayle
205*9712c20fSFrederick Mayle switch (form) {
206*9712c20fSFrederick Mayle case DW_FORM_indirect:
207*9712c20fSFrederick Mayle form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
208*9712c20fSFrederick Mayle &len));
209*9712c20fSFrederick Mayle start += len;
210*9712c20fSFrederick Mayle return SkipAttribute(start, form);
211*9712c20fSFrederick Mayle
212*9712c20fSFrederick Mayle case DW_FORM_flag_present:
213*9712c20fSFrederick Mayle case DW_FORM_implicit_const:
214*9712c20fSFrederick Mayle return start;
215*9712c20fSFrederick Mayle case DW_FORM_addrx1:
216*9712c20fSFrederick Mayle case DW_FORM_data1:
217*9712c20fSFrederick Mayle case DW_FORM_flag:
218*9712c20fSFrederick Mayle case DW_FORM_ref1:
219*9712c20fSFrederick Mayle case DW_FORM_strx1:
220*9712c20fSFrederick Mayle return start + 1;
221*9712c20fSFrederick Mayle case DW_FORM_addrx2:
222*9712c20fSFrederick Mayle case DW_FORM_ref2:
223*9712c20fSFrederick Mayle case DW_FORM_data2:
224*9712c20fSFrederick Mayle case DW_FORM_strx2:
225*9712c20fSFrederick Mayle return start + 2;
226*9712c20fSFrederick Mayle case DW_FORM_addrx3:
227*9712c20fSFrederick Mayle case DW_FORM_strx3:
228*9712c20fSFrederick Mayle return start + 3;
229*9712c20fSFrederick Mayle case DW_FORM_addrx4:
230*9712c20fSFrederick Mayle case DW_FORM_ref4:
231*9712c20fSFrederick Mayle case DW_FORM_data4:
232*9712c20fSFrederick Mayle case DW_FORM_strx4:
233*9712c20fSFrederick Mayle case DW_FORM_ref_sup4:
234*9712c20fSFrederick Mayle return start + 4;
235*9712c20fSFrederick Mayle case DW_FORM_ref8:
236*9712c20fSFrederick Mayle case DW_FORM_data8:
237*9712c20fSFrederick Mayle case DW_FORM_ref_sig8:
238*9712c20fSFrederick Mayle case DW_FORM_ref_sup8:
239*9712c20fSFrederick Mayle return start + 8;
240*9712c20fSFrederick Mayle case DW_FORM_data16:
241*9712c20fSFrederick Mayle return start + 16;
242*9712c20fSFrederick Mayle case DW_FORM_string:
243*9712c20fSFrederick Mayle return start + strlen(reinterpret_cast<const char*>(start)) + 1;
244*9712c20fSFrederick Mayle case DW_FORM_udata:
245*9712c20fSFrederick Mayle case DW_FORM_ref_udata:
246*9712c20fSFrederick Mayle case DW_FORM_strx:
247*9712c20fSFrederick Mayle case DW_FORM_GNU_str_index:
248*9712c20fSFrederick Mayle case DW_FORM_GNU_addr_index:
249*9712c20fSFrederick Mayle case DW_FORM_addrx:
250*9712c20fSFrederick Mayle case DW_FORM_rnglistx:
251*9712c20fSFrederick Mayle case DW_FORM_loclistx:
252*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
253*9712c20fSFrederick Mayle return start + len;
254*9712c20fSFrederick Mayle
255*9712c20fSFrederick Mayle case DW_FORM_sdata:
256*9712c20fSFrederick Mayle reader_->ReadSignedLEB128(start, &len);
257*9712c20fSFrederick Mayle return start + len;
258*9712c20fSFrederick Mayle case DW_FORM_addr:
259*9712c20fSFrederick Mayle return start + reader_->AddressSize();
260*9712c20fSFrederick Mayle case DW_FORM_ref_addr:
261*9712c20fSFrederick Mayle // DWARF2 and 3/4 differ on whether ref_addr is address size or
262*9712c20fSFrederick Mayle // offset size.
263*9712c20fSFrederick Mayle assert(header_.version >= 2);
264*9712c20fSFrederick Mayle if (header_.version == 2) {
265*9712c20fSFrederick Mayle return start + reader_->AddressSize();
266*9712c20fSFrederick Mayle } else if (header_.version >= 3) {
267*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
268*9712c20fSFrederick Mayle }
269*9712c20fSFrederick Mayle break;
270*9712c20fSFrederick Mayle
271*9712c20fSFrederick Mayle case DW_FORM_block1:
272*9712c20fSFrederick Mayle return start + 1 + reader_->ReadOneByte(start);
273*9712c20fSFrederick Mayle case DW_FORM_block2:
274*9712c20fSFrederick Mayle return start + 2 + reader_->ReadTwoBytes(start);
275*9712c20fSFrederick Mayle case DW_FORM_block4:
276*9712c20fSFrederick Mayle return start + 4 + reader_->ReadFourBytes(start);
277*9712c20fSFrederick Mayle case DW_FORM_block:
278*9712c20fSFrederick Mayle case DW_FORM_exprloc: {
279*9712c20fSFrederick Mayle uint64_t size = reader_->ReadUnsignedLEB128(start, &len);
280*9712c20fSFrederick Mayle return start + size + len;
281*9712c20fSFrederick Mayle }
282*9712c20fSFrederick Mayle case DW_FORM_strp:
283*9712c20fSFrederick Mayle case DW_FORM_line_strp:
284*9712c20fSFrederick Mayle case DW_FORM_strp_sup:
285*9712c20fSFrederick Mayle case DW_FORM_sec_offset:
286*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
287*9712c20fSFrederick Mayle }
288*9712c20fSFrederick Mayle fprintf(stderr,"Unhandled form type");
289*9712c20fSFrederick Mayle return NULL;
290*9712c20fSFrederick Mayle }
291*9712c20fSFrederick Mayle
292*9712c20fSFrederick Mayle // Read the abbreviation offset from a compilation unit header.
ReadAbbrevOffset(const uint8_t * headerptr)293*9712c20fSFrederick Mayle size_t CompilationUnit::ReadAbbrevOffset(const uint8_t* headerptr) {
294*9712c20fSFrederick Mayle assert(headerptr + reader_->OffsetSize() < buffer_ + buffer_length_);
295*9712c20fSFrederick Mayle header_.abbrev_offset = reader_->ReadOffset(headerptr);
296*9712c20fSFrederick Mayle return reader_->OffsetSize();
297*9712c20fSFrederick Mayle }
298*9712c20fSFrederick Mayle
299*9712c20fSFrederick Mayle // Read the address size from a compilation unit header.
ReadAddressSize(const uint8_t * headerptr)300*9712c20fSFrederick Mayle size_t CompilationUnit::ReadAddressSize(const uint8_t* headerptr) {
301*9712c20fSFrederick Mayle // Compare against less than or equal because this may be the last
302*9712c20fSFrederick Mayle // section in the file.
303*9712c20fSFrederick Mayle assert(headerptr + 1 <= buffer_ + buffer_length_);
304*9712c20fSFrederick Mayle header_.address_size = reader_->ReadOneByte(headerptr);
305*9712c20fSFrederick Mayle reader_->SetAddressSize(header_.address_size);
306*9712c20fSFrederick Mayle return 1;
307*9712c20fSFrederick Mayle }
308*9712c20fSFrederick Mayle
309*9712c20fSFrederick Mayle // Read the DWO id from a split or skeleton compilation unit header.
ReadDwoId(const uint8_t * headerptr)310*9712c20fSFrederick Mayle size_t CompilationUnit::ReadDwoId(const uint8_t* headerptr) {
311*9712c20fSFrederick Mayle assert(headerptr + 8 <= buffer_ + buffer_length_);
312*9712c20fSFrederick Mayle dwo_id_ = reader_->ReadEightBytes(headerptr);
313*9712c20fSFrederick Mayle return 8;
314*9712c20fSFrederick Mayle }
315*9712c20fSFrederick Mayle
316*9712c20fSFrederick Mayle // Read the type signature from a type or split type compilation unit header.
ReadTypeSignature(const uint8_t * headerptr)317*9712c20fSFrederick Mayle size_t CompilationUnit::ReadTypeSignature(const uint8_t* headerptr) {
318*9712c20fSFrederick Mayle assert(headerptr + 8 <= buffer_ + buffer_length_);
319*9712c20fSFrederick Mayle type_signature_ = reader_->ReadEightBytes(headerptr);
320*9712c20fSFrederick Mayle return 8;
321*9712c20fSFrederick Mayle }
322*9712c20fSFrederick Mayle
323*9712c20fSFrederick Mayle // Read the DWO id from a split or skeleton compilation unit header.
ReadTypeOffset(const uint8_t * headerptr)324*9712c20fSFrederick Mayle size_t CompilationUnit::ReadTypeOffset(const uint8_t* headerptr) {
325*9712c20fSFrederick Mayle assert(headerptr + reader_->OffsetSize() < buffer_ + buffer_length_);
326*9712c20fSFrederick Mayle type_offset_ = reader_->ReadOffset(headerptr);
327*9712c20fSFrederick Mayle return reader_->OffsetSize();
328*9712c20fSFrederick Mayle }
329*9712c20fSFrederick Mayle
330*9712c20fSFrederick Mayle
331*9712c20fSFrederick Mayle // Read a DWARF header. The header is variable length in DWARF3 and DWARF4
332*9712c20fSFrederick Mayle // (and DWARF2 as extended by most compilers), and consists of an length
333*9712c20fSFrederick Mayle // field, a version number, the offset in the .debug_abbrev section for our
334*9712c20fSFrederick Mayle // abbrevs, and an address size. DWARF5 adds a unit_type to distinguish
335*9712c20fSFrederick Mayle // between partial-, full-, skeleton-, split-, and type- compilation units.
ReadHeader()336*9712c20fSFrederick Mayle void CompilationUnit::ReadHeader() {
337*9712c20fSFrederick Mayle const uint8_t* headerptr = buffer_;
338*9712c20fSFrederick Mayle size_t initial_length_size;
339*9712c20fSFrederick Mayle
340*9712c20fSFrederick Mayle assert(headerptr + 4 < buffer_ + buffer_length_);
341*9712c20fSFrederick Mayle const uint64_t initial_length
342*9712c20fSFrederick Mayle = reader_->ReadInitialLength(headerptr, &initial_length_size);
343*9712c20fSFrederick Mayle headerptr += initial_length_size;
344*9712c20fSFrederick Mayle header_.length = initial_length;
345*9712c20fSFrederick Mayle
346*9712c20fSFrederick Mayle assert(headerptr + 2 < buffer_ + buffer_length_);
347*9712c20fSFrederick Mayle header_.version = reader_->ReadTwoBytes(headerptr);
348*9712c20fSFrederick Mayle headerptr += 2;
349*9712c20fSFrederick Mayle
350*9712c20fSFrederick Mayle if (header_.version <= 4) {
351*9712c20fSFrederick Mayle // Older versions of dwarf have a relatively simple structure.
352*9712c20fSFrederick Mayle headerptr += ReadAbbrevOffset(headerptr);
353*9712c20fSFrederick Mayle headerptr += ReadAddressSize(headerptr);
354*9712c20fSFrederick Mayle } else {
355*9712c20fSFrederick Mayle // DWARF5 adds a unit_type field, and various fields based on unit_type.
356*9712c20fSFrederick Mayle assert(headerptr + 1 < buffer_ + buffer_length_);
357*9712c20fSFrederick Mayle uint8_t unit_type = reader_->ReadOneByte(headerptr);
358*9712c20fSFrederick Mayle headerptr += 1;
359*9712c20fSFrederick Mayle headerptr += ReadAddressSize(headerptr);
360*9712c20fSFrederick Mayle headerptr += ReadAbbrevOffset(headerptr);
361*9712c20fSFrederick Mayle switch (unit_type) {
362*9712c20fSFrederick Mayle case DW_UT_compile:
363*9712c20fSFrederick Mayle case DW_UT_partial:
364*9712c20fSFrederick Mayle // nothing else to read
365*9712c20fSFrederick Mayle break;
366*9712c20fSFrederick Mayle case DW_UT_skeleton:
367*9712c20fSFrederick Mayle case DW_UT_split_compile:
368*9712c20fSFrederick Mayle headerptr += ReadDwoId(headerptr);
369*9712c20fSFrederick Mayle break;
370*9712c20fSFrederick Mayle case DW_UT_type:
371*9712c20fSFrederick Mayle case DW_UT_split_type:
372*9712c20fSFrederick Mayle is_type_unit_ = true;
373*9712c20fSFrederick Mayle headerptr += ReadTypeSignature(headerptr);
374*9712c20fSFrederick Mayle headerptr += ReadTypeOffset(headerptr);
375*9712c20fSFrederick Mayle break;
376*9712c20fSFrederick Mayle default:
377*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled compilation unit type 0x%x", unit_type);
378*9712c20fSFrederick Mayle break;
379*9712c20fSFrederick Mayle }
380*9712c20fSFrederick Mayle }
381*9712c20fSFrederick Mayle after_header_ = headerptr;
382*9712c20fSFrederick Mayle
383*9712c20fSFrederick Mayle // This check ensures that we don't have to do checking during the
384*9712c20fSFrederick Mayle // reading of DIEs. header_.length does not include the size of the
385*9712c20fSFrederick Mayle // initial length.
386*9712c20fSFrederick Mayle assert(buffer_ + initial_length_size + header_.length <=
387*9712c20fSFrederick Mayle buffer_ + buffer_length_);
388*9712c20fSFrederick Mayle }
389*9712c20fSFrederick Mayle
Start()390*9712c20fSFrederick Mayle uint64_t CompilationUnit::Start() {
391*9712c20fSFrederick Mayle // First get the debug_info section.
392*9712c20fSFrederick Mayle SectionMap::const_iterator iter =
393*9712c20fSFrederick Mayle GetSectionByName(sections_, ".debug_info");
394*9712c20fSFrederick Mayle assert(iter != sections_.end());
395*9712c20fSFrederick Mayle
396*9712c20fSFrederick Mayle // Set up our buffer
397*9712c20fSFrederick Mayle buffer_ = iter->second.first + offset_from_section_start_;
398*9712c20fSFrederick Mayle if (is_split_dwarf_) {
399*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_info_offset");
400*9712c20fSFrederick Mayle assert(iter != sections_.end());
401*9712c20fSFrederick Mayle buffer_length_ = iter->second.second;
402*9712c20fSFrederick Mayle } else {
403*9712c20fSFrederick Mayle buffer_length_ = iter->second.second - offset_from_section_start_;
404*9712c20fSFrederick Mayle }
405*9712c20fSFrederick Mayle
406*9712c20fSFrederick Mayle // Read the header
407*9712c20fSFrederick Mayle ReadHeader();
408*9712c20fSFrederick Mayle
409*9712c20fSFrederick Mayle // Figure out the real length from the end of the initial length to
410*9712c20fSFrederick Mayle // the end of the compilation unit, since that is the value we
411*9712c20fSFrederick Mayle // return.
412*9712c20fSFrederick Mayle uint64_t ourlength = header_.length;
413*9712c20fSFrederick Mayle if (reader_->OffsetSize() == 8)
414*9712c20fSFrederick Mayle ourlength += 12;
415*9712c20fSFrederick Mayle else
416*9712c20fSFrederick Mayle ourlength += 4;
417*9712c20fSFrederick Mayle
418*9712c20fSFrederick Mayle // See if the user wants this compilation unit, and if not, just return.
419*9712c20fSFrederick Mayle if (!handler_->StartCompilationUnit(offset_from_section_start_,
420*9712c20fSFrederick Mayle reader_->AddressSize(),
421*9712c20fSFrederick Mayle reader_->OffsetSize(),
422*9712c20fSFrederick Mayle header_.length,
423*9712c20fSFrederick Mayle header_.version))
424*9712c20fSFrederick Mayle return ourlength;
425*9712c20fSFrederick Mayle else if (header_.version == 5 && is_type_unit_)
426*9712c20fSFrederick Mayle return ourlength;
427*9712c20fSFrederick Mayle
428*9712c20fSFrederick Mayle // Otherwise, continue by reading our abbreviation entries.
429*9712c20fSFrederick Mayle ReadAbbrevs();
430*9712c20fSFrederick Mayle
431*9712c20fSFrederick Mayle // Set the string section if we have one.
432*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_str");
433*9712c20fSFrederick Mayle if (iter != sections_.end()) {
434*9712c20fSFrederick Mayle string_buffer_ = iter->second.first;
435*9712c20fSFrederick Mayle string_buffer_length_ = iter->second.second;
436*9712c20fSFrederick Mayle }
437*9712c20fSFrederick Mayle
438*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_line");
439*9712c20fSFrederick Mayle if (iter != sections_.end()) {
440*9712c20fSFrederick Mayle line_buffer_ = iter->second.first;
441*9712c20fSFrederick Mayle line_buffer_length_ = iter->second.second;
442*9712c20fSFrederick Mayle }
443*9712c20fSFrederick Mayle
444*9712c20fSFrederick Mayle // Set the line string section if we have one.
445*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_line_str");
446*9712c20fSFrederick Mayle if (iter != sections_.end()) {
447*9712c20fSFrederick Mayle line_string_buffer_ = iter->second.first;
448*9712c20fSFrederick Mayle line_string_buffer_length_ = iter->second.second;
449*9712c20fSFrederick Mayle }
450*9712c20fSFrederick Mayle
451*9712c20fSFrederick Mayle // Set the string offsets section if we have one.
452*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_str_offsets");
453*9712c20fSFrederick Mayle if (iter != sections_.end()) {
454*9712c20fSFrederick Mayle str_offsets_buffer_ = iter->second.first;
455*9712c20fSFrederick Mayle str_offsets_buffer_length_ = iter->second.second;
456*9712c20fSFrederick Mayle }
457*9712c20fSFrederick Mayle
458*9712c20fSFrederick Mayle // Set the address section if we have one.
459*9712c20fSFrederick Mayle iter = GetSectionByName(sections_, ".debug_addr");
460*9712c20fSFrederick Mayle if (iter != sections_.end()) {
461*9712c20fSFrederick Mayle addr_buffer_ = iter->second.first;
462*9712c20fSFrederick Mayle addr_buffer_length_ = iter->second.second;
463*9712c20fSFrederick Mayle }
464*9712c20fSFrederick Mayle
465*9712c20fSFrederick Mayle // Now that we have our abbreviations, start processing DIE's.
466*9712c20fSFrederick Mayle ProcessDIEs();
467*9712c20fSFrederick Mayle
468*9712c20fSFrederick Mayle // If this is a skeleton compilation unit generated with split DWARF,
469*9712c20fSFrederick Mayle // and the client needs the full debug info, we need to find the full
470*9712c20fSFrederick Mayle // compilation unit in a .dwo or .dwp file.
471*9712c20fSFrederick Mayle should_process_split_dwarf_ =
472*9712c20fSFrederick Mayle !is_split_dwarf_ && dwo_name_ != NULL && handler_->NeedSplitDebugInfo();
473*9712c20fSFrederick Mayle
474*9712c20fSFrederick Mayle return ourlength;
475*9712c20fSFrederick Mayle }
476*9712c20fSFrederick Mayle
ProcessFormStringIndex(uint64_t dieoffset,enum DwarfAttribute attr,enum DwarfForm form,uint64_t str_index)477*9712c20fSFrederick Mayle void CompilationUnit::ProcessFormStringIndex(
478*9712c20fSFrederick Mayle uint64_t dieoffset, enum DwarfAttribute attr, enum DwarfForm form,
479*9712c20fSFrederick Mayle uint64_t str_index) {
480*9712c20fSFrederick Mayle const size_t kStringOffsetsTableHeaderSize =
481*9712c20fSFrederick Mayle header_.version >= 5 ? (reader_->OffsetSize() == 8 ? 16 : 8) : 0;
482*9712c20fSFrederick Mayle const uint8_t* str_offsets_table_after_header = str_offsets_base_ ?
483*9712c20fSFrederick Mayle str_offsets_buffer_ + str_offsets_base_ :
484*9712c20fSFrederick Mayle str_offsets_buffer_ + kStringOffsetsTableHeaderSize;
485*9712c20fSFrederick Mayle const uint8_t* offset_ptr =
486*9712c20fSFrederick Mayle str_offsets_table_after_header + str_index * reader_->OffsetSize();
487*9712c20fSFrederick Mayle
488*9712c20fSFrederick Mayle const uint64_t offset = reader_->ReadOffset(offset_ptr);
489*9712c20fSFrederick Mayle if (offset >= string_buffer_length_) {
490*9712c20fSFrederick Mayle return;
491*9712c20fSFrederick Mayle }
492*9712c20fSFrederick Mayle
493*9712c20fSFrederick Mayle const char* str = reinterpret_cast<const char*>(string_buffer_) + offset;
494*9712c20fSFrederick Mayle ProcessAttributeString(dieoffset, attr, form, str);
495*9712c20fSFrederick Mayle }
496*9712c20fSFrederick Mayle
497*9712c20fSFrederick Mayle // Special function for pre-processing the
498*9712c20fSFrederick Mayle // DW_AT_str_offsets_base and DW_AT_addr_base in a DW_TAG_compile_unit die (for
499*9712c20fSFrederick Mayle // DWARF v5). We must make sure to find and process the
500*9712c20fSFrederick Mayle // DW_AT_str_offsets_base and DW_AT_addr_base attributes before attempting to
501*9712c20fSFrederick Mayle // read any string and address attribute in the compile unit.
ProcessOffsetBaseAttribute(uint64_t dieoffset,const uint8_t * start,enum DwarfAttribute attr,enum DwarfForm form,uint64_t implicit_const)502*9712c20fSFrederick Mayle const uint8_t* CompilationUnit::ProcessOffsetBaseAttribute(
503*9712c20fSFrederick Mayle uint64_t dieoffset, const uint8_t* start, enum DwarfAttribute attr,
504*9712c20fSFrederick Mayle enum DwarfForm form, uint64_t implicit_const) {
505*9712c20fSFrederick Mayle size_t len;
506*9712c20fSFrederick Mayle
507*9712c20fSFrederick Mayle switch (form) {
508*9712c20fSFrederick Mayle // DW_FORM_indirect is never used because it is such a space
509*9712c20fSFrederick Mayle // waster.
510*9712c20fSFrederick Mayle case DW_FORM_indirect:
511*9712c20fSFrederick Mayle form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
512*9712c20fSFrederick Mayle &len));
513*9712c20fSFrederick Mayle start += len;
514*9712c20fSFrederick Mayle return ProcessOffsetBaseAttribute(dieoffset, start, attr, form,
515*9712c20fSFrederick Mayle implicit_const);
516*9712c20fSFrederick Mayle
517*9712c20fSFrederick Mayle case DW_FORM_flag_present:
518*9712c20fSFrederick Mayle return start;
519*9712c20fSFrederick Mayle case DW_FORM_data1:
520*9712c20fSFrederick Mayle case DW_FORM_flag:
521*9712c20fSFrederick Mayle return start + 1;
522*9712c20fSFrederick Mayle case DW_FORM_data2:
523*9712c20fSFrederick Mayle return start + 2;
524*9712c20fSFrederick Mayle case DW_FORM_data4:
525*9712c20fSFrederick Mayle return start + 4;
526*9712c20fSFrederick Mayle case DW_FORM_data8:
527*9712c20fSFrederick Mayle return start + 8;
528*9712c20fSFrederick Mayle case DW_FORM_data16:
529*9712c20fSFrederick Mayle // This form is designed for an md5 checksum inside line tables.
530*9712c20fSFrederick Mayle return start + 16;
531*9712c20fSFrederick Mayle case DW_FORM_string: {
532*9712c20fSFrederick Mayle const char* str = reinterpret_cast<const char*>(start);
533*9712c20fSFrederick Mayle return start + strlen(str) + 1;
534*9712c20fSFrederick Mayle }
535*9712c20fSFrederick Mayle case DW_FORM_udata:
536*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
537*9712c20fSFrederick Mayle return start + len;
538*9712c20fSFrederick Mayle case DW_FORM_sdata:
539*9712c20fSFrederick Mayle reader_->ReadSignedLEB128(start, &len);
540*9712c20fSFrederick Mayle return start + len;
541*9712c20fSFrederick Mayle case DW_FORM_addr:
542*9712c20fSFrederick Mayle reader_->ReadAddress(start);
543*9712c20fSFrederick Mayle return start + reader_->AddressSize();
544*9712c20fSFrederick Mayle
545*9712c20fSFrederick Mayle // This is the important one here!
546*9712c20fSFrederick Mayle case DW_FORM_sec_offset:
547*9712c20fSFrederick Mayle if (attr == DW_AT_str_offsets_base ||
548*9712c20fSFrederick Mayle attr == DW_AT_addr_base)
549*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
550*9712c20fSFrederick Mayle reader_->ReadOffset(start));
551*9712c20fSFrederick Mayle else
552*9712c20fSFrederick Mayle reader_->ReadOffset(start);
553*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
554*9712c20fSFrederick Mayle
555*9712c20fSFrederick Mayle case DW_FORM_ref1:
556*9712c20fSFrederick Mayle return start + 1;
557*9712c20fSFrederick Mayle case DW_FORM_ref2:
558*9712c20fSFrederick Mayle return start + 2;
559*9712c20fSFrederick Mayle case DW_FORM_ref4:
560*9712c20fSFrederick Mayle return start + 4;
561*9712c20fSFrederick Mayle case DW_FORM_ref8:
562*9712c20fSFrederick Mayle return start + 8;
563*9712c20fSFrederick Mayle case DW_FORM_ref_udata:
564*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
565*9712c20fSFrederick Mayle return start + len;
566*9712c20fSFrederick Mayle case DW_FORM_ref_addr:
567*9712c20fSFrederick Mayle // DWARF2 and 3/4 differ on whether ref_addr is address size or
568*9712c20fSFrederick Mayle // offset size.
569*9712c20fSFrederick Mayle assert(header_.version >= 2);
570*9712c20fSFrederick Mayle if (header_.version == 2) {
571*9712c20fSFrederick Mayle reader_->ReadAddress(start);
572*9712c20fSFrederick Mayle return start + reader_->AddressSize();
573*9712c20fSFrederick Mayle } else if (header_.version >= 3) {
574*9712c20fSFrederick Mayle reader_->ReadOffset(start);
575*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
576*9712c20fSFrederick Mayle }
577*9712c20fSFrederick Mayle break;
578*9712c20fSFrederick Mayle case DW_FORM_ref_sig8:
579*9712c20fSFrederick Mayle return start + 8;
580*9712c20fSFrederick Mayle case DW_FORM_implicit_const:
581*9712c20fSFrederick Mayle return start;
582*9712c20fSFrederick Mayle case DW_FORM_block1: {
583*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadOneByte(start);
584*9712c20fSFrederick Mayle return start + 1 + datalen;
585*9712c20fSFrederick Mayle }
586*9712c20fSFrederick Mayle case DW_FORM_block2: {
587*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadTwoBytes(start);
588*9712c20fSFrederick Mayle return start + 2 + datalen;
589*9712c20fSFrederick Mayle }
590*9712c20fSFrederick Mayle case DW_FORM_block4: {
591*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadFourBytes(start);
592*9712c20fSFrederick Mayle return start + 4 + datalen;
593*9712c20fSFrederick Mayle }
594*9712c20fSFrederick Mayle case DW_FORM_block:
595*9712c20fSFrederick Mayle case DW_FORM_exprloc: {
596*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadUnsignedLEB128(start, &len);
597*9712c20fSFrederick Mayle return start + datalen + len;
598*9712c20fSFrederick Mayle }
599*9712c20fSFrederick Mayle case DW_FORM_strp: {
600*9712c20fSFrederick Mayle reader_->ReadOffset(start);
601*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
602*9712c20fSFrederick Mayle }
603*9712c20fSFrederick Mayle case DW_FORM_line_strp: {
604*9712c20fSFrederick Mayle reader_->ReadOffset(start);
605*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
606*9712c20fSFrederick Mayle }
607*9712c20fSFrederick Mayle case DW_FORM_strp_sup:
608*9712c20fSFrederick Mayle return start + 4;
609*9712c20fSFrederick Mayle case DW_FORM_ref_sup4:
610*9712c20fSFrederick Mayle return start + 4;
611*9712c20fSFrederick Mayle case DW_FORM_ref_sup8:
612*9712c20fSFrederick Mayle return start + 8;
613*9712c20fSFrederick Mayle case DW_FORM_loclistx:
614*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
615*9712c20fSFrederick Mayle return start + len;
616*9712c20fSFrederick Mayle case DW_FORM_strx:
617*9712c20fSFrederick Mayle case DW_FORM_GNU_str_index: {
618*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
619*9712c20fSFrederick Mayle return start + len;
620*9712c20fSFrederick Mayle }
621*9712c20fSFrederick Mayle case DW_FORM_strx1: {
622*9712c20fSFrederick Mayle return start + 1;
623*9712c20fSFrederick Mayle }
624*9712c20fSFrederick Mayle case DW_FORM_strx2: {
625*9712c20fSFrederick Mayle return start + 2;
626*9712c20fSFrederick Mayle }
627*9712c20fSFrederick Mayle case DW_FORM_strx3: {
628*9712c20fSFrederick Mayle return start + 3;
629*9712c20fSFrederick Mayle }
630*9712c20fSFrederick Mayle case DW_FORM_strx4: {
631*9712c20fSFrederick Mayle return start + 4;
632*9712c20fSFrederick Mayle }
633*9712c20fSFrederick Mayle
634*9712c20fSFrederick Mayle case DW_FORM_addrx:
635*9712c20fSFrederick Mayle case DW_FORM_GNU_addr_index:
636*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
637*9712c20fSFrederick Mayle return start + len;
638*9712c20fSFrederick Mayle case DW_FORM_addrx1:
639*9712c20fSFrederick Mayle return start + 1;
640*9712c20fSFrederick Mayle case DW_FORM_addrx2:
641*9712c20fSFrederick Mayle return start + 2;
642*9712c20fSFrederick Mayle case DW_FORM_addrx3:
643*9712c20fSFrederick Mayle return start + 3;
644*9712c20fSFrederick Mayle case DW_FORM_addrx4:
645*9712c20fSFrederick Mayle return start + 4;
646*9712c20fSFrederick Mayle case DW_FORM_rnglistx:
647*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len);
648*9712c20fSFrederick Mayle return start + len;
649*9712c20fSFrederick Mayle }
650*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type\n");
651*9712c20fSFrederick Mayle return NULL;
652*9712c20fSFrederick Mayle }
653*9712c20fSFrederick Mayle
654*9712c20fSFrederick Mayle // If one really wanted, you could merge SkipAttribute and
655*9712c20fSFrederick Mayle // ProcessAttribute
656*9712c20fSFrederick Mayle // This is all boring data manipulation and calling of the handler.
ProcessAttribute(uint64_t dieoffset,const uint8_t * start,enum DwarfAttribute attr,enum DwarfForm form,uint64_t implicit_const)657*9712c20fSFrederick Mayle const uint8_t* CompilationUnit::ProcessAttribute(
658*9712c20fSFrederick Mayle uint64_t dieoffset, const uint8_t* start, enum DwarfAttribute attr,
659*9712c20fSFrederick Mayle enum DwarfForm form, uint64_t implicit_const) {
660*9712c20fSFrederick Mayle size_t len;
661*9712c20fSFrederick Mayle
662*9712c20fSFrederick Mayle switch (form) {
663*9712c20fSFrederick Mayle // DW_FORM_indirect is never used because it is such a space
664*9712c20fSFrederick Mayle // waster.
665*9712c20fSFrederick Mayle case DW_FORM_indirect:
666*9712c20fSFrederick Mayle form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
667*9712c20fSFrederick Mayle &len));
668*9712c20fSFrederick Mayle start += len;
669*9712c20fSFrederick Mayle return ProcessAttribute(dieoffset, start, attr, form, implicit_const);
670*9712c20fSFrederick Mayle
671*9712c20fSFrederick Mayle case DW_FORM_flag_present:
672*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form, 1);
673*9712c20fSFrederick Mayle return start;
674*9712c20fSFrederick Mayle case DW_FORM_data1:
675*9712c20fSFrederick Mayle case DW_FORM_flag:
676*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
677*9712c20fSFrederick Mayle reader_->ReadOneByte(start));
678*9712c20fSFrederick Mayle return start + 1;
679*9712c20fSFrederick Mayle case DW_FORM_data2:
680*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
681*9712c20fSFrederick Mayle reader_->ReadTwoBytes(start));
682*9712c20fSFrederick Mayle return start + 2;
683*9712c20fSFrederick Mayle case DW_FORM_data4:
684*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
685*9712c20fSFrederick Mayle reader_->ReadFourBytes(start));
686*9712c20fSFrederick Mayle return start + 4;
687*9712c20fSFrederick Mayle case DW_FORM_data8:
688*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
689*9712c20fSFrederick Mayle reader_->ReadEightBytes(start));
690*9712c20fSFrederick Mayle return start + 8;
691*9712c20fSFrederick Mayle case DW_FORM_data16:
692*9712c20fSFrederick Mayle // This form is designed for an md5 checksum inside line tables.
693*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type: DW_FORM_data16\n");
694*9712c20fSFrederick Mayle return start + 16;
695*9712c20fSFrederick Mayle case DW_FORM_string: {
696*9712c20fSFrederick Mayle const char* str = reinterpret_cast<const char*>(start);
697*9712c20fSFrederick Mayle ProcessAttributeString(dieoffset, attr, form, str);
698*9712c20fSFrederick Mayle return start + strlen(str) + 1;
699*9712c20fSFrederick Mayle }
700*9712c20fSFrederick Mayle case DW_FORM_udata:
701*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
702*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len));
703*9712c20fSFrederick Mayle return start + len;
704*9712c20fSFrederick Mayle
705*9712c20fSFrederick Mayle case DW_FORM_sdata:
706*9712c20fSFrederick Mayle ProcessAttributeSigned(dieoffset, attr, form,
707*9712c20fSFrederick Mayle reader_->ReadSignedLEB128(start, &len));
708*9712c20fSFrederick Mayle return start + len;
709*9712c20fSFrederick Mayle case DW_FORM_addr:
710*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
711*9712c20fSFrederick Mayle reader_->ReadAddress(start));
712*9712c20fSFrederick Mayle return start + reader_->AddressSize();
713*9712c20fSFrederick Mayle case DW_FORM_sec_offset:
714*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
715*9712c20fSFrederick Mayle reader_->ReadOffset(start));
716*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
717*9712c20fSFrederick Mayle
718*9712c20fSFrederick Mayle case DW_FORM_ref1:
719*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
720*9712c20fSFrederick Mayle reader_->ReadOneByte(start)
721*9712c20fSFrederick Mayle + offset_from_section_start_);
722*9712c20fSFrederick Mayle return start + 1;
723*9712c20fSFrederick Mayle case DW_FORM_ref2:
724*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
725*9712c20fSFrederick Mayle reader_->ReadTwoBytes(start)
726*9712c20fSFrederick Mayle + offset_from_section_start_);
727*9712c20fSFrederick Mayle return start + 2;
728*9712c20fSFrederick Mayle case DW_FORM_ref4:
729*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
730*9712c20fSFrederick Mayle reader_->ReadFourBytes(start)
731*9712c20fSFrederick Mayle + offset_from_section_start_);
732*9712c20fSFrederick Mayle return start + 4;
733*9712c20fSFrederick Mayle case DW_FORM_ref8:
734*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
735*9712c20fSFrederick Mayle reader_->ReadEightBytes(start)
736*9712c20fSFrederick Mayle + offset_from_section_start_);
737*9712c20fSFrederick Mayle return start + 8;
738*9712c20fSFrederick Mayle case DW_FORM_ref_udata:
739*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
740*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start,
741*9712c20fSFrederick Mayle &len)
742*9712c20fSFrederick Mayle + offset_from_section_start_);
743*9712c20fSFrederick Mayle return start + len;
744*9712c20fSFrederick Mayle case DW_FORM_ref_addr:
745*9712c20fSFrederick Mayle // DWARF2 and 3/4 differ on whether ref_addr is address size or
746*9712c20fSFrederick Mayle // offset size.
747*9712c20fSFrederick Mayle assert(header_.version >= 2);
748*9712c20fSFrederick Mayle if (header_.version == 2) {
749*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
750*9712c20fSFrederick Mayle reader_->ReadAddress(start));
751*9712c20fSFrederick Mayle return start + reader_->AddressSize();
752*9712c20fSFrederick Mayle } else if (header_.version >= 3) {
753*9712c20fSFrederick Mayle handler_->ProcessAttributeReference(dieoffset, attr, form,
754*9712c20fSFrederick Mayle reader_->ReadOffset(start));
755*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
756*9712c20fSFrederick Mayle }
757*9712c20fSFrederick Mayle break;
758*9712c20fSFrederick Mayle case DW_FORM_ref_sig8:
759*9712c20fSFrederick Mayle handler_->ProcessAttributeSignature(dieoffset, attr, form,
760*9712c20fSFrederick Mayle reader_->ReadEightBytes(start));
761*9712c20fSFrederick Mayle return start + 8;
762*9712c20fSFrederick Mayle case DW_FORM_implicit_const:
763*9712c20fSFrederick Mayle handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
764*9712c20fSFrederick Mayle implicit_const);
765*9712c20fSFrederick Mayle return start;
766*9712c20fSFrederick Mayle case DW_FORM_block1: {
767*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadOneByte(start);
768*9712c20fSFrederick Mayle handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 1,
769*9712c20fSFrederick Mayle datalen);
770*9712c20fSFrederick Mayle return start + 1 + datalen;
771*9712c20fSFrederick Mayle }
772*9712c20fSFrederick Mayle case DW_FORM_block2: {
773*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadTwoBytes(start);
774*9712c20fSFrederick Mayle handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 2,
775*9712c20fSFrederick Mayle datalen);
776*9712c20fSFrederick Mayle return start + 2 + datalen;
777*9712c20fSFrederick Mayle }
778*9712c20fSFrederick Mayle case DW_FORM_block4: {
779*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadFourBytes(start);
780*9712c20fSFrederick Mayle handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 4,
781*9712c20fSFrederick Mayle datalen);
782*9712c20fSFrederick Mayle return start + 4 + datalen;
783*9712c20fSFrederick Mayle }
784*9712c20fSFrederick Mayle case DW_FORM_block:
785*9712c20fSFrederick Mayle case DW_FORM_exprloc: {
786*9712c20fSFrederick Mayle uint64_t datalen = reader_->ReadUnsignedLEB128(start, &len);
787*9712c20fSFrederick Mayle handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len,
788*9712c20fSFrederick Mayle datalen);
789*9712c20fSFrederick Mayle return start + datalen + len;
790*9712c20fSFrederick Mayle }
791*9712c20fSFrederick Mayle case DW_FORM_strp: {
792*9712c20fSFrederick Mayle assert(string_buffer_ != NULL);
793*9712c20fSFrederick Mayle
794*9712c20fSFrederick Mayle const uint64_t offset = reader_->ReadOffset(start);
795*9712c20fSFrederick Mayle assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
796*9712c20fSFrederick Mayle
797*9712c20fSFrederick Mayle const char* str = reinterpret_cast<const char*>(string_buffer_ + offset);
798*9712c20fSFrederick Mayle ProcessAttributeString(dieoffset, attr, form, str);
799*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
800*9712c20fSFrederick Mayle }
801*9712c20fSFrederick Mayle case DW_FORM_line_strp: {
802*9712c20fSFrederick Mayle assert(line_string_buffer_ != NULL);
803*9712c20fSFrederick Mayle
804*9712c20fSFrederick Mayle const uint64_t offset = reader_->ReadOffset(start);
805*9712c20fSFrederick Mayle assert(line_string_buffer_ + offset <
806*9712c20fSFrederick Mayle line_string_buffer_ + line_string_buffer_length_);
807*9712c20fSFrederick Mayle
808*9712c20fSFrederick Mayle const char* str =
809*9712c20fSFrederick Mayle reinterpret_cast<const char*>(line_string_buffer_ + offset);
810*9712c20fSFrederick Mayle ProcessAttributeString(dieoffset, attr, form, str);
811*9712c20fSFrederick Mayle return start + reader_->OffsetSize();
812*9712c20fSFrederick Mayle }
813*9712c20fSFrederick Mayle case DW_FORM_strp_sup:
814*9712c20fSFrederick Mayle // No support currently for suplementary object files.
815*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type: DW_FORM_strp_sup\n");
816*9712c20fSFrederick Mayle return start + 4;
817*9712c20fSFrederick Mayle case DW_FORM_ref_sup4:
818*9712c20fSFrederick Mayle // No support currently for suplementary object files.
819*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type: DW_FORM_ref_sup4\n");
820*9712c20fSFrederick Mayle return start + 4;
821*9712c20fSFrederick Mayle case DW_FORM_ref_sup8:
822*9712c20fSFrederick Mayle // No support currently for suplementary object files.
823*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type: DW_FORM_ref_sup8\n");
824*9712c20fSFrederick Mayle return start + 8;
825*9712c20fSFrederick Mayle case DW_FORM_loclistx:
826*9712c20fSFrederick Mayle ProcessAttributeUnsigned(dieoffset, attr, form,
827*9712c20fSFrederick Mayle reader_->ReadUnsignedLEB128(start, &len));
828*9712c20fSFrederick Mayle return start + len;
829*9712c20fSFrederick Mayle case DW_FORM_strx:
830*9712c20fSFrederick Mayle case DW_FORM_GNU_str_index: {
831*9712c20fSFrederick Mayle uint64_t str_index = reader_->ReadUnsignedLEB128(start, &len);
832*9712c20fSFrederick Mayle ProcessFormStringIndex(dieoffset, attr, form, str_index);
833*9712c20fSFrederick Mayle return start + len;
834*9712c20fSFrederick Mayle }
835*9712c20fSFrederick Mayle case DW_FORM_strx1: {
836*9712c20fSFrederick Mayle uint64_t str_index = reader_->ReadOneByte(start);
837*9712c20fSFrederick Mayle ProcessFormStringIndex(dieoffset, attr, form, str_index);
838*9712c20fSFrederick Mayle return start + 1;
839*9712c20fSFrederick Mayle }
840*9712c20fSFrederick Mayle case DW_FORM_strx2: {
841*9712c20fSFrederick Mayle uint64_t str_index = reader_->ReadTwoBytes(start);
842*9712c20fSFrederick Mayle ProcessFormStringIndex(dieoffset, attr, form, str_index);
843*9712c20fSFrederick Mayle return start + 2;
844*9712c20fSFrederick Mayle }
845*9712c20fSFrederick Mayle case DW_FORM_strx3: {
846*9712c20fSFrederick Mayle uint64_t str_index = reader_->ReadThreeBytes(start);
847*9712c20fSFrederick Mayle ProcessFormStringIndex(dieoffset, attr, form, str_index);
848*9712c20fSFrederick Mayle return start + 3;
849*9712c20fSFrederick Mayle }
850*9712c20fSFrederick Mayle case DW_FORM_strx4: {
851*9712c20fSFrederick Mayle uint64_t str_index = reader_->ReadFourBytes(start);
852*9712c20fSFrederick Mayle ProcessFormStringIndex(dieoffset, attr, form, str_index);
853*9712c20fSFrederick Mayle return start + 4;
854*9712c20fSFrederick Mayle }
855*9712c20fSFrederick Mayle
856*9712c20fSFrederick Mayle case DW_FORM_addrx:
857*9712c20fSFrederick Mayle case DW_FORM_GNU_addr_index:
858*9712c20fSFrederick Mayle ProcessAttributeAddrIndex(
859*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadUnsignedLEB128(start, &len));
860*9712c20fSFrederick Mayle return start + len;
861*9712c20fSFrederick Mayle case DW_FORM_addrx1:
862*9712c20fSFrederick Mayle ProcessAttributeAddrIndex(
863*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadOneByte(start));
864*9712c20fSFrederick Mayle return start + 1;
865*9712c20fSFrederick Mayle case DW_FORM_addrx2:
866*9712c20fSFrederick Mayle ProcessAttributeAddrIndex(
867*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadTwoBytes(start));
868*9712c20fSFrederick Mayle return start + 2;
869*9712c20fSFrederick Mayle case DW_FORM_addrx3:
870*9712c20fSFrederick Mayle ProcessAttributeAddrIndex(
871*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadThreeBytes(start));
872*9712c20fSFrederick Mayle return start + 3;
873*9712c20fSFrederick Mayle case DW_FORM_addrx4:
874*9712c20fSFrederick Mayle ProcessAttributeAddrIndex(
875*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadFourBytes(start));
876*9712c20fSFrederick Mayle return start + 4;
877*9712c20fSFrederick Mayle case DW_FORM_rnglistx:
878*9712c20fSFrederick Mayle ProcessAttributeUnsigned(
879*9712c20fSFrederick Mayle dieoffset, attr, form, reader_->ReadUnsignedLEB128(start, &len));
880*9712c20fSFrederick Mayle return start + len;
881*9712c20fSFrederick Mayle }
882*9712c20fSFrederick Mayle fprintf(stderr, "Unhandled form type\n");
883*9712c20fSFrederick Mayle return NULL;
884*9712c20fSFrederick Mayle }
885*9712c20fSFrederick Mayle
ProcessDIE(uint64_t dieoffset,const uint8_t * start,const Abbrev & abbrev)886*9712c20fSFrederick Mayle const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset,
887*9712c20fSFrederick Mayle const uint8_t* start,
888*9712c20fSFrederick Mayle const Abbrev& abbrev) {
889*9712c20fSFrederick Mayle // With DWARF v5, the compile_unit die may contain a
890*9712c20fSFrederick Mayle // DW_AT_str_offsets_base or DW_AT_addr_base. If it does, that attribute must
891*9712c20fSFrederick Mayle // be found and processed before trying to process the other attributes;
892*9712c20fSFrederick Mayle // otherwise the string or address values will all come out incorrect.
893*9712c20fSFrederick Mayle if ((abbrev.tag == DW_TAG_compile_unit ||
894*9712c20fSFrederick Mayle abbrev.tag == DW_TAG_skeleton_unit) &&
895*9712c20fSFrederick Mayle header_.version == 5) {
896*9712c20fSFrederick Mayle uint64_t dieoffset_copy = dieoffset;
897*9712c20fSFrederick Mayle const uint8_t* start_copy = start;
898*9712c20fSFrederick Mayle for (AttributeList::const_iterator i = abbrev.attributes.begin();
899*9712c20fSFrederick Mayle i != abbrev.attributes.end();
900*9712c20fSFrederick Mayle i++) {
901*9712c20fSFrederick Mayle start_copy = ProcessOffsetBaseAttribute(dieoffset_copy, start_copy,
902*9712c20fSFrederick Mayle i->attr_, i->form_,
903*9712c20fSFrederick Mayle i->value_);
904*9712c20fSFrederick Mayle }
905*9712c20fSFrederick Mayle }
906*9712c20fSFrederick Mayle
907*9712c20fSFrederick Mayle for (AttributeList::const_iterator i = abbrev.attributes.begin();
908*9712c20fSFrederick Mayle i != abbrev.attributes.end();
909*9712c20fSFrederick Mayle i++) {
910*9712c20fSFrederick Mayle start = ProcessAttribute(dieoffset, start, i->attr_, i->form_, i->value_);
911*9712c20fSFrederick Mayle }
912*9712c20fSFrederick Mayle
913*9712c20fSFrederick Mayle // If this is a compilation unit in a split DWARF object, verify that
914*9712c20fSFrederick Mayle // the dwo_id matches. If it does not match, we will ignore this
915*9712c20fSFrederick Mayle // compilation unit.
916*9712c20fSFrederick Mayle if (abbrev.tag == DW_TAG_compile_unit
917*9712c20fSFrederick Mayle && is_split_dwarf_
918*9712c20fSFrederick Mayle && dwo_id_ != skeleton_dwo_id_) {
919*9712c20fSFrederick Mayle return NULL;
920*9712c20fSFrederick Mayle }
921*9712c20fSFrederick Mayle
922*9712c20fSFrederick Mayle return start;
923*9712c20fSFrederick Mayle }
924*9712c20fSFrederick Mayle
ProcessDIEs()925*9712c20fSFrederick Mayle void CompilationUnit::ProcessDIEs() {
926*9712c20fSFrederick Mayle const uint8_t* dieptr = after_header_;
927*9712c20fSFrederick Mayle size_t len;
928*9712c20fSFrederick Mayle
929*9712c20fSFrederick Mayle // lengthstart is the place the length field is based on.
930*9712c20fSFrederick Mayle // It is the point in the header after the initial length field
931*9712c20fSFrederick Mayle const uint8_t* lengthstart = buffer_;
932*9712c20fSFrederick Mayle
933*9712c20fSFrederick Mayle // In 64 bit dwarf, the initial length is 12 bytes, because of the
934*9712c20fSFrederick Mayle // 0xffffffff at the start.
935*9712c20fSFrederick Mayle if (reader_->OffsetSize() == 8)
936*9712c20fSFrederick Mayle lengthstart += 12;
937*9712c20fSFrederick Mayle else
938*9712c20fSFrederick Mayle lengthstart += 4;
939*9712c20fSFrederick Mayle
940*9712c20fSFrederick Mayle std::stack<uint64_t> die_stack;
941*9712c20fSFrederick Mayle
942*9712c20fSFrederick Mayle while (dieptr < (lengthstart + header_.length)) {
943*9712c20fSFrederick Mayle // We give the user the absolute offset from the beginning of
944*9712c20fSFrederick Mayle // debug_info, since they need it to deal with ref_addr forms.
945*9712c20fSFrederick Mayle uint64_t absolute_offset = (dieptr - buffer_) + offset_from_section_start_;
946*9712c20fSFrederick Mayle
947*9712c20fSFrederick Mayle uint64_t abbrev_num = reader_->ReadUnsignedLEB128(dieptr, &len);
948*9712c20fSFrederick Mayle
949*9712c20fSFrederick Mayle dieptr += len;
950*9712c20fSFrederick Mayle
951*9712c20fSFrederick Mayle // Abbrev == 0 represents the end of a list of children, or padding
952*9712c20fSFrederick Mayle // at the end of the compilation unit.
953*9712c20fSFrederick Mayle if (abbrev_num == 0) {
954*9712c20fSFrederick Mayle if (die_stack.size() == 0)
955*9712c20fSFrederick Mayle // If it is padding, then we are done with the compilation unit's DIEs.
956*9712c20fSFrederick Mayle return;
957*9712c20fSFrederick Mayle const uint64_t offset = die_stack.top();
958*9712c20fSFrederick Mayle die_stack.pop();
959*9712c20fSFrederick Mayle handler_->EndDIE(offset);
960*9712c20fSFrederick Mayle continue;
961*9712c20fSFrederick Mayle }
962*9712c20fSFrederick Mayle
963*9712c20fSFrederick Mayle const Abbrev& abbrev = abbrevs_->at(static_cast<size_t>(abbrev_num));
964*9712c20fSFrederick Mayle const enum DwarfTag tag = abbrev.tag;
965*9712c20fSFrederick Mayle if (!handler_->StartDIE(absolute_offset, tag)) {
966*9712c20fSFrederick Mayle dieptr = SkipDIE(dieptr, abbrev);
967*9712c20fSFrederick Mayle if (!dieptr) {
968*9712c20fSFrederick Mayle fprintf(stderr,
969*9712c20fSFrederick Mayle "An error happens when skipping a DIE's attributes at offset "
970*9712c20fSFrederick Mayle "0x%" PRIx64
971*9712c20fSFrederick Mayle ". Stopped processing following DIEs in this CU.\n",
972*9712c20fSFrederick Mayle absolute_offset);
973*9712c20fSFrederick Mayle exit(1);
974*9712c20fSFrederick Mayle }
975*9712c20fSFrederick Mayle } else {
976*9712c20fSFrederick Mayle dieptr = ProcessDIE(absolute_offset, dieptr, abbrev);
977*9712c20fSFrederick Mayle if (!dieptr) {
978*9712c20fSFrederick Mayle fprintf(stderr,
979*9712c20fSFrederick Mayle "An error happens when processing a DIE at offset 0x%" PRIx64
980*9712c20fSFrederick Mayle ". Stopped processing following DIEs in this CU.\n",
981*9712c20fSFrederick Mayle absolute_offset);
982*9712c20fSFrederick Mayle exit(1);
983*9712c20fSFrederick Mayle }
984*9712c20fSFrederick Mayle }
985*9712c20fSFrederick Mayle
986*9712c20fSFrederick Mayle if (abbrev.has_children) {
987*9712c20fSFrederick Mayle die_stack.push(absolute_offset);
988*9712c20fSFrederick Mayle } else {
989*9712c20fSFrederick Mayle handler_->EndDIE(absolute_offset);
990*9712c20fSFrederick Mayle }
991*9712c20fSFrederick Mayle }
992*9712c20fSFrederick Mayle }
993*9712c20fSFrederick Mayle
994*9712c20fSFrederick Mayle // Check for a valid ELF file and return the Address size.
995*9712c20fSFrederick Mayle // Returns 0 if not a valid ELF file.
GetElfWidth(const ElfReader & elf)996*9712c20fSFrederick Mayle inline int GetElfWidth(const ElfReader& elf) {
997*9712c20fSFrederick Mayle if (elf.IsElf32File())
998*9712c20fSFrederick Mayle return 4;
999*9712c20fSFrederick Mayle if (elf.IsElf64File())
1000*9712c20fSFrederick Mayle return 8;
1001*9712c20fSFrederick Mayle return 0;
1002*9712c20fSFrederick Mayle }
1003*9712c20fSFrederick Mayle
ProcessSplitDwarf(std::string & split_file,SectionMap & sections,ByteReader & split_byte_reader,uint64_t & cu_offset)1004*9712c20fSFrederick Mayle bool CompilationUnit::ProcessSplitDwarf(std::string& split_file,
1005*9712c20fSFrederick Mayle SectionMap& sections,
1006*9712c20fSFrederick Mayle ByteReader& split_byte_reader,
1007*9712c20fSFrederick Mayle uint64_t& cu_offset) {
1008*9712c20fSFrederick Mayle if (!should_process_split_dwarf_)
1009*9712c20fSFrederick Mayle return false;
1010*9712c20fSFrederick Mayle struct stat statbuf;
1011*9712c20fSFrederick Mayle bool found_in_dwp = false;
1012*9712c20fSFrederick Mayle if (!have_checked_for_dwp_) {
1013*9712c20fSFrederick Mayle // Look for a .dwp file in the same directory as the executable.
1014*9712c20fSFrederick Mayle have_checked_for_dwp_ = true;
1015*9712c20fSFrederick Mayle string dwp_suffix(".dwp");
1016*9712c20fSFrederick Mayle std::string dwp_path = path_ + dwp_suffix;
1017*9712c20fSFrederick Mayle if (stat(dwp_path.c_str(), &statbuf) != 0) {
1018*9712c20fSFrederick Mayle // Fall back to a split .debug file in the same directory.
1019*9712c20fSFrederick Mayle string debug_suffix(".debug");
1020*9712c20fSFrederick Mayle dwp_path = path_;
1021*9712c20fSFrederick Mayle size_t found = path_.rfind(debug_suffix);
1022*9712c20fSFrederick Mayle if (found != string::npos &&
1023*9712c20fSFrederick Mayle found + debug_suffix.length() == path_.length())
1024*9712c20fSFrederick Mayle dwp_path = dwp_path.replace(found, debug_suffix.length(), dwp_suffix);
1025*9712c20fSFrederick Mayle }
1026*9712c20fSFrederick Mayle if (stat(dwp_path.c_str(), &statbuf) == 0) {
1027*9712c20fSFrederick Mayle split_elf_reader_ = std::make_unique<ElfReader>(dwp_path);
1028*9712c20fSFrederick Mayle int width = GetElfWidth(*split_elf_reader_.get());
1029*9712c20fSFrederick Mayle if (width != 0) {
1030*9712c20fSFrederick Mayle split_byte_reader = ByteReader(reader_->GetEndianness());
1031*9712c20fSFrederick Mayle split_byte_reader.SetAddressSize(width);
1032*9712c20fSFrederick Mayle dwp_reader_ = std::make_unique<DwpReader>(split_byte_reader,
1033*9712c20fSFrederick Mayle split_elf_reader_.get());
1034*9712c20fSFrederick Mayle dwp_reader_->Initialize();
1035*9712c20fSFrederick Mayle // If we have a .dwp file, read the debug sections for the requested CU.
1036*9712c20fSFrederick Mayle dwp_reader_->ReadDebugSectionsForCU(dwo_id_, §ions);
1037*9712c20fSFrederick Mayle if (!sections.empty()) {
1038*9712c20fSFrederick Mayle SectionMap::const_iterator cu_iter =
1039*9712c20fSFrederick Mayle GetSectionByName(sections, ".debug_info_offset");
1040*9712c20fSFrederick Mayle SectionMap::const_iterator debug_info_iter =
1041*9712c20fSFrederick Mayle GetSectionByName(sections, ".debug_info");
1042*9712c20fSFrederick Mayle assert(cu_iter != sections.end());
1043*9712c20fSFrederick Mayle assert(debug_info_iter != sections.end());
1044*9712c20fSFrederick Mayle cu_offset = cu_iter->second.first - debug_info_iter->second.first;
1045*9712c20fSFrederick Mayle found_in_dwp = true;
1046*9712c20fSFrederick Mayle split_file = dwp_path;
1047*9712c20fSFrederick Mayle }
1048*9712c20fSFrederick Mayle }
1049*9712c20fSFrederick Mayle }
1050*9712c20fSFrederick Mayle }
1051*9712c20fSFrederick Mayle if (!found_in_dwp) {
1052*9712c20fSFrederick Mayle // If no .dwp file, try to open the .dwo file.
1053*9712c20fSFrederick Mayle if (stat(dwo_name_, &statbuf) == 0) {
1054*9712c20fSFrederick Mayle split_elf_reader_ = std::make_unique<ElfReader>(dwo_name_);
1055*9712c20fSFrederick Mayle int width = GetElfWidth(*split_elf_reader_.get());
1056*9712c20fSFrederick Mayle if (width != 0) {
1057*9712c20fSFrederick Mayle split_byte_reader = ByteReader(ENDIANNESS_LITTLE);
1058*9712c20fSFrederick Mayle split_byte_reader.SetAddressSize(width);
1059*9712c20fSFrederick Mayle ReadDebugSectionsFromDwo(split_elf_reader_.get(), §ions);
1060*9712c20fSFrederick Mayle if (!sections.empty()) {
1061*9712c20fSFrederick Mayle split_file = dwo_name_;
1062*9712c20fSFrederick Mayle }
1063*9712c20fSFrederick Mayle }
1064*9712c20fSFrederick Mayle }
1065*9712c20fSFrederick Mayle }
1066*9712c20fSFrederick Mayle return !split_file.empty();
1067*9712c20fSFrederick Mayle }
1068*9712c20fSFrederick Mayle
ReadDebugSectionsFromDwo(ElfReader * elf_reader,SectionMap * sections)1069*9712c20fSFrederick Mayle void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader,
1070*9712c20fSFrederick Mayle SectionMap* sections) {
1071*9712c20fSFrederick Mayle static const char* const section_names[] = {
1072*9712c20fSFrederick Mayle ".debug_abbrev",
1073*9712c20fSFrederick Mayle ".debug_info",
1074*9712c20fSFrederick Mayle ".debug_str_offsets",
1075*9712c20fSFrederick Mayle ".debug_str"
1076*9712c20fSFrederick Mayle };
1077*9712c20fSFrederick Mayle for (unsigned int i = 0u;
1078*9712c20fSFrederick Mayle i < sizeof(section_names)/sizeof(*(section_names)); ++i) {
1079*9712c20fSFrederick Mayle string base_name = section_names[i];
1080*9712c20fSFrederick Mayle string dwo_name = base_name + ".dwo";
1081*9712c20fSFrederick Mayle size_t section_size;
1082*9712c20fSFrederick Mayle const char* section_data = elf_reader->GetSectionByName(dwo_name,
1083*9712c20fSFrederick Mayle §ion_size);
1084*9712c20fSFrederick Mayle if (section_data != NULL)
1085*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1086*9712c20fSFrederick Mayle base_name, std::make_pair(
1087*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(section_data),
1088*9712c20fSFrederick Mayle section_size)));
1089*9712c20fSFrederick Mayle }
1090*9712c20fSFrederick Mayle }
1091*9712c20fSFrederick Mayle
DwpReader(const ByteReader & byte_reader,ElfReader * elf_reader)1092*9712c20fSFrederick Mayle DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader)
1093*9712c20fSFrederick Mayle : elf_reader_(elf_reader), byte_reader_(byte_reader),
1094*9712c20fSFrederick Mayle cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL),
1095*9712c20fSFrederick Mayle string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0),
1096*9712c20fSFrederick Mayle nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL),
1097*9712c20fSFrederick Mayle offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL),
1098*9712c20fSFrederick Mayle abbrev_size_(0), info_data_(NULL), info_size_(0),
1099*9712c20fSFrederick Mayle str_offsets_data_(NULL), str_offsets_size_(0) {}
1100*9712c20fSFrederick Mayle
Initialize()1101*9712c20fSFrederick Mayle void DwpReader::Initialize() {
1102*9712c20fSFrederick Mayle cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index",
1103*9712c20fSFrederick Mayle &cu_index_size_);
1104*9712c20fSFrederick Mayle if (cu_index_ == NULL) {
1105*9712c20fSFrederick Mayle return;
1106*9712c20fSFrederick Mayle }
1107*9712c20fSFrederick Mayle // The .debug_str.dwo section is shared by all CUs in the file.
1108*9712c20fSFrederick Mayle string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo",
1109*9712c20fSFrederick Mayle &string_buffer_size_);
1110*9712c20fSFrederick Mayle
1111*9712c20fSFrederick Mayle version_ = byte_reader_.ReadFourBytes(
1112*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(cu_index_));
1113*9712c20fSFrederick Mayle
1114*9712c20fSFrederick Mayle if (version_ == 1) {
1115*9712c20fSFrederick Mayle nslots_ = byte_reader_.ReadFourBytes(
1116*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(cu_index_)
1117*9712c20fSFrederick Mayle + 3 * sizeof(uint32_t));
1118*9712c20fSFrederick Mayle phash_ = cu_index_ + 4 * sizeof(uint32_t);
1119*9712c20fSFrederick Mayle pindex_ = phash_ + nslots_ * sizeof(uint64_t);
1120*9712c20fSFrederick Mayle shndx_pool_ = pindex_ + nslots_ * sizeof(uint32_t);
1121*9712c20fSFrederick Mayle if (shndx_pool_ >= cu_index_ + cu_index_size_) {
1122*9712c20fSFrederick Mayle version_ = 0;
1123*9712c20fSFrederick Mayle }
1124*9712c20fSFrederick Mayle } else if (version_ == 2 || version_ == 5) {
1125*9712c20fSFrederick Mayle ncolumns_ = byte_reader_.ReadFourBytes(
1126*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(cu_index_) + sizeof(uint32_t));
1127*9712c20fSFrederick Mayle nunits_ = byte_reader_.ReadFourBytes(
1128*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(cu_index_) + 2 * sizeof(uint32_t));
1129*9712c20fSFrederick Mayle nslots_ = byte_reader_.ReadFourBytes(
1130*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(cu_index_) + 3 * sizeof(uint32_t));
1131*9712c20fSFrederick Mayle phash_ = cu_index_ + 4 * sizeof(uint32_t);
1132*9712c20fSFrederick Mayle pindex_ = phash_ + nslots_ * sizeof(uint64_t);
1133*9712c20fSFrederick Mayle offset_table_ = pindex_ + nslots_ * sizeof(uint32_t);
1134*9712c20fSFrederick Mayle size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32_t);
1135*9712c20fSFrederick Mayle abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo",
1136*9712c20fSFrederick Mayle &abbrev_size_);
1137*9712c20fSFrederick Mayle info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_);
1138*9712c20fSFrederick Mayle str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo",
1139*9712c20fSFrederick Mayle &str_offsets_size_);
1140*9712c20fSFrederick Mayle rnglist_data_ =
1141*9712c20fSFrederick Mayle elf_reader_->GetSectionByName(".debug_rnglists.dwo", &rnglist_size_);
1142*9712c20fSFrederick Mayle if (size_table_ >= cu_index_ + cu_index_size_) {
1143*9712c20fSFrederick Mayle version_ = 0;
1144*9712c20fSFrederick Mayle }
1145*9712c20fSFrederick Mayle }
1146*9712c20fSFrederick Mayle }
1147*9712c20fSFrederick Mayle
ReadDebugSectionsForCU(uint64_t dwo_id,SectionMap * sections)1148*9712c20fSFrederick Mayle void DwpReader::ReadDebugSectionsForCU(uint64_t dwo_id,
1149*9712c20fSFrederick Mayle SectionMap* sections) {
1150*9712c20fSFrederick Mayle if (version_ == 1) {
1151*9712c20fSFrederick Mayle int slot = LookupCU(dwo_id);
1152*9712c20fSFrederick Mayle if (slot == -1) {
1153*9712c20fSFrederick Mayle return;
1154*9712c20fSFrederick Mayle }
1155*9712c20fSFrederick Mayle
1156*9712c20fSFrederick Mayle // The index table points to the section index pool, where we
1157*9712c20fSFrederick Mayle // can read a list of section indexes for the debug sections
1158*9712c20fSFrederick Mayle // for the CU whose dwo_id we are looking for.
1159*9712c20fSFrederick Mayle int index = byte_reader_.ReadFourBytes(
1160*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(pindex_)
1161*9712c20fSFrederick Mayle + slot * sizeof(uint32_t));
1162*9712c20fSFrederick Mayle const char* shndx_list = shndx_pool_ + index * sizeof(uint32_t);
1163*9712c20fSFrederick Mayle for (;;) {
1164*9712c20fSFrederick Mayle if (shndx_list >= cu_index_ + cu_index_size_) {
1165*9712c20fSFrederick Mayle version_ = 0;
1166*9712c20fSFrederick Mayle return;
1167*9712c20fSFrederick Mayle }
1168*9712c20fSFrederick Mayle unsigned int shndx = byte_reader_.ReadFourBytes(
1169*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(shndx_list));
1170*9712c20fSFrederick Mayle shndx_list += sizeof(uint32_t);
1171*9712c20fSFrederick Mayle if (shndx == 0)
1172*9712c20fSFrederick Mayle break;
1173*9712c20fSFrederick Mayle const char* section_name = elf_reader_->GetSectionName(shndx);
1174*9712c20fSFrederick Mayle size_t section_size;
1175*9712c20fSFrederick Mayle const char* section_data;
1176*9712c20fSFrederick Mayle // We're only interested in these four debug sections.
1177*9712c20fSFrederick Mayle // The section names in the .dwo file end with ".dwo", but we
1178*9712c20fSFrederick Mayle // add them to the sections table with their normal names.
1179*9712c20fSFrederick Mayle if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) {
1180*9712c20fSFrederick Mayle section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size);
1181*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1182*9712c20fSFrederick Mayle ".debug_abbrev",
1183*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (section_data),
1184*9712c20fSFrederick Mayle section_size)));
1185*9712c20fSFrederick Mayle } else if (!strncmp(section_name, ".debug_info", strlen(".debug_info"))) {
1186*9712c20fSFrederick Mayle section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size);
1187*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1188*9712c20fSFrederick Mayle ".debug_info",
1189*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (section_data),
1190*9712c20fSFrederick Mayle section_size)));
1191*9712c20fSFrederick Mayle } else if (!strncmp(section_name, ".debug_str_offsets",
1192*9712c20fSFrederick Mayle strlen(".debug_str_offsets"))) {
1193*9712c20fSFrederick Mayle section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size);
1194*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1195*9712c20fSFrederick Mayle ".debug_str_offsets",
1196*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (section_data),
1197*9712c20fSFrederick Mayle section_size)));
1198*9712c20fSFrederick Mayle }
1199*9712c20fSFrederick Mayle }
1200*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1201*9712c20fSFrederick Mayle ".debug_str",
1202*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (string_buffer_),
1203*9712c20fSFrederick Mayle string_buffer_size_)));
1204*9712c20fSFrederick Mayle } else if (version_ == 2 || version_ == 5) {
1205*9712c20fSFrederick Mayle uint32_t index = LookupCUv2(dwo_id);
1206*9712c20fSFrederick Mayle if (index == 0) {
1207*9712c20fSFrederick Mayle return;
1208*9712c20fSFrederick Mayle }
1209*9712c20fSFrederick Mayle
1210*9712c20fSFrederick Mayle // The index points to a row in each of the section offsets table
1211*9712c20fSFrederick Mayle // and the section size table, where we can read the offsets and sizes
1212*9712c20fSFrederick Mayle // of the contributions to each debug section from the CU whose dwo_id
1213*9712c20fSFrederick Mayle // we are looking for. Row 0 of the section offsets table has the
1214*9712c20fSFrederick Mayle // section ids for each column of the table. The size table begins
1215*9712c20fSFrederick Mayle // with row 1.
1216*9712c20fSFrederick Mayle const char* id_row = offset_table_;
1217*9712c20fSFrederick Mayle const char* offset_row = offset_table_
1218*9712c20fSFrederick Mayle + index * ncolumns_ * sizeof(uint32_t);
1219*9712c20fSFrederick Mayle const char* size_row =
1220*9712c20fSFrederick Mayle size_table_ + (index - 1) * ncolumns_ * sizeof(uint32_t);
1221*9712c20fSFrederick Mayle if (size_row + ncolumns_ * sizeof(uint32_t) > cu_index_ + cu_index_size_) {
1222*9712c20fSFrederick Mayle version_ = 0;
1223*9712c20fSFrederick Mayle return;
1224*9712c20fSFrederick Mayle }
1225*9712c20fSFrederick Mayle for (unsigned int col = 0u; col < ncolumns_; ++col) {
1226*9712c20fSFrederick Mayle uint32_t section_id =
1227*9712c20fSFrederick Mayle byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t*>(id_row)
1228*9712c20fSFrederick Mayle + col * sizeof(uint32_t));
1229*9712c20fSFrederick Mayle uint32_t offset = byte_reader_.ReadFourBytes(
1230*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(offset_row)
1231*9712c20fSFrederick Mayle + col * sizeof(uint32_t));
1232*9712c20fSFrederick Mayle uint32_t size = byte_reader_.ReadFourBytes(
1233*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(size_row) + col * sizeof(uint32_t));
1234*9712c20fSFrederick Mayle if (section_id == DW_SECT_ABBREV) {
1235*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1236*9712c20fSFrederick Mayle ".debug_abbrev",
1237*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (abbrev_data_)
1238*9712c20fSFrederick Mayle + offset, size)));
1239*9712c20fSFrederick Mayle } else if (section_id == DW_SECT_INFO) {
1240*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1241*9712c20fSFrederick Mayle ".debug_info",
1242*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*>(info_data_), 0)));
1243*9712c20fSFrederick Mayle // .debug_info_offset will points the buffer for the CU with given
1244*9712c20fSFrederick Mayle // dwo_id.
1245*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1246*9712c20fSFrederick Mayle ".debug_info_offset",
1247*9712c20fSFrederick Mayle std::make_pair(
1248*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(info_data_) + offset, size)));
1249*9712c20fSFrederick Mayle } else if (section_id == DW_SECT_STR_OFFSETS) {
1250*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1251*9712c20fSFrederick Mayle ".debug_str_offsets",
1252*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (str_offsets_data_)
1253*9712c20fSFrederick Mayle + offset, size)));
1254*9712c20fSFrederick Mayle } else if (section_id == DW_SECT_RNGLISTS) {
1255*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1256*9712c20fSFrederick Mayle ".debug_rnglists",
1257*9712c20fSFrederick Mayle std::make_pair(
1258*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(rnglist_data_) + offset,
1259*9712c20fSFrederick Mayle size)));
1260*9712c20fSFrederick Mayle }
1261*9712c20fSFrederick Mayle }
1262*9712c20fSFrederick Mayle sections->insert(std::make_pair(
1263*9712c20fSFrederick Mayle ".debug_str",
1264*9712c20fSFrederick Mayle std::make_pair(reinterpret_cast<const uint8_t*> (string_buffer_),
1265*9712c20fSFrederick Mayle string_buffer_size_)));
1266*9712c20fSFrederick Mayle }
1267*9712c20fSFrederick Mayle }
1268*9712c20fSFrederick Mayle
LookupCU(uint64_t dwo_id)1269*9712c20fSFrederick Mayle int DwpReader::LookupCU(uint64_t dwo_id) {
1270*9712c20fSFrederick Mayle uint32_t slot = static_cast<uint32_t>(dwo_id) & (nslots_ - 1);
1271*9712c20fSFrederick Mayle uint64_t probe = byte_reader_.ReadEightBytes(
1272*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(phash_) + slot * sizeof(uint64_t));
1273*9712c20fSFrederick Mayle if (probe != 0 && probe != dwo_id) {
1274*9712c20fSFrederick Mayle uint32_t secondary_hash =
1275*9712c20fSFrederick Mayle (static_cast<uint32_t>(dwo_id >> 32) & (nslots_ - 1)) | 1;
1276*9712c20fSFrederick Mayle do {
1277*9712c20fSFrederick Mayle slot = (slot + secondary_hash) & (nslots_ - 1);
1278*9712c20fSFrederick Mayle probe = byte_reader_.ReadEightBytes(
1279*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(phash_) + slot * sizeof(uint64_t));
1280*9712c20fSFrederick Mayle } while (probe != 0 && probe != dwo_id);
1281*9712c20fSFrederick Mayle }
1282*9712c20fSFrederick Mayle if (probe == 0)
1283*9712c20fSFrederick Mayle return -1;
1284*9712c20fSFrederick Mayle return slot;
1285*9712c20fSFrederick Mayle }
1286*9712c20fSFrederick Mayle
LookupCUv2(uint64_t dwo_id)1287*9712c20fSFrederick Mayle uint32_t DwpReader::LookupCUv2(uint64_t dwo_id) {
1288*9712c20fSFrederick Mayle uint32_t slot = static_cast<uint32_t>(dwo_id) & (nslots_ - 1);
1289*9712c20fSFrederick Mayle uint64_t probe = byte_reader_.ReadEightBytes(
1290*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(phash_) + slot * sizeof(uint64_t));
1291*9712c20fSFrederick Mayle uint32_t index = byte_reader_.ReadFourBytes(
1292*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(pindex_) + slot * sizeof(uint32_t));
1293*9712c20fSFrederick Mayle if (index != 0 && probe != dwo_id) {
1294*9712c20fSFrederick Mayle uint32_t secondary_hash =
1295*9712c20fSFrederick Mayle (static_cast<uint32_t>(dwo_id >> 32) & (nslots_ - 1)) | 1;
1296*9712c20fSFrederick Mayle do {
1297*9712c20fSFrederick Mayle slot = (slot + secondary_hash) & (nslots_ - 1);
1298*9712c20fSFrederick Mayle probe = byte_reader_.ReadEightBytes(
1299*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(phash_) + slot * sizeof(uint64_t));
1300*9712c20fSFrederick Mayle index = byte_reader_.ReadFourBytes(
1301*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(pindex_) + slot * sizeof(uint32_t));
1302*9712c20fSFrederick Mayle } while (index != 0 && probe != dwo_id);
1303*9712c20fSFrederick Mayle }
1304*9712c20fSFrederick Mayle return index;
1305*9712c20fSFrederick Mayle }
1306*9712c20fSFrederick Mayle
LineInfo(const uint8_t * buffer,uint64_t buffer_length,ByteReader * reader,const uint8_t * string_buffer,size_t string_buffer_length,const uint8_t * line_string_buffer,size_t line_string_buffer_length,LineInfoHandler * handler)1307*9712c20fSFrederick Mayle LineInfo::LineInfo(const uint8_t* buffer, uint64_t buffer_length,
1308*9712c20fSFrederick Mayle ByteReader* reader, const uint8_t* string_buffer,
1309*9712c20fSFrederick Mayle size_t string_buffer_length,
1310*9712c20fSFrederick Mayle const uint8_t* line_string_buffer,
1311*9712c20fSFrederick Mayle size_t line_string_buffer_length, LineInfoHandler* handler):
1312*9712c20fSFrederick Mayle handler_(handler), reader_(reader), buffer_(buffer),
1313*9712c20fSFrederick Mayle string_buffer_(string_buffer),
1314*9712c20fSFrederick Mayle line_string_buffer_(line_string_buffer) {
1315*9712c20fSFrederick Mayle #ifndef NDEBUG
1316*9712c20fSFrederick Mayle buffer_length_ = buffer_length;
1317*9712c20fSFrederick Mayle string_buffer_length_ = string_buffer_length;
1318*9712c20fSFrederick Mayle line_string_buffer_length_ = line_string_buffer_length;
1319*9712c20fSFrederick Mayle #endif
1320*9712c20fSFrederick Mayle header_.std_opcode_lengths = NULL;
1321*9712c20fSFrederick Mayle }
1322*9712c20fSFrederick Mayle
Start()1323*9712c20fSFrederick Mayle uint64_t LineInfo::Start() {
1324*9712c20fSFrederick Mayle ReadHeader();
1325*9712c20fSFrederick Mayle ReadLines();
1326*9712c20fSFrederick Mayle return after_header_ - buffer_;
1327*9712c20fSFrederick Mayle }
1328*9712c20fSFrederick Mayle
ReadTypesAndForms(const uint8_t ** lineptr,uint32_t * content_types,uint32_t * content_forms,uint32_t max_types,uint32_t * format_count)1329*9712c20fSFrederick Mayle void LineInfo::ReadTypesAndForms(const uint8_t** lineptr,
1330*9712c20fSFrederick Mayle uint32_t* content_types,
1331*9712c20fSFrederick Mayle uint32_t* content_forms,
1332*9712c20fSFrederick Mayle uint32_t max_types,
1333*9712c20fSFrederick Mayle uint32_t* format_count) {
1334*9712c20fSFrederick Mayle size_t len;
1335*9712c20fSFrederick Mayle
1336*9712c20fSFrederick Mayle uint32_t count = reader_->ReadUnsignedLEB128(*lineptr, &len);
1337*9712c20fSFrederick Mayle *lineptr += len;
1338*9712c20fSFrederick Mayle if (count < 1 || count > max_types) {
1339*9712c20fSFrederick Mayle return;
1340*9712c20fSFrederick Mayle }
1341*9712c20fSFrederick Mayle for (uint32_t col = 0; col < count; ++col) {
1342*9712c20fSFrederick Mayle content_types[col] = reader_->ReadUnsignedLEB128(*lineptr, &len);
1343*9712c20fSFrederick Mayle *lineptr += len;
1344*9712c20fSFrederick Mayle content_forms[col] = reader_->ReadUnsignedLEB128(*lineptr, &len);
1345*9712c20fSFrederick Mayle *lineptr += len;
1346*9712c20fSFrederick Mayle }
1347*9712c20fSFrederick Mayle *format_count = count;
1348*9712c20fSFrederick Mayle }
1349*9712c20fSFrederick Mayle
ReadStringForm(uint32_t form,const uint8_t ** lineptr)1350*9712c20fSFrederick Mayle const char* LineInfo::ReadStringForm(uint32_t form, const uint8_t** lineptr) {
1351*9712c20fSFrederick Mayle const char* name = nullptr;
1352*9712c20fSFrederick Mayle if (form == DW_FORM_string) {
1353*9712c20fSFrederick Mayle name = reinterpret_cast<const char*>(*lineptr);
1354*9712c20fSFrederick Mayle *lineptr += strlen(name) + 1;
1355*9712c20fSFrederick Mayle return name;
1356*9712c20fSFrederick Mayle } else if (form == DW_FORM_strp) {
1357*9712c20fSFrederick Mayle uint64_t offset = reader_->ReadOffset(*lineptr);
1358*9712c20fSFrederick Mayle assert(offset < string_buffer_length_);
1359*9712c20fSFrederick Mayle *lineptr += reader_->OffsetSize();
1360*9712c20fSFrederick Mayle if (string_buffer_ != nullptr) {
1361*9712c20fSFrederick Mayle name = reinterpret_cast<const char*>(string_buffer_) + offset;
1362*9712c20fSFrederick Mayle return name;
1363*9712c20fSFrederick Mayle }
1364*9712c20fSFrederick Mayle } else if (form == DW_FORM_line_strp) {
1365*9712c20fSFrederick Mayle uint64_t offset = reader_->ReadOffset(*lineptr);
1366*9712c20fSFrederick Mayle assert(offset < line_string_buffer_length_);
1367*9712c20fSFrederick Mayle *lineptr += reader_->OffsetSize();
1368*9712c20fSFrederick Mayle if (line_string_buffer_ != nullptr) {
1369*9712c20fSFrederick Mayle name = reinterpret_cast<const char*>(line_string_buffer_) + offset;
1370*9712c20fSFrederick Mayle return name;
1371*9712c20fSFrederick Mayle }
1372*9712c20fSFrederick Mayle }
1373*9712c20fSFrederick Mayle // Shouldn't be called with a non-string-form, and
1374*9712c20fSFrederick Mayle // if there is a string form but no string buffer,
1375*9712c20fSFrederick Mayle // that is a problem too.
1376*9712c20fSFrederick Mayle assert(0);
1377*9712c20fSFrederick Mayle return nullptr;
1378*9712c20fSFrederick Mayle }
1379*9712c20fSFrederick Mayle
ReadUnsignedData(uint32_t form,const uint8_t ** lineptr)1380*9712c20fSFrederick Mayle uint64_t LineInfo::ReadUnsignedData(uint32_t form, const uint8_t** lineptr) {
1381*9712c20fSFrederick Mayle size_t len;
1382*9712c20fSFrederick Mayle uint64_t value;
1383*9712c20fSFrederick Mayle
1384*9712c20fSFrederick Mayle switch (form) {
1385*9712c20fSFrederick Mayle case DW_FORM_data1:
1386*9712c20fSFrederick Mayle value = reader_->ReadOneByte(*lineptr);
1387*9712c20fSFrederick Mayle *lineptr += 1;
1388*9712c20fSFrederick Mayle return value;
1389*9712c20fSFrederick Mayle case DW_FORM_data2:
1390*9712c20fSFrederick Mayle value = reader_->ReadTwoBytes(*lineptr);
1391*9712c20fSFrederick Mayle *lineptr += 2;
1392*9712c20fSFrederick Mayle return value;
1393*9712c20fSFrederick Mayle case DW_FORM_data4:
1394*9712c20fSFrederick Mayle value = reader_->ReadFourBytes(*lineptr);
1395*9712c20fSFrederick Mayle *lineptr += 4;
1396*9712c20fSFrederick Mayle return value;
1397*9712c20fSFrederick Mayle case DW_FORM_data8:
1398*9712c20fSFrederick Mayle value = reader_->ReadEightBytes(*lineptr);
1399*9712c20fSFrederick Mayle *lineptr += 8;
1400*9712c20fSFrederick Mayle return value;
1401*9712c20fSFrederick Mayle case DW_FORM_udata:
1402*9712c20fSFrederick Mayle value = reader_->ReadUnsignedLEB128(*lineptr, &len);
1403*9712c20fSFrederick Mayle *lineptr += len;
1404*9712c20fSFrederick Mayle return value;
1405*9712c20fSFrederick Mayle default:
1406*9712c20fSFrederick Mayle fprintf(stderr, "Unrecognized data form.");
1407*9712c20fSFrederick Mayle return 0;
1408*9712c20fSFrederick Mayle }
1409*9712c20fSFrederick Mayle }
1410*9712c20fSFrederick Mayle
ReadFileRow(const uint8_t ** lineptr,const uint32_t * content_types,const uint32_t * content_forms,uint32_t row,uint32_t format_count)1411*9712c20fSFrederick Mayle void LineInfo::ReadFileRow(const uint8_t** lineptr,
1412*9712c20fSFrederick Mayle const uint32_t* content_types,
1413*9712c20fSFrederick Mayle const uint32_t* content_forms, uint32_t row,
1414*9712c20fSFrederick Mayle uint32_t format_count) {
1415*9712c20fSFrederick Mayle const char* filename = nullptr;
1416*9712c20fSFrederick Mayle uint64_t dirindex = 0;
1417*9712c20fSFrederick Mayle uint64_t mod_time = 0;
1418*9712c20fSFrederick Mayle uint64_t filelength = 0;
1419*9712c20fSFrederick Mayle
1420*9712c20fSFrederick Mayle for (uint32_t col = 0; col < format_count; ++col) {
1421*9712c20fSFrederick Mayle switch (content_types[col]) {
1422*9712c20fSFrederick Mayle case DW_LNCT_path:
1423*9712c20fSFrederick Mayle filename = ReadStringForm(content_forms[col], lineptr);
1424*9712c20fSFrederick Mayle break;
1425*9712c20fSFrederick Mayle case DW_LNCT_directory_index:
1426*9712c20fSFrederick Mayle dirindex = ReadUnsignedData(content_forms[col], lineptr);
1427*9712c20fSFrederick Mayle break;
1428*9712c20fSFrederick Mayle case DW_LNCT_timestamp:
1429*9712c20fSFrederick Mayle mod_time = ReadUnsignedData(content_forms[col], lineptr);
1430*9712c20fSFrederick Mayle break;
1431*9712c20fSFrederick Mayle case DW_LNCT_size:
1432*9712c20fSFrederick Mayle filelength = ReadUnsignedData(content_forms[col], lineptr);
1433*9712c20fSFrederick Mayle break;
1434*9712c20fSFrederick Mayle case DW_LNCT_MD5:
1435*9712c20fSFrederick Mayle // MD5 entries help a debugger sort different versions of files with
1436*9712c20fSFrederick Mayle // the same name. It is always paired with a DW_FORM_data16 and is
1437*9712c20fSFrederick Mayle // unused in this case.
1438*9712c20fSFrederick Mayle *lineptr += 16;
1439*9712c20fSFrederick Mayle break;
1440*9712c20fSFrederick Mayle default:
1441*9712c20fSFrederick Mayle fprintf(stderr, "Unrecognized form in line table header. %d\n",
1442*9712c20fSFrederick Mayle content_types[col]);
1443*9712c20fSFrederick Mayle assert(false);
1444*9712c20fSFrederick Mayle break;
1445*9712c20fSFrederick Mayle }
1446*9712c20fSFrederick Mayle }
1447*9712c20fSFrederick Mayle assert(filename != nullptr);
1448*9712c20fSFrederick Mayle handler_->DefineFile(filename, row, dirindex, mod_time, filelength);
1449*9712c20fSFrederick Mayle }
1450*9712c20fSFrederick Mayle
1451*9712c20fSFrederick Mayle // The header for a debug_line section is mildly complicated, because
1452*9712c20fSFrederick Mayle // the line info is very tightly encoded.
ReadHeader()1453*9712c20fSFrederick Mayle void LineInfo::ReadHeader() {
1454*9712c20fSFrederick Mayle const uint8_t* lineptr = buffer_;
1455*9712c20fSFrederick Mayle size_t initial_length_size;
1456*9712c20fSFrederick Mayle
1457*9712c20fSFrederick Mayle const uint64_t initial_length
1458*9712c20fSFrederick Mayle = reader_->ReadInitialLength(lineptr, &initial_length_size);
1459*9712c20fSFrederick Mayle
1460*9712c20fSFrederick Mayle lineptr += initial_length_size;
1461*9712c20fSFrederick Mayle header_.total_length = initial_length;
1462*9712c20fSFrederick Mayle assert(buffer_ + initial_length_size + header_.total_length <=
1463*9712c20fSFrederick Mayle buffer_ + buffer_length_);
1464*9712c20fSFrederick Mayle
1465*9712c20fSFrederick Mayle
1466*9712c20fSFrederick Mayle header_.version = reader_->ReadTwoBytes(lineptr);
1467*9712c20fSFrederick Mayle lineptr += 2;
1468*9712c20fSFrederick Mayle
1469*9712c20fSFrederick Mayle if (header_.version >= 5) {
1470*9712c20fSFrederick Mayle uint8_t address_size = reader_->ReadOneByte(lineptr);
1471*9712c20fSFrederick Mayle reader_->SetAddressSize(address_size);
1472*9712c20fSFrederick Mayle lineptr += 1;
1473*9712c20fSFrederick Mayle uint8_t segment_selector_size = reader_->ReadOneByte(lineptr);
1474*9712c20fSFrederick Mayle if (segment_selector_size != 0) {
1475*9712c20fSFrederick Mayle fprintf(stderr,"No support for segmented memory.");
1476*9712c20fSFrederick Mayle }
1477*9712c20fSFrederick Mayle lineptr += 1;
1478*9712c20fSFrederick Mayle } else {
1479*9712c20fSFrederick Mayle // Address size *must* be set by CU ahead of time.
1480*9712c20fSFrederick Mayle assert(reader_->AddressSize() != 0);
1481*9712c20fSFrederick Mayle }
1482*9712c20fSFrederick Mayle
1483*9712c20fSFrederick Mayle header_.prologue_length = reader_->ReadOffset(lineptr);
1484*9712c20fSFrederick Mayle lineptr += reader_->OffsetSize();
1485*9712c20fSFrederick Mayle
1486*9712c20fSFrederick Mayle header_.min_insn_length = reader_->ReadOneByte(lineptr);
1487*9712c20fSFrederick Mayle lineptr += 1;
1488*9712c20fSFrederick Mayle
1489*9712c20fSFrederick Mayle if (header_.version >= 4) {
1490*9712c20fSFrederick Mayle __attribute__((unused)) uint8_t max_ops_per_insn =
1491*9712c20fSFrederick Mayle reader_->ReadOneByte(lineptr);
1492*9712c20fSFrederick Mayle ++lineptr;
1493*9712c20fSFrederick Mayle assert(max_ops_per_insn == 1);
1494*9712c20fSFrederick Mayle }
1495*9712c20fSFrederick Mayle
1496*9712c20fSFrederick Mayle header_.default_is_stmt = reader_->ReadOneByte(lineptr);
1497*9712c20fSFrederick Mayle lineptr += 1;
1498*9712c20fSFrederick Mayle
1499*9712c20fSFrederick Mayle header_.line_base = *reinterpret_cast<const int8_t*>(lineptr);
1500*9712c20fSFrederick Mayle lineptr += 1;
1501*9712c20fSFrederick Mayle
1502*9712c20fSFrederick Mayle header_.line_range = reader_->ReadOneByte(lineptr);
1503*9712c20fSFrederick Mayle lineptr += 1;
1504*9712c20fSFrederick Mayle
1505*9712c20fSFrederick Mayle header_.opcode_base = reader_->ReadOneByte(lineptr);
1506*9712c20fSFrederick Mayle lineptr += 1;
1507*9712c20fSFrederick Mayle
1508*9712c20fSFrederick Mayle header_.std_opcode_lengths = new std::vector<unsigned char>;
1509*9712c20fSFrederick Mayle header_.std_opcode_lengths->resize(header_.opcode_base + 1);
1510*9712c20fSFrederick Mayle (*header_.std_opcode_lengths)[0] = 0;
1511*9712c20fSFrederick Mayle for (int i = 1; i < header_.opcode_base; i++) {
1512*9712c20fSFrederick Mayle (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr);
1513*9712c20fSFrederick Mayle lineptr += 1;
1514*9712c20fSFrederick Mayle }
1515*9712c20fSFrederick Mayle
1516*9712c20fSFrederick Mayle if (header_.version <= 4) {
1517*9712c20fSFrederick Mayle // Directory zero is assumed to be the compilation directory and special
1518*9712c20fSFrederick Mayle // cased where used. It is not actually stored in the dwarf data. But an
1519*9712c20fSFrederick Mayle // empty entry here avoids off-by-one errors elsewhere in the code.
1520*9712c20fSFrederick Mayle handler_->DefineDir("", 0);
1521*9712c20fSFrederick Mayle // It is legal for the directory entry table to be empty.
1522*9712c20fSFrederick Mayle if (*lineptr) {
1523*9712c20fSFrederick Mayle uint32_t dirindex = 1;
1524*9712c20fSFrederick Mayle while (*lineptr) {
1525*9712c20fSFrederick Mayle const char* dirname = reinterpret_cast<const char*>(lineptr);
1526*9712c20fSFrederick Mayle handler_->DefineDir(dirname, dirindex);
1527*9712c20fSFrederick Mayle lineptr += strlen(dirname) + 1;
1528*9712c20fSFrederick Mayle dirindex++;
1529*9712c20fSFrederick Mayle }
1530*9712c20fSFrederick Mayle }
1531*9712c20fSFrederick Mayle lineptr++;
1532*9712c20fSFrederick Mayle // It is also legal for the file entry table to be empty.
1533*9712c20fSFrederick Mayle
1534*9712c20fSFrederick Mayle // Similarly for file zero.
1535*9712c20fSFrederick Mayle handler_->DefineFile("", 0, 0, 0, 0);
1536*9712c20fSFrederick Mayle if (*lineptr) {
1537*9712c20fSFrederick Mayle uint32_t fileindex = 1;
1538*9712c20fSFrederick Mayle size_t len;
1539*9712c20fSFrederick Mayle while (*lineptr) {
1540*9712c20fSFrederick Mayle const char* filename = ReadStringForm(DW_FORM_string, &lineptr);
1541*9712c20fSFrederick Mayle
1542*9712c20fSFrederick Mayle uint64_t dirindex = reader_->ReadUnsignedLEB128(lineptr, &len);
1543*9712c20fSFrederick Mayle lineptr += len;
1544*9712c20fSFrederick Mayle
1545*9712c20fSFrederick Mayle uint64_t mod_time = reader_->ReadUnsignedLEB128(lineptr, &len);
1546*9712c20fSFrederick Mayle lineptr += len;
1547*9712c20fSFrederick Mayle
1548*9712c20fSFrederick Mayle uint64_t filelength = reader_->ReadUnsignedLEB128(lineptr, &len);
1549*9712c20fSFrederick Mayle lineptr += len;
1550*9712c20fSFrederick Mayle handler_->DefineFile(filename, fileindex,
1551*9712c20fSFrederick Mayle static_cast<uint32_t>(dirindex), mod_time,
1552*9712c20fSFrederick Mayle filelength);
1553*9712c20fSFrederick Mayle fileindex++;
1554*9712c20fSFrederick Mayle }
1555*9712c20fSFrederick Mayle }
1556*9712c20fSFrederick Mayle lineptr++;
1557*9712c20fSFrederick Mayle } else {
1558*9712c20fSFrederick Mayle // Read the DWARF-5 directory table.
1559*9712c20fSFrederick Mayle
1560*9712c20fSFrederick Mayle // Dwarf5 supports five different types and forms per directory- and
1561*9712c20fSFrederick Mayle // file-table entry. Theoretically, there could be duplicate entries
1562*9712c20fSFrederick Mayle // in this table, but that would be quite unusual.
1563*9712c20fSFrederick Mayle static const uint32_t kMaxTypesAndForms = 5;
1564*9712c20fSFrederick Mayle uint32_t content_types[kMaxTypesAndForms];
1565*9712c20fSFrederick Mayle uint32_t content_forms[kMaxTypesAndForms];
1566*9712c20fSFrederick Mayle uint32_t format_count;
1567*9712c20fSFrederick Mayle size_t len;
1568*9712c20fSFrederick Mayle
1569*9712c20fSFrederick Mayle ReadTypesAndForms(&lineptr, content_types, content_forms, kMaxTypesAndForms,
1570*9712c20fSFrederick Mayle &format_count);
1571*9712c20fSFrederick Mayle uint32_t entry_count = reader_->ReadUnsignedLEB128(lineptr, &len);
1572*9712c20fSFrederick Mayle lineptr += len;
1573*9712c20fSFrederick Mayle for (uint32_t row = 0; row < entry_count; ++row) {
1574*9712c20fSFrederick Mayle const char* dirname = nullptr;
1575*9712c20fSFrederick Mayle for (uint32_t col = 0; col < format_count; ++col) {
1576*9712c20fSFrederick Mayle // The path is the only relevant content type for this implementation.
1577*9712c20fSFrederick Mayle if (content_types[col] == DW_LNCT_path) {
1578*9712c20fSFrederick Mayle dirname = ReadStringForm(content_forms[col], &lineptr);
1579*9712c20fSFrederick Mayle }
1580*9712c20fSFrederick Mayle }
1581*9712c20fSFrederick Mayle handler_->DefineDir(dirname, row);
1582*9712c20fSFrederick Mayle }
1583*9712c20fSFrederick Mayle
1584*9712c20fSFrederick Mayle // Read the DWARF-5 filename table.
1585*9712c20fSFrederick Mayle ReadTypesAndForms(&lineptr, content_types, content_forms, kMaxTypesAndForms,
1586*9712c20fSFrederick Mayle &format_count);
1587*9712c20fSFrederick Mayle entry_count = reader_->ReadUnsignedLEB128(lineptr, &len);
1588*9712c20fSFrederick Mayle lineptr += len;
1589*9712c20fSFrederick Mayle
1590*9712c20fSFrederick Mayle for (uint32_t row = 0; row < entry_count; ++row) {
1591*9712c20fSFrederick Mayle ReadFileRow(&lineptr, content_types, content_forms, row, format_count);
1592*9712c20fSFrederick Mayle }
1593*9712c20fSFrederick Mayle }
1594*9712c20fSFrederick Mayle after_header_ = lineptr;
1595*9712c20fSFrederick Mayle }
1596*9712c20fSFrederick Mayle
1597*9712c20fSFrederick Mayle /* static */
ProcessOneOpcode(ByteReader * reader,LineInfoHandler * handler,const struct LineInfoHeader & header,const uint8_t * start,struct LineStateMachine * lsm,size_t * len,uintptr pc,bool * lsm_passes_pc)1598*9712c20fSFrederick Mayle bool LineInfo::ProcessOneOpcode(ByteReader* reader,
1599*9712c20fSFrederick Mayle LineInfoHandler* handler,
1600*9712c20fSFrederick Mayle const struct LineInfoHeader& header,
1601*9712c20fSFrederick Mayle const uint8_t* start,
1602*9712c20fSFrederick Mayle struct LineStateMachine* lsm,
1603*9712c20fSFrederick Mayle size_t* len,
1604*9712c20fSFrederick Mayle uintptr pc,
1605*9712c20fSFrederick Mayle bool* lsm_passes_pc) {
1606*9712c20fSFrederick Mayle size_t oplen = 0;
1607*9712c20fSFrederick Mayle size_t templen;
1608*9712c20fSFrederick Mayle uint8_t opcode = reader->ReadOneByte(start);
1609*9712c20fSFrederick Mayle oplen++;
1610*9712c20fSFrederick Mayle start++;
1611*9712c20fSFrederick Mayle
1612*9712c20fSFrederick Mayle // If the opcode is great than the opcode_base, it is a special
1613*9712c20fSFrederick Mayle // opcode. Most line programs consist mainly of special opcodes.
1614*9712c20fSFrederick Mayle if (opcode >= header.opcode_base) {
1615*9712c20fSFrederick Mayle opcode -= header.opcode_base;
1616*9712c20fSFrederick Mayle const int64_t advance_address = (opcode / header.line_range)
1617*9712c20fSFrederick Mayle * header.min_insn_length;
1618*9712c20fSFrederick Mayle const int32_t advance_line = (opcode % header.line_range)
1619*9712c20fSFrederick Mayle + header.line_base;
1620*9712c20fSFrederick Mayle
1621*9712c20fSFrederick Mayle // Check if the lsm passes "pc". If so, mark it as passed.
1622*9712c20fSFrederick Mayle if (lsm_passes_pc &&
1623*9712c20fSFrederick Mayle lsm->address <= pc && pc < lsm->address + advance_address) {
1624*9712c20fSFrederick Mayle *lsm_passes_pc = true;
1625*9712c20fSFrederick Mayle }
1626*9712c20fSFrederick Mayle
1627*9712c20fSFrederick Mayle lsm->address += advance_address;
1628*9712c20fSFrederick Mayle lsm->line_num += advance_line;
1629*9712c20fSFrederick Mayle lsm->basic_block = true;
1630*9712c20fSFrederick Mayle *len = oplen;
1631*9712c20fSFrederick Mayle return true;
1632*9712c20fSFrederick Mayle }
1633*9712c20fSFrederick Mayle
1634*9712c20fSFrederick Mayle // Otherwise, we have the regular opcodes
1635*9712c20fSFrederick Mayle switch (opcode) {
1636*9712c20fSFrederick Mayle case DW_LNS_copy: {
1637*9712c20fSFrederick Mayle lsm->basic_block = false;
1638*9712c20fSFrederick Mayle *len = oplen;
1639*9712c20fSFrederick Mayle return true;
1640*9712c20fSFrederick Mayle }
1641*9712c20fSFrederick Mayle
1642*9712c20fSFrederick Mayle case DW_LNS_advance_pc: {
1643*9712c20fSFrederick Mayle uint64_t advance_address = reader->ReadUnsignedLEB128(start, &templen);
1644*9712c20fSFrederick Mayle oplen += templen;
1645*9712c20fSFrederick Mayle
1646*9712c20fSFrederick Mayle // Check if the lsm passes "pc". If so, mark it as passed.
1647*9712c20fSFrederick Mayle if (lsm_passes_pc && lsm->address <= pc &&
1648*9712c20fSFrederick Mayle pc < lsm->address + header.min_insn_length * advance_address) {
1649*9712c20fSFrederick Mayle *lsm_passes_pc = true;
1650*9712c20fSFrederick Mayle }
1651*9712c20fSFrederick Mayle
1652*9712c20fSFrederick Mayle lsm->address += header.min_insn_length * advance_address;
1653*9712c20fSFrederick Mayle }
1654*9712c20fSFrederick Mayle break;
1655*9712c20fSFrederick Mayle case DW_LNS_advance_line: {
1656*9712c20fSFrederick Mayle const int64_t advance_line = reader->ReadSignedLEB128(start, &templen);
1657*9712c20fSFrederick Mayle oplen += templen;
1658*9712c20fSFrederick Mayle lsm->line_num += static_cast<int32_t>(advance_line);
1659*9712c20fSFrederick Mayle
1660*9712c20fSFrederick Mayle // With gcc 4.2.1, we can get the line_no here for the first time
1661*9712c20fSFrederick Mayle // since DW_LNS_advance_line is called after DW_LNE_set_address is
1662*9712c20fSFrederick Mayle // called. So we check if the lsm passes "pc" here, not in
1663*9712c20fSFrederick Mayle // DW_LNE_set_address.
1664*9712c20fSFrederick Mayle if (lsm_passes_pc && lsm->address == pc) {
1665*9712c20fSFrederick Mayle *lsm_passes_pc = true;
1666*9712c20fSFrederick Mayle }
1667*9712c20fSFrederick Mayle }
1668*9712c20fSFrederick Mayle break;
1669*9712c20fSFrederick Mayle case DW_LNS_set_file: {
1670*9712c20fSFrederick Mayle const uint64_t fileno = reader->ReadUnsignedLEB128(start, &templen);
1671*9712c20fSFrederick Mayle oplen += templen;
1672*9712c20fSFrederick Mayle lsm->file_num = static_cast<uint32_t>(fileno);
1673*9712c20fSFrederick Mayle }
1674*9712c20fSFrederick Mayle break;
1675*9712c20fSFrederick Mayle case DW_LNS_set_column: {
1676*9712c20fSFrederick Mayle const uint64_t colno = reader->ReadUnsignedLEB128(start, &templen);
1677*9712c20fSFrederick Mayle oplen += templen;
1678*9712c20fSFrederick Mayle lsm->column_num = static_cast<uint32_t>(colno);
1679*9712c20fSFrederick Mayle }
1680*9712c20fSFrederick Mayle break;
1681*9712c20fSFrederick Mayle case DW_LNS_negate_stmt: {
1682*9712c20fSFrederick Mayle lsm->is_stmt = !lsm->is_stmt;
1683*9712c20fSFrederick Mayle }
1684*9712c20fSFrederick Mayle break;
1685*9712c20fSFrederick Mayle case DW_LNS_set_basic_block: {
1686*9712c20fSFrederick Mayle lsm->basic_block = true;
1687*9712c20fSFrederick Mayle }
1688*9712c20fSFrederick Mayle break;
1689*9712c20fSFrederick Mayle case DW_LNS_fixed_advance_pc: {
1690*9712c20fSFrederick Mayle const uint16_t advance_address = reader->ReadTwoBytes(start);
1691*9712c20fSFrederick Mayle oplen += 2;
1692*9712c20fSFrederick Mayle
1693*9712c20fSFrederick Mayle // Check if the lsm passes "pc". If so, mark it as passed.
1694*9712c20fSFrederick Mayle if (lsm_passes_pc &&
1695*9712c20fSFrederick Mayle lsm->address <= pc && pc < lsm->address + advance_address) {
1696*9712c20fSFrederick Mayle *lsm_passes_pc = true;
1697*9712c20fSFrederick Mayle }
1698*9712c20fSFrederick Mayle
1699*9712c20fSFrederick Mayle lsm->address += advance_address;
1700*9712c20fSFrederick Mayle }
1701*9712c20fSFrederick Mayle break;
1702*9712c20fSFrederick Mayle case DW_LNS_const_add_pc: {
1703*9712c20fSFrederick Mayle const int64_t advance_address = header.min_insn_length
1704*9712c20fSFrederick Mayle * ((255 - header.opcode_base)
1705*9712c20fSFrederick Mayle / header.line_range);
1706*9712c20fSFrederick Mayle
1707*9712c20fSFrederick Mayle // Check if the lsm passes "pc". If so, mark it as passed.
1708*9712c20fSFrederick Mayle if (lsm_passes_pc &&
1709*9712c20fSFrederick Mayle lsm->address <= pc && pc < lsm->address + advance_address) {
1710*9712c20fSFrederick Mayle *lsm_passes_pc = true;
1711*9712c20fSFrederick Mayle }
1712*9712c20fSFrederick Mayle
1713*9712c20fSFrederick Mayle lsm->address += advance_address;
1714*9712c20fSFrederick Mayle }
1715*9712c20fSFrederick Mayle break;
1716*9712c20fSFrederick Mayle case DW_LNS_extended_op: {
1717*9712c20fSFrederick Mayle const uint64_t extended_op_len = reader->ReadUnsignedLEB128(start,
1718*9712c20fSFrederick Mayle &templen);
1719*9712c20fSFrederick Mayle start += templen;
1720*9712c20fSFrederick Mayle oplen += templen + extended_op_len;
1721*9712c20fSFrederick Mayle
1722*9712c20fSFrederick Mayle const uint64_t extended_op = reader->ReadOneByte(start);
1723*9712c20fSFrederick Mayle start++;
1724*9712c20fSFrederick Mayle
1725*9712c20fSFrederick Mayle switch (extended_op) {
1726*9712c20fSFrederick Mayle case DW_LNE_end_sequence: {
1727*9712c20fSFrederick Mayle lsm->end_sequence = true;
1728*9712c20fSFrederick Mayle *len = oplen;
1729*9712c20fSFrederick Mayle return true;
1730*9712c20fSFrederick Mayle }
1731*9712c20fSFrederick Mayle break;
1732*9712c20fSFrederick Mayle case DW_LNE_set_address: {
1733*9712c20fSFrederick Mayle // With gcc 4.2.1, we cannot tell the line_no here since
1734*9712c20fSFrederick Mayle // DW_LNE_set_address is called before DW_LNS_advance_line is
1735*9712c20fSFrederick Mayle // called. So we do not check if the lsm passes "pc" here. See
1736*9712c20fSFrederick Mayle // also the comment in DW_LNS_advance_line.
1737*9712c20fSFrederick Mayle uint64_t address = reader->ReadAddress(start);
1738*9712c20fSFrederick Mayle lsm->address = address;
1739*9712c20fSFrederick Mayle }
1740*9712c20fSFrederick Mayle break;
1741*9712c20fSFrederick Mayle case DW_LNE_define_file: {
1742*9712c20fSFrederick Mayle const char* filename = reinterpret_cast<const char*>(start);
1743*9712c20fSFrederick Mayle
1744*9712c20fSFrederick Mayle templen = strlen(filename) + 1;
1745*9712c20fSFrederick Mayle start += templen;
1746*9712c20fSFrederick Mayle
1747*9712c20fSFrederick Mayle uint64_t dirindex = reader->ReadUnsignedLEB128(start, &templen);
1748*9712c20fSFrederick Mayle oplen += templen;
1749*9712c20fSFrederick Mayle
1750*9712c20fSFrederick Mayle const uint64_t mod_time = reader->ReadUnsignedLEB128(start,
1751*9712c20fSFrederick Mayle &templen);
1752*9712c20fSFrederick Mayle oplen += templen;
1753*9712c20fSFrederick Mayle
1754*9712c20fSFrederick Mayle const uint64_t filelength = reader->ReadUnsignedLEB128(start,
1755*9712c20fSFrederick Mayle &templen);
1756*9712c20fSFrederick Mayle oplen += templen;
1757*9712c20fSFrederick Mayle
1758*9712c20fSFrederick Mayle if (handler) {
1759*9712c20fSFrederick Mayle handler->DefineFile(filename, -1, static_cast<uint32_t>(dirindex),
1760*9712c20fSFrederick Mayle mod_time, filelength);
1761*9712c20fSFrederick Mayle }
1762*9712c20fSFrederick Mayle }
1763*9712c20fSFrederick Mayle break;
1764*9712c20fSFrederick Mayle }
1765*9712c20fSFrederick Mayle }
1766*9712c20fSFrederick Mayle break;
1767*9712c20fSFrederick Mayle
1768*9712c20fSFrederick Mayle default: {
1769*9712c20fSFrederick Mayle // Ignore unknown opcode silently
1770*9712c20fSFrederick Mayle if (header.std_opcode_lengths) {
1771*9712c20fSFrederick Mayle for (int i = 0; i < (*header.std_opcode_lengths)[opcode]; i++) {
1772*9712c20fSFrederick Mayle reader->ReadUnsignedLEB128(start, &templen);
1773*9712c20fSFrederick Mayle start += templen;
1774*9712c20fSFrederick Mayle oplen += templen;
1775*9712c20fSFrederick Mayle }
1776*9712c20fSFrederick Mayle }
1777*9712c20fSFrederick Mayle }
1778*9712c20fSFrederick Mayle break;
1779*9712c20fSFrederick Mayle }
1780*9712c20fSFrederick Mayle *len = oplen;
1781*9712c20fSFrederick Mayle return false;
1782*9712c20fSFrederick Mayle }
1783*9712c20fSFrederick Mayle
ReadLines()1784*9712c20fSFrederick Mayle void LineInfo::ReadLines() {
1785*9712c20fSFrederick Mayle struct LineStateMachine lsm;
1786*9712c20fSFrederick Mayle
1787*9712c20fSFrederick Mayle // lengthstart is the place the length field is based on.
1788*9712c20fSFrederick Mayle // It is the point in the header after the initial length field
1789*9712c20fSFrederick Mayle const uint8_t* lengthstart = buffer_;
1790*9712c20fSFrederick Mayle
1791*9712c20fSFrederick Mayle // In 64 bit dwarf, the initial length is 12 bytes, because of the
1792*9712c20fSFrederick Mayle // 0xffffffff at the start.
1793*9712c20fSFrederick Mayle if (reader_->OffsetSize() == 8)
1794*9712c20fSFrederick Mayle lengthstart += 12;
1795*9712c20fSFrederick Mayle else
1796*9712c20fSFrederick Mayle lengthstart += 4;
1797*9712c20fSFrederick Mayle
1798*9712c20fSFrederick Mayle const uint8_t* lineptr = after_header_;
1799*9712c20fSFrederick Mayle lsm.Reset(header_.default_is_stmt);
1800*9712c20fSFrederick Mayle
1801*9712c20fSFrederick Mayle // The LineInfoHandler interface expects each line's length along
1802*9712c20fSFrederick Mayle // with its address, but DWARF only provides addresses (sans
1803*9712c20fSFrederick Mayle // length), and an end-of-sequence address; one infers the length
1804*9712c20fSFrederick Mayle // from the next address. So we report a line only when we get the
1805*9712c20fSFrederick Mayle // next line's address, or the end-of-sequence address.
1806*9712c20fSFrederick Mayle bool have_pending_line = false;
1807*9712c20fSFrederick Mayle uint64_t pending_address = 0;
1808*9712c20fSFrederick Mayle uint32_t pending_file_num = 0, pending_line_num = 0, pending_column_num = 0;
1809*9712c20fSFrederick Mayle
1810*9712c20fSFrederick Mayle while (lineptr < lengthstart + header_.total_length) {
1811*9712c20fSFrederick Mayle size_t oplength;
1812*9712c20fSFrederick Mayle bool add_row = ProcessOneOpcode(reader_, handler_, header_,
1813*9712c20fSFrederick Mayle lineptr, &lsm, &oplength, (uintptr)-1,
1814*9712c20fSFrederick Mayle NULL);
1815*9712c20fSFrederick Mayle if (add_row) {
1816*9712c20fSFrederick Mayle if (have_pending_line)
1817*9712c20fSFrederick Mayle handler_->AddLine(pending_address, lsm.address - pending_address,
1818*9712c20fSFrederick Mayle pending_file_num, pending_line_num,
1819*9712c20fSFrederick Mayle pending_column_num);
1820*9712c20fSFrederick Mayle if (lsm.end_sequence) {
1821*9712c20fSFrederick Mayle lsm.Reset(header_.default_is_stmt);
1822*9712c20fSFrederick Mayle have_pending_line = false;
1823*9712c20fSFrederick Mayle } else {
1824*9712c20fSFrederick Mayle pending_address = lsm.address;
1825*9712c20fSFrederick Mayle pending_file_num = lsm.file_num;
1826*9712c20fSFrederick Mayle pending_line_num = lsm.line_num;
1827*9712c20fSFrederick Mayle pending_column_num = lsm.column_num;
1828*9712c20fSFrederick Mayle have_pending_line = true;
1829*9712c20fSFrederick Mayle }
1830*9712c20fSFrederick Mayle }
1831*9712c20fSFrederick Mayle lineptr += oplength;
1832*9712c20fSFrederick Mayle }
1833*9712c20fSFrederick Mayle
1834*9712c20fSFrederick Mayle after_header_ = lengthstart + header_.total_length;
1835*9712c20fSFrederick Mayle }
1836*9712c20fSFrederick Mayle
ReadRanges(enum DwarfForm form,uint64_t data)1837*9712c20fSFrederick Mayle bool RangeListReader::ReadRanges(enum DwarfForm form, uint64_t data) {
1838*9712c20fSFrederick Mayle if (form == DW_FORM_sec_offset) {
1839*9712c20fSFrederick Mayle if (cu_info_->version_ <= 4) {
1840*9712c20fSFrederick Mayle return ReadDebugRanges(data);
1841*9712c20fSFrederick Mayle } else {
1842*9712c20fSFrederick Mayle return ReadDebugRngList(data);
1843*9712c20fSFrederick Mayle }
1844*9712c20fSFrederick Mayle } else if (form == DW_FORM_rnglistx) {
1845*9712c20fSFrederick Mayle if (cu_info_->ranges_base_ == 0) {
1846*9712c20fSFrederick Mayle // In split dwarf, there's no DW_AT_rnglists_base attribute, range_base
1847*9712c20fSFrederick Mayle // will just be the first byte after the header.
1848*9712c20fSFrederick Mayle cu_info_->ranges_base_ = reader_->OffsetSize() == 4? 12: 20;
1849*9712c20fSFrederick Mayle }
1850*9712c20fSFrederick Mayle offset_array_ = cu_info_->ranges_base_;
1851*9712c20fSFrederick Mayle uint64_t index_offset = reader_->OffsetSize() * data;
1852*9712c20fSFrederick Mayle uint64_t range_list_offset =
1853*9712c20fSFrederick Mayle reader_->ReadOffset(cu_info_->buffer_ + offset_array_ + index_offset);
1854*9712c20fSFrederick Mayle
1855*9712c20fSFrederick Mayle return ReadDebugRngList(offset_array_ + range_list_offset);
1856*9712c20fSFrederick Mayle }
1857*9712c20fSFrederick Mayle return false;
1858*9712c20fSFrederick Mayle }
1859*9712c20fSFrederick Mayle
ReadDebugRanges(uint64_t offset)1860*9712c20fSFrederick Mayle bool RangeListReader::ReadDebugRanges(uint64_t offset) {
1861*9712c20fSFrederick Mayle const uint64_t max_address =
1862*9712c20fSFrederick Mayle (reader_->AddressSize() == 4) ? 0xffffffffUL
1863*9712c20fSFrederick Mayle : 0xffffffffffffffffULL;
1864*9712c20fSFrederick Mayle const uint64_t entry_size = reader_->AddressSize() * 2;
1865*9712c20fSFrederick Mayle bool list_end = false;
1866*9712c20fSFrederick Mayle
1867*9712c20fSFrederick Mayle do {
1868*9712c20fSFrederick Mayle if (offset > cu_info_->size_ - entry_size) {
1869*9712c20fSFrederick Mayle return false; // Invalid range detected
1870*9712c20fSFrederick Mayle }
1871*9712c20fSFrederick Mayle
1872*9712c20fSFrederick Mayle uint64_t start_address = reader_->ReadAddress(cu_info_->buffer_ + offset);
1873*9712c20fSFrederick Mayle uint64_t end_address = reader_->ReadAddress(
1874*9712c20fSFrederick Mayle cu_info_->buffer_ + offset + reader_->AddressSize());
1875*9712c20fSFrederick Mayle
1876*9712c20fSFrederick Mayle if (start_address == max_address) { // Base address selection
1877*9712c20fSFrederick Mayle cu_info_->base_address_ = end_address;
1878*9712c20fSFrederick Mayle } else if (start_address == 0 && end_address == 0) { // End-of-list
1879*9712c20fSFrederick Mayle handler_->Finish();
1880*9712c20fSFrederick Mayle list_end = true;
1881*9712c20fSFrederick Mayle } else { // Add a range entry
1882*9712c20fSFrederick Mayle handler_->AddRange(start_address + cu_info_->base_address_,
1883*9712c20fSFrederick Mayle end_address + cu_info_->base_address_);
1884*9712c20fSFrederick Mayle }
1885*9712c20fSFrederick Mayle
1886*9712c20fSFrederick Mayle offset += entry_size;
1887*9712c20fSFrederick Mayle } while (!list_end);
1888*9712c20fSFrederick Mayle
1889*9712c20fSFrederick Mayle return true;
1890*9712c20fSFrederick Mayle }
1891*9712c20fSFrederick Mayle
ReadDebugRngList(uint64_t offset)1892*9712c20fSFrederick Mayle bool RangeListReader::ReadDebugRngList(uint64_t offset) {
1893*9712c20fSFrederick Mayle uint64_t start = 0;
1894*9712c20fSFrederick Mayle uint64_t end = 0;
1895*9712c20fSFrederick Mayle uint64_t range_len = 0;
1896*9712c20fSFrederick Mayle uint64_t index = 0;
1897*9712c20fSFrederick Mayle // A uleb128's length isn't known until after it has been read, so overruns
1898*9712c20fSFrederick Mayle // are only caught after an entire entry.
1899*9712c20fSFrederick Mayle while (offset < cu_info_->size_) {
1900*9712c20fSFrederick Mayle uint8_t entry_type = reader_->ReadOneByte(cu_info_->buffer_ + offset);
1901*9712c20fSFrederick Mayle offset += 1;
1902*9712c20fSFrederick Mayle // Handle each entry type per Dwarf 5 Standard, section 2.17.3.
1903*9712c20fSFrederick Mayle switch (entry_type) {
1904*9712c20fSFrederick Mayle case DW_RLE_end_of_list:
1905*9712c20fSFrederick Mayle handler_->Finish();
1906*9712c20fSFrederick Mayle return true;
1907*9712c20fSFrederick Mayle case DW_RLE_base_addressx:
1908*9712c20fSFrederick Mayle offset += ReadULEB(offset, &index);
1909*9712c20fSFrederick Mayle cu_info_->base_address_ = GetAddressAtIndex(index);
1910*9712c20fSFrederick Mayle break;
1911*9712c20fSFrederick Mayle case DW_RLE_startx_endx:
1912*9712c20fSFrederick Mayle offset += ReadULEB(offset, &index);
1913*9712c20fSFrederick Mayle start = GetAddressAtIndex(index);
1914*9712c20fSFrederick Mayle offset += ReadULEB(offset, &index);
1915*9712c20fSFrederick Mayle end = GetAddressAtIndex(index);
1916*9712c20fSFrederick Mayle handler_->AddRange(start, end);
1917*9712c20fSFrederick Mayle break;
1918*9712c20fSFrederick Mayle case DW_RLE_startx_length:
1919*9712c20fSFrederick Mayle offset += ReadULEB(offset, &index);
1920*9712c20fSFrederick Mayle start = GetAddressAtIndex(index);
1921*9712c20fSFrederick Mayle offset += ReadULEB(offset, &range_len);
1922*9712c20fSFrederick Mayle handler_->AddRange(start, start + range_len);
1923*9712c20fSFrederick Mayle break;
1924*9712c20fSFrederick Mayle case DW_RLE_offset_pair:
1925*9712c20fSFrederick Mayle offset += ReadULEB(offset, &start);
1926*9712c20fSFrederick Mayle offset += ReadULEB(offset, &end);
1927*9712c20fSFrederick Mayle handler_->AddRange(start + cu_info_->base_address_,
1928*9712c20fSFrederick Mayle end + cu_info_->base_address_);
1929*9712c20fSFrederick Mayle break;
1930*9712c20fSFrederick Mayle case DW_RLE_base_address:
1931*9712c20fSFrederick Mayle offset += ReadAddress(offset, &cu_info_->base_address_);
1932*9712c20fSFrederick Mayle break;
1933*9712c20fSFrederick Mayle case DW_RLE_start_end:
1934*9712c20fSFrederick Mayle offset += ReadAddress(offset, &start);
1935*9712c20fSFrederick Mayle offset += ReadAddress(offset, &end);
1936*9712c20fSFrederick Mayle handler_->AddRange(start, end);
1937*9712c20fSFrederick Mayle break;
1938*9712c20fSFrederick Mayle case DW_RLE_start_length:
1939*9712c20fSFrederick Mayle offset += ReadAddress(offset, &start);
1940*9712c20fSFrederick Mayle offset += ReadULEB(offset, &end);
1941*9712c20fSFrederick Mayle handler_->AddRange(start, start + end);
1942*9712c20fSFrederick Mayle break;
1943*9712c20fSFrederick Mayle }
1944*9712c20fSFrederick Mayle }
1945*9712c20fSFrederick Mayle return false;
1946*9712c20fSFrederick Mayle }
1947*9712c20fSFrederick Mayle
1948*9712c20fSFrederick Mayle // A DWARF rule for recovering the address or value of a register, or
1949*9712c20fSFrederick Mayle // computing the canonical frame address. There is one subclass of this for
1950*9712c20fSFrederick Mayle // each '*Rule' member function in CallFrameInfo::Handler.
1951*9712c20fSFrederick Mayle //
1952*9712c20fSFrederick Mayle // It's annoying that we have to handle Rules using pointers (because
1953*9712c20fSFrederick Mayle // the concrete instances can have an arbitrary size). They're small,
1954*9712c20fSFrederick Mayle // so it would be much nicer if we could just handle them by value
1955*9712c20fSFrederick Mayle // instead of fretting about ownership and destruction.
1956*9712c20fSFrederick Mayle //
1957*9712c20fSFrederick Mayle // It seems like all these could simply be instances of std::tr1::bind,
1958*9712c20fSFrederick Mayle // except that we need instances to be EqualityComparable, too.
1959*9712c20fSFrederick Mayle //
1960*9712c20fSFrederick Mayle // This could logically be nested within State, but then the qualified names
1961*9712c20fSFrederick Mayle // get horrendous.
1962*9712c20fSFrederick Mayle class CallFrameInfo::Rule {
1963*9712c20fSFrederick Mayle public:
~Rule()1964*9712c20fSFrederick Mayle virtual ~Rule() { }
1965*9712c20fSFrederick Mayle
1966*9712c20fSFrederick Mayle // Tell HANDLER that, at ADDRESS in the program, REG can be recovered using
1967*9712c20fSFrederick Mayle // this rule. If REG is kCFARegister, then this rule describes how to compute
1968*9712c20fSFrederick Mayle // the canonical frame address. Return what the HANDLER member function
1969*9712c20fSFrederick Mayle // returned.
1970*9712c20fSFrederick Mayle virtual bool Handle(Handler* handler,
1971*9712c20fSFrederick Mayle uint64_t address, int reg) const = 0;
1972*9712c20fSFrederick Mayle
1973*9712c20fSFrederick Mayle // Equality on rules. We use these to decide which rules we need
1974*9712c20fSFrederick Mayle // to report after a DW_CFA_restore_state instruction.
1975*9712c20fSFrederick Mayle virtual bool operator==(const Rule& rhs) const = 0;
1976*9712c20fSFrederick Mayle
operator !=(const Rule & rhs) const1977*9712c20fSFrederick Mayle bool operator!=(const Rule& rhs) const { return ! (*this == rhs); }
1978*9712c20fSFrederick Mayle
1979*9712c20fSFrederick Mayle // Return a pointer to a copy of this rule.
1980*9712c20fSFrederick Mayle virtual Rule* Copy() const = 0;
1981*9712c20fSFrederick Mayle
1982*9712c20fSFrederick Mayle // If this is a base+offset rule, change its base register to REG.
1983*9712c20fSFrederick Mayle // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.)
SetBaseRegister(unsigned reg)1984*9712c20fSFrederick Mayle virtual void SetBaseRegister(unsigned reg) { }
1985*9712c20fSFrederick Mayle
1986*9712c20fSFrederick Mayle // If this is a base+offset rule, change its offset to OFFSET. Otherwise,
1987*9712c20fSFrederick Mayle // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.)
SetOffset(long long offset)1988*9712c20fSFrederick Mayle virtual void SetOffset(long long offset) { }
1989*9712c20fSFrederick Mayle };
1990*9712c20fSFrederick Mayle
1991*9712c20fSFrederick Mayle // Rule: the value the register had in the caller cannot be recovered.
1992*9712c20fSFrederick Mayle class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
1993*9712c20fSFrederick Mayle public:
UndefinedRule()1994*9712c20fSFrederick Mayle UndefinedRule() { }
~UndefinedRule()1995*9712c20fSFrederick Mayle ~UndefinedRule() { }
Handle(Handler * handler,uint64_t address,int reg) const1996*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
1997*9712c20fSFrederick Mayle return handler->UndefinedRule(address, reg);
1998*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const1999*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2000*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2001*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2002*9712c20fSFrederick Mayle const UndefinedRule* our_rhs = dynamic_cast<const UndefinedRule*>(&rhs);
2003*9712c20fSFrederick Mayle return (our_rhs != NULL);
2004*9712c20fSFrederick Mayle }
Copy() const2005*9712c20fSFrederick Mayle Rule* Copy() const { return new UndefinedRule(*this); }
2006*9712c20fSFrederick Mayle };
2007*9712c20fSFrederick Mayle
2008*9712c20fSFrederick Mayle // Rule: the register's value is the same as that it had in the caller.
2009*9712c20fSFrederick Mayle class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
2010*9712c20fSFrederick Mayle public:
SameValueRule()2011*9712c20fSFrederick Mayle SameValueRule() { }
~SameValueRule()2012*9712c20fSFrederick Mayle ~SameValueRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2013*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2014*9712c20fSFrederick Mayle return handler->SameValueRule(address, reg);
2015*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2016*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2017*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2018*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2019*9712c20fSFrederick Mayle const SameValueRule* our_rhs = dynamic_cast<const SameValueRule*>(&rhs);
2020*9712c20fSFrederick Mayle return (our_rhs != NULL);
2021*9712c20fSFrederick Mayle }
Copy() const2022*9712c20fSFrederick Mayle Rule* Copy() const { return new SameValueRule(*this); }
2023*9712c20fSFrederick Mayle };
2024*9712c20fSFrederick Mayle
2025*9712c20fSFrederick Mayle // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER
2026*9712c20fSFrederick Mayle // may be CallFrameInfo::Handler::kCFARegister.
2027*9712c20fSFrederick Mayle class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
2028*9712c20fSFrederick Mayle public:
OffsetRule(int base_register,long offset)2029*9712c20fSFrederick Mayle OffsetRule(int base_register, long offset)
2030*9712c20fSFrederick Mayle : base_register_(base_register), offset_(offset) { }
~OffsetRule()2031*9712c20fSFrederick Mayle ~OffsetRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2032*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2033*9712c20fSFrederick Mayle return handler->OffsetRule(address, reg, base_register_, offset_);
2034*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2035*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2036*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2037*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2038*9712c20fSFrederick Mayle const OffsetRule* our_rhs = dynamic_cast<const OffsetRule*>(&rhs);
2039*9712c20fSFrederick Mayle return (our_rhs &&
2040*9712c20fSFrederick Mayle base_register_ == our_rhs->base_register_ &&
2041*9712c20fSFrederick Mayle offset_ == our_rhs->offset_);
2042*9712c20fSFrederick Mayle }
Copy() const2043*9712c20fSFrederick Mayle Rule* Copy() const { return new OffsetRule(*this); }
2044*9712c20fSFrederick Mayle // We don't actually need SetBaseRegister or SetOffset here, since they
2045*9712c20fSFrederick Mayle // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it
2046*9712c20fSFrederick Mayle // doesn't make sense to use OffsetRule for computing the CFA: it
2047*9712c20fSFrederick Mayle // computes the address at which a register is saved, not a value.
2048*9712c20fSFrederick Mayle private:
2049*9712c20fSFrederick Mayle int base_register_;
2050*9712c20fSFrederick Mayle long offset_;
2051*9712c20fSFrederick Mayle };
2052*9712c20fSFrederick Mayle
2053*9712c20fSFrederick Mayle // Rule: the value the register had in the caller is the value of
2054*9712c20fSFrederick Mayle // BASE_REGISTER plus offset. BASE_REGISTER may be
2055*9712c20fSFrederick Mayle // CallFrameInfo::Handler::kCFARegister.
2056*9712c20fSFrederick Mayle class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
2057*9712c20fSFrederick Mayle public:
ValOffsetRule(int base_register,long offset)2058*9712c20fSFrederick Mayle ValOffsetRule(int base_register, long offset)
2059*9712c20fSFrederick Mayle : base_register_(base_register), offset_(offset) { }
~ValOffsetRule()2060*9712c20fSFrederick Mayle ~ValOffsetRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2061*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2062*9712c20fSFrederick Mayle return handler->ValOffsetRule(address, reg, base_register_, offset_);
2063*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2064*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2065*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2066*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2067*9712c20fSFrederick Mayle const ValOffsetRule* our_rhs = dynamic_cast<const ValOffsetRule*>(&rhs);
2068*9712c20fSFrederick Mayle return (our_rhs &&
2069*9712c20fSFrederick Mayle base_register_ == our_rhs->base_register_ &&
2070*9712c20fSFrederick Mayle offset_ == our_rhs->offset_);
2071*9712c20fSFrederick Mayle }
Copy() const2072*9712c20fSFrederick Mayle Rule* Copy() const { return new ValOffsetRule(*this); }
SetBaseRegister(unsigned reg)2073*9712c20fSFrederick Mayle void SetBaseRegister(unsigned reg) { base_register_ = reg; }
SetOffset(long long offset)2074*9712c20fSFrederick Mayle void SetOffset(long long offset) { offset_ = offset; }
2075*9712c20fSFrederick Mayle private:
2076*9712c20fSFrederick Mayle int base_register_;
2077*9712c20fSFrederick Mayle long offset_;
2078*9712c20fSFrederick Mayle };
2079*9712c20fSFrederick Mayle
2080*9712c20fSFrederick Mayle // Rule: the register has been saved in another register REGISTER_NUMBER_.
2081*9712c20fSFrederick Mayle class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
2082*9712c20fSFrederick Mayle public:
RegisterRule(int register_number)2083*9712c20fSFrederick Mayle explicit RegisterRule(int register_number)
2084*9712c20fSFrederick Mayle : register_number_(register_number) { }
~RegisterRule()2085*9712c20fSFrederick Mayle ~RegisterRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2086*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2087*9712c20fSFrederick Mayle return handler->RegisterRule(address, reg, register_number_);
2088*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2089*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2090*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2091*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2092*9712c20fSFrederick Mayle const RegisterRule* our_rhs = dynamic_cast<const RegisterRule*>(&rhs);
2093*9712c20fSFrederick Mayle return (our_rhs && register_number_ == our_rhs->register_number_);
2094*9712c20fSFrederick Mayle }
Copy() const2095*9712c20fSFrederick Mayle Rule* Copy() const { return new RegisterRule(*this); }
2096*9712c20fSFrederick Mayle private:
2097*9712c20fSFrederick Mayle int register_number_;
2098*9712c20fSFrederick Mayle };
2099*9712c20fSFrederick Mayle
2100*9712c20fSFrederick Mayle // Rule: EXPRESSION evaluates to the address at which the register is saved.
2101*9712c20fSFrederick Mayle class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
2102*9712c20fSFrederick Mayle public:
ExpressionRule(const string & expression)2103*9712c20fSFrederick Mayle explicit ExpressionRule(const string& expression)
2104*9712c20fSFrederick Mayle : expression_(expression) { }
~ExpressionRule()2105*9712c20fSFrederick Mayle ~ExpressionRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2106*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2107*9712c20fSFrederick Mayle return handler->ExpressionRule(address, reg, expression_);
2108*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2109*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2110*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2111*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2112*9712c20fSFrederick Mayle const ExpressionRule* our_rhs = dynamic_cast<const ExpressionRule*>(&rhs);
2113*9712c20fSFrederick Mayle return (our_rhs && expression_ == our_rhs->expression_);
2114*9712c20fSFrederick Mayle }
Copy() const2115*9712c20fSFrederick Mayle Rule* Copy() const { return new ExpressionRule(*this); }
2116*9712c20fSFrederick Mayle private:
2117*9712c20fSFrederick Mayle string expression_;
2118*9712c20fSFrederick Mayle };
2119*9712c20fSFrederick Mayle
2120*9712c20fSFrederick Mayle // Rule: EXPRESSION evaluates to the address at which the register is saved.
2121*9712c20fSFrederick Mayle class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
2122*9712c20fSFrederick Mayle public:
ValExpressionRule(const string & expression)2123*9712c20fSFrederick Mayle explicit ValExpressionRule(const string& expression)
2124*9712c20fSFrederick Mayle : expression_(expression) { }
~ValExpressionRule()2125*9712c20fSFrederick Mayle ~ValExpressionRule() { }
Handle(Handler * handler,uint64_t address,int reg) const2126*9712c20fSFrederick Mayle bool Handle(Handler* handler, uint64_t address, int reg) const {
2127*9712c20fSFrederick Mayle return handler->ValExpressionRule(address, reg, expression_);
2128*9712c20fSFrederick Mayle }
operator ==(const Rule & rhs) const2129*9712c20fSFrederick Mayle bool operator==(const Rule& rhs) const {
2130*9712c20fSFrederick Mayle // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
2131*9712c20fSFrederick Mayle // been carefully considered; cheap RTTI-like workarounds are forbidden.
2132*9712c20fSFrederick Mayle const ValExpressionRule* our_rhs =
2133*9712c20fSFrederick Mayle dynamic_cast<const ValExpressionRule*>(&rhs);
2134*9712c20fSFrederick Mayle return (our_rhs && expression_ == our_rhs->expression_);
2135*9712c20fSFrederick Mayle }
Copy() const2136*9712c20fSFrederick Mayle Rule* Copy() const { return new ValExpressionRule(*this); }
2137*9712c20fSFrederick Mayle private:
2138*9712c20fSFrederick Mayle string expression_;
2139*9712c20fSFrederick Mayle };
2140*9712c20fSFrederick Mayle
2141*9712c20fSFrederick Mayle // A map from register numbers to rules.
2142*9712c20fSFrederick Mayle class CallFrameInfo::RuleMap {
2143*9712c20fSFrederick Mayle public:
RuleMap()2144*9712c20fSFrederick Mayle RuleMap() : cfa_rule_(NULL) { }
RuleMap(const RuleMap & rhs)2145*9712c20fSFrederick Mayle RuleMap(const RuleMap& rhs) : cfa_rule_(NULL) { *this = rhs; }
~RuleMap()2146*9712c20fSFrederick Mayle ~RuleMap() { Clear(); }
2147*9712c20fSFrederick Mayle
2148*9712c20fSFrederick Mayle RuleMap& operator=(const RuleMap& rhs);
2149*9712c20fSFrederick Mayle
2150*9712c20fSFrederick Mayle // Set the rule for computing the CFA to RULE. Take ownership of RULE.
SetCFARule(Rule * rule)2151*9712c20fSFrederick Mayle void SetCFARule(Rule* rule) { delete cfa_rule_; cfa_rule_ = rule; }
2152*9712c20fSFrederick Mayle
2153*9712c20fSFrederick Mayle // Return the current CFA rule. Unlike RegisterRule, this RuleMap retains
2154*9712c20fSFrederick Mayle // ownership of the rule. We use this for DW_CFA_def_cfa_offset and
2155*9712c20fSFrederick Mayle // DW_CFA_def_cfa_register, and for detecting references to the CFA before
2156*9712c20fSFrederick Mayle // a rule for it has been established.
CFARule() const2157*9712c20fSFrederick Mayle Rule* CFARule() const { return cfa_rule_; }
2158*9712c20fSFrederick Mayle
2159*9712c20fSFrederick Mayle // Return the rule for REG, or NULL if there is none. The caller takes
2160*9712c20fSFrederick Mayle // ownership of the result.
2161*9712c20fSFrederick Mayle Rule* RegisterRule(int reg) const;
2162*9712c20fSFrederick Mayle
2163*9712c20fSFrederick Mayle // Set the rule for computing REG to RULE. Take ownership of RULE.
2164*9712c20fSFrederick Mayle void SetRegisterRule(int reg, Rule* rule);
2165*9712c20fSFrederick Mayle
2166*9712c20fSFrederick Mayle // Make all the appropriate calls to HANDLER as if we were changing from
2167*9712c20fSFrederick Mayle // this RuleMap to NEW_RULES at ADDRESS. We use this to implement
2168*9712c20fSFrederick Mayle // DW_CFA_restore_state, where lots of rules can change simultaneously.
2169*9712c20fSFrederick Mayle // Return true if all handlers returned true; otherwise, return false.
2170*9712c20fSFrederick Mayle bool HandleTransitionTo(Handler* handler, uint64_t address,
2171*9712c20fSFrederick Mayle const RuleMap& new_rules) const;
2172*9712c20fSFrederick Mayle
2173*9712c20fSFrederick Mayle private:
2174*9712c20fSFrederick Mayle // A map from register numbers to Rules.
2175*9712c20fSFrederick Mayle typedef std::map<int, Rule*> RuleByNumber;
2176*9712c20fSFrederick Mayle
2177*9712c20fSFrederick Mayle // Remove all register rules and clear cfa_rule_.
2178*9712c20fSFrederick Mayle void Clear();
2179*9712c20fSFrederick Mayle
2180*9712c20fSFrederick Mayle // The rule for computing the canonical frame address. This RuleMap owns
2181*9712c20fSFrederick Mayle // this rule.
2182*9712c20fSFrederick Mayle Rule* cfa_rule_;
2183*9712c20fSFrederick Mayle
2184*9712c20fSFrederick Mayle // A map from register numbers to postfix expressions to recover
2185*9712c20fSFrederick Mayle // their values. This RuleMap owns the Rules the map refers to.
2186*9712c20fSFrederick Mayle RuleByNumber registers_;
2187*9712c20fSFrederick Mayle };
2188*9712c20fSFrederick Mayle
operator =(const RuleMap & rhs)2189*9712c20fSFrederick Mayle CallFrameInfo::RuleMap& CallFrameInfo::RuleMap::operator=(const RuleMap& rhs) {
2190*9712c20fSFrederick Mayle Clear();
2191*9712c20fSFrederick Mayle // Since each map owns the rules it refers to, assignment must copy them.
2192*9712c20fSFrederick Mayle if (rhs.cfa_rule_) cfa_rule_ = rhs.cfa_rule_->Copy();
2193*9712c20fSFrederick Mayle for (RuleByNumber::const_iterator it = rhs.registers_.begin();
2194*9712c20fSFrederick Mayle it != rhs.registers_.end(); it++)
2195*9712c20fSFrederick Mayle registers_[it->first] = it->second->Copy();
2196*9712c20fSFrederick Mayle return *this;
2197*9712c20fSFrederick Mayle }
2198*9712c20fSFrederick Mayle
RegisterRule(int reg) const2199*9712c20fSFrederick Mayle CallFrameInfo::Rule* CallFrameInfo::RuleMap::RegisterRule(int reg) const {
2200*9712c20fSFrederick Mayle assert(reg != Handler::kCFARegister);
2201*9712c20fSFrederick Mayle RuleByNumber::const_iterator it = registers_.find(reg);
2202*9712c20fSFrederick Mayle if (it != registers_.end())
2203*9712c20fSFrederick Mayle return it->second->Copy();
2204*9712c20fSFrederick Mayle else
2205*9712c20fSFrederick Mayle return NULL;
2206*9712c20fSFrederick Mayle }
2207*9712c20fSFrederick Mayle
SetRegisterRule(int reg,Rule * rule)2208*9712c20fSFrederick Mayle void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule* rule) {
2209*9712c20fSFrederick Mayle assert(reg != Handler::kCFARegister);
2210*9712c20fSFrederick Mayle assert(rule);
2211*9712c20fSFrederick Mayle Rule** slot = ®isters_[reg];
2212*9712c20fSFrederick Mayle delete *slot;
2213*9712c20fSFrederick Mayle *slot = rule;
2214*9712c20fSFrederick Mayle }
2215*9712c20fSFrederick Mayle
HandleTransitionTo(Handler * handler,uint64_t address,const RuleMap & new_rules) const2216*9712c20fSFrederick Mayle bool CallFrameInfo::RuleMap::HandleTransitionTo(
2217*9712c20fSFrederick Mayle Handler* handler,
2218*9712c20fSFrederick Mayle uint64_t address,
2219*9712c20fSFrederick Mayle const RuleMap& new_rules) const {
2220*9712c20fSFrederick Mayle // Transition from cfa_rule_ to new_rules.cfa_rule_.
2221*9712c20fSFrederick Mayle if (cfa_rule_ && new_rules.cfa_rule_) {
2222*9712c20fSFrederick Mayle if (*cfa_rule_ != *new_rules.cfa_rule_ &&
2223*9712c20fSFrederick Mayle !new_rules.cfa_rule_->Handle(handler, address,
2224*9712c20fSFrederick Mayle Handler::kCFARegister))
2225*9712c20fSFrederick Mayle return false;
2226*9712c20fSFrederick Mayle } else if (cfa_rule_) {
2227*9712c20fSFrederick Mayle // this RuleMap has a CFA rule but new_rules doesn't.
2228*9712c20fSFrederick Mayle // CallFrameInfo::Handler has no way to handle this --- and shouldn't;
2229*9712c20fSFrederick Mayle // it's garbage input. The instruction interpreter should have
2230*9712c20fSFrederick Mayle // detected this and warned, so take no action here.
2231*9712c20fSFrederick Mayle } else if (new_rules.cfa_rule_) {
2232*9712c20fSFrederick Mayle // This shouldn't be possible: NEW_RULES is some prior state, and
2233*9712c20fSFrederick Mayle // there's no way to remove entries.
2234*9712c20fSFrederick Mayle assert(0);
2235*9712c20fSFrederick Mayle } else {
2236*9712c20fSFrederick Mayle // Both CFA rules are empty. No action needed.
2237*9712c20fSFrederick Mayle }
2238*9712c20fSFrederick Mayle
2239*9712c20fSFrederick Mayle // Traverse the two maps in order by register number, and report
2240*9712c20fSFrederick Mayle // whatever differences we find.
2241*9712c20fSFrederick Mayle RuleByNumber::const_iterator old_it = registers_.begin();
2242*9712c20fSFrederick Mayle RuleByNumber::const_iterator new_it = new_rules.registers_.begin();
2243*9712c20fSFrederick Mayle while (old_it != registers_.end() && new_it != new_rules.registers_.end()) {
2244*9712c20fSFrederick Mayle if (old_it->first < new_it->first) {
2245*9712c20fSFrederick Mayle // This RuleMap has an entry for old_it->first, but NEW_RULES
2246*9712c20fSFrederick Mayle // doesn't.
2247*9712c20fSFrederick Mayle //
2248*9712c20fSFrederick Mayle // This isn't really the right thing to do, but since CFI generally
2249*9712c20fSFrederick Mayle // only mentions callee-saves registers, and GCC's convention for
2250*9712c20fSFrederick Mayle // callee-saves registers is that they are unchanged, it's a good
2251*9712c20fSFrederick Mayle // approximation.
2252*9712c20fSFrederick Mayle if (!handler->SameValueRule(address, old_it->first))
2253*9712c20fSFrederick Mayle return false;
2254*9712c20fSFrederick Mayle old_it++;
2255*9712c20fSFrederick Mayle } else if (old_it->first > new_it->first) {
2256*9712c20fSFrederick Mayle // NEW_RULES has entry for new_it->first, but this RuleMap
2257*9712c20fSFrederick Mayle // doesn't. This shouldn't be possible: NEW_RULES is some prior
2258*9712c20fSFrederick Mayle // state, and there's no way to remove entries.
2259*9712c20fSFrederick Mayle assert(0);
2260*9712c20fSFrederick Mayle } else {
2261*9712c20fSFrederick Mayle // Both maps have an entry for this register. Report the new
2262*9712c20fSFrederick Mayle // rule if it is different.
2263*9712c20fSFrederick Mayle if (*old_it->second != *new_it->second &&
2264*9712c20fSFrederick Mayle !new_it->second->Handle(handler, address, new_it->first))
2265*9712c20fSFrederick Mayle return false;
2266*9712c20fSFrederick Mayle new_it++, old_it++;
2267*9712c20fSFrederick Mayle }
2268*9712c20fSFrederick Mayle }
2269*9712c20fSFrederick Mayle // Finish off entries from this RuleMap with no counterparts in new_rules.
2270*9712c20fSFrederick Mayle while (old_it != registers_.end()) {
2271*9712c20fSFrederick Mayle if (!handler->SameValueRule(address, old_it->first))
2272*9712c20fSFrederick Mayle return false;
2273*9712c20fSFrederick Mayle old_it++;
2274*9712c20fSFrederick Mayle }
2275*9712c20fSFrederick Mayle // Since we only make transitions from a rule set to some previously
2276*9712c20fSFrederick Mayle // saved rule set, and we can only add rules to the map, NEW_RULES
2277*9712c20fSFrederick Mayle // must have fewer rules than *this.
2278*9712c20fSFrederick Mayle assert(new_it == new_rules.registers_.end());
2279*9712c20fSFrederick Mayle
2280*9712c20fSFrederick Mayle return true;
2281*9712c20fSFrederick Mayle }
2282*9712c20fSFrederick Mayle
2283*9712c20fSFrederick Mayle // Remove all register rules and clear cfa_rule_.
Clear()2284*9712c20fSFrederick Mayle void CallFrameInfo::RuleMap::Clear() {
2285*9712c20fSFrederick Mayle delete cfa_rule_;
2286*9712c20fSFrederick Mayle cfa_rule_ = NULL;
2287*9712c20fSFrederick Mayle for (RuleByNumber::iterator it = registers_.begin();
2288*9712c20fSFrederick Mayle it != registers_.end(); it++)
2289*9712c20fSFrederick Mayle delete it->second;
2290*9712c20fSFrederick Mayle registers_.clear();
2291*9712c20fSFrederick Mayle }
2292*9712c20fSFrederick Mayle
2293*9712c20fSFrederick Mayle // The state of the call frame information interpreter as it processes
2294*9712c20fSFrederick Mayle // instructions from a CIE and FDE.
2295*9712c20fSFrederick Mayle class CallFrameInfo::State {
2296*9712c20fSFrederick Mayle public:
2297*9712c20fSFrederick Mayle // Create a call frame information interpreter state with the given
2298*9712c20fSFrederick Mayle // reporter, reader, handler, and initial call frame info address.
State(ByteReader * reader,Handler * handler,Reporter * reporter,uint64_t address)2299*9712c20fSFrederick Mayle State(ByteReader* reader, Handler* handler, Reporter* reporter,
2300*9712c20fSFrederick Mayle uint64_t address)
2301*9712c20fSFrederick Mayle : reader_(reader), handler_(handler), reporter_(reporter),
2302*9712c20fSFrederick Mayle address_(address), entry_(NULL), cursor_(NULL) { }
2303*9712c20fSFrederick Mayle
2304*9712c20fSFrederick Mayle // Interpret instructions from CIE, save the resulting rule set for
2305*9712c20fSFrederick Mayle // DW_CFA_restore instructions, and return true. On error, report
2306*9712c20fSFrederick Mayle // the problem to reporter_ and return false.
2307*9712c20fSFrederick Mayle bool InterpretCIE(const CIE& cie);
2308*9712c20fSFrederick Mayle
2309*9712c20fSFrederick Mayle // Interpret instructions from FDE, and return true. On error,
2310*9712c20fSFrederick Mayle // report the problem to reporter_ and return false.
2311*9712c20fSFrederick Mayle bool InterpretFDE(const FDE& fde);
2312*9712c20fSFrederick Mayle
2313*9712c20fSFrederick Mayle private:
2314*9712c20fSFrederick Mayle // The operands of a CFI instruction, for ParseOperands.
2315*9712c20fSFrederick Mayle struct Operands {
2316*9712c20fSFrederick Mayle unsigned register_number; // A register number.
2317*9712c20fSFrederick Mayle uint64_t offset; // An offset or address.
2318*9712c20fSFrederick Mayle long signed_offset; // A signed offset.
2319*9712c20fSFrederick Mayle string expression; // A DWARF expression.
2320*9712c20fSFrederick Mayle };
2321*9712c20fSFrederick Mayle
2322*9712c20fSFrederick Mayle // Parse CFI instruction operands from STATE's instruction stream as
2323*9712c20fSFrederick Mayle // described by FORMAT. On success, populate OPERANDS with the
2324*9712c20fSFrederick Mayle // results, and return true. On failure, report the problem and
2325*9712c20fSFrederick Mayle // return false.
2326*9712c20fSFrederick Mayle //
2327*9712c20fSFrederick Mayle // Each character of FORMAT should be one of the following:
2328*9712c20fSFrederick Mayle //
2329*9712c20fSFrederick Mayle // 'r' unsigned LEB128 register number (OPERANDS->register_number)
2330*9712c20fSFrederick Mayle // 'o' unsigned LEB128 offset (OPERANDS->offset)
2331*9712c20fSFrederick Mayle // 's' signed LEB128 offset (OPERANDS->signed_offset)
2332*9712c20fSFrederick Mayle // 'a' machine-size address (OPERANDS->offset)
2333*9712c20fSFrederick Mayle // (If the CIE has a 'z' augmentation string, 'a' uses the
2334*9712c20fSFrederick Mayle // encoding specified by the 'R' argument.)
2335*9712c20fSFrederick Mayle // '1' a one-byte offset (OPERANDS->offset)
2336*9712c20fSFrederick Mayle // '2' a two-byte offset (OPERANDS->offset)
2337*9712c20fSFrederick Mayle // '4' a four-byte offset (OPERANDS->offset)
2338*9712c20fSFrederick Mayle // '8' an eight-byte offset (OPERANDS->offset)
2339*9712c20fSFrederick Mayle // 'e' a DW_FORM_block holding a (OPERANDS->expression)
2340*9712c20fSFrederick Mayle // DWARF expression
2341*9712c20fSFrederick Mayle bool ParseOperands(const char* format, Operands* operands);
2342*9712c20fSFrederick Mayle
2343*9712c20fSFrederick Mayle // Interpret one CFI instruction from STATE's instruction stream, update
2344*9712c20fSFrederick Mayle // STATE, report any rule changes to handler_, and return true. On
2345*9712c20fSFrederick Mayle // failure, report the problem and return false.
2346*9712c20fSFrederick Mayle bool DoInstruction();
2347*9712c20fSFrederick Mayle
2348*9712c20fSFrederick Mayle // The following Do* member functions are subroutines of DoInstruction,
2349*9712c20fSFrederick Mayle // factoring out the actual work of operations that have several
2350*9712c20fSFrederick Mayle // different encodings.
2351*9712c20fSFrederick Mayle
2352*9712c20fSFrederick Mayle // Set the CFA rule to be the value of BASE_REGISTER plus OFFSET, and
2353*9712c20fSFrederick Mayle // return true. On failure, report and return false. (Used for
2354*9712c20fSFrederick Mayle // DW_CFA_def_cfa and DW_CFA_def_cfa_sf.)
2355*9712c20fSFrederick Mayle bool DoDefCFA(unsigned base_register, long offset);
2356*9712c20fSFrederick Mayle
2357*9712c20fSFrederick Mayle // Change the offset of the CFA rule to OFFSET, and return true. On
2358*9712c20fSFrederick Mayle // failure, report and return false. (Subroutine for
2359*9712c20fSFrederick Mayle // DW_CFA_def_cfa_offset and DW_CFA_def_cfa_offset_sf.)
2360*9712c20fSFrederick Mayle bool DoDefCFAOffset(long offset);
2361*9712c20fSFrederick Mayle
2362*9712c20fSFrederick Mayle // Specify that REG can be recovered using RULE, and return true. On
2363*9712c20fSFrederick Mayle // failure, report and return false.
2364*9712c20fSFrederick Mayle bool DoRule(unsigned reg, Rule* rule);
2365*9712c20fSFrederick Mayle
2366*9712c20fSFrederick Mayle // Specify that REG can be found at OFFSET from the CFA, and return true.
2367*9712c20fSFrederick Mayle // On failure, report and return false. (Subroutine for DW_CFA_offset,
2368*9712c20fSFrederick Mayle // DW_CFA_offset_extended, and DW_CFA_offset_extended_sf.)
2369*9712c20fSFrederick Mayle bool DoOffset(unsigned reg, long offset);
2370*9712c20fSFrederick Mayle
2371*9712c20fSFrederick Mayle // Specify that the caller's value for REG is the CFA plus OFFSET,
2372*9712c20fSFrederick Mayle // and return true. On failure, report and return false. (Subroutine
2373*9712c20fSFrederick Mayle // for DW_CFA_val_offset and DW_CFA_val_offset_sf.)
2374*9712c20fSFrederick Mayle bool DoValOffset(unsigned reg, long offset);
2375*9712c20fSFrederick Mayle
2376*9712c20fSFrederick Mayle // Restore REG to the rule established in the CIE, and return true. On
2377*9712c20fSFrederick Mayle // failure, report and return false. (Subroutine for DW_CFA_restore and
2378*9712c20fSFrederick Mayle // DW_CFA_restore_extended.)
2379*9712c20fSFrederick Mayle bool DoRestore(unsigned reg);
2380*9712c20fSFrederick Mayle
2381*9712c20fSFrederick Mayle // Return the section offset of the instruction at cursor. For use
2382*9712c20fSFrederick Mayle // in error messages.
CursorOffset()2383*9712c20fSFrederick Mayle uint64_t CursorOffset() { return entry_->offset + (cursor_ - entry_->start); }
2384*9712c20fSFrederick Mayle
2385*9712c20fSFrederick Mayle // Report that entry_ is incomplete, and return false. For brevity.
ReportIncomplete()2386*9712c20fSFrederick Mayle bool ReportIncomplete() {
2387*9712c20fSFrederick Mayle reporter_->Incomplete(entry_->offset, entry_->kind);
2388*9712c20fSFrederick Mayle return false;
2389*9712c20fSFrederick Mayle }
2390*9712c20fSFrederick Mayle
2391*9712c20fSFrederick Mayle // For reading multi-byte values with the appropriate endianness.
2392*9712c20fSFrederick Mayle ByteReader* reader_;
2393*9712c20fSFrederick Mayle
2394*9712c20fSFrederick Mayle // The handler to which we should report the data we find.
2395*9712c20fSFrederick Mayle Handler* handler_;
2396*9712c20fSFrederick Mayle
2397*9712c20fSFrederick Mayle // For reporting problems in the info we're parsing.
2398*9712c20fSFrederick Mayle Reporter* reporter_;
2399*9712c20fSFrederick Mayle
2400*9712c20fSFrederick Mayle // The code address to which the next instruction in the stream applies.
2401*9712c20fSFrederick Mayle uint64_t address_;
2402*9712c20fSFrederick Mayle
2403*9712c20fSFrederick Mayle // The entry whose instructions we are currently processing. This is
2404*9712c20fSFrederick Mayle // first a CIE, and then an FDE.
2405*9712c20fSFrederick Mayle const Entry* entry_;
2406*9712c20fSFrederick Mayle
2407*9712c20fSFrederick Mayle // The next instruction to process.
2408*9712c20fSFrederick Mayle const uint8_t* cursor_;
2409*9712c20fSFrederick Mayle
2410*9712c20fSFrederick Mayle // The current set of rules.
2411*9712c20fSFrederick Mayle RuleMap rules_;
2412*9712c20fSFrederick Mayle
2413*9712c20fSFrederick Mayle // The set of rules established by the CIE, used by DW_CFA_restore
2414*9712c20fSFrederick Mayle // and DW_CFA_restore_extended. We set this after interpreting the
2415*9712c20fSFrederick Mayle // CIE's instructions.
2416*9712c20fSFrederick Mayle RuleMap cie_rules_;
2417*9712c20fSFrederick Mayle
2418*9712c20fSFrederick Mayle // A stack of saved states, for DW_CFA_remember_state and
2419*9712c20fSFrederick Mayle // DW_CFA_restore_state.
2420*9712c20fSFrederick Mayle std::stack<RuleMap> saved_rules_;
2421*9712c20fSFrederick Mayle };
2422*9712c20fSFrederick Mayle
InterpretCIE(const CIE & cie)2423*9712c20fSFrederick Mayle bool CallFrameInfo::State::InterpretCIE(const CIE& cie) {
2424*9712c20fSFrederick Mayle entry_ = &cie;
2425*9712c20fSFrederick Mayle cursor_ = entry_->instructions;
2426*9712c20fSFrederick Mayle while (cursor_ < entry_->end)
2427*9712c20fSFrederick Mayle if (!DoInstruction())
2428*9712c20fSFrederick Mayle return false;
2429*9712c20fSFrederick Mayle // Note the rules established by the CIE, for use by DW_CFA_restore
2430*9712c20fSFrederick Mayle // and DW_CFA_restore_extended.
2431*9712c20fSFrederick Mayle cie_rules_ = rules_;
2432*9712c20fSFrederick Mayle return true;
2433*9712c20fSFrederick Mayle }
2434*9712c20fSFrederick Mayle
InterpretFDE(const FDE & fde)2435*9712c20fSFrederick Mayle bool CallFrameInfo::State::InterpretFDE(const FDE& fde) {
2436*9712c20fSFrederick Mayle entry_ = &fde;
2437*9712c20fSFrederick Mayle cursor_ = entry_->instructions;
2438*9712c20fSFrederick Mayle while (cursor_ < entry_->end)
2439*9712c20fSFrederick Mayle if (!DoInstruction())
2440*9712c20fSFrederick Mayle return false;
2441*9712c20fSFrederick Mayle return true;
2442*9712c20fSFrederick Mayle }
2443*9712c20fSFrederick Mayle
ParseOperands(const char * format,Operands * operands)2444*9712c20fSFrederick Mayle bool CallFrameInfo::State::ParseOperands(const char* format,
2445*9712c20fSFrederick Mayle Operands* operands) {
2446*9712c20fSFrederick Mayle size_t len;
2447*9712c20fSFrederick Mayle const char* operand;
2448*9712c20fSFrederick Mayle
2449*9712c20fSFrederick Mayle for (operand = format; *operand; operand++) {
2450*9712c20fSFrederick Mayle size_t bytes_left = entry_->end - cursor_;
2451*9712c20fSFrederick Mayle switch (*operand) {
2452*9712c20fSFrederick Mayle case 'r':
2453*9712c20fSFrederick Mayle operands->register_number = reader_->ReadUnsignedLEB128(cursor_, &len);
2454*9712c20fSFrederick Mayle if (len > bytes_left) return ReportIncomplete();
2455*9712c20fSFrederick Mayle cursor_ += len;
2456*9712c20fSFrederick Mayle break;
2457*9712c20fSFrederick Mayle
2458*9712c20fSFrederick Mayle case 'o':
2459*9712c20fSFrederick Mayle operands->offset = reader_->ReadUnsignedLEB128(cursor_, &len);
2460*9712c20fSFrederick Mayle if (len > bytes_left) return ReportIncomplete();
2461*9712c20fSFrederick Mayle cursor_ += len;
2462*9712c20fSFrederick Mayle break;
2463*9712c20fSFrederick Mayle
2464*9712c20fSFrederick Mayle case 's':
2465*9712c20fSFrederick Mayle operands->signed_offset = reader_->ReadSignedLEB128(cursor_, &len);
2466*9712c20fSFrederick Mayle if (len > bytes_left) return ReportIncomplete();
2467*9712c20fSFrederick Mayle cursor_ += len;
2468*9712c20fSFrederick Mayle break;
2469*9712c20fSFrederick Mayle
2470*9712c20fSFrederick Mayle case 'a':
2471*9712c20fSFrederick Mayle operands->offset =
2472*9712c20fSFrederick Mayle reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding,
2473*9712c20fSFrederick Mayle &len);
2474*9712c20fSFrederick Mayle if (len > bytes_left) return ReportIncomplete();
2475*9712c20fSFrederick Mayle cursor_ += len;
2476*9712c20fSFrederick Mayle break;
2477*9712c20fSFrederick Mayle
2478*9712c20fSFrederick Mayle case '1':
2479*9712c20fSFrederick Mayle if (1 > bytes_left) return ReportIncomplete();
2480*9712c20fSFrederick Mayle operands->offset = static_cast<unsigned char>(*cursor_++);
2481*9712c20fSFrederick Mayle break;
2482*9712c20fSFrederick Mayle
2483*9712c20fSFrederick Mayle case '2':
2484*9712c20fSFrederick Mayle if (2 > bytes_left) return ReportIncomplete();
2485*9712c20fSFrederick Mayle operands->offset = reader_->ReadTwoBytes(cursor_);
2486*9712c20fSFrederick Mayle cursor_ += 2;
2487*9712c20fSFrederick Mayle break;
2488*9712c20fSFrederick Mayle
2489*9712c20fSFrederick Mayle case '4':
2490*9712c20fSFrederick Mayle if (4 > bytes_left) return ReportIncomplete();
2491*9712c20fSFrederick Mayle operands->offset = reader_->ReadFourBytes(cursor_);
2492*9712c20fSFrederick Mayle cursor_ += 4;
2493*9712c20fSFrederick Mayle break;
2494*9712c20fSFrederick Mayle
2495*9712c20fSFrederick Mayle case '8':
2496*9712c20fSFrederick Mayle if (8 > bytes_left) return ReportIncomplete();
2497*9712c20fSFrederick Mayle operands->offset = reader_->ReadEightBytes(cursor_);
2498*9712c20fSFrederick Mayle cursor_ += 8;
2499*9712c20fSFrederick Mayle break;
2500*9712c20fSFrederick Mayle
2501*9712c20fSFrederick Mayle case 'e': {
2502*9712c20fSFrederick Mayle size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len);
2503*9712c20fSFrederick Mayle if (len > bytes_left || expression_length > bytes_left - len)
2504*9712c20fSFrederick Mayle return ReportIncomplete();
2505*9712c20fSFrederick Mayle cursor_ += len;
2506*9712c20fSFrederick Mayle operands->expression = string(reinterpret_cast<const char*>(cursor_),
2507*9712c20fSFrederick Mayle expression_length);
2508*9712c20fSFrederick Mayle cursor_ += expression_length;
2509*9712c20fSFrederick Mayle break;
2510*9712c20fSFrederick Mayle }
2511*9712c20fSFrederick Mayle
2512*9712c20fSFrederick Mayle default:
2513*9712c20fSFrederick Mayle assert(0);
2514*9712c20fSFrederick Mayle }
2515*9712c20fSFrederick Mayle }
2516*9712c20fSFrederick Mayle
2517*9712c20fSFrederick Mayle return true;
2518*9712c20fSFrederick Mayle }
2519*9712c20fSFrederick Mayle
DoInstruction()2520*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoInstruction() {
2521*9712c20fSFrederick Mayle CIE* cie = entry_->cie;
2522*9712c20fSFrederick Mayle Operands ops;
2523*9712c20fSFrederick Mayle
2524*9712c20fSFrederick Mayle // Our entry's kind should have been set by now.
2525*9712c20fSFrederick Mayle assert(entry_->kind != kUnknown);
2526*9712c20fSFrederick Mayle
2527*9712c20fSFrederick Mayle // We shouldn't have been invoked unless there were more
2528*9712c20fSFrederick Mayle // instructions to parse.
2529*9712c20fSFrederick Mayle assert(cursor_ < entry_->end);
2530*9712c20fSFrederick Mayle
2531*9712c20fSFrederick Mayle unsigned opcode = *cursor_++;
2532*9712c20fSFrederick Mayle if ((opcode & 0xc0) != 0) {
2533*9712c20fSFrederick Mayle switch (opcode & 0xc0) {
2534*9712c20fSFrederick Mayle // Advance the address.
2535*9712c20fSFrederick Mayle case DW_CFA_advance_loc: {
2536*9712c20fSFrederick Mayle size_t code_offset = opcode & 0x3f;
2537*9712c20fSFrederick Mayle address_ += code_offset * cie->code_alignment_factor;
2538*9712c20fSFrederick Mayle break;
2539*9712c20fSFrederick Mayle }
2540*9712c20fSFrederick Mayle
2541*9712c20fSFrederick Mayle // Find a register at an offset from the CFA.
2542*9712c20fSFrederick Mayle case DW_CFA_offset:
2543*9712c20fSFrederick Mayle if (!ParseOperands("o", &ops) ||
2544*9712c20fSFrederick Mayle !DoOffset(opcode & 0x3f, ops.offset * cie->data_alignment_factor))
2545*9712c20fSFrederick Mayle return false;
2546*9712c20fSFrederick Mayle break;
2547*9712c20fSFrederick Mayle
2548*9712c20fSFrederick Mayle // Restore the rule established for a register by the CIE.
2549*9712c20fSFrederick Mayle case DW_CFA_restore:
2550*9712c20fSFrederick Mayle if (!DoRestore(opcode & 0x3f)) return false;
2551*9712c20fSFrederick Mayle break;
2552*9712c20fSFrederick Mayle
2553*9712c20fSFrederick Mayle // The 'if' above should have excluded this possibility.
2554*9712c20fSFrederick Mayle default:
2555*9712c20fSFrederick Mayle assert(0);
2556*9712c20fSFrederick Mayle }
2557*9712c20fSFrederick Mayle
2558*9712c20fSFrederick Mayle // Return here, so the big switch below won't be indented.
2559*9712c20fSFrederick Mayle return true;
2560*9712c20fSFrederick Mayle }
2561*9712c20fSFrederick Mayle
2562*9712c20fSFrederick Mayle switch (opcode) {
2563*9712c20fSFrederick Mayle // Set the address.
2564*9712c20fSFrederick Mayle case DW_CFA_set_loc:
2565*9712c20fSFrederick Mayle if (!ParseOperands("a", &ops)) return false;
2566*9712c20fSFrederick Mayle address_ = ops.offset;
2567*9712c20fSFrederick Mayle break;
2568*9712c20fSFrederick Mayle
2569*9712c20fSFrederick Mayle // Advance the address.
2570*9712c20fSFrederick Mayle case DW_CFA_advance_loc1:
2571*9712c20fSFrederick Mayle if (!ParseOperands("1", &ops)) return false;
2572*9712c20fSFrederick Mayle address_ += ops.offset * cie->code_alignment_factor;
2573*9712c20fSFrederick Mayle break;
2574*9712c20fSFrederick Mayle
2575*9712c20fSFrederick Mayle // Advance the address.
2576*9712c20fSFrederick Mayle case DW_CFA_advance_loc2:
2577*9712c20fSFrederick Mayle if (!ParseOperands("2", &ops)) return false;
2578*9712c20fSFrederick Mayle address_ += ops.offset * cie->code_alignment_factor;
2579*9712c20fSFrederick Mayle break;
2580*9712c20fSFrederick Mayle
2581*9712c20fSFrederick Mayle // Advance the address.
2582*9712c20fSFrederick Mayle case DW_CFA_advance_loc4:
2583*9712c20fSFrederick Mayle if (!ParseOperands("4", &ops)) return false;
2584*9712c20fSFrederick Mayle address_ += ops.offset * cie->code_alignment_factor;
2585*9712c20fSFrederick Mayle break;
2586*9712c20fSFrederick Mayle
2587*9712c20fSFrederick Mayle // Advance the address.
2588*9712c20fSFrederick Mayle case DW_CFA_MIPS_advance_loc8:
2589*9712c20fSFrederick Mayle if (!ParseOperands("8", &ops)) return false;
2590*9712c20fSFrederick Mayle address_ += ops.offset * cie->code_alignment_factor;
2591*9712c20fSFrederick Mayle break;
2592*9712c20fSFrederick Mayle
2593*9712c20fSFrederick Mayle // Compute the CFA by adding an offset to a register.
2594*9712c20fSFrederick Mayle case DW_CFA_def_cfa:
2595*9712c20fSFrederick Mayle if (!ParseOperands("ro", &ops) ||
2596*9712c20fSFrederick Mayle !DoDefCFA(ops.register_number, ops.offset))
2597*9712c20fSFrederick Mayle return false;
2598*9712c20fSFrederick Mayle break;
2599*9712c20fSFrederick Mayle
2600*9712c20fSFrederick Mayle // Compute the CFA by adding an offset to a register.
2601*9712c20fSFrederick Mayle case DW_CFA_def_cfa_sf:
2602*9712c20fSFrederick Mayle if (!ParseOperands("rs", &ops) ||
2603*9712c20fSFrederick Mayle !DoDefCFA(ops.register_number,
2604*9712c20fSFrederick Mayle ops.signed_offset * cie->data_alignment_factor))
2605*9712c20fSFrederick Mayle return false;
2606*9712c20fSFrederick Mayle break;
2607*9712c20fSFrederick Mayle
2608*9712c20fSFrederick Mayle // Change the base register used to compute the CFA.
2609*9712c20fSFrederick Mayle case DW_CFA_def_cfa_register: {
2610*9712c20fSFrederick Mayle if (!ParseOperands("r", &ops)) return false;
2611*9712c20fSFrederick Mayle Rule* cfa_rule = rules_.CFARule();
2612*9712c20fSFrederick Mayle if (!cfa_rule) {
2613*9712c20fSFrederick Mayle if (!DoDefCFA(ops.register_number, ops.offset)) {
2614*9712c20fSFrederick Mayle reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
2615*9712c20fSFrederick Mayle return false;
2616*9712c20fSFrederick Mayle }
2617*9712c20fSFrederick Mayle } else {
2618*9712c20fSFrederick Mayle cfa_rule->SetBaseRegister(ops.register_number);
2619*9712c20fSFrederick Mayle if (!cfa_rule->Handle(handler_, address_,
2620*9712c20fSFrederick Mayle Handler::kCFARegister))
2621*9712c20fSFrederick Mayle return false;
2622*9712c20fSFrederick Mayle }
2623*9712c20fSFrederick Mayle break;
2624*9712c20fSFrederick Mayle }
2625*9712c20fSFrederick Mayle
2626*9712c20fSFrederick Mayle // Change the offset used to compute the CFA.
2627*9712c20fSFrederick Mayle case DW_CFA_def_cfa_offset:
2628*9712c20fSFrederick Mayle if (!ParseOperands("o", &ops) ||
2629*9712c20fSFrederick Mayle !DoDefCFAOffset(ops.offset))
2630*9712c20fSFrederick Mayle return false;
2631*9712c20fSFrederick Mayle break;
2632*9712c20fSFrederick Mayle
2633*9712c20fSFrederick Mayle // Change the offset used to compute the CFA.
2634*9712c20fSFrederick Mayle case DW_CFA_def_cfa_offset_sf:
2635*9712c20fSFrederick Mayle if (!ParseOperands("s", &ops) ||
2636*9712c20fSFrederick Mayle !DoDefCFAOffset(ops.signed_offset * cie->data_alignment_factor))
2637*9712c20fSFrederick Mayle return false;
2638*9712c20fSFrederick Mayle break;
2639*9712c20fSFrederick Mayle
2640*9712c20fSFrederick Mayle // Specify an expression whose value is the CFA.
2641*9712c20fSFrederick Mayle case DW_CFA_def_cfa_expression: {
2642*9712c20fSFrederick Mayle if (!ParseOperands("e", &ops))
2643*9712c20fSFrederick Mayle return false;
2644*9712c20fSFrederick Mayle Rule* rule = new ValExpressionRule(ops.expression);
2645*9712c20fSFrederick Mayle rules_.SetCFARule(rule);
2646*9712c20fSFrederick Mayle if (!rule->Handle(handler_, address_,
2647*9712c20fSFrederick Mayle Handler::kCFARegister))
2648*9712c20fSFrederick Mayle return false;
2649*9712c20fSFrederick Mayle break;
2650*9712c20fSFrederick Mayle }
2651*9712c20fSFrederick Mayle
2652*9712c20fSFrederick Mayle // The register's value cannot be recovered.
2653*9712c20fSFrederick Mayle case DW_CFA_undefined: {
2654*9712c20fSFrederick Mayle if (!ParseOperands("r", &ops) ||
2655*9712c20fSFrederick Mayle !DoRule(ops.register_number, new UndefinedRule()))
2656*9712c20fSFrederick Mayle return false;
2657*9712c20fSFrederick Mayle break;
2658*9712c20fSFrederick Mayle }
2659*9712c20fSFrederick Mayle
2660*9712c20fSFrederick Mayle // The register's value is unchanged from its value in the caller.
2661*9712c20fSFrederick Mayle case DW_CFA_same_value: {
2662*9712c20fSFrederick Mayle if (!ParseOperands("r", &ops) ||
2663*9712c20fSFrederick Mayle !DoRule(ops.register_number, new SameValueRule()))
2664*9712c20fSFrederick Mayle return false;
2665*9712c20fSFrederick Mayle break;
2666*9712c20fSFrederick Mayle }
2667*9712c20fSFrederick Mayle
2668*9712c20fSFrederick Mayle // Find a register at an offset from the CFA.
2669*9712c20fSFrederick Mayle case DW_CFA_offset_extended:
2670*9712c20fSFrederick Mayle if (!ParseOperands("ro", &ops) ||
2671*9712c20fSFrederick Mayle !DoOffset(ops.register_number,
2672*9712c20fSFrederick Mayle ops.offset * cie->data_alignment_factor))
2673*9712c20fSFrederick Mayle return false;
2674*9712c20fSFrederick Mayle break;
2675*9712c20fSFrederick Mayle
2676*9712c20fSFrederick Mayle // The register is saved at an offset from the CFA.
2677*9712c20fSFrederick Mayle case DW_CFA_offset_extended_sf:
2678*9712c20fSFrederick Mayle if (!ParseOperands("rs", &ops) ||
2679*9712c20fSFrederick Mayle !DoOffset(ops.register_number,
2680*9712c20fSFrederick Mayle ops.signed_offset * cie->data_alignment_factor))
2681*9712c20fSFrederick Mayle return false;
2682*9712c20fSFrederick Mayle break;
2683*9712c20fSFrederick Mayle
2684*9712c20fSFrederick Mayle // The register is saved at an offset from the CFA.
2685*9712c20fSFrederick Mayle case DW_CFA_GNU_negative_offset_extended:
2686*9712c20fSFrederick Mayle if (!ParseOperands("ro", &ops) ||
2687*9712c20fSFrederick Mayle !DoOffset(ops.register_number,
2688*9712c20fSFrederick Mayle -ops.offset * cie->data_alignment_factor))
2689*9712c20fSFrederick Mayle return false;
2690*9712c20fSFrederick Mayle break;
2691*9712c20fSFrederick Mayle
2692*9712c20fSFrederick Mayle // The register's value is the sum of the CFA plus an offset.
2693*9712c20fSFrederick Mayle case DW_CFA_val_offset:
2694*9712c20fSFrederick Mayle if (!ParseOperands("ro", &ops) ||
2695*9712c20fSFrederick Mayle !DoValOffset(ops.register_number,
2696*9712c20fSFrederick Mayle ops.offset * cie->data_alignment_factor))
2697*9712c20fSFrederick Mayle return false;
2698*9712c20fSFrederick Mayle break;
2699*9712c20fSFrederick Mayle
2700*9712c20fSFrederick Mayle // The register's value is the sum of the CFA plus an offset.
2701*9712c20fSFrederick Mayle case DW_CFA_val_offset_sf:
2702*9712c20fSFrederick Mayle if (!ParseOperands("rs", &ops) ||
2703*9712c20fSFrederick Mayle !DoValOffset(ops.register_number,
2704*9712c20fSFrederick Mayle ops.signed_offset * cie->data_alignment_factor))
2705*9712c20fSFrederick Mayle return false;
2706*9712c20fSFrederick Mayle break;
2707*9712c20fSFrederick Mayle
2708*9712c20fSFrederick Mayle // The register has been saved in another register.
2709*9712c20fSFrederick Mayle case DW_CFA_register: {
2710*9712c20fSFrederick Mayle if (!ParseOperands("ro", &ops) ||
2711*9712c20fSFrederick Mayle !DoRule(ops.register_number, new RegisterRule(ops.offset)))
2712*9712c20fSFrederick Mayle return false;
2713*9712c20fSFrederick Mayle break;
2714*9712c20fSFrederick Mayle }
2715*9712c20fSFrederick Mayle
2716*9712c20fSFrederick Mayle // An expression yields the address at which the register is saved.
2717*9712c20fSFrederick Mayle case DW_CFA_expression: {
2718*9712c20fSFrederick Mayle if (!ParseOperands("re", &ops) ||
2719*9712c20fSFrederick Mayle !DoRule(ops.register_number, new ExpressionRule(ops.expression)))
2720*9712c20fSFrederick Mayle return false;
2721*9712c20fSFrederick Mayle break;
2722*9712c20fSFrederick Mayle }
2723*9712c20fSFrederick Mayle
2724*9712c20fSFrederick Mayle // An expression yields the caller's value for the register.
2725*9712c20fSFrederick Mayle case DW_CFA_val_expression: {
2726*9712c20fSFrederick Mayle if (!ParseOperands("re", &ops) ||
2727*9712c20fSFrederick Mayle !DoRule(ops.register_number, new ValExpressionRule(ops.expression)))
2728*9712c20fSFrederick Mayle return false;
2729*9712c20fSFrederick Mayle break;
2730*9712c20fSFrederick Mayle }
2731*9712c20fSFrederick Mayle
2732*9712c20fSFrederick Mayle // Restore the rule established for a register by the CIE.
2733*9712c20fSFrederick Mayle case DW_CFA_restore_extended:
2734*9712c20fSFrederick Mayle if (!ParseOperands("r", &ops) ||
2735*9712c20fSFrederick Mayle !DoRestore( ops.register_number))
2736*9712c20fSFrederick Mayle return false;
2737*9712c20fSFrederick Mayle break;
2738*9712c20fSFrederick Mayle
2739*9712c20fSFrederick Mayle // Save the current set of rules on a stack.
2740*9712c20fSFrederick Mayle case DW_CFA_remember_state:
2741*9712c20fSFrederick Mayle saved_rules_.push(rules_);
2742*9712c20fSFrederick Mayle break;
2743*9712c20fSFrederick Mayle
2744*9712c20fSFrederick Mayle // Pop the current set of rules off the stack.
2745*9712c20fSFrederick Mayle case DW_CFA_restore_state: {
2746*9712c20fSFrederick Mayle if (saved_rules_.empty()) {
2747*9712c20fSFrederick Mayle reporter_->EmptyStateStack(entry_->offset, entry_->kind,
2748*9712c20fSFrederick Mayle CursorOffset());
2749*9712c20fSFrederick Mayle return false;
2750*9712c20fSFrederick Mayle }
2751*9712c20fSFrederick Mayle const RuleMap& new_rules = saved_rules_.top();
2752*9712c20fSFrederick Mayle if (rules_.CFARule() && !new_rules.CFARule()) {
2753*9712c20fSFrederick Mayle reporter_->ClearingCFARule(entry_->offset, entry_->kind,
2754*9712c20fSFrederick Mayle CursorOffset());
2755*9712c20fSFrederick Mayle return false;
2756*9712c20fSFrederick Mayle }
2757*9712c20fSFrederick Mayle rules_.HandleTransitionTo(handler_, address_, new_rules);
2758*9712c20fSFrederick Mayle rules_ = new_rules;
2759*9712c20fSFrederick Mayle saved_rules_.pop();
2760*9712c20fSFrederick Mayle break;
2761*9712c20fSFrederick Mayle }
2762*9712c20fSFrederick Mayle
2763*9712c20fSFrederick Mayle // No operation. (Padding instruction.)
2764*9712c20fSFrederick Mayle case DW_CFA_nop:
2765*9712c20fSFrederick Mayle break;
2766*9712c20fSFrederick Mayle
2767*9712c20fSFrederick Mayle // case DW_CFA_AARCH64_negate_ra_state
2768*9712c20fSFrederick Mayle case DW_CFA_GNU_window_save: {
2769*9712c20fSFrederick Mayle if (handler_->Architecture() == "arm64") {
2770*9712c20fSFrederick Mayle // Indicates that the return address, x30 has been signed.
2771*9712c20fSFrederick Mayle // Breakpad will speculatively remove pointer-authentication codes when
2772*9712c20fSFrederick Mayle // interpreting return addresses, regardless of this bit.
2773*9712c20fSFrederick Mayle } else if (handler_->Architecture() == "sparc" ||
2774*9712c20fSFrederick Mayle handler_->Architecture() == "sparcv9") {
2775*9712c20fSFrederick Mayle // A SPARC register window save: Registers 8 through 15 (%o0-%o7)
2776*9712c20fSFrederick Mayle // are saved in registers 24 through 31 (%i0-%i7), and registers
2777*9712c20fSFrederick Mayle // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets
2778*9712c20fSFrederick Mayle // (0-15 * the register size). The register numbers must be
2779*9712c20fSFrederick Mayle // hard-coded. A GNU extension, and not a pretty one.
2780*9712c20fSFrederick Mayle
2781*9712c20fSFrederick Mayle // Save %o0-%o7 in %i0-%i7.
2782*9712c20fSFrederick Mayle for (int i = 8; i < 16; i++)
2783*9712c20fSFrederick Mayle if (!DoRule(i, new RegisterRule(i + 16)))
2784*9712c20fSFrederick Mayle return false;
2785*9712c20fSFrederick Mayle // Save %l0-%l7 and %i0-%i7 at the CFA.
2786*9712c20fSFrederick Mayle for (int i = 16; i < 32; i++)
2787*9712c20fSFrederick Mayle // Assume that the byte reader's address size is the same as
2788*9712c20fSFrederick Mayle // the architecture's register size. !@#%*^ hilarious.
2789*9712c20fSFrederick Mayle if (!DoRule(i, new OffsetRule(Handler::kCFARegister,
2790*9712c20fSFrederick Mayle (i - 16) * reader_->AddressSize())))
2791*9712c20fSFrederick Mayle return false;
2792*9712c20fSFrederick Mayle }
2793*9712c20fSFrederick Mayle break;
2794*9712c20fSFrederick Mayle }
2795*9712c20fSFrederick Mayle
2796*9712c20fSFrederick Mayle // I'm not sure what this is. GDB doesn't use it for unwinding.
2797*9712c20fSFrederick Mayle case DW_CFA_GNU_args_size:
2798*9712c20fSFrederick Mayle if (!ParseOperands("o", &ops)) return false;
2799*9712c20fSFrederick Mayle break;
2800*9712c20fSFrederick Mayle
2801*9712c20fSFrederick Mayle // An opcode we don't recognize.
2802*9712c20fSFrederick Mayle default: {
2803*9712c20fSFrederick Mayle reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset());
2804*9712c20fSFrederick Mayle return false;
2805*9712c20fSFrederick Mayle }
2806*9712c20fSFrederick Mayle }
2807*9712c20fSFrederick Mayle
2808*9712c20fSFrederick Mayle return true;
2809*9712c20fSFrederick Mayle }
2810*9712c20fSFrederick Mayle
DoDefCFA(unsigned base_register,long offset)2811*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoDefCFA(unsigned base_register, long offset) {
2812*9712c20fSFrederick Mayle Rule* rule = new ValOffsetRule(base_register, offset);
2813*9712c20fSFrederick Mayle rules_.SetCFARule(rule);
2814*9712c20fSFrederick Mayle return rule->Handle(handler_, address_,
2815*9712c20fSFrederick Mayle Handler::kCFARegister);
2816*9712c20fSFrederick Mayle }
2817*9712c20fSFrederick Mayle
DoDefCFAOffset(long offset)2818*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoDefCFAOffset(long offset) {
2819*9712c20fSFrederick Mayle Rule* cfa_rule = rules_.CFARule();
2820*9712c20fSFrederick Mayle if (!cfa_rule) {
2821*9712c20fSFrederick Mayle reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
2822*9712c20fSFrederick Mayle return false;
2823*9712c20fSFrederick Mayle }
2824*9712c20fSFrederick Mayle cfa_rule->SetOffset(offset);
2825*9712c20fSFrederick Mayle return cfa_rule->Handle(handler_, address_,
2826*9712c20fSFrederick Mayle Handler::kCFARegister);
2827*9712c20fSFrederick Mayle }
2828*9712c20fSFrederick Mayle
DoRule(unsigned reg,Rule * rule)2829*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoRule(unsigned reg, Rule* rule) {
2830*9712c20fSFrederick Mayle rules_.SetRegisterRule(reg, rule);
2831*9712c20fSFrederick Mayle return rule->Handle(handler_, address_, reg);
2832*9712c20fSFrederick Mayle }
2833*9712c20fSFrederick Mayle
DoOffset(unsigned reg,long offset)2834*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoOffset(unsigned reg, long offset) {
2835*9712c20fSFrederick Mayle if (!rules_.CFARule()) {
2836*9712c20fSFrederick Mayle reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
2837*9712c20fSFrederick Mayle return false;
2838*9712c20fSFrederick Mayle }
2839*9712c20fSFrederick Mayle return DoRule(reg,
2840*9712c20fSFrederick Mayle new OffsetRule(Handler::kCFARegister, offset));
2841*9712c20fSFrederick Mayle }
2842*9712c20fSFrederick Mayle
DoValOffset(unsigned reg,long offset)2843*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoValOffset(unsigned reg, long offset) {
2844*9712c20fSFrederick Mayle if (!rules_.CFARule()) {
2845*9712c20fSFrederick Mayle reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
2846*9712c20fSFrederick Mayle return false;
2847*9712c20fSFrederick Mayle }
2848*9712c20fSFrederick Mayle return DoRule(reg,
2849*9712c20fSFrederick Mayle new ValOffsetRule(Handler::kCFARegister, offset));
2850*9712c20fSFrederick Mayle }
2851*9712c20fSFrederick Mayle
DoRestore(unsigned reg)2852*9712c20fSFrederick Mayle bool CallFrameInfo::State::DoRestore(unsigned reg) {
2853*9712c20fSFrederick Mayle // DW_CFA_restore and DW_CFA_restore_extended don't make sense in a CIE.
2854*9712c20fSFrederick Mayle if (entry_->kind == kCIE) {
2855*9712c20fSFrederick Mayle reporter_->RestoreInCIE(entry_->offset, CursorOffset());
2856*9712c20fSFrederick Mayle return false;
2857*9712c20fSFrederick Mayle }
2858*9712c20fSFrederick Mayle Rule* rule = cie_rules_.RegisterRule(reg);
2859*9712c20fSFrederick Mayle if (!rule) {
2860*9712c20fSFrederick Mayle // This isn't really the right thing to do, but since CFI generally
2861*9712c20fSFrederick Mayle // only mentions callee-saves registers, and GCC's convention for
2862*9712c20fSFrederick Mayle // callee-saves registers is that they are unchanged, it's a good
2863*9712c20fSFrederick Mayle // approximation.
2864*9712c20fSFrederick Mayle rule = new SameValueRule();
2865*9712c20fSFrederick Mayle }
2866*9712c20fSFrederick Mayle return DoRule(reg, rule);
2867*9712c20fSFrederick Mayle }
2868*9712c20fSFrederick Mayle
ReadEntryPrologue(const uint8_t * cursor,Entry * entry)2869*9712c20fSFrederick Mayle bool CallFrameInfo::ReadEntryPrologue(const uint8_t* cursor, Entry* entry) {
2870*9712c20fSFrederick Mayle const uint8_t* buffer_end = buffer_ + buffer_length_;
2871*9712c20fSFrederick Mayle
2872*9712c20fSFrederick Mayle // Initialize enough of ENTRY for use in error reporting.
2873*9712c20fSFrederick Mayle entry->offset = cursor - buffer_;
2874*9712c20fSFrederick Mayle entry->start = cursor;
2875*9712c20fSFrederick Mayle entry->kind = kUnknown;
2876*9712c20fSFrederick Mayle entry->end = NULL;
2877*9712c20fSFrederick Mayle
2878*9712c20fSFrederick Mayle // Read the initial length. This sets reader_'s offset size.
2879*9712c20fSFrederick Mayle size_t length_size;
2880*9712c20fSFrederick Mayle uint64_t length = reader_->ReadInitialLength(cursor, &length_size);
2881*9712c20fSFrederick Mayle if (length_size > size_t(buffer_end - cursor))
2882*9712c20fSFrederick Mayle return ReportIncomplete(entry);
2883*9712c20fSFrederick Mayle cursor += length_size;
2884*9712c20fSFrederick Mayle
2885*9712c20fSFrederick Mayle // In a .eh_frame section, a length of zero marks the end of the series
2886*9712c20fSFrederick Mayle // of entries.
2887*9712c20fSFrederick Mayle if (length == 0 && eh_frame_) {
2888*9712c20fSFrederick Mayle entry->kind = kTerminator;
2889*9712c20fSFrederick Mayle entry->end = cursor;
2890*9712c20fSFrederick Mayle return true;
2891*9712c20fSFrederick Mayle }
2892*9712c20fSFrederick Mayle
2893*9712c20fSFrederick Mayle // Validate the length.
2894*9712c20fSFrederick Mayle if (length > size_t(buffer_end - cursor))
2895*9712c20fSFrederick Mayle return ReportIncomplete(entry);
2896*9712c20fSFrederick Mayle
2897*9712c20fSFrederick Mayle // The length is the number of bytes after the initial length field;
2898*9712c20fSFrederick Mayle // we have that position handy at this point, so compute the end
2899*9712c20fSFrederick Mayle // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine,
2900*9712c20fSFrederick Mayle // and the length didn't fit in a size_t, we would have rejected it
2901*9712c20fSFrederick Mayle // above.)
2902*9712c20fSFrederick Mayle entry->end = cursor + length;
2903*9712c20fSFrederick Mayle
2904*9712c20fSFrederick Mayle // Parse the next field: either the offset of a CIE or a CIE id.
2905*9712c20fSFrederick Mayle size_t offset_size = reader_->OffsetSize();
2906*9712c20fSFrederick Mayle if (offset_size > size_t(entry->end - cursor)) return ReportIncomplete(entry);
2907*9712c20fSFrederick Mayle entry->id = reader_->ReadOffset(cursor);
2908*9712c20fSFrederick Mayle
2909*9712c20fSFrederick Mayle // Don't advance cursor past id field yet; in .eh_frame data we need
2910*9712c20fSFrederick Mayle // the id's position to compute the section offset of an FDE's CIE.
2911*9712c20fSFrederick Mayle
2912*9712c20fSFrederick Mayle // Now we can decide what kind of entry this is.
2913*9712c20fSFrederick Mayle if (eh_frame_) {
2914*9712c20fSFrederick Mayle // In .eh_frame data, an ID of zero marks the entry as a CIE, and
2915*9712c20fSFrederick Mayle // anything else is an offset from the id field of the FDE to the start
2916*9712c20fSFrederick Mayle // of the CIE.
2917*9712c20fSFrederick Mayle if (entry->id == 0) {
2918*9712c20fSFrederick Mayle entry->kind = kCIE;
2919*9712c20fSFrederick Mayle } else {
2920*9712c20fSFrederick Mayle entry->kind = kFDE;
2921*9712c20fSFrederick Mayle // Turn the offset from the id into an offset from the buffer's start.
2922*9712c20fSFrederick Mayle entry->id = (cursor - buffer_) - entry->id;
2923*9712c20fSFrederick Mayle }
2924*9712c20fSFrederick Mayle } else {
2925*9712c20fSFrederick Mayle // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the
2926*9712c20fSFrederick Mayle // offset size for the entry) marks the entry as a CIE, and anything
2927*9712c20fSFrederick Mayle // else is the offset of the CIE from the beginning of the section.
2928*9712c20fSFrederick Mayle if (offset_size == 4)
2929*9712c20fSFrederick Mayle entry->kind = (entry->id == 0xffffffff) ? kCIE : kFDE;
2930*9712c20fSFrederick Mayle else {
2931*9712c20fSFrederick Mayle assert(offset_size == 8);
2932*9712c20fSFrederick Mayle entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE;
2933*9712c20fSFrederick Mayle }
2934*9712c20fSFrederick Mayle }
2935*9712c20fSFrederick Mayle
2936*9712c20fSFrederick Mayle // Now advance cursor past the id.
2937*9712c20fSFrederick Mayle cursor += offset_size;
2938*9712c20fSFrederick Mayle
2939*9712c20fSFrederick Mayle // The fields specific to this kind of entry start here.
2940*9712c20fSFrederick Mayle entry->fields = cursor;
2941*9712c20fSFrederick Mayle
2942*9712c20fSFrederick Mayle entry->cie = NULL;
2943*9712c20fSFrederick Mayle
2944*9712c20fSFrederick Mayle return true;
2945*9712c20fSFrederick Mayle }
2946*9712c20fSFrederick Mayle
ReadCIEFields(CIE * cie)2947*9712c20fSFrederick Mayle bool CallFrameInfo::ReadCIEFields(CIE* cie) {
2948*9712c20fSFrederick Mayle const uint8_t* cursor = cie->fields;
2949*9712c20fSFrederick Mayle size_t len;
2950*9712c20fSFrederick Mayle
2951*9712c20fSFrederick Mayle assert(cie->kind == kCIE);
2952*9712c20fSFrederick Mayle
2953*9712c20fSFrederick Mayle // Prepare for early exit.
2954*9712c20fSFrederick Mayle cie->version = 0;
2955*9712c20fSFrederick Mayle cie->augmentation.clear();
2956*9712c20fSFrederick Mayle cie->code_alignment_factor = 0;
2957*9712c20fSFrederick Mayle cie->data_alignment_factor = 0;
2958*9712c20fSFrederick Mayle cie->return_address_register = 0;
2959*9712c20fSFrederick Mayle cie->has_z_augmentation = false;
2960*9712c20fSFrederick Mayle cie->pointer_encoding = DW_EH_PE_absptr;
2961*9712c20fSFrederick Mayle cie->instructions = 0;
2962*9712c20fSFrederick Mayle
2963*9712c20fSFrederick Mayle // Parse the version number.
2964*9712c20fSFrederick Mayle if (cie->end - cursor < 1)
2965*9712c20fSFrederick Mayle return ReportIncomplete(cie);
2966*9712c20fSFrederick Mayle cie->version = reader_->ReadOneByte(cursor);
2967*9712c20fSFrederick Mayle cursor++;
2968*9712c20fSFrederick Mayle
2969*9712c20fSFrederick Mayle // If we don't recognize the version, we can't parse any more fields of the
2970*9712c20fSFrederick Mayle // CIE. For DWARF CFI, we handle versions 1 through 4 (there was never a
2971*9712c20fSFrederick Mayle // version 2 of CFI data). For .eh_frame, we handle versions 1 and 4 as well;
2972*9712c20fSFrederick Mayle // the difference between those versions seems to be the same as for
2973*9712c20fSFrederick Mayle // .debug_frame.
2974*9712c20fSFrederick Mayle if (cie->version < 1 || cie->version > 4) {
2975*9712c20fSFrederick Mayle reporter_->UnrecognizedVersion(cie->offset, cie->version);
2976*9712c20fSFrederick Mayle return false;
2977*9712c20fSFrederick Mayle }
2978*9712c20fSFrederick Mayle
2979*9712c20fSFrederick Mayle const uint8_t* augmentation_start = cursor;
2980*9712c20fSFrederick Mayle const uint8_t* augmentation_end =
2981*9712c20fSFrederick Mayle reinterpret_cast<const uint8_t*>(memchr(augmentation_start, '\0',
2982*9712c20fSFrederick Mayle cie->end - augmentation_start));
2983*9712c20fSFrederick Mayle if (! augmentation_end) return ReportIncomplete(cie);
2984*9712c20fSFrederick Mayle cursor = augmentation_end;
2985*9712c20fSFrederick Mayle cie->augmentation = string(reinterpret_cast<const char*>(augmentation_start),
2986*9712c20fSFrederick Mayle cursor - augmentation_start);
2987*9712c20fSFrederick Mayle // Skip the terminating '\0'.
2988*9712c20fSFrederick Mayle cursor++;
2989*9712c20fSFrederick Mayle
2990*9712c20fSFrederick Mayle // Is this CFI augmented?
2991*9712c20fSFrederick Mayle if (!cie->augmentation.empty()) {
2992*9712c20fSFrederick Mayle // Is it an augmentation we recognize?
2993*9712c20fSFrederick Mayle if (cie->augmentation[0] == DW_Z_augmentation_start) {
2994*9712c20fSFrederick Mayle // Linux C++ ABI 'z' augmentation, used for exception handling data.
2995*9712c20fSFrederick Mayle cie->has_z_augmentation = true;
2996*9712c20fSFrederick Mayle } else {
2997*9712c20fSFrederick Mayle // Not an augmentation we recognize. Augmentations can have arbitrary
2998*9712c20fSFrederick Mayle // effects on the form of rest of the content, so we have to give up.
2999*9712c20fSFrederick Mayle reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
3000*9712c20fSFrederick Mayle return false;
3001*9712c20fSFrederick Mayle }
3002*9712c20fSFrederick Mayle }
3003*9712c20fSFrederick Mayle
3004*9712c20fSFrederick Mayle if (cie->version >= 4) {
3005*9712c20fSFrederick Mayle cie->address_size = *cursor++;
3006*9712c20fSFrederick Mayle if (cie->address_size != 8 && cie->address_size != 4) {
3007*9712c20fSFrederick Mayle reporter_->UnexpectedAddressSize(cie->offset, cie->address_size);
3008*9712c20fSFrederick Mayle return false;
3009*9712c20fSFrederick Mayle }
3010*9712c20fSFrederick Mayle
3011*9712c20fSFrederick Mayle cie->segment_size = *cursor++;
3012*9712c20fSFrederick Mayle if (cie->segment_size != 0) {
3013*9712c20fSFrederick Mayle reporter_->UnexpectedSegmentSize(cie->offset, cie->segment_size);
3014*9712c20fSFrederick Mayle return false;
3015*9712c20fSFrederick Mayle }
3016*9712c20fSFrederick Mayle }
3017*9712c20fSFrederick Mayle
3018*9712c20fSFrederick Mayle // Parse the code alignment factor.
3019*9712c20fSFrederick Mayle cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
3020*9712c20fSFrederick Mayle if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
3021*9712c20fSFrederick Mayle cursor += len;
3022*9712c20fSFrederick Mayle
3023*9712c20fSFrederick Mayle // Parse the data alignment factor.
3024*9712c20fSFrederick Mayle cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
3025*9712c20fSFrederick Mayle if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
3026*9712c20fSFrederick Mayle cursor += len;
3027*9712c20fSFrederick Mayle
3028*9712c20fSFrederick Mayle // Parse the return address register. This is a ubyte in version 1, and
3029*9712c20fSFrederick Mayle // a ULEB128 in version 3.
3030*9712c20fSFrederick Mayle if (cie->version == 1) {
3031*9712c20fSFrederick Mayle if (cursor >= cie->end) return ReportIncomplete(cie);
3032*9712c20fSFrederick Mayle cie->return_address_register = uint8_t(*cursor++);
3033*9712c20fSFrederick Mayle } else {
3034*9712c20fSFrederick Mayle cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len);
3035*9712c20fSFrederick Mayle if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
3036*9712c20fSFrederick Mayle cursor += len;
3037*9712c20fSFrederick Mayle }
3038*9712c20fSFrederick Mayle
3039*9712c20fSFrederick Mayle // If we have a 'z' augmentation string, find the augmentation data and
3040*9712c20fSFrederick Mayle // use the augmentation string to parse it.
3041*9712c20fSFrederick Mayle if (cie->has_z_augmentation) {
3042*9712c20fSFrederick Mayle uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len);
3043*9712c20fSFrederick Mayle if (size_t(cie->end - cursor) < len + data_size)
3044*9712c20fSFrederick Mayle return ReportIncomplete(cie);
3045*9712c20fSFrederick Mayle cursor += len;
3046*9712c20fSFrederick Mayle const uint8_t* data = cursor;
3047*9712c20fSFrederick Mayle cursor += data_size;
3048*9712c20fSFrederick Mayle const uint8_t* data_end = cursor;
3049*9712c20fSFrederick Mayle
3050*9712c20fSFrederick Mayle cie->has_z_lsda = false;
3051*9712c20fSFrederick Mayle cie->has_z_personality = false;
3052*9712c20fSFrederick Mayle cie->has_z_signal_frame = false;
3053*9712c20fSFrederick Mayle
3054*9712c20fSFrederick Mayle // Walk the augmentation string, and extract values from the
3055*9712c20fSFrederick Mayle // augmentation data as the string directs.
3056*9712c20fSFrederick Mayle for (size_t i = 1; i < cie->augmentation.size(); i++) {
3057*9712c20fSFrederick Mayle switch (cie->augmentation[i]) {
3058*9712c20fSFrederick Mayle case DW_Z_has_LSDA:
3059*9712c20fSFrederick Mayle // The CIE's augmentation data holds the language-specific data
3060*9712c20fSFrederick Mayle // area pointer's encoding, and the FDE's augmentation data holds
3061*9712c20fSFrederick Mayle // the pointer itself.
3062*9712c20fSFrederick Mayle cie->has_z_lsda = true;
3063*9712c20fSFrederick Mayle // Fetch the LSDA encoding from the augmentation data.
3064*9712c20fSFrederick Mayle if (data >= data_end) return ReportIncomplete(cie);
3065*9712c20fSFrederick Mayle cie->lsda_encoding = DwarfPointerEncoding(*data++);
3066*9712c20fSFrederick Mayle if (!reader_->ValidEncoding(cie->lsda_encoding)) {
3067*9712c20fSFrederick Mayle reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding);
3068*9712c20fSFrederick Mayle return false;
3069*9712c20fSFrederick Mayle }
3070*9712c20fSFrederick Mayle // Don't check if the encoding is usable here --- we haven't
3071*9712c20fSFrederick Mayle // read the FDE's fields yet, so we're not prepared for
3072*9712c20fSFrederick Mayle // DW_EH_PE_funcrel, although that's a fine encoding for the
3073*9712c20fSFrederick Mayle // LSDA to use, since it appears in the FDE.
3074*9712c20fSFrederick Mayle break;
3075*9712c20fSFrederick Mayle
3076*9712c20fSFrederick Mayle case DW_Z_has_personality_routine:
3077*9712c20fSFrederick Mayle // The CIE's augmentation data holds the personality routine
3078*9712c20fSFrederick Mayle // pointer's encoding, followed by the pointer itself.
3079*9712c20fSFrederick Mayle cie->has_z_personality = true;
3080*9712c20fSFrederick Mayle // Fetch the personality routine pointer's encoding from the
3081*9712c20fSFrederick Mayle // augmentation data.
3082*9712c20fSFrederick Mayle if (data >= data_end) return ReportIncomplete(cie);
3083*9712c20fSFrederick Mayle cie->personality_encoding = DwarfPointerEncoding(*data++);
3084*9712c20fSFrederick Mayle if (!reader_->ValidEncoding(cie->personality_encoding)) {
3085*9712c20fSFrederick Mayle reporter_->InvalidPointerEncoding(cie->offset,
3086*9712c20fSFrederick Mayle cie->personality_encoding);
3087*9712c20fSFrederick Mayle return false;
3088*9712c20fSFrederick Mayle }
3089*9712c20fSFrederick Mayle if (!reader_->UsableEncoding(cie->personality_encoding)) {
3090*9712c20fSFrederick Mayle reporter_->UnusablePointerEncoding(cie->offset,
3091*9712c20fSFrederick Mayle cie->personality_encoding);
3092*9712c20fSFrederick Mayle return false;
3093*9712c20fSFrederick Mayle }
3094*9712c20fSFrederick Mayle // Fetch the personality routine's pointer itself from the data.
3095*9712c20fSFrederick Mayle cie->personality_address =
3096*9712c20fSFrederick Mayle reader_->ReadEncodedPointer(data, cie->personality_encoding,
3097*9712c20fSFrederick Mayle &len);
3098*9712c20fSFrederick Mayle if (len > size_t(data_end - data))
3099*9712c20fSFrederick Mayle return ReportIncomplete(cie);
3100*9712c20fSFrederick Mayle data += len;
3101*9712c20fSFrederick Mayle break;
3102*9712c20fSFrederick Mayle
3103*9712c20fSFrederick Mayle case DW_Z_has_FDE_address_encoding:
3104*9712c20fSFrederick Mayle // The CIE's augmentation data holds the pointer encoding to use
3105*9712c20fSFrederick Mayle // for addresses in the FDE.
3106*9712c20fSFrederick Mayle if (data >= data_end) return ReportIncomplete(cie);
3107*9712c20fSFrederick Mayle cie->pointer_encoding = DwarfPointerEncoding(*data++);
3108*9712c20fSFrederick Mayle if (!reader_->ValidEncoding(cie->pointer_encoding)) {
3109*9712c20fSFrederick Mayle reporter_->InvalidPointerEncoding(cie->offset,
3110*9712c20fSFrederick Mayle cie->pointer_encoding);
3111*9712c20fSFrederick Mayle return false;
3112*9712c20fSFrederick Mayle }
3113*9712c20fSFrederick Mayle if (!reader_->UsableEncoding(cie->pointer_encoding)) {
3114*9712c20fSFrederick Mayle reporter_->UnusablePointerEncoding(cie->offset,
3115*9712c20fSFrederick Mayle cie->pointer_encoding);
3116*9712c20fSFrederick Mayle return false;
3117*9712c20fSFrederick Mayle }
3118*9712c20fSFrederick Mayle break;
3119*9712c20fSFrederick Mayle
3120*9712c20fSFrederick Mayle case DW_Z_is_signal_trampoline:
3121*9712c20fSFrederick Mayle // Frames using this CIE are signal delivery frames.
3122*9712c20fSFrederick Mayle cie->has_z_signal_frame = true;
3123*9712c20fSFrederick Mayle break;
3124*9712c20fSFrederick Mayle
3125*9712c20fSFrederick Mayle default:
3126*9712c20fSFrederick Mayle // An augmentation we don't recognize.
3127*9712c20fSFrederick Mayle reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
3128*9712c20fSFrederick Mayle return false;
3129*9712c20fSFrederick Mayle }
3130*9712c20fSFrederick Mayle }
3131*9712c20fSFrederick Mayle }
3132*9712c20fSFrederick Mayle
3133*9712c20fSFrederick Mayle // The CIE's instructions start here.
3134*9712c20fSFrederick Mayle cie->instructions = cursor;
3135*9712c20fSFrederick Mayle
3136*9712c20fSFrederick Mayle return true;
3137*9712c20fSFrederick Mayle }
3138*9712c20fSFrederick Mayle
ReadFDEFields(FDE * fde)3139*9712c20fSFrederick Mayle bool CallFrameInfo::ReadFDEFields(FDE* fde) {
3140*9712c20fSFrederick Mayle const uint8_t* cursor = fde->fields;
3141*9712c20fSFrederick Mayle size_t size;
3142*9712c20fSFrederick Mayle
3143*9712c20fSFrederick Mayle fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
3144*9712c20fSFrederick Mayle &size);
3145*9712c20fSFrederick Mayle if (size > size_t(fde->end - cursor))
3146*9712c20fSFrederick Mayle return ReportIncomplete(fde);
3147*9712c20fSFrederick Mayle cursor += size;
3148*9712c20fSFrederick Mayle reader_->SetFunctionBase(fde->address);
3149*9712c20fSFrederick Mayle
3150*9712c20fSFrederick Mayle // For the length, we strip off the upper nybble of the encoding used for
3151*9712c20fSFrederick Mayle // the starting address.
3152*9712c20fSFrederick Mayle DwarfPointerEncoding length_encoding =
3153*9712c20fSFrederick Mayle DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f);
3154*9712c20fSFrederick Mayle fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size);
3155*9712c20fSFrederick Mayle if (size > size_t(fde->end - cursor))
3156*9712c20fSFrederick Mayle return ReportIncomplete(fde);
3157*9712c20fSFrederick Mayle cursor += size;
3158*9712c20fSFrederick Mayle
3159*9712c20fSFrederick Mayle // If the CIE has a 'z' augmentation string, then augmentation data
3160*9712c20fSFrederick Mayle // appears here.
3161*9712c20fSFrederick Mayle if (fde->cie->has_z_augmentation) {
3162*9712c20fSFrederick Mayle uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size);
3163*9712c20fSFrederick Mayle if (size_t(fde->end - cursor) < size + data_size)
3164*9712c20fSFrederick Mayle return ReportIncomplete(fde);
3165*9712c20fSFrederick Mayle cursor += size;
3166*9712c20fSFrederick Mayle
3167*9712c20fSFrederick Mayle // In the abstract, we should walk the augmentation string, and extract
3168*9712c20fSFrederick Mayle // items from the FDE's augmentation data as we encounter augmentation
3169*9712c20fSFrederick Mayle // string characters that specify their presence: the ordering of items
3170*9712c20fSFrederick Mayle // in the augmentation string determines the arrangement of values in
3171*9712c20fSFrederick Mayle // the augmentation data.
3172*9712c20fSFrederick Mayle //
3173*9712c20fSFrederick Mayle // In practice, there's only ever one value in FDE augmentation data
3174*9712c20fSFrederick Mayle // that we support --- the LSDA pointer --- and we have to bail if we
3175*9712c20fSFrederick Mayle // see any unrecognized augmentation string characters. So if there is
3176*9712c20fSFrederick Mayle // anything here at all, we know what it is, and where it starts.
3177*9712c20fSFrederick Mayle if (fde->cie->has_z_lsda) {
3178*9712c20fSFrederick Mayle // Check whether the LSDA's pointer encoding is usable now: only once
3179*9712c20fSFrederick Mayle // we've parsed the FDE's starting address do we call reader_->
3180*9712c20fSFrederick Mayle // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes
3181*9712c20fSFrederick Mayle // usable.
3182*9712c20fSFrederick Mayle if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) {
3183*9712c20fSFrederick Mayle reporter_->UnusablePointerEncoding(fde->cie->offset,
3184*9712c20fSFrederick Mayle fde->cie->lsda_encoding);
3185*9712c20fSFrederick Mayle return false;
3186*9712c20fSFrederick Mayle }
3187*9712c20fSFrederick Mayle
3188*9712c20fSFrederick Mayle fde->lsda_address =
3189*9712c20fSFrederick Mayle reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size);
3190*9712c20fSFrederick Mayle if (size > data_size)
3191*9712c20fSFrederick Mayle return ReportIncomplete(fde);
3192*9712c20fSFrederick Mayle // Ideally, we would also complain here if there were unconsumed
3193*9712c20fSFrederick Mayle // augmentation data.
3194*9712c20fSFrederick Mayle }
3195*9712c20fSFrederick Mayle
3196*9712c20fSFrederick Mayle cursor += data_size;
3197*9712c20fSFrederick Mayle }
3198*9712c20fSFrederick Mayle
3199*9712c20fSFrederick Mayle // The FDE's instructions start after those.
3200*9712c20fSFrederick Mayle fde->instructions = cursor;
3201*9712c20fSFrederick Mayle
3202*9712c20fSFrederick Mayle return true;
3203*9712c20fSFrederick Mayle }
3204*9712c20fSFrederick Mayle
Start()3205*9712c20fSFrederick Mayle bool CallFrameInfo::Start() {
3206*9712c20fSFrederick Mayle const uint8_t* buffer_end = buffer_ + buffer_length_;
3207*9712c20fSFrederick Mayle const uint8_t* cursor;
3208*9712c20fSFrederick Mayle bool all_ok = true;
3209*9712c20fSFrederick Mayle const uint8_t* entry_end;
3210*9712c20fSFrederick Mayle bool ok;
3211*9712c20fSFrederick Mayle
3212*9712c20fSFrederick Mayle // Traverse all the entries in buffer_, skipping CIEs and offering
3213*9712c20fSFrederick Mayle // FDEs to the handler.
3214*9712c20fSFrederick Mayle for (cursor = buffer_; cursor < buffer_end;
3215*9712c20fSFrederick Mayle cursor = entry_end, all_ok = all_ok && ok) {
3216*9712c20fSFrederick Mayle FDE fde;
3217*9712c20fSFrederick Mayle
3218*9712c20fSFrederick Mayle // Make it easy to skip this entry with 'continue': assume that
3219*9712c20fSFrederick Mayle // things are not okay until we've checked all the data, and
3220*9712c20fSFrederick Mayle // prepare the address of the next entry.
3221*9712c20fSFrederick Mayle ok = false;
3222*9712c20fSFrederick Mayle
3223*9712c20fSFrederick Mayle // Read the entry's prologue.
3224*9712c20fSFrederick Mayle if (!ReadEntryPrologue(cursor, &fde)) {
3225*9712c20fSFrederick Mayle if (!fde.end) {
3226*9712c20fSFrederick Mayle // If we couldn't even figure out this entry's extent, then we
3227*9712c20fSFrederick Mayle // must stop processing entries altogether.
3228*9712c20fSFrederick Mayle all_ok = false;
3229*9712c20fSFrederick Mayle break;
3230*9712c20fSFrederick Mayle }
3231*9712c20fSFrederick Mayle entry_end = fde.end;
3232*9712c20fSFrederick Mayle continue;
3233*9712c20fSFrederick Mayle }
3234*9712c20fSFrederick Mayle
3235*9712c20fSFrederick Mayle // The next iteration picks up after this entry.
3236*9712c20fSFrederick Mayle entry_end = fde.end;
3237*9712c20fSFrederick Mayle
3238*9712c20fSFrederick Mayle // Did we see an .eh_frame terminating mark?
3239*9712c20fSFrederick Mayle if (fde.kind == kTerminator) {
3240*9712c20fSFrederick Mayle // If there appears to be more data left in the section after the
3241*9712c20fSFrederick Mayle // terminating mark, warn the user. But this is just a warning;
3242*9712c20fSFrederick Mayle // we leave all_ok true.
3243*9712c20fSFrederick Mayle if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset);
3244*9712c20fSFrederick Mayle break;
3245*9712c20fSFrederick Mayle }
3246*9712c20fSFrederick Mayle
3247*9712c20fSFrederick Mayle // In this loop, we skip CIEs. We only parse them fully when we
3248*9712c20fSFrederick Mayle // parse an FDE that refers to them. This limits our memory
3249*9712c20fSFrederick Mayle // consumption (beyond the buffer itself) to that needed to
3250*9712c20fSFrederick Mayle // process the largest single entry.
3251*9712c20fSFrederick Mayle if (fde.kind != kFDE) {
3252*9712c20fSFrederick Mayle ok = true;
3253*9712c20fSFrederick Mayle continue;
3254*9712c20fSFrederick Mayle }
3255*9712c20fSFrederick Mayle
3256*9712c20fSFrederick Mayle // Validate the CIE pointer.
3257*9712c20fSFrederick Mayle if (fde.id > buffer_length_) {
3258*9712c20fSFrederick Mayle reporter_->CIEPointerOutOfRange(fde.offset, fde.id);
3259*9712c20fSFrederick Mayle continue;
3260*9712c20fSFrederick Mayle }
3261*9712c20fSFrederick Mayle
3262*9712c20fSFrederick Mayle CIE cie;
3263*9712c20fSFrederick Mayle
3264*9712c20fSFrederick Mayle // Parse this FDE's CIE header.
3265*9712c20fSFrederick Mayle if (!ReadEntryPrologue(buffer_ + fde.id, &cie))
3266*9712c20fSFrederick Mayle continue;
3267*9712c20fSFrederick Mayle // This had better be an actual CIE.
3268*9712c20fSFrederick Mayle if (cie.kind != kCIE) {
3269*9712c20fSFrederick Mayle reporter_->BadCIEId(fde.offset, fde.id);
3270*9712c20fSFrederick Mayle continue;
3271*9712c20fSFrederick Mayle }
3272*9712c20fSFrederick Mayle if (!ReadCIEFields(&cie))
3273*9712c20fSFrederick Mayle continue;
3274*9712c20fSFrederick Mayle
3275*9712c20fSFrederick Mayle // TODO(nbilling): This could lead to strange behavior if a single buffer
3276*9712c20fSFrederick Mayle // contained a mixture of DWARF versions as well as address sizes. Not
3277*9712c20fSFrederick Mayle // sure if it's worth handling such a case.
3278*9712c20fSFrederick Mayle
3279*9712c20fSFrederick Mayle // DWARF4 CIE specifies address_size, so use it for this call frame.
3280*9712c20fSFrederick Mayle if (cie.version >= 4) {
3281*9712c20fSFrederick Mayle reader_->SetAddressSize(cie.address_size);
3282*9712c20fSFrederick Mayle }
3283*9712c20fSFrederick Mayle
3284*9712c20fSFrederick Mayle // We now have the values that govern both the CIE and the FDE.
3285*9712c20fSFrederick Mayle cie.cie = &cie;
3286*9712c20fSFrederick Mayle fde.cie = &cie;
3287*9712c20fSFrederick Mayle
3288*9712c20fSFrederick Mayle // Parse the FDE's header.
3289*9712c20fSFrederick Mayle if (!ReadFDEFields(&fde))
3290*9712c20fSFrederick Mayle continue;
3291*9712c20fSFrederick Mayle
3292*9712c20fSFrederick Mayle // Call Entry to ask the consumer if they're interested.
3293*9712c20fSFrederick Mayle if (!handler_->Entry(fde.offset, fde.address, fde.size,
3294*9712c20fSFrederick Mayle cie.version, cie.augmentation,
3295*9712c20fSFrederick Mayle cie.return_address_register)) {
3296*9712c20fSFrederick Mayle // The handler isn't interested in this entry. That's not an error.
3297*9712c20fSFrederick Mayle ok = true;
3298*9712c20fSFrederick Mayle continue;
3299*9712c20fSFrederick Mayle }
3300*9712c20fSFrederick Mayle
3301*9712c20fSFrederick Mayle if (cie.has_z_augmentation) {
3302*9712c20fSFrederick Mayle // Report the personality routine address, if we have one.
3303*9712c20fSFrederick Mayle if (cie.has_z_personality) {
3304*9712c20fSFrederick Mayle if (!handler_
3305*9712c20fSFrederick Mayle ->PersonalityRoutine(cie.personality_address,
3306*9712c20fSFrederick Mayle IsIndirectEncoding(cie.personality_encoding)))
3307*9712c20fSFrederick Mayle continue;
3308*9712c20fSFrederick Mayle }
3309*9712c20fSFrederick Mayle
3310*9712c20fSFrederick Mayle // Report the language-specific data area address, if we have one.
3311*9712c20fSFrederick Mayle if (cie.has_z_lsda) {
3312*9712c20fSFrederick Mayle if (!handler_
3313*9712c20fSFrederick Mayle ->LanguageSpecificDataArea(fde.lsda_address,
3314*9712c20fSFrederick Mayle IsIndirectEncoding(cie.lsda_encoding)))
3315*9712c20fSFrederick Mayle continue;
3316*9712c20fSFrederick Mayle }
3317*9712c20fSFrederick Mayle
3318*9712c20fSFrederick Mayle // If this is a signal-handling frame, report that.
3319*9712c20fSFrederick Mayle if (cie.has_z_signal_frame) {
3320*9712c20fSFrederick Mayle if (!handler_->SignalHandler())
3321*9712c20fSFrederick Mayle continue;
3322*9712c20fSFrederick Mayle }
3323*9712c20fSFrederick Mayle }
3324*9712c20fSFrederick Mayle
3325*9712c20fSFrederick Mayle // Interpret the CIE's instructions, and then the FDE's instructions.
3326*9712c20fSFrederick Mayle State state(reader_, handler_, reporter_, fde.address);
3327*9712c20fSFrederick Mayle ok = state.InterpretCIE(cie) && state.InterpretFDE(fde);
3328*9712c20fSFrederick Mayle
3329*9712c20fSFrederick Mayle // Tell the ByteReader that the function start address from the
3330*9712c20fSFrederick Mayle // FDE header is no longer valid.
3331*9712c20fSFrederick Mayle reader_->ClearFunctionBase();
3332*9712c20fSFrederick Mayle
3333*9712c20fSFrederick Mayle // Report the end of the entry.
3334*9712c20fSFrederick Mayle handler_->End();
3335*9712c20fSFrederick Mayle }
3336*9712c20fSFrederick Mayle
3337*9712c20fSFrederick Mayle return all_ok;
3338*9712c20fSFrederick Mayle }
3339*9712c20fSFrederick Mayle
KindName(EntryKind kind)3340*9712c20fSFrederick Mayle const char* CallFrameInfo::KindName(EntryKind kind) {
3341*9712c20fSFrederick Mayle if (kind == CallFrameInfo::kUnknown)
3342*9712c20fSFrederick Mayle return "entry";
3343*9712c20fSFrederick Mayle else if (kind == CallFrameInfo::kCIE)
3344*9712c20fSFrederick Mayle return "common information entry";
3345*9712c20fSFrederick Mayle else if (kind == CallFrameInfo::kFDE)
3346*9712c20fSFrederick Mayle return "frame description entry";
3347*9712c20fSFrederick Mayle else {
3348*9712c20fSFrederick Mayle assert (kind == CallFrameInfo::kTerminator);
3349*9712c20fSFrederick Mayle return ".eh_frame sequence terminator";
3350*9712c20fSFrederick Mayle }
3351*9712c20fSFrederick Mayle }
3352*9712c20fSFrederick Mayle
ReportIncomplete(Entry * entry)3353*9712c20fSFrederick Mayle bool CallFrameInfo::ReportIncomplete(Entry* entry) {
3354*9712c20fSFrederick Mayle reporter_->Incomplete(entry->offset, entry->kind);
3355*9712c20fSFrederick Mayle return false;
3356*9712c20fSFrederick Mayle }
3357*9712c20fSFrederick Mayle
Incomplete(uint64_t offset,CallFrameInfo::EntryKind kind)3358*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::Incomplete(uint64_t offset,
3359*9712c20fSFrederick Mayle CallFrameInfo::EntryKind kind) {
3360*9712c20fSFrederick Mayle fprintf(stderr,
3361*9712c20fSFrederick Mayle "%s: CFI %s at offset 0x%" PRIx64 " in '%s': entry ends early\n",
3362*9712c20fSFrederick Mayle filename_.c_str(), CallFrameInfo::KindName(kind), offset,
3363*9712c20fSFrederick Mayle section_.c_str());
3364*9712c20fSFrederick Mayle }
3365*9712c20fSFrederick Mayle
EarlyEHTerminator(uint64_t offset)3366*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::EarlyEHTerminator(uint64_t offset) {
3367*9712c20fSFrederick Mayle fprintf(stderr,
3368*9712c20fSFrederick Mayle "%s: CFI at offset 0x%" PRIx64 " in '%s': saw end-of-data marker"
3369*9712c20fSFrederick Mayle " before end of section contents\n",
3370*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str());
3371*9712c20fSFrederick Mayle }
3372*9712c20fSFrederick Mayle
CIEPointerOutOfRange(uint64_t offset,uint64_t cie_offset)3373*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64_t offset,
3374*9712c20fSFrederick Mayle uint64_t cie_offset) {
3375*9712c20fSFrederick Mayle fprintf(stderr,
3376*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3377*9712c20fSFrederick Mayle " CIE pointer is out of range: 0x%" PRIx64 "\n",
3378*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), cie_offset);
3379*9712c20fSFrederick Mayle }
3380*9712c20fSFrederick Mayle
BadCIEId(uint64_t offset,uint64_t cie_offset)3381*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::BadCIEId(uint64_t offset, uint64_t cie_offset) {
3382*9712c20fSFrederick Mayle fprintf(stderr,
3383*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3384*9712c20fSFrederick Mayle " CIE pointer does not point to a CIE: 0x%" PRIx64 "\n",
3385*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), cie_offset);
3386*9712c20fSFrederick Mayle }
3387*9712c20fSFrederick Mayle
UnexpectedAddressSize(uint64_t offset,uint8_t address_size)3388*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::UnexpectedAddressSize(uint64_t offset,
3389*9712c20fSFrederick Mayle uint8_t address_size) {
3390*9712c20fSFrederick Mayle fprintf(stderr,
3391*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3392*9712c20fSFrederick Mayle " CIE specifies unexpected address size: %d\n",
3393*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), address_size);
3394*9712c20fSFrederick Mayle }
3395*9712c20fSFrederick Mayle
UnexpectedSegmentSize(uint64_t offset,uint8_t segment_size)3396*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::UnexpectedSegmentSize(uint64_t offset,
3397*9712c20fSFrederick Mayle uint8_t segment_size) {
3398*9712c20fSFrederick Mayle fprintf(stderr,
3399*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3400*9712c20fSFrederick Mayle " CIE specifies unexpected segment size: %d\n",
3401*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), segment_size);
3402*9712c20fSFrederick Mayle }
3403*9712c20fSFrederick Mayle
UnrecognizedVersion(uint64_t offset,int version)3404*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::UnrecognizedVersion(uint64_t offset, int version) {
3405*9712c20fSFrederick Mayle fprintf(stderr,
3406*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3407*9712c20fSFrederick Mayle " CIE specifies unrecognized version: %d\n",
3408*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), version);
3409*9712c20fSFrederick Mayle }
3410*9712c20fSFrederick Mayle
UnrecognizedAugmentation(uint64_t offset,const string & aug)3411*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64_t offset,
3412*9712c20fSFrederick Mayle const string& aug) {
3413*9712c20fSFrederick Mayle fprintf(stderr,
3414*9712c20fSFrederick Mayle "%s: CFI frame description entry at offset 0x%" PRIx64 " in '%s':"
3415*9712c20fSFrederick Mayle " CIE specifies unrecognized augmentation: '%s'\n",
3416*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), aug.c_str());
3417*9712c20fSFrederick Mayle }
3418*9712c20fSFrederick Mayle
InvalidPointerEncoding(uint64_t offset,uint8_t encoding)3419*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64_t offset,
3420*9712c20fSFrederick Mayle uint8_t encoding) {
3421*9712c20fSFrederick Mayle fprintf(stderr,
3422*9712c20fSFrederick Mayle "%s: CFI common information entry at offset 0x%" PRIx64 " in '%s':"
3423*9712c20fSFrederick Mayle " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n",
3424*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), encoding);
3425*9712c20fSFrederick Mayle }
3426*9712c20fSFrederick Mayle
UnusablePointerEncoding(uint64_t offset,uint8_t encoding)3427*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64_t offset,
3428*9712c20fSFrederick Mayle uint8_t encoding) {
3429*9712c20fSFrederick Mayle fprintf(stderr,
3430*9712c20fSFrederick Mayle "%s: CFI common information entry at offset 0x%" PRIx64 " in '%s':"
3431*9712c20fSFrederick Mayle " 'z' augmentation specifies a pointer encoding for which"
3432*9712c20fSFrederick Mayle " we have no base address: 0x%02x\n",
3433*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), encoding);
3434*9712c20fSFrederick Mayle }
3435*9712c20fSFrederick Mayle
RestoreInCIE(uint64_t offset,uint64_t insn_offset)3436*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::RestoreInCIE(uint64_t offset, uint64_t insn_offset) {
3437*9712c20fSFrederick Mayle fprintf(stderr,
3438*9712c20fSFrederick Mayle "%s: CFI common information entry at offset 0x%" PRIx64 " in '%s':"
3439*9712c20fSFrederick Mayle " the DW_CFA_restore instruction at offset 0x%" PRIx64
3440*9712c20fSFrederick Mayle " cannot be used in a common information entry\n",
3441*9712c20fSFrederick Mayle filename_.c_str(), offset, section_.c_str(), insn_offset);
3442*9712c20fSFrederick Mayle }
3443*9712c20fSFrederick Mayle
BadInstruction(uint64_t offset,CallFrameInfo::EntryKind kind,uint64_t insn_offset)3444*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::BadInstruction(uint64_t offset,
3445*9712c20fSFrederick Mayle CallFrameInfo::EntryKind kind,
3446*9712c20fSFrederick Mayle uint64_t insn_offset) {
3447*9712c20fSFrederick Mayle fprintf(stderr,
3448*9712c20fSFrederick Mayle "%s: CFI %s at offset 0x%" PRIx64 " in section '%s':"
3449*9712c20fSFrederick Mayle " the instruction at offset 0x%" PRIx64 " is unrecognized\n",
3450*9712c20fSFrederick Mayle filename_.c_str(), CallFrameInfo::KindName(kind),
3451*9712c20fSFrederick Mayle offset, section_.c_str(), insn_offset);
3452*9712c20fSFrederick Mayle }
3453*9712c20fSFrederick Mayle
NoCFARule(uint64_t offset,CallFrameInfo::EntryKind kind,uint64_t insn_offset)3454*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::NoCFARule(uint64_t offset,
3455*9712c20fSFrederick Mayle CallFrameInfo::EntryKind kind,
3456*9712c20fSFrederick Mayle uint64_t insn_offset) {
3457*9712c20fSFrederick Mayle fprintf(stderr,
3458*9712c20fSFrederick Mayle "%s: CFI %s at offset 0x%" PRIx64 " in section '%s':"
3459*9712c20fSFrederick Mayle " the instruction at offset 0x%" PRIx64 " assumes that a CFA rule has"
3460*9712c20fSFrederick Mayle " been set, but none has been set\n",
3461*9712c20fSFrederick Mayle filename_.c_str(), CallFrameInfo::KindName(kind), offset,
3462*9712c20fSFrederick Mayle section_.c_str(), insn_offset);
3463*9712c20fSFrederick Mayle }
3464*9712c20fSFrederick Mayle
EmptyStateStack(uint64_t offset,CallFrameInfo::EntryKind kind,uint64_t insn_offset)3465*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::EmptyStateStack(uint64_t offset,
3466*9712c20fSFrederick Mayle CallFrameInfo::EntryKind kind,
3467*9712c20fSFrederick Mayle uint64_t insn_offset) {
3468*9712c20fSFrederick Mayle fprintf(stderr,
3469*9712c20fSFrederick Mayle "%s: CFI %s at offset 0x%" PRIx64 " in section '%s':"
3470*9712c20fSFrederick Mayle " the DW_CFA_restore_state instruction at offset 0x%" PRIx64
3471*9712c20fSFrederick Mayle " should pop a saved state from the stack, but the stack is empty\n",
3472*9712c20fSFrederick Mayle filename_.c_str(), CallFrameInfo::KindName(kind), offset,
3473*9712c20fSFrederick Mayle section_.c_str(), insn_offset);
3474*9712c20fSFrederick Mayle }
3475*9712c20fSFrederick Mayle
ClearingCFARule(uint64_t offset,CallFrameInfo::EntryKind kind,uint64_t insn_offset)3476*9712c20fSFrederick Mayle void CallFrameInfo::Reporter::ClearingCFARule(uint64_t offset,
3477*9712c20fSFrederick Mayle CallFrameInfo::EntryKind kind,
3478*9712c20fSFrederick Mayle uint64_t insn_offset) {
3479*9712c20fSFrederick Mayle fprintf(stderr,
3480*9712c20fSFrederick Mayle "%s: CFI %s at offset 0x%" PRIx64 " in section '%s':"
3481*9712c20fSFrederick Mayle " the DW_CFA_restore_state instruction at offset 0x%" PRIx64
3482*9712c20fSFrederick Mayle " would clear the CFA rule in effect\n",
3483*9712c20fSFrederick Mayle filename_.c_str(), CallFrameInfo::KindName(kind), offset,
3484*9712c20fSFrederick Mayle section_.c_str(), insn_offset);
3485*9712c20fSFrederick Mayle }
3486*9712c20fSFrederick Mayle
3487*9712c20fSFrederick Mayle } // namespace google_breakpad
3488