Example #1
0
File: outform.c Project: AxFab/nasm
const struct ofmt *ofmt_find(const char *name,
			     const struct ofmt_alias **ofmt_alias)
{
    const struct ofmt * const *ofp;
    const struct ofmt *of;
    unsigned int i;

    *ofmt_alias = NULL;

    /* primary targets first */
    for (ofp = drivers; (of = *ofp); ofp++) {
        if (!nasm_stricmp(name, of->shortname))
            return of;
    }

    /* lets walk thru aliases then */
    for (i = 0; i < ARRAY_SIZE(ofmt_aliases); i++) {
        if (ofmt_aliases[i].shortname &&
            !nasm_stricmp(name, ofmt_aliases[i].shortname)) {
            *ofmt_alias = &ofmt_aliases[i];
            return ofmt_aliases[i].ofmt;
        }
    }

    return NULL;
}
Example #2
0
/* parse section attributes */
void section_attrib(char *name, char *attr, int pass,
                    uint32_t *flags_and, uint32_t *flags_or,
                    uint64_t *align, int *type)
{
    char *opt, *val, *next;

    opt = nasm_skip_spaces(attr);
    if (!opt || !*opt)
        return;

    while ((opt = nasm_opt_val(opt, &val, &next))) {
        if (!nasm_stricmp(opt, "align")) {
            *align = atoi(val);
            if (*align == 0) {
                *align = SHA_ANY;
            } else if (!is_power2(*align)) {
                nasm_error(ERR_NONFATAL,
                           "section alignment %"PRId64" is not a power of two",
                           *align);
                *align = SHA_ANY;
            }
        } else if (!nasm_stricmp(opt, "alloc")) {
            *flags_and  |= SHF_ALLOC;
            *flags_or   |= SHF_ALLOC;
        } else if (!nasm_stricmp(opt, "noalloc")) {
            *flags_and  |= SHF_ALLOC;
            *flags_or   &= ~SHF_ALLOC;
        } else if (!nasm_stricmp(opt, "exec")) {
            *flags_and  |= SHF_EXECINSTR;
            *flags_or   |= SHF_EXECINSTR;
        } else if (!nasm_stricmp(opt, "noexec")) {
            *flags_and  |= SHF_EXECINSTR;
            *flags_or   &= ~SHF_EXECINSTR;
        } else if (!nasm_stricmp(opt, "write")) {
            *flags_and  |= SHF_WRITE;
            *flags_or   |= SHF_WRITE;
        } else if (!nasm_stricmp(opt, "tls")) {
            *flags_and  |= SHF_TLS;
            *flags_or   |= SHF_TLS;
        } else if (!nasm_stricmp(opt, "nowrite")) {
            *flags_and  |= SHF_WRITE;
            *flags_or   &= ~SHF_WRITE;
        } else if (!nasm_stricmp(opt, "progbits")) {
            *type = SHT_PROGBITS;
        } else if (!nasm_stricmp(opt, "nobits")) {
            *type = SHT_NOBITS;
        } else if (pass == 1) {
            nasm_error(ERR_WARNING,
                       "Unknown section attribute '%s' ignored on"
                       " declaration of section `%s'", opt, name);
        }
        opt = next;
    }
}
Example #3
0
const unsigned char *nasm_stdmac_find_package(const char *package)
{
    static const struct {
         const char *package;
         const unsigned char *macros;
    } packages[2] = {
        { "altreg", nasm_stdmac_altreg },
        { "smartalign", nasm_stdmac_smartalign },
    };
#define UNUSED 16383
    static const int16_t hash1[2] = {
        0,
        -1,
    };
    static const int16_t hash2[2] = {
        1,
        UNUSED,
    };
    uint32_t k1, k2;
    uint64_t crc;
    uint16_t ix;

    crc = crc64i(UINT64_C(0x076259c3e291c26c), package);
    k1 = (uint32_t)crc;
    k2 = (uint32_t)(crc >> 32);

    ix = hash1[k1 & 0x1] + hash2[k2 & 0x1];
    if (ix >= 2)
        return NULL;

    if (nasm_stricmp(packages[ix].package, package))
        return NULL;

    return packages[ix].macros;
}
Example #4
0
File: outform.c Project: AxFab/nasm
const struct dfmt *dfmt_find(const struct ofmt *ofmt, const char *name)
{
    const struct dfmt * const *dfp;
    const struct dfmt *df;

    for (dfp = ofmt->debug_formats; (df = *dfp); dfp++) {
        if (!nasm_stricmp(name, df->shortname))
            return df;
    }
    return NULL;
}
Example #5
0
int bsii(const char *string, const char **array, int size)
{
    int i = -1, j = size;       /* always, i < index < j */
    while (j - i >= 2) {
        int k = (i + j) / 2;
        int l = nasm_stricmp(string, array[k]);
        if (l < 0)              /* it's in the first half */
            j = k;
        else if (l > 0)         /* it's in the second half */
            i = k;
        else                    /* we've got it :) */
            return k;
    }
    return -1;                  /* we haven't got it :( */
}
Example #6
0
/*
 * because this routine is not bracketed in
 * the main program, this routine will be called even if there
 * is no request for debug info
 * so, we have to make sure the ??LINE segment is avaialbe
 * as the first segment when this debug format is selected
 */
static void dbgls_linnum(const char *lnfname, int32_t lineno, int32_t segto)
{
    struct FileName *fn;
    struct ieeeSection *seg;
    int i = 0;
    if (segto == NO_SEG)
        return;

    /*
     * If `any_segs' is still false, we must define a default
     * segment.
     */
    if (!any_segs) {
        int tempint;            /* ignored */
        if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint))
            nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
    }

    /*
     * Find the segment we are targetting.
     */
    for (seg = seghead; seg; seg = seg->next)
        if (seg->index == segto)
            break;
    if (!seg)
        nasm_error(ERR_PANIC, "lineno directed to nonexistent segment?");

    for (fn = fnhead; fn; fn = fn->next) {
        if (!nasm_stricmp(lnfname, fn->name))
            break;
        i++;
    }
    if (!fn) {
        fn = nasm_malloc(sizeof(*fn));
        fn->name = nasm_malloc(strlen(lnfname) + 1);
        fn->index = i;
        strcpy(fn->name, lnfname);
        fn->next = NULL;
        *fntail = fn;
        fntail = &fn->next;
    }
    ieee_write_byte(seghead, fn->index);
    ieee_write_word(seghead, lineno);
    ieee_write_fixup(segto, NO_SEG, seghead, 4, OUT_ADDRESS,
                     seg->currentpos);

}
static bool declare_label_lptr(union label *lptr,
                               enum label_type type, const char *special)
{
    if (special && !special[0])
        special = NULL;

    if (lptr->defn.type == type ||
        (pass0 == 0 && lptr->defn.type == LBL_LOCAL)) {
        lptr->defn.type = type;
        if (special) {
            if (!lptr->defn.special)
                lptr->defn.special = perm_copy(special);
            else if (nasm_stricmp(lptr->defn.special, special))
                nasm_error(ERR_NONFATAL,
                           "symbol `%s' has inconsistent attributes `%s' and `%s'",
                           lptr->defn.label, lptr->defn.special, special);
        }
        return true;
    }

    /* EXTERN can be replaced with GLOBAL or COMMON */
    if (lptr->defn.type == LBL_EXTERN &&
        (type == LBL_GLOBAL || type == LBL_COMMON)) {
        lptr->defn.type = type;
        /* Override special unconditionally */
        if (special)
            lptr->defn.special = perm_copy(special);
        return true;
    }

    /* GLOBAL or COMMON ignore subsequent EXTERN */
    if ((lptr->defn.type == LBL_GLOBAL || lptr->defn.type == LBL_COMMON) &&
        type == LBL_EXTERN) {
        if (!lptr->defn.special)
            lptr->defn.special = perm_copy(special);
        return false;           /* Don't call define_label() after this! */
    }

    nasm_error(ERR_NONFATAL, "symbol `%s' declared both as %s and %s",
               lptr->defn.label, types[lptr->defn.type], types[type]);

    return false;
}
enum preproc_token pp_token_hash(const char *token)
{
#define UNUSED 16383
    static const int16_t hash1[128] = {
        UNUSED,
        UNUSED,
        0,
        0,
        0,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        0,
        0,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        -45,
        UNUSED,
        0,
        UNUSED,
        -60,
        0,
        UNUSED,
        UNUSED,
        -42,
        UNUSED,
        UNUSED,
        -49,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        48,
        UNUSED,
        UNUSED,
        49,
        5,
        UNUSED,
        -52,
        65,
        UNUSED,
        UNUSED,
        0,
        0,
        UNUSED,
        38,
        UNUSED,
        30,
        0,
        UNUSED,
        6,
        35,
        UNUSED,
        UNUSED,
        60,
        34,
        UNUSED,
        134,
        UNUSED,
        -86,
        -11,
        41,
        17,
        0,
        129,
        -84,
        UNUSED,
        UNUSED,
        82,
        0,
        UNUSED,
        16,
        97,
        -65,
        -100,
        0,
        -10,
        -76,
        UNUSED,
        UNUSED,
        UNUSED,
        1,
        UNUSED,
        0,
        12,
        UNUSED,
        -145,
        41,
        105,
        UNUSED,
        84,
        UNUSED,
        43,
        85,
        UNUSED,
        22,
        0,
        -13,
        UNUSED,
        UNUSED,
        77,
        -2,
        UNUSED,
        UNUSED,
        11,
        91,
        -6,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        106,
        44,
        UNUSED,
    };
    static const int16_t hash2[128] = {
        UNUSED,
        0,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        80,
        0,
        64,
        UNUSED,
        0,
        0,
        0,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        64,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        121,
        0,
        UNUSED,
        21,
        99,
        63,
        UNUSED,
        114,
        UNUSED,
        178,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        -39,
        UNUSED,
        88,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        87,
        UNUSED,
        42,
        UNUSED,
        UNUSED,
        141,
        UNUSED,
        UNUSED,
        UNUSED,
        102,
        UNUSED,
        46,
        105,
        149,
        UNUSED,
        23,
        53,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        0,
        UNUSED,
        UNUSED,
        UNUSED,
        33,
        0,
        0,
        92,
        UNUSED,
        50,
        72,
        UNUSED,
        7,
        42,
        65,
        UNUSED,
        UNUSED,
        112,
        52,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        UNUSED,
        98,
        100,
        71,
        UNUSED,
        19,
        63,
        32,
        UNUSED,
        UNUSED,
        UNUSED,
        96,
        17,
        84,
        132,
        UNUSED,
        37,
        UNUSED,
        9,
        20,
        UNUSED,
        UNUSED,
        75,
        97,
        UNUSED,
    };
    uint32_t k1, k2;
    uint64_t crc;
    uint16_t ix;

    crc = crc64i(UINT64_C(0xaee7ac5ccabdec91), token);
    k1 = (uint32_t)crc;
    k2 = (uint32_t)(crc >> 32);

    ix = hash1[k1 & 0x7f] + hash2[k2 & 0x7f];
    if (ix >= 108)
        return PP_INVALID;

    if (!pp_directives[ix] || nasm_stricmp(pp_directives[ix], token))
        return PP_INVALID;

    return ix;
}
Example #9
0
/*
 * segment registry
 */
static int32_t ieee_segment(char *name, int pass, int *bits)
{
    /*
     * We call the label manager here to define a name for the new
     * segment, and when our _own_ label-definition stub gets
     * called in return, it should register the new segment name
     * using the pointer it gets passed. That way we save memory,
     * by sponging off the label manager.
     */
    if (!name) {
        *bits = 16;
        if (!any_segs)
            return 0;
        return seghead->index;
    } else {
        struct ieeeSection *seg;
        int ieee_idx, attrs;
	bool rn_error;
        char *p;

        /*
         * Look for segment attributes.
         */
        attrs = 0;
        while (*name == '.')
            name++;             /* hack, but a documented one */
        p = name;
        while (*p && !nasm_isspace(*p))
            p++;
        if (*p) {
            *p++ = '\0';
            while (*p && nasm_isspace(*p))
                *p++ = '\0';
        }
        while (*p) {
            while (*p && !nasm_isspace(*p))
                p++;
            if (*p) {
                *p++ = '\0';
                while (*p && nasm_isspace(*p))
                    *p++ = '\0';
            }

            attrs++;
        }

        ieee_idx = 1;
        for (seg = seghead; seg; seg = seg->next) {
            ieee_idx++;
            if (!strcmp(seg->name, name)) {
                if (attrs > 0 && pass == 1)
                    nasm_error(ERR_WARNING, "segment attributes specified on"
                          " redeclaration of segment: ignoring");
                if (seg->use32)
                    *bits = 32;
                else
                    *bits = 16;
                return seg->index;
            }
        }

        *segtail = seg = nasm_malloc(sizeof(*seg));
        seg->next = NULL;
        segtail = &seg->next;
        seg->index = seg_alloc();
        seg->ieee_index = ieee_idx;
        any_segs = true;
        seg->name = NULL;
        seg->currentpos = 0;
        seg->align = 1;         /* default */
        seg->use32 = *bits == 32;       /* default to user spec */
        seg->combine = CMB_PUBLIC;      /* default */
        seg->pubhead = NULL;
        seg->pubtail = &seg->pubhead;
        seg->data = NULL;
        seg->fptr = NULL;
        seg->lochead = NULL;
        seg->loctail = &seg->lochead;

        /*
         * Process the segment attributes.
         */
        p = name;
        while (attrs--) {
            p += strlen(p);
            while (!*p)
                p++;

            /*
             * `p' contains a segment attribute.
             */
            if (!nasm_stricmp(p, "private"))
                seg->combine = CMB_PRIVATE;
            else if (!nasm_stricmp(p, "public"))
                seg->combine = CMB_PUBLIC;
            else if (!nasm_stricmp(p, "common"))
                seg->combine = CMB_COMMON;
            else if (!nasm_stricmp(p, "use16"))
                seg->use32 = false;
            else if (!nasm_stricmp(p, "use32"))
                seg->use32 = true;
            else if (!nasm_strnicmp(p, "align=", 6)) {
                seg->align = readnum(p + 6, &rn_error);
                if (seg->align == 0)
                    seg->align = 1;
                if (rn_error) {
                    seg->align = 1;
                    nasm_error(ERR_NONFATAL, "segment alignment should be"
                          " numeric");
                }
                switch ((int)seg->align) {
                case 1:        /* BYTE */
                case 2:        /* WORD */
                case 4:        /* DWORD */
                case 16:       /* PARA */
                case 256:      /* PAGE */
                case 8:
                case 32:
                case 64:
                case 128:
                    break;
                default:
                    nasm_error(ERR_NONFATAL, "invalid alignment value %d",
                          seg->align);
                    seg->align = 1;
                    break;
                }
            } else if (!nasm_strnicmp(p, "absolute=", 9)) {
                seg->align = SEG_ABS + readnum(p + 9, &rn_error);
                if (rn_error)
                    nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
                          " attribute should be numeric");
            }
        }

        ieee_seg_needs_update = seg;
        if (seg->align >= SEG_ABS)
            define_label(name, NO_SEG, seg->align - SEG_ABS,
			 NULL, false, false);
        else
            define_label(name, seg->index + 1, 0L, NULL, false, false);
        ieee_seg_needs_update = NULL;

        if (seg->use32)
            *bits = 32;
        else
            *bits = 16;
        return seg->index;
    }
}
Example #10
0
static long elf_section_names(char *name, int pass, int *bits)
{
    char *p;
    int flags_and, flags_or, type, align, i;

    /*
     * Default is 32 bits.
     */
    if (!name) {
        *bits = 32;
        return def_seg;
    }

    p = name;
    while (*p && !isspace(*p))
        p++;
    if (*p)
        *p++ = '\0';
    flags_and = flags_or = type = align = 0;

    while (*p && isspace(*p))
        p++;
    while (*p) {
        char *q = p;
        while (*p && !isspace(*p))
            p++;
        if (*p)
            *p++ = '\0';
        while (*p && isspace(*p))
            p++;

        if (!nasm_strnicmp(q, "align=", 6)) {
            align = atoi(q + 6);
            if (align == 0)
                align = 1;
            if ((align - 1) & align) {  /* means it's not a power of two */
                error(ERR_NONFATAL, "section alignment %d is not"
                      " a power of two", align);
                align = 1;
            }
        } else if (!nasm_stricmp(q, "alloc")) {
            flags_and |= SHF_ALLOC;
            flags_or |= SHF_ALLOC;
        } else if (!nasm_stricmp(q, "noalloc")) {
            flags_and |= SHF_ALLOC;
            flags_or &= ~SHF_ALLOC;
        } else if (!nasm_stricmp(q, "exec")) {
            flags_and |= SHF_EXECINSTR;
            flags_or |= SHF_EXECINSTR;
        } else if (!nasm_stricmp(q, "noexec")) {
            flags_and |= SHF_EXECINSTR;
            flags_or &= ~SHF_EXECINSTR;
        } else if (!nasm_stricmp(q, "write")) {
            flags_and |= SHF_WRITE;
            flags_or |= SHF_WRITE;
        } else if (!nasm_stricmp(q, "nowrite")) {
            flags_and |= SHF_WRITE;
            flags_or &= ~SHF_WRITE;
        } else if (!nasm_stricmp(q, "progbits")) {
            type = SHT_PROGBITS;
        } else if (!nasm_stricmp(q, "nobits")) {
            type = SHT_NOBITS;
        }
    }

    if (!strcmp(name, ".comment") ||
        !strcmp(name, ".shstrtab") ||
        !strcmp(name, ".symtab") || !strcmp(name, ".strtab")) {
        error(ERR_NONFATAL, "attempt to redefine reserved section"
              "name `%s'", name);
        return NO_SEG;
    }

    for (i = 0; i < nsects; i++)
        if (!strcmp(name, sects[i]->name))
            break;
    if (i == nsects) {
        if (!strcmp(name, ".text"))
            i = elf_make_section(name, SHT_PROGBITS,
                                 SHF_ALLOC | SHF_EXECINSTR, 16);
        else if (!strcmp(name, ".rodata"))
            i = elf_make_section(name, SHT_PROGBITS, SHF_ALLOC, 4);
        else if (!strcmp(name, ".data"))
            i = elf_make_section(name, SHT_PROGBITS,
                                 SHF_ALLOC | SHF_WRITE, 4);
        else if (!strcmp(name, ".bss"))
            i = elf_make_section(name, SHT_NOBITS,
                                 SHF_ALLOC | SHF_WRITE, 4);
        else
            i = elf_make_section(name, SHT_PROGBITS, SHF_ALLOC, 1);
        if (type)
            sects[i]->type = type;
        if (align)
            sects[i]->align = align;
        sects[i]->flags &= ~flags_and;
        sects[i]->flags |= flags_or;
    } else if (pass == 1) {
        if (type || align || flags_and)
            error(ERR_WARNING, "section attributes ignored on"
                  " redeclaration of section `%s'", name);
    }

    return sects[i]->index;
}
Example #11
0
static long coff_section_names (char *name, int pass, int *bits) 
{
    char *p;
    unsigned long flags, align_and = ~0L, align_or = 0L;
    int i;

    /*
     * Default is 32 bits.
     */
    if (!name)
	*bits = 32;

    if (!name)
	return def_seg;

    p = name;
    while (*p && !isspace(*p)) p++;
    if (*p) *p++ = '\0';
    if (strlen(name) > 8) {
	error (ERR_WARNING, "COFF section names limited to 8 characters:"
	       " truncating");
	name[8] = '\0';
    }
    flags = 0;

    while (*p && isspace(*p)) p++;
    while (*p) {
	char *q = p;
	while (*p && !isspace(*p)) p++;
	if (*p) *p++ = '\0';
	while (*p && isspace(*p)) p++;

	if (!nasm_stricmp(q, "code") || !nasm_stricmp(q, "text")) {
	    flags = TEXT_FLAGS;
	} else if (!nasm_stricmp(q, "data")) {
	    flags = DATA_FLAGS;
	} else if (!nasm_stricmp(q, "bss")) {
	    flags = BSS_FLAGS;
	} else if (!nasm_stricmp(q, "info")) {
	    if (win32)
		flags = INFO_FLAGS;
	    else {
		flags = DATA_FLAGS;    /* gotta do something */
		error (ERR_NONFATAL, "standard COFF does not support"
		       " informational sections");
	    }
	} else if (!nasm_strnicmp(q,"align=",6)) {
	    if (!win32)
		error (ERR_NONFATAL, "standard COFF does not support"
		       " section alignment specification");
	    else {
		if (q[6+strspn(q+6,"0123456789")])
		    error(ERR_NONFATAL, "argument to `align' is not numeric");
		else {
		    unsigned int align = atoi(q+6);
		    if (!align || ((align-1) & align))
			error(ERR_NONFATAL, "argument to `align' is not a"
			      " power of two");
		    else if (align > 64)
			error(ERR_NONFATAL, "Win32 cannot align sections"
			      " to better than 64-byte boundaries");
		    else {
			align_and = ~0x00F00000L;
			align_or = (align == 1 ? 0x00100000L :
				    align == 2 ? 0x00200000L :
				    align == 4 ? 0x00300000L :
				    align == 8 ? 0x00400000L :
				    align == 16 ? 0x00500000L :
				    align == 32 ? 0x00600000L : 0x00700000L);
		    }
		}
	    }
	}
    }

    for (i=0; i<nsects; i++)
	if (!strcmp(name, sects[i]->name))
	    break;
    if (i == nsects) {
	if (!flags) {
	    if (!strcmp(name, ".data"))
		flags = DATA_FLAGS;
	    else if (!strcmp(name, ".bss"))
		flags = BSS_FLAGS;
	    else
		flags = TEXT_FLAGS;
	}
	i = coff_make_section (name, flags);
	if (flags)
	    sects[i]->flags = flags;
	sects[i]->flags &= align_and;
	sects[i]->flags |= align_or;
    } else if (pass == 1) {
	if (flags)
	    error (ERR_WARNING, "section attributes ignored on"
		   " redeclaration of section `%s'", name);
    }

    return sects[i]->index;
}