Removed files that are no longer used by the rewritten linker.

This commit is contained in:
Ian Lance Taylor 1993-12-30 19:57:49 +00:00
parent 4c3721d514
commit 93b135859d
11 changed files with 0 additions and 1332 deletions

View File

@ -56,15 +56,11 @@ ldctor.c
ldctor.h
ldemul.c
ldemul.h
lderror.c
lderror.h
ldexp.c
ldexp.h
ldfile.c
ldfile.h
ldgram.y
ldindr.c
ldindr.h
ldint.texinfo
ldlang.c
ldlang.h
@ -74,19 +70,13 @@ ldmain.c
ldmain.h
ldmisc.c
ldmisc.h
ldsym.c
ldsym.h
ldver.c
ldver.h
ldwarn.c
ldwarn.h
ldwrite.c
ldwrite.h
lexsup.c
mri.c
mri.h
relax.c
relax.h
scripttempl
Things-to-lose:

View File

@ -1,102 +0,0 @@
/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
GLD 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, or (at your option)
any later version.
GLD 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 GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <bfd.h>
#include "sysdep.h"
#include "../bfd/seclet.h"
#include "ld.h"
#include "ldmisc.h"
#include "lderror.h"
#define MAX_ERRORS_IN_A_ROW 5
extern bfd_error_vector_type bfd_error_vector;
static void ld_undefined_symbol PARAMS ((const arelent *,
const bfd_seclet_type *));
static void ld_reloc_truncated PARAMS ((const arelent *,
bfd_seclet_type *));
/* BFD has failed to link something, give a better error message */
static void
ld_undefined_symbol (relent, seclet)
CONST arelent *relent;
CONST bfd_seclet_type *seclet;
{
asymbol *s = *(relent->sym_ptr_ptr);
static asymbol *error_symbol;
static unsigned int error_count;
if (seclet != (bfd_seclet_type *)NULL)
{
asection *section = seclet->u.indirect.section;
bfd *abfd = section->owner;
/* We remember the symbol, and never print more than
a reasonable number of them in a row */
if (s == error_symbol) {
error_count++;
}
else {
error_count = 0;
error_symbol = s;
}
if (error_count < MAX_ERRORS_IN_A_ROW) {
einfo("%X%C: undefined reference to `%T'\n",
abfd,section, seclet->u.indirect.symbols,
relent->address, s);
config.make_executable = false;
}
else if (error_count == MAX_ERRORS_IN_A_ROW) {
einfo("%C: more undefined references to `%T' follow\n",
abfd, section,
seclet->u.indirect.symbols,
relent->address, s);
}
else {
/* Don't print any more */
}
}
else
{
einfo("%Xundefined reference to %s\n", (*(relent->sym_ptr_ptr))->name);
}
}
static void
ld_reloc_truncated (relent, seclet)
CONST arelent *relent;
bfd_seclet_type *seclet;
{
asection *section = seclet->u.indirect.section;
bfd *abfd = section->owner;
einfo("%X%C: relocation truncated to fit %R\n",
abfd, section, seclet->u.indirect.symbols, relent->address, relent);
}
void
init_bfd_error_vector ()
{
bfd_error_vector.undefined_symbol = ld_undefined_symbol;
bfd_error_vector.reloc_value_truncated = ld_reloc_truncated;
}

View File

@ -1 +0,0 @@
void init_bfd_error_vector PARAMS ((void));

View File

@ -1,124 +0,0 @@
/* ldindr.c
Handle indirect symbols.
Copyright (C) 1991 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
GLD 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, or (at your option)
any later version.
GLD 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 GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
An indirect symbol is where a global symbol in one file say's that
all refs like it should be turned into refs of the symbol pointed
at by the value of the indirect symbol.
BFD supplies symbols to be indirected with the BFD_INDIRECT bit
set. Whenever the linker gets one of these, it calls add_indirect
with the symbol. We look up the symbol which this one dereferneces,
and stop if they are the same. If they are not the same, copy all
the information from the current to the dereffed symbol. Set the
indirect bit in the flag. From now on the ldsym_get stuff will
perform the indirection for us, at no charge.
*/
#include "bfd.h"
#include "sysdep.h"
#include "ld.h"
#include "ldsym.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldindr.h"
static asymbol **move_it PARAMS ((asymbol **, asymbol **));
static asymbol **
move_it (a_list, b_list)
asymbol **a_list;
asymbol **b_list;
{
asymbol **head = a_list;
asymbol **cursor = head;
if (a_list == 0) return b_list;
if (b_list == 0) return a_list;
while (1) {
asymbol *ptr = cursor[0];
asymbol **next = (asymbol **)(ptr->udata);
if (next == 0) {
ptr->udata = (PTR) b_list;
return head;
}
cursor = next;
}
}
#if 0
void
copy_over (ldsym, bfdsym)
ldsym_type *ldsym;
asymbol **bfdsym;
{
while (list && *list)
{
refize(enter_global_ref(list, name));
list = (asymbol **)((*list)->udata);
}
}
#endif
/* This call allows us to change the symbol table so that all future
refs to the symbol are patched to know the alias - but we still
have to fix all the old ones */
void
add_indirect (ptr)
asymbol **ptr;
{
ldsym_type *lgs = ldsym_get((*ptr)->name);
ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name);
/* If the mapping has already been done, stop now */
if (lgs == new) return;
lgs->flags |= SYM_INDIRECT;
if (lgs->sdefs_chain && lgs->sdefs_chain[0])
{
einfo("indirect symbol already has definition %s\n", lgs->sdefs_chain[0]);
}
new->scoms_chain = move_it(new->scoms_chain, lgs->scoms_chain);
lgs->scoms_chain = 0;
new->srefs_chain = move_it(new->srefs_chain, lgs->srefs_chain);
lgs->srefs_chain = 0;
new->sdefs_chain = move_it(new->sdefs_chain, lgs->sdefs_chain);
lgs->sdefs_chain = 0;
/* If the result has any commons they should be turned into refs */
if (new->sdefs_chain && new->scoms_chain)
{
refize(new, new->scoms_chain);
}
lgs->sdefs_chain = (asymbol **)new;
lgs->srefs_chain = ptr;
}

View File

@ -1,2 +0,0 @@
void do_indirect PARAMS ((ldsym_type *));
void add_indirect PARAMS ((asymbol **));

View File

@ -1,673 +0,0 @@
/* All symbol handling for the linker
Copyright (C) 1991 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@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. */
/*
We keep a hash table of global symbols. Each entry in a hash table
is called an ldsym_type. Each has three chains; a pointer to a
chain of definitions for the symbol (hopefully one long), a pointer
to a chain of references to the symbol, and a pointer to a chain of
common symbols. Each pointer points into the canonical symbol table
provided by bfd, each one of which points to an asymbol. During
linkage, the linker uses the udata field to point to the next entry
in a canonical table....
ld_sym
| |
+----------+ +----------+
| defs | a canonical symbol table
+----------+ +----------+
| refs | -----> | one entry| -----> asymbol
+----------+ +----------+ | |
| coms | | | +---------+
+----------+ +----------+ | udata |-----> another canonical
+---------+ symbol
It is very simple to make all the symbol pointers point to the same
definition - just run down the chain and make the asymbols pointers
within the canonical table point to the asymbol attacthed to the
definition of the symbol.
*/
#include "bfd.h"
#include "sysdep.h"
#include "ld.h"
#include "ldsym.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "mri.h"
#include "ldmain.h"
/* Head and tail of global symbol table chronological list */
ldsym_type *symbol_head = (ldsym_type *) NULL;
ldsym_type **symbol_tail_ptr = &symbol_head;
CONST char *keepsyms_file;
int kept_syms;
struct obstack global_sym_obstack;
#define obstack_chunk_alloc ldmalloc
#define obstack_chunk_free free
/*
incremented for each symbol in the ldsym_type table
no matter what flavour it is
*/
unsigned int global_symbol_count;
/* LOCALS */
#define TABSIZE 1009
static ldsym_type *global_symbol_hash_table[TABSIZE];
#ifndef __GNUC__
#define __inline
#endif
static __inline int hash_string PARAMS ((const char *key));
static __inline ldsym_type *search PARAMS ((const char *key, int hashval));
static asymbol **process_keepsyms PARAMS ((asymbol **table, int size));
static void print_file_stuff PARAMS ((lang_input_statement_type * f));
static asymbol **write_file_locals PARAMS ((asymbol **output_buffer));
static asymbol **write_file_globals PARAMS ((asymbol **symbol_table));
/* Compute the hash code for symbol name KEY. */
static __inline int
hash_string (key)
CONST char *key;
{
register CONST char *cp;
register int k;
register int l = 0;
cp = key;
k = 0;
while (*cp && l < symbol_truncate)
{
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
l++;
}
return k;
}
static __inline ldsym_type *
search (key, hashval)
CONST char *key;
int hashval;
{
ldsym_type *bp;
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
if (!strncmp (key, bp->name, symbol_truncate))
{
if (bp->flags & SYM_INDIRECT)
{
/* Use the symbol we're aliased to instead */
return (ldsym_type *) (bp->sdefs_chain);
}
return bp;
}
return 0;
}
/* Get the symbol table entry for the global symbol named KEY.
Create one if there is none. */
ldsym_type *
ldsym_get (key)
CONST char *key;
{
register int hashval;
register ldsym_type *bp;
/* Determine the proper bucket. */
hashval = hash_string (key) % TABSIZE;
/* Search the bucket. */
bp = search (key, hashval);
if (bp)
{
return bp;
}
/* Nothing was found; create a new symbol table entry. */
bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type) (sizeof (ldsym_type)));
bp->srefs_chain = (asymbol **) NULL;
bp->sdefs_chain = (asymbol **) NULL;
bp->scoms_chain = (asymbol **) NULL;
bp->name = obstack_copy (&global_sym_obstack, key, strlen (key) + 1);
bp->flags = 0;
/* Add the entry to the bucket. */
bp->link = global_symbol_hash_table[hashval];
global_symbol_hash_table[hashval] = bp;
/* Keep the chronological list up to date too */
*symbol_tail_ptr = bp;
symbol_tail_ptr = &bp->next;
bp->next = 0;
global_symbol_count++;
return bp;
}
/* Like `ldsym_get' but return 0 if the symbol is not already known. */
ldsym_type *
ldsym_get_soft (key)
CONST char *key;
{
register int hashval;
/* Determine which bucket. */
hashval = hash_string (key) % TABSIZE;
/* Search the bucket. */
return search (key, hashval);
}
static asymbol **
process_keepsyms (table, size)
asymbol **table;
int size;
{
struct obstack obstack;
char *start_of_obstack;
FILE *ks_file = 0;
asymbol **out = table;
asymbol **end = table + size;
asymbol **sym;
if (!keepsyms_file || size == 0)
return end;
obstack_init (&obstack);
obstack_alloc (&obstack, 1);
obstack_finish (&obstack);
start_of_obstack = obstack_alloc (&obstack, 1);
ks_file = fopen (keepsyms_file, "r");
if (!ks_file)
{
info_msg ("%X%P: cannot open keep-symbols file `%s'\n", keepsyms_file);
goto egress;
}
errno = 0;
#define KEEP(S) \
do { asymbol **p = (S), *tmp = *out; *out = *p; *p = tmp; out++; } while (0)
while (!feof (ks_file) && !ferror (ks_file))
{
int c;
char *ptr;
int found = 0;
obstack_free (&obstack, start_of_obstack);
do
{
c = getc (ks_file);
if (c == '\n')
c = 0;
obstack_1grow (&obstack, c);
}
while (c > 0);
if (c == EOF)
{
if (!feof (ks_file))
/* error occurred */
{
info_msg ("%X%P: error reading keep-symbols file `%s': %E\n",
keepsyms_file);
out = end;
goto egress;
}
if (obstack_next_free (&obstack) != obstack_base (&obstack) + 1)
/* eof in middle of symbol */
{
info_msg ("%X%P: eof reached mid-line while reading keep-symbols file `%s'\n",
keepsyms_file);
out = end;
goto egress;
}
/* All okay -- no incomplete lines, EOF reached. */
break;
}
ptr = obstack_next_free (&obstack) - 2;
/* discard trailing trash */
while (*ptr == ' '
|| *ptr == '\t')
*ptr-- = 0;
ptr = obstack_base (&obstack);
for (sym = out; sym < end; sym++)
if (!strncmp ((*sym)->name, ptr, symbol_truncate))
{
KEEP (sym);
found = 1;
}
if (!found)
info_msg ("%P: symbol `%s' (requested to be kept) not found\n", ptr);
}
/* It'd be slightly faster to move this pass above the previous one,
but that'd mean any symbols preserved in this pass would generate
warnings if they were also listed in the keepsyms file. */
for (sym = out; sym < end; sym++)
{
asymbol *s = *sym;
if (s->section == &bfd_und_section
|| bfd_is_com_section (s->section)
|| s->flags & BSF_KEEP_G)
KEEP (sym);
}
egress:
obstack_free (&obstack, start_of_obstack);
if (ks_file)
fclose (ks_file);
return out;
}
#if 0
/* This function is not used. */
static void
list_file_locals (entry)
lang_input_statement_type *entry;
{
asymbol **q;
fprintf (config.map_file, "\nLocal symbols of ");
minfo ("%I", entry);
fprintf (config.map_file, ":\n\n");
if (entry->asymbols)
{
for (q = entry->asymbols; *q; q++)
{
asymbol *p = *q;
/* If this is a definition,
update it if necessary by this file's start address. */
if (p->flags & BSF_LOCAL)
info_msg (" %V %s\n", p->value, p->name);
}
}
}
#endif
static void
print_file_stuff (f)
lang_input_statement_type * f;
{
fprintf (config.map_file, " %s\n", f->filename);
if (f->just_syms_flag)
{
fprintf (config.map_file, " symbols only\n");
}
else
{
asection *s;
if (true)
{
for (s = f->the_bfd->sections;
s != (asection *) NULL;
s = s->next)
{
print_address (s->output_offset);
if (s->reloc_done)
{
fprintf (config.map_file, " %08x 2**%2ud %s\n",
(unsigned) bfd_get_section_size_after_reloc (s),
s->alignment_power, s->name);
}
else
{
fprintf (config.map_file, " %08x 2**%2ud %s\n",
(unsigned) bfd_get_section_size_before_reloc (s),
s->alignment_power, s->name);
}
}
}
else
{
for (s = f->the_bfd->sections;
s != (asection *) NULL;
s = s->next)
{
fprintf (config.map_file, "%s ", s->name);
print_address (s->output_offset);
fprintf (config.map_file, "(%x)", (unsigned) bfd_get_section_size_after_reloc (s));
}
fprintf (config.map_file, "hex \n");
}
}
fprintf (config.map_file, "\n");
}
void
ldsym_print_symbol_table ()
{
fprintf (config.map_file, "**FILES**\n\n");
lang_for_each_file (print_file_stuff);
fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
fprintf (config.map_file, "offset section offset symbol\n");
{
register ldsym_type *sp;
for (sp = symbol_head; sp; sp = sp->next)
{
if (sp->flags & SYM_INDIRECT)
{
fprintf (config.map_file, "indirect %s to %s\n",
sp->name, (((ldsym_type *) (sp->sdefs_chain))->name));
}
else
{
if (sp->sdefs_chain)
{
asymbol *defsym = *(sp->sdefs_chain);
asection *defsec = bfd_get_section (defsym);
print_address (defsym->value);
if (defsec)
{
fprintf (config.map_file, " %-10s",
bfd_section_name (output_bfd,
defsec));
print_space ();
print_address (defsym->value + defsec->vma);
}
else
{
fprintf (config.map_file, " .......");
}
}
if (sp->scoms_chain)
{
fprintf (config.map_file, "common ");
print_address ((*(sp->scoms_chain))->value);
fprintf (config.map_file, " %s ", sp->name);
}
else if (sp->sdefs_chain)
{
fprintf (config.map_file, " %s ", sp->name);
}
else
{
fprintf (config.map_file, "undefined ");
fprintf (config.map_file, "%s ", sp->name);
}
}
print_nl ();
}
}
}
static asymbol **
write_file_locals (output_buffer)
asymbol **output_buffer;
{
LANG_FOR_EACH_INPUT_STATEMENT (entry)
{
/* Run trough the symbols and work out what to do with them */
unsigned int i;
/* Add one for the filename symbol if needed */
if (create_object_symbols
!= (lang_output_section_statement_type *) NULL)
{
asection *s;
for (s = entry->the_bfd->sections;
s != (asection *) NULL;
s = s->next)
{
if (s->output_section == create_object_symbols->bfd_section)
{
/* Add symbol to this section */
asymbol *newsym =
(asymbol *) bfd_make_empty_symbol (entry->the_bfd);
newsym->name = entry->local_sym_name;
/* The symbol belongs to the output file's text section */
/* The value is the start of this section in the output file*/
newsym->value = 0;
/* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
"used by the linker" and I can't find any other code that
uses it. Should be a cleaner way of doing this (like an
"application flags" field in the symbol structure?). */
newsym->flags = BSF_LOCAL | BSF_KEEP_G | BSF_FILE;
newsym->section = s;
*output_buffer++ = newsym;
break;
}
}
}
for (i = 0; i < entry->symbol_count; i++)
{
asymbol *p = entry->asymbols[i];
/* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
if (p->section == 0)
p->section = &bfd_abs_section;
if ((p->flags & BSF_GLOBAL)
|| (p->flags & BSF_WEAK))
{
/* If this symbol is marked as occurring now, rather than
at the end, output it now. This is used for COFF C_EXT
FCN symbols. FIXME: There must be a better way. */
if (bfd_asymbol_bfd (p) == entry->the_bfd
&& (p->flags & BSF_NOT_AT_END))
{
*(output_buffer++) = p;
p->flags |= BSF_KEEP;
}
}
else
{
if (p->section == &bfd_ind_section)
{
/* Dont think about indirect symbols */
}
else if (p->flags & BSF_DEBUGGING)
{
/* Only keep the debugger symbols if no stripping required */
if (strip_symbols == STRIP_NONE)
{
*output_buffer++ = p;
}
}
else if (p->section == &bfd_und_section
|| bfd_is_com_section (p->section))
{
/* These must be global. */
}
else if (p->flags & BSF_LOCAL)
{
if (discard_locals == DISCARD_ALL)
{
}
else if (discard_locals == DISCARD_L &&
!strncmp (lprefix, p->name, lprefix_len))
{
}
else if (p->flags == BSF_WARNING)
{
}
else
{
*output_buffer++ = p;
}
}
else if (p->flags & BSF_CONSTRUCTOR)
{
if (strip_symbols != STRIP_ALL)
{
*output_buffer++ = p;
}
}
else
{
FAIL ();
}
}
}
}
return output_buffer;
}
static asymbol **
write_file_globals (symbol_table)
asymbol **symbol_table;
{
FOR_EACH_LDSYM (sp)
{
if (sp->flags & SYM_INDIRECT)
{
asymbol *bufp = (*(sp->srefs_chain));
ldsym_type *aliased_to = (ldsym_type *) (sp->sdefs_chain);
if (aliased_to->sdefs_chain)
{
asymbol *p = aliased_to->sdefs_chain[0];
bufp->value = p->value;
bufp->section = p->section;
bufp->flags = p->flags;
}
else
{
bufp->value = 0;
bufp->flags = 0;
bufp->section = &bfd_und_section;
}
*symbol_table++ = bufp;
}
else if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **) NULL)
{
asymbol *bufp = (*(sp->sdefs_chain));
if ((bufp->flags & BSF_KEEP) == 0)
{
ASSERT (bufp != (asymbol *) NULL);
bufp->name = sp->name;
if (sp->scoms_chain != (asymbol **) NULL)
{
/*
defined as common but not allocated, this happens
only with -r and not -d, write out a common
definition
*/
bufp = *(sp->scoms_chain);
}
*symbol_table++ = bufp;
}
}
else if (sp->scoms_chain != (asymbol **) NULL)
{
/* This symbol is a common - just output */
asymbol *bufp = (*(sp->scoms_chain));
*symbol_table++ = bufp;
}
else if (sp->srefs_chain != (asymbol **) NULL)
{
/* This symbol is undefined but has a reference */
asymbol *bufp = (*(sp->srefs_chain));
*symbol_table++ = bufp;
}
else
{
/*
This symbol has neither defs nor refs, it must have come
from the command line, since noone has used it it has no
data attatched, so we'll ignore it
*/
}
}
return symbol_table;
}
void
ldsym_write ()
{
if (keepsyms_file != 0
&& strip_symbols != STRIP_SOME)
{
info_msg ("%P: `-retain-symbols-file' overrides `-s' and `-S'\n");
strip_symbols = STRIP_SOME;
}
if (strip_symbols != STRIP_ALL)
{
/* We know the maximum size of the symbol table -
it's the size of all the global symbols ever seen +
the size of all the symbols from all the files +
the number of files (for the per file symbols)
+1 (for the null at the end)
*/
asymbol **symbol_table =
((asymbol **)
ldmalloc ((bfd_size_type) ((global_symbol_count
+ total_files_seen
+ total_symbols_seen
+ 1)
* sizeof (asymbol *))));
asymbol **tablep = write_file_locals (symbol_table);
tablep = write_file_globals (tablep);
tablep = process_keepsyms (symbol_table, tablep - symbol_table);
*tablep = (asymbol *) NULL;
bfd_set_symtab (output_bfd, symbol_table, (unsigned) (tablep - symbol_table));
}
}
/*
return true if the supplied symbol name is not in the
linker symbol table
*/
boolean
ldsym_undefined (sym)
CONST char *sym;
{
ldsym_type *from_table = ldsym_get_soft (sym);
if (from_table != (ldsym_type *) NULL)
{
if (from_table->sdefs_chain != (asymbol **) NULL)
return false;
}
return true;
}
void
ldsym_init ()
{
obstack_begin (&global_sym_obstack, 20000);
}

View File

@ -1,79 +0,0 @@
/* ldsym.h -
Copyright (C) 1991 Free Software Foundation, Inc.
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. */
typedef struct user_symbol_struct
{
/* Point to next symbol in this hash chain */
struct user_symbol_struct *link;
/* Name of this symbol. */
CONST char *name;
/* Pointer to next symbol in order of symbol creation */
struct user_symbol_struct *next;
/* Chain of asymbols we see from input files
note that we point to the entry in the canonical table of
the pointer to the asymbol, *not* the asymbol. This means
that we can run back and fix all refs to point to the
defs nearly for free.
*/
asymbol **srefs_chain;
asymbol **sdefs_chain;
/* only ever point to the largest ever common definition -
* all the rest are turned into refs
* scoms and sdefs are never != NULL at same time
*/
asymbol **scoms_chain;
/* If this symbol is a constructor */
#define SYM_CONSTRUCTOR 1
/* If this symbol is a warning symbol */
#define SYM_WARNING 2
/* IF this is an alias for another symbol */
#define SYM_INDIRECT 4
/* If this symbol explicitly should be kept, despite discarding
most others. */
#define SYM_KEEP 8
/* If its got -y set */
#define SYM_Y 16
int flags;
} ldsym_type;
extern ldsym_type *symbol_head;
extern CONST char *keepsyms_file;
extern int kept_syms;
ldsym_type *ldsym_get PARAMS ((CONST char *));
ldsym_type *ldsym_get_soft PARAMS ((CONST char *));
void ldsym_print_symbol_table PARAMS ((void));
void ldsym_write PARAMS ((void));
boolean ldsym_undefined PARAMS ((CONST char *));
#define FOR_EACH_LDSYM(x) \
ldsym_type *x; \
for (x = symbol_head; x != (ldsym_type *)NULL; x = x->next)
void ldsym_init PARAMS ((void));

View File

@ -1,93 +0,0 @@
/*
Copyright (C) 1991 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
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. */
#include "bfd.h"
#include "sysdep.h"
#include "ldsym.h"
#include "ldwarn.h"
#include "ldmisc.h"
/* we keep all the warning symbols in a list, if we ever get a
warning, we'll search it the hard way. This won't be to bad since
warnings are infrequent, and never that many (true or false ?).
*/
typedef struct warning_list_struct {
struct warning_list_struct *next;
asymbol *sym;
} warning_list_type;
static warning_list_type *warning_list;
/* This is a warning symbol, add the error text to a list we keep, and mark
the symbol referenced as requiring a warning */
void
add_warning (sym)
asymbol *sym;
{
CONST char *name = ((asymbol *)(sym->value))->name;
warning_list_type *new;
ldsym_type *lookup = ldsym_get(name);
lookup->flags |= SYM_WARNING;
new = (warning_list_type *)ldmalloc(sizeof(warning_list_type));
new->next = warning_list;
new->sym = sym;
warning_list = new;
}
/* run through the list we kept, and find the warning associated with
this symbol */
CONST char *
fetch_warning (sym)
asymbol *sym;
{
warning_list_type *ptr = warning_list;
while (ptr != (warning_list_type *)NULL) {
if (strcmp(((asymbol*)(ptr->sym->value))->name, sym->name) == 0) {
return ptr->sym->name;
}
ptr = ptr->next;
}
return "This is a warning without a message !";
}
void
produce_warnings (lgs, it)
ldsym_type *lgs;
asymbol *it;
{
asymbol **ptr;
ptr = lgs->srefs_chain;
while (ptr != (asymbol **)NULL) {
asymbol *ref = *ptr;
info_msg ("%B: %s\n", bfd_asymbol_bfd(ref), fetch_warning(it));
ptr = (asymbol **)(ref->udata);
}
}

View File

@ -1,23 +0,0 @@
/* Warning support for the GNU Linker.
Copyright 1991, 1992 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
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. */
void add_warning PARAMS ((asymbol *));
CONST char *fetch_warning PARAMS ((asymbol *));
void produce_warnings PARAMS ((ldsym_type *, asymbol *));

View File

@ -1,205 +0,0 @@
/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
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. */
/*
new age linking
Tie together all the interseting blocks
*/
#include "bfd.h"
#include "../bfd/seclet.h"
#include "coff/internal.h"
#include "sysdep.h"
#include "ld.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldwrite.h"
#include "ldmisc.h"
#include "ldsym.h"
#include "ldgram.h"
#include "relax.h"
static void build_it PARAMS ((lang_statement_union_type *));
static void
build_it (statement)
lang_statement_union_type * statement;
{
switch (statement->header.type)
{
#if 0
{
bfd_byte play_area[SHORT_SIZE];
unsigned int i;
bfd_putshort (output_bfd, statement->fill_statement.fill, play_area);
/* Write out all entire shorts */
for (i = 0;
i < statement->fill_statement.size - SHORT_SIZE + 1;
i += SHORT_SIZE)
{
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset + i,
SHORT_SIZE);
}
/* Now write any remaining byte */
if (i < statement->fill_statement.size)
{
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset + i,
1);
}
abort ();
}
break;
#endif
case lang_data_statement_enum:
{
bfd_vma value = statement->data_statement.value;
bfd_byte play_area[LONG_SIZE];
unsigned int size = 0;
asection *output_section = statement->data_statement.output_section;
switch (statement->data_statement.type)
{
case LONG:
bfd_put_32 (output_section->owner, value, play_area);
size = LONG_SIZE;
break;
case SHORT:
bfd_put_16 (output_section->owner, value, play_area);
size = SHORT_SIZE;
break;
case BYTE:
bfd_put_8 (output_section->owner, value, play_area);
size = BYTE_SIZE;
break;
}
bfd_set_section_contents (output_section->owner,
statement->data_statement.output_section,
play_area,
((file_ptr)
statement->data_statement.output_vma),
size);
}
break;
case lang_input_section_enum:
{
/* Create a new seclet in the output section with this
attached */
if (statement->input_section.ifile->just_syms_flag == false)
{
asection *i = statement->input_section.section;
asection *output_section = i->output_section;
bfd_seclet_type *seclet = bfd_new_seclet (output_section->owner, output_section);
if (i->flags & SEC_NEVER_LOAD)
{
/* We've got a never load section inside one which is going
to be output, we'll change it into a fill seclet */
seclet->type = bfd_fill_seclet;
seclet->u.fill.value = 0;
}
else
{
seclet->type = bfd_indirect_seclet;
seclet->u.indirect.section = i;
seclet->u.indirect.symbols
= statement->input_section.ifile->asymbols;
}
seclet->size = i->_cooked_size;
seclet->offset = i->output_offset;
seclet->next = 0;
}
}
break;
case lang_padding_statement_enum:
/* Make a new seclet with the right filler */
{
/* Create a new seclet in the output section with this
attached */
bfd_seclet_type *seclet =
bfd_new_seclet (statement->padding_statement.output_section->owner,
statement->padding_statement.output_section);
seclet->type = bfd_fill_seclet;
seclet->size = statement->padding_statement.size;
seclet->offset = statement->padding_statement.output_offset;
seclet->u.fill.value = statement->padding_statement.fill;
seclet->next = 0;
}
break;
default:
/* All the other ones fall through */
;
}
}
void
write_relax (output_bfd, data, relocateable)
bfd * output_bfd;
PTR data;
boolean relocateable;
{
/* Tie up all the statements to generate an output bfd structure which
bfd can mull over */
lang_for_each_statement (build_it);
if (bfd_seclet_link (output_bfd, data, relocateable) == false)
einfo ("%F%P: %B: %E\n", output_bfd);
}
/* See if we can change the size of this section by shrinking the
relocations in it. If this happens, then we'll have to renumber the
symbols in it, and shift around the data too.
*/
boolean
relax_section (this_ptr)
lang_statement_union_type ** this_ptr;
{
lang_input_section_type *is = &((*this_ptr)->input_section);
asection *i = is->section;
if (!(i->owner->flags & BFD_IS_RELAXABLE))
{
if (i->owner != script_file->the_bfd)
einfo ("%B: not assembled with -linkrelax\n", i->owner);
}
return bfd_relax_section (i->owner, i, is->ifile->asymbols);
}

View File

@ -1,20 +0,0 @@
/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
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. */
void write_relax PARAMS ((bfd *, PTR data, boolean relocateable));
boolean relax_section PARAMS ((lang_statement_union_type **this_ptr));