* ldlang.c (load_symbols): Check for archive before object. Use
bfd_check_format_matches, and, if ambiguous, print a list of matching formats. If file format is not recognized, treat file as a linker script. * ldgram.y (yyerror): If assuming an object file is a script, mention that. Tweak the format of the error messages. * ldlex.l (lex_warn_invalid): If assuming an object is a script, guess that this is not actually a script, and just report that the file format was not recognized. * ld.texinfo (Options): Admit that -( may be used more than once. Add note that unrecognized object files are now treated as linker scripts. * ldfile.c (ldfile_input_filename): Make const. (ldfile_assumed_script): New variable. (try_open): Change arguments types to const. (ldfile_find_command_file): Likewise. (ldfile_open_command_file): Likewise. Also, set lineno to 1. * ldfile.h: Update declarations for ldfile.c changes. * ldlex.l: Include <ctype.h>. (file_name_stack): Change to be const char *. (lineno_stack): New static variable. (<<EOF>>): Set lineno as well as ldfile_input_filename. (lex_push_file): Make name argument const. Initialize lineno_stack entry. (lex_redirect): Initialize lineno_stack entry. (lex_warn_invalid): Handle non printable characters nicely. * ldlex.h (lex_push_file): Declare second argument as const. * ldgram.y (ifile_p1): Recognize GROUP. * ldlex.l: Recognize GROUP. * ld.texinfo (Option Commands): Document GROUP.
This commit is contained in:
parent
204ba9e37e
commit
0b3499f672
35
ld/ChangeLog
35
ld/ChangeLog
|
@ -1,3 +1,38 @@
|
|||
Tue Sep 13 16:30:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||
|
||||
* ldlang.c (load_symbols): Check for archive before object. Use
|
||||
bfd_check_format_matches, and, if ambiguous, print a list of
|
||||
matching formats. If file format is not recognized, treat file as
|
||||
a linker script.
|
||||
* ldgram.y (yyerror): If assuming an object file is a script,
|
||||
mention that. Tweak the format of the error messages.
|
||||
* ldlex.l (lex_warn_invalid): If assuming an object is a script,
|
||||
guess that this is not actually a script, and just report that the
|
||||
file format was not recognized.
|
||||
* ld.texinfo (Options): Admit that -( may be used more than once.
|
||||
Add note that unrecognized object files are now treated as linker
|
||||
scripts.
|
||||
|
||||
* ldfile.c (ldfile_input_filename): Make const.
|
||||
(ldfile_assumed_script): New variable.
|
||||
(try_open): Change arguments types to const.
|
||||
(ldfile_find_command_file): Likewise.
|
||||
(ldfile_open_command_file): Likewise. Also, set lineno to 1.
|
||||
* ldfile.h: Update declarations for ldfile.c changes.
|
||||
* ldlex.l: Include <ctype.h>.
|
||||
(file_name_stack): Change to be const char *.
|
||||
(lineno_stack): New static variable.
|
||||
(<<EOF>>): Set lineno as well as ldfile_input_filename.
|
||||
(lex_push_file): Make name argument const. Initialize
|
||||
lineno_stack entry.
|
||||
(lex_redirect): Initialize lineno_stack entry.
|
||||
(lex_warn_invalid): Handle non printable characters nicely.
|
||||
* ldlex.h (lex_push_file): Declare second argument as const.
|
||||
|
||||
* ldgram.y (ifile_p1): Recognize GROUP.
|
||||
* ldlex.l: Recognize GROUP.
|
||||
* ld.texinfo (Option Commands): Document GROUP.
|
||||
|
||||
Mon Sep 12 17:04:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||
|
||||
* config/m68klynx.mh: New file.
|
||||
|
|
|
@ -177,8 +177,8 @@ ld [ -o @var{output} ] @var{objfile}@dots{}
|
|||
[ -Map @var{mapfile} ] [ -m @var{emulation} ] [ -N | -n ]
|
||||
[ -noinhibit-exec ] [ -oformat @var{output-format} ]
|
||||
[ -R @var{filename} ] [ -relax ] [ -retain-symbols-file @var{filename} ]
|
||||
[ -r | -Ur ] [ -rpath @var{dir} ] [ -S ] [ -s ] [ -sort-common ]
|
||||
[ -stats ] [ -T @var{commandfile} ]
|
||||
[ -r | -Ur ] [ -rpath @var{dir} ] [ -S ] [ -s ] [ -soname @var{name} ]
|
||||
[ -sort-common ] [ -stats ] [ -T @var{commandfile} ]
|
||||
[ -Ttext @var{org} ] [ -Tdata @var{org} ]
|
||||
[ -Tbss @var{org} ] [ -t ] [ -traditional-format ]
|
||||
[ -u @var{symbol}] [-V] [-v] [ -version ]
|
||||
|
@ -211,11 +211,13 @@ option.
|
|||
@ifclear SingleFormat
|
||||
The exceptions---which may meaningfully be used more than once---are
|
||||
@samp{-A}, @samp{-b} (or its synonym @samp{-format}), @samp{-defsym},
|
||||
@samp{-L}, @samp{-l}, @samp{-R}, and @samp{-u}.
|
||||
@samp{-L}, @samp{-l}, @samp{-R}, @samp{-u}, and @samp{-(} (or its
|
||||
synonym @samp{--start-group})..
|
||||
@end ifclear
|
||||
@ifset SingleFormat
|
||||
The exceptions---which may meaningfully be used more than once---are
|
||||
@samp{-A}, @samp{-defsym}, @samp{-L}, @samp{-l}, @samp{-R}, and @samp{-u}.
|
||||
@samp{-A}, @samp{-defsym}, @samp{-L}, @samp{-l}, @samp{-R}, @samp{-u},
|
||||
and @samp{-(} (or its synonym @samp{--start-group}).
|
||||
@end ifset
|
||||
|
||||
@cindex object files
|
||||
|
@ -230,6 +232,14 @@ and the script command language. If @emph{no} binary input files at all
|
|||
are specified, the linker does not produce any output, and issues the
|
||||
message @samp{No input files}.
|
||||
|
||||
If the linker can not recognize the format of an object file, it will
|
||||
assume that it is a linker script. A script specified in this way
|
||||
augments the main linker script used for the link (either the default
|
||||
linker script or the one specified by using @samp{-T}). This feature
|
||||
permits the linker to link against a file which appears to be an object
|
||||
or an archive, but actually merely defines some symbol values, or uses
|
||||
@code{INPUT} or @code{GROUP} to load other objects. @xref{Commands}.
|
||||
|
||||
For options whose names are a single letter,
|
||||
option arguments must either follow the option letter without intervening
|
||||
whitespace, or be given as separate arguments immediately following the
|
||||
|
@ -579,6 +589,17 @@ Omit debugger symbol information (but not all symbols) from the output file.
|
|||
@item -s
|
||||
Omit all symbol information from the output file.
|
||||
|
||||
@ifset GENERIC
|
||||
@item -soname @var{name}
|
||||
@cindex runtime library name
|
||||
@kindex -soname
|
||||
When creating an ELF shared object, set the internal DT_SONAME field to
|
||||
the specified name. When an executable is linked with a shared object
|
||||
which has a DT_SONAME field, then when the executable is run the dynamic
|
||||
linker will attempt to load the shared object specified by the DT_SONAME
|
||||
field rather than the using the file name given to the linker.
|
||||
@end ifset
|
||||
|
||||
@item -sort-common
|
||||
Normally, when @code{ld} places the global common symbols in the
|
||||
appropriate output sections, it sorts them by size. First come all the
|
||||
|
@ -1211,7 +1232,17 @@ SECTIONS @{ @dots{}
|
|||
@kindex Non constant expression
|
||||
@noindent
|
||||
will cause the error message ``@code{Non constant expression for initial
|
||||
address}''.
|
||||
address}''.
|
||||
|
||||
@cindex provide
|
||||
In some cases, it is desirable for a linker script to define a symbol
|
||||
only if it is referenced, and only if it is not defined by any object
|
||||
included in the link. For example, traditional linkers defined the
|
||||
symbol @samp{etext}. However, ANSI C requires that the user be able to
|
||||
use @samp{etext} as a function name without encountering an error.
|
||||
The @code{PROVIDE} keyword may be used to define a symbol, such as
|
||||
@samp{etext}, only if it is referenced but not defined. The syntax is
|
||||
@code{PROVIDE(@var{symbol} = @var{expression})}.
|
||||
|
||||
@node Arithmetic Functions
|
||||
@subsection Arithmetic Functions
|
||||
|
@ -2019,6 +2050,15 @@ search path, just as for files you specify on the command line.
|
|||
See the description of @samp{-L} in @ref{Options,,Command Line
|
||||
Options}.
|
||||
|
||||
@kindex GROUP ( @var{files} )
|
||||
@cindex grouping input files
|
||||
@item GROUP ( @var{file}, @var{file}, @dots{} )
|
||||
@itemx GROUP ( @var{file} @var{file} @dots{} )
|
||||
This command is like @code{INPUT}, except that the named files should
|
||||
all be archives, and they are searched repeatedly until no new undefined
|
||||
references are created. See the description of @samp{-(} in
|
||||
@ref{Options,,Command Line Options}.
|
||||
|
||||
@ignore
|
||||
@item MAP ( @var{name} )
|
||||
@kindex MAP ( @var{name} )
|
||||
|
|
31
ld/ldgram.y
31
ld/ldgram.y
|
@ -102,8 +102,8 @@ static int error_index;
|
|||
%token <integer> SIZEOF NEXT ADDR
|
||||
%token STARTUP HLL SYSLIB FLOAT NOFLOAT
|
||||
%token ORIGIN FILL
|
||||
%token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS
|
||||
%token ALIGNMOD AT
|
||||
%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
|
||||
%token ALIGNMOD AT PROVIDE
|
||||
%type <token> assign_op
|
||||
%type <name> filename
|
||||
%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD
|
||||
|
@ -249,6 +249,10 @@ ifile_p1:
|
|||
| FORCE_COMMON_ALLOCATION
|
||||
{ command_line.force_common_definition = true ; }
|
||||
| INPUT '(' input_list ')'
|
||||
| GROUP
|
||||
{ lang_enter_group (); }
|
||||
'(' input_list ')'
|
||||
{ lang_leave_group (); }
|
||||
| MAP '(' filename ')'
|
||||
{ lang_add_map($3); }
|
||||
| INCLUDE filename
|
||||
|
@ -402,14 +406,20 @@ end: ';' | ','
|
|||
assignment:
|
||||
NAME '=' mustbe_exp
|
||||
{
|
||||
lang_add_assignment(exp_assop($2,$1,$3));
|
||||
lang_add_assignment (exp_assop ($2, $1, $3));
|
||||
}
|
||||
| NAME assign_op mustbe_exp
|
||||
{
|
||||
|
||||
lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
|
||||
lang_add_assignment (exp_assop ('=', $1,
|
||||
exp_binop ($2,
|
||||
exp_nameop (NAME,
|
||||
$1),
|
||||
$3)));
|
||||
}
|
||||
| PROVIDE '(' NAME '=' mustbe_exp ')'
|
||||
{
|
||||
lang_add_assignment (exp_provide ($3, $5));
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
@ -564,6 +574,8 @@ exp :
|
|||
{ $$ = exp_unop(ABSOLUTE, $3); }
|
||||
| ALIGN_K '(' exp ')'
|
||||
{ $$ = exp_unop(ALIGN_K,$3); }
|
||||
| BLOCK '(' exp ')'
|
||||
{ $$ = exp_unop(ALIGN_K,$3); }
|
||||
| NAME
|
||||
{ $$ = exp_nameop(NAME,$1); }
|
||||
;
|
||||
|
@ -618,8 +630,11 @@ void
|
|||
yyerror(arg)
|
||||
const char *arg;
|
||||
{
|
||||
if (ldfile_assumed_script)
|
||||
einfo ("%P:%s: file format not recognized; treating as linker script\n",
|
||||
ldfile_input_filename);
|
||||
if (error_index > 0 && error_index < ERROR_NAME_MAX)
|
||||
einfo("%P%F: %S %s in %s\n", arg, error_names[error_index-1]);
|
||||
einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
|
||||
else
|
||||
einfo("%P%F: %S %s\n", arg);
|
||||
einfo ("%P%F:%S: %s\n", arg);
|
||||
}
|
||||
|
|
113
ld/ldlang.c
113
ld/ldlang.c
|
@ -72,10 +72,6 @@ static lang_input_statement_type *new_afile
|
|||
const char *target, boolean add_to_list));
|
||||
static void print_flags PARAMS ((int *ignore_flags));
|
||||
static void init_os PARAMS ((lang_output_section_statement_type *s));
|
||||
static void wild_doit PARAMS ((lang_statement_list_type *ptr,
|
||||
asection *section,
|
||||
lang_output_section_statement_type *output,
|
||||
lang_input_statement_type *file));
|
||||
static void wild_section PARAMS ((lang_wild_statement_type *ptr,
|
||||
const char *section,
|
||||
lang_input_statement_type *file,
|
||||
|
@ -628,7 +624,7 @@ init_os (s)
|
|||
|
||||
*/
|
||||
|
||||
static void
|
||||
void
|
||||
wild_doit (ptr, section, output, file)
|
||||
lang_statement_list_type * ptr;
|
||||
asection * section;
|
||||
|
@ -752,27 +748,59 @@ static void
|
|||
load_symbols (entry)
|
||||
lang_input_statement_type *entry;
|
||||
{
|
||||
char **matching;
|
||||
|
||||
if (entry->loaded)
|
||||
return;
|
||||
|
||||
ldfile_open_file (entry);
|
||||
|
||||
if (bfd_check_format (entry->the_bfd, bfd_object))
|
||||
if (! bfd_check_format (entry->the_bfd, bfd_archive)
|
||||
&& ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
|
||||
{
|
||||
bfd_error_type err;
|
||||
|
||||
err = bfd_get_error ();
|
||||
if (err == bfd_error_file_ambiguously_recognized)
|
||||
{
|
||||
char **p;
|
||||
|
||||
einfo ("%B: file not recognized: %E\n", entry->the_bfd);
|
||||
einfo ("%B: matching formats:", entry->the_bfd);
|
||||
for (p = matching; *p != NULL; p++)
|
||||
einfo (" %s", *p);
|
||||
einfo ("%F\n");
|
||||
}
|
||||
else if (err != bfd_error_file_not_recognized)
|
||||
einfo ("%F%B: file not recognized: %E\n", entry->the_bfd);
|
||||
|
||||
/* Try to interpret the file as a linker script. */
|
||||
|
||||
bfd_close (entry->the_bfd);
|
||||
entry->the_bfd = NULL;
|
||||
|
||||
ldfile_open_command_file (entry->filename);
|
||||
|
||||
ldfile_assumed_script = true;
|
||||
parser_input = input_script;
|
||||
yyparse ();
|
||||
ldfile_assumed_script = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* We don't call ldlang_add_file for an archive. Instead, the
|
||||
add_symbols entry point will call ldlang_add_file, via the
|
||||
add_archive_element callback, for each element of the archive
|
||||
which is used. */
|
||||
if (bfd_get_format (entry->the_bfd) == bfd_object)
|
||||
{
|
||||
ldlang_add_file (entry);
|
||||
if (trace_files || trace_file_tries)
|
||||
info_msg ("%I\n", entry);
|
||||
}
|
||||
else if (bfd_check_format (entry->the_bfd, bfd_archive))
|
||||
{
|
||||
/* There is nothing to do here; the add_symbols routine will
|
||||
call ldlang_add_file (via the add_archive_element callback)
|
||||
for each element of the archive which is used. */
|
||||
}
|
||||
else
|
||||
einfo ("%F%B: file not recognized: %E\n", entry->the_bfd);
|
||||
|
||||
if (bfd_link_add_symbols (entry->the_bfd, &link_info) == false)
|
||||
if (! bfd_link_add_symbols (entry->the_bfd, &link_info))
|
||||
einfo ("%F%B: could not read symbols: %E\n", entry->the_bfd);
|
||||
|
||||
entry->loaded = true;
|
||||
|
@ -1155,7 +1183,7 @@ print_output_section_statement (output_section_statement)
|
|||
print_nl ();
|
||||
if (output_section_statement->load_base)
|
||||
{
|
||||
int b = exp_get_value_int(output_section_statement->load_base,
|
||||
int b = exp_get_abs_int(output_section_statement->load_base,
|
||||
0, "output base", lang_final_phase_enum);
|
||||
printf("Output address %08x\n", b);
|
||||
}
|
||||
|
@ -1710,11 +1738,6 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
|
|||
|
||||
bfd_set_section_vma (0, os->bfd_section, dot);
|
||||
|
||||
if (os->load_base) {
|
||||
os->bfd_section->lma
|
||||
= exp_get_value_int(os->load_base, 0,"load base", lang_final_phase_enum);
|
||||
}
|
||||
|
||||
os->bfd_section->output_offset = 0;
|
||||
}
|
||||
|
||||
|
@ -1754,6 +1777,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -1960,6 +1985,11 @@ lang_do_assignments (s, output_section_statement, fill, dot)
|
|||
os->fill, dot);
|
||||
dot = os->bfd_section->vma + os->bfd_section->_raw_size;
|
||||
}
|
||||
if (os->load_base)
|
||||
{
|
||||
os->bfd_section->lma
|
||||
= exp_get_abs_int(os->load_base, 0,"load base", lang_final_phase_enum);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case lang_wild_statement_enum:
|
||||
|
@ -2119,15 +2149,14 @@ lang_finish ()
|
|||
}
|
||||
}
|
||||
|
||||
/* By now we know the target architecture, and we may have an */
|
||||
/* ldfile_output_machine_name */
|
||||
/* Check that the architecture of all the input files is compatible
|
||||
with the output file. */
|
||||
|
||||
static void
|
||||
lang_check ()
|
||||
{
|
||||
lang_statement_union_type *file;
|
||||
bfd *input_bfd;
|
||||
unsigned long input_machine;
|
||||
enum bfd_architecture input_architecture;
|
||||
CONST bfd_arch_info_type *compatible;
|
||||
|
||||
for (file = file_chain.head;
|
||||
|
@ -2135,36 +2164,12 @@ lang_check ()
|
|||
file = file->input_statement.next)
|
||||
{
|
||||
input_bfd = file->input_statement.the_bfd;
|
||||
|
||||
input_machine = bfd_get_mach (input_bfd);
|
||||
input_architecture = bfd_get_arch (input_bfd);
|
||||
|
||||
|
||||
/* Inspect the architecture and ensure we're linking like with
|
||||
like */
|
||||
|
||||
compatible = bfd_arch_get_compatible (input_bfd,
|
||||
output_bfd);
|
||||
|
||||
if (compatible)
|
||||
{
|
||||
ldfile_output_machine = compatible->mach;
|
||||
ldfile_output_architecture = compatible->arch;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
einfo ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n",
|
||||
bfd_printable_name (input_bfd), input_bfd,
|
||||
bfd_printable_name (output_bfd));
|
||||
|
||||
if (! bfd_set_arch_mach (output_bfd,
|
||||
input_architecture,
|
||||
input_machine))
|
||||
einfo ("%P%F:%s: can't set architecture: %E\n",
|
||||
bfd_get_filename (output_bfd));
|
||||
}
|
||||
|
||||
if (compatible == NULL)
|
||||
einfo ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n",
|
||||
bfd_printable_name (input_bfd), input_bfd,
|
||||
bfd_printable_name (output_bfd));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2290,6 +2295,8 @@ lang_place_orphans ()
|
|||
default_common_section, file);
|
||||
}
|
||||
}
|
||||
else if (ldemul_place_orphan (file, s))
|
||||
;
|
||||
else
|
||||
{
|
||||
lang_output_section_statement_type *os =
|
||||
|
|
Loading…
Reference in New Issue