"weak symbol" support (fudged into `a.out' by means of the n_other field).
Weak symbols are to replace indirect (type N_INDR) symbols and will help to clean up name spaces in libraries. Also, some misc. bug fixes, including PR 586, and use stdio for the output file entirely.
This commit is contained in:
parent
da34da6096
commit
8e0a22a5fb
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ld.h,v 1.15 1994/11/30 18:25:00 pk Exp $
|
||||
* $Id: ld.h,v 1.16 1994/12/23 20:32:57 pk Exp $
|
||||
*/
|
||||
/*-
|
||||
* This code is derived from software copyrighted by the Free Software
|
||||
@ -323,7 +323,6 @@ extern int netzmagic;
|
||||
|
||||
|
||||
#ifndef __GNU_STAB__
|
||||
|
||||
/* Line number for the data section. This is to be used to describe
|
||||
the source location of a variable declaration. */
|
||||
#ifndef N_DSLINE
|
||||
@ -335,9 +334,10 @@ extern int netzmagic;
|
||||
#ifndef N_BSLINE
|
||||
#define N_BSLINE (N_SLINE+N_BSS-N_TEXT)
|
||||
#endif
|
||||
|
||||
#endif /* not __GNU_STAB__ */
|
||||
|
||||
|
||||
#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
|
||||
|
||||
|
||||
typedef struct localsymbol {
|
||||
struct nzlist nzlist; /* n[z]list from file */
|
||||
@ -402,14 +402,15 @@ typedef struct glosym {
|
||||
|
||||
long flags;
|
||||
|
||||
#define GS_DEFINED 1 /* Symbol has definition (notyetused)*/
|
||||
#define GS_REFERENCED 2 /* Symbol is referred to by something
|
||||
#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
|
||||
#define GS_REFERENCED 0x2 /* Symbol is referred to by something
|
||||
interesting */
|
||||
#define GS_TRACE 4 /* Symbol will be traced */
|
||||
#define GS_HASJMPSLOT 8 /* */
|
||||
#define GS_TRACE 0x4 /* Symbol will be traced */
|
||||
#define GS_HASJMPSLOT 0x8 /* */
|
||||
#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
|
||||
#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
|
||||
#define GS_CPYRELOCCLAIMED 0x40 /* */
|
||||
#define GS_WEAK 0x80 /* Symbol is weakly defined */
|
||||
|
||||
} symbol;
|
||||
|
||||
@ -429,6 +430,9 @@ extern symbol *symtab[];
|
||||
/* # of global symbols referenced and not defined. */
|
||||
extern int undefined_global_sym_count;
|
||||
|
||||
/* # of weak symbols referenced and not defined. */
|
||||
extern int undefined_weak_sym_count;
|
||||
|
||||
/* # of undefined symbols referenced by shared objects */
|
||||
extern int undefined_shobj_sym_count;
|
||||
|
||||
@ -589,7 +593,7 @@ extern int link_mode;
|
||||
#define SHAREABLE 8 /* Build a shared object */
|
||||
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
|
||||
|
||||
extern int outdesc; /* Output file descriptor. */
|
||||
extern FILE *outstream; /* Output file. */
|
||||
extern struct exec outheader; /* Output file header. */
|
||||
extern int magic; /* Output file magic. */
|
||||
extern int oldmagic;
|
||||
@ -615,8 +619,8 @@ int file_open __P((struct file_entry *));
|
||||
void each_file __P((void (*)(), void *));
|
||||
void each_full_file __P((void (*)(), void *));
|
||||
unsigned long check_each_file __P((unsigned long (*)(), void *));
|
||||
void mywrite __P((void *, int, int, int));
|
||||
void padfile __P((int,int));
|
||||
void mywrite __P((void *, int, int, FILE *));
|
||||
void padfile __P((int, FILE *));
|
||||
|
||||
/* In warnings.c: */
|
||||
void perror_name __P((char *));
|
||||
|
@ -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.38 1994/12/17 16:22:57 pk Exp $
|
||||
* $Id: ld.c,v 1.39 1994/12/23 20:32:51 pk Exp $
|
||||
*/
|
||||
|
||||
/* Define how to initialize system-dependent header fields. */
|
||||
@ -135,7 +135,7 @@ int input_desc;
|
||||
|
||||
/* The name of the file to write; "a.out" by default. */
|
||||
char *output_filename; /* Output file name. */
|
||||
int outdesc; /* Output file descriptor. */
|
||||
FILE *outstream; /* Output file descriptor. */
|
||||
struct exec outheader; /* Output file header. */
|
||||
int magic; /* Output file magic. */
|
||||
int oldmagic;
|
||||
@ -183,11 +183,15 @@ int undefined_shobj_sym_count; /* # of undefined symbols referenced
|
||||
int multiple_def_count; /* # of multiply defined symbols. */
|
||||
int defined_global_sym_count; /* # of defined global symbols. */
|
||||
int common_defined_global_count; /* # of common symbols. */
|
||||
int undefined_weak_sym_count; /* # of weak symbols referenced and
|
||||
not defined. */
|
||||
|
||||
#if notused
|
||||
int special_sym_count; /* # of linker defined symbols. */
|
||||
/* XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
|
||||
* perhaps _etext, _edata and _end should go here too.
|
||||
*/
|
||||
#endif
|
||||
int global_alias_count; /* # of aliased symbols */
|
||||
int set_symbol_count; /* # of N_SET* symbols. */
|
||||
int set_vector_count; /* # of set vectors in output. */
|
||||
@ -1384,6 +1388,8 @@ enter_global_ref(lsp, name, entry)
|
||||
/*
|
||||
* This is an ex common...
|
||||
*/
|
||||
if (com)
|
||||
common_defined_global_count--;
|
||||
sp->common_size = 0;
|
||||
sp->defined = 0;
|
||||
}
|
||||
@ -1429,32 +1435,72 @@ enter_global_ref(lsp, name, entry)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef N_SIZE
|
||||
if (olddef && N_ISWEAK(&nzp->nlist) && !(sp->flags & GS_WEAK)) {
|
||||
#ifdef DEBUG
|
||||
printf("%s: not overridden by weak symbol from %s\n",
|
||||
sp->name, get_file_name(entry));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
#endif
|
||||
if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
|
||||
|
||||
} else if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
|
||||
|
||||
/*
|
||||
* Set `->defined' here, so commons and undefined globals
|
||||
* can be counted correctly.
|
||||
*/
|
||||
if (!sp->defined || sp->defined == (N_UNDF | N_EXT))
|
||||
if (!sp->defined || sp->defined == (N_UNDF | N_EXT)) {
|
||||
sp->defined = type;
|
||||
}
|
||||
|
||||
if (oldref && !olddef)
|
||||
if ((sp->flags & GS_WEAK) && !N_ISWEAK(&nzp->nlist)) {
|
||||
/*
|
||||
* Upgrade an existing weak definition.
|
||||
* We fake it by pretending the symbol is undefined;
|
||||
* must undo any common fiddling, however.
|
||||
*/
|
||||
if (!oldref)
|
||||
errx(1, "internal error: enter_glob_ref: "
|
||||
"weak symbol not referenced");
|
||||
if (!olddef && !com)
|
||||
undefined_weak_sym_count--;
|
||||
undefined_global_sym_count++;
|
||||
sp->defined = type;
|
||||
sp->flags &= ~GS_WEAK;
|
||||
olddef = 0;
|
||||
if (com)
|
||||
common_defined_global_count--;
|
||||
com = 0;
|
||||
sp->common_size = 0;
|
||||
}
|
||||
if (oldref && !olddef) {
|
||||
/*
|
||||
* It used to be undefined and we're defining it.
|
||||
*/
|
||||
undefined_global_sym_count--;
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1,
|
||||
"internal error: enter_glob_ref: undefined_global_sym_count = %d",
|
||||
undefined_global_sym_count);
|
||||
if (sp->flags & GS_WEAK)
|
||||
/* Used to be a weak reference */
|
||||
undefined_weak_sym_count--;
|
||||
if (undefined_global_sym_count < 0 ||
|
||||
undefined_weak_sym_count < 0)
|
||||
errx(1, "internal error: enter_glob_ref: "
|
||||
"undefined_global_sym_count = %d, "
|
||||
"undefined_weak_sym_count = %d",
|
||||
undefined_global_sym_count,
|
||||
undefined_weak_sym_count);
|
||||
|
||||
}
|
||||
|
||||
if (N_ISWEAK(&nzp->nlist))
|
||||
/* The definition is weak */
|
||||
sp->flags |= GS_WEAK;
|
||||
|
||||
if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
|
||||
/*
|
||||
@ -1480,13 +1526,18 @@ enter_global_ref(lsp, name, entry)
|
||||
if (SET_ELEMENT_P(type) && (!olddef || com))
|
||||
set_vector_count++;
|
||||
|
||||
} else if (!oldref && !com)
|
||||
} else if (!oldref && !com) {
|
||||
/*
|
||||
* An unreferenced symbol can already be defined
|
||||
* as common by shared objects.
|
||||
*/
|
||||
undefined_global_sym_count++;
|
||||
|
||||
if (N_ISWEAK(&nzp->nlist)) {
|
||||
/* The reference is weak */
|
||||
sp->flags |= GS_WEAK;
|
||||
undefined_weak_sym_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
|
||||
!T_flag_specified)
|
||||
@ -1496,8 +1547,8 @@ enter_global_ref(lsp, name, entry)
|
||||
register char *reftype;
|
||||
switch (type & N_TYPE) {
|
||||
case N_UNDF:
|
||||
reftype = nzp->nz_value?
|
||||
"defined as common":"referenced";
|
||||
reftype = nzp->nz_value
|
||||
? "defined as common" : "referenced";
|
||||
break;
|
||||
|
||||
case N_ABS:
|
||||
@ -1529,7 +1580,8 @@ enter_global_ref(lsp, name, entry)
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "symbol %s %s in ", sp->name, reftype);
|
||||
fprintf(stderr, "symbol %s %s%s in ", sp->name,
|
||||
(N_ISWEAK(&nzp->nlist))?"weakly ":"", reftype);
|
||||
print_file_name (entry, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
@ -1716,17 +1768,20 @@ printf("set_sect_start = %#x, set_sect_size = %#x\n",
|
||||
}
|
||||
|
||||
if (relocatable_output)
|
||||
/* We write out the original N_SET* symbols */
|
||||
/* We write out the original N_SIZE symbols */
|
||||
global_sym_count += size_sym_count;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(
|
||||
"global symbols %d (defined %d, undefined %d, aliases %d, warnings 2 * %d, \
|
||||
size symbols %d), locals: %d, debug symbols: %d, set_symbols %d\n",
|
||||
"global symbols %d "
|
||||
"(defined %d, undefined %d, weak %d, aliases %d, warnings 2 * %d, "
|
||||
"size symbols %d)\ncommons %d, locals: %d, debug symbols: %d, set_symbols %d\n",
|
||||
global_sym_count,
|
||||
defined_global_sym_count, undefined_global_sym_count,
|
||||
undefined_weak_sym_count,
|
||||
global_alias_count, warn_sym_count, size_sym_count,
|
||||
local_sym_count, debugger_sym_count, set_symbol_count);
|
||||
common_defined_global_count, local_sym_count,
|
||||
debugger_sym_count, set_symbol_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1812,20 +1867,18 @@ digest_pass1()
|
||||
&& (type & N_TYPE) != N_FN
|
||||
&& (type & N_TYPE) != N_SIZE) {
|
||||
/* non-common definition */
|
||||
#if 0
|
||||
if (defs++ && sp->value != p->n_value
|
||||
&& entry_symbol/*XXX*/) {
|
||||
#endif
|
||||
if (defs++ &&
|
||||
sp->def_lsp &&
|
||||
sp->def_lsp->nzlist.nz_value != p->n_value) {
|
||||
if (!N_ISWEAK(p))
|
||||
++defs;
|
||||
if (defs > 1) {
|
||||
sp->mult_defs = 1;
|
||||
multiple_def_count++;
|
||||
} else if (!N_ISWEAK(p) ||
|
||||
(!sp->def_lsp && !sp->common_size)) {
|
||||
sp->def_lsp = lsp;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
sp->defined = type;
|
||||
sp->aux = N_AUX(p);
|
||||
}
|
||||
sp->def_lsp = lsp;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
sp->defined = type;
|
||||
sp->aux = N_AUX(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1877,32 +1930,39 @@ digest_pass1()
|
||||
if (lsp->entry->flags & E_SECONDCLASS)
|
||||
/* Keep looking for something better */
|
||||
continue;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
if (sp->flags & GS_REFERENCED)
|
||||
undefined_global_sym_count--;
|
||||
else
|
||||
sp->flags |= GS_REFERENCED;
|
||||
if (N_ISWEAK(p))
|
||||
/* Keep looking for something better */
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sp->def_lsp) {
|
||||
#ifdef DEBUG
|
||||
printf("pass1: SO definition for %s, type %x in %s at %#x\n",
|
||||
sp->name, type, get_file_name(lsp->entry), p->n_value);
|
||||
sp->name, sp->so_defined, get_file_name(sp->def_lsp->entry),
|
||||
sp->def_lsp->nzlist.nz_value);
|
||||
#endif
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1,
|
||||
"internal error: digest_pass1,2: %s: undefined_global_sym_count = %d",
|
||||
sp->def_lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
if (sp->flags & GS_REFERENCED)
|
||||
undefined_global_sym_count--;
|
||||
else
|
||||
sp->flags |= GS_REFERENCED;
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1, "internal error: digest_pass1,2: "
|
||||
"%s: undefined_global_sym_count = %d",
|
||||
sp->name, undefined_global_sym_count);
|
||||
if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
|
||||
sp = sp->alias;
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
if (sp->alias &&
|
||||
!(sp->alias->flags & GS_REFERENCED)) {
|
||||
sp = sp->alias;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
sp=spsave;
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (setv_fill_count != set_sect_size/sizeof(long))
|
||||
errx(1, "internal error: allocated set symbol space (%d) \
|
||||
doesn't match actual (%d)",
|
||||
errx(1, "internal error: allocated set symbol space (%d) "
|
||||
"doesn't match actual (%d)",
|
||||
set_sect_size/sizeof(long), setv_fill_count);
|
||||
}
|
||||
|
||||
@ -2007,7 +2067,7 @@ consider_relocation(entry, dataseg)
|
||||
lsp = &entry->symbols[reloc->r_symbolnum];
|
||||
sp = lsp->symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: internal error, sp==NULL",
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
|
||||
if (sp->alias)
|
||||
@ -2051,7 +2111,8 @@ consider_relocation(entry, dataseg)
|
||||
alloc_rrs_cpy_reloc(entry, sp);
|
||||
sp->defined = N_SIZE;
|
||||
|
||||
} else if (!sp->defined && sp->common_size == 0)
|
||||
} else if (!sp->defined && sp->common_size == 0 &&
|
||||
sp->so_defined)
|
||||
alloc_rrs_reloc(entry, sp);
|
||||
|
||||
} else {
|
||||
@ -2408,19 +2469,21 @@ write_output()
|
||||
(void)unlink(output_filename);
|
||||
}
|
||||
|
||||
outdesc = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (outdesc < 0)
|
||||
outstream = fopen(output_filename, "w");
|
||||
if (outstream == NULL)
|
||||
err(1, "open: %s", output_filename);
|
||||
|
||||
if (atexit(cleanup))
|
||||
err(1, "atexit");
|
||||
|
||||
if (fstat (outdesc, &statbuf) < 0)
|
||||
if (fstat(fileno(outstream), &statbuf) < 0)
|
||||
err(1, "fstat: %s", output_filename);
|
||||
|
||||
filemode = statbuf.st_mode;
|
||||
|
||||
chmod (output_filename, filemode & ~0111);
|
||||
if (S_ISREG(statbuf.st_mode) &&
|
||||
chmod(output_filename, filemode & ~0111) == -1)
|
||||
err(1, "chmod: %s", output_filename);
|
||||
|
||||
/* Output the a.out header. */
|
||||
write_header();
|
||||
@ -2442,8 +2505,11 @@ write_output()
|
||||
if (chmod (output_filename, filemode | 0111) == -1)
|
||||
err(1, "chmod: %s", output_filename);
|
||||
|
||||
close(outdesc);
|
||||
outdesc = 0;
|
||||
fflush(outstream);
|
||||
/* Report I/O error such as disk full. */
|
||||
if (ferror(outstream) || fclose(outstream) != 0)
|
||||
err(1, "write_output: %s", output_filename);
|
||||
outstream = 0;
|
||||
}
|
||||
|
||||
/* Total number of symbols to be written in the output file. */
|
||||
@ -2493,7 +2559,7 @@ write_header()
|
||||
}
|
||||
|
||||
md_swapout_exec_hdr(&outheader);
|
||||
mywrite(&outheader, sizeof (struct exec), 1, outdesc);
|
||||
mywrite(&outheader, sizeof (struct exec), 1, outstream);
|
||||
md_swapin_exec_hdr(&outheader);
|
||||
|
||||
/*
|
||||
@ -2502,7 +2568,7 @@ write_header()
|
||||
*/
|
||||
|
||||
#ifndef COFF_ENCAPSULATE
|
||||
padfile(N_TXTOFF(outheader) - sizeof outheader, outdesc);
|
||||
padfile(N_TXTOFF(outheader) - sizeof outheader, outstream);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2523,7 +2589,7 @@ write_text()
|
||||
if (trace_files)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
padfile(text_pad, outdesc);
|
||||
padfile(text_pad, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2561,7 +2627,7 @@ copy_text(entry)
|
||||
entry->textrel, entry->ntextrel, entry, 0);
|
||||
|
||||
/* Write the relocated text to the output file. */
|
||||
mywrite(bytes, 1, entry->header.a_text, outdesc);
|
||||
mywrite(bytes, 1, entry->header.a_text, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2578,8 +2644,8 @@ write_data()
|
||||
fprintf(stderr, "Copying and relocating data:\n\n");
|
||||
|
||||
pos = N_DATOFF(outheader) + data_start - rrs_data_start;
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
errx(1, "write_data: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
errx(1, "write_data: fseek");
|
||||
|
||||
each_full_file(copy_data, 0);
|
||||
file_close();
|
||||
@ -2592,13 +2658,13 @@ write_data()
|
||||
if (set_vector_count) {
|
||||
swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
|
||||
mywrite(set_vectors, set_symbol_count + 2*set_vector_count,
|
||||
sizeof (unsigned long), outdesc);
|
||||
sizeof (unsigned long), outstream);
|
||||
}
|
||||
|
||||
if (trace_files)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
padfile(data_pad, outdesc);
|
||||
padfile(data_pad, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2632,7 +2698,7 @@ copy_data(entry)
|
||||
perform_relocation(bytes, entry->header.a_data,
|
||||
entry->datarel, entry->ndatarel, entry, 1);
|
||||
|
||||
mywrite(bytes, 1, entry->header.a_data, outdesc);
|
||||
mywrite(bytes, 1, entry->header.a_data, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2693,6 +2759,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
get_file_name(entry));
|
||||
|
||||
sp = lsp->symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
if (sp->alias)
|
||||
sp = sp->alias;
|
||||
|
||||
@ -2733,6 +2802,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
get_file_name(entry));
|
||||
|
||||
sp = entry->symbols[symindex].symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
if (sp->alias)
|
||||
sp = sp->alias;
|
||||
|
||||
@ -2817,8 +2889,10 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
entry->data_start_address:
|
||||
entry->text_start_address;
|
||||
relocation = addend;
|
||||
if (claim_rrs_reloc(
|
||||
entry, r, sp, &relocation))
|
||||
if ((building_shared_object ||
|
||||
sp->so_defined) &&
|
||||
claim_rrs_reloc(entry, r, sp,
|
||||
&relocation))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -3041,7 +3115,7 @@ coptxtrel(entry)
|
||||
}
|
||||
md_swapout_reloc(entry->textrel, entry->ntextrel);
|
||||
mywrite(entry->textrel, entry->ntextrel,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3106,7 +3180,7 @@ copdatrel(entry)
|
||||
}
|
||||
md_swapout_reloc(entry->datarel, entry->ndatarel);
|
||||
mywrite(entry->datarel, entry->ndatarel,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
}
|
||||
|
||||
void write_file_syms __P((struct file_entry *, int *));
|
||||
@ -3114,15 +3188,15 @@ void write_string_table __P((void));
|
||||
|
||||
/* Offsets and current lengths of symbol and string tables in output file. */
|
||||
|
||||
static int symbol_table_offset;
|
||||
static int symbol_table_len;
|
||||
static int symtab_offset;
|
||||
static int symtab_len;
|
||||
|
||||
/* Address in output file where string table starts. */
|
||||
static int string_table_offset;
|
||||
static int strtab_offset;
|
||||
|
||||
/* Offset within string table
|
||||
where the strings in `strtab_vector' should be written. */
|
||||
static int string_table_len;
|
||||
static int strtab_len;
|
||||
|
||||
/* Total size of string table strings allocated so far,
|
||||
including strings in `strtab_vector'. */
|
||||
@ -3157,8 +3231,6 @@ assign_string_table_index(name)
|
||||
return index;
|
||||
}
|
||||
|
||||
FILE *outstream = (FILE *)0;
|
||||
|
||||
/*
|
||||
* Write the contents of `strtab_vector' into the string table. This is done
|
||||
* once for each file's local&debugger symbols and once for the global
|
||||
@ -3169,23 +3241,13 @@ write_string_table()
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (lseek(outdesc, string_table_offset + string_table_len, 0) ==
|
||||
(off_t)-1)
|
||||
err(1, "write_string_table: %s: lseek", output_filename);
|
||||
|
||||
if (!outstream)
|
||||
outstream = fdopen(outdesc, "w");
|
||||
if (fseek(outstream, strtab_offset + strtab_len, SEEK_SET) != 0)
|
||||
err(1, "write_string_table: %s: fseek", output_filename);
|
||||
|
||||
for (i = 0; i < strtab_index; i++) {
|
||||
fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
|
||||
string_table_len += strtab_lens[i];
|
||||
mywrite(strtab_vector[i], 1, strtab_lens[i], outstream);
|
||||
strtab_len += strtab_lens[i];
|
||||
}
|
||||
|
||||
fflush(outstream);
|
||||
|
||||
/* Report I/O error such as disk full. */
|
||||
if (ferror(outstream))
|
||||
err(1, "write_string_table: %s", output_filename);
|
||||
}
|
||||
|
||||
/* Write the symbol table and string table of the output file. */
|
||||
@ -3209,10 +3271,10 @@ write_syms()
|
||||
/* Size of string table includes the bytes that store the size. */
|
||||
strtab_size = sizeof strtab_size;
|
||||
|
||||
symbol_table_offset = N_SYMOFF(outheader);
|
||||
symbol_table_len = 0;
|
||||
string_table_offset = N_STROFF(outheader);
|
||||
string_table_len = strtab_size;
|
||||
symtab_offset = N_SYMOFF(outheader);
|
||||
symtab_len = 0;
|
||||
strtab_offset = N_STROFF(outheader);
|
||||
strtab_len = strtab_size;
|
||||
|
||||
if (strip_symbols == STRIP_ALL)
|
||||
return;
|
||||
@ -3300,9 +3362,10 @@ write_syms()
|
||||
* these, symbol was discounted in digest_pass1()
|
||||
* (they are in the RRS symbol table).
|
||||
*/
|
||||
if (!building_shared_object)
|
||||
if (building_shared_object)
|
||||
continue;
|
||||
if (!(sp->flags & GS_WEAK))
|
||||
warnx("symbol %s remains undefined", sp->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (syms_written >= global_sym_count)
|
||||
@ -3332,6 +3395,8 @@ write_syms()
|
||||
nl.n_value = sp->alias->value;
|
||||
nl.n_other = N_OTHER(0, sp->alias->aux);
|
||||
} else {
|
||||
int bind = 0;
|
||||
|
||||
if (sp->defined == N_SIZE)
|
||||
nl.n_type = N_DATA | N_EXT;
|
||||
else
|
||||
@ -3341,7 +3406,9 @@ write_syms()
|
||||
errx(1, "%s: N_INDR has value %#x",
|
||||
sp->name, sp->value);
|
||||
nl.n_value = sp->value;
|
||||
nl.n_other = N_OTHER(0, sp->aux);
|
||||
if (sp->def_lsp)
|
||||
bind = N_BIND(&sp->def_lsp->nzlist.nlist);
|
||||
nl.n_other = N_OTHER(bind, sp->aux);
|
||||
}
|
||||
|
||||
} else if (sp->common_size) {
|
||||
@ -3411,18 +3478,17 @@ printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (syms_written != strtab_index || strtab_index != global_sym_count)
|
||||
errx(1, "internal error:\
|
||||
wrong number (%d) of global symbols written into output file, should be %d",
|
||||
syms_written, global_sym_count);
|
||||
errx(1, "internal error: wrong number (%d) of global symbols "
|
||||
"written into output file, should be %d",
|
||||
syms_written, global_sym_count);
|
||||
|
||||
/* Output the buffer full of `struct nlist's. */
|
||||
|
||||
if (lseek(outdesc, symbol_table_offset + symbol_table_len, 0) ==
|
||||
(off_t)-1)
|
||||
err(1, "write_syms: lseek");
|
||||
if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
|
||||
err(1, "write_syms: fseek");
|
||||
md_swapout_symbols(buf, bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
|
||||
symbol_table_len += sizeof(struct nlist) * (bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
|
||||
symtab_len += sizeof(struct nlist) * (bufp - buf);
|
||||
|
||||
/* Write the strings for the global symbols. */
|
||||
write_string_table();
|
||||
@ -3432,18 +3498,19 @@ wrong number (%d) of global symbols written into output file, should be %d",
|
||||
file_close();
|
||||
|
||||
if (syms_written != nsyms)
|
||||
errx(1, "internal error:\
|
||||
wrong number of symbols (%d) written into output file, should be %d",
|
||||
syms_written, nsyms);
|
||||
errx(1, "internal error: wrong number of symbols (%d) "
|
||||
"written into output file, should be %d",
|
||||
syms_written, nsyms);
|
||||
|
||||
if (symbol_table_offset + symbol_table_len != string_table_offset)
|
||||
if (symtab_offset + symtab_len != strtab_offset)
|
||||
errx(1,
|
||||
"internal error: inconsistent symbol table length: %d vs %s",
|
||||
symbol_table_offset + symbol_table_len, string_table_offset);
|
||||
symtab_offset + symtab_len, strtab_offset);
|
||||
|
||||
lseek(outdesc, string_table_offset, 0);
|
||||
if (fseek(outstream, strtab_offset, SEEK_SET) != 0)
|
||||
err(1, "write_syms: fseek");
|
||||
strtab_size = md_swap_long(strtab_size);
|
||||
mywrite(&strtab_size, sizeof(int), 1, outdesc);
|
||||
mywrite(&strtab_size, sizeof(int), 1, outstream);
|
||||
}
|
||||
|
||||
|
||||
@ -3543,10 +3610,11 @@ write_file_syms(entry, syms_written_addr)
|
||||
|
||||
/* All the symbols are now in BUF; write them. */
|
||||
|
||||
lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
|
||||
if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
|
||||
err(1, "write local symbols: fseek");
|
||||
md_swapout_symbols(buf, bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
|
||||
symbol_table_len += sizeof(struct nlist) * (bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
|
||||
symtab_len += sizeof(struct nlist) * (bufp - buf);
|
||||
|
||||
/*
|
||||
* Write the string-table data for the symbols just written, using
|
||||
@ -3582,18 +3650,11 @@ mywrite(buf, count, eltsize, fd)
|
||||
void *buf;
|
||||
int count;
|
||||
int eltsize;
|
||||
int fd;
|
||||
FILE *fd;
|
||||
{
|
||||
register int val;
|
||||
register int bytes = count * eltsize;
|
||||
|
||||
while (bytes > 0) {
|
||||
val = write(fd, buf, bytes);
|
||||
if (val <= 0)
|
||||
err(1, "write: %s", output_filename);
|
||||
buf += val;
|
||||
bytes -= val;
|
||||
}
|
||||
if (fwrite(buf, eltsize, count, fd) != count)
|
||||
err(1, "write");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3601,10 +3662,10 @@ cleanup()
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (outdesc <= 0)
|
||||
if (outstream == 0)
|
||||
return;
|
||||
|
||||
if (fstat(outdesc, &statbuf) == 0) {
|
||||
if (fstat(fileno(outstream), &statbuf) == 0) {
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
(void)unlink(output_filename);
|
||||
}
|
||||
@ -3616,8 +3677,8 @@ cleanup()
|
||||
*/
|
||||
void
|
||||
padfile(padding, fd)
|
||||
int padding;
|
||||
int fd;
|
||||
int padding;
|
||||
FILE *fd;
|
||||
{
|
||||
register char *buf;
|
||||
if (padding <= 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ld.h,v 1.15 1994/11/30 18:25:00 pk Exp $
|
||||
* $Id: ld.h,v 1.16 1994/12/23 20:32:57 pk Exp $
|
||||
*/
|
||||
/*-
|
||||
* This code is derived from software copyrighted by the Free Software
|
||||
@ -323,7 +323,6 @@ extern int netzmagic;
|
||||
|
||||
|
||||
#ifndef __GNU_STAB__
|
||||
|
||||
/* Line number for the data section. This is to be used to describe
|
||||
the source location of a variable declaration. */
|
||||
#ifndef N_DSLINE
|
||||
@ -335,9 +334,10 @@ extern int netzmagic;
|
||||
#ifndef N_BSLINE
|
||||
#define N_BSLINE (N_SLINE+N_BSS-N_TEXT)
|
||||
#endif
|
||||
|
||||
#endif /* not __GNU_STAB__ */
|
||||
|
||||
|
||||
#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
|
||||
|
||||
|
||||
typedef struct localsymbol {
|
||||
struct nzlist nzlist; /* n[z]list from file */
|
||||
@ -402,14 +402,15 @@ typedef struct glosym {
|
||||
|
||||
long flags;
|
||||
|
||||
#define GS_DEFINED 1 /* Symbol has definition (notyetused)*/
|
||||
#define GS_REFERENCED 2 /* Symbol is referred to by something
|
||||
#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
|
||||
#define GS_REFERENCED 0x2 /* Symbol is referred to by something
|
||||
interesting */
|
||||
#define GS_TRACE 4 /* Symbol will be traced */
|
||||
#define GS_HASJMPSLOT 8 /* */
|
||||
#define GS_TRACE 0x4 /* Symbol will be traced */
|
||||
#define GS_HASJMPSLOT 0x8 /* */
|
||||
#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
|
||||
#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
|
||||
#define GS_CPYRELOCCLAIMED 0x40 /* */
|
||||
#define GS_WEAK 0x80 /* Symbol is weakly defined */
|
||||
|
||||
} symbol;
|
||||
|
||||
@ -429,6 +430,9 @@ extern symbol *symtab[];
|
||||
/* # of global symbols referenced and not defined. */
|
||||
extern int undefined_global_sym_count;
|
||||
|
||||
/* # of weak symbols referenced and not defined. */
|
||||
extern int undefined_weak_sym_count;
|
||||
|
||||
/* # of undefined symbols referenced by shared objects */
|
||||
extern int undefined_shobj_sym_count;
|
||||
|
||||
@ -589,7 +593,7 @@ extern int link_mode;
|
||||
#define SHAREABLE 8 /* Build a shared object */
|
||||
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
|
||||
|
||||
extern int outdesc; /* Output file descriptor. */
|
||||
extern FILE *outstream; /* Output file. */
|
||||
extern struct exec outheader; /* Output file header. */
|
||||
extern int magic; /* Output file magic. */
|
||||
extern int oldmagic;
|
||||
@ -615,8 +619,8 @@ int file_open __P((struct file_entry *));
|
||||
void each_file __P((void (*)(), void *));
|
||||
void each_full_file __P((void (*)(), void *));
|
||||
unsigned long check_each_file __P((unsigned long (*)(), void *));
|
||||
void mywrite __P((void *, int, int, int));
|
||||
void padfile __P((int,int));
|
||||
void mywrite __P((void *, int, int, FILE *));
|
||||
void padfile __P((int, FILE *));
|
||||
|
||||
/* In warnings.c: */
|
||||
void perror_name __P((char *));
|
||||
|
@ -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.38 1994/12/17 16:22:57 pk Exp $
|
||||
* $Id: ld.c,v 1.39 1994/12/23 20:32:51 pk Exp $
|
||||
*/
|
||||
|
||||
/* Define how to initialize system-dependent header fields. */
|
||||
@ -135,7 +135,7 @@ int input_desc;
|
||||
|
||||
/* The name of the file to write; "a.out" by default. */
|
||||
char *output_filename; /* Output file name. */
|
||||
int outdesc; /* Output file descriptor. */
|
||||
FILE *outstream; /* Output file descriptor. */
|
||||
struct exec outheader; /* Output file header. */
|
||||
int magic; /* Output file magic. */
|
||||
int oldmagic;
|
||||
@ -183,11 +183,15 @@ int undefined_shobj_sym_count; /* # of undefined symbols referenced
|
||||
int multiple_def_count; /* # of multiply defined symbols. */
|
||||
int defined_global_sym_count; /* # of defined global symbols. */
|
||||
int common_defined_global_count; /* # of common symbols. */
|
||||
int undefined_weak_sym_count; /* # of weak symbols referenced and
|
||||
not defined. */
|
||||
|
||||
#if notused
|
||||
int special_sym_count; /* # of linker defined symbols. */
|
||||
/* XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
|
||||
* perhaps _etext, _edata and _end should go here too.
|
||||
*/
|
||||
#endif
|
||||
int global_alias_count; /* # of aliased symbols */
|
||||
int set_symbol_count; /* # of N_SET* symbols. */
|
||||
int set_vector_count; /* # of set vectors in output. */
|
||||
@ -1384,6 +1388,8 @@ enter_global_ref(lsp, name, entry)
|
||||
/*
|
||||
* This is an ex common...
|
||||
*/
|
||||
if (com)
|
||||
common_defined_global_count--;
|
||||
sp->common_size = 0;
|
||||
sp->defined = 0;
|
||||
}
|
||||
@ -1429,32 +1435,72 @@ enter_global_ref(lsp, name, entry)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef N_SIZE
|
||||
if (olddef && N_ISWEAK(&nzp->nlist) && !(sp->flags & GS_WEAK)) {
|
||||
#ifdef DEBUG
|
||||
printf("%s: not overridden by weak symbol from %s\n",
|
||||
sp->name, get_file_name(entry));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
#endif
|
||||
if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
|
||||
|
||||
} else if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
|
||||
|
||||
/*
|
||||
* Set `->defined' here, so commons and undefined globals
|
||||
* can be counted correctly.
|
||||
*/
|
||||
if (!sp->defined || sp->defined == (N_UNDF | N_EXT))
|
||||
if (!sp->defined || sp->defined == (N_UNDF | N_EXT)) {
|
||||
sp->defined = type;
|
||||
}
|
||||
|
||||
if (oldref && !olddef)
|
||||
if ((sp->flags & GS_WEAK) && !N_ISWEAK(&nzp->nlist)) {
|
||||
/*
|
||||
* Upgrade an existing weak definition.
|
||||
* We fake it by pretending the symbol is undefined;
|
||||
* must undo any common fiddling, however.
|
||||
*/
|
||||
if (!oldref)
|
||||
errx(1, "internal error: enter_glob_ref: "
|
||||
"weak symbol not referenced");
|
||||
if (!olddef && !com)
|
||||
undefined_weak_sym_count--;
|
||||
undefined_global_sym_count++;
|
||||
sp->defined = type;
|
||||
sp->flags &= ~GS_WEAK;
|
||||
olddef = 0;
|
||||
if (com)
|
||||
common_defined_global_count--;
|
||||
com = 0;
|
||||
sp->common_size = 0;
|
||||
}
|
||||
if (oldref && !olddef) {
|
||||
/*
|
||||
* It used to be undefined and we're defining it.
|
||||
*/
|
||||
undefined_global_sym_count--;
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1,
|
||||
"internal error: enter_glob_ref: undefined_global_sym_count = %d",
|
||||
undefined_global_sym_count);
|
||||
if (sp->flags & GS_WEAK)
|
||||
/* Used to be a weak reference */
|
||||
undefined_weak_sym_count--;
|
||||
if (undefined_global_sym_count < 0 ||
|
||||
undefined_weak_sym_count < 0)
|
||||
errx(1, "internal error: enter_glob_ref: "
|
||||
"undefined_global_sym_count = %d, "
|
||||
"undefined_weak_sym_count = %d",
|
||||
undefined_global_sym_count,
|
||||
undefined_weak_sym_count);
|
||||
|
||||
}
|
||||
|
||||
if (N_ISWEAK(&nzp->nlist))
|
||||
/* The definition is weak */
|
||||
sp->flags |= GS_WEAK;
|
||||
|
||||
if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
|
||||
/*
|
||||
@ -1480,13 +1526,18 @@ enter_global_ref(lsp, name, entry)
|
||||
if (SET_ELEMENT_P(type) && (!olddef || com))
|
||||
set_vector_count++;
|
||||
|
||||
} else if (!oldref && !com)
|
||||
} else if (!oldref && !com) {
|
||||
/*
|
||||
* An unreferenced symbol can already be defined
|
||||
* as common by shared objects.
|
||||
*/
|
||||
undefined_global_sym_count++;
|
||||
|
||||
if (N_ISWEAK(&nzp->nlist)) {
|
||||
/* The reference is weak */
|
||||
sp->flags |= GS_WEAK;
|
||||
undefined_weak_sym_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
|
||||
!T_flag_specified)
|
||||
@ -1496,8 +1547,8 @@ enter_global_ref(lsp, name, entry)
|
||||
register char *reftype;
|
||||
switch (type & N_TYPE) {
|
||||
case N_UNDF:
|
||||
reftype = nzp->nz_value?
|
||||
"defined as common":"referenced";
|
||||
reftype = nzp->nz_value
|
||||
? "defined as common" : "referenced";
|
||||
break;
|
||||
|
||||
case N_ABS:
|
||||
@ -1529,7 +1580,8 @@ enter_global_ref(lsp, name, entry)
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "symbol %s %s in ", sp->name, reftype);
|
||||
fprintf(stderr, "symbol %s %s%s in ", sp->name,
|
||||
(N_ISWEAK(&nzp->nlist))?"weakly ":"", reftype);
|
||||
print_file_name (entry, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
@ -1716,17 +1768,20 @@ printf("set_sect_start = %#x, set_sect_size = %#x\n",
|
||||
}
|
||||
|
||||
if (relocatable_output)
|
||||
/* We write out the original N_SET* symbols */
|
||||
/* We write out the original N_SIZE symbols */
|
||||
global_sym_count += size_sym_count;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(
|
||||
"global symbols %d (defined %d, undefined %d, aliases %d, warnings 2 * %d, \
|
||||
size symbols %d), locals: %d, debug symbols: %d, set_symbols %d\n",
|
||||
"global symbols %d "
|
||||
"(defined %d, undefined %d, weak %d, aliases %d, warnings 2 * %d, "
|
||||
"size symbols %d)\ncommons %d, locals: %d, debug symbols: %d, set_symbols %d\n",
|
||||
global_sym_count,
|
||||
defined_global_sym_count, undefined_global_sym_count,
|
||||
undefined_weak_sym_count,
|
||||
global_alias_count, warn_sym_count, size_sym_count,
|
||||
local_sym_count, debugger_sym_count, set_symbol_count);
|
||||
common_defined_global_count, local_sym_count,
|
||||
debugger_sym_count, set_symbol_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1812,20 +1867,18 @@ digest_pass1()
|
||||
&& (type & N_TYPE) != N_FN
|
||||
&& (type & N_TYPE) != N_SIZE) {
|
||||
/* non-common definition */
|
||||
#if 0
|
||||
if (defs++ && sp->value != p->n_value
|
||||
&& entry_symbol/*XXX*/) {
|
||||
#endif
|
||||
if (defs++ &&
|
||||
sp->def_lsp &&
|
||||
sp->def_lsp->nzlist.nz_value != p->n_value) {
|
||||
if (!N_ISWEAK(p))
|
||||
++defs;
|
||||
if (defs > 1) {
|
||||
sp->mult_defs = 1;
|
||||
multiple_def_count++;
|
||||
} else if (!N_ISWEAK(p) ||
|
||||
(!sp->def_lsp && !sp->common_size)) {
|
||||
sp->def_lsp = lsp;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
sp->defined = type;
|
||||
sp->aux = N_AUX(p);
|
||||
}
|
||||
sp->def_lsp = lsp;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
sp->defined = type;
|
||||
sp->aux = N_AUX(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1877,32 +1930,39 @@ digest_pass1()
|
||||
if (lsp->entry->flags & E_SECONDCLASS)
|
||||
/* Keep looking for something better */
|
||||
continue;
|
||||
lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
if (sp->flags & GS_REFERENCED)
|
||||
undefined_global_sym_count--;
|
||||
else
|
||||
sp->flags |= GS_REFERENCED;
|
||||
if (N_ISWEAK(p))
|
||||
/* Keep looking for something better */
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sp->def_lsp) {
|
||||
#ifdef DEBUG
|
||||
printf("pass1: SO definition for %s, type %x in %s at %#x\n",
|
||||
sp->name, type, get_file_name(lsp->entry), p->n_value);
|
||||
sp->name, sp->so_defined, get_file_name(sp->def_lsp->entry),
|
||||
sp->def_lsp->nzlist.nz_value);
|
||||
#endif
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1,
|
||||
"internal error: digest_pass1,2: %s: undefined_global_sym_count = %d",
|
||||
sp->def_lsp->entry->flags |= E_SYMBOLS_USED;
|
||||
if (sp->flags & GS_REFERENCED)
|
||||
undefined_global_sym_count--;
|
||||
else
|
||||
sp->flags |= GS_REFERENCED;
|
||||
if (undefined_global_sym_count < 0)
|
||||
errx(1, "internal error: digest_pass1,2: "
|
||||
"%s: undefined_global_sym_count = %d",
|
||||
sp->name, undefined_global_sym_count);
|
||||
if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
|
||||
sp = sp->alias;
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
if (sp->alias &&
|
||||
!(sp->alias->flags & GS_REFERENCED)) {
|
||||
sp = sp->alias;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
sp=spsave;
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (setv_fill_count != set_sect_size/sizeof(long))
|
||||
errx(1, "internal error: allocated set symbol space (%d) \
|
||||
doesn't match actual (%d)",
|
||||
errx(1, "internal error: allocated set symbol space (%d) "
|
||||
"doesn't match actual (%d)",
|
||||
set_sect_size/sizeof(long), setv_fill_count);
|
||||
}
|
||||
|
||||
@ -2007,7 +2067,7 @@ consider_relocation(entry, dataseg)
|
||||
lsp = &entry->symbols[reloc->r_symbolnum];
|
||||
sp = lsp->symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: internal error, sp==NULL",
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
|
||||
if (sp->alias)
|
||||
@ -2051,7 +2111,8 @@ consider_relocation(entry, dataseg)
|
||||
alloc_rrs_cpy_reloc(entry, sp);
|
||||
sp->defined = N_SIZE;
|
||||
|
||||
} else if (!sp->defined && sp->common_size == 0)
|
||||
} else if (!sp->defined && sp->common_size == 0 &&
|
||||
sp->so_defined)
|
||||
alloc_rrs_reloc(entry, sp);
|
||||
|
||||
} else {
|
||||
@ -2408,19 +2469,21 @@ write_output()
|
||||
(void)unlink(output_filename);
|
||||
}
|
||||
|
||||
outdesc = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (outdesc < 0)
|
||||
outstream = fopen(output_filename, "w");
|
||||
if (outstream == NULL)
|
||||
err(1, "open: %s", output_filename);
|
||||
|
||||
if (atexit(cleanup))
|
||||
err(1, "atexit");
|
||||
|
||||
if (fstat (outdesc, &statbuf) < 0)
|
||||
if (fstat(fileno(outstream), &statbuf) < 0)
|
||||
err(1, "fstat: %s", output_filename);
|
||||
|
||||
filemode = statbuf.st_mode;
|
||||
|
||||
chmod (output_filename, filemode & ~0111);
|
||||
if (S_ISREG(statbuf.st_mode) &&
|
||||
chmod(output_filename, filemode & ~0111) == -1)
|
||||
err(1, "chmod: %s", output_filename);
|
||||
|
||||
/* Output the a.out header. */
|
||||
write_header();
|
||||
@ -2442,8 +2505,11 @@ write_output()
|
||||
if (chmod (output_filename, filemode | 0111) == -1)
|
||||
err(1, "chmod: %s", output_filename);
|
||||
|
||||
close(outdesc);
|
||||
outdesc = 0;
|
||||
fflush(outstream);
|
||||
/* Report I/O error such as disk full. */
|
||||
if (ferror(outstream) || fclose(outstream) != 0)
|
||||
err(1, "write_output: %s", output_filename);
|
||||
outstream = 0;
|
||||
}
|
||||
|
||||
/* Total number of symbols to be written in the output file. */
|
||||
@ -2493,7 +2559,7 @@ write_header()
|
||||
}
|
||||
|
||||
md_swapout_exec_hdr(&outheader);
|
||||
mywrite(&outheader, sizeof (struct exec), 1, outdesc);
|
||||
mywrite(&outheader, sizeof (struct exec), 1, outstream);
|
||||
md_swapin_exec_hdr(&outheader);
|
||||
|
||||
/*
|
||||
@ -2502,7 +2568,7 @@ write_header()
|
||||
*/
|
||||
|
||||
#ifndef COFF_ENCAPSULATE
|
||||
padfile(N_TXTOFF(outheader) - sizeof outheader, outdesc);
|
||||
padfile(N_TXTOFF(outheader) - sizeof outheader, outstream);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2523,7 +2589,7 @@ write_text()
|
||||
if (trace_files)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
padfile(text_pad, outdesc);
|
||||
padfile(text_pad, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2561,7 +2627,7 @@ copy_text(entry)
|
||||
entry->textrel, entry->ntextrel, entry, 0);
|
||||
|
||||
/* Write the relocated text to the output file. */
|
||||
mywrite(bytes, 1, entry->header.a_text, outdesc);
|
||||
mywrite(bytes, 1, entry->header.a_text, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2578,8 +2644,8 @@ write_data()
|
||||
fprintf(stderr, "Copying and relocating data:\n\n");
|
||||
|
||||
pos = N_DATOFF(outheader) + data_start - rrs_data_start;
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
errx(1, "write_data: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
errx(1, "write_data: fseek");
|
||||
|
||||
each_full_file(copy_data, 0);
|
||||
file_close();
|
||||
@ -2592,13 +2658,13 @@ write_data()
|
||||
if (set_vector_count) {
|
||||
swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
|
||||
mywrite(set_vectors, set_symbol_count + 2*set_vector_count,
|
||||
sizeof (unsigned long), outdesc);
|
||||
sizeof (unsigned long), outstream);
|
||||
}
|
||||
|
||||
if (trace_files)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
padfile(data_pad, outdesc);
|
||||
padfile(data_pad, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2632,7 +2698,7 @@ copy_data(entry)
|
||||
perform_relocation(bytes, entry->header.a_data,
|
||||
entry->datarel, entry->ndatarel, entry, 1);
|
||||
|
||||
mywrite(bytes, 1, entry->header.a_data, outdesc);
|
||||
mywrite(bytes, 1, entry->header.a_data, outstream);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2693,6 +2759,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
get_file_name(entry));
|
||||
|
||||
sp = lsp->symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
if (sp->alias)
|
||||
sp = sp->alias;
|
||||
|
||||
@ -2733,6 +2802,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
get_file_name(entry));
|
||||
|
||||
sp = entry->symbols[symindex].symbol;
|
||||
if (sp == NULL)
|
||||
errx(1, "%s: bogus relocation record",
|
||||
get_file_name(entry));
|
||||
if (sp->alias)
|
||||
sp = sp->alias;
|
||||
|
||||
@ -2817,8 +2889,10 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
|
||||
entry->data_start_address:
|
||||
entry->text_start_address;
|
||||
relocation = addend;
|
||||
if (claim_rrs_reloc(
|
||||
entry, r, sp, &relocation))
|
||||
if ((building_shared_object ||
|
||||
sp->so_defined) &&
|
||||
claim_rrs_reloc(entry, r, sp,
|
||||
&relocation))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -3041,7 +3115,7 @@ coptxtrel(entry)
|
||||
}
|
||||
md_swapout_reloc(entry->textrel, entry->ntextrel);
|
||||
mywrite(entry->textrel, entry->ntextrel,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3106,7 +3180,7 @@ copdatrel(entry)
|
||||
}
|
||||
md_swapout_reloc(entry->datarel, entry->ndatarel);
|
||||
mywrite(entry->datarel, entry->ndatarel,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
}
|
||||
|
||||
void write_file_syms __P((struct file_entry *, int *));
|
||||
@ -3114,15 +3188,15 @@ void write_string_table __P((void));
|
||||
|
||||
/* Offsets and current lengths of symbol and string tables in output file. */
|
||||
|
||||
static int symbol_table_offset;
|
||||
static int symbol_table_len;
|
||||
static int symtab_offset;
|
||||
static int symtab_len;
|
||||
|
||||
/* Address in output file where string table starts. */
|
||||
static int string_table_offset;
|
||||
static int strtab_offset;
|
||||
|
||||
/* Offset within string table
|
||||
where the strings in `strtab_vector' should be written. */
|
||||
static int string_table_len;
|
||||
static int strtab_len;
|
||||
|
||||
/* Total size of string table strings allocated so far,
|
||||
including strings in `strtab_vector'. */
|
||||
@ -3157,8 +3231,6 @@ assign_string_table_index(name)
|
||||
return index;
|
||||
}
|
||||
|
||||
FILE *outstream = (FILE *)0;
|
||||
|
||||
/*
|
||||
* Write the contents of `strtab_vector' into the string table. This is done
|
||||
* once for each file's local&debugger symbols and once for the global
|
||||
@ -3169,23 +3241,13 @@ write_string_table()
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (lseek(outdesc, string_table_offset + string_table_len, 0) ==
|
||||
(off_t)-1)
|
||||
err(1, "write_string_table: %s: lseek", output_filename);
|
||||
|
||||
if (!outstream)
|
||||
outstream = fdopen(outdesc, "w");
|
||||
if (fseek(outstream, strtab_offset + strtab_len, SEEK_SET) != 0)
|
||||
err(1, "write_string_table: %s: fseek", output_filename);
|
||||
|
||||
for (i = 0; i < strtab_index; i++) {
|
||||
fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
|
||||
string_table_len += strtab_lens[i];
|
||||
mywrite(strtab_vector[i], 1, strtab_lens[i], outstream);
|
||||
strtab_len += strtab_lens[i];
|
||||
}
|
||||
|
||||
fflush(outstream);
|
||||
|
||||
/* Report I/O error such as disk full. */
|
||||
if (ferror(outstream))
|
||||
err(1, "write_string_table: %s", output_filename);
|
||||
}
|
||||
|
||||
/* Write the symbol table and string table of the output file. */
|
||||
@ -3209,10 +3271,10 @@ write_syms()
|
||||
/* Size of string table includes the bytes that store the size. */
|
||||
strtab_size = sizeof strtab_size;
|
||||
|
||||
symbol_table_offset = N_SYMOFF(outheader);
|
||||
symbol_table_len = 0;
|
||||
string_table_offset = N_STROFF(outheader);
|
||||
string_table_len = strtab_size;
|
||||
symtab_offset = N_SYMOFF(outheader);
|
||||
symtab_len = 0;
|
||||
strtab_offset = N_STROFF(outheader);
|
||||
strtab_len = strtab_size;
|
||||
|
||||
if (strip_symbols == STRIP_ALL)
|
||||
return;
|
||||
@ -3300,9 +3362,10 @@ write_syms()
|
||||
* these, symbol was discounted in digest_pass1()
|
||||
* (they are in the RRS symbol table).
|
||||
*/
|
||||
if (!building_shared_object)
|
||||
if (building_shared_object)
|
||||
continue;
|
||||
if (!(sp->flags & GS_WEAK))
|
||||
warnx("symbol %s remains undefined", sp->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (syms_written >= global_sym_count)
|
||||
@ -3332,6 +3395,8 @@ write_syms()
|
||||
nl.n_value = sp->alias->value;
|
||||
nl.n_other = N_OTHER(0, sp->alias->aux);
|
||||
} else {
|
||||
int bind = 0;
|
||||
|
||||
if (sp->defined == N_SIZE)
|
||||
nl.n_type = N_DATA | N_EXT;
|
||||
else
|
||||
@ -3341,7 +3406,9 @@ write_syms()
|
||||
errx(1, "%s: N_INDR has value %#x",
|
||||
sp->name, sp->value);
|
||||
nl.n_value = sp->value;
|
||||
nl.n_other = N_OTHER(0, sp->aux);
|
||||
if (sp->def_lsp)
|
||||
bind = N_BIND(&sp->def_lsp->nzlist.nlist);
|
||||
nl.n_other = N_OTHER(bind, sp->aux);
|
||||
}
|
||||
|
||||
} else if (sp->common_size) {
|
||||
@ -3411,18 +3478,17 @@ printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (syms_written != strtab_index || strtab_index != global_sym_count)
|
||||
errx(1, "internal error:\
|
||||
wrong number (%d) of global symbols written into output file, should be %d",
|
||||
syms_written, global_sym_count);
|
||||
errx(1, "internal error: wrong number (%d) of global symbols "
|
||||
"written into output file, should be %d",
|
||||
syms_written, global_sym_count);
|
||||
|
||||
/* Output the buffer full of `struct nlist's. */
|
||||
|
||||
if (lseek(outdesc, symbol_table_offset + symbol_table_len, 0) ==
|
||||
(off_t)-1)
|
||||
err(1, "write_syms: lseek");
|
||||
if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
|
||||
err(1, "write_syms: fseek");
|
||||
md_swapout_symbols(buf, bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
|
||||
symbol_table_len += sizeof(struct nlist) * (bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
|
||||
symtab_len += sizeof(struct nlist) * (bufp - buf);
|
||||
|
||||
/* Write the strings for the global symbols. */
|
||||
write_string_table();
|
||||
@ -3432,18 +3498,19 @@ wrong number (%d) of global symbols written into output file, should be %d",
|
||||
file_close();
|
||||
|
||||
if (syms_written != nsyms)
|
||||
errx(1, "internal error:\
|
||||
wrong number of symbols (%d) written into output file, should be %d",
|
||||
syms_written, nsyms);
|
||||
errx(1, "internal error: wrong number of symbols (%d) "
|
||||
"written into output file, should be %d",
|
||||
syms_written, nsyms);
|
||||
|
||||
if (symbol_table_offset + symbol_table_len != string_table_offset)
|
||||
if (symtab_offset + symtab_len != strtab_offset)
|
||||
errx(1,
|
||||
"internal error: inconsistent symbol table length: %d vs %s",
|
||||
symbol_table_offset + symbol_table_len, string_table_offset);
|
||||
symtab_offset + symtab_len, strtab_offset);
|
||||
|
||||
lseek(outdesc, string_table_offset, 0);
|
||||
if (fseek(outstream, strtab_offset, SEEK_SET) != 0)
|
||||
err(1, "write_syms: fseek");
|
||||
strtab_size = md_swap_long(strtab_size);
|
||||
mywrite(&strtab_size, sizeof(int), 1, outdesc);
|
||||
mywrite(&strtab_size, sizeof(int), 1, outstream);
|
||||
}
|
||||
|
||||
|
||||
@ -3543,10 +3610,11 @@ write_file_syms(entry, syms_written_addr)
|
||||
|
||||
/* All the symbols are now in BUF; write them. */
|
||||
|
||||
lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
|
||||
if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
|
||||
err(1, "write local symbols: fseek");
|
||||
md_swapout_symbols(buf, bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
|
||||
symbol_table_len += sizeof(struct nlist) * (bufp - buf);
|
||||
mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
|
||||
symtab_len += sizeof(struct nlist) * (bufp - buf);
|
||||
|
||||
/*
|
||||
* Write the string-table data for the symbols just written, using
|
||||
@ -3582,18 +3650,11 @@ mywrite(buf, count, eltsize, fd)
|
||||
void *buf;
|
||||
int count;
|
||||
int eltsize;
|
||||
int fd;
|
||||
FILE *fd;
|
||||
{
|
||||
register int val;
|
||||
register int bytes = count * eltsize;
|
||||
|
||||
while (bytes > 0) {
|
||||
val = write(fd, buf, bytes);
|
||||
if (val <= 0)
|
||||
err(1, "write: %s", output_filename);
|
||||
buf += val;
|
||||
bytes -= val;
|
||||
}
|
||||
if (fwrite(buf, eltsize, count, fd) != count)
|
||||
err(1, "write");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3601,10 +3662,10 @@ cleanup()
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (outdesc <= 0)
|
||||
if (outstream == 0)
|
||||
return;
|
||||
|
||||
if (fstat(outdesc, &statbuf) == 0) {
|
||||
if (fstat(fileno(outstream), &statbuf) == 0) {
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
(void)unlink(output_filename);
|
||||
}
|
||||
@ -3616,8 +3677,8 @@ cleanup()
|
||||
*/
|
||||
void
|
||||
padfile(padding, fd)
|
||||
int padding;
|
||||
int fd;
|
||||
int padding;
|
||||
FILE *fd;
|
||||
{
|
||||
register char *buf;
|
||||
if (padding <= 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lib.c,v 1.14 1994/06/29 11:18:53 pk Exp $ - library routines
|
||||
* $Id: lib.c,v 1.15 1994/12/23 20:32:58 pk Exp $ - library routines
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -260,6 +260,12 @@ symdef_library(fd, entry, member_length)
|
||||
* be satisfied are 'common' references. This
|
||||
* prevents some problems with name pollution (e.g. a
|
||||
* global common 'utime' linked to a function).
|
||||
*
|
||||
* If we're not forcing the archive in then we don't
|
||||
* need to bother if: we've never heard of the symbol,
|
||||
* or if it is already defined. The last clause causes
|
||||
* archive members to be searched for definitions
|
||||
* satisfying undefined shared object symbols.
|
||||
*/
|
||||
if (!(link_mode & FORCEARCHIVE) &&
|
||||
(!sp || sp->defined ||
|
||||
@ -501,6 +507,9 @@ subfile_wanted_p(entry)
|
||||
sp->defined = type;
|
||||
continue;
|
||||
}
|
||||
if (sp->flags & GS_WEAK)
|
||||
/* Weak symbols don't pull archive members */
|
||||
continue;
|
||||
if (write_map) {
|
||||
print_file_name(entry, stdout);
|
||||
fprintf(stdout, " needed due to %s\n", sp->name);
|
||||
@ -542,8 +551,19 @@ subfile_wanted_p(entry)
|
||||
* a common; ignore it.
|
||||
*/
|
||||
continue;
|
||||
|
||||
if (N_ISWEAK(&lsp->nzlist.nlist))
|
||||
/* Weak symbols don't pull archive members */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, either the new symbol is a common
|
||||
* and the shared object reference is undefined --
|
||||
* in which case we note the common -- or the shared
|
||||
* object reference has a definition -- in which case
|
||||
* the library member takes precedence.
|
||||
*/
|
||||
if (iscommon) {
|
||||
/*
|
||||
* New symbol is common, just takes its
|
||||
@ -565,8 +585,9 @@ subfile_wanted_p(entry)
|
||||
if (write_map) {
|
||||
print_file_name(entry, stdout);
|
||||
fprintf(stdout,
|
||||
" needed due to shared lib ref %s\n",
|
||||
sp->name);
|
||||
" needed due to shared lib ref %s (%d)\n",
|
||||
sp->name,
|
||||
lsp ? lsp->nzlist.nlist.n_type : -1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -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.14 1994/08/21 15:22:43 pk Exp $
|
||||
* $Id: rrs.c,v 1.15 1994/12/23 20:32:59 pk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -700,6 +700,8 @@ consider_rrs_section_lengths()
|
||||
|
||||
if (rrs_section_type == RRS_NONE) {
|
||||
got_symbol->defined = 0;
|
||||
if (reserved_rrs_relocs > 0)
|
||||
errx(1, "internal error: empty RRS has reservations");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -929,36 +931,37 @@ write_rrs_data()
|
||||
return;
|
||||
|
||||
pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
err(1, "write_rrs_data: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
err(1, "write_rrs_data: fseek");
|
||||
|
||||
if (rrs_section_type == RRS_PARTIAL) {
|
||||
/*
|
||||
* Only a GOT and PLT are needed.
|
||||
*/
|
||||
md_swapout_got(rrs_got, number_of_gotslots);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
|
||||
|
||||
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
|
||||
mywrite(rrs_plt, number_of_jmpslots,
|
||||
sizeof(jmpslot_t), outstream);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
md_swapout__dynamic(&rrs_dyn);
|
||||
mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
|
||||
mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outstream);
|
||||
|
||||
md_swapout_so_debug(&rrs_so_debug);
|
||||
mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
|
||||
mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outstream);
|
||||
|
||||
md_swapout_section_dispatch_table(&rrs_sdt);
|
||||
mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
|
||||
mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outstream);
|
||||
|
||||
md_swapout_got(rrs_got, number_of_gotslots);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
|
||||
|
||||
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outstream);
|
||||
}
|
||||
|
||||
void
|
||||
@ -971,23 +974,24 @@ write_rrs_text()
|
||||
int offset = 0;
|
||||
struct shobj *shp;
|
||||
struct sod *sodp;
|
||||
int bind;
|
||||
|
||||
if (rrs_section_type == RRS_PARTIAL)
|
||||
return;
|
||||
|
||||
pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
err(1, "write_rrs_text: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
err(1, "write_rrs_text: fseek");
|
||||
|
||||
/* Write relocation records */
|
||||
md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
|
||||
mywrite(rrs_reloc, reserved_rrs_relocs,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
|
||||
/* Write the RRS symbol hash tables */
|
||||
md_swapout_rrs_hash(rrs_hashtab, number_of_rrs_hash_entries);
|
||||
mywrite(rrs_hashtab, number_of_rrs_hash_entries,
|
||||
sizeof(struct rrs_hash), outdesc);
|
||||
sizeof(struct rrs_hash), outstream);
|
||||
|
||||
/*
|
||||
* Determine size of an RRS symbol entry, allocate space
|
||||
@ -1059,6 +1063,8 @@ write_rrs_text()
|
||||
if (LD_VERSION_NZLIST_P(soversion))
|
||||
nlp->nz_size = 0;
|
||||
|
||||
bind = (sp->flags & GS_WEAK) ? BIND_WEAK : 0;
|
||||
|
||||
if (sp->defined > 1) {
|
||||
/* defined with known type */
|
||||
if (!(link_mode & SHAREABLE) &&
|
||||
@ -1071,7 +1077,7 @@ write_rrs_text()
|
||||
*/
|
||||
nlp->nz_type = sp->alias->defined;
|
||||
nlp->nz_value = sp->alias->value;
|
||||
nlp->nz_other = N_OTHER(0, sp->alias->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->alias->aux);
|
||||
} else if (sp->defined == N_SIZE) {
|
||||
/*
|
||||
* Make sure this symbol isn't going
|
||||
@ -1082,28 +1088,32 @@ write_rrs_text()
|
||||
} else {
|
||||
nlp->nz_type = sp->defined;
|
||||
nlp->nz_value = sp->value;
|
||||
nlp->nz_other = N_OTHER(0, sp->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->aux);
|
||||
}
|
||||
if (LD_VERSION_NZLIST_P(soversion))
|
||||
nlp->nz_size = sp->size;
|
||||
} else if (sp->common_size) {
|
||||
/*
|
||||
* a common definition
|
||||
* A common definition.
|
||||
*/
|
||||
nlp->nz_type = N_UNDF | N_EXT;
|
||||
nlp->nz_value = sp->common_size;
|
||||
nlp->nz_other = N_OTHER(bind, 0);
|
||||
} else if (!sp->defined) {
|
||||
/* undefined */
|
||||
nlp->nz_type = N_UNDF | N_EXT;
|
||||
nlp->nz_value = 0;
|
||||
if (sp->so_defined && sp->jmpslot_offset != -1) {
|
||||
/*
|
||||
* Define a "weak" function symbol.
|
||||
* A PLT entry. The auxiliary type -- which
|
||||
* must be AUX_FUNC -- is used by the run-time
|
||||
* linker to unambiguously resolve function
|
||||
* address references.
|
||||
*/
|
||||
if (sp->aux != AUX_FUNC)
|
||||
errx(1, "%s: non-function jmpslot",
|
||||
sp->name);
|
||||
nlp->nz_other = N_OTHER(0, sp->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->aux);
|
||||
nlp->nz_value =
|
||||
rrs_sdt.sdt_plt + sp->jmpslot_offset;
|
||||
}
|
||||
@ -1148,10 +1158,10 @@ write_rrs_text()
|
||||
md_swapout_symbols(rrs_symbols, number_of_rrs_symbols);
|
||||
else
|
||||
md_swapout_zsymbols(rrs_symbols, number_of_rrs_symbols);
|
||||
mywrite(rrs_symbols, symsize, 1, outdesc);
|
||||
mywrite(rrs_symbols, symsize, 1, outstream);
|
||||
|
||||
/* Write the strings */
|
||||
mywrite(rrs_strtab, rrs_strtab_size, 1, outdesc);
|
||||
mywrite(rrs_strtab, rrs_strtab_size, 1, outstream);
|
||||
|
||||
/*
|
||||
* Write the names of the shared objects needed at run-time
|
||||
@ -1187,7 +1197,7 @@ write_rrs_text()
|
||||
number_of_shobjs);
|
||||
|
||||
md_swapout_sod(sodp, number_of_shobjs);
|
||||
mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
|
||||
mywrite(sodp, number_of_shobjs, sizeof(struct sod), outstream);
|
||||
|
||||
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
|
||||
char *name = shp->entry->local_sym_name;
|
||||
@ -1196,7 +1206,7 @@ write_rrs_text()
|
||||
name += 2;
|
||||
}
|
||||
|
||||
mywrite(name, strlen(name) + 1, 1, outdesc);
|
||||
mywrite(name, strlen(name) + 1, 1, outstream);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: warnings.c,v 1.16 1994/10/19 20:16:38 pk Exp $
|
||||
* $Id: warnings.c,v 1.17 1994/12/23 20:33:01 pk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
static int reported_undefineds;
|
||||
|
||||
/*
|
||||
* Print the filename of ENTRY on OUTFILE (a stdio stream),
|
||||
* and then a newline.
|
||||
@ -466,10 +468,11 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
/* Mark as being noted by relocation warning pass. */
|
||||
SET_BIT(nlist_bitvector, lsp - start_of_syms);
|
||||
|
||||
if (g->undef_refs == 0)
|
||||
reported_undefineds++;
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
/* Listed too many */
|
||||
continue;
|
||||
|
||||
/* Undefined symbol which we should mention */
|
||||
|
||||
if (++(g->undef_refs) == MAX_UREFS_PRINTED) {
|
||||
@ -647,10 +650,16 @@ do_file_warnings (entry, outfile)
|
||||
line_number = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np->n_type);
|
||||
case N_UNDF | N_EXT:
|
||||
/* Don't print out multiple defs at references.*/
|
||||
continue;
|
||||
|
||||
default:
|
||||
warnx("%s: unexpected multiple definitions "
|
||||
"of symbol `%s', type %#x",
|
||||
get_file_name(entry),
|
||||
g->name, np->n_type);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (BIT_SET_P(nlist_bitvector, i)) {
|
||||
@ -658,9 +667,10 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
} else if (list_unresolved_refs &&
|
||||
!g->defined && !g->so_defined) {
|
||||
|
||||
if (g->undef_refs == 0)
|
||||
reported_undefineds++;
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
continue;
|
||||
|
||||
if (++(g->undef_refs) == MAX_UREFS_PRINTED)
|
||||
errfmt = "More undefined `%s' refs follow";
|
||||
else
|
||||
@ -671,7 +681,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
g->def_lsp->entry->flags & E_SECONDCLASS) {
|
||||
fprintf(outfile,
|
||||
"%s: Undefined symbol `%s' referenced (use %s ?)\n",
|
||||
entry->filename,
|
||||
get_file_name(entry),
|
||||
g->name,
|
||||
g->def_lsp->entry->local_sym_name);
|
||||
continue;
|
||||
@ -693,7 +703,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
continue;
|
||||
|
||||
if (line_number == -1)
|
||||
fprintf(outfile, "%s: ", entry->filename);
|
||||
fprintf(outfile, "%s: ", get_file_name(entry));
|
||||
else
|
||||
fprintf(outfile, "%s:%d: ", file_name, line_number);
|
||||
|
||||
@ -714,7 +724,9 @@ do_warnings(outfile)
|
||||
FILE *outfile;
|
||||
{
|
||||
list_unresolved_refs = !relocatable_output &&
|
||||
(undefined_global_sym_count || undefined_shobj_sym_count);
|
||||
( (undefined_global_sym_count - undefined_weak_sym_count) > 0
|
||||
|| undefined_shobj_sym_count
|
||||
);
|
||||
list_multiple_defs = multiple_def_count != 0;
|
||||
|
||||
if (!(list_unresolved_refs ||
|
||||
@ -729,6 +741,13 @@ do_warnings(outfile)
|
||||
|
||||
each_file(do_file_warnings, (void *)outfile);
|
||||
|
||||
if (reported_undefineds !=
|
||||
(undefined_global_sym_count - undefined_weak_sym_count))
|
||||
warnx("Spurious undefined symbols: "
|
||||
"# undefined symbols %d, reported %d\n",
|
||||
(undefined_global_sym_count - undefined_weak_sym_count),
|
||||
reported_undefineds);
|
||||
|
||||
if (list_unresolved_refs || list_multiple_defs)
|
||||
return 0;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lib.c,v 1.14 1994/06/29 11:18:53 pk Exp $ - library routines
|
||||
* $Id: lib.c,v 1.15 1994/12/23 20:32:58 pk Exp $ - library routines
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -260,6 +260,12 @@ symdef_library(fd, entry, member_length)
|
||||
* be satisfied are 'common' references. This
|
||||
* prevents some problems with name pollution (e.g. a
|
||||
* global common 'utime' linked to a function).
|
||||
*
|
||||
* If we're not forcing the archive in then we don't
|
||||
* need to bother if: we've never heard of the symbol,
|
||||
* or if it is already defined. The last clause causes
|
||||
* archive members to be searched for definitions
|
||||
* satisfying undefined shared object symbols.
|
||||
*/
|
||||
if (!(link_mode & FORCEARCHIVE) &&
|
||||
(!sp || sp->defined ||
|
||||
@ -501,6 +507,9 @@ subfile_wanted_p(entry)
|
||||
sp->defined = type;
|
||||
continue;
|
||||
}
|
||||
if (sp->flags & GS_WEAK)
|
||||
/* Weak symbols don't pull archive members */
|
||||
continue;
|
||||
if (write_map) {
|
||||
print_file_name(entry, stdout);
|
||||
fprintf(stdout, " needed due to %s\n", sp->name);
|
||||
@ -542,8 +551,19 @@ subfile_wanted_p(entry)
|
||||
* a common; ignore it.
|
||||
*/
|
||||
continue;
|
||||
|
||||
if (N_ISWEAK(&lsp->nzlist.nlist))
|
||||
/* Weak symbols don't pull archive members */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, either the new symbol is a common
|
||||
* and the shared object reference is undefined --
|
||||
* in which case we note the common -- or the shared
|
||||
* object reference has a definition -- in which case
|
||||
* the library member takes precedence.
|
||||
*/
|
||||
if (iscommon) {
|
||||
/*
|
||||
* New symbol is common, just takes its
|
||||
@ -565,8 +585,9 @@ subfile_wanted_p(entry)
|
||||
if (write_map) {
|
||||
print_file_name(entry, stdout);
|
||||
fprintf(stdout,
|
||||
" needed due to shared lib ref %s\n",
|
||||
sp->name);
|
||||
" needed due to shared lib ref %s (%d)\n",
|
||||
sp->name,
|
||||
lsp ? lsp->nzlist.nlist.n_type : -1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -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.14 1994/08/21 15:22:43 pk Exp $
|
||||
* $Id: rrs.c,v 1.15 1994/12/23 20:32:59 pk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -700,6 +700,8 @@ consider_rrs_section_lengths()
|
||||
|
||||
if (rrs_section_type == RRS_NONE) {
|
||||
got_symbol->defined = 0;
|
||||
if (reserved_rrs_relocs > 0)
|
||||
errx(1, "internal error: empty RRS has reservations");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -929,36 +931,37 @@ write_rrs_data()
|
||||
return;
|
||||
|
||||
pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
err(1, "write_rrs_data: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
err(1, "write_rrs_data: fseek");
|
||||
|
||||
if (rrs_section_type == RRS_PARTIAL) {
|
||||
/*
|
||||
* Only a GOT and PLT are needed.
|
||||
*/
|
||||
md_swapout_got(rrs_got, number_of_gotslots);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
|
||||
|
||||
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
|
||||
mywrite(rrs_plt, number_of_jmpslots,
|
||||
sizeof(jmpslot_t), outstream);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
md_swapout__dynamic(&rrs_dyn);
|
||||
mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
|
||||
mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outstream);
|
||||
|
||||
md_swapout_so_debug(&rrs_so_debug);
|
||||
mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
|
||||
mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outstream);
|
||||
|
||||
md_swapout_section_dispatch_table(&rrs_sdt);
|
||||
mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
|
||||
mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outstream);
|
||||
|
||||
md_swapout_got(rrs_got, number_of_gotslots);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
|
||||
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
|
||||
|
||||
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
|
||||
mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outstream);
|
||||
}
|
||||
|
||||
void
|
||||
@ -971,23 +974,24 @@ write_rrs_text()
|
||||
int offset = 0;
|
||||
struct shobj *shp;
|
||||
struct sod *sodp;
|
||||
int bind;
|
||||
|
||||
if (rrs_section_type == RRS_PARTIAL)
|
||||
return;
|
||||
|
||||
pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
err(1, "write_rrs_text: lseek");
|
||||
if (fseek(outstream, pos, SEEK_SET) != 0)
|
||||
err(1, "write_rrs_text: fseek");
|
||||
|
||||
/* Write relocation records */
|
||||
md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
|
||||
mywrite(rrs_reloc, reserved_rrs_relocs,
|
||||
sizeof(struct relocation_info), outdesc);
|
||||
sizeof(struct relocation_info), outstream);
|
||||
|
||||
/* Write the RRS symbol hash tables */
|
||||
md_swapout_rrs_hash(rrs_hashtab, number_of_rrs_hash_entries);
|
||||
mywrite(rrs_hashtab, number_of_rrs_hash_entries,
|
||||
sizeof(struct rrs_hash), outdesc);
|
||||
sizeof(struct rrs_hash), outstream);
|
||||
|
||||
/*
|
||||
* Determine size of an RRS symbol entry, allocate space
|
||||
@ -1059,6 +1063,8 @@ write_rrs_text()
|
||||
if (LD_VERSION_NZLIST_P(soversion))
|
||||
nlp->nz_size = 0;
|
||||
|
||||
bind = (sp->flags & GS_WEAK) ? BIND_WEAK : 0;
|
||||
|
||||
if (sp->defined > 1) {
|
||||
/* defined with known type */
|
||||
if (!(link_mode & SHAREABLE) &&
|
||||
@ -1071,7 +1077,7 @@ write_rrs_text()
|
||||
*/
|
||||
nlp->nz_type = sp->alias->defined;
|
||||
nlp->nz_value = sp->alias->value;
|
||||
nlp->nz_other = N_OTHER(0, sp->alias->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->alias->aux);
|
||||
} else if (sp->defined == N_SIZE) {
|
||||
/*
|
||||
* Make sure this symbol isn't going
|
||||
@ -1082,28 +1088,32 @@ write_rrs_text()
|
||||
} else {
|
||||
nlp->nz_type = sp->defined;
|
||||
nlp->nz_value = sp->value;
|
||||
nlp->nz_other = N_OTHER(0, sp->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->aux);
|
||||
}
|
||||
if (LD_VERSION_NZLIST_P(soversion))
|
||||
nlp->nz_size = sp->size;
|
||||
} else if (sp->common_size) {
|
||||
/*
|
||||
* a common definition
|
||||
* A common definition.
|
||||
*/
|
||||
nlp->nz_type = N_UNDF | N_EXT;
|
||||
nlp->nz_value = sp->common_size;
|
||||
nlp->nz_other = N_OTHER(bind, 0);
|
||||
} else if (!sp->defined) {
|
||||
/* undefined */
|
||||
nlp->nz_type = N_UNDF | N_EXT;
|
||||
nlp->nz_value = 0;
|
||||
if (sp->so_defined && sp->jmpslot_offset != -1) {
|
||||
/*
|
||||
* Define a "weak" function symbol.
|
||||
* A PLT entry. The auxiliary type -- which
|
||||
* must be AUX_FUNC -- is used by the run-time
|
||||
* linker to unambiguously resolve function
|
||||
* address references.
|
||||
*/
|
||||
if (sp->aux != AUX_FUNC)
|
||||
errx(1, "%s: non-function jmpslot",
|
||||
sp->name);
|
||||
nlp->nz_other = N_OTHER(0, sp->aux);
|
||||
nlp->nz_other = N_OTHER(bind, sp->aux);
|
||||
nlp->nz_value =
|
||||
rrs_sdt.sdt_plt + sp->jmpslot_offset;
|
||||
}
|
||||
@ -1148,10 +1158,10 @@ write_rrs_text()
|
||||
md_swapout_symbols(rrs_symbols, number_of_rrs_symbols);
|
||||
else
|
||||
md_swapout_zsymbols(rrs_symbols, number_of_rrs_symbols);
|
||||
mywrite(rrs_symbols, symsize, 1, outdesc);
|
||||
mywrite(rrs_symbols, symsize, 1, outstream);
|
||||
|
||||
/* Write the strings */
|
||||
mywrite(rrs_strtab, rrs_strtab_size, 1, outdesc);
|
||||
mywrite(rrs_strtab, rrs_strtab_size, 1, outstream);
|
||||
|
||||
/*
|
||||
* Write the names of the shared objects needed at run-time
|
||||
@ -1187,7 +1197,7 @@ write_rrs_text()
|
||||
number_of_shobjs);
|
||||
|
||||
md_swapout_sod(sodp, number_of_shobjs);
|
||||
mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
|
||||
mywrite(sodp, number_of_shobjs, sizeof(struct sod), outstream);
|
||||
|
||||
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
|
||||
char *name = shp->entry->local_sym_name;
|
||||
@ -1196,7 +1206,7 @@ write_rrs_text()
|
||||
name += 2;
|
||||
}
|
||||
|
||||
mywrite(name, strlen(name) + 1, 1, outdesc);
|
||||
mywrite(name, strlen(name) + 1, 1, outstream);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: warnings.c,v 1.16 1994/10/19 20:16:38 pk Exp $
|
||||
* $Id: warnings.c,v 1.17 1994/12/23 20:33:01 pk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
static int reported_undefineds;
|
||||
|
||||
/*
|
||||
* Print the filename of ENTRY on OUTFILE (a stdio stream),
|
||||
* and then a newline.
|
||||
@ -466,10 +468,11 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
/* Mark as being noted by relocation warning pass. */
|
||||
SET_BIT(nlist_bitvector, lsp - start_of_syms);
|
||||
|
||||
if (g->undef_refs == 0)
|
||||
reported_undefineds++;
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
/* Listed too many */
|
||||
continue;
|
||||
|
||||
/* Undefined symbol which we should mention */
|
||||
|
||||
if (++(g->undef_refs) == MAX_UREFS_PRINTED) {
|
||||
@ -647,10 +650,16 @@ do_file_warnings (entry, outfile)
|
||||
line_number = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np->n_type);
|
||||
case N_UNDF | N_EXT:
|
||||
/* Don't print out multiple defs at references.*/
|
||||
continue;
|
||||
|
||||
default:
|
||||
warnx("%s: unexpected multiple definitions "
|
||||
"of symbol `%s', type %#x",
|
||||
get_file_name(entry),
|
||||
g->name, np->n_type);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (BIT_SET_P(nlist_bitvector, i)) {
|
||||
@ -658,9 +667,10 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
} else if (list_unresolved_refs &&
|
||||
!g->defined && !g->so_defined) {
|
||||
|
||||
if (g->undef_refs == 0)
|
||||
reported_undefineds++;
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
continue;
|
||||
|
||||
if (++(g->undef_refs) == MAX_UREFS_PRINTED)
|
||||
errfmt = "More undefined `%s' refs follow";
|
||||
else
|
||||
@ -671,7 +681,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
g->def_lsp->entry->flags & E_SECONDCLASS) {
|
||||
fprintf(outfile,
|
||||
"%s: Undefined symbol `%s' referenced (use %s ?)\n",
|
||||
entry->filename,
|
||||
get_file_name(entry),
|
||||
g->name,
|
||||
g->def_lsp->entry->local_sym_name);
|
||||
continue;
|
||||
@ -693,7 +703,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
|
||||
continue;
|
||||
|
||||
if (line_number == -1)
|
||||
fprintf(outfile, "%s: ", entry->filename);
|
||||
fprintf(outfile, "%s: ", get_file_name(entry));
|
||||
else
|
||||
fprintf(outfile, "%s:%d: ", file_name, line_number);
|
||||
|
||||
@ -714,7 +724,9 @@ do_warnings(outfile)
|
||||
FILE *outfile;
|
||||
{
|
||||
list_unresolved_refs = !relocatable_output &&
|
||||
(undefined_global_sym_count || undefined_shobj_sym_count);
|
||||
( (undefined_global_sym_count - undefined_weak_sym_count) > 0
|
||||
|| undefined_shobj_sym_count
|
||||
);
|
||||
list_multiple_defs = multiple_def_count != 0;
|
||||
|
||||
if (!(list_unresolved_refs ||
|
||||
@ -729,6 +741,13 @@ do_warnings(outfile)
|
||||
|
||||
each_file(do_file_warnings, (void *)outfile);
|
||||
|
||||
if (reported_undefineds !=
|
||||
(undefined_global_sym_count - undefined_weak_sym_count))
|
||||
warnx("Spurious undefined symbols: "
|
||||
"# undefined symbols %d, reported %d\n",
|
||||
(undefined_global_sym_count - undefined_weak_sym_count),
|
||||
reported_undefineds);
|
||||
|
||||
if (list_unresolved_refs || list_multiple_defs)
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user