/* 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, 1997 Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
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)
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)
break;
case ALPHA_MAGIC:
+ case ALPHA_MAGIC_BSD:
arch = bfd_arch_alpha;
mach = 0;
break;
ecoff_get_magic (abfd)
bfd *abfd;
{
+ extern const bfd_target bsd_ecoffalpha_little_vec;
int big, little;
switch (bfd_get_arch (abfd))
return bfd_big_endian (abfd) ? big : little;
case bfd_arch_alpha:
- return ALPHA_MAGIC;
+ return (abfd->xvec == &bsd_ecoffalpha_little_vec
+ ? ALPHA_MAGIC_BSD : ALPHA_MAGIC);
default:
abort ();
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;
section->constructor_chain = reloc_chain;
section->_raw_size += bitsize / 8;
+#endif /* 0 */
+
/* Mark the symbol as a constructor. */
asym->flags |= BSF_CONSTRUCTOR;
}
/*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. */
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. */
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;
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++)
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
&& (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)
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
{
unsigned int hash;
+ if (hlog == 0)
+ return 0;
hash = *s++;
while (*s != '\0')
hash = ((hash >> 27) | (hash << 5)) + *s++;
_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. */
(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;
|| _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;
}
\f