* libecoff.h (struct ecoff_backend_data): Add adjust_headers
field. * ecoff.c (ecoff_sec_to_styp_flags): Check for various Alpha sections, and set styp correctly for them: .got, .hash, .dynamic, .liblist, .rel.dyn, .conflic, .dynstr, .dynsym, .comment. (_bfd_ecoff_styp_to_sec_flags): Check for various Alpha section types. (ecoff_sort_hdrs): New static function. (ecoff_compute_section_file_positions): Return boolean, not void. Sort the sections by VMA before looking through them. Put the first non SEC_ALLOC section on a new page. Put every SEC_ALLOC section on an appropriate boundary within the page. (ecoff_compute_reloc_file_positions): Check return value of ecoff_compute_section_file_positions. (_bfd_ecoff_set_section_contents): Likewise. (_bfd_ecoff_write_object_contents): Check for various Alpha section types when incrementing text_size and data_size. Call adjust_headers backend function if it exists. * coff-alpha.c (alpha_adjust_headers): New static function. (alpha_ecoff_backend_data): Initialize adjust_headers field. * coff-mips.c (mips_ecoff_backend_data): Likewise. PR 8141.
This commit is contained in:
parent
90ce63bb0e
commit
aca736871c
5 changed files with 188 additions and 35 deletions
|
@ -1,5 +1,27 @@
|
|||
Thu Oct 5 11:45:02 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* libecoff.h (struct ecoff_backend_data): Add adjust_headers
|
||||
field.
|
||||
* ecoff.c (ecoff_sec_to_styp_flags): Check for various Alpha
|
||||
sections, and set styp correctly for them: .got, .hash, .dynamic,
|
||||
.liblist, .rel.dyn, .conflic, .dynstr, .dynsym, .comment.
|
||||
(_bfd_ecoff_styp_to_sec_flags): Check for various Alpha section
|
||||
types.
|
||||
(ecoff_sort_hdrs): New static function.
|
||||
(ecoff_compute_section_file_positions): Return boolean, not void.
|
||||
Sort the sections by VMA before looking through them. Put the
|
||||
first non SEC_ALLOC section on a new page. Put every SEC_ALLOC
|
||||
section on an appropriate boundary within the page.
|
||||
(ecoff_compute_reloc_file_positions): Check return value of
|
||||
ecoff_compute_section_file_positions.
|
||||
(_bfd_ecoff_set_section_contents): Likewise.
|
||||
(_bfd_ecoff_write_object_contents): Check for various Alpha
|
||||
section types when incrementing text_size and data_size. Call
|
||||
adjust_headers backend function if it exists.
|
||||
* coff-alpha.c (alpha_adjust_headers): New static function.
|
||||
(alpha_ecoff_backend_data): Initialize adjust_headers field.
|
||||
* coff-mips.c (mips_ecoff_backend_data): Likewise.
|
||||
|
||||
* hosts/i386bsd.h: Restore file incorrectly deleted on Sep 6.
|
||||
|
||||
Wed Oct 4 18:15:02 1995 Jeff Law (law@hurl.cygnus.com)
|
||||
|
|
|
@ -55,6 +55,8 @@ static bfd_vma alpha_convert_external_reloc
|
|||
static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
|
||||
bfd *, asection *,
|
||||
bfd_byte *, PTR));
|
||||
static boolean alpha_adjust_headers
|
||||
PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
|
||||
|
||||
/* ECOFF has COFF sections, but the debugging information is stored in
|
||||
a completely different format. ECOFF targets use some of the
|
||||
|
@ -1935,6 +1937,23 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Do final adjustments to the filehdr and the aouthdr. This routine
|
||||
sets the dynamic bits in the file header. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
alpha_adjust_headers (abfd, fhdr, ahdr)
|
||||
bfd *abfd;
|
||||
struct internal_filehdr *fhdr;
|
||||
struct internal_aouthdr *ahdr;
|
||||
{
|
||||
if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
|
||||
fhdr->f_flags |= F_ALPHA_CALL_SHARED;
|
||||
else if ((abfd->flags & DYNAMIC) != 0)
|
||||
fhdr->f_flags |= F_ALPHA_SHARABLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is the ECOFF backend structure. The backend field of the
|
||||
target vector points to this. */
|
||||
|
||||
|
@ -1956,8 +1975,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
|
|||
alpha_ecoff_swap_scnhdr_in, NULL,
|
||||
alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
|
||||
alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
|
||||
_bfd_ecoff_make_section_hook, _bfd_ecoff_set_alignment_hook,
|
||||
_bfd_ecoff_slurp_symbol_table,
|
||||
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
/* Supported architecture. */
|
||||
|
@ -2023,7 +2041,9 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
|
|||
alpha_adjust_reloc_in,
|
||||
alpha_adjust_reloc_out,
|
||||
/* Relocate section contents while linking. */
|
||||
alpha_relocate_section
|
||||
alpha_relocate_section,
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
alpha_adjust_headers
|
||||
};
|
||||
|
||||
/* Looking up a reloc type is Alpha specific. */
|
||||
|
|
|
@ -2441,8 +2441,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
|
|||
mips_ecoff_swap_scnhdr_in, NULL,
|
||||
mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
|
||||
_bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
|
||||
_bfd_ecoff_make_section_hook, _bfd_ecoff_set_alignment_hook,
|
||||
_bfd_ecoff_slurp_symbol_table,
|
||||
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
/* Supported architecture. */
|
||||
|
@ -2508,7 +2507,9 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
|
|||
mips_adjust_reloc_in,
|
||||
mips_adjust_reloc_out,
|
||||
/* Relocate section contents while linking. */
|
||||
mips_relocate_section
|
||||
mips_relocate_section,
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Looking up a reloc type is MIPS specific. */
|
||||
|
|
164
bfd/ecoff.c
164
bfd/ecoff.c
|
@ -59,7 +59,8 @@ static char *ecoff_type_to_string PARAMS ((bfd *abfd, FDR *fdr,
|
|||
unsigned int indx));
|
||||
static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section,
|
||||
asymbol **symbols));
|
||||
static void ecoff_compute_section_file_positions PARAMS ((bfd *abfd));
|
||||
static int ecoff_sort_hdrs PARAMS ((const PTR, const PTR));
|
||||
static boolean ecoff_compute_section_file_positions PARAMS ((bfd *abfd));
|
||||
static bfd_size_type ecoff_compute_reloc_file_positions PARAMS ((bfd *abfd));
|
||||
static boolean ecoff_get_extr PARAMS ((asymbol *, EXTR *));
|
||||
static void ecoff_set_index PARAMS ((asymbol *, bfd_size_type));
|
||||
|
@ -135,17 +136,6 @@ _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
|
|||
return (PTR) ecoff;
|
||||
}
|
||||
|
||||
/* This is a hook needed by SCO COFF, but we have nothing to do. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
asection *
|
||||
_bfd_ecoff_make_section_hook (abfd, name)
|
||||
bfd *abfd;
|
||||
char *name;
|
||||
{
|
||||
return (asection *) NULL;
|
||||
}
|
||||
|
||||
/* Initialize a new section. */
|
||||
|
||||
boolean
|
||||
|
@ -324,6 +314,27 @@ ecoff_sec_to_styp_flags (name, flags)
|
|||
styp = STYP_XDATA;
|
||||
else if (strcmp (name, _LIB) == 0)
|
||||
styp = STYP_ECOFF_LIB;
|
||||
else if (strcmp (name, _GOT) == 0)
|
||||
styp = STYP_GOT;
|
||||
else if (strcmp (name, _HASH) == 0)
|
||||
styp = STYP_HASH;
|
||||
else if (strcmp (name, _DYNAMIC) == 0)
|
||||
styp = STYP_DYNAMIC;
|
||||
else if (strcmp (name, _LIBLIST) == 0)
|
||||
styp = STYP_LIBLIST;
|
||||
else if (strcmp (name, _RELDYN) == 0)
|
||||
styp = STYP_RELDYN;
|
||||
else if (strcmp (name, _CONFLIC) == 0)
|
||||
styp = STYP_CONFLIC;
|
||||
else if (strcmp (name, _DYNSTR) == 0)
|
||||
styp = STYP_DYNSTR;
|
||||
else if (strcmp (name, _DYNSYM) == 0)
|
||||
styp = STYP_DYNSYM;
|
||||
else if (strcmp (name, _COMMENT) == 0)
|
||||
{
|
||||
styp = STYP_COMMENT;
|
||||
flags &=~ SEC_NEVER_LOAD;
|
||||
}
|
||||
else if (flags & SEC_CODE)
|
||||
styp = STYP_TEXT;
|
||||
else if (flags & SEC_DATA)
|
||||
|
@ -361,7 +372,14 @@ _bfd_ecoff_styp_to_sec_flags (abfd, hdr, name)
|
|||
actually a shared library section. */
|
||||
if ((styp_flags & STYP_TEXT)
|
||||
|| (styp_flags & STYP_ECOFF_INIT)
|
||||
|| (styp_flags & STYP_ECOFF_FINI))
|
||||
|| (styp_flags & STYP_ECOFF_FINI)
|
||||
|| (styp_flags & STYP_DYNAMIC)
|
||||
|| (styp_flags & STYP_LIBLIST)
|
||||
|| (styp_flags & STYP_RELDYN)
|
||||
|| styp_flags == STYP_CONFLIC
|
||||
|| (styp_flags & STYP_DYNSTR)
|
||||
|| (styp_flags & STYP_DYNSYM)
|
||||
|| (styp_flags & STYP_HASH))
|
||||
{
|
||||
if (sec_flags & SEC_NEVER_LOAD)
|
||||
sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
|
||||
|
@ -372,7 +390,8 @@ _bfd_ecoff_styp_to_sec_flags (abfd, hdr, name)
|
|||
|| (styp_flags & STYP_RDATA)
|
||||
|| (styp_flags & STYP_SDATA)
|
||||
|| styp_flags == STYP_PDATA
|
||||
|| styp_flags == STYP_XDATA)
|
||||
|| styp_flags == STYP_XDATA
|
||||
|| (styp_flags & STYP_GOT))
|
||||
{
|
||||
if (sec_flags & SEC_NEVER_LOAD)
|
||||
sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
|
||||
|
@ -2011,27 +2030,77 @@ _bfd_ecoff_get_section_contents (abfd, section, location, offset, count)
|
|||
offset, count);
|
||||
}
|
||||
|
||||
/* Sort sections by VMA, but put SEC_ALLOC sections first. This is
|
||||
called via qsort. */
|
||||
|
||||
static int
|
||||
ecoff_sort_hdrs (arg1, arg2)
|
||||
const PTR arg1;
|
||||
const PTR arg2;
|
||||
{
|
||||
const asection *hdr1 = *(const asection **) arg1;
|
||||
const asection *hdr2 = *(const asection **) arg2;
|
||||
|
||||
if ((hdr1->flags & SEC_ALLOC) != 0)
|
||||
{
|
||||
if ((hdr2->flags & SEC_ALLOC) == 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((hdr2->flags & SEC_ALLOC) != 0)
|
||||
return 1;
|
||||
}
|
||||
if (hdr1->vma < hdr2->vma)
|
||||
return -1;
|
||||
else if (hdr1->vma > hdr2->vma)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate the file position for each section, and set
|
||||
reloc_filepos. */
|
||||
|
||||
static void
|
||||
static boolean
|
||||
ecoff_compute_section_file_positions (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
asection *current;
|
||||
file_ptr sofar;
|
||||
asection **sorted_hdrs;
|
||||
asection *current;
|
||||
unsigned int i;
|
||||
file_ptr old_sofar;
|
||||
boolean first_data;
|
||||
boolean first_data, first_nonalloc;
|
||||
const bfd_vma round = ecoff_backend (abfd)->round;
|
||||
|
||||
sofar = _bfd_ecoff_sizeof_headers (abfd, false);
|
||||
|
||||
/* Sort the sections by VMA. */
|
||||
sorted_hdrs = (asection **) malloc (abfd->section_count
|
||||
* sizeof (asection *));
|
||||
if (sorted_hdrs == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return false;
|
||||
}
|
||||
for (current = abfd->sections, i = 0;
|
||||
current != NULL;
|
||||
current = current->next, i++)
|
||||
sorted_hdrs[i] = current;
|
||||
BFD_ASSERT (i == abfd->section_count);
|
||||
|
||||
qsort (sorted_hdrs, abfd->section_count, sizeof (asection *),
|
||||
ecoff_sort_hdrs);
|
||||
|
||||
first_data = true;
|
||||
for (current = abfd->sections;
|
||||
current != (asection *) NULL;
|
||||
current = current->next)
|
||||
first_nonalloc = true;
|
||||
for (i = 0; i < abfd->section_count; i++)
|
||||
{
|
||||
unsigned int alignment_power;
|
||||
|
||||
current = sorted_hdrs[i];
|
||||
|
||||
/* Only deal with sections which have contents */
|
||||
if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) == 0)
|
||||
continue;
|
||||
|
@ -2062,26 +2131,37 @@ ecoff_compute_section_file_positions (abfd)
|
|||
|| strcmp (current->name, _RDATA) != 0)
|
||||
&& strcmp (current->name, _PDATA) != 0)
|
||||
{
|
||||
const bfd_vma round = ecoff_backend (abfd)->round;
|
||||
|
||||
sofar = (sofar + round - 1) &~ (round - 1);
|
||||
first_data = false;
|
||||
}
|
||||
else if (strcmp (current->name, _LIB) == 0)
|
||||
{
|
||||
const bfd_vma round = ecoff_backend (abfd)->round;
|
||||
/* On Irix 4, the location of contents of the .lib section
|
||||
from a shared library section is also rounded up to a
|
||||
page boundary. */
|
||||
|
||||
sofar = (sofar + round - 1) &~ (round - 1);
|
||||
}
|
||||
else if (first_nonalloc
|
||||
&& (current->flags & SEC_ALLOC) == 0
|
||||
&& (abfd->flags & D_PAGED) != 0)
|
||||
{
|
||||
/* Skip up to the next page for an unallocated section, such
|
||||
as the .comment section on the Alpha. This leaves room
|
||||
for the .bss section. */
|
||||
first_nonalloc = false;
|
||||
sofar = (sofar + round - 1) &~ (round - 1);
|
||||
}
|
||||
|
||||
/* Align the sections in the file to the same boundary on
|
||||
which they are aligned in virtual memory. */
|
||||
old_sofar = sofar;
|
||||
sofar = BFD_ALIGN (sofar, 1 << alignment_power);
|
||||
|
||||
if ((abfd->flags & D_PAGED) != 0
|
||||
&& (current->flags & SEC_ALLOC) != 0)
|
||||
sofar += (current->vma - sofar) % round;
|
||||
|
||||
current->filepos = sofar;
|
||||
|
||||
sofar += current->_raw_size;
|
||||
|
@ -2092,7 +2172,12 @@ ecoff_compute_section_file_positions (abfd)
|
|||
current->_raw_size += sofar - old_sofar;
|
||||
}
|
||||
|
||||
free (sorted_hdrs);
|
||||
sorted_hdrs = NULL;
|
||||
|
||||
ecoff_data (abfd)->reloc_filepos = sofar;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Determine the location of the relocs for all the sections in the
|
||||
|
@ -2112,7 +2197,8 @@ ecoff_compute_reloc_file_positions (abfd)
|
|||
|
||||
if (! abfd->output_has_begun)
|
||||
{
|
||||
ecoff_compute_section_file_positions (abfd);
|
||||
if (! ecoff_compute_section_file_positions (abfd))
|
||||
abort ();
|
||||
abfd->output_has_begun = true;
|
||||
}
|
||||
|
||||
|
@ -2164,7 +2250,10 @@ _bfd_ecoff_set_section_contents (abfd, section, location, offset, count)
|
|||
/* This must be done first, because bfd_set_section_contents is
|
||||
going to set output_has_begun to true. */
|
||||
if (abfd->output_has_begun == false)
|
||||
ecoff_compute_section_file_positions (abfd);
|
||||
{
|
||||
if (! ecoff_compute_section_file_positions (abfd))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If this is a .lib section, bump the vma address so that it winds
|
||||
up being the number of .lib sections output. This is right for
|
||||
|
@ -2472,7 +2561,16 @@ _bfd_ecoff_write_object_contents (abfd)
|
|||
if ((section.s_flags & STYP_TEXT) != 0
|
||||
|| ((section.s_flags & STYP_RDATA) != 0
|
||||
&& backend->rdata_in_text)
|
||||
|| strcmp (current->name, _PDATA) == 0)
|
||||
|| section.s_flags == STYP_PDATA
|
||||
|| (section.s_flags & STYP_DYNAMIC) != 0
|
||||
|| (section.s_flags & STYP_LIBLIST) != 0
|
||||
|| (section.s_flags & STYP_RELDYN) != 0
|
||||
|| section.s_flags == STYP_CONFLIC
|
||||
|| (section.s_flags & STYP_DYNSTR) != 0
|
||||
|| (section.s_flags & STYP_DYNSYM) != 0
|
||||
|| (section.s_flags & STYP_HASH) != 0
|
||||
|| (section.s_flags & STYP_ECOFF_INIT) != 0
|
||||
|| (section.s_flags & STYP_ECOFF_FINI) != 0)
|
||||
{
|
||||
text_size += bfd_get_section_size_before_reloc (current);
|
||||
if (! set_text_start || text_start > vma)
|
||||
|
@ -2487,7 +2585,8 @@ _bfd_ecoff_write_object_contents (abfd)
|
|||
|| (section.s_flags & STYP_LIT8) != 0
|
||||
|| (section.s_flags & STYP_LIT4) != 0
|
||||
|| (section.s_flags & STYP_SDATA) != 0
|
||||
|| strcmp (current->name, _XDATA) == 0)
|
||||
|| section.s_flags == STYP_XDATA
|
||||
|| (section.s_flags & STYP_GOT) != 0)
|
||||
{
|
||||
data_size += bfd_get_section_size_before_reloc (current);
|
||||
if (! set_data_start || data_start > vma)
|
||||
|
@ -2499,7 +2598,9 @@ _bfd_ecoff_write_object_contents (abfd)
|
|||
else if ((section.s_flags & STYP_BSS) != 0
|
||||
|| (section.s_flags & STYP_SBSS) != 0)
|
||||
bss_size += bfd_get_section_size_before_reloc (current);
|
||||
else if ((section.s_flags & STYP_ECOFF_LIB) != 0)
|
||||
else if (section.s_flags == 0
|
||||
|| (section.s_flags & STYP_ECOFF_LIB) != 0
|
||||
|| section.s_flags == STYP_COMMENT)
|
||||
/* Do nothing */ ;
|
||||
else
|
||||
abort ();
|
||||
|
@ -2591,6 +2692,13 @@ _bfd_ecoff_write_object_contents (abfd)
|
|||
for (i = 0; i < 4; i++)
|
||||
internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i];
|
||||
|
||||
/* Let the backend adjust the headers if necessary. */
|
||||
if (backend->adjust_headers)
|
||||
{
|
||||
if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a))
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Write out the file header and the optional header. */
|
||||
|
||||
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
|
||||
|
|
|
@ -68,6 +68,9 @@ struct ecoff_backend_data
|
|||
bfd *input_bfd, asection *input_section,
|
||||
bfd_byte *contents,
|
||||
PTR external_relocs));
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
boolean (*adjust_headers) PARAMS ((bfd *, struct internal_filehdr *,
|
||||
struct internal_aouthdr *));
|
||||
};
|
||||
|
||||
/* This is the target specific information kept for ECOFF files. */
|
||||
|
@ -312,7 +315,6 @@ extern boolean _bfd_ecoff_bfd_final_link
|
|||
/* Hook functions for the generic COFF section reading code. */
|
||||
|
||||
extern PTR _bfd_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
|
||||
extern asection *_bfd_ecoff_make_section_hook PARAMS ((bfd *abfd, char *name));
|
||||
#define _bfd_ecoff_set_alignment_hook \
|
||||
((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
|
||||
extern boolean _bfd_ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
|
||||
|
|
Loading…
Reference in a new issue