1 // -*- mode: C++ -*- 2 3 // Copyright (c) 2010, Google Inc. 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // * Neither the name of Google Inc. nor the names of its 17 // contributors may be used to endorse or promote products derived from 18 // this software without specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 33 34 // Derived from: 35 // cfi_assembler.h: Define CFISection, a class for creating properly 36 // (and improperly) formatted DWARF CFI data for unit tests. 37 38 // Derived from: 39 // test-assembler.h: interface to class for building complex binary streams. 40 41 // To test the Breakpad symbol dumper and processor thoroughly, for 42 // all combinations of host system and minidump processor 43 // architecture, we need to be able to easily generate complex test 44 // data like debugging information and minidump files. 45 // 46 // For example, if we want our unit tests to provide full code 47 // coverage for stack walking, it may be difficult to persuade the 48 // compiler to generate every possible sort of stack walking 49 // information that we want to support; there are probably DWARF CFI 50 // opcodes that GCC never emits. Similarly, if we want to test our 51 // error handling, we will need to generate damaged minidumps or 52 // debugging information that (we hope) the client or compiler will 53 // never produce on its own. 54 // 55 // google_breakpad::TestAssembler provides a predictable and 56 // (relatively) simple way to generate complex formatted data streams 57 // like minidumps and CFI. Furthermore, because TestAssembler is 58 // portable, developers without access to (say) Visual Studio or a 59 // SPARC assembler can still work on test data for those targets. 60 61 #ifndef LUL_TEST_INFRASTRUCTURE_H 62 #define LUL_TEST_INFRASTRUCTURE_H 63 64 #include "LulDwarfExt.h" 65 66 #include <string> 67 #include <vector> 68 69 using std::string; 70 using std::vector; 71 72 namespace lul_test { 73 namespace test_assembler { 74 75 // A Label represents a value not yet known that we need to store in a 76 // section. As long as all the labels a section refers to are defined 77 // by the time we retrieve its contents as bytes, we can use undefined 78 // labels freely in that section's construction. 79 // 80 // A label can be in one of three states: 81 // - undefined, 82 // - defined as the sum of some other label and a constant, or 83 // - a constant. 84 // 85 // A label's value never changes, but it can accumulate constraints. 86 // Adding labels and integers is permitted, and yields a label. 87 // Subtracting a constant from a label is permitted, and also yields a 88 // label. Subtracting two labels that have some relationship to each 89 // other is permitted, and yields a constant. 90 // 91 // For example: 92 // 93 // Label a; // a's value is undefined 94 // Label b; // b's value is undefined 95 // { 96 // Label c = a + 4; // okay, even though a's value is unknown 97 // b = c + 4; // also okay; b is now a+8 98 // } 99 // Label d = b - 2; // okay; d == a+6, even though c is gone 100 // d.Value(); // error: d's value is not yet known 101 // d - a; // is 6, even though their values are not known 102 // a = 12; // now b == 20, and d == 18 103 // d.Value(); // 18: no longer an error 104 // b.Value(); // 20 105 // d = 10; // error: d is already defined. 106 // 107 // Label objects' lifetimes are unconstrained: notice that, in the 108 // above example, even though a and b are only related through c, and 109 // c goes out of scope, the assignment to a sets b's value as well. In 110 // particular, it's not necessary to ensure that a Label lives beyond 111 // Sections that refer to it. 112 class Label { 113 public: 114 Label(); // An undefined label. 115 explicit Label(uint64_t value); // A label with a fixed value 116 Label(const Label& value); // A label equal to another. 117 ~Label(); 118 119 Label& operator=(uint64_t value); 120 Label& operator=(const Label& value); 121 Label operator+(uint64_t addend) const; 122 Label operator-(uint64_t subtrahend) const; 123 uint64_t operator-(const Label& subtrahend) const; 124 125 // We could also provide == and != that work on undefined, but 126 // related, labels. 127 128 // Return true if this label's value is known. If VALUE_P is given, 129 // set *VALUE_P to the known value if returning true. 130 bool IsKnownConstant(uint64_t* value_p = NULL) const; 131 132 // Return true if the offset from LABEL to this label is known. If 133 // OFFSET_P is given, set *OFFSET_P to the offset when returning true. 134 // 135 // You can think of l.KnownOffsetFrom(m, &d) as being like 'd = l-m', 136 // except that it also returns a value indicating whether the 137 // subtraction is possible given what we currently know of l and m. 138 // It can be possible even if we don't know l and m's values. For 139 // example: 140 // 141 // Label l, m; 142 // m = l + 10; 143 // l.IsKnownConstant(); // false 144 // m.IsKnownConstant(); // false 145 // uint64_t d; 146 // l.IsKnownOffsetFrom(m, &d); // true, and sets d to -10. 147 // l-m // -10 148 // m-l // 10 149 // m.Value() // error: m's value is not known 150 bool IsKnownOffsetFrom(const Label& label, uint64_t* offset_p = NULL) const; 151 152 private: 153 // A label's value, or if that is not yet known, how the value is 154 // related to other labels' values. A binding may be: 155 // - a known constant, 156 // - constrained to be equal to some other binding plus a constant, or 157 // - unconstrained, and free to take on any value. 158 // 159 // Many labels may point to a single binding, and each binding may 160 // refer to another, so bindings and labels form trees whose leaves 161 // are labels, whose interior nodes (and roots) are bindings, and 162 // where links point from children to parents. Bindings are 163 // reference counted, allowing labels to be lightweight, copyable, 164 // assignable, placed in containers, and so on. 165 class Binding { 166 public: 167 Binding(); 168 explicit Binding(uint64_t addend); 169 ~Binding(); 170 171 // Increment our reference count. Acquire()172 void Acquire() { reference_count_++; }; 173 // Decrement our reference count, and return true if it is zero. Release()174 bool Release() { return --reference_count_ == 0; } 175 176 // Set this binding to be equal to BINDING + ADDEND. If BINDING is 177 // NULL, then set this binding to the known constant ADDEND. 178 // Update every binding on this binding's chain to point directly 179 // to BINDING, or to be a constant, with addends adjusted 180 // appropriately. 181 void Set(Binding* binding, uint64_t value); 182 183 // Return what we know about the value of this binding. 184 // - If this binding's value is a known constant, set BASE to 185 // NULL, and set ADDEND to its value. 186 // - If this binding is not a known constant but related to other 187 // bindings, set BASE to the binding at the end of the relation 188 // chain (which will always be unconstrained), and set ADDEND to the 189 // value to add to that binding's value to get this binding's 190 // value. 191 // - If this binding is unconstrained, set BASE to this, and leave 192 // ADDEND unchanged. 193 void Get(Binding** base, uint64_t* addend); 194 195 private: 196 // There are three cases: 197 // 198 // - A binding representing a known constant value has base_ NULL, 199 // and addend_ equal to the value. 200 // 201 // - A binding representing a completely unconstrained value has 202 // base_ pointing to this; addend_ is unused. 203 // 204 // - A binding whose value is related to some other binding's 205 // value has base_ pointing to that other binding, and addend_ 206 // set to the amount to add to that binding's value to get this 207 // binding's value. We only represent relationships of the form 208 // x = y+c. 209 // 210 // Thus, the bind_ links form a chain terminating in either a 211 // known constant value or a completely unconstrained value. Most 212 // operations on bindings do path compression: they change every 213 // binding on the chain to point directly to the final value, 214 // adjusting addends as appropriate. 215 Binding* base_; 216 uint64_t addend_; 217 218 // The number of Labels and Bindings pointing to this binding. 219 // (When a binding points to itself, indicating a completely 220 // unconstrained binding, that doesn't count as a reference.) 221 int reference_count_; 222 }; 223 224 // This label's value. 225 Binding* value_; 226 }; 227 228 // Conventions for representing larger numbers as sequences of bytes. 229 enum Endianness { 230 kBigEndian, // Big-endian: the most significant byte comes first. 231 kLittleEndian, // Little-endian: the least significant byte comes first. 232 kUnsetEndian, // used internally 233 }; 234 235 // A section is a sequence of bytes, constructed by appending bytes 236 // to the end. Sections have a convenient and flexible set of member 237 // functions for appending data in various formats: big-endian and 238 // little-endian signed and unsigned values of different sizes; 239 // LEB128 and ULEB128 values (see below), and raw blocks of bytes. 240 // 241 // If you need to append a value to a section that is not convenient 242 // to compute immediately, you can create a label, append the 243 // label's value to the section, and then set the label's value 244 // later, when it's convenient to do so. Once a label's value is 245 // known, the section class takes care of updating all previously 246 // appended references to it. 247 // 248 // Once all the labels to which a section refers have had their 249 // values determined, you can get a copy of the section's contents 250 // as a string. 251 // 252 // Note that there is no specified "start of section" label. This is 253 // because there are typically several different meanings for "the 254 // start of a section": the offset of the section within an object 255 // file, the address in memory at which the section's content appear, 256 // and so on. It's up to the code that uses the Section class to 257 // keep track of these explicitly, as they depend on the application. 258 class Section { 259 public: 260 explicit Section(Endianness endianness = kUnsetEndian) endianness_(endianness)261 : endianness_(endianness){}; 262 263 // A base class destructor should be either public and virtual, 264 // or protected and nonvirtual. ~Section()265 virtual ~Section(){}; 266 267 // Return the default endianness of this section. endianness()268 Endianness endianness() const { return endianness_; } 269 270 // Append the SIZE bytes at DATA to the end of this section. Return 271 // a reference to this section. Append(const string & data)272 Section& Append(const string& data) { 273 contents_.append(data); 274 return *this; 275 }; 276 277 // Append SIZE copies of BYTE to the end of this section. Return a 278 // reference to this section. Append(size_t size,uint8_t byte)279 Section& Append(size_t size, uint8_t byte) { 280 contents_.append(size, (char)byte); 281 return *this; 282 } 283 284 // Append NUMBER to this section. ENDIANNESS is the endianness to 285 // use to write the number. SIZE is the length of the number in 286 // bytes. Return a reference to this section. 287 Section& Append(Endianness endianness, size_t size, uint64_t number); 288 Section& Append(Endianness endianness, size_t size, const Label& label); 289 290 // Append SECTION to the end of this section. The labels SECTION 291 // refers to need not be defined yet. 292 // 293 // Note that this has no effect on any Labels' values, or on 294 // SECTION. If placing SECTION within 'this' provides new 295 // constraints on existing labels' values, then it's up to the 296 // caller to fiddle with those labels as needed. 297 Section& Append(const Section& section); 298 299 // Append the contents of DATA as a series of bytes terminated by 300 // a NULL character. AppendCString(const string & data)301 Section& AppendCString(const string& data) { 302 Append(data); 303 contents_ += '\0'; 304 return *this; 305 } 306 307 // Append VALUE or LABEL to this section, with the given bit width and 308 // endianness. Return a reference to this section. 309 // 310 // The names of these functions have the form <ENDIANNESS><BITWIDTH>: 311 // <ENDIANNESS> is either 'L' (little-endian, least significant byte first), 312 // 'B' (big-endian, most significant byte first), or 313 // 'D' (default, the section's default endianness) 314 // <BITWIDTH> is 8, 16, 32, or 64. 315 // 316 // Since endianness doesn't matter for a single byte, all the 317 // <BITWIDTH>=8 functions are equivalent. 318 // 319 // These can be used to write both signed and unsigned values, as 320 // the compiler will properly sign-extend a signed value before 321 // passing it to the function, at which point the function's 322 // behavior is the same either way. L8(uint8_t value)323 Section& L8(uint8_t value) { 324 contents_ += value; 325 return *this; 326 } B8(uint8_t value)327 Section& B8(uint8_t value) { 328 contents_ += value; 329 return *this; 330 } D8(uint8_t value)331 Section& D8(uint8_t value) { 332 contents_ += value; 333 return *this; 334 } 335 Section &L16(uint16_t), &L32(uint32_t), &L64(uint64_t), &B16(uint16_t), 336 &B32(uint32_t), &B64(uint64_t), &D16(uint16_t), &D32(uint32_t), 337 &D64(uint64_t); 338 Section &L8(const Label&label), &L16(const Label&label), 339 &L32(const Label&label), &L64(const Label&label), &B8(const Label&label), 340 &B16(const Label&label), &B32(const Label&label), &B64(const Label&label), 341 &D8(const Label&label), &D16(const Label&label), &D32(const Label&label), 342 &D64(const Label&label); 343 344 // Append VALUE in a signed LEB128 (Little-Endian Base 128) form. 345 // 346 // The signed LEB128 representation of an integer N is a variable 347 // number of bytes: 348 // 349 // - If N is between -0x40 and 0x3f, then its signed LEB128 350 // representation is a single byte whose value is N. 351 // 352 // - Otherwise, its signed LEB128 representation is (N & 0x7f) | 353 // 0x80, followed by the signed LEB128 representation of N / 128, 354 // rounded towards negative infinity. 355 // 356 // In other words, we break VALUE into groups of seven bits, put 357 // them in little-endian order, and then write them as eight-bit 358 // bytes with the high bit on all but the last. 359 // 360 // Note that VALUE cannot be a Label (we would have to implement 361 // relaxation). 362 Section& LEB128(long long value); 363 364 // Append VALUE in unsigned LEB128 (Little-Endian Base 128) form. 365 // 366 // The unsigned LEB128 representation of an integer N is a variable 367 // number of bytes: 368 // 369 // - If N is between 0 and 0x7f, then its unsigned LEB128 370 // representation is a single byte whose value is N. 371 // 372 // - Otherwise, its unsigned LEB128 representation is (N & 0x7f) | 373 // 0x80, followed by the unsigned LEB128 representation of N / 374 // 128, rounded towards negative infinity. 375 // 376 // Note that VALUE cannot be a Label (we would have to implement 377 // relaxation). 378 Section& ULEB128(uint64_t value); 379 380 // Jump to the next location aligned on an ALIGNMENT-byte boundary, 381 // relative to the start of the section. Fill the gap with PAD_BYTE. 382 // ALIGNMENT must be a power of two. Return a reference to this 383 // section. 384 Section& Align(size_t alignment, uint8_t pad_byte = 0); 385 386 // Return the current size of the section. Size()387 size_t Size() const { return contents_.size(); } 388 389 // Return a label representing the start of the section. 390 // 391 // It is up to the user whether this label represents the section's 392 // position in an object file, the section's address in memory, or 393 // what have you; some applications may need both, in which case 394 // this simple-minded interface won't be enough. This class only 395 // provides a single start label, for use with the Here and Mark 396 // member functions. 397 // 398 // Ideally, we'd provide this in a subclass that actually knows more 399 // about the application at hand and can provide an appropriate 400 // collection of start labels. But then the appending member 401 // functions like Append and D32 would return a reference to the 402 // base class, not the derived class, and the chaining won't work. 403 // Since the only value here is in pretty notation, that's a fatal 404 // flaw. start()405 Label start() const { return start_; } 406 407 // Return a label representing the point at which the next Appended 408 // item will appear in the section, relative to start(). Here()409 Label Here() const { return start_ + Size(); } 410 411 // Set *LABEL to Here, and return a reference to this section. Mark(Label * label)412 Section& Mark(Label* label) { 413 *label = Here(); 414 return *this; 415 } 416 417 // If there are no undefined label references left in this 418 // section, set CONTENTS to the contents of this section, as a 419 // string, and clear this section. Return true on success, or false 420 // if there were still undefined labels. 421 bool GetContents(string* contents); 422 423 private: 424 // Used internally. A reference to a label's value. 425 struct Reference { ReferenceReference426 Reference(size_t set_offset, Endianness set_endianness, size_t set_size, 427 const Label& set_label) 428 : offset(set_offset), 429 endianness(set_endianness), 430 size(set_size), 431 label(set_label) {} 432 433 // The offset of the reference within the section. 434 size_t offset; 435 436 // The endianness of the reference. 437 Endianness endianness; 438 439 // The size of the reference. 440 size_t size; 441 442 // The label to which this is a reference. 443 Label label; 444 }; 445 446 // The default endianness of this section. 447 Endianness endianness_; 448 449 // The contents of the section. 450 string contents_; 451 452 // References to labels within those contents. 453 vector<Reference> references_; 454 455 // A label referring to the beginning of the section. 456 Label start_; 457 }; 458 459 } // namespace test_assembler 460 } // namespace lul_test 461 462 namespace lul_test { 463 464 using lul::DwarfPointerEncoding; 465 using lul_test::test_assembler::Endianness; 466 using lul_test::test_assembler::Label; 467 using lul_test::test_assembler::Section; 468 469 class CFISection : public Section { 470 public: 471 // CFI augmentation strings beginning with 'z', defined by the 472 // Linux/IA-64 C++ ABI, can specify interesting encodings for 473 // addresses appearing in FDE headers and call frame instructions (and 474 // for additional fields whose presence the augmentation string 475 // specifies). In particular, pointers can be specified to be relative 476 // to various base address: the start of the .text section, the 477 // location holding the address itself, and so on. These allow the 478 // frame data to be position-independent even when they live in 479 // write-protected pages. These variants are specified at the 480 // following two URLs: 481 // 482 // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html 483 // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html 484 // 485 // CFISection leaves the production of well-formed 'z'-augmented CIEs and 486 // FDEs to the user, but does provide EncodedPointer, to emit 487 // properly-encoded addresses for a given pointer encoding. 488 // EncodedPointer uses an instance of this structure to find the base 489 // addresses it should use; you can establish a default for all encoded 490 // pointers appended to this section with SetEncodedPointerBases. 491 struct EncodedPointerBases { EncodedPointerBasesEncodedPointerBases492 EncodedPointerBases() : cfi(), text(), data() {} 493 494 // The starting address of this CFI section in memory, for 495 // DW_EH_PE_pcrel. DW_EH_PE_pcrel pointers may only be used in data 496 // that has is loaded into the program's address space. 497 uint64_t cfi; 498 499 // The starting address of this file's .text section, for DW_EH_PE_textrel. 500 uint64_t text; 501 502 // The starting address of this file's .got or .eh_frame_hdr section, 503 // for DW_EH_PE_datarel. 504 uint64_t data; 505 }; 506 507 // Create a CFISection whose endianness is ENDIANNESS, and where 508 // machine addresses are ADDRESS_SIZE bytes long. If EH_FRAME is 509 // true, use the .eh_frame format, as described by the Linux 510 // Standards Base Core Specification, instead of the DWARF CFI 511 // format. 512 CFISection(Endianness endianness, size_t address_size, bool eh_frame = false) Section(endianness)513 : Section(endianness), 514 address_size_(address_size), 515 eh_frame_(eh_frame), 516 pointer_encoding_(lul::DW_EH_PE_absptr), 517 encoded_pointer_bases_(), 518 entry_length_(NULL), 519 in_fde_(false) { 520 // The 'start', 'Here', and 'Mark' members of a CFISection all refer 521 // to section offsets. 522 start() = 0; 523 } 524 525 // Return this CFISection's address size. AddressSize()526 size_t AddressSize() const { return address_size_; } 527 528 // Return true if this CFISection uses the .eh_frame format, or 529 // false if it contains ordinary DWARF CFI data. ContainsEHFrame()530 bool ContainsEHFrame() const { return eh_frame_; } 531 532 // Use ENCODING for pointers in calls to FDEHeader and EncodedPointer. SetPointerEncoding(DwarfPointerEncoding encoding)533 void SetPointerEncoding(DwarfPointerEncoding encoding) { 534 pointer_encoding_ = encoding; 535 } 536 537 // Use the addresses in BASES as the base addresses for encoded 538 // pointers in subsequent calls to FDEHeader or EncodedPointer. 539 // This function makes a copy of BASES. SetEncodedPointerBases(const EncodedPointerBases & bases)540 void SetEncodedPointerBases(const EncodedPointerBases& bases) { 541 encoded_pointer_bases_ = bases; 542 } 543 544 // Append a Common Information Entry header to this section with the 545 // given values. If dwarf64 is true, use the 64-bit DWARF initial 546 // length format for the CIE's initial length. Return a reference to 547 // this section. You should call FinishEntry after writing the last 548 // instruction for the CIE. 549 // 550 // Before calling this function, you will typically want to use Mark 551 // or Here to make a label to pass to FDEHeader that refers to this 552 // CIE's position in the section. 553 CFISection& CIEHeader(uint64_t code_alignment_factor, 554 int data_alignment_factor, 555 unsigned return_address_register, uint8_t version = 3, 556 const string& augmentation = "", bool dwarf64 = false); 557 558 // Append a Frame Description Entry header to this section with the 559 // given values. If dwarf64 is true, use the 64-bit DWARF initial 560 // length format for the CIE's initial length. Return a reference to 561 // this section. You should call FinishEntry after writing the last 562 // instruction for the CIE. 563 // 564 // This function doesn't support entries that are longer than 565 // 0xffffff00 bytes. (The "initial length" is always a 32-bit 566 // value.) Nor does it support .debug_frame sections longer than 567 // 0xffffff00 bytes. 568 CFISection& FDEHeader(Label cie_pointer, uint64_t initial_location, 569 uint64_t address_range, bool dwarf64 = false); 570 571 // Note the current position as the end of the last CIE or FDE we 572 // started, after padding with DW_CFA_nops for alignment. This 573 // defines the label representing the entry's length, cited in the 574 // entry's header. Return a reference to this section. 575 CFISection& FinishEntry(); 576 577 // Append the contents of BLOCK as a DW_FORM_block value: an 578 // unsigned LEB128 length, followed by that many bytes of data. Block(const string & block)579 CFISection& Block(const string& block) { 580 ULEB128(block.size()); 581 Append(block); 582 return *this; 583 } 584 585 // Append ADDRESS to this section, in the appropriate size and 586 // endianness. Return a reference to this section. Address(uint64_t address)587 CFISection& Address(uint64_t address) { 588 Section::Append(endianness(), address_size_, address); 589 return *this; 590 } 591 592 // Append ADDRESS to this section, using ENCODING and BASES. ENCODING 593 // defaults to this section's default encoding, established by 594 // SetPointerEncoding. BASES defaults to this section's bases, set by 595 // SetEncodedPointerBases. If the DW_EH_PE_indirect bit is set in the 596 // encoding, assume that ADDRESS is where the true address is stored. 597 // Return a reference to this section. 598 // 599 // (C++ doesn't let me use default arguments here, because I want to 600 // refer to members of *this in the default argument expression.) EncodedPointer(uint64_t address)601 CFISection& EncodedPointer(uint64_t address) { 602 return EncodedPointer(address, pointer_encoding_, encoded_pointer_bases_); 603 } EncodedPointer(uint64_t address,DwarfPointerEncoding encoding)604 CFISection& EncodedPointer(uint64_t address, DwarfPointerEncoding encoding) { 605 return EncodedPointer(address, encoding, encoded_pointer_bases_); 606 } 607 CFISection& EncodedPointer(uint64_t address, DwarfPointerEncoding encoding, 608 const EncodedPointerBases& bases); 609 610 // Restate some member functions, to keep chaining working nicely. Mark(Label * label)611 CFISection& Mark(Label* label) { 612 Section::Mark(label); 613 return *this; 614 } D8(uint8_t v)615 CFISection& D8(uint8_t v) { 616 Section::D8(v); 617 return *this; 618 } D16(uint16_t v)619 CFISection& D16(uint16_t v) { 620 Section::D16(v); 621 return *this; 622 } D16(Label v)623 CFISection& D16(Label v) { 624 Section::D16(v); 625 return *this; 626 } D32(uint32_t v)627 CFISection& D32(uint32_t v) { 628 Section::D32(v); 629 return *this; 630 } D32(const Label & v)631 CFISection& D32(const Label& v) { 632 Section::D32(v); 633 return *this; 634 } D64(uint64_t v)635 CFISection& D64(uint64_t v) { 636 Section::D64(v); 637 return *this; 638 } D64(const Label & v)639 CFISection& D64(const Label& v) { 640 Section::D64(v); 641 return *this; 642 } LEB128(long long v)643 CFISection& LEB128(long long v) { 644 Section::LEB128(v); 645 return *this; 646 } ULEB128(uint64_t v)647 CFISection& ULEB128(uint64_t v) { 648 Section::ULEB128(v); 649 return *this; 650 } 651 652 private: 653 // A length value that we've appended to the section, but is not yet 654 // known. LENGTH is the appended value; START is a label referring 655 // to the start of the data whose length was cited. 656 struct PendingLength { 657 Label length; 658 Label start; 659 }; 660 661 // Constants used in CFI/.eh_frame data: 662 663 // If the first four bytes of an "initial length" are this constant, then 664 // the data uses the 64-bit DWARF format, and the length itself is the 665 // subsequent eight bytes. 666 static const uint32_t kDwarf64InitialLengthMarker = 0xffffffffU; 667 668 // The CIE identifier for 32- and 64-bit DWARF CFI and .eh_frame data. 669 static const uint32_t kDwarf32CIEIdentifier = ~(uint32_t)0; 670 static const uint64_t kDwarf64CIEIdentifier = ~(uint64_t)0; 671 static const uint32_t kEHFrame32CIEIdentifier = 0; 672 static const uint64_t kEHFrame64CIEIdentifier = 0; 673 674 // The size of a machine address for the data in this section. 675 size_t address_size_; 676 677 // If true, we are generating a Linux .eh_frame section, instead of 678 // a standard DWARF .debug_frame section. 679 bool eh_frame_; 680 681 // The encoding to use for FDE pointers. 682 DwarfPointerEncoding pointer_encoding_; 683 684 // The base addresses to use when emitting encoded pointers. 685 EncodedPointerBases encoded_pointer_bases_; 686 687 // The length value for the current entry. 688 // 689 // Oddly, this must be dynamically allocated. Labels never get new 690 // values; they only acquire constraints on the value they already 691 // have, or assert if you assign them something incompatible. So 692 // each header needs truly fresh Label objects to cite in their 693 // headers and track their positions. The alternative is explicit 694 // destructor invocation and a placement new. Ick. 695 PendingLength* entry_length_; 696 697 // True if we are currently emitting an FDE --- that is, we have 698 // called FDEHeader but have not yet called FinishEntry. 699 bool in_fde_; 700 701 // If in_fde_ is true, this is its starting address. We use this for 702 // emitting DW_EH_PE_funcrel pointers. 703 uint64_t fde_start_address_; 704 }; 705 706 } // namespace lul_test 707 708 #endif // LUL_TEST_INFRASTRUCTURE_H 709