summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-10-30 15:18:29 +0000
committerNick Clifton <nickc@redhat.com>2007-10-30 15:18:29 +0000
commitf1ae87fd2fad5716c2c86b614cbf01935394687d (patch)
tree48847e2e7cde512b08c44524c450a2b4b6bf8d29
parent97bc3322ef0cdc4cc23d5c02b24c60c8e2c98dc5 (diff)
downloadgdb-f1ae87fd2fad5716c2c86b614cbf01935394687d.tar.gz
* 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.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/bfd-in2.h5
-rw-r--r--bfd/elf-m10300.c69
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c6
-rw-r--r--include/elf/ChangeLog4
-rw-r--r--include/elf/mn10300.h34
7 files changed, 103 insertions, 25 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d9d53304c8d..5484c4bdd37 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 5e548674e1f..842a536b03e 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
index 6c688bdcdd2..db8114e53db 100644
--- a/bfd/elf-m10300.c
+++ b/bfd/elf-m10300.c
@@ -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;
}
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 18d01caca70..4d83a4cbdd7 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index aa218754bc7..f413ced7172 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -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
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index a9a1e12fba8..57bcd3b63d8 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -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.
diff --git a/include/elf/mn10300.h b/include/elf/mn10300.h
index 74de473bdcf..444787b5f95 100644
--- a/include/elf/mn10300.h
+++ b/include/elf/mn10300.h
@@ -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