* config/tc-mn10300.c (mn10300_force_relocation): Force a reloc to be generated for alignment fixups.

* config/tc-mn10300.h (TC_FORCE_RELOCATION): Call mn10300_force_relocation.
* elf-m10300.c (mn10300_elf_final_link_relocate): Prevent the accidental termination of DWARF location list entries.
  (mn10300_elf_relax_delete_bytes): Stop deletion if an align reloc is encountered that is larger than or not a mutliple of the number of bytes being deleted.
  When adjusting symbols, any symbols inside the region being deleted must be moved to the end of the region.
  Move align relocs forward if there is room for them after the deletion of the region.
This commit is contained in:
Nick Clifton 2007-11-13 10:40:29 +00:00
parent 0067a5693a
commit b5f5fd962e
11 changed files with 191 additions and 26 deletions

View File

@ -1,3 +1,15 @@
2007-11-13 Nick Clifton <nickc@redhat.com>
* elf-m10300.c (mn10300_elf_final_link_relocate): Prevent the
accidental termination of DWARF location list entries.
(mn10300_elf_relax_delete_bytes): Stop deletion if an align reloc
is encountered that is larger than or not a mutliple of the number
of bytes being deleted.
When adjusting symbols, any symbols inside the region being
deleted must be moved to the end of the region.
Move align relocs forward if there is room for them after the
deletion of the region.
2007-11-13 Alan Modra <amodra@bigpond.net.au>
PR 5233

View File

@ -1039,6 +1039,17 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
case R_MN10300_16:
case R_MN10300_8:
value -= sym_diff_value;
/* If we are computing a 32-bit value for the location lists
and the result is 0 then we add one to the value. A zero
value can result because of linker relaxation deleteing
prologue instructions and using a value of 1 (for the begin
and end offsets in the location list entry) results in a
nul entry which does not prevent the following entries from
being parsed. */
if (r_type == R_MN10300_32
&& value == 0
&& strcmp (input_section->name, ".debug_loc") == 0)
value = 1;
sym_diff_section = NULL;
is_sym_diff_reloc = TRUE;
break;
@ -1856,17 +1867,23 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
--irelend;
/* The deletion must stop at the next ALIGN reloc for an aligment
power larger than the number of bytes we are deleting. */
power larger than, or not a multiple of, the number of bytes we
are deleting. */
for (; irel < irelend; irel++)
if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
&& irel->r_offset > addr
&& irel->r_offset < toaddr
&& count < (1 << irel->r_addend))
{
irelalign = irel;
toaddr = irel->r_offset;
break;
}
{
int alignment = 1 << irel->r_addend;
if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
&& irel->r_offset > addr
&& irel->r_offset < toaddr
&& (count < alignment
|| alignment % count != 0))
{
irelalign = irel;
toaddr = irel->r_offset;
break;
}
}
}
/* Actually delete the bytes. */
@ -1898,11 +1915,17 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
{
/* Get the new reloc address. */
if ((irel->r_offset > addr
&& irel->r_offset < toaddr))
&& irel->r_offset < toaddr)
|| (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
&& irel->r_offset == toaddr))
irel->r_offset -= count;
}
/* Adjust the local symbols defined in this section. */
/* Adjust the local symbols in the section, reducing their value
by the number of bytes deleted. Note - symbols within the deleted
region are moved to the address of the start of the region, which
actually means that they will address the byte beyond the end of
the region once the deletion has been completed. */
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
@ -1910,7 +1933,12 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
isym->st_value -= count;
{
if (isym->st_value < addr + count)
isym->st_value = addr;
else
isym->st_value -= count;
}
/* Adjust the function symbol's size as well. */
else if (isym->st_shndx == sec_shndx
&& ELF_ST_TYPE (isym->st_info) == STT_FUNC
@ -1933,7 +1961,12 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
&& sym_hash->root.u.def.section == sec
&& sym_hash->root.u.def.value > addr
&& sym_hash->root.u.def.value < toaddr)
sym_hash->root.u.def.value -= count;
{
if (sym_hash->root.u.def.value < addr + count)
sym_hash->root.u.def.value = addr;
else
sym_hash->root.u.def.value -= count;
}
/* Adjust the function symbol's size as well. */
else if (sym_hash->root.type == bfd_link_hash_defined
&& sym_hash->root.u.def.section == sec
@ -1943,6 +1976,26 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
sym_hash->size -= count;
}
/* See if we can move the ALIGN reloc forward.
We have adjusted r_offset for it already. */
if (irelalign != NULL)
{
bfd_vma alignto, alignaddr;
if ((int) irelalign->r_addend > 0)
{
/* This is the old address. */
alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend);
/* This is where the align points to now. */
alignaddr = BFD_ALIGN (irelalign->r_offset,
1 << irelalign->r_addend);
if (alignaddr < alignto)
/* Tail recursion. */
return mn10300_elf_relax_delete_bytes (abfd, sec, alignaddr,
(int) (alignto - alignaddr));
}
}
return TRUE;
}

View File

@ -1,3 +1,10 @@
2007-11-13 Nick Clifton <nickc@redhat.com>
* config/tc-mn10300.c (mn10300_force_relocation): Force a reloc to
be generated for alignment fixups.
* config/tc-mn10300.h (TC_FORCE_RELOCATION): Call
mn10300_force_relocation.
2007-11-12 Nick Clifton <nickc@redhat.com>
PR gas/5269

View File

@ -2571,11 +2571,9 @@ mn10300_allow_local_subtract (expressionS * left, expressionS * right, segT sect
void
mn10300_handle_align (fragS *frag)
{
if (! linkrelax)
return;
if ((frag->fr_type == rs_align
|| frag->fr_type == rs_align_code)
if (linkrelax
&& (frag->fr_type == rs_align
|| frag->fr_type == rs_align_code)
&& frag->fr_address + frag->fr_fix > 0
&& frag->fr_offset > 1
&& now_seg != bss_section
@ -2590,3 +2588,14 @@ mn10300_handle_align (fragS *frag)
fix_new (frag, frag->fr_fix, 0, & abs_symbol, frag->fr_offset, FALSE,
BFD_RELOC_MN10300_ALIGN);
}
bfd_boolean
mn10300_force_relocation (struct fix * fixp)
{
if (linkrelax
&& (fixp->fx_pcrel
|| fixp->fx_r_type == BFD_RELOC_MN10300_ALIGN))
return TRUE;
return generic_force_reloc (fixp);
}

View File

@ -26,8 +26,8 @@
#define DIFF_EXPR_OK
#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
#define TC_FORCE_RELOCATION(FIX) \
(generic_force_reloc (FIX))
#define TC_FORCE_RELOCATION(FIX) mn10300_force_relocation (FIX)
extern bfd_boolean mn10300_force_relocation (struct fix *);
#define TC_FORCE_RELOCATION_LOCAL(FIX) \
(!(FIX)->fx_pcrel \
@ -36,14 +36,13 @@
|| (FIX)->fx_r_type == BFD_RELOC_32_GOT_PCREL \
|| TC_FORCE_RELOCATION (FIX))
#define md_parse_name(name, exprP, mode, nextcharP) \
mn10300_parse_name ((name), (exprP), (mode), (nextcharP))
int mn10300_parse_name PARAMS ((char const *, expressionS *,
enum expr_mode, char *));
#define md_parse_name(NAME, EXPRP, MODE, NEXTCHARP) \
mn10300_parse_name ((NAME), (EXPRP), (MODE), (NEXTCHARP))
int mn10300_parse_name (char const *, expressionS *, enum expr_mode, 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 *));
void mn10300_cons_fix_new (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. */

View File

@ -1,3 +1,11 @@
2007-11-13 Nick Clifton <nickc@redhat.com>
* ld-mn10300/i127740.s: New test: Checks relaxation and alignment.
* ld-mn10300/i127740.d: New file: Expected disassembly.
* ld-mn10300/i135409-3.s: New test: Check symbols inside a relaxed region.
* ld-mn10300/i135409-3.d: New file: Expected disassembly.
* ld-mn10300/mn10300.exp: Run new tests.
2007-11-08 Nathan Sidwell <nathan@codesourcery.com>
* ld-vxworks/tls-2.d: New.

View File

@ -0,0 +1,17 @@
tmpdir/i127740.x: file format elf32-.*
Disassembly of section .text:
0+0100 <_main>:
100: 2d 00 03[ ]+mov 768,d1
103: cb[ ]+nop
104: cb[ ]+nop
105: cb[ ]+nop
...
0+0200 <_dummy>:
200: 00[ ]+clr d0
201: 02 00 00[ ]+movbu d0,\(0 <_main-0x100>\)
204: df 00 00[ ]+ret \[\],0
...

View File

@ -0,0 +1,12 @@
.section .text
.global _main
.global _dummy
_main:
mov _g_label,d1 # instruction is changed by relaxations
.balign 0x100
_dummy:
.long _dummy
ret [],0
.size _main, .-_main
.comm _g_label,4,4

View File

@ -0,0 +1,16 @@
tmpdir/i135409-3.x: file format elf32-.*
Disassembly of section .text:
0+0 <_func>:
0: 25 1f 00[ ]+mov 31,a1
3: cb[ ]+nop
0+04 <A>:
4: 25 1f 00[ ]+mov 31,a1
7: cb[ ]+nop
0+08 <BOTTOM>:
8: e1[ ]+add d0,d1
#pass

View File

@ -0,0 +1,16 @@
.text
.global _start
_start:
.type _func, @function
_func:
mov L001,A1
nop
A:
mov L001,A1
BOTTOM:
.balign 0x8
add D0,D1
.size _func, .-func
.data
L001:

View File

@ -47,6 +47,14 @@ set mn10300_tests {
{ {objdump -D i112045-3.d} }
"i112045-3.x"
}
{
"relaxation and alignment directives"
"-relax -Ttext 100"
""
{ "i127740.s" }
{ {objdump -d i127740.d} }
"i127740.x"
}
{
"adjustment of symbols due to relaxation"
"-Tdata 1f -Ttext 0 -relax"
@ -63,6 +71,14 @@ set mn10300_tests {
{ {readelf --syms i135409-2.d} }
"i135409-2.x"
}
{
"adjustment of symbols due to relaxation (with a symbol in the deleted region)"
"-Tdata 1f -Ttext 0 -relax"
""
{ "i135409-3.s" }
{ {objdump -d i135409-3.d} }
"i135409-3.x"
}
}
run_ld_link_tests $mn10300_tests