* 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.
+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.
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,
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 */
};
{ 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. */
sym_diff_value = value;
return bfd_reloc_ok;
+ case R_MN10300_ALIGN:
case R_MN10300_NONE:
return bfd_reloc_ok;
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++)
{
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;
}
|| 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;
}
"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",
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
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
"subsection".
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);
*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 *));
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;
= (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
{
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,
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);
+}
#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
#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 *);
+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
# 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"
}
+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.
/* 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
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
+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.
--- /dev/null
+
+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>\)
+[ ]+...
--- /dev/null
+ .text
+L001:
+ mov L001,A0
+L002:
+ mov L001,A0
+L003:
+
+ .section .rodata
+L004:
+ .long L003-L001
+ .long L003-L002
--- /dev/null
+
+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
--- /dev/null
+ .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:
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
# 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" }
"i112045-1.x"
}
{
- "(shared) difference of two symbols"
- "-shared"
+ "difference of two same-section symbols where the difference is held in another section"
+ "-relax -Ttext 100"
""
- { "i112045-2.s" }
- { {objdump -R i112045-2.d} }
- "i112045-2.x"
+ { "i112045-3.s" }
+ { {objdump -D i112045-3.d} }
+ "i112045-3.x"
}
{
"adjustment of symbols due to relaxation"
- "-Tdata 1f -relax"
+ "-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"
""
- { "i135409.s" }
- { {readelf --syms i135409.d } }
- "i135409.x"
+ { "i112045-2.s" }
+ { {objdump -R i112045-2.d} }
+ "i112045-2.x"
}
}
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