ecoff gprof related fixes & improvements from David Mosberger-Tang

This commit is contained in:
Ken Raeburn 1995-02-07 01:06:25 +00:00
parent 23244cd6e0
commit 97d5a14949
3 changed files with 435 additions and 88 deletions

View File

@ -1,3 +1,14 @@
Mon Feb 6 20:01:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
Sat Feb 4 14:20:24 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
* ecoffswap.h (ecoff_swap_pdr_in, ecoff_swap_pdr_out): added
internalizing/externalizing new "prof" field.
* libecoff.h (ecoff_tdata): added fdrtab.
* ecoff.c (_bfd_ecoff_find_nearest_line): Fixed.
Mon Feb 6 14:25:24 1995 Ian Lance Taylor <ian@cygnus.com>
* libelf.h (struct elf_link_hash_table): Add saw_needed field.

View File

@ -2002,6 +2002,172 @@ _bfd_ecoff_canonicalize_reloc (abfd, section, relptr, symbols)
return section->reloc_count;
}
static int
cmp_fdrtab_entry (const void *leftp, const void *rightp)
{
const struct ecoff_fdrtab_entry *lp = leftp;
const struct ecoff_fdrtab_entry *rp = rightp;
if (lp->base_addr < rp->base_addr)
return -1;
if (lp->base_addr > rp->base_addr)
return 1;
return 0;
}
/*
* Each file descriptor (FDR) has a memory address, to simplify
* looking up an FDR by address, we build a table covering all FDRs
* that have a least one procedure descriptor in them. The final
* table will be sorted by address so we can look it up via binary
* search.
*/
static boolean
mk_fdrtab (bfd *abfd)
{
struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
struct ecoff_fdrtab_entry *tab;
FDR *fdr_ptr;
FDR *fdr_start;
FDR *fdr_end;
boolean stabs;
long len;
/* Make sure we have the FDR's. */
if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info)
|| bfd_get_symcount (abfd) == 0)
return false;
fdr_start = debug_info->fdr;
fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
/* First, let's see how long the table needs to be: */
for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{
if (fdr_ptr->cpd == 0) /* skip FDRs that have no PDRs */
continue;
++len;
}
/* Now, create and fill in the table: */
ecoff_data (abfd)->fdrtab = (struct ecoff_fdrtab_entry*)
bfd_zalloc (abfd,len * sizeof (struct ecoff_fdrtab_entry));
if (ecoff_data (abfd)->fdrtab == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
ecoff_data (abfd)->fdrtab_len = len;
tab = ecoff_data (abfd)->fdrtab;
for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{
if (fdr_ptr->cpd == 0)
continue;
/*
* Check whether this file has stabs debugging information. In
* a file with stabs debugging information, the second local
* symbol is named @stabs.
*/
stabs = false;
if (fdr_ptr->csym >= 2)
{
char *sym_ptr;
SYMR sym;
sym_ptr = ((char *) debug_info->external_sym
+ (fdr_ptr->isymBase + 1)*debug_swap->external_sym_size);
(*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
STABS_SYMBOL) == 0)
stabs = true;
}
if (!stabs)
{
bfd_size_type external_pdr_size;
char *pdr_ptr;
PDR pdr;
external_pdr_size = debug_swap->external_pdr_size;
pdr_ptr = ((char *) debug_info->external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size);
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
/*
* The address of the first PDR is the offset of that
* procedure relative to the beginning of file FDR.
*/
tab->base_addr = fdr_ptr->adr - pdr.adr;
}
else
{
/*
* XXX I don't know about stabs, so this is a guess
* (davidm@cs.arizona.edu):
*/
tab->base_addr = fdr_ptr->adr;
}
tab->fdr = fdr_ptr;
++tab;
}
/*
* Finally, the table is sorted in increasing memory-address order.
* The table is mostly sorted already, but there are cases (e.g.,
* static functions in include files), where this does not hold
* Use "odump -PFv" to verify...
*/
qsort((char*) ecoff_data (abfd)->fdrtab, len,
sizeof(struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
return true;
}
/*
* Return index of first FDR that covers to OFFSET.
*/
static long
lookup (bfd *abfd, bfd_vma offset)
{
long low, high, len;
long mid = -1;
struct ecoff_fdrtab_entry *tab;
len = ecoff_data(abfd)->fdrtab_len;
if (!len)
return -1;
tab = ecoff_data(abfd)->fdrtab;
for (low = 0, high = len - 1 ; low != high ;)
{
mid = (high + low) / 2;
if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
goto find_min;
if (tab[mid].base_addr > offset)
high = mid;
else
low = mid + 1;
}
++mid;
/* last entry is catch-all for all higher addresses: */
if (offset < tab[mid].base_addr)
return -1;
find_min:
while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
--mid;
return mid;
}
/* Provided a BFD, a section and an offset into the section, calculate
and return the name of the source file and the line nearest to the
wanted location. */
@ -2021,49 +2187,39 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
FDR *fdr_ptr;
FDR *fdr_start;
FDR *fdr_end;
FDR *fdr_hold;
struct ecoff_fdrtab_entry *tab;
boolean stabs;
FDR *fdr_ptr;
int i;
offset += section->vma;
/* If we're not in the .text section, we don't have any line
numbers. */
/*
* If we're not in the .text section, we don't have any line
* numbers.
*/
if (strcmp (section->name, _TEXT) != 0
|| offset < ecoff_data (abfd)->text_start
|| offset >= ecoff_data (abfd)->text_end)
return false;
/*
* Build FDR table (sorted by object file's base-address) if
* we don't have it already:
*/
if (!ecoff_data (abfd)->fdrtab && !mk_fdrtab (abfd)) {
return false;
}
tab = ecoff_data (abfd)->fdrtab;
/* Make sure we have the FDR's. */
if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info)
|| bfd_get_symcount (abfd) == 0)
return false;
i = lookup(abfd, offset); /* find first FDR for address OFFSET */
if (i < 0)
return false; /* no FDR, no fun... */
fdr_ptr = tab[i].fdr;
/* Each file descriptor (FDR) has a memory address. Here we track
down which FDR we want. The FDR's are stored in increasing
memory order. If speed is ever important, this can become a
binary search. We must ignore FDR's with no PDR entries; they
will have the adr of the FDR before or after them. */
fdr_start = debug_info->fdr;
fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
fdr_hold = (FDR *) NULL;
for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{
if (fdr_ptr->cpd == 0)
continue;
if (offset < fdr_ptr->adr)
break;
fdr_hold = fdr_ptr;
}
if (fdr_hold == (FDR *) NULL)
return false;
fdr_ptr = fdr_hold;
/* Check whether this file has stabs debugging information. In a
file with stabs debugging information, the second local symbol is
named @stabs. */
/*
* Check whether this file has stabs debugging information. In a
* file with stabs debugging information, the second local symbol is
* named @stabs.
*/
stabs = false;
if (fdr_ptr->csym >= 2)
{
@ -2078,58 +2234,143 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
stabs = true;
}
if (! stabs)
if (!stabs)
{
bfd_size_type external_pdr_size;
char *pdr_ptr;
char *pdr_end;
char *best_pdr = NULL;
FDR *best_fdr;
bfd_vma best_dist = ~0;
PDR pdr;
bfd_vma first_off;
unsigned char *line_ptr;
unsigned char *line_end;
int lineno;
/* This file uses ECOFF debugging information. Each FDR has a
list of procedure descriptors (PDR). PDR's also have an
address, which is relative to the FDR address, and are also
stored in increasing memory order. */
if (offset < fdr_ptr->adr)
return false;
offset -= fdr_ptr->adr;
/*
* This file uses ECOFF debugging information. Each FDR has a
* list of procedure descriptors (PDR). The address in the FDR
* is the absolute address of the first procedure. The address
* in the first PDR gives the offset of that procedure relative
* to the object file's base-address. The addresses in
* subsequent PDRs specify each procedure's address relative to
* the object file's base-address. To make things more juicy,
* whenever the PROF bit in the PDR is set, the real entry point
* of the procedure may be 16 bytes below what would normally be
* the procedure's entry point. Instead, DEC came up with a
* wicked scheme to create profiled libraries "on the fly":
* instead of shipping a regular and a profiled version of each
* library, they insert 16 bytes of unused space in front of
* each procedure and set the "prof" bit in the PDR to indicate
* that there is a gap there (this is done automagically by "as"
* when option "-pg" is specified). Thus, normally, you link
* against such a library and, except for lots of 16 byte gaps
* between functions, things will behave as usual. However,
* when invoking "ld" with option "-pg", it will fill those gaps
* with code that calls mcount(). It then moves the function's
* entry point down by 16 bytes, and out pops a binary that has
* all functions profiled.
*
* NOTE: Neither FDRs nor PDRs are strictly sorted in memory order.
* For example, when including header-files that define
* functions, the FDRs follow behind the including file,
* even though their code may have been generated at a lower
* address. File coff-alpha.c from libbfd illustrates this
* (use "odump -PFv" to look at a file's FDR/PDR). Similarly,
* PDRs are sometimes out of order as well. An example of this
* is OSF/1 v3.0 libc's malloc.c. I'm not sure why this happens,
* but it could be due to optimizations that reorder a function's
* position within an object-file.
*
* Strategy:
*
* On the first call to this function, we build a table of FDRs
* that is sorted by the base-address of the object-file the FDR
* is referring to. Notice that each object-file may contain
* code from multiple source files (e.g., due to code defined in
* include files). Thus, for any given base-address, there may
* be multiple FDRs (but this case is, fortunately, uncommon).
* lookup(addr) guarantees to return the first FDR that applies
* to address ADDR. Thus, after invoking lookup(), we have a
* list of FDRs that may contain the PDR for ADDR. Next, we walk
* through the PDRs of these FDRs and locate the one that is
* closest to ADDR (i.e., for which the difference between ADDR
* and the PDR's entry point is positive and minimal). Once,
* the right FDR and PDR are located, we simply walk through the
* line-number table to lookup the line-number that best matches
* ADDR. Obviously, things could be sped up by keeping a sorted
* list of PDRs instead of a sorted list of FDRs. However, this
* would increase space requirements considerably, which is
* undesirable.
*/
external_pdr_size = debug_swap->external_pdr_size;
pdr_ptr = ((char *) debug_info->external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size);
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
/* Make offset relative to object file's start-address: */
offset -= tab[i].base_addr;
/*
* Search FDR list starting at tab[i] for the PDR that best matches
* OFFSET. Normally, the FDR list is only one entry long.
*/
best_fdr = NULL;
do {
bfd_vma dist, min_dist = 0;
char *pdr_hold;
char *pdr_end;
fdr_ptr = tab[i].fdr;
pdr_ptr = ((char *) debug_info->external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size);
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
/*
* Find PDR that is closest to OFFSET. If pdr.prof is set,
* the procedure entry-point *may* be 0x10 below pdr.adr.
* We simply pretend that pdr.prof *implies* a lower entry-point.
* This is safe because it just means that may identify
* 4 NOPs in front of the function as belonging to the function.
*/
for (pdr_hold = NULL;
pdr_ptr < pdr_end;
(pdr_ptr += external_pdr_size,
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr)))
{
if (offset >= (pdr.adr - 0x10 * pdr.prof))
{
dist = offset - (pdr.adr - 0x10 * pdr.prof);
if (!pdr_hold || dist < min_dist)
{
min_dist = dist;
pdr_hold = pdr_ptr;
}
}
}
if (!best_pdr || min_dist < best_dist)
{
best_dist = min_dist;
best_fdr = fdr_ptr;
best_pdr = pdr_hold;
}
/* continue looping until base_addr of next entry is different: */
} while (++i < ecoff_data (abfd)->fdrtab_len
&& tab[i].base_addr == tab[i - 1].base_addr);
if (!best_fdr || !best_pdr)
return false; /* shouldn't happen... */
/* phew, finally we got something that we can hold onto: */
fdr_ptr = best_fdr;
pdr_ptr = best_pdr;
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
/*
* Now we can look for the actual line number. The line numbers
* are stored in a very funky format, which I won't try to
* describe. The search is bounded by the end of the FDRs line
* number entries.
*/
line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
/* The address of the first PDR is an offset which applies to
the addresses of all the PDR's. */
first_off = pdr.adr;
for (pdr_ptr += external_pdr_size;
pdr_ptr < pdr_end;
pdr_ptr += external_pdr_size)
{
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
if (offset < pdr.adr - first_off)
break;
}
/* Now we can look for the actual line number. The line numbers
are 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 we want; we need this to compute line_end. */
line_end = debug_info->line;
if (pdr_ptr == pdr_end)
line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
else
line_end += fdr_ptr->cbLineOffset + pdr.cbLineOffset;
/* Now change pdr and pdr_ptr to the one we want. */
pdr_ptr -= external_pdr_size;
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
offset -= pdr.adr - first_off;
/* Make offset relative to procedure entry: */
offset -= pdr.adr - 0x10 * pdr.prof;
lineno = pdr.lnLow;
line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
while (line_ptr < line_end)
@ -2155,8 +2396,10 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
offset -= count * 4;
}
/* If fdr_ptr->rss is -1, then this file does not have full
symbols, at least according to gdb/mipsread.c. */
/*
* If fdr_ptr->rss is -1, then this file does not have full
* symbols, at least according to gdb/mipsread.c.
*/
if (fdr_ptr->rss == -1)
{
*filename_ptr = NULL;
@ -2346,6 +2589,7 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
return true;
}
/* Copy private BFD data. This is called by objcopy and strip. We
use it to copy the ECOFF debugging information from one BFD to the

View File

@ -53,12 +53,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ECOFF auxiliary information swapping routines. These are the same
for all ECOFF targets, so they are defined in ecoff.c. */
extern void ecoff_swap_tir_in PARAMS ((int, const struct tir_ext *, TIR *));
extern void ecoff_swap_tir_out PARAMS ((int, const TIR *, struct tir_ext *));
extern void ecoff_swap_rndx_in PARAMS ((int, const struct rndx_ext *,
RNDXR *));
extern void ecoff_swap_rndx_out PARAMS ((int, const RNDXR *,
struct rndx_ext *));
extern void _bfd_ecoff_swap_tir_in
PARAMS ((int, const struct tir_ext *, TIR *));
extern void _bfd_ecoff_swap_tir_out
PARAMS ((int, const TIR *, struct tir_ext *));
extern void _bfd_ecoff_swap_rndx_in
PARAMS ((int, const struct rndx_ext *, RNDXR *));
extern void _bfd_ecoff_swap_rndx_out
PARAMS ((int, const RNDXR *, struct rndx_ext *));
/* Swap in the symbolic header. */
@ -281,6 +283,9 @@ ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr)
#endif
}
/* start-sanitize-mpw */
#ifndef MPW_C
/* end-sanitize-mpw */
/* Swap in the procedure descriptor record. */
static void
@ -317,6 +322,7 @@ ecoff_swap_pdr_in (abfd, ext_copy, intern)
{
intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG);
intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG);
intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG);
intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG)
<< PDR_BITS1_RESERVED_SH_LEFT_BIG)
| ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG)
@ -326,6 +332,7 @@ ecoff_swap_pdr_in (abfd, ext_copy, intern)
{
intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE);
intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE);
intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE);
intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE)
>> PDR_BITS1_RESERVED_SH_LITTLE)
| ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE)
@ -374,6 +381,7 @@ ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
{
ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0)
| (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0)
| (intern->prof ? PDR_BITS1_PROF_BIG : 0)
| ((intern->reserved
>> PDR_BITS1_RESERVED_SH_LEFT_BIG)
& PDR_BITS1_RESERVED_BIG));
@ -384,6 +392,7 @@ ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
{
ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0)
| (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0)
| (intern->prof ? PDR_BITS1_PROF_LITTLE : 0)
| ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE)
& PDR_BITS1_RESERVED_LITTLE));
ext->p_bits2[0] = ((intern->reserved >>
@ -398,6 +407,81 @@ ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
abort();
#endif
}
/* start-sanitize-mpw */
#else /* MPW_C */
/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't
corrupt itself and then freak out. */
/* Swap in the procedure descriptor record. */
static void
ecoff_swap_pdr_in (abfd, ext_copy, intern)
bfd *abfd;
PTR ext_copy;
PDR *intern;
{
struct pdr_ext ext[1];
*ext = *(struct pdr_ext *) ext_copy;
intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr);
intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym);
intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline);
intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask);
intern->regoffset = bfd_h_get_signed_32 (abfd,
(bfd_byte *)ext->p_regoffset);
intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt);
intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask);
intern->fregoffset = bfd_h_get_signed_32 (abfd,
(bfd_byte *)ext->p_fregoffset);
intern->frameoffset = bfd_h_get_signed_32 (abfd,
(bfd_byte *)ext->p_frameoffset);
intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg);
intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg);
intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow);
intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh);
intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset);
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
abort();
#endif
}
/* Swap out the procedure descriptor record. */
static void
ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
bfd *abfd;
const PDR *intern_copy;
PTR ext_ptr;
{
struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
PDR intern[1];
*intern = *intern_copy; /* Make it reasonable to do in-place. */
ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr);
bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym);
bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline);
bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask);
bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset);
bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt);
bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask);
bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset);
bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset);
bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg);
bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg);
bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow);
bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh);
ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset);
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
abort();
#endif
}
#endif /* MPW_C */
/* end-sanitize-mpw */
/* Swap in a symbol record. */
@ -555,11 +639,19 @@ ecoff_swap_ext_out (abfd, intern_copy, ext_ptr)
| (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0)
| (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0));
ext->es_bits2[0] = 0;
#ifdef ECOFF_64
ext->es_bits2[1] = 0;
ext->es_bits2[2] = 0;
#endif
} else {
ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0)
| (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0)
| (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0));
ext->es_bits2[0] = 0;
#ifdef ECOFF_64
ext->es_bits2[1] = 0;
ext->es_bits2[2] = 0;
#endif
}
#ifdef ECOFF_32
@ -643,8 +735,8 @@ ecoff_swap_opt_in (abfd, ext_copy, intern)
| (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE));
}
ecoff_swap_rndx_in (abfd->xvec->header_byteorder_big_p != false,
&ext->o_rndx, &intern->rndx);
_bfd_ecoff_swap_rndx_in (abfd->xvec->header_byteorder_big_p != false,
&ext->o_rndx, &intern->rndx);
intern->offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->o_offset);
@ -682,8 +774,8 @@ ecoff_swap_opt_out (abfd, intern_copy, ext_ptr)
ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE;
}
ecoff_swap_rndx_out (abfd->xvec->header_byteorder_big_p != false,
&intern->rndx, &ext->o_rndx);
_bfd_ecoff_swap_rndx_out (abfd->xvec->header_byteorder_big_p != false,
&intern->rndx, &ext->o_rndx);
bfd_h_put_32 (abfd, intern->value, (bfd_byte *) ext->o_offset);