Some of the latest changes from Paul K (taken from NetBSD-current).

This commit is contained in:
Jordan K. Hubbard 1993-11-22 19:05:31 +00:00
parent 047ea5bd0c
commit d3ab4e4900
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=792
15 changed files with 320 additions and 103 deletions

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: md.c,v 1.2 1993/11/09 04:19:16 paul Exp $ * $Id: md.c,v 1.3 1993/11/15 20:58:20 paul Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -236,6 +236,14 @@ struct relocation_info *rp, *r;
r->r_copy = 1; r->r_copy = 1;
} }
void
md_set_breakpoint(where, savep)
long where;
long *savep;
{
*savep = *(long *)where;
*(char *)where = BPT;
}
#ifdef NEED_SWAP #ifdef NEED_SWAP

View File

@ -1,5 +1,5 @@
/* /*
* $Id: md.h,v 1.3 1993/10/24 00:52:40 pk Exp $ - I386 dependent definitions * $Id: md.h,v 1.2 1993/11/09 04:19:17 paul Exp $ - I386 dependent definitions
*/ */
@ -50,7 +50,7 @@ typedef struct jmpslot {
#define NOP 0x90 #define NOP 0x90
#define CALL 0xe890 /* NOP + CALL opcode */ #define CALL 0xe890 /* NOP + CALL opcode */
#define JUMP 0xe990 /* NOP + JMP opcode */ #define JUMP 0xe990 /* NOP + JMP opcode */
#define TRAP 0xcc /* INT 3 */ #define BPT 0xcc /* breakpoint: INT 3 */
/* /*
* Byte swap defs for cross linking * Byte swap defs for cross linking

View File

@ -32,7 +32,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
Set, indirect, and warning symbol features added by Randy Smith. */ Set, indirect, and warning symbol features added by Randy Smith. */
/* /*
* $Id: ld.c,v 1.8 1993/11/16 07:20:35 paul Exp $ * $Id: ld.c,v 1.9 1993/11/18 20:52:31 jkh Exp $
*/ */
/* Define how to initialize system-dependent header fields. */ /* Define how to initialize system-dependent header fields. */
@ -636,10 +636,15 @@ each_file(function, arg)
for (i = 0; i < number_of_files; i++) { for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i]; register struct file_entry *entry = &file_table[i];
if (entry->scrapped)
continue;
if (entry->library_flag) { if (entry->library_flag) {
register struct file_entry *subentry = entry->subfiles; register struct file_entry *subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) for (; subentry; subentry = subentry->chain) {
if (subentry->scrapped)
continue;
(*function) (subentry, arg); (*function) (subentry, arg);
}
} else } else
(*function) (entry, arg); (*function) (entry, arg);
} }
@ -664,11 +669,16 @@ check_each_file(function, arg)
for (i = 0; i < number_of_files; i++) { for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i]; register struct file_entry *entry = &file_table[i];
if (entry->scrapped)
continue;
if (entry->library_flag) { if (entry->library_flag) {
register struct file_entry *subentry = entry->subfiles; register struct file_entry *subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) for (; subentry; subentry = subentry->chain) {
if (subentry->scrapped)
continue;
if (return_val = (*function) (subentry, arg)) if (return_val = (*function) (subentry, arg))
return return_val; return return_val;
}
} else if (return_val = (*function) (entry, arg)) } else if (return_val = (*function) (entry, arg))
return return_val; return return_val;
} }
@ -686,7 +696,8 @@ each_full_file(function, arg)
for (i = 0; i < number_of_files; i++) { for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i]; register struct file_entry *entry = &file_table[i];
if (entry->just_syms_flag || entry->is_dynamic) if (entry->scrapped ||
entry->just_syms_flag || entry->is_dynamic)
continue; continue;
if (entry->library_flag) { if (entry->library_flag) {
register struct file_entry *subentry = entry->subfiles; register struct file_entry *subentry = entry->subfiles;
@ -816,6 +827,7 @@ read_entry_symbols (desc, entry)
entry->symbols[i].next = NULL; entry->symbols[i].next = NULL;
entry->symbols[i].gotslot_offset = -1; entry->symbols[i].gotslot_offset = -1;
entry->symbols[i].gotslot_claimed = 0; entry->symbols[i].gotslot_claimed = 0;
entry->symbols[i].rename = 0;
} }
entry->strings_offset = N_STROFF(entry->header) + entry->strings_offset = N_STROFF(entry->header) +
@ -840,7 +852,8 @@ read_entry_strings (desc, entry)
int buffer; int buffer;
if (!entry->header_read_flag || !entry->strings_offset) if (!entry->header_read_flag || !entry->strings_offset)
fatal("internal error: %s", "cannot read string table"); fatal_with_file("internal error: cannot read string table for ",
entry);
if (lseek (desc, entry->strings_offset, L_SET) != entry->strings_offset) if (lseek (desc, entry->strings_offset, L_SET) != entry->strings_offset)
fatal_with_file ("read_strings: lseek failure ", entry); fatal_with_file ("read_strings: lseek failure ", entry);
@ -918,7 +931,7 @@ read_entry_relocation (desc, entry)
/* Read in the symbols of all input files. */ /* Read in the symbols of all input files. */
void read_file_symbols (), read_entry_symbols (), read_entry_strings (); void read_file_symbols (), read_entry_symbols ();
void enter_file_symbols (), enter_global_ref (); void enter_file_symbols (), enter_global_ref ();
void void
@ -967,8 +980,10 @@ read_file_symbols (entry)
return; return;
} }
entry->is_dynamic = 1; entry->is_dynamic = 1;
read_shared_object(desc, entry); if (rrs_add_shobj(entry))
rrs_add_shobj(entry); read_shared_object(desc, entry);
else
entry->scrapped = 1;
} else { } else {
read_entry_symbols (desc, entry); read_entry_symbols (desc, entry);
entry->strings = (char *) alloca (entry->string_size); entry->strings = (char *) alloca (entry->string_size);
@ -1320,7 +1335,7 @@ digest_symbols ()
defined_global_sym_count = 0; defined_global_sym_count = 0;
digest_pass1(); digest_pass1();
if (!relocatable_output) { if (1 || !relocatable_output) {
each_full_file(consider_relocation, 0); /* Text */ each_full_file(consider_relocation, 0); /* Text */
each_full_file(consider_relocation, 1); /* Data */ each_full_file(consider_relocation, 1); /* Data */
} }
@ -1505,7 +1520,7 @@ digest_pass1()
register int type = p->n_type; register int type = p->n_type;
if ((type & N_EXT) && type != (N_UNDF | N_EXT) if ((type & N_EXT) && type != (N_UNDF | N_EXT)
&& (type & N_TYPE) != N_FN) { && (type & N_TYPE) != N_FN) {
/* non-common definition */ /* non-common definition */
sp->def_nlist = p; sp->def_nlist = p;
sp->so_defined = type; sp->so_defined = type;
@ -1673,6 +1688,14 @@ consider_relocation (entry, dataseg)
for (; reloc < end; reloc++) { for (; reloc < end; reloc++) {
if (relocatable_output) {
lsp = &entry->symbols[reloc->r_symbolnum];
if (RELOC_BASEREL_P(reloc) && !RELOC_EXTERN_P(reloc)) {
lsp->rename = 1;
}
continue;
}
/* /*
* First, do the PIC specific relocs. * First, do the PIC specific relocs.
* r_relative and r_copy should not occur at this point * r_relative and r_copy should not occur at this point
@ -1941,8 +1964,7 @@ write_header ()
{ {
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0; int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
if (!oldmagic) if (!oldmagic) N_SET_FLAG (outheader, flags);
N_SET_FLAG (outheader, flags);
outheader.a_text = text_size; outheader.a_text = text_size;
outheader.a_data = data_size; outheader.a_data = data_size;
outheader.a_bss = bss_size; outheader.a_bss = bss_size;
@ -1974,10 +1996,10 @@ write_header ()
#ifdef DEBUG #ifdef DEBUG
printf("defined globals: %d, undefined globals %d, locals: %d (non_L: %d), \ printf("defined globals: %d, undefined globals %d, locals: %d (non_L: %d), \
debug symbols: %d, special: %d --> nsyms %d\n", debug symbols: %d, special: %d, set_symbols %d, aliases %d --> nsyms %d\n",
defined_global_sym_count, undefined_global_sym_count, defined_global_sym_count, undefined_global_sym_count,
local_sym_count, non_L_local_sym_count, debugger_sym_count, local_sym_count, non_L_local_sym_count, debugger_sym_count,
special_sym_count, nsyms); special_sym_count, set_symbol_count, global_alias_count, nsyms);
#endif #endif
outheader.a_syms = nsyms * sizeof (struct nlist); outheader.a_syms = nsyms * sizeof (struct nlist);
@ -2375,12 +2397,12 @@ printf("%s: BSS found in so_defined\n", sp->name);
/* For relocatable_output only: write out the relocation, /* For relocatable_output only: write out the relocation,
relocating the addresses-to-be-relocated. */ relocating the addresses-to-be-relocated. */
void coptxtrel (), copdatrel (); void coptxtrel(), copdatrel(), assign_symbolnums();
void void
write_rel () write_rel ()
{ {
register int count = 0; int count = 0;
if (trace_files) if (trace_files)
fprintf (stderr, "Writing text relocation:\n\n"); fprintf (stderr, "Writing text relocation:\n\n");
@ -2408,6 +2430,8 @@ write_rel ()
+ special_sym_count) + special_sym_count)
fatal ("internal error: write_rel: count = %d", count); fatal ("internal error: write_rel: count = %d", count);
each_full_file (assign_symbolnums, &count);
/* Write out the relocations of all files, remembered from copy_text. */ /* Write out the relocations of all files, remembered from copy_text. */
each_full_file (coptxtrel, 0); each_full_file (coptxtrel, 0);
@ -2420,6 +2444,25 @@ write_rel ()
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
/*
* Assign symbol ordinal numbers to local symbols in each entry.
*/
void
assign_symbolnums(entry, countp)
struct file_entry *entry;
int *countp;
{
struct localsymbol *lsp, *lspend;
int n = *countp;
lspend = entry->symbols + entry->nsymbols;
for (lsp = entry->symbols; lsp < lspend; lsp++) {
lsp->symbolnum = n++;
}
*countp = n;
}
void void
coptxtrel(entry) coptxtrel(entry)
struct file_entry *entry; struct file_entry *entry;
@ -2897,12 +2940,25 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *p = &lsp->nzlist.nlist; register struct nlist *p = &lsp->nzlist.nlist;
register int type = p->n_type; register int type = p->n_type;
register int write = 0; register int write = 0;
char *name;
if (p->n_un.n_strx == 0)
name = NULL;
else if (lsp->rename == 0)
name = p->n_un.n_strx + entry->strings;
else {
char *cp = p->n_un.n_strx + entry->strings;
name = (char *)alloca(
strlen(entry->local_sym_name) +
strlen(cp) + 2 );
(void)sprintf(name, "%s.%s", entry->local_sym_name, cp);
(void)printf("%s.%s\n", entry->local_sym_name, cp);
}
/* /*
* WRITE gets 1 for a non-global symbol that should be * WRITE gets 1 for a non-global symbol that should be
* written. * written.
*/ */
if (SET_ELEMENT_P (type)) if (SET_ELEMENT_P (type))
/* /*
* This occurs even if global. These types of * This occurs even if global. These types of
@ -2910,17 +2966,20 @@ write_file_syms(entry, syms_written_addr)
* they are stored globally. * they are stored globally.
*/ */
write = relocatable_output; write = relocatable_output;
else if (!(type & (N_STAB | N_EXT))) else if (!(type & (N_STAB | N_EXT)) && name != NULL)
/* ordinary local symbol */ /* ordinary local symbol */
write = ((discard_locals != DISCARD_ALL) write = (lsp->rename || (
&& !(discard_locals == DISCARD_L && discard_locals != DISCARD_ALL &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX) !(discard_locals == DISCARD_L &&
&& type != N_WARNING); name[0] == LPREFIX) &&
type != N_WARNING) );
else if (!(type & N_EXT)) else if (!(type & N_EXT))
/* debugger symbol */ /* debugger symbol */
write = (strip_symbols == STRIP_NONE) && write = (strip_symbols == STRIP_NONE)/* &&
!(discard_locals == DISCARD_L && !(discard_locals == DISCARD_L &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX); name[0] == LPREFIX)*/;
else if (name == NULL)
error("Amnesiac");
if (write) { if (write) {
/* /*
@ -2928,9 +2987,8 @@ write_file_syms(entry, syms_written_addr)
* in the output string table. * in the output string table.
*/ */
if (p->n_un.n_strx) if (name)
p->n_un.n_strx = assign_string_table_index( p->n_un.n_strx = assign_string_table_index(name);
p->n_un.n_strx + entry->strings);
/* Output this symbol to the buffer and count it. */ /* Output this symbol to the buffer and count it. */

View File

@ -1,4 +1,4 @@
/* $Id: ld.h,v 1.2 1993/11/09 04:18:59 paul Exp $ */ /* $Id: ld.h,v 1.3 1993/11/18 20:52:34 jkh Exp $ */
/*- /*-
* This code is derived from software copyrighted by the Free Software * This code is derived from software copyrighted by the Free Software
* Foundation. * Foundation.
@ -343,11 +343,11 @@ int oldmagic;
typedef struct glosym { typedef struct glosym {
/* Pointer to next symbol in this symbol's hash bucket. */ /* Pointer to next symbol in this symbol's hash bucket. */
struct glosym *link; struct glosym *link;
/* Name of this symbol. */ /* Name of this symbol. */
char *name; char *name;
/* Value of this symbol as a global symbol. */ /* Value of this symbol as a global symbol. */
long value; long value;
/* /*
* Chain of external 'nlist's in files for this symbol, both defs and * Chain of external 'nlist's in files for this symbol, both defs and
* refs. * refs.
@ -357,34 +357,34 @@ typedef struct glosym {
* Any warning message that might be associated with this symbol from * Any warning message that might be associated with this symbol from
* an N_WARNING symbol encountered. * an N_WARNING symbol encountered.
*/ */
char *warning; char *warning;
/* /*
* Nonzero means definitions of this symbol as common have been seen, * Nonzero means definitions of this symbol as common have been seen,
* and the value here is the largest size specified by any of them. * and the value here is the largest size specified by any of them.
*/ */
int max_common_size; int max_common_size;
/* /*
* For relocatable_output, records the index of this global sym in * For relocatable_output, records the index of this global sym in
* the symbol table to be written, with the first global sym given * the symbol table to be written, with the first global sym given
* index 0. * index 0.
*/ */
int symbolnum; int symbolnum;
/* /*
* For dynamically linked output, records the index in the RRS * For dynamically linked output, records the index in the RRS
* symbol table. * symbol table.
*/ */
int rrs_symbolnum; int rrs_symbolnum;
/* /*
* Nonzero means a definition of this global symbol is known to * Nonzero means a definition of this global symbol is known to
* exist. Library members should not be loaded on its account. * exist. Library members should not be loaded on its account.
*/ */
char defined; char defined;
/* /*
* Nonzero means a reference to this global symbol has been seen in a * Nonzero means a reference to this global symbol has been seen in a
* file that is surely being loaded. A value higher than 1 is the * file that is surely being loaded. A value higher than 1 is the
* n_type code for the symbol's definition. * n_type code for the symbol's definition.
*/ */
char referenced; char referenced;
/* /*
* A count of the number of undefined references printed for a * A count of the number of undefined references printed for a
* specific symbol. If a symbol is unresolved at the end of * specific symbol. If a symbol is unresolved at the end of
@ -394,15 +394,15 @@ typedef struct glosym {
* symbol here. When the number hits MAX_UREFS_PRINTED, messages * symbol here. When the number hits MAX_UREFS_PRINTED, messages
* stop. * stop.
*/ */
unsigned char undef_refs; unsigned char undef_refs;
/* /*
* 1 means that this symbol has multiple definitions. 2 means that * 1 means that this symbol has multiple definitions. 2 means that
* it has multiple definitions, and some of them are set elements, * it has multiple definitions, and some of them are set elements,
* one of which has been printed out already. * one of which has been printed out already.
*/ */
unsigned char multiply_defined; unsigned char multiply_defined;
/* Nonzero means print a message at all refs or defs of this symbol */ /* Nonzero means print a message at all refs or defs of this symbol */
char trace; char trace;
/* /*
* For symbols of type N_INDR, this points at the real symbol. * For symbols of type N_INDR, this points at the real symbol.
@ -422,10 +422,10 @@ typedef struct glosym {
* section of the resulting a.out file. They *do* go into the * section of the resulting a.out file. They *do* go into the
* dynamic link information segment. * dynamic link information segment.
*/ */
char so_defined; char so_defined;
/* Size of symbol as determined by N_SIZE 'nlist's in object files */ /* Size of symbol as determined by N_SIZE symbols in object files */
int size; int size;
/* Auxialiary info to put in the `nz_other' field of the /* Auxialiary info to put in the `nz_other' field of the
* RRS symbol table. Used by the run-time linker to resolve * RRS symbol table. Used by the run-time linker to resolve
@ -600,6 +600,8 @@ struct file_entry {
struct localsymbol *next; struct localsymbol *next;
long gotslot_offset; long gotslot_offset;
char gotslot_claimed; char gotslot_claimed;
char rename;
int symbolnum;
} *symbols; } *symbols;
/* Number of symbols in above array. */ /* Number of symbols in above array. */
@ -688,6 +690,9 @@ struct file_entry {
/* This entry is a shared object */ /* This entry is a shared object */
char is_dynamic; char is_dynamic;
/* 1 if this entry is not a major player anymore */
char scrapped;
}; };
typedef struct localsymbol localsymbol_t; typedef struct localsymbol localsymbol_t;
@ -858,7 +863,7 @@ void std_search_dirs __P((char *));
/* In rrs.c: */ /* In rrs.c: */
void init_rrs __P((void)); void init_rrs __P((void));
void rrs_add_shobj __P((struct file_entry *)); int rrs_add_shobj __P((struct file_entry *));
void alloc_rrs_reloc __P((symbol *)); void alloc_rrs_reloc __P((symbol *));
void alloc_rrs_segment_reloc __P((struct relocation_info *)); void alloc_rrs_segment_reloc __P((struct relocation_info *));
void alloc_rrs_jmpslot __P((symbol *)); void alloc_rrs_jmpslot __P((symbol *));

View File

@ -1,5 +1,5 @@
/* /*
* $Id: lib.c,v 1.4 1993/11/05 12:43:11 pk Exp $ - library routines * $Id: lib.c,v 1.2 1993/11/09 04:19:00 paul Exp $ - library routines
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -572,6 +572,8 @@ read_shared_object (desc, entry)
entry->symbols[i].symbol = NULL; entry->symbols[i].symbol = NULL;
entry->symbols[i].next = NULL; entry->symbols[i].next = NULL;
entry->symbols[i].gotslot_offset = -1; entry->symbols[i].gotslot_offset = -1;
entry->symbols[i].gotslot_claimed = 0;
entry->symbols[i].rename = 0;
} }
/* Read strings (text segment) */ /* Read strings (text segment) */

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: rrs.c,v 1.2 1993/11/09 04:19:02 paul Exp $ * $Id: rrs.c,v 1.3 1993/11/17 01:33:24 ache Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -160,19 +160,23 @@ init_rrs()
/* /*
* Add NAME to the list of needed run-time objects. * Add NAME to the list of needed run-time objects.
* Return 1 if ENTRY was added to the list.
*/ */
void int
rrs_add_shobj(entry) rrs_add_shobj(entry)
struct file_entry *entry; struct file_entry *entry;
{ {
struct shobj **p; struct shobj **p;
for (p = &rrs_shobjs; *p != NULL; p = &(*p)->next); for (p = &rrs_shobjs; *p != NULL; p = &(*p)->next)
if (strcmp((*p)->entry->filename, entry->filename) == 0)
return 0;
*p = (struct shobj *)xmalloc(sizeof(struct shobj)); *p = (struct shobj *)xmalloc(sizeof(struct shobj));
(*p)->next = NULL; (*p)->next = NULL;
(*p)->entry = entry; (*p)->entry = entry;
number_of_shobjs++; number_of_shobjs++;
return 1;
} }
void void
@ -294,11 +298,11 @@ symbol *sp;
long *relocation; long *relocation;
{ {
struct relocation_info *r = rrs_next_reloc(); struct relocation_info *r = rrs_next_reloc();
#ifdef DEBUG
if (rp->r_address < text_start + text_size) if (rp->r_address < text_start + text_size)
error("RRS text relocation at %#x (symbol %s)", error("RRS text relocation at %#x (symbol %s)",
rp->r_address, sp->name); rp->r_address, sp->name);
#endif
#ifdef DEBUG #ifdef DEBUG
printf("claim_rrs_reloc: %s\n", sp->name); printf("claim_rrs_reloc: %s\n", sp->name);
#endif #endif
@ -961,6 +965,31 @@ write_rrs_text()
"internal error: %s defined in mysterious way", "internal error: %s defined in mysterious way",
sp->name); sp->name);
/* Handle auxialiary type qualifiers */
switch (sp->aux) {
case 0:
break;
case RRS_FUNC:
if (sp->so_defined != (N_TEXT+N_EXT))
fatal("internal error: %s: other but not text",
sp->name);
if (sp->jmpslot_offset == -1)
fatal(
"internal error: %s has no jmpslot but other",
sp->name);
nlp->nz_other = sp->aux;
nlp->nz_value =
rrs_dyn2.ld_plt + sp->jmpslot_offset;
break;
default:
fatal(
"internal error: %s: unsupported other value: %x",
sp->name, sp->aux);
break;
}
/* Set symbol's name */
nlp->nz_strx = offset; nlp->nz_strx = offset;
strcpy(rrs_strtab + offset, sp->name); strcpy(rrs_strtab + offset, sp->name);
offset += 1 + strlen(sp->name); offset += 1 + strlen(sp->name);

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.3 1993/11/09 04:19:29 paul Exp $ # $Id: Makefile,v 1.4 1993/11/09 04:44:29 paul Exp $
PROG= ld.so PROG= ld.so
SRCS= mdprologue.S rtld.c shlib.c etc.c md.c SRCS= mdprologue.S rtld.c shlib.c etc.c md.c
@ -8,7 +8,7 @@ LDDIR?= $(.CURDIR)/..
PICFLAG=-fpic PICFLAG=-fpic
CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD
LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic
LIBS = -lc_pic -lgcc_pic LIBS = -lc_pic
BINDIR= /usr/libexec BINDIR= /usr/libexec
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE) .PATH: $(LDDIR) $(LDDIR)/$(MACHINE)

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: rtld.c,v 1.2 1993/11/09 04:19:31 paul Exp $ * $Id: rtld.c,v 1.3 1993/11/09 04:44:30 paul Exp $
*/ */
#include <machine/vmparam.h> #include <machine/vmparam.h>
@ -144,7 +144,7 @@ static void reloc_copy __P((void));
static char *rtfindlib __P((char *, int, int, int *)); static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void)); void binder_entry __P((void));
long binder __P((jmpslot_t *)); long binder __P((jmpslot_t *));
static struct nzlist *lookup __P((char *, struct link_map **)); static struct nzlist *lookup __P((char *, struct link_map **, int));
static struct rt_symbol *lookup_rts __P((char *)); static struct rt_symbol *lookup_rts __P((char *));
static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long)); static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
@ -164,6 +164,7 @@ struct link_dynamic *dp;
int nreloc; /* # of ld.so relocations */ int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc; struct relocation_info *reloc;
char **envp; char **envp;
struct ld_debug *ldp;
/* Check version */ /* Check version */
if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN) if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN)
@ -218,7 +219,27 @@ struct link_dynamic *dp;
/* Fill in some field in main's __DYNAMIC structure */ /* Fill in some field in main's __DYNAMIC structure */
crtp->crt_dp->ld_entry = &ld_entry; crtp->crt_dp->ld_entry = &ld_entry;
crtp->crt_dp->ldd->ldd_cp = rt_symbol_head;
ldp = crtp->crt_dp->ldd;
ldp->ldd_cp = rt_symbol_head;
if (ldp->ldd_in_debugger) {
caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
/* Set breakpoint for the benefit of debuggers */
if (mprotect(addr, PAGSIZ,
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot set breakpoint\n");
}
md_set_breakpoint(crtp->crt_bp, &ldp->ldd_bp_inst);
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
perror("mprotect");
}
ldp->ldd_bp_addr = crtp->crt_bp;
if (link_map_head)
ldp->ldd_sym_loaded = 1;
}
} }
@ -265,9 +286,10 @@ struct crt_ldso *crtp;
path = "not found"; path = "not found";
if (lop->lo_library) if (lop->lo_library)
printf("\t-l%s.%d => %s\n", name, lop->lo_major, path); printf("\t-l%s.%d => %s (%#x)\n", name,
lop->lo_major, path, lmp->lm_addr);
else else
printf("\t%s => %s\n", name, path); printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
} }
_exit(0); _exit(0);
@ -423,10 +445,10 @@ reloc_maps()
sym = LM_STRINGS(lmp) + sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx; LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx;
np = lookup(sym, &src_map); np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
if (np == NULL) if (np == NULL)
fatal("Undefined symbol in %s: %s\n", fatal("Undefined symbol \"%s\" in %s\n",
lmp->lm_name, sym); sym, lmp->lm_name);
/* /*
* Found symbol definition. * Found symbol definition.
@ -475,6 +497,17 @@ xprintf("RELOCATE(%s) internal at %#x, reloc = %#x\n", lmp->lm_name, addr, md_ge
} }
if (lmp->lm_rwt) {
if (mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot disable writes to %s\n", lmp->lm_name);
}
lmp->lm_rwt = 0;
}
} }
} }
@ -516,9 +549,10 @@ caddr_t addr;
lmp->lm_name, r->r_address, sym); lmp->lm_name, r->r_address, sym);
#endif #endif
if (mprotect( lmp->lm_addr + LM_TXTADDR(lmp), if (lmp->lm_rwt == 0 &&
LD_TEXTSZ(lmp->lm_ld), mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"), perror("mprotect"),
fatal("Cannot enable writes to %s\n", lmp->lm_name); fatal("Cannot enable writes to %s\n", lmp->lm_name);
@ -527,10 +561,16 @@ caddr_t addr;
lmp->lm_rwt = 1; lmp->lm_rwt = 1;
} }
/*
* Lookup NAME in the link maps. The link map producing a definition
* is returned in SRC_MAP. If STRONG is set, the symbol returned must
* have a proper type (used by binder()).
*/
static struct nzlist * static struct nzlist *
lookup(name, src_map) lookup(name, src_map, strong)
char *name; char *name;
struct link_map **src_map; struct link_map **src_map;
int strong;
{ {
long common_size = 0; long common_size = 0;
struct link_map *lmp; struct link_map *lmp;
@ -587,10 +627,16 @@ struct link_map **src_map;
continue; continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) { if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
/* It's a common, note value and continue search */ if (np->nz_other == RRS_FUNC) {
if (common_size < np->nz_value) /* It's a weak function definition */
common_size = np->nz_value; if (strong)
continue; continue;
} else {
/* It's a common, note value and continue search */
if (common_size < np->nz_value)
common_size = np->nz_value;
continue;
}
} }
*src_map = lmp; *src_map = lmp;
@ -647,7 +693,7 @@ jmpslot_t *jsp;
sym = LM_STRINGS(lmp) + sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx; LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx;
np = lookup(sym, &src_map); np = lookup(sym, &src_map, 1);
if (np == NULL) if (np == NULL)
fatal("Undefined symbol \"%s\" called from %s at %#x", sym, fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
lmp->lm_name, jsp); lmp->lm_name, jsp);
@ -889,10 +935,11 @@ int *usehints;
if (ld_path != NULL) { if (ld_path != NULL) {
/* Prefer paths from LD_LIBRARY_PATH */ /* Prefer paths from LD_LIBRARY_PATH */
while ((cp = strtok(ld_path, ":")) != NULL) { while ((cp = strsep(&ld_path, ":")) != NULL) {
ld_path = NULL;
hint = findhint(name, major, minor, cp); hint = findhint(name, major, minor, cp);
if (ld_path)
*(ld_path-1) = ':';
if (hint) if (hint)
return hint; return hint;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: md.c,v 1.3 1993/11/06 19:15:31 pk Exp $ * $Id: md.c,v 1.2 1993/11/09 04:19:33 paul Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -285,3 +285,12 @@ struct relocation_info *rp, *r;
r->r_addend = 0; r->r_addend = 0;
} }
void
md_set_breakpoint(where, savep)
long where;
long *savep;
{
*savep = *(long *)where;
*(long *)where = BPT;
}

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: md.h,v 1.3 1993/10/24 00:48:20 pk Exp $ * $Id: md.h,v 1.2 1993/11/09 04:19:35 paul Exp $
*/ */
/* /*
@ -122,6 +122,7 @@ typedef struct jmpslot {
#define CALL 0x40000000 /* Call instruction (opcode2) */ #define CALL 0x40000000 /* Call instruction (opcode2) */
#define JMP 0x81c06000 /* Jump %g1 instruction (opcode2) */ #define JMP 0x81c06000 /* Jump %g1 instruction (opcode2) */
#define NOP 0x01000000 /* Delay slot NOP for (reloc_index) */ #define NOP 0x01000000 /* Delay slot NOP for (reloc_index) */
#define BPT 0x91d02001 /* breakpoint: `ta 0x1' */
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* $Id: symbol.c,v 1.3 1993/11/01 16:26:19 pk Exp $ - symbol table routines * $Id: symbol.c,v 1.2 1993/11/09 04:19:04 paul Exp $ - symbol table routines
*/ */
/* Create the symbol table entries for `etext', `edata' and `end'. */ /* Create the symbol table entries for `etext', `edata' and `end'. */
@ -104,8 +104,11 @@ getsym(key)
bp->multiply_defined = 0; bp->multiply_defined = 0;
bp->alias = 0; bp->alias = 0;
bp->setv_count = 0; bp->setv_count = 0;
bp->symbolnum = 0;
bp->rrs_symbolnum = 0;
bp->size = 0; bp->size = 0;
bp->aux = 0;
bp->sorefs = 0; bp->sorefs = 0;
bp->so_defined = 0; bp->so_defined = 0;
bp->def_nlist = 0; bp->def_nlist = 0;

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.3 1993/11/09 04:19:29 paul Exp $ # $Id: Makefile,v 1.4 1993/11/09 04:44:29 paul Exp $
PROG= ld.so PROG= ld.so
SRCS= mdprologue.S rtld.c shlib.c etc.c md.c SRCS= mdprologue.S rtld.c shlib.c etc.c md.c
@ -8,7 +8,7 @@ LDDIR?= $(.CURDIR)/..
PICFLAG=-fpic PICFLAG=-fpic
CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD
LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic
LIBS = -lc_pic -lgcc_pic LIBS = -lc_pic
BINDIR= /usr/libexec BINDIR= /usr/libexec
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE) .PATH: $(LDDIR) $(LDDIR)/$(MACHINE)

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: md.c,v 1.2 1993/11/09 04:19:16 paul Exp $ * $Id: md.c,v 1.3 1993/11/15 20:58:20 paul Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -236,6 +236,14 @@ struct relocation_info *rp, *r;
r->r_copy = 1; r->r_copy = 1;
} }
void
md_set_breakpoint(where, savep)
long where;
long *savep;
{
*savep = *(long *)where;
*(char *)where = BPT;
}
#ifdef NEED_SWAP #ifdef NEED_SWAP

View File

@ -1,5 +1,5 @@
/* /*
* $Id: md.h,v 1.3 1993/10/24 00:52:40 pk Exp $ - I386 dependent definitions * $Id: md.h,v 1.2 1993/11/09 04:19:17 paul Exp $ - I386 dependent definitions
*/ */
@ -50,7 +50,7 @@ typedef struct jmpslot {
#define NOP 0x90 #define NOP 0x90
#define CALL 0xe890 /* NOP + CALL opcode */ #define CALL 0xe890 /* NOP + CALL opcode */
#define JUMP 0xe990 /* NOP + JMP opcode */ #define JUMP 0xe990 /* NOP + JMP opcode */
#define TRAP 0xcc /* INT 3 */ #define BPT 0xcc /* breakpoint: INT 3 */
/* /*
* Byte swap defs for cross linking * Byte swap defs for cross linking

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: rtld.c,v 1.2 1993/11/09 04:19:31 paul Exp $ * $Id: rtld.c,v 1.3 1993/11/09 04:44:30 paul Exp $
*/ */
#include <machine/vmparam.h> #include <machine/vmparam.h>
@ -144,7 +144,7 @@ static void reloc_copy __P((void));
static char *rtfindlib __P((char *, int, int, int *)); static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void)); void binder_entry __P((void));
long binder __P((jmpslot_t *)); long binder __P((jmpslot_t *));
static struct nzlist *lookup __P((char *, struct link_map **)); static struct nzlist *lookup __P((char *, struct link_map **, int));
static struct rt_symbol *lookup_rts __P((char *)); static struct rt_symbol *lookup_rts __P((char *));
static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long)); static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
@ -164,6 +164,7 @@ struct link_dynamic *dp;
int nreloc; /* # of ld.so relocations */ int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc; struct relocation_info *reloc;
char **envp; char **envp;
struct ld_debug *ldp;
/* Check version */ /* Check version */
if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN) if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN)
@ -218,7 +219,27 @@ struct link_dynamic *dp;
/* Fill in some field in main's __DYNAMIC structure */ /* Fill in some field in main's __DYNAMIC structure */
crtp->crt_dp->ld_entry = &ld_entry; crtp->crt_dp->ld_entry = &ld_entry;
crtp->crt_dp->ldd->ldd_cp = rt_symbol_head;
ldp = crtp->crt_dp->ldd;
ldp->ldd_cp = rt_symbol_head;
if (ldp->ldd_in_debugger) {
caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
/* Set breakpoint for the benefit of debuggers */
if (mprotect(addr, PAGSIZ,
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot set breakpoint\n");
}
md_set_breakpoint(crtp->crt_bp, &ldp->ldd_bp_inst);
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
perror("mprotect");
}
ldp->ldd_bp_addr = crtp->crt_bp;
if (link_map_head)
ldp->ldd_sym_loaded = 1;
}
} }
@ -265,9 +286,10 @@ struct crt_ldso *crtp;
path = "not found"; path = "not found";
if (lop->lo_library) if (lop->lo_library)
printf("\t-l%s.%d => %s\n", name, lop->lo_major, path); printf("\t-l%s.%d => %s (%#x)\n", name,
lop->lo_major, path, lmp->lm_addr);
else else
printf("\t%s => %s\n", name, path); printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
} }
_exit(0); _exit(0);
@ -423,10 +445,10 @@ reloc_maps()
sym = LM_STRINGS(lmp) + sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx; LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx;
np = lookup(sym, &src_map); np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
if (np == NULL) if (np == NULL)
fatal("Undefined symbol in %s: %s\n", fatal("Undefined symbol \"%s\" in %s\n",
lmp->lm_name, sym); sym, lmp->lm_name);
/* /*
* Found symbol definition. * Found symbol definition.
@ -475,6 +497,17 @@ xprintf("RELOCATE(%s) internal at %#x, reloc = %#x\n", lmp->lm_name, addr, md_ge
} }
if (lmp->lm_rwt) {
if (mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot disable writes to %s\n", lmp->lm_name);
}
lmp->lm_rwt = 0;
}
} }
} }
@ -516,9 +549,10 @@ caddr_t addr;
lmp->lm_name, r->r_address, sym); lmp->lm_name, r->r_address, sym);
#endif #endif
if (mprotect( lmp->lm_addr + LM_TXTADDR(lmp), if (lmp->lm_rwt == 0 &&
LD_TEXTSZ(lmp->lm_ld), mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"), perror("mprotect"),
fatal("Cannot enable writes to %s\n", lmp->lm_name); fatal("Cannot enable writes to %s\n", lmp->lm_name);
@ -527,10 +561,16 @@ caddr_t addr;
lmp->lm_rwt = 1; lmp->lm_rwt = 1;
} }
/*
* Lookup NAME in the link maps. The link map producing a definition
* is returned in SRC_MAP. If STRONG is set, the symbol returned must
* have a proper type (used by binder()).
*/
static struct nzlist * static struct nzlist *
lookup(name, src_map) lookup(name, src_map, strong)
char *name; char *name;
struct link_map **src_map; struct link_map **src_map;
int strong;
{ {
long common_size = 0; long common_size = 0;
struct link_map *lmp; struct link_map *lmp;
@ -587,10 +627,16 @@ struct link_map **src_map;
continue; continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) { if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
/* It's a common, note value and continue search */ if (np->nz_other == RRS_FUNC) {
if (common_size < np->nz_value) /* It's a weak function definition */
common_size = np->nz_value; if (strong)
continue; continue;
} else {
/* It's a common, note value and continue search */
if (common_size < np->nz_value)
common_size = np->nz_value;
continue;
}
} }
*src_map = lmp; *src_map = lmp;
@ -647,7 +693,7 @@ jmpslot_t *jsp;
sym = LM_STRINGS(lmp) + sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx; LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx;
np = lookup(sym, &src_map); np = lookup(sym, &src_map, 1);
if (np == NULL) if (np == NULL)
fatal("Undefined symbol \"%s\" called from %s at %#x", sym, fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
lmp->lm_name, jsp); lmp->lm_name, jsp);
@ -889,10 +935,11 @@ int *usehints;
if (ld_path != NULL) { if (ld_path != NULL) {
/* Prefer paths from LD_LIBRARY_PATH */ /* Prefer paths from LD_LIBRARY_PATH */
while ((cp = strtok(ld_path, ":")) != NULL) { while ((cp = strsep(&ld_path, ":")) != NULL) {
ld_path = NULL;
hint = findhint(name, major, minor, cp); hint = findhint(name, major, minor, cp);
if (ld_path)
*(ld_path-1) = ':';
if (hint) if (hint)
return hint; return hint;
} }