* mn10300.h (R_MN10300_ALIGN): Define.

* reloc.c (BFD_RELOC_MN10300_ALIGN): Add.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* elf-m10300.h: Handle R_MN10300_ALIGN relocs.
* mn10300_elf_relax_delete_bytes): Honour R_MN10300_ALIGN relocs.
  Re-fix off by one error in comparisons.
* config/tc-mn10300.c (tc_gen_reloc): Fix test that decides when
  sym_diff relocs should be generated.
  (md_apply_fix): Skip R_MN10300_ALIGN relocs.
  (mn10300_fix_adjustable): Do not adjust R_MN10300_ALIGN relocs.
  (mn10300_handle_align): New function.  Generate R_MN10300_ALIGN
  relocs to record alignment requests.
* config/tc-mn10300.h (TC_FORCE_RELOCATION_SUB_SAME): Also force
  R_MN10300_ALIGN relocs.
  (HANDLE_ALIGN): Define.  Call mn10300_handle_align.
* gas/all/gas.exp: Do not run diff1.s test for mn10300.
* ld-mn10300/mn10300.exp: Run new tests.  Skip i126256 test if
  a compiler is not available.
* ld-mn10300/i112045-3.s: New test.
* ld-mn10300/i112045-3.d: Expected disassembly.
* ld-mn10300/i135409.s: Rename to i135409-1.s.
* ld-mn10300/i135409.d: Rename to i135409-1.d
* ld-mn10300/i135409-2.s: New test.
* ld-mn10300/i135409-2.d: Expected symbol table.
* ld-mn10300/i36434.d: Adjust expected disassembly.
This commit is contained in:
Nick Clifton 2007-10-30 15:18:29 +00:00
parent 4e188d170a
commit 569006e582
21 changed files with 298 additions and 64 deletions

View File

@ -1,3 +1,12 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
* reloc.c (BFD_RELOC_MN10300_ALIGN): Add.
* bfd-in2.h: Regenerate.
* libbfd.h: Regnerate.
* elf-m10300.h: Handle R_MN10300_ALIGN relocs.
(mn10300_elf_relax_delete_bytes): Honour R_MN10300_ALIGN relocs.
Re-fix off by one error in comparisons.
2007-10-25 Pedro Alves <pedro_alves@portugalmail.pt>
* bfd-in.h (STRING_COMMA_LEN): Don't handle NULL STR case.

View File

@ -2778,6 +2778,11 @@ allows for a value that is the difference of two symbols
in the same section. */
BFD_RELOC_MN10300_SYM_DIFF,
/* The addend of this reloc is an alignment power that must
be honoured at the offset's location, regardless of linker
relaxation. */
BFD_RELOC_MN10300_ALIGN,
/* i386/elf relocations */
BFD_RELOC_386_GOT32,

View File

@ -469,6 +469,20 @@ static reloc_howto_type elf_mn10300_howto_table[] =
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_MN10300_ALIGN, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
NULL, /* special handler. */
"R_MN10300_ALIGN", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE) /* pcrel_offset */
};
@ -504,7 +518,8 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] =
{ BFD_RELOC_MN10300_GLOB_DAT, R_MN10300_GLOB_DAT },
{ BFD_RELOC_MN10300_JMP_SLOT, R_MN10300_JMP_SLOT },
{ BFD_RELOC_MN10300_RELATIVE, R_MN10300_RELATIVE },
{ BFD_RELOC_MN10300_SYM_DIFF, R_MN10300_SYM_DIFF }
{ BFD_RELOC_MN10300_SYM_DIFF, R_MN10300_SYM_DIFF },
{ BFD_RELOC_MN10300_ALIGN, R_MN10300_ALIGN }
};
/* Create the GOT section. */
@ -1045,6 +1060,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
sym_diff_value = value;
return bfd_reloc_ok;
case R_MN10300_ALIGN:
case R_MN10300_NONE:
return bfd_reloc_ok;
@ -1825,19 +1841,54 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
contents = elf_section_data (sec)->this_hdr.contents;
/* The deletion must stop at the next ALIGN reloc for an aligment
power larger than the number of bytes we are deleting. */
irelalign = NULL;
toaddr = sec->size;
irel = elf_section_data (sec)->relocs;
irelend = irel + sec->reloc_count;
/* If there is an align reloc at the end of the section ignore it.
GAS creates these relocs for reasons of its own, and they just
serve to keep the section artifically inflated. */
if (ELF32_R_TYPE ((irelend - 1)->r_info) == (int) R_MN10300_ALIGN)
--irelend;
/* The deletion must stop at the next ALIGN reloc for an aligment
power larger than 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;
}
/* Actually delete the bytes. */
memmove (contents + addr, contents + addr + count,
(size_t) (toaddr - addr - count));
sec->size -= count;
/* Adjust the section's size if we are shrinking it, or else
pad the bytes between the end of the shrunken region and
the start of the next region with NOP codes. */
if (irelalign == NULL)
{
sec->size -= count;
/* Include symbols at the end of the section, but
not at the end of a sub-region of the section. */
toaddr ++;
}
else
{
int i;
#define NOP_OPCODE 0xcb
for (i = 0; i < count; i ++)
bfd_put_8 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i);
}
/* Adjust all the relocs. */
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
@ -1855,13 +1906,13 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
{
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value <= toaddr)
&& isym->st_value < toaddr)
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
&& isym->st_value + isym->st_size > addr
&& isym->st_value + isym->st_size <= toaddr)
&& isym->st_value + isym->st_size < toaddr)
isym->st_size -= count;
}
@ -1878,14 +1929,14 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
|| sym_hash->root.type == bfd_link_hash_defweak)
&& 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 < toaddr)
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
&& sym_hash->type == STT_FUNC
&& sym_hash->root.u.def.value + sym_hash->size > addr
&& sym_hash->root.u.def.value + sym_hash->size <= toaddr)
&& sym_hash->root.u.def.value + sym_hash->size < toaddr)
sym_hash->size -= count;
}

View File

@ -1047,6 +1047,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MN10300_JMP_SLOT",
"BFD_RELOC_MN10300_RELATIVE",
"BFD_RELOC_MN10300_SYM_DIFF",
"BFD_RELOC_MN10300_ALIGN",
"BFD_RELOC_386_GOT32",
"BFD_RELOC_386_PLT32",

View File

@ -2367,6 +2367,12 @@ ENUMDOC
Together with another reloc targeted at the same location,
allows for a value that is the difference of two symbols
in the same section.
ENUM
BFD_RELOC_MN10300_ALIGN
ENUMDOC
The addend of this reloc is an alignment power that must
be honoured at the offset's location, regardless of linker
relaxation.
COMMENT
ENUM

View File

@ -1,3 +1,15 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
* config/tc-mn10300.c (tc_gen_reloc): Fix test that decides when
sym_diff relocs should be generated.
(md_apply_fix): Skip R_MN10300_ALIGN relocs.
(mn10300_fix_adjustable): Do not adjust R_MN10300_ALIGN relocs.
(mn10300_handle_align): New function. Generate R_MN10300_ALIGN
relocs to record alignment requests.
* config/tc-mn10300.h (TC_FORCE_RELOCATION_SUB_SAME): Also force
R_MN10300_ALIGN relocs.
(HANDLE_ALIGN): Define. Call mn10300_handle_align.
2007-10-30 Nick Clifton <nickc@redhat.com>
* doc/as.texinfo (Section): Replace "subsegment" with

View File

@ -2181,13 +2181,18 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
if (fixp->fx_addsy && fixp->fx_subsy)
{
asection *asec, *ssec;
asec = S_GET_SEGMENT (fixp->fx_addsy);
ssec = S_GET_SEGMENT (fixp->fx_subsy);
reloc->sym_ptr_ptr = NULL;
/* If we have a difference between two (non-absolute) symbols we must
generate two relocs (one for each symbol) and allow the linker to
resolve them - relaxation may change the distances between symbols,
even local symbols defined in the same segment. */
if (S_GET_SEGMENT (fixp->fx_subsy) == seg)
even local symbols defined in the same section. */
if (ssec != absolute_section || asec != absolute_section)
{
arelent * reloc2 = xmalloc (sizeof * reloc);
@ -2201,7 +2206,7 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
*reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
reloc->addend = fixp->fx_offset;
if (S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
if (asec == absolute_section)
reloc->addend += S_GET_VALUE (fixp->fx_addsy);
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
@ -2211,13 +2216,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
fixp->fx_done = 1;
return relocs;
}
if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
|| S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
"Difference of symbols in different sections is not supported");
}
else
{
char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
@ -2248,12 +2246,12 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
= (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
return relocs;
}
}
if (reloc->sym_ptr_ptr)
free (reloc->sym_ptr_ptr);
free (reloc);
return & no_relocs;
if (reloc->sym_ptr_ptr)
free (reloc->sym_ptr_ptr);
free (reloc);
return & no_relocs;
}
}
else
{
@ -2357,6 +2355,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
fixP->fx_done = 0;
return;
case BFD_RELOC_MN10300_ALIGN:
fixP->fx_done = 1;
return;
case BFD_RELOC_NONE:
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
@ -2562,3 +2564,29 @@ mn10300_allow_local_subtract (expressionS * left, expressionS * right, segT sect
return result;
}
/* When relaxing, we need to output a reloc for any .align directive
that requests alignment to a two byte boundary or larger. */
void
mn10300_handle_align (fragS *frag)
{
if (! linkrelax)
return;
if ((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
/* Do not create relocs for the merging sections - such
relocs will prevent the contents from being merged. */
&& (bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) == 0)
/* Create a new fixup to record the alignment request. The symbol is
irrelevent but must be present so we use the absolute section symbol.
The offset from the symbol is used to record the power-of-two alignment
value. The size is set to 0 because the frag may already be aligned,
thus causing cvt_frag_to_fill to reduce the size of the frag to zero. */
fix_new (frag, frag->fr_fix, 0, & abs_symbol, frag->fr_offset, FALSE,
BFD_RELOC_MN10300_ALIGN);
}

View File

@ -66,6 +66,7 @@ void mn10300_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
(((SEC)->flags & SEC_CODE) != 0 \
|| ! SEG_NORMAL (SEC) \
|| (FIX)->fx_r_type == BFD_RELOC_MN10300_ALIGN \
|| TC_FORCE_RELOCATION (FIX))
/* We validate subtract arguments within tc_gen_reloc(), so don't
@ -116,3 +117,6 @@ extern bfd_boolean mn10300_allow_local_subtract (expressionS *, expressionS *, s
#define MAX_RELOC_EXPANSION 2
#define TC_FRAG_TYPE bfd_boolean
#define HANDLE_ALIGN(frag) mn10300_handle_align (frag)
extern void mn10300_handle_align (fragS *);

View File

@ -1,3 +1,7 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
* gas/all/gas.exp: Do not run diff1.s test for mn10300.
2007-10-27 H.J. Lu <hongjiu.lu@intel.com>
PR gas/5221

View File

@ -34,7 +34,12 @@ if { ![istarget cris-*-*] && ![istarget crisv32-*-*]
# This test is meaningless for the PA; the difference of two undefined
# symbols is something that is (and must be) supported on the PA.
if ![istarget hppa*-*-*] then {
#
# The MN10300 port supports link time relaxation which in turn allows
# for link time resolution of the differneces of two symbols which are
# undefined at assembly time. Hence this test will not pass for the
# MN10300.
if { ![istarget hppa*-*-*] && ![istarget mn10300-*-*] && ![istarget am3*-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}

View File

@ -1,3 +1,7 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
* mn10300.h (R_MN10300_ALIGN): Define.
2007-10-25 Daniel Jacobowitz <dan@codesourcery.com>
* ppc.h (Tag_GNU_Power_ABI_Vector): New.

View File

@ -1,23 +1,24 @@
/* MN10300 ELF support for BFD.
Copyright 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
Copyright 1998, 1999, 2000, 2003, 2007 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* This file holds definitions specific to the MN10300 ELF ABI. */
/* This file holds definitions specific to the MN10300 ELF ABI. */
#ifndef _ELF_MN10300_H
#define _ELF_MN10300_H
@ -51,17 +52,18 @@ START_RELOC_NUMBERS (elf_mn10300_reloc_type)
RELOC_NUMBER (R_MN10300_JMP_SLOT, 22)
RELOC_NUMBER (R_MN10300_RELATIVE, 23)
RELOC_NUMBER (R_MN10300_SYM_DIFF, 33)
RELOC_NUMBER (R_MN10300_ALIGN, 34)
END_RELOC_NUMBERS (R_MN10300_MAX)
/* Machine variant if we know it. This field was invented at Cygnus,
but it is hoped that other vendors will adopt it. If some standard
is developed, this code should be changed to follow it. */
is developed, this code should be changed to follow it. */
#define EF_MN10300_MACH 0x00FF0000
/* Cygnus is choosing values between 80 and 9F;
00 - 7F should be left for a future standard;
the rest are open. */
the rest are open. */
#define E_MN10300_MACH_MN10300 0x00810000
#define E_MN10300_MACH_AM33 0x00820000

View File

@ -1,3 +1,15 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
* ld-mn10300/mn10300.exp: Run new tests. Skip i126256 test if
a compiler is not available.
* ld-mn10300/i112045-3.s: New test.
* ld-mn10300/i112045-3.d: Expected disassembly.
* ld-mn10300/i135409.s: Rename to i135409-1.s.
* ld-mn10300/i135409.d: Rename to i135409-1.d
* ld-mn10300/i135409-2.s: New test.
* ld-mn10300/i135409-2.d: Expected symbol table.
* ld-mn10300/i36434.d: Adjust expected disassembly.
2007-10-26 Alan Modra <amodra@bigpond.net.au>
* ld-scripts/rgn-over1.d: Accept extra LOAD at end of map file.

View File

@ -0,0 +1,17 @@
tmpdir/i112045-3.x: file format elf32-.*
Disassembly of section .text:
0+0100 <L001>:
100:[ ]+24 00 01[ ]+mov[ ]+256,a0
0+0103 <L002>:
103:[ ]+24 00 01[ ]+mov[ ]+256,a0
Disassembly of section .rodata:
0+0106 <L004>:
106:[ ]+06 00 00[ ]+movbu[ ]+d1,\(0 <L001-0x100>\)
109:[ ]+00[ ]+clr[ ]+d0
10a:[ ]+03 00 00[ ]+movhu[ ]+d0,\(0 <L001-0x100>\)
[ ]+...

View File

@ -0,0 +1,11 @@
.text
L001:
mov L001,A0
L002:
mov L001,A0
L003:
.section .rodata
L004:
.long L003-L001
.long L003-L002

View File

@ -0,0 +1,11 @@
Symbol table '.symtab' contains .. entries:
Num: Value Size Type Bind Vis Ndx Name
#...
..: 0[0-9a-f]+02[ ]+0 NOTYPE LOCAL DEFAULT . _A
..: 0[0-9a-f]+08[ ]+0 NOTYPE LOCAL DEFAULT . _B
..: 0[0-9a-f]+08[ ]+0 NOTYPE LOCAL DEFAULT . _C
..: 0[0-9a-f]+10[ ]+7 FUNC LOCAL DEFAULT . _func
..: 0[0-9a-f]+14[ ]+0 NOTYPE LOCAL DEFAULT . _D
..: 0[0-9a-f]+17[ ]+0 NOTYPE LOCAL DEFAULT . BOTTOM
#pass

View File

@ -0,0 +1,23 @@
.text
.global _start
_start:
add A0, A1
_A:
mov L001, A0
_B:
.balign 0x8
_C:
nop
.balign 0x10
.type _func, @function
_func:
mov L001, A1
nop
_D:
mov L001, A1
BOTTOM:
.size _func, . - _func
.data
L001:

View File

@ -3,14 +3,14 @@ tmpdir/i36434.x: file format elf32-.*
Disassembly of section .text:
08000000 <_start>:
8000000: fc cd 18 80 mov 134250520,d1
8000004: 00 08
8000006: cb nop
08000074 <_start>:
8000074: fc cd 8c 80 mov 134250636,d1
8000078: 00 08
800007a: cb nop
08000007 <_bar>:
8000007: fc cc 14 00 mov 134217748,d0
800000b: 00 08
800000d: fc cd 15 80 mov 134250517,d1
8000011: 00 08
8000013: cb nop
0800007b <_bar>:
800007b: fc cc 88 00 mov 134217864,d0
800007f: 00 08
8000081: fc cd 89 80 mov 134250633,d1
8000085: 00 08
8000087: cb nop

View File

@ -22,17 +22,17 @@ if {!([istarget "am3*-*-*"]) && !([istarget "mn10300*-*-*"]) } {
# Set up a list as described in ld-lib.exp
set am33_tests {
set mn10300_tests {
{
"am33 string merging"
"--relax -Ttext 0x8000000"
"-relax -Ttext 0x8000074"
""
{ "i36434.s" "i36434-2.s" }
{ {objdump -dz i36434.d} }
"i36434.x"
}
{
"difference of two symbols"
"difference of two same-section symbols"
"-Ttext 0"
""
{ "i112045-1.s" }
@ -40,21 +40,46 @@ set am33_tests {
"i112045-1.x"
}
{
"(shared) difference of two symbols"
"difference of two same-section symbols where the difference is held in another section"
"-relax -Ttext 100"
""
{ "i112045-3.s" }
{ {objdump -D i112045-3.d} }
"i112045-3.x"
}
{
"adjustment of symbols due to relaxation"
"-Tdata 1f -Ttext 0 -relax"
""
{ "i135409-1.s" }
{ {readelf --syms i135409-1.d} }
"i135409-1.x"
}
{
"adjustment of symbols due to relaxation (with alignment directives)"
"-Tdata 1f -Ttext 0 -relax"
""
{ "i135409-2.s" }
{ {readelf --syms i135409-2.d} }
"i135409-2.x"
}
}
run_ld_link_tests $mn10300_tests
if {!([istarget "am3*-*-*"])} {
return
}
set am33_tests {
{
"difference of two same-section symbols (in a shared library)"
"-shared"
""
{ "i112045-2.s" }
{ {objdump -R i112045-2.d} }
"i112045-2.x"
}
{
"adjustment of symbols due to relaxation"
"-Tdata 1f -relax"
""
{ "i135409.s" }
{ {readelf --syms i135409.d } }
"i135409.x"
}
}
run_ld_link_tests $am33_tests
@ -66,7 +91,11 @@ proc i126256-test { } {
global subdir
set tmpdir tmpdir
set testname "Issue 126256 - seg fault whilst linking one shared library into another when relaxation is enabled."
set testname "Seg fault whilst linking one shared library into another when relaxation is enabled."
if {![is_remote host] && [which $CC] == 0} then {
return
}
if { ![ld_compile "$CC -mrelax -fPIC" $srcdir/$subdir/i126256-1.c $tmpdir/i126256-1.o] } {
unresolved $testname