BinStr* BinStrToUnicode(BinStr* pSource, bool Swap) { if(pSource) { pSource->appendInt8(0); BinStr* tmp = new BinStr(); char* pb = (char*)(pSource->ptr()); int l=pSource->length(), L = sizeof(WCHAR)*l; if(tmp) { WCHAR* wz = (WCHAR*)(tmp->getBuff(L)); if(wz) { memset(wz,0,L); WszMultiByteToWideChar(g_uCodePage,0,pb,-1,wz,l); tmp->remove(L-(DWORD)wcslen(wz)*sizeof(WCHAR)); #if BIGENDIAN if (Swap) SwapStringLength(wz, (DWORD)wcslen(wz)); #endif delete pSource; } else { delete tmp; tmp = NULL; fprintf(stderr,"\nOut of memory!\n"); } } else fprintf(stderr,"\nOut of memory!\n"); return tmp; } return NULL; }
static void OnOK(HWND hDlg, LPARAM lParam) { BinStr* s = reinterpret_cast<BinStr*>((LPARAM)GetWindowLongPtr(hDlg, GWLP_USERDATA)); if (!s) return; HWND pinCtrl = GetDlgItem(hDlg, IDC_PIN_EDIT); int len = GetWindowTextLength(pinCtrl); s->resize(len + 1); GetWindowText(pinCtrl, reinterpret_cast<LPSTR>(&(*s)[0]), static_cast<int>(s->size())); // Chop off null cause we don't need it s->resize(s->size() - 1); EndDialog(hDlg, IDOK); }
void AsmMan::EmitDebuggableAttribute(mdToken tkOwner) { mdToken tkCA; Assembler* pAsm = (Assembler*)m_pAssembler; mdToken tkTypeSpec, tkMscorlib, tkParamType; BinStr *pbsSig = new BinStr(); BinStr* bsBytes = new BinStr();; char* szName; tkMscorlib = pAsm->m_fIsMscorlib ? 1 : pAsm->GetAsmRef("mscorlib"); tkTypeSpec = pAsm->ResolveClassRef(tkMscorlib,"System.Diagnostics.DebuggableAttribute",NULL); EmitAssemblyRefs(); // just in case we gained 'mscorlib' AsmRef in GetAsmRef above BOOL fOldStyle = FALSE; if(tkMscorlib == 1) fOldStyle = (m_pAssembly->usVerMajor == 1); else { AsmManAssembly *pAssembly = GetAsmRefByName("mscorlib"); _ASSERTE(pAssembly != NULL); PREFIX_ASSUME(pAssembly != NULL); fOldStyle = (pAssembly->usVerMajor == 1); } bsBytes->appendInt8(1); bsBytes->appendInt8(0); if(fOldStyle) { pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS); corEmitInt(pbsSig,2); pbsSig->appendInt8(ELEMENT_TYPE_VOID); pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN); pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN); //New to old: 0x101->(true,true),0x03->(true,false),0x103->(true,true)+warning bsBytes->appendInt8(1); bsBytes->appendInt8((pAsm->m_dwIncludeDebugInfo==0x03 ? 0 : 1)); if(pAsm->m_dwIncludeDebugInfo == 0x103) { report->warn("\nOption /DEBUG=IMPL is invalid for legacy DebuggableAttribute, /DEBUG used.\n" ); } } else { BinStr bsSigArg; char buffer[80]; sprintf_s(buffer,80, "%s%c%s", "System.Diagnostics.DebuggableAttribute", NESTING_SEP, "DebuggingModes" ); tkParamType = pAsm->ResolveClassRef(tkMscorlib,buffer, NULL); bsSigArg.appendInt8(ELEMENT_TYPE_VALUETYPE); unsigned cnt = CorSigCompressToken(tkParamType, bsSigArg.getBuff(5)); bsSigArg.remove(5 - cnt); pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS); corEmitInt(pbsSig,1); pbsSig->appendInt8(ELEMENT_TYPE_VOID); pbsSig->append(&bsSigArg); bsBytes->appendInt32(pAsm->m_dwIncludeDebugInfo); } bsBytes->appendInt8(0); bsBytes->appendInt8(0); szName = new char[16]; strcpy_s(szName,16,".ctor"); tkCA = pAsm->MakeMemberRef(tkTypeSpec,szName,pbsSig); pAsm->DefineCV(new CustomDescr(tkOwner,tkCA,bsBytes)); }
HRESULT Assembler::CreatePEFile(WCHAR *pwzOutputFilename) { HRESULT hr; DWORD mresourceSize = 0; BYTE* mresourceData = NULL; //IUnknown *pUnknown = NULL; // DWORD i; if(bClock) cMDEmitBegin = GetTickCount(); if(m_fReportProgress) printf("Creating %s file\n", m_fOBJ ? "COFF" : "PE"); if (!m_pEmitter) { printf("Error: Cannot create a PE file with no metadata\n"); return E_FAIL; } if(!(m_fDLL || m_fEntryPointPresent)) { printf("Error: No entry point declared for executable\n"); if(!OnErrGo) return E_FAIL; } if (DoGlobalFixups() == FALSE) return E_FAIL; if(bClock) cMDEmit1 = GetTickCount(); if(m_fOBJ) { // emit pseudo-relocs to pass file name and build number to PEWriter // this should be done BEFORE method emission! char* szInFileName = new char[strlen(m_szSourceFileName)+1]; strcpy(szInFileName,m_szSourceFileName); m_pCeeFileGen->AddSectionReloc(m_pILSection,(DWORD)szInFileName,m_pILSection,(CeeSectionRelocType)0x7FFC); time_t tm; time(&tm); struct tm* loct = localtime(&tm); DWORD compid = 0x002E0000 | (loct->tm_mday + (loct->tm_mon+1)*100); m_pCeeFileGen->AddSectionReloc(m_pILSection,compid,m_pILSection,(CeeSectionRelocType)0x7FFB); } // Allocate space for a strong name signature if we're delay or full // signing the assembly. if (m_pManifest->m_sStrongName.m_pbPublicKey) if (FAILED(hr = AllocateStrongNameSignature())) goto exit; if(bClock) cMDEmit2 = GetTickCount(); // Check undefined local TypeRefs if(m_LocalTypeRefDList.COUNT()) { LocalTypeRefDescr* pLTRD=NULL; BOOL bIsUndefClass = FALSE; while((pLTRD = m_LocalTypeRefDList.POP())) { if(NULL == FindClass(pLTRD->m_szFullName)) { report->msg("%s: Reference to undefined class '%s' (token 0x%08X)\n", "Error", pLTRD->m_szFullName,pLTRD->m_tok); bIsUndefClass = TRUE; } delete pLTRD; } if(bIsUndefClass && !OnErrGo) return E_FAIL; } if(bClock) cMDEmit3 = GetTickCount(); // Emit class members and globals: { Class *pSearch; int i; if(m_fReportProgress) printf("\nEmitting members:\n"); for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(m_fReportProgress) { if(i == 0) printf("Global \t"); else printf("Class %d\t",i); } if(!EmitMembers(pSearch)) { if(!OnErrGo) return E_FAIL; } } } if(bClock) cMDEmit4 = GetTickCount(); if(m_MethodImplDList.COUNT()) { if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT()); if(!EmitMethodImpls()) { if(!OnErrGo) return E_FAIL; } } if(bClock) cMDEmitEnd = cRef2DefBegin = GetTickCount(); // Now, when all items defined in this file are emitted, let's try to resolve member refs to member defs: if(m_MemberRefDList.COUNT()) { MemberRefDescriptor* pMRD; mdToken tkMemberDef = 0; int i,j; unsigned ulTotal=0, ulDefs=0, ulRefs=0; Class *pSearch; if(m_fReportProgress) printf("Resolving member refs: "); while((pMRD = m_MemberRefDList.POP())) { tkMemberDef = 0; MethodDescriptor* pListMD; mdToken pMRD_tdClass = pMRD->m_tdClass; char* pMRD_szName = pMRD->m_szName; ULONG pMRD_dwCSig = (pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->length() : 0); PCOR_SIGNATURE pMRD_pSig = (PCOR_SIGNATURE)(pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->ptr() : NULL); ulTotal++; // MemberRef may reference a method or a field if((pMRD_pSig==NULL)||(*pMRD_pSig != IMAGE_CEE_CS_CALLCONV_FIELD)) { for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(pMRD_tdClass != pSearch->m_cl) continue; for(j=0; (pListMD = pSearch->m_MethodDList.PEEK(j)); j++) { if(pListMD->m_dwCSig != pMRD_dwCSig) continue; if(memcmp(pListMD->m_pSig,pMRD_pSig,pMRD_dwCSig)) continue; if(strcmp(pListMD->m_szName,pMRD_szName)) continue; tkMemberDef = pListMD->m_mdMethodTok; break; } } } if(tkMemberDef == 0) { if((pMRD_pSig==NULL)||(*pMRD_pSig == IMAGE_CEE_CS_CALLCONV_FIELD)) { FieldDescriptor* pListFD; for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(pMRD_tdClass != pSearch->m_cl) continue; for(j=0; (pListFD = pSearch->m_FieldDList.PEEK(j)); j++) { if(pListFD->m_pbsSig) { if(pListFD->m_pbsSig->length() != pMRD_dwCSig) continue; if(memcmp(pListFD->m_pbsSig->ptr(),pMRD_pSig,pMRD_dwCSig)) continue; } else if(pMRD_dwCSig) continue; if(strcmp(pListFD->m_szName,pMRD_szName)) continue; tkMemberDef = pListFD->m_fdFieldTok; break; } } } } if(tkMemberDef==0) { // could not resolve ref to def, make new ref and leave it this way if((pSearch = pMRD->m_pClass)) { mdToken tkRef; BinStr* pbs = new BinStr(); pbs->appendInt8(ELEMENT_TYPE_NAME); strcpy((char*)(pbs->getBuff((unsigned int)strlen(pSearch->m_szFQN)+1)),pSearch->m_szFQN); if(!ResolveTypeSpecToRef(pbs,&tkRef)) tkRef = mdTokenNil; delete pbs; if(RidFromToken(tkRef)) { ULONG cTemp = (ULONG)(strlen(pMRD_szName)+1); WCHAR* wzMemberName = new WCHAR[cTemp]; WszMultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzMemberName,cTemp); hr = m_pEmitter->DefineMemberRef(tkRef, wzMemberName, pMRD_pSig, pMRD_dwCSig, &tkMemberDef); ulRefs++; delete [] wzMemberName; } } } else ulDefs++; if(RidFromToken(tkMemberDef)) { SET_UNALIGNED_VAL32((mdToken *)pMRD->m_ulOffset, tkMemberDef); delete pMRD; } else { report->msg("Error: unresolved member ref '%s' of class 0x%08X\n",pMRD->m_szName,pMRD->m_tdClass); hr = E_FAIL; delete pMRD; if(!OnErrGo) goto exit; } } if(m_fReportProgress) printf("%d -> %d defs, %d refs\n",ulTotal,ulDefs,ulRefs); } if(bClock) cRef2DefEnd = GetTickCount(); // emit manifest info (if any) hr = S_OK; if(m_pManifest) { if (FAILED(hr = m_pManifest->EmitManifest())) goto exit; } if(g_wzResourceFile) if (FAILED(hr=m_pCeeFileGen->SetResourceFileName(m_pCeeFile, g_wzResourceFile))) goto exit; if (FAILED(hr=CreateTLSDirectory())) goto exit; if (FAILED(hr=CreateDebugDirectory())) goto exit; if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit; // Reserve a buffer for the meta-data DWORD metaDataSize; if (FAILED(hr=m_pEmitter->GetSaveSize(cssAccurate, &metaDataSize))) goto exit; BYTE* metaData; if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData))) goto exit; ULONG metaDataOffset; if (FAILED(hr=m_pCeeFileGen->GetSectionDataLen(m_pILSection, &metaDataOffset))) goto exit; metaDataOffset -= metaDataSize; // set managed resource entry, if any if(m_pManifest && m_pManifest->m_dwMResSizeTotal) { mresourceSize = m_pManifest->m_dwMResSizeTotal; if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize, sizeof(DWORD), (void**) &mresourceData))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit; } if(m_VTFList.COUNT()) { GlobalLabel *pGlobalLabel; VTFEntry* pVTFEntry; if(m_pVTable) delete m_pVTable; // can't have both; list takes precedence m_pVTable = new BinStr(); hr = S_OK; for(WORD k=0; (pVTFEntry = m_VTFList.POP()); k++) { if((pGlobalLabel = FindGlobalLabel(pVTFEntry->m_szLabel))) { MethodDescriptor* pMD; Class* pClass; m_pVTable->appendInt32(pGlobalLabel->m_GlobalOffset); m_pVTable->appendInt16(pVTFEntry->m_wCount); m_pVTable->appendInt16(pVTFEntry->m_wType); for(int i=0; (pClass = m_lstClass.PEEK(i)); i++) { for(WORD j = 0; (pMD = pClass->m_MethodDList.PEEK(j)); j++) { if(pMD->m_wVTEntry == k+1) { char* ptr; if(SUCCEEDED(hr = m_pCeeFileGen->ComputeSectionPointer(m_pGlobalDataSection,pGlobalLabel->m_GlobalOffset,&ptr))) { DWORD dwDelta = (pMD->m_wVTSlot-1)*((pVTFEntry->m_wType & COR_VTABLE_32BIT) ? (DWORD) sizeof(DWORD) : (DWORD) sizeof(__int64)); ptr += dwDelta; mdMethodDef* mptr = (mdMethodDef*)ptr; *mptr = pMD->m_mdMethodTok; if(pMD->m_dwExportOrdinal != 0xFFFFFFFF) { EATEntry* pEATE = new EATEntry; pEATE->dwOrdinal = pMD->m_dwExportOrdinal; pEATE->szAlias = pMD->m_szExportAlias ? pMD->m_szExportAlias : pMD->m_szName; pEATE->dwStubRVA = EmitExportStub(pGlobalLabel->m_GlobalOffset+dwDelta); m_EATList.PUSH(pEATE); } } else report->msg("Error: Failed to get pointer to label '%s' inVTable fixup\n",pVTFEntry->m_szLabel); } } } } else { report->msg("Error: Unresolved label '%s' in VTable fixup\n",pVTFEntry->m_szLabel); hr = E_FAIL; } delete pVTFEntry; } if(FAILED(hr)) goto exit; } if(m_pVTable) { //DWORD *pdw = (DWORD *)m_pVTable->ptr(); ULONG i, N = m_pVTable->length()/sizeof(DWORD); ULONG ulVTableOffset; m_pCeeFileGen->GetSectionDataLen (m_pILSection, &ulVTableOffset); if (FAILED(hr=m_pCeeFileGen->SetVTableEntry(m_pCeeFile, m_pVTable->length(),(ULONG)(m_pVTable->ptr())))) goto exit; for(i = 0; i < N; i+=2) { m_pCeeFileGen->AddSectionReloc(m_pILSection, ulVTableOffset+(i*sizeof(DWORD)), m_pGlobalDataSection, srRelocAbsolute); } } if(m_EATList.COUNT()) { if(FAILED(CreateExportDirectory())) goto exit; } if (m_fWindowsCE) { if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit; } else if(m_dwSubsystem) { if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, 4, 0))) goto exit; } if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit; if(m_dwFileAlignment) { if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit; } if(m_stBaseAddress) { if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, m_stBaseAddress))) goto exit; } //Compute all the RVAs if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit; // Fix up any fields that have RVA associated with them if (m_fHaveFieldsWithRvas) { hr = S_OK; ULONG dataSectionRVA; if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit; ULONG tlsSectionRVA; if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit; FieldDescriptor* pListFD; Class* pClass; for(int i=0; (pClass = m_lstClass.PEEK(i)); i++) { for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++) { if (pListFD->m_rvaLabel != 0) { GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel); if (pLabel == 0) { report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName); hr = E_FAIL; continue; } DWORD rva = pLabel->m_GlobalOffset; if (pLabel->m_Section == m_pTLSSection) rva += tlsSectionRVA; else { _ASSERTE(pLabel->m_Section == m_pGlobalDataSection); rva += dataSectionRVA; } if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit; } } } if (FAILED(hr)) goto exit; } if(bClock) cFilegenBegin = GetTickCount(); // actually output the meta-data if (FAILED(hr=m_pCeeFileGen->EmitMetaDataAt(m_pCeeFile, m_pEmitter, m_pILSection, metaDataOffset, metaData, metaDataSize))) goto exit; // actually output the resources if(mresourceSize && mresourceData) { size_t i, N = m_pManifest->m_dwMResNum, sizeread, L; BYTE *ptr = (BYTE*)mresourceData; BOOL mrfail = FALSE; FILE* pFile; char sz[2048]; for(i=0; i < N; i++) { memset(sz,0,2048); WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL); L = m_pManifest->m_dwMResSize[i]; sizeread = 0; memcpy(ptr,&L,sizeof(DWORD)); ptr += sizeof(DWORD); if((pFile = fopen(sz,"rb"))) { sizeread = fread((void *)ptr,1,L,pFile); fclose(pFile); ptr += sizeread; } else { report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]); mrfail = TRUE; } if(sizeread < L) { report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]); mrfail = TRUE; L -= sizeread; memset(ptr,0,L); ptr += L; } } if(mrfail) { hr = E_FAIL; goto exit; } } // Generate the file -- moved to main //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit; hr = S_OK; exit: return hr; }