mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
2003-02-25 Alexandre Oliva <aoliva@redhat.com>
* config/tc-mn10300.c (mn10300_check_fixup): Set GOT_PCREL type for subtracts from GLOBAL_OFFSET_TABLE that could not be simplified. 2002-07-18 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.c (mn10300_check_fixup): Accept subtracts that could not be simplified. (tc_gen_reloc): Turn an absolute fx_subsy into part of fx_offset. 2001-11-04 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't adjust BDF_RELOC_MN10300_GOT32. * config/tc-mn10300.c (mn10300_fix_adjustable): If TC_RELOC_RTSYM_LOC_FIXUP doesn't hold, it's not adjustable. 2001-05-09 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.c (mn10300_parse_name): Don't return a symbol if we know its value. 2001-05-09 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.h (GLOBAL_OFFSET_TABLE_NAME): Remove duplicate underscore prefix. 2001-05-09 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.c (mn10300_parse_name): Store relocation type in X_md, not X_add_number. Zero X_add_number. (mn10300_check_fixup): Extract relocation type from X_md. * config/tc-mn10300.h: Update comment. 2001-04-14 Alexandre Oliva <aoliva@redhat.com> * config/tc-mn10300.h (O_GOTOFF, O_PLT, O_GOT): Replace with... (O_PIC_reloc): this. * config/tc-mn10300.c (mn10300_PIC_related_p): Use it. (mn10300_check_fixup): Likewise. (mn10300_parse_name): Set X_add_number to relocation type. * config/tc-mn10300.h (DIFF_EXPR_OK, GLOBAL_OFFSET_TABLE_NAME, TC_RELOC_RTSYM_LOC_FIXUP, md_parse_name, TC_CONS_FIX_NEW, O_GOTOFF, O_PLT, O_GOT): Define. * config/tc-mn10300.c (mn10300_PIC_related_p): New fn. (mn10300_check_fixup): New fn. (md_assemble): Call it. Check for PIC-related relocs. (mn10300_cons_fix_new): Likewise. New fn. (mn10300_end_of_match): New fn. (mn10300_md_parse_name_cont): New fn.
This commit is contained in:
@ -1,3 +1,45 @@
|
|||||||
|
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
2003-02-25 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.c (mn10300_check_fixup): Set GOT_PCREL type
|
||||||
|
for subtracts from GLOBAL_OFFSET_TABLE that could not be
|
||||||
|
simplified.
|
||||||
|
2002-07-18 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.c (mn10300_check_fixup): Accept subtracts that
|
||||||
|
could not be simplified.
|
||||||
|
(tc_gen_reloc): Turn an absolute fx_subsy into part of fx_offset.
|
||||||
|
2001-11-04 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't adjust
|
||||||
|
BDF_RELOC_MN10300_GOT32.
|
||||||
|
* config/tc-mn10300.c (mn10300_fix_adjustable): If
|
||||||
|
TC_RELOC_RTSYM_LOC_FIXUP doesn't hold, it's not adjustable.
|
||||||
|
2001-05-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.c (mn10300_parse_name): Don't return a
|
||||||
|
symbol if we know its value.
|
||||||
|
2001-05-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.h (GLOBAL_OFFSET_TABLE_NAME): Remove
|
||||||
|
duplicate underscore prefix.
|
||||||
|
2001-05-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.c (mn10300_parse_name): Store relocation
|
||||||
|
type in X_md, not X_add_number. Zero X_add_number.
|
||||||
|
(mn10300_check_fixup): Extract relocation type from X_md.
|
||||||
|
* config/tc-mn10300.h: Update comment.
|
||||||
|
2001-04-14 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
* config/tc-mn10300.h (O_GOTOFF, O_PLT, O_GOT): Replace with...
|
||||||
|
(O_PIC_reloc): this.
|
||||||
|
* config/tc-mn10300.c (mn10300_PIC_related_p): Use it.
|
||||||
|
(mn10300_check_fixup): Likewise.
|
||||||
|
(mn10300_parse_name): Set X_add_number to relocation type.
|
||||||
|
* config/tc-mn10300.h (DIFF_EXPR_OK, GLOBAL_OFFSET_TABLE_NAME,
|
||||||
|
TC_RELOC_RTSYM_LOC_FIXUP, md_parse_name, TC_CONS_FIX_NEW,
|
||||||
|
O_GOTOFF, O_PLT, O_GOT): Define.
|
||||||
|
* config/tc-mn10300.c (mn10300_PIC_related_p): New fn.
|
||||||
|
(mn10300_check_fixup): New fn.
|
||||||
|
(md_assemble): Call it. Check for PIC-related relocs.
|
||||||
|
(mn10300_cons_fix_new): Likewise. New fn.
|
||||||
|
(mn10300_end_of_match): New fn.
|
||||||
|
(mn10300_md_parse_name_cont): New fn.
|
||||||
|
|
||||||
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
2003-07-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
2000-05-25 Alexandre Oliva <aoliva@cygnus.com>
|
2000-05-25 Alexandre Oliva <aoliva@cygnus.com>
|
||||||
|
@ -1219,6 +1219,140 @@ md_begin ()
|
|||||||
current_machine = MN103;
|
current_machine = MN103;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static symbolS *GOT_symbol;
|
||||||
|
|
||||||
|
static inline int mn10300_check_fixup PARAMS ((struct mn10300_fixup *));
|
||||||
|
static inline int mn10300_PIC_related_p PARAMS ((symbolS *));
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
mn10300_PIC_related_p (sym)
|
||||||
|
symbolS *sym;
|
||||||
|
{
|
||||||
|
expressionS *exp;
|
||||||
|
|
||||||
|
if (! sym)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sym == GOT_symbol)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
exp = symbol_get_value_expression (sym);
|
||||||
|
|
||||||
|
return (exp->X_op == O_PIC_reloc
|
||||||
|
|| mn10300_PIC_related_p (exp->X_add_symbol)
|
||||||
|
|| mn10300_PIC_related_p (exp->X_op_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
mn10300_check_fixup (fixup)
|
||||||
|
struct mn10300_fixup *fixup;
|
||||||
|
{
|
||||||
|
expressionS *exp = &fixup->exp;
|
||||||
|
|
||||||
|
repeat:
|
||||||
|
switch (exp->X_op)
|
||||||
|
{
|
||||||
|
case O_add:
|
||||||
|
case O_subtract: /* If we're sufficiently unlucky that the label
|
||||||
|
and the expression that references it happen
|
||||||
|
to end up in different frags, the subtract
|
||||||
|
won't be simplified within expression(). */
|
||||||
|
/* The PIC-related operand must be the first operand of a sum. */
|
||||||
|
if (exp != &fixup->exp || mn10300_PIC_related_p (exp->X_op_symbol))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (exp->X_add_symbol && exp->X_add_symbol == GOT_symbol)
|
||||||
|
fixup->reloc = BFD_RELOC_32_GOT_PCREL;
|
||||||
|
|
||||||
|
exp = symbol_get_value_expression (exp->X_add_symbol);
|
||||||
|
goto repeat;
|
||||||
|
|
||||||
|
case O_symbol:
|
||||||
|
if (exp->X_add_symbol && exp->X_add_symbol == GOT_symbol)
|
||||||
|
fixup->reloc = BFD_RELOC_32_GOT_PCREL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case O_PIC_reloc:
|
||||||
|
fixup->reloc = exp->X_md;
|
||||||
|
exp->X_op = O_symbol;
|
||||||
|
if (fixup->reloc == BFD_RELOC_32_PLT_PCREL
|
||||||
|
&& fixup->opindex >= 0
|
||||||
|
&& (mn10300_operands[fixup->opindex].flags
|
||||||
|
& MN10300_OPERAND_RELAX))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (mn10300_PIC_related_p (exp->X_add_symbol)
|
||||||
|
|| mn10300_PIC_related_p (exp->X_op_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mn10300_cons_fix_new (frag, off, size, exp)
|
||||||
|
fragS *frag;
|
||||||
|
int off, size;
|
||||||
|
expressionS *exp;
|
||||||
|
{
|
||||||
|
struct mn10300_fixup fixup;
|
||||||
|
|
||||||
|
fixup.opindex = -1;
|
||||||
|
fixup.exp = *exp;
|
||||||
|
fixup.reloc = BFD_RELOC_UNUSED;
|
||||||
|
|
||||||
|
mn10300_check_fixup (&fixup);
|
||||||
|
|
||||||
|
if (fixup.reloc == BFD_RELOC_MN10300_GOT32)
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
fixup.reloc = BFD_RELOC_MN10300_GOT16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
fixup.reloc = BFD_RELOC_MN10300_GOT24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else if (fixup.reloc == BFD_RELOC_UNUSED)
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
fixup.reloc = BFD_RELOC_8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
fixup.reloc = BFD_RELOC_16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
fixup.reloc = BFD_RELOC_24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
fixup.reloc = BFD_RELOC_32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else if (size != 4)
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
as_bad (_("unsupported BFD relocation size %u"), size);
|
||||||
|
fixup.reloc = BFD_RELOC_UNUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fix_new_exp (frag, off, size, &fixup.exp, 0, fixup.reloc);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
md_assemble (str)
|
md_assemble (str)
|
||||||
char *str;
|
char *str;
|
||||||
@ -1748,6 +1882,8 @@ md_assemble (str)
|
|||||||
fixups[fc].exp = ex;
|
fixups[fc].exp = ex;
|
||||||
fixups[fc].opindex = *opindex_ptr;
|
fixups[fc].opindex = *opindex_ptr;
|
||||||
fixups[fc].reloc = BFD_RELOC_UNUSED;
|
fixups[fc].reloc = BFD_RELOC_UNUSED;
|
||||||
|
if (mn10300_check_fixup (& fixups[fc]))
|
||||||
|
goto error;
|
||||||
++fc;
|
++fc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2042,7 +2178,11 @@ keep_going:
|
|||||||
const struct mn10300_operand *operand;
|
const struct mn10300_operand *operand;
|
||||||
|
|
||||||
operand = &mn10300_operands[fixups[i].opindex];
|
operand = &mn10300_operands[fixups[i].opindex];
|
||||||
if (fixups[i].reloc != BFD_RELOC_UNUSED)
|
if (fixups[i].reloc != BFD_RELOC_UNUSED
|
||||||
|
&& fixups[i].reloc != BFD_RELOC_32_GOT_PCREL
|
||||||
|
&& fixups[i].reloc != BFD_RELOC_32_GOTOFF
|
||||||
|
&& fixups[i].reloc != BFD_RELOC_32_PLT_PCREL
|
||||||
|
&& fixups[i].reloc != BFD_RELOC_MN10300_GOT32)
|
||||||
{
|
{
|
||||||
reloc_howto_type *reloc_howto;
|
reloc_howto_type *reloc_howto;
|
||||||
int size;
|
int size;
|
||||||
@ -2072,6 +2212,8 @@ keep_going:
|
|||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
|
|
||||||
reloc = BFD_RELOC_NONE;
|
reloc = BFD_RELOC_NONE;
|
||||||
|
if (fixups[i].reloc != BFD_RELOC_UNUSED)
|
||||||
|
reloc = fixups[i].reloc;
|
||||||
/* How big is the reloc? Remember SPLIT relocs are
|
/* How big is the reloc? Remember SPLIT relocs are
|
||||||
implicitly 32bits. */
|
implicitly 32bits. */
|
||||||
if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
|
if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
|
||||||
@ -2083,11 +2225,15 @@ keep_going:
|
|||||||
|
|
||||||
/* Is the reloc pc-relative? */
|
/* Is the reloc pc-relative? */
|
||||||
pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
|
pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
|
||||||
|
if (reloc != BFD_RELOC_NONE)
|
||||||
|
pcrel = bfd_reloc_type_lookup (stdoutput, reloc)->pc_relative;
|
||||||
|
|
||||||
offset = size - (reloc_size + operand->shift) / 8;
|
offset = size - (reloc_size + operand->shift) / 8;
|
||||||
|
|
||||||
/* Choose a proper BFD relocation type. */
|
/* Choose a proper BFD relocation type. */
|
||||||
if (pcrel)
|
if (reloc != BFD_RELOC_NONE)
|
||||||
|
;
|
||||||
|
else if (pcrel)
|
||||||
{
|
{
|
||||||
if (reloc_size == 32)
|
if (reloc_size == 32)
|
||||||
reloc = BFD_RELOC_32_PCREL;
|
reloc = BFD_RELOC_32_PCREL;
|
||||||
@ -2153,6 +2299,13 @@ tc_gen_reloc (seg, fixp)
|
|||||||
}
|
}
|
||||||
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
||||||
|
|
||||||
|
if (fixp->fx_subsy
|
||||||
|
&& S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
|
||||||
|
{
|
||||||
|
fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
|
||||||
|
fixp->fx_subsy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (fixp->fx_addsy && fixp->fx_subsy)
|
if (fixp->fx_addsy && fixp->fx_subsy)
|
||||||
{
|
{
|
||||||
reloc->sym_ptr_ptr = NULL;
|
reloc->sym_ptr_ptr = NULL;
|
||||||
@ -2368,6 +2521,9 @@ bfd_boolean
|
|||||||
mn10300_fix_adjustable (fixp)
|
mn10300_fix_adjustable (fixp)
|
||||||
struct fix *fixp;
|
struct fix *fixp;
|
||||||
{
|
{
|
||||||
|
if (! TC_RELOC_RTSYM_LOC_FIXUP (fixp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
||||||
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2560,3 +2716,87 @@ set_arch_mach (mach)
|
|||||||
|
|
||||||
current_machine = mach;
|
current_machine = mach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char * mn10300_end_of_match PARAMS ((char *, char *));
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
mn10300_end_of_match (cont, what)
|
||||||
|
char *cont, *what;
|
||||||
|
{
|
||||||
|
int len = strlen (what);
|
||||||
|
|
||||||
|
if (strncmp (cont, what, strlen (what)) == 0
|
||||||
|
&& ! is_part_of_name (cont[len]))
|
||||||
|
return cont + len;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mn10300_parse_name (name, exprP, nextcharP)
|
||||||
|
char const *name;
|
||||||
|
expressionS *exprP;
|
||||||
|
char *nextcharP;
|
||||||
|
{
|
||||||
|
char *next = input_line_pointer;
|
||||||
|
char *next_end;
|
||||||
|
int reloc_type;
|
||||||
|
segT segment;
|
||||||
|
|
||||||
|
exprP->X_op_symbol = NULL;
|
||||||
|
|
||||||
|
if (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
|
||||||
|
{
|
||||||
|
if (! GOT_symbol)
|
||||||
|
GOT_symbol = symbol_find_or_make (name);
|
||||||
|
|
||||||
|
exprP->X_add_symbol = GOT_symbol;
|
||||||
|
no_suffix:
|
||||||
|
/* If we have an absolute symbol or a reg,
|
||||||
|
then we know its value now. */
|
||||||
|
segment = S_GET_SEGMENT (exprP->X_add_symbol);
|
||||||
|
if (segment == absolute_section)
|
||||||
|
{
|
||||||
|
exprP->X_op = O_constant;
|
||||||
|
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
|
||||||
|
exprP->X_add_symbol = NULL;
|
||||||
|
}
|
||||||
|
else if (segment == reg_section)
|
||||||
|
{
|
||||||
|
exprP->X_op = O_register;
|
||||||
|
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
|
||||||
|
exprP->X_add_symbol = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exprP->X_op = O_symbol;
|
||||||
|
exprP->X_add_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
exprP->X_add_symbol = symbol_find_or_make (name);
|
||||||
|
|
||||||
|
if (*nextcharP != '@')
|
||||||
|
goto no_suffix;
|
||||||
|
else if ((next_end = mn10300_end_of_match (next + 1, "GOTOFF")))
|
||||||
|
reloc_type = BFD_RELOC_32_GOTOFF;
|
||||||
|
else if ((next_end = mn10300_end_of_match (next + 1, "GOT")))
|
||||||
|
reloc_type = BFD_RELOC_MN10300_GOT32;
|
||||||
|
else if ((next_end = mn10300_end_of_match (next + 1, "PLT")))
|
||||||
|
reloc_type = BFD_RELOC_32_PLT_PCREL;
|
||||||
|
else
|
||||||
|
goto no_suffix;
|
||||||
|
|
||||||
|
*input_line_pointer = *nextcharP;
|
||||||
|
input_line_pointer = next_end;
|
||||||
|
*nextcharP = *input_line_pointer;
|
||||||
|
*input_line_pointer = '\0';
|
||||||
|
|
||||||
|
exprP->X_op = O_PIC_reloc;
|
||||||
|
exprP->X_add_number = 0;
|
||||||
|
exprP->X_md = reloc_type;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -27,6 +27,31 @@
|
|||||||
#error MN10300 support requires BFD_ASSEMBLER
|
#error MN10300 support requires BFD_ASSEMBLER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DIFF_EXPR_OK
|
||||||
|
#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
|
||||||
|
|
||||||
|
#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
|
||||||
|
((FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \
|
||||||
|
&& (FIX)->fx_r_type != BFD_RELOC_MN10300_GOT32 \
|
||||||
|
&& (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \
|
||||||
|
&& ((FIX)->fx_addsy == NULL \
|
||||||
|
|| (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
|
||||||
|
&& ! S_IS_WEAK ((FIX)->fx_addsy) \
|
||||||
|
&& S_IS_DEFINED ((FIX)->fx_addsy) \
|
||||||
|
&& ! S_IS_COMMON ((FIX)->fx_addsy))))
|
||||||
|
|
||||||
|
#define md_parse_name(name, exprP, nextcharP) \
|
||||||
|
mn10300_parse_name ((name), (exprP), (nextcharP))
|
||||||
|
int mn10300_parse_name PARAMS ((char const *, expressionS *, char *));
|
||||||
|
|
||||||
|
#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
|
||||||
|
mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
|
||||||
|
void mn10300_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
|
||||||
|
|
||||||
|
/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
|
||||||
|
symbols. The relocation type is stored in X_md. */
|
||||||
|
#define O_PIC_reloc O_md1
|
||||||
|
|
||||||
/* The target BFD architecture. */
|
/* The target BFD architecture. */
|
||||||
#define TARGET_ARCH bfd_arch_mn10300
|
#define TARGET_ARCH bfd_arch_mn10300
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user