summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2016-12-08 01:03:48 +0000
committerGreg Clayton <gclayton@apple.com>2016-12-08 01:03:48 +0000
commit3462a420d1e6c9d28f920c0aadef280a076f5747 (patch)
tree3dcef20d4facfaab07fb63bb7c145bb116d882b0 /llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
parent7fb5e3434b157a159b15d642a677f8531c91c98d (diff)
downloadbcm5719-llvm-3462a420d1e6c9d28f920c0aadef280a076f5747.tar.gz
bcm5719-llvm-3462a420d1e6c9d28f920c0aadef280a076f5747.zip
Make a DWARF generator so we can unit test DWARF APIs with gtest.
The only tests we have for the DWARF parser are the tests that use llvm-dwarfdump and expect output from textual dumps. More DWARF parser modification are coming in the next few weeks and I wanted to add tests that can verify that we can encode and decode all form types, as well as test some other basic DWARF APIs where we ask DIE objects for their children and siblings. DwarfGenerator.cpp was added in the lib/CodeGen directory. This file contains the code necessary to easily create DWARF for tests: dwarfgen::Generator DG; Triple Triple("x86_64--"); bool success = DG.init(Triple, Version); if (!success) return; dwarfgen::CompileUnit &CU = DG.addCompileUnit(); dwarfgen::DIE CUDie = CU.getUnitDIE(); CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c"); CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C); dwarfgen::DIE SubprogramDie = CUDie.addChild(DW_TAG_subprogram); SubprogramDie.addAttribute(DW_AT_name, DW_FORM_strp, "main"); SubprogramDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, 0x1000U); SubprogramDie.addAttribute(DW_AT_high_pc, DW_FORM_addr, 0x2000U); dwarfgen::DIE IntDie = CUDie.addChild(DW_TAG_base_type); IntDie.addAttribute(DW_AT_name, DW_FORM_strp, "int"); IntDie.addAttribute(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed); IntDie.addAttribute(DW_AT_byte_size, DW_FORM_data1, 4); dwarfgen::DIE ArgcDie = SubprogramDie.addChild(DW_TAG_formal_parameter); ArgcDie.addAttribute(DW_AT_name, DW_FORM_strp, "argc"); // ArgcDie.addAttribute(DW_AT_type, DW_FORM_ref4, IntDie); ArgcDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, IntDie); StringRef FileBytes = DG.generate(); MemoryBufferRef FileBuffer(FileBytes, "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); DWARFContextInMemory DwarfContext(*Obj.get()); This code is backed by the AsmPrinter code that emits DWARF for the actual compiler. While adding unit tests it was discovered that DIEValue that used DIEEntry as their values had bugs where DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref8, and DW_FORM_ref_udata forms were not supported. These are all now supported. Added support for DW_FORM_string so we can emit inlined C strings. Centralized the code to unique abbreviations into a new DIEAbbrevSet class and made both the dwarfgen::Generator and the llvm::DwarfFile classes use the new class. Fixed comments in the llvm::DIE class so that the Offset is known to be the compile/type unit offset. DIEInteger now supports more DW_FORM values. There are also unit tests that cover: Encoding and decoding all form types and values Encoding and decoding all reference types (DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8, DW_FORM_ref_udata, DW_FORM_ref_addr) including cross compile unit references with that go forward one compile unit and backward on compile unit. Differential Revision: https://reviews.llvm.org/D27326 llvm-svn: 289010
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp70
1 files changed, 3 insertions, 67 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index 3179ab15420..595f1d91c4b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -19,37 +19,7 @@
namespace llvm {
DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
- : Asm(AP), StrPool(DA, *Asm, Pref) {}
-
-DwarfFile::~DwarfFile() {
- for (DIEAbbrev *Abbrev : Abbreviations)
- Abbrev->~DIEAbbrev();
-}
-
-// Define a unique number for the abbreviation.
-//
-DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) {
- FoldingSetNodeID ID;
- DIEAbbrev Abbrev = Die.generateAbbrev();
- Abbrev.Profile(ID);
-
- void *InsertPos;
- if (DIEAbbrev *Existing =
- AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
- Die.setAbbrevNumber(Existing->getNumber());
- return *Existing;
- }
-
- // Move the abbreviation to the heap and assign a number.
- DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev));
- Abbreviations.push_back(New);
- New->setNumber(Abbreviations.size());
- Die.setAbbrevNumber(Abbreviations.size());
-
- // Store it for lookup.
- AbbreviationsSet.InsertNode(New, InsertPos);
- return *New;
-}
+ : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {}
void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) {
CUs.push_back(std::move(U));
@@ -98,44 +68,10 @@ unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
// Compute the size and offset of a DIE. The offset is relative to start of the
// CU. It returns the offset after laying out the DIE.
unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
- // Record the abbreviation.
- const DIEAbbrev &Abbrev = assignAbbrevNumber(Die);
-
- // Set DIE offset
- Die.setOffset(Offset);
-
- // Start the size with the size of abbreviation code.
- Offset += getULEB128Size(Die.getAbbrevNumber());
-
- // Size the DIE attribute values.
- for (const auto &V : Die.values())
- // Size attribute value.
- Offset += V.SizeOf(Asm);
-
- // Size the DIE children if any.
- if (Die.hasChildren()) {
- (void)Abbrev;
- assert(Abbrev.hasChildren() && "Children flag not set");
-
- for (auto &Child : Die.children())
- Offset = computeSizeAndOffset(Child, Offset);
-
- // End of children marker.
- Offset += sizeof(int8_t);
- }
-
- Die.setSize(Offset - Die.getOffset());
- return Offset;
+ return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset);
}
-void DwarfFile::emitAbbrevs(MCSection *Section) {
- // Check to see if it is worth the effort.
- if (!Abbreviations.empty()) {
- // Start the debug abbrev section.
- Asm->OutStreamer->SwitchSection(Section);
- Asm->emitDwarfAbbrevs(Abbreviations);
- }
-}
+void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); }
// Emit strings into a string section.
void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) {
OpenPOWER on IntegriCloud