* write.c (dump_section_relocs): Don't convert PC-relative relocs
that have an in-place addend narrower than the addresses used.
This commit is contained in:
parent
7e51250f06
commit
080f9e4f20
2 changed files with 22 additions and 4 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2011-11-15 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
|
* write.c (dump_section_relocs): Don't convert PC-relative relocs
|
||||||
|
that have an in-place addend narrower than the addresses used.
|
||||||
|
|
||||||
2011-11-14 Maciej W. Rozycki <macro@codesourcery.com>
|
2011-11-14 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
* config/tc-mips.c (can_swap_branch_p): Exclude microMIPS
|
* config/tc-mips.c (can_swap_branch_p): Exclude microMIPS
|
||||||
|
|
21
gas/write.c
21
gas/write.c
|
@ -654,15 +654,21 @@ dump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream)
|
||||||
static void
|
static void
|
||||||
resolve_reloc_expr_symbols (void)
|
resolve_reloc_expr_symbols (void)
|
||||||
{
|
{
|
||||||
|
bfd_vma addr_mask = 1;
|
||||||
struct reloc_list *r;
|
struct reloc_list *r;
|
||||||
|
|
||||||
|
/* Avoid a shift by the width of type. */
|
||||||
|
addr_mask <<= bfd_arch_bits_per_address (stdoutput) - 1;
|
||||||
|
addr_mask <<= 1;
|
||||||
|
addr_mask -= 1;
|
||||||
|
|
||||||
for (r = reloc_list; r; r = r->next)
|
for (r = reloc_list; r; r = r->next)
|
||||||
{
|
{
|
||||||
|
reloc_howto_type *howto = r->u.a.howto;
|
||||||
expressionS *symval;
|
expressionS *symval;
|
||||||
symbolS *sym;
|
symbolS *sym;
|
||||||
bfd_vma offset, addend;
|
bfd_vma offset, addend;
|
||||||
asection *sec;
|
asection *sec;
|
||||||
reloc_howto_type *howto;
|
|
||||||
|
|
||||||
resolve_symbol_value (r->u.a.offset_sym);
|
resolve_symbol_value (r->u.a.offset_sym);
|
||||||
symval = symbol_get_value_expression (r->u.a.offset_sym);
|
symval = symbol_get_value_expression (r->u.a.offset_sym);
|
||||||
|
@ -709,7 +715,16 @@ resolve_reloc_expr_symbols (void)
|
||||||
}
|
}
|
||||||
else if (sym != NULL)
|
else if (sym != NULL)
|
||||||
{
|
{
|
||||||
if (S_IS_LOCAL (sym) && !symbol_section_p (sym))
|
/* Convert relocs against local symbols to refer to the
|
||||||
|
corresponding section symbol plus offset instead. Keep
|
||||||
|
PC-relative relocs of the REL variety intact though to
|
||||||
|
prevent the offset from overflowing the relocated field,
|
||||||
|
unless it has enough bits to cover the whole address
|
||||||
|
space. */
|
||||||
|
if (S_IS_LOCAL (sym) && !symbol_section_p (sym)
|
||||||
|
&& !(howto->partial_inplace
|
||||||
|
&& howto->pc_relative
|
||||||
|
&& howto->src_mask != addr_mask))
|
||||||
{
|
{
|
||||||
asection *symsec = S_GET_SEGMENT (sym);
|
asection *symsec = S_GET_SEGMENT (sym);
|
||||||
if (!(((symsec->flags & SEC_MERGE) != 0
|
if (!(((symsec->flags & SEC_MERGE) != 0
|
||||||
|
@ -730,8 +745,6 @@ resolve_reloc_expr_symbols (void)
|
||||||
sym = abs_section_sym;
|
sym = abs_section_sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
howto = r->u.a.howto;
|
|
||||||
|
|
||||||
r->u.b.sec = sec;
|
r->u.b.sec = sec;
|
||||||
r->u.b.s = symbol_get_bfdsym (sym);
|
r->u.b.s = symbol_get_bfdsym (sym);
|
||||||
r->u.b.r.sym_ptr_ptr = &r->u.b.s;
|
r->u.b.r.sym_ptr_ptr = &r->u.b.s;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue