diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cv2pdb.h | 1 | ||||
-rw-r--r-- | src/dwarf2pdb.cpp | 55 | ||||
-rw-r--r-- | src/readDwarf.cpp | 5 | ||||
-rw-r--r-- | src/readDwarf.h | 4 |
4 files changed, 65 insertions, 0 deletions
diff --git a/src/cv2pdb.h b/src/cv2pdb.h index 46f9459..aea458b 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -173,6 +173,7 @@ public: int addDWARFStructure(DWARF_InfoData& id, DWARF_CompilationUnit* cu, DIECursor cursor);
int addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, DIECursor cursor);
int addDWARFBasicType(const char*name, int encoding, int byte_size);
+ int addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIECursor cursor);
int getTypeByDWARFPtr(DWARF_CompilationUnit* cu, byte* ptr);
int getDWARFTypeSize(DWARF_CompilationUnit* cu, byte* ptr);
void getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, DIECursor cursor,
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 2f41d97..63e685e 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -1097,6 +1097,58 @@ int CV2PDB::addDWARFBasicType(const char*name, int encoding, int byte_size) return cvtype;
}
+int CV2PDB::addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIECursor cursor)
+{
+ codeview_reftype* rdtype;
+ codeview_type* dtype;
+
+ checkUserTypeAlloc();
+ checkDWARFTypeAlloc(100);
+
+ int fieldlistType = nextDwarfType++;
+ int count = 0;
+ int basetype = T_INT4;
+
+ rdtype = (codeview_reftype*)(dwarfTypes + cbDwarfTypes);
+ int rdbegin = cbDwarfTypes;
+ rdtype->fieldlist.id = LF_FIELDLIST_V2;
+ rdtype->fieldlist.len = 0;
+ cbDwarfTypes += 4;
+
+ DWARF_InfoData id;
+ while (cursor.readNext(id, true))
+ {
+ if (id.tag == DW_TAG_enumerator && id.has_const_value)
+ {
+ checkDWARFTypeAlloc(kMaxNameLen + 100);
+ codeview_fieldtype* dfieldtype
+ = (codeview_fieldtype*)(dwarfTypes + cbDwarfTypes);
+ cbDwarfTypes += addFieldEnumerate(dfieldtype, id.name, id.const_value);
+ count++;
+ }
+ }
+ rdtype = (codeview_reftype*)(dwarfTypes + rdbegin);
+ rdtype->fieldlist.len += cbDwarfTypes - rdbegin - 2;
+
+ if (enumid.type != 0)
+ {
+ basetype = getTypeByDWARFPtr(cu, enumid.type);
+ }
+ else
+ {
+ // TODO: refactor addDWARFBasicType to reuse the part that creates a
+ // primitive type ID without creating an user type.
+ basetype = T_INT4;
+ }
+
+ dtype = (codeview_type*)(userTypes + cbUserTypes);
+ cbUserTypes += addEnum(dtype, count, fieldlistType, 0, basetype, enumid.name);
+ int enumType = nextUserType++;
+
+ addUdtSymbol(enumType, enumid.name);
+ return enumType;
+}
+
int CV2PDB::getTypeByDWARFPtr(DWARF_CompilationUnit* cu, byte* ptr)
{
std::unordered_map<byte*, int>::iterator it = mapOffsetToType.find(ptr);
@@ -1255,6 +1307,9 @@ bool CV2PDB::createTypes() case DW_TAG_subroutine_type:
case DW_TAG_enumeration_type:
+ cvtype = addDWARFEnum(id, cu, cursor.getSubtreeCursor());
+ break;
+
case DW_TAG_string_type:
case DW_TAG_ptr_to_member_type:
case DW_TAG_set_type:
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp index be1952c..f993f68 100644 --- a/src/readDwarf.cpp +++ b/src/readDwarf.cpp @@ -505,6 +505,11 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull) case DW_AT_location: id.location = a; break;
case DW_AT_frame_base: id.frame_base = a; break;
case DW_AT_language: assert(a.type == Const); id.language = a.cons; break;
+ case DW_AT_const_value:
+ assert(a.type == Const);
+ id.const_value = a.cons;
+ id.has_const_value = true;
+ break;
}
}
diff --git a/src/readDwarf.h b/src/readDwarf.h index 8b9de3d..e2b8eed 100644 --- a/src/readDwarf.h +++ b/src/readDwarf.h @@ -165,6 +165,8 @@ struct DWARF_InfoData long lower_bound;
bool has_lower_bound;
unsigned language;
+ unsigned long const_value;
+ bool has_const_value;
void clear()
{
@@ -195,6 +197,8 @@ struct DWARF_InfoData lower_bound = 0;
has_lower_bound = false;
language = 0;
+ const_value = 0;
+ has_const_value = false;
}
void merge(const DWARF_InfoData& id)
|