X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fecoff.c;h=32a2309e941db78ed19cc2b5e1da40aa098a85a7;hb=d2905643ff04ca59990fea39f2f4ba046fbd41b9;hp=f4549d65769ca99997d164e435a496c7f4c988ff;hpb=656c5b6d7e5f46dd8ce6540a52c543c09ec85f3c;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/ecoff.c b/bfd/ecoff.c index f4549d6576..32a2309e94 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -1,5 +1,6 @@ /* Generic ECOFF (Extended-COFF) routines. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998 + Free Software Foundation, Inc. Original version by Per Bothner. Full support added by Ian Lance Taylor, ian@cygnus.com. @@ -140,20 +141,11 @@ _bfd_ecoff_new_section_hook (abfd, section) bfd *abfd; asection *section; { - /* For the .pdata section, which has a special meaning on the Alpha, - we set the alignment power to 3. We correct this later in - ecoff_compute_section_file_positions. We do this hackery because - we need to know the exact unaligned size of the .pdata section in - order to set the lnnoptr field correctly. For every other - section we use an alignment power of 4; this could be made target - dependent by adding a field to ecoff_backend_data, but 4 appears - to be correct for both the MIPS and the Alpha. */ - if (strcmp (section->name, _PDATA) == 0) - section->alignment_power = 3; - else - section->alignment_power = 4; + section->alignment_power = 4; - if (strcmp (section->name, _TEXT) == 0) + if (strcmp (section->name, _TEXT) == 0 + || strcmp (section->name, _INIT) == 0 + || strcmp (section->name, _FINI) == 0) section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; else if (strcmp (section->name, _DATA) == 0 || strcmp (section->name, _SDATA) == 0) @@ -161,7 +153,8 @@ _bfd_ecoff_new_section_hook (abfd, section) else if (strcmp (section->name, _RDATA) == 0 || strcmp (section->name, _LIT8) == 0 || strcmp (section->name, _LIT4) == 0 - || strcmp (section->name, _RCONST) == 0) + || strcmp (section->name, _RCONST) == 0 + || strcmp (section->name, _PDATA) == 0) section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; else if (strcmp (section->name, _BSS) == 0 || strcmp (section->name, _SBSS) == 0) @@ -842,6 +835,10 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak) case N_SETD: case N_SETB: { + /* This code is no longer needed. It used to be used to + make the linker handle set symbols, but they are now + handled in the add_symbols routine instead. */ +#if 0 const char *name; asection *section; arelent_chain *reloc_chain; @@ -901,6 +898,8 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak) section->constructor_chain = reloc_chain; section->_raw_size += bitsize / 8; +#endif /* 0 */ + /* Mark the symbol as a constructor. */ asym->flags |= BSF_CONSTRUCTOR; } @@ -1306,7 +1305,7 @@ ecoff_type_to_string (abfd, fdr, indx) break; default: - sprintf (p1, "Unknown basic type %d", (int) basic_type); + sprintf (p1, _("Unknown basic type %d"), (int) basic_type); break; } @@ -1445,11 +1444,11 @@ _bfd_ecoff_get_symbol_info (abfd, symbol, ret) /*ARGSUSED*/ boolean -_bfd_ecoff_bfd_is_local_label (abfd, symbol) +_bfd_ecoff_bfd_is_local_label_name (abfd, name) bfd *abfd; - asymbol *symbol; + const char *name; { - return symbol->name[0] == '$'; + return name[0] == '$'; } /* Print information about an ECOFF symbol. */ @@ -1578,17 +1577,17 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how) case stFile: case stBlock: - fprintf (file, "\n End+1 symbol: %ld", + fprintf (file, _("\n End+1 symbol: %ld"), (long) (indx + sym_base)); break; case stEnd: if (ecoff_ext.asym.sc == scText || ecoff_ext.asym.sc == scInfo) - fprintf (file, "\n First symbol: %ld", + fprintf (file, _("\n First symbol: %ld"), (long) (indx + sym_base)); else - fprintf (file, "\n First symbol: %ld", + fprintf (file, _("\n First symbol: %ld"), ((long) (AUX_GET_ISYM (bigendian, &aux_base[ecoff_ext.asym.index]) @@ -1600,14 +1599,14 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how) if (ECOFF_IS_STAB (&ecoff_ext.asym)) ; else if (ecoffsymbol (symbol)->local) - fprintf (file, "\n End+1 symbol: %-7ld Type: %s", + fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"), ((long) (AUX_GET_ISYM (bigendian, &aux_base[ecoff_ext.asym.index]) + sym_base)), ecoff_type_to_string (abfd, fdr, indx + 1)); else - fprintf (file, "\n Local symbol: %ld", + fprintf (file, _("\n Local symbol: %ld"), ((long) indx + (long) sym_base + (ecoff_data (abfd) @@ -1615,23 +1614,23 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how) break; case stStruct: - fprintf (file, "\n struct; End+1 symbol: %ld", + fprintf (file, _("\n struct; End+1 symbol: %ld"), (long) (indx + sym_base)); break; case stUnion: - fprintf (file, "\n union; End+1 symbol: %ld", + fprintf (file, _("\n union; End+1 symbol: %ld"), (long) (indx + sym_base)); break; case stEnum: - fprintf (file, "\n enum; End+1 symbol: %ld", + fprintf (file, _("\n enum; End+1 symbol: %ld"), (long) (indx + sym_base)); break; default: if (! ECOFF_IS_STAB (&ecoff_ext.asym)) - fprintf (file, "\n Type: %s", + fprintf (file, _("\n Type: %s"), ecoff_type_to_string (abfd, fdr, indx)); break; } @@ -1858,10 +1857,10 @@ _bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd) size_t c; boolean local; - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses ECOFF + /* We only want to copy information over if both BFD's use ECOFF format. */ - if (bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) + if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour + || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) return true; /* Copy the GP value and the register masks. */ @@ -2045,6 +2044,7 @@ ecoff_compute_section_file_positions (abfd) asection *current; unsigned int i; file_ptr old_sofar; + boolean rdata_in_text; boolean first_data, first_nonalloc; const bfd_vma round = ecoff_backend (abfd)->round; @@ -2065,6 +2065,27 @@ ecoff_compute_section_file_positions (abfd) qsort (sorted_hdrs, abfd->section_count, sizeof (asection *), ecoff_sort_hdrs); + /* Some versions of the OSF linker put the .rdata section in the + text segment, and some do not. */ + rdata_in_text = ecoff_backend (abfd)->rdata_in_text; + if (rdata_in_text) + { + for (i = 0; i < abfd->section_count; i++) + { + current = sorted_hdrs[i]; + if (strcmp (current->name, _RDATA) == 0) + break; + if ((current->flags & SEC_CODE) == 0 + && strcmp (current->name, _PDATA) != 0 + && strcmp (current->name, _RCONST) != 0) + { + rdata_in_text = false; + break; + } + } + } + ecoff_data (abfd)->rdata_in_text = rdata_in_text; + first_data = true; first_nonalloc = true; for (i = 0; i < abfd->section_count; i++) @@ -2077,13 +2098,10 @@ ecoff_compute_section_file_positions (abfd) supposed to indicate the number of .pdata entries that are really in the section. Each entry is 8 bytes. We store this away in line_filepos before increasing the section size. */ - if (strcmp (current->name, _PDATA) != 0) - alignment_power = current->alignment_power; - else - { - current->line_filepos = current->_raw_size / 8; - alignment_power = 4; - } + if (strcmp (current->name, _PDATA) == 0) + current->line_filepos = current->_raw_size / 8; + + alignment_power = current->alignment_power; /* On Ultrix, the data sections in an executable file must be aligned to a page boundary within the file. This does not @@ -2095,7 +2113,7 @@ ecoff_compute_section_file_positions (abfd) && (abfd->flags & D_PAGED) != 0 && ! first_data && (current->flags & SEC_CODE) == 0 - && (! ecoff_backend (abfd)->rdata_in_text + && (! rdata_in_text || strcmp (current->name, _RDATA) != 0) && strcmp (current->name, _PDATA) != 0 && strcmp (current->name, _RCONST) != 0) @@ -2550,7 +2568,7 @@ _bfd_ecoff_write_object_contents (abfd) if ((section.s_flags & STYP_TEXT) != 0 || ((section.s_flags & STYP_RDATA) != 0 - && backend->rdata_in_text) + && ecoff_data (abfd)->rdata_in_text) || section.s_flags == STYP_PDATA || (section.s_flags & STYP_DYNAMIC) != 0 || (section.s_flags & STYP_LIBLIST) != 0 @@ -2921,6 +2939,8 @@ ecoff_armap_hash (s, rehash, size, hlog) { unsigned int hash; + if (hlog == 0) + return 0; hash = *s++; while (*s != '\0') hash = ((hash >> 27) | (hash << 5)) + *s++; @@ -3122,7 +3142,7 @@ _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx) /* Ultrix appears to use as a hash table size the least power of two greater than twice the number of entries. */ - for (hashlog = 0; (1 << hashlog) <= 2 * orl_count; hashlog++) + for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++) ; hashsize = 1 << hashlog; @@ -3161,7 +3181,14 @@ _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx) armap. */ hdr.ar_uid[0] = '0'; hdr.ar_gid[0] = '0'; +#if 0 hdr.ar_mode[0] = '0'; +#else + /* Building gcc ends up extracting the armap as a file - twice. */ + hdr.ar_mode[0] = '6'; + hdr.ar_mode[1] = '4'; + hdr.ar_mode[2] = '4'; +#endif sprintf (hdr.ar_size, "%-10d", (int) mapsize); @@ -3265,16 +3292,24 @@ const bfd_target * _bfd_ecoff_archive_p (abfd) bfd *abfd; { + struct artdata *tdata_hold; char armag[SARMAG + 1]; - if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG - || strncmp (armag, ARMAG, SARMAG) != 0) + tdata_hold = abfd->tdata.aout_ar_data; + + if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return (const bfd_target *) NULL; } + if (strncmp (armag, ARMAG, SARMAG) != 0) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + /* We are setting bfd_ardata(abfd) here, but since bfd_ardata involves a cast, we can't do it as the left operand of assignment. */ @@ -3282,7 +3317,10 @@ _bfd_ecoff_archive_p (abfd) (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); if (bfd_ardata (abfd) == (struct artdata *) NULL) - return (const bfd_target *) NULL; + { + abfd->tdata.aout_ar_data = tdata_hold; + return (const bfd_target *) NULL; + } bfd_ardata (abfd)->first_file_filepos = SARMAG; bfd_ardata (abfd)->cache = NULL; @@ -3295,10 +3333,43 @@ _bfd_ecoff_archive_p (abfd) || _bfd_ecoff_slurp_extended_name_table (abfd) == false) { bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = (struct artdata *) NULL; + abfd->tdata.aout_ar_data = tdata_hold; return (const bfd_target *) NULL; } + if (bfd_has_map (abfd)) + { + bfd *first; + + /* This archive has a map, so we may presume that the contents + are object files. Make sure that if the first file in the + archive can be recognized as an object file, it is for this + target. If not, assume that this is the wrong format. If + the first file is not an object file, somebody is doing + something weird, and we permit it so that ar -t will work. */ + + first = bfd_openr_next_archived_file (abfd, (bfd *) NULL); + if (first != NULL) + { + boolean fail; + + first->target_defaulted = false; + fail = false; + if (bfd_check_format (first, bfd_object) + && first->xvec != abfd->xvec) + { + (void) bfd_close (first); + bfd_release (abfd, bfd_ardata (abfd)); + abfd->tdata.aout_ar_data = tdata_hold; + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* We ought to close first here, but we can't, because we + have no way to remove it from the archive cache. FIXME. */ + } + } + return abfd->xvec; }