mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:29:58 +00:00
[obj2yaml] Refactor the .debug_pub* sections dumper.
It's good to reuse the DWARF parser in lib/DebugInfo so that we don't need to maintain a separate parser in client side (obj2yaml). Besides, A test case is added whose length field is a very huge value which makes obj2yaml stuck when parsing the section. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D86192
This commit is contained in:
parent
682842361d
commit
6ada6c96e0
@ -430,3 +430,62 @@ LoadCommands:
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
DWARF:
|
||||
|
||||
## c) Test that obj2yaml is able to dump a __debug_pubnames section whose length field is greater than the section size.
|
||||
|
||||
# RUN: yaml2obj --docnum=3 %s | obj2yaml | FileCheck %s --check-prefix=INVALID-LENGTH
|
||||
|
||||
# INVALID-LENGTH: DWARF:
|
||||
# INVALID-LENGTH-NEXT: debug_pubnames:
|
||||
# INVALID-LENGTH-NEXT: Length: 0x00000000DEADBEEF
|
||||
# INVALID-LENGTH-NEXT: Version: 2
|
||||
# INVALID-LENGTH-NEXT: UnitOffset: 0
|
||||
# INVALID-LENGTH-NEXT: UnitSize: 121
|
||||
# INVALID-LENGTH-NEXT: Entries:
|
||||
# INVALID-LENGTH-NEXT: - DieOffset: 0x0000002A
|
||||
# INVALID-LENGTH-NEXT: Name: main
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x0000000A
|
||||
ncmds: 1
|
||||
sizeofcmds: 1888
|
||||
flags: 0x00000000
|
||||
reserved: 0x00000000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 152
|
||||
segname: __DWARF
|
||||
vmaddr: 0x00000000
|
||||
vmsize: 0x00000000
|
||||
fileoff: 0
|
||||
filesize: 0xffff
|
||||
maxprot: 0
|
||||
initprot: 0
|
||||
nsects: 1
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __debug_pubnames
|
||||
segname: __DWARF
|
||||
addr: 0x0000000000000000
|
||||
size: 24
|
||||
offset: 0x000000b8
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
DWARF:
|
||||
debug_pubnames:
|
||||
Length: 0xdeadbeef
|
||||
Version: 2
|
||||
UnitOffset: 0
|
||||
UnitSize: 121
|
||||
Entries:
|
||||
- DieOffset: 0x0000002A
|
||||
Name: main
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||
@ -118,32 +119,31 @@ Error dumpDebugRanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
return ErrorSuccess();
|
||||
}
|
||||
|
||||
static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
|
||||
const DWARFSection &Section,
|
||||
bool IsGNUStyle) {
|
||||
static Optional<DWARFYAML::PubSection>
|
||||
dumpPubSection(const DWARFContext &DCtx, const DWARFSection &Section,
|
||||
bool IsGNUStyle) {
|
||||
DWARFYAML::PubSection Y;
|
||||
DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
|
||||
DCtx.isLittleEndian(), 0);
|
||||
DWARFYAML::PubSection Y;
|
||||
uint64_t Offset = 0;
|
||||
uint64_t Length = PubSectionData.getU32(&Offset);
|
||||
if (Length == dwarf::DW_LENGTH_DWARF64) {
|
||||
Y.Format = dwarf::DWARF64;
|
||||
Y.Length = PubSectionData.getU64(&Offset);
|
||||
} else {
|
||||
Y.Format = dwarf::DWARF32;
|
||||
Y.Length = Length;
|
||||
}
|
||||
Y.Version = PubSectionData.getU16(&Offset);
|
||||
Y.UnitOffset = PubSectionData.getU32(&Offset);
|
||||
Y.UnitSize = PubSectionData.getU32(&Offset);
|
||||
while (Offset < Y.Length) {
|
||||
DWARFYAML::PubEntry NewEntry;
|
||||
NewEntry.DieOffset = PubSectionData.getU32(&Offset);
|
||||
if (IsGNUStyle)
|
||||
NewEntry.Descriptor = PubSectionData.getU8(&Offset);
|
||||
NewEntry.Name = PubSectionData.getCStr(&Offset);
|
||||
Y.Entries.push_back(NewEntry);
|
||||
}
|
||||
DWARFDebugPubTable Table;
|
||||
// We ignore any errors that don't prevent parsing the section, since we can
|
||||
// still represent such sections.
|
||||
Table.extract(PubSectionData, IsGNUStyle,
|
||||
[](Error Err) { consumeError(std::move(Err)); });
|
||||
ArrayRef<DWARFDebugPubTable::Set> Sets = Table.getData();
|
||||
if (Sets.empty())
|
||||
return None;
|
||||
|
||||
// FIXME: Currently, obj2yaml only supports dumping the first pubtable.
|
||||
Y.Format = Sets[0].Format;
|
||||
Y.Length = Sets[0].Length;
|
||||
Y.Version = Sets[0].Version;
|
||||
Y.UnitOffset = Sets[0].Offset;
|
||||
Y.UnitSize = Sets[0].Size;
|
||||
|
||||
for (const DWARFDebugPubTable::Entry &E : Sets[0].Entries)
|
||||
Y.Entries.push_back(
|
||||
DWARFYAML::PubEntry{E.SecOffset, E.Descriptor.toBits(), E.Name});
|
||||
|
||||
return Y;
|
||||
}
|
||||
@ -151,23 +151,16 @@ static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
|
||||
void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
const DWARFObject &D = DCtx.getDWARFObj();
|
||||
|
||||
const DWARFSection PubNames = D.getPubnamesSection();
|
||||
if (!PubNames.Data.empty())
|
||||
Y.PubNames = dumpPubSection(DCtx, PubNames, /*IsGNUStyle=*/false);
|
||||
|
||||
const DWARFSection PubTypes = D.getPubtypesSection();
|
||||
if (!PubTypes.Data.empty())
|
||||
Y.PubTypes = dumpPubSection(DCtx, PubTypes, /*IsGNUStyle=*/false);
|
||||
|
||||
const DWARFSection GNUPubNames = D.getGnuPubnamesSection();
|
||||
if (!GNUPubNames.Data.empty())
|
||||
// TODO: Test dumping .debug_gnu_pubnames section.
|
||||
Y.GNUPubNames = dumpPubSection(DCtx, GNUPubNames, /*IsGNUStyle=*/true);
|
||||
|
||||
const DWARFSection GNUPubTypes = D.getGnuPubtypesSection();
|
||||
if (!GNUPubTypes.Data.empty())
|
||||
// TODO: Test dumping .debug_gnu_pubtypes section.
|
||||
Y.GNUPubTypes = dumpPubSection(DCtx, GNUPubTypes, /*IsGNUStyle=*/true);
|
||||
Y.PubNames =
|
||||
dumpPubSection(DCtx, D.getPubnamesSection(), /*IsGNUStyle=*/false);
|
||||
Y.PubTypes =
|
||||
dumpPubSection(DCtx, D.getPubtypesSection(), /*IsGNUStyle=*/false);
|
||||
// TODO: Test dumping .debug_gnu_pubnames section.
|
||||
Y.GNUPubNames =
|
||||
dumpPubSection(DCtx, D.getGnuPubnamesSection(), /*IsGNUStyle=*/true);
|
||||
// TODO: Test dumping .debug_gnu_pubtypes section.
|
||||
Y.GNUPubTypes =
|
||||
dumpPubSection(DCtx, D.getGnuPubtypesSection(), /*IsGNUStyle=*/true);
|
||||
}
|
||||
|
||||
void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
|
Loading…
Reference in New Issue
Block a user