summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1993-11-30 20:47:54 +0000
committerjkh <jkh@FreeBSD.org>1993-11-30 20:47:54 +0000
commit90b65690ecd280ea567bd543c551a0d528447130 (patch)
tree9392aab4f81d6be4eb1228cfb19ddc38026587ce
parent09904e4dc974d08f55ad948a5489109659abbfdd (diff)
downloadFreeBSD-src-90b65690ecd280ea567bd543c551a0d528447130.zip
FreeBSD-src-90b65690ecd280ea567bd543c551a0d528447130.tar.gz
Many recent fixes from Paul K, add support for chaining of shared lib deps.
-rw-r--r--gnu/usr.bin/ld/Makefile10
-rw-r--r--gnu/usr.bin/ld/etc.c4
-rw-r--r--gnu/usr.bin/ld/i386/md.c4
-rw-r--r--gnu/usr.bin/ld/i386/md.h4
-rw-r--r--gnu/usr.bin/ld/ld.c428
-rw-r--r--gnu/usr.bin/ld/ld.h41
-rw-r--r--gnu/usr.bin/ld/ldconfig/ldconfig.c11
-rw-r--r--gnu/usr.bin/ld/lib.c108
-rw-r--r--gnu/usr.bin/ld/rrs.c118
-rw-r--r--gnu/usr.bin/ld/rtld/rtld.c62
-rw-r--r--gnu/usr.bin/ld/shlib.c29
-rw-r--r--gnu/usr.bin/ld/sparc/md.c4
-rw-r--r--gnu/usr.bin/ld/sparc/md.h4
-rw-r--r--libexec/rtld-aout/i386/md.c4
-rw-r--r--libexec/rtld-aout/i386/md.h4
-rw-r--r--libexec/rtld-aout/rtld.c62
-rw-r--r--libexec/rtld-aout/shlib.c29
-rw-r--r--sbin/ldconfig/ldconfig.c11
18 files changed, 704 insertions, 233 deletions
diff --git a/gnu/usr.bin/ld/Makefile b/gnu/usr.bin/ld/Makefile
index e002e96..ff87a39 100644
--- a/gnu/usr.bin/ld/Makefile
+++ b/gnu/usr.bin/ld/Makefile
@@ -1,18 +1,14 @@
-# $Id: Makefile,v 1.6 1993/11/09 21:23:07 paul Exp $
+# $Id: Makefile,v 1.8 1993/11/03 13:01:36 cgd Exp $
#
PROG= ld
SRCS= ld.c symbol.c lib.c shlib.c warnings.c etc.c rrs.c xbits.c md.c
-CFLAGS += -static -I$(.CURDIR) -I$(.CURDIR)/$(MACHINE)
+CFLAGS += -g -I$(.CURDIR) -I$(.CURDIR)/$(MACHINE)
LDADD+= -lgnumalloc
DPADD+= /usr/lib/libgnumalloc.a
-LDFLAGS+= -Xlinker -Bstatic
-SUBDIR= ldconfig ldd
-.if !defined(NOPIC)
-SUBDIR+= rtld
-.endif
+SUBDIR= ldconfig ldd rtld
.PATH: $(.CURDIR)/$(MACHINE)
diff --git a/gnu/usr.bin/ld/etc.c b/gnu/usr.bin/ld/etc.c
index 33c6bf2..c5ac33f 100644
--- a/gnu/usr.bin/ld/etc.c
+++ b/gnu/usr.bin/ld/etc.c
@@ -1,5 +1,5 @@
/*
- * $Id: etc.c,v 1.2 1993/10/21 00:52:52 pk Exp $
+ * $Id: etc.c,v 1.2 1993/11/09 04:18:52 paul Exp $
*/
#include <sys/param.h>
@@ -72,7 +72,7 @@ fatal(fmt, va_alist)
(void)fprintf(stderr, "\n");
va_end(ap);
- if (outdesc >= 0)
+ if (outdesc > 0)
unlink(output_filename);
exit(1);
}
diff --git a/gnu/usr.bin/ld/i386/md.c b/gnu/usr.bin/ld/i386/md.c
index 2344565..40766df 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.3 1993/11/15 20:58:20 paul Exp $
+ * $Id: md.c,v 1.4 1993/11/22 19:05:23 jkh Exp $
*/
#include <sys/param.h>
@@ -242,7 +242,7 @@ long where;
long *savep;
{
*savep = *(long *)where;
- *(char *)where = BPT;
+ *(char *)where = TRAP;
}
#ifdef NEED_SWAP
diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h
index ca46e81..714073b 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.2 1993/11/09 04:19:17 paul Exp $ - I386 dependent definitions
+ * $Id: md.h,v 1.3 1993/11/22 19:05:24 jkh 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 BPT 0xcc /* breakpoint: INT 3 */
+#define TRAP 0xcc /* 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 37a98a3..5b93e9e 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.9 1993/11/18 20:52:31 jkh Exp $
+ * $Id: ld.c,v 1.10 1993/11/22 19:04:40 jkh Exp $
*/
/* Define how to initialize system-dependent header fields. */
@@ -73,6 +73,10 @@ int force_common_definition;
/* 1 => assign jmp slots to text symbols in shared objects even if non-PIC */
int force_alias_definition;
+/* 1 => some files contain PIC code, affects relocation bits
+ if `relocatable_output'. */
+int pic_code_seen;
+
/*
* Which symbols should be stripped (omitted from the output): none, all, or
* debugger symbols.
@@ -176,6 +180,9 @@ main(argc, argv)
make_executable = 1;
force_executable = 0;
link_mode = DYNAMIC;
+#ifdef SUNOS4
+ link_mode |= SILLYARCHIVE;
+#endif
soversion = LD_VERSION_BSD;
/* Initialize the cumulative counts of symbols. */
@@ -201,6 +208,10 @@ main(argc, argv)
building_shared_object =
(!relocatable_output && (link_mode & SHAREABLE));
+ if (building_shared_object && entry_symbol) {
+ fatal("`-Bshareable' and `-e' options are mutually exclusive");
+ }
+
/* Create the symbols `etext', `edata' and `end'. */
symtab_init(relocatable_output);
@@ -382,6 +393,12 @@ decode_command(argc, argv)
link_mode |= FORCEARCHIVE;
else if (strcmp(string, "shareable") == 0)
link_mode |= SHAREABLE;
+#ifdef SUN_COMPAT
+ else if (strcmp(string, "silly") == 0)
+ link_mode |= SILLYARCHIVE;
+ else if (strcmp(string, "~silly") == 0)
+ link_mode &= ~SILLYARCHIVE;
+#endif
}
if (argv[i][1] == 'A') {
if (p != file_table)
@@ -476,6 +493,10 @@ decode_option(swt, arg)
return;
if (!strcmp(swt + 1, "assert"))
return;
+#ifdef SUN_COMPAT
+ if (!strcmp(swt + 1, "Bsilly"))
+ return;
+#endif
if (!strcmp(swt + 1, "Ttext")) {
text_start = parse(arg, "%x", "invalid argument to -Ttext");
T_flag_specified = 1;
@@ -636,17 +657,38 @@ each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
+ register struct file_entry *subentry;
+
if (entry->scrapped)
continue;
- if (entry->library_flag) {
- register struct file_entry *subentry = entry->subfiles;
+
+ if (!entry->library_flag)
+ (*function) (entry, arg);
+
+ subentry = entry->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
+ (*function) (subentry, arg);
+ }
+
+#ifdef SUN_COMPAT
+ if (entry->silly_archive) {
+
+ if (!entry->is_dynamic)
+ error("Silly");
+
+ if (!entry->silly_archive->library_flag)
+ error("Sillier");
+
+ subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
if (subentry->scrapped)
continue;
(*function) (subentry, arg);
}
- } else
- (*function) (entry, arg);
+ }
+#endif
}
}
@@ -696,15 +738,41 @@ each_full_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
- if (entry->scrapped ||
- entry->just_syms_flag || entry->is_dynamic)
+ register struct file_entry *subentry;
+
+ if (entry->scrapped || entry->just_syms_flag)
continue;
- if (entry->library_flag) {
- register struct file_entry *subentry = entry->subfiles;
- for (; subentry; subentry = subentry->chain)
+
+#ifdef SUN_COMPAT
+ if (entry->silly_archive) {
+
+ if (!entry->is_dynamic)
+ error("Silly");
+
+ if (!entry->silly_archive->library_flag)
+ error("Sillier");
+
+ subentry = entry->silly_archive->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
(*function) (subentry, arg);
- } else
+ }
+ }
+#endif
+ if (entry->is_dynamic)
+ continue;
+
+ if (!entry->library_flag)
(*function) (entry, arg);
+
+ subentry = entry->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
+ (*function) (subentry, arg);
+ }
+
}
}
@@ -729,7 +797,7 @@ file_open (entry)
{
register int desc;
- if (entry->superfile)
+ if (entry->superfile && entry->superfile->library_flag)
return file_open (entry->superfile);
if (entry == input_file)
@@ -827,6 +895,8 @@ 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].write = 0;
+ entry->symbols[i].is_L_symbol = 0;
entry->symbols[i].rename = 0;
}
@@ -980,7 +1050,7 @@ read_file_symbols (entry)
return;
}
entry->is_dynamic = 1;
- if (rrs_add_shobj(entry))
+ if (entry->superfile || rrs_add_shobj(entry))
read_shared_object(desc, entry);
else
entry->scrapped = 1;
@@ -1062,25 +1132,11 @@ enter_file_symbols (entry)
} else if (p->n_type & N_EXT) {
enter_global_ref(lsp,
p->n_un.n_strx + entry->strings, entry);
- } else if (p->n_un.n_strx && !(p->n_type & (N_STAB | N_EXT))
- && !entry->is_dynamic) {
- if ((p->n_un.n_strx + entry->strings)[0] != LPREFIX)
- non_L_local_sym_count++;
- local_sym_count++;
- } else if (!entry->is_dynamic)
- debugger_sym_count++;
+ } else if (p->n_un.n_strx &&
+ (p->n_un.n_strx + entry->strings)[0] == LPREFIX)
+ lsp->is_L_symbol = 1;
}
- /*
- * Count one for the local symbol that we generate,
- * whose name is the file's name (usually) and whose address
- * is the start of the file's text.
- */
-
- if (!entry->is_dynamic) {
- local_sym_count++;
- non_L_local_sym_count++;
- }
}
/*
@@ -1092,7 +1148,7 @@ enter_file_symbols (entry)
* This chain starts in the `refs' for symbols from relocatable objects. A
* backpointer to the global symbol is kept in LSP.
*
- * Symbols from shared objects are linked through `dynref'. For such symbols
+ * Symbols from shared objects are linked through `soref'. For such symbols
* that's all we do at this stage, with the exception of the case where the
* symbol is a common. The `referenced' bit is only set for references from
* relocatable objects.
@@ -1172,6 +1228,8 @@ enter_global_ref (lsp, name, entry)
#ifdef N_SIZE
if (type == (N_SIZE | N_EXT)) {
+ if (relocatable_output && nzp->nz_value != 0 && sp->size == 0)
+ size_sym_count++;
if (sp->size < nzp->nz_value)
sp->size = nzp->nz_value;
} else
@@ -1297,7 +1355,7 @@ void consider_relocation();
* symbols originating from shared objects is searched for a definition.
*
* 2) Then the relocation information of each relocatable file is examined
- * for for possible contributions to the RRS section.
+ * for possible contributions to the RRS section.
*
* 3) When this is done, the sizes and start addresses are set of all segments
* that will appear in the output file (including the RRS segment).
@@ -1335,10 +1393,8 @@ digest_symbols ()
defined_global_sym_count = 0;
digest_pass1();
- if (1 || !relocatable_output) {
- each_full_file(consider_relocation, 0); /* Text */
- each_full_file(consider_relocation, 1); /* Data */
- }
+ each_full_file(consider_relocation, 0); /* Text */
+ each_full_file(consider_relocation, 1); /* Data */
/*
* Compute total size of sections.
@@ -1419,6 +1475,23 @@ printf("bssstart = %#x, bsssize = %#x\n",
bss_size = 0;
data_size += data_pad;
+
+ /*
+ * Calculate total number of symbols that will go into
+ * the output symbol table (barring DISCARD_* settings).
+ */
+ global_sym_count = defined_global_sym_count +
+ undefined_global_sym_count;
+
+ if (dynamic_symbol->referenced)
+ global_sym_count++;
+
+ if (got_symbol->referenced)
+ global_sym_count++;
+
+ if (relocatable_output)
+ /* For each alias we write out two struct nlists */
+ global_sym_count += global_alias_count + size_sym_count;
}
void
@@ -1690,8 +1763,10 @@ consider_relocation (entry, dataseg)
if (relocatable_output) {
lsp = &entry->symbols[reloc->r_symbolnum];
- if (RELOC_BASEREL_P(reloc) && !RELOC_EXTERN_P(reloc)) {
- lsp->rename = 1;
+ if (RELOC_BASEREL_P(reloc)) {
+ pic_code_seen = 1;
+ if (!RELOC_EXTERN_P(reloc))
+ lsp->rename = 1;
}
continue;
}
@@ -1728,12 +1803,12 @@ consider_relocation (entry, dataseg)
sp = lsp->symbol;
if (sp->alias)
sp = sp->alias;
- alloc_rrs_jmpslot(sp);
+ alloc_rrs_jmpslot(entry, sp);
} else if (RELOC_BASEREL_P(reloc)) {
lsp = &entry->symbols[reloc->r_symbolnum];
- alloc_rrs_gotslot(reloc, lsp);
+ alloc_rrs_gotslot(entry, reloc, lsp);
} else if (RELOC_EXTERN_P(reloc)) {
@@ -1778,7 +1853,7 @@ consider_relocation (entry, dataseg)
*/
if (building_shared_object) {
- alloc_rrs_reloc(sp);
+ alloc_rrs_reloc(entry, sp);
continue;
}
@@ -1795,20 +1870,27 @@ consider_relocation (entry, dataseg)
sp->so_defined == N_TEXT + N_EXT) {
/* Call to shared library procedure */
- alloc_rrs_jmpslot(sp);
+ alloc_rrs_jmpslot(entry, sp);
+#define EXPERIMENTAL
+#ifdef EXPERIMENTAL
if (!RELOC_PCREL_P(reloc)) {
+#ifdef DEBUG
+printf("%s: FUNC flag set\n", sp->name);
+#endif
sp->aux = RRS_FUNC;
}
+#endif
+
} else if (sp->size &&
(sp->so_defined == N_DATA + N_EXT ||
sp->so_defined == N_TEXT + N_EXT)) {
/* Reference to shared library data */
- alloc_rrs_cpy_reloc(sp);
+ alloc_rrs_cpy_reloc(entry, sp);
sp->defined = N_SIZE;
} else if (!sp->defined && sp->max_common_size == 0)
- alloc_rrs_reloc(sp);
+ alloc_rrs_reloc(entry, sp);
} else {
/*
@@ -1817,7 +1899,7 @@ consider_relocation (entry, dataseg)
* address dependent.
*/
if (building_shared_object) {
- alloc_rrs_segment_reloc(reloc);
+ alloc_rrs_segment_reloc(entry, reloc);
}
}
}
@@ -1849,13 +1931,15 @@ consider_file_section_lengths (entry)
/*
* Determine where the sections of ENTRY go into the output file,
* whose total section sizes are already known.
- * Also relocate the addresses of the file's local and debugger symbols.
+ * Also relocate the addresses of the file's local and debugger symbols
+ * and determine which of the local symbols will make it into the
+ * output symbol table.
*/
void
relocate_file_addresses (entry)
register struct file_entry *entry;
{
- register struct localsymbol *lsp, *lspend;
+ register struct localsymbol *lsp, *lspend;
entry->text_start_address += text_start;
/*
@@ -1874,13 +1958,14 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
for (lsp = entry->symbols; lsp < lspend; lsp++) {
register struct nlist *p = &lsp->nzlist.nlist;
+ register int type = p->n_type;
+
/*
* If this belongs to a section, update it
* by the section's start address
*/
- register int type = p->n_type & N_TYPE;
- switch (type) {
+ switch (type & N_TYPE) {
case N_TEXT:
case N_SETT:
p->n_value += entry->text_start_address;
@@ -1904,7 +1989,54 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
- entry->header.a_text - entry->header.a_data;
break;
}
+
+ /*
+ * See if this symbol should be in the output symbol table.
+ */
+
+ if (type == N_WARNING)
+ continue;
+
+ if (SET_ELEMENT_P (type)) {
+ /*
+ * This occurs even if global. These types of
+ * symbols are never written globally, though
+ * they are stored globally.
+ */
+ lsp->write = relocatable_output;
+
+ } else if (!(type & (N_STAB | N_EXT))) {
+
+ /*
+ * Ordinary local symbol
+ */
+ lsp->write = (lsp->rename || (
+ discard_locals != DISCARD_ALL &&
+ !(discard_locals == DISCARD_L &&
+ lsp->is_L_symbol)));
+ if (lsp->write)
+ local_sym_count++;
+
+ } else if (!(type & N_EXT)) {
+
+ /*
+ * Debugger symbol
+ */
+ lsp->write = (strip_symbols == STRIP_NONE);
+ if (lsp->write)
+ debugger_sym_count++;
+
+ }
}
+
+ /*
+ * Count one for the local symbol that we generate,
+ * whose name is the file's name (usually) and whose address
+ * is the start of the file's text.
+ */
+ if (discard_locals != DISCARD_ALL)
+ local_sym_count++;
+
}
/* Write the output file */
@@ -1973,33 +2105,19 @@ write_header ()
if (strip_symbols == STRIP_ALL)
nsyms = 0;
- else {
- nsyms = (defined_global_sym_count + undefined_global_sym_count);
- if (discard_locals == DISCARD_L)
- nsyms += non_L_local_sym_count;
- else if (discard_locals == DISCARD_NONE)
- nsyms += local_sym_count;
-
- if (relocatable_output)
- /* For each alias we write out two struct nlists */
- nsyms += set_symbol_count + global_alias_count;
-
- if (dynamic_symbol->referenced)
- nsyms++, special_sym_count++;
-
- if (got_symbol->referenced)
- nsyms++, special_sym_count++;
- }
+ else
+ nsyms = global_sym_count + local_sym_count + debugger_sym_count;
- if (strip_symbols == STRIP_NONE)
- nsyms += debugger_sym_count;
+ if (relocatable_output)
+ nsyms += set_symbol_count;
-#ifdef DEBUG
-printf("defined globals: %d, undefined globals %d, locals: %d (non_L: %d), \
-debug symbols: %d, special: %d, set_symbols %d, aliases %d --> nsyms %d\n",
+printf("global symbols %d (defined %d, undefined %d), locals: %d, \
+debug symbols: %d, set_symbols %d, aliases %d --> nsyms %d\n",
+ global_sym_count,
defined_global_sym_count, undefined_global_sym_count,
- local_sym_count, non_L_local_sym_count, debugger_sym_count,
- special_sym_count, set_symbol_count, global_alias_count, nsyms);
+ local_sym_count, debugger_sym_count,
+ set_symbol_count, global_alias_count, nsyms);
+#ifdef DEBUG
#endif
outheader.a_syms = nsyms * sizeof (struct nlist);
@@ -2213,7 +2331,7 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
data_relocation - text_relocation;
} else
relocation = addend +
- claim_rrs_jmpslot(r, sp, addend);
+ claim_rrs_jmpslot(entry, r, sp, addend);
} else if (RELOC_BASEREL_P(r)) {
@@ -2230,7 +2348,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
relocation = claim_rrs_internal_gotslot(entry,
r, lsp, addend);
else
- relocation = claim_rrs_gotslot(r, lsp, addend);
+ relocation = claim_rrs_gotslot(entry,
+ r, lsp, addend);
} else if (RELOC_EXTERN_P(r)) {
@@ -2246,7 +2365,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
sp = sp->alias;
if (relocatable_output) {
- relocation = addend + sp->value;
+ relocation = addend;
+ /*
+ * In PIC code, we keep the reference to the
+ * external symbol, even if defined now.
+ */
+ if (!pic_code_seen)
+ relocation += sp->value;
} else if (sp->defined) {
if (sp == got_symbol) {
/* Handle _GOT_ refs */
@@ -2262,7 +2387,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
entry->data_start_address:
entry->text_start_address;
relocation = addend;
- if (claim_rrs_reloc(r, sp, &relocation))
+ if (claim_rrs_reloc(entry, r,
+ sp, &relocation))
continue;
} else if (sp->defined == N_SIZE) {
/*
@@ -2275,7 +2401,7 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
relocation = addend + sp->value;
r->r_address = sp->value;
- claim_rrs_cpy_reloc(r, sp);
+ claim_rrs_cpy_reloc(entry, r, sp);
} else
/* Plain old relocation */
relocation = addend + sp->value;
@@ -2305,7 +2431,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
goto undefined;
relocation = addend +
- claim_rrs_jmpslot(r, sp, addend);
+ claim_rrs_jmpslot(entry, r,
+ sp, addend);
break;
case N_DATA+N_EXT:
@@ -2316,7 +2443,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
entry->data_start_address:
entry->text_start_address;
relocation = addend;
- if (claim_rrs_reloc(r, sp, &relocation))
+ if (claim_rrs_reloc(entry, r,
+ sp, &relocation))
continue;
break;
@@ -2382,7 +2510,7 @@ printf("%s: BSS found in so_defined\n", sp->name);
r->r_address += dataseg?
entry->data_start_address:
entry->text_start_address;
- claim_rrs_segment_reloc(r);
+ claim_rrs_segment_reloc(entry, r);
}
}
@@ -2421,13 +2549,14 @@ write_rel ()
FOR_EACH_SYMBOL(i, sp) {
if (sp != dynamic_symbol && sp->referenced) {
sp->symbolnum = count++;
+ if (sp->size)
+ count++;
+ if (sp->alias)
+ count++;
}
} END_EACH_SYMBOL;
- /* Correct, because if (relocatable_output), we will also be writing
- whatever indirect blocks we have. */
- if (count != defined_global_sym_count + undefined_global_sym_count
- + special_sym_count)
+ if (count != global_sym_count)
fatal ("internal error: write_rel: count = %d", count);
each_full_file (assign_symbolnums, &count);
@@ -2457,8 +2586,13 @@ assign_symbolnums(entry, countp)
lspend = entry->symbols + entry->nsymbols;
+ if (discard_locals != DISCARD_ALL)
+ /* Count the N_FN symbol for this entry */
+ n++;
+
for (lsp = entry->symbols; lsp < lspend; lsp++) {
- lsp->symbolnum = n++;
+ if (lsp->write)
+ lsp->symbolnum = n++;
}
*countp = n;
}
@@ -2474,21 +2608,29 @@ coptxtrel(entry)
end = r + entry->ntextrel;
for (; r < end; r++) {
- register int symindex;
- symbol *sp;
+ register int symindex;
+ struct localsymbol *lsp;
+ symbol *sp;
RELOC_ADDRESS(r) += reloc;
- if (!RELOC_EXTERN_P(r))
- continue;
-
symindex = RELOC_SYMBOL(r);
- sp = entry->symbols[symindex].symbol;
+ lsp = &entry->symbols[symindex];
+
+ if (!RELOC_EXTERN_P(r)) {
+ if (!pic_code_seen)
+ continue;
+ if (RELOC_BASEREL_P(r))
+ RELOC_SYMBOL(r) = lsp->symbolnum;
+ continue;
+ }
if (symindex >= entry->nsymbols)
fatal_with_file(
"relocation symbolnum out of range in ", entry);
+ sp = lsp->symbol;
+
#ifdef N_INDR
/* Resolve indirection. */
if ((sp->defined & ~N_EXT) == N_INDR) {
@@ -2504,8 +2646,11 @@ coptxtrel(entry)
*/
if (sp->defined) {
- RELOC_EXTERN_P(r) = 0;
- RELOC_SYMBOL(r) = (sp->defined & N_TYPE);
+ if (!pic_code_seen) {
+ RELOC_EXTERN_P(r) = 0;
+ RELOC_SYMBOL(r) = (sp->defined & N_TYPE);
+ } else
+ RELOC_SYMBOL(r) = sp->symbolnum;
#ifdef RELOC_ADD_EXTRA
/*
* If we aren't going to be adding in the
@@ -2550,8 +2695,13 @@ copdatrel(entry)
RELOC_ADDRESS(r) += reloc;
- if (!RELOC_EXTERN_P(r))
+ if (!RELOC_EXTERN_P(r)) {
+ if (RELOC_BASEREL_P(r))
+ fatal_with_file(
+ "Unsupported relocation type in ",
+ entry);
continue;
+ }
symindex = RELOC_SYMBOL(r);
sp = entry->symbols[symindex].symbol;
@@ -2571,10 +2721,10 @@ copdatrel(entry)
symtype = sp->defined & N_TYPE;
- if (force_common_definition ||
+ if (!pic_code_seen && (force_common_definition ||
symtype == N_DATA ||
symtype == N_TEXT ||
- symtype == N_ABS) {
+ symtype == N_ABS)) {
RELOC_EXTERN_P(r) = 0;
RELOC_SYMBOL(r) = symtype;
} else
@@ -2589,8 +2739,8 @@ copdatrel(entry)
sizeof(struct relocation_info), outdesc);
}
-void write_file_syms ();
-void write_string_table ();
+void write_file_syms __P((struct file_entry *, int *));
+void write_string_table __P((void));
/* Offsets and current lengths of symbol and string tables in output file. */
@@ -2672,10 +2822,6 @@ void
write_syms()
{
/* Number of symbols written so far. */
- int non_local_syms = defined_global_sym_count
- + undefined_global_sym_count
- + global_alias_count
- + special_sym_count;
int syms_written = 0;
struct nlist nl;
@@ -2683,8 +2829,8 @@ write_syms()
* Buffer big enough for all the global symbols. One extra struct
* for each indirect symbol to hold the extra reference following.
*/
- struct nlist *buf
- = (struct nlist *)alloca(non_local_syms * sizeof(struct nlist));
+ struct nlist *buf = (struct nlist *)
+ alloca(global_sym_count * sizeof(struct nlist));
/* Pointer for storing into BUF. */
register struct nlist *bufp = buf;
@@ -2707,8 +2853,8 @@ write_syms()
* extra space for the references following indirect outputs.
*/
- strtab_vector = (char **) alloca((non_local_syms) * sizeof(char *));
- strtab_lens = (int *) alloca((non_local_syms) * sizeof(int));
+ strtab_vector = (char **) alloca((global_sym_count) * sizeof(char *));
+ strtab_lens = (int *) alloca((global_sym_count) * sizeof(int));
strtab_index = 0;
/*
@@ -2817,10 +2963,10 @@ write_syms()
/* Output to the buffer and count it. */
- if (syms_written >= non_local_syms)
+ if (syms_written >= global_sym_count)
fatal(
"internal error: number of symbols exceeds allocated %d",
- non_local_syms);
+ global_sym_count);
*bufp++ = nl;
syms_written++;
@@ -2831,6 +2977,18 @@ write_syms()
nl.n_un.n_strx =
assign_string_table_index(sp->alias->name);
nl.n_value = 0;
+ nl.n_other = 0;
+ nl.n_desc = 0;
+ *bufp++ = nl;
+ syms_written++;
+ }
+
+ if (relocatable_output && sp->size) {
+ nl.n_type = N_SIZE + N_EXT;
+ nl.n_un.n_strx = assign_string_table_index(sp->name);
+ nl.n_value = sp->size;
+ nl.n_other = 0;
+ nl.n_desc = 0;
*bufp++ = nl;
syms_written++;
}
@@ -2840,10 +2998,10 @@ printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
#endif
} END_EACH_SYMBOL;
- if (syms_written != strtab_index || strtab_index != non_local_syms)
+ if (syms_written != strtab_index || strtab_index != global_sym_count)
fatal("internal error:\
wrong number (%d) of global symbols written into output file, should be %d",
- syms_written, non_local_syms);
+ syms_written, global_sym_count);
/* Output the buffer full of `struct nlist's. */
@@ -2927,7 +3085,9 @@ write_file_syms(entry, syms_written_addr)
nl.n_other = 0;
*bufp++ = nl;
(*syms_written_addr)++;
+#if 0
entry->local_syms_offset = *syms_written_addr * sizeof(struct nlist);
+#endif
}
/* Read the file's string table. */
@@ -2942,6 +3102,9 @@ write_file_syms(entry, syms_written_addr)
register int write = 0;
char *name;
+ if (! lsp->write)
+ continue;
+
if (p->n_un.n_strx == 0)
name = NULL;
else if (lsp->rename == 0)
@@ -2952,49 +3115,20 @@ write_file_syms(entry, syms_written_addr)
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 this symbol has a name, allocate space for it
+ * in the output string table.
*/
- if (SET_ELEMENT_P (type))
- /*
- * This occurs even if global. These types of
- * symbols are never written globally, though
- * they are stored globally.
- */
- write = relocatable_output;
- else if (!(type & (N_STAB | N_EXT)) && name != NULL)
- /* ordinary local symbol */
- 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)/* &&
- !(discard_locals == DISCARD_L &&
- name[0] == LPREFIX)*/;
- else if (name == NULL)
- error("Amnesiac");
-
- if (write) {
- /*
- * If this symbol has a name, allocate space for it
- * in the output string table.
- */
- if (name)
- p->n_un.n_strx = assign_string_table_index(name);
+ if (name)
+ p->n_un.n_strx = assign_string_table_index(name);
- /* Output this symbol to the buffer and count it. */
+ /* Output this symbol to the buffer and count it. */
- *bufp++ = *p;
- (*syms_written_addr)++;
- }
+ *bufp++ = *p;
+ (*syms_written_addr)++;
}
/* All the symbols are now in BUF; write them. */
diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h
index f17ff6b..3336b80 100644
--- a/gnu/usr.bin/ld/ld.h
+++ b/gnu/usr.bin/ld/ld.h
@@ -1,4 +1,4 @@
-/* $Id: ld.h,v 1.3 1993/11/18 20:52:34 jkh Exp $ */
+/* $Id: ld.h,v 1.5 1993/11/10 21:53:42 pk Exp $ */
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
@@ -470,6 +470,12 @@ symbol *symtab[TABSIZE];
/* Number of symbols in symbol hash table. */
int num_hash_tab_syms;
+/* Count number of nlist entries for global symbols */
+int global_sym_count;
+
+/* Count number of N_SIZE nlist entries for output (relocatable_output only) */
+int size_sym_count;
+
/* Count the number of nlist entries that are for local symbols.
This count and the three following counts
are incremented as as symbols are entered in the symbol table. */
@@ -583,8 +589,10 @@ struct file_entry {
/* The file's a.out header. */
struct exec header;
+#if 0
/* Offset in file of GDB symbol segment, or 0 if there is none. */
int symseg_offset;
+#endif
/* Describe data from the file loaded into core */
@@ -600,6 +608,8 @@ struct file_entry {
struct localsymbol *next;
long gotslot_offset;
char gotslot_claimed;
+ char write;
+ char is_L_symbol;
char rename;
int symbolnum;
} *symbols;
@@ -640,11 +650,13 @@ struct file_entry {
/* Start of this file's bss seg in the output file core image. */
int bss_start_address;
+#if 0
/*
* Offset in bytes in the output file symbol table of the first local
* symbol for this file. Set by `write_file_symbols'.
*/
int local_syms_offset;
+#endif
/* For library members only */
@@ -666,6 +678,11 @@ struct file_entry {
/* For library member, points to next entry for next member. */
struct file_entry *chain;
+#ifdef SUN_COMPAT
+ /* For shared libraries which have a .sa companion */
+ struct file_entry *silly_archive;
+#endif
+
/* 1 if file is a library. */
char library_flag;
@@ -710,7 +727,8 @@ int number_of_files;
#define FORCEARCHIVE 4 /* Force inclusion of all members
of archives */
#define SHAREABLE 8 /* Build a shared object */
-int link_mode;
+#define SILLYARCHIVE 16 /* Process .sa companions, if any */
+int link_mode;
/*
* Runtime Relocation Section (RRS).
@@ -857,18 +875,25 @@ void read_shared_object __P((int, struct file_entry *));
int findlib __P((struct file_entry *));
/* In shlib.c: */
-char *findshlib __P((char *, int *, int *));
+char *findshlib __P((char *, int *, int *, int));
void add_search_dir __P((char *));
void std_search_dirs __P((char *));
/* In rrs.c: */
void init_rrs __P((void));
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 *));
-void alloc_rrs_gotslot __P((struct relocation_info *, localsymbol_t *));
-void alloc_rrs_copy_reloc __P((symbol *));
+void alloc_rrs_reloc __P((struct file_entry *, symbol *));
+void alloc_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
+void alloc_rrs_jmpslot __P((struct file_entry *, symbol *));
+void alloc_rrs_gotslot __P((struct file_entry *, struct relocation_info *, localsymbol_t *));
+void alloc_rrs_cpy_reloc __P((struct file_entry *, symbol *));
+
+int claim_rrs_reloc __P((struct file_entry *, struct relocation_info *, symbol *, long *));
+long claim_rrs_jmpslot __P((struct file_entry *, struct relocation_info *, symbol *, long));
+long claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
+long claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
+void claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
+void claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
/* In <md>.c */
void md_init_header __P((struct exec *, int, int));
diff --git a/gnu/usr.bin/ld/ldconfig/ldconfig.c b/gnu/usr.bin/ld/ldconfig/ldconfig.c
index b4b9981..899539d 100644
--- a/gnu/usr.bin/ld/ldconfig/ldconfig.c
+++ b/gnu/usr.bin/ld/ldconfig/ldconfig.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: ldconfig.c,v 1.1 1993/10/23 00:17:03 pk Exp $
+ * $Id: ldconfig.c,v 1.2 1993/11/09 04:19:22 paul Exp $
*/
#include <sys/param.h>
@@ -58,7 +58,6 @@ static int verbose;
static int nostd;
static int justread;
-#define MAXDEWEY 8
struct shlib_list {
/* Internal list of shared libraries found */
char *name;
@@ -401,9 +400,13 @@ listhints()
return -1;
}
- printf("\t-l%s.%d.%d => %s\n",
+ printf("\t%d:-l%s.%d.%d => %s (%d -> %d)\n",
+ i,
strtab + bp->hi_namex, bp->hi_major, bp->hi_minor,
- strtab + bp->hi_pathx);
+ strtab + bp->hi_pathx,
+ hinthash(strtab+bp->hi_namex, bp->hi_major, bp->hi_minor)
+ % hdr->hh_nbucket,
+ bp->hi_next);
}
return 0;
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index 8cbb8b4..674f131 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.2 1993/11/09 04:19:00 paul Exp $ - library routines
+ * $Id: lib.c,v 1.3 1993/11/22 19:04:43 jkh Exp $ - library routines
*/
#include <sys/param.h>
@@ -573,6 +573,8 @@ read_shared_object (desc, entry)
entry->symbols[i].next = NULL;
entry->symbols[i].gotslot_offset = -1;
entry->symbols[i].gotslot_claimed = 0;
+ entry->symbols[i].write = 0;
+ entry->symbols[i].is_L_symbol = 0;
entry->symbols[i].rename = 0;
}
@@ -588,9 +590,109 @@ read_shared_object (desc, entry)
enter_file_symbols (entry);
entry->strings = 0;
- /* TODO: examine needed shared objects */
+ /*
+ * Load any subsidiary shared objects.
+ */
if (dyn2.ld_need) {
+ struct link_object lobj;
+ off_t offset;
+ struct file_entry *subentry, *prev = NULL;
+
+ subentry = (struct file_entry *)
+ xmalloc(sizeof(struct file_entry));
+ bzero(subentry, sizeof(struct file_entry));
+
+ subentry->superfile = entry;
+
+ offset = (off_t)dyn2.ld_need;
+ while (1) {
+ char *libname, name[MAXPATHLEN]; /*XXX*/
+
+ lseek(desc, offset, L_SET);
+ if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+ fatal_with_file(
+ "premature eof while reading link objects ",
+ entry);
+ }
+ md_swapin_link_object(&lobj, 1);
+ (void)lseek(desc, (off_t)lobj.lo_name, L_SET);
+ (void)read(desc, name, sizeof(name));
+ if (lobj.lo_library) {
+ int lo_major = lobj.lo_major;
+ int lo_minor = lobj.lo_minor;
+
+ libname = findshlib(name,
+ &lo_major, &lo_minor, 0);
+ if (libname == NULL)
+ fatal("no shared -l%s.%d.%d available",
+ name, lobj.lo_major, lobj.lo_minor);
+ subentry->filename = libname;
+ subentry->local_sym_name = concat("-l", name, "");
+ } else {
+ subentry->filename = strdup(name);
+ subentry->local_sym_name = strdup(name);
+ }
+ read_file_symbols(subentry);
+
+ if (prev)
+ prev->chain = subentry;
+ else
+ entry->subfiles = subentry;
+ prev = subentry;
+ file_open(entry);
+ if ((offset = (off_t)lobj.lo_next) == 0)
+ break;
+ }
}
+#ifdef SUN_COMPAT
+ if (link_mode & SILLYARCHIVE) {
+ char *cp, *sa_name;
+ char armag[SARMAG];
+ int fd;
+ struct file_entry *subentry;
+
+ sa_name = strdup(entry->filename);
+ if (sa_name == NULL)
+ goto out;
+ cp = sa_name + strlen(sa_name) - 1;
+ while (cp > sa_name) {
+ if (!isdigit(*cp) && *cp != '.')
+ break;
+ --cp;
+ }
+ if (cp <= sa_name || *cp != 'o') {
+ /* Not in `libxxx.so.n.m' form */
+ free(sa_name);
+ goto out;
+ }
+
+ *cp = 'a';
+ if ((fd = open(sa_name, O_RDONLY, 0)) < 0)
+ goto out;
+
+ /* Read archive magic */
+ bzero(armag, SARMAG);
+ (void)read(fd, armag, SARMAG);
+ (void)close(fd);
+ if (strncmp(armag, ARMAG, SARMAG) != 0) {
+ error("%s: malformed silly archive",
+ get_file_name(entry));
+ goto out;
+ }
+
+ subentry = (struct file_entry *)
+ xmalloc(sizeof(struct file_entry));
+ bzero(subentry, sizeof(struct file_entry));
+
+ entry->silly_archive = subentry;
+ subentry->superfile = entry;
+ subentry->filename = sa_name;
+ subentry->local_sym_name = sa_name;
+ subentry->library_flag = 1;
+ search_library(file_open(subentry), subentry);
+out:
+ }
+#endif
}
#undef major
@@ -609,7 +711,7 @@ struct file_entry *p;
if (p->search_dynamic_flag == 0)
goto dot_a;
- fname = findshlib(p->filename, &major, &minor);
+ fname = findshlib(p->filename, &major, &minor, 1);
if (fname && (desc = open (fname, O_RDONLY, 0)) > 0) {
p->filename = fname;
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index acefa39..6a3bf08 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.3 1993/11/17 01:33:24 ache Exp $
+ * $Id: rrs.c,v 1.4 1993/11/22 19:04:44 jkh Exp $
*/
#include <sys/param.h>
@@ -180,27 +180,31 @@ struct file_entry *entry;
}
void
-alloc_rrs_reloc(sp)
+alloc_rrs_reloc(entry, sp)
+struct file_entry *entry;
symbol *sp;
{
#ifdef DEBUG
-printf("alloc_rrs_reloc: %s\n", sp->name);
+printf("alloc_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
#endif
reserved_rrs_relocs++;
}
void
-alloc_rrs_segment_reloc(r)
+alloc_rrs_segment_reloc(entry, r)
+struct file_entry *entry;
struct relocation_info *r;
{
#ifdef DEBUG
-printf("alloc_rrs_segment_reloc at %#x\n", r->r_address);
+printf("alloc_rrs_segment_reloc at %#x in %s\n",
+ r->r_address, get_file_name(entry));
#endif
reserved_rrs_relocs++;
}
void
-alloc_rrs_jmpslot(sp)
+alloc_rrs_jmpslot(entry, sp)
+struct file_entry *entry;
symbol *sp;
{
if (sp->jmpslot_offset == -1) {
@@ -214,7 +218,8 @@ symbol *sp;
}
void
-alloc_rrs_gotslot(r, lsp)
+alloc_rrs_gotslot(entry, r, lsp)
+struct file_entry *entry;
struct relocation_info *r;
struct localsymbol *lsp;
{
@@ -222,8 +227,11 @@ struct localsymbol *lsp;
if (!RELOC_EXTERN_P(r)) {
- if (sp != NULL)
- fatal("internal error: lsp->symbol not NULL");
+ if (sp != NULL) {
+ error("%s: relocation for internal symbol expected at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
+ return;
+ }
if (!RELOC_STATICS_THROUGH_GOT_P(r))
/* No need for a GOT slot */
@@ -242,11 +250,20 @@ struct localsymbol *lsp;
reserved_rrs_relocs++;
}
- } else if (sp->gotslot_offset == -1) {
+ } else {
+
+ if (sp == NULL) {
+ error("%s: relocation must refer to global symbol at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
+ return;
+ }
if (sp->alias)
sp = sp->alias;
+ if (sp->gotslot_offset != -1)
+ return;
+
/*
* External symbols always get a relocation entry
*/
@@ -259,13 +276,14 @@ struct localsymbol *lsp;
}
void
-alloc_rrs_cpy_reloc(sp)
+alloc_rrs_cpy_reloc(entry, sp)
+struct file_entry *entry;
symbol *sp;
{
if (sp->cpyreloc_reserved)
return;
#ifdef DEBUG
-printf("alloc_rrs_copy: %s\n", sp->name);
+printf("alloc_rrs_copy: %s in %s\n", sp->name, get_file_name(entry));
#endif
sp->cpyreloc_reserved = 1;
reserved_rrs_relocs++;
@@ -292,7 +310,8 @@ rrs_next_reloc()
* written to a.out.
*/
int
-claim_rrs_reloc(rp, sp, relocation)
+claim_rrs_reloc(entry, rp, sp, relocation)
+struct file_entry *entry;
struct relocation_info *rp;
symbol *sp;
long *relocation;
@@ -300,18 +319,19 @@ long *relocation;
struct relocation_info *r = rrs_next_reloc();
if (rp->r_address < text_start + text_size)
- error("RRS text relocation at %#x (symbol %s)",
- rp->r_address, sp->name);
+ error("%s: RRS text relocation at %#x for \"%s\"",
+ get_file_name(entry), rp->r_address, sp->name);
#ifdef DEBUG
-printf("claim_rrs_reloc: %s\n", sp->name);
+printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
#endif
r->r_address = rp->r_address;
r->r_symbolnum = sp->rrs_symbolnum;
if (link_mode & SYMBOLIC) {
if (!sp->defined)
- error("Cannot reduce symbol %s", sp->name);
+ error("Cannot reduce symbol \"%s\" in %s",
+ sp->name, get_file_name(entry));
RELOC_EXTERN_P(r) = 0;
*relocation += sp->value;
(void) md_make_reloc(rp, r, RELTYPE_RELATIVE);
@@ -326,7 +346,8 @@ printf("claim_rrs_reloc: %s\n", sp->name);
* Claim a jmpslot. Setup RRS relocation if claimed for the first time.
*/
long
-claim_rrs_jmpslot(rp, sp, addend)
+claim_rrs_jmpslot(entry, rp, sp, addend)
+struct file_entry *entry;
struct relocation_info *rp;
symbol *sp;
long addend;
@@ -337,18 +358,21 @@ long addend;
return rrs_dyn2.ld_plt + sp->jmpslot_offset;
#ifdef DEBUG
-printf("claim_rrs_jmpslot: %s(%d) -> offset %x (textreloc %#x)\n",
+printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
+ get_file_name(entry),
sp->name, sp->rrs_symbolnum, sp->jmpslot_offset, text_relocation);
#endif
if (sp->jmpslot_offset == -1)
fatal(
- "internal error: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
+ "internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
+ get_file_name(entry),
sp->name);
if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
if (!sp->defined)
- error("Cannot reduce symbol %s", sp->name);
+ error("Cannot reduce symbol \"%s\" in %s",
+ sp->name, get_file_name(entry));
md_fix_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
rrs_dyn2.ld_plt + sp->jmpslot_offset,
@@ -393,7 +417,8 @@ printf("claim_rrs_jmpslot: %s(%d) -> offset %x (textreloc %#x)\n",
* Return offset into the GOT allocated to this symbol.
*/
long
-claim_rrs_gotslot(rp, lsp, addend)
+claim_rrs_gotslot(entry, rp, lsp, addend)
+struct file_entry *entry;
struct relocation_info *rp;
struct localsymbol *lsp;
long addend;
@@ -402,6 +427,10 @@ long addend;
symbol *sp = lsp->symbol;
int reloc_type = 0;
+ if (sp == NULL) {
+ return 0;
+ }
+
if (sp->alias)
sp = sp->alias;
@@ -411,8 +440,8 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
#endif
if (sp->gotslot_offset == -1)
fatal(
- "internal error: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
- sp->name);
+ "internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
+ get_file_name(entry), sp->name);
if (sp->gotslot_claimed)
/* This symbol already passed here before. */
@@ -435,7 +464,8 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
* RRS_PARTIAL: we don't link against shared objects,
* so again all symbols must be known.
*/
- error("Cannot reduce symbol %s", sp->name);
+ error("Cannot reduce symbol \"%s\" in %s",
+ sp->name, get_file_name(entry));
} else {
@@ -453,7 +483,8 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
* NOTE: RRS_PARTIAL implies !SHAREABLE.
*/
if (!sp->defined)
- error("Cannot reduce symbol %s", sp->name);
+ error("Cannot reduce symbol \"%s\" in %s",
+ sp->name, get_file_name(entry));
return sp->gotslot_offset;
}
@@ -496,13 +527,14 @@ long addend;
return addend - rrs_dyn2.ld_got;
#ifdef DEBUG
-printf("claim_rrsinternal__gotslot: slot offset %#x, addend = %#x\n",
- lsp->gotslot_offset, addend);
+printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
+ get_file_name(entry), lsp->gotslot_offset, addend);
#endif
if (lsp->gotslot_offset == -1)
fatal(
- "internal error: claim_rrs_internal_gotslot: slot_offset == -1\n");
+ "internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
+ get_file_name(entry), RELOC_ADDRESS(rp));
if (lsp->gotslot_claimed)
/* Already done */
@@ -525,7 +557,8 @@ printf("claim_rrsinternal__gotslot: slot offset %#x, addend = %#x\n",
}
void
-claim_rrs_cpy_reloc(rp, sp)
+claim_rrs_cpy_reloc(entry, rp, sp)
+struct file_entry *entry;
struct relocation_info *rp;
symbol *sp;
{
@@ -535,11 +568,12 @@ symbol *sp;
return;
if (!sp->cpyreloc_reserved)
- fatal("internal error: claim_cpy_reloc: %s: no reservation\n",
- sp->name);
+ fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
+ get_file_name(entry), sp->name);
#ifdef DEBUG
-printf("claim_rrs_copy: %s -> %x\n", sp->name, sp->so_defined);
+printf("claim_rrs_copy: %s: %s -> %x\n",
+ get_file_name(entry), sp->name, sp->so_defined);
#endif
r = rrs_next_reloc();
@@ -551,13 +585,15 @@ printf("claim_rrs_copy: %s -> %x\n", sp->name, sp->so_defined);
}
void
-claim_rrs_segment_reloc(rp)
+claim_rrs_segment_reloc(entry, rp)
+struct file_entry *entry;
struct relocation_info *rp;
{
struct relocation_info *r = rrs_next_reloc();
#ifdef DEBUG
-printf("claim_rrs_segment_reloc: %x\n", rp->r_address);
+printf("claim_rrs_segment_reloc: %s at %#x\n",
+ get_file_name(entry), rp->r_address);
#endif
r->r_address = rp->r_address;
RELOC_TYPE(r) = RELOC_TYPE(rp);
@@ -1023,8 +1059,9 @@ write_rrs_text()
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
- if (shp == NULL)
- fatal("internal error: shp == NULL");
+ if (i >= number_of_shobjs)
+ fatal("internal error: # of link objects exceeds %d",
+ number_of_shobjs);
lo[i].lo_name = pos;
lo[i].lo_major = shp->entry->lib_major;
@@ -1039,10 +1076,11 @@ write_rrs_text()
pos += 1 + strlen(name);
lo[i].lo_next = (i == number_of_shobjs - 1) ? 0 :
(rrs_dyn2.ld_need + (i+1)*sizeof(struct link_object));
-
}
- if (shp != NULL)
- fatal("internal error: shp != NULL");
+
+ if (i < number_of_shobjs)
+ fatal("internal error: # of link objects less then expected %d",
+ number_of_shobjs);
md_swapout_link_object(lo, number_of_shobjs);
mywrite(lo, number_of_shobjs, sizeof(struct link_object), outdesc);
diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c
index 0cccd23..2f9e361 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.3 1993/11/09 04:44:30 paul Exp $
+ * $Id: rtld.c,v 1.4 1993/11/22 19:05:27 jkh Exp $
*/
#include <machine/vmparam.h>
@@ -240,6 +240,9 @@ struct link_dynamic *dp;
if (link_map_head)
ldp->ldd_sym_loaded = 1;
}
+
+ /* Close our file descriptor */
+ (void)close(crtp->crt_ldfd);
}
@@ -1055,6 +1058,63 @@ xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
if (mmap(curbrk, incr,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_COPY, fd, 0) == (caddr_t)-1) {
+ xprintf("Cannot map anonymous memory");
+ _exit(1);
+ }
+
+#ifdef NEED_DEV_ZERO
+ close(fd);
+#endif
+
+ oldbrk = curbrk;
+#if TRY_THIS_FOR_A_CHANGE
+ curbrk -= incr;
+#else
+ curbrk += incr;
+#endif
+
+ return oldbrk;
+}
+#else
+
+caddr_t
+sbrk(incr)
+int incr;
+{
+ int fd = -1;
+ caddr_t oldbrk;
+
+xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
+#if DEBUG
+xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
+#endif
+ if (curbrk == 0 && (curbrk = mmap(0, PAGSIZ,
+ PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ xprintf("Cannot map anonymous memory");
+ _exit(1);
+ }
+
+ /* There's valid memory from `curbrk' to next page boundary */
+ if ((long)curbrk + incr <= (((long)curbrk + PAGSIZ) & ~(PAGSIZ - 1))) {
+ oldbrk = curbrk;
+ curbrk += incr;
+ return oldbrk;
+ }
+ /*
+ * If asking for than currently left in this chunk,
+ * go somewhere completely different.
+ */
+
+#ifdef NEED_DEV_ZERO
+ fd = open("/dev/zero", O_RDWR, 0);
+ if (fd == -1)
+ perror("/dev/zero");
+#endif
+
+ if ((curbrk = mmap(0, incr,
+ PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) {
perror("Cannot map anonymous memory");
}
diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c
index 55cd8c3..64e2efc 100644
--- a/gnu/usr.bin/ld/shlib.c
+++ b/gnu/usr.bin/ld/shlib.c
@@ -1,5 +1,5 @@
/*
- * $Id: shlib.c,v 1.4 1993/11/08 13:21:23 pk Exp $
+ * $Id: shlib.c,v 1.2 1993/11/09 04:19:03 paul Exp $
*/
#include <sys/param.h>
@@ -132,9 +132,10 @@ int n1, n2;
#undef minor
char *
-findshlib(name, majorp, minorp)
+findshlib(name, majorp, minorp, do_dot_a)
char *name;
int *majorp, *minorp;
+int do_dot_a;
{
int dewey[MAXDEWEY];
int ndewey;
@@ -154,6 +155,7 @@ int *majorp, *minorp;
for (i = 0; i < n_search_dirs; i++) {
DIR *dd = opendir(search_dirs[i]);
struct dirent *dp;
+ int found_dot_a = 0;
if (dd == NULL)
continue;
@@ -161,6 +163,16 @@ int *majorp, *minorp;
while ((dp = readdir(dd)) != NULL) {
int n, j, might_take_it = 0;
+ if (do_dot_a && path == NULL &&
+ dp->d_namlen == len + 2 &&
+ strncmp(dp->d_name, lname, len) == 0 &&
+ (dp->d_name+len)[0] == '.' &&
+ (dp->d_name+len)[1] == 'a') {
+
+ path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 1;
+ }
+
if (dp->d_namlen < len + 4)
continue;
if (strncmp(dp->d_name, lname, len) != 0)
@@ -171,6 +183,12 @@ int *majorp, *minorp;
if ((n = getdewey(tmp, dp->d_name+len+4)) == 0)
continue;
+ if (major != -1 && found_dot_a) { /* XXX */
+ free(path);
+ path = NULL;
+ found_dot_a = 0;
+ }
+
if (major == -1 && minor == -1) {
might_take_it = 1;
} else if (major != -1 && minor == -1) {
@@ -192,12 +210,19 @@ int *majorp, *minorp;
if (path)
free(path);
path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 0;
bcopy(tmp, dewey, sizeof(dewey));
ndewey = n;
*majorp = dewey[0];
*minorp = dewey[1];
}
closedir(dd);
+
+ if (found_dot_a)
+ /*
+ * There's a .a archive here.
+ */
+ return path;
}
return path;
diff --git a/gnu/usr.bin/ld/sparc/md.c b/gnu/usr.bin/ld/sparc/md.c
index 0b9aef5..bfe184b 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.2 1993/11/09 04:19:33 paul Exp $
+ * $Id: md.c,v 1.3 1993/11/22 19:05:30 jkh Exp $
*/
#include <sys/param.h>
@@ -291,6 +291,6 @@ long where;
long *savep;
{
*savep = *(long *)where;
- *(long *)where = BPT;
+ *(long *)where = TRAP;
}
diff --git a/gnu/usr.bin/ld/sparc/md.h b/gnu/usr.bin/ld/sparc/md.h
index ba6a091..c3e9064 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.2 1993/11/09 04:19:35 paul Exp $
+ * $Id: md.h,v 1.3 1993/11/22 19:05:31 jkh Exp $
*/
/*
@@ -122,7 +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' */
+#define TRAP 0x91d02001 /* ta 0x1 */
/*
diff --git a/libexec/rtld-aout/i386/md.c b/libexec/rtld-aout/i386/md.c
index 2344565..40766df 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.3 1993/11/15 20:58:20 paul Exp $
+ * $Id: md.c,v 1.4 1993/11/22 19:05:23 jkh Exp $
*/
#include <sys/param.h>
@@ -242,7 +242,7 @@ long where;
long *savep;
{
*savep = *(long *)where;
- *(char *)where = BPT;
+ *(char *)where = TRAP;
}
#ifdef NEED_SWAP
diff --git a/libexec/rtld-aout/i386/md.h b/libexec/rtld-aout/i386/md.h
index ca46e81..714073b 100644
--- a/libexec/rtld-aout/i386/md.h
+++ b/libexec/rtld-aout/i386/md.h
@@ -1,5 +1,5 @@
/*
- * $Id: md.h,v 1.2 1993/11/09 04:19:17 paul Exp $ - I386 dependent definitions
+ * $Id: md.h,v 1.3 1993/11/22 19:05:24 jkh 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 BPT 0xcc /* breakpoint: INT 3 */
+#define TRAP 0xcc /* INT 3 */
/*
* Byte swap defs for cross linking
diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c
index 0cccd23..2f9e361 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.3 1993/11/09 04:44:30 paul Exp $
+ * $Id: rtld.c,v 1.4 1993/11/22 19:05:27 jkh Exp $
*/
#include <machine/vmparam.h>
@@ -240,6 +240,9 @@ struct link_dynamic *dp;
if (link_map_head)
ldp->ldd_sym_loaded = 1;
}
+
+ /* Close our file descriptor */
+ (void)close(crtp->crt_ldfd);
}
@@ -1055,6 +1058,63 @@ xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
if (mmap(curbrk, incr,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_COPY, fd, 0) == (caddr_t)-1) {
+ xprintf("Cannot map anonymous memory");
+ _exit(1);
+ }
+
+#ifdef NEED_DEV_ZERO
+ close(fd);
+#endif
+
+ oldbrk = curbrk;
+#if TRY_THIS_FOR_A_CHANGE
+ curbrk -= incr;
+#else
+ curbrk += incr;
+#endif
+
+ return oldbrk;
+}
+#else
+
+caddr_t
+sbrk(incr)
+int incr;
+{
+ int fd = -1;
+ caddr_t oldbrk;
+
+xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
+#if DEBUG
+xprintf("sbrk: incr = %#x, curbrk = %#x\n", incr, curbrk);
+#endif
+ if (curbrk == 0 && (curbrk = mmap(0, PAGSIZ,
+ PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ xprintf("Cannot map anonymous memory");
+ _exit(1);
+ }
+
+ /* There's valid memory from `curbrk' to next page boundary */
+ if ((long)curbrk + incr <= (((long)curbrk + PAGSIZ) & ~(PAGSIZ - 1))) {
+ oldbrk = curbrk;
+ curbrk += incr;
+ return oldbrk;
+ }
+ /*
+ * If asking for than currently left in this chunk,
+ * go somewhere completely different.
+ */
+
+#ifdef NEED_DEV_ZERO
+ fd = open("/dev/zero", O_RDWR, 0);
+ if (fd == -1)
+ perror("/dev/zero");
+#endif
+
+ if ((curbrk = mmap(0, incr,
+ PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) {
perror("Cannot map anonymous memory");
}
diff --git a/libexec/rtld-aout/shlib.c b/libexec/rtld-aout/shlib.c
index 55cd8c3..64e2efc 100644
--- a/libexec/rtld-aout/shlib.c
+++ b/libexec/rtld-aout/shlib.c
@@ -1,5 +1,5 @@
/*
- * $Id: shlib.c,v 1.4 1993/11/08 13:21:23 pk Exp $
+ * $Id: shlib.c,v 1.2 1993/11/09 04:19:03 paul Exp $
*/
#include <sys/param.h>
@@ -132,9 +132,10 @@ int n1, n2;
#undef minor
char *
-findshlib(name, majorp, minorp)
+findshlib(name, majorp, minorp, do_dot_a)
char *name;
int *majorp, *minorp;
+int do_dot_a;
{
int dewey[MAXDEWEY];
int ndewey;
@@ -154,6 +155,7 @@ int *majorp, *minorp;
for (i = 0; i < n_search_dirs; i++) {
DIR *dd = opendir(search_dirs[i]);
struct dirent *dp;
+ int found_dot_a = 0;
if (dd == NULL)
continue;
@@ -161,6 +163,16 @@ int *majorp, *minorp;
while ((dp = readdir(dd)) != NULL) {
int n, j, might_take_it = 0;
+ if (do_dot_a && path == NULL &&
+ dp->d_namlen == len + 2 &&
+ strncmp(dp->d_name, lname, len) == 0 &&
+ (dp->d_name+len)[0] == '.' &&
+ (dp->d_name+len)[1] == 'a') {
+
+ path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 1;
+ }
+
if (dp->d_namlen < len + 4)
continue;
if (strncmp(dp->d_name, lname, len) != 0)
@@ -171,6 +183,12 @@ int *majorp, *minorp;
if ((n = getdewey(tmp, dp->d_name+len+4)) == 0)
continue;
+ if (major != -1 && found_dot_a) { /* XXX */
+ free(path);
+ path = NULL;
+ found_dot_a = 0;
+ }
+
if (major == -1 && minor == -1) {
might_take_it = 1;
} else if (major != -1 && minor == -1) {
@@ -192,12 +210,19 @@ int *majorp, *minorp;
if (path)
free(path);
path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 0;
bcopy(tmp, dewey, sizeof(dewey));
ndewey = n;
*majorp = dewey[0];
*minorp = dewey[1];
}
closedir(dd);
+
+ if (found_dot_a)
+ /*
+ * There's a .a archive here.
+ */
+ return path;
}
return path;
diff --git a/sbin/ldconfig/ldconfig.c b/sbin/ldconfig/ldconfig.c
index b4b9981..899539d 100644
--- a/sbin/ldconfig/ldconfig.c
+++ b/sbin/ldconfig/ldconfig.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: ldconfig.c,v 1.1 1993/10/23 00:17:03 pk Exp $
+ * $Id: ldconfig.c,v 1.2 1993/11/09 04:19:22 paul Exp $
*/
#include <sys/param.h>
@@ -58,7 +58,6 @@ static int verbose;
static int nostd;
static int justread;
-#define MAXDEWEY 8
struct shlib_list {
/* Internal list of shared libraries found */
char *name;
@@ -401,9 +400,13 @@ listhints()
return -1;
}
- printf("\t-l%s.%d.%d => %s\n",
+ printf("\t%d:-l%s.%d.%d => %s (%d -> %d)\n",
+ i,
strtab + bp->hi_namex, bp->hi_major, bp->hi_minor,
- strtab + bp->hi_pathx);
+ strtab + bp->hi_pathx,
+ hinthash(strtab+bp->hi_namex, bp->hi_major, bp->hi_minor)
+ % hdr->hh_nbucket,
+ bp->hi_next);
}
return 0;
OpenPOWER on IntegriCloud