* libecoff.h: Include coff/ecoff.h.

(struct ecoff_backend_data): Move external debugging information
	fields into a single field pointing to an ecoff_debug_swap
	structure.
	(ecoff_data_type): Move debugging information fields into a single
	field pointing to an ecoff_debug_info structure.
	* coff-alpha.c, coff-mips.c, ecoff.c: Corresponding changes.
This commit is contained in:
Ian Lance Taylor
1993-11-18 00:07:33 +00:00
parent 4f09de58cd
commit c9668c588a
2 changed files with 258 additions and 183 deletions

View File

@ -1,3 +1,13 @@
Wed Nov 17 18:43:28 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* libecoff.h: Include coff/ecoff.h.
(struct ecoff_backend_data): Move external debugging information
fields into a single field pointing to an ecoff_debug_swap
structure.
(ecoff_data_type): Move debugging information fields into a single
field pointing to an ecoff_debug_info structure.
* coff-alpha.c, coff-mips.c, ecoff.c: Corresponding changes.
Wed Nov 17 13:56:10 1993 Stan Shebs (shebs@rtl.cygnus.com) Wed Nov 17 13:56:10 1993 Stan Shebs (shebs@rtl.cygnus.com)
* i386lynx.c (swap_std_reloc_in, swap_ext_reloc_in): Ignore * i386lynx.c (swap_std_reloc_in, swap_ext_reloc_in): Ignore

View File

@ -309,6 +309,8 @@ ecoff_sec_to_styp_flags (name, flags)
styp = STYP_SDATA; styp = STYP_SDATA;
else if (strcmp (name, _RDATA) == 0) else if (strcmp (name, _RDATA) == 0)
styp = STYP_RDATA; styp = STYP_RDATA;
else if (strcmp (name, _LITA) == 0)
styp = STYP_LITA;
else if (strcmp (name, _LIT8) == 0) else if (strcmp (name, _LIT8) == 0)
styp = STYP_LIT8; styp = STYP_LIT8;
else if (strcmp (name, _LIT4) == 0) else if (strcmp (name, _LIT4) == 0)
@ -383,7 +385,8 @@ ecoff_styp_to_sec_flags (abfd, hdr)
{ {
sec_flags |= SEC_NEVER_LOAD; sec_flags |= SEC_NEVER_LOAD;
} }
else if ((styp_flags & STYP_LIT8) else if ((styp_flags & STYP_LITA)
|| (styp_flags & STYP_LIT8)
|| (styp_flags & STYP_LIT4)) || (styp_flags & STYP_LIT4))
{ {
sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
@ -624,7 +627,7 @@ ecoff_slurp_symbolic_info (abfd)
as read from the file header, but on ECOFF this is always the as read from the file header, but on ECOFF this is always the
size of the symbolic information header. It would be cleaner to size of the symbolic information header. It would be cleaner to
handle this when we first read the file in coffgen.c. */ handle this when we first read the file in coffgen.c. */
external_hdr_size = backend->external_hdr_size; external_hdr_size = backend->debug_swap.external_hdr_size;
if (bfd_get_symcount (abfd) != external_hdr_size) if (bfd_get_symcount (abfd) != external_hdr_size)
{ {
bfd_error = bad_value; bfd_error = bad_value;
@ -640,10 +643,10 @@ ecoff_slurp_symbolic_info (abfd)
bfd_error = system_call_error; bfd_error = system_call_error;
return false; return false;
} }
internal_symhdr = &ecoff_data (abfd)->symbolic_header; internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
(*backend->swap_hdr_in) (abfd, raw, internal_symhdr); (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);
if (internal_symhdr->magic != backend->sym_magic) if (internal_symhdr->magic != backend->debug_swap.sym_magic)
{ {
bfd_error = bad_value; bfd_error = bad_value;
return false; return false;
@ -670,16 +673,16 @@ ecoff_slurp_symbolic_info (abfd)
raw_end = cb_end raw_end = cb_end
UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char)); UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char));
UPDATE_RAW_END (cbDnOffset, idnMax, backend->external_dnr_size); UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size);
UPDATE_RAW_END (cbPdOffset, ipdMax, backend->external_pdr_size); UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size);
UPDATE_RAW_END (cbSymOffset, isymMax, backend->external_sym_size); UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size);
UPDATE_RAW_END (cbOptOffset, ioptMax, backend->external_opt_size); UPDATE_RAW_END (cbOptOffset, ioptMax, backend->debug_swap.external_opt_size);
UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext)); UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext));
UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char)); UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char));
UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char)); UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char));
UPDATE_RAW_END (cbFdOffset, ifdMax, backend->external_fdr_size); UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size);
UPDATE_RAW_END (cbRfdOffset, crfd, backend->external_rfd_size); UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size);
UPDATE_RAW_END (cbExtOffset, iextMax, backend->external_ext_size); UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size);
#undef UPDATE_RAW_END #undef UPDATE_RAW_END
@ -708,11 +711,11 @@ ecoff_slurp_symbolic_info (abfd)
/* Get pointers for the numeric offsets in the HDRR structure. */ /* Get pointers for the numeric offsets in the HDRR structure. */
#define FIX(off1, off2, type) \ #define FIX(off1, off2, type) \
if (internal_symhdr->off1 == 0) \ if (internal_symhdr->off1 == 0) \
ecoff_data (abfd)->off2 = (type) NULL; \ ecoff_data (abfd)->debug_info.off2 = (type) NULL; \
else \ else \
ecoff_data (abfd)->off2 = (type) ((char *) raw \ ecoff_data (abfd)->debug_info.off2 = (type) ((char *) raw \
+ internal_symhdr->off1 \ + internal_symhdr->off1 \
- raw_base) - raw_base)
FIX (cbLineOffset, line, unsigned char *); FIX (cbLineOffset, line, unsigned char *);
FIX (cbDnOffset, external_dnr, PTR); FIX (cbDnOffset, external_dnr, PTR);
FIX (cbPdOffset, external_pdr, PTR); FIX (cbPdOffset, external_pdr, PTR);
@ -734,21 +737,21 @@ ecoff_slurp_symbolic_info (abfd)
We need to look at the fdr to deal with a lot of information in We need to look at the fdr to deal with a lot of information in
the symbols, so we swap them here. */ the symbols, so we swap them here. */
ecoff_data (abfd)->fdr = ecoff_data (abfd)->debug_info.fdr =
(struct fdr *) bfd_alloc (abfd, (struct fdr *) bfd_alloc (abfd,
(internal_symhdr->ifdMax * (internal_symhdr->ifdMax *
sizeof (struct fdr))); sizeof (struct fdr)));
if (ecoff_data (abfd)->fdr == NULL) if (ecoff_data (abfd)->debug_info.fdr == NULL)
{ {
bfd_error = no_memory; bfd_error = no_memory;
return false; return false;
} }
external_fdr_size = backend->external_fdr_size; external_fdr_size = backend->debug_swap.external_fdr_size;
fdr_ptr = ecoff_data (abfd)->fdr; fdr_ptr = ecoff_data (abfd)->debug_info.fdr;
fraw_src = (char *) ecoff_data (abfd)->external_fdr; fraw_src = (char *) ecoff_data (abfd)->debug_info.external_fdr;
fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size; fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
(*backend->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); (*backend->debug_swap.swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
return true; return true;
} }
@ -1047,12 +1050,14 @@ ecoff_slurp_symbol_table (abfd)
bfd *abfd; bfd *abfd;
{ {
const struct ecoff_backend_data * const backend = ecoff_backend (abfd); const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
const bfd_size_type external_ext_size = backend->external_ext_size; const bfd_size_type external_ext_size
const bfd_size_type external_sym_size = backend->external_sym_size; = backend->debug_swap.external_ext_size;
const bfd_size_type external_sym_size
= backend->debug_swap.external_sym_size;
void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
= backend->swap_ext_in; = backend->debug_swap.swap_ext_in;
void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
= backend->swap_sym_in; = backend->debug_swap.swap_sym_in;
bfd_size_type internal_size; bfd_size_type internal_size;
ecoff_symbol_type *internal; ecoff_symbol_type *internal;
ecoff_symbol_type *internal_ptr; ecoff_symbol_type *internal_ptr;
@ -1082,22 +1087,23 @@ ecoff_slurp_symbol_table (abfd)
internal_ptr = internal; internal_ptr = internal;
indirect_ptr = NULL; indirect_ptr = NULL;
eraw_src = (char *) ecoff_data (abfd)->external_ext; eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext;
eraw_end = (eraw_src eraw_end = (eraw_src
+ (ecoff_data (abfd)->symbolic_header.iextMax + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax
* external_ext_size)); * external_ext_size));
for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++) for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++)
{ {
EXTR internal_esym; EXTR internal_esym;
(*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym); (*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym);
internal_ptr->symbol.name = (ecoff_data (abfd)->ssext internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
+ internal_esym.asym.iss); + internal_esym.asym.iss);
ecoff_set_symbol_info (abfd, &internal_esym.asym, ecoff_set_symbol_info (abfd, &internal_esym.asym,
&internal_ptr->symbol, 1, &indirect_ptr); &internal_ptr->symbol, 1, &indirect_ptr);
/* The alpha uses a negative ifd field for section symbols. */ /* The alpha uses a negative ifd field for section symbols. */
if (internal_esym.ifd >= 0) if (internal_esym.ifd >= 0)
internal_ptr->fdr = ecoff_data (abfd)->fdr + internal_esym.ifd; internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
+ internal_esym.ifd);
else else
internal_ptr->fdr = NULL; internal_ptr->fdr = NULL;
internal_ptr->local = false; internal_ptr->local = false;
@ -1107,14 +1113,14 @@ ecoff_slurp_symbol_table (abfd)
/* The local symbols must be accessed via the fdr's, because the /* The local symbols must be accessed via the fdr's, because the
string and aux indices are relative to the fdr information. */ string and aux indices are relative to the fdr information. */
fdr_ptr = ecoff_data (abfd)->fdr; fdr_ptr = ecoff_data (abfd)->debug_info.fdr;
fdr_end = fdr_ptr + ecoff_data (abfd)->symbolic_header.ifdMax; fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax;
for (; fdr_ptr < fdr_end; fdr_ptr++) for (; fdr_ptr < fdr_end; fdr_ptr++)
{ {
char *lraw_src; char *lraw_src;
char *lraw_end; char *lraw_end;
lraw_src = ((char *) ecoff_data (abfd)->external_sym lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym
+ fdr_ptr->isymBase * external_sym_size); + fdr_ptr->isymBase * external_sym_size);
lraw_end = lraw_src + fdr_ptr->csym * external_sym_size; lraw_end = lraw_src + fdr_ptr->csym * external_sym_size;
for (; for (;
@ -1124,7 +1130,7 @@ ecoff_slurp_symbol_table (abfd)
SYMR internal_sym; SYMR internal_sym;
(*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym); (*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym);
internal_ptr->symbol.name = (ecoff_data (abfd)->ss internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss
+ fdr_ptr->issBase + fdr_ptr->issBase
+ internal_sym.iss); + internal_sym.iss);
ecoff_set_symbol_info (abfd, &internal_sym, ecoff_set_symbol_info (abfd, &internal_sym,
@ -1201,28 +1207,31 @@ ecoff_emit_aggregate (abfd, string, rndx, isym, which)
if (ifd == 0xfff) if (ifd == 0xfff)
ifd = isym; ifd = isym;
sym_base = ecoff_data (abfd)->fdr[ifd].isymBase; sym_base = ecoff_data (abfd)->debug_info.fdr[ifd].isymBase;
ss_base = ecoff_data (abfd)->fdr[ifd].issBase; ss_base = ecoff_data (abfd)->debug_info.fdr[ifd].issBase;
if (indx == indexNil) if (indx == indexNil)
name = "/* no name */"; name = "/* no name */";
else else
{ {
const struct ecoff_backend_data * const backend = ecoff_backend (abfd); const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
SYMR sym; SYMR sym;
indx += sym_base; indx += sym_base;
(*backend->swap_sym_in) (abfd, (*debug_swap->swap_sym_in)
((char *) ecoff_data (abfd)->external_sym (abfd,
+ indx * backend->external_sym_size), ((char *) ecoff_data (abfd)->debug_info.external_sym
&sym); + indx * debug_swap->external_sym_size),
name = ecoff_data (abfd)->ss + ss_base + sym.iss; &sym);
name = ecoff_data (abfd)->debug_info.ss + ss_base + sym.iss;
} }
sprintf (string, sprintf (string,
"%s %s { ifd = %d, index = %d }", "%s %s { ifd = %d, index = %ld }",
which, name, ifd, which, name, ifd,
indx + ecoff_data (abfd)->symbolic_header.iextMax); ((long) indx
+ ecoff_data (abfd)->debug_info.symbolic_header.iextMax));
} }
/* Convert the type information to string format. */ /* Convert the type information to string format. */
@ -1551,7 +1560,8 @@ ecoff_print_symbol (abfd, filep, symbol, how)
asymbol *symbol; asymbol *symbol;
bfd_print_symbol_type how; bfd_print_symbol_type how;
{ {
const struct ecoff_backend_data * const backend = ecoff_backend (abfd); const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
FILE *file = (FILE *)filep; FILE *file = (FILE *)filep;
switch (how) switch (how)
@ -1564,8 +1574,8 @@ ecoff_print_symbol (abfd, filep, symbol, how)
{ {
SYMR ecoff_sym; SYMR ecoff_sym;
(*backend->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
&ecoff_sym); &ecoff_sym);
fprintf (file, "ecoff local "); fprintf (file, "ecoff local ");
fprintf_vma (file, (bfd_vma) ecoff_sym.value); fprintf_vma (file, (bfd_vma) ecoff_sym.value);
fprintf (file, " %x %x", (unsigned) ecoff_sym.st, fprintf (file, " %x %x", (unsigned) ecoff_sym.st,
@ -1575,8 +1585,8 @@ ecoff_print_symbol (abfd, filep, symbol, how)
{ {
EXTR ecoff_ext; EXTR ecoff_ext;
(*backend->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
&ecoff_ext); &ecoff_ext);
fprintf (file, "ecoff extern "); fprintf (file, "ecoff extern ");
fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st, fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st,
@ -1595,25 +1605,25 @@ ecoff_print_symbol (abfd, filep, symbol, how)
if (ecoffsymbol (symbol)->local) if (ecoffsymbol (symbol)->local)
{ {
(*backend->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
&ecoff_ext.asym); &ecoff_ext.asym);
type = 'l'; type = 'l';
pos = ((((char *) ecoffsymbol (symbol)->native pos = ((((char *) ecoffsymbol (symbol)->native
- (char *) ecoff_data (abfd)->external_sym) - (char *) ecoff_data (abfd)->debug_info.external_sym)
/ backend->external_sym_size) / debug_swap->external_sym_size)
+ ecoff_data (abfd)->symbolic_header.iextMax); + ecoff_data (abfd)->debug_info.symbolic_header.iextMax);
jmptbl = ' '; jmptbl = ' ';
cobol_main = ' '; cobol_main = ' ';
weakext = ' '; weakext = ' ';
} }
else else
{ {
(*backend->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
&ecoff_ext); &ecoff_ext);
type = 'e'; type = 'e';
pos = (((char *) ecoffsymbol (symbol)->native pos = (((char *) ecoffsymbol (symbol)->native
- (char *) ecoff_data (abfd)->external_ext) - (char *) ecoff_data (abfd)->debug_info.external_ext)
/ backend->external_ext_size); / debug_swap->external_ext_size);
jmptbl = ecoff_ext.jmptbl ? 'j' : ' '; jmptbl = ecoff_ext.jmptbl ? 'j' : ' ';
cobol_main = ecoff_ext.cobol_main ? 'c' : ' '; cobol_main = ecoff_ext.cobol_main ? 'c' : ' ';
weakext = ecoff_ext.weakext ? 'w' : ' '; weakext = ecoff_ext.weakext ? 'w' : ' ';
@ -1644,11 +1654,12 @@ ecoff_print_symbol (abfd, filep, symbol, how)
using. */ using. */
sym_base = ecoffsymbol (symbol)->fdr->isymBase; sym_base = ecoffsymbol (symbol)->fdr->isymBase;
if (ecoffsymbol (symbol)->local) if (ecoffsymbol (symbol)->local)
sym_base += ecoff_data (abfd)->symbolic_header.iextMax; sym_base +=
ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
/* aux_base is the start of the aux entries for this file; /* aux_base is the start of the aux entries for this file;
asym.index is an offset from this. */ asym.index is an offset from this. */
aux_base = (ecoff_data (abfd)->external_aux aux_base = (ecoff_data (abfd)->debug_info.external_aux
+ ecoffsymbol (symbol)->fdr->iauxBase); + ecoffsymbol (symbol)->fdr->iauxBase);
/* The aux entries are stored in host byte order; the /* The aux entries are stored in host byte order; the
@ -1692,10 +1703,11 @@ ecoff_print_symbol (abfd, filep, symbol, how)
ecoff_type_to_string (abfd, aux_base, indx + 1, ecoff_type_to_string (abfd, aux_base, indx + 1,
bigendian)); bigendian));
else else
fprintf (file, "\n Local symbol: %d", fprintf (file, "\n Local symbol: %ld",
(indx ((long) indx
+ sym_base + (long) sym_base
+ ecoff_data (abfd)->symbolic_header.iextMax)); + (ecoff_data (abfd)
->debug_info.symbolic_header.iextMax)));
break; break;
default: default:
@ -1769,7 +1781,8 @@ ecoff_slurp_reloc_table (abfd, section, symbols)
/* r_symndx is an index into the external symbols. */ /* r_symndx is an index into the external symbols. */
BFD_ASSERT (intern.r_symndx >= 0 BFD_ASSERT (intern.r_symndx >= 0
&& (intern.r_symndx && (intern.r_symndx
< ecoff_data (abfd)->symbolic_header.iextMax)); < (ecoff_data (abfd)
->debug_info.symbolic_header.iextMax)));
rptr->sym_ptr_ptr = symbols + intern.r_symndx; rptr->sym_ptr_ptr = symbols + intern.r_symndx;
rptr->addend = 0; rptr->addend = 0;
} }
@ -1798,6 +1811,7 @@ ecoff_slurp_reloc_table (abfd, section, symbols)
case RELOC_SECTION_LIT4: sec_name = ".lit4"; break; case RELOC_SECTION_LIT4: sec_name = ".lit4"; break;
case RELOC_SECTION_XDATA: sec_name = ".xdata"; break; case RELOC_SECTION_XDATA: sec_name = ".xdata"; break;
case RELOC_SECTION_PDATA: sec_name = ".pdata"; break; case RELOC_SECTION_PDATA: sec_name = ".pdata"; break;
case RELOC_SECTION_FINI: sec_name = ".fini"; break;
case RELOC_SECTION_LITA: sec_name = ".lita"; break; case RELOC_SECTION_LITA: sec_name = ".lita"; break;
default: abort (); default: abort ();
} }
@ -1814,7 +1828,7 @@ ecoff_slurp_reloc_table (abfd, section, symbols)
/* Let the backend select the howto field and do any other /* Let the backend select the howto field and do any other
required processing. */ required processing. */
(*backend->finish_reloc) (abfd, &intern, rptr); (*backend->adjust_reloc_in) (abfd, &intern, rptr);
} }
bfd_release (abfd, external_relocs); bfd_release (abfd, external_relocs);
@ -1887,7 +1901,8 @@ ecoff_find_nearest_line (abfd,
CONST char **functionname_ptr; CONST char **functionname_ptr;
unsigned int *retline_ptr; unsigned int *retline_ptr;
{ {
const struct ecoff_backend_data * const backend = ecoff_backend (abfd); const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
FDR *fdr_ptr; FDR *fdr_ptr;
FDR *fdr_start; FDR *fdr_start;
FDR *fdr_end; FDR *fdr_end;
@ -1917,8 +1932,8 @@ ecoff_find_nearest_line (abfd,
memory order. If speed is ever important, this can become a memory order. If speed is ever important, this can become a
binary search. We must ignore FDR's with no PDR entries; they binary search. We must ignore FDR's with no PDR entries; they
will have the adr of the FDR before or after them. */ will have the adr of the FDR before or after them. */
fdr_start = ecoff_data (abfd)->fdr; fdr_start = ecoff_data (abfd)->debug_info.fdr;
fdr_end = fdr_start + ecoff_data (abfd)->symbolic_header.ifdMax; fdr_end = fdr_start + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax;
fdr_hold = (FDR *) NULL; fdr_hold = (FDR *) NULL;
for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++) for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{ {
@ -1936,11 +1951,11 @@ ecoff_find_nearest_line (abfd,
have an address, which is relative to the FDR address, and are have an address, which is relative to the FDR address, and are
also stored in increasing memory order. */ also stored in increasing memory order. */
offset -= fdr_ptr->adr; offset -= fdr_ptr->adr;
external_pdr_size = backend->external_pdr_size; external_pdr_size = debug_swap->external_pdr_size;
pdr_ptr = ((char *) ecoff_data (abfd)->external_pdr pdr_ptr = ((char *) ecoff_data (abfd)->debug_info.external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size); + fdr_ptr->ipdFirst * external_pdr_size);
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size; pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
(*backend->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
/* The address of the first PDR is an offset which applies to the /* The address of the first PDR is an offset which applies to the
addresses of all the PDR's. */ addresses of all the PDR's. */
@ -1950,7 +1965,7 @@ ecoff_find_nearest_line (abfd,
pdr_ptr < pdr_end; pdr_ptr < pdr_end;
pdr_ptr += external_pdr_size) pdr_ptr += external_pdr_size)
{ {
(*backend->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
if (offset < pdr.adr) if (offset < pdr.adr)
break; break;
} }
@ -1959,7 +1974,7 @@ ecoff_find_nearest_line (abfd,
stored in a very funky format, which I won't try to describe. stored in a very funky format, which I won't try to describe.
Note that right here pdr_ptr and pdr hold the PDR *after* the one Note that right here pdr_ptr and pdr hold the PDR *after* the one
we want; we need this to compute line_end. */ we want; we need this to compute line_end. */
line_end = ecoff_data (abfd)->line; line_end = ecoff_data (abfd)->debug_info.line;
if (pdr_ptr == pdr_end) if (pdr_ptr == pdr_end)
line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine; line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
else else
@ -1967,11 +1982,11 @@ ecoff_find_nearest_line (abfd,
/* Now change pdr and pdr_ptr to the one we want. */ /* Now change pdr and pdr_ptr to the one we want. */
pdr_ptr -= external_pdr_size; pdr_ptr -= external_pdr_size;
(*backend->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
offset -= pdr.adr; offset -= pdr.adr;
lineno = pdr.lnLow; lineno = pdr.lnLow;
line_ptr = (ecoff_data (abfd)->line line_ptr = (ecoff_data (abfd)->debug_info.line
+ fdr_ptr->cbLineOffset + fdr_ptr->cbLineOffset
+ pdr.cbLineOffset); + pdr.cbLineOffset);
while (line_ptr < line_end) while (line_ptr < line_end)
@ -2008,24 +2023,28 @@ ecoff_find_nearest_line (abfd,
{ {
EXTR proc_ext; EXTR proc_ext;
(*backend->swap_ext_in) (abfd, (*debug_swap->swap_ext_in)
((char *) ecoff_data (abfd)->external_ext (abfd,
+ pdr.isym * backend->external_ext_size), ((char *) ecoff_data (abfd)->debug_info.external_ext
&proc_ext); + pdr.isym * debug_swap->external_ext_size),
*functionname_ptr = ecoff_data (abfd)->ssext + proc_ext.asym.iss; &proc_ext);
*functionname_ptr = (ecoff_data (abfd)->debug_info.ssext
+ proc_ext.asym.iss);
} }
} }
else else
{ {
SYMR proc_sym; SYMR proc_sym;
*filename_ptr = ecoff_data (abfd)->ss + fdr_ptr->issBase + fdr_ptr->rss; *filename_ptr = (ecoff_data (abfd)->debug_info.ss
(*backend->swap_sym_in) (abfd, + fdr_ptr->issBase
((char *) ecoff_data (abfd)->external_sym + fdr_ptr->rss);
+ ((fdr_ptr->isymBase + pdr.isym) (*debug_swap->swap_sym_in)
* backend->external_sym_size)), (abfd,
&proc_sym); ((char *) ecoff_data (abfd)->debug_info.external_sym
*functionname_ptr = (ecoff_data (abfd)->ss + (fdr_ptr->isymBase + pdr.isym) * debug_swap->external_sym_size),
&proc_sym);
*functionname_ptr = (ecoff_data (abfd)->debug_info.ss
+ fdr_ptr->issBase + fdr_ptr->issBase
+ proc_sym.iss); + proc_sym.iss);
} }
@ -2119,7 +2138,7 @@ ecoff_rel (output_bfd, seclet, output_section, data, relocateable)
return true; return true;
input_bfd->output_has_begun = true; input_bfd->output_has_begun = true;
output_symhdr = &ecoff_data (output_bfd)->symbolic_header; output_symhdr = &ecoff_data (output_bfd)->debug_info.symbolic_header;
if (input_bfd->xvec->flavour != bfd_target_ecoff_flavour) if (input_bfd->xvec->flavour != bfd_target_ecoff_flavour)
{ {
@ -2165,7 +2184,7 @@ ecoff_rel (output_bfd, seclet, output_section, data, relocateable)
if (bfd_get_symcount (input_bfd) == 0) if (bfd_get_symcount (input_bfd) == 0)
return true; return true;
input_symhdr = &ecoff_data (input_bfd)->symbolic_header; input_symhdr = &ecoff_data (input_bfd)->debug_info.symbolic_header;
/* Figure out how much information we are going to be putting in. /* Figure out how much information we are going to be putting in.
The external symbols are handled separately. */ The external symbols are handled separately. */
@ -2252,17 +2271,18 @@ ecoff_add_string (output_bfd, fdr, string, external)
size_t len; size_t len;
long ret; long ret;
symhdr = &ecoff_data (output_bfd)->symbolic_header; symhdr = &ecoff_data (output_bfd)->debug_info.symbolic_header;
len = strlen (string); len = strlen (string);
if (external) if (external)
{ {
strcpy (ecoff_data (output_bfd)->ssext + symhdr->issExtMax, string); strcpy (ecoff_data (output_bfd)->debug_info.ssext + symhdr->issExtMax,
string);
ret = symhdr->issExtMax; ret = symhdr->issExtMax;
symhdr->issExtMax += len + 1; symhdr->issExtMax += len + 1;
} }
else else
{ {
strcpy (ecoff_data (output_bfd)->ss + symhdr->issMax, string); strcpy (ecoff_data (output_bfd)->debug_info.ss + symhdr->issMax, string);
ret = fdr->cbSs; ret = fdr->cbSs;
symhdr->issMax += len + 1; symhdr->issMax += len + 1;
fdr->cbSs += len + 1; fdr->cbSs += len + 1;
@ -2279,21 +2299,22 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
asection *section; asection *section;
boolean relocateable; boolean relocateable;
{ {
const struct ecoff_backend_data * const backend = ecoff_backend (output_bfd); const struct ecoff_debug_swap * const debug_swap
const bfd_size_type external_sym_size = backend->external_sym_size; = &ecoff_backend (output_bfd)->debug_swap;
const bfd_size_type external_pdr_size = backend->external_pdr_size; const bfd_size_type external_sym_size = debug_swap->external_sym_size;
const bfd_size_type external_fdr_size = backend->external_fdr_size; const bfd_size_type external_pdr_size = debug_swap->external_pdr_size;
const bfd_size_type external_rfd_size = backend->external_rfd_size; const bfd_size_type external_fdr_size = debug_swap->external_fdr_size;
const bfd_size_type external_rfd_size = debug_swap->external_rfd_size;
void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
= backend->swap_sym_in; = debug_swap->swap_sym_in;
void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR)) void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
= backend->swap_sym_out; = debug_swap->swap_sym_out;
void (* const swap_pdr_in) PARAMS ((bfd *, PTR, PDR *)) void (* const swap_pdr_in) PARAMS ((bfd *, PTR, PDR *))
= backend->swap_pdr_in; = debug_swap->swap_pdr_in;
void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR)) void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
= backend->swap_fdr_out; = debug_swap->swap_fdr_out;
void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR)) void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
= backend->swap_rfd_out; = debug_swap->swap_rfd_out;
bfd *input_bfd; bfd *input_bfd;
HDRR *output_symhdr; HDRR *output_symhdr;
HDRR *input_symhdr; HDRR *input_symhdr;
@ -2315,7 +2336,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
input_bfd->output_has_begun = true; input_bfd->output_has_begun = true;
output_ecoff = ecoff_data (output_bfd); output_ecoff = ecoff_data (output_bfd);
output_symhdr = &output_ecoff->symbolic_header; output_symhdr = &output_ecoff->debug_info.symbolic_header;
if (input_bfd->xvec->flavour != bfd_target_ecoff_flavour) if (input_bfd->xvec->flavour != bfd_target_ecoff_flavour)
{ {
@ -2373,7 +2394,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
internal_sym.sc = scUndefined; internal_sym.sc = scUndefined;
internal_sym.index = indexNil; internal_sym.index = indexNil;
(*swap_sym_out) (output_bfd, &internal_sym, (*swap_sym_out) (output_bfd, &internal_sym,
((char *) output_ecoff->external_sym ((char *) output_ecoff->debug_info.external_sym
+ output_symhdr->isymMax * external_sym_size)); + output_symhdr->isymMax * external_sym_size));
++fdr.csym; ++fdr.csym;
++output_symhdr->isymMax; ++output_symhdr->isymMax;
@ -2387,7 +2408,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
it only applies to aux fields and there are none. */ it only applies to aux fields and there are none. */
(*swap_fdr_out) (output_bfd, &fdr, (*swap_fdr_out) (output_bfd, &fdr,
((char *) output_ecoff->external_fdr ((char *) output_ecoff->debug_info.external_fdr
+ output_symhdr->ifdMax * external_fdr_size)); + output_symhdr->ifdMax * external_fdr_size));
++output_symhdr->ifdMax; ++output_symhdr->ifdMax;
return true; return true;
@ -2399,7 +2420,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
if (count == 0) if (count == 0)
return true; return true;
input_ecoff = ecoff_data (input_bfd); input_ecoff = ecoff_data (input_bfd);
input_symhdr = &input_ecoff->symbolic_header; input_symhdr = &input_ecoff->debug_info.symbolic_header;
/* I think that it is more efficient to simply copy the debugging /* I think that it is more efficient to simply copy the debugging
information from the input BFD to the output BFD. Because ECOFF information from the input BFD to the output BFD. Because ECOFF
@ -2408,7 +2429,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
/* Swap in the local symbols, adjust their values, and swap them out /* Swap in the local symbols, adjust their values, and swap them out
again. The external symbols are handled separately. */ again. The external symbols are handled separately. */
sym_out = ((char *) output_ecoff->external_sym sym_out = ((char *) output_ecoff->debug_info.external_sym
+ output_symhdr->isymMax * external_sym_size); + output_symhdr->isymMax * external_sym_size);
esym_ptr = ecoff_data (input_bfd)->canonical_symbols; esym_ptr = ecoff_data (input_bfd)->canonical_symbols;
@ -2446,14 +2467,14 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
input_bfd. */ input_bfd. */
/* Copy the information that does not need swapping. */ /* Copy the information that does not need swapping. */
memcpy (output_ecoff->line + output_symhdr->cbLine, memcpy (output_ecoff->debug_info.line + output_symhdr->cbLine,
input_ecoff->line, input_ecoff->debug_info.line,
input_symhdr->cbLine * sizeof (unsigned char)); input_symhdr->cbLine * sizeof (unsigned char));
memcpy (output_ecoff->external_aux + output_symhdr->iauxMax, memcpy (output_ecoff->debug_info.external_aux + output_symhdr->iauxMax,
input_ecoff->external_aux, input_ecoff->debug_info.external_aux,
input_symhdr->iauxMax * sizeof (union aux_ext)); input_symhdr->iauxMax * sizeof (union aux_ext));
memcpy (output_ecoff->ss + output_symhdr->issMax, memcpy (output_ecoff->debug_info.ss + output_symhdr->issMax,
input_ecoff->ss, input_ecoff->debug_info.ss,
input_symhdr->issMax * sizeof (char)); input_symhdr->issMax * sizeof (char));
/* Some of the information may need to be swapped. */ /* Some of the information may need to be swapped. */
@ -2463,20 +2484,20 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
/* The two BFD's have the same endianness, so memcpy will /* The two BFD's have the same endianness, so memcpy will
suffice. */ suffice. */
if (input_symhdr->idnMax > 0) if (input_symhdr->idnMax > 0)
memcpy (((char *) output_ecoff->external_dnr memcpy (((char *) output_ecoff->debug_info.external_dnr
+ output_symhdr->idnMax * backend->external_dnr_size), + output_symhdr->idnMax * debug_swap->external_dnr_size),
input_ecoff->external_dnr, input_ecoff->debug_info.external_dnr,
input_symhdr->idnMax * backend->external_dnr_size); input_symhdr->idnMax * debug_swap->external_dnr_size);
if (input_symhdr->ipdMax > 0) if (input_symhdr->ipdMax > 0)
memcpy (((char *) output_ecoff->external_pdr memcpy (((char *) output_ecoff->debug_info.external_pdr
+ output_symhdr->ipdMax * external_pdr_size), + output_symhdr->ipdMax * external_pdr_size),
input_ecoff->external_pdr, input_ecoff->debug_info.external_pdr,
input_symhdr->ipdMax * external_pdr_size); input_symhdr->ipdMax * external_pdr_size);
if (input_symhdr->ioptMax > 0) if (input_symhdr->ioptMax > 0)
memcpy (((char *) output_ecoff->external_opt memcpy (((char *) output_ecoff->debug_info.external_opt
+ output_symhdr->ioptMax * backend->external_opt_size), + output_symhdr->ioptMax * debug_swap->external_opt_size),
input_ecoff->external_opt, input_ecoff->debug_info.external_opt,
input_symhdr->ioptMax * backend->external_opt_size); input_symhdr->ioptMax * debug_swap->external_opt_size);
} }
else else
{ {
@ -2488,40 +2509,43 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
/* The two BFD's have different endianness, so we must swap /* The two BFD's have different endianness, so we must swap
everything in and out. This code would always work, but it everything in and out. This code would always work, but it
would be slow in the normal case. */ would be slow in the normal case. */
sz = backend->external_dnr_size; sz = debug_swap->external_dnr_size;
in = (char *) input_ecoff->external_dnr; in = (char *) input_ecoff->debug_info.external_dnr;
end = in + input_symhdr->idnMax * sz; end = in + input_symhdr->idnMax * sz;
out = (char *) output_ecoff->external_dnr + output_symhdr->idnMax * sz; out = ((char *) output_ecoff->debug_info.external_dnr
+ output_symhdr->idnMax * sz);
for (; in < end; in += sz, out += sz) for (; in < end; in += sz, out += sz)
{ {
DNR dnr; DNR dnr;
(*backend->swap_dnr_in) (input_bfd, in, &dnr); (*debug_swap->swap_dnr_in) (input_bfd, in, &dnr);
(*backend->swap_dnr_out) (output_bfd, &dnr, out); (*debug_swap->swap_dnr_out) (output_bfd, &dnr, out);
} }
sz = external_pdr_size; sz = external_pdr_size;
in = (char *) input_ecoff->external_pdr; in = (char *) input_ecoff->debug_info.external_pdr;
end = in + input_symhdr->ipdMax * sz; end = in + input_symhdr->ipdMax * sz;
out = (char *) output_ecoff->external_pdr + output_symhdr->ipdMax * sz; out = ((char *) output_ecoff->debug_info.external_pdr
+ output_symhdr->ipdMax * sz);
for (; in < end; in += sz, out += sz) for (; in < end; in += sz, out += sz)
{ {
PDR pdr; PDR pdr;
(*swap_pdr_in) (input_bfd, in, &pdr); (*swap_pdr_in) (input_bfd, in, &pdr);
(*backend->swap_pdr_out) (output_bfd, &pdr, out); (*debug_swap->swap_pdr_out) (output_bfd, &pdr, out);
} }
sz = backend->external_opt_size; sz = debug_swap->external_opt_size;
in = (char *) input_ecoff->external_opt; in = (char *) input_ecoff->debug_info.external_opt;
end = in + input_symhdr->ioptMax * sz; end = in + input_symhdr->ioptMax * sz;
out = (char *) output_ecoff->external_opt + output_symhdr->ioptMax * sz; out = ((char *) output_ecoff->debug_info.external_opt
+ output_symhdr->ioptMax * sz);
for (; in < end; in += sz, out += sz) for (; in < end; in += sz, out += sz)
{ {
OPTR opt; OPTR opt;
(*backend->swap_opt_in) (input_bfd, in, &opt); (*debug_swap->swap_opt_in) (input_bfd, in, &opt);
(*backend->swap_opt_out) (output_bfd, &opt, out); (*debug_swap->swap_opt_out) (output_bfd, &opt, out);
} }
} }
@ -2529,9 +2553,9 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
ifd values. */ ifd values. */
input_ecoff->ifdbase = output_symhdr->ifdMax; input_ecoff->ifdbase = output_symhdr->ifdMax;
fdr_ptr = input_ecoff->fdr; fdr_ptr = input_ecoff->debug_info.fdr;
fdr_end = fdr_ptr + input_symhdr->ifdMax; fdr_end = fdr_ptr + input_symhdr->ifdMax;
fdr_out = ((char *) output_ecoff->external_fdr fdr_out = ((char *) output_ecoff->debug_info.external_fdr
+ output_symhdr->ifdMax * external_fdr_size); + output_symhdr->ifdMax * external_fdr_size);
for (; fdr_ptr < fdr_end; fdr_ptr++, fdr_out += external_fdr_size) for (; fdr_ptr < fdr_end; fdr_ptr++, fdr_out += external_fdr_size)
{ {
@ -2551,14 +2575,14 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
PDR pdr; PDR pdr;
(*swap_pdr_in) (input_bfd, (*swap_pdr_in) (input_bfd,
((char *) input_ecoff->external_pdr ((char *) input_ecoff->debug_info.external_pdr
+ fdr.ipdFirst * external_pdr_size), + fdr.ipdFirst * external_pdr_size),
&pdr); &pdr);
pdr_off = pdr.adr; pdr_off = pdr.adr;
} }
fdr.adr = (bfd_get_section_vma (output_bfd, section) fdr.adr = (bfd_get_section_vma (output_bfd, section)
+ seclet->offset + seclet->offset
+ (fdr_ptr->adr - input_ecoff->fdr->adr) + (fdr_ptr->adr - input_ecoff->debug_info.fdr->adr)
+ pdr_off); + pdr_off);
fdr.issBase += output_symhdr->issMax; fdr.issBase += output_symhdr->issMax;
@ -2584,7 +2608,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
if (input_symhdr->crfd > 0) if (input_symhdr->crfd > 0)
{ {
void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *)) void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
= backend->swap_rfd_in; = debug_swap->swap_rfd_in;
char *rfd_in; char *rfd_in;
char *rfd_end; char *rfd_end;
char *rfd_out; char *rfd_out;
@ -2593,9 +2617,9 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
linker, so this will only be necessary if one of the input linker, so this will only be necessary if one of the input
files is the result of a partial link. Presumably all files is the result of a partial link. Presumably all
necessary RFD's are present. */ necessary RFD's are present. */
rfd_in = (char *) input_ecoff->external_rfd; rfd_in = (char *) input_ecoff->debug_info.external_rfd;
rfd_end = rfd_in + input_symhdr->crfd * external_rfd_size; rfd_end = rfd_in + input_symhdr->crfd * external_rfd_size;
rfd_out = ((char *) output_ecoff->external_rfd rfd_out = ((char *) output_ecoff->debug_info.external_rfd
+ output_symhdr->crfd * external_rfd_size); + output_symhdr->crfd * external_rfd_size);
for (; for (;
rfd_in < rfd_end; rfd_in < rfd_end;
@ -2622,7 +2646,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
parse and adjust all the debugging information which contains parse and adjust all the debugging information which contains
file indices. */ file indices. */
rfd = output_symhdr->ifdMax; rfd = output_symhdr->ifdMax;
rfd_out = ((char *) output_ecoff->external_rfd rfd_out = ((char *) output_ecoff->debug_info.external_rfd
+ output_symhdr->crfd * external_rfd_size); + output_symhdr->crfd * external_rfd_size);
rfd_end = rfd_out + input_symhdr->ifdMax * external_rfd_size; rfd_end = rfd_out + input_symhdr->ifdMax * external_rfd_size;
for (; rfd_out < rfd_end; rfd_out += external_rfd_size, rfd++) for (; rfd_out < rfd_end; rfd_out += external_rfd_size, rfd++)
@ -2671,14 +2695,14 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
register asection *o; register asection *o;
register bfd_seclet_type *p; register bfd_seclet_type *p;
asymbol **sym_ptr_ptr; asymbol **sym_ptr_ptr;
bfd_size_type debug_align; bfd_size_type debug_align, aux_align;
bfd_size_type size; bfd_size_type size;
char *raw; char *raw;
/* We accumulate the debugging information counts in the symbolic /* We accumulate the debugging information counts in the symbolic
header. */ header. */
symhdr = &ecoff_data (abfd)->symbolic_header; symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
symhdr->magic = backend->sym_magic; symhdr->magic = backend->debug_swap.sym_magic;
/* FIXME: What should the version stamp be? */ /* FIXME: What should the version stamp be? */
symhdr->vstamp = 0; symhdr->vstamp = 0;
symhdr->ilineMax = 0; symhdr->ilineMax = 0;
@ -2714,6 +2738,12 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
{ {
for (o = abfd->sections; o != (asection *) NULL; o = o->next) for (o = abfd->sections; o != (asection *) NULL; o = o->next)
{ {
/* If this is a fake section, just forget it. The register
information is handled in another way. */
if (strcmp (o->name, SCOMMON) == 0
|| strcmp (o->name, REGINFO) == 0)
continue;
/* For SEC_CODE sections, (flags & SEC_CODE) == 0 is false, /* For SEC_CODE sections, (flags & SEC_CODE) == 0 is false,
so they are done on pass 0. For other sections the so they are done on pass 0. For other sections the
expression is true, so they are done on pass 1. */ expression is true, so they are done on pass 1. */
@ -2752,12 +2782,15 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
} }
} }
/* Adjust the counts so that structures are longword aligned. */ /* Adjust the counts so that structures are aligned. */
debug_align = backend->debug_align; debug_align = backend->debug_swap.debug_align;
aux_align = debug_align / sizeof (union aux_ext);
--debug_align; --debug_align;
--aux_align;
symhdr->cbLine = (symhdr->cbLine + debug_align) &~ debug_align; symhdr->cbLine = (symhdr->cbLine + debug_align) &~ debug_align;
symhdr->issMax = (symhdr->issMax + debug_align) &~ debug_align; symhdr->issMax = (symhdr->issMax + debug_align) &~ debug_align;
symhdr->issExtMax = (symhdr->issExtMax + debug_align) &~ debug_align; symhdr->issExtMax = (symhdr->issExtMax + debug_align) &~ debug_align;
symhdr->iauxMax = (symhdr->iauxMax + aux_align) &~ aux_align;
/* Now the counts in symhdr are the correct size for the debugging /* Now the counts in symhdr are the correct size for the debugging
information. We allocate the right amount of space, and reset information. We allocate the right amount of space, and reset
@ -2768,16 +2801,16 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
seeks and small writes, though, and I think this approach is seeks and small writes, though, and I think this approach is
faster. */ faster. */
size = (symhdr->cbLine * sizeof (unsigned char) size = (symhdr->cbLine * sizeof (unsigned char)
+ symhdr->idnMax * backend->external_dnr_size + symhdr->idnMax * backend->debug_swap.external_dnr_size
+ symhdr->ipdMax * backend->external_pdr_size + symhdr->ipdMax * backend->debug_swap.external_pdr_size
+ symhdr->isymMax * backend->external_sym_size + symhdr->isymMax * backend->debug_swap.external_sym_size
+ symhdr->ioptMax * backend->external_opt_size + symhdr->ioptMax * backend->debug_swap.external_opt_size
+ symhdr->iauxMax * sizeof (union aux_ext) + symhdr->iauxMax * sizeof (union aux_ext)
+ symhdr->issMax * sizeof (char) + symhdr->issMax * sizeof (char)
+ symhdr->issExtMax * sizeof (char) + symhdr->issExtMax * sizeof (char)
+ symhdr->ifdMax * backend->external_fdr_size + symhdr->ifdMax * backend->debug_swap.external_fdr_size
+ symhdr->crfd * backend->external_rfd_size + symhdr->crfd * backend->debug_swap.external_rfd_size
+ symhdr->iextMax * backend->external_ext_size); + symhdr->iextMax * backend->debug_swap.external_ext_size);
raw = (char *) bfd_alloc (abfd, size); raw = (char *) bfd_alloc (abfd, size);
if (raw == (char *) NULL) if (raw == (char *) NULL)
{ {
@ -2789,20 +2822,20 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
/* Initialize the raw pointers. */ /* Initialize the raw pointers. */
#define SET(field, count, type, size) \ #define SET(field, count, type, size) \
ecoff_data (abfd)->field = (type) raw; \ ecoff_data (abfd)->debug_info.field = (type) raw; \
raw += symhdr->count * size raw += symhdr->count * size
SET (line, cbLine, unsigned char *, sizeof (unsigned char)); SET (line, cbLine, unsigned char *, sizeof (unsigned char));
SET (external_dnr, idnMax, PTR, backend->external_dnr_size); SET (external_dnr, idnMax, PTR, backend->debug_swap.external_dnr_size);
SET (external_pdr, ipdMax, PTR, backend->external_pdr_size); SET (external_pdr, ipdMax, PTR, backend->debug_swap.external_pdr_size);
SET (external_sym, isymMax, PTR, backend->external_sym_size); SET (external_sym, isymMax, PTR, backend->debug_swap.external_sym_size);
SET (external_opt, ioptMax, PTR, backend->external_opt_size); SET (external_opt, ioptMax, PTR, backend->debug_swap.external_opt_size);
SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext)); SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
SET (ss, issMax, char *, sizeof (char)); SET (ss, issMax, char *, sizeof (char));
SET (ssext, issExtMax, char *, sizeof (char)); SET (ssext, issExtMax, char *, sizeof (char));
SET (external_fdr, ifdMax, PTR, backend->external_fdr_size); SET (external_fdr, ifdMax, PTR, backend->debug_swap.external_fdr_size);
SET (external_rfd, crfd, PTR, backend->external_rfd_size); SET (external_rfd, crfd, PTR, backend->debug_swap.external_rfd_size);
SET (external_ext, iextMax, PTR, backend->external_ext_size); SET (external_ext, iextMax, PTR, backend->debug_swap.external_ext_size);
#undef SET #undef SET
/* Reset the counts so the second pass can use them to know how far /* Reset the counts so the second pass can use them to know how far
@ -2826,6 +2859,9 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
{ {
for (o = abfd->sections; o != (asection *) NULL; o = o->next) for (o = abfd->sections; o != (asection *) NULL; o = o->next)
{ {
if (strcmp (o->name, SCOMMON) == 0
|| strcmp (o->name, REGINFO) == 0)
continue;
if (((o->flags & SEC_CODE) == 0) != ipass) if (((o->flags & SEC_CODE) == 0) != ipass)
continue; continue;
for (p = o->seclets_head; for (p = o->seclets_head;
@ -2845,16 +2881,17 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
sym_ptr_ptr = bfd_get_outsymbols (abfd); sym_ptr_ptr = bfd_get_outsymbols (abfd);
if (sym_ptr_ptr != NULL) if (sym_ptr_ptr != NULL)
{ {
const bfd_size_type external_ext_size = backend->external_ext_size; const bfd_size_type external_ext_size
= backend->debug_swap.external_ext_size;
void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
= backend->swap_ext_in; = backend->debug_swap.swap_ext_in;
void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR)) void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
= backend->swap_ext_out; = backend->debug_swap.swap_ext_out;
char *ssext; char *ssext;
char *external_ext; char *external_ext;
ssext = ecoff_data (abfd)->ssext; ssext = ecoff_data (abfd)->debug_info.ssext;
external_ext = (char *) ecoff_data (abfd)->external_ext; external_ext = (char *) ecoff_data (abfd)->debug_info.external_ext;
for (; *sym_ptr_ptr != NULL; sym_ptr_ptr++) for (; *sym_ptr_ptr != NULL; sym_ptr_ptr++)
{ {
asymbol *sym_ptr; asymbol *sym_ptr;
@ -2928,10 +2965,11 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
} }
} }
/* Adjust the counts so that structures are longword aligned. */ /* Adjust the counts so that structures are aligned. */
symhdr->cbLine = (symhdr->cbLine + debug_align) &~ debug_align; symhdr->cbLine = (symhdr->cbLine + debug_align) &~ debug_align;
symhdr->issMax = (symhdr->issMax + debug_align) &~ debug_align; symhdr->issMax = (symhdr->issMax + debug_align) &~ debug_align;
symhdr->issExtMax = (symhdr->issExtMax + debug_align) &~ debug_align; symhdr->issExtMax = (symhdr->issExtMax + debug_align) &~ debug_align;
symhdr->iauxMax = (symhdr->iauxMax + aux_align) &~ aux_align;
return true; return true;
} }
@ -2975,7 +3013,6 @@ ecoff_sizeof_headers (abfd, reloc)
+ c * bfd_coff_scnhsz (abfd)); + c * bfd_coff_scnhsz (abfd));
} }
/* Get the contents of a section. This is where we handle reading the /* Get the contents of a section. This is where we handle reading the
.reginfo section, which implicitly holds the contents of an .reginfo section, which implicitly holds the contents of an
ecoff_reginfo structure. */ ecoff_reginfo structure. */
@ -3041,11 +3078,16 @@ ecoff_compute_section_file_positions (abfd)
/* On Ultrix, the data sections in an executable file must be /* On Ultrix, the data sections in an executable file must be
aligned to a page boundary within the file. This does not aligned to a page boundary within the file. This does not
affect the section size, though. FIXME: Does this work for affect the section size, though. FIXME: Does this work for
other platforms? */ other platforms? It requires some modification for the
Alpha, because .rdata on the Alpha goes with the text, not
the data. */
if ((abfd->flags & EXEC_P) != 0 if ((abfd->flags & EXEC_P) != 0
&& (abfd->flags & D_PAGED) != 0 && (abfd->flags & D_PAGED) != 0
&& first_data != false && first_data != false
&& (current->flags & SEC_CODE) == 0) && (current->flags & SEC_CODE) == 0
&& (! ecoff_backend (abfd)->rdata_in_text
|| strcmp (current->name, _RDATA) != 0)
&& strcmp (current->name, _PDATA) != 0)
{ {
const bfd_vma round = ecoff_backend (abfd)->round; const bfd_vma round = ecoff_backend (abfd)->round;
@ -3139,8 +3181,13 @@ ecoff_write_object_contents (abfd)
const bfd_size_type filhsz = bfd_coff_filhsz (abfd); const bfd_size_type filhsz = bfd_coff_filhsz (abfd);
const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd); const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd);
const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd); const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd);
const bfd_size_type external_hdr_size = backend->external_hdr_size; const bfd_size_type external_hdr_size
= backend->debug_swap.external_hdr_size;
const bfd_size_type external_reloc_size = backend->external_reloc_size; const bfd_size_type external_reloc_size = backend->external_reloc_size;
void (* const adjust_reloc_out) PARAMS ((bfd *,
const arelent *,
struct internal_reloc *))
= backend->adjust_reloc_out;
void (* const swap_reloc_out) PARAMS ((bfd *, void (* const swap_reloc_out) PARAMS ((bfd *,
const struct internal_reloc *, const struct internal_reloc *,
PTR)) PTR))
@ -3237,9 +3284,7 @@ ecoff_write_object_contents (abfd)
} }
if (strcmp (current->name, REGINFO) == 0) if (strcmp (current->name, REGINFO) == 0)
{ {
BFD_ASSERT ((bfd_get_section_size_before_reloc (current) BFD_ASSERT (current->reloc_count == 0);
== sizeof (struct ecoff_reginfo))
&& current->reloc_count == 0);
continue; continue;
} }
@ -3283,7 +3328,14 @@ ecoff_write_object_contents (abfd)
if (bfd_write (buff, 1, scnhsz, abfd) != scnhsz) if (bfd_write (buff, 1, scnhsz, abfd) != scnhsz)
return false; return false;
if ((section.s_flags & STYP_TEXT) != 0) /* FIXME: On the Alpha .rdata is in the text segment. For MIPS
it is in the .data segment. We guess here as to where it
should go based on the vma, but the choice should be made
more systematically. */
if ((section.s_flags & STYP_TEXT) != 0
|| ((section.s_flags & STYP_RDATA) != 0
&& backend->rdata_in_text)
|| strcmp (current->name, _PDATA) == 0)
{ {
text_size += bfd_get_section_size_before_reloc (current); text_size += bfd_get_section_size_before_reloc (current);
if (text_start == 0 || text_start > vma) if (text_start == 0 || text_start > vma)
@ -3291,6 +3343,7 @@ ecoff_write_object_contents (abfd)
} }
else if ((section.s_flags & STYP_RDATA) != 0 else if ((section.s_flags & STYP_RDATA) != 0
|| (section.s_flags & STYP_DATA) != 0 || (section.s_flags & STYP_DATA) != 0
|| (section.s_flags & STYP_LITA) != 0
|| (section.s_flags & STYP_LIT8) != 0 || (section.s_flags & STYP_LIT8) != 0
|| (section.s_flags & STYP_LIT4) != 0 || (section.s_flags & STYP_LIT4) != 0
|| (section.s_flags & STYP_SDATA) != 0) || (section.s_flags & STYP_SDATA) != 0)
@ -3472,11 +3525,23 @@ ecoff_write_object_contents (abfd)
in.r_symndx = RELOC_SECTION_LIT8; in.r_symndx = RELOC_SECTION_LIT8;
else if (strcmp (name, ".lit4") == 0) else if (strcmp (name, ".lit4") == 0)
in.r_symndx = RELOC_SECTION_LIT4; in.r_symndx = RELOC_SECTION_LIT4;
else if (strcmp (name, ".xdata") == 0)
in.r_symndx = RELOC_SECTION_XDATA;
else if (strcmp (name, ".pdata") == 0)
in.r_symndx = RELOC_SECTION_PDATA;
else if (strcmp (name, ".fini") == 0)
in.r_symndx = RELOC_SECTION_FINI;
else if (strcmp (name, ".lita") == 0)
in.r_symndx = RELOC_SECTION_LITA;
else if (strcmp (name, "*ABS*") == 0)
in.r_symndx = RELOC_SECTION_ABS;
else else
abort (); abort ();
in.r_extern = 0; in.r_extern = 0;
} }
(*adjust_reloc_out) (abfd, reloc, &in);
(*swap_reloc_out) (abfd, &in, (PTR) out_ptr); (*swap_reloc_out) (abfd, &in, (PTR) out_ptr);
} }
@ -3495,14 +3560,14 @@ ecoff_write_object_contents (abfd)
unsigned long sym_offset; unsigned long sym_offset;
/* Set up the offsets in the symbolic header. */ /* Set up the offsets in the symbolic header. */
symhdr = &ecoff_data (abfd)->symbolic_header; symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
sym_offset = ecoff_data (abfd)->sym_filepos + external_hdr_size; sym_offset = ecoff_data (abfd)->sym_filepos + external_hdr_size;
#define SET(offset, size, ptr) \ #define SET(offset, size, ptr) \
if (symhdr->size == 0) \ if (symhdr->size == 0) \
symhdr->offset = 0; \ symhdr->offset = 0; \
else \ else \
symhdr->offset = (((char *) ecoff_data (abfd)->ptr \ symhdr->offset = (((char *) ecoff_data (abfd)->debug_info.ptr \
- (char *) ecoff_data (abfd)->raw_syments) \ - (char *) ecoff_data (abfd)->raw_syments) \
+ sym_offset); + sym_offset);
@ -3523,8 +3588,8 @@ ecoff_write_object_contents (abfd)
SEEK_SET) != 0) SEEK_SET) != 0)
return false; return false;
buff = (PTR) alloca (external_hdr_size); buff = (PTR) alloca (external_hdr_size);
(*backend->swap_hdr_out) (abfd, &ecoff_data (abfd)->symbolic_header, (*backend->debug_swap.swap_hdr_out)
buff); (abfd, &ecoff_data (abfd)->debug_info.symbolic_header, buff);
if (bfd_write (buff, 1, external_hdr_size, abfd) != external_hdr_size) if (bfd_write (buff, 1, external_hdr_size, abfd) != external_hdr_size)
return false; return false;
if (bfd_write ((PTR) ecoff_data (abfd)->raw_syments, 1, if (bfd_write ((PTR) ecoff_data (abfd)->raw_syments, 1,