From: Ian Lance Taylor Date: Tue, 23 Jan 1996 20:59:46 +0000 (+0000) Subject: * ieee.c: Various changes to write out definitions of C++ classes. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b96e1ce4f80e86b0f31901b5af49d571d3c65ed1;p=binutils-gdb.git * ieee.c: Various changes to write out definitions of C++ classes. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e23e8a986e7..0d9d95b3d34 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,19 @@ +Tue Jan 23 15:54:18 1996 Ian Lance Taylor + + * ieee.c: Various changes to write out definitions of C++ classes. + + * debug.c (debug_append_filename): Remove. + * debug.h (debug_append_filename): Don't declare. + + * stabs.c (struct stab_handle): Remove last_type field. Add + so_string and so_value fields. + (finish_stab): Call stab_emit_pending_vars before calling + debug_end_function. Don't warn about pending variables. + (parse_stab): Accumulate N_SO strings until a non N_SO symbol is + seen, rather than calling debug_append_filename. Call + stab_emit_pending_vars before calling debug_end_function. Don't + set info->last_type. + Tue Jan 23 09:53:54 1996 Doug Evans * objdump.c (disassemble_data): Handle unknown endianness. diff --git a/binutils/ieee.c b/binutils/ieee.c index 84505d38e29..e1bef291362 100644 --- a/binutils/ieee.c +++ b/binutils/ieee.c @@ -1,4 +1,4 @@ -/* ieee.c -- Write out IEEE-695 debugging information. +/* ieee.c -- Read and write IEEE-695 debugging information. Copyright (C) 1996 Free Software Foundation, Inc. Written by Ian Lance Taylor . @@ -3136,6 +3136,29 @@ struct ieee_range bfd_vma high; }; +/* This structure holds information for a class on the type stack. */ + +struct ieee_type_class +{ + /* The name of the class. */ + const char *name; + /* The name index in the debugging information. */ + unsigned int indx; + /* The pmisc records for the class. */ + struct ieee_buf *pmiscbuf; + /* The number of pmisc records. */ + unsigned int pmisccount; + /* The name of the class holding the virtual table, if not this + class. */ + const char *vclass; + /* Whether this class holds its own virtual table. */ + boolean ownvptr; + /* The largest virtual table offset seen so far. */ + bfd_vma voffset; + /* The current method. */ + const char *method; +}; + /* This is how we store types for the writing routines. Most types are simply represented by a type index. */ @@ -3148,6 +3171,8 @@ struct ieee_write_type /* If this is a struct, this is where the struct definition is built. */ struct ieee_buf *strdef; + /* If this is a class, this is where the class information is built. */ + struct ieee_type_class *classdef; /* Whether the type is unsigned. */ unsigned int unsignedp : 1; /* Whether this is a reference type. */ @@ -3218,6 +3243,9 @@ struct ieee_handle /* List of buffers for variables and functions in the current compilation unit. */ struct ieee_buf *vars; + /* List of buffers for C++ class definitions in the current + compilation unit. */ + struct ieee_buf *cxx; /* List of buffers for line numbers in the current compilation unit. */ struct ieee_buf *linenos; /* Ranges for the current compilation unit. */ @@ -3243,6 +3271,8 @@ struct ieee_handle const char *lineno_filename; /* Line number name index. */ unsigned int lineno_name_indx; + /* Highest address seen at end of procedure. */ + bfd_vma highaddr; }; static boolean ieee_change_buffer @@ -3258,13 +3288,21 @@ static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int)); static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int)); static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma)); static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *)); +static boolean ieee_write_asn + PARAMS ((struct ieee_handle *, unsigned int, bfd_vma)); +static boolean ieee_write_atn65 + PARAMS ((struct ieee_handle *, unsigned int, const char *)); static boolean ieee_define_type PARAMS ((struct ieee_handle *, unsigned int, boolean)); static boolean ieee_define_named_type - PARAMS ((struct ieee_handle *, const char *, boolean, unsigned int, boolean, - struct ieee_buf **)); + PARAMS ((struct ieee_handle *, const char *, boolean, unsigned int, + unsigned int, boolean, struct ieee_buf **)); static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *)); static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *)); +static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility)); +static boolean ieee_class_method_var + PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean, + boolean, boolean, bfd_vma, boolean)); static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *)); static boolean ieee_start_source PARAMS ((PTR, const char *)); @@ -3654,6 +3692,34 @@ ieee_write_id (info, s) return true; } +/* Write out an ASN record. */ + +static boolean +ieee_write_asn (info, indx, val) + struct ieee_handle *info; + unsigned int indx; + bfd_vma val; +{ + return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) + && ieee_write_number (info, indx) + && ieee_write_number (info, val)); +} + +/* Write out an ATN65 record. */ + +static boolean +ieee_write_atn65 (info, indx, s) + struct ieee_handle *info; + unsigned int indx; + const char *s; +{ + return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) + && ieee_write_number (info, indx) + && ieee_write_number (info, 0) + && ieee_write_number (info, 65) + && ieee_write_id (info, s)); +} + /* Start defining a type. */ static boolean @@ -3662,17 +3728,18 @@ ieee_define_type (info, size, unsignedp) unsigned int size; boolean unsignedp; { - return ieee_define_named_type (info, (const char *) NULL, false, size, + return ieee_define_named_type (info, (const char *) NULL, false, 0, size, unsignedp, (struct ieee_buf **) NULL); } /* Start defining a named type. */ static boolean -ieee_define_named_type (info, name, tagp, size, unsignedp, ppbuf) +ieee_define_named_type (info, name, tagp, id, size, unsignedp, ppbuf) struct ieee_handle *info; const char *name; boolean tagp; + unsigned int id; unsigned int size; boolean unsignedp; struct ieee_buf **ppbuf; @@ -3680,7 +3747,7 @@ ieee_define_named_type (info, name, tagp, size, unsignedp, ppbuf) unsigned int type_indx; unsigned int name_indx; - if (! tagp || name == NULL || *name == '\0') + if (! tagp || id == (unsigned int) -1) { type_indx = info->type_indx; ++info->type_indx; @@ -3688,19 +3755,32 @@ ieee_define_named_type (info, name, tagp, size, unsignedp, ppbuf) else { struct ieee_name_type *nt; + const char *tag; + char ab[20]; + + /* We need to create a tag for internal use even if we don't + want one for external use. This will let us refer to an + anonymous struct. */ + if (name != NULL) + tag = name; + else + { + sprintf (ab, "__anon%u", id); + tag = ab; + } /* The name is a tag. If we have already defined the tag, we must use the existing type index. */ for (nt = info->tags; nt != NULL; nt = nt->next) - if (nt->name[0] == name[0] - && strcmp (nt->name, name) == 0) + if (nt->name[0] == tag[0] + && strcmp (nt->name, tag) == 0) break; if (nt == NULL) { nt = (struct ieee_name_type *) xmalloc (sizeof *nt); memset (nt, 0, sizeof *nt); - nt->name = name; + nt->name = tag; nt->next = info->tags; info->tags = nt; nt->type.indx = info->type_indx; @@ -3936,6 +4016,7 @@ ieee_start_compilation_unit (p, filename) info->types = NULL; info->vars = NULL; + info->cxx = NULL; info->linenos = NULL; info->ranges = NULL; @@ -3958,6 +4039,46 @@ ieee_finish_compilation_unit (info) return false; } + if (info->cxx != NULL) + { + /* Append any C++ information to the global function and + variable information. */ + if (info->vars != NULL) + { + if (! ieee_change_buffer (info, &info->vars)) + return false; + } + else + { + if (! ieee_change_buffer (info, &info->vars) + || ! ieee_write_byte (info, (int) ieee_bb_record_enum) + || ! ieee_write_byte (info, 3) + || ! ieee_write_number (info, 0) + || ! ieee_write_id (info, info->modname)) + return false; + } + + /* We put the pmisc records in a dummy procedure, just as the + MRI compiler does. */ + if (! ieee_write_byte (info, (int) ieee_bb_record_enum) + || ! ieee_write_byte (info, 6) + || ! ieee_write_number (info, 0) + || ! ieee_write_id (info, "__XRYCPP") + || ! ieee_write_number (info, 0) + || ! ieee_write_number (info, 0) + || ! ieee_write_number (info, info->highaddr)) + return false; + + for (pp = &info->vars; *pp != NULL; pp = &(*pp)->next) + ; + *pp = info->cxx; + + if (! ieee_change_buffer (info, &info->vars) + || ! ieee_write_byte (info, (int) ieee_be_record_enum) + || ! ieee_write_number (info, info->highaddr)) + return false; + } + if (info->vars != NULL) { if (! ieee_change_buffer (info, &info->vars) @@ -4231,8 +4352,8 @@ ieee_enum_type (p, tag, names, vals) } } - if (! ieee_define_named_type (info, tag, true, 0, true, - (struct ieee_buf **) NULL) + if (! ieee_define_named_type (info, tag, true, (unsigned int) -1, 0, + true, (struct ieee_buf **) NULL) || ! ieee_write_number (info, simple ? 'E' : 'N')) return false; if (simple) @@ -4504,6 +4625,26 @@ ieee_volatile_type (p) && ieee_write_number (info, indx)); } +/* Convert an enum debug_visibility into a CXXFLAGS value. */ + +static unsigned int +ieee_vis_to_flags (visibility) + enum debug_visibility visibility; +{ + switch (visibility) + { + default: + abort (); + case DEBUG_VISIBILITY_PUBLIC: + return CXXFLAGS_VISIBILITY_PUBLIC; + case DEBUG_VISIBILITY_PRIVATE: + return CXXFLAGS_VISIBILITY_PRIVATE; + case DEBUG_VISIBILITY_PROTECTED: + return CXXFLAGS_VISIBILITY_PROTECTED; + } + /*NOTREACHED*/ +} + /* Start defining a struct type. We build it in the strdef field on the stack, to avoid confusing type definitions required by the fields with the struct type itself. */ @@ -4520,7 +4661,7 @@ ieee_start_struct_type (p, tag, id, structp, size) struct ieee_buf *strdef; strdef = NULL; - if (! ieee_define_named_type (info, tag, true, size, true, &strdef) + if (! ieee_define_named_type (info, tag, true, id, size, true, &strdef) || ! ieee_write_number (info, structp ? 'S' : 'U') || ! ieee_write_number (info, size)) return false; @@ -4552,6 +4693,26 @@ ieee_struct_field (p, name, bitpos, bitsize, visibility) assert (info->type_stack != NULL && info->type_stack->type.strdef != NULL); + if (info->type_stack->type.classdef != NULL) + { + unsigned int flags; + unsigned int nindx; + + /* This is a class. We must add a description of this field to + the class records we are building. */ + + flags = ieee_vis_to_flags (visibility); + nindx = info->type_stack->type.classdef->indx; + if (! ieee_change_buffer (info, + &info->type_stack->type.classdef->pmiscbuf) + || ! ieee_write_asn (info, nindx, 'd') + || ! ieee_write_asn (info, nindx, flags) + || ! ieee_write_atn65 (info, nindx, name) + || ! ieee_write_atn65 (info, nindx, name)) + return false; + info->type_stack->type.classdef->pmisccount += 4; + } + /* If the bitsize doesn't match the expected size, we need to output a bitfield type. */ if (size == 0 || bitsize == size * 8) @@ -4621,11 +4782,75 @@ ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr) boolean ownvptr; { struct ieee_handle *info = (struct ieee_handle *) p; + const char *vclass; + struct ieee_buf *pmiscbuf; + unsigned int indx; + struct ieee_type_class *classdef; + struct ieee_name_type *nt; - /* FIXME. */ + /* A C++ class is output as a C++ struct along with a set of pmisc + records describing the class. */ + + /* We need to have a name so that we can associate the struct and + the class. */ + if (tag == NULL) + { + char *t; + + t = (char *) xmalloc (20); + sprintf (t, "__anon%u", id); + tag = t; + } + + /* We can't write out the virtual table information until we have + finished the class, because we don't know the virtual table size. + We get the size from the largest voffset we see. */ + vclass = NULL; if (vptr && ! ownvptr) - (void) ieee_pop_type (info); - return ieee_start_struct_type (p, tag, id, structp, size); + { + assert (info->type_stack->type.classdef != NULL); + vclass = info->type_stack->type.classdef->name; + (void) ieee_pop_type (info); + } + + if (! ieee_start_struct_type (p, tag, id, structp, size)) + return false; + + indx = info->name_indx; + ++info->name_indx; + + /* We write out pmisc records into the classdef field. We will + write out the pmisc start after we know the number of records we + need. */ + pmiscbuf = NULL; + if (! ieee_change_buffer (info, &pmiscbuf) + || ! ieee_write_asn (info, indx, 'T') + || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') + || ! ieee_write_atn65 (info, indx, tag)) + return false; + + classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); + memset (classdef, 0, sizeof *classdef); + + classdef->name = tag; + classdef->indx = indx; + classdef->pmiscbuf = pmiscbuf; + classdef->pmisccount = 3; + classdef->vclass = vclass; + classdef->ownvptr = ownvptr; + + info->type_stack->type.classdef = classdef; + + /* We need to fill in the classdef in the tag as well, so that it + will be set when ieee_tag_type is called. */ + for (nt = info->tags; nt != NULL; nt = nt->next) + if (nt->name[0] == tag[0] + && strcmp (nt->name, tag) == 0) + break; + assert (nt != NULL); + nt->type.classdef = classdef; + + return true; } /* Add a static member to a class. */ @@ -4638,9 +4863,30 @@ ieee_class_static_member (p, name, physname, visibility) enum debug_visibility visibility; { struct ieee_handle *info = (struct ieee_handle *) p; + unsigned int flags; + unsigned int nindx; - /* FIXME. */ + /* We don't care about the type. Hopefully there will be a call + ieee_variable declaring the physical name and the type, since + that is where an IEEE consumer must get the type. */ (void) ieee_pop_type (info); + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL); + + flags = ieee_vis_to_flags (visibility); + flags |= CXXFLAGS_STATIC; + + nindx = info->type_stack->type.classdef->indx; + + if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) + || ! ieee_write_asn (info, nindx, 'd') + || ! ieee_write_asn (info, nindx, flags) + || ! ieee_write_atn65 (info, nindx, name) + || ! ieee_write_atn65 (info, nindx, physname)) + return false; + info->type_stack->type.classdef->pmisccount += 4; + return true; } @@ -4654,9 +4900,61 @@ ieee_class_baseclass (p, bitpos, virtual, visibility) enum debug_visibility visibility; { struct ieee_handle *info = (struct ieee_handle *) p; + const char *bname; + unsigned int bindx; + char *fname; + unsigned int flags; + unsigned int nindx; + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL + && info->type_stack->next != NULL + && info->type_stack->next->type.classdef != NULL + && info->type_stack->next->type.strdef != NULL); + + bname = info->type_stack->type.classdef->name; + bindx = ieee_pop_type (info); + + /* We are currently defining both a struct and a class. We must + write out a field definition in the struct which holds the base + class. The stabs debugging reader will create a field named + _vb$CLASS for a virtual base class, so we just use that. FIXME: + we should not depend upon a detail of stabs debugging. */ + if (virtual) + { + fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); + sprintf (fname, "_vb$%s", bname); + flags = BASEFLAGS_VIRTUAL; + } + else + { + fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); + sprintf (fname, "_b$%s", bname); + + if (! ieee_change_buffer (info, &info->type_stack->type.strdef) + || ! ieee_write_id (info, fname) + || ! ieee_write_number (info, bindx) + || ! ieee_write_number (info, bitpos / 8)) + return false; + flags = 0; + } + + if (visibility == DEBUG_VISIBILITY_PRIVATE) + flags |= BASEFLAGS_PRIVATE; + + nindx = info->type_stack->type.classdef->indx; + + if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) + || ! ieee_write_asn (info, nindx, 'b') + || ! ieee_write_asn (info, nindx, flags) + || ! ieee_write_atn65 (info, nindx, bname) + || ! ieee_write_asn (info, nindx, 0) + || ! ieee_write_atn65 (info, nindx, fname)) + return false; + info->type_stack->type.classdef->pmisccount += 5; + + free (fname); - /* FIXME. */ - (void) ieee_pop_type (info); return true; } @@ -4667,7 +4965,90 @@ ieee_class_start_method (p, name) PTR p; const char *name; { - /* FIXME. */ + struct ieee_handle *info = (struct ieee_handle *) p; + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL + && info->type_stack->type.classdef->method == NULL); + + info->type_stack->type.classdef->method = name; + + return true; +} + +/* Define a new method variant, either static or not. */ + +static boolean +ieee_class_method_var (info, physname, visibility, staticp, constp, + volatilep, voffset, context) + struct ieee_handle *info; + const char *physname; + enum debug_visibility visibility; + boolean staticp; + boolean constp; + boolean volatilep; + bfd_vma voffset; + boolean context; +{ + unsigned int flags; + unsigned int nindx; + boolean virtual; + + /* We don't need the type of the method. An IEEE consumer which + wants the type must track down the function by the physical name + and get the type from that. */ + (void) ieee_pop_type (info); + + /* We don't use the context. FIXME: We probably ought to use it to + adjust the voffset somehow, but I don't really know how. */ + if (context) + (void) ieee_pop_type (info); + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL + && info->type_stack->type.classdef->method != NULL); + + flags = ieee_vis_to_flags (visibility); + + /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, + CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ + + if (staticp) + flags |= CXXFLAGS_STATIC; + if (constp) + flags |= CXXFLAGS_CONST; + if (volatilep) + flags |= CXXFLAGS_VOLATILE; + + nindx = info->type_stack->type.classdef->indx; + + virtual = context || voffset > 0; + + if (! ieee_change_buffer (info, + &info->type_stack->type.classdef->pmiscbuf) + || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm') + || ! ieee_write_asn (info, nindx, flags) + || ! ieee_write_atn65 (info, nindx, + info->type_stack->type.classdef->method) + || ! ieee_write_atn65 (info, nindx, physname)) + return false; + + if (virtual) + { + if (voffset > info->type_stack->type.classdef->voffset) + info->type_stack->type.classdef->voffset = voffset; + /* FIXME: The size of a vtable entry depends upon the + architecture. */ + if (! ieee_write_asn (info, nindx, (voffset / 4) + 1)) + return false; + ++info->type_stack->type.classdef->pmisccount; + } + + if (! ieee_write_asn (info, nindx, 0)) + return false; + + info->type_stack->type.classdef->pmisccount += 5; + return true; } @@ -4686,11 +5067,8 @@ ieee_class_method_variant (p, physname, visibility, constp, volatilep, { struct ieee_handle *info = (struct ieee_handle *) p; - /* FIXME. */ - (void) ieee_pop_type (info); - if (context) - (void) ieee_pop_type (info); - return true; + return ieee_class_method_var (info, physname, visibility, false, constp, + volatilep, voffset, context); } /* Define a new static method variant. */ @@ -4705,9 +5083,8 @@ ieee_class_static_method_variant (p, physname, visibility, constp, volatilep) { struct ieee_handle *info = (struct ieee_handle *) p; - /* FIXME. */ - (void) ieee_pop_type (info); - return true; + return ieee_class_method_var (info, physname, visibility, true, constp, + volatilep, 0, false); } /* Finish up a method. */ @@ -4716,7 +5093,14 @@ static boolean ieee_class_end_method (p) PTR p; { - /* FIXME. */ + struct ieee_handle *info = (struct ieee_handle *) p; + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL + && info->type_stack->type.classdef->method != NULL); + + info->type_stack->type.classdef->method = NULL; + return true; } @@ -4726,6 +5110,67 @@ static boolean ieee_end_class_type (p) PTR p; { + struct ieee_handle *info = (struct ieee_handle *) p; + unsigned int nindx; + struct ieee_buf **pb; + + assert (info->type_stack != NULL + && info->type_stack->type.classdef != NULL); + + nindx = info->type_stack->type.classdef->indx; + + /* If we have a virtual table, we can write out the information now. */ + if (info->type_stack->type.classdef->vclass != NULL + || info->type_stack->type.classdef->ownvptr) + { + bfd_vma vsize; + + /* FIXME: This calculation is architecture dependent. */ + vsize = (info->type_stack->type.classdef->voffset + 4) / 4; + + if (! ieee_change_buffer (info, + &info->type_stack->type.classdef->pmiscbuf) + || ! ieee_write_asn (info, nindx, 'z') + || ! ieee_write_atn65 (info, nindx, "") + || ! ieee_write_asn (info, nindx, vsize)) + return false; + if (info->type_stack->type.classdef->ownvptr) + { + if (! ieee_write_atn65 (info, nindx, "")) + return false; + } + else + { + if (! ieee_write_atn65 (info, nindx, + info->type_stack->type.classdef->vclass)) + return false; + } + if (! ieee_write_asn (info, nindx, 0)) + return false; + info->type_stack->type.classdef->pmisccount += 5; + } + + /* Now that we know the number of pmisc records, we can write out + the atn62 which starts the pmisc records, and append them to the + C++ buffers. */ + + if (! ieee_change_buffer (info, &info->cxx) + || ! ieee_write_byte (info, (int) ieee_nn_record) + || ! ieee_write_number (info, nindx) + || ! ieee_write_id (info, "") + || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) + || ! ieee_write_number (info, nindx) + || ! ieee_write_number (info, 0) + || ! ieee_write_number (info, 62) + || ! ieee_write_number (info, 80) + || ! ieee_write_number (info, + info->type_stack->type.classdef->pmisccount)) + return false; + + for (pb = &info->cxx; *pb != NULL; pb = &(*pb)->next) + ; + *pb = info->type_stack->type.classdef->pmiscbuf; + return ieee_end_struct_type (p); } @@ -4767,9 +5212,13 @@ ieee_tag_type (p, name, id, kind) { struct ieee_handle *info = (struct ieee_handle *) p; register struct ieee_name_type *nt; + char ab[20]; if (name == NULL) - return true; + { + sprintf (ab, "__anon%u", id); + name = ab; + } for (nt = info->tags; nt != NULL; nt = nt->next) { @@ -4987,7 +5436,7 @@ ieee_typdef (p, name) } } - if (! ieee_define_named_type (info, name, false, size, unsignedp, + if (! ieee_define_named_type (info, name, false, 0, size, unsignedp, (struct ieee_buf **) NULL) || ! ieee_write_number (info, 'T') || ! ieee_write_number (info, indx)) @@ -5131,9 +5580,7 @@ ieee_variable (p, name, kind, val) if (asn) { - if (! ieee_write_2bytes (info, (int) ieee_asn_record_enum) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_number (info, val)) + if (! ieee_write_asn (info, name_indx, val)) return false; } @@ -5280,7 +5727,7 @@ ieee_start_block (p, addr) { if (! ieee_write_byte (info, (int) ieee_bb_record_enum) || ! ieee_write_byte (info, 6) - || ! ieee_write_byte (info, 0) + || ! ieee_write_number (info, 0) || ! ieee_write_id (info, "") || ! ieee_write_number (info, 0) || ! ieee_write_number (info, 0) @@ -5315,6 +5762,9 @@ ieee_end_block (p, addr) --info->block_depth; + if (addr > info->highaddr) + info->highaddr = addr; + return true; } @@ -5396,7 +5846,5 @@ ieee_lineno (p, filename, lineno, addr) && ieee_write_number (info, 7) && ieee_write_number (info, lineno) && ieee_write_number (info, 0) - && ieee_write_2bytes (info, (int) ieee_asn_record_enum) - && ieee_write_number (info, info->lineno_name_indx) - && ieee_write_number (info, addr)); + && ieee_write_asn (info, info->lineno_name_indx, addr)); }