diff options
author | H. Peter Anvin <hpa@zytor.com> | 2002-04-30 20:59:21 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2002-04-30 20:59:21 +0000 |
commit | af535c16cf3f9f628384ec834e3aa325709cb37b (patch) | |
tree | c582b65fc34ae4e66aa559ebe901c76aefa05bd5 /labels.c | |
parent | 41bf8002b2fa402bd344a290fcc9f65de328859c (diff) | |
download | nasm-af535c16cf3f9f628384ec834e3aa325709cb37b.tar.gz nasm-af535c16cf3f9f628384ec834e3aa325709cb37b.tar.bz2 nasm-af535c16cf3f9f628384ec834e3aa325709cb37b.zip |
NASM 0.98.03
Diffstat (limited to 'labels.c')
-rw-r--r-- | labels.c | 237 |
1 files changed, 123 insertions, 114 deletions
@@ -18,15 +18,15 @@ */ #define islocal(l) ((l)[0] == '.' && (l)[1] != '.') -#define LABEL_BLOCK 320 /* no. of labels/block */ +#define LABEL_BLOCK 32 /* no. of labels/block */ #define LBLK_SIZE (LABEL_BLOCK*sizeof(union label)) -#define LABEL_HASHES 32 /* no. of hash table entries */ +#define LABEL_HASHES 37 /* no. of hash table entries */ -#define END_LIST -3 /* don't clash with NO_SEG! */ +#define END_LIST -3 /* don't clash with NO_SEG! */ #define END_BLOCK -2 #define BOGUS_VALUE -4 -#define PERMTS_SIZE 4096 /* size of text blocks */ +#define PERMTS_SIZE 4096 /* size of text blocks */ /* values for label.defn.is_global */ #define DEFINED_BIT 1 @@ -39,24 +39,26 @@ #define GLOBAL_PLACEHOLDER (GLOBAL_BIT) #define GLOBAL_SYMBOL (DEFINED_BIT|GLOBAL_BIT) -union label { /* actual label structures */ +union label { /* actual label structures */ struct { - long segment, offset; + long segment, offset; char *label, *special; - int is_global, is_norm; + int is_global, is_norm; } defn; struct { - long movingon, dummy; - union label *next; + long movingon, dummy; + union label *next; } admin; }; -struct permts { /* permanent text storage */ - struct permts *next; /* for the linked list */ - int size, usage; /* size and used space in ... */ - char data[PERMTS_SIZE]; /* ... the data block itself */ +struct permts { /* permanent text storage */ + struct permts *next; /* for the linked list */ + int size, usage; /* size and used space in ... */ + char data[PERMTS_SIZE]; /* ... the data block itself */ }; +extern int global_offset_changed; /* defined in nasm.c */ + static union label *ltab[LABEL_HASHES];/* using a hash table */ static union label *lfree[LABEL_HASHES];/* pointer into the above */ static struct permts *perm_head; /* start of perm. text storage */ @@ -82,9 +84,9 @@ static union label *find_label (char *label, int create) union label *lptr; if (islocal(label)) - prev = prevlabel; + prev = prevlabel; else - prev = ""; + prev = ""; prevlen = strlen(prev); p = prev; while (*p) hash += *p++; @@ -93,34 +95,34 @@ static union label *find_label (char *label, int create) hash %= LABEL_HASHES; lptr = ltab[hash]; while (lptr->admin.movingon != END_LIST) { - if (lptr->admin.movingon == END_BLOCK) { - lptr = lptr->admin.next; - if (!lptr) - break; - } - if (!strncmp(lptr->defn.label, prev, prevlen) && - !strcmp(lptr->defn.label+prevlen, label)) - return lptr; - lptr++; + if (lptr->admin.movingon == END_BLOCK) { + lptr = lptr->admin.next; + if (!lptr) + break; + } + if (!strncmp(lptr->defn.label, prev, prevlen) && + !strcmp(lptr->defn.label+prevlen, label)) + return lptr; + lptr++; } if (create) { - if (lfree[hash]->admin.movingon == END_BLOCK) { - /* - * must allocate a new block - */ - lfree[hash]->admin.next = (union label *) nasm_malloc (LBLK_SIZE); - lfree[hash] = lfree[hash]->admin.next; - init_block(lfree[hash]); - } - - lfree[hash]->admin.movingon = BOGUS_VALUE; - lfree[hash]->defn.label = perm_copy (prev, label); - lfree[hash]->defn.special = NULL; - lfree[hash]->defn.is_global = NOT_DEFINED_YET; - return lfree[hash]++; + if (lfree[hash]->admin.movingon == END_BLOCK) { + /* + * must allocate a new block + */ + lfree[hash]->admin.next = (union label *) nasm_malloc (LBLK_SIZE); + lfree[hash] = lfree[hash]->admin.next; + init_block(lfree[hash]); + } + + lfree[hash]->admin.movingon = BOGUS_VALUE; + lfree[hash]->defn.label = perm_copy (prev, label); + lfree[hash]->defn.special = NULL; + lfree[hash]->defn.is_global = NOT_DEFINED_YET; + return lfree[hash]++; } else - return NULL; + return NULL; } int lookup_label (char *label, long *segment, long *offset) @@ -128,16 +130,16 @@ int lookup_label (char *label, long *segment, long *offset) union label *lptr; if (!initialised) - return 0; + return 0; lptr = find_label (label, 0); if (lptr && (lptr->defn.is_global & DEFINED_BIT)) { - *segment = lptr->defn.segment; - *offset = lptr->defn.offset; - return 1; + *segment = lptr->defn.segment; + *offset = lptr->defn.offset; + return 1; } else - return 0; + return 0; } int is_extern (char *label) @@ -145,17 +147,17 @@ int is_extern (char *label) union label *lptr; if (!initialised) - return 0; + return 0; lptr = find_label (label, 0); if (lptr && (lptr->defn.is_global & EXTERN_BIT)) - return 1; + return 1; else - return 0; + return 0; } void redefine_label (char *label, long segment, long offset, char *special, - int is_norm, int isextrn, struct ofmt *ofmt, efunc error) + int is_norm, int isextrn, struct ofmt *ofmt, efunc error) { union label *lptr; @@ -165,51 +167,58 @@ void redefine_label (char *label, long segment, long offset, char *special, */ (void) segment; /* Don't warn that this parameter is unused */ - (void) offset; /* Don't warn that this parameter is unused */ (void) special; /* Don't warn that this parameter is unused */ (void) is_norm; /* Don't warn that this parameter is unused */ (void) isextrn; /* Don't warn that this parameter is unused */ (void) ofmt; /* Don't warn that this parameter is unused */ #ifdef DEBUG +#if DEBUG<3 if (!strncmp(label, "debugdump", 9)) - fprintf(stderr, "debug: redefine_label (%s, %ld, %08lx, %s, %d, %d)\n", - label, segment, offset, special, is_norm, isextrn); +#endif + error(ERR_DEBUG, "redefine_label (%s, %ld, %08lx, %s, %d, %d)", + label, segment, offset, special, is_norm, isextrn); #endif + lptr = find_label (label, 1); + if (!lptr) + error (ERR_PANIC, "can't find label `%s' on pass two", label); + if (!islocal(label)) { - lptr = find_label (label, 1); - if (!lptr) - error (ERR_PANIC, "can't find label `%s' on pass two", label); - if (*label != '.' && lptr->defn.is_norm) - prevlabel = lptr->defn.label; + if (*label != '.' && lptr->defn.is_norm) + prevlabel = lptr->defn.label; } + + global_offset_changed |= (lptr->defn.offset != offset); + lptr->defn.offset = offset; } void define_label (char *label, long segment, long offset, char *special, - int is_norm, int isextrn, struct ofmt *ofmt, efunc error) + int is_norm, int isextrn, struct ofmt *ofmt, efunc error) { union label *lptr; #ifdef DEBUG +#if DEBUG<3 if (!strncmp(label, "debugdump", 9)) - fprintf(stderr, "debug: define_label (%s, %ld, %08lx, %s, %d, %d)\n", - label, segment, offset, special, is_norm, isextrn); +#endif + error(ERR_DEBUG, "define_label (%s, %ld, %08lx, %s, %d, %d)", + label, segment, offset, special, is_norm, isextrn); #endif lptr = find_label (label, 1); if (lptr->defn.is_global & DEFINED_BIT) { - error(ERR_NONFATAL, "symbol `%s' redefined", label); - return; + error(ERR_NONFATAL, "symbol `%s' redefined", label); + return; } lptr->defn.is_global |= DEFINED_BIT; if (isextrn) - lptr->defn.is_global |= EXTERN_BIT; + lptr->defn.is_global |= EXTERN_BIT; if (label[0] != '.' && is_norm) /* not local, but not special either */ - prevlabel = lptr->defn.label; + prevlabel = lptr->defn.label; else if (label[0] == '.' && label[1] != '.' && !*prevlabel) - error(ERR_NONFATAL, "attempt to define a local label before any" - " non-local labels"); + error(ERR_NONFATAL, "attempt to define a local label before any" + " non-local labels"); lptr->defn.segment = segment; lptr->defn.offset = offset; @@ -217,39 +226,39 @@ void define_label (char *label, long segment, long offset, char *special, if ( (lptr->defn.is_global & (GLOBAL_BIT|EXTERN_BIT)) != EXTERN_BIT ) { ofmt->symdef (lptr->defn.label, segment, offset, - !!(lptr->defn.is_global & GLOBAL_BIT), - special ? special : lptr->defn.special); + !!(lptr->defn.is_global & GLOBAL_BIT), + special ? special : lptr->defn.special); ofmt->current_dfmt->debug_deflabel (label, segment, offset, - !!(lptr->defn.is_global & GLOBAL_BIT), - special ? special : lptr->defn.special); + !!(lptr->defn.is_global & GLOBAL_BIT), + special ? special : lptr->defn.special); } } void define_common (char *label, long segment, long size, char *special, - struct ofmt *ofmt, efunc error) + struct ofmt *ofmt, efunc error) { union label *lptr; lptr = find_label (label, 1); if (lptr->defn.is_global & DEFINED_BIT) { - error(ERR_NONFATAL, "symbol `%s' redefined", label); - return; + error(ERR_NONFATAL, "symbol `%s' redefined", label); + return; } lptr->defn.is_global |= DEFINED_BIT; - if (label[0] != '.') /* not local, but not special either */ - prevlabel = lptr->defn.label; + if (label[0] != '.') /* not local, but not special either */ + prevlabel = lptr->defn.label; else - error(ERR_NONFATAL, "attempt to define a local label as a " - "common variable"); + error(ERR_NONFATAL, "attempt to define a local label as a " + "common variable"); lptr->defn.segment = segment; lptr->defn.offset = 0; ofmt->symdef (lptr->defn.label, segment, size, 2, - special ? special : lptr->defn.special); + special ? special : lptr->defn.special); ofmt->current_dfmt->debug_deflabel(lptr->defn.label, segment, size, 2, - special ? special : lptr->defn.special); + special ? special : lptr->defn.special); } void declare_as_global (char *label, char *special, efunc error) @@ -257,24 +266,24 @@ void declare_as_global (char *label, char *special, efunc error) union label *lptr; if (islocal(label)) { - error(ERR_NONFATAL, "attempt to declare local symbol `%s' as" - " global", label); - return; + error(ERR_NONFATAL, "attempt to declare local symbol `%s' as" + " global", label); + return; } lptr = find_label (label, 1); switch (lptr->defn.is_global & TYPE_MASK) { case NOT_DEFINED_YET: - lptr->defn.is_global = GLOBAL_PLACEHOLDER; - lptr->defn.special = special ? perm_copy(special, "") : NULL; - break; - case GLOBAL_PLACEHOLDER: /* already done: silently ignore */ + lptr->defn.is_global = GLOBAL_PLACEHOLDER; + lptr->defn.special = special ? perm_copy(special, "") : NULL; + break; + case GLOBAL_PLACEHOLDER: /* already done: silently ignore */ case GLOBAL_SYMBOL: - break; + break; case LOCAL_SYMBOL: - if (!lptr->defn.is_global & EXTERN_BIT) - error(ERR_NONFATAL, "symbol `%s': GLOBAL directive must" - " appear before symbol definition", label); - break; + if (!lptr->defn.is_global & EXTERN_BIT) + error(ERR_NONFATAL, "symbol `%s': GLOBAL directive must" + " appear before symbol definition", label); + break; } } @@ -283,18 +292,18 @@ int init_labels (void) int i; for (i=0; i<LABEL_HASHES; i++) { - ltab[i] = (union label *) nasm_malloc (LBLK_SIZE); - if (!ltab[i]) - return -1; /* can't initialise, panic */ - init_block (ltab[i]); - lfree[i] = ltab[i]; + ltab[i] = (union label *) nasm_malloc (LBLK_SIZE); + if (!ltab[i]) + return -1; /* can't initialise, panic */ + init_block (ltab[i]); + lfree[i] = ltab[i]; } perm_head = - perm_tail = (struct permts *) nasm_malloc (sizeof(struct permts)); + perm_tail = (struct permts *) nasm_malloc (sizeof(struct permts)); if (!perm_head) - return -1; + return -1; perm_head->next = NULL; perm_head->size = PERMTS_SIZE; @@ -314,22 +323,22 @@ void cleanup_labels (void) initialised = FALSE; for (i=0; i<LABEL_HASHES; i++) { - union label *lptr, *lhold; + union label *lptr, *lhold; - lptr = lhold = ltab[i]; + lptr = lhold = ltab[i]; - while (lptr) { - while (lptr->admin.movingon != END_BLOCK) lptr++; - lptr = lptr->admin.next; - nasm_free (lhold); - lhold = lptr; - } + while (lptr) { + while (lptr->admin.movingon != END_BLOCK) lptr++; + lptr = lptr->admin.next; + nasm_free (lhold); + lhold = lptr; + } } while (perm_head) { - perm_tail = perm_head; - perm_head = perm_head->next; - nasm_free (perm_tail); + perm_tail = perm_head; + perm_head = perm_head->next; + nasm_free (perm_tail); } } @@ -338,7 +347,7 @@ static void init_block (union label *blk) int j; for (j=0; j<LABEL_BLOCK-1; j++) - blk[j].admin.movingon = END_LIST; + blk[j].admin.movingon = END_LIST; blk[LABEL_BLOCK-1].admin.movingon = END_BLOCK; blk[LABEL_BLOCK-1].admin.next = NULL; } @@ -349,11 +358,11 @@ static char *perm_copy (char *string1, char *string2) int len = strlen(string1)+strlen(string2)+1; if (perm_tail->size - perm_tail->usage < len) { - perm_tail->next = (struct permts *)nasm_malloc(sizeof(struct permts)); - perm_tail = perm_tail->next; - perm_tail->next = NULL; - perm_tail->size = PERMTS_SIZE; - perm_tail->usage = 0; + perm_tail->next = (struct permts *)nasm_malloc(sizeof(struct permts)); + perm_tail = perm_tail->next; + perm_tail->next = NULL; + perm_tail->size = PERMTS_SIZE; + perm_tail->usage = 0; } p = q = perm_tail->data + perm_tail->usage; while ( (*q = *string1++) ) q++; |