/* Read a symbol table in ECOFF format (Third-Eye).
Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor
#define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)
\f
/* Various complaints about symbol reading that don't abort the process */
+static void
+index_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "bad aux index at symbol %s", arg1);
+}
-static struct deprecated_complaint bad_file_number_complaint =
-{"bad file number %d", 0, 0};
-
-static struct deprecated_complaint index_complaint =
-{"bad aux index at symbol %s", 0, 0};
-
-static struct deprecated_complaint aux_index_complaint =
-{"bad proc end in aux found from symbol %s", 0, 0};
-
-static struct deprecated_complaint block_index_complaint =
-{"bad aux index at block symbol %s", 0, 0};
-
-static struct deprecated_complaint unknown_ext_complaint =
-{"unknown external symbol %s", 0, 0};
-
-static struct deprecated_complaint unknown_sym_complaint =
-{"unknown local symbol %s", 0, 0};
-
-static struct deprecated_complaint unknown_st_complaint =
-{"with type %d", 0, 0};
-
-static struct deprecated_complaint block_overflow_complaint =
-{"block containing %s overfilled", 0, 0};
-
-static struct deprecated_complaint basic_type_complaint =
-{"cannot map ECOFF basic type 0x%x for %s", 0, 0};
-
-static struct deprecated_complaint unknown_type_qual_complaint =
-{"unknown type qualifier 0x%x", 0, 0};
-
-static struct deprecated_complaint array_index_type_complaint =
-{"illegal array index type for %s, assuming int", 0, 0};
-
-static struct deprecated_complaint bad_tag_guess_complaint =
-{"guessed tag type of %s incorrectly", 0, 0};
-
-static struct deprecated_complaint block_member_complaint =
-{"declaration block contains unhandled symbol type %d", 0, 0};
-
-static struct deprecated_complaint stEnd_complaint =
-{"stEnd with storage class %d not handled", 0, 0};
-
-static struct deprecated_complaint unknown_mdebug_symtype_complaint =
-{"unknown symbol type 0x%x", 0, 0};
-
-static struct deprecated_complaint stab_unknown_complaint =
-{"unknown stabs symbol %s", 0, 0};
-
-static struct deprecated_complaint pdr_for_nonsymbol_complaint =
-{"PDR for %s, but no symbol", 0, 0};
-
-static struct deprecated_complaint pdr_static_symbol_complaint =
-{"can't handle PDR for static proc at 0x%lx", 0, 0};
-
-static struct deprecated_complaint bad_setjmp_pdr_complaint =
-{"fixing bad setjmp PDR from libc", 0, 0};
-
-static struct deprecated_complaint bad_fbitfield_complaint =
-{"can't handle TIR fBitfield for %s", 0, 0};
-
-static struct deprecated_complaint bad_continued_complaint =
-{"illegal TIR continued for %s", 0, 0};
-
-static struct deprecated_complaint bad_rfd_entry_complaint =
-{"bad rfd entry for %s: file %d, index %d", 0, 0};
-
-static struct deprecated_complaint unexpected_type_code_complaint =
-{"unexpected type code for %s", 0, 0};
-
-static struct deprecated_complaint unable_to_cross_ref_complaint =
-{"unable to cross ref btTypedef for %s", 0, 0};
-
-static struct deprecated_complaint bad_indirect_xref_complaint =
-{"unable to cross ref btIndirect for %s", 0, 0};
-
-static struct deprecated_complaint illegal_forward_tq0_complaint =
-{"illegal tq0 in forward typedef for %s", 0, 0};
+static void
+unknown_ext_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "unknown external symbol %s", arg1);
+}
-static struct deprecated_complaint illegal_forward_bt_complaint =
-{"illegal bt %d in forward typedef for %s", 0, 0};
+static void
+basic_type_complaint (int arg1, const char *arg2)
+{
+ complaint (&symfile_complaints, "cannot map ECOFF basic type 0x%x for %s",
+ arg1, arg2);
+}
-static struct deprecated_complaint bad_linetable_guess_complaint =
-{"guessed size of linetable for %s incorrectly", 0, 0};
+static void
+bad_tag_guess_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "guessed tag type of %s incorrectly", arg1);
+}
-static struct deprecated_complaint bad_ext_ifd_complaint =
-{"bad ifd for external symbol: %d (max %d)", 0, 0};
+static void
+bad_rfd_entry_complaint (const char *arg1, int arg2, int arg3)
+{
+ complaint (&symfile_complaints, "bad rfd entry for %s: file %d, index %d",
+ arg1, arg2, arg3);
+}
-static struct deprecated_complaint bad_ext_iss_complaint =
-{"bad iss for external symbol: %ld (max %ld)", 0, 0};
+static void
+unexpected_type_code_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "unexpected type code for %s", arg1);
+}
/* Macros and extra defs */
case stProc: /* Procedure, usually goes into global block */
case stStaticProc: /* Static procedure, goes into current block */
+ /* For stProc symbol records, we need to check the storage class
+ as well, as only (stProc, scText) entries represent "real"
+ procedures - See the Compaq document titled "Object File /
+ Symbol Table Format Specification" for more information.
+ If the storage class is not scText, we discard the whole block
+ of symbol records for this stProc. */
+ if (sh->st == stProc && sh->sc != scText)
+ {
+ char *ext_tsym = ext_sh;
+ int keep_counting = 1;
+ SYMR tsym;
+
+ while (keep_counting)
+ {
+ ext_tsym += external_sym_size;
+ (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
+ count++;
+ switch (tsym.st)
+ {
+ case stParam:
+ break;
+ case stEnd:
+ keep_counting = 0;
+ break;
+ default:
+ complaint (&symfile_complaints,
+ "unknown symbol type 0x%x", sh->st);
+ break;
+ }
+ }
+ break;
+ }
s = new_symbol (name);
SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
SYMBOL_CLASS (s) = LOC_BLOCK;
/* Make a type for the procedure itself */
SYMBOL_TYPE (s) = lookup_function_type (t);
+ /* All functions in C++ have prototypes. For C we don't have enough
+ information in the debug info. */
+ if (SYMBOL_LANGUAGE (s) == language_cplus)
+ TYPE_FLAGS (SYMBOL_TYPE (s)) |= TYPE_FLAG_PROTOTYPED;
+
/* Create and enter a new lexical context */
b = new_block (top_stack->maxsyms);
SYMBOL_BLOCK_VALUE (s) = b;
switch (tsym.st)
{
case stEnd:
- goto end_of_fields;
+ /* C++ encodes class types as structures where there the
+ methods are encoded as stProc. The scope of stProc
+ symbols also ends with stEnd, thus creating a risk of
+ taking the wrong stEnd symbol record as the end of
+ the current struct, which would cause GDB to undercount
+ the real number of fields in this struct. To make sure
+ we really reached the right stEnd symbol record, we
+ check the associated name, and match it against the
+ struct name. Since method names are mangled while
+ the class name is not, there is no risk of having a
+ method whose name is identical to the class name
+ (in particular constructor method names are different
+ from the class name). There is therefore no risk that
+ this check stops the count on the StEnd of a method. */
+ if (strcmp (debug_info->ss + cur_fdr->issBase + tsym.iss,
+ name) == 0)
+ goto end_of_fields;
+ break;
case stMember:
if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
break;
default:
- complain (&block_member_complaint, tsym.st);
+ complaint (&symfile_complaints,
+ "declaration block contains unhandled symbol type %d",
+ tsym.st);
}
}
end_of_fields:;
FIELD_TYPE (*f) = t;
FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss;
FIELD_BITSIZE (*f) = 0;
+ FIELD_STATIC_KIND (*f) = 0;
enum_sym = ((struct symbol *)
obstack_alloc (¤t_objfile->symbol_obstack,
;
}
else
- complain (&stEnd_complaint, sh->sc);
+ complaint (&symfile_complaints,
+ "stEnd with storage class %d not handled", sh->sc);
pop_parse_stack (); /* restore previous lexical context */
break;
bitsize = 0;
FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
FIELD_BITSIZE (*f) = bitsize;
+ FIELD_STATIC_KIND (*f) = 0;
break;
case stIndirect: /* forward declaration on Irix5 */
case stConstant:
break; /* constant */
default:
- complain (&unknown_mdebug_symtype_complaint, sh->st);
+ complaint (&symfile_complaints, "unknown symbol type 0x%x", sh->st);
break;
}
/* Handle corrupt aux indices. */
if (aux_index >= (debug_info->fdr + fd)->caux)
{
- complain (&index_complaint, sym_name);
+ index_complaint (sym_name);
return mdebug_type_int;
}
ax += aux_index;
(*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt)))
{
- complain (&basic_type_complaint, t->bt, sym_name);
+ basic_type_complaint (t->bt, sym_name);
return mdebug_type_int;
}
if (map_bt[t->bt])
type_code = TYPE_CODE_ERROR;
break;
default:
- complain (&basic_type_complaint, t->bt, sym_name);
+ basic_type_complaint (t->bt, sym_name);
return mdebug_type_int;
}
}
if (t->fBitfield)
{
int width = AUX_GET_WIDTH (bigend, ax);
-
- /* Inhibit core dumps with some cfront generated objects that
- corrupt the TIR. */
+#if 0 /* OBSOLETE CFront */
+// OBSOLETE /* Inhibit core dumps with some cfront generated objects that
+// OBSOLETE corrupt the TIR. */
+#endif /* OBSOLETE CFront */
+ /* Inhibit core dumps if TIR is corrupted. */
if (bs == (int *) NULL)
{
/* Alpha cc -migrate encodes char and unsigned char types
else if (t->bt == btEnum)
;
else
- complain (&bad_fbitfield_complaint, sym_name);
+ complaint (&symfile_complaints, "can't handle TIR fBitfield for %s",
+ sym_name);
}
else
*bs = width;
if (rf == -1)
{
- complain (&bad_indirect_xref_complaint, sym_name);
+ complaint (&symfile_complaints,
+ "unable to cross ref btIndirect for %s", sym_name);
return mdebug_type_int;
}
xref_fh = get_rfd (fd, rf);
&& TYPE_CODE (tp) != TYPE_CODE_UNION
&& TYPE_CODE (tp) != TYPE_CODE_ENUM)
{
- complain (&unexpected_type_code_complaint, sym_name);
+ unexpected_type_code_complaint (sym_name);
}
else
{
|| (TYPE_CODE (tp) != TYPE_CODE_ENUM
&& type_code == TYPE_CODE_ENUM))
{
- complain (&bad_tag_guess_complaint, sym_name);
+ bad_tag_guess_complaint (sym_name);
}
if (TYPE_CODE (tp) != type_code)
are corrupted. */
if (TYPE_CODE (tp) != TYPE_CODE_RANGE)
{
- complain (&unexpected_type_code_complaint, sym_name);
+ unexpected_type_code_complaint (sym_name);
}
else
{
exception is if we guessed wrong re struct/union/enum. */
if (TYPE_CODE (tp) != type_code)
{
- complain (&bad_tag_guess_complaint, sym_name);
+ bad_tag_guess_complaint (sym_name);
TYPE_CODE (tp) = type_code;
}
if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name))
ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
if (tp == (struct type *) NULL)
{
- complain (&unable_to_cross_ref_complaint, sym_name);
+ complaint (&symfile_complaints,
+ "unable to cross ref btTypedef for %s", sym_name);
tp = mdebug_type_int;
}
}
/* Complain for illegal continuations due to corrupt aux entries. */
if (t->continued)
- complain (&bad_continued_complaint, sym_name);
+ complaint (&symfile_complaints, "illegal TIR continued for %s", sym_name);
return tp;
}
else due to corrupt aux entries. */
if (TYPE_CODE (indx) != TYPE_CODE_INT)
{
- complain (&array_index_type_complaint, sym_name);
+ complaint (&symfile_complaints,
+ "illegal array index type for %s, assuming int", sym_name);
indx = mdebug_type_int;
}
return 0;
default:
- complain (&unknown_type_qual_complaint, tq);
+ complaint (&symfile_complaints, "unknown type qualifier 0x%x", tq);
return 0;
}
}
{
/* Static procedure at address pr->adr. Sigh. */
/* FIXME-32x64. assuming pr->adr fits in long. */
- complain (&pdr_static_symbol_complaint, (unsigned long) pr->adr);
+ complaint (&symfile_complaints,
+ "can't handle PDR for static proc at 0x%lx",
+ (unsigned long) pr->adr);
return;
}
else
}
else
{
- complain (&pdr_for_nonsymbol_complaint, sh_name);
+ complaint (&symfile_complaints, "PDR for %s, but no symbol", sh_name);
#if 1
return;
#else
to make backtrace through setjmp work. */
if (e->pdr.pcreg == 0 && STREQ (sh_name, "setjmp"))
{
- complain (&bad_setjmp_pdr_complaint, 0);
+ complaint (&symfile_complaints, "fixing bad setjmp PDR from libc");
e->pdr.pcreg = RA_REGNUM;
e->pdr.regmask = 0x80000000;
e->pdr.regoffset = -4;
with corrupt binaries. */
if (lt->nitems >= maxlines)
{
- complain (&bad_linetable_guess_complaint, fdr_name (fh));
+ complaint (&symfile_complaints,
+ "guessed size of linetable for %s incorrectly",
+ fdr_name (fh));
break;
}
k = add_line (lt, lineno, l, k);
}
}
\f
+static void
+function_outside_compilation_unit_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints,
+ "function `%s' appears to be defined outside of all compilation units",
+ arg1);
+}
+
/* Master parsing procedure for first-pass reading of file symbols
into a partial_symtab. */
external symbols. */
if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
{
- complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax);
+ complaint (&symfile_complaints,
+ "bad ifd for external symbol: %d (max %ld)", ext_in->ifd,
+ hdr->ifdMax);
continue;
}
if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
{
- complain (&bad_ext_iss_complaint, ext_in->asym.iss,
- hdr->issExtMax);
+ complaint (&symfile_complaints,
+ "bad iss for external symbol: %ld (max %ld)",
+ ext_in->asym.iss, hdr->issExtMax);
continue;
}
/* Fall through. */
default:
ms_type = mst_unknown;
- complain (&unknown_ext_complaint, name);
+ unknown_ext_complaint (name);
}
if (!ECOFF_IN_ELF (cur_bfd))
prim_record_minimal_symbol (name, svalue, ms_type, objfile);
switch (type_code)
{
- static struct deprecated_complaint function_outside_compilation_unit = {
- "function `%s' appears to be defined outside of all compilation units", 0, 0
- };
char *p;
/*
* Standard, external, non-debugger, symbols
psymtab_include_list = (char **)
alloca ((includes_allocated *= 2) *
sizeof (char *));
- memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ memcpy (psymtab_include_list, orig,
includes_used * sizeof (char *));
}
continue;
psymtab_language, objfile);
p += 1;
}
- /* The semantics of C++ state that "struct foo { ... }"
- also defines a typedef for "foo". Unfortuantely, cfront
- never makes the typedef when translating from C++ to C.
- We make the typedef here so that "ptype foo" works as
- expected for cfront translated code. */
- else if (psymtab_language == language_cplus)
- {
- /* Also a typedef with the same name. */
- add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_TYPEDEF,
- &objfile->static_psymbols,
- sh.value, 0,
- psymtab_language, objfile);
- }
+#if 0 /* OBSOLETE CFront */
+// OBSOLETE /* The semantics of C++ state that "struct foo { ... }"
+// OBSOLETE also defines a typedef for "foo". Unfortuantely, cfront
+// OBSOLETE never makes the typedef when translating from C++ to C.
+// OBSOLETE We make the typedef here so that "ptype foo" works as
+// OBSOLETE expected for cfront translated code. */
+// OBSOLETE else if (psymtab_language == language_cplus)
+// OBSOLETE {
+// OBSOLETE /* Also a typedef with the same name. */
+// OBSOLETE add_psymbol_to_list (namestring, p - namestring,
+// OBSOLETE VAR_NAMESPACE, LOC_TYPEDEF,
+// OBSOLETE &objfile->static_psymbols,
+// OBSOLETE sh.value, 0,
+// OBSOLETE psymtab_language, objfile);
+// OBSOLETE }
+#endif /* OBSOLETE CFront */
}
goto check_enum;
case 't':
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
- complain (&function_outside_compilation_unit, name);
+ function_outside_compilation_unit_complaint (name);
xfree (name);
}
sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
- complain (&function_outside_compilation_unit, name);
+ function_outside_compilation_unit_complaint (name);
xfree (name);
}
sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
case '9':
case '-':
case '#': /* for symbol identification (used in live ranges) */
- /* added to support cfront stabs strings */
- case 'Z': /* for definition continuations */
- case 'P': /* for prototypes */
+#if 0 /* OBSOLETE CFront */
+// OBSOLETE /* added to support cfront stabs strings */
+// OBSOLETE case 'Z': /* for definition continuations */
+// OBSOLETE case 'P': /* for prototypes */
+#endif /* OBSOLETE CFront */
continue;
case ':':
time searching to the end of every string looking for
a backslash. */
- complain (&unknown_symchar_complaint, p[1]);
+ complaint (&symfile_complaints,
+ "unknown symbol descriptor `%c'", p[1]);
/* Ignore it; perhaps it is an extension that we don't
know about. */
default:
/* If we haven't found it yet, ignore it. It's probably some
new type we don't know about yet. */
- complain (&unknown_symtype_complaint,
- local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/
+ complaint (&symfile_complaints, "unknown symbol type %s",
+ local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/
continue;
}
if (stabstring
/* FALLTHROUGH */
case stProc:
+ /* Ignore all parameter symbol records. */
+ if (sh.index >= hdr->iauxMax)
+ {
+ /* Should not happen, but does when cross-compiling
+ with the MIPS compiler. FIXME -- pull later. */
+ index_complaint (name);
+ new_sdx = cur_sdx + 1; /* Don't skip at all */
+ }
+ else
+ new_sdx = AUX_GET_ISYM (fh->fBigendian,
+ (debug_info->external_aux
+ + fh->iauxBase
+ + sh.index));
+
+ if (new_sdx <= cur_sdx)
+ {
+ /* This should not happen either... FIXME. */
+ complaint (&symfile_complaints,
+ "bad proc end in aux found from symbol %s",
+ name);
+ new_sdx = cur_sdx + 1; /* Don't skip backward */
+ }
+
+ /* For stProc symbol records, we need to check the
+ storage class as well, as only (stProc, scText)
+ entries represent "real" procedures - See the
+ Compaq document titled "Object File / Symbol Table
+ Format Specification" for more information. If the
+ storage class is not scText, we discard the whole
+ block of symbol records for this stProc. */
+ if (sh.st == stProc && sh.sc != scText)
+ goto skip;
+
/* Usually there is a local and a global stProc symbol
for a function. This means that the function name
has already been entered into the mimimal symbol table
&objfile->static_psymbols,
0, sh.value, psymtab_language, objfile);
- /* Skip over procedure to next one. */
- if (sh.index >= hdr->iauxMax)
- {
- /* Should not happen, but does when cross-compiling
- with the MIPS compiler. FIXME -- pull later. */
- complain (&index_complaint, name);
- new_sdx = cur_sdx + 1; /* Don't skip at all */
- }
- else
- new_sdx = AUX_GET_ISYM (fh->fBigendian,
- (debug_info->external_aux
- + fh->iauxBase
- + sh.index));
procaddr = sh.value;
- if (new_sdx <= cur_sdx)
- {
- /* This should not happen either... FIXME. */
- complain (&aux_index_complaint, name);
- new_sdx = cur_sdx + 1; /* Don't skip backward */
- }
-
cur_sdx = new_sdx;
(*swap_sym_in) (cur_bfd,
((char *) debug_info->external_sym
if (new_sdx <= cur_sdx)
{
/* This happens with the Ultrix kernel. */
- complain (&block_index_complaint, name);
+ complaint (&symfile_complaints,
+ "bad aux index at block symbol %s", name);
new_sdx = cur_sdx + 1; /* Don't skip backward */
}
cur_sdx = new_sdx;
default:
/* Both complaints are valid: one gives symbol name,
the other the offending symbol type. */
- complain (&unknown_sym_complaint, name);
- complain (&unknown_st_complaint, sh.st);
+ complaint (&symfile_complaints, "unknown local symbol %s",
+ name);
+ complaint (&symfile_complaints, "with type %d", sh.st);
cur_sdx++;
continue;
}
class = LOC_LABEL;
break;
default:
- complain (&unknown_ext_complaint,
- debug_info->ssext + psh->iss);
+ unknown_ext_complaint (debug_info->ssext + psh->iss);
/* Fall through, pretend it's global. */
case stGlobal:
/* Global common symbols are resolved by the runtime loader,
&rh);
if (rh < 0 || rh >= hdr->ifdMax)
{
- complain (&bad_file_number_complaint, rh);
+ complaint (&symfile_complaints, "bad file number %ld", rh);
continue;
}
/* These are generated by gcc-2.x, do not complain */
;
else
- complain (&stab_unknown_complaint, name);
+ complaint (&symfile_complaints, "unknown stabs symbol %s", name);
}
if (! last_symtab_ended)
{
/* File indirect entry is corrupt. */
*pname = "<illegal>";
- complain (&bad_rfd_entry_complaint,
- sym_name, xref_fd, rn->index);
+ bad_rfd_entry_complaint (sym_name, xref_fd, rn->index);
return result;
}
{
/* File indirect entry is corrupt. */
*pname = "<illegal>";
- complain (&bad_rfd_entry_complaint,
- sym_name, xref_fd, rn->index);
+ bad_rfd_entry_complaint (sym_name, xref_fd, rn->index);
return result;
}
+ fh->iauxBase + sh.index)->a_ti,
&tir);
if (tir.tq0 != tqNil)
- complain (&illegal_forward_tq0_complaint, sym_name);
+ complaint (&symfile_complaints,
+ "illegal tq0 in forward typedef for %s", sym_name);
switch (tir.bt)
{
case btVoid:
break;
default:
- complain (&illegal_forward_bt_complaint, tir.bt, sym_name);
+ complaint (&symfile_complaints,
+ "illegal bt %d in forward typedef for %s", tir.bt,
+ sym_name);
*tpp = init_type (type_code, 0, 0, (char *) NULL,
current_objfile);
break;
if (b == top_stack->cur_block &&
nsyms >= top_stack->maxsyms)
{
- complain (&block_overflow_complaint, SYMBOL_NAME (s));
+ complaint (&symfile_complaints, "block containing %s overfilled",
+ SYMBOL_NAME (s));
/* In this case shrink_block is actually grow_block, since
BLOCK_NSYMS(b) is larger than its current size. */
origb = b;