freebsd-dev/gnu/usr.bin/ld/symbol.c
Jordan K. Hubbard 09e3d49d92 This is Paul K's latest set of ld changes. A commit was necessary at this
late stage due to the fact that link.h was copyright Sun Microsystems.

This version of ld sync's us up with NetBSD's ld and supports compatablily
with NetBSD's -[zZ] flags (which we had reversed).  Compiling with this
new ld will give you RRS warnings for libraries which do not contain .type
infomation - these wsarnings are harmless and will go away as soon as you
recompile your libraries (cd /usr/src; make libraries).
1994-02-13 20:43:13 +00:00

160 lines
3.3 KiB
C

/*
* $Id: symbol.c,v 1.3 1993/11/22 19:04:45 jkh Exp $ - symbol table routines
*/
/* Create the symbol table entries for `etext', `edata' and `end'. */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <a.out.h>
#include <stab.h>
#include <string.h>
#include "ld.h"
symbol *symtab[SYMTABSIZE]; /* The symbol table. */
int num_hash_tab_syms; /* Number of symbols in symbol hash table. */
symbol *edata_symbol; /* the symbol _edata */
symbol *etext_symbol; /* the symbol _etext */
symbol *end_symbol; /* the symbol _end */
symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
symbol *dynamic_symbol; /* the symbol __DYNAMIC */
void
symtab_init (relocatable_output)
int relocatable_output;
{
/*
* Put linker reserved symbols into symbol table.
*/
#ifndef nounderscore
#define ETEXT_SYM "_etext"
#define EDATA_SYM "_edata"
#define END_SYM "_end"
#define DYN_SYM "__DYNAMIC"
#define GOT_SYM "__GLOBAL_OFFSET_TABLE_"
#else
#define ETEXT_SYM "etext"
#define EDATA_SYM "edata"
#define END_SYM "end"
#define DYN_SYM "_DYNAMIC"
#define GOT_SYM "_GLOBAL_OFFSET_TABLE_"
#endif
dynamic_symbol = getsym (DYN_SYM);
dynamic_symbol->defined = relocatable_output?N_UNDF:(N_DATA | N_EXT);
got_symbol = getsym (GOT_SYM);
got_symbol->defined = N_DATA | N_EXT;
if (relocatable_output)
return;
etext_symbol = getsym (ETEXT_SYM);
edata_symbol = getsym (EDATA_SYM);
end_symbol = getsym (END_SYM);
etext_symbol->defined = N_TEXT | N_EXT;
edata_symbol->defined = N_DATA | N_EXT;
end_symbol->defined = N_BSS | N_EXT;
etext_symbol->flags |= GS_REFERENCED;
edata_symbol->flags |= GS_REFERENCED;
end_symbol->flags |= GS_REFERENCED;
}
/* Compute the hash code for symbol name KEY. */
int
hash_string (key)
char *key;
{
register char *cp;
register int k;
cp = key;
k = 0;
while (*cp)
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
return k;
}
/* Get the symbol table entry for the global symbol named KEY.
Create one if there is none. */
symbol *
getsym(key)
char *key;
{
register int hashval;
register symbol *bp;
/* Determine the proper bucket. */
hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
for (bp = symtab[hashval]; bp; bp = bp->link)
if (! strcmp (key, bp->name))
return bp;
/* Nothing was found; create a new symbol table entry. */
bp = (symbol *) xmalloc (sizeof (symbol));
bp->name = (char *) xmalloc (strlen (key) + 1);
strcpy (bp->name, key);
bp->refs = 0;
bp->defined = 0;
bp->value = 0;
bp->common_size = 0;
bp->warning = 0;
bp->undef_refs = 0;
bp->mult_defs = 0;
bp->alias = 0;
bp->setv_count = 0;
bp->symbolnum = 0;
bp->rrs_symbolnum = 0;
bp->size = 0;
bp->aux = 0;
bp->sorefs = 0;
bp->so_defined = 0;
bp->def_nlist = 0;
bp->jmpslot_offset = -1;
bp->gotslot_offset = -1;
bp->flags = 0;
/* Add the entry to the bucket. */
bp->link = symtab[hashval];
symtab[hashval] = bp;
++num_hash_tab_syms;
return bp;
}
/* Like `getsym' but return 0 if the symbol is not already known. */
symbol *
getsym_soft (key)
char *key;
{
register int hashval;
register symbol *bp;
/* Determine which bucket. */
hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
for (bp = symtab[hashval]; bp; bp = bp->link)
if (! strcmp (key, bp->name))
return bp;
return 0;
}