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:
matt 2007-03-16 22:16:12 +00:00
parent 02f41de9c1
commit e43d142e40
2 changed files with 154 additions and 0 deletions

View File

@ -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 */

View File

@ -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