mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 04:00:07 +08:00
Removed files that are no longer used by the rewritten linker.
This commit is contained in:
10
ld/.Sanitize
10
ld/.Sanitize
@ -56,15 +56,11 @@ ldctor.c
|
|||||||
ldctor.h
|
ldctor.h
|
||||||
ldemul.c
|
ldemul.c
|
||||||
ldemul.h
|
ldemul.h
|
||||||
lderror.c
|
|
||||||
lderror.h
|
|
||||||
ldexp.c
|
ldexp.c
|
||||||
ldexp.h
|
ldexp.h
|
||||||
ldfile.c
|
ldfile.c
|
||||||
ldfile.h
|
ldfile.h
|
||||||
ldgram.y
|
ldgram.y
|
||||||
ldindr.c
|
|
||||||
ldindr.h
|
|
||||||
ldint.texinfo
|
ldint.texinfo
|
||||||
ldlang.c
|
ldlang.c
|
||||||
ldlang.h
|
ldlang.h
|
||||||
@ -74,19 +70,13 @@ ldmain.c
|
|||||||
ldmain.h
|
ldmain.h
|
||||||
ldmisc.c
|
ldmisc.c
|
||||||
ldmisc.h
|
ldmisc.h
|
||||||
ldsym.c
|
|
||||||
ldsym.h
|
|
||||||
ldver.c
|
ldver.c
|
||||||
ldver.h
|
ldver.h
|
||||||
ldwarn.c
|
|
||||||
ldwarn.h
|
|
||||||
ldwrite.c
|
ldwrite.c
|
||||||
ldwrite.h
|
ldwrite.h
|
||||||
lexsup.c
|
lexsup.c
|
||||||
mri.c
|
mri.c
|
||||||
mri.h
|
mri.h
|
||||||
relax.c
|
|
||||||
relax.h
|
|
||||||
scripttempl
|
scripttempl
|
||||||
|
|
||||||
Things-to-lose:
|
Things-to-lose:
|
||||||
|
102
ld/lderror.c
102
ld/lderror.c
@ -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;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
void init_bfd_error_vector PARAMS ((void));
|
|
124
ld/ldindr.c
124
ld/ldindr.c
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
void do_indirect PARAMS ((ldsym_type *));
|
|
||||||
void add_indirect PARAMS ((asymbol **));
|
|
673
ld/ldsym.c
673
ld/ldsym.c
@ -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);
|
|
||||||
}
|
|
79
ld/ldsym.h
79
ld/ldsym.h
@ -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));
|
|
93
ld/ldwarn.c
93
ld/ldwarn.c
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
23
ld/ldwarn.h
23
ld/ldwarn.h
@ -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 *));
|
|
205
ld/relax.c
205
ld/relax.c
@ -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);
|
|
||||||
|
|
||||||
}
|
|
20
ld/relax.h
20
ld/relax.h
@ -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));
|
|
Reference in New Issue
Block a user