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:
parent
013dec1ad9
commit
2a9fa50cd8
9 changed files with 410 additions and 170 deletions
28
ld/ChangeLog
28
ld/ChangeLog
|
@ -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)
|
Wed May 18 10:15:39 1994 Ian Lance Taylor (ian@cygnus.com)
|
||||||
|
|
||||||
* Makefile.in (install): Redirect output of ln to /dev/null.
|
* Makefile.in (install): Redirect output of ln to /dev/null.
|
||||||
|
|
|
@ -372,7 +372,7 @@ emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \
|
||||||
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
|
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
|
||||||
${GENSCRIPTS} mipsidtl
|
${GENSCRIPTS} mipsidtl
|
||||||
eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
|
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
|
${GENSCRIPTS} elf_i386
|
||||||
eelf32mipb.c: $(srcdir)/emulparams/elf32mipb.sh \
|
eelf32mipb.c: $(srcdir)/emulparams/elf32mipb.sh \
|
||||||
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||||
|
|
|
@ -25,6 +25,7 @@ Do-first:
|
||||||
Things-to-keep:
|
Things-to-keep:
|
||||||
|
|
||||||
README
|
README
|
||||||
|
elf32.em
|
||||||
generic.em
|
generic.em
|
||||||
gld960.em
|
gld960.em
|
||||||
gld960c.em
|
gld960c.em
|
||||||
|
|
196
ld/emultempl/elf32.em
Normal file
196
ld/emultempl/elf32.em
Normal 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
85
ld/ld.h
|
@ -18,66 +18,41 @@
|
||||||
along with GLD; see the file COPYING. If not, write to
|
along with GLD; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
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 */
|
/* 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 */
|
/* Pointer to the section where this data will go */
|
||||||
struct lang_input_statement_struct *file;
|
struct lang_input_statement_struct *file;
|
||||||
} section_userdata_type;
|
} section_userdata_type;
|
||||||
|
|
||||||
|
|
||||||
#define get_userdata(x) ((x)->userdata)
|
#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 BYTE_SIZE (1)
|
||||||
#define SHORT_SIZE (2)
|
#define SHORT_SIZE (2)
|
||||||
#define LONG_SIZE (4)
|
#define LONG_SIZE (4)
|
||||||
|
#define QUAD_SIZE (8)
|
||||||
|
|
||||||
/* ALIGN macro changed to ALIGN_N to avoid */
|
/* ALIGN macro changed to ALIGN_N to avoid */
|
||||||
/* conflict in /usr/include/machine/machparam.h */
|
/* 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.
|
you must coerce boundary to the same type as THIS.
|
||||||
??? Is there a portable way to avoid 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'. */
|
/* 1 => assign space to common symbols even if `relocatable_output'. */
|
||||||
boolean force_common_definition;
|
boolean force_common_definition;
|
||||||
boolean relax;
|
boolean relax;
|
||||||
|
|
||||||
} args_type;
|
} args_type;
|
||||||
|
|
||||||
|
extern args_type command_line;
|
||||||
|
|
||||||
typedef int token_code_type;
|
typedef int token_code_type;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -85,41 +60,37 @@ typedef struct
|
||||||
bfd_size_type specified_data_size;
|
bfd_size_type specified_data_size;
|
||||||
boolean magic_demand_paged;
|
boolean magic_demand_paged;
|
||||||
boolean make_executable;
|
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;
|
boolean build_constructors;
|
||||||
|
|
||||||
/* If true, warn about merging common symbols with others. */
|
/* If true, warn about merging common symbols with others. */
|
||||||
boolean warn_common;
|
boolean warn_common;
|
||||||
|
|
||||||
boolean sort_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;
|
boolean text_read_only;
|
||||||
|
|
||||||
char *map_filename;
|
char *map_filename;
|
||||||
FILE *map_file;
|
FILE *map_file;
|
||||||
|
|
||||||
|
boolean stats;
|
||||||
} ld_config_type;
|
} 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_first_phase_enum,
|
||||||
lang_allocating_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));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int yyparse();
|
|
||||||
|
|
54
ld/ldfile.c
54
ld/ldfile.c
|
@ -1,5 +1,4 @@
|
||||||
|
/* Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
|
||||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GLD, the Gnu Linker.
|
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 "ldlang.h"
|
||||||
#include "ldfile.h"
|
#include "ldfile.h"
|
||||||
#include "ldmain.h"
|
#include "ldmain.h"
|
||||||
|
#include "ldgram.h"
|
||||||
#include "ldlex.h"
|
#include "ldlex.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -89,7 +89,7 @@ ldfile_add_library_path(name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
search_dirs_type *new =
|
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->name = name;
|
||||||
new->next = (search_dirs_type*)NULL;
|
new->next = (search_dirs_type*)NULL;
|
||||||
*search_tail_ptr = new;
|
*search_tail_ptr = new;
|
||||||
|
@ -160,41 +160,42 @@ open_a(arch, entry, lib, suffix)
|
||||||
|
|
||||||
void
|
void
|
||||||
ldfile_open_file (entry)
|
ldfile_open_file (entry)
|
||||||
lang_input_statement_type *entry;
|
lang_input_statement_type *entry;
|
||||||
{
|
{
|
||||||
|
if (entry->superfile != NULL)
|
||||||
if (entry->superfile)
|
|
||||||
ldfile_open_file (entry->superfile);
|
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;
|
search_arch_type *arch;
|
||||||
|
|
||||||
/* Try to open <filename><suffix> or lib<filename><suffix>.a */
|
/* Try to open <filename><suffix> or lib<filename><suffix>.a */
|
||||||
|
|
||||||
for (arch = search_arch_head;
|
for (arch = search_arch_head;
|
||||||
arch != (search_arch_type *)NULL;
|
arch != (search_arch_type *) NULL;
|
||||||
arch = arch->next) {
|
arch = arch->next)
|
||||||
if (open_a(arch->name,entry,"lib",".a") != (bfd *)NULL) {
|
{
|
||||||
return;
|
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
|
#ifdef VMS
|
||||||
if (open_a(arch->name,entry,":lib",".a") != (bfd *)NULL) {
|
if (open_a (arch->name, entry, ":lib", ".a") != (bfd *) NULL)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
#endif
|
#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);
|
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. */
|
/* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */
|
||||||
|
|
||||||
static FILE *
|
static FILE *
|
||||||
|
@ -264,6 +265,7 @@ char *name;
|
||||||
ldlex_input_stack = ldfile_find_command_file(name, "");
|
ldlex_input_stack = ldfile_find_command_file(name, "");
|
||||||
|
|
||||||
if (ldlex_input_stack == (FILE *)NULL) {
|
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);
|
einfo("%P%F: cannot open linker script file %s: %E\n",name);
|
||||||
}
|
}
|
||||||
lex_push_file(ldlex_input_stack, name);
|
lex_push_file(ldlex_input_stack, name);
|
||||||
|
@ -316,7 +318,7 @@ ldfile_add_arch(name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
search_arch_type *new =
|
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') {
|
if (*name != '\0') {
|
||||||
|
@ -343,7 +345,7 @@ ldfile_add_arch (in_name)
|
||||||
{
|
{
|
||||||
char *name = buystring(in_name);
|
char *name = buystring(in_name);
|
||||||
search_arch_type *new =
|
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;
|
ldfile_output_machine_name = in_name;
|
||||||
|
|
||||||
|
|
83
ld/ldmain.c
83
ld/ldmain.c
|
@ -72,9 +72,6 @@ boolean trace_file_tries;
|
||||||
instead of complaining if no input files are given. */
|
instead of complaining if no input files are given. */
|
||||||
boolean version_printed;
|
boolean version_printed;
|
||||||
|
|
||||||
/* 1 => write load map. */
|
|
||||||
boolean write_map;
|
|
||||||
|
|
||||||
args_type command_line;
|
args_type command_line;
|
||||||
|
|
||||||
ld_config_type config;
|
ld_config_type config;
|
||||||
|
@ -93,11 +90,10 @@ static boolean multiple_common PARAMS ((struct bfd_link_info *,
|
||||||
bfd_vma));
|
bfd_vma));
|
||||||
static boolean add_to_set PARAMS ((struct bfd_link_info *,
|
static boolean add_to_set PARAMS ((struct bfd_link_info *,
|
||||||
struct bfd_link_hash_entry *,
|
struct bfd_link_hash_entry *,
|
||||||
unsigned int bitsize,
|
bfd_reloc_code_real_type,
|
||||||
bfd *, asection *, bfd_vma));
|
bfd *, asection *, bfd_vma));
|
||||||
static boolean constructor_callback PARAMS ((struct bfd_link_info *,
|
static boolean constructor_callback PARAMS ((struct bfd_link_info *,
|
||||||
boolean constructor,
|
boolean constructor,
|
||||||
unsigned int bitsize,
|
|
||||||
const char *name,
|
const char *name,
|
||||||
bfd *, asection *, bfd_vma));
|
bfd *, asection *, bfd_vma));
|
||||||
static boolean warning_callback PARAMS ((struct bfd_link_info *,
|
static boolean warning_callback PARAMS ((struct bfd_link_info *,
|
||||||
|
@ -162,8 +158,8 @@ main (argc, argv)
|
||||||
|
|
||||||
/* Initialize the data about options. */
|
/* Initialize the data about options. */
|
||||||
trace_files = trace_file_tries = version_printed = false;
|
trace_files = trace_file_tries = version_printed = false;
|
||||||
write_map = false;
|
|
||||||
config.build_constructors = true;
|
config.build_constructors = true;
|
||||||
|
config.dynamic_link = false;
|
||||||
command_line.force_common_definition = false;
|
command_line.force_common_definition = false;
|
||||||
|
|
||||||
link_info.callbacks = &link_callbacks;
|
link_info.callbacks = &link_callbacks;
|
||||||
|
@ -195,6 +191,16 @@ main (argc, argv)
|
||||||
lang_has_input_file = false;
|
lang_has_input_file = false;
|
||||||
parse_args (argc, argv);
|
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
|
/* This essentially adds another -L directory so this must be done after
|
||||||
the -L's in argv have been processed. */
|
the -L's in argv have been processed. */
|
||||||
set_scripts_dir ();
|
set_scripts_dir ();
|
||||||
|
@ -213,10 +219,6 @@ main (argc, argv)
|
||||||
yyparse ();
|
yyparse ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link_info.relocateable && command_line.relax)
|
|
||||||
{
|
|
||||||
einfo ("%P%F: -relax and -r may not be used together\n");
|
|
||||||
}
|
|
||||||
lang_final ();
|
lang_final ();
|
||||||
|
|
||||||
if (lang_has_input_file == false)
|
if (lang_has_input_file == false)
|
||||||
|
@ -296,7 +298,8 @@ main (argc, argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bfd_close (output_bfd);
|
if (! bfd_close (output_bfd))
|
||||||
|
einfo ("%F%B: final close failed: %E\n", output_bfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.stats)
|
if (config.stats)
|
||||||
|
@ -568,8 +571,8 @@ add_archive_element (info, abfd, name)
|
||||||
|
|
||||||
ldlang_add_file (input);
|
ldlang_add_file (input);
|
||||||
|
|
||||||
if (write_map)
|
if (config.map_file != (FILE *) NULL)
|
||||||
info_msg ("%s needed due to %T\n", abfd->filename, name);
|
minfo ("%s needed due to %T\n", abfd->filename, name);
|
||||||
|
|
||||||
if (trace_files || trace_file_tries)
|
if (trace_files || trace_file_tries)
|
||||||
info_msg ("%I\n", input);
|
info_msg ("%I\n", input);
|
||||||
|
@ -664,15 +667,28 @@ multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
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_info *info;
|
||||||
struct bfd_link_hash_entry *h;
|
struct bfd_link_hash_entry *h;
|
||||||
unsigned int bitsize;
|
bfd_reloc_code_real_type reloc;
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *section;
|
asection *section;
|
||||||
bfd_vma value;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,10 +698,9 @@ add_to_set (info, h, bitsize, abfd, section, value)
|
||||||
adding an element to a set, but less general. */
|
adding an element to a set, but less general. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
constructor_callback (info, constructor, bitsize, name, abfd, section, value)
|
constructor_callback (info, constructor, name, abfd, section, value)
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
boolean constructor;
|
boolean constructor;
|
||||||
unsigned int bitsize;
|
|
||||||
const char *name;
|
const char *name;
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *section;
|
asection *section;
|
||||||
|
@ -698,6 +713,11 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
|
||||||
if (! config.build_constructors)
|
if (! config.build_constructors)
|
||||||
return true;
|
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__");
|
set_name = (char *) alloca (1 + sizeof "__CTOR_LIST__");
|
||||||
s = set_name;
|
s = set_name;
|
||||||
if (bfd_get_symbol_leading_char (abfd) != '\0')
|
if (bfd_get_symbol_leading_char (abfd) != '\0')
|
||||||
|
@ -707,8 +727,9 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
|
||||||
else
|
else
|
||||||
strcpy (s, "__DTOR_LIST__");
|
strcpy (s, "__DTOR_LIST__");
|
||||||
|
|
||||||
if (write_map)
|
if (config.map_file != (FILE *) NULL)
|
||||||
info_msg ("Adding %s to constructor/destructor set %s\n", name, set_name);
|
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);
|
h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
|
||||||
if (h == (struct bfd_link_hash_entry *) NULL)
|
if (h == (struct bfd_link_hash_entry *) NULL)
|
||||||
|
@ -722,7 +743,7 @@ constructor_callback (info, constructor, bitsize, name, abfd, section, value)
|
||||||
ourselves. */
|
ourselves. */
|
||||||
}
|
}
|
||||||
|
|
||||||
ldctor_add_set_entry (h, bitsize, section, value);
|
ldctor_add_set_entry (h, BFD_RELOC_CTOR, section, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,8 +811,11 @@ reloc_overflow (info, name, reloc_name, addend, abfd, section, address)
|
||||||
asection *section;
|
asection *section;
|
||||||
bfd_vma address;
|
bfd_vma address;
|
||||||
{
|
{
|
||||||
einfo ("%X%C: relocation truncated to fit: %s %T", abfd, section,
|
if (abfd == (bfd *) NULL)
|
||||||
address, reloc_name, name);
|
einfo ("%P%X: generated");
|
||||||
|
else
|
||||||
|
einfo ("%X%C:", abfd, section, address);
|
||||||
|
einfo (" relocation truncated to fit: %s %T", reloc_name, name);
|
||||||
if (addend != 0)
|
if (addend != 0)
|
||||||
einfo ("+%v", addend);
|
einfo ("+%v", addend);
|
||||||
einfo ("\n");
|
einfo ("\n");
|
||||||
|
@ -809,7 +833,11 @@ reloc_dangerous (info, message, abfd, section, address)
|
||||||
asection *section;
|
asection *section;
|
||||||
bfd_vma address;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,8 +853,11 @@ unattached_reloc (info, name, abfd, section, address)
|
||||||
asection *section;
|
asection *section;
|
||||||
bfd_vma address;
|
bfd_vma address;
|
||||||
{
|
{
|
||||||
einfo ("%X%C: reloc refers to symbol `%T' which is not being output\n",
|
if (abfd == (bfd *) NULL)
|
||||||
abfd, section, address, name);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
ld/lexsup.c
55
ld/lexsup.c
|
@ -57,50 +57,53 @@ parse_args (argc, argv)
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
#define OPTION_CALL_SHARED 150
|
#define OPTION_CALL_SHARED 150
|
||||||
|
#define OPTION_NON_SHARED 151
|
||||||
{"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
|
{"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
|
||||||
{"dc", no_argument, NULL, 'd'},
|
{"dc", no_argument, NULL, 'd'},
|
||||||
#define OPTION_DEFSYM 151
|
#define OPTION_DEFSYM 152
|
||||||
{"defsym", required_argument, NULL, OPTION_DEFSYM},
|
{"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'},
|
{"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},
|
{"EB", no_argument, NULL, OPTION_EB},
|
||||||
#define OPTION_EL 153
|
#define OPTION_EL 154
|
||||||
{"EL", no_argument, NULL, OPTION_EL},
|
{"EL", no_argument, NULL, OPTION_EL},
|
||||||
{"format", required_argument, NULL, 'b'},
|
{"format", required_argument, NULL, 'b'},
|
||||||
#define OPTION_HELP 154
|
#define OPTION_HELP 155
|
||||||
{"help", no_argument, NULL, OPTION_HELP},
|
{"help", no_argument, NULL, OPTION_HELP},
|
||||||
#define OPTION_MAP 155
|
#define OPTION_MAP 156
|
||||||
{"Map", required_argument, NULL, OPTION_MAP},
|
{"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},
|
{"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},
|
||||||
{"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
|
{"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
|
||||||
{"non_shared", no_argument, NULL, OPTION_CALL_SHARED},
|
{"non_shared", no_argument, NULL, OPTION_NON_SHARED},
|
||||||
#define OPTION_OFORMAT 158
|
#define OPTION_OFORMAT 159
|
||||||
{"oformat", required_argument, NULL, OPTION_OFORMAT},
|
{"oformat", required_argument, NULL, OPTION_OFORMAT},
|
||||||
{"Qy", no_argument, NULL, OPTION_CALL_SHARED},
|
#define OPTION_IGNORE 160
|
||||||
#define OPTION_RELAX 159
|
{"Qy", no_argument, NULL, OPTION_IGNORE},
|
||||||
|
#define OPTION_RELAX 161
|
||||||
{"relax", no_argument, NULL, OPTION_RELAX},
|
{"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},
|
{"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},
|
||||||
{"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},
|
{"stats", no_argument, NULL, OPTION_STATS},
|
||||||
#define OPTION_TBSS 163
|
#define OPTION_TBSS 165
|
||||||
{"Tbss", required_argument, NULL, OPTION_TBSS},
|
{"Tbss", required_argument, NULL, OPTION_TBSS},
|
||||||
#define OPTION_TDATA 164
|
#define OPTION_TDATA 166
|
||||||
{"Tdata", required_argument, NULL, OPTION_TDATA},
|
{"Tdata", required_argument, NULL, OPTION_TDATA},
|
||||||
#define OPTION_TTEXT 165
|
#define OPTION_TTEXT 167
|
||||||
{"Ttext", required_argument, NULL, OPTION_TTEXT},
|
{"Ttext", required_argument, NULL, OPTION_TTEXT},
|
||||||
#define OPTION_UR 166
|
#define OPTION_UR 168
|
||||||
{"Ur", no_argument, NULL, OPTION_UR},
|
{"Ur", no_argument, NULL, OPTION_UR},
|
||||||
#define OPTION_VERSION 167
|
#define OPTION_VERSION 169
|
||||||
{"version", no_argument, NULL, OPTION_VERSION},
|
{"version", no_argument, NULL, OPTION_VERSION},
|
||||||
#define OPTION_WARN_COMMON 168
|
#define OPTION_WARN_COMMON 170
|
||||||
{"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
|
{"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
|
@ -124,6 +127,8 @@ parse_args (argc, argv)
|
||||||
(char *) NULL);
|
(char *) NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPTION_IGNORE:
|
||||||
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
ldfile_add_arch (optarg);
|
ldfile_add_arch (optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -139,7 +144,10 @@ parse_args (argc, argv)
|
||||||
yyparse ();
|
yyparse ();
|
||||||
break;
|
break;
|
||||||
case OPTION_CALL_SHARED:
|
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;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
command_line.force_common_definition = true;
|
command_line.force_common_definition = true;
|
||||||
|
@ -194,7 +202,6 @@ parse_args (argc, argv)
|
||||||
/* Ignore. Was handled in a pre-parse. */
|
/* Ignore. Was handled in a pre-parse. */
|
||||||
break;
|
break;
|
||||||
case OPTION_MAP:
|
case OPTION_MAP:
|
||||||
write_map = true;
|
|
||||||
config.map_filename = optarg;
|
config.map_filename = optarg;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
|
@ -229,6 +236,7 @@ parse_args (argc, argv)
|
||||||
config.build_constructors = false;
|
config.build_constructors = false;
|
||||||
config.magic_demand_paged = false;
|
config.magic_demand_paged = false;
|
||||||
config.text_read_only = false;
|
config.text_read_only = false;
|
||||||
|
config.dynamic_link = false;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
lang_add_input_file (optarg,
|
lang_add_input_file (optarg,
|
||||||
|
@ -275,6 +283,7 @@ parse_args (argc, argv)
|
||||||
config.build_constructors = true;
|
config.build_constructors = true;
|
||||||
config.magic_demand_paged = false;
|
config.magic_demand_paged = false;
|
||||||
config.text_read_only = false;
|
config.text_read_only = false;
|
||||||
|
config.dynamic_link = false;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
ldlang_add_undef (optarg);
|
ldlang_add_undef (optarg);
|
||||||
|
|
|
@ -8,12 +8,18 @@
|
||||||
# (e.g., .PARISC.global)
|
# (e.g., .PARISC.global)
|
||||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||||
# executable (e.g., _DYNAMIC_LINK)
|
# 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
|
# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
|
||||||
# .bss section besides __bss_start.
|
# .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 adding sections, do note that the names of some sections are used
|
||||||
# when specifying the start address of the next.
|
# when specifying the start address of the next.
|
||||||
#
|
#
|
||||||
|
PLT=".plt ${RELOCATING-0} : { *(.plt) }"
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
OUTPUT_FORMAT("${OUTPUT_FORMAT}")
|
OUTPUT_FORMAT("${OUTPUT_FORMAT}")
|
||||||
OUTPUT_ARCH(${ARCH})
|
OUTPUT_ARCH(${ARCH})
|
||||||
|
@ -29,62 +35,58 @@ ${RELOCATING- /* For some reason, the Solaris linker makes bad executables
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
/* Read-only sections, merged into text segment: */
|
/* 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)
|
*(.text)
|
||||||
CREATE_OBJECT_SYMBOLS
|
|
||||||
${RELOCATING+_etext = .;}
|
|
||||||
}
|
}
|
||||||
.init ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.init) } =${NOP-0}
|
${RELOCATING+_etext = .;}
|
||||||
.fini ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.fini) } =${NOP-0}
|
.fini ${RELOCATING-0} : { *(.fini) } =${NOP-0}
|
||||||
.ctors ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.ctors) }
|
.ctors ${RELOCATING-0} : { *(.ctors) }
|
||||||
.dtors ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.dtors) }
|
.dtors ${RELOCATING-0} : { *(.dtors) }
|
||||||
.rodata ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.rodata) }
|
.rodata ${RELOCATING-0} : { *(.rodata) }
|
||||||
.rodata1 ${RELOCATING+ALIGN(8)} ${RELOCATING-0} :
|
.rodata1 ${RELOCATING-0} : { *(.rodata1) }
|
||||||
{
|
|
||||||
*(.rodata1)
|
|
||||||
${RELOCATING+. = ALIGN(8);}
|
|
||||||
}
|
|
||||||
${RELOCATING+${OTHER_READONLY_SECTIONS}}
|
${RELOCATING+${OTHER_READONLY_SECTIONS}}
|
||||||
/* also: .hash .dynsym .dynstr .plt(if r/o) .rel.got */
|
|
||||||
|
|
||||||
/* Read-write section, merged into data segment: */
|
/* Read-write section, merged into data segment: */
|
||||||
.data ${RELOCATING+
|
${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
|
||||||
${DATA_ADDR- ADDR(.rodata1)+SIZEOF(.rodata1)+${MAXPAGESIZE}}
|
.data ${RELOCATING-0} :
|
||||||
}
|
|
||||||
${RELOCATING-0} :
|
|
||||||
{
|
{
|
||||||
|
${RELOCATING+${DATA_START_SYMBOLS}}
|
||||||
*(.data)
|
*(.data)
|
||||||
${CONSTRUCTING+CONSTRUCTORS}
|
${CONSTRUCTING+CONSTRUCTORS}
|
||||||
}
|
}
|
||||||
.data1 ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.data1) }
|
.data1 ${RELOCATING-0} : { *(.data1) }
|
||||||
${RELOCATING+${OTHER_READWRITE_SECTIONS}}
|
${RELOCATING+${OTHER_READWRITE_SECTIONS}}
|
||||||
/* also (before uninitialized portion): .dynamic .got .plt(if r/w)
|
.got ${RELOCATING-0} : { *(.got) }
|
||||||
(or does .dynamic go into its own segment?) */
|
.dynamic ${RELOCATING-0} : { *(.dynamic) }
|
||||||
|
${DATA_PLT+${PLT}}
|
||||||
/* We want the small data sections together, so single-instruction offsets
|
/* We want the small data sections together, so single-instruction offsets
|
||||||
can access them all, and initialized data all before uninitialized, so
|
can access them all, and initialized data all before uninitialized, so
|
||||||
we can shorten the on-disk segment size. */
|
we can shorten the on-disk segment size. */
|
||||||
.sdata ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.sdata) }
|
.sdata ${RELOCATING-0} : { *(.sdata) }
|
||||||
${RELOCATING+_edata = .;}
|
${RELOCATING+_edata = .;}
|
||||||
${RELOCATING+__bss_start = ALIGN(8);}
|
${RELOCATING+__bss_start = .;}
|
||||||
${RELOCATING+${OTHER_BSS_SYMBOLS}}
|
${RELOCATING+${OTHER_BSS_SYMBOLS}}
|
||||||
.sbss ${RELOCATING+ALIGN(8)} ${RELOCATING-0} : { *(.sbss) *(.scommon) }
|
.sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) }
|
||||||
.bss ${RELOCATING+ALIGN(8)} ${RELOCATING-0} :
|
.bss ${RELOCATING-0} :
|
||||||
{
|
{
|
||||||
|
*(.dynbss)
|
||||||
*(.bss)
|
*(.bss)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
${RELOCATING+_end = . };
|
|
||||||
${RELOCATING+end = . };
|
|
||||||
}
|
}
|
||||||
|
${RELOCATING+_end = . ;}
|
||||||
/* Debug sections. These should never be loadable, but they must have
|
${RELOCATING+end = . ;}
|
||||||
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) }
|
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
Loading…
Add table
Reference in a new issue