aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/ld/i386/md.c10
-rw-r--r--gnu/usr.bin/ld/i386/md.h4
-rw-r--r--gnu/usr.bin/ld/ld.c112
-rw-r--r--gnu/usr.bin/ld/ld.h39
-rw-r--r--gnu/usr.bin/ld/lib.c4
-rw-r--r--gnu/usr.bin/ld/rrs.c39
-rw-r--r--gnu/usr.bin/ld/rtld/Makefile4
-rw-r--r--gnu/usr.bin/ld/rtld/rtld.c87
-rw-r--r--gnu/usr.bin/ld/sparc/md.c11
-rw-r--r--gnu/usr.bin/ld/sparc/md.h3
-rw-r--r--gnu/usr.bin/ld/symbol.c5
-rw-r--r--libexec/rtld-aout/Makefile4
-rw-r--r--libexec/rtld-aout/i386/md.c10
-rw-r--r--libexec/rtld-aout/i386/md.h4
-rw-r--r--libexec/rtld-aout/rtld.c87
15 files changed, 320 insertions, 103 deletions
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 <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
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 <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) */
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 <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);
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 <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;
}
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 <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;
+}
+
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 <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
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 <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;
}