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
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:
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-void init_bfd_error_vector PARAMS ((void));
+++ /dev/null
-/* 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;
-}
-
-
-
+++ /dev/null
-void do_indirect PARAMS ((ldsym_type *));
-void add_indirect PARAMS ((asymbol **));
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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));
+++ /dev/null
-/*
- 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);
- }
-}
+++ /dev/null
-/* 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 *));
+++ /dev/null
-/* 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);
-
-}
+++ /dev/null
-/* 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));