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>
* 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>

View File

@ -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__ = . ;'

View File

@ -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 = . ;';

View File

@ -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 = . ;';

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));