Add some shell variables and shell code to elf32.em

to allow elf32.em to be used by ports that require
some minor variations or a few extra functions.
Implement for hppaelf and armelf.
Fix header file include order in m68kcoff.em
This commit is contained in:
Alan Modra 2000-07-28 01:33:14 +00:00
parent 04925e1e0b
commit 41392f033d
10 changed files with 279 additions and 1663 deletions

View File

@ -1,5 +1,53 @@
2000-07-28 Alan Modra <alan@linuxcare.com.au> 2000-07-28 Alan Modra <alan@linuxcare.com.au>
* emultempl/armelf.em: Elide functions common to elf32.em,
ie. most of the file.
(arm_elf_after_open): New. Do arm specific things then call
gld${EMULATION_NAME}_after_open.
(arm_elf_before_allocation): New. Call
gld${EMULATION_NAME}_before_allocation then do arm specifics.
(PARSE_AND_LIST_PROLOGUE): Define.
(PARSE_AND_LIST_SHORTOPTS): Define.
(PARSE_AND_LIST_LONGOPTS): Define.
(PARSE_AND_LIST_OPTIONS): Define.
(PARSE_AND_LIST_ARGS_CASES): Define.
(LDEMUL_AFTER_OPEN): Define.
(LDEMUL_BEFORE_ALLOCATION): Define.
(LDEMUL_BEFORE_PARSE): Define.
(LDEMUL_FINISH): Define.
* emultempl/hppaelf.em: Similarly zap most of this file.
(hppaelf_add_stub_section): Prototype.
(hppaelf_layaout_sections_again): Prototype.
(hook_in_stub): Prototype.
(LDEMUL_SET_OUTPUT_ARCH): Define.
(LDEMUL_FINISH): Define.
(LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS): Define.
* emulparams/armelf.sh (TEMPLATE_NAME): Use elf32.
(EXTRA_EM_FILE): New.
* emulparams/armelf_linux.sh: Likewise.
* emulparams/armelf_linux26.sh: Likewise.
* emulparams/hppalinux.sh: Likewise.
* emulparams/hppaelf.sh: Likewise.
(NOP): Define.
* emultempl/elf32.em: Fix formatting.
(EXTRA_EM_FILE): Source it.
(LDEMUL_BEFORE_PARSE, LDEMUL_SYSLIB, LDEMUL_HLL,
LDEMUL_AFTER_PARSE, LDEMUL_AFTER_OPEN, LDEMUL_AFTER_ALLOCATION,
LDEMUL_SET_OUTPUT_ARCH, LDEMUL_CHOOSE_TARGET,
LDEMUL_BEFORE_ALLOCATION, LDEMUL_GET_SCRIPT, LDEMUL_FINISH,
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS,
LDEMUL_OPEN_DYNAMIC_ARCHIVE, LDEMUL_PLACE_ORPHAN,
LDEMUL_SET_SYMBOLS, LDEMUL_PARSE_ARGS, LDEMUL_UNRECOGNIZED_FILE,
LDEMUL_LIST_OPTIONS, LDEMUL_RECOGNIZED_FILE,
LDEMUL_FIND_POTENTIAL_LIBRARIES): New shell vars. Add code to
allow functions in this file to be overridden.
(PARSE_AND_LIST_SHORTOPTS): Handle it.
* emultempl/m68kcoff.em: Include ldfile.h before ldemul.h.
* emultempl/elf32.em: Reorganize file. * emultempl/elf32.em: Reorganize file.
2000-07-27 Ivan Kokshaysky <ink@jurassic.park.msu.ru> 2000-07-27 Ivan Kokshaysky <ink@jurassic.park.msu.ru>

View File

@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
BIG_OUTPUT_FORMAT="elf32-bigarm" BIG_OUTPUT_FORMAT="elf32-bigarm"
LITTLE_OUTPUT_FORMAT="elf32-littlearm" LITTLE_OUTPUT_FORMAT="elf32-littlearm"
TEXT_START_ADDR=0x8000 TEXT_START_ADDR=0x8000
TEMPLATE_NAME=armelf TEMPLATE_NAME=elf32
EXTRA_EM_FILE=armelf
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)' OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
OTHER_BSS_SYMBOLS='__bss_start__ = .;' OTHER_BSS_SYMBOLS='__bss_start__ = .;'
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;' OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;'

View File

@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
BIG_OUTPUT_FORMAT="elf32-bigarm" BIG_OUTPUT_FORMAT="elf32-bigarm"
LITTLE_OUTPUT_FORMAT="elf32-littlearm" LITTLE_OUTPUT_FORMAT="elf32-littlearm"
MAXPAGESIZE=0x8000 MAXPAGESIZE=0x8000
TEMPLATE_NAME=armelf TEMPLATE_NAME=elf32
EXTRA_EM_FILE=armelf
GENERATE_SHLIB_SCRIPT=yes GENERATE_SHLIB_SCRIPT=yes
DATA_START_SYMBOLS='__data_start = . ;'; DATA_START_SYMBOLS='__data_start = . ;';

View File

@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
BIG_OUTPUT_FORMAT="elf32-bigarm" BIG_OUTPUT_FORMAT="elf32-bigarm"
LITTLE_OUTPUT_FORMAT="elf32-littlearm" LITTLE_OUTPUT_FORMAT="elf32-littlearm"
MAXPAGESIZE=0x8000 MAXPAGESIZE=0x8000
TEMPLATE_NAME=armelf TEMPLATE_NAME=elf32
EXTRA_EM_FILE=armelf
GENERATE_SHLIB_SCRIPT=yes GENERATE_SHLIB_SCRIPT=yes
DATA_START_SYMBOLS='__data_start = . ;'; DATA_START_SYMBOLS='__data_start = . ;';

View File

@ -3,5 +3,7 @@ OUTPUT_FORMAT="elf32-hppa"
TEXT_START_ADDR=0x1000 TEXT_START_ADDR=0x1000
TARGET_PAGE_SIZE=0x1000 TARGET_PAGE_SIZE=0x1000
ARCH=hppa ARCH=hppa
NOP=0x08000240
START="$START$" START="$START$"
TEMPLATE_NAME=hppaelf TEMPLATE_NAME=elf32
EXTRA_EM_FILE=hppaelf

View File

@ -6,5 +6,6 @@ MAXPAGESIZE=0x1000
ARCH=hppa ARCH=hppa
NOP=0x08000240 NOP=0x08000240
START="_start" START="_start"
TEMPLATE_NAME=hppaelf
DATA_START_SYMBOLS='$global$ = .;' DATA_START_SYMBOLS='$global$ = .;'
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=hppaelf

File diff suppressed because it is too large Load Diff

View File

@ -69,14 +69,35 @@ static boolean gld${EMULATION_NAME}_place_orphan
PARAMS ((lang_input_statement_type *, asection *)); PARAMS ((lang_input_statement_type *, asection *));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
EOF
# Import any needed special functions and/or overrides.
#
if test -n "$EXTRA_EM_FILE" ; then
. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
fi
# Functions in this file can be overriden by setting the LDEMUL_* shell
# variables. If the name of the overriding function is the same as is
# defined in this file, then don't output this file's version.
# If a different overriding name is given then output the standard function
# as presumably it is called from the overriding function.
#
if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
cat >>e${EMULATION_NAME}.c <<EOF
static void static void
gld${EMULATION_NAME}_before_parse() gld${EMULATION_NAME}_before_parse ()
{ {
ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
config.dynamic_link = ${DYNAMIC_LINK-true}; config.dynamic_link = ${DYNAMIC_LINK-true};
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
} }
EOF
fi
cat >>e${EMULATION_NAME}.c <<EOF
/* These variables are required to pass information back and forth /* These variables are required to pass information back and forth
between after_open and check_needed and stat_needed and vercheck. */ between after_open and check_needed and stat_needed and vercheck. */
@ -325,7 +346,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
return true; return true;
} }
/* Tell the ELF backend that don't want the output file to have a /* Tell the ELF backend that we don't want the output file to have a
DT_NEEDED entry for this file. */ DT_NEEDED entry for this file. */
bfd_elf_set_dt_needed_name (abfd, ""); bfd_elf_set_dt_needed_name (abfd, "");
@ -533,6 +554,10 @@ gld${EMULATION_NAME}_check_needed (s)
} }
} }
EOF
if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
cat >>e${EMULATION_NAME}.c <<EOF
/* This is called after all the input files have been opened. */ /* This is called after all the input files have been opened. */
@ -654,6 +679,10 @@ cat >>e${EMULATION_NAME}.c <<EOF
} }
} }
EOF
fi
cat >>e${EMULATION_NAME}.c <<EOF
/* Look through an expression for an assignment statement. */ /* Look through an expression for an assignment statement. */
@ -726,6 +755,10 @@ gld${EMULATION_NAME}_find_statement_assignment (s)
gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
} }
EOF
if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
cat >>e${EMULATION_NAME}.c <<EOF
/* This is called after the sections have been attached to output /* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */ sections, but before any sizes or addresses have been set. */
@ -801,6 +834,11 @@ gld${EMULATION_NAME}_before_allocation ()
} }
} }
EOF
fi
if test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then
cat >>e${EMULATION_NAME}.c <<EOF
/* Try to open a dynamic archive. This is where we know that ELF /* Try to open a dynamic archive. This is where we know that ELF
dynamic libraries have an extension of .so (or .sl on oddball systems dynamic libraries have an extension of .so (or .sl on oddball systems
@ -884,8 +922,12 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
return true; return true;
} }
EOF
fi
cat >>e${EMULATION_NAME}.c <<EOF
/* A variant of lang_output_section_find. Used by place_orphan. */
/* A variant of lang_output_section_find. */
static lang_output_section_statement_type * static lang_output_section_statement_type *
output_rel_find () output_rel_find ()
{ {
@ -907,18 +949,20 @@ output_rel_find ()
return (lang_output_section_statement_type *) NULL; return (lang_output_section_statement_type *) NULL;
} }
EOF
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
cat >>e${EMULATION_NAME}.c <<EOF
/* Place an orphan section. We use this to put random SHF_ALLOC /* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */ sections in the right segment. */
struct orphan_save struct orphan_save {
{
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
asection **section; asection **section;
lang_statement_union_type **stmt; lang_statement_union_type **stmt;
}; };
/*ARGSUSED*/
static boolean static boolean
gld${EMULATION_NAME}_place_orphan (file, s) gld${EMULATION_NAME}_place_orphan (file, s)
lang_input_statement_type *file; lang_input_statement_type *file;
@ -1137,9 +1181,14 @@ gld${EMULATION_NAME}_place_orphan (file, s)
return true; return true;
} }
EOF
fi
if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
cat >>e${EMULATION_NAME}.c <<EOF
static char * static char *
gld${EMULATION_NAME}_get_script(isfile) gld${EMULATION_NAME}_get_script (isfile)
int *isfile; int *isfile;
EOF EOF
@ -1194,26 +1243,14 @@ cat >>e${EMULATION_NAME}.c <<EOF
else else
return "ldscripts/${EMULATION_NAME}.x"; return "ldscripts/${EMULATION_NAME}.x";
} }
EOF
EOF
fi
fi fi
if test -n "$PARSE_AND_LIST_ARGS_CASES" || test x"$GENERATE_SHLIB_SCRIPT" = xyes; then if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then
NEED_PARSE_AND_LIST=yes
cat >>e${EMULATION_NAME}.c <<EOF if test x"$LDEMUL_PARSE_ARGS" != xgld_"$EMULATION_NAME"_parse_args; then
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE * file));
EOF
else
NEED_PARSE_AND_LIST=no
cat >>e${EMULATION_NAME}.c <<EOF
#define gld_${EMULATION_NAME}_parse_args NULL
#define gld_${EMULATION_NAME}_list_options NULL
EOF
fi
if test -n "$PARSE_AND_LIST_PROLOGUE" ; then if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
@ -1221,7 +1258,6 @@ cat >>e${EMULATION_NAME}.c <<EOF
EOF EOF
fi fi
if test "$NEED_PARSE_AND_LIST" = yes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
#include "getopt.h" #include "getopt.h"
@ -1232,7 +1268,6 @@ cat >>e${EMULATION_NAME}.c <<EOF
static struct option longopts[] = static struct option longopts[] =
{ {
EOF EOF
fi
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
@ -1251,12 +1286,13 @@ cat >>e${EMULATION_NAME}.c <<EOF
EOF EOF
fi fi
if test "$NEED_PARSE_AND_LIST" = yes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
{NULL, no_argument, NULL, 0} {NULL, no_argument, NULL, 0}
}; };
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
static int static int
gld_${EMULATION_NAME}_parse_args (argc, argv) gld_${EMULATION_NAME}_parse_args (argc, argv)
int argc; int argc;
@ -1272,7 +1308,9 @@ gld_${EMULATION_NAME}_parse_args (argc, argv)
opterr = 0; opterr = 0;
wanterror = opterr; wanterror = opterr;
optc = getopt_long_only (argc, argv, "-z:", longopts, &longind); optc = getopt_long_only (argc, argv,
"-${PARSE_AND_LIST_SHORTOPTS}z:", longopts,
&longind);
opterr = prevopterr; opterr = prevopterr;
switch (optc) switch (optc)
@ -1284,7 +1322,6 @@ gld_${EMULATION_NAME}_parse_args (argc, argv)
return 0; return 0;
EOF EOF
fi
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
@ -1332,20 +1369,25 @@ cat >>e${EMULATION_NAME}.c <<EOF
EOF EOF
fi fi
if test "$NEED_PARSE_AND_LIST" = yes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
} }
return 1; return 1;
} }
EOF
fi
if test x"$LDEMUL_LIST_OPTIONS" != xgld_"$EMULATION_NAME"_list_options; then
cat >>e${EMULATION_NAME}.c <<EOF
static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE * file));
static void static void
gld_${EMULATION_NAME}_list_options (file) gld_${EMULATION_NAME}_list_options (file)
FILE * file; FILE * file;
{ {
EOF EOF
fi
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
@ -1371,43 +1413,54 @@ cat >>e${EMULATION_NAME}.c <<EOF
EOF EOF
fi fi
if test "$NEED_PARSE_AND_LIST" = yes; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
} }
EOF EOF
fi
if test -n "$PARSE_AND_LIST_EPILOGUE" ; then if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
$PARSE_AND_LIST_EPILOGUE $PARSE_AND_LIST_EPILOGUE
EOF EOF
fi fi
fi
else
if test x"$LDEMUL_PARSE_ARGS" != xgld_"$EMULATION_NAME"_parse_args; then
cat >>e${EMULATION_NAME}.c <<EOF
#define gld_${EMULATION_NAME}_parse_args NULL
EOF
fi
if test x"$LDEMUL_LIST_OPTIONS" != xgld_"$EMULATION_NAME"_list_options; then
cat >>e${EMULATION_NAME}.c <<EOF
#define gld_${EMULATION_NAME}_list_options NULL
EOF
fi
fi
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{ {
gld${EMULATION_NAME}_before_parse, ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
syslib_default, ${LDEMUL_SYSLIB-syslib_default},
hll_default, ${LDEMUL_HLL-hll_default},
after_parse_default, ${LDEMUL_AFTER_PARSE-after_parse_default},
gld${EMULATION_NAME}_after_open, ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
after_allocation_default, ${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
set_output_arch_default, ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
ldemul_default_target, ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
gld${EMULATION_NAME}_before_allocation, ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
gld${EMULATION_NAME}_get_script, ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
"${EMULATION_NAME}", "${EMULATION_NAME}",
"${OUTPUT_FORMAT}", "${OUTPUT_FORMAT}",
NULL, /* finish */ ${LDEMUL_FINISH-NULL},
NULL, /* create output section statements */ ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
gld${EMULATION_NAME}_open_dynamic_archive, ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
gld${EMULATION_NAME}_place_orphan, ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
NULL, /* set_symbols */ ${LDEMUL_SET_SYMBOLS-NULL},
gld_${EMULATION_NAME}_parse_args, ${LDEMUL_PARSE_ARGS-gld_${EMULATION_NAME}_parse_args},
NULL, /* unrecognized_file */ ${LDEMUL_UNRECOGNIZED_FILE-NULL},
gld_${EMULATION_NAME}_list_options, ${LDEMUL_LIST_OPTIONS-gld_${EMULATION_NAME}_list_options},
NULL, /* recognized_file */ ${LDEMUL_RECOGNIZED_FILE-NULL},
NULL /* find_potential_libraries */ ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
}; };
EOF EOF

View File

@ -1,73 +1,50 @@
# This shell script emits a C file. -*- C -*- # This shell script emits a C file. -*- C -*-
# It does some substitutions. # Copyright (C) 1991, 93, 94, 95, 97, 99, 2000
cat >e${EMULATION_NAME}.c <<EOF # Free Software Foundation, Inc.
/* This file is is generated by a shell script. DO NOT EDIT! */ #
# This file is part of GLD, the Gnu Linker.
#
# 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
/* An emulation for HP PA-RISC ELF linkers. # This file is sourced from elf32.em, and defines extra hppa-elf
Copyright (C) 1991, 93, 94, 95, 97, 99, 2000 # specific routines.
Free Software Foundation, Inc. #
Written by Steve Chamberlain steve@cygnus.com cat >>e${EMULATION_NAME}.c <<EOF
This file is part of GLD, the Gnu Linker.
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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include <ctype.h>
#include "bfdlink.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
#include "ldgram.h"
#include "ldctor.h" #include "ldctor.h"
#include "elf32-hppa.h" #include "elf32-hppa.h"
static void hppaelf_before_parse PARAMS ((void));
static void hppaelf_set_output_arch PARAMS ((void)); static void hppaelf_set_output_arch PARAMS ((void));
static void hppaelf_create_output_section_statements PARAMS ((void)); static void hppaelf_create_output_section_statements PARAMS ((void));
static void hppaelf_delete_padding_statements static void hppaelf_delete_padding_statements
PARAMS ((lang_statement_list_type *list)); PARAMS ((lang_statement_list_type *));
static asection *hppaelf_add_stub_section
PARAMS ((const char *, asection *));
static void hppaelf_layaout_sections_again PARAMS ((void));
static void hppaelf_finish PARAMS ((void)); static void hppaelf_finish PARAMS ((void));
static boolean gld${EMULATION_NAME}_place_orphan
PARAMS ((lang_input_statement_type *, asection *));
static lang_output_section_statement_type *output_rel_find PARAMS ((void));
static char *hppaelf_get_script PARAMS ((int *));
/* Fake input file for stubs. */ /* Fake input file for stubs. */
static lang_input_statement_type *stub_file; static lang_input_statement_type *stub_file;
/* Perform some emulation specific initialization. For PA ELF we set
up the local label prefix and the output architecture. */
static void
hppaelf_before_parse ()
{
ldfile_output_architecture = bfd_arch_hppa;
}
/* Set the output architecture and machine. */ /* Set the output architecture and machine. */
static void static void
hppaelf_set_output_arch() hppaelf_set_output_arch ()
{ {
unsigned long machine = 0; unsigned long machine = 0;
@ -162,6 +139,9 @@ struct hook_stub_info
/* Traverse the linker tree to find the spot where the stub goes. */ /* Traverse the linker tree to find the spot where the stub goes. */
static boolean hook_in_stub
PARAMS ((struct hook_stub_info *, lang_statement_union_type **));
static boolean static boolean
hook_in_stub (info, lp) hook_in_stub (info, lp)
struct hook_stub_info *info; struct hook_stub_info *info;
@ -230,6 +210,7 @@ hook_in_stub (info, lp)
return false; return false;
} }
/* Call-back for elf32_hppa_size_stubs. */ /* Call-back for elf32_hppa_size_stubs. */
/* Create a new stub section, and arrange for it to be linked /* Create a new stub section, and arrange for it to be linked
@ -275,6 +256,7 @@ hppaelf_add_stub_section (stub_name, input_section)
return NULL; return NULL;
} }
/* Another call-back for elf32_hppa_size_stubs. */ /* Another call-back for elf32_hppa_size_stubs. */
static void static void
@ -312,10 +294,10 @@ hppaelf_finish ()
return; return;
/* Call into the BFD backend to do the real work. */ /* Call into the BFD backend to do the real work. */
if (elf32_hppa_size_stubs (stub_file->the_bfd, if (! elf32_hppa_size_stubs (stub_file->the_bfd,
&link_info, &link_info,
&hppaelf_add_stub_section, &hppaelf_add_stub_section,
&hppaelf_layaout_sections_again) == false) &hppaelf_layaout_sections_again))
{ {
einfo ("%X%P: can not size stub section: %E\n"); einfo ("%X%P: can not size stub section: %E\n");
return; return;
@ -324,350 +306,15 @@ hppaelf_finish ()
/* Now build the linker stubs. */ /* Now build the linker stubs. */
if (stub_file->the_bfd->sections != NULL) if (stub_file->the_bfd->sections != NULL)
{ {
if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false) if (! elf32_hppa_build_stubs (stub_file->the_bfd, &link_info))
einfo ("%X%P: can not build stubs: %E\n"); einfo ("%X%P: can not build stubs: %E\n");
} }
} }
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
struct orphan_save
{
lang_output_section_statement_type *os;
asection **section;
lang_statement_union_type **stmt;
};
/*ARGSUSED*/
static boolean
gld${EMULATION_NAME}_place_orphan (file, s)
lang_input_statement_type *file;
asection *s;
{
static struct orphan_save hold_text;
static struct orphan_save hold_rodata;
static struct orphan_save hold_data;
static struct orphan_save hold_bss;
static struct orphan_save hold_rel;
static struct orphan_save hold_interp;
struct orphan_save *place;
lang_statement_list_type *old;
lang_statement_list_type add;
etree_type *address;
const char *secname, *ps;
const char *outsecname;
lang_output_section_statement_type *os;
secname = bfd_get_section_name (s->owner, s);
/* Look through the script to see where to place this section. */
os = lang_output_section_find (secname);
if (os != NULL
&& os->bfd_section != NULL
&& ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
{
/* We have already placed a section with this name. */
wild_doit (&os->children, s, os, file);
return true;
}
if (hold_text.os == NULL)
hold_text.os = lang_output_section_find (".text");
/* If this is a final link, then always put .gnu.warning.SYMBOL
sections into the .text section to get them out of the way. */
if (! link_info.shared
&& ! link_info.relocateable
&& strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
&& hold_text.os != NULL)
{
wild_doit (&hold_text.os->children, s, hold_text.os, file);
return true;
}
/* Decide which segment the section should go in based on the
section name and section flags. We put loadable .note sections
right after the .interp section, so that the PT_NOTE segment is
stored right after the program headers where the OS can read it
in the first page. */
#define HAVE_SECTION(hold, name) \
(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
if (s->flags & SEC_EXCLUDE)
return false;
else if ((s->flags & SEC_ALLOC) == 0)
place = NULL;
else if ((s->flags & SEC_LOAD) != 0
&& strncmp (secname, ".note", 4) == 0
&& HAVE_SECTION (hold_interp, ".interp"))
place = &hold_interp;
else if ((s->flags & SEC_HAS_CONTENTS) == 0
&& HAVE_SECTION (hold_bss, ".bss"))
place = &hold_bss;
else if ((s->flags & SEC_READONLY) == 0
&& HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if (strncmp (secname, ".rel", 4) == 0
&& (hold_rel.os != NULL
|| (hold_rel.os = output_rel_find ()) != NULL))
place = &hold_rel;
else if ((s->flags & SEC_CODE) == 0
&& (s->flags & SEC_READONLY) != 0
&& HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
else if ((s->flags & SEC_READONLY) != 0
&& hold_text.os != NULL)
place = &hold_text;
else
place = NULL;
#undef HAVE_SECTION
/* Choose a unique name for the section. This will be needed if the
same section name appears in the input file with different
loadable or allocateable characteristics. */
outsecname = secname;
if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
{
unsigned int len;
char *newname;
unsigned int i;
len = strlen (outsecname);
newname = xmalloc (len + 5);
strcpy (newname, outsecname);
i = 0;
do
{
sprintf (newname + len, "%d", i);
++i;
}
while (bfd_get_section_by_name (output_bfd, newname) != NULL);
outsecname = newname;
}
if (place != NULL)
{
/* Start building a list of statements for this section. */
old = stat_ptr;
stat_ptr = &add;
lang_list_init (stat_ptr);
/* If the name of the section is representable in C, then create
symbols to mark the start and the end of the section. */
for (ps = outsecname; *ps != '\0'; ps++)
if (! isalnum ((unsigned char) *ps) && *ps != '_')
break;
if (*ps == '\0' && config.build_constructors)
{
char *symname;
etree_type *e_align;
symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
sprintf (symname, "__start_%s", outsecname);
e_align = exp_unop (ALIGN_K,
exp_intop ((bfd_vma) 1 << s->alignment_power));
lang_add_assignment (exp_assop ('=', symname, e_align));
}
}
if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
address = exp_intop ((bfd_vma) 0);
else
address = NULL;
os = lang_enter_output_section_statement (outsecname, address, 0,
(bfd_vma) 0,
(etree_type *) NULL,
(etree_type *) NULL,
(etree_type *) NULL);
wild_doit (&os->children, s, os, file);
lang_leave_output_section_statement
((bfd_vma) 0, "*default*",
(struct lang_output_section_phdr_list *) NULL, "*default*");
if (place != NULL)
{
asection *snew, **pps;
stat_ptr = &add;
if (*ps == '\0' && config.build_constructors)
{
char *symname;
symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
sprintf (symname, "__stop_%s", outsecname);
lang_add_assignment (exp_assop ('=', symname,
exp_nameop (NAME, ".")));
}
stat_ptr = old;
snew = os->bfd_section;
if (place->os->bfd_section != NULL || place->section != NULL)
{
/* Shuffle the section to make the output file look neater. */
if (place->section == NULL)
{
#if 0
/* Finding the end of the list is a little tricky. We
make a wild stab at it by comparing section flags. */
flagword first_flags = place->os->bfd_section->flags;
for (pps = &place->os->bfd_section->next;
*pps != NULL && (*pps)->flags == first_flags;
pps = &(*pps)->next)
;
place->section = pps;
#else
/* Put orphans after the first section on the list. */
place->section = &place->os->bfd_section->next;
#endif
}
/* Unlink the section. */
for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
;
*pps = snew->next;
/* Now tack it on to the "place->os" section list. */
snew->next = *place->section;
*place->section = snew;
}
place->section = &snew->next; /* Save the end of this list. */
if (place->stmt == NULL)
{
/* Put the new statement list right at the head. */
*add.tail = place->os->header.next;
place->os->header.next = add.head;
}
else
{
/* Put it after the last orphan statement we added. */
*add.tail = *place->stmt;
*place->stmt = add.head;
}
place->stmt = add.tail; /* Save the end of this list. */
}
return true;
}
/* A variant of lang_output_section_find. */
static lang_output_section_statement_type *
output_rel_find ()
{
lang_statement_union_type *u;
lang_output_section_statement_type *lookup;
for (u = lang_output_section_statement.head;
u != (lang_statement_union_type *) NULL;
u = lookup->next)
{
lookup = &u->output_section_statement;
if (strncmp (".rel", lookup->name, 4) == 0
&& lookup->bfd_section != NULL
&& (lookup->bfd_section->flags & SEC_ALLOC) != 0)
{
return lookup;
}
}
return (lang_output_section_statement_type *) NULL;
}
/* The script itself gets inserted here. */
static char *
hppaelf_get_script(isfile)
int *isfile;
EOF EOF
if test -n "$COMPILE_IN" # Put these routines in ld_${EMULATION_NAME}_emulation
then #
# Scripts compiled in. LDEMUL_SET_OUTPUT_ARCH=hppaelf_set_output_arch
LDEMUL_FINISH=hppaelf_finish
# sed commands to quote an ld script as a C string. LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements
sc="-f stringify.sed"
cat >>e${EMULATION_NAME}.c <<EOF
{
*isfile = 0;
if (link_info.relocateable == true && config.build_constructors == true)
return
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
fi
echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c
else
# Scripts read from the filesystem.
cat >>e${EMULATION_NAME}.c <<EOF
{
*isfile = 1;
if (link_info.relocateable == true && config.build_constructors == true)
return "ldscripts/${EMULATION_NAME}.xu";
else if (link_info.relocateable == true)
return "ldscripts/${EMULATION_NAME}.xr";
else if (!config.text_read_only)
return "ldscripts/${EMULATION_NAME}.xbn";
else if (!config.magic_demand_paged)
return "ldscripts/${EMULATION_NAME}.xn";
else if (link_info.shared)
return "ldscripts/${EMULATION_NAME}.xs";
else
return "ldscripts/${EMULATION_NAME}.x";
}
EOF
fi
cat >>e${EMULATION_NAME}.c <<EOF
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
hppaelf_before_parse,
syslib_default,
hll_default,
after_parse_default,
after_open_default,
after_allocation_default,
hppaelf_set_output_arch,
ldemul_default_target,
before_allocation_default,
hppaelf_get_script,
"${EMULATION_NAME}",
"elf32-hppa",
hppaelf_finish,
hppaelf_create_output_section_statements,
NULL, /* open dynamic */
gld${EMULATION_NAME}_place_orphan,
NULL, /* set_symbols */
NULL, /* parse_args */
NULL, /* unrecognized_file */
NULL, /* list_options */
NULL, /* recognized_file */
NULL /* find_potential_libraries */
};
EOF

View File

@ -33,8 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "ld.h" #include "ld.h"
#include "ldmain.h" #include "ldmain.h"
#include "ldemul.h"
#include "ldfile.h" #include "ldfile.h"
#include "ldemul.h"
#include "ldmisc.h" #include "ldmisc.h"
static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); static void gld${EMULATION_NAME}_before_parse PARAMS ((void));