#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace dwarf;
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
+
+// Small helper to extract a DIE pointed by a reference
+// attribute. It looks up the Unit containing the DIE and calls
+// DIE.extractFast with the right unit. Returns new unit on success,
+// nullptr otherwise.
+static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE,
+ const DWARFUnit *Unit,
+ uint32_t *Offset) {
+ Unit = Unit->getUnitSection().getUnitForOffset(*Offset);
+ return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr;
+}
-void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
+void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u,
unsigned recurseDepth,
unsigned indent) const {
DataExtractor debug_info_data = u->getDebugInfoExtractor();
}
void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
- const DWARFUnit *u,
+ DWARFUnit *u,
uint32_t *offset_ptr,
uint16_t attr, uint16_t form,
unsigned indent) const {
return;
OS << "\t(";
- formValue.dump(OS, u);
+
+ const char *Name = nullptr;
+ std::string File;
+ if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
+ if (const auto *LT = u->getContext().getLineTableForUnit(u))
+ if (LT->getFileNameByIndex(
+ formValue.getAsUnsignedConstant().getValue(),
+ u->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
+ File = '"' + File + '"';
+ Name = File.c_str();
+ }
+ } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
+ Name = AttributeValueString(attr, *Val);
+
+ if (Name) {
+ OS << Name;
+ } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) {
+ OS << *formValue.getAsUnsignedConstant();
+ } else {
+ formValue.dump(OS, u);
+ }
+
OS << ")\n";
}
return Result.hasValue() ? Result.getValue() : FailValue;
}
+uint64_t
+DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
+ uint64_t FailValue) const {
+ uint64_t Result =
+ getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
+ if (Result != -1ULL)
+ return Result;
+ return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
+}
+
bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
uint64_t &LowPC,
uint64_t &HighPC) const {
}
const char *
-DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
- if (!isSubroutineDIE())
+DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
+ FunctionNameKind Kind) const {
+ if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
return nullptr;
- // Try to get mangled name if possible.
- if (const char *name =
- getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
- return name;
- if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name,
- nullptr))
- return name;
+ // Try to get mangled name only if it was asked for.
+ if (Kind == FunctionNameKind::LinkageName) {
+ if (const char *name =
+ getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
+ return name;
+ if (const char *name =
+ getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
+ return name;
+ }
if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
return name;
// Try to get name from specification DIE.
getAttributeValueAsReference(U, DW_AT_specification, -1U);
if (spec_ref != -1U) {
DWARFDebugInfoEntryMinimal spec_die;
- if (spec_die.extractFast(U, &spec_ref)) {
- if (const char *name = spec_die.getSubroutineName(U))
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) {
+ if (const char *name = spec_die.getSubroutineName(RefU, Kind))
return name;
}
}
getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
if (abs_origin_ref != -1U) {
DWARFDebugInfoEntryMinimal abs_origin_die;
- if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
- if (const char *name = abs_origin_die.getSubroutineName(U))
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U,
+ &abs_origin_ref)) {
+ if (const char *name = abs_origin_die.getSubroutineName(RefU, Kind))
return name;
}
}