mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 05:47:26 +08:00
Jakub Jelinek <jj@ultra.linux.cz>
* config/tc-sparc.c (md_begin): Handle native wordsize aliases. (s_ncons): New function. (native_op_table): New table. (sparc_ip): Be more strict on %hi() etc.; prepare assembler for R_SPARC_OLO10 handling.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
1999-06-07 Jakub Jelinek <jj@ultra.linux.cz>
|
||||||
|
|
||||||
|
* config/tc-sparc.c (md_begin): Handle native wordsize aliases.
|
||||||
|
(s_ncons): New function.
|
||||||
|
(native_op_table): New table.
|
||||||
|
(sparc_ip): Be more strict on %hi() etc.; prepare assembler for
|
||||||
|
R_SPARC_OLO10 handling.
|
||||||
|
|
||||||
Mon Jun 7 10:22:16 1999 Richard Henderson <rth@cygnus.com>
|
Mon Jun 7 10:22:16 1999 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
* expr.h (struct expressionS): Revert last change; widen X_op.
|
* expr.h (struct expressionS): Revert last change; widen X_op.
|
||||||
|
@ -115,6 +115,7 @@ static void s_reserve PARAMS ((int));
|
|||||||
static void s_common PARAMS ((int));
|
static void s_common PARAMS ((int));
|
||||||
static void s_empty PARAMS ((int));
|
static void s_empty PARAMS ((int));
|
||||||
static void s_uacons PARAMS ((int));
|
static void s_uacons PARAMS ((int));
|
||||||
|
static void s_ncons PARAMS ((int));
|
||||||
|
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
const pseudo_typeS md_pseudo_table[] =
|
||||||
{
|
{
|
||||||
@ -123,6 +124,7 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{"empty", s_empty, 0},
|
{"empty", s_empty, 0},
|
||||||
{"global", s_globl, 0},
|
{"global", s_globl, 0},
|
||||||
{"half", cons, 2},
|
{"half", cons, 2},
|
||||||
|
{"nword", s_ncons, 0},
|
||||||
{"optim", s_ignore, 0},
|
{"optim", s_ignore, 0},
|
||||||
{"proc", s_proc, 0},
|
{"proc", s_proc, 0},
|
||||||
{"reserve", s_reserve, 0},
|
{"reserve", s_reserve, 0},
|
||||||
@ -174,9 +176,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
|||||||
changed in read.c. Ideally it shouldn't have to know about it at all,
|
changed in read.c. Ideally it shouldn't have to know about it at all,
|
||||||
but nothing is ideal around here. */
|
but nothing is ideal around here. */
|
||||||
|
|
||||||
static unsigned char octal[256];
|
#define isoctal(c) ((c) >= '0' && (c) < '8')
|
||||||
#define isoctal(c) octal[(unsigned char) (c)]
|
|
||||||
static unsigned char toHex[256];
|
|
||||||
|
|
||||||
struct sparc_it
|
struct sparc_it
|
||||||
{
|
{
|
||||||
@ -184,6 +184,7 @@ struct sparc_it
|
|||||||
unsigned long opcode;
|
unsigned long opcode;
|
||||||
struct nlist *nlistp;
|
struct nlist *nlistp;
|
||||||
expressionS exp;
|
expressionS exp;
|
||||||
|
expressionS exp2;
|
||||||
int pcrel;
|
int pcrel;
|
||||||
bfd_reloc_code_real_type reloc;
|
bfd_reloc_code_real_type reloc;
|
||||||
};
|
};
|
||||||
@ -613,6 +614,27 @@ md_show_usage (stream)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* native operand size opcode translation */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *name32;
|
||||||
|
char *name64;
|
||||||
|
} native_op_table[] =
|
||||||
|
{
|
||||||
|
{"ldn", "ld", "ldx"},
|
||||||
|
{"ldna", "lda", "ldxa"},
|
||||||
|
{"stn", "st", "stx"},
|
||||||
|
{"stna", "sta", "stxa"},
|
||||||
|
{"slln", "sll", "sllx"},
|
||||||
|
{"srln", "srl", "srlx"},
|
||||||
|
{"sran", "sra", "srax"},
|
||||||
|
{"casn", "cas", "casx"},
|
||||||
|
{"casna", "casa", "casxa"},
|
||||||
|
{"clrn", "clr", "clrx"},
|
||||||
|
{NULL, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
/* sparc64 priviledged registers */
|
/* sparc64 priviledged registers */
|
||||||
|
|
||||||
struct priv_reg_entry
|
struct priv_reg_entry
|
||||||
@ -693,16 +715,16 @@ md_begin ()
|
|||||||
retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);
|
retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);
|
||||||
if (retval != NULL)
|
if (retval != NULL)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
|
as_bad (_("Internal error: can't hash `%s': %s\n"),
|
||||||
sparc_opcodes[i].name, retval);
|
sparc_opcodes[i].name, retval);
|
||||||
lose = 1;
|
lose = 1;
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
|
if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
|
as_bad (_("Internal error: losing opcode: `%s' \"%s\"\n"),
|
||||||
sparc_opcodes[i].name, sparc_opcodes[i].args);
|
sparc_opcodes[i].name, sparc_opcodes[i].args);
|
||||||
lose = 1;
|
lose = 1;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
@ -711,18 +733,33 @@ md_begin ()
|
|||||||
&& !strcmp (sparc_opcodes[i].name, name));
|
&& !strcmp (sparc_opcodes[i].name, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; native_op_table[i].name; i++)
|
||||||
|
{
|
||||||
|
const struct sparc_opcode *insn;
|
||||||
|
char *name = sparc_arch_size == 32 ? native_op_table[i].name32 :
|
||||||
|
native_op_table[i].name64;
|
||||||
|
insn = (struct sparc_opcode *)hash_find (op_hash, name);
|
||||||
|
if (insn == NULL)
|
||||||
|
{
|
||||||
|
as_bad (_("Internal error: can't find opcode `%s' for `%s'\n"),
|
||||||
|
name, native_op_table[i].name);
|
||||||
|
lose = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn);
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
as_bad (_("Internal error: can't hash `%s': %s\n"),
|
||||||
|
sparc_opcodes[i].name, retval);
|
||||||
|
lose = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (lose)
|
if (lose)
|
||||||
as_fatal (_("Broken assembler. No assembly attempted."));
|
as_fatal (_("Broken assembler. No assembly attempted."));
|
||||||
|
|
||||||
for (i = '0'; i < '8'; ++i)
|
|
||||||
octal[i] = 1;
|
|
||||||
for (i = '0'; i <= '9'; ++i)
|
|
||||||
toHex[i] = i - '0';
|
|
||||||
for (i = 'a'; i <= 'f'; ++i)
|
|
||||||
toHex[i] = i + 10 - 'a';
|
|
||||||
for (i = 'A'; i <= 'F'; ++i)
|
|
||||||
toHex[i] = i + 10 - 'A';
|
|
||||||
|
|
||||||
qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
|
qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
|
||||||
sizeof (priv_reg_table[0]), cmp_reg_entry);
|
sizeof (priv_reg_table[0]), cmp_reg_entry);
|
||||||
|
|
||||||
@ -1885,89 +1922,221 @@ sparc_ip (str, pinsn)
|
|||||||
if (*s == ' ')
|
if (*s == ' ')
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
/* Check for %hi, etc. */
|
|
||||||
if (*s == '%')
|
|
||||||
{
|
|
||||||
static struct ops {
|
|
||||||
/* The name as it appears in assembler. */
|
|
||||||
char *name;
|
|
||||||
/* strlen (name), precomputed for speed */
|
|
||||||
int len;
|
|
||||||
/* The reloc this pseudo-op translates to. */
|
|
||||||
int reloc;
|
|
||||||
/* Non-zero if for v9 only. */
|
|
||||||
int v9_p;
|
|
||||||
/* Non-zero if can be used in pc-relative contexts. */
|
|
||||||
int pcrel_p;/*FIXME:wip*/
|
|
||||||
} ops[] = {
|
|
||||||
/* hix/lox must appear before hi/lo so %hix won't be
|
|
||||||
mistaken for %hi. */
|
|
||||||
{ "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 },
|
|
||||||
{ "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 },
|
|
||||||
{ "hi", 2, BFD_RELOC_HI22, 0, 1 },
|
|
||||||
{ "lo", 2, BFD_RELOC_LO10, 0, 1 },
|
|
||||||
{ "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
|
|
||||||
{ "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
|
|
||||||
{ "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
|
|
||||||
{ "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 },
|
|
||||||
{ "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 },
|
|
||||||
{ "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 },
|
|
||||||
{ "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 },
|
|
||||||
{ "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 },
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
struct ops *o;
|
|
||||||
|
|
||||||
for (o = ops; o->name; o++)
|
|
||||||
if (strncmp (s + 1, o->name, o->len) == 0)
|
|
||||||
break;
|
|
||||||
if (o->name == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
the_insn.reloc = o->reloc;
|
|
||||||
s += o->len + 1;
|
|
||||||
v9_arg_p = o->v9_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note that if the get_expression() fails, we will still
|
|
||||||
have created U entries in the symbol table for the
|
|
||||||
'symbols' in the input string. Try not to create U
|
|
||||||
symbols for registers, etc. */
|
|
||||||
{
|
{
|
||||||
|
char *s1;
|
||||||
|
char *op_arg = NULL;
|
||||||
|
expressionS op_exp;
|
||||||
|
bfd_reloc_code_real_type old_reloc = the_insn.reloc;
|
||||||
|
|
||||||
|
/* Check for %hi, etc. */
|
||||||
|
if (*s == '%')
|
||||||
|
{
|
||||||
|
static const struct ops {
|
||||||
|
/* The name as it appears in assembler. */
|
||||||
|
char *name;
|
||||||
|
/* strlen (name), precomputed for speed */
|
||||||
|
int len;
|
||||||
|
/* The reloc this pseudo-op translates to. */
|
||||||
|
int reloc;
|
||||||
|
/* Non-zero if for v9 only. */
|
||||||
|
int v9_p;
|
||||||
|
/* Non-zero if can be used in pc-relative contexts. */
|
||||||
|
int pcrel_p;/*FIXME:wip*/
|
||||||
|
} ops[] = {
|
||||||
|
/* hix/lox must appear before hi/lo so %hix won't be
|
||||||
|
mistaken for %hi. */
|
||||||
|
{ "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 },
|
||||||
|
{ "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 },
|
||||||
|
{ "hi", 2, BFD_RELOC_HI22, 0, 1 },
|
||||||
|
{ "lo", 2, BFD_RELOC_LO10, 0, 1 },
|
||||||
|
{ "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
|
||||||
|
{ "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
|
||||||
|
{ "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
|
||||||
|
{ "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 },
|
||||||
|
{ "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 },
|
||||||
|
{ "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 },
|
||||||
|
{ "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 },
|
||||||
|
{ "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
const struct ops *o;
|
||||||
|
|
||||||
|
for (o = ops; o->name; o++)
|
||||||
|
if (strncmp (s + 1, o->name, o->len) == 0)
|
||||||
|
break;
|
||||||
|
if (o->name == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (s[o->len + 1] != '(')
|
||||||
|
{
|
||||||
|
as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
op_arg = o->name;
|
||||||
|
the_insn.reloc = o->reloc;
|
||||||
|
s += o->len + 2;
|
||||||
|
v9_arg_p = o->v9_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that if the get_expression() fails, we will still
|
||||||
|
have created U entries in the symbol table for the
|
||||||
|
'symbols' in the input string. Try not to create U
|
||||||
|
symbols for registers, etc. */
|
||||||
|
|
||||||
/* This stuff checks to see if the expression ends in
|
/* This stuff checks to see if the expression ends in
|
||||||
+%reg. If it does, it removes the register from
|
+%reg. If it does, it removes the register from
|
||||||
the expression, and re-sets 's' to point to the
|
the expression, and re-sets 's' to point to the
|
||||||
right place. */
|
right place. */
|
||||||
|
|
||||||
char *s1;
|
if (op_arg)
|
||||||
|
{
|
||||||
|
int npar = 0;
|
||||||
|
|
||||||
|
for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++)
|
||||||
|
if (*s1 == '(')
|
||||||
|
npar++;
|
||||||
|
else if (*s1 == ')')
|
||||||
|
{
|
||||||
|
if (!npar)
|
||||||
|
break;
|
||||||
|
npar--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s1 != ')')
|
||||||
|
{
|
||||||
|
as_bad (_("Illegal operands: %%%s requires arguments in ()"), op_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*s1 = '\0';
|
||||||
|
(void) get_expression (s);
|
||||||
|
*s1 = ')';
|
||||||
|
s = s1 + 1;
|
||||||
|
if (*s == ',' || *s == ']' || !*s)
|
||||||
|
continue;
|
||||||
|
if (*s != '+' && *s != '-')
|
||||||
|
{
|
||||||
|
as_bad (_("Illegal operands: Can't do arithmetics other than + and - involving %%%s()"), op_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*s1 = '0';
|
||||||
|
s = s1;
|
||||||
|
op_exp = the_insn.exp;
|
||||||
|
memset (&the_insn.exp, 0, sizeof(the_insn.exp));
|
||||||
|
}
|
||||||
|
|
||||||
for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;
|
for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;
|
||||||
|
|
||||||
if (s1 != s && isdigit ((unsigned char) s1[-1]))
|
if (s1 != s && isdigit ((unsigned char) s1[-1]))
|
||||||
{
|
{
|
||||||
if (s1[-2] == '%' && s1[-3] == '+')
|
if (s1[-2] == '%' && s1[-3] == '+')
|
||||||
{
|
s1 -= 3;
|
||||||
s1 -= 3;
|
|
||||||
*s1 = '\0';
|
|
||||||
(void) get_expression (s);
|
|
||||||
*s1 = '+';
|
|
||||||
s = s1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
|
else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
|
||||||
|
s1 -= 4;
|
||||||
|
else
|
||||||
|
s1 = NULL;
|
||||||
|
if (s1)
|
||||||
{
|
{
|
||||||
s1 -= 4;
|
|
||||||
*s1 = '\0';
|
*s1 = '\0';
|
||||||
(void) get_expression (s);
|
(void) get_expression (s);
|
||||||
*s1 = '+';
|
*s1 = '+';
|
||||||
|
if (op_arg)
|
||||||
|
*s = ')';
|
||||||
s = s1;
|
s = s1;
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s1 = NULL;
|
||||||
|
|
||||||
|
if (!s1)
|
||||||
|
{
|
||||||
|
(void) get_expression (s);
|
||||||
|
if (op_arg)
|
||||||
|
*s = ')';
|
||||||
|
s = expr_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op_arg)
|
||||||
|
{
|
||||||
|
the_insn.exp2 = the_insn.exp;
|
||||||
|
the_insn.exp = op_exp;
|
||||||
|
if (the_insn.exp2.X_op == O_absent)
|
||||||
|
the_insn.exp2.X_op = O_illegal;
|
||||||
|
else if (the_insn.exp.X_op == O_absent)
|
||||||
|
{
|
||||||
|
the_insn.exp = the_insn.exp2;
|
||||||
|
the_insn.exp2.X_op = O_illegal;
|
||||||
|
}
|
||||||
|
else if (the_insn.exp.X_op == O_constant)
|
||||||
|
{
|
||||||
|
valueT val = the_insn.exp.X_add_number;
|
||||||
|
switch (the_insn.reloc)
|
||||||
|
{
|
||||||
|
case BFD_RELOC_SPARC_HH22:
|
||||||
|
val = BSR (val, 32);
|
||||||
|
/* intentional fallthrough */
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_LM22:
|
||||||
|
case BFD_RELOC_HI22:
|
||||||
|
val = (val >> 10) & 0x3fffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_HM10:
|
||||||
|
val = BSR (val, 32);
|
||||||
|
/* intentional fallthrough */
|
||||||
|
|
||||||
|
case BFD_RELOC_LO10:
|
||||||
|
val &= 0x3ff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_H44:
|
||||||
|
val >>= 22;
|
||||||
|
val &= 0x3fffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_M44:
|
||||||
|
val >>= 12;
|
||||||
|
val &= 0x3ff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_L44:
|
||||||
|
val &= 0xfff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_HIX22:
|
||||||
|
val = ~ val;
|
||||||
|
val = (val >> 10) & 0x3fffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_SPARC_LOX10:
|
||||||
|
val = (val & 0x3ff) | 0x1c00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
the_insn.exp = the_insn.exp2;
|
||||||
|
the_insn.exp.X_add_number += val;
|
||||||
|
the_insn.exp2.X_op = O_illegal;
|
||||||
|
the_insn.reloc = old_reloc;
|
||||||
|
}
|
||||||
|
else if (the_insn.exp2.X_op != O_constant)
|
||||||
|
{
|
||||||
|
as_bad (_("Illegal operands: Can't add non-constant expression to %%%s()"), op_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (1 || old_reloc != BFD_RELOC_SPARC13
|
||||||
|
|| the_insn.reloc != BFD_RELOC_LO10
|
||||||
|
|| sparc_arch_size != 64
|
||||||
|
|| sparc_pic_code)
|
||||||
|
{
|
||||||
|
as_bad (_("Illegal operands: Can't do arithmetics involving %%%s() of a relocatable symbol"), op_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
the_insn.reloc = BFD_RELOC_SPARC_OLO10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) get_expression (s);
|
|
||||||
s = expr_end;
|
|
||||||
|
|
||||||
/* Check for constants that don't require emitting a reloc. */
|
/* Check for constants that don't require emitting a reloc. */
|
||||||
if (the_insn.exp.X_op == O_constant
|
if (the_insn.exp.X_op == O_constant
|
||||||
&& the_insn.exp.X_add_symbol == 0
|
&& the_insn.exp.X_add_symbol == 0
|
||||||
@ -3395,6 +3564,17 @@ s_uacons (bytes)
|
|||||||
cons (bytes);
|
cons (bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This handles the native word allocation pseudo-op .nword.
|
||||||
|
For sparc_arch_size 32 it is equivalent to .word, for
|
||||||
|
sparc_arch_size 64 it is equivalent to .xword. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s_ncons (bytes)
|
||||||
|
int bytes;
|
||||||
|
{
|
||||||
|
cons (sparc_arch_size == 32 ? 4 : 8);
|
||||||
|
}
|
||||||
|
|
||||||
/* If the --enforce-aligned-data option is used, we require .word,
|
/* If the --enforce-aligned-data option is used, we require .word,
|
||||||
et. al., to be aligned correctly. We do it by setting up an
|
et. al., to be aligned correctly. We do it by setting up an
|
||||||
rs_align_code frag, and checking in HANDLE_ALIGN to make sure that
|
rs_align_code frag, and checking in HANDLE_ALIGN to make sure that
|
||||||
|
Reference in New Issue
Block a user