diff options
Diffstat (limited to 'gnu/usr.bin/ld/ld.c')
-rw-r--r-- | gnu/usr.bin/ld/ld.c | 380 |
1 files changed, 242 insertions, 138 deletions
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c index 5d713a0..14f7cd0 100644 --- a/gnu/usr.bin/ld/ld.c +++ b/gnu/usr.bin/ld/ld.c @@ -32,7 +32,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91"; Set, indirect, and warning symbol features added by Randy Smith. */ /* - * $Id: ld.c,v 1.22 1994/06/15 22:39:40 rich Exp $ + * $Id: ld.c,v 1.23 1994/12/23 22:30:37 nate 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. */ @@ -346,9 +350,6 @@ main(argc, argv) /* Create the symbols `etext', `edata' and `end'. */ symtab_init(relocatable_output); - /* Prepare for the run-time linking support. */ - init_rrs(); - /* * Determine whether to count the header as part of the text size, * and initialize the text size accordingly. This depends on the kind @@ -386,7 +387,7 @@ main(argc, argv) * Print error messages for any missing symbols, for any warning * symbols, and possibly multiple definitions */ - make_executable = do_warnings(stderr); + make_executable &= do_warnings(stderr); /* Print a map, if requested. */ if (write_map) @@ -1344,7 +1345,7 @@ enter_global_ref(lsp, name, entry) int olddef = sp->defined; int com = sp->defined && sp->common_size; - if (type == (N_INDR | N_EXT)) { + if (type == (N_INDR | N_EXT) && !olddef) { sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx); if (sp == sp->alias) { warnx("%s: %s is alias for itself", @@ -1356,6 +1357,10 @@ enter_global_ref(lsp, name, entry) } else { global_alias_count++; } +#if 0 + if (sp->flags & GS_REFERENCED) + sp->alias->flags |= GS_REFERENCED; +#endif } if (entry->flags & E_DYNAMIC) { @@ -1383,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; } @@ -1428,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) { /* @@ -1479,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) @@ -1495,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: @@ -1515,12 +1567,21 @@ enter_global_ref(lsp, name, entry) reftype = "defined in BSS section"; break; + case N_INDR: + reftype = "alias"; + break; + + case N_SIZE: + reftype = "size spec"; + break; + default: reftype = "I don't know this type"; 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"); } @@ -1707,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), \ -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, - global_alias_count, warn_sym_count, - local_sym_count, debugger_sym_count, set_symbol_count); + undefined_weak_sym_count, + global_alias_count, warn_sym_count, size_sym_count, + common_defined_global_count, local_sym_count, + debugger_sym_count, set_symbol_count); #endif } @@ -1738,6 +1802,7 @@ digest_pass1() * definition find this way. */ FOR_EACH_SYMBOL(i, sp) { + symbol *spsave; struct localsymbol *lsp; int defs = 0; @@ -1792,6 +1857,7 @@ digest_pass1() * of this set vector. */ bzero(&reloc, sizeof(reloc)); + RELOC_INIT_SEGMENT_RELOC(&reloc); RELOC_ADDRESS(&reloc) = setv_fill_count * sizeof(long); alloc_rrs_segment_reloc(NULL, &reloc); @@ -1801,15 +1867,18 @@ digest_pass1() && (type & N_TYPE) != N_FN && (type & N_TYPE) != N_SIZE) { /* non-common definition */ - if (defs++ && sp->value != p->n_value - && entry_symbol/*XXX*/) { + 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); } } @@ -1846,6 +1915,7 @@ digest_pass1() continue; } + spsave=sp; again: for (lsp = sp->sorefs; lsp; lsp = lsp->next) { register struct nlist *p = &lsp->nzlist.nlist; @@ -1858,31 +1928,41 @@ digest_pass1() sp->so_defined = type; sp->aux = N_AUX(p); 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("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value); +printf("pass1: SO definition for %s, type %x in %s at %#x\n", + 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); } @@ -1987,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) @@ -2031,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 { @@ -2217,14 +2298,27 @@ digest_pass2() continue; if (sp->alias && - (relocatable_output || building_shared_object || - (sp->alias->defined && !sp->alias->so_defined))) + (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. */ + if (!sp->defined) { + /* + * Change aliased symbol's definition too. + * These things happen if shared object commons + * or data is going into our symbol table. + */ + if (sp->so_defined != (N_INDR+N_EXT)) + warnx( "pass2: %s: alias isn't", + sp->name); + sp->defined = sp->so_defined; + sp->so_defined = 0; + } defined_global_sym_count++; + } if ((sp->defined & N_TYPE) == N_SETV) { /* @@ -2253,6 +2347,7 @@ digest_pass2() struct relocation_info reloc; bzero(&reloc, sizeof(reloc)); + RELOC_INIT_SEGMENT_RELOC(&reloc); RELOC_ADDRESS(&reloc) = (1 + i + length_word_index) * sizeof(long) @@ -2284,7 +2379,11 @@ digest_pass2() sp->value = sp->def_lsp->nzlist.nz_value; if (sp->so_defined && (sp->def_lsp->entry->flags & E_SECONDCLASS)) + /* Flag second-hand definitions */ undefined_global_sym_count++; + if (sp->flags & GS_TRACE) + printf("symbol %s assigned to location %#x\n", + sp->name, sp->value); } /* @@ -2333,11 +2432,9 @@ digest_pass2() size = PALIGN(size, sizeof(int)); - while (!(size & align)) + while (align < MAX_ALIGNMENT && !(size & align)) align <<= 1; - align = align > MAX_ALIGNMENT ? MAX_ALIGNMENT : align; - bss_size = PALIGN(bss_size + data_size + rrs_data_start, align) - (data_size + rrs_data_start); @@ -2372,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(); @@ -2406,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. */ @@ -2419,12 +2521,19 @@ write_header() int flags; if (link_mode & SHAREABLE) + /* Output is shared object */ flags = EX_DYNAMIC | EX_PIC; - else if (pic_code_seen) + else if (relocatable_output && pic_code_seen) + /* Output is relocatable and contains PIC code */ flags = EX_PIC; else if (rrs_section_type == RRS_FULL) + /* Output is a dynamic executable */ flags = EX_DYNAMIC; else + /* + * Output is a static executable + * or a non-PIC relocatable object + */ flags = 0; if (oldmagic && (flags & EX_DPMASK)) @@ -2457,7 +2566,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); /* @@ -2466,7 +2575,7 @@ write_header() */ #ifndef COFF_ENCAPSULATE - padfile(N_TXTOFF(outheader) - sizeof outheader, outdesc); + padfile(N_TXTOFF(outheader) - sizeof outheader, outstream); #endif } @@ -2487,7 +2596,7 @@ write_text() if (trace_files) fprintf(stderr, "\n"); - padfile(text_pad, outdesc); + padfile(text_pad, outstream); } /* @@ -2525,7 +2634,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); } /* @@ -2542,8 +2651,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(); @@ -2556,13 +2665,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); } /* @@ -2596,7 +2705,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); } /* @@ -2657,6 +2766,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; @@ -2697,6 +2809,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; @@ -2761,11 +2876,11 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg) "symbol %s claims RRS in %s%s\n", sp->name, get_file_name(entry), (sp->so_defined == (N_TEXT+N_EXT) && - sp->jmpslot_offset != -1)? + sp->flags & GS_HASJMPSLOT)? " (JMPSLOT)":""); } if (sp->so_defined == (N_TEXT+N_EXT) && - sp->jmpslot_offset != -1) { + sp->flags & GS_HASJMPSLOT) { /* * Claim a jmpslot if one was allocated. * @@ -2781,8 +2896,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; } } @@ -3005,7 +3122,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 @@ -3070,7 +3187,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 *)); @@ -3078,15 +3195,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'. */ @@ -3121,8 +3238,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 @@ -3133,23 +3248,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. */ @@ -3173,10 +3278,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; @@ -3264,9 +3369,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) @@ -3296,6 +3402,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 @@ -3305,7 +3413,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) { @@ -3375,18 +3485,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(); @@ -3396,18 +3505,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); } @@ -3507,10 +3617,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 @@ -3546,18 +3657,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 @@ -3565,10 +3669,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); } @@ -3580,8 +3684,8 @@ cleanup() */ void padfile(padding, fd) - int padding; - int fd; + int padding; + FILE *fd; { register char *buf; if (padding <= 0) |