Add support for ELF shared libraries.

* ld.h (ld_config_type): Add field dynamic_link.
	* ldmain.c (main): Initialize config.dynamic_link to false.  Warn
	on attempts to use -r with -relax, -call_shared or -s.
	* lexsup.c (longopts): Separate OPTION_CALL_SHARED from
	OPTION_NON_SHARED.  Add OPTION_IGNORE.  Adjust macro values
	accordingly.  Add "dy" and "non_shared" options.  Change "Qy" to
	OPTION_IGNORE for now.  Handle OPTION_CALL_SHARED and
	OPTION_NON_SHARED by setting dynamic_link field accordingly.
	Handle OPTION_IGNORE by ignoring it.  Clear dynamic_link field for
	-r and -Ur.
	* ldfile.c (ldfile_open_file): If config.dynamic_link is true, try
	opening a file with a .so extension first.
	* emultempl/elf32.em: New file.
	* emulparams/elf32_sparc.sh (TEXT_START_ADDR): Change to 0x10000.
	(NONPAGED_TEXT_START_ADDR): Likewise.
	(TEMPLATE_NAME): Define as elf32.
	(DATA_PLT): Define.
	* emulparams/elf_i386.sh (TEMPLATE_NAME): Define as elf32.
	* scripttempl/elf.sc: Add placement for new dynamic sections.
	Don't use CREATE_OBJECT_SYMBOLS.  Define _etext, _edata and _end
	outside of any section.  Don't use ALIGN(8); just let one section
	VMA follow another.  Put .dynbss in .bss.  Don't mention debugging
	sections; they'll be handled correctly anyhow.
	* Makefile.in (eelf_i386.c): Depend upon elf32.em, not generic.em.
This commit is contained in:
Ian Lance Taylor 1994-05-19 18:25:10 +00:00
parent 013dec1ad9
commit 2a9fa50cd8
9 changed files with 410 additions and 170 deletions

View File

@ -1,3 +1,31 @@
Thu May 19 13:31:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
Add support for ELF shared libraries.
* ld.h (ld_config_type): Add field dynamic_link.
* ldmain.c (main): Initialize config.dynamic_link to false. Warn
on attempts to use -r with -relax, -call_shared or -s.
* lexsup.c (longopts): Separate OPTION_CALL_SHARED from
OPTION_NON_SHARED. Add OPTION_IGNORE. Adjust macro values
accordingly. Add "dy" and "non_shared" options. Change "Qy" to
OPTION_IGNORE for now. Handle OPTION_CALL_SHARED and
OPTION_NON_SHARED by setting dynamic_link field accordingly.
Handle OPTION_IGNORE by ignoring it. Clear dynamic_link field for
-r and -Ur.
* ldfile.c (ldfile_open_file): If config.dynamic_link is true, try
opening a file with a .so extension first.
* emultempl/elf32.em: New file.
* emulparams/elf32_sparc.sh (TEXT_START_ADDR): Change to 0x10000.
(NONPAGED_TEXT_START_ADDR): Likewise.
(TEMPLATE_NAME): Define as elf32.
(DATA_PLT): Define.
* emulparams/elf_i386.sh (TEMPLATE_NAME): Define as elf32.
* scripttempl/elf.sc: Add placement for new dynamic sections.
Don't use CREATE_OBJECT_SYMBOLS. Define _etext, _edata and _end
outside of any section. Don't use ALIGN(8); just let one section
VMA follow another. Put .dynbss in .bss. Don't mention debugging
sections; they'll be handled correctly anyhow.
* Makefile.in (eelf_i386.c): Depend upon elf32.em, not generic.em.
Wed May 18 10:15:39 1994 Ian Lance Taylor (ian@cygnus.com)
* Makefile.in (install): Redirect output of ln to /dev/null.

View File

@ -372,7 +372,7 @@ emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
${GENSCRIPTS} mipsidtl
eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf_i386
eelf32mipb.c: $(srcdir)/emulparams/elf32mipb.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}

View File

@ -25,6 +25,7 @@ Do-first:
Things-to-keep:
README
elf32.em
generic.em
gld960.em
gld960c.em

196
ld/emultempl/elf32.em Normal file
View File

@ -0,0 +1,196 @@
# 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! */
/* 32 bit ELF emulation code for ${EMULATION_NAME}
Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define TARGET_IS_${EMULATION_NAME}
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "ld.h"
#include "config.h"
#include "ldmain.h"
#include "ldemul.h"
#include "ldfile.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
static void gld${EMULATION_NAME}_find_statement_assignment
PARAMS ((lang_statement_union_type *));
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static void
gld${EMULATION_NAME}_before_parse()
{
ldfile_output_architecture = bfd_arch_${ARCH};
config.dynamic_link = true;
}
/* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */
static void
gld${EMULATION_NAME}_before_allocation ()
{
/* If we are going to make any variable assignments, we need to let
the ELF backend know about them in case the variables are
referred to by dynamic objects. */
lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
/* Let the ELF backend work out the sizes of any sections required
by dynamic linking. */
if (! bfd_elf32_size_dynamic_sections (output_bfd, &link_info))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
}
/* This is called by the before_allocation routine via
lang_for_each_statement. It locates any assignment statements, and
tells the ELF backend about them, in case they are assignments to
symbols which are referred to by dynamic objects. */
static void
gld${EMULATION_NAME}_find_statement_assignment (s)
lang_statement_union_type *s;
{
if (s->header.type == lang_assignment_statement_enum)
gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
}
/* Look through an expression for an assignment statement. */
static void
gld${EMULATION_NAME}_find_exp_assignment (exp)
etree_type *exp;
{
switch (exp->type.node_class)
{
case etree_assign:
if (strcmp (exp->assign.dst, ".") != 0)
{
if (! bfd_elf32_record_link_assignment (output_bfd, &link_info,
exp->assign.dst))
einfo ("%P%F: failed to record assignment to %s: %E\n",
exp->assign.dst);
}
gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
break;
case etree_binary:
gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
break;
case etree_trinary:
gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
break;
case etree_unary:
gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
break;
default:
break;
}
}
static char *
gld${EMULATION_NAME}_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='s/["\\]/\\&/g
s/$/\\n\\/
1s/^/"/
$s/$/n"/
'
cat >>e${EMULATION_NAME}.c <<EOF
{
*isfile = 0;
if (link_info.relocateable == true && config.build_constructors == true)
return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
else if (link_info.relocateable == true)
return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
else if (!config.text_read_only)
return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
else if (!config.magic_demand_paged)
return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
else
return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
}
EOF
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
return "ldscripts/${EMULATION_NAME}.x";
}
EOF
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,
after_allocation_default,
set_output_arch_default,
ldemul_default_target,
gld${EMULATION_NAME}_before_allocation,
gld${EMULATION_NAME}_get_script,
"${EMULATION_NAME}",
"${OUTPUT_FORMAT}"
};
EOF

85
ld/ld.h
View File

@ -18,66 +18,41 @@
along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef LD_H
#define LD_H
#define flag_is_not_at_end(x) ((x) & BSF_NOT_AT_END)
#define flag_is_ordinary_local(x) (((x) & (BSF_LOCAL))&!((x) & (BSF_DEBUGGING)))
#define flag_is_debugger(x) ((x) & BSF_DEBUGGING)
#define flag_is_undefined_or_global(x) ((x) & (BSF_UNDEFINED | BSF_GLOBAL))
#define flag_is_defined(x) (!((x) & (BSF_UNDEFINED)))
#define flag_is_global_or_common(x) ((x) & (BSF_GLOBAL | BSF_FORT_COMM))
#define flag_is_undefined_or_global_or_common(x) ((x) & (BSF_UNDEFINED | BSF_GLOBAL | BSF_FORT_COMM))
#define flag_is_undefined_or_global_or_common_or_constructor(x) ((x) & (BSF_UNDEFINED | BSF_GLOBAL | BSF_FORT_COMM | BSF_CONSTRUCTOR))
#define flag_is_constructor(x) ((x) & BSF_CONSTRUCTOR)
#define flag_is_common(x) ((x) & BSF_FORT_COMM)
#define flag_is_global(x) ((x) & (BSF_GLOBAL))
#define flag_is_weak(x) ((x) & BSF_WEAK)
#define flag_is_undefined(x) ((x) & BSF_UNDEFINED)
#define flag_set(x,y) (x = y)
#define flag_is_fort_comm(x) ((x) & BSF_FORT_COMM)
#define flag_is_absolute(x) ((x) & BSF_ABSOLUTE)
/* Extra information we hold on sections */
typedef struct user_section_struct {
typedef struct user_section_struct
{
/* Pointer to the section where this data will go */
struct lang_input_statement_struct *file;
} section_userdata_type;
#define get_userdata(x) ((x)->userdata)
#define as_output_section_statement(x) ((x)->otheruserdata)
/* Which symbols should be stripped (omitted from the output):
none, all, or debugger symbols. */
typedef enum { STRIP_NONE, STRIP_ALL, STRIP_DEBUGGER, STRIP_SOME } strip_symbols_type;
/* Which local symbols should be omitted:
none, all, or those starting with L.
This is irrelevant if STRIP_NONE. */
typedef enum { DISCARD_NONE, DISCARD_ALL, DISCARD_L } discard_locals_type;
#define BYTE_SIZE (1)
#define SHORT_SIZE (2)
#define LONG_SIZE (4)
#define QUAD_SIZE (8)
/* ALIGN macro changed to ALIGN_N to avoid */
/* conflict in /usr/include/machine/machparam.h */
/* WARNING: If THIS is a 64 bit address and BOUNDARY is an unsigned int,
/* WARNING: If THIS is a 64 bit address and BOUNDARY is a 32 bit int,
you must coerce boundary to the same type as THIS.
??? Is there a portable way to avoid this. */
#define ALIGN_N(this, boundary) ((( (this) + ((boundary) -1)) & (~((boundary)-1))))
#define ALIGN_N(this, boundary) \
((( (this) + ((boundary) -1)) & (~((boundary)-1))))
typedef struct {
typedef struct
{
/* 1 => assign space to common symbols even if `relocatable_output'. */
boolean force_common_definition;
boolean relax;
} args_type;
extern args_type command_line;
typedef int token_code_type;
typedef struct
@ -85,41 +60,37 @@ typedef struct
bfd_size_type specified_data_size;
boolean magic_demand_paged;
boolean make_executable;
/* 1 => write relocation into output file so can re-input it later. */
boolean relocateable_output;
/* Will we build contstructors, or leave alone ? */
/* If true, doing a dynamic link. */
boolean dynamic_link;
boolean build_constructors;
/* If true, warn about merging common symbols with others. */
boolean warn_common;
boolean sort_common;
/* these flags may seem mutually exclusive, but not setting them
allows the back end to decide what would be the best thing to do */
boolean text_read_only;
char *map_filename;
FILE *map_file;
char *map_filename;
FILE *map_file;
boolean stats;
} ld_config_type;
#define set_asymbol_chain(x,y) ((x)->udata = (PTR)y)
#define get_asymbol_chain(x) ((asymbol **)((x)->udata))
#define get_loader_symbol(x) ((loader_global_asymbol *)((x)->udata))
#define set_loader_symbol(x,y) ((x)->udata = (PTR)y)
extern ld_config_type config;
typedef enum {
typedef enum
{
lang_first_phase_enum,
lang_allocating_phase_enum,
lang_final_phase_enum } lang_phase_type;
lang_final_phase_enum
} lang_phase_type;
extern boolean had_script;
extern boolean force_make_executable;
extern int yyparse PARAMS ((void));
int yyparse();
#endif

View File

@ -1,5 +1,4 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@ -32,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ldlang.h"
#include "ldfile.h"
#include "ldmain.h"
#include "ldgram.h"
#include "ldlex.h"
#include <ctype.h>
@ -89,7 +89,7 @@ ldfile_add_library_path(name)
char *name;
{
search_dirs_type *new =
(search_dirs_type *)ldmalloc((bfd_size_type)(sizeof(search_dirs_type)));
(search_dirs_type *)xmalloc((bfd_size_type)(sizeof(search_dirs_type)));
new->name = name;
new->next = (search_dirs_type*)NULL;
*search_tail_ptr = new;
@ -160,41 +160,42 @@ open_a(arch, entry, lib, suffix)
void
ldfile_open_file (entry)
lang_input_statement_type *entry;
lang_input_statement_type *entry;
{
if (entry->superfile)
if (entry->superfile != NULL)
ldfile_open_file (entry->superfile);
if (entry->search_dirs_flag)
if (! entry->search_dirs_flag)
entry->the_bfd = cached_bfd_openr (entry->filename, entry);
else
{
search_arch_type *arch;
/* Try to open <filename><suffix> or lib<filename><suffix>.a */
for (arch = search_arch_head;
arch != (search_arch_type *)NULL;
arch = arch->next) {
if (open_a(arch->name,entry,"lib",".a") != (bfd *)NULL) {
return;
}
arch != (search_arch_type *) NULL;
arch = arch->next)
{
if (config.dynamic_link)
{
/* FIXME: Perhaps we will sometimes want something other
than .so. */
if (open_a (arch->name, entry, "lib", ".so") != (bfd *) NULL)
return;
}
if (open_a (arch->name, entry, "lib", ".a") != (bfd *) NULL)
return;
#ifdef VMS
if (open_a(arch->name,entry,":lib",".a") != (bfd *)NULL) {
return;
}
if (open_a (arch->name, entry, ":lib", ".a") != (bfd *) NULL)
return;
#endif
}
}
}
else {
entry->the_bfd = cached_bfd_openr (entry->filename, entry);
}
if (!entry->the_bfd)
if (entry->the_bfd == NULL)
einfo("%F%P: cannot open %s: %E\n", entry->local_sym_name);
}
/* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */
static FILE *
@ -264,6 +265,7 @@ char *name;
ldlex_input_stack = ldfile_find_command_file(name, "");
if (ldlex_input_stack == (FILE *)NULL) {
bfd_set_error (bfd_error_system_call);
einfo("%P%F: cannot open linker script file %s: %E\n",name);
}
lex_push_file(ldlex_input_stack, name);
@ -316,7 +318,7 @@ ldfile_add_arch(name)
char *name;
{
search_arch_type *new =
(search_arch_type *)ldmalloc((bfd_size_type)(sizeof(search_arch_type)));
(search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
if (*name != '\0') {
@ -343,7 +345,7 @@ ldfile_add_arch (in_name)
{
char *name = buystring(in_name);
search_arch_type *new =
(search_arch_type *)ldmalloc((bfd_size_type)(sizeof(search_arch_type)));
(search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
ldfile_output_machine_name = in_name;

View File

@ -72,9 +72,6 @@ boolean trace_file_tries;
instead of complaining if no input files are given. */
boolean version_printed;
/* 1 => write load map. */
boolean write_map;
args_type command_line;
ld_config_type config;
@ -93,11 +90,10 @@ static boolean multiple_common PARAMS ((struct bfd_link_info *,
bfd_vma));
static boolean add_to_set PARAMS ((struct bfd_link_info *,
struct bfd_link_hash_entry *,
unsigned int bitsize,
bfd_reloc_code_real_type,
bfd *, asection *, bfd_vma));
static boolean constructor_callback PARAMS ((struct bfd_link_info *,
boolean constructor,
unsigned int bitsize,
const char *name,
bfd *, asection *, bfd_vma));
static boolean warning_callback PARAMS ((struct bfd_link_info *,
@ -162,8 +158,8 @@ main (argc, argv)
/* Initialize the data about options. */
trace_files = trace_file_tries = version_printed = false;
write_map = false;
config.build_constructors = true;
config.dynamic_link = false;
command_line.force_common_definition = false;
link_info.callbacks = &link_callbacks;
@ -195,6 +191,16 @@ main (argc, argv)
lang_has_input_file = false;
parse_args (argc, argv);
if (link_info.relocateable)
{
if (command_line.relax)
einfo ("%P%F: -relax and -r may not be used together\n");
if (config.dynamic_link)
einfo ("%P%F: -r and -call_shared may not be used together\n");
if (link_info.strip == strip_all)
einfo ("%P%F: -r and -s may not be used together\n");
}
/* This essentially adds another -L directory so this must be done after
the -L's in argv have been processed. */
set_scripts_dir ();
@ -213,10 +219,6 @@ main (argc, argv)
yyparse ();
}
if (link_info.relocateable && command_line.relax)
{
einfo ("%P%F: -relax and -r may not be used together\n");
}
lang_final ();
if (lang_has_input_file == false)
@ -296,7 +298,8 @@ main (argc, argv)
}
else
{
bfd_close (output_bfd);
if (! bfd_close (output_bfd))
einfo ("%F%B: final close failed: %E\n", output_bfd);
}
if (config.stats)
@ -568,8 +571,8 @@ add_archive_element (info, abfd, name)
ldlang_add_file (input);
if (write_map)
info_msg ("%s needed due to %T\n", abfd->filename, name);
if (config.map_file != (FILE *) NULL)
minfo ("%s needed due to %T\n", abfd->filename, name);
if (trace_files || trace_file_tries)
info_msg ("%I\n", input);
@ -664,15 +667,28 @@ multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
/*ARGSUSED*/
static boolean
add_to_set (info, h, bitsize, abfd, section, value)
add_to_set (info, h, reloc, abfd, section, value)
struct bfd_link_info *info;
struct bfd_link_hash_entry *h;
unsigned int bitsize;
bfd_reloc_code_real_type reloc;
bfd *abfd;
asection *section;
bfd_vma value;
{
ldctor_add_set_entry (h, bitsize, section, value);
if (! config.build_constructors)
return true;
ldctor_add_set_entry (h, reloc, section, value);
if (h->type == bfd_link_hash_new)
{
h->type = bfd_link_hash_undefined;
h->u.undef.abfd = abfd;
/* We don't call bfd_link_add_undef to add this to the list of
undefined symbols because we are going to define it
ourselves. */
}
return true;
}
@ -682,10 +698,9 @@ add_to_set (info, h, bitsize, abfd, section, value)
adding an element to a set, but less general. */
static boolean
constructor_callback (info, constructor, bitsize, name, abfd, section, value)
constructor_callback (info, constructor, name, abfd, section, value)
struct bfd_link_info *info;
boolean constructor;
unsigned int bitsize;
const char *name;
bfd *abfd;
asection *section;
@ -698,6 +713,11 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
if (! config.build_constructors)
return true;
/* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
useful error message. */
if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL)
einfo ("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported");
set_name = (char *) alloca (1 + sizeof "__CTOR_LIST__");
s = set_name;
if (bfd_get_symbol_leading_char (abfd) != '\0')
@ -707,8 +727,9 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
else
strcpy (s, "__DTOR_LIST__");
if (write_map)
info_msg ("Adding %s to constructor/destructor set %s\n", name, set_name);
if (config.map_file != (FILE *) NULL)
fprintf (config.map_file,
"Adding %s to constructor/destructor set %s\n", name, set_name);
h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
if (h == (struct bfd_link_hash_entry *) NULL)
@ -722,7 +743,7 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
ourselves. */
}
ldctor_add_set_entry (h, bitsize, section, value);
ldctor_add_set_entry (h, BFD_RELOC_CTOR, section, value);
return true;
}
@ -790,8 +811,11 @@ reloc_overflow (info, name, reloc_name, addend, abfd, section, address)
asection *section;
bfd_vma address;
{
einfo ("%X%C: relocation truncated to fit: %s %T", abfd, section,
address, reloc_name, name);
if (abfd == (bfd *) NULL)
einfo ("%P%X: generated");
else
einfo ("%X%C:", abfd, section, address);
einfo (" relocation truncated to fit: %s %T", reloc_name, name);
if (addend != 0)
einfo ("+%v", addend);
einfo ("\n");
@ -809,7 +833,11 @@ reloc_dangerous (info, message, abfd, section, address)
asection *section;
bfd_vma address;
{
einfo ("%X%C: dangerous relocation: %s\n", abfd, section, address, message);
if (abfd == (bfd *) NULL)
einfo ("%P%X: generated");
else
einfo ("%X%C:", abfd, section, address);
einfo ("dangerous relocation: %s\n", message);
return true;
}
@ -825,8 +853,11 @@ unattached_reloc (info, name, abfd, section, address)
asection *section;
bfd_vma address;
{
einfo ("%X%C: reloc refers to symbol `%T' which is not being output\n",
abfd, section, address, name);
if (abfd == (bfd *) NULL)
einfo ("%P%X: generated");
else
einfo ("%X%C:", abfd, section, address);
einfo (" reloc refers to symbol `%T' which is not being output\n", name);
return true;
}

View File

@ -57,50 +57,53 @@ parse_args (argc, argv)
static struct option longopts[] = {
#define OPTION_CALL_SHARED 150
#define OPTION_NON_SHARED 151
{"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
{"dc", no_argument, NULL, 'd'},
#define OPTION_DEFSYM 151
#define OPTION_DEFSYM 152
{"defsym", required_argument, NULL, OPTION_DEFSYM},
{"dn", no_argument, NULL, OPTION_CALL_SHARED},
{"dn", no_argument, NULL, OPTION_NON_SHARED},
{"dp", no_argument, NULL, 'd'},
#define OPTION_EB 152
{"dy", no_argument, NULL, OPTION_CALL_SHARED},
#define OPTION_EB 153
{"EB", no_argument, NULL, OPTION_EB},
#define OPTION_EL 153
#define OPTION_EL 154
{"EL", no_argument, NULL, OPTION_EL},
{"format", required_argument, NULL, 'b'},
#define OPTION_HELP 154
#define OPTION_HELP 155
{"help", no_argument, NULL, OPTION_HELP},
#define OPTION_MAP 155
#define OPTION_MAP 156
{"Map", required_argument, NULL, OPTION_MAP},
#define OPTION_NO_KEEP_MEMORY 156
#define OPTION_NO_KEEP_MEMORY 157
{"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
#define OPTION_NOINHIBIT_EXEC 157
#define OPTION_NOINHIBIT_EXEC 158
{"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
{"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
{"non_shared", no_argument, NULL, OPTION_CALL_SHARED},
#define OPTION_OFORMAT 158
{"non_shared", no_argument, NULL, OPTION_NON_SHARED},
#define OPTION_OFORMAT 159
{"oformat", required_argument, NULL, OPTION_OFORMAT},
{"Qy", no_argument, NULL, OPTION_CALL_SHARED},
#define OPTION_RELAX 159
#define OPTION_IGNORE 160
{"Qy", no_argument, NULL, OPTION_IGNORE},
#define OPTION_RELAX 161
{"relax", no_argument, NULL, OPTION_RELAX},
#define OPTION_RETAIN_SYMBOLS_FILE 160
#define OPTION_RETAIN_SYMBOLS_FILE 162
{"retain-symbols-file", no_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
#define OPTION_SORT_COMMON 161
#define OPTION_SORT_COMMON 163
{"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
{"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
#define OPTION_STATS 162
#define OPTION_STATS 164
{"stats", no_argument, NULL, OPTION_STATS},
#define OPTION_TBSS 163
#define OPTION_TBSS 165
{"Tbss", required_argument, NULL, OPTION_TBSS},
#define OPTION_TDATA 164
#define OPTION_TDATA 166
{"Tdata", required_argument, NULL, OPTION_TDATA},
#define OPTION_TTEXT 165
#define OPTION_TTEXT 167
{"Ttext", required_argument, NULL, OPTION_TTEXT},
#define OPTION_UR 166
#define OPTION_UR 168
{"Ur", no_argument, NULL, OPTION_UR},
#define OPTION_VERSION 167
#define OPTION_VERSION 169
{"version", no_argument, NULL, OPTION_VERSION},
#define OPTION_WARN_COMMON 168
#define OPTION_WARN_COMMON 170
{"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
{NULL, no_argument, NULL, 0}
};
@ -124,6 +127,8 @@ parse_args (argc, argv)
(char *) NULL);
break;
case OPTION_IGNORE:
break;
case 'A':
ldfile_add_arch (optarg);
break;
@ -139,7 +144,10 @@ parse_args (argc, argv)
yyparse ();
break;
case OPTION_CALL_SHARED:
set_default_dirlist ((char *) longopts[longind].name);
config.dynamic_link = true;
break;
case OPTION_NON_SHARED:
config.dynamic_link = false;
break;
case 'd':
command_line.force_common_definition = true;
@ -194,7 +202,6 @@ parse_args (argc, argv)
/* Ignore. Was handled in a pre-parse. */
break;
case OPTION_MAP:
write_map = true;
config.map_filename = optarg;
break;
case 'N':
@ -229,6 +236,7 @@ parse_args (argc, argv)
config.build_constructors = false;
config.magic_demand_paged = false;
config.text_read_only = false;
config.dynamic_link = false;
break;
case 'R':
lang_add_input_file (optarg,
@ -275,6 +283,7 @@ parse_args (argc, argv)
config.build_constructors = true;
config.magic_demand_paged = false;
config.text_read_only = false;
config.dynamic_link = false;
break;
case 'u':
ldlang_add_undef (optarg);

View File

@ -8,12 +8,18 @@
# (e.g., .PARISC.global)
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
# executable (e.g., _DYNAMIC_LINK)
# TEXT_START_SYMBOLS - symbols that appear at the start of the
# .text section.
# DATA_START_SYMBOLS - symbols that appear at the start of the
# .data section.
# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
# .bss section besides __bss_start.
# DATA_PLT - .plt should be in data segment, not text segment.
#
# When adding sections, do note that the names of some sections are used
# when specifying the start address of the next.
#
PLT=".plt ${RELOCATING-0} : { *(.plt) }"
cat <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}")
OUTPUT_ARCH(${ARCH})
@ -29,62 +35,58 @@ ${RELOCATING- /* For some reason, the Solaris linker makes bad executables
SECTIONS
{
/* Read-only sections, merged into text segment: */
.text ${RELOCATING+${TEXT_START_ADDR}} ${RELOCATING-0} :
${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}
.interp ${RELOCATING-0} : { *(.interp) }
.hash ${RELOCATING-0} : { *(.hash) }
.dynsym ${RELOCATING-0} : { *(.dynsym) }
.dynstr ${RELOCATING-0} : { *(.dynstr) }
.rel.bss ${RELOCATING-0} : { *(.rel.bss) }
.rel.plt ${RELOCATING-0} : { *(.rel.plt) }
.rela.bss ${RELOCATING-0} : { *(.rela.bss) }
.rela.plt ${RELOCATING-0} : { *(.rela.plt) }
.init ${RELOCATING-0} : { *(.init) } =${NOP-0}
${DATA_PLT-${PLT}}
.text ${RELOCATING-0} :
{
${RELOCATING+${TEXT_START_SYMBOLS}}
*(.text)
CREATE_OBJECT_SYMBOLS
${RELOCATING+_etext = .;}
}
.init ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.init) } =${NOP-0}
.fini ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.fini) } =${NOP-0}
.ctors ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.ctors) }
.dtors ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.dtors) }
.rodata ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.rodata) }
.rodata1 ${RELOCATING+ALIGN(8)} ${RELOCATING-0} :
{
*(.rodata1)
${RELOCATING+. = ALIGN(8);}
}
${RELOCATING+_etext = .;}
.fini ${RELOCATING-0} : { *(.fini) } =${NOP-0}
.ctors ${RELOCATING-0} : { *(.ctors) }
.dtors ${RELOCATING-0} : { *(.dtors) }
.rodata ${RELOCATING-0} : { *(.rodata) }
.rodata1 ${RELOCATING-0} : { *(.rodata1) }
${RELOCATING+${OTHER_READONLY_SECTIONS}}
/* also: .hash .dynsym .dynstr .plt(if r/o) .rel.got */
/* Read-write section, merged into data segment: */
.data ${RELOCATING+
${DATA_ADDR- ADDR(.rodata1)+SIZEOF(.rodata1)+${MAXPAGESIZE}}
}
${RELOCATING-0} :
${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
.data ${RELOCATING-0} :
{
${RELOCATING+${DATA_START_SYMBOLS}}
*(.data)
${CONSTRUCTING+CONSTRUCTORS}
}
.data1 ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.data1) }
.data1 ${RELOCATING-0} : { *(.data1) }
${RELOCATING+${OTHER_READWRITE_SECTIONS}}
/* also (before uninitialized portion): .dynamic .got .plt(if r/w)
(or does .dynamic go into its own segment?) */
.got ${RELOCATING-0} : { *(.got) }
.dynamic ${RELOCATING-0} : { *(.dynamic) }
${DATA_PLT+${PLT}}
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.sdata) }
.sdata ${RELOCATING-0} : { *(.sdata) }
${RELOCATING+_edata = .;}
${RELOCATING+__bss_start = ALIGN(8);}
${RELOCATING+__bss_start = .;}
${RELOCATING+${OTHER_BSS_SYMBOLS}}
.sbss ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.sbss) *(.scommon) }
.bss ${RELOCATING+ALIGN(8)} ${RELOCATING-0} :
.sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) }
.bss ${RELOCATING-0} :
{
*(.dynbss)
*(.bss)
*(COMMON)
${RELOCATING+_end = . };
${RELOCATING+end = . };
}
/* Debug sections. These should never be loadable, but they must have
zero addresses for the debuggers to work correctly. */
.line 0 : { *(.line) }
.debug 0 : { *(.debug) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
${RELOCATING+_end = . ;}
${RELOCATING+end = . ;}
}
EOF