Patches to fix bugs reported by roland McGrath

This commit is contained in:
Steve Chamberlain
1991-08-06 21:28:21 +00:00
parent e929a4c57a
commit 1af27af8bc
3 changed files with 123 additions and 54 deletions

View File

@@ -3,13 +3,11 @@
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 create an entry into the ldsym hash table as if it
were a normal symbol, but with the SYM_INDIRECT bit set in the
flags.
When it comes time to tie up the symbols at a later date, the flag
will be seen and a call made to do the right thing (tm)
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.
*/
@@ -18,41 +16,52 @@
#include "bfd.h"
#include "ld.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
DEFUN(add_indirect,(ptr),
asymbol **ptr)
{
if (config.relocateable_output == false) {
ldsym_type *sp = ldsym_get((*ptr)->name);
sp->flags |= SYM_INDIRECT;
sp->sdefs_chain = 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;
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;
}
}