aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/ecoff.c392
-rw-r--r--bfd/ecoffswap.h112
3 files changed, 431 insertions, 84 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index be78ac0..6434308 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index d6fbea9..4d80edc 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -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;
- (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
- /* The address of the first PDR is an offset which applies to
- the addresses of all the PDR's. */
- first_off = pdr.adr;
+ /* 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;
+ }
+ }
+ }
- 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;
- }
+ 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);
- /* 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;
+ if (!best_fdr || !best_pdr)
+ return false; /* shouldn't happen... */
- /* Now change pdr and pdr_ptr to the one we want. */
- pdr_ptr -= external_pdr_size;
+ /* 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;
- 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
diff --git a/bfd/ecoffswap.h b/bfd/ecoffswap.h
index 087e052..4500f0f 100644
--- a/bfd/ecoffswap.h
+++ b/bfd/ecoffswap.h
@@ -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);