145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Symbol table handling
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2001-2007  Michael Urman, Peter Johnson
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "util.h"
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <limits.h>
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <ctype.h>
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "libyasm-stdint.h"
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "coretype.h"
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "valparam.h"
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "hamt.h"
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "assocdat.h"
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "errwarn.h"
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "intnum.h"
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "floatnum.h"
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "expr.h"
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "symrec.h"
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "bytecode.h"
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "section.h"
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "objfmt.h"
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef enum {
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SYM_UNKNOWN,                /* for unknown type (COMMON/EXTERN) */
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SYM_EQU,                    /* for EQU defined symbols (expressions) */
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SYM_LABEL,                  /* for labels */
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SYM_CURPOS,                 /* for labels representing the current
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   assembly position */
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SYM_SPECIAL                 /* for special symbols that need to be in
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   the symbol table but otherwise have no
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   purpose */
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} sym_type;
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_symrec {
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *name;
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym_type type;
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_sym_status status;
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_sym_vis visibility;
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long def_line;     /* line where symbol was first defined */
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long decl_line;    /* line where symbol was first declared */
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long use_line;     /* line where symbol was first used */
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    union {
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_expr *expn;        /* equ value */
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* bytecode immediately preceding a label */
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /*@dependent@*/ yasm_bytecode *precbc;
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } value;
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned int size;          /* 0 if not user-defined */
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *segment;        /* for segmented systems like DOS */
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* associated data; NULL if none */
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Linked list of symbols not in the symbol table. */
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct non_table_symrec_s {
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@reldef@*/ SLIST_ENTRY(non_table_symrec_s) link;
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@owned@*/ yasm_symrec *rec;
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} non_table_symrec;
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_symtab {
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* The symbol table: a hash array mapped trie (HAMT). */
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@only@*/ HAMT *sym_table;
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Symbols not in the table */
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int case_sensitive;
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgobjext_valparams_destroy(void *data)
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_vps_destroy((yasm_valparamhead *)data);
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgobjext_valparams_print(void *data, FILE *f, int indent_level)
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_vps_print((yasm_valparamhead *)data, f);
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_assoc_data_callback objext_valparams_cb = {
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    objext_valparams_destroy,
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    objext_valparams_print
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcommon_size_destroy(void *data)
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr **e = (yasm_expr **)data;
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr_destroy(*e);
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(data);
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcommon_size_print(void *data, FILE *f, int indent_level)
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr **e = (yasm_expr **)data;
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr_print(*e, f);
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_assoc_data_callback common_size_cb = {
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    common_size_destroy,
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    common_size_print
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab *
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_create(void)
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symtab->sym_table = HAMT_create(0, yasm_internal_error_);
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SLIST_INIT(&symtab->non_table_syms);
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symtab->case_sensitive = 1;
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return symtab;
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_set_case_sensitive(yasm_symtab *symtab, int sensitive)
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symtab->case_sensitive = sensitive;
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymrec_destroy_one(/*@only@*/ void *d)
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *sym = d;
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(sym->name);
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->type == SYM_EQU && (sym->status & YASM_SYM_VALUED))
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_expr_destroy(sym->value.expn);
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm__assoc_data_destroy(sym->assoc_data);
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(sym);
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@partial@*/ yasm_symrec *
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymrec_new_common(/*@keep@*/ char *name, int case_sensitive)
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = yasm_xmalloc(sizeof(yasm_symrec));
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!case_sensitive) {
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *c;
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (c=name; *c; c++)
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            *c = tolower(*c);
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->name = name;
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->type = SYM_UNKNOWN;
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->def_line = 0;
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->decl_line = 0;
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->use_line = 0;
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->visibility = YASM_SYM_LOCAL;
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->size = 0;
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->segment = NULL;
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->assoc_data = NULL;
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@partial@*/ /*@dependent@*/ yasm_symrec *
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymtab_get_or_new_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symrec_new_common(name, symtab->case_sensitive);
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int replace = 0;
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->status = YASM_SYM_NOSTATUS;
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!symtab->case_sensitive) {
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *c;
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (c=name; *c; c++)
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            *c = tolower(*c);
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return HAMT_insert(symtab->sym_table, name, rec, &replace,
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       symrec_destroy_one);
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@partial@*/ /*@dependent@*/ yasm_symrec *
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymtab_get_or_new_not_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym->rec = symrec_new_common(name, symtab->case_sensitive);
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym->rec->status = YASM_SYM_NOTINTABLE;
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SLIST_INSERT_HEAD(&symtab->non_table_syms, sym, link);
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->rec;
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* create a new symrec */
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@-freshtrans -mustfree@*/
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@partial@*/ /*@dependent@*/ yasm_symrec *
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymtab_get_or_new(yasm_symtab *symtab, const char *name, int in_table)
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *symname = yasm__xstrdup(name);
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (in_table)
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return symtab_get_or_new_in_table(symtab, symname);
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return symtab_get_or_new_not_in_table(symtab, symname);
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@=freshtrans =mustfree@*/
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_traverse(yasm_symtab *symtab, void *d,
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     int (*func) (yasm_symrec *sym, void *d))
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst yasm_symtab_iter *
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_first(const yasm_symtab *symtab)
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (const yasm_symtab_iter *)HAMT_first(symtab->sym_table);
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ const yasm_symtab_iter *
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_next(const yasm_symtab_iter *prev)
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (const yasm_symtab_iter *)HAMT_next((const HAMTEntry *)prev);
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_iter_value(const yasm_symtab_iter *cur)
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (yasm_symrec *)HAMTEntry_get_data((const HAMTEntry *)cur);
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_abs_sym(yasm_symtab *symtab)
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_get_or_new(symtab, "", 1);
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->def_line = 0;
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->decl_line = 0;
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->use_line = 0;
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->type = SYM_EQU;
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->value.expn =
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0);
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->status |= YASM_SYM_DEFINED|YASM_SYM_VALUED|YASM_SYM_USED;
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (rec->use_line == 0)
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->use_line = line;   /* set line number of first use */
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->status |= YASM_SYM_USED;
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_get(yasm_symtab *symtab, const char *name)
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!symtab->case_sensitive) {
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *_name = yasm__xstrdup(name);
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *c;
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_symrec *ret;
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (c=_name; *c; c++)
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            *c = tolower(*c);
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ret = HAMT_search(symtab->sym_table, _name);
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(_name);
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return ret;
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return HAMT_search(symtab->sym_table, name);
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@dependent@*/ yasm_symrec *
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymtab_define(yasm_symtab *symtab, const char *name, sym_type type,
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org              int in_table, unsigned long line)
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_get_or_new(symtab, name, in_table);
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (rec->status & YASM_SYM_DEFINED) {
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set_xref(rec->def_line!=0 ? rec->def_line : rec->decl_line,
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            N_("`%s' previously defined here"), name);
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_GENERAL, N_("redefinition of `%s'"),
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       name);
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else {
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (rec->visibility & YASM_SYM_EXTERN)
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_warn_set(YASM_WARN_GENERAL,
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          N_("`%s' both defined and declared extern"), name);
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->def_line = line;   /* set line number of definition */
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->type = type;
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->status |= YASM_SYM_DEFINED;
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->size = 0;
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->segment = NULL;
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_define_equ(yasm_symtab *symtab, const char *name, yasm_expr *e,
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       unsigned long line)
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_define(symtab, name, SYM_EQU, 1, line);
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm_error_occurred())
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return rec;
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->value.expn = e;
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->status |= YASM_SYM_VALUED;
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_define_label(yasm_symtab *symtab, const char *name,
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         yasm_bytecode *precbc, int in_table,
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         unsigned long line)
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_define(symtab, name, SYM_LABEL, in_table, line);
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm_error_occurred())
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return rec;
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->value.precbc = precbc;
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (in_table && precbc)
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_bc__add_symrec(precbc, rec);
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_define_curpos(yasm_symtab *symtab, const char *name,
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          yasm_bytecode *precbc, unsigned long line)
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_define(symtab, name, SYM_CURPOS, 0, line);
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm_error_occurred())
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return rec;
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->value.precbc = precbc;
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_define_special(yasm_symtab *symtab, const char *name,
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           yasm_sym_vis vis)
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_define(symtab, name, SYM_SPECIAL, 1, 0);
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm_error_occurred())
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return rec;
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->status |= YASM_SYM_VALUED;
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    rec->visibility = vis;
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec *
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_declare(yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    unsigned long line)
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec_declare(rec, vis, line);
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return rec;
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_declare(yasm_symrec *rec, yasm_sym_vis vis, unsigned long line)
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Allowable combinations:
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *  Existing State--------------  vis  New State-------------------
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *  DEFINED GLOBAL COMMON EXTERN  GCE  DEFINED GLOBAL COMMON EXTERN
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *     0      -      0      0     GCE     0      G      C      E
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *     0      -      0      1     GE      0      G      0      E
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *     0      -      1      0     GC      0      G      C      0
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * X   0      -      1      1
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     *     1      -      0      0      G      1      G      0      0
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * X   1      -      -      1
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * X   1      -      1      -
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if ((vis == YASM_SYM_GLOBAL) ||
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (!(rec->status & YASM_SYM_DEFINED) &&
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         (!(rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN)) ||
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          ((rec->visibility & YASM_SYM_COMMON) && (vis == YASM_SYM_COMMON)) ||
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          ((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN))))) {
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->decl_line = line;
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        rec->visibility |= vis;
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_GENERAL,
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            N_("duplicate definition of `%s'; first defined on line %lu"),
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            rec->name, rec->def_line!=0 ? rec->def_line : rec->decl_line);
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct symtab_finalize_info {
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long firstundef_line;
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int undef_extern;
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_errwarns *errwarns;
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} symtab_finalize_info;
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symtab_finalize_info *info = (symtab_finalize_info *)d;
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* error if a symbol is used but never defined or extern/common declared */
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if ((sym->status & YASM_SYM_USED) && !(sym->status & YASM_SYM_DEFINED) &&
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (info->undef_extern)
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sym->visibility |= YASM_SYM_EXTERN;
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else {
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set(YASM_ERROR_GENERAL,
42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           N_("undefined symbol `%s' (first use)"), sym->name);
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(info->errwarns, sym->use_line);
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (sym->use_line < info->firstundef_line)
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                info->firstundef_line = sym->use_line;
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            yasm_errwarns *errwarns)
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symtab_finalize_info info;
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.firstundef_line = ULONG_MAX;
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.undef_extern = undef_extern;
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.errwarns = errwarns;
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym);
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (info.firstundef_line < ULONG_MAX) {
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_GENERAL,
44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       N_(" (Each undefined symbol is reported only once.)"));
44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_errwarn_propagate(errwarns, info.firstundef_line);
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_destroy(yasm_symtab *symtab)
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    HAMT_destroy(symtab->sym_table, symrec_destroy_one);
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (!SLIST_EMPTY(&symtab->non_table_syms)) {
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        non_table_symrec *sym = SLIST_FIRST(&symtab->non_table_syms);
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        SLIST_REMOVE_HEAD(&symtab->non_table_syms, link);
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        symrec_destroy_one(sym->rec);
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(sym);
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(symtab);
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct symrec_print_data {
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    FILE *f;
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int indent_level;
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} symrec_print_data;
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@+voidabstract@*/
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsymrec_print_wrapper(yasm_symrec *sym, /*@null@*/ void *d)
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symrec_print_data *data = (symrec_print_data *)d;
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    assert(data != NULL);
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(data->f, "%*sSymbol `%s'\n", data->indent_level, "", sym->name);
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec_print(sym, data->f, data->indent_level+1);
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symrec_print_data data;
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    data.f = f;
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    data.indent_level = indent_level;
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symtab_traverse(symtab, &data, symrec_print_wrapper);
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@=voidabstract@*/
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char *
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_name(const yasm_symrec *sym)
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->name;
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar *
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_global_name(const yasm_symrec *sym, const yasm_object *object)
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->visibility & (YASM_SYM_GLOBAL|YASM_SYM_COMMON|YASM_SYM_EXTERN)) {
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *name = yasm_xmalloc(strlen(object->global_prefix) +
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  strlen(sym->name) +
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  strlen(object->global_suffix) + 1);
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        strcpy(name, object->global_prefix);
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        strcat(name, sym->name);
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        strcat(name, object->global_suffix);
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return name;
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return yasm__xstrdup(sym->name);
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_sym_vis
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_visibility(const yasm_symrec *sym)
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->visibility;
51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_sym_status
51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_status(const yasm_symrec *sym)
51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->status;
51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunsigned long
52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_def_line(const yasm_symrec *sym)
52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->def_line;
52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunsigned long
52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_decl_line(const yasm_symrec *sym)
52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->decl_line;
53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunsigned long
53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_use_line(const yasm_symrec *sym)
53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->use_line;
53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst yasm_expr *
54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_equ(const yasm_symrec *sym)
54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->type == SYM_EQU && (sym->status & YASM_SYM_VALUED))
54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return sym->value.expn;
54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (const yasm_expr *)NULL;
54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_label(const yasm_symrec *sym,
54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      yasm_symrec_get_label_bytecodep *precbc)
55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!(sym->type == SYM_LABEL || sym->type == SYM_CURPOS)
55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        || !sym->value.precbc) {
55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *precbc = sym->value.precbc;
55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 1;
55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_set_size(yasm_symrec *sym, int size)
56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym->size = size;
56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_size(const yasm_symrec *sym)
56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->size;
57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_set_segment(yasm_symrec *sym, const char *segment)
57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym->segment = segment;
57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char *
57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_segment(const yasm_symrec *sym)
58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return sym->segment;
58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_is_abs(const yasm_symrec *sym)
58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (sym->def_line == 0 && sym->type == SYM_EQU &&
58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sym->name[0] == '\0');
58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_is_special(const yasm_symrec *sym)
59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (sym->type == SYM_SPECIAL);
59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_is_curpos(const yasm_symrec *sym)
59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (sym->type == SYM_CURPOS);
60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_set_objext_valparams(yasm_symrec *sym,
60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 /*@only@*/ yasm_valparamhead *objext_valparams)
60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec_add_data(sym, &objext_valparams_cb, objext_valparams);
60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparamhead *
61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_objext_valparams(yasm_symrec *sym)
61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return yasm_symrec_get_data(sym, &objext_valparams_cb);
61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_set_common_size(yasm_symrec *sym,
61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            /*@only@*/ yasm_expr *common_size)
61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr **ep = yasm_xmalloc(sizeof(yasm_expr *));
62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *ep = common_size;
62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec_add_data(sym, &common_size_cb, ep);
62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_expr **
62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_common_size(yasm_symrec *sym)
62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (yasm_expr **)yasm_symrec_get_data(sym, &common_size_cb);
62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid *
63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_get_data(yasm_symrec *sym,
63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     const yasm_assoc_data_callback *callback)
63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return yasm__assoc_data_get(sym->assoc_data, callback);
63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_add_data(yasm_symrec *sym,
64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     const yasm_assoc_data_callback *callback, void *data)
64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    sym->assoc_data = yasm__assoc_data_add(sym->assoc_data, callback, data);
64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level)
64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch (sym->type) {
64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case SYM_UNKNOWN:
65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case SYM_EQU:
65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*s_EQU_\n", indent_level, "");
65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*sExpn=", indent_level, "");
65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (sym->status & YASM_SYM_VALUED)
65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_expr_print(sym->value.expn, f);
65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else
65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "***UNVALUED***");
65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "\n");
66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case SYM_LABEL:
66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case SYM_CURPOS:
66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*s_%s_\n%*sSection:\n", indent_level, "",
66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    sym->type == SYM_LABEL ? "Label" : "CurPos",
66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    indent_level, "");
66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_section_print(yasm_bc_get_section(sym->value.precbc), f,
66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               indent_level+1, 0);
66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_bc_print(sym->value.precbc, f, indent_level+1);
67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case SYM_SPECIAL:
67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "%*s-Special-\n", indent_level, "");
67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sStatus=", indent_level, "");
67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->status == YASM_SYM_NOSTATUS)
67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "None\n");
67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else {
68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->status & YASM_SYM_USED)
68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Used,");
68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->status & YASM_SYM_DEFINED)
68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Defined,");
68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->status & YASM_SYM_VALUED)
68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Valued,");
68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->status & YASM_SYM_NOTINTABLE)
68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Not in Table,");
68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "\n");
68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sVisibility=", indent_level, "");
69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->visibility == YASM_SYM_LOCAL)
69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "Local\n");
69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else {
69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->visibility & YASM_SYM_GLOBAL)
69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Global,");
69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->visibility & YASM_SYM_COMMON)
69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Common,");
69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sym->visibility & YASM_SYM_EXTERN)
70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "Extern,");
70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "\n");
70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (sym->assoc_data) {
70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "%*sAssociated data:\n", indent_level, "");
70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm__assoc_data_print(sym->assoc_data, f, indent_level+1);
70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sLine Index (Defined)=%lu\n", indent_level, "",
71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sym->def_line);
71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sLine Index (Declared)=%lu\n", indent_level, "",
71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sym->decl_line);
71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sLine Index (Used)=%lu\n", indent_level, "", sym->use_line);
71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
715