Steal code from tc-sparc.[ch] to implement a vax specific "cons" routine.
Add a %pcrel{32,16,8}(exp) special which emit a PC32 relocation to exp. This will be used by the gcc dwarf code to generic .eh_frame sections which are read-only and can be put in the text PT_LOAD.
This commit is contained in:
parent
02f41de9c1
commit
e43d142e40
|
@ -3546,4 +3546,150 @@ tc_gen_reloc (section, fixp)
|
|||
}
|
||||
#endif /* BFD_ASSEMBLER */
|
||||
|
||||
static char *vax_cons_special_reloc;
|
||||
|
||||
void
|
||||
vax_cons (exp, size)
|
||||
expressionS *exp;
|
||||
int size;
|
||||
{
|
||||
char *save;
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
vax_cons_special_reloc = NULL;
|
||||
save = input_line_pointer;
|
||||
if (input_line_pointer[0] == '%')
|
||||
{
|
||||
if (strncmp (input_line_pointer + 1, "pcrel", 5) == 0)
|
||||
{
|
||||
input_line_pointer += 6;
|
||||
vax_cons_special_reloc = "pcrel";
|
||||
}
|
||||
if (vax_cons_special_reloc)
|
||||
{
|
||||
int bad = 0;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
if (*input_line_pointer != '8')
|
||||
bad = 1;
|
||||
input_line_pointer--;
|
||||
break;
|
||||
case 2:
|
||||
if (input_line_pointer[0] != '1' || input_line_pointer[1] != '6')
|
||||
bad = 1;
|
||||
break;
|
||||
case 4:
|
||||
if (input_line_pointer[0] != '3' || input_line_pointer[1] != '2')
|
||||
bad = 1;
|
||||
break;
|
||||
default:
|
||||
bad = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bad)
|
||||
{
|
||||
as_bad (_("Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"),
|
||||
vax_cons_special_reloc, size * 8, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_line_pointer += 2;
|
||||
if (*input_line_pointer != '(')
|
||||
{
|
||||
as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
|
||||
vax_cons_special_reloc, size * 8);
|
||||
bad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bad)
|
||||
{
|
||||
input_line_pointer = save;
|
||||
vax_cons_special_reloc = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int c;
|
||||
char *end = ++input_line_pointer;
|
||||
int npar = 0;
|
||||
|
||||
while (! is_end_of_line[(c = *end)])
|
||||
{
|
||||
if (c == '(')
|
||||
npar++;
|
||||
else if (c == ')')
|
||||
{
|
||||
if (!npar)
|
||||
break;
|
||||
npar--;
|
||||
}
|
||||
end++;
|
||||
}
|
||||
|
||||
if (c != ')')
|
||||
as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
|
||||
vax_cons_special_reloc, size * 8);
|
||||
else
|
||||
{
|
||||
*end = '\0';
|
||||
expression (exp);
|
||||
*end = c;
|
||||
if (input_line_pointer != end)
|
||||
{
|
||||
as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
|
||||
vax_cons_special_reloc, size * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_line_pointer++;
|
||||
SKIP_WHITESPACE ();
|
||||
c = *input_line_pointer;
|
||||
if (! is_end_of_line[c] && c != ',')
|
||||
as_bad (_("Illegal operands: garbage after %%r_%s%d()"),
|
||||
vax_cons_special_reloc, size * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vax_cons_special_reloc == NULL)
|
||||
expression (exp);
|
||||
}
|
||||
|
||||
/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
|
||||
reloc for a cons. */
|
||||
|
||||
void
|
||||
vax_cons_fix_new (frag, where, nbytes, exp)
|
||||
fragS *frag;
|
||||
int where;
|
||||
unsigned int nbytes;
|
||||
expressionS *exp;
|
||||
{
|
||||
bfd_reloc_code_real_type r;
|
||||
|
||||
r = (nbytes == 1 ? BFD_RELOC_8 :
|
||||
(nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
|
||||
|
||||
if (vax_cons_special_reloc)
|
||||
{
|
||||
if (*vax_cons_special_reloc == 'p')
|
||||
{
|
||||
switch (nbytes)
|
||||
{
|
||||
case 1: r = BFD_RELOC_8_PCREL; break;
|
||||
case 2: r = BFD_RELOC_16_PCREL; break;
|
||||
case 4: r = BFD_RELOC_32_PCREL; break;
|
||||
default: abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
|
||||
vax_cons_special_reloc = NULL;
|
||||
}
|
||||
|
||||
/* end of tc-vax.c */
|
||||
|
|
|
@ -56,6 +56,14 @@
|
|||
|
||||
long md_chars_to_number PARAMS ((unsigned char *, int));
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) vax_cons (EXP, NBYTES)
|
||||
#define TC_CONS_FIX_NEW vax_cons_fix_new
|
||||
void vax_cons PARAMS ((expressionS *, int));
|
||||
void vax_cons_fix_new
|
||||
PARAMS ((struct frag *, int, unsigned int, struct expressionS *));
|
||||
#endif
|
||||
|
||||
extern const struct relax_type md_relax_table[];
|
||||
#define TC_GENERIC_RELAX_TABLE md_relax_table
|
||||
|
||||
|
|
Loading…
Reference in New Issue