X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fpdp11.c;h=2eca67c4a7ccca221068abfa37a33e367dac0519;hb=a975c88e6549c508ec86658e6816d7b8f16af13c;hp=5ad95236590ea951a916d8cb14fd5fc7207f2724;hpb=23c8270e9dc60bb78c1800b7deedc117efdb9e92;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 5ad9523659..2eca67c4a7 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -22,7 +22,9 @@ /* BFD backend for PDP-11, running 2.11BSD in particular. This file was hacked up by looking hard at the existing vaxnetbsd - back end and the header files in 2.11BSD. + back end and the header files in 2.11BSD. The symbol table format + of 2.11BSD has been extended to accommodate .stab symbols. See + struct pdp11_external_nlist below for details. TODO * support for V7 file formats @@ -101,10 +103,23 @@ struct pdp11_external_exec #define A_FLAG_RELOC_STRIPPED 0x0001 +/* The following struct defines the format of an entry in the object file + symbol table. In the original 2.11BSD struct the index into the string + table is stored as a long, but the PDP11 C convention for storing a long in + memory placed the most significant word first even though the bytes within a + word are stored least significant first. So here the string table index is + considered to be just 16 bits and the first two bytes of the struct were + previously named e_unused. To extend the symbol table format to accommodate + .stab symbols, the e_unused bytes are renamed e_desc to store the desc field + of the .stab symbol. The GDP Project's STABS document says that the "other" + field is almost always unused and can be set to zero; the only nonzero cases + identified were for stabs in their own sections, which does not apply for + pdp11 a.out format, and for a special case of GNU Modula2 which is not + supported for the PDP11. */ #define external_nlist pdp11_external_nlist struct pdp11_external_nlist { - bfd_byte e_unused[2]; /* Unused. */ + bfd_byte e_desc[2]; /* The desc field for .stab symbols, else 0. */ bfd_byte e_strx[2]; /* Index into string table of name. */ bfd_byte e_type[1]; /* Type of symbol. */ bfd_byte e_ovly[1]; /* Overlay number. */ @@ -151,6 +166,13 @@ static bfd_boolean MY(write_object_contents) (bfd *); #include "aout/stab_gnu.h" #include "aout/ar.h" +/* The symbol type numbers for the 16-bit a.out format from 2.11BSD differ from + those defined in aout64.h so we must redefine them here. N_EXT changes from + 0x01 to 0x20 which creates a conflict with some .stab values, in particular + between undefined externals (N_UNDF+N_EXT) vs. global variables (N_GYSM) and + between external bss symbols (N_BSS+N_EXT) vs. function names (N_FUN). We + disambiguate those conflicts with a hack in is_stab() to look for the ':' in + the global variable or function name string. */ #undef N_TYPE #undef N_UNDF #undef N_ABS @@ -170,7 +192,12 @@ static bfd_boolean MY(write_object_contents) (bfd *); #define N_REG 0x14 /* Register symbol. */ #define N_FN 0x1f /* File name. */ #define N_EXT 0x20 /* External flag. */ -#define N_STAB 0xc0 /* Not relevant; modified aout64.h's 0xe0 to avoid N_EXT. */ +/* Type numbers from .stab entries that could conflict: + N_GSYM 0x20 Global variable [conflict with external undef] + N_FNAME 0x22 Function name (for BSD Fortran) [ignored] + N_FUN 0x24 Function name [conflict with external BSS] + N_NOMAP 0x34 No DST map for sym. [ext. reg. doesn't exist] +*/ #define RELOC_SIZE 2 @@ -255,6 +282,7 @@ reloc_howto_type howto_table_pdp11[] = /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ HOWTO( 0, 0, 1, 16, FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE), HOWTO( 1, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE), +HOWTO( 2, 0, 2, 32, FALSE, 0, complain_overflow_signed,0,"32", TRUE, 0x0000ffff,0x0000ffff, FALSE), }; #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0])) @@ -276,6 +304,8 @@ NAME (aout, reloc_type_lookup) (bfd * abfd ATTRIBUTE_UNUSED, return &howto_table_pdp11[0]; case BFD_RELOC_16_PCREL: return &howto_table_pdp11[1]; + case BFD_RELOC_32: + return &howto_table_pdp11[2]; default: return NULL; } @@ -297,6 +327,19 @@ NAME (aout, reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED, return NULL; } +/* Disambiguate conflicts between normal symbol types and .stab symbol types + (undefined externals N_UNDF+N_EXT vs. global variables N_GYSM and external + bss symbols N_BSS+N_EXT vs. function names N_FUN) with a hack to look for + the ':' in the global variable or function name string. */ + +static int +is_stab (int type, const char *name) +{ + if (type == N_GSYM || type == N_FUN) + return (index(name, ':') != NULL); + return (type > N_FUN); +} + static int pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp) { @@ -620,8 +663,11 @@ NAME (aout, some_aout_object_p) (bfd *abfd, sets the entry point, and that is likely to be non-zero for most systems. */ if (execp->a_entry != 0 - || (execp->a_entry >= obj_textsec(abfd)->vma - && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size)) + || (execp->a_entry >= obj_textsec (abfd)->vma + && execp->a_entry < (obj_textsec (abfd)->vma + + obj_textsec (abfd)->size) + && execp->a_trsize == 0 + && execp->a_drsize == 0)) abfd->flags |= EXEC_P; #ifdef STAT_FOR_EXEC else @@ -1238,7 +1284,7 @@ aout_get_external_symbols (bfd *abfd) syms = (struct external_nlist *) _bfd_malloc_and_read (abfd, count * EXTERNAL_NLIST_SIZE, count * EXTERNAL_NLIST_SIZE); - if (syms == NULL && count != 0) + if (syms == NULL) return FALSE; #endif @@ -1252,36 +1298,54 @@ aout_get_external_symbols (bfd *abfd) unsigned char string_chars[BYTES_IN_LONG]; bfd_size_type stringsize; char *strings; + bfd_size_type amt = BYTES_IN_LONG; /* Get the size of the strings. */ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 - || (bfd_bread ((void *) string_chars, (bfd_size_type) BYTES_IN_LONG, - abfd) != BYTES_IN_LONG)) + || bfd_bread ((void *) string_chars, amt, abfd) != amt) return FALSE; stringsize = H_GET_32 (abfd, string_chars); + if (stringsize == 0) + stringsize = 1; + else if (stringsize < BYTES_IN_LONG + || (size_t) stringsize != stringsize) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } #ifdef USE_MMAP - if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize, - &obj_aout_string_window (abfd), TRUE)) - return FALSE; - strings = (char *) obj_aout_string_window (abfd).data; -#else - strings = bfd_malloc (stringsize + 1); - if (strings == NULL) - return FALSE; - - /* Skip space for the string count in the buffer for convenience - when using indexes. */ - if (bfd_bread (strings + 4, stringsize - 4, abfd) != stringsize - 4) + if (stringsize >= BYTES_IN_LONG) { - free (strings); - return FALSE; + if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize + 1, + &obj_aout_string_window (abfd), TRUE)) + return FALSE; + strings = (char *) obj_aout_string_window (abfd).data; } + else #endif + { + strings = (char *) bfd_malloc (stringsize + 1); + if (strings == NULL) + return FALSE; + + if (stringsize >= BYTES_IN_LONG) + { + /* Keep the string count in the buffer for convenience + when indexing with e_strx. */ + amt = stringsize - BYTES_IN_LONG; + if (bfd_bread (strings + BYTES_IN_LONG, amt, abfd) != amt) + { + free (strings); + return FALSE; + } + } + } /* Ensure that a zero index yields an empty string. */ strings[0] = '\0'; - strings[stringsize - 1] = 0; + /* Ensure that the string buffer is NUL terminated. */ + strings[stringsize] = 0; obj_aout_external_strings (abfd) = strings; obj_aout_external_string_size (abfd) = stringsize; @@ -1301,7 +1365,7 @@ translate_from_native_sym_flags (bfd *abfd, { flagword visible; - if (cache_ptr->type == N_FN) + if (is_stab (cache_ptr->type, cache_ptr->symbol.name)) { asection *sec; @@ -1309,20 +1373,25 @@ translate_from_native_sym_flags (bfd *abfd, cache_ptr->symbol.flags = BSF_DEBUGGING; /* Work out the symbol section. */ - switch (cache_ptr->type & N_TYPE) + switch (cache_ptr->type) { - case N_TEXT: + case N_SO: + case N_SOL: + case N_FUN: + case N_ENTRY: + case N_SLINE: case N_FN: sec = obj_textsec (abfd); break; - case N_DATA: + case N_STSYM: + case N_DSLINE: sec = obj_datasec (abfd); break; - case N_BSS: + case N_LCSYM: + case N_BSLINE: sec = obj_bsssec (abfd); break; default: - case N_ABS: sec = bfd_abs_section_ptr; break; } @@ -1394,10 +1463,12 @@ translate_to_native_sym_flags (bfd *abfd, bfd_vma value = cache_ptr->value; asection *sec; bfd_vma off; + const char *name = cache_ptr->name != NULL ? cache_ptr->name : "*unknown*"; /* Mask out any existing type bits in case copying from one section to another. */ - sym_pointer->e_type[0] &= ~N_TYPE; + if (!is_stab (sym_pointer->e_type[0], name)) + sym_pointer->e_type[0] &= ~N_TYPE; sec = bfd_asymbol_section (cache_ptr); off = 0; @@ -1409,7 +1480,7 @@ translate_to_native_sym_flags (bfd *abfd, _bfd_error_handler /* xgettext:c-format */ (_("%pB: can not represent section for symbol `%s' in a.out object file format"), - abfd, cache_ptr->name != NULL ? cache_ptr->name : "*unknown*"); + abfd, name); bfd_set_error (bfd_error_nonrepresentable_section); return FALSE; } @@ -1470,7 +1541,7 @@ NAME (aout, make_empty_symbol) (bfd *abfd) return &new_symbol_type->symbol; } -/* Translate a set of internal symbols into external symbols. */ +/* Translate a set of external symbols into internal symbols. */ bfd_boolean NAME (aout, translate_symbol_table) (bfd *abfd, @@ -1487,6 +1558,7 @@ NAME (aout, translate_symbol_table) (bfd *abfd, for (; ext < ext_end; ext++, in++) { bfd_vma x; + int ovly; x = GET_WORD (abfd, ext->e_strx); in->symbol.the_bfd = abfd; @@ -1501,11 +1573,27 @@ NAME (aout, translate_symbol_table) (bfd *abfd, else if (x < strsize) in->symbol.name = str + x; else - return FALSE; + { + _bfd_error_handler + (_("%pB: invalid string offset %" PRIu64 " >= %" PRIu64), + abfd, (uint64_t) x, (uint64_t) strsize); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + ovly = H_GET_8 (abfd, ext->e_ovly); + if (ovly != 0) + { + _bfd_error_handler + (_("%pB: symbol indicates overlay (not supported)"), abfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } in->symbol.value = GET_WORD (abfd, ext->e_value); - /* TODO: is 0 a safe value here? */ - in->desc = 0; + /* e_desc is zero for normal symbols but for .stab symbols it + carries the desc field in our extended 2.11BSD format. */ + in->desc = H_GET_16 (abfd, ext->e_desc); in->other = 0; in->type = H_GET_8 (abfd, ext->e_type); in->symbol.udata.p = NULL; @@ -1593,7 +1681,7 @@ NAME (aout, slurp_symbol_table) (bfd *abfd) /* Get the index of a string in a strtab, adding it if it is not already present. */ -static INLINE bfd_size_type +static inline bfd_size_type add_to_stringtab (bfd *abfd, struct bfd_strtab_hash *tab, const char *str, @@ -1656,23 +1744,27 @@ NAME (aout, write_syms) (bfd *abfd) bfd_size_type indx; struct external_nlist nsp; - PUT_WORD (abfd, 0, nsp.e_unused); - indx = add_to_stringtab (abfd, strtab, g->name, FALSE); if (indx == (bfd_size_type) -1) goto error_return; PUT_WORD (abfd, indx, nsp.e_strx); if (bfd_asymbol_flavour(g) == abfd->xvec->flavour) - H_PUT_8 (abfd, aout_symbol(g)->type, nsp.e_type); + { + H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc); + H_PUT_8 (abfd, 0, nsp.e_ovly); + H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type); + } else - H_PUT_8 (abfd, 0, nsp.e_type); + { + H_PUT_16 (abfd, 0, nsp.e_desc); + H_PUT_8 (abfd, 0, nsp.e_ovly); + H_PUT_8 (abfd, 0, nsp.e_type); + } if (! translate_to_native_sym_flags (abfd, g, &nsp)) goto error_return; - H_PUT_8 (abfd, 0, nsp.e_ovly); - if (bfd_bwrite ((void *)&nsp, (bfd_size_type) EXTERNAL_NLIST_SIZE, abfd) != EXTERNAL_NLIST_SIZE) goto error_return; @@ -1831,10 +1923,12 @@ pdp11_aout_swap_reloc_in (bfd * abfd, local or global. */ r_extern = (reloc_entry & RTYPE) == REXT; - if (r_extern && r_index > symcount) + if (r_extern && r_index >= symcount) { /* We could arrange to return an error, but it might be useful - to see the file even if it is bad. */ + to see the file even if it is bad. FIXME: Of course this + means that objdump -r *doesn't* see the actual reloc, and + objcopy silently writes a different reloc. */ r_extern = 0; r_index = N_ABS; } @@ -1957,6 +2051,15 @@ NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section) { bfd_byte *r; + if ((*generic)->howto == NULL + || (*generic)->sym_ptr_ptr == NULL) + { + bfd_set_error (bfd_error_invalid_operation); + _bfd_error_handler (_("%pB: attempt to write out " + "unknown reloc type"), abfd); + bfd_release (abfd, native); + return FALSE; + } r = native + (*generic)->address; pdp11_aout_swap_reloc_out (abfd, *generic, r); count--; @@ -2225,8 +2328,8 @@ NAME (aout, find_nearest_line) (bfd *abfd, size_t filelen, funclen; char *buf; - *filename_ptr = abfd->filename; - *functionname_ptr = 0; + *filename_ptr = bfd_get_filename (abfd); + *functionname_ptr = NULL; *line_ptr = 0; if (discriminator_ptr) *discriminator_ptr = 0; @@ -2254,7 +2357,10 @@ NAME (aout, find_nearest_line) (bfd *abfd, const char * symname; symname = q->symbol.name; - if (strcmp (symname + strlen (symname) - 2, ".o") == 0) + + if (symname != NULL + && strlen (symname) > 2 + && strcmp (symname + strlen (symname) - 2, ".o") == 0) { if (q->symbol.value > low_line_vma) { @@ -2286,7 +2392,7 @@ NAME (aout, find_nearest_line) (bfd *abfd, /* Look ahead to next symbol to check if that too is an N_SO. */ p++; if (*p == NULL) - break; + goto done; q = (aout_symbol_type *)(*p); if (q->type != (int) N_SO) goto next; @@ -2347,8 +2453,7 @@ NAME (aout, find_nearest_line) (bfd *abfd, else funclen = strlen (bfd_asymbol_name (func)); - if (adata (abfd).line_buf != NULL) - free (adata (abfd).line_buf); + free (adata (abfd).line_buf); if (filelen + funclen == 0) adata (abfd).line_buf = buf = NULL; else @@ -2365,9 +2470,17 @@ NAME (aout, find_nearest_line) (bfd *abfd, *filename_ptr = main_file_name; else { - sprintf (buf, "%s%s", directory_name, main_file_name); - *filename_ptr = buf; - buf += filelen + 1; + if (buf == NULL) + /* PR binutils/20891: In a corrupt input file both + main_file_name and directory_name can be empty... */ + * filename_ptr = NULL; + else + { + snprintf (buf, filelen + 1, "%s%s", directory_name, + main_file_name); + *filename_ptr = buf; + buf += filelen + 1; + } } } @@ -2376,6 +2489,12 @@ NAME (aout, find_nearest_line) (bfd *abfd, const char *function = func->name; char *colon; + if (buf == NULL) + { + /* PR binutils/20892: In a corrupt input file func can be empty. */ + * functionname_ptr = NULL; + return TRUE; + } /* The caller expects a symbol name. We actually have a function name, without the leading underscore. Put the underscore back in, so that the caller gets a symbol name. */ @@ -2415,7 +2534,7 @@ NAME (aout, bfd_free_cached_info) (bfd *abfd) if (bfd_get_format (abfd) != bfd_object) return TRUE; -#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; } +#define BFCI_FREE(x) do { free (x); x = NULL; } while (0) BFCI_FREE (obj_aout_symbols (abfd)); #ifdef USE_MMAP @@ -2586,17 +2705,17 @@ aout_link_check_ar_symbols (bfd *abfd, for (; p < pend; p++) { int type = H_GET_8 (abfd, p->e_type); - const char *name; + const char *name = strings + GET_WORD (abfd, p->e_strx); struct bfd_link_hash_entry *h; /* Ignore symbols that are not externally visible. This is an optimization only, as we check the type more thoroughly below. */ if ((type & N_EXT) == 0 + || is_stab(type, name) || type == N_FN) continue; - name = strings + GET_WORD (abfd, p->e_strx); h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); /* We are only interested in symbols that are currently @@ -2806,6 +2925,13 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) type = H_GET_8 (abfd, p->e_type); + /* Ignore debugging symbols. */ + if (is_stab(type, name)) + continue; + + /* PR 19629: Corrupt binaries can contain illegal string offsets. */ + if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) + return FALSE; name = strings + GET_WORD (abfd, p->e_strx); value = GET_WORD (abfd, p->e_value); flags = BSF_GLOBAL; @@ -2813,8 +2939,8 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) switch (type) { default: - /* Anything else should be a debugging symbol. */ - BFD_ASSERT ((type & N_STAB) != 0); + /* Shouldn't be any types not covered. */ + BFD_ASSERT (0); continue; case N_UNDF: @@ -2918,6 +3044,9 @@ aout_link_includes_newfunc (struct bfd_hash_entry *entry, return (struct bfd_hash_entry *) ret; } +/* Write out a symbol that was not associated with an a.out input + object. */ + static bfd_boolean aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data) { @@ -3014,12 +3143,14 @@ aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data) } H_PUT_8 (output_bfd, type, outsym.e_type); + H_PUT_8 (output_bfd, 0, outsym.e_ovly); indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string, FALSE); if (indx == (bfd_size_type) -1) /* FIXME: No way to handle errors. */ abort (); + PUT_WORD (output_bfd, 0, outsym.e_desc); PUT_WORD (output_bfd, indx, outsym.e_strx); PUT_WORD (output_bfd, val, outsym.e_value); @@ -3302,8 +3433,15 @@ pdp11_aout_link_input_section (struct aout_final_link_info *flaginfo, r_extern = (r_type == REXT); howto_idx = r_pcrel; - BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_pdp11)); - howto = howto_table_pdp11 + howto_idx; + if (howto_idx < TABLE_SIZE (howto_table_pdp11)) + howto = howto_table_pdp11 + howto_idx; + else + { + _bfd_error_handler (_("%pB: unsupported relocation type"), + input_bfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } } if (relocatable) @@ -3914,26 +4052,14 @@ NAME (aout, final_link) (bfd *abfd, } } - if (aout_info.contents != NULL) - { - free (aout_info.contents); - aout_info.contents = NULL; - } - if (aout_info.relocs != NULL) - { - free (aout_info.relocs); - aout_info.relocs = NULL; - } - if (aout_info.symbol_map != NULL) - { - free (aout_info.symbol_map); - aout_info.symbol_map = NULL; - } - if (aout_info.output_syms != NULL) - { - free (aout_info.output_syms); - aout_info.output_syms = NULL; - } + free (aout_info.contents); + aout_info.contents = NULL; + free (aout_info.relocs); + aout_info.relocs = NULL; + free (aout_info.symbol_map); + aout_info.symbol_map = NULL; + free (aout_info.output_syms); + aout_info.output_syms = NULL; if (includes_hash_initialized) { bfd_hash_table_free (&aout_info.includes.root); @@ -3993,14 +4119,10 @@ NAME (aout, final_link) (bfd *abfd, return TRUE; error_return: - if (aout_info.contents != NULL) - free (aout_info.contents); - if (aout_info.relocs != NULL) - free (aout_info.relocs); - if (aout_info.symbol_map != NULL) - free (aout_info.symbol_map); - if (aout_info.output_syms != NULL) - free (aout_info.output_syms); + free (aout_info.contents); + free (aout_info.relocs); + free (aout_info.symbol_map); + free (aout_info.output_syms); if (includes_hash_initialized) bfd_hash_table_free (&aout_info.includes.root); return FALSE; @@ -4037,13 +4159,16 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) discarding such symbols. */ if (strip != strip_all && (strip != strip_some - || bfd_hash_lookup (flaginfo->info->keep_hash, input_bfd->filename, + || bfd_hash_lookup (flaginfo->info->keep_hash, + bfd_get_filename (input_bfd), FALSE, FALSE) != NULL) && discard != discard_all) { H_PUT_8 (output_bfd, N_TEXT, outsym->e_type); + H_PUT_8 (output_bfd, 0, outsym->e_ovly); + H_PUT_16 (output_bfd, 0, outsym->e_desc); strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab, - input_bfd->filename, FALSE); + bfd_get_filename (input_bfd), FALSE); if (strtab_index == (bfd_size_type) -1) return FALSE; PUT_WORD (output_bfd, strtab_index, outsym->e_strx); @@ -4155,7 +4280,7 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) case strip_none: break; case strip_debugger: - if ((type & N_STAB) != 0) + if (is_stab (type, name)) skip = TRUE; break; case strip_some: @@ -4175,7 +4300,33 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) } /* Get the value of the symbol. */ - if ((type & N_TYPE) == N_TEXT + if (is_stab (type, name)) + { + switch (type) + { + default: + symsec = bfd_abs_section_ptr; + break; + case N_SO: + case N_SOL: + case N_FUN: + case N_ENTRY: + case N_SLINE: + case N_FN: + symsec = obj_textsec (input_bfd); + break; + case N_STSYM: + case N_DSLINE: + symsec = obj_datasec (input_bfd); + break; + case N_LCSYM: + case N_BSLINE: + symsec = obj_bsssec (input_bfd); + break; + } + val = GET_WORD (input_bfd, sym->e_value); + } + else if ((type & N_TYPE) == N_TEXT || type == N_WEAKT) symsec = obj_textsec (input_bfd); else if ((type & N_TYPE) == N_DATA @@ -4203,11 +4354,6 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) val = GET_WORD (input_bfd, sym->e_value); symsec = NULL; } - else if ((type & N_STAB) != 0) - { - val = GET_WORD (input_bfd, sym->e_value); - symsec = NULL; - } else { /* If we get here with an indirect symbol, it means that @@ -4321,7 +4467,7 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) case discard_sec_merge: break; case discard_l: - if ((type & N_STAB) == 0 + if (!is_stab (type, name) && bfd_is_local_label_name (input_bfd, name)) skip = TRUE; break; @@ -4445,6 +4591,8 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) /* Copy this symbol into the list of symbols we are going to write out. */ H_PUT_8 (output_bfd, type, outsym->e_type); + H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_ovly), outsym->e_ovly); + H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc); copy = FALSE; if (! flaginfo->info->keep_memory) {