Browse Source
* metag.h: New file. * dis-asm.h (print_insn_metag): New declaration. * metag.h: New file. * Makefile.am: Add Meta. * Makefile.in: Regenerate. * configure: Regenerate. * configure.in: Add Meta. * disassemble.c: Add Meta support. * metag-dis.c: New file. * Makefile.am: Add Meta. * Makefile.in: Regenerate. * archures.c (bfd_mach_metag): New. * bfd-in2.h: Regenerate. * config.bfd: Add Meta. * configure: Regenerate. * configure.in: Add Meta. * cpu-metag.c: New file. * elf-bfd.h: Add Meta. * elf32-metag.c: New file. * elf32-metag.h: New file. * libbfd.h: Regenerate. * reloc.c: Add Meta relocations. * targets.c: Add Meta. * Makefile.am: Add Meta. * Makefile.in: Regenerate. * config/tc-metag.c: New file. * config/tc-metag.h: New file. * configure.tgt: Add Meta. * doc/Makefile.am: Add Meta. * doc/Makefile.in: Regenerate. * doc/all.texi: Add Meta. * doc/as.texiinfo: Document Meta options. * doc/c-metag.texi: New file. * gas/metag/labelarithmetic.d: New file. * gas/metag/labelarithmetic.s: New file. * gas/metag/metacore12.d: New file. * gas/metag/metacore12.s: New file. * gas/metag/metacore21-invalid.l: New file. * gas/metag/metacore21-invalid.s: New file. * gas/metag/metacore21.d: New file. * gas/metag/metacore21.s: New file. * gas/metag/metacore21ext.d: New file. * gas/metag/metacore21ext.s: New file. * gas/metag/metadsp21-invalid.l: New file. * gas/metag/metadsp21-invalid.s: New file. * gas/metag/metadsp21.d: New file. * gas/metag/metadsp21.s: New file. * gas/metag/metadsp21ext.d: New file. * gas/metag/metadsp21ext.s: New file. * gas/metag/metafpu21.d: New file. * gas/metag/metafpu21.s: New file. * gas/metag/metafpu21ext.d: New file. * gas/metag/metafpu21ext.s: New file. * gas/metag/metag.exp: New file. * gas/metag/tls.d: New file. * gas/metag/tls.s: New file. * Makefile.am: Add Meta. * Makefile.in: Regenerate. * configure.tgt: Add Meta. * emulparams/elf32metag.sh: New file. * emultempl/metagelf.em: New file. * ld-elf/merge.d: Mark Meta as xfail. * ld-gc/start.d: Skip this test on Meta. * ld-gc/personality.d: Skip this test on Meta. * ld-metag/external.s: New file. * ld-metag/metag.exp: New file. * ld-metag/pcrel.d: New file. * ld-metag/pcrel.s: New file. * ld-metag/shared.d: New file. * ld-metag/shared.r: New file. * ld-metag/shared.s: New file. * ld-metag/stub.d: New file. * ld-metag/stub.s: New file. * ld-metag/stub_pic_app.d: New file. * ld-metag/stub_pic_app.r: New file. * ld-metag/stub_pic_app.s: New file. * ld-metag/stub_pic_shared.d: New file. * ld-metag/stub_pic_shared.s: New file. * ld-metag/stub_shared.d: New file. * ld-metag/stub_shared.r: New file. * ld-metag/stub_shared.s: New file. * binutils/readelf.c: (guess_is_rela): Add EM_METAG. (dump_relocations): Add EM_METAG. (get_machine_name): Correct case for Meta. (is_32bit_abs_reloc): Add support for Meta ADDR32 reloc. (is_none_reloc): Add support for Meta NONE reloc.gdb_7_6-branch
55 changed files with 17988 additions and 5 deletions
@ -0,0 +1,41 @@ |
|||
/* BFD support for the Imagination Technologies Meta processor.
|
|||
Copyright (C) 2013 Free Software Foundation, Inc. |
|||
Contributed by Imagination Technologies Ltd. |
|||
|
|||
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 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. |
|||
|
|||
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. */ |
|||
|
|||
#include "sysdep.h" |
|||
#include "bfd.h" |
|||
#include "libbfd.h" |
|||
|
|||
const bfd_arch_info_type bfd_metag_arch = |
|||
{ |
|||
32, /* Bits per word. */ |
|||
32, /* Bits per address. */ |
|||
8, /* Bits per byte. */ |
|||
bfd_arch_metag, /* Architecture. */ |
|||
bfd_mach_metag, /* Machine. */ |
|||
"metag", /* Architecture name. */ |
|||
"metag", /* Printable name. */ |
|||
4, /* Section align power. */ |
|||
TRUE, /* The default ? */ |
|||
bfd_default_compatible, /* Architecture comparison fn. */ |
|||
bfd_default_scan, /* String to architecture convert fn. */ |
|||
bfd_arch_default_fill, /* Default fill. */ |
|||
NULL /* Next in list. */ |
|||
}; |
|||
File diff suppressed because it is too large
@ -0,0 +1,38 @@ |
|||
/* Meta support for 32-bit ELF
|
|||
Copyright (C) 2013 Free Software Foundation, Inc. |
|||
Contributed by Imagination Technologies Ltd. |
|||
|
|||
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 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. |
|||
|
|||
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. */ |
|||
|
|||
#ifndef _ELF32_METAG_H |
|||
#define _ELF32_METAG_H |
|||
|
|||
extern int elf_metag_setup_section_lists |
|||
(bfd *, struct bfd_link_info *); |
|||
|
|||
extern void elf_metag_next_input_section |
|||
(struct bfd_link_info *, asection *); |
|||
|
|||
extern bfd_boolean elf_metag_size_stubs |
|||
(bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma, |
|||
asection * (*) (const char *, asection *), void (*) (void)); |
|||
|
|||
extern bfd_boolean elf_metag_build_stubs |
|||
(struct bfd_link_info *); |
|||
|
|||
#endif /* _ELF32_METAG_H */ |
|||
File diff suppressed because it is too large
@ -0,0 +1,72 @@ |
|||
/* tc-metag.h -- Header file for tc-metag.c.
|
|||
Copyright (C) 2013 Free Software Foundation, Inc. |
|||
Contributed by Imagination Technologies Ltd. |
|||
|
|||
This file is part of GAS, the GNU Assembler. |
|||
|
|||
GAS 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, or (at your option) |
|||
any later version. |
|||
|
|||
GAS 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 GAS; see the file COPYING. If not, write to the Free |
|||
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
|||
02110-1301, USA. */ |
|||
|
|||
#define TC_METAG |
|||
|
|||
#define LISTING_HEADER "META GAS " |
|||
|
|||
/* The target BFD architecture. */ |
|||
#define TARGET_ARCH bfd_arch_metag |
|||
|
|||
#define TARGET_FORMAT "elf32-metag" |
|||
|
|||
#define TARGET_BYTES_BIG_ENDIAN 0 |
|||
|
|||
/* Permit temporary numeric labels. */ |
|||
#define LOCAL_LABELS_FB 1 |
|||
|
|||
#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */ |
|||
|
|||
/* We don't need to handle .word strangely. */ |
|||
#define WORKING_DOT_WORD |
|||
|
|||
/* Values passed to md_apply_fix don't include the symbol value. */ |
|||
#define MD_APPLY_SYM_VALUE(FIX) 0 |
|||
|
|||
#define tc_fix_adjustable(FIX) metag_fix_adjustable (FIX) |
|||
extern bfd_boolean metag_fix_adjustable (struct fix *); |
|||
|
|||
#define TC_FORCE_RELOCATION(fix) metag_force_relocation (fix) |
|||
extern int metag_force_relocation (struct fix *); |
|||
|
|||
#define TC_HANDLES_FX_DONE |
|||
|
|||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */ |
|||
#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) |
|||
extern long md_pcrel_from_section (struct fix *, segT); |
|||
|
|||
#define HANDLE_ALIGN(fragp) metag_handle_align (fragp) |
|||
extern void metag_handle_align (struct frag *); |
|||
|
|||
#define DWARF2_LINE_MIN_INSN_LENGTH 1 |
|||
|
|||
#define md_parse_name(name, exprP, mode, nextcharP) \ |
|||
metag_parse_name ((name), (exprP), (mode), (nextcharP)) |
|||
extern int metag_parse_name (char const *, expressionS *, enum expr_mode, char *); |
|||
|
|||
/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
|
|||
symbols. The relocation type is stored in X_md. */ |
|||
#define O_PIC_reloc O_md1 |
|||
|
|||
#define TC_CASE_SENSITIVE |
|||
|
|||
extern const char metag_symbol_chars[]; |
|||
#define tc_symbol_chars metag_symbol_chars |
|||
@ -0,0 +1,82 @@ |
|||
@c Copyright 2013 Free Software Foundation, Inc. |
|||
@c Contributed by Imagination Technologies Ltd. |
|||
@c This is part of the GAS manual. |
|||
@c For copying conditions, see the file as.texinfo. |
|||
@ifset GENERIC |
|||
@page |
|||
@node Meta-Dependent |
|||
@chapter Meta Dependent Features |
|||
@end ifset |
|||
@ifclear GENERIC |
|||
@node Machine Dependencies |
|||
@chapter Meta Dependent Features |
|||
@end ifclear |
|||
|
|||
@cindex Meta support |
|||
@menu |
|||
* Meta Options:: Options |
|||
* Meta Syntax:: Meta Assembler Syntax |
|||
@end menu |
|||
|
|||
@node Meta Options |
|||
@section Options |
|||
|
|||
@cindex options for Meta |
|||
@cindex Meta options |
|||
@cindex architectures, Meta |
|||
@cindex Meta architectures |
|||
|
|||
The Imagination Technologies Meta architecture is implemented in a |
|||
number of versions, with each new version adding new features such as |
|||
instructions and registers. For precise details of what instructions |
|||
each core supports, please see the chip's technical reference manual. |
|||
|
|||
The following table lists all available Meta options. |
|||
|
|||
@table @code |
|||
@item -mcpu=metac11 |
|||
Generate code for Meta 1.1. |
|||
|
|||
@item -mcpu=metac12 |
|||
Generate code for Meta 1.2. |
|||
|
|||
@item -mcpu=metac21 |
|||
Generate code for Meta 2.1. |
|||
|
|||
@item -mfpu=metac21 |
|||
Allow code to use FPU hardware of Meta 2.1. |
|||
|
|||
@end table |
|||
|
|||
@node Meta Syntax |
|||
@section Syntax |
|||
|
|||
@menu |
|||
* Meta-Chars:: Special Characters |
|||
* Meta-Regs:: Register Names |
|||
@end menu |
|||
|
|||
@node Meta-Chars |
|||
@subsection Special Characters |
|||
|
|||
@cindex line comment character, Meta |
|||
@cindex Meta line comment character |
|||
@samp{!} is the line comment character. |
|||
|
|||
@cindex line separator, Meta |
|||
@cindex statement separator, Meta |
|||
@cindex Meta line separator |
|||
You can use @samp{;} instead of a newline to separate statements. |
|||
|
|||
@cindex symbol names, @samp{$} in |
|||
@cindex @code{$} in symbol names |
|||
Since @samp{$} has no special meaning, you may use it in symbol names. |
|||
|
|||
@node Meta-Regs |
|||
@subsection Register Names |
|||
|
|||
@cindex Meta registers |
|||
@cindex registers, Meta |
|||
Registers can be specified either using their mnemonic names, such as |
|||
@samp{D0Re0}, or using the unit plus register number separated by a @samp{.}, |
|||
such as @samp{D0.0}. |
|||
@ -0,0 +1,91 @@ |
|||
/* Meta ELF support for BFD.
|
|||
Copyright (C) 2013 Free Software Foundation, Inc. |
|||
Contributed by Imagination Technologies Ltd. |
|||
|
|||
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 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. |
|||
|
|||
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. */ |
|||
|
|||
#ifndef _ELF_METAG_H |
|||
#define _ELF_METAG_H |
|||
|
|||
#include "elf/reloc-macros.h" |
|||
|
|||
/* Relocation types. */ |
|||
|
|||
START_RELOC_NUMBERS (elf_metag_reloc_type) |
|||
RELOC_NUMBER (R_METAG_HIADDR16, 0) |
|||
RELOC_NUMBER (R_METAG_LOADDR16, 1) |
|||
RELOC_NUMBER (R_METAG_ADDR32, 2) |
|||
RELOC_NUMBER (R_METAG_NONE, 3) |
|||
RELOC_NUMBER (R_METAG_RELBRANCH, 4) |
|||
RELOC_NUMBER (R_METAG_GETSETOFF, 5) |
|||
|
|||
/* Backward compatability */ |
|||
RELOC_NUMBER (R_METAG_REG32OP1, 6) |
|||
RELOC_NUMBER (R_METAG_REG32OP2, 7) |
|||
RELOC_NUMBER (R_METAG_REG32OP3, 8) |
|||
RELOC_NUMBER (R_METAG_REG16OP1, 9) |
|||
RELOC_NUMBER (R_METAG_REG16OP2, 10) |
|||
RELOC_NUMBER (R_METAG_REG16OP3, 11) |
|||
RELOC_NUMBER (R_METAG_REG32OP4, 12) |
|||
|
|||
RELOC_NUMBER (R_METAG_HIOG, 13) |
|||
RELOC_NUMBER (R_METAG_LOOG, 14) |
|||
|
|||
RELOC_NUMBER (R_METAG_REL8, 15) |
|||
RELOC_NUMBER (R_METAG_REL16, 16) |
|||
|
|||
/* GNU */ |
|||
RELOC_NUMBER (R_METAG_GNU_VTINHERIT,30) |
|||
RELOC_NUMBER (R_METAG_GNU_VTENTRY, 31) |
|||
|
|||
/* PIC relocations */ |
|||
RELOC_NUMBER (R_METAG_HI16_GOTOFF, 32) |
|||
RELOC_NUMBER (R_METAG_LO16_GOTOFF, 33) |
|||
RELOC_NUMBER (R_METAG_GETSET_GOTOFF,34) |
|||
RELOC_NUMBER (R_METAG_GETSET_GOT, 35) |
|||
RELOC_NUMBER (R_METAG_HI16_GOTPC, 36) |
|||
RELOC_NUMBER (R_METAG_LO16_GOTPC, 37) |
|||
RELOC_NUMBER (R_METAG_HI16_PLT, 38) |
|||
RELOC_NUMBER (R_METAG_LO16_PLT, 39) |
|||
RELOC_NUMBER (R_METAG_RELBRANCH_PLT,40) |
|||
RELOC_NUMBER (R_METAG_GOTOFF, 41) |
|||
RELOC_NUMBER (R_METAG_PLT, 42) |
|||
RELOC_NUMBER (R_METAG_COPY, 43) |
|||
RELOC_NUMBER (R_METAG_JMP_SLOT, 44) |
|||
RELOC_NUMBER (R_METAG_RELATIVE, 45) |
|||
RELOC_NUMBER (R_METAG_GLOB_DAT, 46) |
|||
|
|||
/* TLS relocations */ |
|||
RELOC_NUMBER (R_METAG_TLS_GD, 47) |
|||
RELOC_NUMBER (R_METAG_TLS_LDM, 48) |
|||
RELOC_NUMBER (R_METAG_TLS_LDO_HI16, 49) |
|||
RELOC_NUMBER (R_METAG_TLS_LDO_LO16, 50) |
|||
RELOC_NUMBER (R_METAG_TLS_LDO, 51) |
|||
RELOC_NUMBER (R_METAG_TLS_IE, 52) |
|||
RELOC_NUMBER (R_METAG_TLS_IENONPIC, 53) |
|||
RELOC_NUMBER (R_METAG_TLS_IENONPIC_HI16,54) |
|||
RELOC_NUMBER (R_METAG_TLS_IENONPIC_LO16,55) |
|||
RELOC_NUMBER (R_METAG_TLS_TPOFF, 56) |
|||
RELOC_NUMBER (R_METAG_TLS_DTPMOD, 57) |
|||
RELOC_NUMBER (R_METAG_TLS_DTPOFF, 58) |
|||
RELOC_NUMBER (R_METAG_TLS_LE, 59) |
|||
RELOC_NUMBER (R_METAG_TLS_LE_HI16, 60) |
|||
RELOC_NUMBER (R_METAG_TLS_LE_LO16, 61) |
|||
|
|||
END_RELOC_NUMBERS (R_METAG_MAX) |
|||
|
|||
#endif /* _ELF_METAG_H */ |
|||
File diff suppressed because it is too large
@ -0,0 +1,30 @@ |
|||
MACHINE= |
|||
SCRIPT_NAME=elf |
|||
TEMPLATE_NAME=elf32 |
|||
GENERATE_SHLIB_SCRIPT=yes |
|||
GENERATE_PIE_SCRIPT=yes |
|||
OUTPUT_FORMAT="elf32-metag" |
|||
TEXT_START_ADDR=0x10005000 |
|||
ARCH=metag |
|||
MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" |
|||
ENTRY=__start |
|||
NOP=0xa0fffffe |
|||
EXTRA_EM_FILE=metagelf |
|||
USER_LABEL_PREFIX=_ |
|||
OTHER_SECTIONS=" |
|||
.core_text 0x80000000 : |
|||
{ |
|||
*(.core_text) |
|||
} |
|||
.core_data 0x82000000 : |
|||
{ |
|||
*(.core_data) |
|||
*(.core_rodata) |
|||
} |
|||
.internal_memory 0xe0200000 : |
|||
{ |
|||
*(.internal_text) |
|||
*(.internal_data) |
|||
*(.internal_rodata) |
|||
} |
|||
" |
|||
@ -0,0 +1,337 @@ |
|||
# This shell script emits a C file. -*- C -*- |
|||
# Copyright 2013 Free Software Foundation, Inc. |
|||
# |
|||
# This file is part of GNU Binutils. |
|||
# |
|||
# 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. |
|||
# |
|||
# 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 is sourced from elf32.em, and defines extra metagelf |
|||
# specific routines. Taken from hppaelf.em. |
|||
# |
|||
fragment <<EOF |
|||
|
|||
#include "ldctor.h" |
|||
#include "elf32-metag.h" |
|||
|
|||
|
|||
/* Fake input file for stubs. */ |
|||
static lang_input_statement_type *stub_file; |
|||
|
|||
/* Whether we need to call metag_layout_sections_again. */ |
|||
static int need_laying_out = 0; |
|||
|
|||
/* Maximum size of a group of input sections that can be handled by |
|||
one stub section. A value of +/-1 indicates the bfd back-end |
|||
should use a suitable default size. */ |
|||
static bfd_signed_vma group_size = 1; |
|||
|
|||
/* This is called before the input files are opened. We create a new |
|||
fake input file to hold the stub sections. */ |
|||
|
|||
static void |
|||
metagelf_create_output_section_statements (void) |
|||
{ |
|||
extern const bfd_target bfd_elf32_metag_vec; |
|||
|
|||
if (link_info.output_bfd->xvec != &bfd_elf32_metag_vec) |
|||
return; |
|||
|
|||
stub_file = lang_add_input_file ("linker stubs", |
|||
lang_input_file_is_fake_enum, |
|||
NULL); |
|||
stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd); |
|||
if (stub_file->the_bfd == NULL |
|||
|| ! bfd_set_arch_mach (stub_file->the_bfd, |
|||
bfd_get_arch (link_info.output_bfd), |
|||
bfd_get_mach (link_info.output_bfd))) |
|||
{ |
|||
einfo ("%X%P: can not create BFD %E\n"); |
|||
return; |
|||
} |
|||
|
|||
stub_file->the_bfd->flags |= BFD_LINKER_CREATED; |
|||
ldlang_add_file (stub_file); |
|||
} |
|||
|
|||
|
|||
struct hook_stub_info |
|||
{ |
|||
lang_statement_list_type add; |
|||
asection *input_section; |
|||
}; |
|||
|
|||
/* Traverse the linker tree to find the spot where the stub goes. */ |
|||
|
|||
static bfd_boolean |
|||
hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp) |
|||
{ |
|||
lang_statement_union_type *l; |
|||
bfd_boolean ret; |
|||
|
|||
for (; (l = *lp) != NULL; lp = &l->header.next) |
|||
{ |
|||
switch (l->header.type) |
|||
{ |
|||
case lang_constructors_statement_enum: |
|||
ret = hook_in_stub (info, &constructor_list.head); |
|||
if (ret) |
|||
return ret; |
|||
break; |
|||
|
|||
case lang_output_section_statement_enum: |
|||
ret = hook_in_stub (info, |
|||
&l->output_section_statement.children.head); |
|||
if (ret) |
|||
return ret; |
|||
break; |
|||
|
|||
case lang_wild_statement_enum: |
|||
ret = hook_in_stub (info, &l->wild_statement.children.head); |
|||
if (ret) |
|||
return ret; |
|||
break; |
|||
|
|||
case lang_group_statement_enum: |
|||
ret = hook_in_stub (info, &l->group_statement.children.head); |
|||
if (ret) |
|||
return ret; |
|||
break; |
|||
|
|||
case lang_input_section_enum: |
|||
if (l->input_section.section == info->input_section) |
|||
{ |
|||
/* We've found our section. Insert the stub immediately |
|||
before its associated input section. */ |
|||
*lp = info->add.head; |
|||
*(info->add.tail) = l; |
|||
return TRUE; |
|||
} |
|||
break; |
|||
|
|||
case lang_data_statement_enum: |
|||
case lang_reloc_statement_enum: |
|||
case lang_object_symbols_statement_enum: |
|||
case lang_output_statement_enum: |
|||
case lang_target_statement_enum: |
|||
case lang_input_statement_enum: |
|||
case lang_assignment_statement_enum: |
|||
case lang_padding_statement_enum: |
|||
case lang_address_statement_enum: |
|||
case lang_fill_statement_enum: |
|||
break; |
|||
|
|||
default: |
|||
FAIL (); |
|||
break; |
|||
} |
|||
} |
|||
return FALSE; |
|||
} |
|||
|
|||
|
|||
/* Call-back for elf_metag_size_stubs. */ |
|||
|
|||
/* Create a new stub section, and arrange for it to be linked |
|||
immediately before INPUT_SECTION. */ |
|||
|
|||
static asection * |
|||
metagelf_add_stub_section (const char *stub_sec_name, asection *input_section) |
|||
{ |
|||
asection *stub_sec; |
|||
flagword flags; |
|||
asection *output_section; |
|||
const char *secname; |
|||
lang_output_section_statement_type *os; |
|||
struct hook_stub_info info; |
|||
|
|||
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE |
|||
| SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP); |
|||
stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd, |
|||
stub_sec_name, flags); |
|||
if (stub_sec == NULL) |
|||
goto err_ret; |
|||
|
|||
output_section = input_section->output_section; |
|||
secname = bfd_get_section_name (output_section->owner, output_section); |
|||
os = lang_output_section_find (secname); |
|||
|
|||
info.input_section = input_section; |
|||
lang_list_init (&info.add); |
|||
lang_add_section (&info.add, stub_sec, NULL, os); |
|||
|
|||
if (info.add.head == NULL) |
|||
goto err_ret; |
|||
|
|||
if (hook_in_stub (&info, &os->children.head)) |
|||
return stub_sec; |
|||
|
|||
err_ret: |
|||
einfo ("%X%P: can not make stub section: %E\n"); |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
/* Another call-back for elf_metag_size_stubs. */ |
|||
|
|||
static void |
|||
metagelf_layout_sections_again (void) |
|||
{ |
|||
/* If we have changed sizes of the stub sections, then we need |
|||
to recalculate all the section offsets. This may mean we need to |
|||
add even more stubs. */ |
|||
gld${EMULATION_NAME}_map_segments (TRUE); |
|||
need_laying_out = -1; |
|||
} |
|||
|
|||
|
|||
static void |
|||
build_section_lists (lang_statement_union_type *statement) |
|||
{ |
|||
if (statement->header.type == lang_input_section_enum) |
|||
{ |
|||
asection *i = statement->input_section.section; |
|||
|
|||
if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms |
|||
&& (i->flags & SEC_EXCLUDE) == 0 |
|||
&& i->output_section != NULL |
|||
&& i->output_section->owner == link_info.output_bfd) |
|||
{ |
|||
elf_metag_next_input_section (&link_info, i); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* For Meta we use this opportunity to build linker stubs. */ |
|||
|
|||
static void |
|||
gld${EMULATION_NAME}_after_allocation (void) |
|||
{ |
|||
/* bfd_elf_discard_info just plays with data and debugging sections, |
|||
ie. doesn't affect code size, so we can delay resizing the |
|||
sections. It's likely we'll resize everything in the process of |
|||
adding stubs. */ |
|||
if (bfd_elf_discard_info (link_info.output_bfd, &link_info)) |
|||
need_laying_out = 1; |
|||
|
|||
/* If generating a relocatable output file, then we don't |
|||
have to examine the relocs. */ |
|||
if (stub_file != NULL && !link_info.relocatable) |
|||
{ |
|||
int ret = elf_metag_setup_section_lists (link_info.output_bfd, |
|||
&link_info); |
|||
|
|||
if (ret != 0) |
|||
{ |
|||
if (ret < 0) |
|||
{ |
|||
einfo ("%X%P: can not size stub section: %E\n"); |
|||
return; |
|||
} |
|||
|
|||
lang_for_each_statement (build_section_lists); |
|||
|
|||
/* Call into the BFD backend to do the real work. */ |
|||
if (! elf_metag_size_stubs (link_info.output_bfd, |
|||
stub_file->the_bfd, |
|||
&link_info, |
|||
group_size, |
|||
&metagelf_add_stub_section, |
|||
&metagelf_layout_sections_again)) |
|||
{ |
|||
einfo ("%X%P: can not size stub section: %E\n"); |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (need_laying_out != -1) |
|||
gld${EMULATION_NAME}_map_segments (need_laying_out); |
|||
|
|||
if (! link_info.relocatable) |
|||
{ |
|||
/* Now build the linker stubs. */ |
|||
if (stub_file != NULL && stub_file->the_bfd->sections != NULL) |
|||
{ |
|||
if (! elf_metag_build_stubs (&link_info)) |
|||
einfo ("%X%P: can not build stubs: %E\n"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Avoid processing the fake stub_file in vercheck, stat_needed and |
|||
check_needed routines. */ |
|||
|
|||
static void (*real_func) (lang_input_statement_type *); |
|||
|
|||
static void metag_for_each_input_file_wrapper (lang_input_statement_type *l) |
|||
{ |
|||
if (l != stub_file) |
|||
(*real_func) (l); |
|||
} |
|||
|
|||
static void |
|||
metag_lang_for_each_input_file (void (*func) (lang_input_statement_type *)) |
|||
{ |
|||
real_func = func; |
|||
lang_for_each_input_file (&metag_for_each_input_file_wrapper); |
|||
} |
|||
|
|||
#define lang_for_each_input_file metag_lang_for_each_input_file |
|||
|
|||
EOF |
|||
|
|||
# Define some shell vars to insert bits of code into the standard elf |
|||
# parse_args and list_options functions. |
|||
# |
|||
PARSE_AND_LIST_PROLOGUE=' |
|||
#define OPTION_STUBGROUP_SIZE 301 |
|||
' |
|||
|
|||
PARSE_AND_LIST_LONGOPTS=' |
|||
{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE }, |
|||
' |
|||
|
|||
PARSE_AND_LIST_OPTIONS=' |
|||
fprintf (file, _("\ |
|||
--stub-group-size=N Maximum size of a group of input sections that\n\ |
|||
can be handled by one stub section. A negative\n\ |
|||
value locates all stubs before their branches\n\ |
|||
(with a group size of -N), while a positive\n\ |
|||
value allows two groups of input sections, one\n\ |
|||
before, and one after each stub section.\n\ |
|||
Values of +/-1 indicate the linker should\n\ |
|||
choose suitable defaults.\n" |
|||
)); |
|||
' |
|||
|
|||
PARSE_AND_LIST_ARGS_CASES=' |
|||
case OPTION_STUBGROUP_SIZE: |
|||
{ |
|||
const char *end; |
|||
group_size = bfd_scan_vma (optarg, &end, 0); |
|||
if (*end) |
|||
einfo (_("%P%F: invalid number `%s'\''\n"), optarg); |
|||
} |
|||
break; |
|||
' |
|||
|
|||
# Put these extra metagelf routines in ld_${EMULATION_NAME}_emulation |
|||
# |
|||
LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation |
|||
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=metagelf_create_output_section_statements |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue