Commit 490b287c authored by Lucian Grijincu's avatar Lucian Grijincu Committed by Facebook GitHub Bot

folly::symbolizer: add support for DWARF5

Summary:
folly::symbolizer now supports both DWARF4 and DWARF5 debug info
- http://www.dwarfstd.org/doc/DWARF4.pdf
- http://www.dwarfstd.org/doc/DWARF5.pdf

Split DWARF (Debug Fission)
- with `-fsplit-dwarf-inlining`: folly::symbolizer will use the debug info from the skeleton CU.
- without `-fsplit-dwarf-inlining`: folly::symbolizer won't read .dwo sections and can't symbolize it (yet).

Major things that changed between the standards that affect folly::symbolizer:
- new forms DW_FORM_addrx*, DW_FORM_loclistx, DW_FORM_rnglistx, DW_FORM_strx*, whose values are interpreted against new CU attributes DW_AT_addr_base, DW_AT_loclists_base, DW_AT_rnglists_base, DW_AT_str_offsets_base
- The .debug_line line header format is completely re-written and the constraint that the file register must be >= 1 was lifted.
- DWARF5 `.debug_loclists` replaces DWARF4 `.debug_ranges`

Differential Revision: D25521092

fbshipit-source-id: 5b48e8abed495f379d8b119177913f55ae11bd2b
parent 0c8f7e29
This diff is collapsed.
......@@ -165,6 +165,9 @@ class Dwarf {
/** Get an ELF section by name. */
folly::StringPiece getSection(const char* name) const;
detail::CompilationUnit getCompilationUnit(uint64_t offset) const;
detail::CompilationUnit findCompilationUnit(uint64_t targetOffset) const;
/** cu must exist during the life cycle of created detail::Die. */
detail::Die getDieAtOffset(
const detail::CompilationUnit& cu, uint64_t offset) const;
......@@ -191,6 +194,12 @@ class Dwarf {
*/
detail::DIEAbbreviation getAbbreviation(uint64_t code, uint64_t offset) const;
detail::Attribute readAttribute(
const detail::CompilationUnit& cu,
const detail::Die& die,
detail::AttributeSpec spec,
folly::StringPiece& info) const;
/**
* Iterates over all attributes of a debugging info entry, calling the given
* callable for each. If all attributes are visited, then return the offset of
......@@ -212,18 +221,24 @@ class Dwarf {
* .debug_ranges.
*/
bool isAddrInRangeList(
const detail::CompilationUnit& cu,
uint64_t address,
folly::Optional<uint64_t> baseAddr,
size_t offset,
uint8_t addrSize) const;
const ElfFile* elf_;
const folly::StringPiece debugInfo_; // .debug_info
const folly::StringPiece debugAbbrev_; // .debug_abbrev
const folly::StringPiece debugLine_; // .debug_line
const folly::StringPiece debugStr_; // .debug_str
const folly::StringPiece debugAddr_; // .debug_addr (DWARF 5)
const folly::StringPiece debugAranges_; // .debug_aranges
const folly::StringPiece debugInfo_; // .debug_info
const folly::StringPiece debugLine_; // .debug_line
const folly::StringPiece debugLineStr_; // .debug_line_str (DWARF 5)
const folly::StringPiece debugLoclists_; // .debug_loclists (DWARF 5)
const folly::StringPiece debugRanges_; // .debug_ranges
const folly::StringPiece debugRnglists_; // .debug_rnglists (DWARF 5)
const folly::StringPiece debugStr_; // .debug_str
const folly::StringPiece debugStrOffsets_; // .debug_str_offsets (DWARF 5)
};
class Dwarf::Section {
......@@ -250,15 +265,15 @@ class Dwarf::Section {
class Dwarf::LineNumberVM {
public:
LineNumberVM(
folly::StringPiece data, folly::StringPiece compilationDirectory);
folly::StringPiece data,
folly::StringPiece compilationDirectory,
folly::StringPiece debugStr,
folly::StringPiece debugLineStr);
bool findAddress(uintptr_t target, Path& file, uint64_t& line);
/** Gets full file name at given index including directory. */
Path getFullFileName(uint64_t index) const {
auto fn = getFileName(index);
return Path({}, getIncludeDirectory(fn.directoryIndex), fn.relativeName);
}
Path getFullFileName(uint64_t index) const;
private:
void init();
......@@ -304,6 +319,8 @@ class Dwarf::LineNumberVM {
bool is64Bit_;
folly::StringPiece data_;
folly::StringPiece compilationDirectory_;
folly::StringPiece debugStr_; // needed for DWARF 5
folly::StringPiece debugLineStr_; // DWARF 5
// Header
uint16_t version_;
......@@ -314,11 +331,25 @@ class Dwarf::LineNumberVM {
uint8_t opcodeBase_;
const uint8_t* standardOpcodeLengths_;
folly::StringPiece includeDirectories_;
size_t includeDirectoryCount_;
folly::StringPiece fileNames_;
size_t fileNameCount_;
// 6.2.4 The Line Number Program Header.
struct {
size_t includeDirectoryCount;
folly::StringPiece includeDirectories;
size_t fileNameCount;
folly::StringPiece fileNames;
} v4_;
struct {
uint8_t directoryEntryFormatCount;
folly::StringPiece directoryEntryFormat;
uint64_t directoriesCount;
folly::StringPiece directories;
uint8_t fileNameEntryFormatCount;
folly::StringPiece fileNameEntryFormat;
uint64_t fileNamesCount;
folly::StringPiece fileNames;
} v5_;
// State machine registers
uint64_t address_;
......
......@@ -261,6 +261,8 @@ class ElfFile {
/** Find the section containing the given address */
const ElfShdr* getSectionContainingAddress(ElfAddr addr) const noexcept;
const char* filepath() const { return filepath_; }
private:
OpenResult init() noexcept;
void reset() noexcept;
......
......@@ -151,9 +151,12 @@ void expectFrameEq(
auto demangled = folly::demangle(frame.name);
EXPECT_TRUE(demangled == shortName || demangled == fullName)
<< "Found: demangled=" << demangled
<< " expecting shortName=" << shortName << " or fullName=" << fullName;
<< " expecting shortName=" << shortName << " or fullName=" << fullName
<< " address: " << frame.addr << " hex(address): " << std::hex
<< frame.addr;
EXPECT_EQ(normalizePath(frame.location.file.toString()), normalizePath(file))
<< ' ' << fullName;
<< ' ' << fullName << " address: " << frame.addr
<< " hex(address): " << std::hex << frame.addr;
EXPECT_EQ(frame.location.line, lineno) << ' ' << fullName;
}
......@@ -474,6 +477,12 @@ TEST(Dwarf, FindParameterNames) {
extraInlineFrames,
[&](const folly::StringPiece name) { names.push_back(name); });
if (names.empty()) {
// When using -fsplit-dwarf-inlining info about parameters will not be
// emitted for the inlined debug info.
return;
}
ASSERT_EQ(2, names.size());
ASSERT_EQ("a", names[0]);
ASSERT_EQ("b", names[1]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment