X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fexperimental%2Fsymbolizer%2FDwarf.h;h=bc535e2e61c65580b732752407588630e15d53e0;hb=HEAD;hp=3b2615012cddad27e56a2b9d752e485abe7901d8;hpb=5c77fedbef46995a71ffa268c9fcaf49efddd01b;p=folly.git diff --git a/folly/experimental/symbolizer/Dwarf.h b/folly/experimental/symbolizer/Dwarf.h index 3b261501..bc535e2e 100644 --- a/folly/experimental/symbolizer/Dwarf.h +++ b/folly/experimental/symbolizer/Dwarf.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2012-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,12 @@ // DWARF record parser -#ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_DWARF_H_ -#define FOLLY_EXPERIMENTAL_SYMBOLIZER_DWARF_H_ +#pragma once #include -#include "folly/experimental/symbolizer/Elf.h" -#include "folly/Range.h" +#include +#include namespace folly { namespace symbolizer { @@ -41,9 +40,8 @@ namespace symbolizer { * actually support many of the version 4 features (such as VLIW, multiple * operations per instruction) * - * Note that the DWARF record parser does not allocate heap memory at all - * during normal operation (it might in the error case, as throwing exceptions - * uses the heap). This is on purpose: you can use the parser from + * Note that the DWARF record parser does not allocate heap memory at all. + * This is on purpose: you can use the parser from * memory-constrained situations (such as an exception handler for * std::out_of_memory) If it weren't for this requirement, some things would * be much simpler: the Path class would be unnecessary and would be replaced @@ -65,14 +63,22 @@ class Dwarf { */ class Path { public: - Path() { } + Path() {} - Path(folly::StringPiece baseDir, folly::StringPiece subDir, - folly::StringPiece file); + Path( + folly::StringPiece baseDir, + folly::StringPiece subDir, + folly::StringPiece file); - folly::StringPiece baseDir() const { return baseDir_; }; - folly::StringPiece subDir() const { return subDir_; } - folly::StringPiece file() const { return file_; } + folly::StringPiece baseDir() const { + return baseDir_; + } + folly::StringPiece subDir() const { + return subDir_; + } + folly::StringPiece file() const { + return file_; + } size_t size() const; @@ -102,22 +108,39 @@ class Dwarf { folly::StringPiece file_; }; - struct LocationInfo { - LocationInfo() : hasMainFile(false), hasFileAndLine(false), line(0) { } + enum class LocationInfoMode { + // Don't resolve location info. + DISABLED, + // Perform CU lookup using .debug_aranges (might be incomplete). + FAST, + // Scan all CU in .debug_info (slow!) on .debug_aranges lookup failure. + FULL, + }; - bool hasMainFile; + struct LocationInfo { + bool hasMainFile = false; Path mainFile; - bool hasFileAndLine; + bool hasFileAndLine = false; Path file; - uint64_t line; + uint64_t line = 0; }; - /** Find the file and line number information corresponding to address */ - bool findAddress(uintptr_t address, LocationInfo& info) const; + /** + * Find the file and line number information corresponding to address. + */ + bool findAddress(uintptr_t address, LocationInfo& info, LocationInfoMode mode) + const; private: + static bool + findDebugInfoOffset(uintptr_t address, StringPiece aranges, uint64_t& offset); + void init(); + bool findLocation( + uintptr_t address, + StringPiece& infoEntry, + LocationInfo& info) const; const ElfFile* elf_; @@ -127,7 +150,7 @@ class Dwarf { // (yes, DWARF-32 and DWARF-64 sections may coexist in the same file) class Section { public: - Section() : is64Bit_(false) { } + Section() : is64Bit_(false) {} explicit Section(folly::StringPiece d); @@ -136,7 +159,9 @@ class Dwarf { bool next(folly::StringPiece& chunk); // Is the current chunk 64 bit? - bool is64Bit() const { return is64Bit_; } + bool is64Bit() const { + return is64Bit_; + } private: // Yes, 32- and 64- bit sections may coexist. Yikes! @@ -161,8 +186,9 @@ class Dwarf { // Interpreter for the line number bytecode VM class LineNumberVM { public: - LineNumberVM(folly::StringPiece data, - folly::StringPiece compilationDirectory); + LineNumberVM( + folly::StringPiece data, + folly::StringPiece compilationDirectory); bool findAddress(uintptr_t address, Path& file, uint64_t& line); @@ -173,9 +199,9 @@ class Dwarf { // Execute until we commit one new row to the line number matrix bool next(folly::StringPiece& program); enum StepResult { - CONTINUE, // Continue feeding opcodes - COMMIT, // Commit new tuple - END, // End of sequence + CONTINUE, // Continue feeding opcodes + COMMIT, // Commit new tuple + END, // End of sequence }; // Execute one opcode StepResult step(folly::StringPiece& program); @@ -247,10 +273,8 @@ class Dwarf { // Read one attribute value, advance sp typedef boost::variant AttributeValue; - AttributeValue readAttributeValue( - folly::StringPiece& sp, - uint64_t form, - bool is64Bit) const; + AttributeValue + readAttributeValue(folly::StringPiece& sp, uint64_t form, bool is64Bit) const; // Get an ELF section by name, return true if found bool getSection(const char* name, folly::StringPiece* section) const; @@ -258,19 +282,16 @@ class Dwarf { // Get a string from the .debug_str section folly::StringPiece getStringFromStringSection(uint64_t offset) const; - folly::StringPiece info_; // .debug_info - folly::StringPiece abbrev_; // .debug_abbrev - folly::StringPiece aranges_; // .debug_aranges - folly::StringPiece line_; // .debug_line - folly::StringPiece strings_; // .debug_str + folly::StringPiece info_; // .debug_info + folly::StringPiece abbrev_; // .debug_abbrev + folly::StringPiece aranges_; // .debug_aranges + folly::StringPiece line_; // .debug_line + folly::StringPiece strings_; // .debug_str }; inline std::ostream& operator<<(std::ostream& out, const Dwarf::Path& path) { return out << path.toString(); } -} // namespace symbolizer -} // namespace folly - -#endif /* FOLLY_EXPERIMENTAL_SYMBOLIZER_DWARF_H_ */ - +} // namespace symbolizer +} // namespace folly