mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 13:56:22 +08:00
Patches to fix bugs reported by roland McGrath
This commit is contained in:
@ -80,7 +80,6 @@ ldsym.h
|
|||||||
ldvanilla.c
|
ldvanilla.c
|
||||||
ldver.c
|
ldver.c
|
||||||
ldver.h
|
ldver.h
|
||||||
ldversion.c
|
|
||||||
ldwarn.h
|
ldwarn.h
|
||||||
ldwrite.c
|
ldwrite.c
|
||||||
ldwrite.h
|
ldwrite.h
|
||||||
@ -93,6 +92,9 @@ echo Done in `pwd`.
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# $Log$
|
# $Log$
|
||||||
|
# Revision 1.4 1991/08/06 21:28:21 steve
|
||||||
|
# Patches to fix bugs reported by roland McGrath
|
||||||
|
#
|
||||||
# Revision 1.3 1991/08/01 23:59:06 steve
|
# Revision 1.3 1991/08/01 23:59:06 steve
|
||||||
# *** empty log message ***
|
# *** empty log message ***
|
||||||
#
|
#
|
||||||
|
81
ld/ldindr.c
81
ld/ldindr.c
@ -3,13 +3,11 @@
|
|||||||
|
|
||||||
BFD supplies symbols to be indirected with the BFD_INDIRECT bit
|
BFD supplies symbols to be indirected with the BFD_INDIRECT bit
|
||||||
set. Whenever the linker gets one of these, it calls add_indirect
|
set. Whenever the linker gets one of these, it calls add_indirect
|
||||||
with the symbol. We create an entry into the ldsym hash table as if it
|
with the symbol. We look up the symbol which this one dereferneces,
|
||||||
were a normal symbol, but with the SYM_INDIRECT bit set in the
|
and stop if they are the same. If they are not the same, copy all
|
||||||
flags.
|
the information from the current to the dereffed symbol. Set the
|
||||||
|
indirect bit in the flag. From now on the ldsym_get stuff will
|
||||||
When it comes time to tie up the symbols at a later date, the flag
|
perform the indirection for us, at no charge.
|
||||||
will be seen and a call made to do the right thing (tm)
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -18,41 +16,52 @@
|
|||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "ld.h"
|
#include "ld.h"
|
||||||
#include "ldsym.h"
|
#include "ldsym.h"
|
||||||
|
#include "ldmisc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static asymbol **
|
||||||
|
DEFUN(move_it,(a_list, b_list),
|
||||||
|
asymbol **a_list AND
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern ld_config_type config;
|
|
||||||
void
|
void
|
||||||
DEFUN(add_indirect,(ptr),
|
DEFUN(add_indirect,(ptr),
|
||||||
asymbol **ptr)
|
asymbol **ptr)
|
||||||
{
|
{
|
||||||
if (config.relocateable_output == false) {
|
ldsym_type *lgs = ldsym_get((*ptr)->name);
|
||||||
ldsym_type *sp = ldsym_get((*ptr)->name);
|
ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name);
|
||||||
sp->flags |= SYM_INDIRECT;
|
|
||||||
sp->sdefs_chain = ptr;
|
/* If the mapping has already been done, stop now */
|
||||||
}
|
if (lgs == new) return;
|
||||||
|
lgs->flags |= SYM_INDIRECT;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
lgs->sdefs_chain = (asymbol **)new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DEFUN(do_indirect,(ptr),
|
|
||||||
ldsym_type *ptr)
|
|
||||||
{
|
|
||||||
if (config.relocateable_output == false) {
|
|
||||||
/* Dig out the symbol were indirecting to. It's held in the value
|
|
||||||
field.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
CONST char *name = ((asymbol *)(*(ptr->sdefs_chain))->value)->name;
|
|
||||||
|
|
||||||
ldsym_type *new = ldsym_get(name);
|
|
||||||
|
|
||||||
/* We have to make a copy of the sdefs_chain item name, since
|
|
||||||
symbols will be clobbered on writing, and we want to write the
|
|
||||||
same string twice */
|
|
||||||
|
|
||||||
|
|
||||||
ptr->sdefs_chain[0][0] = new->sdefs_chain[0][0];
|
|
||||||
ptr->sdefs_chain[0][0].name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
88
ld/ldsym.c
88
ld/ldsym.c
@ -26,9 +26,40 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
Written by Steve Chamberlain steve@cygnus.com
|
Written by Steve Chamberlain steve@cygnus.com
|
||||||
|
|
||||||
All symbol handling for the linker
|
All symbol handling for the linker
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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. Duringing
|
||||||
|
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 "sysdep.h"
|
#include "sysdep.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
|
||||||
@ -61,12 +92,15 @@ extern boolean option_longmap ;
|
|||||||
static ldsym_type *global_symbol_hash_table[TABSIZE];
|
static ldsym_type *global_symbol_hash_table[TABSIZE];
|
||||||
|
|
||||||
/* Compute the hash code for symbol name KEY. */
|
/* Compute the hash code for symbol name KEY. */
|
||||||
|
static
|
||||||
|
#ifdef __GNUC__
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
int
|
int
|
||||||
hash_string (key)
|
DEFUN(hash_string,(key),
|
||||||
char *key;
|
CONST char *key)
|
||||||
{
|
{
|
||||||
register char *cp;
|
register CONST char *cp;
|
||||||
register int k;
|
register int k;
|
||||||
|
|
||||||
cp = key;
|
cp = key;
|
||||||
@ -77,6 +111,28 @@ hash_string (key)
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
#ifdef __GNUC__
|
||||||
|
inline
|
||||||
|
#endif ldsym_type *bp;
|
||||||
|
ldsym_type *
|
||||||
|
DEFUN(search,(key,hashval) ,
|
||||||
|
CONST char *key AND
|
||||||
|
int hashval)
|
||||||
|
{
|
||||||
|
ldsym_type *bp;
|
||||||
|
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
|
||||||
|
if (! strcmp (key, bp->name)) {
|
||||||
|
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.
|
/* Get the symbol table entry for the global symbol named KEY.
|
||||||
Create one if there is none. */
|
Create one if there is none. */
|
||||||
ldsym_type *
|
ldsym_type *
|
||||||
@ -91,10 +147,10 @@ DEFUN(ldsym_get,(key),
|
|||||||
hashval = hash_string (key) % TABSIZE;
|
hashval = hash_string (key) % TABSIZE;
|
||||||
|
|
||||||
/* Search the bucket. */
|
/* Search the bucket. */
|
||||||
|
bp = search(key, hashval);
|
||||||
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
|
if(bp) {
|
||||||
if (! strcmp (key, bp->name))
|
|
||||||
return bp;
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Nothing was found; create a new symbol table entry. */
|
/* Nothing was found; create a new symbol table entry. */
|
||||||
|
|
||||||
@ -132,12 +188,7 @@ DEFUN(ldsym_get_soft,(key),
|
|||||||
hashval = hash_string (key) % TABSIZE;
|
hashval = hash_string (key) % TABSIZE;
|
||||||
|
|
||||||
/* Search the bucket. */
|
/* Search the bucket. */
|
||||||
|
return search(key, hashval);
|
||||||
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
|
|
||||||
if (! strcmp (key, bp->name))
|
|
||||||
return bp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -214,6 +265,11 @@ ldsym_print_symbol_table ()
|
|||||||
|
|
||||||
for (sp = symbol_head; sp; sp = sp->next)
|
for (sp = symbol_head; sp; sp = sp->next)
|
||||||
{
|
{
|
||||||
|
if (sp->flags & SYM_INDIRECT) {
|
||||||
|
fprintf(stdout,"indirect %s to %s\n",
|
||||||
|
sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (sp->sdefs_chain)
|
if (sp->sdefs_chain)
|
||||||
{
|
{
|
||||||
asymbol *defsym = *(sp->sdefs_chain);
|
asymbol *defsym = *(sp->sdefs_chain);
|
||||||
@ -247,6 +303,8 @@ ldsym_print_symbol_table ()
|
|||||||
else {
|
else {
|
||||||
printf("undefined ");
|
printf("undefined ");
|
||||||
printf("%s ",sp->name);
|
printf("%s ",sp->name);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print_nl();
|
print_nl();
|
||||||
|
|
||||||
@ -352,7 +410,7 @@ asymbol **symbol_table;
|
|||||||
{
|
{
|
||||||
FOR_EACH_LDSYM(sp)
|
FOR_EACH_LDSYM(sp)
|
||||||
{
|
{
|
||||||
if (sp->sdefs_chain != (asymbol **)NULL) {
|
if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
|
||||||
asymbol *bufp = (*(sp->sdefs_chain));
|
asymbol *bufp = (*(sp->sdefs_chain));
|
||||||
|
|
||||||
if ((bufp->flags & BSF_KEEP) ==0) {
|
if ((bufp->flags & BSF_KEEP) ==0) {
|
||||||
|
Reference in New Issue
Block a user