hppaelf.em: Merge from elf32.em and implement multiple linker stubs.

Makefile.am: Re-enable ehppaelf.o, add ehppalinux.o
configure.tgt: targ_emul=hppalinux for hppa*linux
This commit is contained in:
Alan Modra 2000-07-09 08:45:29 +00:00
parent ad1079af05
commit 4900fc0695
7 changed files with 580 additions and 136 deletions

View File

@ -1,3 +1,49 @@
2000-07-09 Alan Modra <alan@linuxcare.com.au>
Changes to create multiple linker stubs, positioned immediately
before the section where they are required.
* emultempl/hppaelf.em: Include elf32-hppa.h.
(stub_sec, file_chain): Delete.
(hppaelf_create_output_section_statements): Don't make a stub
section here.
(hook_stub_info): New struct.
(hook_in_stub): New function.
(hppaelf_add_stub_section): New function.
(hppaelf_finish): Do nothing for relocateable links. Modify the
call to elf32_hppa_size_stubs. Move code for updating section
layout from here...
(hppaelf_layaout_sections_again): ..to here, a new function.
* emultempl/hppaelf.em (hppaelf_delete_padding_statements): Fix
broken list handling. Pass in a pointer to the list.
(hppaelf_finish): Update call to hppaelf_delete_padding_statements
for above changes.
(hppaelf_before_parse): Prototype.
(hppaelf_set_output_arch): Prototype.
(hppaelf_create_output_section_statements): Prototype.
(hppaelf_delete_padding_statements): Prototype.
(hppaelf_finish): Prototype.
Merge from elf32.em
* emultempl/hppaelf.em: Include ctype.h.
(struct orphan_save): New.
(gld${EMULATION_NAME}_place_orphan): New.
(output_rel_find): New.
(hppaelf_get_script): Update from elf32.em.
(ld_hppaelf_emulation): Rename to ld_${EMULATION_NAME}_emulation.
Change emulation_name field to "${EMULATION_NAME}". Add
gld${EMULATION_NAME}_place_orphan.
* Makefile.am (ALL_EMULATIONS): Reinstate ehppaelf.o, add
ehppalinux.o, sort it. Regenerate dependencies.
(ehppalinux.c): Depend on hppaelf.em
* Makefile.in: Regenerate.
* configure.tgt: targ_emul=hppalinux for hppa*linux
* emulparams/hppalinux.sh: New.
* emulparams/hppaelf.sh (TARGET_PAGE_SIZE): Write in hex.
2000-07-08 Alan Modra <alan@linuxcare.com.au>
* lexsup.c (parse_args): Copy section name.

View File

@ -104,53 +104,53 @@ ALL_EMULATIONS = \
eaixrs6.o \
ealpha.o \
earcelf.o \
earmelf.o \
earmelf_oabi.o \
earmelf_linux.o \
earmelf_linux26.o \
earm_epoc_pe.o \
earmaoutb.o \
earmaoutl.o \
earmcoff.o \
earmelf.o \
earmelf_linux.o \
earmelf_linux26.o \
earmelf_oabi.o \
earmnbsd.o \
earmpe.o \
earm_epoc_pe.o \
eavr1200.o \
eavr23xx.o \
eavr44x4.o \
eavr4433.o \
eavr44x4.o \
eavr85xx.o \
eavrmega603.o \
eavrmega103.o \
eavrmega161.o \
eavrmega603.o \
ecoff_sparc.o \
ed10velf.o \
ed30velf.o \
ed30v_e.o \
ed30v_o.o \
ed30velf.o \
edelta68.o \
eebmon29k.o \
eelf32_sparc.o \
eelf32_i960.o \
eelf32_sparc.o \
eelf32b4300.o \
eelf32bmip.o \
eelf32ebmip.o \
eelf32elmip.o \
eelf32bmipn32.o \
eelf32btsmip.o \
eelf32ebmip.o \
eelf32elmip.o \
eelf32fr30.o \
eelf32i370.o \
eelf32l4300.o \
eelf32lmip.o \
eelf32lppc.o \
eelf32lppcsim.o \
eelf32mcore.o \
eelf32ppc.o \
eelf32ppcsim.o \
eelf32ppclinux.o \
eelf32ppcsim.o \
eelf_i386.o \
eelf_i386_be.o \
egld960.o \
egld960coff.o \
eelf32fr30.o \
eelf32mcore.o \
eh8300.o \
eh8300h.o \
eh8300s.o \
@ -161,6 +161,8 @@ ALL_EMULATIONS = \
eh8500s.o \
ehp300bsd.o \
ehp3hpux.o \
ehppaelf.o \
ehppalinux.o \
ei386aout.o \
ei386beos.o \
ei386bsd.o \
@ -199,10 +201,10 @@ ALL_EMULATIONS = \
emipslnews.o \
emipspe.o \
enews.o \
epjelf.o \
epjlelf.o \
ens32knbsd.o \
epc532macha.o \
epjelf.o \
epjlelf.o \
eppcmacos.o \
eppcnw.o \
eppcpe.o \
@ -210,8 +212,8 @@ ALL_EMULATIONS = \
esa29200.o \
esh.o \
eshelf.o \
eshlelf.o \
eshl.o \
eshlelf.o \
eshpe.o \
esparcaout.o \
esparclinux.o \
@ -231,20 +233,16 @@ ALL_EMULATIONS = \
ez8001.o \
ez8002.o
# The following object file has been removed from ALL_EMULATIONS
# because the BFD support is currently broken.
# ehppaelf.o
ALL_64_EMULATIONS = \
eelf64_ia64.o \
eelf64_sparc.o \
eelf64alpha.o \
eelf64hppa.o \
eelf64bmip.o
eelf64bmip.o \
eelf64hppa.o
ALL_EMUL_EXTRA_OFILES = \
pe-dll.o \
deffilep.o
deffilep.o \
pe-dll.o
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
@ -521,6 +519,9 @@ ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \
ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \
$(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS}
${GENSCRIPTS} hppaelf "$(tdir_hppaelf)"
ehppalinux.c: $(srcdir)/emulparams/hppalinux.sh \
$(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} hppalinux "$(tdir_hppalinux)"
ei386aout.c: $(srcdir)/emulparams/i386aout.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} i386aout "$(tdir_i386aout)"

View File

@ -207,53 +207,53 @@ ALL_EMULATIONS = \
eaixrs6.o \
ealpha.o \
earcelf.o \
earmelf.o \
earmelf_oabi.o \
earmelf_linux.o \
earmelf_linux26.o \
earm_epoc_pe.o \
earmaoutb.o \
earmaoutl.o \
earmcoff.o \
earmelf.o \
earmelf_linux.o \
earmelf_linux26.o \
earmelf_oabi.o \
earmnbsd.o \
earmpe.o \
earm_epoc_pe.o \
eavr1200.o \
eavr23xx.o \
eavr44x4.o \
eavr4433.o \
eavr44x4.o \
eavr85xx.o \
eavrmega603.o \
eavrmega103.o \
eavrmega161.o \
eavrmega603.o \
ecoff_sparc.o \
ed10velf.o \
ed30velf.o \
ed30v_e.o \
ed30v_o.o \
ed30velf.o \
edelta68.o \
eebmon29k.o \
eelf32_sparc.o \
eelf32_i960.o \
eelf32_sparc.o \
eelf32b4300.o \
eelf32bmip.o \
eelf32ebmip.o \
eelf32elmip.o \
eelf32bmipn32.o \
eelf32btsmip.o \
eelf32ebmip.o \
eelf32elmip.o \
eelf32fr30.o \
eelf32i370.o \
eelf32l4300.o \
eelf32lmip.o \
eelf32lppc.o \
eelf32lppcsim.o \
eelf32mcore.o \
eelf32ppc.o \
eelf32ppcsim.o \
eelf32ppclinux.o \
eelf32ppcsim.o \
eelf_i386.o \
eelf_i386_be.o \
egld960.o \
egld960coff.o \
eelf32fr30.o \
eelf32mcore.o \
eh8300.o \
eh8300h.o \
eh8300s.o \
@ -264,6 +264,8 @@ ALL_EMULATIONS = \
eh8500s.o \
ehp300bsd.o \
ehp3hpux.o \
ehppaelf.o \
ehppalinux.o \
ei386aout.o \
ei386beos.o \
ei386bsd.o \
@ -302,10 +304,10 @@ ALL_EMULATIONS = \
emipslnews.o \
emipspe.o \
enews.o \
epjelf.o \
epjlelf.o \
ens32knbsd.o \
epc532macha.o \
epjelf.o \
epjlelf.o \
eppcmacos.o \
eppcnw.o \
eppcpe.o \
@ -313,8 +315,8 @@ ALL_EMULATIONS = \
esa29200.o \
esh.o \
eshelf.o \
eshlelf.o \
eshl.o \
eshlelf.o \
eshpe.o \
esparcaout.o \
esparclinux.o \
@ -335,21 +337,17 @@ ALL_EMULATIONS = \
ez8002.o
# The following object file has been removed from ALL_EMULATIONS
# because the BFD support is currently broken.
# ehppaelf.o
ALL_64_EMULATIONS = \
eelf64_ia64.o \
eelf64_sparc.o \
eelf64alpha.o \
eelf64hppa.o \
eelf64bmip.o
eelf64bmip.o \
eelf64hppa.o
ALL_EMUL_EXTRA_OFILES = \
pe-dll.o \
deffilep.o
deffilep.o \
pe-dll.o
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
@ -446,7 +444,7 @@ deffilep.c ldgram.c ldlex.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
TAR = tar
GZIP_ENV = --best
SOURCES = $(ld_new_SOURCES) $(EXTRA_ld_new_SOURCES)
OBJECTS = $(ld_new_OBJECTS)
@ -1222,6 +1220,9 @@ ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \
ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \
$(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS}
${GENSCRIPTS} hppaelf "$(tdir_hppaelf)"
ehppalinux.c: $(srcdir)/emulparams/hppalinux.sh \
$(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} hppalinux "$(tdir_hppalinux)"
ei386aout.c: $(srcdir)/emulparams/i386aout.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} i386aout "$(tdir_i386aout)"

View File

@ -208,6 +208,7 @@ m68*-*-netbsd*) targ_emul=m68knbsd ;;
m68*-*-psos*) targ_emul=m68kpsos ;;
m68*-*-rtems*) targ_emul=m68kcoff ;;
hppa*64*-*) targ_emul=elf64hppa ;;
hppa*-*-linux-gnu*) targ_emul=hppalinux ;;
hppa*-*-*elf*) targ_emul=hppaelf ;;
hppa*-*-linux-gnu*) targ_emul=hppaelf ;;
hppa*-*-lites*) targ_emul=hppaelf ;;

View File

@ -1,7 +1,7 @@
SCRIPT_NAME=hppaelf
OUTPUT_FORMAT="elf32-hppa"
TEXT_START_ADDR=0x1000
TARGET_PAGE_SIZE=4096
TARGET_PAGE_SIZE=0x1000
ARCH=hppa
START="$START$"
TEMPLATE_NAME=hppaelf

View File

@ -0,0 +1,10 @@
SCRIPT_NAME=elf
OUTPUT_FORMAT="elf32-hppa"
TEXT_START_ADDR=0x1000
TARGET_PAGE_SIZE=0x1000
MAXPAGESIZE=0x1000
ARCH=hppa
NOP=0x08000240
START="_start"
TEMPLATE_NAME=hppaelf
DATA_START_SYMBOLS='$global$ = .;'

View File

@ -1,8 +1,11 @@
# 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! */
/* An emulation for HP PA-RISC ELF linkers.
Copyright (C) 1991, 93, 94, 95, 97, 1999 Free Software Foundation, Inc.
Copyright (C) 1991, 93, 94, 95, 97, 99, 2000
Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
@ -23,25 +26,35 @@ 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 "ldemul.h"
#include "ldfile.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldmisc.h"
#include "ldmain.h"
#include "ldgram.h"
#include "ldctor.h"
#include "elf32-hppa.h"
/* Section in which we build stubs. */
static asection *stub_sec;
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));
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;
/* FIXME. This doesn't belong here. */
extern lang_statement_list_type file_chain;
/* Perform some emulation specific initialization. For PA ELF we set
up the local label prefix and the output architecture. */
@ -62,7 +75,7 @@ hppaelf_set_output_arch()
}
/* This is called before the input files are opened. We create a new
fake input file to hold the stub section. */
fake input file to hold the stub sections. */
static void
hppaelf_create_output_section_statements ()
@ -80,66 +93,46 @@ hppaelf_create_output_section_statements ()
return;
}
stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text");
/* Don't set SEC_RELOC until we actually have relocations in this
section. */
if (stub_sec == NULL
|| ! bfd_set_section_flags (stub_file->the_bfd, stub_sec,
(SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_IN_MEMORY)))
{
einfo ("%X%P: can not create stub section: %E\n");
return;
}
ldlang_add_file (stub_file);
}
/* Walk all the lang statements splicing out any padding statements from
/* Walk all the lang statements splicing out any padding statements from
the list. */
static void
hppaelf_delete_padding_statements (s, prev)
lang_statement_union_type *s;
lang_statement_union_type **prev;
hppaelf_delete_padding_statements (list)
lang_statement_list_type *list;
{
lang_statement_union_type *sprev = NULL;
for (; s != NULL; s = s->next)
lang_statement_union_type *s;
lang_statement_union_type **ps;
for (ps = &list->head; (s = *ps) != NULL; ps = &s->next)
{
switch (s->header.type)
{
/* We want recursively walk these sections. */
/* We want to recursively walk these sections. */
case lang_constructors_statement_enum:
hppaelf_delete_padding_statements (constructor_list.head,
&constructor_list.head);
hppaelf_delete_padding_statements (&constructor_list);
break;
case lang_output_section_statement_enum:
hppaelf_delete_padding_statements (s->output_section_statement.
children.head,
&s->output_section_statement.
children.head);
hppaelf_delete_padding_statements (&s->output_section_statement.children);
break;
case lang_group_statement_enum:
hppaelf_delete_padding_statements (&s->group_statement.children);
break;
/* Huh? What is a lang_wild_statement? */
case lang_wild_statement_enum:
hppaelf_delete_padding_statements (s->wild_statement.
children.head,
&s->wild_statement.
children.head);
hppaelf_delete_padding_statements (&s->wild_statement.children);
break;
/* Here's what we are really looking for. Splice these out of
the list. */
case lang_padding_statement_enum:
if (sprev)
sprev->header.next = s->header.next;
else
**prev = *s;
*ps = s->next;
if (*ps == NULL)
list->tail = ps;
break;
/* We don't care about these cases. */
@ -157,51 +150,435 @@ hppaelf_delete_padding_statements (s, prev)
abort ();
break;
}
sprev = s;
}
}
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 boolean
hook_in_stub (info, lp)
struct hook_stub_info *info;
lang_statement_union_type **lp;
{
lang_statement_union_type *l;
boolean ret;
for (; (l = *lp) != NULL; lp = &l->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 elf32_hppa_size_stubs. */
/* Create a new stub section, and arrange for it to be linked
immediately before INPUT_SECTION. */
static asection *
hppaelf_add_stub_section (stub_name, input_section)
const char *stub_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;
stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_name);
if (stub_sec == NULL)
goto err_ret;
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
| SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
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);
wild_doit (&info.add, stub_sec, os, stub_file);
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 elf32_hppa_size_stubs. */
static void
hppaelf_layaout_sections_again ()
{
/* 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. */
/* Delete all the padding statements, they're no longer valid. */
hppaelf_delete_padding_statements (stat_ptr);
/* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section,
&stat_ptr->head, 0, (bfd_vma) 0, false);
/* Redo special stuff. */
ldemul_after_allocation ();
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section,
(fill_type) 0, (bfd_vma) 0);
}
/* Final emulation specific call. For the PA we use this opportunity
to build linker stubs. */
static void
hppaelf_finish ()
{
/* If generating a relocateable output file, then we don't
have to examine the relocs. */
if (link_info.relocateable)
return;
/* Call into the BFD backend to do the real work. */
if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info)
== false)
if (elf32_hppa_size_stubs (stub_file->the_bfd,
&link_info,
&hppaelf_add_stub_section,
&hppaelf_layaout_sections_again) == false)
{
einfo ("%X%P: can not size stub section: %E\n");
return;
}
/* If the size of the stub section is nonzero, then we need
to resize the sections, recompute the assignments, and finally
build the stubs. */
if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0)
/* Now build the linker stubs. */
if (stub_file->the_bfd->sections != NULL)
{
/* Delete all the padding statements, they're no longer valid. */
hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head);
/* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section,
&stat_ptr->head, 0, (bfd_vma) 0, false);
/* Redo special stuff. */
ldemul_after_allocation ();
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head,
abs_output_section,
(fill_type) 0, (bfd_vma) 0);
/* Now build the linker stubs. */
if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false)
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
{
einfo ("%X%P: can not build stubs: %E\n");
return;
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. */
@ -219,7 +596,7 @@ then
sc="-f stringify.sed"
cat >>e${EMULATION_NAME}.c <<EOF
{
{
*isfile = 0;
if (link_info.relocateable == true && config.build_constructors == true)
@ -232,6 +609,12 @@ echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}
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
@ -251,6 +634,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
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";
}
@ -260,7 +645,7 @@ fi
cat >>e${EMULATION_NAME}.c <<EOF
struct ld_emulation_xfer_struct ld_hppaelf_emulation =
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
hppaelf_before_parse,
syslib_default,
@ -272,17 +657,17 @@ struct ld_emulation_xfer_struct ld_hppaelf_emulation =
ldemul_default_target,
before_allocation_default,
hppaelf_get_script,
"hppaelf",
"${EMULATION_NAME}",
"elf32-hppa",
hppaelf_finish,
hppaelf_create_output_section_statements,
NULL, /* open dynamic archive */
NULL, /* place orphan */
NULL, /* set symbols */
NULL, /* parse args */
NULL, /* unrecognized file */
NULL, /* list options */
NULL, /* recognized file */
NULL /* find_potential_libraries */
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