summaryrefslogtreecommitdiff
path: root/gcc/mips-tfile.c
diff options
context:
space:
mode:
authorrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>1991-12-10 21:28:11 +0000
committerrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>1991-12-10 21:28:11 +0000
commit08456f3546164bbd6fab4bbc36035029c89b70cc (patch)
tree2d475fcb6a0c438e99cda01fc1f7b38dd63e68b3 /gcc/mips-tfile.c
parent9f6010db6b9c09bf89442540236acfef04b99802 (diff)
downloadgcc-08456f3546164bbd6fab4bbc36035029c89b70cc.tar.gz
*** empty log message ***
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/mips-tfile.c')
-rw-r--r--gcc/mips-tfile.c994
1 files changed, 807 insertions, 187 deletions
diff --git a/gcc/mips-tfile.c b/gcc/mips-tfile.c
index 2a23486556b..85990d38231 100644
--- a/gcc/mips-tfile.c
+++ b/gcc/mips-tfile.c
@@ -640,6 +640,11 @@ typedef char *CPTR_T;
#define Size_t unsigned int
#define Ptrdiff_t int
+#define CODE_MASK 0x8F300
+#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
+#define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
+#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
+
/* The following might be called from obstack or malloc,
so they can't be static. */
@@ -652,11 +657,6 @@ extern PTR_T xcalloc __proto((Size_t, Size_t));
extern PTR_T xrealloc __proto((PTR_T, Size_t));
extern void xfree __proto((PTR_T));
-extern PTR_T malloc __proto((Size_t));
-extern PTR_T calloc __proto((Size_t, Size_t));
-extern PTR_T realloc __proto((PTR_T, Size_t));
-extern void free __proto((PTR_T));
-
extern void fatal(); /* can't use prototypes here */
extern void error();
@@ -689,6 +689,31 @@ main ()
#include <signal.h>
#include <sys/stat.h>
+#ifdef USG
+#include "stab.h" /* If doing DBX on sysV, use our own stab.h. */
+#else
+#include <stab.h> /* On BSD, use the system's stab.h. */
+#endif /* not USG */
+
+#ifdef __GNU_STAB__
+#define STAB_CODE_TYPE enum __stab_debug_code
+#else
+#define STAB_CODE_TYPE int
+#endif
+
+#ifdef _OSF_SOURCE
+#define HAS_STDLIB_H
+#define HAS_UNISTD_H
+#endif
+
+#ifdef HAS_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAS_UNISTD_H
+#include <unistd.h>
+#endif
+
#ifndef errno
extern int errno; /* MIPS errno.h doesn't declare this */
#endif
@@ -887,6 +912,21 @@ typedef enum hash_state {
hash_record = 2 /* ok to record hash, but don't use prev. */
} hash_state_t;
+
+/* Types of different sized allocation requests. */
+enum alloc_type {
+ alloc_type_none, /* dummy value */
+ alloc_type_scope, /* nested scopes linked list */
+ alloc_type_vlinks, /* glue linking pages in varray */
+ alloc_type_shash, /* string hash element */
+ alloc_type_thash, /* type hash element */
+ alloc_type_tag, /* struct/union/tag element */
+ alloc_type_forward, /* element to hold unknown tag */
+ alloc_type_thead, /* head of type hash list */
+ alloc_type_varray, /* general varray allocation */
+ alloc_type_last /* last+1 element for array bounds */
+};
+
#define WORD_ALIGN(x) (((x) + 3) & ~3)
#define DWORD_ALIGN(x) (((x) + 7) & ~7)
@@ -959,6 +999,7 @@ typedef unsigned long symint_t;
/* Linked list support for nested scopes (file, block, structure, etc.). */
typedef struct scope {
struct scope *prev; /* previous scope level */
+ struct scope *free; /* free list pointer */
SYMR *lsym; /* pointer to local symbol node */
symint_t lnumber; /* lsym index */
st_t type; /* type of the node */
@@ -968,6 +1009,7 @@ typedef struct scope {
/* Forward reference list for tags referenced, but not yet defined. */
typedef struct forward {
struct forward *next; /* next forward reference */
+ struct forward *free; /* free list pointer */
AUXU *ifd_ptr; /* pointer to store file index */
AUXU *index_ptr; /* pointer to store symbol index */
AUXU *type_ptr; /* pointer to munge type info */
@@ -977,6 +1019,7 @@ typedef struct forward {
/* Linked list support for tags. The first tag in the list is always
the current tag for that block. */
typedef struct tag {
+ struct tag *free; /* free list pointer */
struct shash *hash_ptr; /* pointer to the hash table head */
struct tag *same_name; /* tag with same name in outer scope */
struct tag *same_block; /* next tag defined in the same block. */
@@ -986,17 +1029,27 @@ typedef struct tag {
symint_t index; /* index within file's local symbols */
} tag_t;
+
/* Head of a block's linked list of tags. */
typedef struct thead {
struct thead *prev; /* previous block */
+ struct thead *free; /* free list pointer */
struct tag *first_tag; /* first tag in block defined */
} thead_t;
+/* Union containing pointers to each the small structures which are freed up. */
+typedef union small_free {
+ scope_t *f_scope; /* scope structure */
+ thead_t *f_thead; /* tag head structure */
+ tag_t *f_tag; /* tag element structure */
+ forward_t *f_forward; /* forward tag reference */
+} small_free_t;
+
+
/* String hash table support. The size of the hash table must fit
within a page. */
-
#ifndef SHASH_SIZE
#define SHASH_SIZE 1009
#endif
@@ -1010,6 +1063,7 @@ typedef struct shash {
symint_t index; /* index within string table */
EXTR *esym_ptr; /* global symbol pointer */
SYMR *sym_ptr; /* local symbol pointer */
+ SYMR *end_ptr; /* symbol pointer to end block */
tag_t *tag_ptr; /* tag pointer */
PDR *proc_ptr; /* procedure descriptor pointer */
} shash_t;
@@ -1031,44 +1085,26 @@ typedef struct thash {
} thash_t;
-/* Union of various small structures that are allocated and freed
- from the same heap. */
-
-typedef union word8 {
- union word8 *prev; /* previous word8 structure */
- scope_t s; /* scope structure */
- vlinks_t v; /* varray linked list */
- shash_t sh; /* string hash linked list */
- thash_t th; /* type hash linked list */
- tag_t t; /* tag structure */
- forward_t f; /* forward tag references */
- thead_t thead; /* thead strcture */
- long words[8]; /* words to zero out when allocating */
-} word8_t;
-
-
/* Extended file descriptor that contains all of the support necessary
to add things to each file separately. */
typedef struct efdr {
- FDR fdr; /* File header to be written out */
- FDR *orig_fdr; /* original file header */
- char *name; /* filename */
- int name_len; /* length of the filename */
- symint_t void_type; /* aux. pointer to 'void' type */
- symint_t int_type; /* aux. pointer to 'int' type */
- scope_t *cur_scope; /* current nested scopes */
- symint_t file_index; /* current file number */
- int nested_scopes; /* # nested scopes */
- varray_t strings; /* local strings */
- varray_t symbols; /* local symbols */
- varray_t procs; /* procedures */
- varray_t aux_syms; /* auxiliary symbols */
-
- struct efdr *next_file; /* next file descriptor */
-
+ FDR fdr; /* File header to be written out */
+ FDR *orig_fdr; /* original file header */
+ char *name; /* filename */
+ int name_len; /* length of the filename */
+ symint_t void_type; /* aux. pointer to 'void' type */
+ symint_t int_type; /* aux. pointer to 'int' type */
+ scope_t *cur_scope; /* current nested scopes */
+ symint_t file_index; /* current file number */
+ int nested_scopes; /* # nested scopes */
+ varray_t strings; /* local strings */
+ varray_t symbols; /* local symbols */
+ varray_t procs; /* procedures */
+ varray_t aux_syms; /* auxiliary symbols */
+ struct efdr *next_file; /* next file descriptor */
/* string/type hash tables */
- shash_t **shash_head; /* string hash table */
- thash_t *thash_head[THASH_SIZE];
+ shash_t **shash_head; /* string hash table */
+ thash_t *thash_head[THASH_SIZE];
} efdr_t;
/* Pre-initialized extended file structure. */
@@ -1094,7 +1130,7 @@ static efdr_t init_file =
langC, /* lang: language for this file */
1, /* fMerge: whether this file can be merged */
0, /* fReadin: true if read in (not just created) */
-#ifdef BYTES_BIG_ENDIAN
+#if BYTES_BIG_ENDIAN
1, /* fBigendian: if 1, compiled on big endian machine */
#else
0, /* fBigendian: if 1, compiled on big endian machine */
@@ -1125,25 +1161,42 @@ static efdr_t init_file =
};
-static efdr_t *first_file; /* first file descriptor */
-static efdr_t *last_file; /* last file descriptor */
+static efdr_t *first_file; /* first file descriptor */
+static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
/* Union of various things that are held in pages. */
typedef union page {
- char byte [ PAGE_SIZE ];
- unsigned char ubyte[ PAGE_SIZE ];
- efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
- FDR ofile[ PAGE_SIZE / sizeof (FDR) ];
- PDR proc [ PAGE_SIZE / sizeof (PDR) ];
- SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
- EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
- AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
- DNR dense[ PAGE_SIZE / sizeof (DNR) ];
- word8_t word8[ PAGE_SIZE / sizeof (word8_t) ];
+ char byte [ PAGE_SIZE ];
+ unsigned char ubyte [ PAGE_SIZE ];
+ efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
+ FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
+ PDR proc [ PAGE_SIZE / sizeof (PDR) ];
+ SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
+ EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
+ AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
+ DNR dense [ PAGE_SIZE / sizeof (DNR) ];
+ scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
+ vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
+ shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
+ thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
+ tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
+ forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
+ thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
} page_t;
+/* Structure holding allocation information for small sized structures. */
+typedef struct alloc_info {
+ char *alloc_name; /* name of this allocation type (must be first) */
+ page_t *cur_page; /* current page being allocated from */
+ small_free_t free_list; /* current free list if any */
+ int unallocated; /* number of elements unallocated on page */
+ int total_alloc; /* total number of allocations */
+ int total_free; /* total number of frees */
+ int total_pages; /* total number of pages allocated */
+} alloc_info_t;
+
/* Type information collected together. */
typedef struct type_info {
bt_t basic_type; /* basic type */
@@ -1482,7 +1535,10 @@ static tq_t map_coff_derived_type[ (int)DT_MAX ] = {
};
+/* Keep track of different sized allocation requests. */
+static alloc_info_t alloc_counts[ (int)alloc_type_last ];
+
/* Pointers and such to the original symbol table that is read in. */
static struct filehdr orig_file_header; /* global object file header */
@@ -1520,6 +1576,8 @@ static EXTR *orig_ext_syms; /* external symbols */
static HDRR symbolic_header; /* symbolic header */
static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
static PDR *cur_proc_ptr = (PDR *) 0; /* current procedure header */
+static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info */
+static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */
static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/
static thead_t *cur_tag_head = (thead_t *)0; /* current tag head */
static long file_offset = 0; /* current file offset */
@@ -1541,6 +1599,14 @@ static int had_errors = 0; /* != 0 if errors were found */
static int rename_output = 0; /* != 0 if rename output file*/
static int delete_input = 0; /* != 0 if delete input after done */
+
+/* Pseudo symbol to use when putting stabs into the symbol table. */
+#ifndef STABS_SYMBOL
+#define STABS_SYMBOL "@stabs"
+#endif
+
+static char stabs_symbol[] = STABS_SYMBOL;
+
/* Forward reference for functions. See the definition for more details. */
@@ -1620,6 +1686,10 @@ STATIC void parse_def __proto((const char *));
STATIC void parse_end __proto((const char *));
STATIC void parse_ent __proto((const char *));
STATIC void parse_file __proto((const char *));
+STATIC void parse_stabs_common
+ __proto((const char *, const char *, const char *));
+STATIC void parse_stabs __proto((const char *));
+STATIC void parse_stabn __proto((const char *));
STATIC page_t *read_seek __proto((Size_t, off_t, const char *));
STATIC void copy_object __proto((void));
@@ -1637,9 +1707,18 @@ STATIC page_t *allocate_cluster
__proto((Size_t));
#endif
-STATIC word8_t *allocate_word8 __proto((void));
-STATIC void free_word8 __proto((word8_t *));
+STATIC forward_t *allocate_forward __proto((void));
+STATIC scope_t *allocate_scope __proto((void));
+STATIC shash_t *allocate_shash __proto((void));
+STATIC tag_t *allocate_tag __proto((void));
+STATIC thash_t *allocate_thash __proto((void));
+STATIC thead_t *allocate_thead __proto((void));
+STATIC vlinks_t *allocate_vlinks __proto((void));
+STATIC void free_forward __proto((forward_t *));
+STATIC void free_scope __proto((scope_t *));
+STATIC void free_tag __proto((tag_t *));
+STATIC void free_thead __proto((thead_t *));
/* Prototypes for library functions used. */
#if !defined(NO_LIB_PROTOTYPE) && !defined(_OSF_SOURCE) && !defined(_STDIO_H_)
@@ -1668,25 +1747,27 @@ extern int rename __proto((const char *, const char *));
extern int setvbuf __proto((FILE *, char *, int, int));
extern int fputs __proto((char *, FILE *));
#endif
-
-#ifndef NO_LIB_INTERNALS
-extern int _filbuf __proto((FILE *));
-extern int _flsbuf __proto((int, FILE *));
-#endif
#endif
extern char *sbrk __proto((int));
+
+#ifndef HAS_STDLIB_H
extern PTR_T malloc __proto((Size_t));
extern PTR_T calloc __proto((Size_t, Size_t));
extern PTR_T realloc __proto((PTR_T, Size_t));
extern void free __proto((PTR_T));
+extern int getopt __proto((int, char **, const char *));
+#endif
+
+#ifndef HAS_UNISTD_H
extern int close __proto((int));
extern int write __proto((int, CPTR_T, Size_t));
extern int read __proto((int, PTR_T, Size_t));
extern long lseek __proto((int, long, int));
extern int ftruncate __proto((int, long));
-extern int getopt __proto((int, char **, const char *));
extern int fstat __proto((int, struct stat *));
+#endif
+
extern char *mktemp __proto((char *));
extern char *optarg;
@@ -1718,6 +1799,10 @@ static pseudo_ops_t pseudo_ops[] = {
{ ".end", sizeof(".end")-1, parse_end },
{ ".ent", sizeof(".ent")-1, parse_ent },
{ ".file", sizeof(".file")-1, parse_file },
+ { "#.stabs", sizeof("#.stabs")-1, parse_stabs },
+ { "#.stabn", sizeof("#.stabn")-1, parse_stabn },
+ { ".stabs", sizeof(".stabs")-1, parse_stabs },
+ { ".stabn", sizeof(".stabn")-1, parse_stabn },
};
@@ -1727,7 +1812,7 @@ STATIC void
add_varray_page (vp)
varray_t *vp; /* varray to add page to */
{
- vlinks_t *new_links = (vlinks_t *) allocate_word8 ();
+ vlinks_t *new_links = allocate_vlinks ();
#ifdef MALLOC_CHECK
if (vp->object_size > 1)
@@ -1736,6 +1821,9 @@ add_varray_page (vp)
#endif
new_links->datum = allocate_page ();
+ alloc_counts[ (int)alloc_type_varray ].total_alloc++;
+ alloc_counts[ (int)alloc_type_varray ].total_pages++;
+
new_links->start_index = vp->num_allocated;
vp->objects_last_page = 0;
@@ -1817,7 +1905,7 @@ add_string (vp, hash_tbl, start, end_p1, ret_hash)
add_varray_page (vp);
}
- hash_ptr = (shash_t *) allocate_word8 ();
+ hash_ptr = allocate_shash ();
hash_ptr->next = hash_tbl[hi];
hash_tbl[hi] = hash_ptr;
@@ -1882,10 +1970,14 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
ret = vp->num_allocated++;
+ if (MIPS_IS_STAB(psym))
+ return ret;
+
/* Save the symbol within the hash table if this is a static
- item. */
- if (type == st_Global || type == st_Static || type == st_Label
- || type == st_Proc || type == st_StaticProc)
+ item, and it has a name. */
+ if (hash_ptr != (shash_t *)0
+ && (type == st_Global || type == st_Static || type == st_Label
+ || type == st_Proc || type == st_StaticProc))
hash_ptr->sym_ptr = psym;
/* push or pop a scope if appropriate. */
@@ -1898,7 +1990,7 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
case st_Proc: /* procedure */
case st_StaticProc: /* static procedure */
case st_Block: /* begin scope */
- pscope = (scope_t *) allocate_word8 ();
+ pscope = allocate_scope ();
pscope->prev = cur_file_ptr->cur_scope;
pscope->lsym = psym;
pscope->lnumber = ret;
@@ -1913,7 +2005,7 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
file types, so that tags can span file boundaries. */
if (type != st_File && storage != sc_Info)
{
- ptag_head = (thead_t *) allocate_word8 ();
+ ptag_head = allocate_thead ();
ptag_head->first_tag = 0;
ptag_head->prev = cur_tag_head;
cur_tag_head = ptag_head;
@@ -1948,10 +2040,10 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
ptag_next = ptag->same_block;
ptag->hash_ptr->tag_ptr = ptag->same_name;
- free_word8 ((word8_t *) ptag);
+ free_tag (ptag);
}
- free_word8 ((word8_t *) ptag_head);
+ free_thead (ptag_head);
}
cur_file_ptr->cur_scope = pscope->prev;
@@ -1981,7 +2073,7 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
}
}
- free_word8 ((word8_t *) pscope);
+ free_scope (pscope);
}
}
@@ -2181,7 +2273,7 @@ add_aux_sym_tir (t, state, hash_tbl)
if (hash_ptr == (thash_t *)0)
{
- hash_ptr = (thash_t *) allocate_word8 ();
+ hash_ptr = allocate_thash ();
hash_ptr->next = hash_tbl[hi];
hash_ptr->type = aux;
hash_ptr->index = vp->num_allocated;
@@ -2198,6 +2290,19 @@ add_aux_sym_tir (t, state, hash_tbl)
ret = vp->num_allocated++;
+ /* Add bitfield length if it exists.
+
+ NOTE: Mips documentation claims bitfield goes at the end of the
+ AUX record, but the DECstation compiler emits it here.
+ (This would only make a difference for enum bitfields.)
+
+ Also note: We use the last size given since gcc may emit 2
+ for an enum bitfield. */
+
+ if (t->bitfield)
+ (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
+
+
/* Add tag information if needed. Structure, union, and enum
references add 2 aux symbols: a [file index, symbol index]
pointer to the structure type, and the current file index. */
@@ -2221,7 +2326,7 @@ add_aux_sym_tir (t, state, hash_tbl)
}
else
{
- register forward_t *forward_ref = (forward_t *) allocate_word8 ();
+ register forward_t *forward_ref = allocate_forward ();
forward_ref->type_ptr = aux_ptr;
forward_ref->next = t->tag_ptr->forward_ref;
@@ -2237,11 +2342,6 @@ add_aux_sym_tir (t, state, hash_tbl)
}
}
- /* Add bitfield length if it exists. */
- if (t->bitfield)
- (void) add_aux_sym_symint ((symint_t)t->sizes[0]);
-
-
/* Add information about array bounds if they exist. */
for (i = 0; i < t->num_dims; i++)
{
@@ -2256,6 +2356,9 @@ add_aux_sym_tir (t, state, hash_tbl)
: (t->sizes[i] * 8) / t->dimensions[i]);
};
+ /* NOTE: Mips documentation claism that the bitfield width goes here.
+ But it needs to be emitted earlier. */
+
return ret;
}
@@ -2295,7 +2398,7 @@ get_tag (tag_start, tag_end_p1, index, basic_type)
tag_end_p1,
&hash_ptr);
- tag_ptr = (tag_t *) allocate_word8 ();
+ tag_ptr = allocate_tag ();
tag_ptr->forward_ref = (forward_t *) 0;
tag_ptr->hash_ptr = hash_ptr;
tag_ptr->same_name = hash_ptr->tag_ptr;
@@ -2362,7 +2465,7 @@ add_unknown_tag (ptag)
f_cur->ifd_ptr->isym = file_index;
f_cur->index_ptr->rndx.index = sym_index;
- free_word8 ((word8_t *) f_cur);
+ free_forward (f_cur);
}
return;
@@ -2405,13 +2508,17 @@ add_procedure (func_start, func_end_p1)
{
register PDR *old_proc_ptr = shash_ptr->proc_ptr;
register SYMR *sym_ptr = shash_ptr->sym_ptr;
+ register FDR *orig_fdr = file_ptr->orig_fdr;
if (old_proc_ptr != (PDR *)0
&& sym_ptr != (SYMR *)0
&& ((st_t)sym_ptr->st == st_Proc || (st_t)sym_ptr->st == st_StaticProc))
{
- cur_oproc_ptr = old_proc_ptr;
+ cur_oproc_begin = sym_ptr;
+ cur_oproc_end = shash_ptr->end_ptr;
value = sym_ptr->value;
+
+ cur_oproc_ptr = old_proc_ptr;
proc_type = (st_t)sym_ptr->st;
*new_proc_ptr = *old_proc_ptr; /* initialize */
}
@@ -2424,10 +2531,8 @@ add_procedure (func_start, func_end_p1)
new_proc_ptr->isym = file_ptr->symbols.num_allocated;
/* Push the start of the function. */
- (void) add_local_symbol (func_start,
- func_end_p1,
- proc_type,
- sc_Text,
+ (void) add_local_symbol (func_start, func_end_p1,
+ proc_type, sc_Text,
value,
(symint_t)0);
}
@@ -2499,12 +2604,8 @@ add_file (file_start, file_end_p1)
file_ptr->name_len = file_end_p1 - file_start;
/* Update the linked list of file descriptors. */
- if (first_file == (efdr_t *)0)
- first_file = file_ptr;
- else
- last_file->next_file = file_ptr;
-
- last_file = file_ptr;
+ *last_file_ptr = file_ptr;
+ last_file_ptr = &file_ptr->next_file;
/* Add void & int types to the file (void should be first to catch
errant 0's within the index fields). */
@@ -2717,11 +2818,15 @@ parse_begin (start)
return;
}
- (void) add_local_symbol ((const char *)0,
- (const char *)0,
- st_Block,
- sc_Text,
- (symint_t)hash_ptr->sym_ptr->value,
+ if (cur_oproc_begin == (SYMR *)0)
+ {
+ error ("Procedure table %.*s not found for #.begin", end_p1 - start, start);
+ return;
+ }
+
+ (void) add_local_symbol ((const char *)0, (const char *)0,
+ st_Block, sc_Text,
+ (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
(symint_t)0);
}
@@ -2745,7 +2850,7 @@ parse_bend (start)
if (cur_proc_ptr == (PDR *)0)
{
- error ("#.begin directive without a preceeding .ent directive");
+ error ("#.bend directive without a preceeding .ent directive");
return;
}
@@ -2759,15 +2864,19 @@ parse_bend (start)
if (hash_ptr == (shash_t *)0)
{
- error ("Label %.*s not found for #.begin", end_p1 - start, start);
+ error ("Label %.*s not found for #.bend", end_p1 - start, start);
return;
}
- (void) add_local_symbol ((const char *)0,
- (const char *)0,
- st_End,
- sc_Text,
- (symint_t)hash_ptr->sym_ptr->value,
+ if (cur_oproc_begin == (SYMR *)0)
+ {
+ error ("Procedure table %.*s not found for #.bend", end_p1 - start, start);
+ return;
+ }
+
+ (void) add_local_symbol ((const char *)0, (const char *)0,
+ st_End, sc_Text,
+ (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
(symint_t)0);
}
@@ -3115,9 +3224,12 @@ parse_def (name_start)
if ((orig_hash_ptr == (shash_t *)0
|| orig_hash_ptr->sym_ptr == (SYMR *)0)
&& eptr == (EXTR *)0)
- error ("internal error, %.*s not found in original or external symbol tables",
- arg_end_p1 - arg_start,
- arg_start);
+ {
+ fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
+ arg_end_p1 - arg_start,
+ arg_start);
+ value = 0;
+ }
else
{
SYMR *ptr = (orig_hash_ptr != (shash_t *)0
@@ -3290,10 +3402,8 @@ parse_def (name_start)
|| eptr->asym.st == (int)st_Nil
|| cur_proc_ptr != (PDR *)0)
{
- symint_t isym = add_local_symbol (name_start,
- name_end_p1,
- symbol_type,
- storage_class,
+ symint_t isym = add_local_symbol (name_start, name_end_p1,
+ symbol_type, storage_class,
value,
index);
@@ -3321,7 +3431,7 @@ parse_def (name_start)
f_cur->ifd_ptr->isym = file_index;
f_cur->index_ptr->rndx.index = isym;
- free_word8 ((word8_t *) f_cur);
+ free_forward (f_cur);
}
tag_ptr->forward_ref = (forward_t *)0;
@@ -3389,23 +3499,14 @@ parse_end (start)
orig_fdr = cur_file_ptr->orig_fdr;
value = 0;
- if (orig_fdr != (FDR *)0 && cur_oproc_ptr != (PDR *)0)
- {
- register SYMR *sym_ptr = ORIG_LSYMS (orig_fdr->isymBase + cur_oproc_ptr->isym);
+ if (orig_fdr != (FDR *)0 && cur_oproc_end != (SYMR *)0)
+ value = cur_oproc_end->value;
- if ((st_t)sym_ptr->st == st_Proc
- || (st_t)sym_ptr->st == st_StaticProc)
- {
- AUXU *aptr = ORIG_AUX (orig_fdr->iauxBase + sym_ptr->index);
- symint_t end_index = aptr->isym;
- value = (ORIG_LSYMS (orig_fdr->isymBase + end_index - 1))->value;
- }
- }
+ else
+ error ("Cannot find .end block for %.*s", end_func_p1 - start_func, start_func);
- (void) add_local_symbol (start_func,
- end_func_p1,
- st_End,
- sc_Text,
+ (void) add_local_symbol (start_func, end_func_p1,
+ st_End, sc_Text,
value,
(symint_t)0);
@@ -3479,6 +3580,201 @@ parse_file (start)
}
+/* Parse .stabs directives.
+
+ .stabs directives have five fields:
+ "string" a string, encoding the type information.
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ 0 a zero or line number
+ value a numeric value or an address.
+
+ If the value is relocatable, we transform this into:
+ iss points as an index into string space
+ value value from lookup of the name
+ st st from lookup of the name
+ sc sc from lookup of the name
+ index code|CODE_MASK
+
+ If the value is not relocatable, we transform this into:
+ iss points as an index into string space
+ value value
+ st st_Nil
+ sc sc_Nil
+ index code|CODE_MASK
+
+ .stabn directives have four fields (string is null):
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ 0 a zero or a line number
+ value a numeric value or an address. */
+
+STATIC void
+parse_stabs_common (string_start, string_end, rest)
+ const char *string_start; /* start of string or NULL */
+ const char *string_end; /* end+1 of string or NULL */
+ const char *rest; /* rest of the directive. */
+{
+ efdr_t *save_file_ptr = cur_file_ptr;
+ symint_t code;
+ symint_t value;
+ char *p;
+ st_t st;
+ sc_t sc;
+ int ch;
+ static int stabs_seen = 0;
+
+ if (stabs_seen++ == 0)
+ {
+ /* Add a dummy @stabs dymbol. */
+ (void) add_local_symbol (stabs_symbol,
+ stabs_symbol + sizeof (stabs_symbol),
+ stNil, scInfo, -1, MIPS_MARK_STAB(0));
+ }
+
+ /* Read code from stabs. */
+ if (!isdigit (*rest))
+ {
+ error ("Illegal .stabs/.stabn directive, code is non-numeric");
+ return;
+ }
+
+ code = strtol (rest, &p, 0);
+
+ /* Line number stabs are handled differently, since they have two values,
+ the line number and the address of the label. We use the index field
+ (aka code) to hold the line number, and the value field to hold the
+ address. The symbol type is st_Label, which should be different from
+ the other stabs, so that gdb can recognize it. */
+
+ if (code == (int)N_SLINE)
+ {
+ SYMR *sym_ptr;
+ shash_t *shash_ptr;
+
+ /* Skip ,0, */
+ if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !isdigit (p[3]))
+ {
+ error ("Illegal line number .stabs/.stabn directive");
+ return;
+ }
+
+ code = strtol (p+3, &p, 0);
+ ch = *++p;
+ if (code <= 0 || p[-1] != ',' || isdigit (ch) || !IS_ASM_IDENT (ch))
+ {
+ error ("Illegal line number .stabs/.stabn directive");
+ return;
+ }
+
+ shash_ptr = hash_string (p,
+ strlen (p) - 1,
+ &orig_str_hash[0],
+ (symint_t *)0);
+
+ if (shash_ptr == (shash_t *)0
+ || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
+ {
+ error ("Illegal .stabs/.stabn directive, value not found");
+ return;
+ }
+
+ if ((st_t) sym_ptr->st != st_Label)
+ {
+ error ("Illegal line number .stabs/.stabn directive");
+ return;
+ }
+
+ st = st_Label;
+ sc = (sc_t) sym_ptr->sc;
+ value = sym_ptr->value;
+ }
+ else
+ {
+ code = MIPS_MARK_STAB(code);
+
+ /* Skip ,0,0, */
+ if (p[0] != ',' || p[1] != '0' || p[2] != ',' || p[3] != '0' || p[4] != ',')
+ {
+ error ("Illegal .stabs/.stabn directive, manditory 0 isn't");
+ return;
+ }
+
+ p += 5;
+ ch = *p;
+ if (!IS_ASM_IDENT (ch) && ch != '-')
+ {
+ error ("Illegal .stabs/.stabn directive, bad character");
+ return;
+ }
+
+ if (isdigit (ch) || ch == '-')
+ {
+ st = st_Nil;
+ sc = sc_Nil;
+ value = strtol (p, &p, 0);
+ if (*p != '\n')
+ {
+ error ("Illegal .stabs/.stabn directive, stuff after numeric value");
+ return;
+ }
+ }
+ else if (!IS_ASM_IDENT (ch))
+ {
+ error ("Illegal .stabs/.stabn directive, bad character");
+ return;
+ }
+ else
+ {
+ SYMR *sym_ptr;
+ shash_t *shash_ptr = hash_string (p,
+ strlen (p) - 1,
+ &orig_str_hash[0],
+ (symint_t *)0);
+
+ if (shash_ptr == (shash_t *)0
+ || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
+ {
+ error ("Illegal .stabs/.stabn directive, value not found");
+ return;
+ }
+
+ st = (st_t) sym_ptr->st;
+ sc = (sc_t) sym_ptr->sc;
+ value = sym_ptr->value;
+ }
+ }
+
+ (void) add_local_symbol (string_start, string_end, st, sc, value, code);
+ /* Restore normal file type. */
+ cur_file_ptr = save_file_ptr;
+}
+
+
+STATIC void
+parse_stabs (start)
+ const char *start; /* start of directive */
+{
+ const char *end = strchr (start+1, '"');
+
+ if (*start != '"' || end == (const char *)0 || end[1] != ',')
+ {
+ error ("Illegal .stabs directive, no string");
+ return;
+ }
+
+ parse_stabs_common (start+1, end, end+2);
+}
+
+
+STATIC void
+parse_stabn (start)
+ const char *start; /* start of directive */
+{
+ parse_stabs_common ((const char *)0, (const char *)0, start);
+}
+
+
/* Parse the input file, and write the lines to the output file
if needed. */
@@ -3496,7 +3792,7 @@ parse_input __proto((void))
/* Add a dummy scope block around the entire compilation unit for
structures defined outside of blocks. */
- ptag_head = (thead_t *) allocate_word8 ();
+ ptag_head = allocate_thead ();
ptag_head->first_tag = 0;
ptag_head->prev = cur_tag_head;
cur_tag_head = ptag_head;
@@ -3534,10 +3830,10 @@ parse_input __proto((void))
ptag_next = ptag->same_block;
ptag->hash_ptr->tag_ptr = ptag->same_name;
- free_word8 ((word8_t *) ptag);
+ free_tag (ptag);
}
- free_word8 ((word8_t *) ptag_head);
+ free_thead (ptag_head);
}
@@ -3576,10 +3872,8 @@ update_headers __proto((void))
file_ptr = file_ptr->next_file)
{
cur_file_ptr = file_ptr;
- (void) add_local_symbol ((const char *)0,
- (const char *)0,
- st_End,
- sc_Text,
+ (void) add_local_symbol ((const char *)0, (const char *)0,
+ st_End, sc_Text,
(symint_t)0,
(symint_t)0);
@@ -4023,6 +4317,7 @@ copy_object __proto((void))
register int sys_write;
register int fd, es;
register int delete_ifd = 0;
+ register int *remap_file_number;
struct stat stat_buf;
if (debug)
@@ -4168,12 +4463,33 @@ copy_object __proto((void))
}
+ /* Create array to map original file numbers to the new file numbers
+ (in case there are duplicate filenames, we collapse them into one
+ file section, the MIPS assembler may or may not collapse them). */
+
+ remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
+
+ for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
+ {
+ register FDR *fd_ptr = ORIG_FILES (fd);
+ register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
+
+ /* file support itself. */
+ add_file (filename, filename + strlen (filename));
+ remap_file_number[fd] = cur_file_ptr->file_index;
+ }
+
+ if (delete_ifd > 0) /* just in case */
+ remap_file_number[0] = remap_file_number[1];
+
+
/* Loop, adding each of the external symbols. These must be in
order or otherwise we would have to change the relocation
entries. We don't just call add_bytes, because we need to have
the names put into the external hash table. We set the type to
'void' for now, and parse_def will fill in the correct type if it
- is in the symbol table. */
+ is in the symbol table. We must add the external symbols before
+ the locals, since the locals do lookups against the externals. */
if (debug)
fprintf (stderr, "\tehash\n");
@@ -4182,6 +4498,7 @@ copy_object __proto((void))
{
register EXTR *eptr = orig_ext_syms + es;
register char *ename = ORIG_ESTRS (eptr->asym.iss);
+ register unsigned ifd = eptr->ifd;
(void) add_ext_symbol (ename,
ename + strlen (ename),
@@ -4189,7 +4506,7 @@ copy_object __proto((void))
(sc_t) eptr->asym.sc,
eptr->asym.value,
(symint_t)((eptr->asym.index == indexNil) ? indexNil : 0),
- eptr->ifd - delete_ifd);
+ (ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
}
@@ -4258,7 +4575,7 @@ copy_object __proto((void))
else
{
- shash_ptr = (shash_t *) allocate_word8 ();
+ shash_ptr = allocate_shash ();
shash_ptr->next = orig_str_hash[hash_index];
orig_str_hash[hash_index] = shash_ptr;
@@ -4268,6 +4585,27 @@ copy_object __proto((void))
shash_ptr->sym_ptr = sym;
}
}
+ break;
+
+ case st_End:
+ if ((sc_t) sym->sc == sc_Text)
+ {
+ register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
+
+ if (*str != '\0')
+ {
+ register Size_t len = strlen (str);
+ register shash_t *shash_ptr = hash_string (str,
+ (Ptrdiff_t)len,
+ &orig_str_hash[0],
+ (symint_t *)0);
+
+ if (shash_ptr != (shash_t *)0)
+ shash_ptr->end_ptr = sym;
+ }
+ }
+ break;
+
}
}
@@ -4355,6 +4693,7 @@ main (argc, argv)
char *p = strrchr (argv[0], '/');
char *num_end;
int option;
+ int i;
progname = (p != 0) ? p+1 : argv[0];
@@ -4373,12 +4712,18 @@ main (argc, argv)
sizeof (page_t),
PAGE_USIZE);
- if (sizeof (word8_t) != 8 * sizeof (symint_t))
- fatal ("Word8_t has a sizeof %d bytes, when it should be %d",
- sizeof (word8_t),
- 8 * sizeof (symint_t));
#endif
+ alloc_counts[ alloc_type_none ].alloc_name = "none";
+ alloc_counts[ alloc_type_scope ].alloc_name = "scope";
+ alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
+ alloc_counts[ alloc_type_shash ].alloc_name = "shash";
+ alloc_counts[ alloc_type_thash ].alloc_name = "thash";
+ alloc_counts[ alloc_type_tag ].alloc_name = "tag";
+ alloc_counts[ alloc_type_forward ].alloc_name = "forward";
+ alloc_counts[ alloc_type_thead ].alloc_name = "thead";
+ alloc_counts[ alloc_type_varray ].alloc_name = "varray";
+
int_type_info = type_info_init;
int_type_info.basic_type = bt_Int;
@@ -4500,7 +4845,7 @@ main (argc, argv)
fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
}
- free_multiple_pages (buffer, 4);
+ free_multiple_pages ((page_t *)buffer, 4);
if (len < 0)
pfatal_with_name (object_name);
@@ -4532,24 +4877,27 @@ main (argc, argv)
pfatal_with_name (argv[optind]);
}
-
-#ifdef _IOFBF
- /* Try to prevent stdio from malloc'ing memory for the buffers. At the
- same time, increase the size of mips' stdio buffers. */
-
- setvbuf (object_stream, (char *) allocate_multiple_pages (2), _IOFBF, 2*PAGE_SIZE);
- setvbuf (obj_in_stream, (char *) allocate_multiple_pages (2), _IOFBF, 2*PAGE_SIZE);
- setvbuf (stdin, (char *) allocate_multiple_pages (2), _IOFBF, 2*PAGE_SIZE);
- setvbuf (stdout, (char *) allocate_multiple_pages (2), _IOFBF, 2*PAGE_SIZE);
- setvbuf (stderr, (char *) allocate_multiple_pages (2), _IOLBF, 2*PAGE_SIZE);
-#endif
-
copy_object (); /* scan & copy object file */
parse_input (); /* scan all of input */
update_headers (); /* write out tfile */
write_object ();
+ if (debug)
+ {
+ fprintf (stderr, "\n\tAllocation summary:\n\n");
+ for (i = (int)alloc_type_none; i < (int)alloc_type_last; i++)
+ if (alloc_counts[i].total_alloc)
+ {
+ fprintf (stderr,
+ "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
+ alloc_counts[i].alloc_name,
+ alloc_counts[i].total_alloc,
+ alloc_counts[i].total_free,
+ alloc_counts[i].total_pages);
+ }
+ }
+
return (had_errors) ? 1 : 0;
}
@@ -4751,65 +5099,337 @@ allocate_page __proto((void))
}
-/* Allocate and release 4 word quanities. */
+/* Allocate scoping information. */
+
+STATIC scope_t *
+allocate_scope __proto((void))
+{
+ register scope_t *ptr;
+ static scope_t initial_scope;
+
+#ifndef MALLOC_CHECK
+ ptr = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
+ if (ptr != (scope_t *)0)
+ alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
+
+ else
+ {
+ register int unallocated = alloc_counts[ (int)alloc_type_scope ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_scope ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (scope_t);
+ alloc_counts[ (int)alloc_type_scope ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_scope ].total_pages++;
+ }
+
+ ptr = &cur_page->scope[ --unallocated ];
+ alloc_counts[ (int)alloc_type_scope ].unallocated = unallocated;
+ }
+
+#else
+ ptr = (scope_t *) xmalloc (sizeof (scope_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_scope ].total_alloc++;
+ *ptr = initial_scope;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+STATIC void
+free_scope (ptr)
+ scope_t *ptr;
+{
+ alloc_counts[ (int)alloc_type_scope ].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
+ alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr;
+
+#else
+ xfree ((PTR_T) ptr);
+#endif
+
+}
+
+
+/* Allocate links for pages in a virtual array. */
+
+STATIC vlinks_t *
+allocate_vlinks __proto((void))
+{
+ register vlinks_t *ptr;
+ static vlinks_t initial_vlinks;
+
+#ifndef MALLOC_CHECK
+ register int unallocated = alloc_counts[ (int)alloc_type_vlinks ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_vlinks ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (vlinks_t);
+ alloc_counts[ (int)alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_vlinks ].total_pages++;
+ }
+
+ ptr = &cur_page->vlinks[ --unallocated ];
+ alloc_counts[ (int)alloc_type_vlinks ].unallocated = unallocated;
+
+#else
+ ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_vlinks ].total_alloc++;
+ *ptr = initial_vlinks;
+ return ptr;
+}
+
+
+/* Allocate string hash buckets. */
+
+STATIC shash_t *
+allocate_shash __proto((void))
+{
+ register shash_t *ptr;
+ static shash_t initial_shash;
+
+#ifndef MALLOC_CHECK
+ register int unallocated = alloc_counts[ (int)alloc_type_shash ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_shash ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (shash_t);
+ alloc_counts[ (int)alloc_type_shash ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_shash ].total_pages++;
+ }
+
+ ptr = &cur_page->shash[ --unallocated ];
+ alloc_counts[ (int)alloc_type_shash ].unallocated = unallocated;
+
+#else
+ ptr = (shash_t *) xmalloc (sizeof (shash_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_shash ].total_alloc++;
+ *ptr = initial_shash;
+ return ptr;
+}
+
+
+/* Allocate type hash buckets. */
+
+STATIC thash_t *
+allocate_thash __proto((void))
+{
+ register thash_t *ptr;
+ static thash_t initial_thash;
+
+#ifndef MALLOC_CHECK
+ register int unallocated = alloc_counts[ (int)alloc_type_thash ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_thash ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thash_t);
+ alloc_counts[ (int)alloc_type_thash ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_thash ].total_pages++;
+ }
+
+ ptr = &cur_page->thash[ --unallocated ];
+ alloc_counts[ (int)alloc_type_thash ].unallocated = unallocated;
+
+#else
+ ptr = (thash_t *) xmalloc (sizeof (thash_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_thash ].total_alloc++;
+ *ptr = initial_thash;
+ return ptr;
+}
+
+
+/* Allocate structure, union, or enum tag information. */
+
+STATIC tag_t *
+allocate_tag __proto((void))
+{
+ register tag_t *ptr;
+ static tag_t initial_tag;
#ifndef MALLOC_CHECK
-static word8_t *word8_free_list = (word8_t *)0;
+ ptr = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
+ if (ptr != (tag_t *)0)
+ alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr->free;
+
+ else
+ {
+ register int unallocated = alloc_counts[ (int)alloc_type_tag ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_tag ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (tag_t);
+ alloc_counts[ (int)alloc_type_tag ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_tag ].total_pages++;
+ }
+
+ ptr = &cur_page->tag[ --unallocated ];
+ alloc_counts[ (int)alloc_type_tag ].unallocated = unallocated;
+ }
+
+#else
+ ptr = (tag_t *) xmalloc (sizeof (tag_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_tag ].total_alloc++;
+ *ptr = initial_tag;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+STATIC void
+free_tag (ptr)
+ tag_t *ptr;
+{
+ alloc_counts[ (int)alloc_type_tag ].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
+ alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr;
+
+#else
+ xfree ((PTR_T) ptr);
#endif
-STATIC word8_t *
-allocate_word8 __proto((void))
+}
+
+
+/* Allocate forward reference to a yet unknown tag. */
+
+STATIC forward_t *
+allocate_forward __proto((void))
{
+ register forward_t *ptr;
+ static forward_t initial_forward;
+
#ifndef MALLOC_CHECK
- register word8_t *ptr = word8_free_list;
- if (ptr != (word8_t *)0)
- word8_free_list = ptr->prev;
+ ptr = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
+ if (ptr != (forward_t *)0)
+ alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr->free;
+
else
{
- register int i;
- register page_t *page_ptr;
+ register int unallocated = alloc_counts[ (int)alloc_type_forward ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_forward ].cur_page;
- page_ptr = allocate_page ();
- ptr = &page_ptr->word8[0];
- for (i = 0; i < (PAGE_SIZE / sizeof (word8_t)) - 1; i++)
+ if (unallocated == 0)
{
- ptr->prev = word8_free_list;
- word8_free_list = ptr;
- ptr++;
+ unallocated = PAGE_SIZE / sizeof (forward_t);
+ alloc_counts[ (int)alloc_type_forward ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_forward ].total_pages++;
}
+
+ ptr = &cur_page->forward[ --unallocated ];
+ alloc_counts[ (int)alloc_type_forward ].unallocated = unallocated;
}
- ptr->words[0] = 0;
- ptr->words[1] = 0;
- ptr->words[2] = 0;
- ptr->words[3] = 0;
- ptr->words[4] = 0;
- ptr->words[5] = 0;
- ptr->words[6] = 0;
- ptr->words[7] = 0;
+#else
+ ptr = (forward_t *) xmalloc (sizeof (forward_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_forward ].total_alloc++;
+ *ptr = initial_forward;
return ptr;
+}
-#else /* MALLOC_CHECK */
- return (word8_t *) xcalloc (1, sizeof (word8_t));
+/* Free scoping information. */
-#endif /* MALLOC_CHECK */
+STATIC void
+free_forward (ptr)
+ forward_t *ptr;
+{
+ alloc_counts[ (int)alloc_type_forward ].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
+ alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr;
+
+#else
+ xfree ((PTR_T) ptr);
+#endif
+
+}
+
+
+/* Allocate head of type hash list. */
+
+STATIC thead_t *
+allocate_thead __proto((void))
+{
+ register thead_t *ptr;
+ static thead_t initial_thead;
+
+#ifndef MALLOC_CHECK
+ ptr = alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
+ if (ptr != (thead_t *)0)
+ alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
+
+ else
+ {
+ register int unallocated = alloc_counts[ (int)alloc_type_thead ].unallocated;
+ register page_t *cur_page = alloc_counts[ (int)alloc_type_thead ].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thead_t);
+ alloc_counts[ (int)alloc_type_thead ].cur_page = cur_page = allocate_page ();
+ alloc_counts[ (int)alloc_type_thead ].total_pages++;
+ }
+
+ ptr = &cur_page->thead[ --unallocated ];
+ alloc_counts[ (int)alloc_type_thead ].unallocated = unallocated;
+ }
+
+#else
+ ptr = (thead_t *) xmalloc (sizeof (thead_t));
+
+#endif
+
+ alloc_counts[ (int)alloc_type_thead ].total_alloc++;
+ *ptr = initial_thead;
+ return ptr;
}
+/* Free scoping information. */
+
STATIC void
-free_word8 (ptr)
- word8_t *ptr;
+free_thead (ptr)
+ thead_t *ptr;
{
+ alloc_counts[ (int)alloc_type_thead ].total_free++;
+
#ifndef MALLOC_CHECK
- ptr->prev = word8_free_list;
- word8_free_list = ptr;
+ ptr->free = (thead_t *) alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
+ alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr;
-#else /* MALLOC_CHECK */
- xfree ((PTR_T)ptr);
+#else
+ xfree ((PTR_T) ptr);
+#endif
-#endif /* MALLOC_CHECK */
}
-#endif /* MIPS_DEBUGGING defined */
+#endif /* MIPS_DEBUGGING_INFO *?
/* Output an error message and exit */