toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.cc

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 // Copyright (c) 2010 Google Inc. All Rights Reserved.
michael@0 2 //
michael@0 3 // Redistribution and use in source and binary forms, with or without
michael@0 4 // modification, are permitted provided that the following conditions are
michael@0 5 // met:
michael@0 6 //
michael@0 7 // * Redistributions of source code must retain the above copyright
michael@0 8 // notice, this list of conditions and the following disclaimer.
michael@0 9 // * Redistributions in binary form must reproduce the above
michael@0 10 // copyright notice, this list of conditions and the following disclaimer
michael@0 11 // in the documentation and/or other materials provided with the
michael@0 12 // distribution.
michael@0 13 // * Neither the name of Google Inc. nor the names of its
michael@0 14 // contributors may be used to endorse or promote products derived from
michael@0 15 // this software without specific prior written permission.
michael@0 16 //
michael@0 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 28
michael@0 29 // CFI reader author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
michael@0 30
michael@0 31 // Implementation of dwarf2reader::LineInfo, dwarf2reader::CompilationUnit,
michael@0 32 // and dwarf2reader::CallFrameInfo. See dwarf2reader.h for details.
michael@0 33
michael@0 34 #include "common/dwarf/dwarf2reader.h"
michael@0 35
michael@0 36 #include <assert.h>
michael@0 37 #include <stdint.h>
michael@0 38 #include <stdio.h>
michael@0 39 #include <string.h>
michael@0 40
michael@0 41 #include <map>
michael@0 42 #include <memory>
michael@0 43 #include <stack>
michael@0 44 #include <string>
michael@0 45 #include <utility>
michael@0 46
michael@0 47 #include "common/dwarf/bytereader-inl.h"
michael@0 48 #include "common/dwarf/bytereader.h"
michael@0 49 #include "common/dwarf/line_state_machine.h"
michael@0 50 #include "common/using_std_string.h"
michael@0 51
michael@0 52 namespace dwarf2reader {
michael@0 53
michael@0 54 CompilationUnit::CompilationUnit(const SectionMap& sections, uint64 offset,
michael@0 55 ByteReader* reader, Dwarf2Handler* handler)
michael@0 56 : offset_from_section_start_(offset), reader_(reader),
michael@0 57 sections_(sections), handler_(handler), abbrevs_(NULL),
michael@0 58 string_buffer_(NULL), string_buffer_length_(0) {}
michael@0 59
michael@0 60 // Read a DWARF2/3 abbreviation section.
michael@0 61 // Each abbrev consists of a abbreviation number, a tag, a byte
michael@0 62 // specifying whether the tag has children, and a list of
michael@0 63 // attribute/form pairs.
michael@0 64 // The list of forms is terminated by a 0 for the attribute, and a
michael@0 65 // zero for the form. The entire abbreviation section is terminated
michael@0 66 // by a zero for the code.
michael@0 67
michael@0 68 void CompilationUnit::ReadAbbrevs() {
michael@0 69 if (abbrevs_)
michael@0 70 return;
michael@0 71
michael@0 72 // First get the debug_abbrev section. ".debug_abbrev" is the name
michael@0 73 // recommended in the DWARF spec, and used on Linux;
michael@0 74 // "__debug_abbrev" is the name used in Mac OS X Mach-O files.
michael@0 75 SectionMap::const_iterator iter = sections_.find(".debug_abbrev");
michael@0 76 if (iter == sections_.end())
michael@0 77 iter = sections_.find("__debug_abbrev");
michael@0 78 assert(iter != sections_.end());
michael@0 79
michael@0 80 abbrevs_ = new std::vector<Abbrev>;
michael@0 81 abbrevs_->resize(1);
michael@0 82
michael@0 83 // The only way to check whether we are reading over the end of the
michael@0 84 // buffer would be to first compute the size of the leb128 data by
michael@0 85 // reading it, then go back and read it again.
michael@0 86 const char* abbrev_start = iter->second.first +
michael@0 87 header_.abbrev_offset;
michael@0 88 const char* abbrevptr = abbrev_start;
michael@0 89 #ifndef NDEBUG
michael@0 90 const uint64 abbrev_length = iter->second.second - header_.abbrev_offset;
michael@0 91 #endif
michael@0 92
michael@0 93 while (1) {
michael@0 94 CompilationUnit::Abbrev abbrev;
michael@0 95 size_t len;
michael@0 96 const uint64 number = reader_->ReadUnsignedLEB128(abbrevptr, &len);
michael@0 97
michael@0 98 if (number == 0)
michael@0 99 break;
michael@0 100 abbrev.number = number;
michael@0 101 abbrevptr += len;
michael@0 102
michael@0 103 assert(abbrevptr < abbrev_start + abbrev_length);
michael@0 104 const uint64 tag = reader_->ReadUnsignedLEB128(abbrevptr, &len);
michael@0 105 abbrevptr += len;
michael@0 106 abbrev.tag = static_cast<enum DwarfTag>(tag);
michael@0 107
michael@0 108 assert(abbrevptr < abbrev_start + abbrev_length);
michael@0 109 abbrev.has_children = reader_->ReadOneByte(abbrevptr);
michael@0 110 abbrevptr += 1;
michael@0 111
michael@0 112 assert(abbrevptr < abbrev_start + abbrev_length);
michael@0 113
michael@0 114 while (1) {
michael@0 115 const uint64 nametemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
michael@0 116 abbrevptr += len;
michael@0 117
michael@0 118 assert(abbrevptr < abbrev_start + abbrev_length);
michael@0 119 const uint64 formtemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
michael@0 120 abbrevptr += len;
michael@0 121 if (nametemp == 0 && formtemp == 0)
michael@0 122 break;
michael@0 123
michael@0 124 const enum DwarfAttribute name =
michael@0 125 static_cast<enum DwarfAttribute>(nametemp);
michael@0 126 const enum DwarfForm form = static_cast<enum DwarfForm>(formtemp);
michael@0 127 abbrev.attributes.push_back(std::make_pair(name, form));
michael@0 128 }
michael@0 129 assert(abbrev.number == abbrevs_->size());
michael@0 130 abbrevs_->push_back(abbrev);
michael@0 131 }
michael@0 132 }
michael@0 133
michael@0 134 // Skips a single DIE's attributes.
michael@0 135 const char* CompilationUnit::SkipDIE(const char* start,
michael@0 136 const Abbrev& abbrev) {
michael@0 137 for (AttributeList::const_iterator i = abbrev.attributes.begin();
michael@0 138 i != abbrev.attributes.end();
michael@0 139 i++) {
michael@0 140 start = SkipAttribute(start, i->second);
michael@0 141 }
michael@0 142 return start;
michael@0 143 }
michael@0 144
michael@0 145 // Skips a single attribute form's data.
michael@0 146 const char* CompilationUnit::SkipAttribute(const char* start,
michael@0 147 enum DwarfForm form) {
michael@0 148 size_t len;
michael@0 149
michael@0 150 switch (form) {
michael@0 151 case DW_FORM_indirect:
michael@0 152 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
michael@0 153 &len));
michael@0 154 start += len;
michael@0 155 return SkipAttribute(start, form);
michael@0 156
michael@0 157 case DW_FORM_flag_present:
michael@0 158 return start;
michael@0 159 case DW_FORM_data1:
michael@0 160 case DW_FORM_flag:
michael@0 161 case DW_FORM_ref1:
michael@0 162 return start + 1;
michael@0 163 case DW_FORM_ref2:
michael@0 164 case DW_FORM_data2:
michael@0 165 return start + 2;
michael@0 166 case DW_FORM_ref4:
michael@0 167 case DW_FORM_data4:
michael@0 168 return start + 4;
michael@0 169 case DW_FORM_ref8:
michael@0 170 case DW_FORM_data8:
michael@0 171 case DW_FORM_ref_sig8:
michael@0 172 return start + 8;
michael@0 173 case DW_FORM_string:
michael@0 174 return start + strlen(start) + 1;
michael@0 175 case DW_FORM_udata:
michael@0 176 case DW_FORM_ref_udata:
michael@0 177 reader_->ReadUnsignedLEB128(start, &len);
michael@0 178 return start + len;
michael@0 179
michael@0 180 case DW_FORM_sdata:
michael@0 181 reader_->ReadSignedLEB128(start, &len);
michael@0 182 return start + len;
michael@0 183 case DW_FORM_addr:
michael@0 184 return start + reader_->AddressSize();
michael@0 185 case DW_FORM_ref_addr:
michael@0 186 // DWARF2 and 3 differ on whether ref_addr is address size or
michael@0 187 // offset size.
michael@0 188 assert(header_.version == 2 || header_.version == 3);
michael@0 189 if (header_.version == 2) {
michael@0 190 return start + reader_->AddressSize();
michael@0 191 } else if (header_.version == 3) {
michael@0 192 return start + reader_->OffsetSize();
michael@0 193 }
michael@0 194
michael@0 195 case DW_FORM_block1:
michael@0 196 return start + 1 + reader_->ReadOneByte(start);
michael@0 197 case DW_FORM_block2:
michael@0 198 return start + 2 + reader_->ReadTwoBytes(start);
michael@0 199 case DW_FORM_block4:
michael@0 200 return start + 4 + reader_->ReadFourBytes(start);
michael@0 201 case DW_FORM_block:
michael@0 202 case DW_FORM_exprloc: {
michael@0 203 uint64 size = reader_->ReadUnsignedLEB128(start, &len);
michael@0 204 return start + size + len;
michael@0 205 }
michael@0 206 case DW_FORM_strp:
michael@0 207 case DW_FORM_sec_offset:
michael@0 208 return start + reader_->OffsetSize();
michael@0 209 }
michael@0 210 fprintf(stderr,"Unhandled form type");
michael@0 211 return NULL;
michael@0 212 }
michael@0 213
michael@0 214 // Read a DWARF2/3 header.
michael@0 215 // The header is variable length in DWARF3 (and DWARF2 as extended by
michael@0 216 // most compilers), and consists of an length field, a version number,
michael@0 217 // the offset in the .debug_abbrev section for our abbrevs, and an
michael@0 218 // address size.
michael@0 219 void CompilationUnit::ReadHeader() {
michael@0 220 const char* headerptr = buffer_;
michael@0 221 size_t initial_length_size;
michael@0 222
michael@0 223 assert(headerptr + 4 < buffer_ + buffer_length_);
michael@0 224 const uint64 initial_length
michael@0 225 = reader_->ReadInitialLength(headerptr, &initial_length_size);
michael@0 226 headerptr += initial_length_size;
michael@0 227 header_.length = initial_length;
michael@0 228
michael@0 229 assert(headerptr + 2 < buffer_ + buffer_length_);
michael@0 230 header_.version = reader_->ReadTwoBytes(headerptr);
michael@0 231 headerptr += 2;
michael@0 232
michael@0 233 assert(headerptr + reader_->OffsetSize() < buffer_ + buffer_length_);
michael@0 234 header_.abbrev_offset = reader_->ReadOffset(headerptr);
michael@0 235 headerptr += reader_->OffsetSize();
michael@0 236
michael@0 237 assert(headerptr + 1 < buffer_ + buffer_length_);
michael@0 238 header_.address_size = reader_->ReadOneByte(headerptr);
michael@0 239 reader_->SetAddressSize(header_.address_size);
michael@0 240 headerptr += 1;
michael@0 241
michael@0 242 after_header_ = headerptr;
michael@0 243
michael@0 244 // This check ensures that we don't have to do checking during the
michael@0 245 // reading of DIEs. header_.length does not include the size of the
michael@0 246 // initial length.
michael@0 247 assert(buffer_ + initial_length_size + header_.length <=
michael@0 248 buffer_ + buffer_length_);
michael@0 249 }
michael@0 250
michael@0 251 uint64 CompilationUnit::Start() {
michael@0 252 // First get the debug_info section. ".debug_info" is the name
michael@0 253 // recommended in the DWARF spec, and used on Linux; "__debug_info"
michael@0 254 // is the name used in Mac OS X Mach-O files.
michael@0 255 SectionMap::const_iterator iter = sections_.find(".debug_info");
michael@0 256 if (iter == sections_.end())
michael@0 257 iter = sections_.find("__debug_info");
michael@0 258 assert(iter != sections_.end());
michael@0 259
michael@0 260 // Set up our buffer
michael@0 261 buffer_ = iter->second.first + offset_from_section_start_;
michael@0 262 buffer_length_ = iter->second.second - offset_from_section_start_;
michael@0 263
michael@0 264 // Read the header
michael@0 265 ReadHeader();
michael@0 266
michael@0 267 // Figure out the real length from the end of the initial length to
michael@0 268 // the end of the compilation unit, since that is the value we
michael@0 269 // return.
michael@0 270 uint64 ourlength = header_.length;
michael@0 271 if (reader_->OffsetSize() == 8)
michael@0 272 ourlength += 12;
michael@0 273 else
michael@0 274 ourlength += 4;
michael@0 275
michael@0 276 // See if the user wants this compilation unit, and if not, just return.
michael@0 277 if (!handler_->StartCompilationUnit(offset_from_section_start_,
michael@0 278 reader_->AddressSize(),
michael@0 279 reader_->OffsetSize(),
michael@0 280 header_.length,
michael@0 281 header_.version))
michael@0 282 return ourlength;
michael@0 283
michael@0 284 // Otherwise, continue by reading our abbreviation entries.
michael@0 285 ReadAbbrevs();
michael@0 286
michael@0 287 // Set the string section if we have one. ".debug_str" is the name
michael@0 288 // recommended in the DWARF spec, and used on Linux; "__debug_str"
michael@0 289 // is the name used in Mac OS X Mach-O files.
michael@0 290 iter = sections_.find(".debug_str");
michael@0 291 if (iter == sections_.end())
michael@0 292 iter = sections_.find("__debug_str");
michael@0 293 if (iter != sections_.end()) {
michael@0 294 string_buffer_ = iter->second.first;
michael@0 295 string_buffer_length_ = iter->second.second;
michael@0 296 }
michael@0 297
michael@0 298 // Now that we have our abbreviations, start processing DIE's.
michael@0 299 ProcessDIEs();
michael@0 300
michael@0 301 return ourlength;
michael@0 302 }
michael@0 303
michael@0 304 // If one really wanted, you could merge SkipAttribute and
michael@0 305 // ProcessAttribute
michael@0 306 // This is all boring data manipulation and calling of the handler.
michael@0 307 const char* CompilationUnit::ProcessAttribute(
michael@0 308 uint64 dieoffset, const char* start, enum DwarfAttribute attr,
michael@0 309 enum DwarfForm form) {
michael@0 310 size_t len;
michael@0 311
michael@0 312 switch (form) {
michael@0 313 // DW_FORM_indirect is never used because it is such a space
michael@0 314 // waster.
michael@0 315 case DW_FORM_indirect:
michael@0 316 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
michael@0 317 &len));
michael@0 318 start += len;
michael@0 319 return ProcessAttribute(dieoffset, start, attr, form);
michael@0 320
michael@0 321 case DW_FORM_flag_present:
michael@0 322 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1);
michael@0 323 return start;
michael@0 324 case DW_FORM_data1:
michael@0 325 case DW_FORM_flag:
michael@0 326 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 327 reader_->ReadOneByte(start));
michael@0 328 return start + 1;
michael@0 329 case DW_FORM_data2:
michael@0 330 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 331 reader_->ReadTwoBytes(start));
michael@0 332 return start + 2;
michael@0 333 case DW_FORM_data4:
michael@0 334 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 335 reader_->ReadFourBytes(start));
michael@0 336 return start + 4;
michael@0 337 case DW_FORM_data8:
michael@0 338 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 339 reader_->ReadEightBytes(start));
michael@0 340 return start + 8;
michael@0 341 case DW_FORM_string: {
michael@0 342 const char* str = start;
michael@0 343 handler_->ProcessAttributeString(dieoffset, attr, form,
michael@0 344 str);
michael@0 345 return start + strlen(str) + 1;
michael@0 346 }
michael@0 347 case DW_FORM_udata:
michael@0 348 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 349 reader_->ReadUnsignedLEB128(start,
michael@0 350 &len));
michael@0 351 return start + len;
michael@0 352
michael@0 353 case DW_FORM_sdata:
michael@0 354 handler_->ProcessAttributeSigned(dieoffset, attr, form,
michael@0 355 reader_->ReadSignedLEB128(start, &len));
michael@0 356 return start + len;
michael@0 357 case DW_FORM_addr:
michael@0 358 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 359 reader_->ReadAddress(start));
michael@0 360 return start + reader_->AddressSize();
michael@0 361 case DW_FORM_sec_offset:
michael@0 362 handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
michael@0 363 reader_->ReadOffset(start));
michael@0 364 return start + reader_->OffsetSize();
michael@0 365
michael@0 366 case DW_FORM_ref1:
michael@0 367 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 368 reader_->ReadOneByte(start)
michael@0 369 + offset_from_section_start_);
michael@0 370 return start + 1;
michael@0 371 case DW_FORM_ref2:
michael@0 372 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 373 reader_->ReadTwoBytes(start)
michael@0 374 + offset_from_section_start_);
michael@0 375 return start + 2;
michael@0 376 case DW_FORM_ref4:
michael@0 377 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 378 reader_->ReadFourBytes(start)
michael@0 379 + offset_from_section_start_);
michael@0 380 return start + 4;
michael@0 381 case DW_FORM_ref8:
michael@0 382 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 383 reader_->ReadEightBytes(start)
michael@0 384 + offset_from_section_start_);
michael@0 385 return start + 8;
michael@0 386 case DW_FORM_ref_udata:
michael@0 387 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 388 reader_->ReadUnsignedLEB128(start,
michael@0 389 &len)
michael@0 390 + offset_from_section_start_);
michael@0 391 return start + len;
michael@0 392 case DW_FORM_ref_addr:
michael@0 393 // DWARF2 and 3 differ on whether ref_addr is address size or
michael@0 394 // offset size.
michael@0 395 assert(header_.version == 2 || header_.version == 3);
michael@0 396 if (header_.version == 2) {
michael@0 397 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 398 reader_->ReadAddress(start));
michael@0 399 return start + reader_->AddressSize();
michael@0 400 } else if (header_.version == 3) {
michael@0 401 handler_->ProcessAttributeReference(dieoffset, attr, form,
michael@0 402 reader_->ReadOffset(start));
michael@0 403 return start + reader_->OffsetSize();
michael@0 404 }
michael@0 405 break;
michael@0 406 case DW_FORM_ref_sig8:
michael@0 407 handler_->ProcessAttributeSignature(dieoffset, attr, form,
michael@0 408 reader_->ReadEightBytes(start));
michael@0 409 return start + 8;
michael@0 410
michael@0 411 case DW_FORM_block1: {
michael@0 412 uint64 datalen = reader_->ReadOneByte(start);
michael@0 413 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 1,
michael@0 414 datalen);
michael@0 415 return start + 1 + datalen;
michael@0 416 }
michael@0 417 case DW_FORM_block2: {
michael@0 418 uint64 datalen = reader_->ReadTwoBytes(start);
michael@0 419 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 2,
michael@0 420 datalen);
michael@0 421 return start + 2 + datalen;
michael@0 422 }
michael@0 423 case DW_FORM_block4: {
michael@0 424 uint64 datalen = reader_->ReadFourBytes(start);
michael@0 425 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 4,
michael@0 426 datalen);
michael@0 427 return start + 4 + datalen;
michael@0 428 }
michael@0 429 case DW_FORM_block:
michael@0 430 case DW_FORM_exprloc: {
michael@0 431 uint64 datalen = reader_->ReadUnsignedLEB128(start, &len);
michael@0 432 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len,
michael@0 433 datalen);
michael@0 434 return start + datalen + len;
michael@0 435 }
michael@0 436 case DW_FORM_strp: {
michael@0 437 assert(string_buffer_ != NULL);
michael@0 438
michael@0 439 const uint64 offset = reader_->ReadOffset(start);
michael@0 440 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
michael@0 441
michael@0 442 const char* str = string_buffer_ + offset;
michael@0 443 handler_->ProcessAttributeString(dieoffset, attr, form,
michael@0 444 str);
michael@0 445 return start + reader_->OffsetSize();
michael@0 446 }
michael@0 447 }
michael@0 448 fprintf(stderr, "Unhandled form type\n");
michael@0 449 return NULL;
michael@0 450 }
michael@0 451
michael@0 452 const char* CompilationUnit::ProcessDIE(uint64 dieoffset,
michael@0 453 const char* start,
michael@0 454 const Abbrev& abbrev) {
michael@0 455 for (AttributeList::const_iterator i = abbrev.attributes.begin();
michael@0 456 i != abbrev.attributes.end();
michael@0 457 i++) {
michael@0 458 start = ProcessAttribute(dieoffset, start, i->first, i->second);
michael@0 459 }
michael@0 460 return start;
michael@0 461 }
michael@0 462
michael@0 463 void CompilationUnit::ProcessDIEs() {
michael@0 464 const char* dieptr = after_header_;
michael@0 465 size_t len;
michael@0 466
michael@0 467 // lengthstart is the place the length field is based on.
michael@0 468 // It is the point in the header after the initial length field
michael@0 469 const char* lengthstart = buffer_;
michael@0 470
michael@0 471 // In 64 bit dwarf, the initial length is 12 bytes, because of the
michael@0 472 // 0xffffffff at the start.
michael@0 473 if (reader_->OffsetSize() == 8)
michael@0 474 lengthstart += 12;
michael@0 475 else
michael@0 476 lengthstart += 4;
michael@0 477
michael@0 478 std::stack<uint64> die_stack;
michael@0 479
michael@0 480 while (dieptr < (lengthstart + header_.length)) {
michael@0 481 // We give the user the absolute offset from the beginning of
michael@0 482 // debug_info, since they need it to deal with ref_addr forms.
michael@0 483 uint64 absolute_offset = (dieptr - buffer_) + offset_from_section_start_;
michael@0 484
michael@0 485 uint64 abbrev_num = reader_->ReadUnsignedLEB128(dieptr, &len);
michael@0 486
michael@0 487 dieptr += len;
michael@0 488
michael@0 489 // Abbrev == 0 represents the end of a list of children, or padding
michael@0 490 // at the end of the compilation unit.
michael@0 491 if (abbrev_num == 0) {
michael@0 492 if (die_stack.size() == 0)
michael@0 493 // If it is padding, then we are done with the compilation unit's DIEs.
michael@0 494 return;
michael@0 495 const uint64 offset = die_stack.top();
michael@0 496 die_stack.pop();
michael@0 497 handler_->EndDIE(offset);
michael@0 498 continue;
michael@0 499 }
michael@0 500
michael@0 501 const Abbrev& abbrev = abbrevs_->at(static_cast<size_t>(abbrev_num));
michael@0 502 const enum DwarfTag tag = abbrev.tag;
michael@0 503 if (!handler_->StartDIE(absolute_offset, tag)) {
michael@0 504 dieptr = SkipDIE(dieptr, abbrev);
michael@0 505 } else {
michael@0 506 dieptr = ProcessDIE(absolute_offset, dieptr, abbrev);
michael@0 507 }
michael@0 508
michael@0 509 if (abbrev.has_children) {
michael@0 510 die_stack.push(absolute_offset);
michael@0 511 } else {
michael@0 512 handler_->EndDIE(absolute_offset);
michael@0 513 }
michael@0 514 }
michael@0 515 }
michael@0 516
michael@0 517 LineInfo::LineInfo(const char* buffer, uint64 buffer_length,
michael@0 518 ByteReader* reader, LineInfoHandler* handler):
michael@0 519 handler_(handler), reader_(reader), buffer_(buffer),
michael@0 520 buffer_length_(buffer_length) {
michael@0 521 header_.std_opcode_lengths = NULL;
michael@0 522 }
michael@0 523
michael@0 524 uint64 LineInfo::Start() {
michael@0 525 ReadHeader();
michael@0 526 ReadLines();
michael@0 527 return after_header_ - buffer_;
michael@0 528 }
michael@0 529
michael@0 530 // The header for a debug_line section is mildly complicated, because
michael@0 531 // the line info is very tightly encoded.
michael@0 532 void LineInfo::ReadHeader() {
michael@0 533 const char* lineptr = buffer_;
michael@0 534 size_t initial_length_size;
michael@0 535
michael@0 536 const uint64 initial_length
michael@0 537 = reader_->ReadInitialLength(lineptr, &initial_length_size);
michael@0 538
michael@0 539 lineptr += initial_length_size;
michael@0 540 header_.total_length = initial_length;
michael@0 541 assert(buffer_ + initial_length_size + header_.total_length <=
michael@0 542 buffer_ + buffer_length_);
michael@0 543
michael@0 544 // Address size *must* be set by CU ahead of time.
michael@0 545 assert(reader_->AddressSize() != 0);
michael@0 546
michael@0 547 header_.version = reader_->ReadTwoBytes(lineptr);
michael@0 548 lineptr += 2;
michael@0 549
michael@0 550 header_.prologue_length = reader_->ReadOffset(lineptr);
michael@0 551 lineptr += reader_->OffsetSize();
michael@0 552
michael@0 553 header_.min_insn_length = reader_->ReadOneByte(lineptr);
michael@0 554 lineptr += 1;
michael@0 555
michael@0 556 header_.default_is_stmt = reader_->ReadOneByte(lineptr);
michael@0 557 lineptr += 1;
michael@0 558
michael@0 559 header_.line_base = *reinterpret_cast<const int8*>(lineptr);
michael@0 560 lineptr += 1;
michael@0 561
michael@0 562 header_.line_range = reader_->ReadOneByte(lineptr);
michael@0 563 lineptr += 1;
michael@0 564
michael@0 565 header_.opcode_base = reader_->ReadOneByte(lineptr);
michael@0 566 lineptr += 1;
michael@0 567
michael@0 568 header_.std_opcode_lengths = new std::vector<unsigned char>;
michael@0 569 header_.std_opcode_lengths->resize(header_.opcode_base + 1);
michael@0 570 (*header_.std_opcode_lengths)[0] = 0;
michael@0 571 for (int i = 1; i < header_.opcode_base; i++) {
michael@0 572 (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr);
michael@0 573 lineptr += 1;
michael@0 574 }
michael@0 575
michael@0 576 // It is legal for the directory entry table to be empty.
michael@0 577 if (*lineptr) {
michael@0 578 uint32 dirindex = 1;
michael@0 579 while (*lineptr) {
michael@0 580 const char* dirname = lineptr;
michael@0 581 handler_->DefineDir(dirname, dirindex);
michael@0 582 lineptr += strlen(dirname) + 1;
michael@0 583 dirindex++;
michael@0 584 }
michael@0 585 }
michael@0 586 lineptr++;
michael@0 587
michael@0 588 // It is also legal for the file entry table to be empty.
michael@0 589 if (*lineptr) {
michael@0 590 uint32 fileindex = 1;
michael@0 591 size_t len;
michael@0 592 while (*lineptr) {
michael@0 593 const char* filename = lineptr;
michael@0 594 lineptr += strlen(filename) + 1;
michael@0 595
michael@0 596 uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len);
michael@0 597 lineptr += len;
michael@0 598
michael@0 599 uint64 mod_time = reader_->ReadUnsignedLEB128(lineptr, &len);
michael@0 600 lineptr += len;
michael@0 601
michael@0 602 uint64 filelength = reader_->ReadUnsignedLEB128(lineptr, &len);
michael@0 603 lineptr += len;
michael@0 604 handler_->DefineFile(filename, fileindex, static_cast<uint32>(dirindex),
michael@0 605 mod_time, filelength);
michael@0 606 fileindex++;
michael@0 607 }
michael@0 608 }
michael@0 609 lineptr++;
michael@0 610
michael@0 611 after_header_ = lineptr;
michael@0 612 }
michael@0 613
michael@0 614 /* static */
michael@0 615 bool LineInfo::ProcessOneOpcode(ByteReader* reader,
michael@0 616 LineInfoHandler* handler,
michael@0 617 const struct LineInfoHeader &header,
michael@0 618 const char* start,
michael@0 619 struct LineStateMachine* lsm,
michael@0 620 size_t* len,
michael@0 621 uintptr pc,
michael@0 622 bool *lsm_passes_pc) {
michael@0 623 size_t oplen = 0;
michael@0 624 size_t templen;
michael@0 625 uint8 opcode = reader->ReadOneByte(start);
michael@0 626 oplen++;
michael@0 627 start++;
michael@0 628
michael@0 629 // If the opcode is great than the opcode_base, it is a special
michael@0 630 // opcode. Most line programs consist mainly of special opcodes.
michael@0 631 if (opcode >= header.opcode_base) {
michael@0 632 opcode -= header.opcode_base;
michael@0 633 const int64 advance_address = (opcode / header.line_range)
michael@0 634 * header.min_insn_length;
michael@0 635 const int32 advance_line = (opcode % header.line_range)
michael@0 636 + header.line_base;
michael@0 637
michael@0 638 // Check if the lsm passes "pc". If so, mark it as passed.
michael@0 639 if (lsm_passes_pc &&
michael@0 640 lsm->address <= pc && pc < lsm->address + advance_address) {
michael@0 641 *lsm_passes_pc = true;
michael@0 642 }
michael@0 643
michael@0 644 lsm->address += advance_address;
michael@0 645 lsm->line_num += advance_line;
michael@0 646 lsm->basic_block = true;
michael@0 647 *len = oplen;
michael@0 648 return true;
michael@0 649 }
michael@0 650
michael@0 651 // Otherwise, we have the regular opcodes
michael@0 652 switch (opcode) {
michael@0 653 case DW_LNS_copy: {
michael@0 654 lsm->basic_block = false;
michael@0 655 *len = oplen;
michael@0 656 return true;
michael@0 657 }
michael@0 658
michael@0 659 case DW_LNS_advance_pc: {
michael@0 660 uint64 advance_address = reader->ReadUnsignedLEB128(start, &templen);
michael@0 661 oplen += templen;
michael@0 662
michael@0 663 // Check if the lsm passes "pc". If so, mark it as passed.
michael@0 664 if (lsm_passes_pc && lsm->address <= pc &&
michael@0 665 pc < lsm->address + header.min_insn_length * advance_address) {
michael@0 666 *lsm_passes_pc = true;
michael@0 667 }
michael@0 668
michael@0 669 lsm->address += header.min_insn_length * advance_address;
michael@0 670 }
michael@0 671 break;
michael@0 672 case DW_LNS_advance_line: {
michael@0 673 const int64 advance_line = reader->ReadSignedLEB128(start, &templen);
michael@0 674 oplen += templen;
michael@0 675 lsm->line_num += static_cast<int32>(advance_line);
michael@0 676
michael@0 677 // With gcc 4.2.1, we can get the line_no here for the first time
michael@0 678 // since DW_LNS_advance_line is called after DW_LNE_set_address is
michael@0 679 // called. So we check if the lsm passes "pc" here, not in
michael@0 680 // DW_LNE_set_address.
michael@0 681 if (lsm_passes_pc && lsm->address == pc) {
michael@0 682 *lsm_passes_pc = true;
michael@0 683 }
michael@0 684 }
michael@0 685 break;
michael@0 686 case DW_LNS_set_file: {
michael@0 687 const uint64 fileno = reader->ReadUnsignedLEB128(start, &templen);
michael@0 688 oplen += templen;
michael@0 689 lsm->file_num = static_cast<uint32>(fileno);
michael@0 690 }
michael@0 691 break;
michael@0 692 case DW_LNS_set_column: {
michael@0 693 const uint64 colno = reader->ReadUnsignedLEB128(start, &templen);
michael@0 694 oplen += templen;
michael@0 695 lsm->column_num = static_cast<uint32>(colno);
michael@0 696 }
michael@0 697 break;
michael@0 698 case DW_LNS_negate_stmt: {
michael@0 699 lsm->is_stmt = !lsm->is_stmt;
michael@0 700 }
michael@0 701 break;
michael@0 702 case DW_LNS_set_basic_block: {
michael@0 703 lsm->basic_block = true;
michael@0 704 }
michael@0 705 break;
michael@0 706 case DW_LNS_fixed_advance_pc: {
michael@0 707 const uint16 advance_address = reader->ReadTwoBytes(start);
michael@0 708 oplen += 2;
michael@0 709
michael@0 710 // Check if the lsm passes "pc". If so, mark it as passed.
michael@0 711 if (lsm_passes_pc &&
michael@0 712 lsm->address <= pc && pc < lsm->address + advance_address) {
michael@0 713 *lsm_passes_pc = true;
michael@0 714 }
michael@0 715
michael@0 716 lsm->address += advance_address;
michael@0 717 }
michael@0 718 break;
michael@0 719 case DW_LNS_const_add_pc: {
michael@0 720 const int64 advance_address = header.min_insn_length
michael@0 721 * ((255 - header.opcode_base)
michael@0 722 / header.line_range);
michael@0 723
michael@0 724 // Check if the lsm passes "pc". If so, mark it as passed.
michael@0 725 if (lsm_passes_pc &&
michael@0 726 lsm->address <= pc && pc < lsm->address + advance_address) {
michael@0 727 *lsm_passes_pc = true;
michael@0 728 }
michael@0 729
michael@0 730 lsm->address += advance_address;
michael@0 731 }
michael@0 732 break;
michael@0 733 case DW_LNS_extended_op: {
michael@0 734 const uint64 extended_op_len = reader->ReadUnsignedLEB128(start,
michael@0 735 &templen);
michael@0 736 start += templen;
michael@0 737 oplen += templen + extended_op_len;
michael@0 738
michael@0 739 const uint64 extended_op = reader->ReadOneByte(start);
michael@0 740 start++;
michael@0 741
michael@0 742 switch (extended_op) {
michael@0 743 case DW_LNE_end_sequence: {
michael@0 744 lsm->end_sequence = true;
michael@0 745 *len = oplen;
michael@0 746 return true;
michael@0 747 }
michael@0 748 break;
michael@0 749 case DW_LNE_set_address: {
michael@0 750 // With gcc 4.2.1, we cannot tell the line_no here since
michael@0 751 // DW_LNE_set_address is called before DW_LNS_advance_line is
michael@0 752 // called. So we do not check if the lsm passes "pc" here. See
michael@0 753 // also the comment in DW_LNS_advance_line.
michael@0 754 uint64 address = reader->ReadAddress(start);
michael@0 755 lsm->address = address;
michael@0 756 }
michael@0 757 break;
michael@0 758 case DW_LNE_define_file: {
michael@0 759 const char* filename = start;
michael@0 760
michael@0 761 templen = strlen(filename) + 1;
michael@0 762 start += templen;
michael@0 763
michael@0 764 uint64 dirindex = reader->ReadUnsignedLEB128(start, &templen);
michael@0 765 oplen += templen;
michael@0 766
michael@0 767 const uint64 mod_time = reader->ReadUnsignedLEB128(start,
michael@0 768 &templen);
michael@0 769 oplen += templen;
michael@0 770
michael@0 771 const uint64 filelength = reader->ReadUnsignedLEB128(start,
michael@0 772 &templen);
michael@0 773 oplen += templen;
michael@0 774
michael@0 775 if (handler) {
michael@0 776 handler->DefineFile(filename, -1, static_cast<uint32>(dirindex),
michael@0 777 mod_time, filelength);
michael@0 778 }
michael@0 779 }
michael@0 780 break;
michael@0 781 }
michael@0 782 }
michael@0 783 break;
michael@0 784
michael@0 785 default: {
michael@0 786 // Ignore unknown opcode silently
michael@0 787 if (header.std_opcode_lengths) {
michael@0 788 for (int i = 0; i < (*header.std_opcode_lengths)[opcode]; i++) {
michael@0 789 reader->ReadUnsignedLEB128(start, &templen);
michael@0 790 start += templen;
michael@0 791 oplen += templen;
michael@0 792 }
michael@0 793 }
michael@0 794 }
michael@0 795 break;
michael@0 796 }
michael@0 797 *len = oplen;
michael@0 798 return false;
michael@0 799 }
michael@0 800
michael@0 801 void LineInfo::ReadLines() {
michael@0 802 struct LineStateMachine lsm;
michael@0 803
michael@0 804 // lengthstart is the place the length field is based on.
michael@0 805 // It is the point in the header after the initial length field
michael@0 806 const char* lengthstart = buffer_;
michael@0 807
michael@0 808 // In 64 bit dwarf, the initial length is 12 bytes, because of the
michael@0 809 // 0xffffffff at the start.
michael@0 810 if (reader_->OffsetSize() == 8)
michael@0 811 lengthstart += 12;
michael@0 812 else
michael@0 813 lengthstart += 4;
michael@0 814
michael@0 815 const char* lineptr = after_header_;
michael@0 816 lsm.Reset(header_.default_is_stmt);
michael@0 817
michael@0 818 // The LineInfoHandler interface expects each line's length along
michael@0 819 // with its address, but DWARF only provides addresses (sans
michael@0 820 // length), and an end-of-sequence address; one infers the length
michael@0 821 // from the next address. So we report a line only when we get the
michael@0 822 // next line's address, or the end-of-sequence address.
michael@0 823 bool have_pending_line = false;
michael@0 824 uint64 pending_address = 0;
michael@0 825 uint32 pending_file_num = 0, pending_line_num = 0, pending_column_num = 0;
michael@0 826
michael@0 827 while (lineptr < lengthstart + header_.total_length) {
michael@0 828 size_t oplength;
michael@0 829 bool add_row = ProcessOneOpcode(reader_, handler_, header_,
michael@0 830 lineptr, &lsm, &oplength, (uintptr)-1,
michael@0 831 NULL);
michael@0 832 if (add_row) {
michael@0 833 if (have_pending_line)
michael@0 834 handler_->AddLine(pending_address, lsm.address - pending_address,
michael@0 835 pending_file_num, pending_line_num,
michael@0 836 pending_column_num);
michael@0 837 if (lsm.end_sequence) {
michael@0 838 lsm.Reset(header_.default_is_stmt);
michael@0 839 have_pending_line = false;
michael@0 840 } else {
michael@0 841 pending_address = lsm.address;
michael@0 842 pending_file_num = lsm.file_num;
michael@0 843 pending_line_num = lsm.line_num;
michael@0 844 pending_column_num = lsm.column_num;
michael@0 845 have_pending_line = true;
michael@0 846 }
michael@0 847 }
michael@0 848 lineptr += oplength;
michael@0 849 }
michael@0 850
michael@0 851 after_header_ = lengthstart + header_.total_length;
michael@0 852 }
michael@0 853
michael@0 854 // A DWARF rule for recovering the address or value of a register, or
michael@0 855 // computing the canonical frame address. There is one subclass of this for
michael@0 856 // each '*Rule' member function in CallFrameInfo::Handler.
michael@0 857 //
michael@0 858 // It's annoying that we have to handle Rules using pointers (because
michael@0 859 // the concrete instances can have an arbitrary size). They're small,
michael@0 860 // so it would be much nicer if we could just handle them by value
michael@0 861 // instead of fretting about ownership and destruction.
michael@0 862 //
michael@0 863 // It seems like all these could simply be instances of std::tr1::bind,
michael@0 864 // except that we need instances to be EqualityComparable, too.
michael@0 865 //
michael@0 866 // This could logically be nested within State, but then the qualified names
michael@0 867 // get horrendous.
michael@0 868 class CallFrameInfo::Rule {
michael@0 869 public:
michael@0 870 virtual ~Rule() { }
michael@0 871
michael@0 872 // Tell HANDLER that, at ADDRESS in the program, REGISTER can be
michael@0 873 // recovered using this rule. If REGISTER is kCFARegister, then this rule
michael@0 874 // describes how to compute the canonical frame address. Return what the
michael@0 875 // HANDLER member function returned.
michael@0 876 virtual bool Handle(Handler *handler,
michael@0 877 uint64 address, int register) const = 0;
michael@0 878
michael@0 879 // Equality on rules. We use these to decide which rules we need
michael@0 880 // to report after a DW_CFA_restore_state instruction.
michael@0 881 virtual bool operator==(const Rule &rhs) const = 0;
michael@0 882
michael@0 883 bool operator!=(const Rule &rhs) const { return ! (*this == rhs); }
michael@0 884
michael@0 885 // Return a pointer to a copy of this rule.
michael@0 886 virtual Rule *Copy() const = 0;
michael@0 887
michael@0 888 // If this is a base+offset rule, change its base register to REG.
michael@0 889 // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.)
michael@0 890 virtual void SetBaseRegister(unsigned reg) { }
michael@0 891
michael@0 892 // If this is a base+offset rule, change its offset to OFFSET. Otherwise,
michael@0 893 // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.)
michael@0 894 virtual void SetOffset(long long offset) { }
michael@0 895
michael@0 896 // A RTTI workaround, to make it possible to implement equality
michael@0 897 // comparisons on classes derived from this one.
michael@0 898 enum CFIRTag {
michael@0 899 CFIR_UNDEFINED_RULE,
michael@0 900 CFIR_SAME_VALUE_RULE,
michael@0 901 CFIR_OFFSET_RULE,
michael@0 902 CFIR_VAL_OFFSET_RULE,
michael@0 903 CFIR_REGISTER_RULE,
michael@0 904 CFIR_EXPRESSION_RULE,
michael@0 905 CFIR_VAL_EXPRESSION_RULE
michael@0 906 };
michael@0 907
michael@0 908 // Produce the tag that identifies the child class of this object.
michael@0 909 virtual CFIRTag getTag() const = 0;
michael@0 910 };
michael@0 911
michael@0 912 // Rule: the value the register had in the caller cannot be recovered.
michael@0 913 class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
michael@0 914 public:
michael@0 915 UndefinedRule() { }
michael@0 916 ~UndefinedRule() { }
michael@0 917 CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; }
michael@0 918 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 919 return handler->UndefinedRule(address, reg);
michael@0 920 }
michael@0 921 bool operator==(const Rule &rhs) const {
michael@0 922 if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false;
michael@0 923 return true;
michael@0 924 }
michael@0 925 Rule *Copy() const { return new UndefinedRule(*this); }
michael@0 926 };
michael@0 927
michael@0 928 // Rule: the register's value is the same as that it had in the caller.
michael@0 929 class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
michael@0 930 public:
michael@0 931 SameValueRule() { }
michael@0 932 ~SameValueRule() { }
michael@0 933 CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; }
michael@0 934 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 935 return handler->SameValueRule(address, reg);
michael@0 936 }
michael@0 937 bool operator==(const Rule &rhs) const {
michael@0 938 if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false;
michael@0 939 return true;
michael@0 940 }
michael@0 941 Rule *Copy() const { return new SameValueRule(*this); }
michael@0 942 };
michael@0 943
michael@0 944 // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER
michael@0 945 // may be CallFrameInfo::Handler::kCFARegister.
michael@0 946 class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
michael@0 947 public:
michael@0 948 OffsetRule(int base_register, long offset)
michael@0 949 : base_register_(base_register), offset_(offset) { }
michael@0 950 ~OffsetRule() { }
michael@0 951 CFIRTag getTag() const { return CFIR_OFFSET_RULE; }
michael@0 952 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 953 return handler->OffsetRule(address, reg, base_register_, offset_);
michael@0 954 }
michael@0 955 bool operator==(const Rule &rhs) const {
michael@0 956 if (rhs.getTag() != CFIR_OFFSET_RULE) return false;
michael@0 957 const OffsetRule *our_rhs = static_cast<const OffsetRule *>(&rhs);
michael@0 958 return (base_register_ == our_rhs->base_register_ &&
michael@0 959 offset_ == our_rhs->offset_);
michael@0 960 }
michael@0 961 Rule *Copy() const { return new OffsetRule(*this); }
michael@0 962 // We don't actually need SetBaseRegister or SetOffset here, since they
michael@0 963 // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it
michael@0 964 // doesn't make sense to use OffsetRule for computing the CFA: it
michael@0 965 // computes the address at which a register is saved, not a value.
michael@0 966 private:
michael@0 967 int base_register_;
michael@0 968 long offset_;
michael@0 969 };
michael@0 970
michael@0 971 // Rule: the value the register had in the caller is the value of
michael@0 972 // BASE_REGISTER plus offset. BASE_REGISTER may be
michael@0 973 // CallFrameInfo::Handler::kCFARegister.
michael@0 974 class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
michael@0 975 public:
michael@0 976 ValOffsetRule(int base_register, long offset)
michael@0 977 : base_register_(base_register), offset_(offset) { }
michael@0 978 ~ValOffsetRule() { }
michael@0 979 CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; }
michael@0 980 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 981 return handler->ValOffsetRule(address, reg, base_register_, offset_);
michael@0 982 }
michael@0 983 bool operator==(const Rule &rhs) const {
michael@0 984 if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false;
michael@0 985 const ValOffsetRule *our_rhs = static_cast<const ValOffsetRule *>(&rhs);
michael@0 986 return (base_register_ == our_rhs->base_register_ &&
michael@0 987 offset_ == our_rhs->offset_);
michael@0 988 }
michael@0 989 Rule *Copy() const { return new ValOffsetRule(*this); }
michael@0 990 void SetBaseRegister(unsigned reg) { base_register_ = reg; }
michael@0 991 void SetOffset(long long offset) { offset_ = offset; }
michael@0 992 private:
michael@0 993 int base_register_;
michael@0 994 long offset_;
michael@0 995 };
michael@0 996
michael@0 997 // Rule: the register has been saved in another register REGISTER_NUMBER_.
michael@0 998 class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
michael@0 999 public:
michael@0 1000 explicit RegisterRule(int register_number)
michael@0 1001 : register_number_(register_number) { }
michael@0 1002 ~RegisterRule() { }
michael@0 1003 CFIRTag getTag() const { return CFIR_REGISTER_RULE; }
michael@0 1004 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 1005 return handler->RegisterRule(address, reg, register_number_);
michael@0 1006 }
michael@0 1007 bool operator==(const Rule &rhs) const {
michael@0 1008 if (rhs.getTag() != CFIR_REGISTER_RULE) return false;
michael@0 1009 const RegisterRule *our_rhs = static_cast<const RegisterRule *>(&rhs);
michael@0 1010 return (register_number_ == our_rhs->register_number_);
michael@0 1011 }
michael@0 1012 Rule *Copy() const { return new RegisterRule(*this); }
michael@0 1013 private:
michael@0 1014 int register_number_;
michael@0 1015 };
michael@0 1016
michael@0 1017 // Rule: EXPRESSION evaluates to the address at which the register is saved.
michael@0 1018 class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
michael@0 1019 public:
michael@0 1020 explicit ExpressionRule(const string &expression)
michael@0 1021 : expression_(expression) { }
michael@0 1022 ~ExpressionRule() { }
michael@0 1023 CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; }
michael@0 1024 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 1025 return handler->ExpressionRule(address, reg, expression_);
michael@0 1026 }
michael@0 1027 bool operator==(const Rule &rhs) const {
michael@0 1028 if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false;
michael@0 1029 const ExpressionRule *our_rhs = static_cast<const ExpressionRule *>(&rhs);
michael@0 1030 return (expression_ == our_rhs->expression_);
michael@0 1031 }
michael@0 1032 Rule *Copy() const { return new ExpressionRule(*this); }
michael@0 1033 private:
michael@0 1034 string expression_;
michael@0 1035 };
michael@0 1036
michael@0 1037 // Rule: EXPRESSION evaluates to the address at which the register is saved.
michael@0 1038 class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
michael@0 1039 public:
michael@0 1040 explicit ValExpressionRule(const string &expression)
michael@0 1041 : expression_(expression) { }
michael@0 1042 ~ValExpressionRule() { }
michael@0 1043 CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; }
michael@0 1044 bool Handle(Handler *handler, uint64 address, int reg) const {
michael@0 1045 return handler->ValExpressionRule(address, reg, expression_);
michael@0 1046 }
michael@0 1047 bool operator==(const Rule &rhs) const {
michael@0 1048 if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false;
michael@0 1049 const ValExpressionRule *our_rhs =
michael@0 1050 static_cast<const ValExpressionRule *>(&rhs);
michael@0 1051 return (expression_ == our_rhs->expression_);
michael@0 1052 }
michael@0 1053 Rule *Copy() const { return new ValExpressionRule(*this); }
michael@0 1054 private:
michael@0 1055 string expression_;
michael@0 1056 };
michael@0 1057
michael@0 1058 // A map from register numbers to rules.
michael@0 1059 class CallFrameInfo::RuleMap {
michael@0 1060 public:
michael@0 1061 RuleMap() : cfa_rule_(NULL) { }
michael@0 1062 RuleMap(const RuleMap &rhs) : cfa_rule_(NULL) { *this = rhs; }
michael@0 1063 ~RuleMap() { Clear(); }
michael@0 1064
michael@0 1065 RuleMap &operator=(const RuleMap &rhs);
michael@0 1066
michael@0 1067 // Set the rule for computing the CFA to RULE. Take ownership of RULE.
michael@0 1068 void SetCFARule(Rule *rule) { delete cfa_rule_; cfa_rule_ = rule; }
michael@0 1069
michael@0 1070 // Return the current CFA rule. Unlike RegisterRule, this RuleMap retains
michael@0 1071 // ownership of the rule. We use this for DW_CFA_def_cfa_offset and
michael@0 1072 // DW_CFA_def_cfa_register, and for detecting references to the CFA before
michael@0 1073 // a rule for it has been established.
michael@0 1074 Rule *CFARule() const { return cfa_rule_; }
michael@0 1075
michael@0 1076 // Return the rule for REG, or NULL if there is none. The caller takes
michael@0 1077 // ownership of the result.
michael@0 1078 Rule *RegisterRule(int reg) const;
michael@0 1079
michael@0 1080 // Set the rule for computing REG to RULE. Take ownership of RULE.
michael@0 1081 void SetRegisterRule(int reg, Rule *rule);
michael@0 1082
michael@0 1083 // Make all the appropriate calls to HANDLER as if we were changing from
michael@0 1084 // this RuleMap to NEW_RULES at ADDRESS. We use this to implement
michael@0 1085 // DW_CFA_restore_state, where lots of rules can change simultaneously.
michael@0 1086 // Return true if all handlers returned true; otherwise, return false.
michael@0 1087 bool HandleTransitionTo(Handler *handler, uint64 address,
michael@0 1088 const RuleMap &new_rules) const;
michael@0 1089
michael@0 1090 private:
michael@0 1091 // A map from register numbers to Rules.
michael@0 1092 typedef std::map<int, Rule *> RuleByNumber;
michael@0 1093
michael@0 1094 // Remove all register rules and clear cfa_rule_.
michael@0 1095 void Clear();
michael@0 1096
michael@0 1097 // The rule for computing the canonical frame address. This RuleMap owns
michael@0 1098 // this rule.
michael@0 1099 Rule *cfa_rule_;
michael@0 1100
michael@0 1101 // A map from register numbers to postfix expressions to recover
michael@0 1102 // their values. This RuleMap owns the Rules the map refers to.
michael@0 1103 RuleByNumber registers_;
michael@0 1104 };
michael@0 1105
michael@0 1106 CallFrameInfo::RuleMap &CallFrameInfo::RuleMap::operator=(const RuleMap &rhs) {
michael@0 1107 Clear();
michael@0 1108 // Since each map owns the rules it refers to, assignment must copy them.
michael@0 1109 if (rhs.cfa_rule_) cfa_rule_ = rhs.cfa_rule_->Copy();
michael@0 1110 for (RuleByNumber::const_iterator it = rhs.registers_.begin();
michael@0 1111 it != rhs.registers_.end(); it++)
michael@0 1112 registers_[it->first] = it->second->Copy();
michael@0 1113 return *this;
michael@0 1114 }
michael@0 1115
michael@0 1116 CallFrameInfo::Rule *CallFrameInfo::RuleMap::RegisterRule(int reg) const {
michael@0 1117 assert(reg != Handler::kCFARegister);
michael@0 1118 RuleByNumber::const_iterator it = registers_.find(reg);
michael@0 1119 if (it != registers_.end())
michael@0 1120 return it->second->Copy();
michael@0 1121 else
michael@0 1122 return NULL;
michael@0 1123 }
michael@0 1124
michael@0 1125 void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule *rule) {
michael@0 1126 assert(reg != Handler::kCFARegister);
michael@0 1127 assert(rule);
michael@0 1128 Rule **slot = &registers_[reg];
michael@0 1129 delete *slot;
michael@0 1130 *slot = rule;
michael@0 1131 }
michael@0 1132
michael@0 1133 bool CallFrameInfo::RuleMap::HandleTransitionTo(
michael@0 1134 Handler *handler,
michael@0 1135 uint64 address,
michael@0 1136 const RuleMap &new_rules) const {
michael@0 1137 // Transition from cfa_rule_ to new_rules.cfa_rule_.
michael@0 1138 if (cfa_rule_ && new_rules.cfa_rule_) {
michael@0 1139 if (*cfa_rule_ != *new_rules.cfa_rule_ &&
michael@0 1140 !new_rules.cfa_rule_->Handle(handler, address,
michael@0 1141 Handler::kCFARegister))
michael@0 1142 return false;
michael@0 1143 } else if (cfa_rule_) {
michael@0 1144 // this RuleMap has a CFA rule but new_rules doesn't.
michael@0 1145 // CallFrameInfo::Handler has no way to handle this --- and shouldn't;
michael@0 1146 // it's garbage input. The instruction interpreter should have
michael@0 1147 // detected this and warned, so take no action here.
michael@0 1148 } else if (new_rules.cfa_rule_) {
michael@0 1149 // This shouldn't be possible: NEW_RULES is some prior state, and
michael@0 1150 // there's no way to remove entries.
michael@0 1151 assert(0);
michael@0 1152 } else {
michael@0 1153 // Both CFA rules are empty. No action needed.
michael@0 1154 }
michael@0 1155
michael@0 1156 // Traverse the two maps in order by register number, and report
michael@0 1157 // whatever differences we find.
michael@0 1158 RuleByNumber::const_iterator old_it = registers_.begin();
michael@0 1159 RuleByNumber::const_iterator new_it = new_rules.registers_.begin();
michael@0 1160 while (old_it != registers_.end() && new_it != new_rules.registers_.end()) {
michael@0 1161 if (old_it->first < new_it->first) {
michael@0 1162 // This RuleMap has an entry for old_it->first, but NEW_RULES
michael@0 1163 // doesn't.
michael@0 1164 //
michael@0 1165 // This isn't really the right thing to do, but since CFI generally
michael@0 1166 // only mentions callee-saves registers, and GCC's convention for
michael@0 1167 // callee-saves registers is that they are unchanged, it's a good
michael@0 1168 // approximation.
michael@0 1169 if (!handler->SameValueRule(address, old_it->first))
michael@0 1170 return false;
michael@0 1171 old_it++;
michael@0 1172 } else if (old_it->first > new_it->first) {
michael@0 1173 // NEW_RULES has entry for new_it->first, but this RuleMap
michael@0 1174 // doesn't. This shouldn't be possible: NEW_RULES is some prior
michael@0 1175 // state, and there's no way to remove entries.
michael@0 1176 assert(0);
michael@0 1177 } else {
michael@0 1178 // Both maps have an entry for this register. Report the new
michael@0 1179 // rule if it is different.
michael@0 1180 if (*old_it->second != *new_it->second &&
michael@0 1181 !new_it->second->Handle(handler, address, new_it->first))
michael@0 1182 return false;
michael@0 1183 new_it++, old_it++;
michael@0 1184 }
michael@0 1185 }
michael@0 1186 // Finish off entries from this RuleMap with no counterparts in new_rules.
michael@0 1187 while (old_it != registers_.end()) {
michael@0 1188 if (!handler->SameValueRule(address, old_it->first))
michael@0 1189 return false;
michael@0 1190 old_it++;
michael@0 1191 }
michael@0 1192 // Since we only make transitions from a rule set to some previously
michael@0 1193 // saved rule set, and we can only add rules to the map, NEW_RULES
michael@0 1194 // must have fewer rules than *this.
michael@0 1195 assert(new_it == new_rules.registers_.end());
michael@0 1196
michael@0 1197 return true;
michael@0 1198 }
michael@0 1199
michael@0 1200 // Remove all register rules and clear cfa_rule_.
michael@0 1201 void CallFrameInfo::RuleMap::Clear() {
michael@0 1202 delete cfa_rule_;
michael@0 1203 cfa_rule_ = NULL;
michael@0 1204 for (RuleByNumber::iterator it = registers_.begin();
michael@0 1205 it != registers_.end(); it++)
michael@0 1206 delete it->second;
michael@0 1207 registers_.clear();
michael@0 1208 }
michael@0 1209
michael@0 1210 // The state of the call frame information interpreter as it processes
michael@0 1211 // instructions from a CIE and FDE.
michael@0 1212 class CallFrameInfo::State {
michael@0 1213 public:
michael@0 1214 // Create a call frame information interpreter state with the given
michael@0 1215 // reporter, reader, handler, and initial call frame info address.
michael@0 1216 State(ByteReader *reader, Handler *handler, Reporter *reporter,
michael@0 1217 uint64 address)
michael@0 1218 : reader_(reader), handler_(handler), reporter_(reporter),
michael@0 1219 address_(address), entry_(NULL), cursor_(NULL) { }
michael@0 1220
michael@0 1221 // Interpret instructions from CIE, save the resulting rule set for
michael@0 1222 // DW_CFA_restore instructions, and return true. On error, report
michael@0 1223 // the problem to reporter_ and return false.
michael@0 1224 bool InterpretCIE(const CIE &cie);
michael@0 1225
michael@0 1226 // Interpret instructions from FDE, and return true. On error,
michael@0 1227 // report the problem to reporter_ and return false.
michael@0 1228 bool InterpretFDE(const FDE &fde);
michael@0 1229
michael@0 1230 private:
michael@0 1231 // The operands of a CFI instruction, for ParseOperands.
michael@0 1232 struct Operands {
michael@0 1233 unsigned register_number; // A register number.
michael@0 1234 uint64 offset; // An offset or address.
michael@0 1235 long signed_offset; // A signed offset.
michael@0 1236 string expression; // A DWARF expression.
michael@0 1237 };
michael@0 1238
michael@0 1239 // Parse CFI instruction operands from STATE's instruction stream as
michael@0 1240 // described by FORMAT. On success, populate OPERANDS with the
michael@0 1241 // results, and return true. On failure, report the problem and
michael@0 1242 // return false.
michael@0 1243 //
michael@0 1244 // Each character of FORMAT should be one of the following:
michael@0 1245 //
michael@0 1246 // 'r' unsigned LEB128 register number (OPERANDS->register_number)
michael@0 1247 // 'o' unsigned LEB128 offset (OPERANDS->offset)
michael@0 1248 // 's' signed LEB128 offset (OPERANDS->signed_offset)
michael@0 1249 // 'a' machine-size address (OPERANDS->offset)
michael@0 1250 // (If the CIE has a 'z' augmentation string, 'a' uses the
michael@0 1251 // encoding specified by the 'R' argument.)
michael@0 1252 // '1' a one-byte offset (OPERANDS->offset)
michael@0 1253 // '2' a two-byte offset (OPERANDS->offset)
michael@0 1254 // '4' a four-byte offset (OPERANDS->offset)
michael@0 1255 // '8' an eight-byte offset (OPERANDS->offset)
michael@0 1256 // 'e' a DW_FORM_block holding a (OPERANDS->expression)
michael@0 1257 // DWARF expression
michael@0 1258 bool ParseOperands(const char *format, Operands *operands);
michael@0 1259
michael@0 1260 // Interpret one CFI instruction from STATE's instruction stream, update
michael@0 1261 // STATE, report any rule changes to handler_, and return true. On
michael@0 1262 // failure, report the problem and return false.
michael@0 1263 bool DoInstruction();
michael@0 1264
michael@0 1265 // The following Do* member functions are subroutines of DoInstruction,
michael@0 1266 // factoring out the actual work of operations that have several
michael@0 1267 // different encodings.
michael@0 1268
michael@0 1269 // Set the CFA rule to be the value of BASE_REGISTER plus OFFSET, and
michael@0 1270 // return true. On failure, report and return false. (Used for
michael@0 1271 // DW_CFA_def_cfa and DW_CFA_def_cfa_sf.)
michael@0 1272 bool DoDefCFA(unsigned base_register, long offset);
michael@0 1273
michael@0 1274 // Change the offset of the CFA rule to OFFSET, and return true. On
michael@0 1275 // failure, report and return false. (Subroutine for
michael@0 1276 // DW_CFA_def_cfa_offset and DW_CFA_def_cfa_offset_sf.)
michael@0 1277 bool DoDefCFAOffset(long offset);
michael@0 1278
michael@0 1279 // Specify that REG can be recovered using RULE, and return true. On
michael@0 1280 // failure, report and return false.
michael@0 1281 bool DoRule(unsigned reg, Rule *rule);
michael@0 1282
michael@0 1283 // Specify that REG can be found at OFFSET from the CFA, and return true.
michael@0 1284 // On failure, report and return false. (Subroutine for DW_CFA_offset,
michael@0 1285 // DW_CFA_offset_extended, and DW_CFA_offset_extended_sf.)
michael@0 1286 bool DoOffset(unsigned reg, long offset);
michael@0 1287
michael@0 1288 // Specify that the caller's value for REG is the CFA plus OFFSET,
michael@0 1289 // and return true. On failure, report and return false. (Subroutine
michael@0 1290 // for DW_CFA_val_offset and DW_CFA_val_offset_sf.)
michael@0 1291 bool DoValOffset(unsigned reg, long offset);
michael@0 1292
michael@0 1293 // Restore REG to the rule established in the CIE, and return true. On
michael@0 1294 // failure, report and return false. (Subroutine for DW_CFA_restore and
michael@0 1295 // DW_CFA_restore_extended.)
michael@0 1296 bool DoRestore(unsigned reg);
michael@0 1297
michael@0 1298 // Return the section offset of the instruction at cursor. For use
michael@0 1299 // in error messages.
michael@0 1300 uint64 CursorOffset() { return entry_->offset + (cursor_ - entry_->start); }
michael@0 1301
michael@0 1302 // Report that entry_ is incomplete, and return false. For brevity.
michael@0 1303 bool ReportIncomplete() {
michael@0 1304 reporter_->Incomplete(entry_->offset, entry_->kind);
michael@0 1305 return false;
michael@0 1306 }
michael@0 1307
michael@0 1308 // For reading multi-byte values with the appropriate endianness.
michael@0 1309 ByteReader *reader_;
michael@0 1310
michael@0 1311 // The handler to which we should report the data we find.
michael@0 1312 Handler *handler_;
michael@0 1313
michael@0 1314 // For reporting problems in the info we're parsing.
michael@0 1315 Reporter *reporter_;
michael@0 1316
michael@0 1317 // The code address to which the next instruction in the stream applies.
michael@0 1318 uint64 address_;
michael@0 1319
michael@0 1320 // The entry whose instructions we are currently processing. This is
michael@0 1321 // first a CIE, and then an FDE.
michael@0 1322 const Entry *entry_;
michael@0 1323
michael@0 1324 // The next instruction to process.
michael@0 1325 const char *cursor_;
michael@0 1326
michael@0 1327 // The current set of rules.
michael@0 1328 RuleMap rules_;
michael@0 1329
michael@0 1330 // The set of rules established by the CIE, used by DW_CFA_restore
michael@0 1331 // and DW_CFA_restore_extended. We set this after interpreting the
michael@0 1332 // CIE's instructions.
michael@0 1333 RuleMap cie_rules_;
michael@0 1334
michael@0 1335 // A stack of saved states, for DW_CFA_remember_state and
michael@0 1336 // DW_CFA_restore_state.
michael@0 1337 std::stack<RuleMap> saved_rules_;
michael@0 1338 };
michael@0 1339
michael@0 1340 bool CallFrameInfo::State::InterpretCIE(const CIE &cie) {
michael@0 1341 entry_ = &cie;
michael@0 1342 cursor_ = entry_->instructions;
michael@0 1343 while (cursor_ < entry_->end)
michael@0 1344 if (!DoInstruction())
michael@0 1345 return false;
michael@0 1346 // Note the rules established by the CIE, for use by DW_CFA_restore
michael@0 1347 // and DW_CFA_restore_extended.
michael@0 1348 cie_rules_ = rules_;
michael@0 1349 return true;
michael@0 1350 }
michael@0 1351
michael@0 1352 bool CallFrameInfo::State::InterpretFDE(const FDE &fde) {
michael@0 1353 entry_ = &fde;
michael@0 1354 cursor_ = entry_->instructions;
michael@0 1355 while (cursor_ < entry_->end)
michael@0 1356 if (!DoInstruction())
michael@0 1357 return false;
michael@0 1358 return true;
michael@0 1359 }
michael@0 1360
michael@0 1361 bool CallFrameInfo::State::ParseOperands(const char *format,
michael@0 1362 Operands *operands) {
michael@0 1363 size_t len;
michael@0 1364 const char *operand;
michael@0 1365
michael@0 1366 for (operand = format; *operand; operand++) {
michael@0 1367 size_t bytes_left = entry_->end - cursor_;
michael@0 1368 switch (*operand) {
michael@0 1369 case 'r':
michael@0 1370 operands->register_number = reader_->ReadUnsignedLEB128(cursor_, &len);
michael@0 1371 if (len > bytes_left) return ReportIncomplete();
michael@0 1372 cursor_ += len;
michael@0 1373 break;
michael@0 1374
michael@0 1375 case 'o':
michael@0 1376 operands->offset = reader_->ReadUnsignedLEB128(cursor_, &len);
michael@0 1377 if (len > bytes_left) return ReportIncomplete();
michael@0 1378 cursor_ += len;
michael@0 1379 break;
michael@0 1380
michael@0 1381 case 's':
michael@0 1382 operands->signed_offset = reader_->ReadSignedLEB128(cursor_, &len);
michael@0 1383 if (len > bytes_left) return ReportIncomplete();
michael@0 1384 cursor_ += len;
michael@0 1385 break;
michael@0 1386
michael@0 1387 case 'a':
michael@0 1388 operands->offset =
michael@0 1389 reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding,
michael@0 1390 &len);
michael@0 1391 if (len > bytes_left) return ReportIncomplete();
michael@0 1392 cursor_ += len;
michael@0 1393 break;
michael@0 1394
michael@0 1395 case '1':
michael@0 1396 if (1 > bytes_left) return ReportIncomplete();
michael@0 1397 operands->offset = static_cast<unsigned char>(*cursor_++);
michael@0 1398 break;
michael@0 1399
michael@0 1400 case '2':
michael@0 1401 if (2 > bytes_left) return ReportIncomplete();
michael@0 1402 operands->offset = reader_->ReadTwoBytes(cursor_);
michael@0 1403 cursor_ += 2;
michael@0 1404 break;
michael@0 1405
michael@0 1406 case '4':
michael@0 1407 if (4 > bytes_left) return ReportIncomplete();
michael@0 1408 operands->offset = reader_->ReadFourBytes(cursor_);
michael@0 1409 cursor_ += 4;
michael@0 1410 break;
michael@0 1411
michael@0 1412 case '8':
michael@0 1413 if (8 > bytes_left) return ReportIncomplete();
michael@0 1414 operands->offset = reader_->ReadEightBytes(cursor_);
michael@0 1415 cursor_ += 8;
michael@0 1416 break;
michael@0 1417
michael@0 1418 case 'e': {
michael@0 1419 size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len);
michael@0 1420 if (len > bytes_left || expression_length > bytes_left - len)
michael@0 1421 return ReportIncomplete();
michael@0 1422 cursor_ += len;
michael@0 1423 operands->expression = string(cursor_, expression_length);
michael@0 1424 cursor_ += expression_length;
michael@0 1425 break;
michael@0 1426 }
michael@0 1427
michael@0 1428 default:
michael@0 1429 assert(0);
michael@0 1430 }
michael@0 1431 }
michael@0 1432
michael@0 1433 return true;
michael@0 1434 }
michael@0 1435
michael@0 1436 bool CallFrameInfo::State::DoInstruction() {
michael@0 1437 CIE *cie = entry_->cie;
michael@0 1438 Operands ops;
michael@0 1439
michael@0 1440 // Our entry's kind should have been set by now.
michael@0 1441 assert(entry_->kind != kUnknown);
michael@0 1442
michael@0 1443 // We shouldn't have been invoked unless there were more
michael@0 1444 // instructions to parse.
michael@0 1445 assert(cursor_ < entry_->end);
michael@0 1446
michael@0 1447 unsigned opcode = *cursor_++;
michael@0 1448 if ((opcode & 0xc0) != 0) {
michael@0 1449 switch (opcode & 0xc0) {
michael@0 1450 // Advance the address.
michael@0 1451 case DW_CFA_advance_loc: {
michael@0 1452 size_t code_offset = opcode & 0x3f;
michael@0 1453 address_ += code_offset * cie->code_alignment_factor;
michael@0 1454 break;
michael@0 1455 }
michael@0 1456
michael@0 1457 // Find a register at an offset from the CFA.
michael@0 1458 case DW_CFA_offset:
michael@0 1459 if (!ParseOperands("o", &ops) ||
michael@0 1460 !DoOffset(opcode & 0x3f, ops.offset * cie->data_alignment_factor))
michael@0 1461 return false;
michael@0 1462 break;
michael@0 1463
michael@0 1464 // Restore the rule established for a register by the CIE.
michael@0 1465 case DW_CFA_restore:
michael@0 1466 if (!DoRestore(opcode & 0x3f)) return false;
michael@0 1467 break;
michael@0 1468
michael@0 1469 // The 'if' above should have excluded this possibility.
michael@0 1470 default:
michael@0 1471 assert(0);
michael@0 1472 }
michael@0 1473
michael@0 1474 // Return here, so the big switch below won't be indented.
michael@0 1475 return true;
michael@0 1476 }
michael@0 1477
michael@0 1478 switch (opcode) {
michael@0 1479 // Set the address.
michael@0 1480 case DW_CFA_set_loc:
michael@0 1481 if (!ParseOperands("a", &ops)) return false;
michael@0 1482 address_ = ops.offset;
michael@0 1483 break;
michael@0 1484
michael@0 1485 // Advance the address.
michael@0 1486 case DW_CFA_advance_loc1:
michael@0 1487 if (!ParseOperands("1", &ops)) return false;
michael@0 1488 address_ += ops.offset * cie->code_alignment_factor;
michael@0 1489 break;
michael@0 1490
michael@0 1491 // Advance the address.
michael@0 1492 case DW_CFA_advance_loc2:
michael@0 1493 if (!ParseOperands("2", &ops)) return false;
michael@0 1494 address_ += ops.offset * cie->code_alignment_factor;
michael@0 1495 break;
michael@0 1496
michael@0 1497 // Advance the address.
michael@0 1498 case DW_CFA_advance_loc4:
michael@0 1499 if (!ParseOperands("4", &ops)) return false;
michael@0 1500 address_ += ops.offset * cie->code_alignment_factor;
michael@0 1501 break;
michael@0 1502
michael@0 1503 // Advance the address.
michael@0 1504 case DW_CFA_MIPS_advance_loc8:
michael@0 1505 if (!ParseOperands("8", &ops)) return false;
michael@0 1506 address_ += ops.offset * cie->code_alignment_factor;
michael@0 1507 break;
michael@0 1508
michael@0 1509 // Compute the CFA by adding an offset to a register.
michael@0 1510 case DW_CFA_def_cfa:
michael@0 1511 if (!ParseOperands("ro", &ops) ||
michael@0 1512 !DoDefCFA(ops.register_number, ops.offset))
michael@0 1513 return false;
michael@0 1514 break;
michael@0 1515
michael@0 1516 // Compute the CFA by adding an offset to a register.
michael@0 1517 case DW_CFA_def_cfa_sf:
michael@0 1518 if (!ParseOperands("rs", &ops) ||
michael@0 1519 !DoDefCFA(ops.register_number,
michael@0 1520 ops.signed_offset * cie->data_alignment_factor))
michael@0 1521 return false;
michael@0 1522 break;
michael@0 1523
michael@0 1524 // Change the base register used to compute the CFA.
michael@0 1525 case DW_CFA_def_cfa_register: {
michael@0 1526 Rule *cfa_rule = rules_.CFARule();
michael@0 1527 if (!cfa_rule) {
michael@0 1528 reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
michael@0 1529 return false;
michael@0 1530 }
michael@0 1531 if (!ParseOperands("r", &ops)) return false;
michael@0 1532 cfa_rule->SetBaseRegister(ops.register_number);
michael@0 1533 if (!cfa_rule->Handle(handler_, address_,
michael@0 1534 Handler::kCFARegister))
michael@0 1535 return false;
michael@0 1536 break;
michael@0 1537 }
michael@0 1538
michael@0 1539 // Change the offset used to compute the CFA.
michael@0 1540 case DW_CFA_def_cfa_offset:
michael@0 1541 if (!ParseOperands("o", &ops) ||
michael@0 1542 !DoDefCFAOffset(ops.offset))
michael@0 1543 return false;
michael@0 1544 break;
michael@0 1545
michael@0 1546 // Change the offset used to compute the CFA.
michael@0 1547 case DW_CFA_def_cfa_offset_sf:
michael@0 1548 if (!ParseOperands("s", &ops) ||
michael@0 1549 !DoDefCFAOffset(ops.signed_offset * cie->data_alignment_factor))
michael@0 1550 return false;
michael@0 1551 break;
michael@0 1552
michael@0 1553 // Specify an expression whose value is the CFA.
michael@0 1554 case DW_CFA_def_cfa_expression: {
michael@0 1555 if (!ParseOperands("e", &ops))
michael@0 1556 return false;
michael@0 1557 Rule *rule = new ValExpressionRule(ops.expression);
michael@0 1558 rules_.SetCFARule(rule);
michael@0 1559 if (!rule->Handle(handler_, address_,
michael@0 1560 Handler::kCFARegister))
michael@0 1561 return false;
michael@0 1562 break;
michael@0 1563 }
michael@0 1564
michael@0 1565 // The register's value cannot be recovered.
michael@0 1566 case DW_CFA_undefined: {
michael@0 1567 if (!ParseOperands("r", &ops) ||
michael@0 1568 !DoRule(ops.register_number, new UndefinedRule()))
michael@0 1569 return false;
michael@0 1570 break;
michael@0 1571 }
michael@0 1572
michael@0 1573 // The register's value is unchanged from its value in the caller.
michael@0 1574 case DW_CFA_same_value: {
michael@0 1575 if (!ParseOperands("r", &ops) ||
michael@0 1576 !DoRule(ops.register_number, new SameValueRule()))
michael@0 1577 return false;
michael@0 1578 break;
michael@0 1579 }
michael@0 1580
michael@0 1581 // Find a register at an offset from the CFA.
michael@0 1582 case DW_CFA_offset_extended:
michael@0 1583 if (!ParseOperands("ro", &ops) ||
michael@0 1584 !DoOffset(ops.register_number,
michael@0 1585 ops.offset * cie->data_alignment_factor))
michael@0 1586 return false;
michael@0 1587 break;
michael@0 1588
michael@0 1589 // The register is saved at an offset from the CFA.
michael@0 1590 case DW_CFA_offset_extended_sf:
michael@0 1591 if (!ParseOperands("rs", &ops) ||
michael@0 1592 !DoOffset(ops.register_number,
michael@0 1593 ops.signed_offset * cie->data_alignment_factor))
michael@0 1594 return false;
michael@0 1595 break;
michael@0 1596
michael@0 1597 // The register is saved at an offset from the CFA.
michael@0 1598 case DW_CFA_GNU_negative_offset_extended:
michael@0 1599 if (!ParseOperands("ro", &ops) ||
michael@0 1600 !DoOffset(ops.register_number,
michael@0 1601 -ops.offset * cie->data_alignment_factor))
michael@0 1602 return false;
michael@0 1603 break;
michael@0 1604
michael@0 1605 // The register's value is the sum of the CFA plus an offset.
michael@0 1606 case DW_CFA_val_offset:
michael@0 1607 if (!ParseOperands("ro", &ops) ||
michael@0 1608 !DoValOffset(ops.register_number,
michael@0 1609 ops.offset * cie->data_alignment_factor))
michael@0 1610 return false;
michael@0 1611 break;
michael@0 1612
michael@0 1613 // The register's value is the sum of the CFA plus an offset.
michael@0 1614 case DW_CFA_val_offset_sf:
michael@0 1615 if (!ParseOperands("rs", &ops) ||
michael@0 1616 !DoValOffset(ops.register_number,
michael@0 1617 ops.signed_offset * cie->data_alignment_factor))
michael@0 1618 return false;
michael@0 1619 break;
michael@0 1620
michael@0 1621 // The register has been saved in another register.
michael@0 1622 case DW_CFA_register: {
michael@0 1623 if (!ParseOperands("ro", &ops) ||
michael@0 1624 !DoRule(ops.register_number, new RegisterRule(ops.offset)))
michael@0 1625 return false;
michael@0 1626 break;
michael@0 1627 }
michael@0 1628
michael@0 1629 // An expression yields the address at which the register is saved.
michael@0 1630 case DW_CFA_expression: {
michael@0 1631 if (!ParseOperands("re", &ops) ||
michael@0 1632 !DoRule(ops.register_number, new ExpressionRule(ops.expression)))
michael@0 1633 return false;
michael@0 1634 break;
michael@0 1635 }
michael@0 1636
michael@0 1637 // An expression yields the caller's value for the register.
michael@0 1638 case DW_CFA_val_expression: {
michael@0 1639 if (!ParseOperands("re", &ops) ||
michael@0 1640 !DoRule(ops.register_number, new ValExpressionRule(ops.expression)))
michael@0 1641 return false;
michael@0 1642 break;
michael@0 1643 }
michael@0 1644
michael@0 1645 // Restore the rule established for a register by the CIE.
michael@0 1646 case DW_CFA_restore_extended:
michael@0 1647 if (!ParseOperands("r", &ops) ||
michael@0 1648 !DoRestore( ops.register_number))
michael@0 1649 return false;
michael@0 1650 break;
michael@0 1651
michael@0 1652 // Save the current set of rules on a stack.
michael@0 1653 case DW_CFA_remember_state:
michael@0 1654 saved_rules_.push(rules_);
michael@0 1655 break;
michael@0 1656
michael@0 1657 // Pop the current set of rules off the stack.
michael@0 1658 case DW_CFA_restore_state: {
michael@0 1659 if (saved_rules_.empty()) {
michael@0 1660 reporter_->EmptyStateStack(entry_->offset, entry_->kind,
michael@0 1661 CursorOffset());
michael@0 1662 return false;
michael@0 1663 }
michael@0 1664 const RuleMap &new_rules = saved_rules_.top();
michael@0 1665 if (rules_.CFARule() && !new_rules.CFARule()) {
michael@0 1666 reporter_->ClearingCFARule(entry_->offset, entry_->kind,
michael@0 1667 CursorOffset());
michael@0 1668 return false;
michael@0 1669 }
michael@0 1670 rules_.HandleTransitionTo(handler_, address_, new_rules);
michael@0 1671 rules_ = new_rules;
michael@0 1672 saved_rules_.pop();
michael@0 1673 break;
michael@0 1674 }
michael@0 1675
michael@0 1676 // No operation. (Padding instruction.)
michael@0 1677 case DW_CFA_nop:
michael@0 1678 break;
michael@0 1679
michael@0 1680 // A SPARC register window save: Registers 8 through 15 (%o0-%o7)
michael@0 1681 // are saved in registers 24 through 31 (%i0-%i7), and registers
michael@0 1682 // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets
michael@0 1683 // (0-15 * the register size). The register numbers must be
michael@0 1684 // hard-coded. A GNU extension, and not a pretty one.
michael@0 1685 case DW_CFA_GNU_window_save: {
michael@0 1686 // Save %o0-%o7 in %i0-%i7.
michael@0 1687 for (int i = 8; i < 16; i++)
michael@0 1688 if (!DoRule(i, new RegisterRule(i + 16)))
michael@0 1689 return false;
michael@0 1690 // Save %l0-%l7 and %i0-%i7 at the CFA.
michael@0 1691 for (int i = 16; i < 32; i++)
michael@0 1692 // Assume that the byte reader's address size is the same as
michael@0 1693 // the architecture's register size. !@#%*^ hilarious.
michael@0 1694 if (!DoRule(i, new OffsetRule(Handler::kCFARegister,
michael@0 1695 (i - 16) * reader_->AddressSize())))
michael@0 1696 return false;
michael@0 1697 break;
michael@0 1698 }
michael@0 1699
michael@0 1700 // I'm not sure what this is. GDB doesn't use it for unwinding.
michael@0 1701 case DW_CFA_GNU_args_size:
michael@0 1702 if (!ParseOperands("o", &ops)) return false;
michael@0 1703 break;
michael@0 1704
michael@0 1705 // An opcode we don't recognize.
michael@0 1706 default: {
michael@0 1707 reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset());
michael@0 1708 return false;
michael@0 1709 }
michael@0 1710 }
michael@0 1711
michael@0 1712 return true;
michael@0 1713 }
michael@0 1714
michael@0 1715 bool CallFrameInfo::State::DoDefCFA(unsigned base_register, long offset) {
michael@0 1716 Rule *rule = new ValOffsetRule(base_register, offset);
michael@0 1717 rules_.SetCFARule(rule);
michael@0 1718 return rule->Handle(handler_, address_,
michael@0 1719 Handler::kCFARegister);
michael@0 1720 }
michael@0 1721
michael@0 1722 bool CallFrameInfo::State::DoDefCFAOffset(long offset) {
michael@0 1723 Rule *cfa_rule = rules_.CFARule();
michael@0 1724 if (!cfa_rule) {
michael@0 1725 reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
michael@0 1726 return false;
michael@0 1727 }
michael@0 1728 cfa_rule->SetOffset(offset);
michael@0 1729 return cfa_rule->Handle(handler_, address_,
michael@0 1730 Handler::kCFARegister);
michael@0 1731 }
michael@0 1732
michael@0 1733 bool CallFrameInfo::State::DoRule(unsigned reg, Rule *rule) {
michael@0 1734 rules_.SetRegisterRule(reg, rule);
michael@0 1735 return rule->Handle(handler_, address_, reg);
michael@0 1736 }
michael@0 1737
michael@0 1738 bool CallFrameInfo::State::DoOffset(unsigned reg, long offset) {
michael@0 1739 if (!rules_.CFARule()) {
michael@0 1740 reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
michael@0 1741 return false;
michael@0 1742 }
michael@0 1743 return DoRule(reg,
michael@0 1744 new OffsetRule(Handler::kCFARegister, offset));
michael@0 1745 }
michael@0 1746
michael@0 1747 bool CallFrameInfo::State::DoValOffset(unsigned reg, long offset) {
michael@0 1748 if (!rules_.CFARule()) {
michael@0 1749 reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
michael@0 1750 return false;
michael@0 1751 }
michael@0 1752 return DoRule(reg,
michael@0 1753 new ValOffsetRule(Handler::kCFARegister, offset));
michael@0 1754 }
michael@0 1755
michael@0 1756 bool CallFrameInfo::State::DoRestore(unsigned reg) {
michael@0 1757 // DW_CFA_restore and DW_CFA_restore_extended don't make sense in a CIE.
michael@0 1758 if (entry_->kind == kCIE) {
michael@0 1759 reporter_->RestoreInCIE(entry_->offset, CursorOffset());
michael@0 1760 return false;
michael@0 1761 }
michael@0 1762 Rule *rule = cie_rules_.RegisterRule(reg);
michael@0 1763 if (!rule) {
michael@0 1764 // This isn't really the right thing to do, but since CFI generally
michael@0 1765 // only mentions callee-saves registers, and GCC's convention for
michael@0 1766 // callee-saves registers is that they are unchanged, it's a good
michael@0 1767 // approximation.
michael@0 1768 rule = new SameValueRule();
michael@0 1769 }
michael@0 1770 return DoRule(reg, rule);
michael@0 1771 }
michael@0 1772
michael@0 1773 bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) {
michael@0 1774 const char *buffer_end = buffer_ + buffer_length_;
michael@0 1775
michael@0 1776 // Initialize enough of ENTRY for use in error reporting.
michael@0 1777 entry->offset = cursor - buffer_;
michael@0 1778 entry->start = cursor;
michael@0 1779 entry->kind = kUnknown;
michael@0 1780 entry->end = NULL;
michael@0 1781
michael@0 1782 // Read the initial length. This sets reader_'s offset size.
michael@0 1783 size_t length_size;
michael@0 1784 uint64 length = reader_->ReadInitialLength(cursor, &length_size);
michael@0 1785 if (length_size > size_t(buffer_end - cursor))
michael@0 1786 return ReportIncomplete(entry);
michael@0 1787 cursor += length_size;
michael@0 1788
michael@0 1789 // In a .eh_frame section, a length of zero marks the end of the series
michael@0 1790 // of entries.
michael@0 1791 if (length == 0 && eh_frame_) {
michael@0 1792 entry->kind = kTerminator;
michael@0 1793 entry->end = cursor;
michael@0 1794 return true;
michael@0 1795 }
michael@0 1796
michael@0 1797 // Validate the length.
michael@0 1798 if (length > size_t(buffer_end - cursor))
michael@0 1799 return ReportIncomplete(entry);
michael@0 1800
michael@0 1801 // The length is the number of bytes after the initial length field;
michael@0 1802 // we have that position handy at this point, so compute the end
michael@0 1803 // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine,
michael@0 1804 // and the length didn't fit in a size_t, we would have rejected it
michael@0 1805 // above.)
michael@0 1806 entry->end = cursor + length;
michael@0 1807
michael@0 1808 // Parse the next field: either the offset of a CIE or a CIE id.
michael@0 1809 size_t offset_size = reader_->OffsetSize();
michael@0 1810 if (offset_size > size_t(entry->end - cursor)) return ReportIncomplete(entry);
michael@0 1811 entry->id = reader_->ReadOffset(cursor);
michael@0 1812
michael@0 1813 // Don't advance cursor past id field yet; in .eh_frame data we need
michael@0 1814 // the id's position to compute the section offset of an FDE's CIE.
michael@0 1815
michael@0 1816 // Now we can decide what kind of entry this is.
michael@0 1817 if (eh_frame_) {
michael@0 1818 // In .eh_frame data, an ID of zero marks the entry as a CIE, and
michael@0 1819 // anything else is an offset from the id field of the FDE to the start
michael@0 1820 // of the CIE.
michael@0 1821 if (entry->id == 0) {
michael@0 1822 entry->kind = kCIE;
michael@0 1823 } else {
michael@0 1824 entry->kind = kFDE;
michael@0 1825 // Turn the offset from the id into an offset from the buffer's start.
michael@0 1826 entry->id = (cursor - buffer_) - entry->id;
michael@0 1827 }
michael@0 1828 } else {
michael@0 1829 // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the
michael@0 1830 // offset size for the entry) marks the entry as a CIE, and anything
michael@0 1831 // else is the offset of the CIE from the beginning of the section.
michael@0 1832 if (offset_size == 4)
michael@0 1833 entry->kind = (entry->id == 0xffffffff) ? kCIE : kFDE;
michael@0 1834 else {
michael@0 1835 assert(offset_size == 8);
michael@0 1836 entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE;
michael@0 1837 }
michael@0 1838 }
michael@0 1839
michael@0 1840 // Now advance cursor past the id.
michael@0 1841 cursor += offset_size;
michael@0 1842
michael@0 1843 // The fields specific to this kind of entry start here.
michael@0 1844 entry->fields = cursor;
michael@0 1845
michael@0 1846 entry->cie = NULL;
michael@0 1847
michael@0 1848 return true;
michael@0 1849 }
michael@0 1850
michael@0 1851 bool CallFrameInfo::ReadCIEFields(CIE *cie) {
michael@0 1852 const char *cursor = cie->fields;
michael@0 1853 size_t len;
michael@0 1854
michael@0 1855 assert(cie->kind == kCIE);
michael@0 1856
michael@0 1857 // Prepare for early exit.
michael@0 1858 cie->version = 0;
michael@0 1859 cie->augmentation.clear();
michael@0 1860 cie->code_alignment_factor = 0;
michael@0 1861 cie->data_alignment_factor = 0;
michael@0 1862 cie->return_address_register = 0;
michael@0 1863 cie->has_z_augmentation = false;
michael@0 1864 cie->pointer_encoding = DW_EH_PE_absptr;
michael@0 1865 cie->instructions = 0;
michael@0 1866
michael@0 1867 // Parse the version number.
michael@0 1868 if (cie->end - cursor < 1)
michael@0 1869 return ReportIncomplete(cie);
michael@0 1870 cie->version = reader_->ReadOneByte(cursor);
michael@0 1871 cursor++;
michael@0 1872
michael@0 1873 // If we don't recognize the version, we can't parse any more fields of the
michael@0 1874 // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a
michael@0 1875 // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well;
michael@0 1876 // the difference between those versions seems to be the same as for
michael@0 1877 // .debug_frame.
michael@0 1878 if (cie->version < 1 || cie->version > 3) {
michael@0 1879 reporter_->UnrecognizedVersion(cie->offset, cie->version);
michael@0 1880 return false;
michael@0 1881 }
michael@0 1882
michael@0 1883 const char *augmentation_start = cursor;
michael@0 1884 const void *augmentation_end =
michael@0 1885 memchr(augmentation_start, '\0', cie->end - augmentation_start);
michael@0 1886 if (! augmentation_end) return ReportIncomplete(cie);
michael@0 1887 cursor = static_cast<const char *>(augmentation_end);
michael@0 1888 cie->augmentation = string(augmentation_start,
michael@0 1889 cursor - augmentation_start);
michael@0 1890 // Skip the terminating '\0'.
michael@0 1891 cursor++;
michael@0 1892
michael@0 1893 // Is this CFI augmented?
michael@0 1894 if (!cie->augmentation.empty()) {
michael@0 1895 // Is it an augmentation we recognize?
michael@0 1896 if (cie->augmentation[0] == DW_Z_augmentation_start) {
michael@0 1897 // Linux C++ ABI 'z' augmentation, used for exception handling data.
michael@0 1898 cie->has_z_augmentation = true;
michael@0 1899 } else {
michael@0 1900 // Not an augmentation we recognize. Augmentations can have arbitrary
michael@0 1901 // effects on the form of rest of the content, so we have to give up.
michael@0 1902 reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
michael@0 1903 return false;
michael@0 1904 }
michael@0 1905 }
michael@0 1906
michael@0 1907 // Parse the code alignment factor.
michael@0 1908 cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
michael@0 1909 if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
michael@0 1910 cursor += len;
michael@0 1911
michael@0 1912 // Parse the data alignment factor.
michael@0 1913 cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
michael@0 1914 if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
michael@0 1915 cursor += len;
michael@0 1916
michael@0 1917 // Parse the return address register. This is a ubyte in version 1, and
michael@0 1918 // a ULEB128 in version 3.
michael@0 1919 if (cie->version == 1) {
michael@0 1920 if (cursor >= cie->end) return ReportIncomplete(cie);
michael@0 1921 cie->return_address_register = uint8(*cursor++);
michael@0 1922 } else {
michael@0 1923 cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len);
michael@0 1924 if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
michael@0 1925 cursor += len;
michael@0 1926 }
michael@0 1927
michael@0 1928 // If we have a 'z' augmentation string, find the augmentation data and
michael@0 1929 // use the augmentation string to parse it.
michael@0 1930 if (cie->has_z_augmentation) {
michael@0 1931 uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len);
michael@0 1932 if (size_t(cie->end - cursor) < len + data_size)
michael@0 1933 return ReportIncomplete(cie);
michael@0 1934 cursor += len;
michael@0 1935 const char *data = cursor;
michael@0 1936 cursor += data_size;
michael@0 1937 const char *data_end = cursor;
michael@0 1938
michael@0 1939 cie->has_z_lsda = false;
michael@0 1940 cie->has_z_personality = false;
michael@0 1941 cie->has_z_signal_frame = false;
michael@0 1942
michael@0 1943 // Walk the augmentation string, and extract values from the
michael@0 1944 // augmentation data as the string directs.
michael@0 1945 for (size_t i = 1; i < cie->augmentation.size(); i++) {
michael@0 1946 switch (cie->augmentation[i]) {
michael@0 1947 case DW_Z_has_LSDA:
michael@0 1948 // The CIE's augmentation data holds the language-specific data
michael@0 1949 // area pointer's encoding, and the FDE's augmentation data holds
michael@0 1950 // the pointer itself.
michael@0 1951 cie->has_z_lsda = true;
michael@0 1952 // Fetch the LSDA encoding from the augmentation data.
michael@0 1953 if (data >= data_end) return ReportIncomplete(cie);
michael@0 1954 cie->lsda_encoding = DwarfPointerEncoding(*data++);
michael@0 1955 if (!reader_->ValidEncoding(cie->lsda_encoding)) {
michael@0 1956 reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding);
michael@0 1957 return false;
michael@0 1958 }
michael@0 1959 // Don't check if the encoding is usable here --- we haven't
michael@0 1960 // read the FDE's fields yet, so we're not prepared for
michael@0 1961 // DW_EH_PE_funcrel, although that's a fine encoding for the
michael@0 1962 // LSDA to use, since it appears in the FDE.
michael@0 1963 break;
michael@0 1964
michael@0 1965 case DW_Z_has_personality_routine:
michael@0 1966 // The CIE's augmentation data holds the personality routine
michael@0 1967 // pointer's encoding, followed by the pointer itself.
michael@0 1968 cie->has_z_personality = true;
michael@0 1969 // Fetch the personality routine pointer's encoding from the
michael@0 1970 // augmentation data.
michael@0 1971 if (data >= data_end) return ReportIncomplete(cie);
michael@0 1972 cie->personality_encoding = DwarfPointerEncoding(*data++);
michael@0 1973 if (!reader_->ValidEncoding(cie->personality_encoding)) {
michael@0 1974 reporter_->InvalidPointerEncoding(cie->offset,
michael@0 1975 cie->personality_encoding);
michael@0 1976 return false;
michael@0 1977 }
michael@0 1978 if (!reader_->UsableEncoding(cie->personality_encoding)) {
michael@0 1979 reporter_->UnusablePointerEncoding(cie->offset,
michael@0 1980 cie->personality_encoding);
michael@0 1981 return false;
michael@0 1982 }
michael@0 1983 // Fetch the personality routine's pointer itself from the data.
michael@0 1984 cie->personality_address =
michael@0 1985 reader_->ReadEncodedPointer(data, cie->personality_encoding,
michael@0 1986 &len);
michael@0 1987 if (len > size_t(data_end - data))
michael@0 1988 return ReportIncomplete(cie);
michael@0 1989 data += len;
michael@0 1990 break;
michael@0 1991
michael@0 1992 case DW_Z_has_FDE_address_encoding:
michael@0 1993 // The CIE's augmentation data holds the pointer encoding to use
michael@0 1994 // for addresses in the FDE.
michael@0 1995 if (data >= data_end) return ReportIncomplete(cie);
michael@0 1996 cie->pointer_encoding = DwarfPointerEncoding(*data++);
michael@0 1997 if (!reader_->ValidEncoding(cie->pointer_encoding)) {
michael@0 1998 reporter_->InvalidPointerEncoding(cie->offset,
michael@0 1999 cie->pointer_encoding);
michael@0 2000 return false;
michael@0 2001 }
michael@0 2002 if (!reader_->UsableEncoding(cie->pointer_encoding)) {
michael@0 2003 reporter_->UnusablePointerEncoding(cie->offset,
michael@0 2004 cie->pointer_encoding);
michael@0 2005 return false;
michael@0 2006 }
michael@0 2007 break;
michael@0 2008
michael@0 2009 case DW_Z_is_signal_trampoline:
michael@0 2010 // Frames using this CIE are signal delivery frames.
michael@0 2011 cie->has_z_signal_frame = true;
michael@0 2012 break;
michael@0 2013
michael@0 2014 default:
michael@0 2015 // An augmentation we don't recognize.
michael@0 2016 reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
michael@0 2017 return false;
michael@0 2018 }
michael@0 2019 }
michael@0 2020 }
michael@0 2021
michael@0 2022 // The CIE's instructions start here.
michael@0 2023 cie->instructions = cursor;
michael@0 2024
michael@0 2025 return true;
michael@0 2026 }
michael@0 2027
michael@0 2028 bool CallFrameInfo::ReadFDEFields(FDE *fde) {
michael@0 2029 const char *cursor = fde->fields;
michael@0 2030 size_t size;
michael@0 2031
michael@0 2032 fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
michael@0 2033 &size);
michael@0 2034 if (size > size_t(fde->end - cursor))
michael@0 2035 return ReportIncomplete(fde);
michael@0 2036 cursor += size;
michael@0 2037 reader_->SetFunctionBase(fde->address);
michael@0 2038
michael@0 2039 // For the length, we strip off the upper nybble of the encoding used for
michael@0 2040 // the starting address.
michael@0 2041 DwarfPointerEncoding length_encoding =
michael@0 2042 DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f);
michael@0 2043 fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size);
michael@0 2044 if (size > size_t(fde->end - cursor))
michael@0 2045 return ReportIncomplete(fde);
michael@0 2046 cursor += size;
michael@0 2047
michael@0 2048 // If the CIE has a 'z' augmentation string, then augmentation data
michael@0 2049 // appears here.
michael@0 2050 if (fde->cie->has_z_augmentation) {
michael@0 2051 uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size);
michael@0 2052 if (size_t(fde->end - cursor) < size + data_size)
michael@0 2053 return ReportIncomplete(fde);
michael@0 2054 cursor += size;
michael@0 2055
michael@0 2056 // In the abstract, we should walk the augmentation string, and extract
michael@0 2057 // items from the FDE's augmentation data as we encounter augmentation
michael@0 2058 // string characters that specify their presence: the ordering of items
michael@0 2059 // in the augmentation string determines the arrangement of values in
michael@0 2060 // the augmentation data.
michael@0 2061 //
michael@0 2062 // In practice, there's only ever one value in FDE augmentation data
michael@0 2063 // that we support --- the LSDA pointer --- and we have to bail if we
michael@0 2064 // see any unrecognized augmentation string characters. So if there is
michael@0 2065 // anything here at all, we know what it is, and where it starts.
michael@0 2066 if (fde->cie->has_z_lsda) {
michael@0 2067 // Check whether the LSDA's pointer encoding is usable now: only once
michael@0 2068 // we've parsed the FDE's starting address do we call reader_->
michael@0 2069 // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes
michael@0 2070 // usable.
michael@0 2071 if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) {
michael@0 2072 reporter_->UnusablePointerEncoding(fde->cie->offset,
michael@0 2073 fde->cie->lsda_encoding);
michael@0 2074 return false;
michael@0 2075 }
michael@0 2076
michael@0 2077 fde->lsda_address =
michael@0 2078 reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size);
michael@0 2079 if (size > data_size)
michael@0 2080 return ReportIncomplete(fde);
michael@0 2081 // Ideally, we would also complain here if there were unconsumed
michael@0 2082 // augmentation data.
michael@0 2083 }
michael@0 2084
michael@0 2085 cursor += data_size;
michael@0 2086 }
michael@0 2087
michael@0 2088 // The FDE's instructions start after those.
michael@0 2089 fde->instructions = cursor;
michael@0 2090
michael@0 2091 return true;
michael@0 2092 }
michael@0 2093
michael@0 2094 bool CallFrameInfo::Start() {
michael@0 2095 const char *buffer_end = buffer_ + buffer_length_;
michael@0 2096 const char *cursor;
michael@0 2097 bool all_ok = true;
michael@0 2098 const char *entry_end;
michael@0 2099 bool ok;
michael@0 2100
michael@0 2101 // Traverse all the entries in buffer_, skipping CIEs and offering
michael@0 2102 // FDEs to the handler.
michael@0 2103 for (cursor = buffer_; cursor < buffer_end;
michael@0 2104 cursor = entry_end, all_ok = all_ok && ok) {
michael@0 2105 FDE fde;
michael@0 2106
michael@0 2107 // Make it easy to skip this entry with 'continue': assume that
michael@0 2108 // things are not okay until we've checked all the data, and
michael@0 2109 // prepare the address of the next entry.
michael@0 2110 ok = false;
michael@0 2111
michael@0 2112 // Read the entry's prologue.
michael@0 2113 if (!ReadEntryPrologue(cursor, &fde)) {
michael@0 2114 if (!fde.end) {
michael@0 2115 // If we couldn't even figure out this entry's extent, then we
michael@0 2116 // must stop processing entries altogether.
michael@0 2117 all_ok = false;
michael@0 2118 break;
michael@0 2119 }
michael@0 2120 entry_end = fde.end;
michael@0 2121 continue;
michael@0 2122 }
michael@0 2123
michael@0 2124 // The next iteration picks up after this entry.
michael@0 2125 entry_end = fde.end;
michael@0 2126
michael@0 2127 // Did we see an .eh_frame terminating mark?
michael@0 2128 if (fde.kind == kTerminator) {
michael@0 2129 // If there appears to be more data left in the section after the
michael@0 2130 // terminating mark, warn the user. But this is just a warning;
michael@0 2131 // we leave all_ok true.
michael@0 2132 if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset);
michael@0 2133 break;
michael@0 2134 }
michael@0 2135
michael@0 2136 // In this loop, we skip CIEs. We only parse them fully when we
michael@0 2137 // parse an FDE that refers to them. This limits our memory
michael@0 2138 // consumption (beyond the buffer itself) to that needed to
michael@0 2139 // process the largest single entry.
michael@0 2140 if (fde.kind != kFDE) {
michael@0 2141 ok = true;
michael@0 2142 continue;
michael@0 2143 }
michael@0 2144
michael@0 2145 // Validate the CIE pointer.
michael@0 2146 if (fde.id > buffer_length_) {
michael@0 2147 reporter_->CIEPointerOutOfRange(fde.offset, fde.id);
michael@0 2148 continue;
michael@0 2149 }
michael@0 2150
michael@0 2151 CIE cie;
michael@0 2152
michael@0 2153 // Parse this FDE's CIE header.
michael@0 2154 if (!ReadEntryPrologue(buffer_ + fde.id, &cie))
michael@0 2155 continue;
michael@0 2156 // This had better be an actual CIE.
michael@0 2157 if (cie.kind != kCIE) {
michael@0 2158 reporter_->BadCIEId(fde.offset, fde.id);
michael@0 2159 continue;
michael@0 2160 }
michael@0 2161 if (!ReadCIEFields(&cie))
michael@0 2162 continue;
michael@0 2163
michael@0 2164 // We now have the values that govern both the CIE and the FDE.
michael@0 2165 cie.cie = &cie;
michael@0 2166 fde.cie = &cie;
michael@0 2167
michael@0 2168 // Parse the FDE's header.
michael@0 2169 if (!ReadFDEFields(&fde))
michael@0 2170 continue;
michael@0 2171
michael@0 2172 // Call Entry to ask the consumer if they're interested.
michael@0 2173 if (!handler_->Entry(fde.offset, fde.address, fde.size,
michael@0 2174 cie.version, cie.augmentation,
michael@0 2175 cie.return_address_register)) {
michael@0 2176 // The handler isn't interested in this entry. That's not an error.
michael@0 2177 ok = true;
michael@0 2178 continue;
michael@0 2179 }
michael@0 2180
michael@0 2181 if (cie.has_z_augmentation) {
michael@0 2182 // Report the personality routine address, if we have one.
michael@0 2183 if (cie.has_z_personality) {
michael@0 2184 if (!handler_
michael@0 2185 ->PersonalityRoutine(cie.personality_address,
michael@0 2186 IsIndirectEncoding(cie.personality_encoding)))
michael@0 2187 continue;
michael@0 2188 }
michael@0 2189
michael@0 2190 // Report the language-specific data area address, if we have one.
michael@0 2191 if (cie.has_z_lsda) {
michael@0 2192 if (!handler_
michael@0 2193 ->LanguageSpecificDataArea(fde.lsda_address,
michael@0 2194 IsIndirectEncoding(cie.lsda_encoding)))
michael@0 2195 continue;
michael@0 2196 }
michael@0 2197
michael@0 2198 // If this is a signal-handling frame, report that.
michael@0 2199 if (cie.has_z_signal_frame) {
michael@0 2200 if (!handler_->SignalHandler())
michael@0 2201 continue;
michael@0 2202 }
michael@0 2203 }
michael@0 2204
michael@0 2205 // Interpret the CIE's instructions, and then the FDE's instructions.
michael@0 2206 State state(reader_, handler_, reporter_, fde.address);
michael@0 2207 ok = state.InterpretCIE(cie) && state.InterpretFDE(fde);
michael@0 2208
michael@0 2209 // Tell the ByteReader that the function start address from the
michael@0 2210 // FDE header is no longer valid.
michael@0 2211 reader_->ClearFunctionBase();
michael@0 2212
michael@0 2213 // Report the end of the entry.
michael@0 2214 handler_->End();
michael@0 2215 }
michael@0 2216
michael@0 2217 return all_ok;
michael@0 2218 }
michael@0 2219
michael@0 2220 const char *CallFrameInfo::KindName(EntryKind kind) {
michael@0 2221 if (kind == CallFrameInfo::kUnknown)
michael@0 2222 return "entry";
michael@0 2223 else if (kind == CallFrameInfo::kCIE)
michael@0 2224 return "common information entry";
michael@0 2225 else if (kind == CallFrameInfo::kFDE)
michael@0 2226 return "frame description entry";
michael@0 2227 else {
michael@0 2228 assert (kind == CallFrameInfo::kTerminator);
michael@0 2229 return ".eh_frame sequence terminator";
michael@0 2230 }
michael@0 2231 }
michael@0 2232
michael@0 2233 bool CallFrameInfo::ReportIncomplete(Entry *entry) {
michael@0 2234 reporter_->Incomplete(entry->offset, entry->kind);
michael@0 2235 return false;
michael@0 2236 }
michael@0 2237
michael@0 2238 void CallFrameInfo::Reporter::Incomplete(uint64 offset,
michael@0 2239 CallFrameInfo::EntryKind kind) {
michael@0 2240 fprintf(stderr,
michael@0 2241 "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
michael@0 2242 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
michael@0 2243 section_.c_str());
michael@0 2244 }
michael@0 2245
michael@0 2246 void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) {
michael@0 2247 fprintf(stderr,
michael@0 2248 "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
michael@0 2249 " before end of section contents\n",
michael@0 2250 filename_.c_str(), offset, section_.c_str());
michael@0 2251 }
michael@0 2252
michael@0 2253 void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset,
michael@0 2254 uint64 cie_offset) {
michael@0 2255 fprintf(stderr,
michael@0 2256 "%s: CFI frame description entry at offset 0x%llx in '%s':"
michael@0 2257 " CIE pointer is out of range: 0x%llx\n",
michael@0 2258 filename_.c_str(), offset, section_.c_str(), cie_offset);
michael@0 2259 }
michael@0 2260
michael@0 2261 void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
michael@0 2262 fprintf(stderr,
michael@0 2263 "%s: CFI frame description entry at offset 0x%llx in '%s':"
michael@0 2264 " CIE pointer does not point to a CIE: 0x%llx\n",
michael@0 2265 filename_.c_str(), offset, section_.c_str(), cie_offset);
michael@0 2266 }
michael@0 2267
michael@0 2268 void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
michael@0 2269 fprintf(stderr,
michael@0 2270 "%s: CFI frame description entry at offset 0x%llx in '%s':"
michael@0 2271 " CIE specifies unrecognized version: %d\n",
michael@0 2272 filename_.c_str(), offset, section_.c_str(), version);
michael@0 2273 }
michael@0 2274
michael@0 2275 void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
michael@0 2276 const string &aug) {
michael@0 2277 fprintf(stderr,
michael@0 2278 "%s: CFI frame description entry at offset 0x%llx in '%s':"
michael@0 2279 " CIE specifies unrecognized augmentation: '%s'\n",
michael@0 2280 filename_.c_str(), offset, section_.c_str(), aug.c_str());
michael@0 2281 }
michael@0 2282
michael@0 2283 void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset,
michael@0 2284 uint8 encoding) {
michael@0 2285 fprintf(stderr,
michael@0 2286 "%s: CFI common information entry at offset 0x%llx in '%s':"
michael@0 2287 " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n",
michael@0 2288 filename_.c_str(), offset, section_.c_str(), encoding);
michael@0 2289 }
michael@0 2290
michael@0 2291 void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset,
michael@0 2292 uint8 encoding) {
michael@0 2293 fprintf(stderr,
michael@0 2294 "%s: CFI common information entry at offset 0x%llx in '%s':"
michael@0 2295 " 'z' augmentation specifies a pointer encoding for which"
michael@0 2296 " we have no base address: 0x%02x\n",
michael@0 2297 filename_.c_str(), offset, section_.c_str(), encoding);
michael@0 2298 }
michael@0 2299
michael@0 2300 void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) {
michael@0 2301 fprintf(stderr,
michael@0 2302 "%s: CFI common information entry at offset 0x%llx in '%s':"
michael@0 2303 " the DW_CFA_restore instruction at offset 0x%llx"
michael@0 2304 " cannot be used in a common information entry\n",
michael@0 2305 filename_.c_str(), offset, section_.c_str(), insn_offset);
michael@0 2306 }
michael@0 2307
michael@0 2308 void CallFrameInfo::Reporter::BadInstruction(uint64 offset,
michael@0 2309 CallFrameInfo::EntryKind kind,
michael@0 2310 uint64 insn_offset) {
michael@0 2311 fprintf(stderr,
michael@0 2312 "%s: CFI %s at offset 0x%llx in section '%s':"
michael@0 2313 " the instruction at offset 0x%llx is unrecognized\n",
michael@0 2314 filename_.c_str(), CallFrameInfo::KindName(kind),
michael@0 2315 offset, section_.c_str(), insn_offset);
michael@0 2316 }
michael@0 2317
michael@0 2318 void CallFrameInfo::Reporter::NoCFARule(uint64 offset,
michael@0 2319 CallFrameInfo::EntryKind kind,
michael@0 2320 uint64 insn_offset) {
michael@0 2321 fprintf(stderr,
michael@0 2322 "%s: CFI %s at offset 0x%llx in section '%s':"
michael@0 2323 " the instruction at offset 0x%llx assumes that a CFA rule has"
michael@0 2324 " been set, but none has been set\n",
michael@0 2325 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
michael@0 2326 section_.c_str(), insn_offset);
michael@0 2327 }
michael@0 2328
michael@0 2329 void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset,
michael@0 2330 CallFrameInfo::EntryKind kind,
michael@0 2331 uint64 insn_offset) {
michael@0 2332 fprintf(stderr,
michael@0 2333 "%s: CFI %s at offset 0x%llx in section '%s':"
michael@0 2334 " the DW_CFA_restore_state instruction at offset 0x%llx"
michael@0 2335 " should pop a saved state from the stack, but the stack is empty\n",
michael@0 2336 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
michael@0 2337 section_.c_str(), insn_offset);
michael@0 2338 }
michael@0 2339
michael@0 2340 void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset,
michael@0 2341 CallFrameInfo::EntryKind kind,
michael@0 2342 uint64 insn_offset) {
michael@0 2343 fprintf(stderr,
michael@0 2344 "%s: CFI %s at offset 0x%llx in section '%s':"
michael@0 2345 " the DW_CFA_restore_state instruction at offset 0x%llx"
michael@0 2346 " would clear the CFA rule in effect\n",
michael@0 2347 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
michael@0 2348 section_.c_str(), insn_offset);
michael@0 2349 }
michael@0 2350
michael@0 2351 } // namespace dwarf2reader

mercurial