From 9cd6183c5ecf823517ef6640831b635bfd3f888e Mon Sep 17 00:00:00 2001 From: Alex Budovski Date: Wed, 22 Mar 2023 19:55:11 -0500 Subject: Add comments to various files This is just a preparatory change to improve the documentation in the code. No functional changes. --- src/PEImage.cpp | 6 ++++++ src/dwarf2pdb.cpp | 14 ++++++++++++++ src/readDwarf.cpp | 5 +++++ src/readDwarf.h | 13 +++++++++++++ 4 files changed, 38 insertions(+) diff --git a/src/PEImage.cpp b/src/PEImage.cpp index 247d514..4b39a3f 100644 --- a/src/PEImage.cpp +++ b/src/PEImage.cpp @@ -375,6 +375,7 @@ bool PEImage::_initFromCVDebugDir(IMAGE_DEBUG_DIRECTORY* ddir) } /////////////////////////////////////////////////////////////////////// +// Used for PE (EXE/DLL) files. bool PEImage::initDWARFPtr(bool initDbgDir) { dos = DPV (0); @@ -410,6 +411,7 @@ bool PEImage::initDWARFPtr(bool initDbgDir) return true; } +// Used for COFF objects. bool PEImage::initDWARFObject() { IMAGE_FILE_HEADER* hdr = DPV (0); @@ -466,8 +468,11 @@ void PEImage::initSec(PESection& peSec, int secNo) const peSec.secNo = secNo; } +// Initialize all the DWARF sections present in this PE or COFF file. +// Common to both object and image modules. void PEImage::initDWARFSegments() { + // Scan all the PE sections in this image. for(int s = 0; s < nsec; s++) { const char* name = (const char*) sec[s].Name; @@ -477,6 +482,7 @@ void PEImage::initDWARFSegments() name = strtable + off; } + // Is 'name' one of the DWARF sections? for (const SectionDescriptor *sec_desc : sec_descriptors) { if (!strcmp(name, sec_desc->name)) { PESection& peSec = this->*(sec_desc->pSec); diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 3019856..f759142 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -953,6 +953,7 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DIECursor cursor, int baseo return nfields; } +// Add a class/struct/union to the database. int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DIECursor cursor) { //printf("Adding struct %s, entryoff %d, abbrev %d\n", structid.name, structid.entryOff, structid.abbrev); @@ -1359,6 +1360,8 @@ int CV2PDB::getDWARFTypeSize(const DIECursor& parent, byte* typePtr) return 0; } +// Scan the .debug_info section and allocate type IDs for each unique type and +// create a mapping to look them up by their address. bool CV2PDB::mapTypes() { int typeID = nextUserType; @@ -1367,13 +1370,18 @@ bool CV2PDB::mapTypes() if (debug & DbgBasic) fprintf(stderr, "%s:%d: mapTypes()\n", __FUNCTION__, __LINE__); + // Scan each compilation unit in '.debug_info'. while (off < img.debug_info.length) { DWARF_CompilationUnitInfo cu{}; + + // Read the next compilation unit from 'off' and update it to the next + // CU. byte* ptr = cu.read(debug, img, &off); if (!ptr) continue; + // We only support regular full 'DW_UT_compile' compilation units. if (cu.unit_type != DW_UT_compile) { if (debug & DbgDwarfCompilationUnit) fprintf(stderr, "%s:%d: skipping compilation unit offs=%x, unit_type=%d\n", __FUNCTION__, __LINE__, @@ -1418,6 +1426,7 @@ bool CV2PDB::mapTypes() case DW_TAG_mutable_type: // withdrawn case DW_TAG_shared_type: case DW_TAG_rvalue_reference_type: + // Reserve a typeID and store it in the map for quick lookup. mapOffsetToType.insert(std::make_pair(id.entryPtr, typeID)); typeID++; } @@ -1444,9 +1453,14 @@ bool CV2PDB::createTypes() fprintf(stderr, "%s:%d: createTypes()\n", __FUNCTION__, __LINE__); unsigned long off = 0; + + // Scan each compilation unit in '.debug_info'. while (off < img.debug_info.length) { DWARF_CompilationUnitInfo cu{}; + + // Read the next compilation unit from 'off' and update it to the next + // CU, returning the pointer just beyond the header to the first DIE. byte* ptr = cu.read(debug, img, &off); if (!ptr) continue; diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp index b77a1d0..1058c60 100644 --- a/src/readDwarf.cpp +++ b/src/readDwarf.cpp @@ -34,6 +34,11 @@ void DIECursor::setContext(PEImage* img_, DebugLevel debug_) debug = debug_; } +// Read one compilation unit from `img`'s .debug_info section, starting at +// offset `*off`, updating it in the process to the start of the next one in the +// section. +// Returns a pointer to the first DIE, skipping past the CU header, or NULL +// on failure. byte* DWARF_CompilationUnitInfo::read(DebugLevel debug, const PEImage& img, unsigned long *off) { byte* ptr = img.debug_info.byteAt(*off); diff --git a/src/readDwarf.h b/src/readDwarf.h index 5e1db99..56e89a3 100644 --- a/src/readDwarf.h +++ b/src/readDwarf.h @@ -180,24 +180,37 @@ struct DWARF_FileName } }; +// In-memory representation of a DIE (Debugging Info Entry). struct DWARF_InfoData { + // Pointer into the mapped image section where this DIE is located. byte* entryPtr; + + // Code to find the abbrev entry for this DIE, or 0 if it a sentinel marking + // the end of a sibling chain. int code; + + // Pointer to the abbreviation table entry that corresponds to this DIE. byte* abbrev; int tag; + + // Does this DIE have children? int hasChild; const char* name; const char* linkage_name; const char* dir; unsigned long byte_size; + + // Pointer to the sibling DIE in the mapped image. byte* sibling; unsigned long encoding; unsigned long pclo; unsigned long pchi; unsigned long ranges; // -1u when attribute is not present unsigned long pcentry; + + // Pointer to the DW_AT_type DIE describing the type of this DIE. byte* type; byte* containing_type; byte* specification; -- cgit v0.12