diff options
author | jkh <jkh@FreeBSD.org> | 1993-11-30 20:47:54 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1993-11-30 20:47:54 +0000 |
commit | 90b65690ecd280ea567bd543c551a0d528447130 (patch) | |
tree | 9392aab4f81d6be4eb1228cfb19ddc38026587ce /gnu | |
parent | 09904e4dc974d08f55ad948a5489109659abbfdd (diff) | |
download | FreeBSD-src-90b65690ecd280ea567bd543c551a0d528447130.zip FreeBSD-src-90b65690ecd280ea567bd543c551a0d528447130.tar.gz |
Many recent fixes from Paul K, add support for chaining of shared lib deps.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/ld/Makefile | 10 | ||||
-rw-r--r-- | gnu/usr.bin/ld/etc.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/ld/i386/md.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/ld/i386/md.h | 4 | ||||
-rw-r--r-- | gnu/usr.bin/ld/ld.c | 428 | ||||
-rw-r--r-- | gnu/usr.bin/ld/ld.h | 41 | ||||
-rw-r--r-- | gnu/usr.bin/ld/ldconfig/ldconfig.c | 11 | ||||
-rw-r--r-- | gnu/usr.bin/ld/lib.c | 108 | ||||
-rw-r--r-- | gnu/usr.bin/ld/rrs.c | 118 | ||||
-rw-r--r-- | gnu/usr.bin/ld/rtld/rtld.c | 62 | ||||
-rw-r--r-- | gnu/usr.bin/ld/shlib.c | 29 | ||||
-rw-r--r-- | gnu/usr.bin/ld/sparc/md.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/ld/sparc/md.h | 4 |
13 files changed, 605 insertions, 222 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 */ /* |