diff --git a/src/coreclr/ilasm/asmman.cpp b/src/coreclr/ilasm/asmman.cpp index 2e4b98b2dca74..7b5fd474b6515 100644 --- a/src/coreclr/ilasm/asmman.cpp +++ b/src/coreclr/ilasm/asmman.cpp @@ -353,7 +353,7 @@ void AsmMan::EmitDebuggableAttribute(mdToken tkOwner) pbsSig->appendInt8(ELEMENT_TYPE_VOID); pbsSig->append(&bsSigArg); - bsBytes->appendInt32(pAsm->m_dwIncludeDebugInfo); + bsBytes->appendInt32(VAL32(pAsm->m_dwIncludeDebugInfo)); } bsBytes->appendInt8(0); bsBytes->appendInt8(0); diff --git a/src/coreclr/ilasm/asmparse.y b/src/coreclr/ilasm/asmparse.y index 29179ffcec8ae..db3d82c4baf90 100644 --- a/src/coreclr/ilasm/asmparse.y +++ b/src/coreclr/ilasm/asmparse.y @@ -331,14 +331,14 @@ ownerType : typeSpec { $$ = $1; } /* Verbal description of custom attribute initialization blob */ customBlobDescr : customBlobArgs customBlobNVPairs { $$ = $1; - $$->appendInt16(nCustomBlobNVPairs); + $$->appendInt16(VAL16(nCustomBlobNVPairs)); $$->append($2); nCustomBlobNVPairs = 0; } ; customBlobArgs : /* EMPTY */ { $$ = new BinStr(); $$->appendInt16(VAL16(0x0001)); } | customBlobArgs serInit { $$ = $1; - $$->appendFrom($2, (*($2->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); } + AppendFieldToCustomBlob($$,$2); } | customBlobArgs compControl { $$ = $1; } ; @@ -347,7 +347,7 @@ customBlobNVPairs : /* EMPTY */ { $$ = $1; $$->appendInt8($2); $$->append($3); AppendStringWithLength($$,$4); - $$->appendFrom($6, (*($6->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); + AppendFieldToCustomBlob($$,$6); nCustomBlobNVPairs++; } | customBlobNVPairs compControl { $$ = $1; } ; diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp index aa94f55797262..e8044d16ab2b7 100644 --- a/src/coreclr/ilasm/assem.cpp +++ b/src/coreclr/ilasm/assem.cpp @@ -766,7 +766,17 @@ BOOL Assembler::EmitMethod(Method *pMethod) dwCPlusTypeFlag= (DWORD)*(pMethod->m_pRetValue->ptr()); pValue = (void const *)(pMethod->m_pRetValue->ptr()+1); cbValue = pMethod->m_pRetValue->length()-1; - if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) cbValue /= sizeof(WCHAR); + if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) + { + cbValue /= sizeof(WCHAR); +#if BIGENDIAN + void* pValueTemp = _alloca(cbValue * sizeof(WCHAR)); + memcpy(pValueTemp, pValue, cbValue * sizeof(WCHAR)); + pValue = pValueTemp; + + SwapStringLength((WCHAR*)pValue, cbValue); +#endif + } } else { @@ -804,7 +814,17 @@ BOOL Assembler::EmitMethod(Method *pMethod) dwCPlusTypeFlag= (DWORD)*(pAN->pValue->ptr()); pValue = (void const *)(pAN->pValue->ptr()+1); cbValue = pAN->pValue->length()-1; - if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) cbValue /= sizeof(WCHAR); + if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) + { + cbValue /= sizeof(WCHAR); +#if BIGENDIAN + void* pValueTemp = _alloca(cbValue * sizeof(WCHAR)); + memcpy(pValueTemp, pValue, cbValue * sizeof(WCHAR)); + pValue = pValueTemp; + + SwapStringLength((WCHAR*)pValue, cbValue); +#endif + } } else { @@ -986,13 +1006,25 @@ BOOL Assembler::EmitProp(PropDescriptor* pPD) } mdOthers[nOthers] = mdMethodDefNil; // like null-terminator + void* pValue = pPD->m_pValue; +#if BIGENDIAN + if (pPD->m_dwCPlusTypeFlag == ELEMENT_TYPE_STRING) + { + void* pValueTemp = _alloca(pPD->m_cbValue * sizeof(WCHAR)); + memcpy(pValueTemp, pValue, pPD->m_cbValue * sizeof(WCHAR)); + pValue = pValueTemp; + + SwapStringLength((WCHAR*)pValue, pPD->m_cbValue); + } +#endif + if(FAILED(m_pEmitter->DefineProperty( pPD->m_tdClass, wzMemberName, pPD->m_dwAttr, pPD->m_pSig, pPD->m_dwCSig, pPD->m_dwCPlusTypeFlag, - pPD->m_pValue, + pValue, pPD->m_cbValue, mdSet, mdGet, diff --git a/src/coreclr/ilasm/assembler.h b/src/coreclr/ilasm/assembler.h index b7ec921f5792d..794532ab4703d 100644 --- a/src/coreclr/ilasm/assembler.h +++ b/src/coreclr/ilasm/assembler.h @@ -429,9 +429,9 @@ class PermissionDecl m_TypeSpec = type; m_pbsBlob = new BinStr(); - m_pbsBlob->appendInt16(VAL16(1)); // prolog 0x01 0x00 - m_pbsBlob->appendInt32((int)action); // 4-byte action - if(pbsPairs) // name-value pairs if any + m_pbsBlob->appendInt16(VAL16(1)); // prolog 0x01 0x00 + m_pbsBlob->appendInt32(VAL32((int)action)); // 4-byte action + if(pbsPairs) // name-value pairs if any { if(pbsPairs->length() > 2) m_pbsBlob->appendFrom(pbsPairs,2); diff --git a/src/coreclr/ilasm/grammar_after.cpp b/src/coreclr/ilasm/grammar_after.cpp index 790df23bfd4db..a3f1fb7a21822 100644 --- a/src/coreclr/ilasm/grammar_after.cpp +++ b/src/coreclr/ilasm/grammar_after.cpp @@ -366,6 +366,134 @@ static void AppendStringWithLength(BinStr* pbs, __in __nullterminated char* sz) } } +/********************************************************************************/ +/* Append a typed field initializer to an untyped custom attribute blob + * Since the result is untyped, we have to byte-swap here on big-endian systems + */ +#ifdef BIGENDIAN +static int ByteSwapCustomBlob(BYTE *ptr, int length, int type, bool isSZArray) +{ + BYTE *orig_ptr = ptr; + + int nElem = 1; + if (isSZArray) + { + _ASSERTE(length >= 4); + nElem = GET_UNALIGNED_32(ptr); + SET_UNALIGNED_VAL32(ptr, nElem); + if (nElem == 0xffffffff) + nElem = 0; + ptr += 4; + length -= 4; + } + + for (int i = 0; i < nElem; i++) + { + switch (type) + { + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + _ASSERTE(length >= 1); + ptr++; + length--; + break; + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + _ASSERTE(length >= 2); + SET_UNALIGNED_VAL16(ptr, GET_UNALIGNED_16(ptr)); + ptr += 2; + length -= 2; + break; + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_R4: + _ASSERTE(length >= 4); + SET_UNALIGNED_VAL32(ptr, GET_UNALIGNED_32(ptr)); + ptr += 4; + length -= 4; + break; + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R8: + _ASSERTE(length >= 8); + SET_UNALIGNED_VAL64(ptr, GET_UNALIGNED_64(ptr)); + ptr += 8; + length -= 8; + break; + case ELEMENT_TYPE_STRING: + case SERIALIZATION_TYPE_TYPE: + _ASSERTE(length >= 1); + if (*ptr == 0xFF) + { + ptr++; + length--; + } + else + { + int skipped = CorSigUncompressData((PCCOR_SIGNATURE&)ptr); + _ASSERTE(length >= skipped); + ptr += skipped; + length -= skipped; + } + break; + case SERIALIZATION_TYPE_TAGGED_OBJECT: + { + _ASSERTE(length >= 1); + bool objIsSZArray = false; + int objType = *ptr; + ptr++; + length--; + if (type == ELEMENT_TYPE_SZARRAY) + { + _ASSERTE(length >= 1); + objIsSZArray = false; + objType = *ptr; + ptr++; + length--; + } + int skipped = ByteSwapCustomBlob(ptr, length, objType, objIsSZArray); + _ASSERTE(length >= skipped); + ptr += skipped; + length -= skipped; + break; + } + } + } + + return ptr - orig_ptr; +} +#endif + +static void AppendFieldToCustomBlob(BinStr* pBlob, __in BinStr* pField) +{ + pBlob->appendFrom(pField, (*(pField->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); + +#ifdef BIGENDIAN + BYTE *fieldPtr = pField->ptr(); + int fieldLength = pField->length(); + + bool isSZArray = false; + int type = fieldPtr[0]; + fieldLength--; + if (type == ELEMENT_TYPE_SZARRAY) + { + isSZArray = true; + type = fieldPtr[1]; + fieldLength--; + } + + // This may be a bytearray that must not be swapped. + if (type == ELEMENT_TYPE_STRING && !isSZArray) + return; + + BYTE *blobPtr = pBlob->ptr() + (pBlob->length() - fieldLength); + ByteSwapCustomBlob(blobPtr, fieldLength, type, isSZArray); +#endif +} + + /********************************************************************************/ /* fetch the next token, and return it Also set the yylval.union if the lexical token also has a value */ diff --git a/src/coreclr/ilasm/grammar_before.cpp b/src/coreclr/ilasm/grammar_before.cpp index 43b45bf36b974..b32684ef91ea5 100644 --- a/src/coreclr/ilasm/grammar_before.cpp +++ b/src/coreclr/ilasm/grammar_before.cpp @@ -50,6 +50,7 @@ static char* newStringWDel(__in __nullterminated char* str1, char delimiter, __i static char* newString(__in __nullterminated const char* str1); static void corEmitInt(BinStr* buff, unsigned data); static void AppendStringWithLength(BinStr* pbs, __in __nullterminated char* sz); +static void AppendFieldToCustomBlob(BinStr* pBlob, __in BinStr* pField); bool bParsingByteArray = FALSE; int iOpcodeLen = 0; int iCallConv = 0; diff --git a/src/coreclr/ilasm/prebuilt/asmparse.cpp b/src/coreclr/ilasm/prebuilt/asmparse.cpp index 4e7131a90a726..e3afe381a62f8 100644 --- a/src/coreclr/ilasm/prebuilt/asmparse.cpp +++ b/src/coreclr/ilasm/prebuilt/asmparse.cpp @@ -2280,7 +2280,7 @@ case 73: case 74: #line 334 "asmparse.y" { yyval.binstr = yypvt[-1].binstr; - yyval.binstr->appendInt16(nCustomBlobNVPairs); + yyval.binstr->appendInt16(VAL16(nCustomBlobNVPairs)); yyval.binstr->append(yypvt[-0].binstr); nCustomBlobNVPairs = 0; } break; case 75: @@ -2289,7 +2289,7 @@ case 75: case 76: #line 341 "asmparse.y" { yyval.binstr = yypvt[-1].binstr; - yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); } break; + AppendFieldToCustomBlob(yyval.binstr,yypvt[-0].binstr); } break; case 77: #line 343 "asmparse.y" { yyval.binstr = yypvt[-1].binstr; } break; @@ -2301,7 +2301,7 @@ case 79: { yyval.binstr = yypvt[-5].binstr; yyval.binstr->appendInt8(yypvt[-4].int32); yyval.binstr->append(yypvt[-3].binstr); AppendStringWithLength(yyval.binstr,yypvt[-2].string); - yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); + AppendFieldToCustomBlob(yyval.binstr,yypvt[-0].binstr); nCustomBlobNVPairs++; } break; case 80: #line 353 "asmparse.y" diff --git a/src/coreclr/ilasm/writer.cpp b/src/coreclr/ilasm/writer.cpp index dd2404847c86f..c7bc6d56d4367 100644 --- a/src/coreclr/ilasm/writer.cpp +++ b/src/coreclr/ilasm/writer.cpp @@ -1223,12 +1223,12 @@ HRESULT Assembler::CreatePEFile(__in __nullterminated WCHAR *pwzOutputFilename) *pb = ELEMENT_TYPE_TYPEDEF; memcpy(++pb,pTDD->m_szName,namesize); pTDD->m_tkTypeSpec = ResolveLocalMemberRef(pTDD->m_tkTypeSpec); - memcpy(pb+namesize,&(pTDD->m_tkTypeSpec),sizeof(mdToken)); + SET_UNALIGNED_VAL32(pb+namesize, pTDD->m_tkTypeSpec); if(TypeFromToken(pTDD->m_tkTypeSpec)==mdtCustomAttribute) { CustomDescr* pCA = pTDD->m_pCA; - pbs->appendInt32(pCA->tkType); - pbs->appendInt32(pCA->tkOwner); + pbs->appendInt32(VAL32(pCA->tkType)); + pbs->appendInt32(VAL32(pCA->tkOwner)); if(pCA->pBlob) pbs->append(pCA->pBlob); } ResolveTypeSpec(pbs); @@ -1314,9 +1314,9 @@ HRESULT Assembler::CreatePEFile(__in __nullterminated WCHAR *pwzOutputFilename) { Method* pMD; Class* pClass; - m_pVTable->appendInt32(pGlobalLabel->m_GlobalOffset); - m_pVTable->appendInt16(pVTFEntry->m_wCount); - m_pVTable->appendInt16(pVTFEntry->m_wType); + m_pVTable->appendInt32(VAL32(pGlobalLabel->m_GlobalOffset)); + m_pVTable->appendInt16(VAL16(pVTFEntry->m_wCount)); + m_pVTable->appendInt16(VAL16(pVTFEntry->m_wType)); for(int i=0; (pClass = m_lstClass.PEEK(i)); i++) { for(WORD j = 0; (pMD = pClass->m_MethodList.PEEK(j)); j++)