Initial revision

This commit is contained in:
Steve Chamberlain 1991-08-01 23:29:03 +00:00
parent 7bfa94e296
commit 812df84bc9
3 changed files with 134 additions and 0 deletions

58
ld/ldindr.c Normal file
View file

@ -0,0 +1,58 @@
/* ldindr.c
Handle indirect symbols.
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)
*/
#include "sysdep.h"
#include "bfd.h"
#include "ld.h"
#include "ldsym.h"
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;
}
}
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;
}
}

4
ld/ldindr.h Normal file
View file

@ -0,0 +1,4 @@
void EXFUN(do_indirect, (ldsym_type *));
void EXFUN(add_indirect,(asymbol *));

72
ld/ldwarn.c Normal file
View file

@ -0,0 +1,72 @@
#include "sysdep.h"
#include "bfd.h"
#include "ldsym.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
DEFUN(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 *
DEFUN(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
DEFUN(produce_warnings,(lgs,it),
ldsym_type *lgs AND
asymbol *it)
{
asymbol **ptr;
ptr = lgs->srefs_chain;
while (ptr != (asymbol **)NULL) {
asymbol *ref = *ptr;
info("%B: %s\n", ref->the_bfd, fetch_warning(it));
ptr = (asymbol **)(ref->udata);
}
}