This commit is contained in:
seta75D
2021-10-11 18:37:13 -03:00
commit ff309bfe1c
14130 changed files with 3180272 additions and 0 deletions

54
lang/ld/MakeCommon Normal file
View File

@@ -0,0 +1,54 @@
#
# @(#)MakeCommon 1.1 94/10/31 SMI
#
.KEEP_STATE:
arch-sun3 = SUN3
arch-sun2 = SUN2
arch-sun4 = SUN4
arch-sun3x = SUN3
arch-sun4c = SUN4
TARGET=$(arch$(TARGET_ARCH))
cpu-sun2 = m68k
cpu-sun3 = m68k
cpu-sun3x = m68k
cpu-sun4 = sparc
cpu-sun4c = sparc
CPU=$(cpu$(TARGET_ARCH))
#
# Code browser changes:
#
# Comment out the next line to disable code browser.
BROWSER = -DBROWSER
CB_DIR = ../../browser/cblib
CB_LIB = $(CB_DIR)/$(CPU)/libcb.a
CB_LIBRARY-DBROWSER = $(CB_LIB)
CB_DIRECTORY-DBROWSER = $(CB_DIR)/src
CFLAGS += $(DBX) -DSUNPRO -I../../vroot -I$(CB_DIRECTORY$(BROWSER)) $(BROWSER)
VROOT_DIR = ../../vroot
VROOT_LIB = $(VROOT_DIR)/vroot.a
$(CB_LIB) $(VROOT_LIB): FRC
(cd $(@D); $(MAKE) $(@F))
FRC:
HDRS = ../dynamic.h
MID_SRCS = ../ld.c ../rtsetup.c ../incl.c ../libfind.c ../verscmp.c \
../vroot.c ../extra.c
MID_OBJS = $(MID_SRCS:../%.c=%.o)
OBJS = ${MID_OBJS}
LIBS = $(CB_LIBRARY$(BROWSER)) $(VROOT_LIB)
${MID_OBJS}: ../$$(@:.o=.c)
$(CC) $(CFLAGS) -c ../$(@:.o=.c)
masterclean:
rm -f ${PROGRAM} ${OBJS}
masterlint :
lint $(LINTFLAGS) -I.. $(MID_SRCS)

26
lang/ld/Makefile Normal file
View File

@@ -0,0 +1,26 @@
#
# @(#)Makefile 1.1 94/10/31 SMI
#
DESTDIR=
all: FRC
cd ${CPU}; make ${MFLAGS} CC="${CC}" AS="${AS}"
xm68k: FRC
cd m68k; make ${MFLAGS} CC="${CC}" AS="${AS}"
xsparc: FRC
cd sparc; make ${MFLAGS} CC="${CC}" AS="${AS}"
xall: FRC
cd m68k; make ${MFLAGS} CC="${CC}" AS="${AS}"
cd sparc; make ${MFLAGS} CC="${CC}" AS="${AS}"
install: FRC
cd ${CPU}; make ${MFLAGS} DESTDIR=${DESTDIR} install
clean:
cd ${CPU}; make ${MFLAGS} clean
FRC:

143
lang/ld/dynamic.h Normal file
View File

@@ -0,0 +1,143 @@
/* @(#)dynamic.h 1.1 94/10/31 SMI; */
#define LHSIZ 31
#define RTHS 126
#define MAXLIB 126
struct libentry {
char *addr; /* address where lib is mapped to */
char *name; /* path name of library */
struct libentry *next;
};
struct dynamic {
struct libentry *lib_entry; /* ptr to list of libraries */
int ds; /* size of data link table */
int js; /* size of data jump table */
int rs; /* size of relocation */
int hs; /* size of symbol hash table */
int ss; /* size of symbol */
int sts; /* size of symbol strings */
int ts; /* size of text aera */
int lib; /* number of libraries */
int libstr; /* lenght of libraries strings */
int got_off; /* offset in GOT of 0'th entry */
};
/*
* +++++ for sun2 we need to fix the problem where
* displacement (jb_un.jb.location) is greater than 64k
*/
#if TARGET==SUN4
struct jbind {
int jb_inst[3]; /* need 4 instructions for jump slot */
};
#endif
#if TARGET==SUN3 || TARGET==SUN2
struct jbind {
unsigned short code;
unsigned short cl_hi;
unsigned short cl_low;
short reloc_index;
};
#endif
struct fshash {
int fssymbno; /* ordinal symbol number */
int next; /* index to the hash array pointed by fs_hash */
};
#undef relocation_info
#if TARGET== SUN4
# define relocation_info reloc_info_sparc
# define r_symbolnum r_index
#else /* !sun4 , thus mc68000 */
# define relocation_info reloc_info_68k
#endif /* mc68000 */
/*
* this structure is used to build the hash and the symbol tables for
* runtime linking.
*/
struct runtime {
int *dt; /* pointer to data linkage table */
struct jbind *jt; /* pointer to jump linkage table */
struct relocation_info *rp; /* ptr to first runtime reloc entry */
int rl; /* no of reloc needed for runtime */
struct fshash *hp; /* first entry of hash table */
struct nlist *sp; /* first entry of runtime symb table */
struct fshash *hp_last; /* last entry of hash table */
struct nlist *sp_last; /* last entry of symbol table */
char *fsstr; /* pointer to strings aera */
int hp_ind; /* index to the next hash entry */
struct nlist *spp; /* ptr to next available symbol entry */
int *dtp; /* ptr to next available data slot */
struct jbind *jtp; /* ptr to next available jump slot */
int dto; /* offset in bytes into data table */
int jto; /* offset in bytes into jump table */
struct relocation_info *rpp; /* ptr to next available reloc entry */
struct dynamic *dp; /* ptr to dynamic structure */
int fsoff; /* current offset to fast symbol aera */
int fsalloc; /* space allocated for fast symbols */
char *searchpath; /* search pathname */
int spthlen; /* search pathname string len */
int us; /* number of undefined symbols */
char *libname; /* pointer to the shlib name list */
int lko_i; /* index into lko array */
long buckets; /* number of hash buckets needed */
struct link_object lko[MAXLIB];/* link object array */
};
struct dslot {
int js; /* jump table slots */
int ds; /* data table slots */
int ss; /* static table slots */
};
struct rl {
int rl_d; /* total no of reloc for data segment */
int rl_de; /* no of reloc to external symb in data segment */
int rl_t; /* total no of non pic reloc for text segment */
int rl_te; /* no of non pic reloc to external in text segment */
};
struct ssymbol {
struct ssymbol *ss_next; /* next symbol */
char *ssp; /* pointer to symbol */
int ssflag; /* object or process symbol */
};
#if TARGET==SUN4
#define SETHI 0x03000000 /* sethi %hi(val),%g1 */
#define SETHIG0 0x01000000 /* sethi %hi(val),%g0 */
#define ORIT 0x82106000 /* or %g1,val,%g1 */
#define JMPI 0x81c06000 /* jmpl %g1 */
#define NOP 0x01000000 /* nop */
#define BA 0x10800000 /* branch always */
#define TRAP 0x91d02001
#define SAVE 0x9de3bfa0 /* save minimun frame */
#define CALL 0x40000000 /* call instuction */
#define lalign(i) (i%(sizeof (double)) ? i + ((sizeof (double))-(i%(sizeof (double)))) : i)
#endif
#if TARGET==SUN3 || TARGET==SUN2
#define lalign(i) (i%(sizeof (long)) ? i + ((sizeof (long))-(i%(sizeof (long)))) : i)
#define NOP 0x4e71
#define JSR 0x4eb9
#define JUMP 0x4ef9
#define TRAP 0x4e4f
#if TARGET==SUN2
#define JBSR 0x6100
#else
#define JBSR 0x61ff
#endif
#endif
#define D_NAME "__DYNAMIC"
#define LDPATH "LD_LIBRARY_PATH"
#define v1 ld_un.ld_1
#define v2 ld_un.ld_2

127
lang/ld/extra.c Normal file
View File

@@ -0,0 +1,127 @@
#ident "@(#)extra.c 1.1 94/10/31"
#include <a.out.h>
#include <stdio.h>
/*
* collect_extra_sections is called from load2() when it is
* noticed that there is more stuff after the string table.
* this is assumed to be the extra section stuff, which
* is to be concatenated, each in its respective sections,
* at the end of the output file. Because we don't know
* how long the string table is going to turn out to be,
* we cannot simply copy to the appropriate place in
* that file. Instead, we use temp files, which have
* to be copied at the end. Sad.
*/
#define MAX_EXTRA_SECTIONS 2
FILE * temp_file[MAX_EXTRA_SECTIONS] = { NULL, NULL };
char * temp_file_name[MAX_EXTRA_SECTIONS] = { NULL, NULL };
int n_extra_sections = 0;
int total_size[MAX_EXTRA_SECTIONS];
void
collect_extra_sections( iop, loc, offset, maxoff )
void * iop; /* opaque-to-me pointer to an IO block. */
long loc; /* offset in containing file (for archives) */
int offset; /* where in the input file/element the string table ends */
int maxoff; /* where the input file/element ends */
{
struct extra_sections xtra;
int section_size[ MAX_EXTRA_SECTIONS];
FILE * sect_fd;
int secno, l, seclength;
char buffer[512];
/* establish IO contact with the extra sections */
dseek1( iop, loc+offset, maxoff-offset );
/* read the header */
mget( (char *)&xtra, sizeof(xtra), iop);
if (xtra.extra_magic != EXTRA_MAGIC)
error(1, "bad secondary magic number");
if ( xtra.extra_nsects >= MAX_EXTRA_SECTIONS )
error(1, "too many extra sections");
/* read the section size table */
mget( (char *)section_size, xtra.extra_nsects*sizeof(int), iop );
/* open the temp files, as necessary */
while ( n_extra_sections < xtra.extra_nsects ){
create_section_temp( n_extra_sections++ );
}
/* now shovel the stuff */
for ( secno = 0 ; secno < xtra.extra_nsects ; secno += 1 ){
seclength = 0;
sect_fd = temp_file[secno];
while ( (l = section_size[secno] - seclength) > 0 ){
if ( l > sizeof(buffer) ) l = sizeof(buffer);
mget( buffer, l, iop );
fwrite( buffer, l, 1, sect_fd );
seclength += l;
}
total_size[secno] += seclength;
}
}
void
write_extra_sections( strout )
void * strout; /* opaque-to-me pointer to an IO block. */
{
struct extra_sections xtra;
FILE * sect_fd;
int secno, l, seclength;
char buffer[512];
if ( n_extra_sections == 0 ) return;
/* setup and write the header */
xtra.extra_magic = EXTRA_MAGIC;
xtra.extra_nsects = n_extra_sections;
bwrite( &xtra, sizeof(xtra), strout );
/* write segment size table */
bwrite( &total_size[0], n_extra_sections*sizeof(total_size[0]), strout );
/* now shovel the stuff */
for ( secno = 0 ; secno < xtra.extra_nsects ; secno += 1 ){
seclength = 0;
sect_fd = temp_file[secno];
rewind( sect_fd );
while ( (l = total_size[secno] - seclength) > 0 ){
if ( l > sizeof(buffer) ) l = sizeof(buffer);
if ( fread( buffer, 1, l, sect_fd ) != l )
error(1, "ioerror in write_extra_sections");
bwrite( buffer, l, strout );
seclength += l;
}
}
}
/*
* junk routines for tmp file housekeeping.
*/
create_section_temp( n ) /* called from collect_extra_sections() as needed */
{
char tmpprefix[23] ; /* random number */
sprintf( tmpprefix, "ld.%d.", n );
temp_file_name[n] = tempnam( NULL, tmpprefix );
if ( (temp_file[n] = fopen( temp_file_name[n], "w+")) == NULL){
error(1,"cannot create section temp files");
}
}
void
delete_section_temps() /* called from delexit() */
{
while (n_extra_sections > 0 ){
fclose( temp_file[n_extra_sections-1] );
if ( unlink( temp_file_name[n_extra_sections-1] ) != 0 ){
error(1, "cannot remove section temp files");
}
free( temp_file_name[n_extra_sections-1] );
n_extra_sections -= 1;
}
}

318
lang/ld/incl.c Normal file
View File

@@ -0,0 +1,318 @@
#ifndef lint
static char sccsid[] = "@(#)incl.c 1.1 94/10/31 Copyr 1991 Sun Micro";
#endif
/*
* Copyright (c) 1986, 1991 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <a.out.h>
#include <stab.h>
#include <ctype.h>
/*
* Info about each include file
*/
struct incl {
char *name; /* Name of header file */
int nstatic; /* # of statics in the file */
int nsymbols; /* # of symbols in header file */
int checksum; /* Checksum for header file */
int ord; /* Ordinal # of header file */
int exclude; /* Flag: include/exclude syms */
struct incl *next; /* Linked Hash list */
};
#define NINCL_STACK 10 /* Size of the include stack */
#define INCL_HASH 64 /* Size of header file hash table */
static struct incl **incl_stack; /* Include file stack */
static int stack_size; /* Size of incl_stack */
static struct incl **stkp; /* Stack pointer */
static struct incl *incl_table[INCL_HASH]; /* Table saved for pass 2 */
static struct incl *cur_incl; /* Current header file */
static int obj_ord; /* Saved value of header_num */
extern int ssize; /* Size of symbol section */
extern int header_num; /* Ordinal value of next header file */
struct incl *find_ord();
char *strcpy();
char *mymalloc();
char *realloc();
/*
* Allocate the intial include file stack.
* The stack will grow if necessary.
*/
alloc_inclstack()
{
if ((incl_stack = (struct incl **) mymalloc(NINCL_STACK*sizeof(struct incl *))) == 0)
error(1, "ran out of memory (alloc_inclstack)");
stkp = incl_stack;
stack_size = NINCL_STACK;
}
/*
* Beginning a new object file. Remember the ordinal number
* of the next header file in case this object file is not
* used and everything needs to be ripped out and thrown away.
*/
new_obj1()
{
obj_ord = header_num;
}
/*
* Enter a new include file.
* Stack the current one, if it is active.
* Allocate a structure and initialize it.
*/
start_incl1(sym, ord)
struct nlist *sym;
int ord;
{
char *name;
int n;
register char *namespace;
if (stkp >= &incl_stack[stack_size]) {
n = stkp - incl_stack;
stack_size += NINCL_STACK;
if ((incl_stack = (struct incl **) realloc(incl_stack,
stack_size * sizeof(struct incl *))) == 0)
error(1, "ran out of memory (start_incl1)");
stkp = &incl_stack[n];
}
*stkp++ = cur_incl;
name = sym->n_un.n_name;
if ((cur_incl = (struct incl *) mymalloc(sizeof(struct incl))) == 0)
error(1, "ran out of memory (start_incl1)");
if ((namespace = mymalloc(strlen(name) + 1)) == 0)
error(1, "ran out of memory (start_incl1)");
cur_incl->name = strcpy(namespace, name);
cur_incl->nstatic = 0;
cur_incl->nsymbols = 0;
cur_incl->checksum = 0;
cur_incl->ord = ord;
cur_incl->exclude = 0;
cur_incl->next = NULL;
}
/*
* Found the end of an include file.
* Hash on its name and enter it into the
* has table. Pass two will find it by
* its name and ordinal number.
* Also, pop one off of the stack.
*/
end_incl1()
{
int h;
h = hash(cur_incl->name);
cur_incl->next = incl_table[h];
incl_table[h] = cur_incl;
cur_incl = *--stkp;
}
/*
*
* Found a dbx symbol in pass one.
* If there is an active header file, include the info.
* The checksum is the summation of all the characters except for
* filenumbers which are digits immediately following an open
* parenthesis in the n_name field of the nlist
* structure.
*/
stab1(sym)
struct nlist *sym;
{
register char *cp;
if (cur_incl == NULL) {
return;
}
cur_incl->nsymbols++;
if (sym->n_type == N_STSYM || sym->n_type == N_LCSYM || sym->n_type == N_EXCL ) {
cur_incl->nstatic++;
}
cp = sym->n_un.n_name;
if (sym->n_type != N_EXCL && cp != NULL) {
while (*cp != '\0') {
cur_incl->checksum += *cp;
if (*cp == '(') {
while (*++cp != '\0' && isdigit(*cp))
;
/*
If no more symbols then return
else continue at the top loop
*/
if (*cp == '\0')
return;
else
continue;
}
cp++;
}
}
}
/*
* An object file was not used.
* Must remove any header files it had from the hash table.
*/
incl_free()
{
struct incl *ip;
struct incl *next;
struct incl **ipp;
struct incl **bpatch;
int nhdrs;
int removed;
if (obj_ord == header_num) {
return;
}
removed = 0;
nhdrs = header_num - obj_ord;
for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) {
bpatch = ipp;
for (ip = *ipp; ip != NULL; ip = next) {
next = ip->next;
if (ip->ord >= obj_ord) {
*bpatch = ip->next;
free((char *) ip);
removed++;
} else {
bpatch = &ip->next;
}
}
}
if (removed != nhdrs) {
fprintf(stderr, "incl_free removed %d nhdrs %d\n",
removed, nhdrs);
}
header_num = obj_ord;
}
/*
* See what header files can be excluded from the final output.
* The important goal here is to determine how many symbols
* will be excluded so that "ssize" can be adjusted. "Ssize"
* determines the value that will be stored into the a_syms
* field of the a.out header and also determines where the
* string table will begin.
*/
merge_headers()
{
register struct incl *ip;
register struct incl **ipp;
for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) {
for (ip = *ipp; ip != NULL; ip = ip->next) {
ip->exclude = find_prev(ip);
if (ip->exclude) {
ssize -= (ip->nsymbols + 1) *
sizeof(struct nlist);
}
}
}
cur_incl = NULL;
}
/*
* Found the beginning of a header file in pass2.
* Find the struct for the header file created in pass1.
* See if there is an identical struct for a header file
* with a lower ordinal value. If so, the symbols in this
* file can be discarded.
*/
start_incl2(sym, ord)
struct nlist *sym;
int ord;
{
struct incl *ip;
int r;
if (stkp > &incl_stack[stack_size]) {
error(1, "include stack too deep");
}
*stkp++ = cur_incl;
cur_incl = find_ord(sym, ord);
sym->n_value = cur_incl->checksum;
if (cur_incl->exclude) {
sym->n_type = N_EXCL;
}
return(cur_incl->exclude);
}
end_incl2()
{
cur_incl = *--stkp;
return(cur_incl != NULL && cur_incl->exclude);
}
/*
* Find a header file with a given ordinal number.
*/
struct incl *
find_ord(sym, ord)
struct nlist *sym;
int ord;
{
register struct incl *ip;
int h;
h = hash(sym->n_un.n_name);
for (ip = incl_table[h]; ip != NULL; ip = ip->next) {
if (ip->ord == ord) {
return(ip);
}
}
error(1, "no include table entry for header file '%s'",
sym->n_un.n_name);
}
/*
* Try to find an identical header file with a lower ordinal number.
*/
find_prev(incl)
register struct incl *incl;
{
register struct incl *ip;
int h;
if (incl->nstatic > 0) {
return(0);
}
h = hash(incl->name);
for (ip = incl_table[h]; ip != NULL; ip = ip->next) {
if (ip->nsymbols == incl->nsymbols &&
ip->nstatic == 0 &&
ip->checksum == incl->checksum &&
ip->ord < incl->ord &&
strcmp(incl->name, ip->name) == 0) {
return(1);
}
}
return(0);
}
/*
* Compute a hash from a string.
* Simply sum the characters and mod.
*/
hash(str)
char *str;
{
register int sum;
register char *cp;
sum = 0;
for (cp = str; *cp; cp++) {
sum += *cp;
}
return(sum % INCL_HASH);
}

5395
lang/ld/ld.c Normal file

File diff suppressed because it is too large Load Diff

106
lang/ld/libfind.c Normal file
View File

@@ -0,0 +1,106 @@
/* @(#)libfind.c 1.1 94/10/31 */
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <values.h>
#include <sys/param.h>
#include <sys/dir.h>
/*
* At batch time if we have been asked which version number of some
* library then we follow the search path until we found it else
* if no version is found then we take the highest version in the
* first directory where a macthing library is found.
*/
#define LIBSTR 255
#define SPECIFIC 1
extern stol();
extern char *calloc();
getshlib(dir, lib, mj, mn)
char *dir;
char *lib;
int *mj;
int *mn;
{
char *p;
char *version;
char *file;
int len = 0;
int lib_len = 0;
DIR *dirp;
register struct direct *dp;
int maj = -MAXINT;
int min = -MAXINT;
int still_looking = 1;
int cmp = 0;
int flag = 0;
int timeslooked =0;
/*
* determine whether a specific version of the library is wanted here.
*/
version = calloc(LIBSTR, 1);
file = calloc(LIBSTR, 1);
p = lib;
while (*p != '\0') {
len++;
if (*p != '.')
p++;
else
break;
}
if (*p == '.') {
if (strncmp(++p, "so", 2))
error(1, "expected libx.so(.major.minor.xxx)\n");
else {
flag = SPECIFIC;
lib_len = p - lib + 3;
if (!stol(p + 3,'.', &p, &maj))
error(1, "expected libx.so(.major.minor.xxx)\n");
if (!stol(++p, '.', &p, &min))
error(1, "expected libx.so(.major.minor.xxx)\n");
}
} else strcat(lib, ".so.");
sprintf(version,"%d.%d", maj, min);
len = strlen(lib);
/*
* open the directory
*/
dirp = opendir(dir);
if (dirp == NULL)
return (-1);
for (dp = readdir(dirp); dp != NULL && still_looking; dp = readdir(dirp)) {
if (!strncmp(lib , dp->d_name, len)) {
if (flag == SPECIFIC) {
strncpy(file, dp->d_name, lib_len);
still_looking = 0;
} else {
if (((cmp = verscmp(dp->d_name + len, version)) > 0) ||
((cmp == 0) && (*file == NULL))) {
strncpy(file, dp->d_name, len);
*version = '\0';
strcpy(version, dp->d_name + len);
};
}
}
}
closedir(dirp);
if (file[0] != NULL) {
strcat(dir, "/");
strcat(dir, file);
strcat(dir, version);
stol(version, '.', &version, &maj);
stol(++version, '.', &version, &min);
*mj = maj;
*mn = min;
return 0;
} else
return -1;
}

19
lang/ld/reloc_info.h Normal file
View File

@@ -0,0 +1,19 @@
/* @(#)reloc_info.h 1.1 94/10/31 SMI; */
/* <a.out.h> must be included before this file. */
/* This is so the common linker code can refer to either the 68k or
* SPARC relcation structure via the same name.
*/
#undef relocation_info
#if (TARGET==SUN2) || (TARGET==SUN3)
#define relocation_info reloc_info_68k
#define MAX_GOT_SIZE 16384 /* XXX Should this be here? */
#endif
#if (TARGET==SUN4)
#define relocation_info reloc_info_sparc
#define MAX_GOT_SIZE 2048 /* XXX Should this be here? */
#endif

277
lang/ld/rtsetup.c Normal file
View File

@@ -0,0 +1,277 @@
#ifndef lint
static char sccsid[] = "@(#)rtsetup.c 1.1 94/10/31"; /* from UCB 5.4 85/11/26 */
#endif not lint
#include <sys/types.h>
#include <a.out.h>
#include <link.h>
#include "dynamic.h"
#include "reloc_info.h"
#include <sys/param.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/mman.h>
char *mymalloc();
extern int picflag;
fs_init(rt, sb)
register struct runtime *rt;
register int sb; /* no of symbols for runtime linking */
{
register int i;
long buckets;
/* buckets = sb/4; */
buckets = (sb < 4 ? sb : sb/4);
rt->hp = (struct fshash *) mymalloc((buckets+sb)*sizeof(struct fshash));
rt->sp = (struct nlist *) mymalloc(sb * sizeof (struct nlist));
rt->hp_last = rt->hp + (buckets+sb);
rt->sp_last = rt->sp + sb;
rt->fsalloc = lalign(rt->fsalloc);
rt->fsstr = (char *) calloc(rt->fsalloc, 1);
if (rt->hp == 0 || rt->sp == 0 || rt->fsstr == 0)
error(1, "out of memory in buildfs");
rt->spp = rt->sp;
for (i = 0; i < buckets; i++) {
(rt->hp+i)->fssymbno = -1; /* mark it empty with -1 */
(rt->hp+i)->next = 0; /* init with null index ptr */
}
rt->hp_ind = buckets;
rt->buckets = buckets;
}
/*
* this routine does a bunch of initializations for runtime linking
*/
rt_init(rt)
register struct runtime *rt;
{
register int i;
i = totalsymb();
fs_init(rt, i);
rt->rl = calcreloc();
if ((rt->rp = (struct relocation_info *) calloc (rt->rl,
sizeof (struct relocation_info))) == 0)
error(1, "out of memory for dynamic relocation");
rt->rpp = rt->rp;
}
dp_init(rt)
register struct runtime *rt;
{
register struct dynamic *dp = rt->dp;
register int i;
i = totalsymb();
dp->rs = rt->rl * sizeof (struct relocation_info);
dp->ss = i * sizeof (struct nlist);
dp->sts = rt->fsalloc;
dp->hs = rt->hp_ind * sizeof (struct fshash);
/*
* jump table entries needed to be on an even boundary
*/
dp->libstr = lalign(dp->libstr);
}
/*
* initialize for data and jump linkage.
*/
dj_init(rt, slp, flag)
register struct runtime *rt;
register struct dslot *slp;
register int flag; /* if nonzero then set it up for runtime linking */
{
register struct dynamic *dp = rt->dp;
/*
* for runtime linking we need one extra slot in the data linkage
* table to store the address of symbol __DYNAMIC. This is done
* so that the runtime linker can find its own dynamic structure
* before it can relocate itself.
* We also need an extra slot in the jump linkage table which
* contained the direct jump to the runtime binder (all the
* jump entries do a pc relative jump to this slot).
*/
if (slp->ds || slp->ss || slp->js) {
slp->ds += 1;
slp->js += 1;
}
/*
* Calculate the offset into the GOT storage area for the
* GOT symbol itself. In some implementations, the GOT may
* be accessed by a signed displacement, this fact is adjusted
* for here.
*/
dp->got_off = slp->ds + slp->ss;
if ((slp->ds + slp->ss) > MAX_GOT_SIZE) {
if (picflag == 1)
error(1,
"GLOBAL_OFFSET_TABLE overflown: need to use -PIC");
dp->got_off = 0;
} else {
if (dp->got_off > (MAX_GOT_SIZE / 2))
dp->got_off = ((MAX_GOT_SIZE / 2) - dp->got_off) *
sizeof (int);
else
dp->got_off = 0;
}
/*
* be careful here: the number of bytes for jump slots
* are machine dependent. +++++++
*/
dp->ds = (slp->ds + slp->ss) * sizeof(int);
dp->js = slp->js * sizeof(struct jbind);
if ((rt->dt = (int *) calloc(dp->ds, sizeof(int))) == 0)
error(1, "can't allocate space for data linkage table");
rt->dtp = rt->dt;
rt->dto = dp->got_off;
if (dp->js != 0) {
if ((rt->jt = (struct jbind *) calloc(dp->js,
sizeof(struct jbind))) == 0)
error(1, "can't allocate space for jump linkage table");
if (flag) {
rt->jtp = rt->jt + 1;
rt->jto = sizeof(struct jbind);
#if TARGET==SUN4
setupjs(rt->jt, 0);
#endif
#if TARGET==SUN3 || TARGET==SUN2
rt->jt->code = JUMP;
#endif
} else {
rt->jtp = rt->jt;
rt->jto = 0;
}
}
}
init_lkd(lkdp, rt, ts, db)
register struct link_dynamic *lkdp;
register struct runtime *rt;
int ts; /* text size */
int db; /* database */
{
int off;
int i;
int j;
int k = 0;
char *cp = rt->libname;
lkdp->ld_version = 2;
lkdp->v2->ld_got = db + sizeof(struct link_dynamic) +
sizeof(struct ld_debug) + sizeof(struct link_dynamic_2);
lkdp->v2->ld_plt = lkdp->v2->ld_got + rt->dp->ds;
lkdp->v2->ld_got += abs(rt->dp->got_off);
lkdp->v2->ld_plt_sz = rt->dp->js;
lkdp->v2->ld_rel = ts;
lkdp->v2->ld_hash = lkdp->v2->ld_rel + rt->dp->rs;
lkdp->v2->ld_stab = lkdp->v2->ld_hash + rt->dp->hs;
lkdp->v2->ld_symbols = lkdp->v2->ld_stab + rt->dp->ss;
if (rt->searchpath)
lkdp->v2->ld_rules = lkdp->v2->ld_symbols + rt->fsalloc;
lkdp->v2->ld_symb_size = rt->fsalloc;
i = rt->dp->lib;
if (i == 0)
lkdp->v2->ld_need = 0;
else {
if (lkdp->v2->ld_rules)
lkdp->v2->ld_need = lkdp->v2->ld_rules +
lalign(rt->spthlen);
else
lkdp->v2->ld_need = lkdp->v2->ld_symbols + rt->fsalloc;
off = lkdp->v2->ld_need + (i * sizeof(struct link_object));
j = 0;
while (i > 0) {
rt->lko[j].lo_name = off + k;
k += strlen(cp) + 1;
cp = rt->libname + k;
i--;
if (i == 0)
rt->lko[j].lo_next = 0;
else
rt->lko[j].lo_next = lkdp->v2->ld_need +
((j+1)*sizeof(struct link_object));
j++;
}
}
}
#define skipblank(cp) while ( *cp == ' ' || *cp == '\n' ) cp++;
#define GLOB_SYMB "object global"
struct ssymbol *ssymbol_p;
/*
* this routine read in symbols from a file of the following format:
* object global s1, s2, s3, ...., sn;
* any reference to theses symbols will then be reduced to a relative
* relocation.
*/
int
getsymb(filename)
char *filename;
{
int fd;
struct stat sb;
char *buf;
char *cp;
char *cp1;
struct ssymbol *nsp;
struct ssymbol *csp;
char sc;
/*
* open file
*/
if ((fd = open(filename, O_RDONLY)) == -1)
error(1, "open symbol file %s failed", filename);
if (fstat(fd, &sb) == -1)
error(1, "fstat symbol file %s failed", filename);
buf = mmap(0, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
/*
* look for key word "object global"
*/
cp = buf;
while ( *cp == ' ' ) cp++;
if (!strcmp(cp, GLOB_SYMB))
error(1, "missing key word (object global) in symbol file");
cp += strlen(GLOB_SYMB);
skipblank(cp);
/*
* loop until ";", the marker for the end of the list is found.
*/
csp = ssymbol_p;
cp1 = cp;
for (;;) {
if (*cp != ',' && *cp != ';') {
cp++;
continue;
}
sc = *cp;
*cp++ = '\0';
nsp = (struct ssymbol *) malloc( sizeof(struct ssymbol));
nsp->ssp = cp1;
nsp->ss_next = 0;
if (csp)
csp->ss_next = nsp;
else
ssymbol_p = nsp;
csp = nsp;
skipblank(cp);
cp1 = cp;
if (sc == ';')
break;
}
}

27
lang/ld/sparc/Makefile Normal file
View File

@@ -0,0 +1,27 @@
#
# @(#)Makefile 1.1 94/10/31
#
xall : all
include ../MakeCommon
DIR= ..
CFLAGS += -O -DSUN2=0 -DSUN3=1 -DSUN4=2 -Dsun4 -DDEBUG -DTARGET=$(TARGET) -I..
HDRS= dynamic.h reloc_info.h
PROGRAM = ld
all: ${HDRS:%.h=$(DIR)/%.h} ${PROGRAM}
${PROGRAM}: ${LIBS} ${OBJS}
${CC} -o ${PROGRAM} ${OBJS} ${LIBS}
install: ${PROGRAM}
install -s ${PROGRAM} ${DESTDIR}/usr/bin/${PROGRAM}
clean: masterclean
tags:
ctags $(MID_SRCS)
lint : masterlint

310
lang/ld/sparc/incl.c Normal file
View File

@@ -0,0 +1,310 @@
#ifndef lint
static char sccsid[] = "@(#)incl.c 1.1 94/10/31";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include "a.out.h"
#include <stab.h>
#include <ctype.h>
/*
* Info about each include file
*/
struct incl {
char *name; /* Name of header file */
int nstatic; /* # of statics in the file */
int nsymbols; /* # of symbols in header file */
int checksum; /* Checksum for header file */
int ord; /* Ordinal # of header file */
int exclude; /* Flag: include/exclude syms */
struct incl *next; /* Linked Hash list */
};
#define NINCL_STACK 10 /* Size of the include stack */
#define INCL_HASH 64 /* Size of header file hash table */
static struct incl **incl_stack; /* Include file stack */
static int stack_size; /* Size of incl_stack */
static struct incl **stkp; /* Stack pointer */
static struct incl *incl_table[INCL_HASH]; /* Table saved for pass 2 */
static struct incl *cur_incl; /* Current header file */
static int obj_ord; /* Saved value of header_num */
extern int ssize; /* Size of symbol section */
extern int header_num; /* Ordinal value of next header file */
struct incl *find_ord();
char *strcpy();
char *malloc();
char *realloc();
/*
* Allocate the intial include file stack.
* The stack will grow if necessary.
*/
alloc_inclstack()
{
if ((incl_stack = (struct incl **) malloc(NINCL_STACK*sizeof(struct incl *))) == 0)
error(1, "ran out of memory (alloc_inclstack)");
stkp = incl_stack;
stack_size = NINCL_STACK;
}
/*
* Beginning a new object file. Remember the ordinal number
* of the next header file in case this object file is not
* used and everything needs to be ripped out and thrown away.
*/
new_obj1()
{
obj_ord = header_num;
}
/*
* Enter a new include file.
* Stack the current one, if it is active.
* Allocate a structure and initialize it.
*/
start_incl1(sym, ord)
struct nlist *sym;
int ord;
{
char *name;
int n;
register char *namespace;
if (stkp > &incl_stack[stack_size]) {
n = stkp - incl_stack;
stack_size += NINCL_STACK;
if ((incl_stack = (struct incl **) realloc(incl_stack,
stack_size * sizeof(struct incl *))) == 0)
error(1, "ran out of memory (start_incl1)");
stkp = &incl_stack[n];
}
*stkp++ = cur_incl;
name = sym->n_un.n_name;
if ((cur_incl = (struct incl *) malloc(sizeof(struct incl))) == 0)
error(1, "ran out of memory (start_incl1)");
if ((namespace = malloc(strlen(name) + 1)) == 0)
error(1, "ran out of memory (start_incl1)");
cur_incl->name = strcpy(namespace, name);
cur_incl->nstatic = 0;
cur_incl->nsymbols = 0;
cur_incl->checksum = 0;
cur_incl->ord = ord;
cur_incl->exclude = 0;
cur_incl->next = NULL;
}
/*
* Found the end of an include file.
* Hash on its name and enter it into the
* has table. Pass two will find it by
* its name and ordinal number.
* Also, pop one off of the stack.
*/
end_incl1()
{
int h;
h = hash(cur_incl->name);
cur_incl->next = incl_table[h];
incl_table[h] = cur_incl;
cur_incl = *--stkp;
}
/*
* Found a dbx symbol in pass one.
* If there is an active header file, include the info.
* The checksum is the summation of all the letters, underscores,
* and equals signs in the n_name field of the nlist
* structure.
*
* The equals signs are counted because they are present whenever
* new type is defined. We want to insure that each inclusion of
* a header file defines the same number of types.
*/
stab1(sym)
struct nlist *sym;
{
register char *cp;
if (cur_incl == NULL) {
return;
}
cur_incl->nsymbols++;
if (sym->n_type == N_STSYM || sym->n_type == N_LCSYM || sym->n_type == N_EXCL ) {
cur_incl->nstatic++;
}
cp = sym->n_un.n_name;
if (sym->n_type != N_EXCL && cp != NULL) {
while (*cp != '\0') {
if (isalpha(*cp) || *cp == '_' || *cp == '=') {
cur_incl->checksum += *cp;
}
cp++;
}
}
}
/*
* An object file was not used.
* Must remove any header files it had from the hash table.
*/
incl_free()
{
struct incl *ip;
struct incl *next;
struct incl **ipp;
struct incl **bpatch;
int nhdrs;
int removed;
if (obj_ord == header_num) {
return;
}
removed = 0;
nhdrs = header_num - obj_ord;
for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) {
bpatch = ipp;
for (ip = *ipp; ip != NULL; ip = next) {
next = ip->next;
if (ip->ord >= obj_ord) {
*bpatch = ip->next;
free((char *) ip);
removed++;
} else {
bpatch = &ip->next;
}
}
}
if (removed != nhdrs) {
fprintf(stderr, "incl_free removed %d nhdrs %d\n",
removed, nhdrs);
}
header_num = obj_ord;
}
/*
* See what header files can be excluded from the final output.
* The important goal here is to determine how many symbols
* will be excluded so that "ssize" can be adjusted. "Ssize"
* determines the value that will be stored into the a_syms
* field of the a.out header and also determines where the
* string table will begin.
*/
merge_headers()
{
register struct incl *ip;
register struct incl **ipp;
for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) {
for (ip = *ipp; ip != NULL; ip = ip->next) {
ip->exclude = find_prev(ip);
if (ip->exclude) {
ssize -= (ip->nsymbols + 1) *
sizeof(struct nlist);
}
}
}
cur_incl = NULL;
}
/*
* Found the beginning of a header file in pass2.
* Find the struct for the header file created in pass1.
* See if there is an identical struct for a header file
* with a lower ordinal value. If so, the symbols in this
* file can be discarded.
*/
start_incl2(sym, ord)
struct nlist *sym;
int ord;
{
struct incl *ip;
int r;
if (stkp > &incl_stack[NINCL_STACK]) {
error(1, "include stack too deep");
}
*stkp++ = cur_incl;
cur_incl = find_ord(sym, ord);
sym->n_value = cur_incl->checksum;
if (cur_incl->exclude) {
sym->n_type = N_EXCL;
}
return(cur_incl->exclude);
}
end_incl2()
{
cur_incl = *--stkp;
return(cur_incl != NULL && cur_incl->exclude);
}
/*
* Find a header file with a given ordinal number.
*/
struct incl *
find_ord(sym, ord)
struct nlist *sym;
int ord;
{
register struct incl *ip;
int h;
h = hash(sym->n_un.n_name);
for (ip = incl_table[h]; ip != NULL; ip = ip->next) {
if (ip->ord == ord) {
return(ip);
}
}
error(1, "no include table entry for header file '%s'",
sym->n_un.n_name);
}
/*
* Try to find an identical header file with a lower ordinal number.
*/
find_prev(incl)
register struct incl *incl;
{
register struct incl *ip;
int h;
if (incl->nstatic > 0) {
return(0);
}
h = hash(incl->name);
for (ip = incl_table[h]; ip != NULL; ip = ip->next) {
if (ip->nsymbols == incl->nsymbols &&
ip->nstatic == 0 &&
ip->checksum == incl->checksum &&
ip->ord < incl->ord &&
strcmp(incl->name, ip->name) == 0) {
return(1);
}
}
return(0);
}
/*
* Compute a hash from a string.
* Simply sum the characters and mod.
*/
hash(str)
char *str;
{
register int sum;
register char *cp;
sum = 0;
for (cp = str; *cp; cp++) {
sum += *cp;
}
return(sum % INCL_HASH);
}

114
lang/ld/verscmp.c Normal file
View File

@@ -0,0 +1,114 @@
/* @(#)verscmp.c 1.1 94/10/31 */
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
#define SKIP_DOT(str) ((*str == '.') ? ++str : str)
#define EMPTY(str) ((str == NULL) || (*str == '\0'))
#define NULL 0
#define isdigit(c) (((c) >= '0') && ((c) <= '9') ? 1:0)
int stol();
/*
* Test whether the string is of digit[.digit]* format
*/
rest_ok(str)
char *str; /* input string */
{
int dummy; /* integer place holder */
int legal = 1; /* return flag */
while (!EMPTY(str)) {
if (!stol(str, '.', &str, &dummy)) {
legal = 0;
break;
};
if (EMPTY(str))
break;
else SKIP_DOT(str);
};
return(legal);
};
/*
* Compare 2 strings and test whether they are of the form digit[.digit]*.
* It will return -1, 0, or 1 depending on whether c1p is less, equal or
* greater than c2p
*/
verscmp(c1p, c2p)
char *c1p; /* input string */
char *c2p; /* input string */
{
char *l_c1p = c1p; /* working copy of c1p */
char *l_c2p = c2p; /* working copy of c2p */
int l_c1p_ok = 0; /* is c1p a legal string */
int c2p_dig = 0; /* int that c1p currently represents */
int c1p_dig = 0; /* int that c2p currently represents */
int result = 0;
while ((l_c1p_ok = stol(l_c1p,'.', &l_c1p, &c1p_dig)) &&
stol(l_c2p,'.', &l_c2p, &c2p_dig) && (c2p_dig == c1p_dig)) {
if (EMPTY(l_c1p) && EMPTY(l_c2p))
return(0);
else if (EMPTY(l_c1p) && !EMPTY(l_c2p) && rest_ok(SKIP_DOT(l_c2p)))
return(-1);
else if (EMPTY(l_c2p) && !EMPTY(l_c1p) && rest_ok(SKIP_DOT(l_c1p)))
return(1);
l_c1p++; l_c2p++;
};
if (!l_c1p_ok)
return(-1);
else if (c1p_dig < c2p_dig)
return(-1);
else if ((c1p_dig > c2p_dig) && rest_ok(SKIP_DOT(l_c1p)))
return(1);
else return(-1);
}
/*
* "stol" attempts to interpret a collection of characters between delimiters
* as a decimal digit. It stops interpreting when it reaches a delimiter or
* when character does not represent a digit. In the first case it returns
* success and the latter failure.
*/
int
stol(cp, delimit, ptr, i)
char *cp; /* ptr to input string */
char delimit; /* delimiter */
char **ptr; /* left pointing to next del. or illegal
character */
int *i; /* digit that the string represents */
{
int c = 0; /* current char */
int n = 0; /* working copy of i */
int neg = 0; /* is number negative */
if (ptr != (char **)0)
*ptr = cp; /* in case no number is formed */
if (EMPTY(cp))
return(0);
if (!isdigit(c = *cp) && (c == '-')) {
neg++;
c = *++cp;
};
if (EMPTY(cp) || !isdigit(c))
return(0);
while (isdigit(c = *cp) && (*cp++ != '\0')) {
n *= 10;
n += c - '0';
};
if (ptr != (char **)0)
*ptr = cp;
if ((*cp == '\0') || (*cp == delimit)) {
*i = neg ? -n : n;
return (1);
};
return (0);
}

101
lang/ld/vroot.c Normal file
View File

@@ -0,0 +1,101 @@
#ifndef lint
static char sccsid[] = "@(#)vroot.c 1.1 94/10/31";
#endif not lint
#include <stdio.h>
#include <sys/param.h>
static char *get_next_name();
extern char *getenv();
extern char *malloc();
#define NDEFDIRS 3 /* number of default directories in dirs[] */
extern char *dirs[];
extern int ndir;
extern char *defaults_dir[];
/*
* support virtual root for cross compiling
*/
dovroot()
{
char *vroot = getenv("VIRTUAL_ROOT");
char *dn;
int i;
char *vroot_copy;
if (vroot) {
vroot_copy = malloc(strlen(vroot) + 1);
strcpy(vroot_copy, vroot);
while (dn = get_next_name(&vroot_copy))
if (strcmp(dn, "/"))
newvrt(dn);
}
}
static
newvrt(dn)
char *dn;
{
char *cp;
int len = strlen(dn);
int i;
for (i = 0; i < NDEFDIRS; i++) {
dirs[ndir++] = cp = malloc(len + strlen(defaults_dir[i]) + 1);
strcpy(cp, dn);
strcat(cp, defaults_dir[i]);
}
}
/*
* Extract list of directories needed from colon separated string.
*/
static char *
get_next_name(list)
char **list;
{
char *lp = *list;
char *cp = *list;;
if (lp != NULL && *lp != '\0') {
while (*lp != '\0' && *lp != ':')
lp++;
if (*lp == ':') {
*lp = '\0';
*list = lp + 1;
} else
*list = NULL;
} else
*list = NULL;
return(cp);
}
char *
stripvroot(path)
char *path;
{
char *vroot = getenv("VIRTUAL_ROOT");
char *dn;
int i;
char *vroot_copy;
static char buf[MAXPATHLEN+1];
if (vroot) {
vroot_copy = malloc(strlen(vroot) + 1);
strcpy(vroot_copy, vroot);
while (dn = get_next_name(&vroot_copy)) {
if(((i = strlen(dn)) != 0) && (strcmp(dn, "/") != 0))
if (strncmp(dn, path, i) == 0) {
(void)strcpy(buf, &path[i]);
return(buf);
}
}
}
return(path);
}