#include "DIE.h"
#include "DwarfDebug.h"
+#include "DwarfUnit.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
using namespace llvm;
case dwarf::DW_FORM_flag_present:
// Emit something to keep the lines and comments in sync.
// FIXME: Is there a better way to do this?
- if (Asm->OutStreamer.hasRawTextSupport())
- Asm->OutStreamer.EmitRawText("");
+ Asm->OutStreamer.AddBlankLine();
return;
case dwarf::DW_FORM_flag: // Fall thru
case dwarf::DW_FORM_ref1: // Fall thru
case dwarf::DW_FORM_ref8: // Fall thru
case dwarf::DW_FORM_ref_sig8: // Fall thru
case dwarf::DW_FORM_data8: return sizeof(int64_t);
- case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer);
- case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer);
- case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
- case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
+ case dwarf::DW_FORM_GNU_str_index: return getULEB128Size(Integer);
+ case dwarf::DW_FORM_GNU_addr_index: return getULEB128Size(Integer);
+ case dwarf::DW_FORM_udata: return getULEB128Size(Integer);
+ case dwarf::DW_FORM_sdata: return getSLEB128Size(Integer);
case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize();
default: llvm_unreachable("DIE Value form not supported yet");
}
///
unsigned DIEDelta::SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
+ if (Form == dwarf::DW_FORM_sec_offset) return 4;
if (Form == dwarf::DW_FORM_strp) return 4;
return AP->getDataLayout().getPointerSize();
}
// specified to be four bytes in the DWARF 32-bit format and eight bytes
// in the DWARF 64-bit format, while DWARF Version 2 specifies that such
// references have the same size as an address on the target system.
- if (AP->getDwarfDebug()->getDwarfVersion() == 2)
+ const DwarfDebug *DD = AP->getDwarfDebug();
+ assert(DD && "Expected Dwarf Debug info to be available");
+ if (DD->getDwarfVersion() == 2)
return AP->getDataLayout().getPointerSize();
return sizeof(int32_t);
}
}
#endif
+//===----------------------------------------------------------------------===//
+// DIETypeSignature Implementation
+//===----------------------------------------------------------------------===//
+void DIETypeSignature::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const {
+ assert(Form == dwarf::DW_FORM_ref_sig8);
+ Asm->OutStreamer.EmitIntValue(Unit.getTypeSignature(), 8);
+}
+
+#ifndef NDEBUG
+void DIETypeSignature::print(raw_ostream &O) const {
+ O << format("Type Unit: 0x%lx", Unit.getTypeSignature());
+}
+
+void DIETypeSignature::dump() const { print(dbgs()); }
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIELoc Implementation
+//===----------------------------------------------------------------------===//
+
+/// ComputeSize - calculate the size of the location expression.
+///
+unsigned DIELoc::ComputeSize(AsmPrinter *AP) const {
+ if (Size)
+ return Size;
+
+ unsigned Sz = 0;
+ const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
+ for (unsigned i = 0, N = Values.size(); i < N; ++i)
+ Sz += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
+
+ return Sz;
+}
+
+/// EmitValue - Emit location data.
+///
+void DIELoc::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const {
+ switch (Form) {
+ default: llvm_unreachable("Improper form for block");
+ case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
+ case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
+ case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
+ case dwarf::DW_FORM_block:
+ case dwarf::DW_FORM_exprloc:
+ Asm->EmitULEB128(Size); break;
+ }
+
+ const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
+ for (unsigned i = 0, N = Values.size(); i < N; ++i)
+ Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
+}
+
+/// SizeOf - Determine size of location data in bytes.
+///
+unsigned DIELoc::SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
+ switch (Form) {
+ case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
+ case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
+ case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
+ case dwarf::DW_FORM_block:
+ case dwarf::DW_FORM_exprloc:
+ return Size + getULEB128Size(Size);
+ default: llvm_unreachable("Improper form for block");
+ }
+}
+
+#ifndef NDEBUG
+void DIELoc::print(raw_ostream &O) const {
+ O << "ExprLoc: ";
+ DIE::print(O, 5);
+}
+#endif
+
//===----------------------------------------------------------------------===//
// DIEBlock Implementation
//===----------------------------------------------------------------------===//
/// ComputeSize - calculate the size of the block.
///
-unsigned DIEBlock::ComputeSize(AsmPrinter *AP) {
- if (!Size) {
- const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
- }
+unsigned DIEBlock::ComputeSize(AsmPrinter *AP) const {
+ if (Size)
+ return Size;
+
+ unsigned Sz = 0;
+ const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
+ for (unsigned i = 0, N = Values.size(); i < N; ++i)
+ Sz += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
- return Size;
+ return Sz;
}
/// EmitValue - Emit block data.
case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
- case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
+ case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
default: llvm_unreachable("Improper form for block");
}
}