mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
All ELF relocs.
This commit is contained in:
@ -1,3 +1,24 @@
|
|||||||
|
Wed Feb 15 15:07:00 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||||
|
|
||||||
|
* config/tc-ppc.c (md_pseudo_table): If ELF, go to ppc_elf_cons
|
||||||
|
instead of cons.
|
||||||
|
(md_show_usage): Show all of the PowerPc options.
|
||||||
|
(ppc_elf_suffix): New function to recognize ELF suffixes that
|
||||||
|
specify a relocation, such as @GOT.
|
||||||
|
(ppc_elf_cons): Replacement for the standard cons function that
|
||||||
|
knows about the ELF suffixes.
|
||||||
|
(ppc_fixup): Add reloc field to hold non-standard relocation.
|
||||||
|
(md_assemble): Handle ELF suffixes like @GOT.
|
||||||
|
(md_create_short_jump): Dummy in case WORKING_DOT_WORD is not
|
||||||
|
defined.
|
||||||
|
(md_create_long_jump): Ditto.
|
||||||
|
(md_short_jump_size): Ditto.
|
||||||
|
(md_long_jump_size): Ditto.
|
||||||
|
(md_apply_fix): Handle BFD_RELOC_32_PCREL, BFD_RELOC_LO16,
|
||||||
|
BFD_RELOC_HI16, BFD_RELOC_HI16_S, BFD_RELOC_PPC_TOC16, and
|
||||||
|
BFD_RELOC_16 relocations. If relocation can not be found, print
|
||||||
|
the decimal value of the relocation.
|
||||||
|
|
||||||
Wed Feb 15 11:46:02 1995 Ian Lance Taylor <ian@cygnus.com>
|
Wed Feb 15 11:46:02 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
* config/tc-mips.c (macro): Don't use the target register as a
|
* config/tc-mips.c (macro): Don't use the target register as a
|
||||||
|
@ -55,6 +55,10 @@ static void ppc_stabx PARAMS ((int));
|
|||||||
static void ppc_rename PARAMS ((int));
|
static void ppc_rename PARAMS ((int));
|
||||||
static void ppc_toc PARAMS ((int));
|
static void ppc_toc PARAMS ((int));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **));
|
||||||
|
static void ppc_elf_cons PARAMS ((int));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generic assembler global variables which must be defined by all
|
/* Generic assembler global variables which must be defined by all
|
||||||
targets. */
|
targets. */
|
||||||
@ -107,6 +111,12 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{ "stabx", ppc_stabx, 0 },
|
{ "stabx", ppc_stabx, 0 },
|
||||||
{ "toc", ppc_toc, 0 },
|
{ "toc", ppc_toc, 0 },
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
{ "long", ppc_elf_cons, 4 },
|
||||||
|
{ "word", ppc_elf_cons, 2 },
|
||||||
|
{ "short", ppc_elf_cons, 2 },
|
||||||
|
{ "byte", ppc_elf_cons, 1 },
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This pseudo-op is used even when not generating XCOFF output. */
|
/* This pseudo-op is used even when not generating XCOFF output. */
|
||||||
{ "tc", ppc_tc, 0 },
|
{ "tc", ppc_tc, 0 },
|
||||||
@ -187,6 +197,10 @@ static bfd_size_type ppc_debug_name_section_size;
|
|||||||
symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
|
symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
|
||||||
#endif /* OBJ_ELF */
|
#endif /* OBJ_ELF */
|
||||||
|
|
||||||
|
#ifndef WORKING_DOT_WORD
|
||||||
|
const int md_short_jump_size = 4;
|
||||||
|
const int md_long_jump_size = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
CONST char *md_shortopts = "um:VQ:";
|
CONST char *md_shortopts = "um:VQ:";
|
||||||
@ -277,7 +291,8 @@ PowerPC options:\n\
|
|||||||
-mpwrx generate code for IBM POWER/2 (RIOS2)\n\
|
-mpwrx generate code for IBM POWER/2 (RIOS2)\n\
|
||||||
-mpwr generate code for IBM POWER (RIOS1)\n\
|
-mpwr generate code for IBM POWER (RIOS1)\n\
|
||||||
-m601 generate code for Motorola PowerPC 601\n\
|
-m601 generate code for Motorola PowerPC 601\n\
|
||||||
-mppc generate code for Motorola PowerPC 603/604\n\
|
-mppc, -mppc32, -m603, -m604\n\
|
||||||
|
generate code for Motorola PowerPC 603/604\n\
|
||||||
-many generate code for any architecture (PWR/PWRX/PPC)\n");
|
-many generate code for any architecture (PWR/PWRX/PPC)\n");
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
fprintf(stream, "\
|
fprintf(stream, "\
|
||||||
@ -469,6 +484,91 @@ ppc_insert_operand (insn, operand, val, file, line)
|
|||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
/* Parse @got, etc. and return the desired relocation. */
|
||||||
|
static bfd_reloc_code_real_type
|
||||||
|
ppc_elf_suffix (str_p)
|
||||||
|
char **str_p;
|
||||||
|
{
|
||||||
|
char *str = *str_p;
|
||||||
|
|
||||||
|
if (*str != '@')
|
||||||
|
return BFD_RELOC_UNUSED;
|
||||||
|
|
||||||
|
if (strncmp (str, "@GOT", 4) == 0 || strncmp (str, "@got", 4) == 0)
|
||||||
|
{
|
||||||
|
*str_p += 4;
|
||||||
|
return BFD_RELOC_PPC_TOC16;
|
||||||
|
}
|
||||||
|
else if (strncmp (str, "@L", 2) == 0 || strncmp (str, "@l", 2) == 0)
|
||||||
|
{
|
||||||
|
*str_p += 2;
|
||||||
|
return BFD_RELOC_LO16;
|
||||||
|
}
|
||||||
|
else if (strncmp (str, "@HA", 3) == 0 || strncmp (str, "@ha", 3) == 0)
|
||||||
|
{
|
||||||
|
*str_p += 3;
|
||||||
|
return BFD_RELOC_HI16_S;
|
||||||
|
}
|
||||||
|
else if (strncmp (str, "@H", 2) == 0 || strncmp (str, "@h", 2) == 0)
|
||||||
|
{
|
||||||
|
*str_p += 2;
|
||||||
|
return BFD_RELOC_HI16;
|
||||||
|
}
|
||||||
|
else if (strncmp (str, "@PCREL", 6) == 0 || strncmp (str, "@pcrel", 6) == 0)
|
||||||
|
{ /* this is a hack */
|
||||||
|
*str_p += 6;
|
||||||
|
return BFD_RELOC_32_PCREL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BFD_RELOC_UNUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like normal .long, except support @got, etc. */
|
||||||
|
/* worker to do .byte etc statements */
|
||||||
|
/* clobbers input_line_pointer, checks */
|
||||||
|
/* end-of-line. */
|
||||||
|
static void
|
||||||
|
ppc_elf_cons (nbytes)
|
||||||
|
register int nbytes; /* 1=.byte, 2=.word, 4=.long */
|
||||||
|
{
|
||||||
|
expressionS exp;
|
||||||
|
bfd_reloc_code_real_type reloc;
|
||||||
|
|
||||||
|
if (is_it_end_of_statement ())
|
||||||
|
{
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
expression (&exp);
|
||||||
|
if (nbytes == 4
|
||||||
|
&& exp.X_op == O_symbol
|
||||||
|
&& *input_line_pointer == '@'
|
||||||
|
&& (reloc = ppc_elf_suffix (&input_line_pointer)) != BFD_RELOC_UNUSED)
|
||||||
|
{
|
||||||
|
register char *p = frag_more ((int) nbytes);
|
||||||
|
reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
|
||||||
|
int offset = (!reloc_howto) ? 0 : (nbytes - bfd_get_reloc_size (reloc_howto));
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
fix_new_exp (frag_now, p - frag_now->fr_literal + offset, (int) nbytes - offset, &exp, 0, reloc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit_expr (&exp, (unsigned int) nbytes);
|
||||||
|
}
|
||||||
|
while (*input_line_pointer++ == ',');
|
||||||
|
|
||||||
|
input_line_pointer--; /* Put terminator back into stream. */
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* OBJ_ELF */
|
||||||
|
|
||||||
/* We need to keep a list of fixups. We can't simply generate them as
|
/* We need to keep a list of fixups. We can't simply generate them as
|
||||||
we go, because that would require us to first create the frag, and
|
we go, because that would require us to first create the frag, and
|
||||||
that would screw up references to ``.''. */
|
that would screw up references to ``.''. */
|
||||||
@ -477,6 +577,7 @@ struct ppc_fixup
|
|||||||
{
|
{
|
||||||
expressionS exp;
|
expressionS exp;
|
||||||
int opindex;
|
int opindex;
|
||||||
|
bfd_reloc_code_real_type reloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_INSN_FIXUPS (5)
|
#define MAX_INSN_FIXUPS (5)
|
||||||
@ -498,6 +599,7 @@ md_assemble (str)
|
|||||||
int fc;
|
int fc;
|
||||||
char *f;
|
char *f;
|
||||||
int i;
|
int i;
|
||||||
|
bfd_reloc_code_real_type reloc;
|
||||||
|
|
||||||
/* Get the opcode. */
|
/* Get the opcode. */
|
||||||
for (s = str; *s != '\0' && ! isspace (*s); s++)
|
for (s = str; *s != '\0' && ! isspace (*s); s++)
|
||||||
@ -632,6 +734,20 @@ md_assemble (str)
|
|||||||
else if (ex.X_op == O_constant)
|
else if (ex.X_op == O_constant)
|
||||||
insn = ppc_insert_operand (insn, operand, ex.X_add_number,
|
insn = ppc_insert_operand (insn, operand, ex.X_add_number,
|
||||||
(char *) NULL, 0);
|
(char *) NULL, 0);
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
else if ((reloc = ppc_elf_suffix (&str)) != BFD_RELOC_UNUSED)
|
||||||
|
{
|
||||||
|
/* We need to generate a fixup for this expression. */
|
||||||
|
if (fc >= MAX_INSN_FIXUPS)
|
||||||
|
as_fatal ("too many fixups");
|
||||||
|
fixups[fc].exp = ex;
|
||||||
|
fixups[fc].opindex = 0;
|
||||||
|
fixups[fc].reloc = reloc;
|
||||||
|
++fc;
|
||||||
|
}
|
||||||
|
#endif /* OBJ_ELF */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We need to generate a fixup for this expression. */
|
/* We need to generate a fixup for this expression. */
|
||||||
@ -639,6 +755,7 @@ md_assemble (str)
|
|||||||
as_fatal ("too many fixups");
|
as_fatal ("too many fixups");
|
||||||
fixups[fc].exp = ex;
|
fixups[fc].exp = ex;
|
||||||
fixups[fc].opindex = *opindex_ptr;
|
fixups[fc].opindex = *opindex_ptr;
|
||||||
|
fixups[fc].reloc = BFD_RELOC_UNUSED;
|
||||||
++fc;
|
++fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,6 +805,19 @@ md_assemble (str)
|
|||||||
const struct powerpc_operand *operand;
|
const struct powerpc_operand *operand;
|
||||||
|
|
||||||
operand = &powerpc_operands[fixups[i].opindex];
|
operand = &powerpc_operands[fixups[i].opindex];
|
||||||
|
if (fixups[i].reloc != BFD_RELOC_UNUSED)
|
||||||
|
{
|
||||||
|
reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
|
||||||
|
int offset = (!reloc_howto) ? 0 : (4 - bfd_get_reloc_size (reloc_howto));
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
fix_new_exp (frag_now, f - frag_now->fr_literal + offset, 4 - offset,
|
||||||
|
&fixups[i].exp, (reloc_howto && reloc_howto->pc_relative),
|
||||||
|
fixups[i].reloc);
|
||||||
|
}
|
||||||
|
else
|
||||||
fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
|
fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
|
||||||
&fixups[i].exp,
|
&fixups[i].exp,
|
||||||
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
|
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
|
||||||
@ -696,6 +826,29 @@ md_assemble (str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WORKING_DOT_WORD
|
||||||
|
/* Handle long and short jumps */
|
||||||
|
void
|
||||||
|
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||||
|
char *ptr;
|
||||||
|
addressT from_addr, to_addr;
|
||||||
|
fragS *frag;
|
||||||
|
symbolS *to_symbol;
|
||||||
|
{
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||||
|
char *ptr;
|
||||||
|
addressT from_addr, to_addr;
|
||||||
|
fragS *frag;
|
||||||
|
symbolS *to_symbol;
|
||||||
|
{
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle a macro. Gather all the operands, transform them as
|
/* Handle a macro. Gather all the operands, transform them as
|
||||||
described by the macro, and call md_assemble recursively. All the
|
described by the macro, and call md_assemble recursively. All the
|
||||||
operands are separated by commas; we don't accept parentheses
|
operands are separated by commas; we don't accept parentheses
|
||||||
@ -1789,7 +1942,7 @@ ppc_symbol_new_hook (sym)
|
|||||||
sym->sy_tc.class = XMC_TI;
|
sym->sy_tc.class = XMC_TI;
|
||||||
else if (strcmp (s, "TB]") == 0)
|
else if (strcmp (s, "TB]") == 0)
|
||||||
sym->sy_tc.class = XMC_TB;
|
sym->sy_tc.class = XMC_TB;
|
||||||
else if (strcmp (s, "TC0]") == 0 || strcm (s, "T0]") == 0)
|
else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
|
||||||
sym->sy_tc.class = XMC_TC0;
|
sym->sy_tc.class = XMC_TC0;
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
@ -2492,9 +2645,14 @@ md_apply_fix (fixp, valuep)
|
|||||||
switch (fixp->fx_r_type)
|
switch (fixp->fx_r_type)
|
||||||
{
|
{
|
||||||
case BFD_RELOC_32:
|
case BFD_RELOC_32:
|
||||||
|
case BFD_RELOC_32_PCREL:
|
||||||
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
|
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
|
||||||
value, 4);
|
value, 4);
|
||||||
break;
|
break;
|
||||||
|
case BFD_RELOC_LO16:
|
||||||
|
case BFD_RELOC_HI16:
|
||||||
|
case BFD_RELOC_HI16_S:
|
||||||
|
case BFD_RELOC_PPC_TOC16:
|
||||||
case BFD_RELOC_16:
|
case BFD_RELOC_16:
|
||||||
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
|
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
|
||||||
value, 2);
|
value, 2);
|
||||||
@ -2542,7 +2700,7 @@ tc_gen_reloc (seg, fixp)
|
|||||||
if (reloc->howto == (reloc_howto_type *) NULL)
|
if (reloc->howto == (reloc_howto_type *) NULL)
|
||||||
{
|
{
|
||||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||||
"reloc not supported by object file format");
|
"reloc %d not supported by object file format", (int)fixp->fx_r_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
reloc->addend = fixp->fx_addnumber;
|
reloc->addend = fixp->fx_addnumber;
|
||||||
|
Reference in New Issue
Block a user