* ldmain.c (main): Initialize new field link_info.static_link.

* ldmain.c (add_keepsyms_file): Add \n at end of einfo calls.
	(constructor_callback): Likewise.
	* ldmisc.c (vfinfo): Likewise.
	* ldwrite.c (build_link_order): Likewise.
This commit is contained in:
Ian Lance Taylor 1995-10-25 15:48:53 +00:00
parent 28a0c10399
commit 7d6439d974
4 changed files with 224 additions and 61 deletions

View File

@ -1,5 +1,16 @@
Wed Oct 25 11:27:25 1995 Ian Lance Taylor <ian@cygnus.com>
* emultempl/aix.em: Add support for various AIX linker options,
for AIX import and export files, and for AIX shared objects.
* scripttempl/aix.sc: Add .pad. Put .ds just before the TOC.
* ldmain.c (main): Initialize new field link_info.static_link.
* ldmain.c (add_keepsyms_file): Add \n at end of einfo calls.
(constructor_callback): Likewise.
* ldmisc.c (vfinfo): Likewise.
* ldwrite.c (build_link_order): Likewise.
* ld.texinfo: The MRI ALIGN directive is supported.
Mon Oct 23 11:46:43 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>

View File

@ -1,5 +1,5 @@
/* Main program of GNU linker.
Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
Copyright (C) 1991, 92, 93, 94, 1995 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
@ -22,11 +22,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
#include "bfd.h"
#include "sysdep.h"
#include <stdio.h>
#include <ctype.h>
#include "libiberty.h"
#include "progress.h"
#include "bfdlink.h"
#include "config.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
@ -46,11 +46,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
#include <string.h>
/* Use sbrk() except on specific OS types */
#if !defined(__amigados__) && !defined(WINDOWS_NT)
#define HAVE_SBRK
#endif
static char *get_emulation PARAMS ((int, char **));
static void set_scripts_dir PARAMS ((void));
@ -106,7 +101,9 @@ static boolean constructor_callback PARAMS ((struct bfd_link_info *,
const char *name,
bfd *, asection *, bfd_vma));
static boolean warning_callback PARAMS ((struct bfd_link_info *,
const char *));
const char *, const char *, bfd *,
asection *, bfd_vma));
static void warning_find_reloc PARAMS ((bfd *, asection *, PTR));
static boolean undefined_symbol PARAMS ((struct bfd_link_info *,
const char *, bfd *,
asection *, bfd_vma));
@ -181,6 +178,7 @@ main (argc, argv)
link_info.relocateable = false;
link_info.shared = false;
link_info.symbolic = false;
link_info.static_link = false;
link_info.strip = strip_none;
link_info.discard = discard_none;
link_info.lprefix_len = 1;
@ -191,15 +189,8 @@ main (argc, argv)
link_info.hash = NULL;
link_info.keep_hash = NULL;
link_info.notice_hash = NULL;
link_info.subsystem = console;
link_info.stack_heap_parameters.stack_defined = false;
link_info.stack_heap_parameters.heap_defined = false;
link_info.stack_heap_parameters.stack_reserve = 0;
link_info.stack_heap_parameters.stack_commit = 0;
link_info.stack_heap_parameters.heap_reserve = 0;
link_info.stack_heap_parameters.heap_commit = 0;
ldfile_add_arch ("");
config.make_executable = true;
@ -216,6 +207,8 @@ main (argc, argv)
lang_has_input_file = false;
parse_args (argc, argv);
ldemul_set_symbols ();
if (link_info.relocateable)
{
if (command_line.relax)
@ -255,10 +248,12 @@ main (argc, argv)
info_msg (s);
info_msg ("\n==================================================\n");
}
lex_string = s;
lex_redirect (s);
}
parser_input = input_script;
yyparse ();
lex_string = NULL;
}
lang_final ();
@ -475,22 +470,21 @@ set_scripts_dir ()
/* Look for "ldscripts" in the dir where our binary is. */
end = strrchr (program_name, '/');
if (end)
if (end == NULL)
{
dirlen = end - program_name;
/* Make a copy of program_name in dir.
Leave room for later "/../lib". */
dir = (char *) xmalloc (dirlen + 8);
strncpy (dir, program_name, dirlen);
dir[dirlen] = '\0';
}
else
{
dirlen = 1;
dir = (char *) xmalloc (dirlen + 8);
strcpy (dir, ".");
/* Don't look for ldscripts in the current directory. There is
too much potential for confusion. */
return;
}
dirlen = end - program_name;
/* Make a copy of program_name in dir.
Leave room for later "/../lib". */
dir = (char *) xmalloc (dirlen + 8);
strncpy (dir, program_name, dirlen);
dir[dirlen] = '\0';
if (check_for_scripts_dir (dir))
return; /* Don't free dir. */
@ -539,7 +533,7 @@ add_keepsyms_file (filename)
if (file == (FILE *) NULL)
{
bfd_set_error (bfd_error_system_call);
einfo ("%X%P: %s: %E", filename);
einfo ("%X%P: %s: %E\n", filename);
return;
}
@ -577,7 +571,7 @@ add_keepsyms_file (filename)
if (bfd_hash_lookup (link_info.keep_hash, buf, true, true)
== (struct bfd_hash_entry *) NULL)
einfo ("%P%F: bfd_hash_lookup for insertion failed: %E");
einfo ("%P%F: bfd_hash_lookup for insertion failed: %E\n");
}
}
@ -602,7 +596,7 @@ add_archive_element (info, abfd, name)
lang_input_statement_type *input;
input = ((lang_input_statement_type *)
xmalloc ((bfd_size_type) sizeof (lang_input_statement_type)));
xmalloc (sizeof (lang_input_statement_type)));
input->filename = abfd->filename;
input->local_sym_name = abfd->filename;
input->the_bfd = abfd;
@ -734,6 +728,10 @@ add_to_set (info, h, reloc, abfd, section, value)
asection *section;
bfd_vma value;
{
if (config.warn_constructors)
einfo ("%P: warning: global constructor %s used\n",
h->root.string);
if (! config.build_constructors)
return true;
@ -765,9 +763,12 @@ constructor_callback (info, constructor, name, abfd, section, value)
asection *section;
bfd_vma value;
{
char *set_name;
char *s;
struct bfd_link_hash_entry *h;
char set_name[1 + sizeof "__CTOR_LIST__"];
if (config.warn_constructors)
einfo ("%P: warning: global constructor %s used\n", name);
if (! config.build_constructors)
return true;
@ -775,9 +776,8 @@ constructor_callback (info, constructor, name, abfd, section, value)
/* 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");
einfo ("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n");
set_name = (char *) alloca (1 + sizeof "__CTOR_LIST__");
s = set_name;
if (bfd_get_symbol_leading_char (abfd) != '\0')
*s++ = bfd_get_symbol_leading_char (abfd);
@ -792,7 +792,7 @@ constructor_callback (info, constructor, name, abfd, section, value)
h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
if (h == (struct bfd_link_hash_entry *) NULL)
einfo ("%P%F: bfd_link_hash_lookup failed: %E");
einfo ("%P%F: bfd_link_hash_lookup failed: %E\n");
if (h->type == bfd_link_hash_new)
{
h->type = bfd_link_hash_undefined;
@ -806,18 +806,130 @@ constructor_callback (info, constructor, name, abfd, section, value)
return true;
}
/* A structure used by warning_callback to pass information through
bfd_map_over_sections. */
struct warning_callback_info
{
boolean found;
const char *warning;
const char *symbol;
asymbol **asymbols;
};
/* This is called when there is a reference to a warning symbol. */
/*ARGSUSED*/
static boolean
warning_callback (info, warning)
warning_callback (info, warning, symbol, abfd, section, address)
struct bfd_link_info *info;
const char *warning;
const char *symbol;
bfd *abfd;
asection *section;
bfd_vma address;
{
einfo ("%P: %s\n", warning);
if (section != NULL)
einfo ("%C: %s\n", abfd, section, address, warning);
else if (abfd == NULL)
einfo ("%P: %s\n", warning);
else if (symbol == NULL)
einfo ("%B: %s\n", abfd, warning);
else
{
lang_input_statement_type *entry;
asymbol **asymbols;
struct warning_callback_info info;
/* Look through the relocs to see if we can find a plausible
address. */
entry = (lang_input_statement_type *) abfd->usrdata;
if (entry != NULL && entry->asymbols != NULL)
asymbols = entry->asymbols;
else
{
long symsize;
long symbol_count;
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
einfo ("%B%F: could not read symbols: %E\n", abfd);
asymbols = (asymbol **) xmalloc (symsize);
symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
if (symbol_count < 0)
einfo ("%B%F: could not read symbols: %E\n", abfd);
if (entry != NULL)
{
entry->asymbols = asymbols;
entry->symbol_count = symbol_count;
}
}
info.found = false;
info.warning = warning;
info.symbol = symbol;
info.asymbols = asymbols;
bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info);
if (! info.found)
einfo ("%B: %s\n", abfd, warning);
}
return true;
}
/* This is called by warning_callback for each section. It checks the
relocs of the section to see if it can find a reference to the
symbol which triggered the warning. If it can, it uses the reloc
to give an error message with a file and line number. */
static void
warning_find_reloc (abfd, sec, iarg)
bfd *abfd;
asection *sec;
PTR iarg;
{
struct warning_callback_info *info = (struct warning_callback_info *) iarg;
long relsize;
arelent **relpp;
long relcount;
arelent **p, **pend;
if (info->found)
return;
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize < 0)
einfo ("%B%F: could not read relocs: %E\n", abfd);
if (relsize == 0)
return;
relpp = (arelent **) xmalloc (relsize);
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
if (relcount < 0)
einfo ("%B%F: could not read relocs: %E\n", abfd);
p = relpp;
pend = p + relcount;
for (; p < pend && *p != NULL; p++)
{
arelent *q = *p;
if (q->sym_ptr_ptr != NULL
&& *q->sym_ptr_ptr != NULL
&& strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
{
/* We found a reloc for the symbol we are looking for. */
einfo ("%C: %s\n", abfd, sec, q->address, info->warning);
info->found = true;
break;
}
}
free (relpp);
}
/* This is called when an undefined symbol is found. */
/*ARGSUSED*/

View File

@ -17,12 +17,22 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include <varargs.h>
#include <demangle.h>
/* this collection of routines wants to use the Unix style varargs
use special abbreviated portion of varargs.h */
#ifdef WINDOWS_NT
/* Since macro __STDC__ is defined, the compiler will raise and error if
VARARGS.H from mstools\h is included. Since we only need a portion of
this header file, it has been incorporated into local header file
xvarargs.h */
#include "xvarargs.h"
#else
#include <varargs.h>
#endif
#include "ld.h"
#include "ldmisc.h"
@ -33,6 +43,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ldmain.h"
#include "ldfile.h"
/* VARARGS*/
static void finfo ();
static const char *demangle PARAMS ((const char *string,
@ -55,6 +66,7 @@ static const char *demangle PARAMS ((const char *string,
%R info about a relent
%s arbitrary string, like printf
%d integer, like printf
%u integer, like printf
*/
static const char *
@ -189,11 +201,12 @@ vfinfo(fp, fmt, arg)
case 'S':
/* print script file and linenumber */
{
if (ldfile_input_filename) {
fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
}
}
if (parsing_defsym)
fprintf (fp, "--defsym %s", lex_string);
else if (ldfile_input_filename != NULL)
fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
else
fprintf (fp, "built in linker script:%u", lineno);
break;
case 'R':
@ -214,6 +227,7 @@ vfinfo(fp, fmt, arg)
or section name as a last resort. The arguments are a BFD,
a section, and an offset. */
{
static bfd *last_bfd;
static char *last_file = NULL;
static char *last_function = NULL;
bfd *abfd;
@ -241,11 +255,11 @@ vfinfo(fp, fmt, arg)
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
einfo ("%B%F: could not read symbols", abfd);
einfo ("%B%F: could not read symbols\n", abfd);
asymbols = (asymbol **) xmalloc (symsize);
symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
if (symbol_count < 0)
einfo ("%B%F: could not read symbols", abfd);
einfo ("%B%F: could not read symbols\n", abfd);
if (entry != (lang_input_statement_type *) NULL)
{
entry->asymbols = asymbols;
@ -257,18 +271,25 @@ vfinfo(fp, fmt, arg)
if (bfd_find_nearest_line (abfd, section, asymbols, offset,
&filename, &functionname, &linenumber))
{
if (filename == (char *) NULL)
filename = abfd->filename;
if (functionname != NULL && fmt[-1] == 'C')
{
if (last_file == NULL
if (filename == (char *) NULL)
filename = abfd->filename;
if (last_bfd == NULL
|| last_file == NULL
|| last_function == NULL
|| last_bfd != abfd
|| strcmp (last_file, filename) != 0
|| strcmp (last_function, functionname) != 0)
{
fprintf (fp, "%s: In function `%s':\n", filename,
demangle (functionname, 1));
/* We use abfd->filename in this initial line,
in case filename is a .h file or something
similarly unhelpful. */
finfo (fp, "%B: In function `%s':\n",
abfd, demangle (functionname, 1));
last_bfd = abfd;
if (last_file != NULL)
free (last_file);
last_file = buystring (filename);
@ -277,18 +298,30 @@ vfinfo(fp, fmt, arg)
last_function = buystring (functionname);
}
discard_last = false;
fprintf (fp, "%s:%u", filename, linenumber);
if (linenumber != 0)
fprintf (fp, "%s:%u", filename, linenumber);
else
finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
}
else if (filename == NULL
|| strcmp (filename, abfd->filename) == 0)
{
finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
if (linenumber != 0)
finfo (fp, "%u", linenumber);
}
else if (linenumber != 0)
fprintf (fp, "%s:%u", filename, linenumber);
finfo (fp, "%B:%s:%u", abfd, filename, linenumber);
else
finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
finfo (fp, "%B(%s+0x%v):%s", abfd, section->name, offset,
filename);
}
else
finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
if (discard_last)
{
last_bfd = NULL;
if (last_file != NULL)
{
free (last_file);
@ -312,6 +345,11 @@ vfinfo(fp, fmt, arg)
/* integer, like printf */
fprintf(fp,"%d", va_arg(arg, int));
break;
case 'u':
/* unsigned integer, like printf */
fprintf(fp,"%u", va_arg(arg, unsigned int));
break;
}
}
}

View File

@ -35,6 +35,8 @@ static void print_symbol_table PARAMS ((void));
static void print_file_stuff PARAMS ((lang_input_statement_type *));
static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
extern char *strdup();
/* Build link_order structures for the BFD linker. */
static void
@ -54,7 +56,7 @@ build_link_order (statement)
link_order = bfd_new_link_order (output_bfd, output_section);
if (link_order == NULL)
einfo ("%P%F: bfd_new_link_order failed");
einfo ("%P%F: bfd_new_link_order failed\n");
link_order->type = bfd_data_link_order;
link_order->offset = statement->data_statement.output_vma;
@ -100,7 +102,7 @@ build_link_order (statement)
link_order = bfd_new_link_order (output_bfd, output_section);
if (link_order == NULL)
einfo ("%P%F: bfd_new_link_order failed");
einfo ("%P%F: bfd_new_link_order failed\n");
link_order->offset = rs->output_vma;
link_order->size = bfd_get_reloc_size (rs->howto);
@ -223,7 +225,7 @@ clone_section (abfd, s, count)
chars of base section name and a digit suffix */
do
{
int i;
unsigned int i;
char b[6];
for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
b[i] = s->name[i];
@ -253,7 +255,7 @@ clone_section (abfd, s, count)
n->output_section = n;
n->orelocation = 0;
n->reloc_count = 0;
n->alignment_power = 1;
n->alignment_power = s->alignment_power;
return n;
}