| 1 | /* stabshll.c -- Convert GNU-style a.out debug information into
 | 
|---|
| 2 |                  IBM OS/2 HLL 3 debug information
 | 
|---|
| 3 |    Copyright (c) 1993-1998 Eberhard Mattes
 | 
|---|
| 4 | 
 | 
|---|
| 5 | This file is part of emxomf.
 | 
|---|
| 6 | 
 | 
|---|
| 7 | emxomf is free software; you can redistribute it and/or modify
 | 
|---|
| 8 | it under the terms of the GNU General Public License as published by
 | 
|---|
| 9 | the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 10 | any later version.
 | 
|---|
| 11 | 
 | 
|---|
| 12 | emxomf is distributed in the hope that it will be useful,
 | 
|---|
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 15 | GNU General Public License for more details.
 | 
|---|
| 16 | 
 | 
|---|
| 17 | You should have received a copy of the GNU General Public License
 | 
|---|
| 18 | along with emxomf; see the file COPYING.  If not, write to
 | 
|---|
| 19 | the Free Software Foundation, 59 Temple Place - Suite 330,
 | 
|---|
| 20 | Boston, MA 02111-1307, USA.  */
 | 
|---|
| 21 | //#define HLL_DEBUG 1
 | 
|---|
| 22 | 
 | 
|---|
| 23 | #define DEMANGLE_PROC_NAMES 1
 | 
|---|
| 24 | 
 | 
|---|
| 25 | /*******************************************************************************
 | 
|---|
| 26 | *   Header Files                                                               *
 | 
|---|
| 27 | *******************************************************************************/
 | 
|---|
| 28 | #include <stdio.h>
 | 
|---|
| 29 | #include <stdlib.h>
 | 
|---|
| 30 | #include <string.h>
 | 
|---|
| 31 | #include <stdarg.h>
 | 
|---|
| 32 | #include <time.h>
 | 
|---|
| 33 | #include <alloca.h>
 | 
|---|
| 34 | #include <ctype.h>
 | 
|---|
| 35 | #ifdef DEMANGLE_PROC_NAMES
 | 
|---|
| 36 | # include <demangle.h>
 | 
|---|
| 37 | #endif
 | 
|---|
| 38 | #include "defs.h"
 | 
|---|
| 39 | #include "emxomf.h"
 | 
|---|
| 40 | #include "grow.h"
 | 
|---|
| 41 | #include "stabshll.h"
 | 
|---|
| 42 | 
 | 
|---|
| 43 | 
 | 
|---|
| 44 | /*******************************************************************************
 | 
|---|
| 45 | *   Defined Constants And Macros                                               *
 | 
|---|
| 46 | *******************************************************************************/
 | 
|---|
| 47 | /* Field ID values for the type table. */
 | 
|---|
| 48 | 
 | 
|---|
| 49 | #define FID_nil         0x80    /* No data */
 | 
|---|
| 50 | #define FID_void        0x81    /* Type void */
 | 
|---|
| 51 | #define FID_string      0x82    /* A length-prefixed string follows */
 | 
|---|
| 52 | #define FID_index       0x83    /* A type index follows */
 | 
|---|
| 53 | #define FID_span_16u    0x85    /* An unsigned 16-bit number follows */
 | 
|---|
| 54 | #define FID_span_32u    0x86    /* An unsigned 32-bit number follows */
 | 
|---|
| 55 | #define FID_span_8s     0x88    /* A signed 8-bit number follows */
 | 
|---|
| 56 | #define FID_span_16s    0x89    /* A signed 16-bit number follows */
 | 
|---|
| 57 | #define FID_span_32s    0x8a    /* A signed 32-bit number follows */
 | 
|---|
| 58 | #define FID_span_8u     0x8b    /* An unsigned 8-bit number follows */
 | 
|---|
| 59 | 
 | 
|---|
| 60 | /* Static scope table subrecord types. */
 | 
|---|
| 61 | 
 | 
|---|
| 62 | #define SST_begin       0x00    /* Begin block */
 | 
|---|
| 63 | #define SST_proc        0x01    /* Procedure */
 | 
|---|
| 64 | #define SST_end         0x02    /* End block or end procedure */
 | 
|---|
| 65 | #define SST_auto        0x04    /* Scoped variable */
 | 
|---|
| 66 | #define SST_static      0x05    /* Static variable */
 | 
|---|
| 67 | #define SST_reg         0x0d    /* Register variable */
 | 
|---|
| 68 | #define SST_changseg    0x11    /* Change default segment */
 | 
|---|
| 69 | #define SST_tag         0x16    /* Structure, union, enum tags */
 | 
|---|
| 70 | #define SST_tag2        0x19    /* Extended tag for long names (C++ class). */
 | 
|---|
| 71 | #define SST_memfunc     0x1a    /* C++ member function */
 | 
|---|
| 72 | #define SST_CPPproc     0x1d    /* C++ function */
 | 
|---|
| 73 | #define SST_CPPstatic   0x1e    /* C++ static variable */
 | 
|---|
| 74 | #define SST_cuinfo      0x40    /* Compile unit information */
 | 
|---|
| 75 | 
 | 
|---|
| 76 | /* Class  visibility. */
 | 
|---|
| 77 | 
 | 
|---|
| 78 | #define VIS_PRIVATE     0x00    /* private */
 | 
|---|
| 79 | #define VIS_PROTECTED   0x01    /* protected */
 | 
|---|
| 80 | #define VIS_PUBLIC      0x02    /* public */
 | 
|---|
| 81 | 
 | 
|---|
| 82 | #define MEMBER_VIS      0x03    /* Member visibility mask */
 | 
|---|
| 83 | #define MEMBER_FUNCTION 0x08    /* It's a member function */
 | 
|---|
| 84 | #define MEMBER_VIRTUAL  0x10    /* Member function / base class is virtual */
 | 
|---|
| 85 | #define MEMBER_VOLATILE 0x20    /* Member function is volatile */
 | 
|---|
| 86 | #define MEMBER_CONST    0x40    /* Member function is const */
 | 
|---|
| 87 | #define MEMBER_STATIC   0x80    /* Member is static */
 | 
|---|
| 88 | #define MEMBER_CTOR     0x100   /* Member function is a constructor */
 | 
|---|
| 89 | #define MEMBER_DTOR     0x200   /* Member function is a destructor */
 | 
|---|
| 90 | #define MEMBER_BASE     0x400   /* It's a base class */
 | 
|---|
| 91 | 
 | 
|---|
| 92 | /* Flags for ty_struc. */
 | 
|---|
| 93 | 
 | 
|---|
| 94 | #define STRUC_FORWARD   0x01    /* Structure declared forward */
 | 
|---|
| 95 | 
 | 
|---|
| 96 | 
 | 
|---|
| 97 | /*******************************************************************************
 | 
|---|
| 98 | *   Structures and Typedefs                                                    *
 | 
|---|
| 99 | *******************************************************************************/
 | 
|---|
| 100 | enum type_tag
 | 
|---|
| 101 | {
 | 
|---|
| 102 |   ty_stabs_ref,                 /* Reference to stabs type */
 | 
|---|
| 103 |   ty_prim,                      /* Primitive type */
 | 
|---|
| 104 |   ty_alias,                     /* Equivalent type */
 | 
|---|
| 105 |   ty_pointer,                   /* Pointer type */
 | 
|---|
| 106 |   ty_func,                      /* Function */
 | 
|---|
| 107 |   ty_args,                      /* Function arguments */
 | 
|---|
| 108 |   ty_struc,                     /* Structure or union */
 | 
|---|
| 109 |   ty_types,                     /* Type list for structure/union */
 | 
|---|
| 110 |   ty_fields,                    /* Field list for structure/union */
 | 
|---|
| 111 |   ty_enu,                       /* Enumeration type */
 | 
|---|
| 112 |   ty_values,                    /* Enumeration values */
 | 
|---|
| 113 |   ty_array,                     /* Array */
 | 
|---|
| 114 |   ty_bits,                      /* Bit field / bit string */
 | 
|---|
| 115 |   ty_ref,                       /* Reference type (C++) */
 | 
|---|
| 116 |   ty_member,                    /* Member of a C++ class */
 | 
|---|
| 117 |   ty_class,                     /* A C++ class */
 | 
|---|
| 118 |   ty_memfunc,                   /* A C++ member function */
 | 
|---|
| 119 |   ty_baseclass,                 /* A C++ base class */
 | 
|---|
| 120 |   ty_max
 | 
|---|
| 121 | };
 | 
|---|
| 122 | 
 | 
|---|
| 123 | /* A structure field. */
 | 
|---|
| 124 | 
 | 
|---|
| 125 | struct field
 | 
|---|
| 126 | {
 | 
|---|
| 127 |   dword offset;                 /* Offset, in bytes */
 | 
|---|
| 128 |   const char *name;             /* Field name */
 | 
|---|
| 129 | };
 | 
|---|
| 130 | 
 | 
|---|
| 131 | /* An enumeration value. */
 | 
|---|
| 132 | 
 | 
|---|
| 133 | struct value
 | 
|---|
| 134 | {
 | 
|---|
| 135 |   long index;                   /* The value */
 | 
|---|
| 136 |   const char *name;             /* The name */
 | 
|---|
| 137 | };
 | 
|---|
| 138 | 
 | 
|---|
| 139 | /* Temporary representation of a structure field. */
 | 
|---|
| 140 | 
 | 
|---|
| 141 | struct tmp_field
 | 
|---|
| 142 | {
 | 
|---|
| 143 |   struct type *type;            /* The internal type */
 | 
|---|
| 144 |   dword offset;                 /* The offset of the field */
 | 
|---|
| 145 |   const char *name;             /* The field name */
 | 
|---|
| 146 |   const char *sname;            /* Static name */
 | 
|---|
| 147 |   const char *mnglname;         /* Mangled name for methods. (#456) */
 | 
|---|
| 148 |   int flags;                    /* Member flags (visibility) */
 | 
|---|
| 149 | };
 | 
|---|
| 150 | 
 | 
|---|
| 151 | 
 | 
|---|
| 152 | /* Internal representation of a type. */
 | 
|---|
| 153 | 
 | 
|---|
| 154 | struct type
 | 
|---|
| 155 | {
 | 
|---|
| 156 |   enum type_tag tag;            /* The type of this type */
 | 
|---|
| 157 |   int index;                    /* The HLL index for this type */
 | 
|---|
| 158 |   struct type *next;            /* All types are chained in a single list */
 | 
|---|
| 159 |   struct type *nexthash;        /* All types are chained in the hash list */
 | 
|---|
| 160 |   union
 | 
|---|
| 161 |     {
 | 
|---|
| 162 |       int stabs_ref;            /* Reference a stabs type */
 | 
|---|
| 163 |       struct type *pointer;     /* Pointer to another type */
 | 
|---|
| 164 |       struct type *alias;       /* Alias for another type */
 | 
|---|
| 165 |       struct type *ref;         /* Reference to another type */
 | 
|---|
| 166 |       struct
 | 
|---|
| 167 |         {                       /* Structure */
 | 
|---|
| 168 |           struct type *types;   /* Types of the fields */
 | 
|---|
| 169 |           struct type *fields;  /* Field names and offsets */
 | 
|---|
| 170 |           dword size;           /* Size of the structure, in bytes */
 | 
|---|
| 171 |           word count;           /* Number of fields */
 | 
|---|
| 172 |           word flags;           /* Flags (STRUC_FORWARD) */
 | 
|---|
| 173 |           const char *name;     /* Name of the structure */
 | 
|---|
| 174 |         } struc;
 | 
|---|
| 175 |       struct
 | 
|---|
| 176 |         {                       /* Class */
 | 
|---|
| 177 |           struct type *members; /* Members */
 | 
|---|
| 178 |           dword size;           /* Size of the class, in bytes */
 | 
|---|
| 179 |           word count;           /* Number of fields */
 | 
|---|
| 180 |           const char *name;     /* Name of the class */
 | 
|---|
| 181 |         } class;
 | 
|---|
| 182 |       struct
 | 
|---|
| 183 |         {                       /* Enumeration */
 | 
|---|
| 184 |           struct type *type;    /* Base type */
 | 
|---|
| 185 |           struct type *values;  /* Values */
 | 
|---|
| 186 |           long first;           /* Smallest value */
 | 
|---|
| 187 |           long last;            /* Biggest value */
 | 
|---|
| 188 |           const char *name;     /* Name of the enum */
 | 
|---|
| 189 |         } enu;
 | 
|---|
| 190 |       struct
 | 
|---|
| 191 |         {                       /* Array */
 | 
|---|
| 192 |           struct type *itype;   /* Index type */
 | 
|---|
| 193 |           struct type *etype;   /* Element type */
 | 
|---|
| 194 |           long first;           /* First index */
 | 
|---|
| 195 |           long last;            /* Last index */
 | 
|---|
| 196 |         } array;
 | 
|---|
| 197 |       struct
 | 
|---|
| 198 |         {                       /* Bitfield */
 | 
|---|
| 199 |           struct type *type;    /* Base type */
 | 
|---|
| 200 |           long start;           /* First bit */
 | 
|---|
| 201 |           long count;           /* Number of bits */
 | 
|---|
| 202 |         } bits;
 | 
|---|
| 203 |       struct
 | 
|---|
| 204 |         {                       /* Function */
 | 
|---|
| 205 |           struct type *ret;     /* Return type */
 | 
|---|
| 206 |           struct type *args;    /* Argument types */
 | 
|---|
| 207 |           struct type *domain;  /* Domain type (C++ member) (#456) */
 | 
|---|
| 208 |           int arg_count;        /* Number of arguments */
 | 
|---|
| 209 |         } func;
 | 
|---|
| 210 |       struct
 | 
|---|
| 211 |         {                       /* Function arguments */
 | 
|---|
| 212 |           struct type **list;   /* Array of argument types */
 | 
|---|
| 213 |           int count;            /* Number of arguments */
 | 
|---|
| 214 |         } args;
 | 
|---|
| 215 |       struct
 | 
|---|
| 216 |         {                       /* List of types */
 | 
|---|
| 217 |           struct type **list;   /* Array of types */
 | 
|---|
| 218 |           int count;            /* Number of types */
 | 
|---|
| 219 |         } types;
 | 
|---|
| 220 |       struct
 | 
|---|
| 221 |         {                       /* Structure fields */
 | 
|---|
| 222 |           struct field *list;   /* The fields */
 | 
|---|
| 223 |           int count;            /* Number of fields */
 | 
|---|
| 224 |         } fields;
 | 
|---|
| 225 |       struct
 | 
|---|
| 226 |         {                       /* Class member */
 | 
|---|
| 227 |           struct type *type;    /* Type of the member */
 | 
|---|
| 228 |           dword offset;         /* Offset of the member, in bytes */
 | 
|---|
| 229 |           int flags;            /* Member flags (visibility etc.) */
 | 
|---|
| 230 |           const char *name;     /* Name of the member */
 | 
|---|
| 231 |           const char *sname;    /* Static name */
 | 
|---|
| 232 |         } member;
 | 
|---|
| 233 |       struct
 | 
|---|
| 234 |         {                       /* Enumeration values */
 | 
|---|
| 235 |           struct value *list;   /* Array of values */
 | 
|---|
| 236 |           int count;            /* Number of values */
 | 
|---|
| 237 |         } values;
 | 
|---|
| 238 |       struct
 | 
|---|
| 239 |         {                       /* Member function */
 | 
|---|
| 240 |           struct type *type;    /* Function type */
 | 
|---|
| 241 |           dword offset;         /* Offset in the virtual table */
 | 
|---|
| 242 |           int flags;            /* Member flags (visibility etc.) */
 | 
|---|
| 243 |           const char *name;     /* Name of the member function */
 | 
|---|
| 244 |           const char *mnglname; /* Mangled Name of the member function. (#456) */
 | 
|---|
| 245 |         } memfunc;
 | 
|---|
| 246 |       struct
 | 
|---|
| 247 |         {                       /* Base class */
 | 
|---|
| 248 |           struct type *type;    /* The base class */
 | 
|---|
| 249 |           dword offset;         /* Offset of the base class */
 | 
|---|
| 250 |           int flags;            /* Visibility, virtual */
 | 
|---|
| 251 |         } baseclass;
 | 
|---|
| 252 |     } d;
 | 
|---|
| 253 | };
 | 
|---|
| 254 | 
 | 
|---|
| 255 | 
 | 
|---|
| 256 | /* A block. */
 | 
|---|
| 257 | 
 | 
|---|
| 258 | struct block
 | 
|---|
| 259 | {
 | 
|---|
| 260 |   dword addr;                   /* Start address of the block */
 | 
|---|
| 261 |   size_t patch_ptr;             /* Index into SST buffer for patching */
 | 
|---|
| 262 | };
 | 
|---|
| 263 | 
 | 
|---|
| 264 | /* Timestamp for the compiler unit information SST subrecord. */
 | 
|---|
| 265 | 
 | 
|---|
| 266 | #pragma pack(1)
 | 
|---|
| 267 | 
 | 
|---|
| 268 | struct timestamp
 | 
|---|
| 269 | {
 | 
|---|
| 270 |   byte hours;
 | 
|---|
| 271 |   byte minutes;
 | 
|---|
| 272 |   byte seconds;
 | 
|---|
| 273 |   byte hundredths;
 | 
|---|
| 274 |   byte day;
 | 
|---|
| 275 |   byte month;
 | 
|---|
| 276 |   word year;
 | 
|---|
| 277 | };
 | 
|---|
| 278 | 
 | 
|---|
| 279 | #pragma pack()
 | 
|---|
| 280 | 
 | 
|---|
| 281 | 
 | 
|---|
| 282 | /*******************************************************************************
 | 
|---|
| 283 | *   Global Variables                                                           *
 | 
|---|
| 284 | *******************************************************************************/
 | 
|---|
| 285 | /* This variable points to the next character of a stabs type being
 | 
|---|
| 286 |    parsed. */
 | 
|---|
| 287 | 
 | 
|---|
| 288 | static const char *parse_ptr;
 | 
|---|
| 289 | 
 | 
|---|
| 290 | /* Start of the stabs string we're parsing. Useful when printing
 | 
|---|
| 291 |    messages. */
 | 
|---|
| 292 | static const char *parse_start;
 | 
|---|
| 293 | 
 | 
|---|
| 294 | /* Current stabs index. Useful when printing messages. */
 | 
|---|
| 295 | static int        *parse_pindex;
 | 
|---|
| 296 | 
 | 
|---|
| 297 | /* The next HLL type index.  When creating a complex type, this index
 | 
|---|
| 298 |    is used.  Then, this variable is incremented. */
 | 
|---|
| 299 | 
 | 
|---|
| 300 | static int hll_type_index;
 | 
|---|
| 301 | 
 | 
|---|
| 302 | /* We keep all internal types in a single list.  When creating a new
 | 
|---|
| 303 |    type, we first look through the list to find out whether an
 | 
|---|
| 304 |    identical type already exists.  Doing a linear search is
 | 
|---|
| 305 |    inefficient, but that doesn't matter here, according to
 | 
|---|
| 306 |    experience.  This variable points to the first type of the list. */
 | 
|---|
| 307 | 
 | 
|---|
| 308 | static struct type *type_head;
 | 
|---|
| 309 | #define TYPE_HASH_MAX   211
 | 
|---|
| 310 | static struct type *atype_tag[TYPE_HASH_MAX];
 | 
|---|
| 311 | #ifdef HASH_DEBUG
 | 
|---|
| 312 | static int          ctypes = 0;
 | 
|---|
| 313 | static int          ctype_tag[TYPE_HASH_MAX];
 | 
|---|
| 314 | #endif
 | 
|---|
| 315 | 
 | 
|---|
| 316 | /* This growing array keeps track of stabs vs. internal types.  It is
 | 
|---|
| 317 |    indexed by stabs type numbers. */
 | 
|---|
| 318 | 
 | 
|---|
| 319 | static struct type **stype_list;
 | 
|---|
| 320 | static struct grow stype_grow;
 | 
|---|
| 321 | 
 | 
|---|
| 322 | /* We collect function arguments in this growing array. */
 | 
|---|
| 323 | 
 | 
|---|
| 324 | static struct type **args_list;
 | 
|---|
| 325 | static struct grow args_grow;
 | 
|---|
| 326 | 
 | 
|---|
| 327 | /* This stack (implemented with a growing array) keeps track of
 | 
|---|
| 328 |    begin/end block nesting. */
 | 
|---|
| 329 | 
 | 
|---|
| 330 | static struct block *block_stack;
 | 
|---|
| 331 | static struct grow block_grow;
 | 
|---|
| 332 | 
 | 
|---|
| 333 | /* This string pool contains field names etc. */
 | 
|---|
| 334 | 
 | 
|---|
| 335 | static struct strpool *str_pool;
 | 
|---|
| 336 | 
 | 
|---|
| 337 | /* This variable holds the sym_ptr index of the most recently
 | 
|---|
| 338 |    encountered N_LBRAC symbol. */
 | 
|---|
| 339 | 
 | 
|---|
| 340 | static int lbrac_index;
 | 
|---|
| 341 | 
 | 
|---|
| 342 | /* The index (in sst) of the most recently started SST subrecord. */
 | 
|---|
| 343 | 
 | 
|---|
| 344 | static size_t subrec_start;
 | 
|---|
| 345 | 
 | 
|---|
| 346 | /* The proc_patch_base contains the index where the base address and
 | 
|---|
| 347 |    function length are to be patched into the SST. */
 | 
|---|
| 348 | 
 | 
|---|
| 349 | static size_t proc_patch_base;
 | 
|---|
| 350 | 
 | 
|---|
| 351 | /* The base address used by the most recently proc record in the
 | 
|---|
| 352 |    SST. */
 | 
|---|
| 353 | 
 | 
|---|
| 354 | static size_t proc_start_addr;
 | 
|---|
| 355 | 
 | 
|---|
| 356 | /* The internal type of the most recently defined function.  Valid
 | 
|---|
| 357 |    only if last_fun_valid is TRUE. */
 | 
|---|
| 358 | 
 | 
|---|
| 359 | static struct type last_fun_type;
 | 
|---|
| 360 | 
 | 
|---|
| 361 | /* This variable is TRUE if a function has recently been defined. */
 | 
|---|
| 362 | 
 | 
|---|
| 363 | static int last_fun_valid;
 | 
|---|
| 364 | 
 | 
|---|
| 365 | /* The length of the prologue of the most recently defined
 | 
|---|
| 366 |    function. */
 | 
|---|
| 367 | 
 | 
|---|
| 368 | static int prologue_length;
 | 
|---|
| 369 | 
 | 
|---|
| 370 | /* The address of the most recently defined function. */
 | 
|---|
| 371 | 
 | 
|---|
| 372 | static dword last_fun_addr;
 | 
|---|
| 373 | 
 | 
|---|
| 374 | /* This variable is non-zero when converting a translated C++
 | 
|---|
| 375 |    program. */
 | 
|---|
| 376 | 
 | 
|---|
| 377 | static int cplusplus_flag;
 | 
|---|
| 378 | 
 | 
|---|
| 379 | /* Unnamed structures are numbered sequentially, using this
 | 
|---|
| 380 |    counter. */
 | 
|---|
| 381 | 
 | 
|---|
| 382 | static int unnamed_struct_number;
 | 
|---|
| 383 | 
 | 
|---|
| 384 | /* kso #456 2003-06-11: Reversed quiet workaround. */
 | 
|---|
| 385 | #define no_warning warning_parse
 | 
|---|
| 386 | 
 | 
|---|
| 387 | 
 | 
|---|
| 388 | /*******************************************************************************
 | 
|---|
| 389 | *   Internal Functions                                                         *
 | 
|---|
| 390 | *******************************************************************************/
 | 
|---|
| 391 | static void parse_typedef (int *index);
 | 
|---|
| 392 | static void warning_parse (const char *pszFormat, ...);
 | 
|---|
| 393 | 
 | 
|---|
| 394 | 
 | 
|---|
| 395 | /**
 | 
|---|
| 396 |  * Report an warning in which might be connecting to parsing.
 | 
|---|
| 397 |  *
 | 
|---|
| 398 |  * @param   pszFormat   Message string.
 | 
|---|
| 399 |  * @param   ...         More arguments
 | 
|---|
| 400 |  */
 | 
|---|
| 401 | static void warning_parse (const char *pszFormat, ...)
 | 
|---|
| 402 | {
 | 
|---|
| 403 |   va_list args;
 | 
|---|
| 404 | 
 | 
|---|
| 405 |   if (warning_level < 2)
 | 
|---|
| 406 |     {
 | 
|---|
| 407 |       static const char *s_pszComplainedFor = NULL;
 | 
|---|
| 408 |       if (warning_level == 1 && s_pszComplainedFor == error_fname)
 | 
|---|
| 409 |         {
 | 
|---|
| 410 |           s_pszComplainedFor = error_fname;
 | 
|---|
| 411 |           fprintf (stderr, "emxomf warning: debug info conversion issues for '%s'. (-v for details.)\n", error_fname);
 | 
|---|
| 412 |         }
 | 
|---|
| 413 |     }
 | 
|---|
| 414 |   else
 | 
|---|
| 415 |     {
 | 
|---|
| 416 |       va_start(args, pszFormat);
 | 
|---|
| 417 |       fprintf (stderr, "emxomf warning: ");
 | 
|---|
| 418 |       vfprintf (stderr, pszFormat, args);
 | 
|---|
| 419 |       va_end (args);
 | 
|---|
| 420 |       fputc ('\n', stderr);
 | 
|---|
| 421 | 
 | 
|---|
| 422 |       if (parse_ptr && parse_start && parse_ptr >= parse_start)
 | 
|---|
| 423 |         {
 | 
|---|
| 424 |           if (parse_pindex && *parse_pindex >= 0 && *parse_pindex < sym_count)
 | 
|---|
| 425 |             fprintf (stderr, "emxomf info: parsing sym no.%d type=%d at char '%c' in position %d:\n%s\n",
 | 
|---|
| 426 |                      *parse_pindex, sym_ptr[*parse_pindex].n_type,
 | 
|---|
| 427 |                      *parse_ptr, parse_ptr - parse_start, parse_start);
 | 
|---|
| 428 |           else
 | 
|---|
| 429 |             fprintf (stderr, "emxomf info: parsing '%c' at position %d:\n%s\n",
 | 
|---|
| 430 |                      *parse_ptr, parse_ptr - parse_start, parse_start);
 | 
|---|
| 431 |         }
 | 
|---|
| 432 |     }
 | 
|---|
| 433 | }
 | 
|---|
| 434 | 
 | 
|---|
| 435 | 
 | 
|---|
| 436 | /* Start a type table record of type TYPE, with type qualifier QUAL.
 | 
|---|
| 437 |    tt_end() must be called to finish the record after writing the
 | 
|---|
| 438 |    record contents. */
 | 
|---|
| 439 | 
 | 
|---|
| 440 | static void tt_start (byte type, byte qual)
 | 
|---|
| 441 | {
 | 
|---|
| 442 |   subrec_start = tt.size;
 | 
|---|
| 443 |   grow_by (&tt_boundary_grow, 1);
 | 
|---|
| 444 |   tt_boundary[tt_boundary_grow.count++] = tt.size;
 | 
|---|
| 445 |   buffer_word (&tt, 0);    /* Length of sub-record */
 | 
|---|
| 446 |   buffer_byte (&tt, type); /* Type of sub-record */
 | 
|---|
| 447 |   buffer_byte (&tt, qual); /* Type qualifier */
 | 
|---|
| 448 | }
 | 
|---|
| 449 | 
 | 
|---|
| 450 | 
 | 
|---|
| 451 | /* Finish a type table record.  This function must be called after
 | 
|---|
| 452 |    tt_start(). */
 | 
|---|
| 453 | 
 | 
|---|
| 454 | static void tt_end (void)
 | 
|---|
| 455 | {
 | 
|---|
| 456 |   *(word *)(tt.buf + subrec_start) = tt.size - subrec_start - 2;
 | 
|---|
| 457 | }
 | 
|---|
| 458 | 
 | 
|---|
| 459 | 
 | 
|---|
| 460 | /* Put the type index TI into the type table.  TI = -1 encodes the
 | 
|---|
| 461 |    `nil' type (no type), 0x97 encodes the `void' type.  All other
 | 
|---|
| 462 |    values are type indices. */
 | 
|---|
| 463 | 
 | 
|---|
| 464 | static void tt_index (int ti)
 | 
|---|
| 465 | {
 | 
|---|
| 466 |   if (ti == -1)                 /* nil */
 | 
|---|
| 467 |     buffer_byte (&tt, FID_nil);
 | 
|---|
| 468 |   else if (ti == 0x97)          /* void */
 | 
|---|
| 469 |     buffer_byte (&tt, FID_void);
 | 
|---|
| 470 |   else
 | 
|---|
| 471 |     {
 | 
|---|
| 472 |       buffer_byte (&tt, FID_index);
 | 
|---|
| 473 |       buffer_word (&tt, ti);
 | 
|---|
| 474 |     }
 | 
|---|
| 475 | }
 | 
|---|
| 476 | 
 | 
|---|
| 477 | 
 | 
|---|
| 478 | /* Put an 8-bit byte into the type table. */
 | 
|---|
| 479 | 
 | 
|---|
| 480 | static void tt_byte (byte x)
 | 
|---|
| 481 | {
 | 
|---|
| 482 |   buffer_byte (&tt, x);
 | 
|---|
| 483 | }
 | 
|---|
| 484 | 
 | 
|---|
| 485 | 
 | 
|---|
| 486 | /* Put a 16-bit word into the type table. */
 | 
|---|
| 487 | 
 | 
|---|
| 488 | static void tt_word (word x)
 | 
|---|
| 489 | {
 | 
|---|
| 490 |   buffer_word (&tt, x);
 | 
|---|
| 491 | }
 | 
|---|
| 492 | 
 | 
|---|
| 493 | 
 | 
|---|
| 494 | /* Put a 32-bit double word into the type table. */
 | 
|---|
| 495 | 
 | 
|---|
| 496 | static void tt_dword (dword x)
 | 
|---|
| 497 | {
 | 
|---|
| 498 |   buffer_dword (&tt, x);
 | 
|---|
| 499 | }
 | 
|---|
| 500 | 
 | 
|---|
| 501 | 
 | 
|---|
| 502 | /* Put the name S into the type table. */
 | 
|---|
| 503 | 
 | 
|---|
| 504 | static void tt_name (const char *s)
 | 
|---|
| 505 | {
 | 
|---|
| 506 |   buffer_byte (&tt, FID_string);
 | 
|---|
| 507 |   buffer_nstr (&tt, s);
 | 
|---|
| 508 | }
 | 
|---|
| 509 | 
 | 
|---|
| 510 | 
 | 
|---|
| 511 | /* Put the mangled name S into the type table. */
 | 
|---|
| 512 | 
 | 
|---|
| 513 | static void tt_enc (const char *s)
 | 
|---|
| 514 | {
 | 
|---|
| 515 |   buffer_enc (&tt, s);
 | 
|---|
| 516 | }
 | 
|---|
| 517 | 
 | 
|---|
| 518 | 
 | 
|---|
| 519 | /* Put the unsigned number N into the type table.  Depending on the
 | 
|---|
| 520 |    magnitude of N, different encodings are used. */
 | 
|---|
| 521 | 
 | 
|---|
| 522 | static void tt_unsigned_span (dword n)
 | 
|---|
| 523 | {
 | 
|---|
| 524 |   if (n <= 0xff)
 | 
|---|
| 525 |     {
 | 
|---|
| 526 |       buffer_byte (&tt, FID_span_8u);
 | 
|---|
| 527 |       buffer_byte (&tt, n);
 | 
|---|
| 528 |     }
 | 
|---|
| 529 |   else if (n <= 0xffff)
 | 
|---|
| 530 |     {
 | 
|---|
| 531 |       buffer_byte (&tt, FID_span_16u);
 | 
|---|
| 532 |       buffer_word (&tt, n);
 | 
|---|
| 533 |     }
 | 
|---|
| 534 |   else
 | 
|---|
| 535 |     {
 | 
|---|
| 536 |       buffer_byte (&tt, FID_span_32u);
 | 
|---|
| 537 |       buffer_dword (&tt, n);
 | 
|---|
| 538 |     }
 | 
|---|
| 539 | }
 | 
|---|
| 540 | 
 | 
|---|
| 541 | 
 | 
|---|
| 542 | /* Put the signed number N into the type table.  Depending on the
 | 
|---|
| 543 |    magnitude of N, different encodings are used. */
 | 
|---|
| 544 | 
 | 
|---|
| 545 | static void tt_signed_span (long n)
 | 
|---|
| 546 | {
 | 
|---|
| 547 |   if (-127 <= n && n <= 127)
 | 
|---|
| 548 |     {
 | 
|---|
| 549 |       buffer_byte (&tt, FID_span_8s);
 | 
|---|
| 550 |       buffer_byte (&tt, n);
 | 
|---|
| 551 |     }
 | 
|---|
| 552 |   else if (-32767 <= n && n <= 32767)
 | 
|---|
| 553 |     {
 | 
|---|
| 554 |       buffer_byte (&tt, FID_span_16s);
 | 
|---|
| 555 |       buffer_word (&tt, n);
 | 
|---|
| 556 |     }
 | 
|---|
| 557 |   else
 | 
|---|
| 558 |     {
 | 
|---|
| 559 |       buffer_byte (&tt, FID_span_32s);
 | 
|---|
| 560 |       buffer_dword (&tt, n);
 | 
|---|
| 561 |     }
 | 
|---|
| 562 | }
 | 
|---|
| 563 | 
 | 
|---|
| 564 | 
 | 
|---|
| 565 | /* Start a static scope table subrecord of type TYPE.  sst_end() must
 | 
|---|
| 566 |    be called to finish the subrecord after writing the subrecord
 | 
|---|
| 567 |    data. */
 | 
|---|
| 568 | 
 | 
|---|
| 569 | static void sst_start (byte type)
 | 
|---|
| 570 | {
 | 
|---|
| 571 |   subrec_start = sst.size;
 | 
|---|
| 572 |   grow_by (&sst_boundary_grow, 1);
 | 
|---|
| 573 |   sst_boundary[sst_boundary_grow.count++] = sst.size;
 | 
|---|
| 574 |   /* Length of sub-record - bird: not sure if HL03 likes this. */
 | 
|---|
| 575 |   buffer_byte (&sst, 0x80);
 | 
|---|
| 576 |   buffer_byte (&sst, 0);
 | 
|---|
| 577 |   /* Type of sub-record */
 | 
|---|
| 578 |   buffer_byte (&sst, type);
 | 
|---|
| 579 | }
 | 
|---|
| 580 | 
 | 
|---|
| 581 | 
 | 
|---|
| 582 | /* Finish a static scope table subrecord.  This function must be
 | 
|---|
| 583 |    called after sst_start(). */
 | 
|---|
| 584 | 
 | 
|---|
| 585 | static void sst_end (void)
 | 
|---|
| 586 | {
 | 
|---|
| 587 |   int len = sst.size - subrec_start - 2;
 | 
|---|
| 588 |   /* -- experimental...
 | 
|---|
| 589 |   if (len > 1000)
 | 
|---|
| 590 |     error ("sst_end: Record too big");
 | 
|---|
| 591 |   */
 | 
|---|
| 592 |   sst.buf[subrec_start] = (len >> 8) | 0x80;
 | 
|---|
| 593 |   sst.buf[subrec_start + 1] = 0xff & len;
 | 
|---|
| 594 | }
 | 
|---|
| 595 | 
 | 
|---|
| 596 | 
 | 
|---|
| 597 | /* Define a static variable in the static scope table.  NAME is the
 | 
|---|
| 598 |    name of the variable, ADDR is the address of the variable (segment
 | 
|---|
| 599 |    offset), TYPE_INDEX is the HLL type index.  If EXT is zero, SYM_SEG
 | 
|---|
| 600 |    is the segment (N_DATA, for instance).  If EXT is non-zero, SYM_SEG
 | 
|---|
| 601 |    is the stabs symbol index (for the relocation table).  This
 | 
|---|
| 602 |    function also creates appropriate relocation table entries. */
 | 
|---|
| 603 | 
 | 
|---|
| 604 | static void sst_static (const char *name, dword addr, int type_index,
 | 
|---|
| 605 |                         int sym_seg, int ext, const struct nlist *psym)
 | 
|---|
| 606 | {
 | 
|---|
| 607 |   struct relocation_info r;
 | 
|---|
| 608 |   size_t len = strlen (name);
 | 
|---|
| 609 | 
 | 
|---|
| 610 |   if (!psym)
 | 
|---|
| 611 |     {
 | 
|---|
| 612 |       psym = find_symbol_ex (name, -1, ext);
 | 
|---|
| 613 |       if (!psym)
 | 
|---|
| 614 |         {
 | 
|---|
| 615 |           char *psz = alloca (len + 2);
 | 
|---|
| 616 |           *psz = '_';
 | 
|---|
| 617 |           memcpy(psz + 1, name, len + 1);
 | 
|---|
| 618 |           psym = find_symbol_ex (psz, -1, ext);
 | 
|---|
| 619 |         }
 | 
|---|
| 620 |     }
 | 
|---|
| 621 |   if (psym)
 | 
|---|
| 622 |     set_hll_type (psym - sym_ptr, type_index);
 | 
|---|
| 623 | 
 | 
|---|
| 624 |   if (len > 255)
 | 
|---|
| 625 |     sst_start (SST_CPPstatic);
 | 
|---|
| 626 |   else
 | 
|---|
| 627 |     sst_start (SST_static);
 | 
|---|
| 628 |   r.r_address = sst.size;
 | 
|---|
| 629 |   buffer_dword (&sst, addr);      /* Segment offset */
 | 
|---|
| 630 |   buffer_word (&sst, 0);          /* Segment address */
 | 
|---|
| 631 |   buffer_word (&sst, type_index); /* Type index */
 | 
|---|
| 632 |   if (len > 255)
 | 
|---|
| 633 |     buffer_enc (&sst, name);      /* Symbol name - encoded. */
 | 
|---|
| 634 |   else
 | 
|---|
| 635 |     buffer_nstr (&sst, name);     /* Symbol name */
 | 
|---|
| 636 |   sst_end ();
 | 
|---|
| 637 |   r.r_extern = ext;
 | 
|---|
| 638 |   r.r_length = 2;
 | 
|---|
| 639 |   r.r_symbolnum = sym_seg;
 | 
|---|
| 640 |   r.r_pcrel = 0;
 | 
|---|
| 641 |   r.r_pad = 0;
 | 
|---|
| 642 |   buffer_mem (&sst_reloc, &r, sizeof (r));
 | 
|---|
| 643 |   r.r_address += 4;
 | 
|---|
| 644 |   r.r_length = 1;
 | 
|---|
| 645 |   buffer_mem (&sst_reloc, &r, sizeof (r));
 | 
|---|
| 646 | }
 | 
|---|
| 647 | 
 | 
|---|
| 648 | /**
 | 
|---|
| 649 |  * Try calculate a good hash (yeah sure).
 | 
|---|
| 650 |  *
 | 
|---|
| 651 |  * @returns hash index.
 | 
|---|
| 652 |  * @param   t     type
 | 
|---|
| 653 |  */
 | 
|---|
| 654 | static inline unsigned type_hash (struct type *t)
 | 
|---|
| 655 | {
 | 
|---|
| 656 |   register unsigned uhash = 0;
 | 
|---|
| 657 |   switch (t->tag)
 | 
|---|
| 658 |     {
 | 
|---|
| 659 |       case ty_alias:        uhash = (unsigned)t->d.alias; break;
 | 
|---|
| 660 |       case ty_stabs_ref:    uhash = (unsigned)t->d.stabs_ref; break;
 | 
|---|
| 661 |       case ty_prim:         uhash = (unsigned)t->index; break;
 | 
|---|
| 662 |       case ty_pointer:      uhash = (unsigned)t->d.pointer; break;
 | 
|---|
| 663 |       case ty_ref:          uhash = (unsigned)t->d.ref; break;
 | 
|---|
| 664 |       case ty_struc:        uhash = (unsigned)t->d.struc.name; break;
 | 
|---|
| 665 |       case ty_class:        uhash = (unsigned)t->d.class.name; break;
 | 
|---|
| 666 |       case ty_enu:          uhash = (unsigned)t->d.enu.name; break;
 | 
|---|
| 667 |       case ty_array:        uhash = (unsigned)t->d.array.etype; break;
 | 
|---|
| 668 |       case ty_bits:         uhash = (unsigned)t->d.bits.type; break;
 | 
|---|
| 669 |       case ty_func:         uhash = (unsigned)t->d.func.args ^ (unsigned)t->d.func.arg_count ^ (unsigned)t->d.func.ret ^ (unsigned)t->d.func.domain; break;
 | 
|---|
| 670 |       case ty_types:        uhash = (unsigned)t->d.types.count  << 3; break;
 | 
|---|
| 671 |       case ty_args:         uhash = (unsigned)t->d.args.count   << 3; break;
 | 
|---|
| 672 |       case ty_fields:       uhash = (unsigned)t->d.fields.count << 3; break;
 | 
|---|
| 673 |       case ty_member:       uhash = (unsigned)t->d.member.type ^ (unsigned)t->d.member.name >> 7; break;
 | 
|---|
| 674 |       case ty_values:       uhash = (unsigned)t->d.values.count << 3; break;
 | 
|---|
| 675 |       case ty_memfunc:      uhash = (unsigned)t->d.memfunc.type; break;
 | 
|---|
| 676 |       case ty_baseclass:    uhash = (unsigned)t->d.baseclass.type; break;
 | 
|---|
| 677 |       default:break; /* shut up warnings. */
 | 
|---|
| 678 |     }
 | 
|---|
| 679 |   uhash += t->tag;
 | 
|---|
| 680 |   return (uhash ^ uhash >> 13) % TYPE_HASH_MAX;
 | 
|---|
| 681 | }
 | 
|---|
| 682 | 
 | 
|---|
| 683 | 
 | 
|---|
| 684 | /**
 | 
|---|
| 685 |  * Search a list for a type.
 | 
|---|
| 686 |  * @returns pointer to the type we found.
 | 
|---|
| 687 |  * @returns NULL if not found.
 | 
|---|
| 688 |  * @param   p       Pointer to the head list.
 | 
|---|
| 689 |  * @param   src     Type to find.
 | 
|---|
| 690 |  * @param   fhash   Whether or not to follow the hash list or the main list.
 | 
|---|
| 691 |  */
 | 
|---|
| 692 | #ifdef HASH_DEBUG
 | 
|---|
| 693 | static struct type *type_find (struct type *p, const struct type *src, int fhash)
 | 
|---|
| 694 | #else
 | 
|---|
| 695 | static struct type *type_find (struct type *p, const struct type *src)
 | 
|---|
| 696 | #endif
 | 
|---|
| 697 | {
 | 
|---|
| 698 |   int i;
 | 
|---|
| 699 |   for (; p != NULL;
 | 
|---|
| 700 | #ifdef HASH_DEBUG
 | 
|---|
| 701 |        p = fhash ? p->nexthash : p->next )
 | 
|---|
| 702 | #else
 | 
|---|
| 703 |        p = p->nexthash                   )
 | 
|---|
| 704 | #endif
 | 
|---|
| 705 |     if (p->tag == src->tag)
 | 
|---|
| 706 |       switch (p->tag)
 | 
|---|
| 707 |         {
 | 
|---|
| 708 |         case ty_alias:
 | 
|---|
| 709 |           if (p->d.alias == src->d.alias)
 | 
|---|
| 710 |             return p;
 | 
|---|
| 711 |           break;
 | 
|---|
| 712 |         case ty_stabs_ref:
 | 
|---|
| 713 |           if (p->d.stabs_ref == src->d.stabs_ref)
 | 
|---|
| 714 |             return p;
 | 
|---|
| 715 |           break;
 | 
|---|
| 716 |         case ty_prim:
 | 
|---|
| 717 |           if (p->index == src->index)
 | 
|---|
| 718 |             return p;
 | 
|---|
| 719 |           break;
 | 
|---|
| 720 |         case ty_pointer:
 | 
|---|
| 721 |           if (p->d.pointer == src->d.pointer)
 | 
|---|
| 722 |             return p;
 | 
|---|
| 723 |           break;
 | 
|---|
| 724 |         case ty_ref:
 | 
|---|
| 725 |           if (p->d.ref == src->d.ref)
 | 
|---|
| 726 |             return p;
 | 
|---|
| 727 |           break;
 | 
|---|
| 728 |         case ty_struc:
 | 
|---|
| 729 |           if (p->d.struc.fields == src->d.struc.fields
 | 
|---|
| 730 |               && p->d.struc.types == src->d.struc.types
 | 
|---|
| 731 |               && p->d.struc.name == src->d.struc.name
 | 
|---|
| 732 |               && p->d.struc.flags == src->d.struc.flags)
 | 
|---|
| 733 |             return p;
 | 
|---|
| 734 |           break;
 | 
|---|
| 735 |         case ty_class:
 | 
|---|
| 736 |           if (p->d.class.members == src->d.class.members
 | 
|---|
| 737 |               && p->d.class.name == src->d.class.name)
 | 
|---|
| 738 |             return p;
 | 
|---|
| 739 |           break;
 | 
|---|
| 740 |         case ty_enu:
 | 
|---|
| 741 |           if (p->d.enu.type == src->d.enu.type
 | 
|---|
| 742 |               && p->d.enu.values == src->d.enu.values
 | 
|---|
| 743 |               && p->d.enu.name == src->d.enu.name)
 | 
|---|
| 744 |             return p;
 | 
|---|
| 745 |           break;
 | 
|---|
| 746 |         case ty_array:
 | 
|---|
| 747 |           if (p->d.array.etype == src->d.array.etype
 | 
|---|
| 748 |               && p->d.array.itype == src->d.array.itype
 | 
|---|
| 749 |               && p->d.array.first == src->d.array.first
 | 
|---|
| 750 |               && p->d.array.last == src->d.array.last)
 | 
|---|
| 751 |             return p;
 | 
|---|
| 752 |           break;
 | 
|---|
| 753 |         case ty_bits:
 | 
|---|
| 754 |           if (p->d.bits.type == src->d.bits.type
 | 
|---|
| 755 |               && p->d.bits.start == src->d.bits.start
 | 
|---|
| 756 |               && p->d.bits.count == src->d.bits.count)
 | 
|---|
| 757 |             return p;
 | 
|---|
| 758 |           break;
 | 
|---|
| 759 |         case ty_func:
 | 
|---|
| 760 |           if (p->d.func.ret == src->d.func.ret
 | 
|---|
| 761 |               && p->d.func.args == src->d.func.args
 | 
|---|
| 762 |               && p->d.func.domain == src->d.func.domain
 | 
|---|
| 763 |               && p->d.func.arg_count == src->d.func.arg_count)
 | 
|---|
| 764 |             return p;
 | 
|---|
| 765 |           break;
 | 
|---|
| 766 |         case ty_args:
 | 
|---|
| 767 |           if (p->d.args.count == src->d.args.count)
 | 
|---|
| 768 |             {
 | 
|---|
| 769 |               for (i = 0; i < p->d.args.count; ++i)
 | 
|---|
| 770 |                 if (p->d.args.list[i] != src->d.args.list[i])
 | 
|---|
| 771 |                   break;
 | 
|---|
| 772 |               if (i >= p->d.args.count)
 | 
|---|
| 773 |                 return p;
 | 
|---|
| 774 |             }
 | 
|---|
| 775 |           break;
 | 
|---|
| 776 |         case ty_types:
 | 
|---|
| 777 |           if (p->d.types.count == src->d.types.count)
 | 
|---|
| 778 |             {
 | 
|---|
| 779 |               for (i = 0; i < p->d.types.count; ++i)
 | 
|---|
| 780 |                 if (p->d.types.list[i] != src->d.types.list[i])
 | 
|---|
| 781 |                   break;
 | 
|---|
| 782 |               if (i >= p->d.types.count)
 | 
|---|
| 783 |                 return p;
 | 
|---|
| 784 |             }
 | 
|---|
| 785 |           break;
 | 
|---|
| 786 |         case ty_fields:
 | 
|---|
| 787 |           if (p->d.fields.count == src->d.fields.count)
 | 
|---|
| 788 |             {
 | 
|---|
| 789 |               for (i = 0; i < p->d.fields.count; ++i)
 | 
|---|
| 790 |                 if (p->d.fields.list[i].offset != src->d.fields.list[i].offset
 | 
|---|
| 791 |                     || p->d.fields.list[i].name != src->d.fields.list[i].name)
 | 
|---|
| 792 |                   break;
 | 
|---|
| 793 |               if (i >= p->d.fields.count)
 | 
|---|
| 794 |                 return p;
 | 
|---|
| 795 |             }
 | 
|---|
| 796 |           break;
 | 
|---|
| 797 |         case ty_member:
 | 
|---|
| 798 |           if (p->d.member.type == src->d.member.type
 | 
|---|
| 799 |               && p->d.member.offset == src->d.member.offset
 | 
|---|
| 800 |               && p->d.member.flags == src->d.member.flags
 | 
|---|
| 801 |               && p->d.member.name == src->d.member.name
 | 
|---|
| 802 |               && p->d.member.sname == src->d.member.sname)
 | 
|---|
| 803 |             return p;
 | 
|---|
| 804 |           break;
 | 
|---|
| 805 |         case ty_values:
 | 
|---|
| 806 |           if (p->d.values.count == src->d.values.count)
 | 
|---|
| 807 |             {
 | 
|---|
| 808 |               for (i = 0; i < p->d.values.count; ++i)
 | 
|---|
| 809 |                 if (p->d.values.list[i].index != src->d.values.list[i].index
 | 
|---|
| 810 |                     || p->d.values.list[i].name != src->d.values.list[i].name)
 | 
|---|
| 811 |                   break;
 | 
|---|
| 812 |               if (i >= p->d.values.count)
 | 
|---|
| 813 |                 return p;
 | 
|---|
| 814 |             }
 | 
|---|
| 815 |           break;
 | 
|---|
| 816 |         case ty_memfunc:
 | 
|---|
| 817 |           if (p->d.memfunc.type == src->d.memfunc.type
 | 
|---|
| 818 |               && p->d.memfunc.offset == src->d.memfunc.offset
 | 
|---|
| 819 |               && p->d.memfunc.flags == src->d.memfunc.flags
 | 
|---|
| 820 |               && p->d.memfunc.name == src->d.memfunc.name
 | 
|---|
| 821 |               && p->d.memfunc.mnglname == src->d.memfunc.mnglname)
 | 
|---|
| 822 |             return p;
 | 
|---|
| 823 |           break;
 | 
|---|
| 824 |         case ty_baseclass:
 | 
|---|
| 825 |           if (p->d.baseclass.type == src->d.baseclass.type
 | 
|---|
| 826 |               && p->d.baseclass.offset == src->d.baseclass.offset
 | 
|---|
| 827 |               && p->d.baseclass.flags == src->d.baseclass.flags)
 | 
|---|
| 828 |             return p;
 | 
|---|
| 829 |           break;
 | 
|---|
| 830 |         default:
 | 
|---|
| 831 |           abort ();
 | 
|---|
| 832 |         }
 | 
|---|
| 833 |   return NULL;
 | 
|---|
| 834 | }
 | 
|---|
| 835 | 
 | 
|---|
| 836 | 
 | 
|---|
| 837 | /* Add a new internal type to the list of internal types.  If an
 | 
|---|
| 838 |    identical type already exists, a pointer to that type is returned.
 | 
|---|
| 839 |    Otherwise, a copy of the new type is added to the list and a
 | 
|---|
| 840 |    pointer to that type is returned.  It isn't worth my while to
 | 
|---|
| 841 |    improve the speed of this function, for instance by using
 | 
|---|
| 842 |    hashing.
 | 
|---|
| 843 | 
 | 
|---|
| 844 |    Actually it is worth while optimizing it as it takes 85% of the
 | 
|---|
| 845 |    time here... or rather it was.
 | 
|---|
| 846 | 
 | 
|---|
| 847 |    ctypes=25301 */
 | 
|---|
| 848 | 
 | 
|---|
| 849 | static struct type *type_add (struct type *src)
 | 
|---|
| 850 | {
 | 
|---|
| 851 |   struct type *p;
 | 
|---|
| 852 |   unsigned ihash;
 | 
|---|
| 853 |   int i;
 | 
|---|
| 854 | 
 | 
|---|
| 855 |   ihash = type_hash(src);
 | 
|---|
| 856 | #ifdef HASH_DEBUG
 | 
|---|
| 857 |   p = type_find (atype_tag[ihash], src, 1);
 | 
|---|
| 858 | #else
 | 
|---|
| 859 |   p = type_find (atype_tag[ihash], src);
 | 
|---|
| 860 | #endif
 | 
|---|
| 861 |   if (p)
 | 
|---|
| 862 |     {
 | 
|---|
| 863 |       return p;
 | 
|---|
| 864 |     }
 | 
|---|
| 865 | 
 | 
|---|
| 866 | #ifdef HASH_DEBUG
 | 
|---|
| 867 | /*  {
 | 
|---|
| 868 |     struct type *pcheck = type_find (type_head, src, 0);
 | 
|---|
| 869 |     if (pcheck)
 | 
|---|
| 870 |       {
 | 
|---|
| 871 |         printf("\n\thash algorithm is borked! tag=%d\n", pcheck->tag);
 | 
|---|
| 872 |         return pcheck;
 | 
|---|
| 873 |       }
 | 
|---|
| 874 |   } */
 | 
|---|
| 875 |   ctype_tag[ihash]++;
 | 
|---|
| 876 |   ctypes++;
 | 
|---|
| 877 | #endif
 | 
|---|
| 878 | 
 | 
|---|
| 879 |   p = xmalloc (sizeof (*p));
 | 
|---|
| 880 |   *p = *src;
 | 
|---|
| 881 |   p->next = type_head;
 | 
|---|
| 882 |   type_head = p;
 | 
|---|
| 883 |   p->nexthash = atype_tag[ihash];
 | 
|---|
| 884 |   atype_tag[ihash] = p;
 | 
|---|
| 885 |   switch (src->tag)
 | 
|---|
| 886 |     {
 | 
|---|
| 887 |     case ty_args:
 | 
|---|
| 888 |       i = src->d.args.count * sizeof (*(src->d.args.list));
 | 
|---|
| 889 |       p->d.args.list = xmalloc (i);
 | 
|---|
| 890 |       memcpy (p->d.args.list, src->d.args.list, i);
 | 
|---|
| 891 |       break;
 | 
|---|
| 892 |     case ty_types:
 | 
|---|
| 893 |       i = src->d.types.count * sizeof (*(src->d.types.list));
 | 
|---|
| 894 |       p->d.types.list = xmalloc (i);
 | 
|---|
| 895 |       memcpy (p->d.types.list, src->d.types.list, i);
 | 
|---|
| 896 |       break;
 | 
|---|
| 897 |     case ty_fields:
 | 
|---|
| 898 |       i = src->d.fields.count * sizeof (*(src->d.fields.list));
 | 
|---|
| 899 |       p->d.fields.list = xmalloc (i);
 | 
|---|
| 900 |       memcpy (p->d.fields.list, src->d.fields.list, i);
 | 
|---|
| 901 |       break;
 | 
|---|
| 902 |     case ty_values:
 | 
|---|
| 903 |       i = src->d.values.count * sizeof (*(src->d.values.list));
 | 
|---|
| 904 |       p->d.values.list = xmalloc (i);
 | 
|---|
| 905 |       memcpy (p->d.values.list, src->d.values.list, i);
 | 
|---|
| 906 |       break;
 | 
|---|
| 907 |     default:
 | 
|---|
| 908 |       break;
 | 
|---|
| 909 |     }
 | 
|---|
| 910 |   return p;
 | 
|---|
| 911 | }
 | 
|---|
| 912 | 
 | 
|---|
| 913 | 
 | 
|---|
| 914 | /* Associate the stabs type number NUMBER with the internal type
 | 
|---|
| 915 |    HLL. */
 | 
|---|
| 916 | 
 | 
|---|
| 917 | static void stype_add (int number, struct type *hll)
 | 
|---|
| 918 | {
 | 
|---|
| 919 |   int i;
 | 
|---|
| 920 | 
 | 
|---|
| 921 |   /* Stabs type numbers are greater than zero. */
 | 
|---|
| 922 | 
 | 
|---|
| 923 |   if (number < 1)
 | 
|---|
| 924 |     error ("stype_add: Invalid type index %d", number);
 | 
|---|
| 925 | 
 | 
|---|
| 926 |   /* Remember the current size of the table and grow the table as
 | 
|---|
| 927 |      required. */
 | 
|---|
| 928 | 
 | 
|---|
| 929 |   i = stype_grow.alloc;
 | 
|---|
| 930 |   grow_to (&stype_grow, number);
 | 
|---|
| 931 | 
 | 
|---|
| 932 |   /* Initialize the new table entries. */
 | 
|---|
| 933 | 
 | 
|---|
| 934 |   while (i < stype_grow.alloc)
 | 
|---|
| 935 |     stype_list[i++] = NULL;
 | 
|---|
| 936 | 
 | 
|---|
| 937 |   /* Put the type into the table. */
 | 
|---|
| 938 | 
 | 
|---|
| 939 | #ifdef HLL_DEBUG
 | 
|---|
| 940 |   printf ("  type: stabs %d => HLL 0x%x\n", number, hll->index);
 | 
|---|
| 941 | #endif
 | 
|---|
| 942 | #if 0 /* not good test... as we do some types twice. */
 | 
|---|
| 943 |   if (stype_list[number-1] != NULL && stype_list[number-1] != hll)
 | 
|---|
| 944 |     warning ("Type stabs %d allready mapped to HLL 0x%x, new HLL 0x%x!!\n", number, stype_list[number-1]->index, hll->index);
 | 
|---|
| 945 | #endif
 | 
|---|
| 946 | 
 | 
|---|
| 947 |   stype_list[number-1] = hll;
 | 
|---|
| 948 | }
 | 
|---|
| 949 | 
 | 
|---|
| 950 | 
 | 
|---|
| 951 | /* Find the internal type associated with the stabs type number
 | 
|---|
| 952 |    NUMBER.  If there is no such type, return NULL. */
 | 
|---|
| 953 | 
 | 
|---|
| 954 | static struct type *stype_find (int number)
 | 
|---|
| 955 | {
 | 
|---|
| 956 |   /* Stabs type numbers are greater than zero. */
 | 
|---|
| 957 | 
 | 
|---|
| 958 |   if (number < 1)
 | 
|---|
| 959 |     error ("stype_find: Invalid type index %d", number);
 | 
|---|
| 960 | 
 | 
|---|
| 961 |   /* Adjust the index and check if it is within the current size of
 | 
|---|
| 962 |      the table. */
 | 
|---|
| 963 | 
 | 
|---|
| 964 |   --number;
 | 
|---|
| 965 |   if (number >= stype_grow.alloc)
 | 
|---|
| 966 |     return NULL;
 | 
|---|
| 967 |   else
 | 
|---|
| 968 |     return stype_list[number];
 | 
|---|
| 969 | }
 | 
|---|
| 970 | 
 | 
|---|
| 971 | 
 | 
|---|
| 972 | /* Dereference stabs references until finding a non-reference. */
 | 
|---|
| 973 | 
 | 
|---|
| 974 | static const struct type *follow_refs (const struct type *t)
 | 
|---|
| 975 | {
 | 
|---|
| 976 |   const struct type *t2;
 | 
|---|
| 977 | 
 | 
|---|
| 978 |   while (t->tag == ty_stabs_ref)
 | 
|---|
| 979 |     {
 | 
|---|
| 980 |       t2 = stype_find (t->d.stabs_ref);
 | 
|---|
| 981 |       if (t2 == NULL)
 | 
|---|
| 982 |         break;
 | 
|---|
| 983 |       t = t2;
 | 
|---|
| 984 |     }
 | 
|---|
| 985 | 
 | 
|---|
| 986 |   return t;
 | 
|---|
| 987 | }
 | 
|---|
| 988 | 
 | 
|---|
| 989 | 
 | 
|---|
| 990 | #if defined (HLL_DEBUG)
 | 
|---|
| 991 | 
 | 
|---|
| 992 | /* This function is used to print an internal type for debugging. */
 | 
|---|
| 993 | 
 | 
|---|
| 994 | static void show_type (struct type *tp)
 | 
|---|
| 995 | {
 | 
|---|
| 996 |   /* precaution so we don't iterate for ever here when showing classes. */
 | 
|---|
| 997 |   static int    fShowClass;
 | 
|---|
| 998 |   int i;
 | 
|---|
| 999 | 
 | 
|---|
| 1000 |   /* Currently we crash when showing FILE (stdio.h). So, better not crash here..  */
 | 
|---|
| 1001 |   if (!tp)
 | 
|---|
| 1002 |     {
 | 
|---|
| 1003 |     printf("!!! error! NULL type pointer! !!!");
 | 
|---|
| 1004 |     return;
 | 
|---|
| 1005 |     }
 | 
|---|
| 1006 | 
 | 
|---|
| 1007 |   switch (tp->tag)
 | 
|---|
| 1008 |     {
 | 
|---|
| 1009 |     case ty_prim:
 | 
|---|
| 1010 |       printf ("%#x", tp->index);
 | 
|---|
| 1011 |       break;
 | 
|---|
| 1012 |     case ty_stabs_ref:
 | 
|---|
| 1013 |       printf ("t%d", tp->d.stabs_ref);
 | 
|---|
| 1014 |       break;
 | 
|---|
| 1015 |     case ty_alias:
 | 
|---|
| 1016 |       show_type (tp->d.alias);
 | 
|---|
| 1017 |       break;
 | 
|---|
| 1018 |     case ty_pointer:
 | 
|---|
| 1019 |       printf ("(");
 | 
|---|
| 1020 |       show_type (tp->d.pointer);
 | 
|---|
| 1021 |       printf (")*");
 | 
|---|
| 1022 |       break;
 | 
|---|
| 1023 |     case ty_ref:
 | 
|---|
| 1024 |       printf ("(");
 | 
|---|
| 1025 |       show_type (tp->d.ref);
 | 
|---|
| 1026 |       printf (")&");
 | 
|---|
| 1027 |       break;
 | 
|---|
| 1028 |     case ty_struc:
 | 
|---|
| 1029 |       printf ("{");
 | 
|---|
| 1030 |       show_type (tp->d.struc.types);
 | 
|---|
| 1031 |       printf ("}");
 | 
|---|
| 1032 |       break;
 | 
|---|
| 1033 |     case ty_class:
 | 
|---|
| 1034 |       printf ("{");
 | 
|---|
| 1035 |       if (!fShowClass)
 | 
|---|
| 1036 |         {
 | 
|---|
| 1037 |           fShowClass = 1;
 | 
|---|
| 1038 |           show_type (tp->d.class.members);
 | 
|---|
| 1039 |           fShowClass = 0;
 | 
|---|
| 1040 |         }
 | 
|---|
| 1041 |       else
 | 
|---|
| 1042 |         printf ("<-!-!->");
 | 
|---|
| 1043 |       printf ("}");
 | 
|---|
| 1044 |       break;
 | 
|---|
| 1045 |     case ty_enu:
 | 
|---|
| 1046 |       printf ("{");
 | 
|---|
| 1047 |       show_type (tp->d.enu.values);
 | 
|---|
| 1048 |       printf ("}");
 | 
|---|
| 1049 |       break;
 | 
|---|
| 1050 |     case ty_array:
 | 
|---|
| 1051 |       printf ("(");
 | 
|---|
| 1052 |       show_type (tp->d.array.etype);
 | 
|---|
| 1053 |       printf ("[%ld]", tp->d.array.last + 1 - tp->d.array.first);
 | 
|---|
| 1054 |       break;
 | 
|---|
| 1055 |     case ty_bits:
 | 
|---|
| 1056 |       show_type (tp->d.bits.type);
 | 
|---|
| 1057 |       printf (":%ld:%ld", tp->d.bits.start, tp->d.bits.count);
 | 
|---|
| 1058 |       break;
 | 
|---|
| 1059 |     case ty_func:
 | 
|---|
| 1060 |       show_type (tp->d.func.ret);
 | 
|---|
| 1061 |       printf ("(");
 | 
|---|
| 1062 |       if (tp->d.func.args != NULL)
 | 
|---|
| 1063 |         show_type (tp->d.func.args);
 | 
|---|
| 1064 |       printf (")");
 | 
|---|
| 1065 |       break;
 | 
|---|
| 1066 |     case ty_args:
 | 
|---|
| 1067 |       for (i = 0; i < tp->d.args.count; ++i)
 | 
|---|
| 1068 |         {
 | 
|---|
| 1069 |           if (i != 0)
 | 
|---|
| 1070 |             printf (", ");
 | 
|---|
| 1071 |           show_type (tp->d.args.list[i]);
 | 
|---|
| 1072 |         }
 | 
|---|
| 1073 |       break;
 | 
|---|
| 1074 |     case ty_types:
 | 
|---|
| 1075 |       for (i = 0; i < tp->d.types.count; ++i)
 | 
|---|
| 1076 |         {
 | 
|---|
| 1077 |           if (i != 0)
 | 
|---|
| 1078 |             printf (", ");
 | 
|---|
| 1079 |           show_type (tp->d.types.list[i]);
 | 
|---|
| 1080 |         }
 | 
|---|
| 1081 |       break;
 | 
|---|
| 1082 |     case ty_fields:
 | 
|---|
| 1083 |       for (i = 0; i < tp->d.fields.count; ++i)
 | 
|---|
| 1084 |         {
 | 
|---|
| 1085 |           if (i != 0)
 | 
|---|
| 1086 |             printf (", ");
 | 
|---|
| 1087 |           printf ("%s", tp->d.fields.list[i].name);
 | 
|---|
| 1088 |         }
 | 
|---|
| 1089 |       break;
 | 
|---|
| 1090 |     case ty_member:
 | 
|---|
| 1091 |       printf ("%s", tp->d.member.name);
 | 
|---|
| 1092 |       break;
 | 
|---|
| 1093 |     case ty_values:
 | 
|---|
| 1094 |       for (i = 0; i < tp->d.values.count; ++i)
 | 
|---|
| 1095 |         {
 | 
|---|
| 1096 |           if (i != 0)
 | 
|---|
| 1097 |             printf (", ");
 | 
|---|
| 1098 |           printf ("%s", tp->d.values.list[i].name);
 | 
|---|
| 1099 |         }
 | 
|---|
| 1100 |       break;
 | 
|---|
| 1101 |     case ty_memfunc:
 | 
|---|
| 1102 |       show_type (tp->d.memfunc.type);
 | 
|---|
| 1103 |       break;
 | 
|---|
| 1104 |     case ty_baseclass:
 | 
|---|
| 1105 |       printf ("{");
 | 
|---|
| 1106 |       show_type (tp->d.baseclass.type);
 | 
|---|
| 1107 |       printf ("}");
 | 
|---|
| 1108 |       break;
 | 
|---|
| 1109 |     default:
 | 
|---|
| 1110 |       error ("show_type: Unknown type: %d", tp->tag);
 | 
|---|
| 1111 |     }
 | 
|---|
| 1112 | }
 | 
|---|
| 1113 | 
 | 
|---|
| 1114 | #endif
 | 
|---|
| 1115 | 
 | 
|---|
| 1116 | 
 | 
|---|
| 1117 | /**
 | 
|---|
| 1118 |  * Tries to complete a struct forward reference.
 | 
|---|
| 1119 |  *
 | 
|---|
| 1120 |  * @returns 0 on success
 | 
|---|
| 1121 |  * @returns 1 on failure.
 | 
|---|
| 1122 |  * @param   tp  Pointer to the struct/class to complete.
 | 
|---|
| 1123 |  * @remark  Nasy hack for strstreambuf.
 | 
|---|
| 1124 |  */
 | 
|---|
| 1125 | static int try_complete_struct(const struct type *tp)
 | 
|---|
| 1126 | {
 | 
|---|
| 1127 |     int         cch;
 | 
|---|
| 1128 |     const char *pszName;
 | 
|---|
| 1129 |     int         i;
 | 
|---|
| 1130 | 
 | 
|---|
| 1131 |     if (tp->tag == ty_struc)
 | 
|---|
| 1132 |         return 0;
 | 
|---|
| 1133 |     if (tp->d.struc.flags != STRUC_FORWARD)
 | 
|---|
| 1134 |         return 1;
 | 
|---|
| 1135 | 
 | 
|---|
| 1136 |     pszName = tp->d.struc.name;
 | 
|---|
| 1137 |     cch = strlen(pszName);
 | 
|---|
| 1138 |     for (i = 0; i < sym_count; ++i)
 | 
|---|
| 1139 |         switch (sym_ptr[i].n_type)
 | 
|---|
| 1140 |         {
 | 
|---|
| 1141 |             case N_LSYM:
 | 
|---|
| 1142 |             case N_LCSYM:
 | 
|---|
| 1143 |             case N_GSYM:
 | 
|---|
| 1144 |             case N_PSYM:
 | 
|---|
| 1145 |             case N_RSYM:
 | 
|---|
| 1146 |             case N_STSYM:
 | 
|---|
| 1147 |             case N_FUN:
 | 
|---|
| 1148 |                 if (    !memcmp(str_ptr + sym_ptr[i].n_un.n_strx, pszName, cch)
 | 
|---|
| 1149 |                     &&  *(char*)(str_ptr + sym_ptr[i].n_un.n_strx + cch) == ':'
 | 
|---|
| 1150 |                     )
 | 
|---|
| 1151 |                 {
 | 
|---|
| 1152 |                     parse_typedef(&i);
 | 
|---|
| 1153 |                     return 1;
 | 
|---|
| 1154 |                 } /* if */
 | 
|---|
| 1155 |         } /* switch */
 | 
|---|
| 1156 | 
 | 
|---|
| 1157 |     return 0;
 | 
|---|
| 1158 | }
 | 
|---|
| 1159 | 
 | 
|---|
| 1160 | 
 | 
|---|
| 1161 | 
 | 
|---|
| 1162 | /* Return the size of the internal type TP, in bytes. */
 | 
|---|
| 1163 | 
 | 
|---|
| 1164 | static dword type_size (const struct type *tp)
 | 
|---|
| 1165 | {
 | 
|---|
| 1166 |   switch (tp->tag)
 | 
|---|
| 1167 |     {
 | 
|---|
| 1168 |     case ty_prim:
 | 
|---|
| 1169 | 
 | 
|---|
| 1170 |       /* Primitive types. */
 | 
|---|
| 1171 | 
 | 
|---|
| 1172 |       if (tp->index >= 0xa0 && tp->index <= 0xbf)
 | 
|---|
| 1173 |         return 4;               /* Near pointer */
 | 
|---|
| 1174 |       switch (tp->index)
 | 
|---|
| 1175 |         {
 | 
|---|
| 1176 |         case 0x97:              /* void */
 | 
|---|
| 1177 |           return 0;
 | 
|---|
| 1178 |         case 0x80:              /* 8 bit signed */
 | 
|---|
| 1179 |         case 0x84:              /* 8 bit unsigned */
 | 
|---|
| 1180 |         case 0x90:              /* 8 bit boolean */
 | 
|---|
| 1181 |           return 1;
 | 
|---|
| 1182 |         case 0x81:              /* 16 bit signed */
 | 
|---|
| 1183 |         case 0x85:              /* 16 bit unsigned */
 | 
|---|
| 1184 |           return 2;
 | 
|---|
| 1185 |         case 0x82:              /* 32 bit signed */
 | 
|---|
| 1186 |         case 0x86:              /* 32 bit unsigned */
 | 
|---|
| 1187 |         case 0x88:              /* 32 bit real */
 | 
|---|
| 1188 |           return 4;
 | 
|---|
| 1189 |         case 0x89:              /* 64 bit real */
 | 
|---|
| 1190 |         case 0x8c:              /* 64 bit complex */
 | 
|---|
| 1191 |           return 8;
 | 
|---|
| 1192 |         case 0x8a:              /* 80 bit real (96 bits of storage) */
 | 
|---|
| 1193 |           return 12;
 | 
|---|
| 1194 |         case 0x8d:              /* 128 bit complex */
 | 
|---|
| 1195 |           return 16;
 | 
|---|
| 1196 |         case 0x8e:              /* 160 bit complex */
 | 
|---|
| 1197 |           return 24;
 | 
|---|
| 1198 |         case 0x8f:              /* 256 bit complex (birds invention) */
 | 
|---|
| 1199 |           return 32;
 | 
|---|
| 1200 |         }
 | 
|---|
| 1201 |       error ("type_size: Unknown primitive type: %d", tp->index);
 | 
|---|
| 1202 | 
 | 
|---|
| 1203 |     case ty_stabs_ref:
 | 
|---|
| 1204 | 
 | 
|---|
| 1205 |       #if 0
 | 
|---|
| 1206 |       /* This should not happen. */
 | 
|---|
| 1207 | 
 | 
|---|
| 1208 |       no_warning ("stabs type %d not defined", tp->d.stabs_ref);
 | 
|---|
| 1209 | 
 | 
|---|
| 1210 |       return 4;
 | 
|---|
| 1211 |       #else
 | 
|---|
| 1212 |       /* This seems to happen although it shouldn't... Try do something at least. */
 | 
|---|
| 1213 | 
 | 
|---|
| 1214 |       tp = follow_refs (tp);
 | 
|---|
| 1215 |       if (!tp || tp->tag == ty_stabs_ref)
 | 
|---|
| 1216 |         {
 | 
|---|
| 1217 |           no_warning ("stabs type %d not defined", tp->d.stabs_ref);
 | 
|---|
| 1218 |           return 4;
 | 
|---|
| 1219 |         }
 | 
|---|
| 1220 |       return type_size (tp);
 | 
|---|
| 1221 |       #endif
 | 
|---|
| 1222 | 
 | 
|---|
| 1223 |     case ty_alias:
 | 
|---|
| 1224 | 
 | 
|---|
| 1225 |       /* An alias.  Return the size of the referenced type. */
 | 
|---|
| 1226 | 
 | 
|---|
| 1227 |       return type_size (tp->d.alias);
 | 
|---|
| 1228 | 
 | 
|---|
| 1229 |     case ty_pointer:
 | 
|---|
| 1230 |     case ty_ref:
 | 
|---|
| 1231 | 
 | 
|---|
| 1232 |       /* Pointers and references are 32-bit values. */
 | 
|---|
| 1233 | 
 | 
|---|
| 1234 |       return 4;
 | 
|---|
| 1235 | 
 | 
|---|
| 1236 |     case ty_struc:
 | 
|---|
| 1237 | 
 | 
|---|
| 1238 |       /* The size of a structure is stored in the type structure. */
 | 
|---|
| 1239 | 
 | 
|---|
| 1240 |       if (   tp->d.struc.flags & STRUC_FORWARD
 | 
|---|
| 1241 |           && try_complete_struct(tp))
 | 
|---|
| 1242 |         {
 | 
|---|
| 1243 |           no_warning ("size of incomplete structure %s is unknown (off %ld)\n stabs: %s",
 | 
|---|
| 1244 |                       tp->d.struc.name, parse_ptr - parse_start, parse_start);
 | 
|---|
| 1245 |           return 0;
 | 
|---|
| 1246 |         }
 | 
|---|
| 1247 |       return tp->d.struc.size;
 | 
|---|
| 1248 | 
 | 
|---|
| 1249 |     case ty_class:
 | 
|---|
| 1250 | 
 | 
|---|
| 1251 |       /* The size of a class is stored in the type structure. */
 | 
|---|
| 1252 | 
 | 
|---|
| 1253 |       return tp->d.class.size;
 | 
|---|
| 1254 | 
 | 
|---|
| 1255 |     case ty_enu:
 | 
|---|
| 1256 | 
 | 
|---|
| 1257 |       /* Return the size of the base type for an enumeration type. */
 | 
|---|
| 1258 | 
 | 
|---|
| 1259 |       return type_size (tp->d.enu.type);
 | 
|---|
| 1260 | 
 | 
|---|
| 1261 |     case ty_array:
 | 
|---|
| 1262 | 
 | 
|---|
| 1263 |       /* Multiply the element size with the number of array elements
 | 
|---|
| 1264 |          for arrays. */
 | 
|---|
| 1265 | 
 | 
|---|
| 1266 |       return ((tp->d.array.last + 1 - tp->d.array.first) *
 | 
|---|
| 1267 |               type_size (tp->d.array.etype));
 | 
|---|
| 1268 | 
 | 
|---|
| 1269 |     case ty_bits:
 | 
|---|
| 1270 | 
 | 
|---|
| 1271 |       /* Use the size of the base type for bitfields. */
 | 
|---|
| 1272 | 
 | 
|---|
| 1273 |       return type_size (tp->d.bits.type);
 | 
|---|
| 1274 | 
 | 
|---|
| 1275 |     case ty_member:
 | 
|---|
| 1276 | 
 | 
|---|
| 1277 |       /* Use the size of the member's type for members. */
 | 
|---|
| 1278 | 
 | 
|---|
| 1279 |       return type_size (tp->d.member.type);
 | 
|---|
| 1280 | 
 | 
|---|
| 1281 |     case ty_baseclass:
 | 
|---|
| 1282 | 
 | 
|---|
| 1283 |       /* The size of a base class is the size of the base class :-) */
 | 
|---|
| 1284 | 
 | 
|---|
| 1285 |       return type_size (tp->d.baseclass.type);
 | 
|---|
| 1286 | 
 | 
|---|
| 1287 |     case ty_func:
 | 
|---|
| 1288 |     case ty_args:
 | 
|---|
| 1289 |     case ty_types:
 | 
|---|
| 1290 |     case ty_fields:
 | 
|---|
| 1291 |     case ty_values:
 | 
|---|
| 1292 |     case ty_memfunc:
 | 
|---|
| 1293 | 
 | 
|---|
| 1294 |       /* This cannot not happen. */
 | 
|---|
| 1295 | 
 | 
|---|
| 1296 |       error ("type_size: cannot compute size for tag %d", tp->tag);
 | 
|---|
| 1297 | 
 | 
|---|
| 1298 |     default:
 | 
|---|
| 1299 | 
 | 
|---|
| 1300 |       /* This cannot happen. */
 | 
|---|
| 1301 | 
 | 
|---|
| 1302 |       error ("type_size: unknown type: %d", tp->tag);
 | 
|---|
| 1303 |     }
 | 
|---|
| 1304 | }
 | 
|---|
| 1305 | 
 | 
|---|
| 1306 | 
 | 
|---|
| 1307 | /* Turn a struct into a class.  This needs to be done when a struct is
 | 
|---|
| 1308 |    referenced as base class (unfortunately, a simple class looks like
 | 
|---|
| 1309 |    a struct). */
 | 
|---|
| 1310 | 
 | 
|---|
| 1311 | static void struct_to_class (struct type *tp)
 | 
|---|
| 1312 | {
 | 
|---|
| 1313 |   struct type t, *t1, **list, **types;
 | 
|---|
| 1314 |   struct field *fields;
 | 
|---|
| 1315 |   int i, n;
 | 
|---|
| 1316 | 
 | 
|---|
| 1317 |   if (tp->index != -1)
 | 
|---|
| 1318 |     {
 | 
|---|
| 1319 |       warning ("Base class cannot be converted from struct");
 | 
|---|
| 1320 |       return;
 | 
|---|
| 1321 |     }
 | 
|---|
| 1322 |   n = tp->d.struc.count;
 | 
|---|
| 1323 |   if (n == 0)
 | 
|---|
| 1324 |     list = NULL;
 | 
|---|
| 1325 |   else
 | 
|---|
| 1326 |     {
 | 
|---|
| 1327 |       if (tp->d.struc.fields->tag != ty_fields
 | 
|---|
| 1328 |           || tp->d.struc.fields->d.fields.count != n)
 | 
|---|
| 1329 |         {
 | 
|---|
| 1330 |           warning ("Invalid struct field list");
 | 
|---|
| 1331 |           return;
 | 
|---|
| 1332 |         }
 | 
|---|
| 1333 |       fields = tp->d.struc.fields->d.fields.list;
 | 
|---|
| 1334 |       if (tp->d.struc.types->tag != ty_types
 | 
|---|
| 1335 |           || tp->d.struc.types->d.types.count != n)
 | 
|---|
| 1336 |         {
 | 
|---|
| 1337 |           warning ("Invalid struct types list");
 | 
|---|
| 1338 |           return;
 | 
|---|
| 1339 |         }
 | 
|---|
| 1340 |       types = tp->d.struc.types->d.types.list;
 | 
|---|
| 1341 |       list = xmalloc (n * sizeof (*list));
 | 
|---|
| 1342 |       for (i = 0; i < n; ++i)
 | 
|---|
| 1343 |         {
 | 
|---|
| 1344 |           t.tag = ty_member;
 | 
|---|
| 1345 |           t.index = -1;
 | 
|---|
| 1346 |           t.d.member.type = types[i];
 | 
|---|
| 1347 |           t.d.member.offset = fields[i].offset;
 | 
|---|
| 1348 |           t.d.member.flags = VIS_PUBLIC;
 | 
|---|
| 1349 |           t.d.member.name = fields[i].name;
 | 
|---|
| 1350 |           t.d.member.sname = NULL;
 | 
|---|
| 1351 |           list[i] = type_add (&t);
 | 
|---|
| 1352 |         }
 | 
|---|
| 1353 |     }
 | 
|---|
| 1354 | 
 | 
|---|
| 1355 |   t.tag = ty_types;
 | 
|---|
| 1356 |   t.index = -1;
 | 
|---|
| 1357 |   t.d.types.count = n;
 | 
|---|
| 1358 |   t.d.types.list = list;
 | 
|---|
| 1359 |   t1 = type_add (&t);
 | 
|---|
| 1360 |   free (list);
 | 
|---|
| 1361 | 
 | 
|---|
| 1362 |   t = *tp;
 | 
|---|
| 1363 |   tp->tag = ty_class;
 | 
|---|
| 1364 |   tp->d.class.members = t1;
 | 
|---|
| 1365 |   tp->d.class.size = t.d.struc.size;
 | 
|---|
| 1366 |   tp->d.class.count = t.d.struc.count;
 | 
|---|
| 1367 |   tp->d.class.name = t.d.struc.name;
 | 
|---|
| 1368 | }
 | 
|---|
| 1369 | 
 | 
|---|
| 1370 | 
 | 
|---|
| 1371 | /* Build and return the internal representation of the `long long'
 | 
|---|
| 1372 |    type.  As IPMD doesn't know about `long long' we use the following
 | 
|---|
| 1373 |    structure instead:
 | 
|---|
| 1374 | 
 | 
|---|
| 1375 |      struct _long_long
 | 
|---|
| 1376 |      {
 | 
|---|
| 1377 |        unsigned long lo, hi;
 | 
|---|
| 1378 |      };
 | 
|---|
| 1379 | 
 | 
|---|
| 1380 |    This function could be optimized by remembering the type in a
 | 
|---|
| 1381 |    global variable. */
 | 
|---|
| 1382 | 
 | 
|---|
| 1383 | static struct type *make_long_long (void)
 | 
|---|
| 1384 | {
 | 
|---|
| 1385 |   struct type t, *t1, *t2, *t3, *types[2];
 | 
|---|
| 1386 |   struct field fields[2];
 | 
|---|
| 1387 | 
 | 
|---|
| 1388 |   /* Let t1 be `unsigned long'. */
 | 
|---|
| 1389 | 
 | 
|---|
| 1390 |   t.tag = ty_prim;
 | 
|---|
| 1391 |   t.index = 0x86;               /* 32 bit unsigned */
 | 
|---|
| 1392 |   t1 = type_add (&t);
 | 
|---|
| 1393 | 
 | 
|---|
| 1394 |   /* Let t2 be the field types: unsigned long, unsigned long. */
 | 
|---|
| 1395 | 
 | 
|---|
| 1396 |   types[0] = t1;
 | 
|---|
| 1397 |   types[1] = t1;
 | 
|---|
| 1398 |   t.tag = ty_types;
 | 
|---|
| 1399 |   t.index = -1;
 | 
|---|
| 1400 |   t.d.types.count = 2;
 | 
|---|
| 1401 |   t.d.types.list = types;
 | 
|---|
| 1402 |   t2 = type_add (&t);
 | 
|---|
| 1403 | 
 | 
|---|
| 1404 |   /* Let t3 be the fields: lo (at 0), hi (at 4). */
 | 
|---|
| 1405 | 
 | 
|---|
| 1406 |   fields[0].offset = 0; fields[0].name = strpool_add (str_pool, "lo");
 | 
|---|
| 1407 |   fields[1].offset = 4; fields[1].name = strpool_add (str_pool, "hi");
 | 
|---|
| 1408 |   t.tag = ty_fields;
 | 
|---|
| 1409 |   t.index = -1;
 | 
|---|
| 1410 |   t.d.fields.count = 2;
 | 
|---|
| 1411 |   t.d.fields.list = fields;
 | 
|---|
| 1412 |   t3 = type_add (&t);
 | 
|---|
| 1413 | 
 | 
|---|
| 1414 |   /* Build the structure type from t1, t2 and t3. */
 | 
|---|
| 1415 | 
 | 
|---|
| 1416 |   t.tag = ty_struc;
 | 
|---|
| 1417 |   t.d.struc.count = 2;
 | 
|---|
| 1418 |   t.d.struc.size = 8;
 | 
|---|
| 1419 |   t.d.struc.types = t2;
 | 
|---|
| 1420 |   t.d.struc.fields = t3;
 | 
|---|
| 1421 |   t.d.struc.name = strpool_add (str_pool, "_long_long");
 | 
|---|
| 1422 |   t.d.struc.flags = 0;
 | 
|---|
| 1423 |   return type_add (&t);
 | 
|---|
| 1424 | }
 | 
|---|
| 1425 | 
 | 
|---|
| 1426 | 
 | 
|---|
| 1427 | /* Parse a (signed) long long number in a stabs type.  The number is
 | 
|---|
| 1428 |    given in octal or decimal notation.  The result is stored to
 | 
|---|
| 1429 |    *NUMBER.  This function returns TRUE iff successful.  We don't
 | 
|---|
| 1430 |    check for overflow. */
 | 
|---|
| 1431 | 
 | 
|---|
| 1432 | static int parse_long_long (long long *number)
 | 
|---|
| 1433 | {
 | 
|---|
| 1434 |   long long n;
 | 
|---|
| 1435 |   int neg, base;
 | 
|---|
| 1436 | 
 | 
|---|
| 1437 |   n = 0; neg = FALSE; base = 10;
 | 
|---|
| 1438 |   if (*parse_ptr == '-')
 | 
|---|
| 1439 |     {
 | 
|---|
| 1440 |       neg = TRUE;
 | 
|---|
| 1441 |       ++parse_ptr;
 | 
|---|
| 1442 |     }
 | 
|---|
| 1443 |   if (*parse_ptr == '0')
 | 
|---|
| 1444 |     base = 8;
 | 
|---|
| 1445 |   if (!(*parse_ptr >= '0' && *parse_ptr < base + '0'))
 | 
|---|
| 1446 |     {
 | 
|---|
| 1447 |       *number = 0;
 | 
|---|
| 1448 |       return FALSE;
 | 
|---|
| 1449 |     }
 | 
|---|
| 1450 |   while (*parse_ptr >= '0' && *parse_ptr < base + '0')
 | 
|---|
| 1451 |     {
 | 
|---|
| 1452 |       n = n * base + (*parse_ptr - '0');
 | 
|---|
| 1453 |       ++parse_ptr;
 | 
|---|
| 1454 |     }
 | 
|---|
| 1455 |   *number = (neg ? -n : n);
 | 
|---|
| 1456 |   return TRUE;
 | 
|---|
| 1457 | }
 | 
|---|
| 1458 | 
 | 
|---|
| 1459 | 
 | 
|---|
| 1460 | /* Parse a (signed) number in a stabs type.  The number is given in
 | 
|---|
| 1461 |    octal or decimal notation.  The result is stored to *NUMBER.  This
 | 
|---|
| 1462 |    function returns TRUE iff successful.  We don't check for
 | 
|---|
| 1463 |    overflow. */
 | 
|---|
| 1464 | 
 | 
|---|
| 1465 | static int parse_number (long *number)
 | 
|---|
| 1466 | {
 | 
|---|
| 1467 |   long long n;
 | 
|---|
| 1468 |   int result;
 | 
|---|
| 1469 | 
 | 
|---|
| 1470 |   result = parse_long_long (&n);
 | 
|---|
| 1471 |   *number = (long)n;
 | 
|---|
| 1472 |   return result;
 | 
|---|
| 1473 | }
 | 
|---|
| 1474 | 
 | 
|---|
| 1475 | 
 | 
|---|
| 1476 | /* Check the next character in a stabs type for C.  If the next
 | 
|---|
| 1477 |    character matches C, the character is skipped and TRUE is
 | 
|---|
| 1478 |    returned.  Otherwise, a warning message is displayed and FALSE is
 | 
|---|
| 1479 |    returned. */
 | 
|---|
| 1480 | 
 | 
|---|
| 1481 | static int parse_char (char c)
 | 
|---|
| 1482 | {
 | 
|---|
| 1483 |   if (*parse_ptr != c)
 | 
|---|
| 1484 |     {
 | 
|---|
| 1485 |       no_warning ("Invalid symbol data: `%c' expected, found '%c' (off %ld)\n stabs: %s",
 | 
|---|
| 1486 |                   c, *parse_ptr, parse_ptr - parse_start, parse_start);
 | 
|---|
| 1487 |       return FALSE;
 | 
|---|
| 1488 |     }
 | 
|---|
| 1489 |   ++parse_ptr;
 | 
|---|
| 1490 |   return TRUE;
 | 
|---|
| 1491 | }
 | 
|---|
| 1492 | 
 | 
|---|
| 1493 | 
 | 
|---|
| 1494 | /* Parse mangled arguments of a member functions.  For instance, ic
 | 
|---|
| 1495 |    means an `int' argument and a `char' argument.  Return FALSE on
 | 
|---|
| 1496 |    failure. */
 | 
|---|
| 1497 | 
 | 
|---|
| 1498 | static int parse_mangled_args (void)
 | 
|---|
| 1499 | {
 | 
|---|
| 1500 |   while (*parse_ptr != ';')
 | 
|---|
| 1501 |     {
 | 
|---|
| 1502 |       switch (*parse_ptr)
 | 
|---|
| 1503 |         {
 | 
|---|
| 1504 |         case 0:
 | 
|---|
| 1505 |           warning ("Missing semicolon after mangled arguments");
 | 
|---|
| 1506 |           return FALSE;
 | 
|---|
| 1507 |         default:
 | 
|---|
| 1508 |           /* TODO */
 | 
|---|
| 1509 |           break;
 | 
|---|
| 1510 |         }
 | 
|---|
| 1511 |       ++parse_ptr;
 | 
|---|
| 1512 |     }
 | 
|---|
| 1513 |   ++parse_ptr;                  /* Skip semicolon */
 | 
|---|
| 1514 |   return TRUE;
 | 
|---|
| 1515 | }
 | 
|---|
| 1516 | 
 | 
|---|
| 1517 | 
 | 
|---|
| 1518 | /* Parse the visibility of a class or member. */
 | 
|---|
| 1519 | 
 | 
|---|
| 1520 | static int parse_visibility (void)
 | 
|---|
| 1521 | {
 | 
|---|
| 1522 |   switch (*parse_ptr)
 | 
|---|
| 1523 |     {
 | 
|---|
| 1524 |     case '0':
 | 
|---|
| 1525 |       ++parse_ptr;
 | 
|---|
| 1526 |       return VIS_PRIVATE;
 | 
|---|
| 1527 |     case '1':
 | 
|---|
| 1528 |       ++parse_ptr;
 | 
|---|
| 1529 |       return VIS_PROTECTED;
 | 
|---|
| 1530 |     case '2':
 | 
|---|
| 1531 |       ++parse_ptr;
 | 
|---|
| 1532 |       return VIS_PUBLIC;
 | 
|---|
| 1533 |     default:
 | 
|---|
| 1534 |       ++parse_ptr;
 | 
|---|
| 1535 |       no_warning ("Invalid visibility: %c", *parse_ptr);
 | 
|---|
| 1536 |       if (*parse_ptr != 0)
 | 
|---|
| 1537 |         ++parse_ptr;
 | 
|---|
| 1538 |       return VIS_PUBLIC;
 | 
|---|
| 1539 |     }
 | 
|---|
| 1540 | }
 | 
|---|
| 1541 | 
 | 
|---|
| 1542 | 
 | 
|---|
| 1543 | /* Add TYPE_NAME to `str_pool', replacing a NULL string with a unique
 | 
|---|
| 1544 |    string. */
 | 
|---|
| 1545 | 
 | 
|---|
| 1546 | static const char *add_struct_name (const char *type_name)
 | 
|---|
| 1547 | {
 | 
|---|
| 1548 |   char tmp[32];
 | 
|---|
| 1549 | 
 | 
|---|
| 1550 |   /* Some names have only spaces for gdb safety, let's make an
 | 
|---|
| 1551 |      fake name for those. */
 | 
|---|
| 1552 |   if (type_name != NULL)
 | 
|---|
| 1553 |     {
 | 
|---|
| 1554 |       const char *psz = type_name;
 | 
|---|
| 1555 |       while (*psz == ' ' || *psz == '\t')
 | 
|---|
| 1556 |           psz++;
 | 
|---|
| 1557 |       if (!*psz)
 | 
|---|
| 1558 |           type_name = NULL;
 | 
|---|
| 1559 |     }
 | 
|---|
| 1560 | 
 | 
|---|
| 1561 |   if (type_name == NULL)
 | 
|---|
| 1562 |     {
 | 
|---|
| 1563 |       sprintf (tmp, "__%d", unnamed_struct_number++);
 | 
|---|
| 1564 |       type_name = tmp;
 | 
|---|
| 1565 |     }
 | 
|---|
| 1566 |   return strpool_add (str_pool, type_name);
 | 
|---|
| 1567 | }
 | 
|---|
| 1568 | 
 | 
|---|
| 1569 | /**
 | 
|---|
| 1570 |  * Finds the next colon in the string and returns pointer to it.
 | 
|---|
| 1571 |  * For C++ template support, colons within <> are not considered.
 | 
|---|
| 1572 |  *
 | 
|---|
| 1573 |  * @returns Pointer to next colon within psz.
 | 
|---|
| 1574 |  * @returns NULL if not found.
 | 
|---|
| 1575 |  * @param   pszString   String to search.
 | 
|---|
| 1576 |  * @param   chType      Type we're parsing. Use '\0' if unknown or it
 | 
|---|
| 1577 |  *                      should be ignored
 | 
|---|
| 1578 |  * @remark  Still a bad hack this.
 | 
|---|
| 1579 |  */
 | 
|---|
| 1580 | #ifdef COLON_DEBUG
 | 
|---|
| 1581 | static const char *nextcolon2(const char *pszString, char chType)
 | 
|---|
| 1582 | {
 | 
|---|
| 1583 |     static const char *_nextcolon2(const char *pszString, char chType);
 | 
|---|
| 1584 |     const char *psz = _nextcolon2(pszString, chType);
 | 
|---|
| 1585 |     fprintf(stderr, "COLON: %.100s\n%.32s\n", pszString, psz);
 | 
|---|
| 1586 |     return psz;
 | 
|---|
| 1587 | }
 | 
|---|
| 1588 | static const char *_nextcolon2(const char *pszString, char chType)
 | 
|---|
| 1589 | #else
 | 
|---|
| 1590 | static const char *nextcolon2(const char *pszString, char chType)
 | 
|---|
| 1591 | #endif
 | 
|---|
| 1592 | {
 | 
|---|
| 1593 |     const char *pszColon;
 | 
|---|
| 1594 |     const char *psz;
 | 
|---|
| 1595 | 
 | 
|---|
| 1596 |     /* permanent operator hack */
 | 
|---|
| 1597 |     if (    pszString[0] == 'o'
 | 
|---|
| 1598 |         &&  pszString[1] == 'p'
 | 
|---|
| 1599 |         &&  pszString[2] == 'e'
 | 
|---|
| 1600 |         &&  pszString[3] == 'r'
 | 
|---|
| 1601 |         &&  pszString[4] == 'a'
 | 
|---|
| 1602 |         &&  pszString[5] == 't'
 | 
|---|
| 1603 |         &&  pszString[6] == 'o'
 | 
|---|
| 1604 |         &&  pszString[7] == 'r')
 | 
|---|
| 1605 |     {
 | 
|---|
| 1606 |         psz = pszString + 8;
 | 
|---|
| 1607 |         while (*psz && !isalnum(*psz) && *psz != '_') /* potential operator chars */
 | 
|---|
| 1608 |         {
 | 
|---|
| 1609 |             if (*psz == ':')
 | 
|---|
| 1610 |             {
 | 
|---|
| 1611 |                 if (    psz - pszString >= 1 + 8
 | 
|---|
| 1612 |                     &&  psz - pszString <= 3 + 8)
 | 
|---|
| 1613 |                     return psz;
 | 
|---|
| 1614 |                 break;
 | 
|---|
| 1615 |             }
 | 
|---|
| 1616 |             psz++;
 | 
|---|
| 1617 |         }
 | 
|---|
| 1618 | 
 | 
|---|
| 1619 |     }
 | 
|---|
| 1620 | 
 | 
|---|
| 1621 |     /* normal life */
 | 
|---|
| 1622 |     pszColon = strchr(pszString, ':');
 | 
|---|
| 1623 |     if (!pszColon)
 | 
|---|
| 1624 |         return NULL;
 | 
|---|
| 1625 |     psz = strchr(pszString, '<');
 | 
|---|
| 1626 | 
 | 
|---|
| 1627 |     if (psz && psz < pszColon && pszColon[1] == ':')
 | 
|---|
| 1628 |     {
 | 
|---|
| 1629 |         int   cNesting = 0;             /* <> level */
 | 
|---|
| 1630 | 
 | 
|---|
| 1631 |         for (;;psz++)
 | 
|---|
| 1632 |         {
 | 
|---|
| 1633 |             switch (*psz)
 | 
|---|
| 1634 |             {
 | 
|---|
| 1635 |                 case '<':   cNesting++; break;
 | 
|---|
| 1636 |                 case '>':   cNesting--; break;
 | 
|---|
| 1637 |                 case ':':
 | 
|---|
| 1638 |                     if (cNesting > 0)
 | 
|---|
| 1639 |                         break;
 | 
|---|
| 1640 |                     /* hack: continue on ">::" (but not on "operator...") */
 | 
|---|
| 1641 |                     if (    chType != 'x'
 | 
|---|
| 1642 |                         &&  psz[1] == ':'
 | 
|---|
| 1643 |                         &&  psz > pszString && psz[-1] == '>'
 | 
|---|
| 1644 |                             )
 | 
|---|
| 1645 |                     {
 | 
|---|
| 1646 |                         psz++;
 | 
|---|
| 1647 |                         break;
 | 
|---|
| 1648 |                     }
 | 
|---|
| 1649 |                     return psz;
 | 
|---|
| 1650 |                 case '\0':
 | 
|---|
| 1651 |                     return NULL;
 | 
|---|
| 1652 |             }
 | 
|---|
| 1653 |         }
 | 
|---|
| 1654 |     }
 | 
|---|
| 1655 |     else
 | 
|---|
| 1656 |     {
 | 
|---|
| 1657 |         if (chType != 'x')
 | 
|---|
| 1658 |         {
 | 
|---|
| 1659 |             /* skip '::' (hack:) if not followed by number. */
 | 
|---|
| 1660 |             while (*pszColon && pszColon[1] == ':' && (pszColon[2] > '9' || pszColon[2] < '0'))
 | 
|---|
| 1661 |             {
 | 
|---|
| 1662 |                 pszColon += 2;
 | 
|---|
| 1663 |                 while (*pszColon != ':' && *pszColon)
 | 
|---|
| 1664 |                     pszColon++;
 | 
|---|
| 1665 |             }
 | 
|---|
| 1666 |         }
 | 
|---|
| 1667 |     }
 | 
|---|
| 1668 | 
 | 
|---|
| 1669 |     return pszColon;
 | 
|---|
| 1670 | }
 | 
|---|
| 1671 | 
 | 
|---|
| 1672 | /* old version */
 | 
|---|
| 1673 | static inline const char *nextcolon(const char *pszString)
 | 
|---|
| 1674 | {
 | 
|---|
| 1675 |     return nextcolon2(pszString, '\0');
 | 
|---|
| 1676 | }
 | 
|---|
| 1677 | 
 | 
|---|
| 1678 | 
 | 
|---|
| 1679 | 
 | 
|---|
| 1680 | /* Parse a stabs type (which is named TYPE_NAME; TYPE_NAME is NULL for
 | 
|---|
| 1681 |    an unnamed type) and return the internal representation of that
 | 
|---|
| 1682 |    type. */
 | 
|---|
| 1683 | 
 | 
|---|
| 1684 | static struct type *parse_type (const char *type_name)
 | 
|---|
| 1685 | {
 | 
|---|
| 1686 |   const char *saved_ptr, *p1;
 | 
|---|
| 1687 |   char ch;
 | 
|---|
| 1688 |   struct type t, *result, *t1, *t2, *t3, **tlist;
 | 
|---|
| 1689 |   int i, n, class_flag, is_void;
 | 
|---|
| 1690 |   long num1, num2, size, lo, hi, valid, offset, width, code;
 | 
|---|
| 1691 |   long long range_lo, range_hi;
 | 
|---|
| 1692 |   struct tmp_field *tmp_fields, *tf;
 | 
|---|
| 1693 |   struct value *tmp_values, *tv;
 | 
|---|
| 1694 |   struct grow g1 = GROW_INIT;
 | 
|---|
| 1695 |   enum type_tag tt;
 | 
|---|
| 1696 | 
 | 
|---|
| 1697 |   valid = TRUE; result = NULL;
 | 
|---|
| 1698 |   t.index = -1;
 | 
|---|
| 1699 |   switch (*parse_ptr)
 | 
|---|
| 1700 |     {
 | 
|---|
| 1701 |     case '0': case '1': case '2': case '3': case '4':
 | 
|---|
| 1702 |     case '5': case '6': case '7': case '8': case '9':
 | 
|---|
| 1703 |       if (!parse_number (&num1))
 | 
|---|
| 1704 |         goto syntax;
 | 
|---|
| 1705 | 
 | 
|---|
| 1706 |       /* Special case: self reference => void */
 | 
|---|
| 1707 |       is_void = FALSE;
 | 
|---|
| 1708 |       if (*parse_ptr == '=' && parse_ptr[1] >= '0' && parse_ptr[1] <= '9')
 | 
|---|
| 1709 |         {
 | 
|---|
| 1710 |           saved_ptr = parse_ptr++;
 | 
|---|
| 1711 |           if (!parse_number (&num2))
 | 
|---|
| 1712 |             goto syntax;
 | 
|---|
| 1713 |           if (num2 == num1)
 | 
|---|
| 1714 |             is_void = TRUE;
 | 
|---|
| 1715 |           else
 | 
|---|
| 1716 |             parse_ptr = saved_ptr;
 | 
|---|
| 1717 |         }
 | 
|---|
| 1718 |       if (is_void)
 | 
|---|
| 1719 |         {
 | 
|---|
| 1720 |           t.tag = ty_prim;
 | 
|---|
| 1721 |           t.index = 0x97;       /* void */
 | 
|---|
| 1722 |           result = type_add (&t);
 | 
|---|
| 1723 |           stype_add (num1, result);
 | 
|---|
| 1724 |         }
 | 
|---|
| 1725 |       else if (*parse_ptr == '=')
 | 
|---|
| 1726 |         {
 | 
|---|
| 1727 |           /* Nested definition */
 | 
|---|
| 1728 |           ++parse_ptr;
 | 
|---|
| 1729 |           result = parse_type (type_name);
 | 
|---|
| 1730 |           stype_add (num1, result);
 | 
|---|
| 1731 |         }
 | 
|---|
| 1732 |       else
 | 
|---|
| 1733 |         {
 | 
|---|
| 1734 |           result = stype_find (num1);
 | 
|---|
| 1735 |           if (result == NULL)
 | 
|---|
| 1736 |             {
 | 
|---|
| 1737 |               t.tag = ty_stabs_ref;
 | 
|---|
| 1738 |               t.d.stabs_ref = num1;
 | 
|---|
| 1739 |             }
 | 
|---|
| 1740 |         }
 | 
|---|
| 1741 |       break;
 | 
|---|
| 1742 | 
 | 
|---|
| 1743 |     case 'r':
 | 
|---|
| 1744 | 
 | 
|---|
| 1745 |       /* A range type: r<base_type>;<lower_bound>;<upper_bound>;
 | 
|---|
| 1746 | 
 | 
|---|
| 1747 |          Special cases:
 | 
|---|
| 1748 | 
 | 
|---|
| 1749 |          lower_bound | upper_bound | type
 | 
|---|
| 1750 |          ------------+-------------+------------------------
 | 
|---|
| 1751 |          n > 0       | 0           | floating point, n bytes
 | 
|---|
| 1752 | 
 | 
|---|
| 1753 |          */
 | 
|---|
| 1754 | 
 | 
|---|
| 1755 |       ++parse_ptr;
 | 
|---|
| 1756 |       if (!parse_number (&num1) || !parse_char (';')
 | 
|---|
| 1757 |           || !parse_long_long (&range_lo) || !parse_char (';')
 | 
|---|
| 1758 |           || !parse_long_long (&range_hi) || !parse_char (';'))
 | 
|---|
| 1759 |         goto syntax;
 | 
|---|
| 1760 |       t.tag = ty_prim;
 | 
|---|
| 1761 |       if (range_lo == -128 && range_hi == 127)
 | 
|---|
| 1762 |         t.index = 0x80;         /* 8 bit signed */
 | 
|---|
| 1763 |       else if (range_lo == -32768 && range_hi == 32767)
 | 
|---|
| 1764 |         t.index = 0x81;         /* 16 bit signed */
 | 
|---|
| 1765 |       else if (range_lo == -2147483647 - 1 && range_hi == 2147483647)
 | 
|---|
| 1766 |         t.index = 0x82;         /* 32 bit signed */
 | 
|---|
| 1767 |       else if (range_lo == 0 && range_hi == 127)
 | 
|---|
| 1768 |         t.index = 0x84;         /* 8 bit character */
 | 
|---|
| 1769 |       else if (range_lo == 0 && range_hi == 255)
 | 
|---|
| 1770 |         t.index = 0x84;         /* 8 bit unsigned */
 | 
|---|
| 1771 |       else if (range_lo == 0 && range_hi == 65535)
 | 
|---|
| 1772 |         t.index = 0x85;         /* 16 bit unsigned */
 | 
|---|
| 1773 |       else if (range_lo == 0 && range_hi == 0xffffffff)
 | 
|---|
| 1774 |         t.index = 0x86;         /* 32 bit unsigned */
 | 
|---|
| 1775 |       else if (range_lo == 0 && range_hi == -1)
 | 
|---|
| 1776 |         {
 | 
|---|
| 1777 |           if (type_name != NULL
 | 
|---|
| 1778 |               && (strcmp (type_name, "long long unsigned int") == 0
 | 
|---|
| 1779 |                   || strcmp (type_name, "long long int") == 0))
 | 
|---|
| 1780 |             result = make_long_long ();
 | 
|---|
| 1781 |           else
 | 
|---|
| 1782 |             t.index = 0x86;     /* 32 bit unsigned */
 | 
|---|
| 1783 |         }
 | 
|---|
| 1784 |       else if ((unsigned long long)range_lo == 0x8000000000000000ULL
 | 
|---|
| 1785 |                && range_hi == 0x7fffffffffffffffLL)
 | 
|---|
| 1786 |         result = make_long_long ();
 | 
|---|
| 1787 |       else if (range_lo == 4 && range_hi == 0)
 | 
|---|
| 1788 |         t.index = 0x88;         /* 32 bit real */
 | 
|---|
| 1789 |       else if (range_lo == 8 && range_hi == 0)
 | 
|---|
| 1790 |         t.index = 0x89;         /* 64 bit real */
 | 
|---|
| 1791 |       else if (range_lo == 12 && range_hi == 0)
 | 
|---|
| 1792 |         t.index = 0x8a;         /* 80 bit real */
 | 
|---|
| 1793 |       else
 | 
|---|
| 1794 |         {
 | 
|---|
| 1795 |           no_warning ("Unknown range type: %lld..%lld", range_lo, range_hi);
 | 
|---|
| 1796 |           goto syntax;
 | 
|---|
| 1797 |         }
 | 
|---|
| 1798 |       break;
 | 
|---|
| 1799 | 
 | 
|---|
| 1800 |     case 'R':
 | 
|---|
| 1801 | 
 | 
|---|
| 1802 |       /* Complex number: R<?base_type?>;<size bytes>;<0>; */
 | 
|---|
| 1803 | 
 | 
|---|
| 1804 |       ++parse_ptr;
 | 
|---|
| 1805 |       if (!parse_number (&num1) || !parse_char (';')
 | 
|---|
| 1806 |           || !parse_number (&width) || !parse_char (';')
 | 
|---|
| 1807 |           || !parse_number (&code) || !parse_char (';'))
 | 
|---|
| 1808 |         goto syntax;
 | 
|---|
| 1809 | 
 | 
|---|
| 1810 |       /*
 | 
|---|
| 1811 |        * The 192bit type is not defined in the HLL specs, but we assume it for
 | 
|---|
| 1812 |        * convenince right now.
 | 
|---|
| 1813 |        *
 | 
|---|
| 1814 |        * It seems like no debugger acutally supports these types. So, we should,
 | 
|---|
| 1815 |        * when somebody requires it for debugging complex math, make structs out
 | 
|---|
| 1816 |        * of these declarations like GCC does for the 'complex int' type.
 | 
|---|
| 1817 |        *
 | 
|---|
| 1818 |        * .stabs "FakeComplexInt:t21=22=s8real:1,0,32;imag:1,32,32;;",128,0,0,0
 | 
|---|
| 1819 |        * .stabs "FakeComplexFloat:t23=24=s8real:12,0,32;imag:12,32,32;;",128,0,0,0
 | 
|---|
| 1820 |        * .stabs "FakeComplexDouble:t25=26=s16real:13,0,64;imag:13,64,64;;",128,0,0,0
 | 
|---|
| 1821 |        * .stabs "FakeComplexLongDouble:t27=28=s24real:14,0,96;imag:14,96,96;;",128,0,0,0
 | 
|---|
| 1822 |        *
 | 
|---|
| 1823 |        */
 | 
|---|
| 1824 |       t.tag = ty_prim;
 | 
|---|
| 1825 |       if (width == 8 && code == 0)
 | 
|---|
| 1826 |         t.index = 0x8c;
 | 
|---|
| 1827 |       else if (width == 16 && code == 0)
 | 
|---|
| 1828 |         t.index = 0x8d ;
 | 
|---|
| 1829 |       else if (width == 20 && code == 0)
 | 
|---|
| 1830 |         t.index = 0x8e;
 | 
|---|
| 1831 |       else if (width == 24 && code == 0)
 | 
|---|
| 1832 |         t.index = 0x8f; //TODO: bogus!!!
 | 
|---|
| 1833 |       else
 | 
|---|
| 1834 |         {
 | 
|---|
| 1835 |           no_warning ("Unknown complex type: %ld/%ld", width, code);
 | 
|---|
| 1836 |           goto syntax;
 | 
|---|
| 1837 |         }
 | 
|---|
| 1838 |       break;
 | 
|---|
| 1839 | 
 | 
|---|
| 1840 |     case '*':
 | 
|---|
| 1841 | 
 | 
|---|
| 1842 |       /* A pointer type: *<type> */
 | 
|---|
| 1843 | 
 | 
|---|
| 1844 |       ++parse_ptr;
 | 
|---|
| 1845 |       t1 = parse_type (NULL);
 | 
|---|
| 1846 |       t.tag = ty_pointer;
 | 
|---|
| 1847 |       t.d.pointer = t1;
 | 
|---|
| 1848 |       break;
 | 
|---|
| 1849 | 
 | 
|---|
| 1850 |     case 'k':
 | 
|---|
| 1851 | 
 | 
|---|
| 1852 |       /* A const type: k<type>
 | 
|---|
| 1853 |          HLL don't have const typedefs afaik, so we just make it an alias. */
 | 
|---|
| 1854 | 
 | 
|---|
| 1855 |       ++parse_ptr;
 | 
|---|
| 1856 |       t1 = parse_type (NULL);
 | 
|---|
| 1857 |       t.tag = ty_alias;
 | 
|---|
| 1858 |       t.d.alias = t1;
 | 
|---|
| 1859 |       break;
 | 
|---|
| 1860 | 
 | 
|---|
| 1861 |    case 'B':
 | 
|---|
| 1862 | 
 | 
|---|
| 1863 |       /* A volatile type: B<type>
 | 
|---|
| 1864 |          This is a SUN extension, and right now we don't care to generate
 | 
|---|
| 1865 |          specific HLL for it and stick with an alias. */
 | 
|---|
| 1866 | 
 | 
|---|
| 1867 |       ++parse_ptr;
 | 
|---|
| 1868 |       t1 = parse_type (NULL);
 | 
|---|
| 1869 |       t.tag = ty_alias;
 | 
|---|
| 1870 |       t.d.alias = t1;
 | 
|---|
| 1871 |       break;
 | 
|---|
| 1872 | 
 | 
|---|
| 1873 | 
 | 
|---|
| 1874 |     case '&':
 | 
|---|
| 1875 | 
 | 
|---|
| 1876 |       /* A reference type (C++): &<type> */
 | 
|---|
| 1877 | 
 | 
|---|
| 1878 |       ++parse_ptr;
 | 
|---|
| 1879 |       t1 = parse_type (NULL);
 | 
|---|
| 1880 |       t.tag = ty_ref;
 | 
|---|
| 1881 |       t.d.ref = t1;
 | 
|---|
| 1882 |       break;
 | 
|---|
| 1883 | 
 | 
|---|
| 1884 |     case '#':
 | 
|---|
| 1885 | 
 | 
|---|
| 1886 |       /* A member function:
 | 
|---|
| 1887 | 
 | 
|---|
| 1888 |          short format: ##<return_type>;
 | 
|---|
| 1889 | 
 | 
|---|
| 1890 |          long format:  #<domain_type>,<return_type>{,<arg_type>};
 | 
|---|
| 1891 | 
 | 
|---|
| 1892 |          */
 | 
|---|
| 1893 | 
 | 
|---|
| 1894 |       ++parse_ptr;
 | 
|---|
| 1895 |       args_grow.count = 0;  /* ASSUMES we can safely use args_grow/args_list. */
 | 
|---|
| 1896 |       t2 = NULL;            /* t2=Domain type; t1=Return type; */
 | 
|---|
| 1897 |       if (*parse_ptr == '#')
 | 
|---|
| 1898 |         {
 | 
|---|
| 1899 |           ++parse_ptr;
 | 
|---|
| 1900 |           t1 = parse_type (NULL);
 | 
|---|
| 1901 |           if (!parse_char (';'))
 | 
|---|
| 1902 |             goto syntax;
 | 
|---|
| 1903 |           no_warning ("We don't understand '##' methods.");
 | 
|---|
| 1904 |         }
 | 
|---|
| 1905 |       else
 | 
|---|
| 1906 |         {
 | 
|---|
| 1907 |           t2 = parse_type (NULL); /* Domain type */
 | 
|---|
| 1908 |           if (!parse_char (','))
 | 
|---|
| 1909 |             goto syntax;
 | 
|---|
| 1910 |           t1 = parse_type (NULL); /* Return type */
 | 
|---|
| 1911 |           /* Arguments */
 | 
|---|
| 1912 |           while (*parse_ptr != ';')
 | 
|---|
| 1913 |             {
 | 
|---|
| 1914 |               if (!parse_char (','))
 | 
|---|
| 1915 |                 goto syntax;
 | 
|---|
| 1916 |               grow_by (&args_grow, 1);
 | 
|---|
| 1917 |               args_list[args_grow.count++] = parse_type (NULL); /* Argument type */
 | 
|---|
| 1918 |             }
 | 
|---|
| 1919 |           ++parse_ptr;
 | 
|---|
| 1920 |         }
 | 
|---|
| 1921 | 
 | 
|---|
| 1922 |       t3 = NULL;
 | 
|---|
| 1923 |       #if 0 /* this doesn't really seems to be required, but can just as well leave it in. */
 | 
|---|
| 1924 |       if (args_grow.count)
 | 
|---|
| 1925 |         {
 | 
|---|
| 1926 |           t.tag = ty_args;
 | 
|---|
| 1927 |           t.index = -1;
 | 
|---|
| 1928 |           t.d.args.count = args_grow.count;
 | 
|---|
| 1929 |           t.d.args.list = xmalloc (args_grow.count * sizeof (*args_list));
 | 
|---|
| 1930 |           memcpy (t.d.args.list, args_list, args_grow.count * sizeof (*args_list));
 | 
|---|
| 1931 |           t3 = type_add (&t);
 | 
|---|
| 1932 |           free (t.d.args.list);
 | 
|---|
| 1933 |         }
 | 
|---|
| 1934 |       #endif
 | 
|---|
| 1935 | 
 | 
|---|
| 1936 |       /* Make a function type from the return type t1 */
 | 
|---|
| 1937 |       t.tag = ty_func;
 | 
|---|
| 1938 |       t.d.func.ret = t1;
 | 
|---|
| 1939 |       t.d.func.domain = t2;
 | 
|---|
| 1940 |       t.d.func.args = t3;
 | 
|---|
| 1941 |       t.d.func.arg_count = args_grow.count;
 | 
|---|
| 1942 |       args_grow.count = 0;
 | 
|---|
| 1943 |       t1 = type_add(&t);
 | 
|---|
| 1944 | 
 | 
|---|
| 1945 |       break;
 | 
|---|
| 1946 | 
 | 
|---|
| 1947 |     case '@':
 | 
|---|
| 1948 | 
 | 
|---|
| 1949 |       /* Special GNU-defined types:
 | 
|---|
| 1950 | 
 | 
|---|
| 1951 |          @s<bits>;<code>;
 | 
|---|
| 1952 | 
 | 
|---|
| 1953 |          BITS:          Number of bits
 | 
|---|
| 1954 |          CODE:          Identifies the type:
 | 
|---|
| 1955 |                         -16              bool
 | 
|---|
| 1956 |                         -20              char
 | 
|---|
| 1957 | 
 | 
|---|
| 1958 |          @s<bits>;<range record>
 | 
|---|
| 1959 |             Used for 64 bit ints.
 | 
|---|
| 1960 | 
 | 
|---|
| 1961 |          @s<bits>;<num records>
 | 
|---|
| 1962 |             Used for non-standard enums.
 | 
|---|
| 1963 | 
 | 
|---|
| 1964 |          @<basetype>,<membertype>
 | 
|---|
| 1965 |             Used for addressing class/struct/union members.
 | 
|---|
| 1966 |       */
 | 
|---|
| 1967 | 
 | 
|---|
| 1968 |       ++parse_ptr;
 | 
|---|
| 1969 |       switch (*parse_ptr)
 | 
|---|
| 1970 |         {
 | 
|---|
| 1971 |         case 's':
 | 
|---|
| 1972 |           ++parse_ptr;
 | 
|---|
| 1973 |           if (!parse_number (&size) || !parse_char (';'))
 | 
|---|
| 1974 |             goto syntax;
 | 
|---|
| 1975 |           if (*parse_ptr == 'r')
 | 
|---|
| 1976 |             { /* nested */
 | 
|---|
| 1977 |               return parse_type(type_name);
 | 
|---|
| 1978 |             }
 | 
|---|
| 1979 |           if (*parse_ptr == 'e')
 | 
|---|
| 1980 |             goto l_parse_enum;
 | 
|---|
| 1981 | 
 | 
|---|
| 1982 |           if (!parse_number (&code))
 | 
|---|
| 1983 |             goto syntax;
 | 
|---|
| 1984 |           if (size == 8 && code == -16)
 | 
|---|
| 1985 |             {
 | 
|---|
| 1986 | #if 0 /* debugger doesn't understand this game */
 | 
|---|
| 1987 |               t.tag = ty_prim;
 | 
|---|
| 1988 |               t.index = 0x90;   /* 8 bit boolean */
 | 
|---|
| 1989 | #else
 | 
|---|
| 1990 |               t.tag = ty_values;
 | 
|---|
| 1991 |               t.d.values.count = 2;
 | 
|---|
| 1992 |               t.d.values.list = xmalloc (2 * sizeof (*t.d.values.list));
 | 
|---|
| 1993 |               t.d.values.list[0].index = 0;
 | 
|---|
| 1994 |               t.d.values.list[0].name  = strpool_add (str_pool, "false");
 | 
|---|
| 1995 |               t.d.values.list[1].index = 1;
 | 
|---|
| 1996 |               t.d.values.list[1].name  = strpool_add (str_pool, "true");
 | 
|---|
| 1997 |               t1 = type_add (&t);
 | 
|---|
| 1998 |               free (t.d.values.list);
 | 
|---|
| 1999 | 
 | 
|---|
| 2000 |               t.tag = ty_prim;
 | 
|---|
| 2001 |               t.index = 0x80;
 | 
|---|
| 2002 |               t2 = type_add (&t);
 | 
|---|
| 2003 | 
 | 
|---|
| 2004 |               t.tag = ty_enu;
 | 
|---|
| 2005 |               t.index = -1;
 | 
|---|
| 2006 |               t.d.enu.values = t1;
 | 
|---|
| 2007 |               t.d.enu.type = t2;
 | 
|---|
| 2008 |               t.d.enu.name = add_struct_name (NULL);
 | 
|---|
| 2009 |               t.d.enu.first = 0;
 | 
|---|
| 2010 |               t.d.enu.last = 1;
 | 
|---|
| 2011 | #endif
 | 
|---|
| 2012 |             }
 | 
|---|
| 2013 |           else
 | 
|---|
| 2014 |             {
 | 
|---|
| 2015 |               warning ("Unknown GNU extension type code: %ld, %ld bits",
 | 
|---|
| 2016 |                        code, size);
 | 
|---|
| 2017 |               goto syntax;
 | 
|---|
| 2018 |             }
 | 
|---|
| 2019 |           if (!parse_char (';'))
 | 
|---|
| 2020 |             goto syntax;
 | 
|---|
| 2021 |           break;
 | 
|---|
| 2022 | 
 | 
|---|
| 2023 |         case '0': case '1': case '2': case '3': case '4':
 | 
|---|
| 2024 |         case '5': case '6': case '7': case '8': case '9':
 | 
|---|
| 2025 |           {
 | 
|---|
| 2026 |             /* just make it an integer - see dbxout.c OFFSET_TYPE case. */
 | 
|---|
| 2027 |             if (    parse_number (&num1)
 | 
|---|
| 2028 |                 &&  *parse_ptr == ','
 | 
|---|
| 2029 |                 &&  ++parse_ptr
 | 
|---|
| 2030 |                 &&  parse_number (&num2)
 | 
|---|
| 2031 |                 )
 | 
|---|
| 2032 |               {
 | 
|---|
| 2033 |                 t.tag = ty_prim;
 | 
|---|
| 2034 |                 t.index = 0x82;         /* 32 bit signed */
 | 
|---|
| 2035 |               }
 | 
|---|
| 2036 |             else
 | 
|---|
| 2037 |               {
 | 
|---|
| 2038 |                 warning_parse ("Invalid BASE_OFFSET GNU extension format!");
 | 
|---|
| 2039 |                 goto syntax;
 | 
|---|
| 2040 |               }
 | 
|---|
| 2041 |             break;
 | 
|---|
| 2042 |           }
 | 
|---|
| 2043 | 
 | 
|---|
| 2044 |         default:
 | 
|---|
| 2045 |           warning ("Unknown GNU extension type: @%c", *parse_ptr);
 | 
|---|
| 2046 |           goto syntax;
 | 
|---|
| 2047 |         }
 | 
|---|
| 2048 |       break;
 | 
|---|
| 2049 | 
 | 
|---|
| 2050 |     case 'x':
 | 
|---|
| 2051 | 
 | 
|---|
| 2052 |       /* Incomplete type: xs<name>:
 | 
|---|
| 2053 |                           xu<name>:
 | 
|---|
| 2054 |                           xe<name>: */
 | 
|---|
| 2055 | 
 | 
|---|
| 2056 |       ++parse_ptr;
 | 
|---|
| 2057 |       ch = *parse_ptr++;
 | 
|---|
| 2058 |       p1 = nextcolon2 (parse_ptr, 'x');
 | 
|---|
| 2059 |       if (p1 == NULL)
 | 
|---|
| 2060 |         {
 | 
|---|
| 2061 |           warning ("Invalid forward reference: missing colon");
 | 
|---|
| 2062 |           goto syntax;
 | 
|---|
| 2063 |         }
 | 
|---|
| 2064 | 
 | 
|---|
| 2065 |       switch (ch)
 | 
|---|
| 2066 |         {
 | 
|---|
| 2067 |         case 's':
 | 
|---|
| 2068 |         case 'u':
 | 
|---|
| 2069 |           {
 | 
|---|
| 2070 |             /* make a fake structure. */
 | 
|---|
| 2071 |             t.tag = ty_prim;
 | 
|---|
| 2072 |             t.index = 0x80;
 | 
|---|
| 2073 |             tlist = xmalloc (1 * sizeof (*t.d.types.list));
 | 
|---|
| 2074 |             tlist[0] = type_add (&t);
 | 
|---|
| 2075 |             t.tag = ty_types;
 | 
|---|
| 2076 |             t.index = -1;
 | 
|---|
| 2077 |             t.d.types.count = 1;
 | 
|---|
| 2078 |             t.d.types.list = tlist;
 | 
|---|
| 2079 |             t1 = type_add (&t);
 | 
|---|
| 2080 |             free (tlist);
 | 
|---|
| 2081 | 
 | 
|---|
| 2082 |             t.tag = ty_fields;
 | 
|---|
| 2083 |             t.index = -1;
 | 
|---|
| 2084 |             t.d.fields.count = 1;
 | 
|---|
| 2085 |             t.d.fields.list = xmalloc (1 * sizeof (*t.d.fields.list));
 | 
|---|
| 2086 |             t.d.fields.list[0].offset = 0;
 | 
|---|
| 2087 |             t.d.fields.list[0].name = strpool_add (str_pool, "This_Is_an_Incomplete_Structure_SORRY");
 | 
|---|
| 2088 |             t2 = type_add (&t);
 | 
|---|
| 2089 |             free (t.d.fields.list);
 | 
|---|
| 2090 | 
 | 
|---|
| 2091 |             t.tag = ty_struc;
 | 
|---|
| 2092 |             t.index = -1;
 | 
|---|
| 2093 |             t.d.struc.types = t1;
 | 
|---|
| 2094 |             t.d.struc.fields = t2;
 | 
|---|
| 2095 |             t.d.struc.size = 1;
 | 
|---|
| 2096 |             t.d.struc.count = 1;
 | 
|---|
| 2097 |             t.d.struc.name = strpool_addn (str_pool, parse_ptr, p1 - parse_ptr);
 | 
|---|
| 2098 |             t.d.struc.flags = STRUC_FORWARD;
 | 
|---|
| 2099 | 
 | 
|---|
| 2100 |             /* Avoid adding an incomplete type if the complete one is
 | 
|---|
| 2101 |                already defined.  We're ignoring scoping (TODO). */
 | 
|---|
| 2102 | 
 | 
|---|
| 2103 |             for (t3 = type_head; t3 != NULL; t3 = t3->next)
 | 
|---|
| 2104 |               if ((t3->tag == ty_struc && t3->d.struc.name == t.d.struc.name
 | 
|---|
| 2105 |                    && !(t3->d.struc.flags & STRUC_FORWARD))
 | 
|---|
| 2106 |                   || (t3->tag == ty_class && t3->d.class.name == t.d.struc.name))
 | 
|---|
| 2107 |                 {
 | 
|---|
| 2108 |                   result = t3;
 | 
|---|
| 2109 |                   break;
 | 
|---|
| 2110 |                 }
 | 
|---|
| 2111 |             break;
 | 
|---|
| 2112 |           }
 | 
|---|
| 2113 | 
 | 
|---|
| 2114 |         case 'e':
 | 
|---|
| 2115 |           { /* just make it a primary. */
 | 
|---|
| 2116 |             /** @todo make an enum perhaps? */
 | 
|---|
| 2117 |             t.tag = ty_prim;
 | 
|---|
| 2118 |             t.index = 0x82;             /* 32 bit signed */
 | 
|---|
| 2119 |             break;
 | 
|---|
| 2120 |           }
 | 
|---|
| 2121 | 
 | 
|---|
| 2122 |         default:
 | 
|---|
| 2123 |           warning ("Unknown forward reference: %c", ch);
 | 
|---|
| 2124 |           parse_ptr = p1 + 1;
 | 
|---|
| 2125 |           goto syntax;
 | 
|---|
| 2126 |         }
 | 
|---|
| 2127 |       parse_ptr = p1 + 1;
 | 
|---|
| 2128 |       break;
 | 
|---|
| 2129 | 
 | 
|---|
| 2130 |     case 's':                           /* struct, class */
 | 
|---|
| 2131 |     case 'u':                           /* union */
 | 
|---|
| 2132 | 
 | 
|---|
| 2133 |       /* Structures, unions and classes:
 | 
|---|
| 2134 | 
 | 
|---|
| 2135 |          s<size>[<baseclasses>]{<field>}{<method>}
 | 
|---|
| 2136 | 
 | 
|---|
| 2137 |          BASECLASSES: !<#baseclasses>,{<baseclass>;}
 | 
|---|
| 2138 |          BASECLASS:   <virtuality><visibility><offset>,<type>
 | 
|---|
| 2139 |          FIELD:       <name>:[/0|1|2]<type>,<offset>,<width>;
 | 
|---|
| 2140 |          FIELD:       <name>:[/0|1|2]<type>:<static_name>;
 | 
|---|
| 2141 |          METHOD:      <name>::{<type>:<args>};
 | 
|---|
| 2142 | 
 | 
|---|
| 2143 |          */
 | 
|---|
| 2144 | 
 | 
|---|
| 2145 |       ++parse_ptr;
 | 
|---|
| 2146 |       class_flag = FALSE;
 | 
|---|
| 2147 |       if (!parse_number (&size))
 | 
|---|
| 2148 |         goto syntax;
 | 
|---|
| 2149 |       grow_init (&g1, &tmp_fields, sizeof (*tmp_fields), 8);
 | 
|---|
| 2150 | 
 | 
|---|
| 2151 |       /* Parse the base classes, if present. */
 | 
|---|
| 2152 | 
 | 
|---|
| 2153 |       if (*parse_ptr == '!')
 | 
|---|
| 2154 |         {
 | 
|---|
| 2155 |           long i, n;
 | 
|---|
| 2156 | 
 | 
|---|
| 2157 |           ++parse_ptr;
 | 
|---|
| 2158 |           class_flag = TRUE;
 | 
|---|
| 2159 |           if (!parse_number (&n) || !parse_char (','))
 | 
|---|
| 2160 |             goto syntax;
 | 
|---|
| 2161 |           for (i = 0; i < n; ++i)
 | 
|---|
| 2162 |             {
 | 
|---|
| 2163 |               grow_by (&g1, 1);
 | 
|---|
| 2164 |               tf = &tmp_fields[g1.count++];
 | 
|---|
| 2165 |               tf->flags = MEMBER_BASE;
 | 
|---|
| 2166 |               tf->name = NULL;
 | 
|---|
| 2167 |               tf->sname = NULL;
 | 
|---|
| 2168 |               switch (*parse_ptr)
 | 
|---|
| 2169 |                 {
 | 
|---|
| 2170 |                 case '0':
 | 
|---|
| 2171 |                   ++parse_ptr;
 | 
|---|
| 2172 |                   break;
 | 
|---|
| 2173 |                 case '1':
 | 
|---|
| 2174 |                   tf->flags |= MEMBER_VIRTUAL;
 | 
|---|
| 2175 |                   ++parse_ptr;
 | 
|---|
| 2176 |                   break;
 | 
|---|
| 2177 |                 default:
 | 
|---|
| 2178 |                   warning ("Invalid base class visibility: %c", *parse_ptr);
 | 
|---|
| 2179 |                   if (*parse_ptr != 0)
 | 
|---|
| 2180 |                     ++parse_ptr;
 | 
|---|
| 2181 |                 }
 | 
|---|
| 2182 | 
 | 
|---|
| 2183 |               tf->flags |= parse_visibility ();
 | 
|---|
| 2184 |               if (!parse_number (&offset) || !parse_char (','))
 | 
|---|
| 2185 |                 goto syntax;
 | 
|---|
| 2186 |               tf->offset = offset >> 3;
 | 
|---|
| 2187 |               t1 = parse_type (NULL);
 | 
|---|
| 2188 |               switch (t1->tag)
 | 
|---|
| 2189 |                 {
 | 
|---|
| 2190 |                 case ty_class:
 | 
|---|
| 2191 |                   break;
 | 
|---|
| 2192 |                 case ty_struc:
 | 
|---|
| 2193 |                   /* kso #456 2003-06-11: Don't mess with forward defines! */
 | 
|---|
| 2194 |                   if (!(   (t1->d.struc.flags & STRUC_FORWARD)
 | 
|---|
| 2195 |                         /*&& t1->d.struc.types == NULL
 | 
|---|
| 2196 |                         && t1->d.struc.fields == NULL*/))
 | 
|---|
| 2197 |                     struct_to_class (t1);
 | 
|---|
| 2198 |                   break;
 | 
|---|
| 2199 |                 default:
 | 
|---|
| 2200 |                   warning ("Invalid base class type");
 | 
|---|
| 2201 |                 }
 | 
|---|
| 2202 |               tf->type = t1;
 | 
|---|
| 2203 |               if (!parse_char (';'))
 | 
|---|
| 2204 |                 goto syntax;
 | 
|---|
| 2205 |             }
 | 
|---|
| 2206 |         }
 | 
|---|
| 2207 | 
 | 
|---|
| 2208 |       while (*parse_ptr != ';')
 | 
|---|
| 2209 |         {
 | 
|---|
| 2210 |           p1 = nextcolon (parse_ptr);
 | 
|---|
| 2211 |           if (p1 == NULL)
 | 
|---|
| 2212 |             {
 | 
|---|
| 2213 |               warning ("Invalid structure type: missing colon");
 | 
|---|
| 2214 |               goto syntax;
 | 
|---|
| 2215 |             }
 | 
|---|
| 2216 |           n = p1 - parse_ptr;
 | 
|---|
| 2217 |           grow_by (&g1, 1);
 | 
|---|
| 2218 |           tf = &tmp_fields[g1.count++];
 | 
|---|
| 2219 |           tf->type = NULL;
 | 
|---|
| 2220 |           tf->offset = 0;
 | 
|---|
| 2221 |           tf->flags = VIS_PUBLIC;
 | 
|---|
| 2222 |           tf->name = strpool_addn (str_pool, parse_ptr, n);
 | 
|---|
| 2223 |           tf->mnglname = tf->sname = NULL;
 | 
|---|
| 2224 |           parse_ptr = p1 + 1;
 | 
|---|
| 2225 |           if (*parse_ptr == ':')
 | 
|---|
| 2226 |             {
 | 
|---|
| 2227 |               class_flag = TRUE;
 | 
|---|
| 2228 |               ++parse_ptr;
 | 
|---|
| 2229 |               do
 | 
|---|
| 2230 |                 {
 | 
|---|
| 2231 |                   const char * pszMangled;
 | 
|---|
| 2232 | 
 | 
|---|
| 2233 |                   t1 = parse_type (NULL);
 | 
|---|
| 2234 |                   offset = 0;
 | 
|---|
| 2235 |                   if (t1 == NULL || t1->tag != ty_func)
 | 
|---|
| 2236 |                     {
 | 
|---|
| 2237 |                       no_warning ("Invalid member function type");
 | 
|---|
| 2238 |                       goto syntax;
 | 
|---|
| 2239 |                     }
 | 
|---|
| 2240 | 
 | 
|---|
| 2241 |                   if (*parse_ptr != ':')
 | 
|---|
| 2242 |                     {
 | 
|---|
| 2243 |                       no_warning ("Arguments for member function missing");
 | 
|---|
| 2244 |                       goto syntax;
 | 
|---|
| 2245 |                     }
 | 
|---|
| 2246 |                   ++parse_ptr;
 | 
|---|
| 2247 |                   pszMangled = parse_ptr;
 | 
|---|
| 2248 |                   if (!parse_mangled_args ())
 | 
|---|
| 2249 |                     goto syntax;
 | 
|---|
| 2250 |                   tf->mnglname = strpool_addn(str_pool, pszMangled, parse_ptr - pszMangled - 1); /* ASSUMES no extra spaces! */
 | 
|---|
| 2251 |                   tf->flags = parse_visibility () | MEMBER_FUNCTION;
 | 
|---|
| 2252 |                   switch (*parse_ptr)
 | 
|---|
| 2253 |                     {
 | 
|---|
| 2254 |                     case 'A':
 | 
|---|
| 2255 |                       ++parse_ptr;
 | 
|---|
| 2256 |                       break;
 | 
|---|
| 2257 |                     case 'B':
 | 
|---|
| 2258 |                       tf->flags |= MEMBER_CONST;
 | 
|---|
| 2259 |                       ++parse_ptr;
 | 
|---|
| 2260 |                       break;
 | 
|---|
| 2261 |                     case 'C':
 | 
|---|
| 2262 |                       tf->flags |= MEMBER_VOLATILE;
 | 
|---|
| 2263 |                       ++parse_ptr;
 | 
|---|
| 2264 |                       break;
 | 
|---|
| 2265 |                     case 'D':
 | 
|---|
| 2266 |                       tf->flags |= MEMBER_CONST | MEMBER_VOLATILE;
 | 
|---|
| 2267 |                       ++parse_ptr;
 | 
|---|
| 2268 |                       break;
 | 
|---|
| 2269 |                     default:
 | 
|---|
| 2270 |                       no_warning ("Unknown member function qualifier: %c",
 | 
|---|
| 2271 |                                *parse_ptr);
 | 
|---|
| 2272 |                       if (*parse_ptr != 0)
 | 
|---|
| 2273 |                         ++parse_ptr;
 | 
|---|
| 2274 |                     }
 | 
|---|
| 2275 |                   switch (*parse_ptr)
 | 
|---|
| 2276 |                     {
 | 
|---|
| 2277 |                     case '.':
 | 
|---|
| 2278 |                       ++parse_ptr;
 | 
|---|
| 2279 |                       break;
 | 
|---|
| 2280 |                     case '*':
 | 
|---|
| 2281 |                       tf->flags |= MEMBER_VIRTUAL;
 | 
|---|
| 2282 |                       ++parse_ptr;
 | 
|---|
| 2283 |                       if (!parse_number (&offset) || !parse_char (';'))
 | 
|---|
| 2284 |                         {
 | 
|---|
| 2285 |                           warning ("Invalid data for virtual member function");
 | 
|---|
| 2286 |                           goto syntax;
 | 
|---|
| 2287 |                         }
 | 
|---|
| 2288 |                       parse_type (NULL);
 | 
|---|
| 2289 |                       if (!parse_char (';'))
 | 
|---|
| 2290 |                         {
 | 
|---|
| 2291 |                           warning ("Invalid data for virtual member function");
 | 
|---|
| 2292 |                           goto syntax;
 | 
|---|
| 2293 |                         }
 | 
|---|
| 2294 |                       break;
 | 
|---|
| 2295 |                     case '?':
 | 
|---|
| 2296 |                       tf->flags |= MEMBER_STATIC;
 | 
|---|
| 2297 |                       ++parse_ptr;
 | 
|---|
| 2298 |                       break;
 | 
|---|
| 2299 |                     default:
 | 
|---|
| 2300 |                       no_warning ("Unknown member function qualifier: %c",
 | 
|---|
| 2301 |                                *parse_ptr);
 | 
|---|
| 2302 |                       if (*parse_ptr != 0)
 | 
|---|
| 2303 |                         ++parse_ptr;
 | 
|---|
| 2304 |                     }
 | 
|---|
| 2305 |                   /* Contstructor / Destructor hack -
 | 
|---|
| 2306 |                    * TODO: verify that this doesn't really work with overloaded constructors and fix it.
 | 
|---|
| 2307 |                    */
 | 
|---|
| 2308 |                   if (!(tf->flags & MEMBER_STATIC))
 | 
|---|
| 2309 |                     {
 | 
|---|
| 2310 |                       /* using the strpool is much faster! */
 | 
|---|
| 2311 |                       static const char *pszCompCtor, *pszBaseCtor, *pszCompDtor, *pszBaseDtor = NULL;
 | 
|---|
| 2312 |                       if (!pszBaseDtor)
 | 
|---|
| 2313 |                         {
 | 
|---|
| 2314 |                           pszCompCtor = strpool_addn(str_pool, "__comp_ctor", 11);
 | 
|---|
| 2315 |                           pszBaseCtor = strpool_addn(str_pool, "__base_ctor", 11);
 | 
|---|
| 2316 |                           pszCompDtor = strpool_addn(str_pool, "__comp_dtor", 11);
 | 
|---|
| 2317 |                           pszBaseDtor = strpool_addn(str_pool, "__base_dtor", 11);
 | 
|---|
| 2318 |                         }
 | 
|---|
| 2319 | 
 | 
|---|
| 2320 |                       if (tf->name == pszCompCtor || tf->name == pszBaseCtor)
 | 
|---|
| 2321 |                           tf->flags |= MEMBER_CTOR;
 | 
|---|
| 2322 |                       else if (tf->name == pszCompDtor || tf->name == pszBaseDtor)
 | 
|---|
| 2323 |                           tf->flags |= MEMBER_DTOR;
 | 
|---|
| 2324 |                     }
 | 
|---|
| 2325 |                   tf->type = t1;
 | 
|---|
| 2326 |                   tf->offset = offset;
 | 
|---|
| 2327 |                   if (*parse_ptr != ';')
 | 
|---|
| 2328 |                     {
 | 
|---|
| 2329 |                       /* Another member function with the same name
 | 
|---|
| 2330 |                          follows. */
 | 
|---|
| 2331 | 
 | 
|---|
| 2332 |                       grow_by (&g1, 1);
 | 
|---|
| 2333 |                       tf = &tmp_fields[g1.count++];
 | 
|---|
| 2334 |                       tf->flags = VIS_PUBLIC | MEMBER_FUNCTION;
 | 
|---|
| 2335 |                       tf->name = tf[-1].name;
 | 
|---|
| 2336 |                     }
 | 
|---|
| 2337 |                 } while (*parse_ptr != ';');
 | 
|---|
| 2338 |               ++parse_ptr;
 | 
|---|
| 2339 |             }
 | 
|---|
| 2340 |           else
 | 
|---|
| 2341 |             {
 | 
|---|
| 2342 |               if (*parse_ptr == '/')
 | 
|---|
| 2343 |                 {
 | 
|---|
| 2344 |                   class_flag = TRUE;
 | 
|---|
| 2345 |                   ++parse_ptr;
 | 
|---|
| 2346 |                   tf->flags = parse_visibility ();
 | 
|---|
| 2347 |                 }
 | 
|---|
| 2348 |               t1 = parse_type (NULL);
 | 
|---|
| 2349 |               if (*parse_ptr == ':')
 | 
|---|
| 2350 |                 {
 | 
|---|
| 2351 |                   /* Static member */
 | 
|---|
| 2352 | 
 | 
|---|
| 2353 |                   ++parse_ptr;
 | 
|---|
| 2354 |                   tf->flags |= MEMBER_STATIC;
 | 
|---|
| 2355 |                   p1 = strchr (parse_ptr, ';');
 | 
|---|
| 2356 |                   if (p1 == NULL)
 | 
|---|
| 2357 |                     {
 | 
|---|
| 2358 |                       warning ("Invalid static member: missing semicolon");
 | 
|---|
| 2359 |                       goto syntax;
 | 
|---|
| 2360 |                     }
 | 
|---|
| 2361 |                   n = p1 - parse_ptr;
 | 
|---|
| 2362 |                   tf->sname = strpool_addn (str_pool, parse_ptr, n);
 | 
|---|
| 2363 |                   parse_ptr = p1 + 1;
 | 
|---|
| 2364 |                   tf->offset = 0;
 | 
|---|
| 2365 |                 }
 | 
|---|
| 2366 |               else
 | 
|---|
| 2367 |                 {
 | 
|---|
| 2368 |                   if (!parse_char (',') || !parse_number (&offset))
 | 
|---|
| 2369 |                     goto syntax;
 | 
|---|
| 2370 |                   if (*parse_ptr == ',')
 | 
|---|
| 2371 |                     {
 | 
|---|
| 2372 |                       ++parse_ptr;
 | 
|---|
| 2373 |                       if (!parse_number (&width))
 | 
|---|
| 2374 |                         goto syntax;
 | 
|---|
| 2375 |                     }
 | 
|---|
| 2376 |                   else
 | 
|---|
| 2377 |                     width = 0;      /* vtable pointer field */
 | 
|---|
| 2378 |                   if (!parse_char (';'))
 | 
|---|
| 2379 |                     goto syntax;
 | 
|---|
| 2380 |                   if ((offset & 7) != 0 || width != 8 * type_size (t1))
 | 
|---|
| 2381 |                     {
 | 
|---|
| 2382 |                       t.tag = ty_bits;
 | 
|---|
| 2383 |                       t.d.bits.type = t1;
 | 
|---|
| 2384 |                       t.d.bits.start = offset & 7;
 | 
|---|
| 2385 |                       t.d.bits.count = width;
 | 
|---|
| 2386 |                       t1 = type_add (&t);
 | 
|---|
| 2387 |                     }
 | 
|---|
| 2388 |                   tf->offset = offset >> 3;
 | 
|---|
| 2389 |                 }
 | 
|---|
| 2390 |               tf->type = t1;
 | 
|---|
| 2391 |             }
 | 
|---|
| 2392 | 
 | 
|---|
| 2393 |           /* the debuggers croak if the field doesn't have a name. */
 | 
|---|
| 2394 | 
 | 
|---|
| 2395 |           if ((!tf->name || !*tf->name) 
 | 
|---|
| 2396 |            && (!tf->sname || !*tf->sname)
 | 
|---|
| 2397 |            && (!tf->mnglname || !*tf->mnglname))
 | 
|---|
| 2398 |             tf->name = strpool_add (str_pool, "<anonymous>");
 | 
|---|
| 2399 |         }
 | 
|---|
| 2400 |       ++parse_ptr;
 | 
|---|
| 2401 |       if (*parse_ptr == '~')
 | 
|---|
| 2402 |         {
 | 
|---|
| 2403 |           /* Type reference to the first base class.  This field is
 | 
|---|
| 2404 |              present for classes which contain virtual functions. */
 | 
|---|
| 2405 | 
 | 
|---|
| 2406 |           ++parse_ptr;
 | 
|---|
| 2407 |           if (!parse_char ('%'))
 | 
|---|
| 2408 |             goto syntax;
 | 
|---|
| 2409 |           t1 = parse_type (NULL);
 | 
|---|
| 2410 |           if (!parse_char (';'))
 | 
|---|
| 2411 |             goto syntax;
 | 
|---|
| 2412 |         }
 | 
|---|
| 2413 | 
 | 
|---|
| 2414 |       if (class_flag)
 | 
|---|
| 2415 |         {
 | 
|---|
| 2416 |           tlist = xmalloc (g1.count * sizeof (*t.d.types.list));
 | 
|---|
| 2417 |           for (i = 0; i < g1.count; ++i)
 | 
|---|
| 2418 |             {
 | 
|---|
| 2419 |               if (tmp_fields[i].flags & MEMBER_FUNCTION)
 | 
|---|
| 2420 |                 {
 | 
|---|
| 2421 |                   t2 = tmp_fields[i].type;
 | 
|---|
| 2422 |                   tt = follow_refs (t2)->tag;
 | 
|---|
| 2423 |                   /* TODO: check later if ty_stabs_ref */
 | 
|---|
| 2424 |                   if (tt != ty_func && tt != ty_stabs_ref)
 | 
|---|
| 2425 |                     error ("Invalid type for member function %s",
 | 
|---|
| 2426 |                            tmp_fields[i].name);
 | 
|---|
| 2427 |                   t.tag = ty_memfunc;
 | 
|---|
| 2428 |                   t.d.memfunc.type = t2;
 | 
|---|
| 2429 |                   t.d.memfunc.name = tmp_fields[i].name;
 | 
|---|
| 2430 |                   t.d.memfunc.mnglname = tmp_fields[i].mnglname;
 | 
|---|
| 2431 |                   t.d.memfunc.flags = tmp_fields[i].flags;
 | 
|---|
| 2432 |                   t.d.memfunc.offset = tmp_fields[i].offset;
 | 
|---|
| 2433 |                 }
 | 
|---|
| 2434 |               else if (tmp_fields[i].flags & MEMBER_BASE)
 | 
|---|
| 2435 |                 {
 | 
|---|
| 2436 |                   t.tag = ty_baseclass;
 | 
|---|
| 2437 |                   t.d.baseclass.type = tmp_fields[i].type;
 | 
|---|
| 2438 |                   t.d.baseclass.flags = tmp_fields[i].flags;
 | 
|---|
| 2439 |                   t.d.baseclass.offset = tmp_fields[i].offset;
 | 
|---|
| 2440 |                 }
 | 
|---|
| 2441 |               else
 | 
|---|
| 2442 |                 {
 | 
|---|
| 2443 |                   t.tag = ty_member;
 | 
|---|
| 2444 |                   t.d.member.type = tmp_fields[i].type;
 | 
|---|
| 2445 |                   t.d.member.offset = tmp_fields[i].offset;
 | 
|---|
| 2446 |                   t.d.member.flags = tmp_fields[i].flags;
 | 
|---|
| 2447 |                   t.d.member.name = tmp_fields[i].name;
 | 
|---|
| 2448 |                   t.d.member.sname = tmp_fields[i].sname;
 | 
|---|
| 2449 |                 }
 | 
|---|
| 2450 |               t2 = type_add (&t);
 | 
|---|
| 2451 |               tlist[i] = t2;
 | 
|---|
| 2452 |             }
 | 
|---|
| 2453 |           t.tag = ty_types;
 | 
|---|
| 2454 |           t.d.types.count = g1.count;
 | 
|---|
| 2455 |           t.d.types.list = tlist;
 | 
|---|
| 2456 |           t1 = type_add (&t);
 | 
|---|
| 2457 |           free (tlist);
 | 
|---|
| 2458 | 
 | 
|---|
| 2459 |           t.tag = ty_class;
 | 
|---|
| 2460 |           t.d.class.members = t1;
 | 
|---|
| 2461 |           t.d.class.size = size;
 | 
|---|
| 2462 |           t.d.class.count = g1.count;
 | 
|---|
| 2463 |           t.d.class.name = add_struct_name (type_name);
 | 
|---|
| 2464 | 
 | 
|---|
| 2465 |           /* Check if there is an incomplete type waiting to be filled
 | 
|---|
| 2466 |              in (forward reference).  We're ignoring scoping (TODO). */
 | 
|---|
| 2467 | 
 | 
|---|
| 2468 |           for (t3 = type_head; t3 != NULL; t3 = t3->next)
 | 
|---|
| 2469 |             if (t3->tag == ty_struc && t3->d.struc.name == t.d.class.name
 | 
|---|
| 2470 |                 /*&& t3->d.struc.types == NULL && t3->d.struc.fields == NULL */
 | 
|---|
| 2471 |                 && (t3->d.struc.flags & STRUC_FORWARD))
 | 
|---|
| 2472 |               {
 | 
|---|
| 2473 |                 if (t3->index != -1)
 | 
|---|
| 2474 |                   warning ("This cannot happen, case 1");
 | 
|---|
| 2475 |                 result = t3;
 | 
|---|
| 2476 |                 t3->tag = ty_class;
 | 
|---|
| 2477 |                 t3->d.class = t.d.class;
 | 
|---|
| 2478 |                 break;
 | 
|---|
| 2479 |               }
 | 
|---|
| 2480 |         }
 | 
|---|
| 2481 |       else
 | 
|---|
| 2482 |         {
 | 
|---|
| 2483 |           t.tag = ty_types;
 | 
|---|
| 2484 |           t.d.types.count = g1.count;
 | 
|---|
| 2485 |           t.d.types.list = xmalloc (g1.count * sizeof (*t.d.types.list));
 | 
|---|
| 2486 |           for (i = 0; i < g1.count; ++i)
 | 
|---|
| 2487 |             t.d.types.list[i] = tmp_fields[i].type;
 | 
|---|
| 2488 |           t1 = type_add (&t);
 | 
|---|
| 2489 |           free (t.d.types.list);
 | 
|---|
| 2490 | 
 | 
|---|
| 2491 |           t.tag = ty_fields;
 | 
|---|
| 2492 |           t.d.fields.count = g1.count;
 | 
|---|
| 2493 |           t.d.fields.list = xmalloc (g1.count * sizeof (*t.d.fields.list));
 | 
|---|
| 2494 |           for (i = 0; i < g1.count; ++i)
 | 
|---|
| 2495 |             {
 | 
|---|
| 2496 |               t.d.fields.list[i].offset = tmp_fields[i].offset;
 | 
|---|
| 2497 |               t.d.fields.list[i].name = tmp_fields[i].name;
 | 
|---|
| 2498 |             }
 | 
|---|
| 2499 |           t2 = type_add (&t);
 | 
|---|
| 2500 |           free (t.d.fields.list);
 | 
|---|
| 2501 | 
 | 
|---|
| 2502 |           t.tag = ty_struc;
 | 
|---|
| 2503 |           t.d.struc.count = g1.count;
 | 
|---|
| 2504 |           t.d.struc.size = size;
 | 
|---|
| 2505 |           t.d.struc.types = t1;
 | 
|---|
| 2506 |           t.d.struc.fields = t2;
 | 
|---|
| 2507 |           t.d.struc.name = add_struct_name (type_name);
 | 
|---|
| 2508 |           t.d.struc.flags = 0;
 | 
|---|
| 2509 | 
 | 
|---|
| 2510 |           /* Check if there is an incomplete type waiting to be filled
 | 
|---|
| 2511 |              in (forward reference).  We're ignoring scoping (TODO). */
 | 
|---|
| 2512 | 
 | 
|---|
| 2513 |           for (t3 = type_head; t3 != NULL; t3 = t3->next)
 | 
|---|
| 2514 |             if (t3->tag == ty_struc && t3->d.struc.name == t.d.struc.name
 | 
|---|
| 2515 |                 /* && t3->d.struc.types == NULL && t3->d.struc.fields == NULL */
 | 
|---|
| 2516 |                 && (t3->d.struc.flags & STRUC_FORWARD))
 | 
|---|
| 2517 |               {
 | 
|---|
| 2518 |                 if (t3->index != -1)
 | 
|---|
| 2519 |                   warning ("This cannot happen, case 1");
 | 
|---|
| 2520 |                 result = t3;
 | 
|---|
| 2521 |                 t3->d.struc = t.d.struc;
 | 
|---|
| 2522 |                 break;
 | 
|---|
| 2523 |               }
 | 
|---|
| 2524 |         }
 | 
|---|
| 2525 |       grow_free (&g1);
 | 
|---|
| 2526 |       break;
 | 
|---|
| 2527 | 
 | 
|---|
| 2528 |     case 'e':
 | 
|---|
| 2529 |       size = 32;
 | 
|---|
| 2530 | l_parse_enum:
 | 
|---|
| 2531 | 
 | 
|---|
| 2532 |       /* Enumeration type: e{<name>:<value>,}; */
 | 
|---|
| 2533 | 
 | 
|---|
| 2534 |       ++parse_ptr;
 | 
|---|
| 2535 |       grow_init (&g1, &tmp_values, sizeof (*tmp_values), 8);
 | 
|---|
| 2536 |       while (*parse_ptr != ';')
 | 
|---|
| 2537 |         {
 | 
|---|
| 2538 |           p1 = nextcolon (parse_ptr);
 | 
|---|
| 2539 |           if (p1 == NULL)
 | 
|---|
| 2540 |             {
 | 
|---|
| 2541 |               warning ("Invalid enum type: missing colon");
 | 
|---|
| 2542 |               goto syntax;
 | 
|---|
| 2543 |             }
 | 
|---|
| 2544 |           n = p1 - parse_ptr;
 | 
|---|
| 2545 |           grow_by (&g1, 1);
 | 
|---|
| 2546 |           tv = &tmp_values[g1.count++];
 | 
|---|
| 2547 |           tv->name = strpool_addn (str_pool, parse_ptr, n);
 | 
|---|
| 2548 |           parse_ptr = p1 + 1;
 | 
|---|
| 2549 |           if (!parse_number (&tv->index) || !parse_char (','))
 | 
|---|
| 2550 |             goto syntax;
 | 
|---|
| 2551 |         }
 | 
|---|
| 2552 |       ++parse_ptr;
 | 
|---|
| 2553 |       t.tag = ty_values;
 | 
|---|
| 2554 |       t.d.values.count = g1.count;
 | 
|---|
| 2555 |       t.d.values.list = xmalloc (g1.count * sizeof (*t.d.values.list));
 | 
|---|
| 2556 |       if (g1.count == 0)
 | 
|---|
| 2557 |         lo = hi = 0;
 | 
|---|
| 2558 |       else
 | 
|---|
| 2559 |         lo = hi = tmp_values[0].index;
 | 
|---|
| 2560 |       for (i = 0; i < g1.count; ++i)
 | 
|---|
| 2561 |         {
 | 
|---|
| 2562 |           t.d.values.list[i].index = tmp_values[i].index;
 | 
|---|
| 2563 |           t.d.values.list[i].name = tmp_values[i].name;
 | 
|---|
| 2564 |           if (tmp_values[i].index < lo)
 | 
|---|
| 2565 |             lo = tmp_values[i].index;
 | 
|---|
| 2566 |           if (tmp_values[i].index > hi)
 | 
|---|
| 2567 |             hi = tmp_values[i].index;
 | 
|---|
| 2568 |         }
 | 
|---|
| 2569 |       t1 = type_add (&t);
 | 
|---|
| 2570 |       free (t.d.values.list);
 | 
|---|
| 2571 | 
 | 
|---|
| 2572 |       t.tag = ty_prim;
 | 
|---|
| 2573 |       switch (size)
 | 
|---|
| 2574 |         {
 | 
|---|
| 2575 |         case 8:  t.index = 0x80; break;   /* 8 bit signed */
 | 
|---|
| 2576 |         case 16: t.index = 0x81; break;   /* 16 bit signed */
 | 
|---|
| 2577 |         case 32: t.index = 0x82; break;   /* 32 bit signed */
 | 
|---|
| 2578 |         case 64: result = t2 = make_long_long (); break;
 | 
|---|
| 2579 |         default: goto syntax;
 | 
|---|
| 2580 |         }
 | 
|---|
| 2581 |       if (!result)
 | 
|---|
| 2582 |         t2 = type_add (&t);
 | 
|---|
| 2583 | 
 | 
|---|
| 2584 |       t.tag = ty_enu;
 | 
|---|
| 2585 |       t.index = -1;
 | 
|---|
| 2586 |       t.d.enu.values = t1;
 | 
|---|
| 2587 |       t.d.enu.type = t2;
 | 
|---|
| 2588 |       t.d.enu.name = add_struct_name (type_name);
 | 
|---|
| 2589 |       t.d.enu.first = lo;
 | 
|---|
| 2590 |       t.d.enu.last = hi;
 | 
|---|
| 2591 |       grow_free (&g1);
 | 
|---|
| 2592 |       break;
 | 
|---|
| 2593 | 
 | 
|---|
| 2594 |     case 'a':
 | 
|---|
| 2595 |       /* An array: ar<index_type>;<lower_bound>;<upper_bound>;<el_type> */
 | 
|---|
| 2596 | 
 | 
|---|
| 2597 |       ++parse_ptr;
 | 
|---|
| 2598 |       if (!parse_char ('r'))
 | 
|---|
| 2599 |         goto syntax;
 | 
|---|
| 2600 |       if (strncmp (parse_ptr, "0;", 2) == 0)
 | 
|---|
| 2601 |         {
 | 
|---|
| 2602 |           /* This invalid type index seems to be caused by a bug of
 | 
|---|
| 2603 |              GCC 2.8.1.  Replace with a 32-bit signed integer. */
 | 
|---|
| 2604 | 
 | 
|---|
| 2605 |           t.tag = ty_prim;
 | 
|---|
| 2606 |           t.index = 0x82;       /* 32 bit signed */
 | 
|---|
| 2607 |           t1 = type_add (&t);
 | 
|---|
| 2608 |           ++parse_ptr;
 | 
|---|
| 2609 |         }
 | 
|---|
| 2610 |       else
 | 
|---|
| 2611 |         t1 = parse_type (NULL); /* Index type */
 | 
|---|
| 2612 |       if (!parse_char (';')
 | 
|---|
| 2613 |           || !parse_number (&lo) || !parse_char (';')   /* Lower bound */
 | 
|---|
| 2614 |           || !parse_number (&hi) || !parse_char (';'))  /* Upper bound */
 | 
|---|
| 2615 |         goto syntax;
 | 
|---|
| 2616 |       t2 = parse_type (NULL);   /* Elements type */
 | 
|---|
| 2617 |       if (lo == 0 && hi == 0)   /* Variable-length array */
 | 
|---|
| 2618 |         {
 | 
|---|
| 2619 |           t.tag = ty_pointer;   /* Turn into pointer */
 | 
|---|
| 2620 |           t.d.pointer = t2;
 | 
|---|
| 2621 |         }
 | 
|---|
| 2622 |       else
 | 
|---|
| 2623 |         {
 | 
|---|
| 2624 |           t.tag = ty_array;
 | 
|---|
| 2625 |           t.d.array.first = lo;
 | 
|---|
| 2626 |           t.d.array.last = hi;
 | 
|---|
| 2627 |           t.d.array.itype = t1;
 | 
|---|
| 2628 |           t.d.array.etype = t2;
 | 
|---|
| 2629 |         }
 | 
|---|
| 2630 |       break;
 | 
|---|
| 2631 | 
 | 
|---|
| 2632 |     case 'f':
 | 
|---|
| 2633 | 
 | 
|---|
| 2634 |       /* A function: f<return_type> */
 | 
|---|
| 2635 | 
 | 
|---|
| 2636 |       ++parse_ptr;
 | 
|---|
| 2637 |       t1 = parse_type (NULL);   /* Return type */
 | 
|---|
| 2638 |       t.tag = ty_func;
 | 
|---|
| 2639 |       t.d.func.ret = t1;
 | 
|---|
| 2640 |       t.d.func.domain = NULL;
 | 
|---|
| 2641 |       t.d.func.args = NULL;
 | 
|---|
| 2642 |       t.d.func.arg_count = 0;
 | 
|---|
| 2643 |       break;
 | 
|---|
| 2644 | 
 | 
|---|
| 2645 |     default:
 | 
|---|
| 2646 |       no_warning ("Unknown type: %c", *parse_ptr);
 | 
|---|
| 2647 |       goto syntax;
 | 
|---|
| 2648 |     }
 | 
|---|
| 2649 | 
 | 
|---|
| 2650 |   /* Add the type to the tables. */
 | 
|---|
| 2651 | 
 | 
|---|
| 2652 |   if (result == NULL)
 | 
|---|
| 2653 |     result = type_add (&t);
 | 
|---|
| 2654 |   return result;
 | 
|---|
| 2655 | 
 | 
|---|
| 2656 | syntax:
 | 
|---|
| 2657 |   no_warning ("syntax error in stabs: %c (off %ld)\n stabs: %s",
 | 
|---|
| 2658 |               *parse_ptr, parse_ptr - parse_start, parse_start);
 | 
|---|
| 2659 | 
 | 
|---|
| 2660 |   grow_free (&g1);
 | 
|---|
| 2661 |   t.tag = ty_prim;
 | 
|---|
| 2662 |   t.index = 0x82;               /* 32 bit signed */
 | 
|---|
| 2663 |   return type_add (&t);
 | 
|---|
| 2664 | }
 | 
|---|
| 2665 | 
 | 
|---|
| 2666 | 
 | 
|---|
| 2667 | /* Parse a stabs type (the name of the type is TYPE_NAME, which is
 | 
|---|
| 2668 |    NULL for an unnamed type) and check for end of the string.  If not
 | 
|---|
| 2669 |    all characters of the string have been parsed, a warning message is
 | 
|---|
| 2670 |    displayed.  Return the internal representation of the type. */
 | 
|---|
| 2671 | 
 | 
|---|
| 2672 | static struct type *parse_complete_type (const char *type_name)
 | 
|---|
| 2673 | {
 | 
|---|
| 2674 |   struct type *tp;
 | 
|---|
| 2675 | 
 | 
|---|
| 2676 |   tp = parse_type (type_name);
 | 
|---|
| 2677 |   if (*parse_ptr != 0)
 | 
|---|
| 2678 |       no_warning ("unexpected character at end of stabs type: %c (off %ld)\n stabs: %s",
 | 
|---|
| 2679 |                   *parse_ptr, parse_ptr - parse_start, parse_start);
 | 
|---|
| 2680 |   return tp;
 | 
|---|
| 2681 | }
 | 
|---|
| 2682 | 
 | 
|---|
| 2683 | 
 | 
|---|
| 2684 | /* Create an HLL type number for type TP. If a type number has already
 | 
|---|
| 2685 |    been assigned to TP, use that number.  Otherwise, allocate a new
 | 
|---|
| 2686 |    (complex) type number and define the type in the $$TYPES segment.
 | 
|---|
| 2687 |    The HLL type number us stored to *HLL.
 | 
|---|
| 2688 | 
 | 
|---|
| 2689 |    Note: This function must not be called between sst_start() and
 | 
|---|
| 2690 |    sst_end() or tt_start() and tt_end() as entries are made both in
 | 
|---|
| 2691 |    the SST ($$SYMBOLS) and the type table ($$TYPES). */
 | 
|---|
| 2692 | 
 | 
|---|
| 2693 | static void make_type (struct type *tp, int *hll)
 | 
|---|
| 2694 | {
 | 
|---|
| 2695 |   struct type *t1;
 | 
|---|
| 2696 |   int ti_1, ti_2, ti_3, i, qual;
 | 
|---|
| 2697 |   int patch1;
 | 
|---|
| 2698 | 
 | 
|---|
| 2699 | #define RETURN(X) do {*hll = (X); return;} while (0)
 | 
|---|
| 2700 | 
 | 
|---|
| 2701 |   if (tp->index <= -2)
 | 
|---|
| 2702 |     {
 | 
|---|
| 2703 |       /* bird: A hack where we allow a 2nd recursion of rectain types.
 | 
|---|
| 2704 |        * The normal issue is C++ class references. */
 | 
|---|
| 2705 |       if (tp->tag != ty_alias || tp->index <= -3)
 | 
|---|
| 2706 |         {
 | 
|---|
| 2707 |           warning_parse ("Cycle detected by make_type.");
 | 
|---|
| 2708 |           RETURN (0);
 | 
|---|
| 2709 |         }
 | 
|---|
| 2710 |     }
 | 
|---|
| 2711 |   if (tp->index > -1)
 | 
|---|
| 2712 |     RETURN (tp->index);
 | 
|---|
| 2713 |   tp->index--;
 | 
|---|
| 2714 |   switch (tp->tag)
 | 
|---|
| 2715 |     {
 | 
|---|
| 2716 |     case ty_stabs_ref:
 | 
|---|
| 2717 |       t1 = stype_find (tp->d.stabs_ref);
 | 
|---|
| 2718 |       if (t1 == NULL)
 | 
|---|
| 2719 |         {
 | 
|---|
| 2720 |           warning_parse ("Undefined stabs type %d referenced", tp->d.stabs_ref);
 | 
|---|
| 2721 |           RETURN (0x82);        /* 32 bit signed */
 | 
|---|
| 2722 |         }
 | 
|---|
| 2723 |       make_type (t1, &tp->index);
 | 
|---|
| 2724 |       *hll = tp->index;
 | 
|---|
| 2725 |       break;
 | 
|---|
| 2726 | 
 | 
|---|
| 2727 |     case ty_alias:
 | 
|---|
| 2728 |       make_type (tp->d.alias, &tp->index);
 | 
|---|
| 2729 |       *hll = tp->index;
 | 
|---|
| 2730 |       break;
 | 
|---|
| 2731 | 
 | 
|---|
| 2732 |     case ty_pointer:
 | 
|---|
| 2733 |       ti_1 = tp->d.pointer->index;
 | 
|---|
| 2734 |       if (ti_1 >= 0x80 && ti_1 <= 0xa0)
 | 
|---|
| 2735 |         {
 | 
|---|
| 2736 |           tp->index = ti_1 + 0x20;
 | 
|---|
| 2737 |           RETURN (tp->index);
 | 
|---|
| 2738 |         }
 | 
|---|
| 2739 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2740 |       tt_start (0x7a, 0x01);    /* 32-bit near pointer */
 | 
|---|
| 2741 |       patch1 = tt.size;
 | 
|---|
| 2742 |       tt_index (0);
 | 
|---|
| 2743 |       tt_end ();
 | 
|---|
| 2744 |       make_type (tp->d.pointer, &ti_1);
 | 
|---|
| 2745 |       buffer_patch_word (&tt, patch1+1, ti_1);
 | 
|---|
| 2746 |       break;
 | 
|---|
| 2747 | 
 | 
|---|
| 2748 |     case ty_ref:
 | 
|---|
| 2749 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2750 |       tt_start (0x48, 0x00);    /* Reference type (C++) */
 | 
|---|
| 2751 |       patch1 = tt.size;
 | 
|---|
| 2752 |       tt_word (0);
 | 
|---|
| 2753 |       tt_end ();
 | 
|---|
| 2754 |       make_type (tp->d.ref, &ti_1);
 | 
|---|
| 2755 |       buffer_patch_word (&tt, patch1, ti_1);
 | 
|---|
| 2756 |       break;
 | 
|---|
| 2757 | 
 | 
|---|
| 2758 |     case ty_struc:
 | 
|---|
| 2759 |     {
 | 
|---|
| 2760 |       struct field *fields = NULL;
 | 
|---|
| 2761 |       struct type **types = NULL;
 | 
|---|
| 2762 |       int           cFields = tp->d.struc.count;
 | 
|---|
| 2763 | 
 | 
|---|
| 2764 |       if (    tp->d.struc.fields
 | 
|---|
| 2765 |           &&  tp->d.struc.fields->tag == ty_fields
 | 
|---|
| 2766 |           &&  tp->d.struc.fields->d.fields.count == cFields)
 | 
|---|
| 2767 |           fields = tp->d.struc.fields->d.fields.list;
 | 
|---|
| 2768 |       if (   tp->d.struc.types
 | 
|---|
| 2769 |           && tp->d.struc.types->tag == ty_types
 | 
|---|
| 2770 |           && tp->d.struc.types->d.types.count == cFields)
 | 
|---|
| 2771 |           types = tp->d.struc.types->d.types.list;
 | 
|---|
| 2772 | 
 | 
|---|
| 2773 |       if (cplusplus_flag && ((types && fields) || !cFields))
 | 
|---|
| 2774 |         {
 | 
|---|
| 2775 |           struct type   t;
 | 
|---|
| 2776 |           struct type **list;
 | 
|---|
| 2777 |           int           i;
 | 
|---|
| 2778 |           *hll = tp->index = hll_type_index++;
 | 
|---|
| 2779 |           tt_start (0x40, 0x01);      /* Class is-struct */
 | 
|---|
| 2780 |           tt_dword (tp->d.struc.size);
 | 
|---|
| 2781 |           tt_word (tp->d.struc.count);
 | 
|---|
| 2782 |           patch1 = tt.size;
 | 
|---|
| 2783 |           tt_word (0);                /* Members */
 | 
|---|
| 2784 |           tt_enc (tp->d.struc.name);  /* Class name */
 | 
|---|
| 2785 |           tt_end ();
 | 
|---|
| 2786 | 
 | 
|---|
| 2787 |           list = xmalloc (cFields * sizeof (*list));
 | 
|---|
| 2788 |           for (i = 0; i < cFields; ++i)
 | 
|---|
| 2789 |             {
 | 
|---|
| 2790 |               t.tag             = ty_member;
 | 
|---|
| 2791 |               t.index           = -1;
 | 
|---|
| 2792 |               t.d.member.type   = types[i];
 | 
|---|
| 2793 |               t.d.member.offset = fields[i].offset;
 | 
|---|
| 2794 |               t.d.member.flags  = VIS_PUBLIC;
 | 
|---|
| 2795 |               t.d.member.name   = fields[i].name;
 | 
|---|
| 2796 |               t.d.member.sname  = NULL;
 | 
|---|
| 2797 |               list[i] = type_add (&t);
 | 
|---|
| 2798 |             }
 | 
|---|
| 2799 | 
 | 
|---|
| 2800 |           t.tag = ty_types;
 | 
|---|
| 2801 |           t.index = -1;
 | 
|---|
| 2802 |           t.d.types.count = cFields;
 | 
|---|
| 2803 |           t.d.types.list = list;
 | 
|---|
| 2804 |           t1 = type_add (&t);
 | 
|---|
| 2805 |           free (list);
 | 
|---|
| 2806 | 
 | 
|---|
| 2807 |           make_type (t1, &ti_1);
 | 
|---|
| 2808 |           buffer_patch_word (&tt, patch1, ti_1);
 | 
|---|
| 2809 |         }
 | 
|---|
| 2810 |       else
 | 
|---|
| 2811 |         {
 | 
|---|
| 2812 |           tt_start (0x79, 0x00);    /* Structure/Union */
 | 
|---|
| 2813 |           tt_dword (tp->d.struc.size);
 | 
|---|
| 2814 |           tt_word (tp->d.struc.count);
 | 
|---|
| 2815 |           patch1 = tt.size;
 | 
|---|
| 2816 |           tt_index (0);
 | 
|---|
| 2817 |           tt_index (0);
 | 
|---|
| 2818 |           tt_name (tp->d.struc.name);
 | 
|---|
| 2819 |           tt_end ();
 | 
|---|
| 2820 |           *hll = tp->index = hll_type_index++;
 | 
|---|
| 2821 |           if (tp->d.struc.types == NULL && tp->d.struc.fields == NULL)
 | 
|---|
| 2822 |             {
 | 
|---|
| 2823 |               ti_1 = 0;
 | 
|---|
| 2824 |               ti_2 = 1;
 | 
|---|
| 2825 |             }
 | 
|---|
| 2826 |           else
 | 
|---|
| 2827 |             {
 | 
|---|
| 2828 |               make_type (tp->d.struc.types, &ti_1);
 | 
|---|
| 2829 |               make_type (tp->d.struc.fields, &ti_2);
 | 
|---|
| 2830 |             }
 | 
|---|
| 2831 |           buffer_patch_word (&tt, patch1+1, ti_1);
 | 
|---|
| 2832 |           buffer_patch_word (&tt, patch1+4, ti_2);
 | 
|---|
| 2833 |         }
 | 
|---|
| 2834 |       break;
 | 
|---|
| 2835 |     }
 | 
|---|
| 2836 | 
 | 
|---|
| 2837 |     case ty_class:
 | 
|---|
| 2838 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2839 |       tt_start (0x40, 0x00);      /* Class */
 | 
|---|
| 2840 |       tt_dword (tp->d.class.size);
 | 
|---|
| 2841 |       tt_word (tp->d.class.count);
 | 
|---|
| 2842 |       patch1 = tt.size;
 | 
|---|
| 2843 |       tt_word (0);                /* Members */
 | 
|---|
| 2844 |       tt_enc (tp->d.class.name);  /* Class name */
 | 
|---|
| 2845 |       tt_end ();
 | 
|---|
| 2846 |       make_type (tp->d.class.members, &ti_1);
 | 
|---|
| 2847 |       buffer_patch_word (&tt, patch1, ti_1);
 | 
|---|
| 2848 |       break;
 | 
|---|
| 2849 | 
 | 
|---|
| 2850 |     case ty_member:
 | 
|---|
| 2851 |       qual = 0;
 | 
|---|
| 2852 |       if (tp->d.member.flags & MEMBER_STATIC)
 | 
|---|
| 2853 |         qual |= 0x01;
 | 
|---|
| 2854 |       tt_start (0x46, qual);
 | 
|---|
| 2855 |       tt_byte (tp->d.member.flags & MEMBER_VIS);
 | 
|---|
| 2856 |       patch1 = tt.size;
 | 
|---|
| 2857 |       tt_word (0);
 | 
|---|
| 2858 |       tt_unsigned_span (tp->d.member.offset);
 | 
|---|
| 2859 |       if (tp->d.member.flags & MEMBER_STATIC)
 | 
|---|
| 2860 |         tt_enc (tp->d.member.sname);
 | 
|---|
| 2861 |       else
 | 
|---|
| 2862 |         tt_enc ("");
 | 
|---|
| 2863 |       tt_enc (tp->d.member.name);
 | 
|---|
| 2864 |       tt_end ();
 | 
|---|
| 2865 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2866 | 
 | 
|---|
| 2867 |       make_type (tp->d.member.type, &ti_1);
 | 
|---|
| 2868 |       buffer_patch_word (&tt, patch1, ti_1);
 | 
|---|
| 2869 |       break;
 | 
|---|
| 2870 | 
 | 
|---|
| 2871 |     case ty_enu:
 | 
|---|
| 2872 |       make_type (tp->d.enu.type, &ti_1);
 | 
|---|
| 2873 |       make_type (tp->d.enu.values, &ti_2);
 | 
|---|
| 2874 |       tt_start (0x7b, 0x00);            /* Enum */
 | 
|---|
| 2875 |       tt_index (ti_1);                  /* Element's data type */
 | 
|---|
| 2876 |       tt_index (ti_2);                  /* List of values */
 | 
|---|
| 2877 |       tt_signed_span (tp->d.enu.first); /* Minimum index */
 | 
|---|
| 2878 |       tt_signed_span (tp->d.enu.last);  /* Maximum index */
 | 
|---|
| 2879 |       tt_name (tp->d.enu.name);
 | 
|---|
| 2880 |       tt_end ();
 | 
|---|
| 2881 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2882 |       break;
 | 
|---|
| 2883 | 
 | 
|---|
| 2884 |     case ty_array:
 | 
|---|
| 2885 |       make_type (tp->d.array.itype, &ti_1);
 | 
|---|
| 2886 |       make_type (tp->d.array.etype, &ti_2);
 | 
|---|
| 2887 |       tt_start (0x78, 0x00);    /* Array */
 | 
|---|
| 2888 |       tt_dword (type_size (tp));
 | 
|---|
| 2889 |       tt_index (ti_1);
 | 
|---|
| 2890 |       tt_index (ti_2);
 | 
|---|
| 2891 |       tt_name ("");             /* Name */
 | 
|---|
| 2892 |       tt_end ();
 | 
|---|
| 2893 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2894 |       break;
 | 
|---|
| 2895 | 
 | 
|---|
| 2896 |     case ty_bits:
 | 
|---|
| 2897 |       tt_start (0x5c, 0x0a);    /* Bit string */
 | 
|---|
| 2898 |       tt_byte (tp->d.bits.start);
 | 
|---|
| 2899 |       tt_unsigned_span (tp->d.bits.count);
 | 
|---|
| 2900 |       tt_end ();
 | 
|---|
| 2901 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2902 |       break;
 | 
|---|
| 2903 | 
 | 
|---|
| 2904 |     case ty_func:
 | 
|---|
| 2905 |       tt_start (0x54, 0x05);          /* Function */
 | 
|---|
| 2906 |       tt_word (tp->d.func.arg_count); /* Number of parameters */
 | 
|---|
| 2907 |       tt_word (tp->d.func.arg_count); /* Max. Number of parameters */
 | 
|---|
| 2908 |       patch1 = tt.size;
 | 
|---|
| 2909 |       tt_index (0);                   /* Return value */
 | 
|---|
| 2910 |       tt_index (0);                   /* Argument list */
 | 
|---|
| 2911 |       tt_end ();
 | 
|---|
| 2912 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2913 | 
 | 
|---|
| 2914 |       if (tp->d.func.domain)
 | 
|---|
| 2915 |         make_type (tp->d.func.domain, &ti_3);
 | 
|---|
| 2916 |       make_type (tp->d.func.ret, &ti_1);
 | 
|---|
| 2917 |       if (tp->d.func.args == NULL)
 | 
|---|
| 2918 |         ti_2 = 0;
 | 
|---|
| 2919 |       else
 | 
|---|
| 2920 |         make_type (tp->d.func.args, &ti_2);
 | 
|---|
| 2921 |       buffer_patch_word (&tt, patch1+1, ti_1);
 | 
|---|
| 2922 |       buffer_patch_word (&tt, patch1+4, ti_2);
 | 
|---|
| 2923 |       break;
 | 
|---|
| 2924 | 
 | 
|---|
| 2925 |     case ty_args:
 | 
|---|
| 2926 |       if (tp->d.args.count == 0)
 | 
|---|
| 2927 |         {
 | 
|---|
| 2928 |           tp->index = 0;
 | 
|---|
| 2929 |           RETURN (tp->index);
 | 
|---|
| 2930 |         }
 | 
|---|
| 2931 |       for (i = 0; i < tp->d.args.count; ++i)
 | 
|---|
| 2932 |         make_type (tp->d.args.list[i], &ti_1);
 | 
|---|
| 2933 |       tt_start (0x7f, 0x04);    /* List (function parameters) */
 | 
|---|
| 2934 |       for (i = 0; i < tp->d.args.count; ++i)
 | 
|---|
| 2935 |         {
 | 
|---|
| 2936 |           tt_byte (0x01);        /* Flag: pass by value, no descriptor */
 | 
|---|
| 2937 |           tt_index (tp->d.args.list[i]->index);
 | 
|---|
| 2938 |         }
 | 
|---|
| 2939 |       tt_end ();
 | 
|---|
| 2940 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2941 |       break;
 | 
|---|
| 2942 | 
 | 
|---|
| 2943 |     case ty_types:
 | 
|---|
| 2944 |       if (tp->d.types.count == 0)
 | 
|---|
| 2945 |         {
 | 
|---|
| 2946 |           tp->index = 0;
 | 
|---|
| 2947 |           RETURN (tp->index);
 | 
|---|
| 2948 |         }
 | 
|---|
| 2949 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2950 |       tt_start (0x7f, 0x01);    /* List (structure field types) */
 | 
|---|
| 2951 |       patch1 = tt.size;
 | 
|---|
| 2952 |       for (i = 0; i < tp->d.types.count; ++i)
 | 
|---|
| 2953 |         tt_index (0);
 | 
|---|
| 2954 |       tt_end ();
 | 
|---|
| 2955 |       for (i = 0; i < tp->d.types.count; ++i)
 | 
|---|
| 2956 |         {
 | 
|---|
| 2957 |           make_type (tp->d.types.list[i], &ti_1);
 | 
|---|
| 2958 |           buffer_patch_word (&tt, patch1 + 1 + 3*i, ti_1);
 | 
|---|
| 2959 |         }
 | 
|---|
| 2960 |       break;
 | 
|---|
| 2961 | 
 | 
|---|
| 2962 |     case ty_fields:
 | 
|---|
| 2963 |       if (tp->d.fields.count == 0)
 | 
|---|
| 2964 |         {
 | 
|---|
| 2965 |           tp->index = 0;
 | 
|---|
| 2966 |           RETURN (tp->index);
 | 
|---|
| 2967 |         }
 | 
|---|
| 2968 |       tt_start (0x7f, 0x02);    /* List (structure field names) */
 | 
|---|
| 2969 |       for (i = 0; i < tp->d.fields.count; ++i)
 | 
|---|
| 2970 |         {
 | 
|---|
| 2971 |           tt_name (tp->d.fields.list[i].name);
 | 
|---|
| 2972 |           tt_unsigned_span (tp->d.fields.list[i].offset);
 | 
|---|
| 2973 |         }
 | 
|---|
| 2974 |       tt_end ();
 | 
|---|
| 2975 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2976 |       break;
 | 
|---|
| 2977 | 
 | 
|---|
| 2978 |     case ty_values:
 | 
|---|
| 2979 |       if (tp->d.values.count == 0)
 | 
|---|
| 2980 |         {
 | 
|---|
| 2981 |           tp->index = -1;
 | 
|---|
| 2982 |           RETURN (tp->index);
 | 
|---|
| 2983 |         }
 | 
|---|
| 2984 |       tt_start (0x7f, 0x03);    /* Enum values */
 | 
|---|
| 2985 |       for (i = 0; i < tp->d.values.count; ++i)
 | 
|---|
| 2986 |         {
 | 
|---|
| 2987 |           tt_name (tp->d.values.list[i].name);
 | 
|---|
| 2988 |           tt_unsigned_span (tp->d.values.list[i].index);
 | 
|---|
| 2989 |         }
 | 
|---|
| 2990 |       tt_end ();
 | 
|---|
| 2991 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 2992 |       break;
 | 
|---|
| 2993 | 
 | 
|---|
| 2994 |     case ty_memfunc:
 | 
|---|
| 2995 |       make_type (tp->d.memfunc.type, &ti_1);
 | 
|---|
| 2996 |       qual = 0;
 | 
|---|
| 2997 |       if (tp->d.memfunc.flags & MEMBER_STATIC)
 | 
|---|
| 2998 |         qual |= 0x01;
 | 
|---|
| 2999 |       if (tp->d.memfunc.flags & MEMBER_CONST)
 | 
|---|
| 3000 |         qual |= 0x04;
 | 
|---|
| 3001 |       if (tp->d.memfunc.flags & MEMBER_VOLATILE)
 | 
|---|
| 3002 |         qual |= 0x08;
 | 
|---|
| 3003 |       if (tp->d.memfunc.flags & MEMBER_VIRTUAL)
 | 
|---|
| 3004 |         qual |= 0x10;
 | 
|---|
| 3005 |       tt_start (0x45, qual);          /* Member Function */
 | 
|---|
| 3006 |       tt_byte (tp->d.memfunc.flags & MEMBER_VIS); /* Protection */
 | 
|---|
| 3007 |       if (tp->d.memfunc.flags & MEMBER_CTOR)
 | 
|---|
| 3008 |         tt_byte (1);                  /* Constructor */
 | 
|---|
| 3009 |       else if (tp->d.memfunc.flags & MEMBER_DTOR)
 | 
|---|
| 3010 |         tt_byte (2);                  /* Destructor */
 | 
|---|
| 3011 |       else
 | 
|---|
| 3012 |         tt_byte (0);                  /* Regular member function */
 | 
|---|
| 3013 |       tt_word (ti_1);                 /* Type index of function */
 | 
|---|
| 3014 |       if (tp->d.memfunc.flags & MEMBER_VIRTUAL)
 | 
|---|
| 3015 |         tt_unsigned_span (tp->d.memfunc.offset); /* Index into vtable */
 | 
|---|
| 3016 |       tt_enc (tp->d.memfunc.name);    /* Name of the function */
 | 
|---|
| 3017 |       tt_end ();
 | 
|---|
| 3018 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 3019 |       break;
 | 
|---|
| 3020 | 
 | 
|---|
| 3021 |     case ty_baseclass:
 | 
|---|
| 3022 |       make_type (tp->d.baseclass.type, &ti_1);
 | 
|---|
| 3023 |       qual = 0;
 | 
|---|
| 3024 |       if (tp->d.baseclass.flags & MEMBER_VIRTUAL)
 | 
|---|
| 3025 |         qual |= 0x01;
 | 
|---|
| 3026 |       tt_start (0x41, qual);      /* Base Class */
 | 
|---|
| 3027 |       tt_byte (tp->d.baseclass.flags & MEMBER_VIS);
 | 
|---|
| 3028 |       tt_word (ti_1);             /* Type */
 | 
|---|
| 3029 |       tt_unsigned_span (tp->d.baseclass.offset);
 | 
|---|
| 3030 |       tt_end ();
 | 
|---|
| 3031 |       *hll = tp->index = hll_type_index++;
 | 
|---|
| 3032 |       break;
 | 
|---|
| 3033 | 
 | 
|---|
| 3034 |     default:
 | 
|---|
| 3035 |       error ("make_type: unknown tag %d", tp->tag);
 | 
|---|
| 3036 |     }
 | 
|---|
| 3037 | }
 | 
|---|
| 3038 | 
 | 
|---|
| 3039 | 
 | 
|---|
| 3040 | /* Parse an unnamed stabs type and return an HLL type index for it. */
 | 
|---|
| 3041 | 
 | 
|---|
| 3042 | static int hll_type (void)
 | 
|---|
| 3043 | {
 | 
|---|
| 3044 |   struct type *tp;
 | 
|---|
| 3045 |   int ti;
 | 
|---|
| 3046 | 
 | 
|---|
| 3047 |   tp = parse_complete_type (NULL);
 | 
|---|
| 3048 |   make_type (tp, &ti);
 | 
|---|
| 3049 |   return ti;
 | 
|---|
| 3050 | }
 | 
|---|
| 3051 | 
 | 
|---|
| 3052 | 
 | 
|---|
| 3053 | /* Return the symbol name of symbol *INDEX, concatenating the names of
 | 
|---|
| 3054 |    successive symbol table entries if necessary.  A pointer to the
 | 
|---|
| 3055 |    string is stored to *STR.  If symbols are concatenated, *INDEX is
 | 
|---|
| 3056 |    adjusted to refer to the last symbol table entry used, in order to
 | 
|---|
| 3057 |    refer to the next symbol after incrementing by one.  If TRUE is
 | 
|---|
| 3058 |    returned, the caller should free the string when it is no longer
 | 
|---|
| 3059 |    needed.  If FALSE is returned, the string must not be freed. */
 | 
|---|
| 3060 | 
 | 
|---|
| 3061 | static int concat_symbols (int *index, const char **str)
 | 
|---|
| 3062 | {
 | 
|---|
| 3063 |   int i, n, len;
 | 
|---|
| 3064 |   char *new;
 | 
|---|
| 3065 |   const char *p;
 | 
|---|
| 3066 | 
 | 
|---|
| 3067 |   len = 0;
 | 
|---|
| 3068 |   for (i = *index; i < sym_count; ++i)
 | 
|---|
| 3069 |     {
 | 
|---|
| 3070 |       p = str_ptr + sym_ptr[i].n_un.n_strx;
 | 
|---|
| 3071 |       n = strlen (p);
 | 
|---|
| 3072 |       if (n > 0 && p[n-1] == '\\')
 | 
|---|
| 3073 |         len += n - 1;
 | 
|---|
| 3074 |       else
 | 
|---|
| 3075 |         {
 | 
|---|
| 3076 |           len += n;
 | 
|---|
| 3077 |           break;
 | 
|---|
| 3078 |         }
 | 
|---|
| 3079 |     }
 | 
|---|
| 3080 |   if (i == *index)
 | 
|---|
| 3081 |     {
 | 
|---|
| 3082 |       *str = str_ptr + sym_ptr[i].n_un.n_strx;
 | 
|---|
| 3083 |       return FALSE;
 | 
|---|
| 3084 |     }
 | 
|---|
| 3085 |   else
 | 
|---|
| 3086 |     {
 | 
|---|
| 3087 |       new = xmalloc (len + 1);
 | 
|---|
| 3088 |       *str = new;
 | 
|---|
| 3089 |       for (i = *index; i < sym_count; ++i)
 | 
|---|
| 3090 |         {
 | 
|---|
| 3091 |           p = str_ptr + sym_ptr[i].n_un.n_strx;
 | 
|---|
| 3092 |           n = strlen (p);
 | 
|---|
| 3093 |           if (n > 0 && p[n-1] == '\\')
 | 
|---|
| 3094 |             {
 | 
|---|
| 3095 |               memcpy (new, p, n - 1);
 | 
|---|
| 3096 |               new += n - 1;
 | 
|---|
| 3097 |             }
 | 
|---|
| 3098 |           else
 | 
|---|
| 3099 |             {
 | 
|---|
| 3100 |               memcpy (new, p, n);
 | 
|---|
| 3101 |               new += n;
 | 
|---|
| 3102 |               break;
 | 
|---|
| 3103 |             }
 | 
|---|
| 3104 |         }
 | 
|---|
| 3105 |       *new = 0;
 | 
|---|
| 3106 |       *index = i;
 | 
|---|
| 3107 |       return TRUE;
 | 
|---|
| 3108 |     }
 | 
|---|
| 3109 | }
 | 
|---|
| 3110 | 
 | 
|---|
| 3111 | 
 | 
|---|
| 3112 | /* Parse a stabs type definition and store the internal representation
 | 
|---|
| 3113 |    of that type.  The sym_ptr index is passed in INDEX.  As we might
 | 
|---|
| 3114 |    have to concatenate successive symbol table entries, *INDEX is
 | 
|---|
| 3115 |    updated to refer to the next symbol. */
 | 
|---|
| 3116 | 
 | 
|---|
| 3117 | static void parse_typedef (int *index)
 | 
|---|
| 3118 | {
 | 
|---|
| 3119 |   char *name;
 | 
|---|
| 3120 |   const char *str, *p;
 | 
|---|
| 3121 |   struct type *t;
 | 
|---|
| 3122 |   int n, alloc_flag;
 | 
|---|
| 3123 | 
 | 
|---|
| 3124 |   alloc_flag = concat_symbols (index, &str);
 | 
|---|
| 3125 |   parse_start = str;
 | 
|---|
| 3126 |   parse_pindex = index;
 | 
|---|
| 3127 |   p = nextcolon (str);
 | 
|---|
| 3128 |   if (p != NULL)
 | 
|---|
| 3129 |     {
 | 
|---|
| 3130 |       n = p - str;
 | 
|---|
| 3131 |       name = alloca (n + 1);
 | 
|---|
| 3132 |       memcpy (name, str, n);
 | 
|---|
| 3133 |       name[n] = 0;
 | 
|---|
| 3134 | #if defined (HLL_DEBUG)
 | 
|---|
| 3135 |       printf ("LSYM/LCSYM/GSYM/PSYM/RSYM/STSYM/FUN %s\n", str);
 | 
|---|
| 3136 | #endif
 | 
|---|
| 3137 |       parse_ptr = p + 1;
 | 
|---|
| 3138 |       switch (*parse_ptr)
 | 
|---|
| 3139 |         {
 | 
|---|
| 3140 |         case 'f':
 | 
|---|
| 3141 |         case 'F':
 | 
|---|
| 3142 |           ++parse_ptr;
 | 
|---|
| 3143 |           /* Note: don't call parse_complete_type() as there's a comma
 | 
|---|
| 3144 |              at the end for nested functions. */
 | 
|---|
| 3145 |           t = parse_type (NULL);
 | 
|---|
| 3146 |           break;
 | 
|---|
| 3147 | 
 | 
|---|
| 3148 |         case 't':
 | 
|---|
| 3149 |         case 'T':
 | 
|---|
| 3150 |           ++parse_ptr;
 | 
|---|
| 3151 |           if (*parse_ptr == 't')
 | 
|---|
| 3152 |             ++parse_ptr;        /* synonymous type */
 | 
|---|
| 3153 |           t = parse_complete_type (name);
 | 
|---|
| 3154 | #if defined (HLL_DEBUG)
 | 
|---|
| 3155 |           printf ("  type: ");
 | 
|---|
| 3156 |           show_type (t);
 | 
|---|
| 3157 |           printf ("\n");
 | 
|---|
| 3158 | #endif
 | 
|---|
| 3159 |           break;
 | 
|---|
| 3160 | 
 | 
|---|
| 3161 |         case 'p':
 | 
|---|
| 3162 |         case 'r':
 | 
|---|
| 3163 |         case 'G':
 | 
|---|
| 3164 |         case 'S':
 | 
|---|
| 3165 |         case 'V':
 | 
|---|
| 3166 |           ++parse_ptr;
 | 
|---|
| 3167 |           t = parse_complete_type (name);
 | 
|---|
| 3168 | #if defined (HLL_DEBUG)
 | 
|---|
| 3169 |           printf ("  type: ");
 | 
|---|
| 3170 |           show_type (t);
 | 
|---|
| 3171 |           printf ("\n");
 | 
|---|
| 3172 | #endif
 | 
|---|
| 3173 |           break;
 | 
|---|
| 3174 | 
 | 
|---|
| 3175 |         case '0': case '1': case '2': case '3': case '4':
 | 
|---|
| 3176 |         case '5': case '6': case '7': case '8': case '9':
 | 
|---|
| 3177 |           t = parse_complete_type (name);
 | 
|---|
| 3178 | #if defined (HLL_DEBUG)
 | 
|---|
| 3179 |           printf ("  type: ");
 | 
|---|
| 3180 |           show_type (t);
 | 
|---|
| 3181 |           printf ("\n");
 | 
|---|
| 3182 | #endif
 | 
|---|
| 3183 |           break;
 | 
|---|
| 3184 |         }
 | 
|---|
| 3185 |     }
 | 
|---|
| 3186 |   if (alloc_flag)
 | 
|---|
| 3187 |     free ((void *)str);         /* remove const attribute */
 | 
|---|
| 3188 | }
 | 
|---|
| 3189 | 
 | 
|---|
| 3190 | 
 | 
|---|
| 3191 | /* Write a `begin' subrecord to the SST.  The block begins at ADDR in
 | 
|---|
| 3192 |    the text segment. */
 | 
|---|
| 3193 | 
 | 
|---|
| 3194 | static size_t hll_begin (dword addr)
 | 
|---|
| 3195 | {
 | 
|---|
| 3196 |   size_t ptr;
 | 
|---|
| 3197 |   struct relocation_info r;
 | 
|---|
| 3198 | 
 | 
|---|
| 3199 |   sst_start (SST_begin);
 | 
|---|
| 3200 |   r.r_address = sst.size;
 | 
|---|
| 3201 |   ptr = sst.size;
 | 
|---|
| 3202 |   buffer_dword (&sst, addr);    /* Segment offset */
 | 
|---|
| 3203 |   buffer_dword (&sst, 0);       /* Length of block -- patched later */
 | 
|---|
| 3204 | #if 1
 | 
|---|
| 3205 |   buffer_nstr (&sst, "");       /* Name of block (optional) */
 | 
|---|
| 3206 | #endif
 | 
|---|
| 3207 |   sst_end ();
 | 
|---|
| 3208 | 
 | 
|---|
| 3209 |   r.r_extern = 0;
 | 
|---|
| 3210 |   r.r_length = 2;
 | 
|---|
| 3211 |   r.r_symbolnum = N_TEXT;
 | 
|---|
| 3212 |   r.r_pcrel = 0;
 | 
|---|
| 3213 |   r.r_pad = 0;
 | 
|---|
| 3214 |   buffer_mem (&sst_reloc, &r, sizeof (r));
 | 
|---|
| 3215 |   return ptr;
 | 
|---|
| 3216 | }
 | 
|---|
| 3217 | 
 | 
|---|
| 3218 | 
 | 
|---|
| 3219 | /* Start of a block.  Write a `begin' subrecord to the SST.  The block
 | 
|---|
| 3220 |    begins at ADDR in the text segment.  Push the block onto the block
 | 
|---|
| 3221 |    stack. */
 | 
|---|
| 3222 | 
 | 
|---|
| 3223 | static void block_begin (dword addr)
 | 
|---|
| 3224 | {
 | 
|---|
| 3225 |   size_t ptr;
 | 
|---|
| 3226 | 
 | 
|---|
| 3227 |   ptr = hll_begin (addr);
 | 
|---|
| 3228 |   grow_by (&block_grow, 1);
 | 
|---|
| 3229 |   block_stack[block_grow.count].patch_ptr = ptr;
 | 
|---|
| 3230 |   block_stack[block_grow.count].addr = addr;
 | 
|---|
| 3231 |   ++block_grow.count;
 | 
|---|
| 3232 | }
 | 
|---|
| 3233 | 
 | 
|---|
| 3234 | 
 | 
|---|
| 3235 | /* Write an `end' subrecord to the SST.  PATCH_PTR is the sst index of
 | 
|---|
| 3236 |    the `begin' subrecord for this block.  Add ADD_START to the start
 | 
|---|
| 3237 |    address of the block and set the length of the block to LENGTH, in
 | 
|---|
| 3238 |    bytes. */
 | 
|---|
| 3239 | 
 | 
|---|
| 3240 | static void hll_end (size_t patch_ptr, int add_start, size_t length)
 | 
|---|
| 3241 | {
 | 
|---|
| 3242 |   *(dword *)(sst.buf+patch_ptr+0) += add_start;
 | 
|---|
| 3243 |   *(dword *)(sst.buf+patch_ptr+4) = length;
 | 
|---|
| 3244 |   sst_start (SST_end);
 | 
|---|
| 3245 |   sst_end ();
 | 
|---|
| 3246 | }
 | 
|---|
| 3247 | 
 | 
|---|
| 3248 | 
 | 
|---|
| 3249 | /* Return TRUE iff symbol table entry S defines a function. */
 | 
|---|
| 3250 | 
 | 
|---|
| 3251 | static int is_fun (const struct nlist *s)
 | 
|---|
| 3252 | {
 | 
|---|
| 3253 |   const char *p;
 | 
|---|
| 3254 | 
 | 
|---|
| 3255 |   if (s->n_type != N_FUN)
 | 
|---|
| 3256 |     return FALSE;
 | 
|---|
| 3257 |   p = nextcolon (str_ptr + s->n_un.n_strx);
 | 
|---|
| 3258 |   if (p == NULL)
 | 
|---|
| 3259 |     return FALSE;
 | 
|---|
| 3260 |   return (p[1] == 'F' || p[1] == 'f');
 | 
|---|
| 3261 | }
 | 
|---|
| 3262 | 
 | 
|---|
| 3263 | 
 | 
|---|
| 3264 | /* Approximate a function prologue length by examining the code.  The
 | 
|---|
| 3265 |    function starts at START and ends at END. */
 | 
|---|
| 3266 | 
 | 
|---|
| 3267 | static int get_prologue_length (dword start, dword end)
 | 
|---|
| 3268 | {
 | 
|---|
| 3269 |   dword i;
 | 
|---|
| 3270 | 
 | 
|---|
| 3271 |   if (end > text_size)
 | 
|---|
| 3272 |     end = text_size;
 | 
|---|
| 3273 |   i = start;
 | 
|---|
| 3274 |   if (i < end && text_ptr[i] == 0x55) ++i;                  /* PUSH EBP */
 | 
|---|
| 3275 |   if (i + 1 < end && text_ptr[i+0] == 0x89
 | 
|---|
| 3276 |       && text_ptr[i+1] == 0xe5)                             /* MOV  EBP, ESP */
 | 
|---|
| 3277 |     i += 2;
 | 
|---|
| 3278 |   if (i + 2 < end && text_ptr[i+0] == 0x83
 | 
|---|
| 3279 |       && text_ptr[i+1] == 0xec)                             /* SUB  ESP, n8 */
 | 
|---|
| 3280 |     i += 3;
 | 
|---|
| 3281 |   return i - start;
 | 
|---|
| 3282 | }
 | 
|---|
| 3283 | 
 | 
|---|
| 3284 | 
 | 
|---|
| 3285 | /* End of a function reached.  Try to find the function length.  I is
 | 
|---|
| 3286 |    the sym_ptr index of the current symbol -- we search the symbol
 | 
|---|
| 3287 |    table starting at I to find the next function for estimating the
 | 
|---|
| 3288 |    function length. */
 | 
|---|
| 3289 | 
 | 
|---|
| 3290 | static void fun_end (int i)
 | 
|---|
| 3291 | {
 | 
|---|
| 3292 |   int p_len;
 | 
|---|
| 3293 |   dword addr;
 | 
|---|
| 3294 | 
 | 
|---|
| 3295 |   addr = text_size;
 | 
|---|
| 3296 |   while (i < sym_count)
 | 
|---|
| 3297 |     {
 | 
|---|
| 3298 |       if (is_fun (&sym_ptr[i]))
 | 
|---|
| 3299 |         {
 | 
|---|
| 3300 |           addr = sym_ptr[i].n_value;
 | 
|---|
| 3301 |           break;
 | 
|---|
| 3302 |         }
 | 
|---|
| 3303 |       ++i;
 | 
|---|
| 3304 |     }
 | 
|---|
| 3305 |   if (prologue_length != -1)
 | 
|---|
| 3306 |     p_len = prologue_length;
 | 
|---|
| 3307 |   else
 | 
|---|
| 3308 |     p_len = get_prologue_length (proc_start_addr, addr);
 | 
|---|
| 3309 |   *(dword *)(sst.buf+proc_patch_base + 0) = addr - proc_start_addr;
 | 
|---|
| 3310 |   *(word *)(sst.buf+proc_patch_base + 4) = p_len;
 | 
|---|
| 3311 |   *(dword *)(sst.buf+proc_patch_base + 6) = addr - proc_start_addr;
 | 
|---|
| 3312 |   proc_patch_base = 0;
 | 
|---|
| 3313 |   sst_start (SST_end);
 | 
|---|
| 3314 |   sst_end ();
 | 
|---|
| 3315 | }
 | 
|---|
| 3316 | 
 | 
|---|
| 3317 | 
 | 
|---|
| 3318 | /* End of a block (N_RBRAC encountered).  I is the sym_ptr index of
 | 
|---|
| 3319 |    the N_RBRAC symbol.  If we reach the outmost block level, we call
 | 
|---|
| 3320 |    fun_end(). */
 | 
|---|
| 3321 | 
 | 
|---|
| 3322 | static void block_end (int i)
 | 
|---|
| 3323 | {
 | 
|---|
| 3324 |   if (block_grow.count == 0)
 | 
|---|
| 3325 |     {
 | 
|---|
| 3326 |       /** @todo fix this - broken after my last change (bird 2003-10-06) */
 | 
|---|
| 3327 |       /* warning ("Invalid N_RBRAC without N_LBRAC"); */
 | 
|---|
| 3328 |     }
 | 
|---|
| 3329 |   else
 | 
|---|
| 3330 |     {
 | 
|---|
| 3331 |       --block_grow.count;
 | 
|---|
| 3332 |       hll_end (block_stack[block_grow.count].patch_ptr, 0,
 | 
|---|
| 3333 |                sym_ptr[i].n_value - block_stack[block_grow.count].addr);
 | 
|---|
| 3334 |       if (block_grow.count == 1) /* we make one extra begin */
 | 
|---|
| 3335 |         {
 | 
|---|
| 3336 |           --block_grow.count;
 | 
|---|
| 3337 |           hll_end (block_stack[block_grow.count].patch_ptr, 0,
 | 
|---|
| 3338 |                    sym_ptr[i].n_value - block_stack[block_grow.count].addr);
 | 
|---|
| 3339 |         }
 | 
|---|
| 3340 |       if (block_grow.count == 0 && proc_patch_base != 0)
 | 
|---|
| 3341 |         fun_end (i);
 | 
|---|
| 3342 |     }
 | 
|---|
| 3343 | }
 | 
|---|
| 3344 | 
 | 
|---|
| 3345 | 
 | 
|---|
| 3346 | /* Define a function.  SYMBOL points to the sym_ptr entry.  The
 | 
|---|
| 3347 |    function arguments are taken from the args_list array.  Several
 | 
|---|
| 3348 |    fields of the SST entry are filled-in later, when reaching the end
 | 
|---|
| 3349 |    of the function.  proc_patch_base is used for remembering the place
 | 
|---|
| 3350 |    where to patch the SST entry. */
 | 
|---|
| 3351 | 
 | 
|---|
| 3352 | static void define_fun (const struct nlist *symbol)
 | 
|---|
| 3353 | {
 | 
|---|
| 3354 |   struct type t, *t1, *t2, *t3;
 | 
|---|
| 3355 |   struct relocation_info r;
 | 
|---|
| 3356 |   const char *str, *p, *p2;
 | 
|---|
| 3357 |   const char *name, *mnglname;
 | 
|---|
| 3358 | #ifdef DEMANGLE_PROC_NAMES
 | 
|---|
| 3359 |   char *pszFree;
 | 
|---|
| 3360 | #endif
 | 
|---|
| 3361 |   size_t cchName, cchMnglName;
 | 
|---|
| 3362 |   int ti, ticlass;
 | 
|---|
| 3363 | 
 | 
|---|
| 3364 |   str = str_ptr + symbol->n_un.n_strx;
 | 
|---|
| 3365 |   p = nextcolon (str);
 | 
|---|
| 3366 |   if (p == NULL)
 | 
|---|
| 3367 |     abort ();
 | 
|---|
| 3368 |   cchName = cchMnglName = p - str;
 | 
|---|
| 3369 |   name = mnglname = strpool_addn (str_pool, str, cchMnglName);
 | 
|---|
| 3370 |   proc_start_addr = symbol->n_value;
 | 
|---|
| 3371 | 
 | 
|---|
| 3372 | #ifdef DEMANGLE_PROC_NAMES
 | 
|---|
| 3373 |   /* demangle the name */
 | 
|---|
| 3374 |   pszFree = cplus_demangle (mnglname, DMGL_ANSI | DMGL_PARAMS);
 | 
|---|
| 3375 |   if (!pszFree && (*mnglname == '_' || *mnglname == '*'))
 | 
|---|
| 3376 |     pszFree = cplus_demangle (mnglname + 1, DMGL_ANSI | DMGL_PARAMS);
 | 
|---|
| 3377 |   if (pszFree)
 | 
|---|
| 3378 |     {
 | 
|---|
| 3379 |       cchName = strlen (pszFree);
 | 
|---|
| 3380 |       name = pszFree;
 | 
|---|
| 3381 |     }
 | 
|---|
| 3382 |   else if (*mnglname == '*')
 | 
|---|
| 3383 |     {
 | 
|---|
| 3384 |       cchName--;
 | 
|---|
| 3385 |       name++;
 | 
|---|
| 3386 |     }
 | 
|---|
| 3387 | #endif
 | 
|---|
| 3388 | 
 | 
|---|
| 3389 |   /* now let's see if there is a memfunc for this name. */
 | 
|---|
| 3390 |   for (t1 = type_head; t1; t1 = t1->next)
 | 
|---|
| 3391 |     if (    t1->tag == ty_memfunc
 | 
|---|
| 3392 |         &&  t1->d.memfunc.mnglname == mnglname)
 | 
|---|
| 3393 |       break;
 | 
|---|
| 3394 | 
 | 
|---|
| 3395 |   if (t1)
 | 
|---|
| 3396 |     { /* C++ member function */
 | 
|---|
| 3397 |       t2 = t1->d.memfunc.type;
 | 
|---|
| 3398 |       if (t2 && t2->tag == ty_func && t2->d.func.domain)
 | 
|---|
| 3399 |         make_type (t2->d.func.domain, &ticlass);
 | 
|---|
| 3400 |       else
 | 
|---|
| 3401 |         { /* the hard way - search for the freaking string in suitable .stabs.
 | 
|---|
| 3402 |            * I think this is rather slow when done for many members.. :/ */
 | 
|---|
| 3403 |           int i;
 | 
|---|
| 3404 |           for (i = 0, t3 = NULL, ticlass = -1; !t3 && i < sym_count; ++i)
 | 
|---|
| 3405 |             switch (sym_ptr[i].n_type)
 | 
|---|
| 3406 |               {
 | 
|---|
| 3407 |               case N_LSYM:
 | 
|---|
| 3408 |                 {
 | 
|---|
| 3409 |                   str = str_ptr + sym_ptr[i].n_un.n_strx;
 | 
|---|
| 3410 |                   p = nextcolon (str);
 | 
|---|
| 3411 |                   if (p && p[1] == 'T' && p[2] == 't')
 | 
|---|
| 3412 |                     {
 | 
|---|
| 3413 |                       /* Now, there can be several name which NAME is a
 | 
|---|
| 3414 |                        * substring in.
 | 
|---|
| 3415 |                        */
 | 
|---|
| 3416 |                       /** @todo: the string parsing still is a bit spooky. */
 | 
|---|
| 3417 |                       for (p2 = p; (p2 = strstr (p2, mnglname)) != NULL; p2 += cchMnglName)
 | 
|---|
| 3418 |                         if (p2[-1] == ':' && p2[cchMnglName] == ';')
 | 
|---|
| 3419 |                         {
 | 
|---|
| 3420 |                             int stab = atoi (&p[3]);
 | 
|---|
| 3421 |                             t3 = stype_find (stab);
 | 
|---|
| 3422 |                             break;
 | 
|---|
| 3423 |                         }
 | 
|---|
| 3424 |                     }
 | 
|---|
| 3425 |                   break;
 | 
|---|
| 3426 |                 }
 | 
|---|
| 3427 |               }
 | 
|---|
| 3428 |           if (t3)
 | 
|---|
| 3429 |             make_type (t3, &ticlass);
 | 
|---|
| 3430 |           if (ticlass < 0)
 | 
|---|
| 3431 |             {
 | 
|---|
| 3432 |               warning (" Can't figure out which class method '%s' is a member of!", mnglname);
 | 
|---|
| 3433 |               ticlass = 0;
 | 
|---|
| 3434 |             }
 | 
|---|
| 3435 |         }
 | 
|---|
| 3436 | 
 | 
|---|
| 3437 |       make_type (t1, &ti);
 | 
|---|
| 3438 |       sst_start (SST_memfunc);
 | 
|---|
| 3439 |       r.r_address = sst.size;
 | 
|---|
| 3440 |       buffer_dword (&sst, symbol->n_value); /* Segment offset */
 | 
|---|
| 3441 |       buffer_word (&sst, ti);       /* Type index */
 | 
|---|
| 3442 |       proc_patch_base = sst.size;
 | 
|---|
| 3443 |       buffer_dword (&sst, 0);       /* Length of proc */
 | 
|---|
| 3444 |       buffer_word (&sst, 0);        /* Length of prologue */
 | 
|---|
| 3445 |       buffer_dword (&sst, 0);       /* Length of prologue and body */
 | 
|---|
| 3446 |       buffer_word (&sst, ticlass);  /* Class type (for member functions) */
 | 
|---|
| 3447 |       buffer_byte (&sst, 8);        /* 32-bit near */
 | 
|---|
| 3448 |       buffer_enc (&sst, name);      /* Proc name */
 | 
|---|
| 3449 |       sst_end ();
 | 
|---|
| 3450 |     }
 | 
|---|
| 3451 |   else
 | 
|---|
| 3452 |     {
 | 
|---|
| 3453 |       if (args_grow.count == 0)
 | 
|---|
| 3454 |         t1 = NULL;
 | 
|---|
| 3455 |       else
 | 
|---|
| 3456 |         {
 | 
|---|
| 3457 |           t.tag = ty_args;
 | 
|---|
| 3458 |           t.index = -1;
 | 
|---|
| 3459 |           t.d.args.count = args_grow.count;
 | 
|---|
| 3460 |           t.d.args.list = xmalloc (args_grow.count * sizeof (*args_list));
 | 
|---|
| 3461 |           memcpy (t.d.args.list, args_list, args_grow.count * sizeof (*args_list));
 | 
|---|
| 3462 |           t1 = type_add (&t);
 | 
|---|
| 3463 |           free (t.d.args.list);
 | 
|---|
| 3464 |         }
 | 
|---|
| 3465 |       last_fun_type.d.func.args = t1;
 | 
|---|
| 3466 |       last_fun_type.d.func.arg_count = args_grow.count;
 | 
|---|
| 3467 |       t2 = type_add (&last_fun_type);
 | 
|---|
| 3468 |       make_type (t2, &ti);
 | 
|---|
| 3469 | 
 | 
|---|
| 3470 |       sst_start (cplusplus_flag || cchName > 255 ? SST_CPPproc : SST_proc);
 | 
|---|
| 3471 |       r.r_address = sst.size;
 | 
|---|
| 3472 |       buffer_dword (&sst, symbol->n_value); /* Segment offset */
 | 
|---|
| 3473 |       buffer_word (&sst, ti);       /* Type index */
 | 
|---|
| 3474 |       proc_patch_base = sst.size;
 | 
|---|
| 3475 |       buffer_dword (&sst, 0);       /* Length of proc */
 | 
|---|
| 3476 |       buffer_word (&sst, 0);        /* Length of prologue */
 | 
|---|
| 3477 |       buffer_dword (&sst, 0);       /* Length of prologue and body */
 | 
|---|
| 3478 |       buffer_word (&sst, 0);        /* Class type (for member functions) */
 | 
|---|
| 3479 |       buffer_byte (&sst, 8);        /* 32-bit near */
 | 
|---|
| 3480 |       if (cplusplus_flag || cchName > 255)
 | 
|---|
| 3481 |         buffer_enc (&sst, name);    /* Proc name */
 | 
|---|
| 3482 |       else
 | 
|---|
| 3483 |         buffer_nstr (&sst, name);   /* Proc name */
 | 
|---|
| 3484 |       sst_end ();
 | 
|---|
| 3485 |     }
 | 
|---|
| 3486 |   r.r_extern = 0;
 | 
|---|
| 3487 |   r.r_length = 2;
 | 
|---|
| 3488 |   r.r_symbolnum = N_TEXT;
 | 
|---|
| 3489 |   r.r_pcrel = 0;
 | 
|---|
| 3490 |   r.r_pad = 0;
 | 
|---|
| 3491 |   buffer_mem (&sst_reloc, &r, sizeof (r));
 | 
|---|
| 3492 |   set_hll_type (symbol - sym_ptr, ti);
 | 
|---|
| 3493 | 
 | 
|---|
| 3494 | #ifdef DEMANGLE_PROC_NAMES
 | 
|---|
| 3495 |   /* free the demangled name. */
 | 
|---|
| 3496 |   free (pszFree);
 | 
|---|
| 3497 | #endif
 | 
|---|
| 3498 | }
 | 
|---|
| 3499 | 
 | 
|---|
| 3500 | 
 | 
|---|
| 3501 | /* Locate the next N_LBRAC starting at symbol I.  If found, set
 | 
|---|
| 3502 |    lbrac_index to the index of N_LBRAC and start a new block.  If
 | 
|---|
| 3503 |    there is no N_LBRAC, set lbrac_index to -1. */
 | 
|---|
| 3504 | 
 | 
|---|
| 3505 | static void next_lbrac (int i)
 | 
|---|
| 3506 | {
 | 
|---|
| 3507 |   lbrac_index = -1;
 | 
|---|
| 3508 |   for (; i < sym_count; ++i)
 | 
|---|
| 3509 |     if (sym_ptr[i].n_type == N_RBRAC || is_fun (&sym_ptr[i]))
 | 
|---|
| 3510 |       return;
 | 
|---|
| 3511 |     else if (sym_ptr[i].n_type == N_LBRAC)
 | 
|---|
| 3512 |       {
 | 
|---|
| 3513 |         lbrac_index = i;
 | 
|---|
| 3514 |         block_begin (sym_ptr[i].n_value);
 | 
|---|
| 3515 |         return;
 | 
|---|
| 3516 |       }
 | 
|---|
| 3517 | }
 | 
|---|
| 3518 | 
 | 
|---|
| 3519 | 
 | 
|---|
| 3520 | /* Parse a stabs symbol.  The sym_ptr index is passed in INDEX.  As we
 | 
|---|
| 3521 |    might have to concatenate successive symbol table entries, *INDEX
 | 
|---|
| 3522 |    is updated to refer to the next symbol.  WHERE is the segment where
 | 
|---|
| 3523 |    the symbol is defined (N_DATA, for instance).  If WHERE is -1,
 | 
|---|
| 3524 |    there is no segment.  MSG is used for warning messages. This
 | 
|---|
| 3525 |    function is called recursively for static functions (F) There's up
 | 
|---|
| 3526 |    to one level of recursion.  The arguments of a function are read
 | 
|---|
| 3527 |    twice: If FLAG is TRUE, we turn the arguments into local symbols;
 | 
|---|
| 3528 |    if FLAG is FALSE, we put arguments into the args_list array. */
 | 
|---|
| 3529 | 
 | 
|---|
| 3530 | static void parse_symbol (int *index, int where, const char *msg, int flag)
 | 
|---|
| 3531 | {
 | 
|---|
| 3532 |   char *name;
 | 
|---|
| 3533 |   const char *str, *p;
 | 
|---|
| 3534 |   const struct nlist *symbol;
 | 
|---|
| 3535 |   struct type *t1;
 | 
|---|
| 3536 |   int i, n, ti, alloc_flag;
 | 
|---|
| 3537 | 
 | 
|---|
| 3538 |   symbol = &sym_ptr[*index];
 | 
|---|
| 3539 |   alloc_flag = concat_symbols (index, &str);
 | 
|---|
| 3540 |   parse_start = str;
 | 
|---|
| 3541 |   parse_pindex = index;
 | 
|---|
| 3542 |   p = nextcolon (str);
 | 
|---|
| 3543 |   if (p != NULL)
 | 
|---|
| 3544 |     {
 | 
|---|
| 3545 |       n = p - str;
 | 
|---|
| 3546 |       name = alloca (n + 1);
 | 
|---|
| 3547 |       memcpy (name, str, n);
 | 
|---|
| 3548 |       name[n] = 0;
 | 
|---|
| 3549 | #if defined (HLL_DEBUG)
 | 
|---|
| 3550 |       printf ("%s %s\n", msg, str);
 | 
|---|
| 3551 | #endif
 | 
|---|
| 3552 | 
 | 
|---|
| 3553 |       parse_ptr = p + 1;
 | 
|---|
| 3554 |       switch (*parse_ptr)
 | 
|---|
| 3555 |         {
 | 
|---|
| 3556 |         case 'G':
 | 
|---|
| 3557 |           /* Static storage, global scope */
 | 
|---|
| 3558 |           {
 | 
|---|
| 3559 |           const struct nlist *sym2 = NULL;
 | 
|---|
| 3560 |           ++parse_ptr;
 | 
|---|
| 3561 |           ti = hll_type ();
 | 
|---|
| 3562 | #if defined (HLL_DEBUG)
 | 
|---|
| 3563 |           printf ("  type=%#x\n", ti);
 | 
|---|
| 3564 | #endif
 | 
|---|
| 3565 | 
 | 
|---|
| 3566 |           /* Check for a ugly hack in dbxout.c which allow us to resolve
 | 
|---|
| 3567 |              communal and global variables more accuratly. The n_value is -12357
 | 
|---|
| 3568 |              and the previous entry is 0xfe. What the previous entry contains
 | 
|---|
| 3569 |              is the assembly name of the symbol.
 | 
|---|
| 3570 | 
 | 
|---|
| 3571 |              Another part of that hack is that n_value is contains the
 | 
|---|
| 3572 |              symbol value so we don't need to look up the symbol for that
 | 
|---|
| 3573 |              reason (but as it turns out we have to look it up to see where
 | 
|---|
| 3574 |              it is in most cases, bah). */
 | 
|---|
| 3575 |           if (   symbol->n_value == -12357
 | 
|---|
| 3576 |               && *index >= 1
 | 
|---|
| 3577 |               && symbol[-1].n_type == 0xfe)
 | 
|---|
| 3578 |             {
 | 
|---|
| 3579 |               sym2 = find_symbol_ex (symbol[-1].n_un.n_strx + str_ptr, *index - 1, 1);
 | 
|---|
| 3580 |               if (!sym2)
 | 
|---|
| 3581 |                 {
 | 
|---|
| 3582 |                   warning ("Cannot find address of communal/external variable %s", name);
 | 
|---|
| 3583 |                   return;
 | 
|---|
| 3584 |                 }
 | 
|---|
| 3585 |             }
 | 
|---|
| 3586 |           else if (where == -1)
 | 
|---|
| 3587 |             { /* This is not very nice, we have to look up the symbol
 | 
|---|
| 3588 |                  like we used to do in order to the the segment right.
 | 
|---|
| 3589 |                  Should probably just use the external/communal hack above
 | 
|---|
| 3590 |                  for everything or change the n_type of the 'G' stab... However,
 | 
|---|
| 3591 |                  this will work for most cases and it will be compatible with
 | 
|---|
| 3592 |                  the unmodified dbxout.c code. */
 | 
|---|
| 3593 |               if (symbol->n_type == N_FUN) /* in case GCC change... */
 | 
|---|
| 3594 |                   where = N_TEXT;
 | 
|---|
| 3595 |               else
 | 
|---|
| 3596 |                 {
 | 
|---|
| 3597 |                   size_t cch = strlen (name);
 | 
|---|
| 3598 |                   char *psz = alloca (cch + 2);
 | 
|---|
| 3599 |                   *psz = '_';
 | 
|---|
| 3600 |                   memcpy (psz + 1, name, cch + 1);
 | 
|---|
| 3601 |                   sym2 = find_symbol (psz);
 | 
|---|
| 3602 |                   if (!sym2)
 | 
|---|
| 3603 |                     sym2 = find_symbol (psz + 1);
 | 
|---|
| 3604 |                   where = N_DATA;
 | 
|---|
| 3605 |                 }
 | 
|---|
| 3606 |             }
 | 
|---|
| 3607 |           /* if we're lucky we've got a symbol... */
 | 
|---|
| 3608 |           if (sym2)
 | 
|---|
| 3609 |             {
 | 
|---|
| 3610 |               if (sym2->n_type == N_EXT)
 | 
|---|
| 3611 |                 sst_static (name, 0, ti, sym2 - sym_ptr, 1, sym2);
 | 
|---|
| 3612 |               else
 | 
|---|
| 3613 |                 sst_static (name, sym2->n_value, ti, sym2->n_type, 0, sym2);
 | 
|---|
| 3614 |             }
 | 
|---|
| 3615 |           else
 | 
|---|
| 3616 |             sst_static (name, symbol->n_value, ti, where, 0, NULL);
 | 
|---|
| 3617 |           break;
 | 
|---|
| 3618 |           }
 | 
|---|
| 3619 | 
 | 
|---|
| 3620 |         case 'S':
 | 
|---|
| 3621 |         case 'V':
 | 
|---|
| 3622 | 
 | 
|---|
| 3623 |           /* S = static storage, file scope,
 | 
|---|
| 3624 |              V = static storage, local scope */
 | 
|---|
| 3625 | 
 | 
|---|
| 3626 |           if (where == -1)
 | 
|---|
| 3627 |             {
 | 
|---|
| 3628 |               warning ("Cannot use symbol type %c with N_%s", *parse_ptr, msg);
 | 
|---|
| 3629 |               return;
 | 
|---|
| 3630 |             }
 | 
|---|
| 3631 |           ++parse_ptr;
 | 
|---|
| 3632 |           ti = hll_type ();
 | 
|---|
| 3633 | #if defined (HLL_DEBUG)
 | 
|---|
| 3634 |           printf ("  type=%#x\n", ti);
 | 
|---|
| 3635 | #endif
 | 
|---|
| 3636 |           sst_static (name, symbol->n_value, ti, where, 0, NULL);
 | 
|---|
| 3637 |           break;
 | 
|---|
| 3638 | 
 | 
|---|
| 3639 |         case 'p':
 | 
|---|
| 3640 | 
 | 
|---|
| 3641 |           /* Function argument. */
 | 
|---|
| 3642 | 
 | 
|---|
| 3643 |           if (where != -1)
 | 
|---|
| 3644 |             {
 | 
|---|
| 3645 |               warning ("Cannot use argument symbol with N_%s", msg);
 | 
|---|
| 3646 |               return;
 | 
|---|
| 3647 |             }
 | 
|---|
| 3648 |           ++parse_ptr;
 | 
|---|
| 3649 |           if (flag)
 | 
|---|
| 3650 |             {
 | 
|---|
| 3651 |               ti = hll_type ();
 | 
|---|
| 3652 | #if defined (HLL_DEBUG)
 | 
|---|
| 3653 |               printf ("  type=%#x\n", ti);
 | 
|---|
| 3654 | #endif
 | 
|---|
| 3655 |               sst_start (SST_auto);
 | 
|---|
| 3656 |               buffer_dword (&sst, symbol->n_value);/* Offset into stk frame */
 | 
|---|
| 3657 |               buffer_word (&sst, ti);              /* Type index */
 | 
|---|
| 3658 |               buffer_nstr (&sst, name);            /* Symbol name */
 | 
|---|
| 3659 |               sst_end ();
 | 
|---|
| 3660 |             }
 | 
|---|
| 3661 |           else
 | 
|---|
| 3662 |             {
 | 
|---|
| 3663 |               t1 = parse_complete_type (NULL);
 | 
|---|
| 3664 |               grow_by (&args_grow, 1);
 | 
|---|
| 3665 |               args_list[args_grow.count++] = t1;
 | 
|---|
| 3666 |             }
 | 
|---|
| 3667 |           break;
 | 
|---|
| 3668 | 
 | 
|---|
| 3669 |         case 'r':
 | 
|---|
| 3670 | 
 | 
|---|
| 3671 |           /* Register variable. */
 | 
|---|
| 3672 | 
 | 
|---|
| 3673 |           if (where != -1)
 | 
|---|
| 3674 |             {
 | 
|---|
| 3675 |               warning ("Cannot use register symbol with N_%s", msg);
 | 
|---|
| 3676 |               return;
 | 
|---|
| 3677 |             }
 | 
|---|
| 3678 |           ++parse_ptr;
 | 
|---|
| 3679 |           ti = hll_type ();
 | 
|---|
| 3680 |           switch (symbol->n_value)
 | 
|---|
| 3681 |             {
 | 
|---|
| 3682 |             case 0:             /* EAX */
 | 
|---|
| 3683 |               i = 0x10;
 | 
|---|
| 3684 |               break;
 | 
|---|
| 3685 |             case 1:             /* ECX */
 | 
|---|
| 3686 |               i = 0x11;
 | 
|---|
| 3687 |               break;
 | 
|---|
| 3688 |             case 2:             /* EDX */
 | 
|---|
| 3689 |               i = 0x12;
 | 
|---|
| 3690 |               break;
 | 
|---|
| 3691 |             case 3:             /* EBX */
 | 
|---|
| 3692 |               i = 0x13;
 | 
|---|
| 3693 |               break;
 | 
|---|
| 3694 |             case 4:             /* ESP */
 | 
|---|
| 3695 |               i = 0x14;
 | 
|---|
| 3696 |               break;
 | 
|---|
| 3697 |             case 5:             /* EBP */
 | 
|---|
| 3698 |               i = 0x15;
 | 
|---|
| 3699 |               break;
 | 
|---|
| 3700 |             case 6:             /* ESI */
 | 
|---|
| 3701 |               i = 0x16;
 | 
|---|
| 3702 |               break;
 | 
|---|
| 3703 |             case 7:             /* EDI */
 | 
|---|
| 3704 |               i = 0x17;
 | 
|---|
| 3705 |               break;
 | 
|---|
| 3706 |             case 12:            /* ST(0) */
 | 
|---|
| 3707 |               i = 0x80;
 | 
|---|
| 3708 |               break;
 | 
|---|
| 3709 |             case 13:            /* ST(1) */
 | 
|---|
| 3710 |               i = 0x81;
 | 
|---|
| 3711 |               break;
 | 
|---|
| 3712 |             case 14:            /* ST(2) */
 | 
|---|
| 3713 |               i = 0x82;
 | 
|---|
| 3714 |               break;
 | 
|---|
| 3715 |             case 15:            /* ST(3) */
 | 
|---|
| 3716 |               i = 0x83;
 | 
|---|
| 3717 |               break;
 | 
|---|
| 3718 |             case 16:            /* ST(4) */
 | 
|---|
| 3719 |               i = 0x84;
 | 
|---|
| 3720 |               break;
 | 
|---|
| 3721 |             case 17:            /* ST(5) */
 | 
|---|
| 3722 |               i = 0x85;
 | 
|---|
| 3723 |               break;
 | 
|---|
| 3724 |             case 18:            /* ST(6) */
 | 
|---|
| 3725 |               i = 0x86;
 | 
|---|
| 3726 |               break;
 | 
|---|
| 3727 |             case 19:            /* ST(7) */
 | 
|---|
| 3728 |               i = 0x87;
 | 
|---|
| 3729 |               break;
 | 
|---|
| 3730 |             default:
 | 
|---|
| 3731 |               warning ("unknown register %lu", symbol->n_value);
 | 
|---|
| 3732 |               return;
 | 
|---|
| 3733 |             }
 | 
|---|
| 3734 |           sst_start (SST_reg);      /* Register variable */
 | 
|---|
| 3735 |           buffer_word (&sst, ti);   /* Type index */
 | 
|---|
| 3736 |           buffer_byte (&sst, i);    /* Register number */
 | 
|---|
| 3737 |           buffer_nstr (&sst, name); /* Symbol name */
 | 
|---|
| 3738 |           sst_end ();
 | 
|---|
| 3739 |           break;
 | 
|---|
| 3740 | 
 | 
|---|
| 3741 |         case '0': case '1': case '2': case '3': case '4':
 | 
|---|
| 3742 |         case '5': case '6': case '7': case '8': case '9':
 | 
|---|
| 3743 | 
 | 
|---|
| 3744 |           /* Local symbol. */
 | 
|---|
| 3745 | 
 | 
|---|
| 3746 |           if (where != -1)
 | 
|---|
| 3747 |             {
 | 
|---|
| 3748 |               warning ("Cannot use local symbol with N_%s", msg);
 | 
|---|
| 3749 |               return;
 | 
|---|
| 3750 |             }
 | 
|---|
| 3751 |           ti = hll_type ();
 | 
|---|
| 3752 | #if defined (HLL_DEBUG)
 | 
|---|
| 3753 |           printf ("  type=%#x\n", ti);
 | 
|---|
| 3754 | #endif
 | 
|---|
| 3755 |           sst_start (SST_auto);
 | 
|---|
| 3756 |           buffer_dword (&sst, symbol->n_value);  /* Offset into stk frame */
 | 
|---|
| 3757 |           buffer_word (&sst, ti);                /* Type index */
 | 
|---|
| 3758 |           buffer_nstr (&sst, name);              /* Symbol name */
 | 
|---|
| 3759 |           sst_end ();
 | 
|---|
| 3760 |           break;
 | 
|---|
| 3761 | 
 | 
|---|
| 3762 |         case 'F':
 | 
|---|
| 3763 |         case 'f':
 | 
|---|
| 3764 | 
 | 
|---|
| 3765 |           /* Function. */
 | 
|---|
| 3766 | 
 | 
|---|
| 3767 |           ++parse_ptr;
 | 
|---|
| 3768 |           if (where != N_TEXT)
 | 
|---|
| 3769 |             {
 | 
|---|
| 3770 |               warning ("Cannot use function with N_%s", msg);
 | 
|---|
| 3771 |               return;
 | 
|---|
| 3772 |             }
 | 
|---|
| 3773 |           last_fun_type.tag = ty_func;
 | 
|---|
| 3774 |           last_fun_type.index = -1;
 | 
|---|
| 3775 |           last_fun_type.d.func.domain = NULL;
 | 
|---|
| 3776 |           last_fun_type.d.func.ret = parse_type (NULL);
 | 
|---|
| 3777 | 
 | 
|---|
| 3778 |           /* Don't check for end of string -- parse_ptr points to a
 | 
|---|
| 3779 |              comma for nested functions! */
 | 
|---|
| 3780 | 
 | 
|---|
| 3781 |           last_fun_type.d.func.args = NULL;
 | 
|---|
| 3782 |           last_fun_type.d.func.arg_count = 0;
 | 
|---|
| 3783 |           last_fun_valid = TRUE;
 | 
|---|
| 3784 |           args_grow.count = 0;
 | 
|---|
| 3785 |           last_fun_addr = symbol->n_value;
 | 
|---|
| 3786 |           prologue_length = -1;
 | 
|---|
| 3787 | 
 | 
|---|
| 3788 |           for (i = *index + 1; i < sym_count && sym_ptr[i].n_type == N_PSYM; ++i)
 | 
|---|
| 3789 |             parse_symbol (&i, -1, "PSYM", FALSE);
 | 
|---|
| 3790 | 
 | 
|---|
| 3791 |           define_fun (symbol);
 | 
|---|
| 3792 | 
 | 
|---|
| 3793 |           /* Now look for N_LBRAC */
 | 
|---|
| 3794 |           next_lbrac (i);
 | 
|---|
| 3795 |           if (lbrac_index != -1)
 | 
|---|
| 3796 |             {
 | 
|---|
| 3797 |               if (prologue_length == -1)
 | 
|---|
| 3798 |                 prologue_length = sym_ptr[lbrac_index].n_value - last_fun_addr;
 | 
|---|
| 3799 |             }
 | 
|---|
| 3800 |           else
 | 
|---|
| 3801 |             {/* kso #456 2003-06-05: We need a begin to catch the parameters. */
 | 
|---|
| 3802 |               prologue_length = 0;
 | 
|---|
| 3803 |               block_begin (proc_start_addr);
 | 
|---|
| 3804 |             }
 | 
|---|
| 3805 | 
 | 
|---|
| 3806 |           /* Parameters */
 | 
|---|
| 3807 |           while (*index + 1 < sym_count && sym_ptr[*index+1].n_type == N_PSYM)
 | 
|---|
| 3808 |             {
 | 
|---|
| 3809 |               ++(*index);
 | 
|---|
| 3810 |               parse_symbol (index, -1, "PSYM", TRUE);
 | 
|---|
| 3811 |             }
 | 
|---|
| 3812 | 
 | 
|---|
| 3813 |           /* Start another block for the local variables. This is to work
 | 
|---|
| 3814 |              around some missing bracets in stabs and to fix problem with
 | 
|---|
| 3815 |              C++ bool type.  */
 | 
|---|
| 3816 |           dword addr = proc_start_addr + prologue_length;
 | 
|---|
| 3817 |           if (lbrac_index >= 0 && sym_ptr[lbrac_index].n_value > addr)
 | 
|---|
| 3818 |             addr = sym_ptr[lbrac_index].n_value;
 | 
|---|
| 3819 |           block_begin (addr);
 | 
|---|
| 3820 | 
 | 
|---|
| 3821 |           /* Local variables  (fix for boolparam testcase too). */
 | 
|---|
| 3822 |           while (*index + 1 < sym_count && sym_ptr[*index+1].n_type == N_LSYM)
 | 
|---|
| 3823 |             {
 | 
|---|
| 3824 |               ++(*index);
 | 
|---|
| 3825 |               parse_symbol (index, -1, "LSYM", TRUE);
 | 
|---|
| 3826 |             }
 | 
|---|
| 3827 | 
 | 
|---|
| 3828 |           /* If there's no N_LBRAC, write SST_end now */
 | 
|---|
| 3829 |           if (lbrac_index == -1)
 | 
|---|
| 3830 |             {/* kso #456 2003-06-05: We need a begin to catch the parameters. */
 | 
|---|
| 3831 |               while (block_grow.count > 0)
 | 
|---|
| 3832 |                 block_end (*index+1);
 | 
|---|
| 3833 |             }
 | 
|---|
| 3834 |           break;
 | 
|---|
| 3835 |         }
 | 
|---|
| 3836 |     }
 | 
|---|
| 3837 |   if (alloc_flag)
 | 
|---|
| 3838 |     free ((void *)str);         /* Remove the const attribute */
 | 
|---|
| 3839 | }
 | 
|---|
| 3840 | 
 | 
|---|
| 3841 | 
 | 
|---|
| 3842 | /* Create a type tag for HLL type index INDEX.  TYPE is either SST_tag
 | 
|---|
| 3843 |    (for structures and unions) or SST_tag2 (for classes).  NAME is
 | 
|---|
| 3844 |    the name of the structure, union or class. */
 | 
|---|
| 3845 | 
 | 
|---|
| 3846 | static void type_tag (int type, int index, const char *name)
 | 
|---|
| 3847 | {
 | 
|---|
| 3848 |   if (name != NULL)
 | 
|---|
| 3849 |     {
 | 
|---|
| 3850 |       size_t cch;
 | 
|---|
| 3851 |       if (type == SST_tag2 || (cch = strlen(name)) > 250)
 | 
|---|
| 3852 |        {
 | 
|---|
| 3853 |           sst_start (SST_tag2);
 | 
|---|
| 3854 |           buffer_word (&sst, index);
 | 
|---|
| 3855 |           buffer_enc (&sst, name);
 | 
|---|
| 3856 |         }
 | 
|---|
| 3857 |       else
 | 
|---|
| 3858 |         {
 | 
|---|
| 3859 |           char  achName[256];
 | 
|---|
| 3860 |           memcpy (achName, name, cch);
 | 
|---|
| 3861 |           achName[cch] = '\0';
 | 
|---|
| 3862 | 
 | 
|---|
| 3863 |           sst_start (type);
 | 
|---|
| 3864 |           buffer_word (&sst, index);
 | 
|---|
| 3865 |           buffer_nstr (&sst, achName);
 | 
|---|
| 3866 |         }
 | 
|---|
| 3867 |       sst_end ();
 | 
|---|
| 3868 |     }
 | 
|---|
| 3869 | }
 | 
|---|
| 3870 | 
 | 
|---|
| 3871 | 
 | 
|---|
| 3872 | /* Write a CuInfo SST entry to tell the debugger what compiler (C or
 | 
|---|
| 3873 |    C++) has been used. */
 | 
|---|
| 3874 | 
 | 
|---|
| 3875 | static void write_cuinfo (void)
 | 
|---|
| 3876 | {
 | 
|---|
| 3877 |   struct timestamp ts;
 | 
|---|
| 3878 |   time_t now;
 | 
|---|
| 3879 |   struct tm *tp;
 | 
|---|
| 3880 |   byte lang;
 | 
|---|
| 3881 | 
 | 
|---|
| 3882 |   if (cplusplus_flag)
 | 
|---|
| 3883 |     lang = 0x02;                /* C++ */
 | 
|---|
| 3884 |   else
 | 
|---|
| 3885 |     lang = 0x01;                /* C */
 | 
|---|
| 3886 | 
 | 
|---|
| 3887 |   time (&now);
 | 
|---|
| 3888 |   tp = localtime (&now);
 | 
|---|
| 3889 |   ts.year = tp->tm_year + 1900;
 | 
|---|
| 3890 |   ts.month = tp->tm_mon + 1;
 | 
|---|
| 3891 |   ts.day = tp->tm_mday;
 | 
|---|
| 3892 |   ts.hours = tp->tm_hour;
 | 
|---|
| 3893 |   ts.minutes = tp->tm_min;
 | 
|---|
| 3894 |   ts.seconds = tp->tm_sec;
 | 
|---|
| 3895 |   ts.hundredths = 0;
 | 
|---|
| 3896 |   sst_start (SST_cuinfo);
 | 
|---|
| 3897 |   buffer_byte (&sst, lang);
 | 
|---|
| 3898 |   buffer_nstr (&sst, "    ");       /* Compiler options */
 | 
|---|
| 3899 |   buffer_nstr (&sst, __DATE__);     /* Compiler date */
 | 
|---|
| 3900 |   buffer_mem (&sst, &ts, sizeof (ts));
 | 
|---|
| 3901 |   sst_end ();
 | 
|---|
| 3902 | }
 | 
|---|
| 3903 | 
 | 
|---|
| 3904 | 
 | 
|---|
| 3905 | /* Write a ChangSeg SST entry to define the text segment. */
 | 
|---|
| 3906 | 
 | 
|---|
| 3907 | static void write_changseg (void)
 | 
|---|
| 3908 | {
 | 
|---|
| 3909 |   struct relocation_info r;
 | 
|---|
| 3910 | 
 | 
|---|
| 3911 |   sst_start (SST_changseg);
 | 
|---|
| 3912 |   r.r_address = sst.size;
 | 
|---|
| 3913 |   buffer_word (&sst, 0);        /* Segment number */
 | 
|---|
| 3914 |   buffer_word (&sst, 0);        /* Reserved */
 | 
|---|
| 3915 |   sst_end ();
 | 
|---|
| 3916 |   r.r_extern = 0;
 | 
|---|
| 3917 |   r.r_length = 1;
 | 
|---|
| 3918 |   r.r_symbolnum = N_TEXT;
 | 
|---|
| 3919 |   r.r_pcrel = 0;
 | 
|---|
| 3920 |   r.r_pad = 0;
 | 
|---|
| 3921 |   buffer_mem (&sst_reloc, &r, sizeof (r));
 | 
|---|
| 3922 | }
 | 
|---|
| 3923 | 
 | 
|---|
| 3924 | 
 | 
|---|
| 3925 | /* Convert debug information.  The data is taken from the symbol and
 | 
|---|
| 3926 |    string tables of the current a.out module.  Output is put into the
 | 
|---|
| 3927 |    tt, sst etc. buffers. */
 | 
|---|
| 3928 | 
 | 
|---|
| 3929 | void convert_debug (void)
 | 
|---|
| 3930 | {
 | 
|---|
| 3931 |   int i;
 | 
|---|
| 3932 |   struct type *t1, *t2;
 | 
|---|
| 3933 | #if defined (HLL_DEBUG)
 | 
|---|
| 3934 |   setvbuf(stdout, NULL, _IONBF, 256);
 | 
|---|
| 3935 | #endif
 | 
|---|
| 3936 | 
 | 
|---|
| 3937 |   str_pool = strpool_init ();
 | 
|---|
| 3938 |   grow_init (&stype_grow, &stype_list, sizeof (*stype_list), 32);
 | 
|---|
| 3939 |   type_head = NULL; hll_type_index = 512;
 | 
|---|
| 3940 |   grow_init (&block_grow, &block_stack, sizeof (*block_stack), 16);
 | 
|---|
| 3941 |   grow_init (&args_grow, &args_list, sizeof (*args_list), 16);
 | 
|---|
| 3942 |   last_fun_valid = FALSE; prologue_length = -1;
 | 
|---|
| 3943 |   unnamed_struct_number = 1;
 | 
|---|
| 3944 | 
 | 
|---|
| 3945 |   /* Check whether converting a translated C++ program. */
 | 
|---|
| 3946 | #if 1 /* kso #465 2003-06-04: pretend everything is C++, that symbols is no longer present. */
 | 
|---|
| 3947 |   cplusplus_flag = 1;
 | 
|---|
| 3948 | #else
 | 
|---|
| 3949 |   cplusplus_flag = (find_symbol ("__gnu_compiled_cplusplus") != NULL);
 | 
|---|
| 3950 | #endif
 | 
|---|
| 3951 | 
 | 
|---|
| 3952 | 
 | 
|---|
| 3953 |   /* Parse the typedefs to avoid forward references. */
 | 
|---|
| 3954 | 
 | 
|---|
| 3955 |   for (i = 0; i < sym_count; ++i)
 | 
|---|
| 3956 |     switch (sym_ptr[i].n_type)
 | 
|---|
| 3957 |       {
 | 
|---|
| 3958 |       case N_LSYM:
 | 
|---|
| 3959 |       case N_LCSYM:
 | 
|---|
| 3960 |       case N_GSYM:
 | 
|---|
| 3961 |       case N_PSYM:
 | 
|---|
| 3962 |       case N_RSYM:
 | 
|---|
| 3963 |       case N_STSYM:
 | 
|---|
| 3964 |       case N_FUN:
 | 
|---|
| 3965 |         parse_typedef (&i);
 | 
|---|
| 3966 |         break;
 | 
|---|
| 3967 |       }
 | 
|---|
| 3968 | 
 | 
|---|
| 3969 |   /* Provide information about the compiler. */
 | 
|---|
| 3970 | 
 | 
|---|
| 3971 |   write_cuinfo ();
 | 
|---|
| 3972 | 
 | 
|---|
| 3973 |   /* Change the default segment. */
 | 
|---|
| 3974 | 
 | 
|---|
| 3975 |   write_changseg ();
 | 
|---|
| 3976 | 
 | 
|---|
| 3977 |   /* Parse the other symbol table entries. */
 | 
|---|
| 3978 | 
 | 
|---|
| 3979 |   lbrac_index = -1; block_grow.count = 0; proc_patch_base = 0;
 | 
|---|
| 3980 |   for (i = 0; i < sym_count; ++i)
 | 
|---|
| 3981 |     switch (sym_ptr[i].n_type)
 | 
|---|
| 3982 |       {
 | 
|---|
| 3983 |       case N_LSYM:
 | 
|---|
| 3984 |         parse_symbol (&i, -1, "LSYM", TRUE);
 | 
|---|
| 3985 |         break;
 | 
|---|
| 3986 | 
 | 
|---|
| 3987 |       case N_GSYM:
 | 
|---|
| 3988 |         parse_symbol (&i, -1, "GSYM", TRUE);
 | 
|---|
| 3989 |         break;
 | 
|---|
| 3990 | 
 | 
|---|
| 3991 |       case N_LCSYM:
 | 
|---|
| 3992 |         parse_symbol (&i, N_BSS, "LCSYM", TRUE);
 | 
|---|
| 3993 |         break;
 | 
|---|
| 3994 | 
 | 
|---|
| 3995 |       case N_STSYM:
 | 
|---|
| 3996 |         parse_symbol (&i, N_DATA, "STSYM", TRUE);
 | 
|---|
| 3997 |         break;
 | 
|---|
| 3998 | 
 | 
|---|
| 3999 |       case N_RSYM:
 | 
|---|
| 4000 |         parse_symbol (&i, -1, "RSYM", TRUE);
 | 
|---|
| 4001 |         break;
 | 
|---|
| 4002 | 
 | 
|---|
| 4003 |       case N_LBRAC:
 | 
|---|
| 4004 |         if (lbrac_index == -1)  /* N_LBRAC without local symbols */
 | 
|---|
| 4005 |           block_begin (sym_ptr[i].n_value);
 | 
|---|
| 4006 |         else if (i != lbrac_index)
 | 
|---|
| 4007 |           warning ("Invalid N_LBRAC");
 | 
|---|
| 4008 |         next_lbrac (i + 1);
 | 
|---|
| 4009 |         break;
 | 
|---|
| 4010 | 
 | 
|---|
| 4011 |       case N_RBRAC:
 | 
|---|
| 4012 |         block_end (i);
 | 
|---|
| 4013 |         next_lbrac (i + 1);
 | 
|---|
| 4014 |         break;
 | 
|---|
| 4015 | 
 | 
|---|
| 4016 |       case N_FUN:
 | 
|---|
| 4017 |         parse_symbol (&i, N_TEXT, "FUN", TRUE);
 | 
|---|
| 4018 |         break;
 | 
|---|
| 4019 |       }
 | 
|---|
| 4020 | 
 | 
|---|
| 4021 | #ifdef HASH_DEBUG
 | 
|---|
| 4022 | fprintf(stderr, "\n");
 | 
|---|
| 4023 | for (i = 0; i < TYPE_HASH_MAX; i++)
 | 
|---|
| 4024 |   if (i % 7 == 6)
 | 
|---|
| 4025 |     fprintf(stderr, "%3d: %4d\n", i, ctype_tag[i]);
 | 
|---|
| 4026 |   else
 | 
|---|
| 4027 |     fprintf(stderr, "%3d: %4d   ", i, ctype_tag[i]);
 | 
|---|
| 4028 | fprintf(stderr, "\nctypes=%d\n", ctypes);
 | 
|---|
| 4029 | for (i = 0; i < TYPE_HASH_MAX; i++)
 | 
|---|
| 4030 |   if (ctype_tag[i] > 1000)
 | 
|---|
| 4031 |     {
 | 
|---|
| 4032 |       int       j;
 | 
|---|
| 4033 |       unsigned  au[ty_max];
 | 
|---|
| 4034 |       memset(&au[0], 0, sizeof(au));
 | 
|---|
| 4035 |       for (t1 = atype_tag[i]; t1 != NULL; t1 = t1->nexthash)
 | 
|---|
| 4036 |         au[t1->tag]++;
 | 
|---|
| 4037 | 
 | 
|---|
| 4038 |       fprintf(stderr, "\nIndex %d is overpopulated (%d):\n", i, ctype_tag[i]);
 | 
|---|
| 4039 |       for (j = 0; j < 18; j++)
 | 
|---|
| 4040 |         if (j % 7 == 6)
 | 
|---|
| 4041 |           fprintf(stderr, "%2d: %4d\n", j, au[j]);
 | 
|---|
| 4042 |         else
 | 
|---|
| 4043 |           fprintf(stderr, "%2d: %4d   ", j, au[j]);
 | 
|---|
| 4044 |     }
 | 
|---|
| 4045 | #endif
 | 
|---|
| 4046 | 
 | 
|---|
| 4047 |   /* Create tags for structures, unions and classes. */
 | 
|---|
| 4048 | 
 | 
|---|
| 4049 |   for (t1 = type_head; t1 != NULL; t1 = t1->next)
 | 
|---|
| 4050 |     if (t1->index != -1)
 | 
|---|
| 4051 |       switch (t1->tag)
 | 
|---|
| 4052 |         {
 | 
|---|
| 4053 |         case ty_struc:
 | 
|---|
| 4054 |           type_tag (SST_tag, t1->index, t1->d.struc.name);
 | 
|---|
| 4055 |           break;
 | 
|---|
| 4056 |         case ty_class:
 | 
|---|
| 4057 |           type_tag (SST_tag2, t1->index, t1->d.class.name);
 | 
|---|
| 4058 |           break;
 | 
|---|
| 4059 |         case ty_enu:
 | 
|---|
| 4060 |           type_tag (SST_tag, t1->index, t1->d.enu.name);
 | 
|---|
| 4061 |           break;
 | 
|---|
| 4062 |         default:
 | 
|---|
| 4063 |           break;
 | 
|---|
| 4064 |         }
 | 
|---|
| 4065 | 
 | 
|---|
| 4066 | #ifdef HLL_DEBUG
 | 
|---|
| 4067 |   printf ("Stabs to HLL type mappings: %d/%d\n", stype_grow.count, stype_grow.alloc);
 | 
|---|
| 4068 |   for (i = 0; i < stype_grow.alloc; i++)
 | 
|---|
| 4069 |     if (stype_list[i])
 | 
|---|
| 4070 |       {
 | 
|---|
| 4071 |         printf ("  %3d => 0x%03x/%-3d  ", i + 1, stype_list[i]->index, stype_list[i]->index);
 | 
|---|
| 4072 |         show_type (stype_list[i]);
 | 
|---|
| 4073 |         printf("\n");
 | 
|---|
| 4074 |       }
 | 
|---|
| 4075 | #endif
 | 
|---|
| 4076 | 
 | 
|---|
| 4077 | 
 | 
|---|
| 4078 |   /* Deallocate memory. */
 | 
|---|
| 4079 | 
 | 
|---|
| 4080 |   grow_free (&stype_grow);
 | 
|---|
| 4081 |   grow_free (&args_grow);
 | 
|---|
| 4082 |   grow_free (&block_grow);
 | 
|---|
| 4083 |   for (t1 = type_head; t1 != NULL; t1 = t2)
 | 
|---|
| 4084 |     {
 | 
|---|
| 4085 |       t2 = t1->next;
 | 
|---|
| 4086 |       switch (t1->tag)
 | 
|---|
| 4087 |         {
 | 
|---|
| 4088 |         case ty_args:
 | 
|---|
| 4089 |           if (t1->d.args.list != NULL)
 | 
|---|
| 4090 |             free (t1->d.args.list);
 | 
|---|
| 4091 |           break;
 | 
|---|
| 4092 |         case ty_types:
 | 
|---|
| 4093 |           if (t1->d.types.list != NULL)
 | 
|---|
| 4094 |             free (t1->d.types.list);
 | 
|---|
| 4095 |           break;
 | 
|---|
| 4096 |         case ty_fields:
 | 
|---|
| 4097 |           if (t1->d.fields.list != NULL)
 | 
|---|
| 4098 |             free (t1->d.fields.list);
 | 
|---|
| 4099 |           break;
 | 
|---|
| 4100 |         case ty_values:
 | 
|---|
| 4101 |           if (t1->d.values.list != NULL)
 | 
|---|
| 4102 |             free (t1->d.values.list);
 | 
|---|
| 4103 |           break;
 | 
|---|
| 4104 |         default:
 | 
|---|
| 4105 |           break;
 | 
|---|
| 4106 |         }
 | 
|---|
| 4107 |       free (t1);
 | 
|---|
| 4108 |     }
 | 
|---|
| 4109 |   type_head = NULL;
 | 
|---|
| 4110 |   memset (&atype_tag, 0, sizeof(atype_tag));
 | 
|---|
| 4111 |   strpool_free (str_pool);
 | 
|---|
| 4112 |   str_pool = NULL;
 | 
|---|
| 4113 | }
 | 
|---|