Sync up with Paul K's latest ld from cesium.
This commit is contained in:
parent
a4a6a87d67
commit
00abba10e4
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: etc.c,v 1.4 1993/12/02 00:56:33 jkh Exp $
|
||||
* $Id: etc.c,v 1.5 1993/12/04 00:52:55 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -85,7 +85,7 @@ fatal(fmt, va_alist)
|
||||
|
||||
char *
|
||||
concat(s1, s2, s3)
|
||||
char *s1, *s2, *s3;
|
||||
const char *s1, *s2, *s3;
|
||||
{
|
||||
register int len1 = strlen (s1),
|
||||
len2 = strlen (s2),
|
||||
@ -150,22 +150,6 @@ xrealloc(ptr, size)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USG
|
||||
void
|
||||
bzero(p, n)
|
||||
char *p;
|
||||
{
|
||||
memset (p, 0, n);
|
||||
}
|
||||
|
||||
void
|
||||
bcopy(from, to, n)
|
||||
char *from, *to;
|
||||
{
|
||||
memcpy (to, from, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* These must move */
|
||||
|
||||
@ -192,8 +176,10 @@ mywrite (buf, count, eltsize, desc)
|
||||
}
|
||||
}
|
||||
|
||||
/* Output PADDING zero-bytes to descriptor OUTDESC.
|
||||
PADDING may be negative; in that case, do nothing. */
|
||||
/*
|
||||
* Output PADDING zero-bytes to descriptor OUTDESC.
|
||||
* PADDING may be negative; in that case, do nothing.
|
||||
*/
|
||||
|
||||
void
|
||||
padfile (padding, outdesc)
|
||||
|
@ -1,5 +1,33 @@
|
||||
/*
|
||||
* $Id: md.h,v 1.3 1993/11/22 19:05:24 jkh Exp $ - I386 dependent definitions
|
||||
* Copyright (c) 1993 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Paul Kranenburg.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software withough specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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.5 1993/12/08 10:14:48 pk Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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.14 1993/12/02 05:09:52 nate Exp $
|
||||
* $Id: ld.c,v 1.15 1993/12/04 00:52:56 jkh Exp $
|
||||
*/
|
||||
|
||||
/* Define how to initialize system-dependent header fields. */
|
||||
@ -55,6 +55,10 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
#ifndef DEFAULT_SOVERSION
|
||||
#define DEFAULT_SOVERSION LD_VERSION_BSD
|
||||
#endif
|
||||
|
||||
int building_shared_object;
|
||||
|
||||
/* 1 => write relocation into output file so can re-input it later. */
|
||||
@ -77,6 +81,9 @@ int force_alias_definition;
|
||||
if `relocatable_output'. */
|
||||
int pic_code_seen;
|
||||
|
||||
/* 1 => data segment must be page aligned, even if `-n' or `-N' */
|
||||
int page_align_data;
|
||||
|
||||
/*
|
||||
* Which symbols should be stripped (omitted from the output): none, all, or
|
||||
* debugger symbols.
|
||||
@ -127,6 +134,25 @@ int specified_data_size;
|
||||
long *set_vectors;
|
||||
int setv_fill_count;
|
||||
|
||||
static void decode_option __P((char *, char *));
|
||||
static void decode_command __P((int, char **));
|
||||
static int classify_arg __P((char *));
|
||||
static void enter_global_ref __P((struct localsymbol *,
|
||||
char *, struct file_entry *));
|
||||
static void digest_symbols __P((void));
|
||||
static void digest_pass1 __P((void)), digest_pass2 __P((void));
|
||||
static void consider_file_section_lengths __P((struct file_entry *));
|
||||
static void relocate_file_addresses __P((struct file_entry *));
|
||||
static void consider_relocation __P((struct file_entry *, int));
|
||||
static void perform_relocation __P((char *, int,
|
||||
struct relocation_info *, int,
|
||||
struct file_entry *, int));
|
||||
static void copy_text __P((struct file_entry *));
|
||||
static void copy_data __P((struct file_entry *));
|
||||
static void coptxtrel __P((struct file_entry *));
|
||||
static void copdatrel __P((struct file_entry *));
|
||||
static void assign_symbolnums __P((struct file_entry *, int *));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
@ -163,6 +189,7 @@ main(argc, argv)
|
||||
|
||||
data_pad = 0;
|
||||
text_pad = 0;
|
||||
page_align_data = 0;
|
||||
|
||||
/* Initialize the data about options. */
|
||||
|
||||
@ -180,7 +207,10 @@ main(argc, argv)
|
||||
make_executable = 1;
|
||||
force_executable = 0;
|
||||
link_mode = DYNAMIC;
|
||||
soversion = LD_VERSION_BSD;
|
||||
#ifdef SUNOS4
|
||||
link_mode |= SILLYARCHIVE;
|
||||
#endif
|
||||
soversion = DEFAULT_SOVERSION;
|
||||
|
||||
/* Initialize the cumulative counts of symbols. */
|
||||
|
||||
@ -262,8 +292,6 @@ main(argc, argv)
|
||||
exit(!make_executable);
|
||||
}
|
||||
|
||||
void decode_option();
|
||||
|
||||
/*
|
||||
* Analyze a command line argument. Return 0 if the argument is a filename.
|
||||
* Return 1 if the argument is a option complete in itself. Return 2 if the
|
||||
@ -273,7 +301,7 @@ void decode_option();
|
||||
* options.
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
classify_arg(arg)
|
||||
register char *arg;
|
||||
{
|
||||
@ -320,10 +348,10 @@ classify_arg(arg)
|
||||
* each input file, and setting variables according to the options.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
decode_command(argc, argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int i;
|
||||
register struct file_entry *p;
|
||||
@ -390,6 +418,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)
|
||||
@ -467,7 +501,7 @@ set_element_prefixed_p(name)
|
||||
* files.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
decode_option(swt, arg)
|
||||
register char *swt, *arg;
|
||||
{
|
||||
@ -484,6 +518,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;
|
||||
@ -551,16 +589,19 @@ decode_option(swt, arg)
|
||||
case 'Q':
|
||||
magic = oldmagic = QMAGIC;
|
||||
return;
|
||||
#endif
|
||||
case 'Z':
|
||||
magic = ZMAGIC;
|
||||
oldmagic = 0;
|
||||
magic = oldmagic = ZMAGIC;
|
||||
return;
|
||||
#endif
|
||||
|
||||
case 'o':
|
||||
output_filename = arg;
|
||||
return;
|
||||
|
||||
case 'p':
|
||||
page_align_data = 1;
|
||||
return;
|
||||
|
||||
case 'r':
|
||||
relocatable_output = 1;
|
||||
magic = OMAGIC;
|
||||
@ -644,17 +685,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
|
||||
}
|
||||
}
|
||||
|
||||
@ -704,15 +766,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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -737,7 +825,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)
|
||||
@ -802,6 +890,7 @@ read_header (desc, entry)
|
||||
* descriptor DESC. Also read the length of the string table, which follows
|
||||
* the symbol table, but don't read the contents of the string table.
|
||||
*/
|
||||
|
||||
void
|
||||
read_entry_symbols (desc, entry)
|
||||
struct file_entry *entry;
|
||||
@ -941,8 +1030,6 @@ read_entry_relocation (desc, entry)
|
||||
|
||||
/* Read in the symbols of all input files. */
|
||||
|
||||
void read_file_symbols (), read_entry_symbols ();
|
||||
void enter_file_symbols (), enter_global_ref ();
|
||||
|
||||
void
|
||||
load_symbols ()
|
||||
@ -990,7 +1077,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;
|
||||
@ -1095,7 +1182,7 @@ enter_file_symbols (entry)
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
enter_global_ref (lsp, name, entry)
|
||||
struct localsymbol *lsp;
|
||||
char *name;
|
||||
@ -1117,8 +1204,9 @@ enter_global_ref (lsp, name, entry)
|
||||
lsp->nzlist.nz_type = N_TEXT|N_EXT;
|
||||
lsp->nzlist.nz_value = 0;
|
||||
make_executable = 0;
|
||||
} else
|
||||
} else {
|
||||
global_alias_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->is_dynamic) {
|
||||
@ -1273,9 +1361,6 @@ contains_symbol (entry, np)
|
||||
}
|
||||
|
||||
|
||||
void consider_file_section_lengths (), relocate_file_addresses ();
|
||||
void consider_relocation();
|
||||
|
||||
/*
|
||||
* Having entered all the global symbols and found the sizes of sections of
|
||||
* all files to be linked, make all appropriate deductions from this data.
|
||||
@ -1295,7 +1380,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).
|
||||
@ -1307,9 +1392,8 @@ void consider_relocation();
|
||||
*
|
||||
*/
|
||||
|
||||
void digest_pass1(), digest_pass2();
|
||||
|
||||
void
|
||||
static void
|
||||
digest_symbols ()
|
||||
{
|
||||
|
||||
@ -1323,9 +1407,9 @@ digest_symbols ()
|
||||
* the vector, plus a word for each symbol for a zero at the
|
||||
* end of the vector (for incremental linking).
|
||||
*/
|
||||
set_sect_size = (2 * set_symbol_count + set_vector_count) *
|
||||
set_sect_size = (set_symbol_count + 2 * set_vector_count) *
|
||||
sizeof (unsigned long);
|
||||
set_vectors = (unsigned long *) xmalloc (set_sect_size);
|
||||
set_vectors = (long *)xmalloc (set_sect_size);
|
||||
setv_fill_count = 0;
|
||||
}
|
||||
|
||||
@ -1354,7 +1438,7 @@ digest_symbols ()
|
||||
* the padding in the text segment size.
|
||||
*/
|
||||
|
||||
if (magic == ZMAGIC) {
|
||||
if (magic == ZMAGIC || page_align_data) {
|
||||
int text_end = text_size + N_TXTOFF(outheader);
|
||||
text_pad = PALIGN(text_end, page_size) - text_end;
|
||||
text_size += text_pad;
|
||||
@ -1429,12 +1513,24 @@ printf("bssstart = %#x, bsssize = %#x\n",
|
||||
if (got_symbol->referenced)
|
||||
global_sym_count++;
|
||||
|
||||
if (relocatable_output)
|
||||
if (relocatable_output || building_shared_object)
|
||||
/* For each alias we write out two struct nlists */
|
||||
global_sym_count += global_alias_count + size_sym_count;
|
||||
global_sym_count += global_alias_count;
|
||||
|
||||
if (relocatable_output)
|
||||
/* We write out the original N_SET* symbols */
|
||||
global_sym_count += size_sym_count;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("global symbols %d (defined %d, undefined %d, aliases %d), locals: %d, \
|
||||
debug symbols: %d, set_symbols %d\n",
|
||||
global_sym_count,
|
||||
defined_global_sym_count, undefined_global_sym_count, global_alias_count,
|
||||
local_sym_count, debugger_sym_count, set_symbol_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
digest_pass1()
|
||||
{
|
||||
|
||||
@ -1510,7 +1606,14 @@ digest_pass1()
|
||||
if ((sp->defined & N_TYPE) == N_SETV)
|
||||
/* Allocate zero entry in set vector */
|
||||
setv_fill_count++;
|
||||
defined_global_sym_count++;
|
||||
/*
|
||||
* At this stage, we do not know whether an alias
|
||||
* is going to be defined for real here, or whether
|
||||
* it refers to a shared object symbol. The decision
|
||||
* is deferred until digest_pass2().
|
||||
*/
|
||||
if (!sp->alias)
|
||||
defined_global_sym_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1528,6 +1631,7 @@ digest_pass1()
|
||||
continue;
|
||||
}
|
||||
|
||||
again:
|
||||
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
|
||||
register struct nlist *p = &lsp->nzlist.nlist;
|
||||
register int type = p->n_type;
|
||||
@ -1537,17 +1641,29 @@ digest_pass1()
|
||||
/* non-common definition */
|
||||
sp->def_nlist = p;
|
||||
sp->so_defined = type;
|
||||
undefined_global_sym_count--;
|
||||
if (sp->referenced)
|
||||
undefined_global_sym_count--;
|
||||
else
|
||||
sp->referenced = 1;
|
||||
#ifdef DEBUG
|
||||
printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
|
||||
#endif
|
||||
if (sp->alias && !sp->alias->referenced) {
|
||||
sp = sp->alias;
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (setv_fill_count != set_sect_size/sizeof(long))
|
||||
fatal("internal error: allocated set symbol space (%d) \
|
||||
doesn't match actual (%d)",
|
||||
set_sect_size/sizeof(long), setv_fill_count);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
digest_pass2()
|
||||
{
|
||||
/*
|
||||
@ -1562,6 +1678,16 @@ digest_pass2()
|
||||
if (!sp->referenced)
|
||||
continue;
|
||||
|
||||
if (sp->alias &&
|
||||
(relocatable_output || building_shared_object ||
|
||||
(sp->alias->defined && !sp->alias->so_defined)))
|
||||
/*
|
||||
* The alias points at a defined symbol, so it
|
||||
* must itself be counted as one too, in order to
|
||||
* compute the correct number of symbol table entries.
|
||||
*/
|
||||
defined_global_sym_count++;
|
||||
|
||||
if ((sp->defined & N_TYPE) == N_SETV) {
|
||||
/*
|
||||
* Set length word at front of vector and zero byte
|
||||
@ -1676,11 +1802,12 @@ digest_pass2()
|
||||
} END_EACH_SYMBOL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scan relocation info in ENTRY for contributions to the dynamic section of
|
||||
* the output file.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
consider_relocation (entry, dataseg)
|
||||
struct file_entry *entry;
|
||||
int dataseg;
|
||||
@ -1849,7 +1976,7 @@ printf("%s: FUNC flag set\n", sp->name);
|
||||
* Accumulate the section sizes of input file ENTRY into the section sizes of
|
||||
* the output file.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
consider_file_section_lengths (entry)
|
||||
register struct file_entry *entry;
|
||||
{
|
||||
@ -1875,7 +2002,7 @@ consider_file_section_lengths (entry)
|
||||
* and determine which of the local symbols will make it into the
|
||||
* output symbol table.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
relocate_file_addresses (entry)
|
||||
register struct file_entry *entry;
|
||||
{
|
||||
@ -2025,18 +2152,20 @@ write_output ()
|
||||
if (chmod (output_filename, filemode | 0111) == -1)
|
||||
perror_name (output_filename);
|
||||
}
|
||||
|
||||
void modify_location (), perform_relocation (), copy_text (), copy_data ();
|
||||
|
||||
/* Total number of symbols to be written in the output file. */
|
||||
int nsyms;
|
||||
static int nsyms;
|
||||
|
||||
void
|
||||
write_header ()
|
||||
{
|
||||
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
|
||||
|
||||
if (!oldmagic) N_SET_FLAG (outheader, flags);
|
||||
#ifdef QMAGIC
|
||||
if (!oldmagic)
|
||||
#endif
|
||||
N_SET_FLAG (outheader, flags);
|
||||
|
||||
outheader.a_text = text_size;
|
||||
outheader.a_data = data_size;
|
||||
outheader.a_bss = bss_size;
|
||||
@ -2051,15 +2180,6 @@ write_header ()
|
||||
if (relocatable_output)
|
||||
nsyms += set_symbol_count;
|
||||
|
||||
#ifdef DEBUG
|
||||
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, debugger_sym_count,
|
||||
set_symbol_count, global_alias_count, nsyms);
|
||||
#endif
|
||||
|
||||
outheader.a_syms = nsyms * sizeof (struct nlist);
|
||||
|
||||
if (relocatable_output) {
|
||||
@ -2462,10 +2582,10 @@ printf("%s: BSS found in so_defined\n", sp->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* For relocatable_output only: write out the relocation,
|
||||
relocating the addresses-to-be-relocated. */
|
||||
|
||||
void coptxtrel(), copdatrel(), assign_symbolnums();
|
||||
/*
|
||||
* For relocatable_output only: write out the relocation,
|
||||
* relocating the addresses-to-be-relocated.
|
||||
*/
|
||||
|
||||
void
|
||||
write_rel ()
|
||||
@ -2513,10 +2633,11 @@ write_rel ()
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Assign symbol ordinal numbers to local symbols in each entry.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
assign_symbolnums(entry, countp)
|
||||
struct file_entry *entry;
|
||||
int *countp;
|
||||
@ -2537,7 +2658,7 @@ assign_symbolnums(entry, countp)
|
||||
*countp = n;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
coptxtrel(entry)
|
||||
struct file_entry *entry;
|
||||
{
|
||||
@ -2613,7 +2734,7 @@ coptxtrel(entry)
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
copdatrel(entry)
|
||||
struct file_entry *entry;
|
||||
{
|
||||
@ -2684,28 +2805,28 @@ void write_string_table __P((void));
|
||||
|
||||
/* Offsets and current lengths of symbol and string tables in output file. */
|
||||
|
||||
int symbol_table_offset;
|
||||
int symbol_table_len;
|
||||
static int symbol_table_offset;
|
||||
static int symbol_table_len;
|
||||
|
||||
/* Address in output file where string table starts. */
|
||||
int string_table_offset;
|
||||
static int string_table_offset;
|
||||
|
||||
/* Offset within string table
|
||||
where the strings in `strtab_vector' should be written. */
|
||||
int string_table_len;
|
||||
static int string_table_len;
|
||||
|
||||
/* Total size of string table strings allocated so far,
|
||||
including strings in `strtab_vector'. */
|
||||
int strtab_size;
|
||||
static int strtab_size;
|
||||
|
||||
/* Vector whose elements are strings to be added to the string table. */
|
||||
char **strtab_vector;
|
||||
static char **strtab_vector;
|
||||
|
||||
/* Vector whose elements are the lengths of those strings. */
|
||||
int *strtab_lens;
|
||||
static int *strtab_lens;
|
||||
|
||||
/* Index in `strtab_vector' at which the next string will be stored. */
|
||||
int strtab_index;
|
||||
static int strtab_index;
|
||||
|
||||
/*
|
||||
* Add the string NAME to the output file string table. Record it in
|
||||
@ -2713,7 +2834,7 @@ int strtab_index;
|
||||
* table that this string will have.
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
assign_string_table_index(name)
|
||||
char *name;
|
||||
{
|
||||
@ -2823,6 +2944,7 @@ write_syms()
|
||||
/* Scan the symbol hash table, bucket by bucket. */
|
||||
|
||||
FOR_EACH_SYMBOL(i, sp) {
|
||||
|
||||
if (sp == dynamic_symbol)
|
||||
/* Already dealt with above */
|
||||
continue;
|
||||
@ -2831,7 +2953,7 @@ write_syms()
|
||||
/* Came from shared object but was not used */
|
||||
continue;
|
||||
|
||||
if (sp->so_defined)
|
||||
if (sp->so_defined || (sp->alias && sp->alias->so_defined))
|
||||
/*
|
||||
* Definition came from shared object,
|
||||
* don't mention it here
|
||||
@ -2850,39 +2972,52 @@ write_syms()
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Construct a `struct nlist' for the symbol. */
|
||||
if (syms_written >= global_sym_count)
|
||||
fatal(
|
||||
"internal error: number of symbols exceeds alloc'd %d",
|
||||
global_sym_count);
|
||||
|
||||
/*
|
||||
* Construct a `struct nlist' for the symbol.
|
||||
*/
|
||||
nl.n_other = 0;
|
||||
nl.n_desc = 0;
|
||||
|
||||
/*
|
||||
* common condition needs to be before undefined
|
||||
* condition because unallocated commons are set
|
||||
* undefined in digest_symbols
|
||||
*/
|
||||
if (sp->defined > 1) {
|
||||
/* defined with known type */
|
||||
|
||||
if (!relocatable_output && sp->alias &&
|
||||
sp->alias->defined > 1) {
|
||||
/*
|
||||
* defined with known type
|
||||
*/
|
||||
if (!relocatable_output && !building_shared_object &&
|
||||
sp->alias && sp->alias->defined > 1) {
|
||||
/*
|
||||
* If the target of an indirect symbol has
|
||||
* been defined and we are outputting an
|
||||
* executable, resolve the indirection; it's
|
||||
* no longer needed
|
||||
* no longer needed.
|
||||
*/
|
||||
nl.n_type = sp->alias->defined;
|
||||
nl.n_type = sp->alias->value;
|
||||
} else if (sp->defined == N_SIZE)
|
||||
nl.n_type = N_DATA | N_EXT;
|
||||
else
|
||||
nl.n_type = sp->defined;
|
||||
nl.n_value = sp->value;
|
||||
nl.n_value = sp->alias->value;
|
||||
} else {
|
||||
if (sp->defined == N_SIZE)
|
||||
nl.n_type = N_DATA | N_EXT;
|
||||
else
|
||||
nl.n_type = sp->defined;
|
||||
if (nl.n_type == (N_INDR|N_EXT) &&
|
||||
sp->value != 0)
|
||||
fatal("%s: N_INDR has value %#x",
|
||||
sp->name, sp->value);
|
||||
nl.n_value = sp->value;
|
||||
}
|
||||
|
||||
} else if (sp->max_common_size) {
|
||||
/*
|
||||
* defined as common but not allocated,
|
||||
* happens only with -r and not -d, write out
|
||||
* a common definition
|
||||
* a common definition.
|
||||
*
|
||||
* common condition needs to be before undefined
|
||||
* condition because unallocated commons are set
|
||||
* undefined in digest_symbols.
|
||||
*/
|
||||
nl.n_type = N_UNDF | N_EXT;
|
||||
nl.n_value = sp->max_common_size;
|
||||
@ -2903,10 +3038,6 @@ write_syms()
|
||||
|
||||
/* Output to the buffer and count it. */
|
||||
|
||||
if (syms_written >= global_sym_count)
|
||||
fatal(
|
||||
"internal error: number of symbols exceeds allocated %d",
|
||||
global_sym_count);
|
||||
*bufp++ = nl;
|
||||
syms_written++;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: ld.h,v 1.6 1993/12/02 00:56:37 jkh Exp $ */
|
||||
/* $Id: ld.h,v 1.7 1993/12/04 00:52:58 jkh Exp $ */
|
||||
/*-
|
||||
* This code is derived from software copyrighted by the Free Software
|
||||
* Foundation.
|
||||
@ -678,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;
|
||||
|
||||
@ -722,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).
|
||||
@ -824,13 +830,14 @@ char **search_dirs;
|
||||
/* Length of the vector `search_dirs'. */
|
||||
int n_search_dirs;
|
||||
|
||||
void digest_symbols __P((void));
|
||||
void load_symbols __P((void));
|
||||
void decode_command __P((int, char **));
|
||||
void read_header __P((int, struct file_entry *));
|
||||
void read_entry_symbols __P((int, struct file_entry *));
|
||||
void read_entry_strings __P((int, struct file_entry *));
|
||||
void read_entry_relocation __P((int, struct file_entry *));
|
||||
void enter_file_symbols __P((struct file_entry *));
|
||||
void read_file_symbols __P((struct file_entry *));
|
||||
|
||||
void write_output __P((void));
|
||||
void write_header __P((void));
|
||||
void write_text __P((void));
|
||||
@ -856,7 +863,7 @@ void *xrealloc __P((void *, int));
|
||||
void fatal __P((char *, ...));
|
||||
void error __P((char *, ...));
|
||||
void padfile __P((int,int));
|
||||
char *concat __P((char *, char *, char *));
|
||||
char *concat __P((const char *, const char *, const char *));
|
||||
int parse __P((char *, char *, char *));
|
||||
|
||||
/* In symbol.c: */
|
||||
@ -869,7 +876,7 @@ 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 *));
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lib.c,v 1.5 1993/12/02 00:56:38 jkh Exp $ - library routines
|
||||
* $Id: lib.c,v 1.6 1993/12/04 00:52:59 jkh Exp $ - library routines
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -78,7 +78,8 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
{
|
||||
int bytes_read;
|
||||
register int namelen;
|
||||
int member_length;
|
||||
int member_length, content_length;
|
||||
int starting_offset;
|
||||
register char *name;
|
||||
struct ar_hdr hdr1;
|
||||
register struct file_entry *subentry;
|
||||
@ -104,22 +105,49 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
&& hdr1.ar_name[namelen] != '/';
|
||||
namelen++);
|
||||
|
||||
name = (char *) xmalloc(namelen + 1);
|
||||
strncpy(name, hdr1.ar_name, namelen);
|
||||
name[namelen] = 0;
|
||||
starting_offset = subfile_offset + sizeof hdr1;
|
||||
content_length = member_length;
|
||||
|
||||
#ifdef AR_EFMT1
|
||||
/*
|
||||
* BSD 4.4 extended AR format: #1/<namelen>, with name as the
|
||||
* first <namelen> bytes of the file
|
||||
*/
|
||||
if ( (hdr1.ar_name[0] == '#') &&
|
||||
(hdr1.ar_name[1] == '1') &&
|
||||
(hdr1.ar_name[2] == '/') &&
|
||||
(isdigit(hdr1.ar_name[3]))) {
|
||||
|
||||
namelen = atoi(&hdr1.ar_name[3]);
|
||||
name = (char *)xmalloc(namelen + 1);
|
||||
if (read(desc, name, namelen) != namelen)
|
||||
fatal_with_file(
|
||||
"malformatted header of archive member in ",
|
||||
library_entry);
|
||||
name[namelen] = 0;
|
||||
content_length -= namelen;
|
||||
starting_offset += namelen;
|
||||
} else
|
||||
|
||||
#endif
|
||||
{
|
||||
name = (char *)xmalloc(namelen + 1);
|
||||
strncpy(name, hdr1.ar_name, namelen);
|
||||
name[namelen] = 0;
|
||||
}
|
||||
|
||||
subentry->filename = name;
|
||||
subentry->local_sym_name = name;
|
||||
subentry->symbols = 0;
|
||||
subentry->strings = 0;
|
||||
subentry->subfiles = 0;
|
||||
subentry->starting_offset = subfile_offset + sizeof hdr1;
|
||||
subentry->starting_offset = starting_offset;
|
||||
subentry->superfile = library_entry;
|
||||
subentry->library_flag = 0;
|
||||
subentry->header_read_flag = 0;
|
||||
subentry->just_syms_flag = 0;
|
||||
subentry->chain = 0;
|
||||
subentry->total_size = member_length;
|
||||
subentry->total_size = content_length;
|
||||
|
||||
(*length_loc) = member_length;
|
||||
|
||||
@ -474,6 +502,9 @@ subfile_wanted_p(entry)
|
||||
int defs = 0;
|
||||
|
||||
/* Check for undefined symbols in shared objects */
|
||||
if (sp->sorefs == NULL)
|
||||
continue;
|
||||
|
||||
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
|
||||
type = lsp->nzlist.nlist.n_type;
|
||||
if ( (type & N_EXT) &&
|
||||
@ -590,9 +621,110 @@ 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)); /*XXX*/
|
||||
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
|
||||
@ -611,7 +743,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;
|
||||
|
@ -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.8 1993/12/02 09:32:26 ache Exp $
|
||||
* $Id: rrs.c,v 1.9 1993/12/04 00:53:00 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -726,6 +726,16 @@ consider_rrs_section_lengths()
|
||||
rrs_strtab_size += 1 + strlen(sp->name);
|
||||
if (sp != dynamic_symbol)
|
||||
sp->rrs_symbolnum = number_of_rrs_symbols++;
|
||||
if (sp->alias) {
|
||||
/*
|
||||
* (sigh) Always allocate space to hold the
|
||||
* indirection. At this point there's not
|
||||
* enough information to decide whether it's
|
||||
* actually needed or not.
|
||||
*/
|
||||
number_of_rrs_symbols++;
|
||||
rrs_strtab_size += 1 + strlen(sp->alias->name);
|
||||
}
|
||||
}
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
@ -973,7 +983,17 @@ write_rrs_text()
|
||||
|
||||
if (sp->defined > 1) {
|
||||
/* defined with known type */
|
||||
if (sp->defined == N_SIZE) {
|
||||
if (!(link_mode & SHAREABLE) &&
|
||||
sp->alias && sp->alias->defined > 1) {
|
||||
/*
|
||||
* If the target of an indirect symbol has
|
||||
* been defined and we are outputting an
|
||||
* executable, resolve the indirection; it's
|
||||
* no longer needed.
|
||||
*/
|
||||
nlp->nz_type = sp->alias->defined;
|
||||
nlp->nz_value = sp->alias->value;
|
||||
} else if (sp->defined == N_SIZE) {
|
||||
/*
|
||||
* Make sure this symbol isn't going
|
||||
* to define anything.
|
||||
@ -1001,7 +1021,6 @@ write_rrs_text()
|
||||
"internal error: %s defined in mysterious way",
|
||||
sp->name);
|
||||
|
||||
|
||||
/* Handle auxialiary type qualifiers */
|
||||
switch (sp->aux) {
|
||||
case 0:
|
||||
@ -1020,7 +1039,7 @@ write_rrs_text()
|
||||
break;
|
||||
default:
|
||||
fatal(
|
||||
"internal error: %s: unsupported other value: %x",
|
||||
"internal error: %s: unsupported other value: %x",
|
||||
sp->name, sp->aux);
|
||||
break;
|
||||
}
|
||||
@ -1030,14 +1049,32 @@ write_rrs_text()
|
||||
strcpy(rrs_strtab + offset, sp->name);
|
||||
offset += 1 + strlen(sp->name);
|
||||
|
||||
if (sp->alias) {
|
||||
/*
|
||||
* Write an extra symbol for indirections (possibly
|
||||
* just a dummy).
|
||||
*/
|
||||
int t = (nlp->nz_type == N_INDR + N_EXT);
|
||||
|
||||
INCR_NLP(nlp);
|
||||
nlp->nz_type = N_UNDF + t?N_EXT:0;
|
||||
nlp->nz_un.n_strx = offset;
|
||||
nlp->nz_value = 0;
|
||||
nlp->nz_other = 0;
|
||||
nlp->nz_desc = 0;
|
||||
nlp->nz_size = 0;
|
||||
strcpy(rrs_strtab + offset, sp->alias->name);
|
||||
offset += 1 + strlen(sp->alias->name);
|
||||
}
|
||||
|
||||
INCR_NLP(nlp);
|
||||
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (MALIGN(offset) != rrs_strtab_size)
|
||||
fatal(
|
||||
"internal error: inconsistent RRS string table length: %d",
|
||||
offset);
|
||||
"internal error: inconsistent RRS string table length: %d, expected %d",
|
||||
offset, rrs_strtab_size);
|
||||
|
||||
/* Write the symbol table */
|
||||
if (rrs_symbol_size == sizeof(struct nlist))
|
||||
@ -1059,8 +1096,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;
|
||||
@ -1075,10 +1113,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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: shlib.c,v 1.4 1993/12/02 00:56:40 jkh Exp $
|
||||
* $Id: shlib.c,v 1.5 1993/12/04 00:53:02 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -11,16 +11,21 @@
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <a.out.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
#ifdef SUNOS4
|
||||
char *strsep();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard directories to search for files specified by -l.
|
||||
*/
|
||||
#ifndef STANDARD_SEARCH_DIRS
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/local/lib"
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#endif
|
||||
|
||||
char *standard_search_dirs[] = {
|
||||
@ -132,9 +137,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 +160,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 +168,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 +188,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 +215,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;
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
/*
|
||||
* $Id: md-static-funcs.c,v 1.2 1993/12/08 10:28:56 pk Exp $
|
||||
*
|
||||
* Simple SPARC relocations for the benefit of self-relocation of ld.so
|
||||
* avoiding the use of global variables (ie. reloc_bitshift[] et. al.).
|
||||
* Only types supported are RELOC_32 and RELOC_RELATIVE.
|
||||
|
@ -1,5 +1,33 @@
|
||||
/*
|
||||
* $Id: md.c,v 1.3 1993/11/22 19:05:30 jkh Exp $
|
||||
* Copyright (c) 1993 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Paul Kranenburg.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software withough specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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.6 1993/12/08 10:29:02 pk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -181,9 +209,14 @@ int type;
|
||||
#if 1
|
||||
/*
|
||||
* This wouldn't be strictly necessary - we could record the
|
||||
* location value "in situ" in stead of in the r_addend field -
|
||||
* relocation value "in situ" in stead of in the r_addend field -
|
||||
* but we are being Sun compatible here. Besides, Sun's ld.so
|
||||
* has a bug that prevents it from handling this alternate method
|
||||
* has a bug that prevents it from handling this alternate method.
|
||||
*
|
||||
* IT WOULD BE REALLY NICE TO HAVE CONSISTENCY THROUGHOUT THE ENTIRE
|
||||
* RELOCATION PROCESS, ie. using `r_addend' for storing all partially
|
||||
* completed relocations, in stead of mixing them in both relocation
|
||||
* records and in the segment data.
|
||||
*/
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_addend -= pc_relocation;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: warnings.c,v 1.4 1993/11/05 12:45:25 pk Exp $
|
||||
* $Id: warnings.c,v 1.2 1993/11/09 04:19:06 paul Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -9,6 +9,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
@ -112,10 +113,8 @@ fatal_with_file (fmt, entry, va_alist)
|
||||
*/
|
||||
void
|
||||
perror_name (name)
|
||||
char *name;
|
||||
char *name;
|
||||
{
|
||||
extern int errno, sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
char *s;
|
||||
|
||||
if (errno < sys_nerr)
|
||||
@ -133,8 +132,6 @@ void
|
||||
perror_file (entry)
|
||||
struct file_entry *entry;
|
||||
{
|
||||
extern int errno, sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
char *s;
|
||||
|
||||
if (errno < sys_nerr)
|
||||
@ -165,19 +162,17 @@ print_symbols(outfile)
|
||||
for (i = 0; i < TABSIZE; i++) {
|
||||
register symbol *sp;
|
||||
for (sp = symtab[i]; sp; sp = sp->link) {
|
||||
if (sp->defined == 1)
|
||||
if (sp->defined == (N_UNDF|N_EXT))
|
||||
fprintf(outfile, " %s: common, length %#x\n",
|
||||
sp->name, sp->max_common_size);
|
||||
if ( sp->referenced) {
|
||||
if (sp->defined)
|
||||
fprintf(outfile, " %s: %#x %#x\n",
|
||||
sp->name, sp->value, sp->size);
|
||||
else
|
||||
fprintf(outfile, " %s: undefined\n",
|
||||
sp->name);
|
||||
} else
|
||||
if (!sp->referenced)
|
||||
fprintf(outfile, " %s: unreferenced\n",
|
||||
sp->name);
|
||||
sp->name);
|
||||
else if (!sp->defined)
|
||||
fprintf(outfile, " %s: undefined\n", sp->name);
|
||||
else
|
||||
fprintf(outfile, " %s: %#x, size %#x\n",
|
||||
sp->name, sp->value, sp->size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +186,7 @@ describe_file_sections(entry, outfile)
|
||||
{
|
||||
fprintf(outfile, " ");
|
||||
print_file_name(entry, outfile);
|
||||
if (entry->just_syms_flag)
|
||||
if (entry->just_syms_flag || entry->is_dynamic)
|
||||
fprintf(outfile, " symbols only\n", 0);
|
||||
else
|
||||
fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
|
||||
@ -659,15 +654,17 @@ do_file_warnings (entry, outfile)
|
||||
if (list_multiple_defs && g->multiply_defined) {
|
||||
errfmt = "Definition of symbol %s (multiply defined)";
|
||||
switch (s->n_type) {
|
||||
|
||||
case N_TEXT | N_EXT:
|
||||
line_number = address_to_line (s->n_value, text_scan);
|
||||
file_name = text_scan[0].filename;
|
||||
break;
|
||||
|
||||
case N_DATA | N_EXT:
|
||||
line_number = address_to_line (s->n_value, data_scan);
|
||||
file_name = data_scan[0].filename;
|
||||
break;
|
||||
#if 0
|
||||
|
||||
case N_SETA | N_EXT:
|
||||
case N_SETT | N_EXT:
|
||||
case N_SETD | N_EXT:
|
||||
@ -676,16 +673,16 @@ do_file_warnings (entry, outfile)
|
||||
continue;
|
||||
errfmt = "First set element definition of symbol %s (multiply defined)";
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/* Don't print out multiple defs
|
||||
at references.*/
|
||||
printf("Multiple def: %s, type %#x\n", g->name, s->n_type);
|
||||
/* Don't print out multiple defs at references.*/
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (BIT_SET_P (nlist_bitvector, i))
|
||||
} else if (BIT_SET_P (nlist_bitvector, i)) {
|
||||
continue;
|
||||
else if (list_unresolved_refs && !g->defined && !g->so_defined) {
|
||||
} else if (list_unresolved_refs && !g->defined && !g->so_defined) {
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
continue;
|
||||
|
||||
|
@ -1,5 +1,33 @@
|
||||
/*
|
||||
* $Id: md.h,v 1.3 1993/11/22 19:05:24 jkh Exp $ - I386 dependent definitions
|
||||
* Copyright (c) 1993 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Paul Kranenburg.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software withough specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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.5 1993/12/08 10:14:48 pk Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: shlib.c,v 1.4 1993/12/02 00:56:40 jkh Exp $
|
||||
* $Id: shlib.c,v 1.5 1993/12/04 00:53:02 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -11,16 +11,21 @@
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <a.out.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
#ifdef SUNOS4
|
||||
char *strsep();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard directories to search for files specified by -l.
|
||||
*/
|
||||
#ifndef STANDARD_SEARCH_DIRS
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/local/lib"
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#endif
|
||||
|
||||
char *standard_search_dirs[] = {
|
||||
@ -132,9 +137,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 +160,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 +168,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 +188,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 +215,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;
|
||||
|
Loading…
Reference in New Issue
Block a user