mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 19:59:57 +00:00
f4f71cd77b
In my refactoring I introduced a bug where we were using the reference size instead of the offset size for DW_FORM_strp and similar forms. This patch resolves the error and adds a test case testing all the DWARF forms for DWARF2 AddrSize 8. There is similar coverage already in the DWARFDebugInfoTest sources that covers the parser. Once I migrate the DWARFGenerator APIs to be built on the YAML tools they will be fully covered under the same tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297230 91177308-0d34-0410-b5e6-96231b3b80d8
179 lines
5.9 KiB
C++
179 lines
5.9 KiB
C++
//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DWARFVisitor.h"
|
|
#include "llvm/ObjectYAML/DWARFYAML.h"
|
|
|
|
using namespace llvm;
|
|
|
|
template <typename T>
|
|
void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) {
|
|
switch (Size) {
|
|
case 8:
|
|
onValue((uint64_t)U);
|
|
break;
|
|
case 4:
|
|
onValue((uint32_t)U);
|
|
break;
|
|
case 2:
|
|
onValue((uint16_t)U);
|
|
break;
|
|
case 1:
|
|
onValue((uint8_t)U);
|
|
break;
|
|
default:
|
|
llvm_unreachable("Invalid integer write size.");
|
|
}
|
|
}
|
|
|
|
unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
|
|
return Unit.Length.isDWARF64() ? 8 : 4;
|
|
}
|
|
|
|
unsigned getRefSize(const DWARFYAML::Unit &Unit) {
|
|
if (Unit.Version == 2)
|
|
return Unit.AddrSize;
|
|
return getOffsetSize(Unit);
|
|
}
|
|
|
|
template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
|
|
for (auto &Unit : DebugInfo.CompileUnits) {
|
|
onStartCompileUnit(Unit);
|
|
auto FirstAbbrevCode = Unit.Entries[0].AbbrCode;
|
|
|
|
for (auto &Entry : Unit.Entries) {
|
|
onStartDIE(Unit, Entry);
|
|
if (Entry.AbbrCode == 0u)
|
|
continue;
|
|
auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode];
|
|
auto FormVal = Entry.Values.begin();
|
|
auto AbbrForm = Abbrev.Attributes.begin();
|
|
for (;
|
|
FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
|
|
++FormVal, ++AbbrForm) {
|
|
onForm(*AbbrForm, *FormVal);
|
|
dwarf::Form Form = AbbrForm->Form;
|
|
bool Indirect;
|
|
do {
|
|
Indirect = false;
|
|
switch (Form) {
|
|
case dwarf::DW_FORM_addr:
|
|
onVariableSizeValue(FormVal->Value, Unit.AddrSize);
|
|
break;
|
|
case dwarf::DW_FORM_ref_addr:
|
|
onVariableSizeValue(FormVal->Value, getRefSize(Unit));
|
|
break;
|
|
case dwarf::DW_FORM_exprloc:
|
|
case dwarf::DW_FORM_block:
|
|
onValue((uint64_t)FormVal->BlockData.size(), true);
|
|
onValue(
|
|
MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
|
|
FormVal->BlockData.size()),
|
|
""));
|
|
break;
|
|
case dwarf::DW_FORM_block1: {
|
|
auto writeSize = FormVal->BlockData.size();
|
|
onValue((uint8_t)writeSize);
|
|
onValue(
|
|
MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
|
|
FormVal->BlockData.size()),
|
|
""));
|
|
break;
|
|
}
|
|
case dwarf::DW_FORM_block2: {
|
|
auto writeSize = FormVal->BlockData.size();
|
|
onValue((uint16_t)writeSize);
|
|
onValue(
|
|
MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
|
|
FormVal->BlockData.size()),
|
|
""));
|
|
break;
|
|
}
|
|
case dwarf::DW_FORM_block4: {
|
|
auto writeSize = FormVal->BlockData.size();
|
|
onValue((uint32_t)writeSize);
|
|
onValue(
|
|
MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
|
|
FormVal->BlockData.size()),
|
|
""));
|
|
break;
|
|
}
|
|
case dwarf::DW_FORM_data1:
|
|
case dwarf::DW_FORM_ref1:
|
|
case dwarf::DW_FORM_flag:
|
|
case dwarf::DW_FORM_strx1:
|
|
case dwarf::DW_FORM_addrx1:
|
|
onValue((uint8_t)FormVal->Value);
|
|
break;
|
|
case dwarf::DW_FORM_data2:
|
|
case dwarf::DW_FORM_ref2:
|
|
case dwarf::DW_FORM_strx2:
|
|
case dwarf::DW_FORM_addrx2:
|
|
onValue((uint16_t)FormVal->Value);
|
|
break;
|
|
case dwarf::DW_FORM_data4:
|
|
case dwarf::DW_FORM_ref4:
|
|
case dwarf::DW_FORM_ref_sup4:
|
|
case dwarf::DW_FORM_strx4:
|
|
case dwarf::DW_FORM_addrx4:
|
|
onValue((uint32_t)FormVal->Value);
|
|
break;
|
|
case dwarf::DW_FORM_data8:
|
|
case dwarf::DW_FORM_ref8:
|
|
case dwarf::DW_FORM_ref_sup8:
|
|
onValue((uint64_t)FormVal->Value);
|
|
break;
|
|
case dwarf::DW_FORM_sdata:
|
|
onValue((int64_t)FormVal->Value, true);
|
|
break;
|
|
case dwarf::DW_FORM_udata:
|
|
case dwarf::DW_FORM_ref_udata:
|
|
onValue((uint64_t)FormVal->Value, true);
|
|
break;
|
|
case dwarf::DW_FORM_string:
|
|
onValue(FormVal->CStr);
|
|
break;
|
|
case dwarf::DW_FORM_indirect:
|
|
onValue((uint64_t)FormVal->Value, true);
|
|
Indirect = true;
|
|
Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
|
|
++FormVal;
|
|
break;
|
|
case dwarf::DW_FORM_strp:
|
|
case dwarf::DW_FORM_sec_offset:
|
|
case dwarf::DW_FORM_GNU_ref_alt:
|
|
case dwarf::DW_FORM_GNU_strp_alt:
|
|
case dwarf::DW_FORM_line_strp:
|
|
case dwarf::DW_FORM_strp_sup:
|
|
onVariableSizeValue(FormVal->Value, getOffsetSize(Unit));
|
|
break;
|
|
case dwarf::DW_FORM_ref_sig8:
|
|
onValue((uint64_t)FormVal->Value);
|
|
break;
|
|
case dwarf::DW_FORM_GNU_addr_index:
|
|
case dwarf::DW_FORM_GNU_str_index:
|
|
onValue((uint64_t)FormVal->Value, true);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} while (Indirect);
|
|
}
|
|
onEndDIE(Unit, Entry);
|
|
}
|
|
onEndCompileUnit(Unit);
|
|
}
|
|
}
|
|
|
|
// Explicitly instantiate the two template expansions.
|
|
template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
|
|
template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;
|