This commit is contained in:
purplerain 2023-05-16 22:16:59 +00:00
parent ab90ba3a7c
commit 9e5eddc6af
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
57 changed files with 838 additions and 537 deletions

View file

@ -1819,8 +1819,11 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
if (IndirectBranches)
CmdArgs.push_back("-mbranch-target-enforce");
} else {
if (Triple.isOSOpenBSD())
if (Triple.isOSOpenBSD()) {
CmdArgs.push_back("-msign-return-address=non-leaf");
CmdArgs.push_back("-msign-return-address-key=a_key");
CmdArgs.push_back("-mbranch-target-enforce");
}
}
// Handle -msve_vector_bits=<bits>

View file

@ -621,7 +621,11 @@ private:
} // namespace
AArch64BtiPac::AArch64BtiPac() {
#ifdef __OpenBSD__
btiHeader = true;
#else
btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
#endif
// A BTI (Branch Target Indicator) Plt Entry is only required if the
// address of the PLT entry can be taken by the program, which permits an
// indirect jump to the PLT entry. This can happen when the address
@ -717,6 +721,10 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
}
static TargetInfo *getTargetInfo() {
#ifdef __OpenBSD__
static AArch64BtiPac t;
return &t;
#else
if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
static AArch64BtiPac t;
@ -724,6 +732,7 @@ static TargetInfo *getTargetInfo() {
}
static AArch64 t;
return &t;
#endif
}
TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); }

View file

@ -99,6 +99,7 @@ static void SIMD_Fixup (int, int);
static void PNI_Fixup (int, int);
static void XCR_Fixup (int, int);
static void SVME_Fixup (int, int);
static void SSP_Fixup (int, int);
static void INVLPG_Fixup (int, int);
static void BadOp (void);
static void SEG_Fixup (int, int);
@ -106,6 +107,7 @@ static void VMX_Fixup (int, int);
static void REP_Fixup (int, int);
static void OP_0f38 (int, int);
static void OP_0f3a (int, int);
static void OP_0f1e (int, int);
static void OP_data (int, int);
struct dis_private {
@ -324,6 +326,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define OP0FAE OP_0fae, v_mode
#define OP0F38 OP_0f38, 0
#define OP0F3A OP_0f3a, 0
#define OP0F1E OP_0f1e, v_mode
#define OPDATA OP_data, 0
/* Used handle "rep" prefix for string instructions. */
@ -471,6 +474,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
#define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0
#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
@ -494,6 +498,7 @@ struct dis386 {
'B' => print 'b' if suffix_always is true
'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
. size prefix
'D' => print '64' in place of rex64 prefix
'E' => print 'e' if 32-bit form of jcxz
'F' => print 'w' or 'l' depending on address size prefix (loop insns)
'H' => print ",pt" or ",pn" branch hint
@ -852,7 +857,7 @@ static const struct dis386 dis386_twobyte[] = {
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ PREGRP33 },
{ "(bad)", XX, XX, XX },
/* 20 */
{ "movZ", Rm, Cm, XX },
@ -1135,7 +1140,7 @@ static const unsigned char twobyte_has_modrm[256] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
/* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
/* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0, /* 1f */
/* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
/* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
/* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
@ -1416,7 +1421,7 @@ static const struct dis386 grps[][8] = {
{ "lgdt{Q|Q||}", XCR_Fixup, 0, XX, XX },
{ "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX },
{ "smswQ", Ev, XX, XX },
{ "(bad)", XX, XX, XX },
{ "", SSP_Fixup, 0, XX, XX },
{ "lmsw", Ew, XX, XX },
{ "invlpg", INVLPG_Fixup, w_mode, XX, XX },
},
@ -1436,9 +1441,9 @@ static const struct dis386 grps[][8] = {
{ "(bad)", XX, XX, XX },
{ "cmpxchg8b", Eq, XX, XX },
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "xrstorsD",Ev, XX, XX },
{ "xsavecD",Ev, XX, XX },
{ "xsavesD",Ev, XX, XX },
{ "", VM, XX, XX }, /* See OP_VMX. */
{ "", VM2, XX, XX },
},
@ -1477,13 +1482,13 @@ static const struct dis386 grps[][8] = {
},
/* GRP13 */
{
{ "fxsave", OP0FAE, XX, XX },
{ "fxrstor", OP0FAE, XX, XX },
{ "fxsaveD", OP0FAE, XX, XX },
{ "fxrstorD", OP0FAE, XX, XX },
{ "ldmxcsr", OP0FAE, XX, XX },
{ "stmxcsr", OP0FAE, XX, XX },
{ "xsave", Ev, XX, XX },
{ "xrstor", OP0FAE, XX, XX },
{ "xsaveopt", OP0FAE, XX, XX },
{ "xsaveD", OP0FAE, XX, XX },
{ "xrstorD", OP0FAE, XX, XX },
{ "xsaveoptD",OP0FAE, XX, XX },
{ "clflush", OP0FAE, XX, XX },
},
/* GRP14 */
@ -1529,7 +1534,7 @@ static const struct dis386 grps[][8] = {
{ "(bad)", OP_0f07, 0, XX, XX },
{ "(bad)", OP_0f07, 0, XX, XX },
{ "(bad)", OP_0f07, 0, XX, XX },
}
},
};
static const struct dis386 prefix_user_table[][4] = {
@ -1764,6 +1769,13 @@ static const struct dis386 prefix_user_table[][4] = {
{ "(bad)", XM, EX, XX },
{ "lddqu", XM, M, XX },
},
/* PREGRP33 */
{
{ "(bad)", XM, EX, XX },
{ "", OP0F1E, XX, XX },
{ "(bad)", XM, EX, XX },
{ "(bad)", XM, EX, XX },
},
};
static const struct dis386 x86_64_table[][2] = {
@ -3397,6 +3409,14 @@ putop (const char *template, int sizeflag)
used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
case 'D':
USED_REX (REX_MODE64);
if (rex & REX_MODE64)
{
*obufp++ = '6';
*obufp++ = '4';
}
break;
case 'E': /* For jcxz/jecxz */
if (address_mode == mode_64bit)
{
@ -4828,9 +4848,110 @@ OP_0f07 (int bytemode, int sizeflag)
OP_E (bytemode, sizeflag);
}
static void
OP_0f1e (int bytemode, int sizeflag)
{
used_prefixes |= PREFIX_REPZ;
switch (*codep++)
{
case 0xfa:
strcpy (obuf, "endbr64");
break;
case 0xfb:
strcpy (obuf, "endbr32");
break;
default:
USED_REX (REX_MODE64);
if (rex & REX_MODE64)
strcpy (obuf, "rdsspq");
else
strcpy (obuf, "rdsspd");
OP_E (bytemode, sizeflag);
return;
}
}
static void
OP_0fae (int bytemode, int sizeflag)
{
if (prefixes & PREFIX_REPZ)
{
used_prefixes |= PREFIX_REPZ;
if (mod != 3)
{
if (reg == 6)
{
strcpy (obuf, "clrssbsy");
OP_E (bytemode, sizeflag);
}
else
BadOp ();
return;
}
switch (reg)
{
case 0:
strcpy (obuf, "rdfsbase");
break;
case 1:
strcpy (obuf, "rdgsbase");
break;
case 2:
strcpy (obuf, "wrfsbase");
break;
case 3:
strcpy (obuf, "wrgsbase");
break;
case 4:
strcpy (obuf, "ptwrite");
break;
case 5:
USED_REX (REX_MODE64);
if (rex & REX_MODE64)
strcpy (obuf, "incsspq");
else
strcpy (obuf, "incsspd");
break;
case 6:
strcpy (obuf, "umonitor"); /* XXX wrong size for r16/r32/r64 arg */
break;
case 7:
BadOp ();
return;
}
OP_E (bytemode, sizeflag);
return;
}
if (prefixes & PREFIX_REPNZ)
{
if (mod == 3 && reg == 6)
{
used_prefixes |= PREFIX_REPNZ;
strcpy (obuf, "umwait");
OP_E (bytemode, sizeflag);
}
else
BadOp ();
return;
}
if (prefixes & PREFIX_DATA)
{
if (mod != 3 && reg >= 6)
strcpy (obuf, reg == 6 ? "clwb" : "clflushopt");
else if (mod == 3 && reg == 6)
strcpy (obuf, "tpause"); /* XXX wrong size for r16/r32/r64 arg */
else
{
BadOp ();
return;
}
used_prefixes |= PREFIX_DATA;
OP_E (bytemode, sizeflag);
return;
}
if (mod == 3)
{
if (reg == 7)
@ -4839,21 +4960,9 @@ OP_0fae (int bytemode, int sizeflag)
strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
else if (reg == 5)
strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
if (reg < 4 && prefixes == PREFIX_REPZ)
{
if (reg == 0)
strcpy (obuf, "rdfsbase");
else if (reg == 1)
strcpy (obuf, "rdgsbase");
else if (reg == 2)
strcpy (obuf, "wrfsbase");
else
strcpy (obuf, "wrgsbase");
}
else if (reg < 5 || rm != 0)
else if (reg < 5)
{
BadOp (); /* bad sfence, mfence, or lfence */
BadOp ();
return;
}
}
@ -5031,6 +5140,7 @@ SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
static void
PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
{
/* missing: encls==np0f01cf */
if (mod == 3 && reg == 1 && rm <= 1)
{
/* Override "sidt". */
@ -5105,7 +5215,8 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
static void
XCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
{
if (mod == 3 && reg == 2 && rm <= 1)
if (mod == 3 && reg == 2 && (rm <= 1 || rm >= 4) &&
(prefixes & (PREFIX_REPZ|PREFIX_REPNZ|PREFIX_DATA)) == 0)
{
/* Override "lgdt". */
size_t olen = strlen (obuf);
@ -5125,13 +5236,26 @@ XCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
|| strncmp (p - 3, "32", 2) == 0))
p -= 7;
if (rm)
{
strcpy (p, "xsetbv");
}
else
switch (rm)
{
case 0:
strcpy (p, "xgetbv");
break;
case 1:
strcpy (p, "xsetbv");
break;
case 4:
strcpy (p, "vmfunc");
break;
case 5:
strcpy (p, "xend");
break;
case 6:
strcpy (p, "xtest");
break;
case 7:
strcpy (p, "enclu");
break;
}
codep++;
@ -5210,6 +5334,78 @@ SVME_Fixup (int bytemode, int sizeflag)
}
}
static void
SSP_Fixup (int bytemode, int sizeflag)
{
used_prefixes |= (prefixes & (PREFIX_REPZ | PREFIX_REPNZ));
if (mod != 3)
{
if (prefixes & PREFIX_REPZ)
{
strcpy (obuf, "rstorssp");
OP_M (bytemode, sizeflag);
}
else
BadOp ();
return;
}
if (prefixes & PREFIX_REPZ)
switch (*codep++)
{
case 0xe8:
strcpy (obuf, "setssbsy");
break;
case 0xea:
strcpy (obuf, "saveprevssp");
break;
case 0xec:
strcpy (obuf, "uiret");
break;
case 0xed:
strcpy (obuf, "testui");
break;
case 0xee:
strcpy (obuf, "clui");
break;
case 0xef:
strcpy (obuf, "stui");
break;
default:
break;
}
else if (prefixes & PREFIX_REPNZ)
switch (*codep)
{
case 0xe8:
strcpy (obuf, "xsusldtrk");
break;
case 0xe9:
strcpy (obuf, "xresldtrk");
break;
default:
BadOp ();
return;
}
else
switch (*codep)
{
case 0xe8:
strcpy (obuf, "serialize");
break;
case 0xee:
strcpy (obuf, "rdpkru");
break;
case 0xef:
strcpy (obuf, "wrpkru");
break;
default:
BadOp ();
return;
}
codep++;
}
static void
INVLPG_Fixup (int bytemode, int sizeflag)
{
@ -5292,6 +5488,7 @@ SEG_Fixup (int extrachar, int sizeflag)
static void
VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
{
/* missing: enclv==np0f01c0 pconfig==np0f01c5 */
if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
{
/* Override "sgdt". */
@ -5328,8 +5525,17 @@ OP_VMX (int bytemode, int sizeflag)
{
if (mod == 3)
{
strcpy (obuf, "rdrand");
OP_E (v_mode, sizeflag);
used_prefixes |= (prefixes & PREFIX_REPZ);
if (prefixes & PREFIX_REPZ)
{
strcpy (obuf, "senduipi");
OP_G (m_mode, sizeflag);
}
else
{
strcpy (obuf, "rdrand");
OP_E (v_mode, sizeflag);
}
}
else
{
@ -5349,7 +5555,11 @@ OP_VMX2 (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
{
if (mod == 3)
{
strcpy (obuf, "rdseed");
used_prefixes |= (prefixes & PREFIX_REPZ);
if (prefixes & PREFIX_REPZ)
strcpy (obuf, "rdpid");
else
strcpy (obuf, "rdseed");
OP_E (v_mode, sizeflag);
}
else