aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp21
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.h4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp36
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h6
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.h8
-rw-r--r--lib/DebugInfo/DWARFContext.cpp6
-rw-r--r--lib/DebugInfo/DWARFContext.h5
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp13
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp28
-rw-r--r--lib/DebugInfo/DWARFFormValue.h2
-rw-r--r--test/DebugInfo/X86/fission-cu.ll8
12 files changed, 120 insertions, 19 deletions
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 32d6cb2..f33f0f9 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -197,6 +197,7 @@ void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const {
case dwarf::DW_FORM_data4: Size = 4; break;
case dwarf::DW_FORM_ref8: // Fall thru
case dwarf::DW_FORM_data8: Size = 8; break;
+ case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;
case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
case dwarf::DW_FORM_addr:
@@ -220,6 +221,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const {
case dwarf::DW_FORM_data4: return sizeof(int32_t);
case dwarf::DW_FORM_ref8: // 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_udata: return MCAsmInfo::getULEB128Size(Integer);
case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize();
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 854d82c..60d7cd3 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -128,6 +128,27 @@ void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
/// reference to the string pool instead of immediate strings so that DIEs have
/// more predictable sizes.
void CompileUnit::addString(DIE *Die, unsigned Attribute, StringRef String) {
+ if (!DD->useSplitDwarf()) {
+ MCSymbol *Symb = DU->getStringPoolEntry(String);
+ DIEValue *Value;
+ if (Asm->needsRelocationsForDwarfStringPool())
+ Value = new (DIEValueAllocator) DIELabel(Symb);
+ else {
+ MCSymbol *StringPool = DU->getStringPoolSym();
+ Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
+ }
+ Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
+ } else {
+ unsigned idx = DU->getStringPoolIndex(String);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
+ Die->addValue(Attribute, dwarf::DW_FORM_GNU_str_index, Value);
+ }
+}
+
+/// addLocalString - Add a string attribute data and value. This is guaranteed
+/// to be in the local string pool instead of indirected.
+void CompileUnit::addLocalString(DIE *Die, unsigned Attribute,
+ StringRef String) {
MCSymbol *Symb = DU->getStringPoolEntry(String);
DIEValue *Value;
if (Asm->needsRelocationsForDwarfStringPool())
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 368234b..f210dcc 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -198,6 +198,10 @@ public:
///
void addString(DIE *Die, unsigned Attribute, const StringRef Str);
+ /// addLocalString - Add a string attribute data and value.
+ ///
+ void addLocalString(DIE *Die, unsigned Attribute, const StringRef Str);
+
/// addLabel - Add a Dwarf label attribute data and value.
///
void addLabel(DIE *Die, unsigned Attribute, unsigned Form,
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 321256a..11b853f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -228,6 +228,16 @@ MCSymbol *DwarfUnits::getStringPoolEntry(StringRef Str) {
return Entry.first = Asm->GetTempSymbol(StringPref, Entry.second);
}
+unsigned DwarfUnits::getStringPoolIndex(StringRef Str) {
+ std::pair<MCSymbol*, unsigned> &Entry =
+ StringPool->GetOrCreateValue(Str).getValue();
+ if (Entry.first) return Entry.second;
+
+ Entry.second = NextStringPoolNumber++;
+ Entry.first = Asm->GetTempSymbol(StringPref, Entry.second);
+ return Entry.second;
+}
+
// Define a unique number for the abbreviation.
//
void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) {
@@ -2116,12 +2126,14 @@ void DwarfDebug::emitDebugPubTypes() {
}
// Emit strings into a string section.
-void DwarfUnits::emitStrings(const MCSection *Section) {
+void DwarfUnits::emitStrings(const MCSection *StrSection,
+ const MCSection *OffsetSection = NULL,
+ const MCSymbol *StrSecSym = NULL) {
if (StringPool->empty()) return;
// Start the dwarf str section.
- Asm->OutStreamer.SwitchSection(Section);
+ Asm->OutStreamer.SwitchSection(StrSection);
// Get all of the string pool entries and put them in an array by their ID so
// we can sort them.
@@ -2144,6 +2156,17 @@ void DwarfUnits::emitStrings(const MCSection *Section) {
Entries[i].second->getKeyLength()+1),
0/*addrspace*/);
}
+
+ // If we've got an offset section go ahead and emit that now as well.
+ if (OffsetSection) {
+ Asm->OutStreamer.SwitchSection(OffsetSection);
+ unsigned offset = 0;
+ unsigned size = 4;
+ for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
+ Asm->OutStreamer.EmitIntValue(offset, size, 0);
+ offset += Entries[i].second->getKeyLength() + 1;
+ }
+ }
}
// Emit visible names into a debug str section.
@@ -2377,7 +2400,7 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) {
DIUnit.getLanguage(), Die, Asm,
this, &SkeletonHolder);
// FIXME: This should be the .dwo file.
- NewCU->addString(Die, dwarf::DW_AT_GNU_dwo_name, FN);
+ NewCU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, FN);
// FIXME: We also need DW_AT_addr_base and DW_AT_dwo_id.
@@ -2393,7 +2416,7 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) {
NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
if (!CompilationDir.empty())
- NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
+ NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
SkeletonHolder.addUnit(NewCU);
@@ -2458,5 +2481,8 @@ void DwarfDebug::emitDebugAbbrevDWO() {
// sections.
void DwarfDebug::emitDebugStrDWO() {
assert(useSplitDwarf() && "No split dwarf?");
- InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection());
+ const MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();
+ const MCSymbol *StrSym = DwarfStrSectionSym;
+ InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
+ OffSec, StrSym);
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 59e4890..cc6c0f7 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -240,7 +240,7 @@ public:
const MCSymbol *);
/// \brief Emit all of the strings to the section given.
- void emitStrings(const MCSection *);
+ void emitStrings(const MCSection *, const MCSection *, const MCSymbol *);
/// \brief Returns the entry into the start of the pool.
MCSymbol *getStringPoolSym();
@@ -249,6 +249,10 @@ public:
/// string text.
MCSymbol *getStringPoolEntry(StringRef Str);
+ /// \brief Returns the index into the string pool with the given
+ /// string text.
+ unsigned getStringPoolIndex(StringRef Str);
+
/// \brief Returns the string pool.
StrPool *getStringPool() { return StringPool; }
};
diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h
index ba638df..c58664f 100644
--- a/lib/DebugInfo/DWARFCompileUnit.h
+++ b/lib/DebugInfo/DWARFCompileUnit.h
@@ -28,6 +28,7 @@ class DWARFCompileUnit {
StringRef AbbrevSection;
StringRef RangeSection;
StringRef StringSection;
+ StringRef StringOffsetSection;
const RelocAddrMap *RelocMap;
bool isLittleEndian;
@@ -42,13 +43,16 @@ class DWARFCompileUnit {
public:
DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
- StringRef RS, StringRef SS, const RelocAddrMap *M, bool LE) :
+ StringRef RS, StringRef SS, StringRef SOS,
+ const RelocAddrMap *M, bool LE) :
Abbrev(DA), InfoSection(IS), AbbrevSection(AS),
- RangeSection(RS), StringSection(SS), RelocMap(M), isLittleEndian(LE) {
+ RangeSection(RS), StringSection(SS), StringOffsetSection(SOS),
+ RelocMap(M), isLittleEndian(LE) {
clear();
}
StringRef getStringSection() const { return StringSection; }
+ StringRef getStringOffsetSection() const { return StringOffsetSection; }
const RelocAddrMap *getRelocMap() const { return RelocMap; }
DataExtractor getDebugInfoExtractor() const;
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 1270e6e..d6d9fcf 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -152,7 +152,8 @@ void DWARFContext::parseCompileUnits() {
while (DIData.isValidOffset(offset)) {
CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
getAbbrevSection(), getRangeSection(),
- getStringSection(), &infoRelocMap(),
+ getStringSection(), "",
+ &infoRelocMap(),
isLittleEndian()));
if (!CUs.back().extract(DIData, &offset)) {
CUs.pop_back();
@@ -172,6 +173,7 @@ void DWARFContext::parseDWOCompileUnits() {
getAbbrevDWOSection(),
getRangeDWOSection(),
getStringDWOSection(),
+ getStringOffsetDWOSection(),
&infoDWORelocMap(),
isLittleEndian()));
if (!DWOCUs.back().extract(DIData, &offset)) {
@@ -382,6 +384,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
AbbrevDWOSection = data;
else if (name == "debug_str.dwo")
StringDWOSection = data;
+ else if (name == "debug_str_offsets.dwo")
+ StringOffsetDWOSection = data;
// Any more debug info sections go here.
else
continue;
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index 0c3eb30..c6d6283 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -106,6 +106,7 @@ public:
virtual StringRef getInfoDWOSection() = 0;
virtual StringRef getAbbrevDWOSection() = 0;
virtual StringRef getStringDWOSection() = 0;
+ virtual StringRef getStringOffsetDWOSection() = 0;
virtual StringRef getRangeDWOSection() = 0;
virtual const RelocAddrMap &infoDWORelocMap() const = 0;
@@ -140,6 +141,7 @@ class DWARFContextInMemory : public DWARFContext {
StringRef InfoDWOSection;
StringRef AbbrevDWOSection;
StringRef StringDWOSection;
+ StringRef StringOffsetDWOSection;
StringRef RangeDWOSection;
public:
@@ -157,6 +159,9 @@ public:
virtual StringRef getInfoDWOSection() { return InfoDWOSection; }
virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; }
virtual StringRef getStringDWOSection() { return StringDWOSection; }
+ virtual StringRef getStringOffsetDWOSection() {
+ return StringOffsetDWOSection;
+ }
virtual StringRef getRangeDWOSection() { return RangeDWOSection; }
virtual const RelocAddrMap &infoDWORelocMap() const { return InfoDWORelocMap; }
};
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index c083b8c..bb11850 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -12,6 +12,7 @@
#include "DWARFContext.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFFormValue.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -113,9 +114,14 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
uint32_t i;
uint16_t form;
for (i=0; i<numAttributes; ++i) {
+
form = AbbrevDecl->getFormByIndex(i);
- const uint8_t fixed_skip_size = fixed_form_sizes[form];
+ // FIXME: Currently we're checking if this is less than the last
+ // entry in the fixed_form_sizes table, but this should be changed
+ // to use dynamic dispatch.
+ const uint8_t fixed_skip_size = (form < DW_FORM_ref_sig8) ?
+ fixed_form_sizes[form] : 0;
if (fixed_skip_size)
offset += fixed_skip_size;
else {
@@ -187,6 +193,8 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
debug_info_data.getULEB128(&offset);
break;
@@ -207,7 +215,6 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
return false;
}
offset += form_size;
-
} while (form_is_indirect);
}
}
@@ -327,6 +334,8 @@ DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu,
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
debug_info_data.getULEB128(&offset);
break;
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index 1610db2..47fad8b 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARFFormValue.cpp
@@ -46,8 +46,6 @@ static const uint8_t form_sizes_addr4[] = {
0, // 0x18 DW_FORM_exprloc
0, // 0x19 DW_FORM_flag_present
8, // 0x20 DW_FORM_ref_sig8
- 4, // 0x1f01 DW_FORM_GNU_addr_index
- 4, // 0x1f02 DW_FORM_GNU_str_index
};
static const uint8_t form_sizes_addr8[] = {
@@ -78,8 +76,6 @@ static const uint8_t form_sizes_addr8[] = {
0, // 0x18 DW_FORM_exprloc
0, // 0x19 DW_FORM_flag_present
8, // 0x20 DW_FORM_ref_sig8
- 8, // 0x1f01 DW_FORM_GNU_addr_index
- 8, // 0x1f01 DW_FORM_GNU_str_index
};
const uint8_t *
@@ -295,6 +291,8 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
debug_info_data.getULEB128(offset_ptr);
return true;
@@ -321,6 +319,7 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
void
DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
DataExtractor debug_str_data(cu->getStringSection(), true, 0);
+ DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
uint64_t uvalue = getUnsigned();
bool cu_relative_offset = false;
@@ -379,6 +378,17 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
}
break;
}
+ case DW_FORM_GNU_str_index: {
+ OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
+ const char *dbg_str = getIndirectCString(&debug_str_data,
+ &debug_str_offset_data);
+ if (dbg_str) {
+ OS << '"';
+ OS.write_escaped(dbg_str);
+ OS << '"';
+ }
+ break;
+ }
case DW_FORM_ref_addr:
OS << format("0x%016" PRIx64, uvalue);
break;
@@ -436,6 +446,16 @@ DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
return NULL;
}
+const char*
+DWARFFormValue::getIndirectCString(const DataExtractor *DS,
+ const DataExtractor *DSO) const {
+ if (!DS || !DSO) return NULL;
+
+ uint32_t offset = Value.uval * 4;
+ uint32_t soffset = DSO->getULEB128(&offset);
+ return DS->getCStr(&soffset);
+}
+
uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
uint64_t die_offset = Value.uval;
switch (Form) {
diff --git a/lib/DebugInfo/DWARFFormValue.h b/lib/DebugInfo/DWARFFormValue.h
index c5b590d..7768c18 100644
--- a/lib/DebugInfo/DWARFFormValue.h
+++ b/lib/DebugInfo/DWARFFormValue.h
@@ -64,6 +64,8 @@ public:
uint64_t getUnsigned() const { return Value.uval; }
int64_t getSigned() const { return Value.sval; }
const char *getAsCString(const DataExtractor *debug_str_data_ptr) const;
+ const char *getIndirectCString(const DataExtractor *,
+ const DataExtractor *) const;
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
const DWARFCompileUnit *cu) const;
static bool skipValue(uint16_t form, DataExtractor debug_info_data,
diff --git a/test/DebugInfo/X86/fission-cu.ll b/test/DebugInfo/X86/fission-cu.ll
index 22f59dd..3ada3ef 100644
--- a/test/DebugInfo/X86/fission-cu.ll
+++ b/test/DebugInfo/X86/fission-cu.ll
@@ -30,10 +30,10 @@
; FIXME: Strings will ultimately be a different form.
; CHECK: .debug_info.dwo contents:
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_producer [DW_FORM_strp]
+; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000000) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)")
; CHECK: DW_AT_language [DW_FORM_data2] (0x000c)
-; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000035] = "baz.c")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000001) string = "baz.c")
; CHECK: DW_TAG_base_type
-; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000061] = "int")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "int")
; CHECK: DW_TAG_variable
-; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000005f] = "a")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "a")