gdb: replace msym_bunch with deque
Commit Message
From: Simon Marchi <simon.marchi@efficios.com>
This patch replaces the msym_bunch implementation with an std::deque.
I initially tried to replace it with a vector. However, that doesn't
work, because minimal_symbol references need to stay valid across calls
to minimal_symbol_reade::record_full in at least one spot.
elf_symtab_read calls minimal_symbol_reader::record_full (through
function record_minimal_symbol) to record a minimal symbol for a PLT
entry and then uses a previously added minimal symbol to set the size of
the PLT minimal symbol. If we used a vector, a re-allocation could
happen which would invalidate the reference to the previous minimal
symbol (luckily this was caught by ASan).
An std::deque implementation typically uses a sequence of fixed-sized
arrays, much like our current msym_bunch implementation. So adding an
item at the end will not invalidate existing references. But unlike our
msym_bunch, we don't have to worry about memory management.
I am a bit puzzled about this code in
minimal_symbol_reader::record_full:
/* If we already read minimal symbols for this objfile, then don't
ever allocate a new one. */
if (!m_objfile->per_bfd->minsyms_read)
{
m_msym_bunch_index++;
m_objfile->per_bfd->n_minsyms++;
}
I am not sure when minsyms_read would already be true when reading
minimal symbols, and if we should do anything differently here.
Change-Id: I7d10c6aca42cc9dcf80b483394e1e56351a9465f
---
gdb/minsyms.c | 95 ++++++++-------------------------------------------
gdb/minsyms.h | 23 ++++---------
2 files changed, 21 insertions(+), 97 deletions(-)
base-commit: 04a9afc1d81058275219b499fd75c983967a30c1
Comments
>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:
Simon> An std::deque implementation typically uses a sequence of fixed-sized
Simon> arrays, much like our current msym_bunch implementation. So adding an
Simon> item at the end will not invalidate existing references. But unlike our
Simon> msym_bunch, we don't have to worry about memory management.
FWIW we have another instance of this idiom in buildsym.
Simon> I am a bit puzzled about this code in
Simon> minimal_symbol_reader::record_full:
Simon> I am not sure when minsyms_read would already be true when reading
Simon> minimal symbols, and if we should do anything differently here.
It's been a long time since I worked on this, but IIRC there were
readers where minimal symbol reading was mixed with partial symbol reading.
In these cases we could reuse the already-read minimal symbols but not
the partial symbols. This code, and the check in
minimal_symbol_reader::install, were there to allow the reuse without
creating new symbols.
The particular check you highlighted is just based on the idea that the
code is still trying to create a minimal symbol, but since it won't ever
be installed, there's no point to allocating more memory, we can just
reuse the same one over and over.
It's possible all this is obsolete given the stabs removal. You'd have
to investigate. But anyway all of this was a hack to avoid doing work
on these ancient / obsolete readers.
Simon> + /* The minimal symbols recorded so far. This uses a deque instead of e.g. a
Simon> + vector, because references to minimal symbols need to stay valid across
Simon> + calls to recod_full. */
Typo, "record_full"
Tom
>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
Tom> It's possible all this is obsolete given the stabs removal. You'd have
Tom> to investigate. But anyway all of this was a hack to avoid doing work
Tom> on these ancient / obsolete readers.
mdebugread.c seems to use this feature.
BTW I meant to approve your patch.
Approved-By: Tom Tromey <tom@tromey.com>
Tom
On 12/17/25 1:46 PM, Tom Tromey wrote:
>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>
> Tom> It's possible all this is obsolete given the stabs removal. You'd have
> Tom> to investigate. But anyway all of this was a hack to avoid doing work
> Tom> on these ancient / obsolete readers.
>
> mdebugread.c seems to use this feature.
Indeed, I dug into that in the mean time. I'd like if someone with
historical knowledge could fact-check me here. My understanding is:
- There is the ECOFF format, which based on COFF but also specifies a
debug information format (is that what mdebug is?). ECOFF seems to
have been used mostly on Alpha and MIPS, before being superseded by
ELF somewhere around 2000.
- During the transition from ECOFF to ELF, it was made possible to put
ECOFF debug info inside ELF.
- The ECOFF debug info format was eventually completely replaced by
DWARF, in about the same time frame.
So the situation that interests us is when you have ECOFF-in-ELF. We
first read the ELF minimal symbols in elf_symfile_read, then go into
elfmdebug_build_psymtabs. elfmdebug_build_psymtabs is able to generate
minimal symbols (useful when you have ECOFF debug info in an ECOFF
executable I presume), but in this case we don't want to have those
minimal symbols, we already have the ELF ones. Hence the need for this
"don't actually create minimal symbols if we already have minimal
symbols".
Here are some relevant comments. This on in elfmdebug_build_psymtabs:
/* FIXME: It's not clear whether we should be getting minimal symbol
information from .mdebug in an ELF file, or whether we will.
Re-initialize the minimal symbol reader in case we do. */
And this one in parse_partial_symbols (also in mdebugread.c):
/* ECOFF in ELF:
For ECOFF in ELF, we skip the creation of the minimal symbols.
The ECOFF symbols should be a subset of the Elf symbols, and the
section information of the elf symbols will be more accurate.
FIXME! What about Irix 5's native linker?
By default, Elf sections which don't exist in ECOFF
get put in ECOFF's absolute section by the gnu linker.
Since absolute sections don't get relocated, we
end up calculating an address different from that of
the symbol's minimal symbol (created earlier from the
Elf symtab).
To fix this, either :
1) don't create the duplicate symbol
(assumes ECOFF symtab is a subset of the ELF symtab;
assumes no side-effects result from ignoring ECOFF symbol)
2) create it, only if lookup for existing symbol in ELF's minimal
symbols fails
(inefficient;
assumes no side-effects result from ignoring ECOFF symbol)
3) create it, but lookup ELF's minimal symbol and use it's section
during relocation, then modify "uniquify" phase to merge and
eliminate the duplicate symbol
(highly inefficient)
I've implemented #1 here...
Skip the creation of the minimal symbols based on the ECOFF
symbol table. */
I'm thinking that ECOFF is ripe to get removed from GDB, given that it
has been replaced with ELF/DWARF for about 25 years. That would mean
removing:
- mdebugread.c
- mipsread.c
Removing those would allow many more cleanups, I think.
> BTW I meant to approve your patch.
> Approved-By: Tom Tromey <tom@tromey.com>
Ok, so I think that the consequence of my patch is that if you're
parsing ECOFF-in-ELF, then we'll allocate minimal symbols unnecessarily
in mdebugread's minimal_symbol_reader. They still won't get installed
because of the check in minimal_symbol_reader::install. They will get
freed when the minimal_symbol_reader gets destroyed. So that means
slightly higher memory usage for the duration of
elfmdebug_build_psymtabs, but no change in behavior. I can live with
that, so I'll go ahead and push the patch.
Simon
>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:
Simon> Indeed, I dug into that in the mean time. I'd like if someone with
Simon> historical knowledge could fact-check me here.
FWIW I suspect no such person exists.
This stuff is definitely before my time.
Simon> I'm thinking that ECOFF is ripe to get removed from GDB, given that it
Simon> has been replaced with ELF/DWARF for about 25 years. That would mean
Simon> removing:
Simon> - mdebugread.c
Simon> - mipsread.c
Simon> Removing those would allow many more cleanups, I think.
Works for me.
Tom
On 2025-12-18 13:07, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:
>
> Simon> Indeed, I dug into that in the mean time. I'd like if someone with
> Simon> historical knowledge could fact-check me here.
>
> FWIW I suspect no such person exists.
Given a lot of this is MIPS-specific, I was hoping that Maciej could be
able to help (adding in CC).
Simon
On Thu, 18 Dec 2025, Simon Marchi wrote:
> > Simon> Indeed, I dug into that in the mean time. I'd like if someone with
> > Simon> historical knowledge could fact-check me here.
> >
> > FWIW I suspect no such person exists.
>
> Given a lot of this is MIPS-specific, I was hoping that Maciej could be
> able to help (adding in CC).
I don't know offhand as it's stuff I haven't touched for ages now. I'll
see what I can do. Also I can see you've pushed your change already, so I
gather there's no rush. NB it was bad timing to get into this discussion
as I had an emergency situation to handle and overall hectic time through
recent weeks.
Happy New Year for now!
Maciej
On 2026-01-03 18:24, Maciej W. Rozycki wrote:
> On Thu, 18 Dec 2025, Simon Marchi wrote:
>
>>> Simon> Indeed, I dug into that in the mean time. I'd like if someone with
>>> Simon> historical knowledge could fact-check me here.
>>>
>>> FWIW I suspect no such person exists.
>>
>> Given a lot of this is MIPS-specific, I was hoping that Maciej could be
>> able to help (adding in CC).
>
> I don't know offhand as it's stuff I haven't touched for ages now. I'll
> see what I can do. Also I can see you've pushed your change already, so I
> gather there's no rush. NB it was bad timing to get into this discussion
> as I had an emergency situation to handle and overall hectic time through
> recent weeks.
>
> Happy New Year for now!
Thanks for replying, hope all is well for you.
I pushed the patch because I convinced myself that the patch wouldn't
break the ECOFF-in-ELF case. Here is the relevant quote from my
previous message:
Ok, so I think that the consequence of my patch is that if you're
parsing ECOFF-in-ELF, then we'll allocate minimal symbols unnecessarily
in mdebugread's minimal_symbol_reader. They still won't get installed
because of the check in minimal_symbol_reader::install. They will get
freed when the minimal_symbol_reader gets destroyed. So that means
slightly higher memory usage for the duration of
elfmdebug_build_psymtabs, but no change in behavior. I can live with
that, so I'll go ahead and push the patch.
Of course, this is all based on my understanding, from the information I
gleaned here and there. It seems like not many people remember this era
nowadays :(.
What would help me, if you have time (no rush), is to tell me if we can
reasonably consider the code in mipsread.c (and mdebugread.c, which
seems related) to be obsolete and remove it.
Simon
On Sat, 3 Jan 2026, Simon Marchi wrote:
> >> Given a lot of this is MIPS-specific, I was hoping that Maciej could be
> >> able to help (adding in CC).
> >
> > I don't know offhand as it's stuff I haven't touched for ages now. I'll
> > see what I can do. Also I can see you've pushed your change already, so I
> > gather there's no rush. NB it was bad timing to get into this discussion
> > as I had an emergency situation to handle and overall hectic time through
> > recent weeks.
> >
> > Happy New Year for now!
>
> Thanks for replying, hope all is well for you.
I'm fine myself, thank you, just even busier and more distracted than
usual.
> I pushed the patch because I convinced myself that the patch wouldn't
> break the ECOFF-in-ELF case. Here is the relevant quote from my
> previous message:
>
> Ok, so I think that the consequence of my patch is that if you're
> parsing ECOFF-in-ELF, then we'll allocate minimal symbols unnecessarily
> in mdebugread's minimal_symbol_reader. They still won't get installed
> because of the check in minimal_symbol_reader::install. They will get
> freed when the minimal_symbol_reader gets destroyed. So that means
> slightly higher memory usage for the duration of
> elfmdebug_build_psymtabs, but no change in behavior. I can live with
> that, so I'll go ahead and push the patch.
>
> Of course, this is all based on my understanding, from the information I
> gleaned here and there. It seems like not many people remember this era
> nowadays :(.
My early MIPS experience certainly overlaps with the era (even MIPS/COFF,
as in ULTRIX/MIPS), but I never got into the details back then. At least
I usually know where to look for when chasing bits now.
The mdebug spec continues living online I believe, though it could be at
archive.org only nowadays; I can check. I have a local copy for anyone
needing it too. Yes, it does refer Third Eye Software.
> What would help me, if you have time (no rush), is to tell me if we can
> reasonably consider the code in mipsread.c (and mdebugread.c, which
> seems related) to be obsolete and remove it.
As I say I'll see what I can do. Overall emitting ECOFF-in-ELF frame
unwinding information aka Procedure Description Records (PDR), a valuable
subset of the mdebug stuff, continues being supported by MIPS GCC and GAS.
No other stuff is relevant anymore; we have no support for IRIX or ULTRIX
targets left and the GNU tools can't produce other ECOFF debug information
for MIPS targets anymore.
NB I had plans/ideas to improve PDR handling in GDB, but this has never
materialised. It's good having/improving IMHO as PDR records are very
lightweight and retained by `strip', and with its variable frame format
the MIPS target is very bad for debugging when execution is stopped at a
random place with no associated debug information, which might be libc or
suchlike. Then you just have the PC and the register stack available and
nothing else, not even the return address ($ra may have been clobbered).
But all the PDR support is gone from GDB AFAICT and ISTR now having a
discussion as to bringing it back some 20 years ago while I was still at
MTI, possibly with Daniel Jacobowitz. The messages should be easy to
chase, but otherwise I have to conclude none of this is relevant to MIPS
targets anymore. So I guess I've figured it out for you already.
This stuff is possibly used by the Alpha target however, though I'm not
sure offhand as I'm less familiar with the matters there.
HTH,
Maciej
On 2026-01-05 03:07, Maciej W. Rozycki wrote:
> On Sat, 3 Jan 2026, Simon Marchi wrote:
>
>>>> Given a lot of this is MIPS-specific, I was hoping that Maciej could be
>>>> able to help (adding in CC).
>>>
>>> I don't know offhand as it's stuff I haven't touched for ages now. I'll
>>> see what I can do. Also I can see you've pushed your change already, so I
>>> gather there's no rush. NB it was bad timing to get into this discussion
>>> as I had an emergency situation to handle and overall hectic time through
>>> recent weeks.
>>>
>>> Happy New Year for now!
>>
>> Thanks for replying, hope all is well for you.
>
> I'm fine myself, thank you, just even busier and more distracted than
> usual.
>
>> I pushed the patch because I convinced myself that the patch wouldn't
>> break the ECOFF-in-ELF case. Here is the relevant quote from my
>> previous message:
>>
>> Ok, so I think that the consequence of my patch is that if you're
>> parsing ECOFF-in-ELF, then we'll allocate minimal symbols unnecessarily
>> in mdebugread's minimal_symbol_reader. They still won't get installed
>> because of the check in minimal_symbol_reader::install. They will get
>> freed when the minimal_symbol_reader gets destroyed. So that means
>> slightly higher memory usage for the duration of
>> elfmdebug_build_psymtabs, but no change in behavior. I can live with
>> that, so I'll go ahead and push the patch.
>>
>> Of course, this is all based on my understanding, from the information I
>> gleaned here and there. It seems like not many people remember this era
>> nowadays :(.
>
> My early MIPS experience certainly overlaps with the era (even MIPS/COFF,
> as in ULTRIX/MIPS), but I never got into the details back then. At least
> I usually know where to look for when chasing bits now.
>
> The mdebug spec continues living online I believe, though it could be at
> archive.org only nowadays; I can check. I have a local copy for anyone
> needing it too. Yes, it does refer Third Eye Software.
I dug a bit deeper and found these links. The last one is especially
useful to understand the history.
ECOFF spec
https://web.archive.org/web/20160305114748/http://h41361.www4.hp.com/docs/base_doc/DOCUMENTATION/V50A_ACRO_SUP/OBJSPEC.PDF
mdebug, on David Anderson's page
https://www.prevanders.net/#mdebug
mdebug spec (at least some version of it)
https://www.prevanders.net/Mdebug.ps
Note from Peter Rowell about mdebug
http://www.datahedron.com/mips.html
https://www.prevanders.net/mdebug.html (mirror)
>> What would help me, if you have time (no rush), is to tell me if we can
>> reasonably consider the code in mipsread.c (and mdebugread.c, which
>> seems related) to be obsolete and remove it.
>
> As I say I'll see what I can do. Overall emitting ECOFF-in-ELF frame
> unwinding information aka Procedure Description Records (PDR), a valuable
> subset of the mdebug stuff, continues being supported by MIPS GCC and GAS.
> No other stuff is relevant anymore; we have no support for IRIX or ULTRIX
> targets left and the GNU tools can't produce other ECOFF debug information
> for MIPS targets anymore.
>
> NB I had plans/ideas to improve PDR handling in GDB, but this has never
> materialised. It's good having/improving IMHO as PDR records are very
> lightweight and retained by `strip', and with its variable frame format
> the MIPS target is very bad for debugging when execution is stopped at a
> random place with no associated debug information, which might be libc or
> suchlike. Then you just have the PC and the register stack available and
> nothing else, not even the return address ($ra may have been clobbered).
>
> But all the PDR support is gone from GDB AFAICT and ISTR now having a
> discussion as to bringing it back some 20 years ago while I was still at
> MTI, possibly with Daniel Jacobowitz. The messages should be easy to
> chase, but otherwise I have to conclude none of this is relevant to MIPS
> targets anymore. So I guess I've figured it out for you already.
Ok, thanks for the precious information.
> This stuff is possibly used by the Alpha target however, though I'm not
> sure offhand as I'm less familiar with the matters there.
I am mostly convinced that none of this is relevant anymore. And if it
ever became relevant anymore for some reason, I think it would be better
to just start from scratch, given how much this has bit-rotten.
Simon
>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:
Simon> I am mostly convinced that none of this is relevant anymore. And if it
Simon> ever became relevant anymore for some reason, I think it would be better
Simon> to just start from scratch, given how much this has bit-rotten.
+1 to that
Tom
@@ -143,17 +143,6 @@ msymbol_is_function (struct objfile *objfile, minimal_symbol *minsym,
}
}
-/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
- At the end, copy them all into one newly allocated array. */
-
-#define BUNCH_SIZE 127
-
-struct msym_bunch
- {
- struct msym_bunch *next;
- struct minimal_symbol contents[BUNCH_SIZE];
- };
-
/* See minsyms.h. */
unsigned int
@@ -1087,32 +1076,10 @@ get_symbol_leading_char (program_space *pspace, bfd *abfd)
/* See minsyms.h. */
minimal_symbol_reader::minimal_symbol_reader (struct objfile *obj)
-: m_objfile (obj),
- m_msym_bunch (NULL),
- /* Note that presetting m_msym_bunch_index to BUNCH_SIZE causes the
- first call to save a minimal symbol to allocate the memory for
- the first bunch. */
- m_msym_bunch_index (BUNCH_SIZE),
- m_msym_count (0)
+ : m_objfile (obj)
{
}
-/* Discard the currently collected minimal symbols, if any. If we wish
- to save them for later use, we must have already copied them somewhere
- else before calling this function. */
-
-minimal_symbol_reader::~minimal_symbol_reader ()
-{
- struct msym_bunch *next;
-
- while (m_msym_bunch != NULL)
- {
- next = m_msym_bunch->next;
- xfree (m_msym_bunch);
- m_msym_bunch = next;
- }
-}
-
/* See minsyms.h. */
void
@@ -1180,9 +1147,6 @@ minimal_symbol_reader::record_full (std::string_view name,
enum minimal_symbol_type ms_type,
int section)
{
- struct msym_bunch *newobj;
- struct minimal_symbol *msymbol;
-
/* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
the minimal symbols, because if there is also another symbol
at the same address (e.g. the first function of the file),
@@ -1207,14 +1171,7 @@ minimal_symbol_reader::record_full (std::string_view name,
hex_string (LONGEST (address)),
section, (int) name.size (), name.data ());
- if (m_msym_bunch_index == BUNCH_SIZE)
- {
- newobj = XCNEW (struct msym_bunch);
- m_msym_bunch_index = 0;
- newobj->next = m_msym_bunch;
- m_msym_bunch = newobj;
- }
- msymbol = &m_msym_bunch->contents[m_msym_bunch_index];
+ minimal_symbol *msymbol = &m_msyms.emplace_back ();
msymbol->set_language (language_unknown,
&m_objfile->per_bfd->storage_obstack);
@@ -1226,17 +1183,13 @@ minimal_symbol_reader::record_full (std::string_view name,
msymbol->set_unrelocated_address (address);
msymbol->set_section_index (section);
-
msymbol->set_type (ms_type);
/* If we already read minimal symbols for this objfile, then don't
ever allocate a new one. */
if (!m_objfile->per_bfd->minsyms_read)
- {
- m_msym_bunch_index++;
- m_objfile->per_bfd->n_minsyms++;
- }
- m_msym_count++;
+ m_objfile->per_bfd->n_minsyms++;
+
return msymbol;
}
@@ -1465,59 +1418,41 @@ class minimal_symbol_install_worker
void
minimal_symbol_reader::install ()
{
- int mcount;
- struct msym_bunch *bunch;
- struct minimal_symbol *msymbols;
- int alloc_count;
-
if (m_objfile->per_bfd->minsyms_read)
return;
- if (m_msym_count > 0)
+ if (!m_msyms.empty ())
{
- symtab_create_debug_printf ("installing %d minimal symbols of objfile %s",
- m_msym_count, objfile_name (m_objfile));
+ symtab_create_debug_printf ("installing %zu minimal symbols of objfile %s",
+ m_msyms.size (), objfile_name (m_objfile));
/* Allocate enough space, into which we will gather the bunches
of new and existing minimal symbols, sort them, and then
compact out the duplicate entries. Once we have a final
table, we will give back the excess space. */
-
- alloc_count = m_msym_count + m_objfile->per_bfd->minimal_symbol_count;
+ int alloc_count
+ = m_msyms.size () + m_objfile->per_bfd->minimal_symbol_count;
gdb::unique_xmalloc_ptr<minimal_symbol>
msym_holder (XNEWVEC (minimal_symbol, alloc_count));
- msymbols = msym_holder.get ();
+ minimal_symbol *msymbols = msym_holder.get ();
/* Copy in the existing minimal symbols, if there are any. */
-
if (m_objfile->per_bfd->minimal_symbol_count)
memcpy (msymbols, m_objfile->per_bfd->msymbols.get (),
m_objfile->per_bfd->minimal_symbol_count
* sizeof (struct minimal_symbol));
- /* Walk through the list of minimal symbol bunches, adding each symbol
- to the new contiguous array of symbols. Note that we start with the
- current, possibly partially filled bunch (thus we use the current
- msym_bunch_index for the first bunch we copy over), and thereafter
- each bunch is full. */
-
- mcount = m_objfile->per_bfd->minimal_symbol_count;
-
- for (bunch = m_msym_bunch; bunch != NULL; bunch = bunch->next)
- {
- memcpy (&msymbols[mcount], &bunch->contents[0],
- m_msym_bunch_index * sizeof (struct minimal_symbol));
- mcount += m_msym_bunch_index;
- m_msym_bunch_index = BUNCH_SIZE;
- }
+ /* Walk through the list of recorded minimal symbol, adding each symbol
+ to the new contiguous array of symbols. */
+ int mcount = m_objfile->per_bfd->minimal_symbol_count;
+ std::copy (m_msyms.begin (), m_msyms.end (), &msymbols[mcount]);
+ mcount += m_msyms.size ();
/* Sort the minimal symbols by address. */
-
std::sort (msymbols, msymbols + mcount, minimal_symbol_is_less_than);
/* Compact out any duplicates, and free up whatever space we are
no longer using. */
-
mcount = compact_minimal_symbols (msymbols, mcount, m_objfile);
msym_holder.reset (XRESIZEVEC (struct minimal_symbol,
msym_holder.release (),
@@ -20,6 +20,8 @@
#ifndef GDB_MINSYMS_H
#define GDB_MINSYMS_H
+#include <deque>
+
struct program_space;
struct type;
@@ -78,8 +80,6 @@ struct bound_minimal_symbol
as opaque and use functions provided by minsyms.c to inspect them.
*/
-struct msym_bunch;
-
/* An RAII-based object that is used to record minimal symbols while
they are being read. */
class minimal_symbol_reader
@@ -92,8 +92,6 @@ class minimal_symbol_reader
explicit minimal_symbol_reader (struct objfile *);
- ~minimal_symbol_reader ();
-
/* Install the minimal symbols that have been collected into the
given objfile. */
@@ -154,19 +152,10 @@ class minimal_symbol_reader
struct objfile *m_objfile;
- /* Bunch currently being filled up.
- The next field points to chain of filled bunches. */
-
- struct msym_bunch *m_msym_bunch;
-
- /* Number of slots filled in current bunch. */
-
- int m_msym_bunch_index;
-
- /* Total number of minimal symbols recorded so far for the
- objfile. */
-
- int m_msym_count;
+ /* The minimal symbols recorded so far. This uses a deque instead of e.g. a
+ vector, because references to minimal symbols need to stay valid across
+ calls to recod_full. */
+ std::deque<minimal_symbol> m_msyms;
};