From 6f47f877b7b29c6fe8169a5dd7bced5fd68e9b49 Mon Sep 17 00:00:00 2001 From: sagitario Date: Sat, 3 Mar 2012 08:15:49 +0000 Subject: tabify --- src/PEImage.cpp | 196 +-- src/PEImage.h | 46 +- src/cv2pdb.cpp | 86 +- src/cv2pdb.h | 72 +- src/cvutil.cpp | 56 +- src/demangle.cpp | 6 +- src/dviewhelper/dviewhelper.cpp | 60 +- src/dwarf2pdb.cpp | 2794 +++++++++++++++++++-------------------- src/main.cpp | 74 +- src/symutil.cpp | 32 +- 10 files changed, 1711 insertions(+), 1711 deletions(-) diff --git a/src/PEImage.cpp b/src/PEImage.cpp index 2d6f03f..1a9afbd 100644 --- a/src/PEImage.cpp +++ b/src/PEImage.cpp @@ -103,16 +103,16 @@ bool PEImage::replaceDebugSection (const void* data, int datalen, bool initCV) { // append new debug directory to data IMAGE_DEBUG_DIRECTORY debugdir; - if(dbgDir) - debugdir = *dbgDir; - else - memset(&debugdir, 0, sizeof(debugdir)); + if(dbgDir) + debugdir = *dbgDir; + else + memset(&debugdir, 0, sizeof(debugdir)); int xdatalen = datalen + sizeof(debugdir); // assume there is place for another section because of section alignment int s; DWORD lastVirtualAddress = 0; - int cntSections = countSections(); + int cntSections = countSections(); for(s = 0; s < cntSections; s++) { if (strcmp ((char*) sec [s].Name, ".debug") == 0) @@ -128,7 +128,7 @@ bool PEImage::replaceDebugSection (const void* data, int datalen, bool initCV) lastVirtualAddress = sec [s].VirtualAddress + sec[s].Misc.VirtualSize; } - int align = IMGHDR(OptionalHeader.FileAlignment); + int align = IMGHDR(OptionalHeader.FileAlignment); int align_len = xdatalen; int fill = 0; @@ -142,7 +142,7 @@ bool PEImage::replaceDebugSection (const void* data, int datalen, bool initCV) return setError("cannot alloc new image"); int salign_len = xdatalen; - align = IMGHDR(OptionalHeader.SectionAlignment); + align = IMGHDR(OptionalHeader.SectionAlignment); if (align > 0) { lastVirtualAddress = ((lastVirtualAddress + align - 1) / align) * align; @@ -165,17 +165,17 @@ bool PEImage::replaceDebugSection (const void* data, int datalen, bool initCV) IMGHDR(OptionalHeader.SizeOfImage) = sec[s].VirtualAddress + salign_len; IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress) = lastVirtualAddress + datalen; - IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size) = sizeof(IMAGE_DEBUG_DIRECTORY); + IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size) = sizeof(IMAGE_DEBUG_DIRECTORY); // append debug data chunk to existing file image memcpy(newdata, dump_base, dump_total_len); memset(newdata + dump_total_len, 0, fill); memcpy(newdata + dump_total_len + fill, data, datalen); - if(!dbgDir) - { - debugdir.Type = 2; - } + if(!dbgDir) + { + debugdir.Type = 2; + } dbgDir = (IMAGE_DEBUG_DIRECTORY*) (newdata + dump_total_len + fill + datalen); memcpy(dbgDir, &debugdir, sizeof(debugdir)); @@ -208,26 +208,26 @@ bool PEImage::initCVPtr(bool initDbgDir) hdr64 = DPV (dos->e_lfanew); if(!hdr32) return setError("no optional header found"); - if(hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || - hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) - hdr32 = 0; - else - hdr64 = 0; + if(hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || + hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) + hdr32 = 0; + else + hdr64 = 0; - if(IMGHDR(Signature) != IMAGE_NT_SIGNATURE) - return setError("optional header does not have PE signature"); - if(IMGHDR(FileHeader.SizeOfOptionalHeader) < sizeof(IMAGE_OPTIONAL_HEADER32)) - return setError("optional header too small"); + if(IMGHDR(Signature) != IMAGE_NT_SIGNATURE) + return setError("optional header does not have PE signature"); + if(IMGHDR(FileHeader.SizeOfOptionalHeader) < sizeof(IMAGE_OPTIONAL_HEADER32)) + return setError("optional header too small"); - sec = hdr32 ? IMAGE_FIRST_SECTION(hdr32) : IMAGE_FIRST_SECTION(hdr64); + sec = hdr32 ? IMAGE_FIRST_SECTION(hdr32) : IMAGE_FIRST_SECTION(hdr64); - if(IMGHDR(OptionalHeader.NumberOfRvaAndSizes) <= IMAGE_DIRECTORY_ENTRY_DEBUG) - return setError("too few entries in data directory"); + if(IMGHDR(OptionalHeader.NumberOfRvaAndSizes) <= IMAGE_DIRECTORY_ENTRY_DEBUG) + return setError("too few entries in data directory"); - if(IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size) != 0x1c) - return setError("unexpected size of DEBUG data directory entry"); + if(IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size) != 0x1c) + return setError("unexpected size of DEBUG data directory entry"); - int off = IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress); + int off = IMGHDR(OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress); dbgDir = RVA(off, 0x1c); if (!dbgDir) return setError("debug directory not placed in image"); @@ -271,86 +271,86 @@ bool PEImage::initDWARFPtr(bool initDbgDir) hdr64 = DPV (dos->e_lfanew); if(!hdr32) return setError("no optional header found"); - if(hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || - hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) - hdr32 = 0; - else - hdr64 = 0; - - if(IMGHDR(Signature) != IMAGE_NT_SIGNATURE) - return setError("optional header does not have PE signature"); - if(IMGHDR(FileHeader.SizeOfOptionalHeader) < sizeof(IMAGE_OPTIONAL_HEADER32)) - return setError("optional header too small"); - - dbgDir = 0; - sec = hdr32 ? IMAGE_FIRST_SECTION(hdr32) : IMAGE_FIRST_SECTION(hdr64); - int nsec = IMGHDR(FileHeader.NumberOfSections); - const char* strtable = DPV(IMGHDR(FileHeader.PointerToSymbolTable) + IMGHDR(FileHeader.NumberOfSymbols) * IMAGE_SIZEOF_SYMBOL); - for(int s = 0; s < nsec; s++) - { - const char* name = (const char*) sec[s].Name; - if(name[0] == '/') - { - int off = strtol(name + 1, 0, 10); - name = strtable + off; - } - if(strcmp(name, ".debug_aranges") == 0) - debug_aranges = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_pubnames") == 0) - debug_pubnames = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_pubtypes") == 0) - debug_pubtypes = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_info") == 0) - debug_info = DPV(sec[s].PointerToRawData, debug_info_length = sec[s].Misc.VirtualSize); - if(strcmp(name, ".debug_abbrev") == 0) - debug_abbrev = DPV(sec[s].PointerToRawData, debug_abbrev_length = sec[s].Misc.VirtualSize); - if(strcmp(name, ".debug_line") == 0) - debug_line = DPV(sec[s].PointerToRawData, debug_line_length = sec[s].Misc.VirtualSize); - if(strcmp(name, ".debug_frame") == 0) - debug_frame = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_str") == 0) - debug_str = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_loc") == 0) - debug_loc = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); - if(strcmp(name, ".debug_ranges") == 0) - debug_ranges = DPV(sec[s].PointerToRawData, debug_ranges_length = sec[s].Misc.VirtualSize); - if(strcmp(name, ".reloc") == 0) - reloc = DPV(sec[s].PointerToRawData, reloc_length = sec[s].Misc.VirtualSize); - if(strcmp(name, ".text") == 0) - codeSegment = s; - } - - setError(0); - - return true; + if(hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || + hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) + hdr32 = 0; + else + hdr64 = 0; + + if(IMGHDR(Signature) != IMAGE_NT_SIGNATURE) + return setError("optional header does not have PE signature"); + if(IMGHDR(FileHeader.SizeOfOptionalHeader) < sizeof(IMAGE_OPTIONAL_HEADER32)) + return setError("optional header too small"); + + dbgDir = 0; + sec = hdr32 ? IMAGE_FIRST_SECTION(hdr32) : IMAGE_FIRST_SECTION(hdr64); + int nsec = IMGHDR(FileHeader.NumberOfSections); + const char* strtable = DPV(IMGHDR(FileHeader.PointerToSymbolTable) + IMGHDR(FileHeader.NumberOfSymbols) * IMAGE_SIZEOF_SYMBOL); + for(int s = 0; s < nsec; s++) + { + const char* name = (const char*) sec[s].Name; + if(name[0] == '/') + { + int off = strtol(name + 1, 0, 10); + name = strtable + off; + } + if(strcmp(name, ".debug_aranges") == 0) + debug_aranges = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_pubnames") == 0) + debug_pubnames = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_pubtypes") == 0) + debug_pubtypes = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_info") == 0) + debug_info = DPV(sec[s].PointerToRawData, debug_info_length = sec[s].Misc.VirtualSize); + if(strcmp(name, ".debug_abbrev") == 0) + debug_abbrev = DPV(sec[s].PointerToRawData, debug_abbrev_length = sec[s].Misc.VirtualSize); + if(strcmp(name, ".debug_line") == 0) + debug_line = DPV(sec[s].PointerToRawData, debug_line_length = sec[s].Misc.VirtualSize); + if(strcmp(name, ".debug_frame") == 0) + debug_frame = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_str") == 0) + debug_str = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_loc") == 0) + debug_loc = DPV(sec[s].PointerToRawData, sec[s].SizeOfRawData); + if(strcmp(name, ".debug_ranges") == 0) + debug_ranges = DPV(sec[s].PointerToRawData, debug_ranges_length = sec[s].Misc.VirtualSize); + if(strcmp(name, ".reloc") == 0) + reloc = DPV(sec[s].PointerToRawData, reloc_length = sec[s].Misc.VirtualSize); + if(strcmp(name, ".text") == 0) + codeSegment = s; + } + + setError(0); + + return true; } int PEImage::findSection(unsigned int off) const { - off -= IMGHDR(OptionalHeader.ImageBase); - int nsec = IMGHDR(FileHeader.NumberOfSections); + off -= IMGHDR(OptionalHeader.ImageBase); + int nsec = IMGHDR(FileHeader.NumberOfSections); for(int s = 0; s < nsec; s++) - if(sec[s].VirtualAddress <= off && off < sec[s].VirtualAddress + sec[s].Misc.VirtualSize) - return s; - return -1; + if(sec[s].VirtualAddress <= off && off < sec[s].VirtualAddress + sec[s].Misc.VirtualSize) + return s; + return -1; } int PEImage::findSymbol(const char* name, unsigned long& off) const { - IMAGE_SYMBOL* symtable = DPV(IMGHDR(FileHeader.PointerToSymbolTable)); - int syms = IMGHDR(FileHeader.NumberOfSymbols); - const char* strtable = (const char*) (symtable + syms); - for(int i = 0; i < syms; i++) - { - IMAGE_SYMBOL* sym = symtable + i; - const char* symname = sym->N.Name.Short == 0 ? strtable + sym->N.Name.Long : (char*)sym->N.ShortName; - if(strcmp(symname, name) == 0 || (symname[0] == '_' && strcmp(symname + 1, name) == 0)) - { - off = sym->Value; - return sym->SectionNumber; - } - } - return -1; + IMAGE_SYMBOL* symtable = DPV(IMGHDR(FileHeader.PointerToSymbolTable)); + int syms = IMGHDR(FileHeader.NumberOfSymbols); + const char* strtable = (const char*) (symtable + syms); + for(int i = 0; i < syms; i++) + { + IMAGE_SYMBOL* sym = symtable + i; + const char* symname = sym->N.Name.Short == 0 ? strtable + sym->N.Name.Long : (char*)sym->N.ShortName; + if(strcmp(symname, name) == 0 || (symname[0] == '_' && strcmp(symname + 1, name) == 0)) + { + off = sym->Value; + return sym->SectionNumber; + } + } + return -1; } /////////////////////////////////////////////////////////////////////// diff --git a/src/PEImage.h b/src/PEImage.h index f3c5511..a2009aa 100644 --- a/src/PEImage.h +++ b/src/PEImage.h @@ -50,7 +50,7 @@ public: for (int i = 0; i < hdr->FileHeader.NumberOfSections; i++) { if (rva >= sec[i].VirtualAddress && - rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData) + rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData) return DPV

(sec[i].PointerToRawData + rva - sec[i].VirtualAddress, len); } return 0; @@ -63,8 +63,8 @@ public: bool initCVPtr(bool initDbgDir); bool initDWARFPtr(bool initDbgDir); - bool hasDWARF() const { return debug_line != 0; } - bool isX64() const { return hdr64 != 0; } + bool hasDWARF() const { return debug_line != 0; } + bool isX64() const { return hdr64 != 0; } int countCVEntries() const; OMFDirEntry* getCVEntry(int i) const; @@ -75,18 +75,18 @@ public: static void* alloc_aligned(unsigned int size, unsigned int align, unsigned int alignoff = 0); static void free_aligned(void* p); - int countSections() const { return IMGHDR(FileHeader.NumberOfSections); } - int findSection(unsigned int off) const; - int findSymbol(const char* name, unsigned long& off) const; - const IMAGE_SECTION_HEADER& getSection(int s) const { return sec[s]; } - unsigned long long getImageBase() const { return IMGHDR(OptionalHeader.ImageBase); } + int countSections() const { return IMGHDR(FileHeader.NumberOfSections); } + int findSection(unsigned int off) const; + int findSymbol(const char* name, unsigned long& off) const; + const IMAGE_SECTION_HEADER& getSection(int s) const { return sec[s]; } + unsigned long long getImageBase() const { return IMGHDR(OptionalHeader.ImageBase); } private: int fd; void* dump_base; int dump_total_len; - // codeview + // codeview IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS32* hdr32; IMAGE_NT_HEADERS64* hdr64; @@ -96,20 +96,20 @@ private: OMFDirEntry* dirEntry; public: - //dwarf - char* debug_aranges; - char* debug_pubnames; - char* debug_pubtypes; - char* debug_info; unsigned long debug_info_length; - char* debug_abbrev; unsigned long debug_abbrev_length; - char* debug_line; unsigned long debug_line_length; - char* debug_frame; - char* debug_str; - char* debug_loc; - char* debug_ranges; unsigned long debug_ranges_length; - char* reloc; unsigned long reloc_length; - - int codeSegment; + //dwarf + char* debug_aranges; + char* debug_pubnames; + char* debug_pubtypes; + char* debug_info; unsigned long debug_info_length; + char* debug_abbrev; unsigned long debug_abbrev_length; + char* debug_line; unsigned long debug_line_length; + char* debug_frame; + char* debug_str; + char* debug_loc; + char* debug_ranges; unsigned long debug_ranges_length; + char* reloc; unsigned long reloc_length; + + int codeSegment; int cv_base; }; diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index 17a7b92..aa6380c 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -34,7 +34,7 @@ CV2PDB::CV2PDB(PEImage& image) memset(translatedTypedefs, 0, sizeof(translatedTypedefs)); cntTypedefs = 0; nextUserType = 0x1000; - nextDwarfType = 0x1000; + nextDwarfType = 0x1000; addClassTypeEnum = true; addStringViewHelper = false; @@ -80,7 +80,7 @@ bool CV2PDB::cleanup(bool commit) free(userTypes); if (udtSymbols) free(udtSymbols); - if (dwarfTypes) + if (dwarfTypes) free(dwarfTypes); delete [] pointerTypes; @@ -1406,7 +1406,7 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType) int dataptrType = nextUserType++; int dstringType = 0; - if(addStringViewHelper && + if(addStringViewHelper && (strcmp(name, "string") == 0 || strcmp(name, "wstring") == 0 || strcmp(name, "dstring") == 0)) { // nextUserType + 1: field list (size, array) @@ -1747,16 +1747,16 @@ int CV2PDB::appendModifierType(int type, int attr) checkUserTypeAlloc(); codeview_type* dtype = (codeview_type*) (userTypes + cbUserTypes); - dtype->modifier_v2.id = LF_MODIFIER_V2; + dtype->modifier_v2.id = LF_MODIFIER_V2; dtype->modifier_v2.type = translateType(type); dtype->modifier_v2.attribute = attr; - int len = sizeof(dtype->modifier_v2); + int len = sizeof(dtype->modifier_v2); //for (; len & 3; len++) // userTypes[cbUserTypes + len] = 0xf4 - (len & 3); dtype->modifier_v2.len = len - 2; - cbUserTypes += len; + cbUserTypes += len; - nextUserType++; + nextUserType++; return nextUserType - 1; } @@ -1894,9 +1894,9 @@ bool CV2PDB::isCppInterface(const codeview_type* cvtype) bool CV2PDB::isClassType(int type) { - if(const codeview_type* cvt = getTypeData(type)) - return isClass(cvt); - return false; + if(const codeview_type* cvt = getTypeData(type)) + return isClass(cvt); + return false; } void CV2PDB::ensureUDT(int type, const codeview_type* cvtype) @@ -1933,8 +1933,8 @@ void CV2PDB::ensureUDT(int type, const codeview_type* cvtype) int CV2PDB::createEmptyFieldListType() { - if(emptyFieldListType > 0) - return emptyFieldListType; + if(emptyFieldListType > 0) + return emptyFieldListType; checkUserTypeAlloc(); codeview_reftype* rdtype = (codeview_reftype*) (userTypes + cbUserTypes); @@ -1943,7 +1943,7 @@ int CV2PDB::createEmptyFieldListType() cbUserTypes += rdtype->fieldlist.len + 2; emptyFieldListType = nextUserType++; - return emptyFieldListType; + return emptyFieldListType; } int CV2PDB::appendTypedef(int type, const char* name, bool saveTranslation) @@ -1952,34 +1952,34 @@ int CV2PDB::appendTypedef(int type, const char* name, bool saveTranslation) if(type == 0x78) basetype = 0x75; // dchar type not understood by debugger, use uint instead - int typedefType; - if(useTypedefEnum) - { - checkUserTypeAlloc(); - - int fieldlistType = createEmptyFieldListType(); - - codeview_type* dtype = (codeview_type*) (userTypes + cbUserTypes); - dtype->enumeration_v2.id = (v3 ? LF_ENUM_V3 : LF_ENUM_V2); - dtype->enumeration_v2.type = basetype; - dtype->enumeration_v2.fieldlist = fieldlistType; - dtype->enumeration_v2.count = 0; - dtype->enumeration_v2.property = kPropReserved2; - int len = cstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, name); - len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); - writeUserTypeLen(dtype, len); - typedefType = nextUserType++; - } - else - { - typedefType = appendModifierType(type, 0); - } - if(saveTranslation) - { - typedefs[cntTypedefs] = type; - translatedTypedefs[cntTypedefs] = typedefType; - cntTypedefs++; - } + int typedefType; + if(useTypedefEnum) + { + checkUserTypeAlloc(); + + int fieldlistType = createEmptyFieldListType(); + + codeview_type* dtype = (codeview_type*) (userTypes + cbUserTypes); + dtype->enumeration_v2.id = (v3 ? LF_ENUM_V3 : LF_ENUM_V2); + dtype->enumeration_v2.type = basetype; + dtype->enumeration_v2.fieldlist = fieldlistType; + dtype->enumeration_v2.count = 0; + dtype->enumeration_v2.property = kPropReserved2; + int len = cstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, name); + len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); + writeUserTypeLen(dtype, len); + typedefType = nextUserType++; + } + else + { + typedefType = appendModifierType(type, 0); + } + if(saveTranslation) + { + typedefs[cntTypedefs] = type; + translatedTypedefs[cntTypedefs] = typedefType; + cntTypedefs++; + } return typedefType; } @@ -2962,7 +2962,7 @@ codeview_symbol* CV2PDB::findUdtSymbol(const char* name) for(int p = 0; p < cbGlobalSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (globalSymbols + p); - if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) + if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) return sym; p += sym->common.len + 2; } @@ -2994,7 +2994,7 @@ void CV2PDB::checkUdtSymbolAlloc(int size, int add) bool CV2PDB::addUdtSymbol(int type, const char* name) { - checkUdtSymbolAlloc(100 + kMaxNameLen); + checkUdtSymbolAlloc(100 + kMaxNameLen); // no need to convert to udt_v2/udt_v3, the debugger is fine with it. codeview_symbol* sym = (codeview_symbol*) (udtSymbols + cbUdtSymbols); diff --git a/src/cv2pdb.h b/src/cv2pdb.h index 0dc6a44..1adbe61 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -49,7 +49,7 @@ public: int _doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reftype* fieldlist, int arg); int addFields(codeview_reftype* dfieldlist, const codeview_reftype* fieldlist, int maxdlen); int countFields(const codeview_reftype* fieldlist); - int countNestedTypes(const codeview_reftype* fieldlist, int type); + int countNestedTypes(const codeview_reftype* fieldlist, int type); int addAggregate(codeview_type* dtype, bool clss, int n_element, int fieldlist, int property, int derived, int vshape, int structlen, const char*name); @@ -70,8 +70,8 @@ public: void checkUserTypeAlloc(int size = 1000, int add = 10000); void checkGlobalTypeAlloc(int size, int add = 1000); - void checkUdtSymbolAlloc(int size, int add = 10000); - void checkDWARFTypeAlloc(int size, int add = 10000); + void checkUdtSymbolAlloc(int size, int add = 10000); + void checkDWARFTypeAlloc(int size, int add = 10000); void writeUserTypeLen(codeview_type* type, int len); const codeview_type* getTypeData(int type); @@ -80,7 +80,7 @@ public: const codeview_type* findCompleteClassType(const codeview_type* cvtype, int* ptype = 0); int findMemberFunctionType(codeview_symbol* lastGProcSym, int thisPtrType); - int createEmptyFieldListType(); + int createEmptyFieldListType(); int fixProperty(int type, int prop, int fieldType); bool derivesFromObject(const codeview_type* cvtype); @@ -112,19 +112,19 @@ public: const char* appendDelegate(int thisType, int funcType); int appendObjectType (int object_derived_type, int enumType, const char* classSymbol); int appendPointerType(int pointedType, int attr); - int appendModifierType(int type, int attr); + int appendModifierType(int type, int attr); int appendTypedef(int type, const char* name, bool saveTranslation = true); int appendComplex(int cplxtype, int basetype, int elemsize, const char* name); void appendTypedefs(); int appendEnumerator(const char* typeName, const char* enumName, int enumValue, int prop); int appendClassTypeEnum(const codeview_type* fieldlist, int type, const char* name); - void appendStackVar(const char* name, int type, int offset); - void appendGlobalVar(const char* name, int type, int seg, int offset); - bool appendEndArg(); - void appendEnd(); - void appendLexicalBlock(DWARF_InfoData& id, unsigned int proclo); + void appendStackVar(const char* name, int type, int offset); + void appendGlobalVar(const char* name, int type, int seg, int offset); + bool appendEndArg(); + void appendEnd(); + void appendLexicalBlock(DWARF_InfoData& id, unsigned int proclo); - bool hasClassTypeEnum(const codeview_type* fieldlist); + bool hasClassTypeEnum(const codeview_type* fieldlist); bool insertClassTypeEnums(); int insertBaseClass(const codeview_type* fieldlist, int type); @@ -156,26 +156,26 @@ public: mspdb::Mod* globalMod(); - // DWARF - bool createDWARFModules(); - unsigned char* getDWARFAbbrev(int off, int n); - bool addDWARFTypes(); - bool addDWARFLines(); - bool addDWARFPublics(); - bool relocateDebugLineInfo(); - bool writeDWARFImage(const char* opath); - - bool addDWARFSectionContrib(mspdb::Mod* mod, unsigned long pclo, unsigned long pchi); - bool addDWARFProc(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); - int addDWARFStructure(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); - int addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); - int addDWARFBasicType(const char*name, int encoding, int byte_size); - bool iterateDWARFDebugInfo(int op); - int getTypeByDWARFOffset(DWARF_CompilationUnit* cu, int off); - int getDWARFTypeSize(DWARF_CompilationUnit* cu, int typeOff); - int getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, - unsigned char* &locals, unsigned char* end, int& upperBound); - bool readDWARFInfoData(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &p, bool mergeInfo = false); + // DWARF + bool createDWARFModules(); + unsigned char* getDWARFAbbrev(int off, int n); + bool addDWARFTypes(); + bool addDWARFLines(); + bool addDWARFPublics(); + bool relocateDebugLineInfo(); + bool writeDWARFImage(const char* opath); + + bool addDWARFSectionContrib(mspdb::Mod* mod, unsigned long pclo, unsigned long pchi); + bool addDWARFProc(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); + int addDWARFStructure(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); + int addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); + int addDWARFBasicType(const char*name, int encoding, int byte_size); + bool iterateDWARFDebugInfo(int op); + int getTypeByDWARFOffset(DWARF_CompilationUnit* cu, int off); + int getDWARFTypeSize(DWARF_CompilationUnit* cu, int typeOff); + int getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, + unsigned char* &locals, unsigned char* end, int& upperBound); + bool readDWARFInfoData(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &p, bool mergeInfo = false); // private: BYTE* libraries; @@ -225,7 +225,7 @@ public: int nextDwarfType; int objectType; - int emptyFieldListType; + int emptyFieldListType; int classEnumType; int ifaceEnumType; int cppIfaceEnumType; @@ -242,7 +242,7 @@ public: int cntTypedefs; bool addClassTypeEnum; - bool addStringViewHelper; + bool addStringViewHelper; bool useGlobalMod; bool thisIsNotRef; bool v3; @@ -253,9 +253,9 @@ public: double Dversion; - // DWARF - int codeSegOff; - std::map mapOffsetToType; + // DWARF + int codeSegOff; + std::map mapOffsetToType; }; diff --git a/src/cvutil.cpp b/src/cvutil.cpp index 95e8ea3..b8ad78a 100644 --- a/src/cvutil.cpp +++ b/src/cvutil.cpp @@ -181,33 +181,33 @@ int numeric_leaf(int* value, const void* leaf) int write_numeric_leaf(int value, void* leaf) { - if(value >= 0 && value < LF_NUMERIC) - { - *(unsigned short int*) leaf = (unsigned short) value; - return 2; - } - unsigned short int* type = (unsigned short int*) leaf; - leaf = type + 1; - if (value >= -128 && value <= 127) - { - *type = LF_CHAR; - *(char*) leaf = (char)value; - return 3; - } - if (value >= -32768 && value <= 32767) - { - *type = LF_SHORT; - *(short*) leaf = (short)value; - return 4; - } - if (value >= 0 && value <= 65535) - { - *type = LF_USHORT; - *(unsigned short*) leaf = (unsigned short)value; - return 4; - } - *type = LF_LONG; - *(long*) leaf = (long)value; - return 6; + if(value >= 0 && value < LF_NUMERIC) + { + *(unsigned short int*) leaf = (unsigned short) value; + return 2; + } + unsigned short int* type = (unsigned short int*) leaf; + leaf = type + 1; + if (value >= -128 && value <= 127) + { + *type = LF_CHAR; + *(char*) leaf = (char)value; + return 3; + } + if (value >= -32768 && value <= 32767) + { + *type = LF_SHORT; + *(short*) leaf = (short)value; + return 4; + } + if (value >= 0 && value <= 65535) + { + *type = LF_USHORT; + *(unsigned short*) leaf = (unsigned short)value; + return 4; + } + *type = LF_LONG; + *(long*) leaf = (long)value; + return 6; } diff --git a/src/demangle.cpp b/src/demangle.cpp index af7c318..8fa3053 100644 --- a/src/demangle.cpp +++ b/src/demangle.cpp @@ -647,14 +647,14 @@ void unittest() } const char s[] = "_D12intellisen\xd1" "11LibraryInfo14findDe\xeaitionMFKS\x80\x8f\xaf" "0SearchDataZA\x80\x91\x9d\x80\x8a\xbb" "8count\x80\x83\x90MFAyaP\x80\x8f\xaa" "9JSONscopeH\x80\x83\x93S3std4json\x80\x85\x98ValueZb"; - char buf[512]; - dsym2c((const BYTE*) s, sizeof(s) - 1, buf, sizeof(buf)); + char buf[512]; + dsym2c((const BYTE*) s, sizeof(s) - 1, buf, sizeof(buf)); } bool d_demangle(const char* name, char* demangled, int maxlen, bool plain) { #ifdef _DEBUG - static bool once; if(!once) { once = true; unittest(); } + static bool once; if(!once) { once = true; unittest(); } #endif Demangle d; diff --git a/src/dviewhelper/dviewhelper.cpp b/src/dviewhelper/dviewhelper.cpp index c9d16af..e2b295a 100644 --- a/src/dviewhelper/dviewhelper.cpp +++ b/src/dviewhelper/dviewhelper.cpp @@ -34,23 +34,23 @@ struct DEBUGHELPER // possible processor types typedef enum _MPT { - mptix86 = 0, // Intel X86 - mptia64 = 1, // Intel Merced - mptamd64 = 2, // AMD64 - mptUnknown = 3 // Unknown + mptix86 = 0, // Intel X86 + mptia64 = 1, // Intel Merced + mptamd64 = 2, // AMD64 + mptUnknown = 3 // Unknown } MPT; HRESULT readMem(DEBUGHELPER *pHelper, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot) { - if(pHelper->dwVersion < 0x20000) - return pHelper->ReadDebuggeeMemory(pHelper, (DWORD)qwAddr, nWant, pWhere, nGot); - return pHelper->ReadDebuggeeMemoryEx(pHelper, qwAddr, nWant, pWhere, nGot); + if(pHelper->dwVersion < 0x20000) + return pHelper->ReadDebuggeeMemory(pHelper, (DWORD)qwAddr, nWant, pWhere, nGot); + return pHelper->ReadDebuggeeMemoryEx(pHelper, qwAddr, nWant, pWhere, nGot); } struct DString { - DWORD length; - DWORD data; + DWORD length; + DWORD data; }; /////////////////////////////////////////////////////////////////////////////// @@ -58,34 +58,34 @@ struct DString HRESULT WINAPI StringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD sizePerChar) { - DWORDLONG qwAddress = dwAddress; - if(pHelper->dwVersion >= 0x20000) - qwAddress = pHelper->GetRealAddress(pHelper); + DWORDLONG qwAddress = dwAddress; + if(pHelper->dwVersion >= 0x20000) + qwAddress = pHelper->GetRealAddress(pHelper); - int proc = 0; - if(pHelper->dwVersion >= 0x20000) - proc = pHelper->GetProcessorType(pHelper); - int sizeOfPtr = proc == 0 ? 4 : 8; + int proc = 0; + if(pHelper->dwVersion >= 0x20000) + proc = pHelper->GetProcessorType(pHelper); + int sizeOfPtr = proc == 0 ? 4 : 8; // Get the string struct - char strdata[16]; + char strdata[16]; DWORD read; if (readMem(pHelper, qwAddress, 2*sizeOfPtr, strdata, &read) != S_OK) { - strncpy(pResult,"Cannot access struct", max); - return S_OK; + strncpy(pResult,"Cannot access struct", max); + return S_OK; + } + DWORDLONG length, data; + if(sizeOfPtr > 4) + { + length = *(DWORDLONG*) strdata; + data = *(DWORDLONG*) (strdata + sizeOfPtr); + } + else + { + length = *(DWORD*) strdata; + data = *(DWORD*) (strdata + sizeOfPtr); } - DWORDLONG length, data; - if(sizeOfPtr > 4) - { - length = *(DWORDLONG*) strdata; - data = *(DWORDLONG*) (strdata + sizeOfPtr); - } - else - { - length = *(DWORD*) strdata; - data = *(DWORD*) (strdata + sizeOfPtr); - } if (length == 0) { strncpy(pResult,"\"\"", max); diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 1bc942c..eb325e7 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -25,511 +25,511 @@ unsigned int LEB128(unsigned char* &p) { - unsigned int x = 0; - int shift = 0; - while(*p & 0x80) - { - x |= (*p & 0x7f) << shift; - shift += 7; - p++; - } - x |= *p << shift; - p++; - return x; + unsigned int x = 0; + int shift = 0; + while(*p & 0x80) + { + x |= (*p & 0x7f) << shift; + shift += 7; + p++; + } + x |= *p << shift; + p++; + return x; } unsigned int LEB128(unsigned char* base, int& off) { - unsigned char* p = base + off; - unsigned int x = LEB128(p); - off = p - base; - return x; + unsigned char* p = base + off; + unsigned int x = LEB128(p); + off = p - base; + return x; } int SLEB128(unsigned char* &p) { - unsigned int x = 0; - int shift = 0; - while(*p & 0x80) - { - x |= (*p & 0x7f) << shift; - shift += 7; - p++; - } - x |= *p << shift; - if(*p & 0x40) - x |= -(1 << (shift + 7)); // sign extend - p++; - return x; + unsigned int x = 0; + int shift = 0; + while(*p & 0x80) + { + x |= (*p & 0x7f) << shift; + shift += 7; + p++; + } + x |= *p << shift; + if(*p & 0x40) + x |= -(1 << (shift + 7)); // sign extend + p++; + return x; } unsigned int RD2(unsigned char* p) { - unsigned int x = *p++; - x |= *p++ << 8; - return x; + unsigned int x = *p++; + x |= *p++ << 8; + return x; } unsigned int RD4(unsigned char* p) { - unsigned int x = *p++; - x |= *p++ << 8; - x |= *p++ << 16; - x |= *p++ << 24; - return x; + unsigned int x = *p++; + x |= *p++ << 8; + x |= *p++ << 16; + x |= *p++ << 24; + return x; } unsigned long long RD8(unsigned char* p) { - unsigned long long x = *p++; - for(int shift = 8; shift < 64; shift += 8) - x |= (unsigned long long) *p++ << shift; - return x; + unsigned long long x = *p++; + for(int shift = 8; shift < 64; shift += 8) + x |= (unsigned long long) *p++ << shift; + return x; } unsigned long long RDsize(unsigned char* p, int size) { - if(size > 8) - size = 8; - unsigned long long x = *p++; - for(int shift = 8; shift < size * 8; shift += 8) - x |= (unsigned long long) *p++ << shift; - return x; + if(size > 8) + size = 8; + unsigned long long x = *p++; + for(int shift = 8; shift < size * 8; shift += 8) + x |= (unsigned long long) *p++ << shift; + return x; } /////////////////////////////////////////////////////////////////////////////// -#include "pshpack1.h" - +#include "pshpack1.h" + struct DWARF_CompilationUnit { - unsigned int unit_length; // 12 byte in DWARF-64 - unsigned short version; - unsigned int debug_abbrev_offset; // 8 byte in DWARF-64 - unsigned char address_size; + unsigned int unit_length; // 12 byte in DWARF-64 + unsigned short version; + unsigned int debug_abbrev_offset; // 8 byte in DWARF-64 + unsigned char address_size; - bool isDWARF64() const { return unit_length == ~0; } - int refSize() const { return unit_length == ~0 ? 8 : 4; } + bool isDWARF64() const { return unit_length == ~0; } + int refSize() const { return unit_length == ~0 ? 8 : 4; } }; struct DWARF_FileName { - const char* file_name; - unsigned int dir_index; - unsigned long lastModification; - unsigned long fileLength; - - void read(unsigned char* &p) - { - file_name = (const char*) p; - p += strlen((const char*) p) + 1; - dir_index = LEB128(p); - lastModification = LEB128(p); - fileLength = LEB128(p); - } + const char* file_name; + unsigned int dir_index; + unsigned long lastModification; + unsigned long fileLength; + + void read(unsigned char* &p) + { + file_name = (const char*) p; + p += strlen((const char*) p) + 1; + dir_index = LEB128(p); + lastModification = LEB128(p); + fileLength = LEB128(p); + } }; struct DWARF_InfoData { - int entryOff; - int code; - int tag; - int hasChild; - - const char* name; - const char* linkage_name; - const char* dir; - unsigned long byte_size; - unsigned long sibling; - unsigned long encoding; - unsigned long pclo; - unsigned long pchi; - unsigned long ranges; - unsigned long type; - unsigned long containing_type; - unsigned long specification; - unsigned long inlined; - unsigned long external; - unsigned long long location; // first 8 bytes - unsigned long long member_location; // first 8 bytes - unsigned long locationlist; // offset into debug_loc - long frame_base; - long upper_bound; - long lower_bound; + int entryOff; + int code; + int tag; + int hasChild; + + const char* name; + const char* linkage_name; + const char* dir; + unsigned long byte_size; + unsigned long sibling; + unsigned long encoding; + unsigned long pclo; + unsigned long pchi; + unsigned long ranges; + unsigned long type; + unsigned long containing_type; + unsigned long specification; + unsigned long inlined; + unsigned long external; + unsigned long long location; // first 8 bytes + unsigned long long member_location; // first 8 bytes + unsigned long locationlist; // offset into debug_loc + long frame_base; + long upper_bound; + long lower_bound; }; static const int maximum_operations_per_instruction = 1; struct DWARF_LineNumberProgramHeader { - unsigned int unit_length; // 12 byte in DWARF-64 - unsigned short version; - unsigned int header_length; // 8 byte in DWARF-64 - unsigned char minimum_instruction_length; - //unsigned char maximum_operations_per_instruction; (// not in DWARF 2 - unsigned char default_is_stmt; - signed char line_base; - unsigned char line_range; - unsigned char opcode_base; - //LEB128 standard_opcode_lengths[opcode_base]; - // string include_directories[] // zero byte terminated - // DWARF_FileNames file_names[] // zero byte terminated + unsigned int unit_length; // 12 byte in DWARF-64 + unsigned short version; + unsigned int header_length; // 8 byte in DWARF-64 + unsigned char minimum_instruction_length; + //unsigned char maximum_operations_per_instruction; (// not in DWARF 2 + unsigned char default_is_stmt; + signed char line_base; + unsigned char line_range; + unsigned char opcode_base; + //LEB128 standard_opcode_lengths[opcode_base]; + // string include_directories[] // zero byte terminated + // DWARF_FileNames file_names[] // zero byte terminated }; struct DWARF_LineState { - // hdr info - std::vector include_dirs; - std::vector files; - - unsigned long address; - unsigned int op_index; - unsigned int file; - unsigned int line; - unsigned int column; - bool is_stmt; - bool basic_block; - bool end_sequence; - bool prologue_end; - bool epilogue_end; - unsigned int isa; - unsigned int discriminator; - - // not part of the "documented" state - DWARF_FileName* file_ptr; - unsigned long seg_offset; - unsigned long last_addr; - std::vector lineInfo; - - DWARF_LineState() - { - seg_offset = 0x400000; - init(0); - } - - void init(DWARF_LineNumberProgramHeader* hdr) - { - address = 0; - op_index = 0; - file = 1; - line = 1; - column = 0; - is_stmt = hdr && hdr->default_is_stmt != 0; - basic_block = false; - end_sequence = false; - prologue_end = false; - epilogue_end = false; - isa = 0; - discriminator = 0; - } - - void advance_addr(DWARF_LineNumberProgramHeader* hdr, int operation_advance) - { - int address_advance = hdr->minimum_instruction_length * ((op_index + operation_advance) / maximum_operations_per_instruction); - address += address_advance; - op_index = (op_index + operation_advance) % maximum_operations_per_instruction; - } - - void addLineInfo() - { + // hdr info + std::vector include_dirs; + std::vector files; + + unsigned long address; + unsigned int op_index; + unsigned int file; + unsigned int line; + unsigned int column; + bool is_stmt; + bool basic_block; + bool end_sequence; + bool prologue_end; + bool epilogue_end; + unsigned int isa; + unsigned int discriminator; + + // not part of the "documented" state + DWARF_FileName* file_ptr; + unsigned long seg_offset; + unsigned long last_addr; + std::vector lineInfo; + + DWARF_LineState() + { + seg_offset = 0x400000; + init(0); + } + + void init(DWARF_LineNumberProgramHeader* hdr) + { + address = 0; + op_index = 0; + file = 1; + line = 1; + column = 0; + is_stmt = hdr && hdr->default_is_stmt != 0; + basic_block = false; + end_sequence = false; + prologue_end = false; + epilogue_end = false; + isa = 0; + discriminator = 0; + } + + void advance_addr(DWARF_LineNumberProgramHeader* hdr, int operation_advance) + { + int address_advance = hdr->minimum_instruction_length * ((op_index + operation_advance) / maximum_operations_per_instruction); + address += address_advance; + op_index = (op_index + operation_advance) % maximum_operations_per_instruction; + } + + void addLineInfo() + { #if 0 - const char* fname = (file == 0 ? file_ptr->file_name : files[file - 1].file_name); - printf("Adr:%08x Line: %5d File: %s\n", address, line, fname); + const char* fname = (file == 0 ? file_ptr->file_name : files[file - 1].file_name); + printf("Adr:%08x Line: %5d File: %s\n", address, line, fname); #endif - if(address < seg_offset) - return; - mspdb::LineInfoEntry entry; - entry.offset = address - seg_offset; - entry.line = line; - lineInfo.push_back(entry); - } + if(address < seg_offset) + return; + mspdb::LineInfoEntry entry; + entry.offset = address - seg_offset; + entry.line = line; + lineInfo.push_back(entry); + } }; -#include "poppack.h" +#include "poppack.h" /////////////////////////////////////////////////////////////////////////////// long decodeLocation(unsigned char* loc, int &id, int& size) { - unsigned char* p = loc; - int stackDepth = 0; - long data = 0; - do - { - int op = *p++; - id = -1; - size = 0; - - switch(op) - { - case DW_OP_addr: id = S_GDATA_V2; size = 4; data = RD4(p); break; - case DW_OP_fbreg: id = S_BPREL_V2; data = SLEB128(p); break; - case DW_OP_const1u: id = S_CONSTANT_V2; size = 1; data = *p; break; - case DW_OP_const2u: id = S_CONSTANT_V2; size = 2; data = RD2(p); break; - case DW_OP_const4u: id = S_CONSTANT_V2; size = 4; data = RD4(p); break; - case DW_OP_const1s: id = S_CONSTANT_V2; size = 1; data = (char)*p; break; - case DW_OP_const2s: id = S_CONSTANT_V2; size = 2; data = (short)RD2(p); break; - case DW_OP_const4s: id = S_CONSTANT_V2; size = 4; data = (int)RD4(p); break; - case DW_OP_constu: id = S_CONSTANT_V2; data = LEB128(p); break; - case DW_OP_consts: id = S_CONSTANT_V2; data = SLEB128(p); break; - case DW_OP_plus_uconst: id = S_CONSTANT_V2; data = LEB128(p); break; - case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: - case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: - case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: - case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: - case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: - case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: - case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: - case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: - id = S_CONSTANT_V2; - data = op - DW_OP_lit0; - break; - case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: - case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: - case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: - case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: - case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: - case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: - case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: - case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: - id = S_REGISTER_V2; - break; - case DW_OP_regx: - id = S_REGISTER_V2; - data = LEB128(p); // reg - break; - case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: - case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: - case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: - case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: - case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: - case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: - case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: - case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: - id = S_REGISTER_V2; - data = SLEB128(p); - break; - case DW_OP_bregx: - id = S_REGISTER_V2; - data = LEB128(p); // reg - data = SLEB128(p); - break; - - case DW_OP_deref: break; - case DW_OP_deref_size: size = 1; break; - case DW_OP_dup: stackDepth++; break; - case DW_OP_drop: stackDepth--; break; - case DW_OP_over: stackDepth++; break; - case DW_OP_pick: size = 1; stackDepth++; break; - case DW_OP_swap: break; - case DW_OP_rot: break; - case DW_OP_xderef: stackDepth--; break; - case DW_OP_xderef_size: size = 1; stackDepth--; break; - - case DW_OP_push_object_address: stackDepth++; break; /* DWARF3 */ - case DW_OP_call2: size = 2; break; - case DW_OP_call4: size = 4; break; - case DW_OP_form_tls_address: break; - case DW_OP_call_frame_cfa: stackDepth++; break; - case DW_OP_call_ref: - case DW_OP_bit_piece: - case DW_OP_implicit_value: /* DWARF4 */ - case DW_OP_stack_value: - assert(!"unsupported expression operations"); - - // unary operations pop and push - case DW_OP_abs: - case DW_OP_neg: - case DW_OP_not: - break; - // biary operations pop twice and push - case DW_OP_and: - case DW_OP_div: - case DW_OP_minus: - case DW_OP_mod: - case DW_OP_mul: - case DW_OP_or: - case DW_OP_plus: - case DW_OP_shl: - case DW_OP_shr: - case DW_OP_shra: - case DW_OP_xor: - case DW_OP_eq: - case DW_OP_ge: - case DW_OP_gt: - case DW_OP_le: - case DW_OP_lt: - case DW_OP_ne: - stackDepth--; break; - case DW_OP_bra: - case DW_OP_skip: - size = RD2(p) + 2; - break; - } - if(id >= 0) - stackDepth++; - p += size; - } - while(false); // stackDepth > 0); - size = p - loc; - return data; + unsigned char* p = loc; + int stackDepth = 0; + long data = 0; + do + { + int op = *p++; + id = -1; + size = 0; + + switch(op) + { + case DW_OP_addr: id = S_GDATA_V2; size = 4; data = RD4(p); break; + case DW_OP_fbreg: id = S_BPREL_V2; data = SLEB128(p); break; + case DW_OP_const1u: id = S_CONSTANT_V2; size = 1; data = *p; break; + case DW_OP_const2u: id = S_CONSTANT_V2; size = 2; data = RD2(p); break; + case DW_OP_const4u: id = S_CONSTANT_V2; size = 4; data = RD4(p); break; + case DW_OP_const1s: id = S_CONSTANT_V2; size = 1; data = (char)*p; break; + case DW_OP_const2s: id = S_CONSTANT_V2; size = 2; data = (short)RD2(p); break; + case DW_OP_const4s: id = S_CONSTANT_V2; size = 4; data = (int)RD4(p); break; + case DW_OP_constu: id = S_CONSTANT_V2; data = LEB128(p); break; + case DW_OP_consts: id = S_CONSTANT_V2; data = SLEB128(p); break; + case DW_OP_plus_uconst: id = S_CONSTANT_V2; data = LEB128(p); break; + case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: + case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: + case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: + case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: + case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: + case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: + case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: + case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: + id = S_CONSTANT_V2; + data = op - DW_OP_lit0; + break; + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: + case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: + case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: + case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: + case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: + case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: + case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: + case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: + id = S_REGISTER_V2; + break; + case DW_OP_regx: + id = S_REGISTER_V2; + data = LEB128(p); // reg + break; + case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: + case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: + case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: + case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: + case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: + case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: + case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: + case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: + id = S_REGISTER_V2; + data = SLEB128(p); + break; + case DW_OP_bregx: + id = S_REGISTER_V2; + data = LEB128(p); // reg + data = SLEB128(p); + break; + + case DW_OP_deref: break; + case DW_OP_deref_size: size = 1; break; + case DW_OP_dup: stackDepth++; break; + case DW_OP_drop: stackDepth--; break; + case DW_OP_over: stackDepth++; break; + case DW_OP_pick: size = 1; stackDepth++; break; + case DW_OP_swap: break; + case DW_OP_rot: break; + case DW_OP_xderef: stackDepth--; break; + case DW_OP_xderef_size: size = 1; stackDepth--; break; + + case DW_OP_push_object_address: stackDepth++; break; /* DWARF3 */ + case DW_OP_call2: size = 2; break; + case DW_OP_call4: size = 4; break; + case DW_OP_form_tls_address: break; + case DW_OP_call_frame_cfa: stackDepth++; break; + case DW_OP_call_ref: + case DW_OP_bit_piece: + case DW_OP_implicit_value: /* DWARF4 */ + case DW_OP_stack_value: + assert(!"unsupported expression operations"); + + // unary operations pop and push + case DW_OP_abs: + case DW_OP_neg: + case DW_OP_not: + break; + // biary operations pop twice and push + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + stackDepth--; break; + case DW_OP_bra: + case DW_OP_skip: + size = RD2(p) + 2; + break; + } + if(id >= 0) + stackDepth++; + p += size; + } + while(false); // stackDepth > 0); + size = p - loc; + return data; } long decodeLocation(unsigned long long loc, int &id) { - int size; - return decodeLocation((unsigned char*) &loc, id, size); + int size; + return decodeLocation((unsigned char*) &loc, id, size); } unsigned char* CV2PDB::getDWARFAbbrev(int off, int findcode) { - if(!img.debug_abbrev) - return 0; - - unsigned char* p = (unsigned char*) img.debug_abbrev; - while(off < (int)img.debug_abbrev_length) - { - int code = LEB128(p, off); - if(code == findcode) - return p + off; - if(code == 0) - return 0; - int tag = LEB128(p, off); - int hasChild = p[off++]; - - // skip attributes - int attr, form; - do - { - attr = LEB128(p, off); - form = LEB128(p, off); - } - while(attr || form); - } - return 0; + if(!img.debug_abbrev) + return 0; + + unsigned char* p = (unsigned char*) img.debug_abbrev; + while(off < (int)img.debug_abbrev_length) + { + int code = LEB128(p, off); + if(code == findcode) + return p + off; + if(code == 0) + return 0; + int tag = LEB128(p, off); + int hasChild = p[off++]; + + // skip attributes + int attr, form; + do + { + attr = LEB128(p, off); + form = LEB128(p, off); + } + while(attr || form); + } + return 0; } bool CV2PDB::readDWARFInfoData(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &p, bool mergeInfo) { - int entryOff = p - (unsigned char*) cu; - int code = LEB128(p); - if(code == 0) - return false; // end of children list? - - unsigned char* abbrev = getDWARFAbbrev(cu->debug_abbrev_offset, code); - assert(abbrev); - if(!abbrev) - return false; - int tag = LEB128(abbrev); - int hasChild = *abbrev++; - - if(!mergeInfo) - { - id.entryOff = entryOff; - id.code = code; - id.tag = tag; - id.hasChild = hasChild; - - id.name = 0; - id.linkage_name = 0; - id.dir = 0; - id.byte_size = 0; - id.sibling = 0; - id.encoding = 0; - id.pclo = 0; - id.pchi = 0; - id.ranges = 0; - id.type = 0; - id.containing_type = 0; - id.specification = 0; - id.inlined = 0; - id.external = 0; - id.member_location = 0; - id.location = 0; - id.locationlist = 0; - id.frame_base = -1; - id.upper_bound = 0; - id.lower_bound = 0; - } - int attr, form; - for( ; ; ) - { - attr = LEB128(abbrev); - form = LEB128(abbrev); - - if(attr == 0 && form == 0) - break; - - const char* str = 0; - int size = 0; - unsigned long addr = 0; - unsigned long data = 0; - unsigned long long lldata = 0; - bool isRef = false; - switch(form) - { - case DW_FORM_addr: addr = *(unsigned long *)p; size = cu->address_size; break; - case DW_FORM_block2: size = RD2(p) + 2; break; - case DW_FORM_block4: size = RD4(p) + 4; break; - case DW_FORM_data2: size = 2; lldata = data = RD2(p); break; - case DW_FORM_data4: size = 4; lldata = data = RD4(p); break; - case DW_FORM_data8: size = 8; lldata = RD8(p); data = (unsigned long) lldata; break; - case DW_FORM_string: str = (const char*) p; size = strlen(str) + 1; break; - case DW_FORM_block: size = LEB128(p); lldata = RDsize(p, size); data = (unsigned long) lldata; break; - case DW_FORM_block1: size = *p++; lldata = RDsize(p, size); data = (unsigned long) lldata; break; - case DW_FORM_data1: size = 1; lldata = data = *p; break; - case DW_FORM_flag: size = 1; lldata = data = *p; break; - case DW_FORM_sdata: lldata = data = SLEB128(p); size = 0; break; - case DW_FORM_strp: size = cu->refSize(); str = (const char*) (img.debug_str + RDsize(p, size)); break; - case DW_FORM_udata: lldata = data = LEB128(p); size = 0; break; - case DW_FORM_ref_addr: size = cu->address_size; lldata = RDsize(p, size); data = (unsigned long) lldata; isRef = true; break; - case DW_FORM_ref1: size = 1; lldata = data = *p; isRef = true; break; - case DW_FORM_ref2: size = 2; lldata = data = RD2(p); isRef = true; break; - case DW_FORM_ref4: size = 4; lldata = data = RD4(p); isRef = true; break; - case DW_FORM_ref8: size = 8; lldata = RD8(p); data = (unsigned long) lldata; isRef = true; break; - case DW_FORM_ref_udata: lldata = data = LEB128(p); size = 0; isRef = true; break; - case DW_FORM_exprloc: size = LEB128(p); break; - case DW_FORM_flag_present: size = 1; break; - case DW_FORM_ref_sig8: size = 8; break; - case DW_FORM_indirect: - case DW_FORM_sec_offset: - default: return setError("unknown DWARF form entry"); - } - switch(attr) - { - case DW_AT_byte_size: id.byte_size = data; break; - case DW_AT_sibling: id.sibling = data; break; - case DW_AT_encoding: id.encoding = data; break; - case DW_AT_name: id.name = str; break; - case DW_AT_MIPS_linkage_name: id.linkage_name = str; break; - case DW_AT_comp_dir: id.dir = str; break; - case DW_AT_low_pc: id.pclo = addr; break; - case DW_AT_high_pc: id.pchi = addr; break; - case DW_AT_ranges: id.ranges = data; break; - case DW_AT_type: id.type = data; break; - case DW_AT_inline: id.inlined = data; break; - case DW_AT_external: id.external = data; break; - case DW_AT_upper_bound: id.upper_bound = data; break; - case DW_AT_lower_bound: id.lower_bound = data; break; - case DW_AT_containing_type: id.containing_type = data; break; - case DW_AT_specification: id.specification = data; break; - case DW_AT_data_member_location: id.member_location = lldata; break; - case DW_AT_location: - if(form == DW_FORM_block1) - id.location = lldata; - else - id.locationlist = data; - break; - case DW_AT_frame_base: - if(form != DW_FORM_block2 && form != DW_FORM_block4 && form != DW_FORM_block1 && form != DW_FORM_block) - id.frame_base = data; - break; - } - p += size; - } - return true; + int entryOff = p - (unsigned char*) cu; + int code = LEB128(p); + if(code == 0) + return false; // end of children list? + + unsigned char* abbrev = getDWARFAbbrev(cu->debug_abbrev_offset, code); + assert(abbrev); + if(!abbrev) + return false; + int tag = LEB128(abbrev); + int hasChild = *abbrev++; + + if(!mergeInfo) + { + id.entryOff = entryOff; + id.code = code; + id.tag = tag; + id.hasChild = hasChild; + + id.name = 0; + id.linkage_name = 0; + id.dir = 0; + id.byte_size = 0; + id.sibling = 0; + id.encoding = 0; + id.pclo = 0; + id.pchi = 0; + id.ranges = 0; + id.type = 0; + id.containing_type = 0; + id.specification = 0; + id.inlined = 0; + id.external = 0; + id.member_location = 0; + id.location = 0; + id.locationlist = 0; + id.frame_base = -1; + id.upper_bound = 0; + id.lower_bound = 0; + } + int attr, form; + for( ; ; ) + { + attr = LEB128(abbrev); + form = LEB128(abbrev); + + if(attr == 0 && form == 0) + break; + + const char* str = 0; + int size = 0; + unsigned long addr = 0; + unsigned long data = 0; + unsigned long long lldata = 0; + bool isRef = false; + switch(form) + { + case DW_FORM_addr: addr = *(unsigned long *)p; size = cu->address_size; break; + case DW_FORM_block2: size = RD2(p) + 2; break; + case DW_FORM_block4: size = RD4(p) + 4; break; + case DW_FORM_data2: size = 2; lldata = data = RD2(p); break; + case DW_FORM_data4: size = 4; lldata = data = RD4(p); break; + case DW_FORM_data8: size = 8; lldata = RD8(p); data = (unsigned long) lldata; break; + case DW_FORM_string: str = (const char*) p; size = strlen(str) + 1; break; + case DW_FORM_block: size = LEB128(p); lldata = RDsize(p, size); data = (unsigned long) lldata; break; + case DW_FORM_block1: size = *p++; lldata = RDsize(p, size); data = (unsigned long) lldata; break; + case DW_FORM_data1: size = 1; lldata = data = *p; break; + case DW_FORM_flag: size = 1; lldata = data = *p; break; + case DW_FORM_sdata: lldata = data = SLEB128(p); size = 0; break; + case DW_FORM_strp: size = cu->refSize(); str = (const char*) (img.debug_str + RDsize(p, size)); break; + case DW_FORM_udata: lldata = data = LEB128(p); size = 0; break; + case DW_FORM_ref_addr: size = cu->address_size; lldata = RDsize(p, size); data = (unsigned long) lldata; isRef = true; break; + case DW_FORM_ref1: size = 1; lldata = data = *p; isRef = true; break; + case DW_FORM_ref2: size = 2; lldata = data = RD2(p); isRef = true; break; + case DW_FORM_ref4: size = 4; lldata = data = RD4(p); isRef = true; break; + case DW_FORM_ref8: size = 8; lldata = RD8(p); data = (unsigned long) lldata; isRef = true; break; + case DW_FORM_ref_udata: lldata = data = LEB128(p); size = 0; isRef = true; break; + case DW_FORM_exprloc: size = LEB128(p); break; + case DW_FORM_flag_present: size = 1; break; + case DW_FORM_ref_sig8: size = 8; break; + case DW_FORM_indirect: + case DW_FORM_sec_offset: + default: return setError("unknown DWARF form entry"); + } + switch(attr) + { + case DW_AT_byte_size: id.byte_size = data; break; + case DW_AT_sibling: id.sibling = data; break; + case DW_AT_encoding: id.encoding = data; break; + case DW_AT_name: id.name = str; break; + case DW_AT_MIPS_linkage_name: id.linkage_name = str; break; + case DW_AT_comp_dir: id.dir = str; break; + case DW_AT_low_pc: id.pclo = addr; break; + case DW_AT_high_pc: id.pchi = addr; break; + case DW_AT_ranges: id.ranges = data; break; + case DW_AT_type: id.type = data; break; + case DW_AT_inline: id.inlined = data; break; + case DW_AT_external: id.external = data; break; + case DW_AT_upper_bound: id.upper_bound = data; break; + case DW_AT_lower_bound: id.lower_bound = data; break; + case DW_AT_containing_type: id.containing_type = data; break; + case DW_AT_specification: id.specification = data; break; + case DW_AT_data_member_location: id.member_location = lldata; break; + case DW_AT_location: + if(form == DW_FORM_block1) + id.location = lldata; + else + id.locationlist = data; + break; + case DW_AT_frame_base: + if(form != DW_FORM_block2 && form != DW_FORM_block4 && form != DW_FORM_block1 && form != DW_FORM_block) + id.frame_base = data; + break; + } + p += size; + } + return true; } void CV2PDB::checkDWARFTypeAlloc(int size, int add) @@ -543,115 +543,115 @@ void CV2PDB::checkDWARFTypeAlloc(int size, int add) void CV2PDB::appendStackVar(const char* name, int type, int offset) { - unsigned int len; - unsigned int align = 4; + unsigned int len; + unsigned int align = 4; // if(type > 0x1020) // type = 0x74; - checkUdtSymbolAlloc(100 + kMaxNameLen); - - codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->stack_v2.offset = offset; - cvs->stack_v2.symtype = type; - if(img.isX64()) - { - cvs->stack_xxxx_v3.id = S_BPREL_XXXX_V3; - // register as in "Microsoft Symbol and Type Information" 6.1, see also dia2dump/regs.cpp - cvs->stack_xxxx_v3.unknown = 0x14e; // 0x14f: esp relative, 0x14e: ebp relative - len = cstrcpy_v (true, (BYTE*) cvs->stack_xxxx_v3.name, name); - len += (BYTE*) &cvs->stack_xxxx_v3.name - (BYTE*) cvs; - } - else - { - cvs->stack_v2.id = v3 ? S_BPREL_V3 : S_BPREL_V2; - len = cstrcpy_v (v3, (BYTE*) &cvs->stack_v2.p_name, name); - len += (BYTE*) &cvs->stack_v2.p_name - (BYTE*) cvs; - } - for (; len & (align-1); len++) - udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); - cvs->stack_v2.len = len - 2; - cbUdtSymbols += len; + checkUdtSymbolAlloc(100 + kMaxNameLen); + + codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + cvs->stack_v2.offset = offset; + cvs->stack_v2.symtype = type; + if(img.isX64()) + { + cvs->stack_xxxx_v3.id = S_BPREL_XXXX_V3; + // register as in "Microsoft Symbol and Type Information" 6.1, see also dia2dump/regs.cpp + cvs->stack_xxxx_v3.unknown = 0x14e; // 0x14f: esp relative, 0x14e: ebp relative + len = cstrcpy_v (true, (BYTE*) cvs->stack_xxxx_v3.name, name); + len += (BYTE*) &cvs->stack_xxxx_v3.name - (BYTE*) cvs; + } + else + { + cvs->stack_v2.id = v3 ? S_BPREL_V3 : S_BPREL_V2; + len = cstrcpy_v (v3, (BYTE*) &cvs->stack_v2.p_name, name); + len += (BYTE*) &cvs->stack_v2.p_name - (BYTE*) cvs; + } + for (; len & (align-1); len++) + udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); + cvs->stack_v2.len = len - 2; + cbUdtSymbols += len; } void CV2PDB::appendGlobalVar(const char* name, int type, int seg, int offset) { - unsigned int len; - unsigned int align = 4; + unsigned int len; + unsigned int align = 4; - for(char* cname = (char*) name; *cname; cname++) - if (*cname == '.') - *cname = dotReplacementChar; + for(char* cname = (char*) name; *cname; cname++) + if (*cname == '.') + *cname = dotReplacementChar; - checkUdtSymbolAlloc(100 + kMaxNameLen); + checkUdtSymbolAlloc(100 + kMaxNameLen); - codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->data_v2.id = v3 ? S_GDATA_V3 : S_GDATA_V2; - cvs->data_v2.offset = offset; - cvs->data_v2.symtype = type; - cvs->data_v2.segment = seg; + codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + cvs->data_v2.id = v3 ? S_GDATA_V3 : S_GDATA_V2; + cvs->data_v2.offset = offset; + cvs->data_v2.symtype = type; + cvs->data_v2.segment = seg; len = cstrcpy_v (v3, (BYTE*) &cvs->data_v2.p_name, name); len += (BYTE*) &cvs->data_v2.p_name - (BYTE*) cvs; - for (; len & (align-1); len++) - udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); - cvs->data_v2.len = len - 2; - cbUdtSymbols += len; + for (; len & (align-1); len++) + udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); + cvs->data_v2.len = len - 2; + cbUdtSymbols += len; } bool CV2PDB::appendEndArg() { - checkUdtSymbolAlloc(8); + checkUdtSymbolAlloc(8); - codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->common.id = S_ENDARG_V1; - cvs->common.len = 2; - cbUdtSymbols += 4; - return true; + codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + cvs->common.id = S_ENDARG_V1; + cvs->common.len = 2; + cbUdtSymbols += 4; + return true; } void CV2PDB::appendEnd() { - checkUdtSymbolAlloc(8); + checkUdtSymbolAlloc(8); - codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->common.id = S_END_V1; - cvs->common.len = 2; - cbUdtSymbols += 4; + codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + cvs->common.id = S_END_V1; + cvs->common.len = 2; + cbUdtSymbols += 4; } void CV2PDB::appendLexicalBlock(DWARF_InfoData& id, unsigned int proclo) { - checkUdtSymbolAlloc(32); + checkUdtSymbolAlloc(32); - codeview_symbol*dsym = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + codeview_symbol*dsym = (codeview_symbol*) (udtSymbols + cbUdtSymbols); dsym->block_v3.id = S_BLOCK_V3; dsym->block_v3.parent = 0; dsym->block_v3.end = 0; // destSize + sizeof(dsym->block_v3) + 12; - dsym->block_v3.length = id.pchi - id.pclo; + dsym->block_v3.length = id.pchi - id.pclo; dsym->block_v3.offset = id.pclo - codeSegOff; dsym->block_v3.segment = img.codeSegment + 1; dsym->block_v3.name[0] = 0; - int len = sizeof(dsym->block_v3); - for (; len & 3; len++) - udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); - dsym->block_v3.len = len - 2; - cbUdtSymbols += len; + int len = sizeof(dsym->block_v3); + for (; len & 3; len++) + udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); + dsym->block_v3.len = len - 2; + cbUdtSymbols += len; } bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, - unsigned char* &locals, unsigned char* end) + unsigned char* &locals, unsigned char* end) { - unsigned int pclo = procid.pclo - codeSegOff; - unsigned int pchi = procid.pchi - codeSegOff; + unsigned int pclo = procid.pclo - codeSegOff; + unsigned int pchi = procid.pchi - codeSegOff; - int length = procid.hasChild ? end - locals : 0; - unsigned int len; - unsigned int align = 4; + int length = procid.hasChild ? end - locals : 0; + unsigned int len; + unsigned int align = 4; - checkUdtSymbolAlloc(100 + kMaxNameLen); + checkUdtSymbolAlloc(100 + kMaxNameLen); - // GLOBALPROC - codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + // GLOBALPROC + codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); cvs->proc_v2.id = v3 ? S_GPROC_V3 : S_GPROC_V2; cvs->proc_v2.pparent = 0; cvs->proc_v2.pend = 0; @@ -668,1027 +668,1027 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, len = cstrcpy_v (v3, (BYTE*) &cvs->proc_v2.p_name, procid.name); len += (BYTE*) &cvs->proc_v2.p_name - (BYTE*) cvs; - for (; len & (align-1); len++) - udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); + for (; len & (align-1); len++) + udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); cvs->proc_v2.len = len - 2; - cbUdtSymbols += len; + cbUdtSymbols += len; #if 0 - addStackVar("local_var", 0x1001, 8); + addStackVar("local_var", 0x1001, 8); #endif - int frameOff = 8; // assume ebp+8 in fb - if(img.debug_loc && procid.frame_base >= 0) - { - unsigned char* loc = (unsigned char*) (img.debug_loc + procid.frame_base); - int frame_breg = cu->address_size == 8 ? DW_OP_breg6 : DW_OP_breg5; + int frameOff = 8; // assume ebp+8 in fb + if(img.debug_loc && procid.frame_base >= 0) + { + unsigned char* loc = (unsigned char*) (img.debug_loc + procid.frame_base); + int frame_breg = cu->address_size == 8 ? DW_OP_breg6 : DW_OP_breg5; #if 1 - while(RDsize(loc, cu->address_size) != 0 || RDsize(loc + cu->address_size, cu->address_size) != 0) - { - loc += 2*cu->address_size; - int opsize = RD2(loc); - loc += 2; - if(*loc == frame_breg) - { - unsigned char* p = loc + 1; - frameOff = SLEB128(p); - break; - } - loc += opsize; - } + while(RDsize(loc, cu->address_size) != 0 || RDsize(loc + cu->address_size, cu->address_size) != 0) + { + loc += 2*cu->address_size; + int opsize = RD2(loc); + loc += 2; + if(*loc == frame_breg) + { + unsigned char* p = loc + 1; + frameOff = SLEB128(p); + break; + } + loc += opsize; + } #endif - } - if(cu && locals && length) - { - bool endarg = false; - unsigned char* p = locals; - unsigned char* end = locals + length; - DWARF_InfoData id; - int off = 8; - int cvid; - - std::vector lexicalBlockEnd; - lexicalBlockEnd.push_back(end); - while(lexicalBlockEnd.size() > 0) - { - if(p >= lexicalBlockEnd.back()) - { - if (!endarg) - endarg = appendEndArg(); - appendEnd(); - lexicalBlockEnd.pop_back(); - continue; - } - if(!readDWARFInfoData(id, cu, p)) - continue; - - if (id.tag == DW_TAG_formal_parameter) - { - if(id.name) - { - off = decodeLocation(id.location, cvid); - if(cvid == S_BPREL_V2) - appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); - } - } - else - { - if(!endarg) - endarg = appendEndArg(); - switch(id.tag) - { - case DW_TAG_variable: - if(id.name) - { - off = decodeLocation(id.location, cvid); - if(cvid == S_BPREL_V2) - appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); - } - break; - case DW_TAG_subprogram: - if(id.hasChild && !id.inlined) - p = (id.sibling ? (unsigned char*) cu + id.sibling : end); - break; - case DW_TAG_lexical_block: - if(id.hasChild && id.pchi != id.pclo) - { - appendLexicalBlock(id, pclo + codeSegOff); - if(id.sibling) - lexicalBlockEnd.push_back((unsigned char*) cu + id.sibling); - else - lexicalBlockEnd.push_back(lexicalBlockEnd.back()); - } - break; - default: - break; - } - } - } - } - else - { - appendEndArg(); - appendEnd(); - } - return true; + } + if(cu && locals && length) + { + bool endarg = false; + unsigned char* p = locals; + unsigned char* end = locals + length; + DWARF_InfoData id; + int off = 8; + int cvid; + + std::vector lexicalBlockEnd; + lexicalBlockEnd.push_back(end); + while(lexicalBlockEnd.size() > 0) + { + if(p >= lexicalBlockEnd.back()) + { + if (!endarg) + endarg = appendEndArg(); + appendEnd(); + lexicalBlockEnd.pop_back(); + continue; + } + if(!readDWARFInfoData(id, cu, p)) + continue; + + if (id.tag == DW_TAG_formal_parameter) + { + if(id.name) + { + off = decodeLocation(id.location, cvid); + if(cvid == S_BPREL_V2) + appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); + } + } + else + { + if(!endarg) + endarg = appendEndArg(); + switch(id.tag) + { + case DW_TAG_variable: + if(id.name) + { + off = decodeLocation(id.location, cvid); + if(cvid == S_BPREL_V2) + appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); + } + break; + case DW_TAG_subprogram: + if(id.hasChild && !id.inlined) + p = (id.sibling ? (unsigned char*) cu + id.sibling : end); + break; + case DW_TAG_lexical_block: + if(id.hasChild && id.pchi != id.pclo) + { + appendLexicalBlock(id, pclo + codeSegOff); + if(id.sibling) + lexicalBlockEnd.push_back((unsigned char*) cu + id.sibling); + else + lexicalBlockEnd.push_back(lexicalBlockEnd.back()); + } + break; + default: + break; + } + } + } + } + else + { + appendEndArg(); + appendEnd(); + } + return true; } int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* cu, - unsigned char* &locals, unsigned char* end) + unsigned char* &locals, unsigned char* end) { - bool isunion = structid.tag == DW_TAG_union_type; - int length = structid.hasChild ? end - locals : 0; - - int fieldlistType = 0; - int nfields = 0; - if(cu && locals && length) - { - checkDWARFTypeAlloc(100); - codeview_reftype* fl = (codeview_reftype*) (dwarfTypes + cbDwarfTypes); - int flbegin = cbDwarfTypes; - fl->fieldlist.id = LF_FIELDLIST_V2; - cbDwarfTypes += 4; + bool isunion = structid.tag == DW_TAG_union_type; + int length = structid.hasChild ? end - locals : 0; + + int fieldlistType = 0; + int nfields = 0; + if(cu && locals && length) + { + checkDWARFTypeAlloc(100); + codeview_reftype* fl = (codeview_reftype*) (dwarfTypes + cbDwarfTypes); + int flbegin = cbDwarfTypes; + fl->fieldlist.id = LF_FIELDLIST_V2; + cbDwarfTypes += 4; #if 0 - if(structid.containing_type && structid.containing_type != structid.entryOff) - { - codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); - bc->bclass_v2.id = LF_BCLASS_V2; - bc->bclass_v2.offset = 0; - bc->bclass_v2.type = getTypeByDWARFOffset(cu, structid.containing_type); - bc->bclass_v2.attribute = 3; // public - cbDwarfTypes += sizeof(bc->bclass_v2); - for (; cbDwarfTypes & 3; cbDwarfTypes++) - dwarfTypes[cbDwarfTypes] = 0xf4 - (cbDwarfTypes & 3); - nfields++; - } + if(structid.containing_type && structid.containing_type != structid.entryOff) + { + codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); + bc->bclass_v2.id = LF_BCLASS_V2; + bc->bclass_v2.offset = 0; + bc->bclass_v2.type = getTypeByDWARFOffset(cu, structid.containing_type); + bc->bclass_v2.attribute = 3; // public + cbDwarfTypes += sizeof(bc->bclass_v2); + for (; cbDwarfTypes & 3; cbDwarfTypes++) + dwarfTypes[cbDwarfTypes] = 0xf4 - (cbDwarfTypes & 3); + nfields++; + } #endif - unsigned char* p = locals; - unsigned char* end = locals + length; - DWARF_InfoData id; - int len = 0; - while(p < end) - { - if(!readDWARFInfoData(id, cu, p)) - continue; - - int cvid = -1; - if (id.tag == DW_TAG_member && id.name) - { - int off = isunion ? 0 : decodeLocation(id.member_location, cvid); - if(isunion || cvid == S_CONSTANT_V2) - { - checkDWARFTypeAlloc(kMaxNameLen + 100); - codeview_fieldtype* dfieldtype = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); - cbDwarfTypes += addFieldMember(dfieldtype, 0, off, getTypeByDWARFOffset(cu, id.type), id.name); - nfields++; - } - } - else if(id.tag == DW_TAG_inheritance) - { - int off = decodeLocation(id.member_location, cvid); - if(cvid == S_CONSTANT_V2) - { - codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); - bc->bclass_v2.id = LF_BCLASS_V2; - bc->bclass_v2.offset = off; - bc->bclass_v2.type = getTypeByDWARFOffset(cu, id.type); - bc->bclass_v2.attribute = 3; // public - cbDwarfTypes += sizeof(bc->bclass_v2); - for (; cbDwarfTypes & 3; cbDwarfTypes++) - dwarfTypes[cbDwarfTypes] = 0xf4 - (cbDwarfTypes & 3); - nfields++; - } - } - if(id.sibling) - p = (unsigned char*) cu + id.sibling; - } - fl = (codeview_reftype*) (dwarfTypes + flbegin); - fl->fieldlist.len = cbDwarfTypes - flbegin - 2; - fieldlistType = nextDwarfType++; - } - - checkUserTypeAlloc(kMaxNameLen + 100); - codeview_type* cvt = (codeview_type*) (userTypes + cbUserTypes); - - const char* name = (structid.name ? structid.name : "__noname"); - int attr = fieldlistType ? 0 : kPropIncomplete; - int len = addAggregate(cvt, false, nfields, fieldlistType, attr, 0, 0, structid.byte_size, name); - cbUserTypes += len; - - //ensureUDT()? - int cvtype = nextUserType++; - addUdtSymbol(cvtype, name); - return cvtype; + unsigned char* p = locals; + unsigned char* end = locals + length; + DWARF_InfoData id; + int len = 0; + while(p < end) + { + if(!readDWARFInfoData(id, cu, p)) + continue; + + int cvid = -1; + if (id.tag == DW_TAG_member && id.name) + { + int off = isunion ? 0 : decodeLocation(id.member_location, cvid); + if(isunion || cvid == S_CONSTANT_V2) + { + checkDWARFTypeAlloc(kMaxNameLen + 100); + codeview_fieldtype* dfieldtype = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); + cbDwarfTypes += addFieldMember(dfieldtype, 0, off, getTypeByDWARFOffset(cu, id.type), id.name); + nfields++; + } + } + else if(id.tag == DW_TAG_inheritance) + { + int off = decodeLocation(id.member_location, cvid); + if(cvid == S_CONSTANT_V2) + { + codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); + bc->bclass_v2.id = LF_BCLASS_V2; + bc->bclass_v2.offset = off; + bc->bclass_v2.type = getTypeByDWARFOffset(cu, id.type); + bc->bclass_v2.attribute = 3; // public + cbDwarfTypes += sizeof(bc->bclass_v2); + for (; cbDwarfTypes & 3; cbDwarfTypes++) + dwarfTypes[cbDwarfTypes] = 0xf4 - (cbDwarfTypes & 3); + nfields++; + } + } + if(id.sibling) + p = (unsigned char*) cu + id.sibling; + } + fl = (codeview_reftype*) (dwarfTypes + flbegin); + fl->fieldlist.len = cbDwarfTypes - flbegin - 2; + fieldlistType = nextDwarfType++; + } + + checkUserTypeAlloc(kMaxNameLen + 100); + codeview_type* cvt = (codeview_type*) (userTypes + cbUserTypes); + + const char* name = (structid.name ? structid.name : "__noname"); + int attr = fieldlistType ? 0 : kPropIncomplete; + int len = addAggregate(cvt, false, nfields, fieldlistType, attr, 0, 0, structid.byte_size, name); + cbUserTypes += len; + + //ensureUDT()? + int cvtype = nextUserType++; + addUdtSymbol(cvtype, name); + return cvtype; } int CV2PDB::getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, - unsigned char* &locals, unsigned char* end, int& upperBound) + unsigned char* &locals, unsigned char* end, int& upperBound) { - int length = arrayid.hasChild ? end - locals : 0; - int lowerBound = 0; - - if(cu && locals && length) - { - unsigned char* p = locals; - unsigned char* end = locals + length; - DWARF_InfoData id; - int len = 0; - while(p < end) - { - if(!readDWARFInfoData(id, cu, p)) - continue; - - int cvid = -1; - if (id.tag == DW_TAG_subrange_type) - { - lowerBound = id.lower_bound; - upperBound = id.upper_bound; - } - if(id.sibling) - p = (unsigned char*) cu + id.sibling; - } - } - return lowerBound; + int length = arrayid.hasChild ? end - locals : 0; + int lowerBound = 0; + + if(cu && locals && length) + { + unsigned char* p = locals; + unsigned char* end = locals + length; + DWARF_InfoData id; + int len = 0; + while(p < end) + { + if(!readDWARFInfoData(id, cu, p)) + continue; + + int cvid = -1; + if (id.tag == DW_TAG_subrange_type) + { + lowerBound = id.lower_bound; + upperBound = id.upper_bound; + } + if(id.sibling) + p = (unsigned char*) cu + id.sibling; + } + } + return lowerBound; } int CV2PDB::addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, - unsigned char* &locals, unsigned char* end) + unsigned char* &locals, unsigned char* end) { - int upperBound, lowerBound = getDWARFArrayBounds(arrayid, cu, locals, end, upperBound); - - checkUserTypeAlloc(kMaxNameLen + 100); - codeview_type* cvt = (codeview_type*) (userTypes + cbUserTypes); - - cvt->array_v2.id = v3 ? LF_ARRAY_V3 : LF_ARRAY_V2; - cvt->array_v2.elemtype = getTypeByDWARFOffset(cu, arrayid.type); - cvt->array_v2.idxtype = 0x74; - int len = (BYTE*)&cvt->array_v2.arrlen - (BYTE*)cvt; - int size = (upperBound - lowerBound + 1) * getDWARFTypeSize(cu, arrayid.type); - len += write_numeric_leaf(size, &cvt->array_v2.arrlen); - ((BYTE*)cvt)[len++] = 0; // empty name + int upperBound, lowerBound = getDWARFArrayBounds(arrayid, cu, locals, end, upperBound); + + checkUserTypeAlloc(kMaxNameLen + 100); + codeview_type* cvt = (codeview_type*) (userTypes + cbUserTypes); + + cvt->array_v2.id = v3 ? LF_ARRAY_V3 : LF_ARRAY_V2; + cvt->array_v2.elemtype = getTypeByDWARFOffset(cu, arrayid.type); + cvt->array_v2.idxtype = 0x74; + int len = (BYTE*)&cvt->array_v2.arrlen - (BYTE*)cvt; + int size = (upperBound - lowerBound + 1) * getDWARFTypeSize(cu, arrayid.type); + len += write_numeric_leaf(size, &cvt->array_v2.arrlen); + ((BYTE*)cvt)[len++] = 0; // empty name for (; len & 3; len++) - userTypes[cbUserTypes + len] = 0xf4 - (len & 3); + userTypes[cbUserTypes + len] = 0xf4 - (len & 3); cvt->array_v2.len = len - 2; - cbUserTypes += len; + cbUserTypes += len; - int cvtype = nextUserType++; - return cvtype; + int cvtype = nextUserType++; + return cvtype; } bool CV2PDB::addDWARFTypes() { - checkUdtSymbolAlloc(100); - - int prefix = 4; - DWORD* ddata = new DWORD [img.debug_info_length/4]; // large enough - unsigned char *data = (unsigned char*) (ddata + prefix); - unsigned int off = 0; - unsigned int len; - unsigned int align = 4; - - // SSEARCH - codeview_symbol* cvs = (codeview_symbol*) (data + off); - cvs->ssearch_v1.id = S_SSEARCH_V1; - cvs->ssearch_v1.segment = img.codeSegment + 1; - cvs->ssearch_v1.offset = 0; - len = sizeof(cvs->ssearch_v1); - for (; len & (align-1); len++) - data[off + len] = 0xf4 - (len & 3); - cvs->ssearch_v1.len = len - 2; - off += len; - - // COMPILAND - cvs = (codeview_symbol*) (data + off); - cvs->compiland_v1.id = S_COMPILAND_V1; - cvs->compiland_v1.unknown = 0x800100; // ?, 0x100: C++, - cvs->compiland_v1.unknown |= img.isX64() ? 0xd0 : 6; //0x06: Pentium Pro/II, 0xd0: x64 - len = sizeof(cvs->compiland_v1) - sizeof(cvs->compiland_v1.p_name); - len += c2p("cv2pdb", cvs->compiland_v1.p_name); - for (; len & (align-1); len++) - data[off + len] = 0xf4 - (len & 3); - cvs->compiland_v1.len = len - 2; - off += len; + checkUdtSymbolAlloc(100); + + int prefix = 4; + DWORD* ddata = new DWORD [img.debug_info_length/4]; // large enough + unsigned char *data = (unsigned char*) (ddata + prefix); + unsigned int off = 0; + unsigned int len; + unsigned int align = 4; + + // SSEARCH + codeview_symbol* cvs = (codeview_symbol*) (data + off); + cvs->ssearch_v1.id = S_SSEARCH_V1; + cvs->ssearch_v1.segment = img.codeSegment + 1; + cvs->ssearch_v1.offset = 0; + len = sizeof(cvs->ssearch_v1); + for (; len & (align-1); len++) + data[off + len] = 0xf4 - (len & 3); + cvs->ssearch_v1.len = len - 2; + off += len; + + // COMPILAND + cvs = (codeview_symbol*) (data + off); + cvs->compiland_v1.id = S_COMPILAND_V1; + cvs->compiland_v1.unknown = 0x800100; // ?, 0x100: C++, + cvs->compiland_v1.unknown |= img.isX64() ? 0xd0 : 6; //0x06: Pentium Pro/II, 0xd0: x64 + len = sizeof(cvs->compiland_v1) - sizeof(cvs->compiland_v1.p_name); + len += c2p("cv2pdb", cvs->compiland_v1.p_name); + for (; len & (align-1); len++) + data[off + len] = 0xf4 - (len & 3); + cvs->compiland_v1.len = len - 2; + off += len; #if 0 - // define one proc over everything - int s = codeSegment; - int pclo = 0; // img.getImageBase() + img.getSection(s).VirtualAddress; - int pchi = pclo + img.getSection(s).Misc.VirtualSize; - addDWARFProc("procall", pclo, pchi, 0, 0, 0); + // define one proc over everything + int s = codeSegment; + int pclo = 0; // img.getImageBase() + img.getSection(s).VirtualAddress; + int pchi = pclo + img.getSection(s).Misc.VirtualSize; + addDWARFProc("procall", pclo, pchi, 0, 0, 0); #endif - ////////////////////////// - mspdb::Mod* mod = globalMod(); - //return writeSymbols (mod, ddata, off, prefix, true); - return addSymbols (mod, data, off, true); + ////////////////////////// + mspdb::Mod* mod = globalMod(); + //return writeSymbols (mod, ddata, off, prefix, true); + return addSymbols (mod, data, off, true); } bool CV2PDB::addDWARFSectionContrib(mspdb::Mod* mod, unsigned long pclo, unsigned long pchi) { - int segIndex = img.findSection(pclo); - if(segIndex >= 0) - { - int segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO - int rc = mod->AddSecContrib(segIndex, pclo, pchi - pclo, segFlags); - if (rc <= 0) - return setError("cannot add section contribution to module"); - } - return true; + int segIndex = img.findSection(pclo); + if(segIndex >= 0) + { + int segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO + int rc = mod->AddSecContrib(segIndex, pclo, pchi - pclo, segFlags); + if (rc <= 0) + return setError("cannot add section contribution to module"); + } + return true; } int CV2PDB::addDWARFBasicType(const char*name, int encoding, int byte_size) { - int type = 0, mode = 0, size = 0; - switch(encoding) - { - case DW_ATE_boolean: type = 3; break; - case DW_ATE_complex_float: type = 5; byte_size /= 2; break; - case DW_ATE_float: type = 4; break; - case DW_ATE_signed: type = 1; break; - case DW_ATE_signed_char: type = 7; break; - case DW_ATE_unsigned: type = 2; break; - case DW_ATE_unsigned_char: type = 7; break; - case DW_ATE_imaginary_float:type = 4; break; - default: - setError("unknown basic type encoding"); - } - switch(type) - { - case 1: // signed - case 2: // unsigned - case 3: // boolean - switch(byte_size) - { - case 1: size = 0; break; - case 2: size = 1; break; - case 4: size = 2; break; - case 8: size = 3; break; - default: - setError("unsupported integer type size"); - } - break; - case 4: - case 5: - switch(byte_size) - { - case 4: size = 0; break; - case 8: size = 1; break; - case 10: size = 2; break; - case 12: size = 2; break; // with padding bytes - case 16: size = 3; break; - case 6: size = 4; break; - default: - setError("unsupported real type size"); - } - break; - case 7: - switch(byte_size) - { - case 1: size = 0; break; - case 2: size = encoding == DW_ATE_signed_char ? 2 : 3; break; - case 4: size = encoding == DW_ATE_signed_char ? 4 : 5; break; - case 8: size = encoding == DW_ATE_signed_char ? 6 : 7; break; - default: - setError("unsupported real int type size"); - } - } - int t = size | (type << 4); - t = translateType(t); - int cvtype = appendTypedef(t, name, false); - if(useTypedefEnum) - addUdtSymbol(cvtype, name); - return cvtype; + int type = 0, mode = 0, size = 0; + switch(encoding) + { + case DW_ATE_boolean: type = 3; break; + case DW_ATE_complex_float: type = 5; byte_size /= 2; break; + case DW_ATE_float: type = 4; break; + case DW_ATE_signed: type = 1; break; + case DW_ATE_signed_char: type = 7; break; + case DW_ATE_unsigned: type = 2; break; + case DW_ATE_unsigned_char: type = 7; break; + case DW_ATE_imaginary_float:type = 4; break; + default: + setError("unknown basic type encoding"); + } + switch(type) + { + case 1: // signed + case 2: // unsigned + case 3: // boolean + switch(byte_size) + { + case 1: size = 0; break; + case 2: size = 1; break; + case 4: size = 2; break; + case 8: size = 3; break; + default: + setError("unsupported integer type size"); + } + break; + case 4: + case 5: + switch(byte_size) + { + case 4: size = 0; break; + case 8: size = 1; break; + case 10: size = 2; break; + case 12: size = 2; break; // with padding bytes + case 16: size = 3; break; + case 6: size = 4; break; + default: + setError("unsupported real type size"); + } + break; + case 7: + switch(byte_size) + { + case 1: size = 0; break; + case 2: size = encoding == DW_ATE_signed_char ? 2 : 3; break; + case 4: size = encoding == DW_ATE_signed_char ? 4 : 5; break; + case 8: size = encoding == DW_ATE_signed_char ? 6 : 7; break; + default: + setError("unsupported real int type size"); + } + } + int t = size | (type << 4); + t = translateType(t); + int cvtype = appendTypedef(t, name, false); + if(useTypedefEnum) + addUdtSymbol(cvtype, name); + return cvtype; } int CV2PDB::getTypeByDWARFOffset(DWARF_CompilationUnit* cu, int off) { - int cuoff = (char*) cu - img.debug_info; - std::map::iterator it = mapOffsetToType.find(cuoff + off); - if(it == mapOffsetToType.end()) - return 0x03; // void - return it->second; + int cuoff = (char*) cu - img.debug_info; + std::map::iterator it = mapOffsetToType.find(cuoff + off); + if(it == mapOffsetToType.end()) + return 0x03; // void + return it->second; } int CV2PDB::getDWARFTypeSize(DWARF_CompilationUnit* cu, int typeOff) { - DWARF_InfoData id; - unsigned char* p = (unsigned char*) cu + typeOff; - if(!readDWARFInfoData(id, cu, p)) - return 0; - if(id.byte_size > 0) - return id.byte_size; - - switch(id.tag) - { - case DW_TAG_ptr_to_member_type: - case DW_TAG_reference_type: - case DW_TAG_pointer_type: - return cu->address_size; - case DW_TAG_array_type: - { - int upperBound, lowerBound = getDWARFArrayBounds(id, cu, p, p + 1, upperBound); - return (upperBound + lowerBound + 1) * getDWARFTypeSize(cu, id.type); - } - default: - if(id.type) - return getDWARFTypeSize(cu, id.type); - break; - } - return 0; + DWARF_InfoData id; + unsigned char* p = (unsigned char*) cu + typeOff; + if(!readDWARFInfoData(id, cu, p)) + return 0; + if(id.byte_size > 0) + return id.byte_size; + + switch(id.tag) + { + case DW_TAG_ptr_to_member_type: + case DW_TAG_reference_type: + case DW_TAG_pointer_type: + return cu->address_size; + case DW_TAG_array_type: + { + int upperBound, lowerBound = getDWARFArrayBounds(id, cu, p, p + 1, upperBound); + return (upperBound + lowerBound + 1) * getDWARFTypeSize(cu, id.type); + } + default: + if(id.type) + return getDWARFTypeSize(cu, id.type); + break; + } + return 0; } enum iterateOp { kOpMapTypes, kOpCreateTypes }; bool CV2PDB::iterateDWARFDebugInfo(int op) { - mspdb::Mod* mod = globalMod(); - int typeID = nextUserType; - - int pointerAttr = img.isX64() ? 0x1000C : 0x800A; - for(unsigned long off = 0; off < img.debug_info_length; ) - { - DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*) (img.debug_info + off); - int length = cu->unit_length; - if(length < 0) - break; - - length += sizeof(length); - unsigned char* end = (unsigned char*) cu + length; - std::vector endStack; - endStack.push_back(end); - - for(unsigned char* p = (unsigned char*) (cu + 1); endStack.size() > 0; ) - { - if(p >= endStack.back()) - { - endStack.pop_back(); - continue; - } - DWARF_InfoData id; - if(!readDWARFInfoData(id, cu, p)) - continue; - if(id.specification) - { - unsigned char* q = (unsigned char*) cu + id.specification; - readDWARFInfoData(id, cu, q, true); - } - if(id.hasChild) - if(id.sibling) - endStack.push_back((unsigned char*) cu + id.sibling); - else - endStack.push_back(endStack.back()); - - if(op == kOpMapTypes) - { - switch(id.tag) - { - case DW_TAG_base_type: - case DW_TAG_typedef: - case DW_TAG_pointer_type: - case DW_TAG_subroutine_type: - case DW_TAG_array_type: - case DW_TAG_const_type: - case DW_TAG_structure_type: - case DW_TAG_reference_type: - - case DW_TAG_class_type: - case DW_TAG_enumeration_type: - case DW_TAG_string_type: - case DW_TAG_union_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_subrange_type: - case DW_TAG_file_type: - case DW_TAG_packed_type: - case DW_TAG_thrown_type: - case DW_TAG_volatile_type: - case DW_TAG_restrict_type: // DWARF3 - case DW_TAG_interface_type: - case DW_TAG_unspecified_type: - case DW_TAG_mutable_type: // withdrawn - case DW_TAG_shared_type: - case DW_TAG_rvalue_reference_type: - mapOffsetToType.insert(std::pair(off + id.entryOff, typeID)); - typeID++; - } - } - else - { - int cvtype = -1; - switch(id.tag) - { - case DW_TAG_base_type: - cvtype = addDWARFBasicType(id.name, id.encoding, id.byte_size); - break; - case DW_TAG_typedef: - cvtype = appendModifierType(getTypeByDWARFOffset(cu, id.type), 0); - addUdtSymbol(cvtype, id.name); - break; - case DW_TAG_pointer_type: - cvtype = appendPointerType(getTypeByDWARFOffset(cu, id.type), pointerAttr); - break; - case DW_TAG_const_type: - cvtype = appendModifierType(getTypeByDWARFOffset(cu, id.type), 1); - break; - case DW_TAG_reference_type: - cvtype = appendPointerType(getTypeByDWARFOffset(cu, id.type), pointerAttr | 0x20); - break; - - case DW_TAG_class_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - cvtype = addDWARFStructure(id, cu, p, endStack.back()); - break; - case DW_TAG_array_type: - cvtype = addDWARFArray(id, cu, p, endStack.back()); - break; - case DW_TAG_subroutine_type: - case DW_TAG_subrange_type: - - case DW_TAG_enumeration_type: - case DW_TAG_string_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_file_type: - case DW_TAG_packed_type: - case DW_TAG_thrown_type: - case DW_TAG_volatile_type: - case DW_TAG_restrict_type: // DWARF3 - case DW_TAG_interface_type: - case DW_TAG_unspecified_type: - case DW_TAG_mutable_type: // withdrawn - case DW_TAG_shared_type: - case DW_TAG_rvalue_reference_type: - cvtype = appendPointerType(0x74, pointerAttr); - break; - - case DW_TAG_subprogram: - if(id.name && id.pclo && id.pchi) - { - addDWARFProc(id, cu, p, endStack.back()); - int rc = mod->AddPublic2(id.name, img.codeSegment + 1, id.pclo - codeSegOff, 0); - } - break; - - case DW_TAG_compile_unit: - #if !FULL_CONTRIB - if(id.dir && id.name) - { - if(id.ranges > 0 && id.ranges < img.debug_ranges_length) - { - unsigned char* r = (unsigned char*)img.debug_ranges + id.ranges; - unsigned char* rend = (unsigned char*)img.debug_ranges + img.debug_ranges_length; - while(r < rend) - { - unsigned long pclo = RD4(r); r += 4; - unsigned long pchi = RD4(r); r += 4; - if(pclo == 0 && pchi == 0) - break; - //printf("%s %s %x - %x\n", dir, name, pclo, pchi); - if(!addDWARFSectionContrib(mod, pclo, pchi)) - return false; - } - } - else - { - //printf("%s %s %x - %x\n", dir, name, pclo, pchi); - if(!addDWARFSectionContrib(mod, id.pclo, id.pchi)) - return false; - } - } - #endif - break; - - case DW_TAG_variable: - if(id.name) - { - int seg = -1; - unsigned long segOff; - if(id.location == 0 && id.external && id.linkage_name) - { - seg = img.findSymbol(id.linkage_name, segOff); - } - else - { - int cvid; - segOff = decodeLocation(id.location, cvid); - if(cvid == S_GDATA_V2) - seg = img.findSection(segOff); - if(seg >= 0) - segOff -= img.getImageBase() + img.getSection(seg).VirtualAddress; - } - if(seg >= 0) - { - int type = getTypeByDWARFOffset(cu, id.type); - appendGlobalVar(id.name, type, seg + 1, segOff); - int rc = mod->AddPublic2(id.name, seg + 1, segOff, type); - } - } - break; - case DW_TAG_formal_parameter: - case DW_TAG_unspecified_parameters: - case DW_TAG_inheritance: - case DW_TAG_member: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - default: - break; - } - if(cvtype >= 0) - { - assert(cvtype == typeID); typeID++; - assert(mapOffsetToType[off + id.entryOff] == cvtype); - } - } - } - off += length; - } - - if(op == kOpMapTypes) - nextDwarfType = typeID; - - return true; + mspdb::Mod* mod = globalMod(); + int typeID = nextUserType; + + int pointerAttr = img.isX64() ? 0x1000C : 0x800A; + for(unsigned long off = 0; off < img.debug_info_length; ) + { + DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*) (img.debug_info + off); + int length = cu->unit_length; + if(length < 0) + break; + + length += sizeof(length); + unsigned char* end = (unsigned char*) cu + length; + std::vector endStack; + endStack.push_back(end); + + for(unsigned char* p = (unsigned char*) (cu + 1); endStack.size() > 0; ) + { + if(p >= endStack.back()) + { + endStack.pop_back(); + continue; + } + DWARF_InfoData id; + if(!readDWARFInfoData(id, cu, p)) + continue; + if(id.specification) + { + unsigned char* q = (unsigned char*) cu + id.specification; + readDWARFInfoData(id, cu, q, true); + } + if(id.hasChild) + if(id.sibling) + endStack.push_back((unsigned char*) cu + id.sibling); + else + endStack.push_back(endStack.back()); + + if(op == kOpMapTypes) + { + switch(id.tag) + { + case DW_TAG_base_type: + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_subroutine_type: + case DW_TAG_array_type: + case DW_TAG_const_type: + case DW_TAG_structure_type: + case DW_TAG_reference_type: + + case DW_TAG_class_type: + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_union_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_set_type: + case DW_TAG_subrange_type: + case DW_TAG_file_type: + case DW_TAG_packed_type: + case DW_TAG_thrown_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: // DWARF3 + case DW_TAG_interface_type: + case DW_TAG_unspecified_type: + case DW_TAG_mutable_type: // withdrawn + case DW_TAG_shared_type: + case DW_TAG_rvalue_reference_type: + mapOffsetToType.insert(std::pair(off + id.entryOff, typeID)); + typeID++; + } + } + else + { + int cvtype = -1; + switch(id.tag) + { + case DW_TAG_base_type: + cvtype = addDWARFBasicType(id.name, id.encoding, id.byte_size); + break; + case DW_TAG_typedef: + cvtype = appendModifierType(getTypeByDWARFOffset(cu, id.type), 0); + addUdtSymbol(cvtype, id.name); + break; + case DW_TAG_pointer_type: + cvtype = appendPointerType(getTypeByDWARFOffset(cu, id.type), pointerAttr); + break; + case DW_TAG_const_type: + cvtype = appendModifierType(getTypeByDWARFOffset(cu, id.type), 1); + break; + case DW_TAG_reference_type: + cvtype = appendPointerType(getTypeByDWARFOffset(cu, id.type), pointerAttr | 0x20); + break; + + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + cvtype = addDWARFStructure(id, cu, p, endStack.back()); + break; + case DW_TAG_array_type: + cvtype = addDWARFArray(id, cu, p, endStack.back()); + break; + case DW_TAG_subroutine_type: + case DW_TAG_subrange_type: + + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_set_type: + case DW_TAG_file_type: + case DW_TAG_packed_type: + case DW_TAG_thrown_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: // DWARF3 + case DW_TAG_interface_type: + case DW_TAG_unspecified_type: + case DW_TAG_mutable_type: // withdrawn + case DW_TAG_shared_type: + case DW_TAG_rvalue_reference_type: + cvtype = appendPointerType(0x74, pointerAttr); + break; + + case DW_TAG_subprogram: + if(id.name && id.pclo && id.pchi) + { + addDWARFProc(id, cu, p, endStack.back()); + int rc = mod->AddPublic2(id.name, img.codeSegment + 1, id.pclo - codeSegOff, 0); + } + break; + + case DW_TAG_compile_unit: + #if !FULL_CONTRIB + if(id.dir && id.name) + { + if(id.ranges > 0 && id.ranges < img.debug_ranges_length) + { + unsigned char* r = (unsigned char*)img.debug_ranges + id.ranges; + unsigned char* rend = (unsigned char*)img.debug_ranges + img.debug_ranges_length; + while(r < rend) + { + unsigned long pclo = RD4(r); r += 4; + unsigned long pchi = RD4(r); r += 4; + if(pclo == 0 && pchi == 0) + break; + //printf("%s %s %x - %x\n", dir, name, pclo, pchi); + if(!addDWARFSectionContrib(mod, pclo, pchi)) + return false; + } + } + else + { + //printf("%s %s %x - %x\n", dir, name, pclo, pchi); + if(!addDWARFSectionContrib(mod, id.pclo, id.pchi)) + return false; + } + } + #endif + break; + + case DW_TAG_variable: + if(id.name) + { + int seg = -1; + unsigned long segOff; + if(id.location == 0 && id.external && id.linkage_name) + { + seg = img.findSymbol(id.linkage_name, segOff); + } + else + { + int cvid; + segOff = decodeLocation(id.location, cvid); + if(cvid == S_GDATA_V2) + seg = img.findSection(segOff); + if(seg >= 0) + segOff -= img.getImageBase() + img.getSection(seg).VirtualAddress; + } + if(seg >= 0) + { + int type = getTypeByDWARFOffset(cu, id.type); + appendGlobalVar(id.name, type, seg + 1, segOff); + int rc = mod->AddPublic2(id.name, seg + 1, segOff, type); + } + } + break; + case DW_TAG_formal_parameter: + case DW_TAG_unspecified_parameters: + case DW_TAG_inheritance: + case DW_TAG_member: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: + default: + break; + } + if(cvtype >= 0) + { + assert(cvtype == typeID); typeID++; + assert(mapOffsetToType[off + id.entryOff] == cvtype); + } + } + } + off += length; + } + + if(op == kOpMapTypes) + nextDwarfType = typeID; + + return true; } bool CV2PDB::createDWARFModules() { - if(!img.debug_info) - return setError("no .debug_info section found"); + if(!img.debug_info) + return setError("no .debug_info section found"); - codeSegOff = img.getImageBase() + img.getSection(img.codeSegment).VirtualAddress; + codeSegOff = img.getImageBase() + img.getSection(img.codeSegment).VirtualAddress; - mspdb::Mod* mod = globalMod(); - for (int s = 0; s < img.countSections(); s++) + mspdb::Mod* mod = globalMod(); + for (int s = 0; s < img.countSections(); s++) { - const IMAGE_SECTION_HEADER& sec = img.getSection(s); - int rc = dbi->AddSec(s + 1, 0x10d, 0, sec.SizeOfRawData); + const IMAGE_SECTION_HEADER& sec = img.getSection(s); + int rc = dbi->AddSec(s + 1, 0x10d, 0, sec.SizeOfRawData); if (rc <= 0) return setError("cannot add section"); } #define FULL_CONTRIB 1 #if FULL_CONTRIB - // we use a single global module, so we can simply add the whole text segment - int segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO - int s = img.codeSegment; - int pclo = 0; // img.getImageBase() + img.getSection(s).VirtualAddress; - int pchi = pclo + img.getSection(s).Misc.VirtualSize; - int rc = mod->AddSecContrib(s + 1, pclo, pchi - pclo, segFlags); - if (rc <= 0) - return setError("cannot add section contribution to module"); + // we use a single global module, so we can simply add the whole text segment + int segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO + int s = img.codeSegment; + int pclo = 0; // img.getImageBase() + img.getSection(s).VirtualAddress; + int pchi = pclo + img.getSection(s).Misc.VirtualSize; + int rc = mod->AddSecContrib(s + 1, pclo, pchi - pclo, segFlags); + if (rc <= 0) + return setError("cannot add section contribution to module"); #endif - checkUserTypeAlloc(); + checkUserTypeAlloc(); *(DWORD*) userTypes = 4; cbUserTypes = 4; createEmptyFieldListType(); if(Dversion > 0) - { - appendComplex(0x50, 0x40, 4, "cfloat"); - appendComplex(0x51, 0x41, 8, "cdouble"); - appendComplex(0x52, 0x42, 12, "creal"); - } - - countEntries = 0; - if(!iterateDWARFDebugInfo(kOpMapTypes)) - return false; - if(!iterateDWARFDebugInfo(kOpCreateTypes)) - return false; + { + appendComplex(0x50, 0x40, 4, "cfloat"); + appendComplex(0x51, 0x41, 8, "cdouble"); + appendComplex(0x52, 0x42, 12, "creal"); + } + + countEntries = 0; + if(!iterateDWARFDebugInfo(kOpMapTypes)) + return false; + if(!iterateDWARFDebugInfo(kOpCreateTypes)) + return false; #if 0 modules = new mspdb::Mod* [countEntries]; memset (modules, 0, countEntries * sizeof(*modules)); for (int m = 0; m < countEntries; m++) - { + { mspdb::Mod* mod = globalMod(); - } + } #endif - if(cbUserTypes > 0 || cbDwarfTypes) - { - if(dwarfTypes) - { - checkUserTypeAlloc(cbDwarfTypes); - memcpy(userTypes + cbUserTypes, dwarfTypes, cbDwarfTypes); - cbUserTypes += cbDwarfTypes; - cbDwarfTypes = 0; - } - int rc = mod->AddTypes(userTypes, cbUserTypes); + if(cbUserTypes > 0 || cbDwarfTypes) + { + if(dwarfTypes) + { + checkUserTypeAlloc(cbDwarfTypes); + memcpy(userTypes + cbUserTypes, dwarfTypes, cbDwarfTypes); + cbUserTypes += cbDwarfTypes; + cbDwarfTypes = 0; + } + int rc = mod->AddTypes(userTypes, cbUserTypes); if (rc <= 0) return setError("cannot add type info to module"); - } - return true; + } + return true; } bool isRelativePath(const std::string& s) { - if(s.length() < 1) - return true; - if(s[0] == '/' || s[0] == '\\') - return false; - if(s.length() < 2) - return true; - if(s[1] == ':') - return false; - return true; + if(s.length() < 1) + return true; + if(s[0] == '/' || s[0] == '\\') + return false; + if(s.length() < 2) + return true; + if(s[1] == ':') + return false; + return true; } static int cmpAdr(const void* s1, const void* s2) { - const mspdb::LineInfoEntry* e1 = (const mspdb::LineInfoEntry*) s1; - const mspdb::LineInfoEntry* e2 = (const mspdb::LineInfoEntry*) s2; - return e1->offset - e2->offset; + const mspdb::LineInfoEntry* e1 = (const mspdb::LineInfoEntry*) s1; + const mspdb::LineInfoEntry* e2 = (const mspdb::LineInfoEntry*) s2; + return e1->offset - e2->offset; } bool _flushDWARFLines(CV2PDB* cv2pdb, DWARF_LineState& state) { - if(state.lineInfo.size() == 0) - return true; - - unsigned int saddr = state.lineInfo[0].offset; - unsigned int eaddr = state.lineInfo.back().offset; - int segIndex = cv2pdb->img.findSection(saddr + state.seg_offset); - if(segIndex < 0) - { - // throw away invalid lines (mostly due to "set address to 0") - state.lineInfo.resize(0); - return true; - //return false; - } + if(state.lineInfo.size() == 0) + return true; + + unsigned int saddr = state.lineInfo[0].offset; + unsigned int eaddr = state.lineInfo.back().offset; + int segIndex = cv2pdb->img.findSection(saddr + state.seg_offset); + if(segIndex < 0) + { + // throw away invalid lines (mostly due to "set address to 0") + state.lineInfo.resize(0); + return true; + //return false; + } // if(saddr >= 0x4000) // return true; - const DWARF_FileName* dfn; - if(state.file == 0) - dfn = state.file_ptr; - else if(state.file > 0 && state.file <= state.files.size()) - dfn = &state.files[state.file - 1]; - else - return false; - std::string fname = dfn->file_name; - - if(isRelativePath(fname) && - dfn->dir_index > 0 && dfn->dir_index <= state.include_dirs.size()) - { - std::string dir = state.include_dirs[dfn->dir_index - 1]; - if(dir.length() > 0 && dir[dir.length() - 1] != '/' && dir[dir.length() - 1] != '\\') - dir.append("\\"); - fname = dir + fname; - } - for(size_t i = 0; i < fname.length(); i++) - if(fname[i] == '/') - fname[i] = '\\'; - - mspdb::Mod* mod = cv2pdb->globalMod(); + const DWARF_FileName* dfn; + if(state.file == 0) + dfn = state.file_ptr; + else if(state.file > 0 && state.file <= state.files.size()) + dfn = &state.files[state.file - 1]; + else + return false; + std::string fname = dfn->file_name; + + if(isRelativePath(fname) && + dfn->dir_index > 0 && dfn->dir_index <= state.include_dirs.size()) + { + std::string dir = state.include_dirs[dfn->dir_index - 1]; + if(dir.length() > 0 && dir[dir.length() - 1] != '/' && dir[dir.length() - 1] != '\\') + dir.append("\\"); + fname = dir + fname; + } + for(size_t i = 0; i < fname.length(); i++) + if(fname[i] == '/') + fname[i] = '\\'; + + mspdb::Mod* mod = cv2pdb->globalMod(); #if 1 - bool dump = false; // (fname == "cvtest.d"); - //qsort(&state.lineInfo[0], state.lineInfo.size(), sizeof(state.lineInfo[0]), cmpAdr); + bool dump = false; // (fname == "cvtest.d"); + //qsort(&state.lineInfo[0], state.lineInfo.size(), sizeof(state.lineInfo[0]), cmpAdr); #if 0 - printf("%s:\n", fname.c_str()); - for(size_t ln = 0; ln < state.lineInfo.size(); ln++) - printf(" %08x: %4d\n", state.lineInfo[ln].offset + 0x401000, state.lineInfo[ln].line); + printf("%s:\n", fname.c_str()); + for(size_t ln = 0; ln < state.lineInfo.size(); ln++) + printf(" %08x: %4d\n", state.lineInfo[ln].offset + 0x401000, state.lineInfo[ln].line); #endif - unsigned int firstLine = state.lineInfo[0].line; - unsigned int firstAddr = state.lineInfo[0].offset; - unsigned int firstEntry = 0; - unsigned int entry = 0; - for(size_t ln = firstEntry; ln < state.lineInfo.size(); ln++) - { - if(state.lineInfo[ln].line < firstLine || state.lineInfo[ln].offset < firstAddr) - { - if(ln > firstEntry) - { - unsigned int length = state.lineInfo[entry-1].offset + 1; // firstAddr has been subtracted before - if(dump) - printf("AddLines(%08x+%04x, Line=%4d+%3d, %s)\n", firstAddr, length, firstLine, entry - firstEntry, fname.c_str()); - int rc = mod->AddLines(fname.c_str(), segIndex + 1, firstAddr, length, firstAddr, firstLine, - (unsigned char*) &state.lineInfo[firstEntry], - (ln - firstEntry) * sizeof(state.lineInfo[0])); - firstLine = state.lineInfo[ln].line; - firstAddr = state.lineInfo[ln].offset; - firstEntry = entry; - } - } - else if(ln > firstEntry && state.lineInfo[ln].offset == state.lineInfo[ln-1].offset) - continue; // skip entries without offset change - state.lineInfo[entry].line = state.lineInfo[ln].line - firstLine; - state.lineInfo[entry].offset = state.lineInfo[ln].offset - firstAddr; - entry++; - } - unsigned int length = eaddr - firstAddr; - if(dump) - printf("AddLines(%08x+%04x, Line=%4d+%3d, %s)\n", firstAddr, length, firstLine, entry - firstEntry, fname.c_str()); - int rc = mod->AddLines(fname.c_str(), segIndex + 1, firstAddr, length, firstAddr, firstLine, - (unsigned char*) &state.lineInfo[firstEntry], - (entry - firstEntry) * sizeof(state.lineInfo[0])); + unsigned int firstLine = state.lineInfo[0].line; + unsigned int firstAddr = state.lineInfo[0].offset; + unsigned int firstEntry = 0; + unsigned int entry = 0; + for(size_t ln = firstEntry; ln < state.lineInfo.size(); ln++) + { + if(state.lineInfo[ln].line < firstLine || state.lineInfo[ln].offset < firstAddr) + { + if(ln > firstEntry) + { + unsigned int length = state.lineInfo[entry-1].offset + 1; // firstAddr has been subtracted before + if(dump) + printf("AddLines(%08x+%04x, Line=%4d+%3d, %s)\n", firstAddr, length, firstLine, entry - firstEntry, fname.c_str()); + int rc = mod->AddLines(fname.c_str(), segIndex + 1, firstAddr, length, firstAddr, firstLine, + (unsigned char*) &state.lineInfo[firstEntry], + (ln - firstEntry) * sizeof(state.lineInfo[0])); + firstLine = state.lineInfo[ln].line; + firstAddr = state.lineInfo[ln].offset; + firstEntry = entry; + } + } + else if(ln > firstEntry && state.lineInfo[ln].offset == state.lineInfo[ln-1].offset) + continue; // skip entries without offset change + state.lineInfo[entry].line = state.lineInfo[ln].line - firstLine; + state.lineInfo[entry].offset = state.lineInfo[ln].offset - firstAddr; + entry++; + } + unsigned int length = eaddr - firstAddr; + if(dump) + printf("AddLines(%08x+%04x, Line=%4d+%3d, %s)\n", firstAddr, length, firstLine, entry - firstEntry, fname.c_str()); + int rc = mod->AddLines(fname.c_str(), segIndex + 1, firstAddr, length, firstAddr, firstLine, + (unsigned char*) &state.lineInfo[firstEntry], + (entry - firstEntry) * sizeof(state.lineInfo[0])); #else - unsigned int firstLine = 0; - unsigned int firstAddr = 0; - int rc = mod->AddLines(fname.c_str(), segIndex + 1, saddr, eaddr - saddr, firstAddr, firstLine, - (unsigned char*) &state.lineInfo[0], state.lineInfo.size() * sizeof(state.lineInfo[0])); + unsigned int firstLine = 0; + unsigned int firstAddr = 0; + int rc = mod->AddLines(fname.c_str(), segIndex + 1, saddr, eaddr - saddr, firstAddr, firstLine, + (unsigned char*) &state.lineInfo[0], state.lineInfo.size() * sizeof(state.lineInfo[0])); #endif - state.lineInfo.resize(0); - return rc > 0; + state.lineInfo.resize(0); + return rc > 0; } bool CV2PDB::addDWARFLines() { - if(!img.debug_line) - return setError("no .debug_line section found"); - - mspdb::Mod* mod = globalMod(); - for(unsigned long off = 0; off < img.debug_line_length; ) - { - DWARF_LineNumberProgramHeader* hdr = (DWARF_LineNumberProgramHeader*) (img.debug_line + off); - int length = hdr->unit_length; - if(length < 0) - break; - length += sizeof(length); - - unsigned char* p = (unsigned char*) (hdr + 1); - unsigned char* end = (unsigned char*) hdr + length; - - std::vector opcode_lengths; - opcode_lengths.resize(hdr->opcode_base); - opcode_lengths[0] = 0; - for(int o = 1; o < hdr->opcode_base && p < end; o++) - opcode_lengths[o] = LEB128(p); - - DWARF_LineState state; - state.seg_offset = img.getImageBase() + img.getSection(img.codeSegment).VirtualAddress; - - // dirs - while(p < end) - { - if(*p == 0) - break; - state.include_dirs.push_back((const char*) p); - p += strlen((const char*) p) + 1; - } - p++; - - // files - DWARF_FileName fname; - while(p < end && *p) - { - fname.read(p); - state.files.push_back(fname); - } - p++; - - std::vector lineInfo; - - state.init(hdr); - while(p < end) - { - int opcode = *p++; - if(opcode >= hdr->opcode_base) - { - // special opcode - int adjusted_opcode = opcode - hdr->opcode_base; - int operation_advance = adjusted_opcode / hdr->line_range; - state.advance_addr(hdr, operation_advance); - int line_advance = hdr->line_base + (adjusted_opcode % hdr->line_range); - state.line += line_advance; - - state.addLineInfo(); - - state.basic_block = false; - state.prologue_end = false; - state.epilogue_end = false; - state.discriminator = 0; - } - else - { - switch(opcode) - { - case 0: // extended - { - int exlength = LEB128(p); - unsigned char* q = p + exlength; - int excode = *p++; - switch(excode) - { - case DW_LNE_end_sequence: - if((char*)p - img.debug_line >= 0xe4e0) - p = p; - state.end_sequence = true; - state.last_addr = state.address; - state.addLineInfo(); - if(!_flushDWARFLines(this, state)) - return setError("cannot add line number info to module"); - state.init(hdr); - break; - case DW_LNE_set_address: - if(unsigned long adr = RD4(p)) - state.address = adr; - else - state.address = state.last_addr; // strange adr 0 for templates? - state.op_index = 0; - break; - case DW_LNE_define_file: - fname.read(p); - state.file_ptr = &fname; - state.file = 0; - break; - case DW_LNE_set_discriminator: - state.discriminator = LEB128(p); - break; - } - p = q; - } - break; - case DW_LNS_copy: - state.addLineInfo(); - state.basic_block = false; - state.prologue_end = false; - state.epilogue_end = false; - state.discriminator = 0; - break; - case DW_LNS_advance_pc: - state.advance_addr(hdr, LEB128(p)); - break; - case DW_LNS_advance_line: - state.line += SLEB128(p); - break; - case DW_LNS_set_file: - if(!_flushDWARFLines(this, state)) - return setError("cannot add line number info to module"); - state.file = LEB128(p); - break; - case DW_LNS_set_column: - state.column = LEB128(p); - break; - case DW_LNS_negate_stmt: - state.is_stmt = !state.is_stmt; - break; - case DW_LNS_set_basic_block: - state.basic_block = true; - break; - case DW_LNS_const_add_pc: - state.advance_addr(hdr, (255 - hdr->opcode_base) / hdr->line_range); - break; - case DW_LNS_fixed_advance_pc: - state.address += RD2(p); - state.op_index = 0; - break; - case DW_LNS_set_prologue_end: - state.prologue_end = true; - break; - case DW_LNS_set_epilogue_begin: - state.epilogue_end = true; - break; - case DW_LNS_set_isa: - state.isa = LEB128(p); - break; - default: - // unknown standard opcode - for(unsigned int arg = 0; arg < opcode_lengths[opcode]; arg++) - LEB128(p); - break; - } - } - } - if(!_flushDWARFLines(this, state)) - return setError("cannot add line number info to module"); - - off += length; - } - - return true; + if(!img.debug_line) + return setError("no .debug_line section found"); + + mspdb::Mod* mod = globalMod(); + for(unsigned long off = 0; off < img.debug_line_length; ) + { + DWARF_LineNumberProgramHeader* hdr = (DWARF_LineNumberProgramHeader*) (img.debug_line + off); + int length = hdr->unit_length; + if(length < 0) + break; + length += sizeof(length); + + unsigned char* p = (unsigned char*) (hdr + 1); + unsigned char* end = (unsigned char*) hdr + length; + + std::vector opcode_lengths; + opcode_lengths.resize(hdr->opcode_base); + opcode_lengths[0] = 0; + for(int o = 1; o < hdr->opcode_base && p < end; o++) + opcode_lengths[o] = LEB128(p); + + DWARF_LineState state; + state.seg_offset = img.getImageBase() + img.getSection(img.codeSegment).VirtualAddress; + + // dirs + while(p < end) + { + if(*p == 0) + break; + state.include_dirs.push_back((const char*) p); + p += strlen((const char*) p) + 1; + } + p++; + + // files + DWARF_FileName fname; + while(p < end && *p) + { + fname.read(p); + state.files.push_back(fname); + } + p++; + + std::vector lineInfo; + + state.init(hdr); + while(p < end) + { + int opcode = *p++; + if(opcode >= hdr->opcode_base) + { + // special opcode + int adjusted_opcode = opcode - hdr->opcode_base; + int operation_advance = adjusted_opcode / hdr->line_range; + state.advance_addr(hdr, operation_advance); + int line_advance = hdr->line_base + (adjusted_opcode % hdr->line_range); + state.line += line_advance; + + state.addLineInfo(); + + state.basic_block = false; + state.prologue_end = false; + state.epilogue_end = false; + state.discriminator = 0; + } + else + { + switch(opcode) + { + case 0: // extended + { + int exlength = LEB128(p); + unsigned char* q = p + exlength; + int excode = *p++; + switch(excode) + { + case DW_LNE_end_sequence: + if((char*)p - img.debug_line >= 0xe4e0) + p = p; + state.end_sequence = true; + state.last_addr = state.address; + state.addLineInfo(); + if(!_flushDWARFLines(this, state)) + return setError("cannot add line number info to module"); + state.init(hdr); + break; + case DW_LNE_set_address: + if(unsigned long adr = RD4(p)) + state.address = adr; + else + state.address = state.last_addr; // strange adr 0 for templates? + state.op_index = 0; + break; + case DW_LNE_define_file: + fname.read(p); + state.file_ptr = &fname; + state.file = 0; + break; + case DW_LNE_set_discriminator: + state.discriminator = LEB128(p); + break; + } + p = q; + } + break; + case DW_LNS_copy: + state.addLineInfo(); + state.basic_block = false; + state.prologue_end = false; + state.epilogue_end = false; + state.discriminator = 0; + break; + case DW_LNS_advance_pc: + state.advance_addr(hdr, LEB128(p)); + break; + case DW_LNS_advance_line: + state.line += SLEB128(p); + break; + case DW_LNS_set_file: + if(!_flushDWARFLines(this, state)) + return setError("cannot add line number info to module"); + state.file = LEB128(p); + break; + case DW_LNS_set_column: + state.column = LEB128(p); + break; + case DW_LNS_negate_stmt: + state.is_stmt = !state.is_stmt; + break; + case DW_LNS_set_basic_block: + state.basic_block = true; + break; + case DW_LNS_const_add_pc: + state.advance_addr(hdr, (255 - hdr->opcode_base) / hdr->line_range); + break; + case DW_LNS_fixed_advance_pc: + state.address += RD2(p); + state.op_index = 0; + break; + case DW_LNS_set_prologue_end: + state.prologue_end = true; + break; + case DW_LNS_set_epilogue_begin: + state.epilogue_end = true; + break; + case DW_LNS_set_isa: + state.isa = LEB128(p); + break; + default: + // unknown standard opcode + for(unsigned int arg = 0; arg < opcode_lengths[opcode]; arg++) + LEB128(p); + break; + } + } + } + if(!_flushDWARFLines(this, state)) + return setError("cannot add line number info to module"); + + off += length; + } + + return true; } bool CV2PDB::relocateDebugLineInfo() { - if(!img.reloc || !img.reloc_length) - return true; - - unsigned int img_base = 0x400000; - char* relocbase = img.reloc; - char* relocend = img.reloc + img.reloc_length; - while(relocbase < relocend) - { - unsigned int virtadr = *(unsigned int *) relocbase; - unsigned int chksize = *(unsigned int *) (relocbase + 4); - - char* p = img.RVA (virtadr, 1); - if(p >= img.debug_line && p < img.debug_line + img.debug_line_length) - { - for (unsigned int p = 8; p < chksize; p += 2) - { - unsigned short entry = *(unsigned short*)(relocbase + p); - unsigned short type = (entry >> 12) & 0xf; - unsigned short off = entry & 0xfff; - - if(type == 3) // HIGHLOW - { - *(long*) (p + off) += img_base; - } - } - } - if(chksize == 0 || chksize >= img.reloc_length) - break; - relocbase += chksize; - } - return true; + if(!img.reloc || !img.reloc_length) + return true; + + unsigned int img_base = 0x400000; + char* relocbase = img.reloc; + char* relocend = img.reloc + img.reloc_length; + while(relocbase < relocend) + { + unsigned int virtadr = *(unsigned int *) relocbase; + unsigned int chksize = *(unsigned int *) (relocbase + 4); + + char* p = img.RVA (virtadr, 1); + if(p >= img.debug_line && p < img.debug_line + img.debug_line_length) + { + for (unsigned int p = 8; p < chksize; p += 2) + { + unsigned short entry = *(unsigned short*)(relocbase + p); + unsigned short type = (entry >> 12) & 0xf; + unsigned short off = entry & 0xfff; + + if(type == 3) // HIGHLOW + { + *(long*) (p + off) += img_base; + } + } + } + if(chksize == 0 || chksize >= img.reloc_length) + break; + relocbase += chksize; + } + return true; } bool CV2PDB::addDWARFPublics() { - mspdb::Mod* mod = globalMod(); + mspdb::Mod* mod = globalMod(); - int type = 0; - int rc = mod->AddPublic2("public_all", img.codeSegment + 1, 0, 0x1000); + int type = 0; + int rc = mod->AddPublic2("public_all", img.codeSegment + 1, 0, 0x1000); if (rc <= 0) return setError("cannot add public"); - return true; + return true; } bool CV2PDB::writeDWARFImage(const char* opath) diff --git a/src/main.cpp b/src/main.cpp index 69807aa..7ac2972 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) if (!img.load(argv[1])) fatal("%s: %s", argv[1], img.getLastError()); - if (img.countCVEntries() == 0 && !img.hasDWARF()) + if (img.countCVEntries() == 0 && !img.hasDWARF()) fatal("%s: no codeview debug entries found", argv[1]); CV2PDB cv2pdb(img); @@ -146,55 +146,55 @@ int main(int argc, char** argv) if(!cv2pdb.openPDB(pdbname)) fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if(img.hasDWARF()) - { - if(!cv2pdb.relocateDebugLineInfo()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + if(img.hasDWARF()) + { + if(!cv2pdb.relocateDebugLineInfo()) + fatal("%s: %s", argv[1], cv2pdb.getLastError()); - if(!cv2pdb.createDWARFModules()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if(!cv2pdb.createDWARFModules()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if(!cv2pdb.addDWARFTypes()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if(!cv2pdb.addDWARFTypes()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if(!cv2pdb.addDWARFLines()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if(!cv2pdb.addDWARFLines()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.addDWARFPublics()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.addDWARFPublics()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.writeDWARFImage(outname)) - fatal("%s: %s", outname, cv2pdb.getLastError()); - } - else - { - if (!cv2pdb.initSegMap()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + if (!cv2pdb.writeDWARFImage(outname)) + fatal("%s: %s", outname, cv2pdb.getLastError()); + } + else + { + if (!cv2pdb.initSegMap()) + fatal("%s: %s", argv[1], cv2pdb.getLastError()); - if (!cv2pdb.initGlobalSymbols()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + if (!cv2pdb.initGlobalSymbols()) + fatal("%s: %s", argv[1], cv2pdb.getLastError()); - if (!cv2pdb.initGlobalTypes()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + if (!cv2pdb.initGlobalTypes()) + fatal("%s: %s", argv[1], cv2pdb.getLastError()); - if (!cv2pdb.createModules()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.createModules()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.addTypes()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.addTypes()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.addSymbols()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.addSymbols()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.addSrcLines()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.addSrcLines()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.addPublics()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + if (!cv2pdb.addPublics()) + fatal("%s: %s", pdbname, cv2pdb.getLastError()); - if (!cv2pdb.writeImage(outname)) - fatal("%s: %s", outname, cv2pdb.getLastError()); - } + if (!cv2pdb.writeImage(outname)) + fatal("%s: %s", outname, cv2pdb.getLastError()); + } return 0; } diff --git a/src/symutil.cpp b/src/symutil.cpp index 91e086e..7c92c0c 100644 --- a/src/symutil.cpp +++ b/src/symutil.cpp @@ -113,9 +113,9 @@ int pstrlen(const BYTE* &p) int pstrmemlen(const BYTE* p) { - const BYTE* q = p; - int len = pstrlen(p); - return len + (p - q); + const BYTE* q = p; + int len = pstrlen(p); + return len + (p - q); } int dstrlen(const BYTE* &p, bool cstr) @@ -146,19 +146,19 @@ char* p2c(const p_string& p, int idx) int c2p(const char* c, BYTE* p) { - BYTE* q = p; - int len = strlen(c); - if(len > 255) - { - *p++ = 0xff; - *p++ = 0; - *p++ = len & 0xff; - *p++ = len >> 8; - } - else - *p++ = len; - memcpy(p, c, len); - return p + len - q; + BYTE* q = p; + int len = strlen(c); + if(len > 255) + { + *p++ = 0xff; + *p++ = 0; + *p++ = len & 0xff; + *p++ = len >> 8; + } + else + *p++ = len; + memcpy(p, c, len); + return p + len - q; } int c2p(const char* c, p_string& p) -- cgit v0.12