aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ecoff.c52
-rw-r--r--bfd/ecofflink.c32
-rw-r--r--bfd/elf64-alpha.c12
-rw-r--r--bfd/elfxx-mips.c40
-rw-r--r--bfd/libbfd-in.h2
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/libecoff.h3
-rw-r--r--gas/config/obj-ecoff.c1
-rw-r--r--gas/config/obj-elf.c1
-rw-r--r--include/coff/ecoff.h5
10 files changed, 66 insertions, 84 deletions
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index f2626c5..522a442 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -117,12 +117,15 @@ _bfd_ecoff_bfd_free_cached_info (bfd *abfd)
if ((bfd_get_format (abfd) == bfd_object
|| bfd_get_format (abfd) == bfd_core)
&& (tdata = ecoff_data (abfd)) != NULL)
- while (tdata->mips_refhi_list != NULL)
- {
- struct mips_hi *ref = tdata->mips_refhi_list;
- tdata->mips_refhi_list = ref->next;
- free (ref);
- }
+ {
+ while (tdata->mips_refhi_list != NULL)
+ {
+ struct mips_hi *ref = tdata->mips_refhi_list;
+ tdata->mips_refhi_list = ref->next;
+ free (ref);
+ }
+ _bfd_ecoff_free_ecoff_debug_info (&tdata->debug_info);
+ }
return _bfd_generic_bfd_free_cached_info (abfd);
}
@@ -524,7 +527,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
/* Check whether we've already gotten it, and whether there's any to
get. */
- if (ecoff_data (abfd)->raw_syments != NULL)
+ if (debug->alloc_syments)
return true;
if (ecoff_data (abfd)->sym_filepos == 0)
{
@@ -595,7 +598,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
if (raw == NULL)
return false;
- ecoff_data (abfd)->raw_syments = raw;
+ debug->alloc_syments = true;
/* Get pointers for the numeric offsets in the HDRR structure. */
#define FIX(start, count, ptr, type) \
@@ -1918,6 +1921,9 @@ _bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd;
oinfo->external_rfd = iinfo->external_rfd;
+
+ /* Flag that oinfo entries should not be freed. */
+ oinfo->alloc_syments = true;
}
else
{
@@ -3809,9 +3815,9 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
((char *) debug->ptr)[amt] = 0; \
} while (0)
- /* If raw_syments is not NULL, then the data was already by read by
+ /* If alloc_syments is true, then the data was already by read by
_bfd_ecoff_slurp_symbolic_info. */
- if (ecoff_data (input_bfd)->raw_syments == NULL)
+ if (!debug->alloc_syments)
{
READ (line, cbLineOffset, cbLine, sizeof (unsigned char));
READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size);
@@ -3833,31 +3839,7 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
input_bfd, debug, swap, info));
return_something:
- if (ecoff_data (input_bfd)->raw_syments == NULL)
- {
- free (debug->line);
- free (debug->external_dnr);
- free (debug->external_pdr);
- free (debug->external_sym);
- free (debug->external_opt);
- free (debug->external_aux);
- free (debug->ss);
- free (debug->external_fdr);
- free (debug->external_rfd);
-
- /* Make sure we don't accidentally follow one of these pointers
- into freed memory. */
- debug->line = NULL;
- debug->external_dnr = NULL;
- debug->external_pdr = NULL;
- debug->external_sym = NULL;
- debug->external_opt = NULL;
- debug->external_aux = NULL;
- debug->ss = NULL;
- debug->external_fdr = NULL;
- debug->external_rfd = NULL;
- }
-
+ _bfd_ecoff_free_ecoff_debug_info (debug);
return ret;
}
diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c
index bba2592..5b7acd5 100644
--- a/bfd/ecofflink.c
+++ b/bfd/ecofflink.c
@@ -1696,6 +1696,38 @@ bfd_ecoff_write_accumulated_debug (void * handle,
/* Handle the find_nearest_line function for both ECOFF and MIPS ELF
files. */
+/* Free ECOFF debugging info used by find_nearest_line. */
+
+void
+_bfd_ecoff_free_ecoff_debug_info (struct ecoff_debug_info *debug)
+{
+ if (!debug->alloc_syments)
+ {
+ free (debug->line);
+ free (debug->external_dnr);
+ free (debug->external_pdr);
+ free (debug->external_sym);
+ free (debug->external_opt);
+ free (debug->external_aux);
+ free (debug->ss);
+ free (debug->ssext);
+ free (debug->external_fdr);
+ free (debug->external_rfd);
+ free (debug->external_ext);
+ }
+ debug->line= NULL;
+ debug->external_dnr= NULL;
+ debug->external_pdr= NULL;
+ debug->external_sym= NULL;
+ debug->external_opt= NULL;
+ debug->external_aux= NULL;
+ debug->ss= NULL;
+ debug->ssext= NULL;
+ debug->external_fdr= NULL;
+ debug->external_rfd= NULL;
+ debug->external_ext= NULL;
+}
+
/* Compare FDR entries. This is called via qsort. */
static int
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index 5cf9a66..125379b 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1425,17 +1425,7 @@ elf64_alpha_read_ecoff_info (bfd *abfd, asection *section,
error_return:
free (ext_hdr);
- free (debug->line);
- free (debug->external_dnr);
- free (debug->external_pdr);
- free (debug->external_sym);
- free (debug->external_opt);
- free (debug->external_aux);
- free (debug->ss);
- free (debug->ssext);
- free (debug->external_fdr);
- free (debug->external_rfd);
- free (debug->external_ext);
+ _bfd_ecoff_free_ecoff_debug_info (debug);
return false;
}
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 7d29ec2..a618f6f 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -1389,35 +1389,6 @@ struct mips_elf_find_line
struct ecoff_find_line i;
};
-/* Free ECOFF debugging info used by find_nearest_line. */
-
-static void
-free_ecoff_debug (struct ecoff_debug_info *debug)
-{
- free (debug->line);
- free (debug->external_dnr);
- free (debug->external_pdr);
- free (debug->external_sym);
- free (debug->external_opt);
- free (debug->external_aux);
- free (debug->ss);
- free (debug->ssext);
- free (debug->external_fdr);
- free (debug->external_rfd);
- free (debug->external_ext);
- debug->line = NULL;
- debug->external_dnr = NULL;
- debug->external_pdr = NULL;
- debug->external_sym = NULL;
- debug->external_opt = NULL;
- debug->external_aux = NULL;
- debug->ss = NULL;
- debug->ssext = NULL;
- debug->external_fdr = NULL;
- debug->external_rfd = NULL;
- debug->external_ext = NULL;
-}
-
bool
_bfd_mips_elf_free_cached_info (bfd *abfd)
{
@@ -1435,7 +1406,7 @@ _bfd_mips_elf_free_cached_info (bfd *abfd)
free (hi);
}
if (tdata->find_line_info != NULL)
- free_ecoff_debug (&tdata->find_line_info->d);
+ _bfd_ecoff_free_ecoff_debug_info (&tdata->find_line_info->d);
}
return _bfd_elf_free_cached_info (abfd);
}
@@ -1523,7 +1494,7 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
error_return:
free (ext_hdr);
- free_ecoff_debug (debug);
+ _bfd_ecoff_free_ecoff_debug_info (debug);
return false;
}
@@ -13225,7 +13196,7 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
fi->d.fdr = bfd_alloc (abfd, amt);
if (fi->d.fdr == NULL)
{
- free_ecoff_debug (&fi->d);
+ _bfd_ecoff_free_ecoff_debug_info (&fi->d);
msec->flags = origflags;
return false;
}
@@ -15043,6 +15014,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* We accumulate the debugging information itself in the
debug_info structure. */
+ debug.alloc_syments = false;
debug.line = NULL;
debug.external_dnr = NULL;
debug.external_pdr = NULL;
@@ -15128,7 +15100,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
(mdebug_handle, abfd, &debug, swap, input_bfd,
&input_debug, input_swap, info)))
{
- free_ecoff_debug (&input_debug);
+ _bfd_ecoff_free_ecoff_debug_info (&input_debug);
return false;
}
@@ -15171,7 +15143,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
}
/* Free up the information we just read. */
- free_ecoff_debug (&input_debug);
+ _bfd_ecoff_free_ecoff_debug_info (&input_debug);
/* Hack: reset the SEC_HAS_CONTENTS flag so that
elf_link_input_bfd ignores this section. */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index ae1b61a..03ae099 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -787,6 +787,8 @@ struct ecoff_debug_swap;
struct ecoff_extr;
struct ecoff_find_line;
+extern void _bfd_ecoff_free_ecoff_debug_info
+ (struct ecoff_debug_info *debug);
extern bool _bfd_ecoff_locate_line
(bfd *, asection *, bfd_vma, struct ecoff_debug_info * const,
const struct ecoff_debug_swap * const, struct ecoff_find_line *,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 92fbf01..a9fa111 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -793,6 +793,8 @@ struct ecoff_debug_swap;
struct ecoff_extr;
struct ecoff_find_line;
+extern void _bfd_ecoff_free_ecoff_debug_info
+ (struct ecoff_debug_info *debug);
extern bool _bfd_ecoff_locate_line
(bfd *, asection *, bfd_vma, struct ecoff_debug_info * const,
const struct ecoff_debug_swap * const, struct ecoff_find_line *,
diff --git a/bfd/libecoff.h b/bfd/libecoff.h
index 0c4bb43..2267c7b 100644
--- a/bfd/libecoff.h
+++ b/bfd/libecoff.h
@@ -124,9 +124,6 @@ typedef struct ecoff_tdata
/* The ECOFF symbolic debugging information. */
struct ecoff_debug_info debug_info;
- /* The unswapped ECOFF symbolic information. */
- void * raw_syments;
-
/* The canonical BFD symbols. */
struct ecoff_symbol_struct *canonical_symbols;
diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c
index 092f6f2..26da2af 100644
--- a/gas/config/obj-ecoff.c
+++ b/gas/config/obj-ecoff.c
@@ -151,6 +151,7 @@ ecoff_frob_file (void)
ecoff_build_debug (hdr, &buf, debug_swap);
/* Finish up the ecoff_tdata structure. */
+ ecoff_data (stdoutput)->debug_info.alloc_syments = true;
set = buf;
#define SET(ptr, count, type, size) \
if (hdr->count == 0) \
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index bf3ef54..753a929 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -3008,6 +3008,7 @@ elf_frob_file_after_relocs (void)
ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
/* Set up the pointers in debug. */
+ debug.alloc_syments = true;
#define SET(ptr, offset, type) \
debug.ptr = (type) (buf + debug.symbolic_header.offset)
diff --git a/include/coff/ecoff.h b/include/coff/ecoff.h
index 169d8f6..991d92f 100644
--- a/include/coff/ecoff.h
+++ b/include/coff/ecoff.h
@@ -299,7 +299,10 @@ struct ecoff_debug_info
all pointers to arrays, not single structures. They will be NULL
if there are no instances of the relevant structure. These
fields are also used by the assembler to output ECOFF debugging
- information. */
+ information. If alloc_syments is true then the pointers are to
+ objalloc memory, or into a single malloc'd buffer, or otherwise
+ should not be freed. */
+ bool alloc_syments;
unsigned char *line;
void *external_dnr; /* struct dnr_ext */
void *external_pdr; /* struct pdr_ext */