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
* 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>
@ -236,6 +236,14 @@ struct relocation_info *rp, *r;
r->r_copy = 1;
}
void
md_set_breakpoint(where, savep)
long where;
long *savep;
{
*savep = *(long *)where;
*(char *)where = BPT;
}
#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 CALL 0xe890 /* NOP + CALL opcode */
#define JUMP 0xe990 /* NOP + JMP opcode */
#define TRAP 0xcc /* INT 3 */
#define BPT 0xcc /* breakpoint: INT 3 */
/*
* 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. */
/*
* $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. */
@ -636,10 +636,15 @@ each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
if (entry->scrapped)
continue;
if (entry->library_flag) {
register struct file_entry *subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain)
for (; subentry; subentry = subentry->chain) {
if (subentry->scrapped)
continue;
(*function) (subentry, arg);
}
} else
(*function) (entry, arg);
}
@ -664,11 +669,16 @@ check_each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
if (entry->scrapped)
continue;
if (entry->library_flag) {
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))
return return_val;
}
} else if (return_val = (*function) (entry, arg))
return return_val;
}
@ -686,7 +696,8 @@ each_full_file(function, arg)
for (i = 0; i < number_of_files; 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;
if (entry->library_flag) {
register struct file_entry *subentry = entry->subfiles;
@ -816,6 +827,7 @@ read_entry_symbols (desc, entry)
entry->symbols[i].next = NULL;
entry->symbols[i].gotslot_offset = -1;
entry->symbols[i].gotslot_claimed = 0;
entry->symbols[i].rename = 0;
}
entry->strings_offset = N_STROFF(entry->header) +
@ -840,7 +852,8 @@ read_entry_strings (desc, entry)
int buffer;
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)
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. */
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
@ -967,8 +980,10 @@ read_file_symbols (entry)
return;
}
entry->is_dynamic = 1;
read_shared_object(desc, entry);
rrs_add_shobj(entry);
if (rrs_add_shobj(entry))
read_shared_object(desc, entry);
else
entry->scrapped = 1;
} else {
read_entry_symbols (desc, entry);
entry->strings = (char *) alloca (entry->string_size);
@ -1320,7 +1335,7 @@ digest_symbols ()
defined_global_sym_count = 0;
digest_pass1();
if (!relocatable_output) {
if (1 || !relocatable_output) {
each_full_file(consider_relocation, 0); /* Text */
each_full_file(consider_relocation, 1); /* Data */
}
@ -1505,7 +1520,7 @@ digest_pass1()
register int type = p->n_type;
if ((type & N_EXT) && type != (N_UNDF | N_EXT)
&& (type & N_TYPE) != N_FN) {
&& (type & N_TYPE) != N_FN) {
/* non-common definition */
sp->def_nlist = p;
sp->so_defined = type;
@ -1673,6 +1688,14 @@ consider_relocation (entry, dataseg)
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.
* 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;
if (!oldmagic)
N_SET_FLAG (outheader, flags);
if (!oldmagic) N_SET_FLAG (outheader, flags);
outheader.a_text = text_size;
outheader.a_data = data_size;
outheader.a_bss = bss_size;
@ -1974,10 +1996,10 @@ write_header ()
#ifdef DEBUG
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,
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
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,
relocating the addresses-to-be-relocated. */
void coptxtrel (), copdatrel ();
void coptxtrel(), copdatrel(), assign_symbolnums();
void
write_rel ()
{
register int count = 0;
int count = 0;
if (trace_files)
fprintf (stderr, "Writing text relocation:\n\n");
@ -2408,6 +2430,8 @@ write_rel ()
+ special_sym_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. */
each_full_file (coptxtrel, 0);
@ -2420,6 +2444,25 @@ write_rel ()
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
coptxtrel(entry)
struct file_entry *entry;
@ -2897,12 +2940,25 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *p = &lsp->nzlist.nlist;
register int type = p->n_type;
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
* written.
*/
if (SET_ELEMENT_P (type))
/*
* This occurs even if global. These types of
@ -2910,17 +2966,20 @@ write_file_syms(entry, syms_written_addr)
* they are stored globally.
*/
write = relocatable_output;
else if (!(type & (N_STAB | N_EXT)))
else if (!(type & (N_STAB | N_EXT)) && name != NULL)
/* ordinary local symbol */
write = ((discard_locals != DISCARD_ALL)
&& !(discard_locals == DISCARD_L &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX)
&& type != N_WARNING);
write = (lsp->rename || (
discard_locals != DISCARD_ALL &&
!(discard_locals == DISCARD_L &&
name[0] == LPREFIX) &&
type != N_WARNING) );
else if (!(type & N_EXT))
/* debugger symbol */
write = (strip_symbols == STRIP_NONE) &&
write = (strip_symbols == STRIP_NONE)/* &&
!(discard_locals == DISCARD_L &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX);
name[0] == LPREFIX)*/;
else if (name == NULL)
error("Amnesiac");
if (write) {
/*
@ -2928,9 +2987,8 @@ write_file_syms(entry, syms_written_addr)
* in the output string table.
*/
if (p->n_un.n_strx)
p->n_un.n_strx = assign_string_table_index(
p->n_un.n_strx + entry->strings);
if (name)
p->n_un.n_strx = assign_string_table_index(name);
/* 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
* Foundation.
@ -343,11 +343,11 @@ int oldmagic;
typedef struct glosym {
/* Pointer to next symbol in this symbol's hash bucket. */
struct glosym *link;
struct glosym *link;
/* Name of this symbol. */
char *name;
char *name;
/* 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
* refs.
@ -357,34 +357,34 @@ typedef struct glosym {
* Any warning message that might be associated with this symbol from
* an N_WARNING symbol encountered.
*/
char *warning;
char *warning;
/*
* Nonzero means definitions of this symbol as common have been seen,
* 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
* the symbol table to be written, with the first global sym given
* index 0.
*/
int symbolnum;
int symbolnum;
/*
* For dynamically linked output, records the index in the RRS
* symbol table.
*/
int rrs_symbolnum;
int rrs_symbolnum;
/*
* Nonzero means a definition of this global symbol is known to
* 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
* file that is surely being loaded. A value higher than 1 is the
* n_type code for the symbol's definition.
*/
char referenced;
char referenced;
/*
* A count of the number of undefined references printed for a
* 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
* stop.
*/
unsigned char undef_refs;
unsigned char undef_refs;
/*
* 1 means that this symbol has multiple definitions. 2 means that
* it has multiple definitions, and some of them are set elements,
* 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 */
char trace;
char trace;
/*
* 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
* dynamic link information segment.
*/
char so_defined;
char so_defined;
/* Size of symbol as determined by N_SIZE 'nlist's in object files */
int size;
/* Size of symbol as determined by N_SIZE symbols in object files */
int size;
/* Auxialiary info to put in the `nz_other' field of the
* RRS symbol table. Used by the run-time linker to resolve
@ -600,6 +600,8 @@ struct file_entry {
struct localsymbol *next;
long gotslot_offset;
char gotslot_claimed;
char rename;
int symbolnum;
} *symbols;
/* Number of symbols in above array. */
@ -688,6 +690,9 @@ struct file_entry {
/* This entry is a shared object */
char is_dynamic;
/* 1 if this entry is not a major player anymore */
char scrapped;
};
typedef struct localsymbol localsymbol_t;
@ -858,7 +863,7 @@ void std_search_dirs __P((char *));
/* In rrs.c: */
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_segment_reloc __P((struct relocation_info *));
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>
@ -572,6 +572,8 @@ read_shared_object (desc, entry)
entry->symbols[i].symbol = NULL;
entry->symbols[i].next = NULL;
entry->symbols[i].gotslot_offset = -1;
entry->symbols[i].gotslot_claimed = 0;
entry->symbols[i].rename = 0;
}
/* Read strings (text segment) */

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* 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>
@ -160,19 +160,23 @@ init_rrs()
/*
* 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)
struct file_entry *entry;
{
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)->next = NULL;
(*p)->entry = entry;
number_of_shobjs++;
return 1;
}
void
@ -294,11 +298,11 @@ symbol *sp;
long *relocation;
{
struct relocation_info *r = rrs_next_reloc();
#ifdef DEBUG
if (rp->r_address < text_start + text_size)
error("RRS text relocation at %#x (symbol %s)",
rp->r_address, sp->name);
#endif
#ifdef DEBUG
printf("claim_rrs_reloc: %s\n", sp->name);
#endif
@ -961,6 +965,31 @@ write_rrs_text()
"internal error: %s defined in mysterious way",
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;
strcpy(rrs_strtab + offset, 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
SRCS= mdprologue.S rtld.c shlib.c etc.c md.c
@ -8,7 +8,7 @@ LDDIR?= $(.CURDIR)/..
PICFLAG=-fpic
CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD
LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic
LIBS = -lc_pic -lgcc_pic
LIBS = -lc_pic
BINDIR= /usr/libexec
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* 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>
@ -144,7 +144,7 @@ static void reloc_copy __P((void));
static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void));
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 *enter_rts __P((char *, long, int, caddr_t, long));
@ -164,6 +164,7 @@ struct link_dynamic *dp;
int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc;
char **envp;
struct ld_debug *ldp;
/* Check version */
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 */
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";
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
printf("\t%s => %s\n", name, path);
printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
}
_exit(0);
@ -423,10 +445,10 @@ reloc_maps()
sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx;
np = lookup(sym, &src_map);
np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
if (np == NULL)
fatal("Undefined symbol in %s: %s\n",
lmp->lm_name, sym);
fatal("Undefined symbol \"%s\" in %s\n",
sym, lmp->lm_name);
/*
* 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);
#endif
if (mprotect( lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
if (lmp->lm_rwt == 0 &&
mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot enable writes to %s\n", lmp->lm_name);
@ -527,10 +561,16 @@ caddr_t addr;
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 *
lookup(name, src_map)
char *name;
lookup(name, src_map, strong)
char *name;
struct link_map **src_map;
int strong;
{
long common_size = 0;
struct link_map *lmp;
@ -587,10 +627,16 @@ struct link_map **src_map;
continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
/* It's a common, note value and continue search */
if (common_size < np->nz_value)
common_size = np->nz_value;
continue;
if (np->nz_other == RRS_FUNC) {
/* It's a weak function definition */
if (strong)
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;
@ -647,7 +693,7 @@ jmpslot_t *jsp;
sym = LM_STRINGS(lmp) +
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)
fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
lmp->lm_name, jsp);
@ -889,10 +935,11 @@ int *usehints;
if (ld_path != NULL) {
/* 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);
if (ld_path)
*(ld_path-1) = ':';
if (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>
@ -285,3 +285,12 @@ struct relocation_info *rp, *r;
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
* 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 JMP 0x81c06000 /* Jump %g1 instruction (opcode2) */
#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'. */
@ -104,8 +104,11 @@ getsym(key)
bp->multiply_defined = 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;

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
SRCS= mdprologue.S rtld.c shlib.c etc.c md.c
@ -8,7 +8,7 @@ LDDIR?= $(.CURDIR)/..
PICFLAG=-fpic
CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD
LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic
LIBS = -lc_pic -lgcc_pic
LIBS = -lc_pic
BINDIR= /usr/libexec
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* 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>
@ -236,6 +236,14 @@ struct relocation_info *rp, *r;
r->r_copy = 1;
}
void
md_set_breakpoint(where, savep)
long where;
long *savep;
{
*savep = *(long *)where;
*(char *)where = BPT;
}
#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 CALL 0xe890 /* NOP + CALL opcode */
#define JUMP 0xe990 /* NOP + JMP opcode */
#define TRAP 0xcc /* INT 3 */
#define BPT 0xcc /* breakpoint: INT 3 */
/*
* 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
* 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>
@ -144,7 +144,7 @@ static void reloc_copy __P((void));
static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void));
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 *enter_rts __P((char *, long, int, caddr_t, long));
@ -164,6 +164,7 @@ struct link_dynamic *dp;
int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc;
char **envp;
struct ld_debug *ldp;
/* Check version */
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 */
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";
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
printf("\t%s => %s\n", name, path);
printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
}
_exit(0);
@ -423,10 +445,10 @@ reloc_maps()
sym = LM_STRINGS(lmp) +
LM_SYMBOL(lmp,RELOC_SYMBOL(r))->nz_strx;
np = lookup(sym, &src_map);
np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
if (np == NULL)
fatal("Undefined symbol in %s: %s\n",
lmp->lm_name, sym);
fatal("Undefined symbol \"%s\" in %s\n",
sym, lmp->lm_name);
/*
* 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);
#endif
if (mprotect( lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
if (lmp->lm_rwt == 0 &&
mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
LD_TEXTSZ(lmp->lm_ld),
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
fatal("Cannot enable writes to %s\n", lmp->lm_name);
@ -527,10 +561,16 @@ caddr_t addr;
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 *
lookup(name, src_map)
char *name;
lookup(name, src_map, strong)
char *name;
struct link_map **src_map;
int strong;
{
long common_size = 0;
struct link_map *lmp;
@ -587,10 +627,16 @@ struct link_map **src_map;
continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
/* It's a common, note value and continue search */
if (common_size < np->nz_value)
common_size = np->nz_value;
continue;
if (np->nz_other == RRS_FUNC) {
/* It's a weak function definition */
if (strong)
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;
@ -647,7 +693,7 @@ jmpslot_t *jsp;
sym = LM_STRINGS(lmp) +
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)
fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
lmp->lm_name, jsp);
@ -889,10 +935,11 @@ int *usehints;
if (ld_path != NULL) {
/* 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);
if (ld_path)
*(ld_path-1) = ':';
if (hint)
return hint;
}