diff --git a/gnu/usr.bin/ld/i386/md.c b/gnu/usr.bin/ld/i386/md.c index c0b7eba7c8d2..2344565ceba7 100644 --- a/gnu/usr.bin/ld/i386/md.c +++ b/gnu/usr.bin/ld/i386/md.c @@ -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 @@ -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 diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h index ecd18159c214..ca46e81f6c36 100644 --- a/gnu/usr.bin/ld/i386/md.h +++ b/gnu/usr.bin/ld/i386/md.h @@ -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 diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c index 126e4ac60258..37a98a3042bf 100644 --- a/gnu/usr.bin/ld/ld.c +++ b/gnu/usr.bin/ld/ld.c @@ -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. */ diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h index 320d0733f03f..f17ff6b121dd 100644 --- a/gnu/usr.bin/ld/ld.h +++ b/gnu/usr.bin/ld/ld.h @@ -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 *)); diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c index d66f3df2924d..8cbb8b479aed 100644 --- a/gnu/usr.bin/ld/lib.c +++ b/gnu/usr.bin/ld/lib.c @@ -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 @@ -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) */ diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c index b999c6258f3c..acefa3920fce 100644 --- a/gnu/usr.bin/ld/rrs.c +++ b/gnu/usr.bin/ld/rrs.c @@ -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 @@ -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); diff --git a/gnu/usr.bin/ld/rtld/Makefile b/gnu/usr.bin/ld/rtld/Makefile index 06b215cdf2c5..a107bff9c5ae 100644 --- a/gnu/usr.bin/ld/rtld/Makefile +++ b/gnu/usr.bin/ld/rtld/Makefile @@ -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) diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c index 9c4f0bcbb648..0cccd23d12c0 100644 --- a/gnu/usr.bin/ld/rtld/rtld.c +++ b/gnu/usr.bin/ld/rtld/rtld.c @@ -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 @@ -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; } diff --git a/gnu/usr.bin/ld/sparc/md.c b/gnu/usr.bin/ld/sparc/md.c index 5424f15e4718..0b9aef566f42 100644 --- a/gnu/usr.bin/ld/sparc/md.c +++ b/gnu/usr.bin/ld/sparc/md.c @@ -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 @@ -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; +} + diff --git a/gnu/usr.bin/ld/sparc/md.h b/gnu/usr.bin/ld/sparc/md.h index e81d184815d0..ba6a0912d79f 100644 --- a/gnu/usr.bin/ld/sparc/md.h +++ b/gnu/usr.bin/ld/sparc/md.h @@ -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' */ /* diff --git a/gnu/usr.bin/ld/symbol.c b/gnu/usr.bin/ld/symbol.c index 899786c78983..d789a3a54bb6 100644 --- a/gnu/usr.bin/ld/symbol.c +++ b/gnu/usr.bin/ld/symbol.c @@ -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; diff --git a/libexec/rtld-aout/Makefile b/libexec/rtld-aout/Makefile index 06b215cdf2c5..a107bff9c5ae 100644 --- a/libexec/rtld-aout/Makefile +++ b/libexec/rtld-aout/Makefile @@ -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) diff --git a/libexec/rtld-aout/i386/md.c b/libexec/rtld-aout/i386/md.c index c0b7eba7c8d2..2344565ceba7 100644 --- a/libexec/rtld-aout/i386/md.c +++ b/libexec/rtld-aout/i386/md.c @@ -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 @@ -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 diff --git a/libexec/rtld-aout/i386/md.h b/libexec/rtld-aout/i386/md.h index ecd18159c214..ca46e81f6c36 100644 --- a/libexec/rtld-aout/i386/md.h +++ b/libexec/rtld-aout/i386/md.h @@ -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 diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c index 9c4f0bcbb648..0cccd23d12c0 100644 --- a/libexec/rtld-aout/rtld.c +++ b/libexec/rtld-aout/rtld.c @@ -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 @@ -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; }