Remove IA-64/Itanium support.
// support to worry about on ARM so don't ever create the stub for ARM binaries.
m_createCorMainStub = false;
}
+ else if ((createFlags & ICEE_CREATE_MACHINE_MASK) == ICEE_CREATE_MACHINE_ARM64)
+ {
+ m_ntHeaders->FileHeader.Machine = VAL16(IMAGE_FILE_MACHINE_ARM64);
+
+ // The OS loader already knows how to initialize pure managed assemblies and we have no legacy OS
+ // support to worry about on ARM64 so don't ever create the stub for ARM64 binaries.
+ m_createCorMainStub = false;
+ }
else
{
_ASSERTE(!"Invalid target machine");
%token _FILE NOMETADATA_ _HASH _ASSEMBLY _PUBLICKEY _PUBLICKEYTOKEN ALGORITHM_ _VER _LOCALE EXTERN_
%token _MRESOURCE
%token _MODULE _EXPORT
-%token LEGACY_ LIBRARY_ X86_ IA64_ AMD64_ ARM_
+%token LEGACY_ LIBRARY_ X86_ AMD64_ ARM_ ARM64_
/* field marshaling */
%token MARSHAL_ CUSTOM_ SYSSTRING_ FIXED_ VARIANT_ CURRENCY_ SYSCHAR_ DECIMAL_ DATE_ BSTR_ TBSTR_ LPSTR_
%token LPWSTR_ LPTSTR_ OBJECTREF_ IUNKNOWN_ IDISPATCH_ STRUCT_ SAFEARRAY_ BYVALSTR_ LPVOID_ ANY_ ARRAY_ LPSTRUCT_
| asmAttr LEGACY_ LIBRARY_ { $$ = $1; }
| asmAttr CIL_ { SET_PA($$,$1,afPA_MSIL); }
| asmAttr X86_ { SET_PA($$,$1,afPA_x86); }
- | asmAttr IA64_ { SET_PA($$,$1,afPA_IA64); }
| asmAttr AMD64_ { SET_PA($$,$1,afPA_AMD64); }
| asmAttr ARM_ { SET_PA($$,$1,afPA_ARM); }
+ | asmAttr ARM64_ { SET_PA($$,$1,afPA_ARM64); }
;
assemblyDecls : /* EMPTY */
printf("\n/HIGHENTROPYVA Set High Entropy Virtual Address capable PE32+ images (default for /APPCONTAINER)");
printf("\n/NOCORSTUB Suppress generation of CORExeMain stub");
printf("\n/STRIPRELOC Indicate that no base relocations are needed");
- printf("\n/ITANIUM Target processor: Intel Itanium");
printf("\n/X64 Target processor: 64bit AMD processor");
- printf("\n/ARM Target processor: ARM processor");
+ printf("\n/ARM Target processor: ARM (AArch32) processor");
+ printf("\n/ARM64 Target processor: ARM64 (AArch64) processor");
printf("\n/32BITPREFERRED Create a 32BitPreferred image (PE32)");
printf("\n/ENC=<file> Create Edit-and-Continue deltas from specified source file");
printf("\n\nKey may be '-' or '/'\nOptions are recognized by first 3 characters\nDefault source file extension is .il\n");
printf("\nTarget defaults:");
- printf("\n/PE64 => /PE64 /ITANIUM");
- printf("\n/ITANIUM => /PE64 /ITANIUM");
+ printf("\n/PE64 => /PE64 /X64");
printf("\n/X64 => /PE64 /X64");
printf("\n\n");
{
pAsm->m_fOptimize = TRUE;
}
- else if (!_stricmp(szOpt, "ITA"))
- {
- pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
- pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_IA64;
- }
else if (!_stricmp(szOpt, "X64"))
{
pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
}
else if (!_stricmp(szOpt, "ARM"))
{
- pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
- pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_ARM;
+ // szOpt is only 3 characters long. That is not enough to distinguish "ARM" and "ARM64".
+ // We could change it to be longer, but that would affect the existing usability (ARM64 was
+ // added much later). Thus, just distinguish the two here.
+ char szOpt2[5 + 1] = { 0 };
+ WszWideCharToMultiByte(uCodePage, 0, &argv[i][1], 5, szOpt2, sizeof(szOpt2), NULL, NULL);
+ if (!_stricmp(szOpt2, "ARM"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_ARM;
+ }
+ else if (!_stricmp(szOpt2, "ARM64"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_ARM64;
+ }
+ else
+ {
+ goto InvalidOption;
+ }
}
else if (!_stricmp(szOpt, "32B"))
{
if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
||(pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM))
{
- printf("\nMachine type /ITANIUM or /X64 must be specified for 64 bit targets.");
+ printf("\nMachine type /ARM64 or /X64 must be specified for 64 bit targets.");
if(!pAsm->OnErrGo)
{
pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
- pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_IA64;
- printf(" Type set to ITANIUM.");
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_AMD64;
+ printf(" Type set to X64.");
}
printf("\n");
}
}
else
{
- if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_IA64)
+ if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM64)
||(pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_AMD64))
{
- printf("\n64 bit target must be specified for machine type /ITANIUM or /X64.");
+ printf("\n64 bit target must be specified for machine type /ARM64 or /X64.");
if(!pAsm->OnErrGo)
{
pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_FILE_PE32;
printf("\n");
}
}
- if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_IA64))
- {
- pAsm->m_dwComImageFlags &= ~COMIMAGE_FLAGS_ILONLY;
- }
if(pAsm->m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32)
{
if(g_stBaseAddress > 0x80000000)
# define LEGACY_ 473
# define LIBRARY_ 474
# define X86_ 475
-# define IA64_ 476
-# define AMD64_ 477
-# define ARM_ 478
+# define AMD64_ 476
+# define ARM_ 477
+# define ARM64_ 478
# define MARSHAL_ 479
# define CUSTOM_ 480
# define SYSSTRING_ 481
{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_x86); } break;
case 780:
#line 1946 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_IA64); } break;
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_AMD64); } break;
case 781:
#line 1947 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_AMD64); } break;
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM); } break;
case 782:
#line 1948 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM); } break;
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM64); } break;
case 785:
#line 1955 "asmparse.y"
{ PASMM->SetAssemblyHashAlg(yypvt[-0].int32); } break;
0xf8df, 0xf000, // ldr pc, [pc, #0]
0x0000, 0x0000 //address of VTFixup slot
};
-
-static const BYTE ExportStubIA64Template[] =
+static const WORD ExportStubARM64Template[] =
{
- // ld8 r9 = [gp] ;;
- // ld8 r10 = [r9],8
- // nop.i ;;
- // ld8 gp = [r9]
- // mov b6 = r10
- // br.cond.sptk.few b6
- //
- 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40,
- 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50,
- 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of the template
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //address of VTFixup slot
+ // TODO (this is a copy of ARM right now) !!!!!!!!!!!!!!!
+
+ // Jump through VTFixup table
+ 0xf8df, 0xf000, // ldr pc, [pc, #0]
+ 0x0000, 0x0000 //address of VTFixup slot
};
+
DWORD Assembler::EmitExportStub(DWORD dwVTFSlotRVA)
{
DWORD EXPORT_STUB_SIZE = (DWORD)(sizeof(WORD)+sizeof(DWORD));
DWORD PEFileOffset;
BYTE* outBuff;
DWORD* pdwVTFSlotRVA;
- if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_IA64)
- {
- STUB_TEMPLATE = (BYTE*)&ExportStubIA64Template[0];
- EXPORT_STUB_SIZE = sizeof(ExportStubIA64Template);
- OFFSET_OF_ADDR = 40;
- if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, EXPORT_STUB_SIZE, STUB_ALIGNMENT, (void **) &outBuff))) return 0;
- memcpy(outBuff,STUB_TEMPLATE,EXPORT_STUB_SIZE);
- pdwVTFSlotRVA = (DWORD*)(&outBuff[OFFSET_OF_ADDR]);
- *pdwVTFSlotRVA = VAL32(dwVTFSlotRVA);
-
- // The offset where we start, (not where the alignment bytes start!)
- if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
-
- PEFileOffset -= EXPORT_STUB_SIZE;
- *((DWORD*)(&outBuff[OFFSET_OF_ADDR - 8])) = PEFileOffset; // set PLabel
- m_pCeeFileGen->AddSectionReloc(m_pILSection, PEFileOffset+OFFSET_OF_ADDR-8,m_pILSection, srRelocHighLow);
- m_pCeeFileGen->AddSectionReloc(m_pILSection, PEFileOffset+OFFSET_OF_ADDR,m_pGlobalDataSection, srRelocHighLow);
- PEFileOffset += OFFSET_OF_ADDR - 8; // entry point is PLabel, which points at the template
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_AMD64)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubAMD64Template[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubAMD64Template);
+ OFFSET_OF_ADDR = 2;
+ STUB_ALIGNMENT = 4;
+ }
+ else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubX86Template[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubX86Template);
+ OFFSET_OF_ADDR = 2;
+ }
+ else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubARMTemplate[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubARMTemplate);
+ OFFSET_OF_ADDR = 4;
+ STUB_ALIGNMENT = 4;
+ }
+ else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM64)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubARM64Template[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubARM64Template);
+ OFFSET_OF_ADDR = 4;
+ STUB_ALIGNMENT = 4;
+ report->error("NYI");
+ return NULL;
}
else
{
- if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_AMD64)
- {
- STUB_TEMPLATE = (BYTE*)&ExportStubAMD64Template[0];
- EXPORT_STUB_SIZE = sizeof(ExportStubAMD64Template);
- OFFSET_OF_ADDR = 2;
- STUB_ALIGNMENT = 4;
- }
- else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
- {
- STUB_TEMPLATE = (BYTE*)&ExportStubX86Template[0];
- EXPORT_STUB_SIZE = sizeof(ExportStubX86Template);
- OFFSET_OF_ADDR = 2;
- }
- else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM)
- {
- STUB_TEMPLATE = (BYTE*)&ExportStubARMTemplate[0];
- EXPORT_STUB_SIZE = sizeof(ExportStubARMTemplate);
- OFFSET_OF_ADDR = 4;
- STUB_ALIGNMENT = 4;
- }
- else
- {
- report->error("Unmanaged exports are not implemented for unknown platform");
- return NULL;
- }
- // Addr must be aligned, not the stub!
- if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
- if((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))
- {
- ULONG L = STUB_ALIGNMENT - ((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1));
- if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, L, 1, (void **) &outBuff))) return 0;
- memset(outBuff,0,L);
- }
-
- if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, EXPORT_STUB_SIZE, 1, (void **) &outBuff))) return 0;
- memcpy(outBuff,STUB_TEMPLATE,EXPORT_STUB_SIZE);
- pdwVTFSlotRVA = (DWORD*)(&outBuff[OFFSET_OF_ADDR]);
- *pdwVTFSlotRVA = VAL32(dwVTFSlotRVA);
-
- // The offset where we start, (not where the alignment bytes start!)
- if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
-
- PEFileOffset -= EXPORT_STUB_SIZE;
- _ASSERTE(((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))==0);
- m_pCeeFileGen->AddSectionReloc(m_pILSection, PEFileOffset+OFFSET_OF_ADDR,m_pGlobalDataSection, srRelocHighLow);
+ report->error("Unmanaged exports are not implemented for unknown platform");
+ return NULL;
+ }
+ // Addr must be aligned, not the stub!
+ if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
+ if((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))
+ {
+ ULONG L = STUB_ALIGNMENT - ((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1));
+ if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, L, 1, (void **) &outBuff))) return 0;
+ memset(outBuff,0,L);
}
+
+ if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, EXPORT_STUB_SIZE, 1, (void **) &outBuff))) return 0;
+ memcpy(outBuff,STUB_TEMPLATE,EXPORT_STUB_SIZE);
+ pdwVTFSlotRVA = (DWORD*)(&outBuff[OFFSET_OF_ADDR]);
+ *pdwVTFSlotRVA = VAL32(dwVTFSlotRVA);
+
+ // The offset where we start, (not where the alignment bytes start!)
+ if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
+
+ PEFileOffset -= EXPORT_STUB_SIZE;
+ _ASSERTE(((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))==0);
+ m_pCeeFileGen->AddSectionReloc(m_pILSection, PEFileOffset+OFFSET_OF_ADDR,m_pGlobalDataSection, srRelocHighLow);
+
if(m_dwCeeFileFlags & ICEE_CREATE_FILE_STRIP_RELOCS)
{
report->error("Base relocations are emitted, while /STRIPRELOC option has been specified");
if(IsAfPA_NoPlatform(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("noplatform "));
if(IsAfPA_MSIL(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("cil "));
if(IsAfPA_x86(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("x86 "));
- if(IsAfPA_IA64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("ia64 "));
if(IsAfPA_AMD64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("amd64 "));
+ if(IsAfPA_ARM(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("arm "));
+ if(IsAfPA_ARM64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("arm64 "));
wzName[ulNameLen] = 0;
if(IsAfContentType_WindowsRuntime(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("windowsruntime "));
if(IsAfPA_MSIL(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("cil "));
if(IsAfPA_x86(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("x86 "));
- if(IsAfPA_IA64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("ia64 "));
if(IsAfPA_AMD64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("amd64 "));
+ if(IsAfPA_ARM(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("arm "));
+ if(IsAfPA_ARM64(dwFlags)) strcat_s(szString,SZSTRING_SIZE,KEYWORD("arm64 "));
{
char* sz = new char[3*ulNameLen+32];
afPA_IA64 = 0x0030, // Processor Architecture: Itanium (PE32+)
afPA_AMD64 = 0x0040, // Processor Architecture: AMD X64 (PE32+)
afPA_ARM = 0x0050, // Processor Architecture: ARM (PE32)
+ afPA_ARM64 = 0x0060, // Processor Architecture: ARM64 (PE32+)
afPA_NoPlatform = 0x0070, // applies to any platform but cannot run on any (e.g. reference assembly), should not have "specified" set
afPA_Specified = 0x0080, // Propagate PA flags to AssemblyRef record
afPA_Mask = 0x0070, // Bits describing the processor architecture
#define IsAfPA_IA64(x) (((x) & afPA_Mask) == afPA_IA64)
#define IsAfPA_AMD64(x) (((x) & afPA_Mask) == afPA_AMD64)
#define IsAfPA_ARM(x) (((x) & afPA_Mask) == afPA_ARM)
+#define IsAfPA_ARM64(x) (((x) & afPA_Mask) == afPA_ARM64)
#define IsAfPA_NoPlatform(x) (((x) & afPA_FullMask) == afPA_NoPlatform)
#define IsAfPA_Specified(x) ((x) & afPA_Specified)
#define PAIndex(x) (((x) & afPA_Mask) >> afPA_Shift)
#define ICEE_CREATE_FILE_STRIP_RELOCS 0x00000008 // strip the .reloc section
#define ICEE_CREATE_FILE_EMIT_FIXUPS 0x00000010 // emit fixups for use by Vulcan
-#define ICEE_CREATE_MACHINE_MASK 0x0000FF00 // space for up to 256 machine targets
+#define ICEE_CREATE_MACHINE_MASK 0x0000FF00 // space for up to 256 machine targets (note: most users just do a bit check, not an equality compare after applying the mask)
#define ICEE_CREATE_MACHINE_ILLEGAL 0x00000000 // An illegal machine name
#define ICEE_CREATE_MACHINE_I386 0x00000100 // Create a IMAGE_FILE_MACHINE_I386
#define ICEE_CREATE_MACHINE_IA64 0x00000200 // Create a IMAGE_FILE_MACHINE_IA64
#define ICEE_CREATE_MACHINE_AMD64 0x00000400 // Create a IMAGE_FILE_MACHINE_AMD64
#define ICEE_CREATE_MACHINE_ARM 0x00000800 // Create a IMAGE_FILE_MACHINE_ARMNT
+#define ICEE_CREATE_MACHINE_ARM64 0x00001000 // Create a IMAGE_FILE_MACHINE_ARM64
// Pass this to CreateCeeFileEx to create a pure IL Exe or DLL
#define ICEE_CREATE_FILE_PURE_IL ICEE_CREATE_FILE_PE32 | \
KYWD( "legacy", LEGACY_, NO_VALUE )
KYWD( "library", LIBRARY_, NO_VALUE )
KYWD( "x86", X86_, NO_VALUE )
- KYWD( "ia64", IA64_, NO_VALUE )
KYWD( "amd64", AMD64_, NO_VALUE )
KYWD( "arm", ARM_, NO_VALUE )
+ KYWD( "arm64", ARM64_, NO_VALUE )
KYWD( ".publickey", _PUBLICKEY, NO_VALUE )
KYWD( ".publickeytoken",_PUBLICKEYTOKEN, NO_VALUE )
KYWD( "algorithm", ALGORITHM_, NO_VALUE )
inline bool IsPE64(PEKIND x)
{
- return ( (x == peIA64) || (x == peAMD64) );
+ return ( (x == peIA64) || (x == peAMD64) || (x == peARM64) );
}
inline bool IsPE32(PEKIND x)