From bfe8224f3e58132636e352fae6f3b943438fccb4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 31 Mar 1994 16:58:23 +0000 Subject: [PATCH] * coffgen.c (coff_write_symbol): Reindented. Changed to return boolean, and changed written to unsigned int *. Check error returns from called functions. (coff_write_alien_symbol): Likewise. (coff_write_native_symbol): Likewise. (coff_write_symbols): Likewise. Reworked checks on whether to write symbol name to string table for clarity and to avoid core dumping when given a non COFF symbol. * libcoff-in.h (coff_write_symbols): Declare as returning boolean. * libcoff.h: Rebuilt. * coffcode.h (coff_write_object_contents): Check return value of coff_write_symbols. --- bfd/ChangeLog | 15 ++ bfd/coffcode.h | 3 +- bfd/coffgen.c | 399 ++++++++++++++++++++++++++++--------------------- 3 files changed, 245 insertions(+), 172 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c2d010550bf..0732eaa07e5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +Thu Mar 31 11:52:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * coffgen.c (coff_write_symbol): Reindented. Changed to return + boolean, and changed written to unsigned int *. Check error + returns from called functions. + (coff_write_alien_symbol): Likewise. + (coff_write_native_symbol): Likewise. + (coff_write_symbols): Likewise. Reworked checks on whether to + write symbol name to string table for clarity and to avoid core + dumping when given a non COFF symbol. + * libcoff-in.h (coff_write_symbols): Declare as returning boolean. + * libcoff.h: Rebuilt. + * coffcode.h (coff_write_object_contents): Check return value of + coff_write_symbols. + Wed Mar 30 16:25:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) Changes to let BFD return an error indication from diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 0f984fecae4..10cf9ff0cec 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1768,7 +1768,8 @@ coff_write_object_contents (abfd) if (!coff_renumber_symbols (abfd)) return false; coff_mangle_symbols (abfd); - coff_write_symbols (abfd); + if (! coff_write_symbols (abfd)) + return false; if (!coff_write_linenumbers (abfd)) return false; coff_write_relocs (abfd); diff --git a/bfd/coffgen.c b/bfd/coffgen.c index e0880482122..d7fd2af3e4e 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -41,6 +41,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "coff/internal.h" #include "libcoff.h" +static boolean coff_write_symbol PARAMS ((bfd *, asymbol *, + combined_entry_type *, + unsigned int *)); +static boolean coff_write_alien_symbol PARAMS ((bfd *, asymbol *, + unsigned int *)); +static boolean coff_write_native_symbol PARAMS ((bfd *, coff_symbol_type *, + unsigned int *)); + static asection bfd_debug_section = { "*DEBUG*" }; /* Take a section header read from a coff file (in HOST byte order), @@ -645,56 +653,62 @@ coff_fix_symbol_name (abfd, symbol, native) } } -#define set_index(symbol, idx) ((symbol)->udata =(PTR) (idx)) +/* We need to keep track of the symbol index so that when we write out + the relocs we can get the index for a symbol. This method is a + hack. FIXME. */ + +#define set_index(symbol, idx) ((symbol)->udata = (PTR) (idx)) + +/* Write a symbol out to a COFF file. */ -static unsigned int +static boolean coff_write_symbol (abfd, symbol, native, written) bfd *abfd; asymbol *symbol; combined_entry_type *native; - unsigned int written; + unsigned int *written; { - unsigned int numaux = native->u.syment.n_numaux; - int type = native->u.syment.n_type; - int class = native->u.syment.n_sclass; + unsigned int numaux = native->u.syment.n_numaux; + int type = native->u.syment.n_type; + int class = native->u.syment.n_sclass; PTR buf; bfd_size_type symesz; - /* @@ bfd_debug_section isn't accessible outside this file, but we know - that C_FILE symbols belong there. So move them. */ + /* @@ bfd_debug_section isn't accessible outside this file, but we + know that C_FILE symbols belong there. So move them. */ if (native->u.syment.n_sclass == C_FILE) symbol->section = &bfd_debug_section; if (symbol->section == &bfd_abs_section) - { - native->u.syment.n_scnum = N_ABS; - } + { + native->u.syment.n_scnum = N_ABS; + } else if (symbol->section == &bfd_debug_section) - { - native->u.syment.n_scnum = N_DEBUG; - } + { + native->u.syment.n_scnum = N_DEBUG; + } else if (symbol->section == &bfd_und_section) - { - native->u.syment.n_scnum = N_UNDEF; - } + { + native->u.syment.n_scnum = N_UNDEF; + } else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - } - + { + native->u.syment.n_scnum = + symbol->section->output_section->target_index; + } - coff_fix_symbol_name(abfd, symbol, native); + coff_fix_symbol_name (abfd, symbol, native); symesz = bfd_coff_symesz (abfd); buf = bfd_alloc (abfd, symesz); if (!buf) { bfd_set_error (bfd_error_no_memory); - abort(); /* FIXME */ + return false; } - bfd_coff_swap_sym_out(abfd, &native->u.syment, buf); - bfd_write(buf, 1, symesz, abfd); + bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); + if (bfd_write (buf, 1, symesz, abfd) != symesz) + return false; bfd_release (abfd, buf); if (native->u.syment.n_numaux > 0) @@ -707,227 +721,270 @@ coff_write_symbol (abfd, symbol, native, written) if (!buf) { bfd_set_error (bfd_error_no_memory); - abort(); /* FIXME */ + return false; } for (j = 0; j < native->u.syment.n_numaux; j++) { - bfd_coff_swap_aux_out(abfd, - &((native + j + 1)->u.auxent), - type, - class, - j, - native->u.syment.n_numaux, - buf); - bfd_write(buf, 1, auxesz, abfd); + bfd_coff_swap_aux_out (abfd, + &((native + j + 1)->u.auxent), + type, + class, + j, + native->u.syment.n_numaux, + buf); + if (bfd_write (buf, 1, auxesz, abfd)!= auxesz) + return false; } bfd_release (abfd, buf); } - /* - Reuse somewhere in the symbol to keep the index - */ - set_index(symbol, written); - return written + 1 + numaux; + + /* Store the index for use when we write out the relocs. */ + set_index (symbol, *written); + + *written += numaux + 1; + return true; } +/* Write out a symbol to a COFF file that does not come from a COFF + file originally. This symbol may have been created by the linker, + or we may be linking a non COFF file to a COFF file. */ -static unsigned int +static boolean coff_write_alien_symbol (abfd, symbol, written) bfd *abfd; asymbol *symbol; - unsigned int written; + unsigned int *written; { - /* - This symbol has been created by the loader, or come from a non - coff format. It has no native element to inherit, make our - own - */ combined_entry_type *native; combined_entry_type dummy; + native = &dummy; native->u.syment.n_type = T_NULL; native->u.syment.n_flags = 0; if (symbol->section == &bfd_und_section) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; + { + native->u.syment.n_scnum = N_UNDEF; + native->u.syment.n_value = symbol->value; } else if (bfd_is_com_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - - } - - else if (symbol->flags & BSF_DEBUGGING) { - /* - remove name so it doesn't take up any space - */ - symbol->name = ""; + { + native->u.syment.n_scnum = N_UNDEF; + native->u.syment.n_value = symbol->value; } - else { - native->u.syment.n_scnum = symbol->section->output_section->target_index; - native->u.syment.n_value = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - /* Copy the any flags from the the file hdr into the symbol */ + else if (symbol->flags & BSF_DEBUGGING) { - coff_symbol_type *c = coff_symbol_from(abfd, symbol); - if (c != (coff_symbol_type *)NULL) { - native->u.syment.n_flags = bfd_asymbol_bfd(&c->symbol)->flags; - } + /* Remove the symbol name so that it does not take up any space. + COFF won't know what to do with it anyhow. */ + symbol->name = ""; } + else + { + native->u.syment.n_scnum = + symbol->section->output_section->target_index; + native->u.syment.n_value = (symbol->value + + symbol->section->output_section->vma + + symbol->section->output_offset); + + /* Copy the any flags from the the file header into the symbol. + FIXME: Why? */ + { + coff_symbol_type *c = coff_symbol_from (abfd, symbol); + if (c != (coff_symbol_type *) NULL) + native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; + } } - native->u.syment.n_type = 0; + native->u.syment.n_type = 0; if (symbol->flags & BSF_LOCAL) - native->u.syment.n_sclass = C_STAT; + native->u.syment.n_sclass = C_STAT; else - native->u.syment.n_sclass = C_EXT; - native->u.syment.n_numaux = 0; + native->u.syment.n_sclass = C_EXT; + native->u.syment.n_numaux = 0; - return coff_write_symbol(abfd, symbol, native, written); + return coff_write_symbol (abfd, symbol, native, written); } -static unsigned int +/* Write a native symbol to a COFF file. */ + +static boolean coff_write_native_symbol (abfd, symbol, written) bfd *abfd; coff_symbol_type *symbol; - unsigned int written; + unsigned int *written; { - /* - Does this symbol have an ascociated line number - if so then - make it remember this symbol index. Also tag the auxent of - this symbol to point to the right place in the lineno table - */ combined_entry_type *native = symbol->native; + alent *lineno = symbol->lineno; - alent *lineno = symbol->lineno; - - if (lineno && !symbol->done_lineno) { - unsigned int count = 0; - lineno[count].u.offset = written; - if (native->u.syment.n_numaux) { - union internal_auxent *a = &((native+1)->u.auxent); + /* If this symbol has an associated line number, we must store the + symbol index in the line number field. We also tag the auxent to + point to the right place in the lineno table. */ + if (lineno && !symbol->done_lineno) + { + unsigned int count = 0; + lineno[count].u.offset = *written; + if (native->u.syment.n_numaux) + { + union internal_auxent *a = &((native+1)->u.auxent); - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = - symbol->symbol.section->output_section->moving_line_filepos; - } - /* - And count and relocate all other linenumbers - */ + a->x_sym.x_fcnary.x_fcn.x_lnnoptr = + symbol->symbol.section->output_section->moving_line_filepos; + } - count++; - while (lineno[count].line_number) { + /* Count and relocate all other linenumbers. */ + count++; + while (lineno[count].line_number != 0) + { #if 0 -/* 13 april 92. sac -I've been told this, but still need proof: -> The second bug is also in `bfd/coffcode.h'. This bug causes the linker to screw -> up the pc-relocations for all the line numbers in COFF code. This bug isn't -> only specific to A29K implementations, but affects all systems using COFF -> format binaries. Note that in COFF object files, the line number core offsets -> output by the assembler are relative to the start of each procedure, not -> to the start of the .text section. This patch relocates the line numbers -> relative to the `native->u.syment.n_value' instead of the section virtual -> address. modular!olson@cs.arizona.edu (Jon Olson) -*/ - lineno[count].u.offset += native->u.syment.n_value; - + /* 13 april 92. sac + I've been told this, but still need proof: + > The second bug is also in `bfd/coffcode.h'. This bug + > causes the linker to screw up the pc-relocations for + > all the line numbers in COFF code. This bug isn't only + > specific to A29K implementations, but affects all + > systems using COFF format binaries. Note that in COFF + > object files, the line number core offsets output by + > the assembler are relative to the start of each + > procedure, not to the start of the .text section. This + > patch relocates the line numbers relative to the + > `native->u.syment.n_value' instead of the section + > virtual address. + > modular!olson@cs.arizona.edu (Jon Olson) + */ + lineno[count].u.offset += native->u.syment.n_value; #else - lineno[count].u.offset += - symbol->symbol.section->output_section->vma + - symbol->symbol.section->output_offset; + lineno[count].u.offset += + (symbol->symbol.section->output_section->vma + + symbol->symbol.section->output_offset); #endif - count++; - } - symbol->done_lineno = true; + count++; + } + symbol->done_lineno = true; - symbol->symbol.section->output_section->moving_line_filepos += - count * bfd_coff_linesz (abfd); - } - return coff_write_symbol(abfd, &( symbol->symbol), native,written); + symbol->symbol.section->output_section->moving_line_filepos += + count * bfd_coff_linesz (abfd); + } + + return coff_write_symbol (abfd, &(symbol->symbol), native, written); } -void +/* Write out the COFF symbols. */ + +boolean coff_write_symbols (abfd) - bfd *abfd; + bfd *abfd; { - unsigned int i; - unsigned int limit = bfd_get_symcount(abfd); - unsigned int written = 0; - - asymbol **p; + unsigned int i; + unsigned int limit = bfd_get_symcount(abfd); + unsigned int written = 0; + asymbol **p; string_size = 0; debug_string_size = 0; /* Seek to the right place */ - bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET); + if (bfd_seek (abfd, obj_sym_filepos(abfd), SEEK_SET) != 0) + return false; /* Output all the symbols we have */ written = 0; for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *symbol = *p; - coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol); - - if (c_symbol == (coff_symbol_type *) NULL || - c_symbol->native == (combined_entry_type *)NULL) - { - written = coff_write_alien_symbol(abfd, symbol, written); - } - else - { - written = coff_write_native_symbol(abfd, c_symbol, written); - } + { + asymbol *symbol = *p; + coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); - } + if (c_symbol == (coff_symbol_type *) NULL + || c_symbol->native == (combined_entry_type *)NULL) + { + if (! coff_write_alien_symbol (abfd, symbol, &written)) + return false; + } + else + { + if (! coff_write_native_symbol (abfd, c_symbol, &written)) + return false; + } + } - bfd_get_symcount(abfd) = written; + bfd_get_symcount (abfd) = written; /* Now write out strings */ if (string_size != 0) { - unsigned int size = string_size + 4; + unsigned int size = string_size + 4; bfd_byte buffer[4]; - bfd_h_put_32(abfd, size, buffer); - bfd_write((PTR) buffer, 1, sizeof(buffer), abfd); + bfd_h_put_32 (abfd, size, buffer); + bfd_write ((PTR) buffer, 1, sizeof (buffer), abfd); for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *q = *p; - size_t name_length = strlen(q->name); - int maxlen; - coff_symbol_type* c_symbol = coff_symbol_from(abfd, q); - maxlen = ((c_symbol != NULL && c_symbol->native != NULL) && - (c_symbol->native->u.syment.n_sclass == C_FILE)) ? - FILNMLEN : SYMNMLEN; - - if (name_length > maxlen - && ! bfd_coff_symname_in_debug (abfd, - &c_symbol->native->u.syment)) - bfd_write((PTR) (q->name), 1, name_length + 1, abfd); - } + { + asymbol *q = *p; + size_t name_length = strlen (q->name); + coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); + size_t maxlen; + + /* Figure out whether the symbol name should go in the string + table. Symbol names that are short enough are stored + directly in the syment structure. File names permit a + different, longer, length in the syment structure. On + XCOFF, some symbol names are stored in the .debug section + rather than in the string table. */ + + if (c_symbol == NULL + || c_symbol->native == NULL) + { + /* This is not a COFF symbol, so it certainly is not a + file name, nor does it go in the .debug section. */ + maxlen = SYMNMLEN; + } + else if (bfd_coff_symname_in_debug (abfd, + &c_symbol->native->u.syment)) + { + /* This symbol name is in the XCOFF .debug section. + Don't write it into the string table. */ + maxlen = name_length; + } + else if (c_symbol->native->u.syment.n_sclass == C_FILE) + maxlen = FILNMLEN; + else + maxlen = SYMNMLEN; + + if (name_length > maxlen) + { + if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd) + != name_length + 1) + return false; + } + } } - else { - /* We would normally not write anything here, but we'll write - out 4 so that any stupid coff reader which tries to read - the string table even when there isn't one won't croak. */ - unsigned int size = 4; - bfd_byte buffer[4]; - - bfd_h_put_32 (abfd, size, buffer); - bfd_write((PTR) buffer, 1, sizeof (buffer), abfd); - } + else + { + /* We would normally not write anything here, but we'll write + out 4 so that any stupid coff reader which tries to read the + string table even when there isn't one won't croak. */ + unsigned int size = 4; + bfd_byte buffer[4]; + + bfd_h_put_32 (abfd, size, buffer); + if (bfd_write ((PTR) buffer, 1, 4, abfd) != 4) + return false; + } + /* Make sure the .debug section was created to be the correct size. + We should create it ourselves on the fly, but we don't because + BFD won't let us write to any section until we know how large all + the sections are. We could still do it by making another pass + over the symbols. FIXME. */ BFD_ASSERT (debug_string_size == 0 || (debug_string_section != (asection *) NULL && (BFD_ALIGN (debug_string_size, 1 << debug_string_section->alignment_power) == bfd_section_size (abfd, debug_string_section)))); + + return true; } boolean -- 2.30.2