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:
parent
04925e1e0b
commit
41392f033d
48
ld/ChangeLog
48
ld/ChangeLog
@ -1,5 +1,53 @@
|
||||
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.
|
||||
|
||||
2000-07-27 Ivan Kokshaysky <ink@jurassic.park.msu.ru>
|
||||
|
@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
|
||||
BIG_OUTPUT_FORMAT="elf32-bigarm"
|
||||
LITTLE_OUTPUT_FORMAT="elf32-littlearm"
|
||||
TEXT_START_ADDR=0x8000
|
||||
TEMPLATE_NAME=armelf
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=armelf
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
|
||||
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
|
||||
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;'
|
||||
|
@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
|
||||
BIG_OUTPUT_FORMAT="elf32-bigarm"
|
||||
LITTLE_OUTPUT_FORMAT="elf32-littlearm"
|
||||
MAXPAGESIZE=0x8000
|
||||
TEMPLATE_NAME=armelf
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=armelf
|
||||
GENERATE_SHLIB_SCRIPT=yes
|
||||
|
||||
DATA_START_SYMBOLS='__data_start = . ;';
|
||||
|
@ -4,7 +4,8 @@ OUTPUT_FORMAT="elf32-littlearm"
|
||||
BIG_OUTPUT_FORMAT="elf32-bigarm"
|
||||
LITTLE_OUTPUT_FORMAT="elf32-littlearm"
|
||||
MAXPAGESIZE=0x8000
|
||||
TEMPLATE_NAME=armelf
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=armelf
|
||||
GENERATE_SHLIB_SCRIPT=yes
|
||||
|
||||
DATA_START_SYMBOLS='__data_start = . ;';
|
||||
|
@ -3,5 +3,7 @@ OUTPUT_FORMAT="elf32-hppa"
|
||||
TEXT_START_ADDR=0x1000
|
||||
TARGET_PAGE_SIZE=0x1000
|
||||
ARCH=hppa
|
||||
NOP=0x08000240
|
||||
START="$START$"
|
||||
TEMPLATE_NAME=hppaelf
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=hppaelf
|
||||
|
@ -6,5 +6,6 @@ MAXPAGESIZE=0x1000
|
||||
ARCH=hppa
|
||||
NOP=0x08000240
|
||||
START="_start"
|
||||
TEMPLATE_NAME=hppaelf
|
||||
DATA_START_SYMBOLS='$global$ = .;'
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=hppaelf
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -69,14 +69,35 @@ static boolean gld${EMULATION_NAME}_place_orphan
|
||||
PARAMS ((lang_input_statement_type *, asection *));
|
||||
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
|
||||
gld${EMULATION_NAME}_before_parse()
|
||||
gld${EMULATION_NAME}_before_parse ()
|
||||
{
|
||||
ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
|
||||
config.dynamic_link = ${DYNAMIC_LINK-true};
|
||||
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
|
||||
between after_open and check_needed and stat_needed and vercheck. */
|
||||
@ -325,7 +346,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
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. */
|
||||
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. */
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -726,6 +755,10 @@ gld${EMULATION_NAME}_find_statement_assignment (s)
|
||||
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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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 *
|
||||
output_rel_find ()
|
||||
{
|
||||
@ -907,18 +949,20 @@ output_rel_find ()
|
||||
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
|
||||
sections in the right segment. */
|
||||
|
||||
struct orphan_save
|
||||
{
|
||||
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;
|
||||
@ -1137,9 +1181,14 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||
return true;
|
||||
}
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
|
||||
static char *
|
||||
gld${EMULATION_NAME}_get_script(isfile)
|
||||
gld${EMULATION_NAME}_get_script (isfile)
|
||||
int *isfile;
|
||||
EOF
|
||||
|
||||
@ -1194,26 +1243,14 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
else
|
||||
return "ldscripts/${EMULATION_NAME}.x";
|
||||
}
|
||||
EOF
|
||||
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$PARSE_AND_LIST_ARGS_CASES" || test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
|
||||
NEED_PARSE_AND_LIST=yes
|
||||
if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then
|
||||
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
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 x"$LDEMUL_PARSE_ARGS" != xgld_"$EMULATION_NAME"_parse_args; then
|
||||
|
||||
if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
@ -1221,7 +1258,6 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "$NEED_PARSE_AND_LIST" = yes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
|
||||
#include "getopt.h"
|
||||
@ -1232,7 +1268,6 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
static struct option longopts[] =
|
||||
{
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
@ -1251,12 +1286,13 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "$NEED_PARSE_AND_LIST" = yes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
|
||||
|
||||
static int
|
||||
gld_${EMULATION_NAME}_parse_args (argc, argv)
|
||||
int argc;
|
||||
@ -1272,7 +1308,9 @@ gld_${EMULATION_NAME}_parse_args (argc, argv)
|
||||
opterr = 0;
|
||||
|
||||
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;
|
||||
|
||||
switch (optc)
|
||||
@ -1284,7 +1322,6 @@ gld_${EMULATION_NAME}_parse_args (argc, argv)
|
||||
return 0;
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
@ -1332,20 +1369,25 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "$NEED_PARSE_AND_LIST" = yes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
}
|
||||
|
||||
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
|
||||
gld_${EMULATION_NAME}_list_options (file)
|
||||
FILE * file;
|
||||
{
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
@ -1371,43 +1413,54 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "$NEED_PARSE_AND_LIST" = yes; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
$PARSE_AND_LIST_EPILOGUE
|
||||
EOF
|
||||
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
|
||||
|
||||
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
||||
{
|
||||
gld${EMULATION_NAME}_before_parse,
|
||||
syslib_default,
|
||||
hll_default,
|
||||
after_parse_default,
|
||||
gld${EMULATION_NAME}_after_open,
|
||||
after_allocation_default,
|
||||
set_output_arch_default,
|
||||
ldemul_default_target,
|
||||
gld${EMULATION_NAME}_before_allocation,
|
||||
gld${EMULATION_NAME}_get_script,
|
||||
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
|
||||
${LDEMUL_SYSLIB-syslib_default},
|
||||
${LDEMUL_HLL-hll_default},
|
||||
${LDEMUL_AFTER_PARSE-after_parse_default},
|
||||
${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
|
||||
${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
|
||||
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
|
||||
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
|
||||
${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
|
||||
${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
|
||||
"${EMULATION_NAME}",
|
||||
"${OUTPUT_FORMAT}",
|
||||
NULL, /* finish */
|
||||
NULL, /* create output section statements */
|
||||
gld${EMULATION_NAME}_open_dynamic_archive,
|
||||
gld${EMULATION_NAME}_place_orphan,
|
||||
NULL, /* set_symbols */
|
||||
gld_${EMULATION_NAME}_parse_args,
|
||||
NULL, /* unrecognized_file */
|
||||
gld_${EMULATION_NAME}_list_options,
|
||||
NULL, /* recognized_file */
|
||||
NULL /* find_potential_libraries */
|
||||
${LDEMUL_FINISH-NULL},
|
||||
${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
|
||||
${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
|
||||
${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
|
||||
${LDEMUL_SET_SYMBOLS-NULL},
|
||||
${LDEMUL_PARSE_ARGS-gld_${EMULATION_NAME}_parse_args},
|
||||
${LDEMUL_UNRECOGNIZED_FILE-NULL},
|
||||
${LDEMUL_LIST_OPTIONS-gld_${EMULATION_NAME}_list_options},
|
||||
${LDEMUL_RECOGNIZED_FILE-NULL},
|
||||
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
||||
};
|
||||
EOF
|
||||
|
@ -1,73 +1,50 @@
|
||||
# This shell script emits a C file. -*- C -*-
|
||||
# It does some substitutions.
|
||||
cat >e${EMULATION_NAME}.c <<EOF
|
||||
/* This file is is generated by a shell script. DO NOT EDIT! */
|
||||
# Copyright (C) 1991, 93, 94, 95, 97, 99, 2000
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# 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.
|
||||
Copyright (C) 1991, 93, 94, 95, 97, 99, 2000
|
||||
Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain steve@cygnus.com
|
||||
# This file is sourced from elf32.em, and defines extra hppa-elf
|
||||
# specific routines.
|
||||
#
|
||||
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 "elf32-hppa.h"
|
||||
|
||||
static void hppaelf_before_parse PARAMS ((void));
|
||||
static void hppaelf_set_output_arch PARAMS ((void));
|
||||
static void hppaelf_create_output_section_statements PARAMS ((void));
|
||||
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 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. */
|
||||
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. */
|
||||
|
||||
static void
|
||||
hppaelf_set_output_arch()
|
||||
hppaelf_set_output_arch ()
|
||||
{
|
||||
unsigned long machine = 0;
|
||||
|
||||
@ -162,6 +139,9 @@ struct hook_stub_info
|
||||
|
||||
/* 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
|
||||
hook_in_stub (info, lp)
|
||||
struct hook_stub_info *info;
|
||||
@ -230,6 +210,7 @@ hook_in_stub (info, lp)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Call-back for elf32_hppa_size_stubs. */
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* Another call-back for elf32_hppa_size_stubs. */
|
||||
|
||||
static void
|
||||
@ -312,10 +294,10 @@ hppaelf_finish ()
|
||||
return;
|
||||
|
||||
/* Call into the BFD backend to do the real work. */
|
||||
if (elf32_hppa_size_stubs (stub_file->the_bfd,
|
||||
&link_info,
|
||||
&hppaelf_add_stub_section,
|
||||
&hppaelf_layaout_sections_again) == false)
|
||||
if (! elf32_hppa_size_stubs (stub_file->the_bfd,
|
||||
&link_info,
|
||||
&hppaelf_add_stub_section,
|
||||
&hppaelf_layaout_sections_again))
|
||||
{
|
||||
einfo ("%X%P: can not size stub section: %E\n");
|
||||
return;
|
||||
@ -324,350 +306,15 @@ hppaelf_finish ()
|
||||
/* Now build the linker stubs. */
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
if test -n "$COMPILE_IN"
|
||||
then
|
||||
# Scripts compiled in.
|
||||
|
||||
# sed commands to quote an ld script as a C string.
|
||||
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
|
||||
# Put these routines in ld_${EMULATION_NAME}_emulation
|
||||
#
|
||||
LDEMUL_SET_OUTPUT_ARCH=hppaelf_set_output_arch
|
||||
LDEMUL_FINISH=hppaelf_finish
|
||||
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements
|
||||
|
@ -33,8 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "ld.h"
|
||||
#include "ldmain.h"
|
||||
#include "ldemul.h"
|
||||
#include "ldfile.h"
|
||||
#include "ldemul.h"
|
||||
#include "ldmisc.h"
|
||||
|
||||
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
|
||||
|
Loading…
Reference in New Issue
Block a user