Пример #1
0
static void coff_cleanup(int debuginfo) 
{
    struct Reloc *r;
    int i;

    (void) debuginfo;

    coff_write();
    fclose (coffp);
    for (i=0; i<nsects; i++) {
	if (sects[i]->data)
	    saa_free (sects[i]->data);
	while (sects[i]->head) {
	    r = sects[i]->head;
	    sects[i]->head = sects[i]->head->next;
	    nasm_free (r);
	}
	nasm_free (sects[i]);
    }
    nasm_free (sects);
    saa_free (syms);
    raa_free (bsym);
    raa_free (symval);
    saa_free (strs);
}
Пример #2
0
static void aout_cleanup(int debuginfo) 
{
    struct Reloc *r;

    (void) debuginfo;

    aout_pad_sections();
    aout_fixup_relocs(&stext);
    aout_fixup_relocs(&sdata);
    aout_write();
    fclose (aoutfp);
    saa_free (stext.data);
    while (stext.head) {
	r = stext.head;
	stext.head = stext.head->next;
	nasm_free (r);
    }
    saa_free (sdata.data);
    while (sdata.head) {
	r = sdata.head;
	sdata.head = sdata.head->next;
	nasm_free (r);
    }
    saa_free (syms);
    raa_free (bsym);
    saa_free (strs);
}
Пример #3
0
static void elf_cleanup(int debuginfo)
{
    struct Reloc *r;
    int i;

    (void)debuginfo;

    elf_write();
    fclose(elffp);
    for (i = 0; i < nsects; i++) {
        if (sects[i]->type != SHT_NOBITS)
            saa_free(sects[i]->data);
        if (sects[i]->head)
            saa_free(sects[i]->rel);
        while (sects[i]->head) {
            r = sects[i]->head;
            sects[i]->head = sects[i]->head->next;
            nasm_free(r);
        }
    }
    nasm_free(sects);
    saa_free(syms);
    raa_free(bsym);
    saa_free(strs);
    if (of_elf.current_dfmt) {
        of_elf.current_dfmt->cleanup();
    }
}
Пример #4
0
void cleanup_labels (void) 
{
    int i;

    initialised = FALSE;

    for (i=0; i<LABEL_HASHES; i++) {
	union label *lptr, *lhold;

	lptr = lhold = ltab[i];

	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);
    }
}
Пример #5
0
static char *nop_getline(void)
{
    char *buffer, *p, *q;
    int bufsize;

    bufsize = BUF_DELTA;
    buffer = nasm_malloc(BUF_DELTA);
    src_set_linnum(src_get_linnum() + nop_lineinc);

    while (1) {                 /* Loop to handle %line */

        p = buffer;
        while (1) {             /* Loop to handle long lines */
            q = fgets(p, bufsize - (p - buffer), nop_fp);
            if (!q)
                break;
            p += strlen(p);
            if (p > buffer && p[-1] == '\n')
                break;
            if (p - buffer > bufsize - 10) {
                int offset;
                offset = p - buffer;
                bufsize += BUF_DELTA;
                buffer = nasm_realloc(buffer, bufsize);
                p = buffer + offset;
            }
        }

        if (!q && p == buffer) {
            nasm_free(buffer);
            return NULL;
        }

        /*
         * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
         * them are present at the end of the line.
         */
        buffer[strcspn(buffer, "\r\n\032")] = '\0';

        if (!nasm_strnicmp(buffer, "%line", 5)) {
            int32_t ln;
            int li;
            char *nm = nasm_malloc(strlen(buffer));
            if (sscanf(buffer + 5, "%"PRId32"+%d %s", &ln, &li, nm) == 3) {
                nasm_free(src_set_fname(nm));
                src_set_linnum(ln);
                nop_lineinc = li;
                continue;
            }
            nasm_free(nm);
        }
        break;
    }

    nop_list->line(LIST_READ, buffer);

    return buffer;
}
Пример #6
0
static void dbg_cleanup(void)
{
    dfmt->cleanup();
    while (dbgsect) {
        struct Section *tmp = dbgsect;
        dbgsect = dbgsect->next;
        nasm_free(tmp->name);
        nasm_free(tmp);
    }
}
Пример #7
0
static void dbg_cleanup(void)
{
    while (dbgsect) {
	struct Section *tmp = dbgsect;
	dbgsect = dbgsect->next;
	nasm_free (tmp->name);
	nasm_free (tmp);
    }
    fclose(dbgf);
}
Пример #8
0
void saa_free(struct SAA *s)
{
    char **p;
    size_t n;

    for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
        nasm_free(*p);

    nasm_free(s->blk_ptrs);
    nasm_free(s);
}
Пример #9
0
static void dbg_cleanup(int debuginfo)
{
    (void)debuginfo;
    of_dbg.current_dfmt->cleanup();
    while (dbgsect) {
        struct Section *tmp = dbgsect;
        dbgsect = dbgsect->next;
        nasm_free(tmp->name);
        nasm_free(tmp);
    }
}
Пример #10
0
void cleanup_insn(insn * i)
{
    extop *e;

    while ((e = i->eops)) {
        i->eops = e->next;
        if (e->type == EOT_DB_STRING_FREE)
            nasm_free(e->stringval);
        nasm_free(e);
    }
}
Пример #11
0
static void freenode(struct segtabnode *n)
{
    if (!n)
        return;
    freenode(n->left);
    freenode(n->right);
    nasm_free(n);
}
Пример #12
0
void stabs_cleanup()
{
    struct linelist *ptr, *del;
    if (!stabslines)
        return;
    ptr = stabslines;
    while (ptr) {
        del = ptr;
        ptr = ptr->next;
        nasm_free(del);
    }
    if (stabbuf)
        nasm_free(stabbuf);
    if (stabrelbuf)
        nasm_free(stabrelbuf);
    if (stabstrbuf)
        nasm_free(stabstrbuf);
}
Пример #13
0
void cleanup_insn (insn *i) {
    extop *e;

    while (i->eops) {
	e = i->eops;
	i->eops = i->eops->next;
	nasm_free (e);
    }
}
Пример #14
0
static void as86_cleanup(void)
{
    struct Piece *p;

    as86_write();
    saa_free(stext.data);
    while (stext.head) {
        p = stext.head;
        stext.head = stext.head->next;
        nasm_free(p);
    }
    saa_free(sdata.data);
    while (sdata.head) {
        p = sdata.head;
        sdata.head = sdata.head->next;
        nasm_free(p);
    }
    saa_free(syms);
    raa_free(bsym);
    saa_free(strs);
}
Пример #15
0
void cleanup_labels(void)
{
    union label *lptr, *lhold;

    initialized = false;

    hash_free(&ltab);

    lptr = lhold = ldata;
    while (lptr) {
        lptr = &lptr[LABEL_BLOCK-1];
        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);
    }
}
Пример #16
0
static void list_cleanup(void)
{
    if (!listp)
        return;

    while (mistack) {
        MacroInhibit *temp = mistack;
        mistack = temp->next;
        nasm_free(temp);
    }

    list_emit();
    fclose(listfp);
}
Пример #17
0
static void dbgls_cleanup(void)
{
    struct ieeeSection *segtmp;
    while (fnhead) {
        struct FileName *fntemp = fnhead;
        fnhead = fnhead->next;
        nasm_free(fntemp->name);
        nasm_free(fntemp);
    }
    for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
        while (segtmp->lochead) {
            struct ieeePublic *loctmp = segtmp->lochead;
            segtmp->lochead = loctmp->next;
            nasm_free(loctmp->name);
            nasm_free(loctmp);
        }
    }
    while (arrhead) {
        struct Array *arrtmp = arrhead;
        arrhead = arrhead->next;
        nasm_free(arrtmp);
    }
}
Пример #18
0
static void as86_cleanup(int debuginfo) 
{
    struct Piece *p;

    (void) debuginfo;

    as86_write();
    fclose (as86fp);
    saa_free (stext.data);
    while (stext.head) {
	p = stext.head;
	stext.head = stext.head->next;
	nasm_free (p);
    }
    saa_free (sdata.data);
    while (sdata.head) {
	p = sdata.head;
	sdata.head = sdata.head->next;
	nasm_free (p);
    }
    saa_free (syms);
    raa_free (bsym);
    saa_free (strs);
}
Пример #19
0
static void list_downlevel(int type)
{
    if (!listp)
        return;

    if (type == LIST_INCBIN || type == LIST_TIMES) {
        suppress &= ~(type == LIST_INCBIN ? 1 : 2);
        return;
    }

    listlevel--;
    while (mistack && mistack->level > listlevel) {
        MacroInhibit *temp = mistack;
        mistack = temp->next;
        nasm_free(temp);
    }
}
Пример #20
0
/*
 * Internal routine: finds the `union label' corresponding to the
 * given label name. Creates a new one, if it isn't found, and if
 * `create' is true.
 */
static union label *find_label(const char *label, bool create, bool *created)
{
    union label *lptr, **lpp;
    char *label_str = NULL;
    struct hash_insert ip;

    nasm_assert(label != NULL);

    if (islocal(label))
        label = label_str = nasm_strcat(prevlabel, label);

    lpp = (union label **) hash_find(&ltab, label, &ip);
    lptr = lpp ? *lpp : NULL;

    if (lptr || !create) {
        if (created)
            *created = false;
        return lptr;
    }

    /* Create a new label... */
    if (lfree->admin.movingon == END_BLOCK) {
        /*
         * must allocate a new block
         */
        lfree->admin.next = nasm_malloc(LBLK_SIZE);
        lfree = lfree->admin.next;
        init_block(lfree);
    }

    if (created)
        *created = true;

    nasm_zero(*lfree);
    lfree->defn.label     = perm_copy(label);
    lfree->defn.subsection = NO_SEG;
    if (label_str)
        nasm_free(label_str);

    hash_add(&ip, lfree->defn.label, lfree);
    return lfree++;
}
Пример #21
0
/*
 * Rundown
 */
static void ieee_cleanup(int debuginfo)
{
    ieee_write_file(debuginfo);
    of_ieee.current_dfmt->cleanup();
    while (seghead) {
        struct ieeeSection *segtmp = seghead;
        seghead = seghead->next;
        while (segtmp->pubhead) {
            struct ieeePublic *pubtmp = segtmp->pubhead;
            segtmp->pubhead = pubtmp->next;
            nasm_free(pubtmp);
        }
        while (segtmp->fptr) {
            struct ieeeFixupp *fixtmp = segtmp->fptr;
            segtmp->fptr = fixtmp->next;
            nasm_free(fixtmp);
        }
        while (segtmp->data) {
            struct ieeeObjData *dattmp = segtmp->data;
            segtmp->data = dattmp->next;
            nasm_free(dattmp);
        }
        nasm_free(segtmp);
    }
    while (fpubhead) {
        struct ieeePublic *pubtmp = fpubhead;
        fpubhead = fpubhead->next;
        nasm_free(pubtmp);
    }
    while (exthead) {
        struct ieeeExternal *exttmp = exthead;
        exthead = exthead->next;
        nasm_free(exttmp);
    }
    while (ebhead) {
        struct ExtBack *ebtmp = ebhead;
        ebhead = ebhead->next;
        nasm_free(ebtmp);
    }
}
Пример #22
0
static void list_line(int type, char *line)
{
    if (!listp)
        return;

    if (user_nolist)
      return;

    if (mistack && mistack->inhibiting) {
        if (type == LIST_MACRO)
            return;
        else {                  /* pop the m i stack */
            MacroInhibit *temp = mistack;
            mistack = temp->next;
            nasm_free(temp);
        }
    }
    list_emit();
    listlineno = src_get_linnum();
    listlinep = true;
    strncpy(listline, line, LIST_MAX_LEN - 1);
    listline[LIST_MAX_LEN - 1] = '\0';
    listlevel_e = listlevel;
}
Пример #23
0
static void elf_deflabel(char *name, long segment, long offset,
                         int is_global, char *special)
{
    int pos = strslen;
    struct Symbol *sym;
    int special_used = FALSE;

#if defined(DEBUG) && DEBUG>2
    fprintf(stderr,
            " elf_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
            name, segment, offset, is_global, special);
#endif
    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
        /*
         * This is a NASM special symbol. We never allow it into
         * the ELF symbol table, even if it's a valid one. If it
         * _isn't_ a valid one, we should barf immediately.
         */
        if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
            strcmp(name, "..got") && strcmp(name, "..plt") &&
            strcmp(name, "..sym"))
            error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
        return;
    }

    if (is_global == 3) {
        struct Symbol **s;
        /*
         * Fix up a forward-reference symbol size from the first
         * pass.
         */
        for (s = &fwds; *s; s = &(*s)->nextfwd)
            if (!strcmp((*s)->name, name)) {
                struct tokenval tokval;
                expr *e;
                char *p = special;

                while (*p && !isspace(*p))
                    p++;
                while (*p && isspace(*p))
                    p++;
                stdscan_reset();
                stdscan_bufptr = p;
                tokval.t_type = TOKEN_INVALID;
                e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
                if (e) {
                    if (!is_simple(e))
                        error(ERR_NONFATAL, "cannot use relocatable"
                              " expression as symbol size");
                    else
                        (*s)->size = reloc_value(e);
                }

                /*
                 * Remove it from the list of unresolved sizes.
                 */
                nasm_free((*s)->name);
                *s = (*s)->nextfwd;
                return;
            }
        return;                 /* it wasn't an important one */
    }

    saa_wbytes(strs, name, (long)(1 + strlen(name)));
    strslen += 1 + strlen(name);

    sym = saa_wstruct(syms);

    sym->strpos = pos;
    sym->type = is_global ? SYM_GLOBAL : 0;
    sym->size = 0;
    if (segment == NO_SEG)
        sym->section = SHN_ABS;
    else {
        int i;
        sym->section = SHN_UNDEF;
        if (nsects == 0 && segment == def_seg) {
            int tempint;
            if (segment != elf_section_names(".text", 2, &tempint))
                error(ERR_PANIC,
                      "strange segment conditions in ELF driver");
            sym->section = nsects;
        } else {
            for (i = 0; i < nsects; i++)
                if (segment == sects[i]->index) {
                    sym->section = i + 1;
                    break;
                }
        }
    }

    if (is_global == 2) {
        sym->size = offset;
        sym->value = 0;
        sym->section = SHN_COMMON;
        /*
         * We have a common variable. Check the special text to see
         * if it's a valid number and power of two; if so, store it
         * as the alignment for the common variable.
         */
        if (special) {
            int err;
            sym->value = readnum(special, &err);
            if (err)
                error(ERR_NONFATAL, "alignment constraint `%s' is not a"
                      " valid number", special);
            else if ((sym->value | (sym->value - 1)) != 2 * sym->value - 1)
                error(ERR_NONFATAL, "alignment constraint `%s' is not a"
                      " power of two", special);
        }
        special_used = TRUE;
    } else
        sym->value = (sym->section == SHN_UNDEF ? 0 : offset);

    if (sym->type == SYM_GLOBAL) {
        /*
         * There's a problem here that needs fixing.
         * If sym->section == SHN_ABS, then the first line of the
         * else section causes a core dump, because its a reference
         * beyond the end of the section array.
         * This behaviour is exhibited by this code:
         *     GLOBAL crash_nasm
         *     crash_nasm equ 0
         *
         * I'm not sure how to procede, because I haven't got the
         * first clue about how ELF works, so I don't know what to
         * do with it. Furthermore, I'm not sure what the rest of this
         * section of code does. Help?
         *
         * For now, I'll see if doing absolutely nothing with it will
         * work...
         */
        if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
            bsym = raa_write(bsym, segment, nglobs);
        } else if (sym->section != SHN_ABS) {
            /*
             * This is a global symbol; so we must add it to the linked
             * list of global symbols in its section. We'll push it on
             * the beginning of the list, because it doesn't matter
             * much which end we put it on and it's easier like this.
             *
             * In addition, we check the special text for symbol
             * type and size information.
             */
            sym->next = sects[sym->section - 1]->gsyms;
            sects[sym->section - 1]->gsyms = sym;

            if (special) {
                int n = strcspn(special, " ");

                if (!nasm_strnicmp(special, "function", n))
                    sym->type |= SYM_FUNCTION;
                else if (!nasm_strnicmp(special, "data", n) ||
                         !nasm_strnicmp(special, "object", n))
                    sym->type |= SYM_DATA;
                else
                    error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
                          n, special);
                if (special[n]) {
                    struct tokenval tokval;
                    expr *e;
                    int fwd = FALSE;
                    char *saveme = stdscan_bufptr;      /* bugfix? fbk 8/10/00 */

                    while (special[n] && isspace(special[n]))
                        n++;
                    /*
                     * We have a size expression; attempt to
                     * evaluate it.
                     */
                    stdscan_reset();
                    stdscan_bufptr = special + n;
                    tokval.t_type = TOKEN_INVALID;
                    e = evaluate(stdscan, NULL, &tokval, &fwd, 0, error,
                                 NULL);
                    if (fwd) {
                        sym->nextfwd = fwds;
                        fwds = sym;
                        sym->name = nasm_strdup(name);
                    } else if (e) {
                        if (!is_simple(e))
                            error(ERR_NONFATAL, "cannot use relocatable"
                                  " expression as symbol size");
                        else
                            sym->size = reloc_value(e);
                    }
                    stdscan_bufptr = saveme;    /* bugfix? fbk 8/10/00 */
                }
                special_used = TRUE;
            }
        }
        sym->globnum = nglobs;
        nglobs++;
    } else
        nlocals++;

    if (special && !special_used)
        error(ERR_NONFATAL, "no special symbol features supported here");
}
Пример #24
0
/*
 * Unimportant cleanup is done to avoid confusing people who are trying
 * to debug real memory leaks
 */
void stdscan_cleanup(void)
{
    stdscan_reset();
    nasm_free(stdscan_tempstorage);
}
Пример #25
0
static void stdscan_pop(void)
{
    nasm_free(stdscan_tempstorage[--stdscan_templen]);
}
Пример #26
0
int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f)
{
    char buf[512];
    int i, t;
    void *hdr;
    rdfheaderrec *r;
    int32_t l;

    rdl_error = 0;
    lib->referenced++;

    if (!lib->fp) {
        lib->fp = fopen(lib->name, "rb");

        if (!lib->fp) {
            rdl_error = 1;
            return 0;
        }
    } else
        rewind(lib->fp);

    while (!feof(lib->fp)) {
        /*
         * read the module name from the file, and prepend
         * the library name and '.' to it.
         */
        strcpy(buf, lib->name);

        i = strlen(lib->name);
        buf[i++] = '.';
        t = i;
        while (fread(buf + i, 1, 1, lib->fp) == 1 && i < 512 && buf[i])
            i++;

        buf[i] = 0;

        if (feof(lib->fp))
            break;
        if (!strcmp(buf + t, ".dir")) { /* skip over directory */
            nasm_read(&l, 4, lib->fp);
            fseek(lib->fp, l, SEEK_CUR);
            continue;
        }
        /*
         * open the RDOFF module
         */
        if (rdfopenhere(f, lib->fp, &lib->referenced, buf)) {
            rdl_error = 16 * rdf_errno;
            return 0;
        }
        /*
         * read in the header, and scan for exported symbols
         */
        hdr = nasm_malloc(f->header_len);
        rdfloadseg(f, RDOFF_HEADER, hdr);

        while ((r = rdfgetheaderrec(f))) {
            if (r->type != 3)   /* not an export */
                continue;

            if (!strcmp(r->e.label, label)) {   /* match! */
                nasm_free(hdr);      /* reset to 'just open' */
                f->header_loc = NULL;   /* state... */
                f->header_fp = 0;
                return 1;
            }
        }

        /* find start of next module... */
        i = f->eof_offset;
        rdfclose(f);
        fseek(lib->fp, i, SEEK_SET);
    }

    /*
     * close the file if nobody else is using it
     */
    lib->referenced--;
    if (!lib->referenced) {
        fclose(lib->fp);
        lib->fp = NULL;
    }
    return 0;
}
Пример #27
0
static void aout_deflabel (char *name, long segment, long offset,
			   int is_global, char *special) 
{
    int pos = strslen+4;
    struct Symbol *sym;
    int special_used = FALSE;

    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
	/*
	 * This is a NASM special symbol. We never allow it into
	 * the a.out symbol table, even if it's a valid one. If it
	 * _isn't_ a valid one, we should barf immediately.
	 */
	if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
	    strcmp(name, "..got") && strcmp(name, "..plt") &&
	    strcmp(name, "..sym"))
	    error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
	return;
    }

    if (is_global == 3) {
	struct Symbol **s;
	/*
	 * Fix up a forward-reference symbol size from the first
	 * pass.
	 */
	for (s = &fwds; *s; s = &(*s)->nextfwd)
	    if (!strcmp((*s)->name, name)) {
		struct tokenval tokval;
		expr *e;
		char *p = special;

		while (*p && !isspace(*p)) p++;
		while (*p && isspace(*p)) p++;
		stdscan_reset();
		stdscan_bufptr = p;
		tokval.t_type = TOKEN_INVALID;
		e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
		if (e) {
		    if (!is_simple(e))
			error (ERR_NONFATAL, "cannot use relocatable"
			       " expression as symbol size");
		    else
			(*s)->size = reloc_value(e);
		}

		/*
		 * Remove it from the list of unresolved sizes.
		 */
		nasm_free ((*s)->name);
		*s = (*s)->nextfwd;
		return;
	    }
	return;			       /* it wasn't an important one */
    }

    saa_wbytes (strs, name, (long)(1+strlen(name)));
    strslen += 1+strlen(name);

    sym = saa_wstruct (syms);

    sym->strpos = pos;
    sym->type = is_global ? SYM_GLOBAL : 0;
    sym->segment = segment;
    if (segment == NO_SEG)
	sym->type |= SECT_ABS;
    else if (segment == stext.index) {
	sym->type |= SECT_TEXT;
	if (is_global) {
	    sym->next = stext.gsyms;
	    stext.gsyms = sym;
	} else if (!stext.asym)
	    stext.asym = sym;
    } else if (segment == sdata.index) {
	sym->type |= SECT_DATA;
	if (is_global) {
	    sym->next = sdata.gsyms;
	    sdata.gsyms = sym;
	} else if (!sdata.asym)
	    sdata.asym = sym;
    } else if (segment == sbss.index) {
	sym->type |= SECT_BSS;
	if (is_global) {
	    sym->next = sbss.gsyms;
	    sbss.gsyms = sym;
	} else if (!sbss.asym)
	    sbss.asym = sym;
    } else
	sym->type = SYM_GLOBAL;
    if (is_global == 2)
	sym->value = offset;
    else
	sym->value = (sym->type == SYM_GLOBAL ? 0 : offset);

    if (is_global && sym->type != SYM_GLOBAL) {
	/*
	 * Global symbol exported _from_ this module. We must check
	 * the special text for type information.
	 */

	if (special) {
	    int n = strcspn(special, " ");

	    if (!nasm_strnicmp(special, "function", n))
		sym->type |= SYM_FUNCTION;
	    else if (!nasm_strnicmp(special, "data", n) ||
		     !nasm_strnicmp(special, "object", n))
		sym->type |= SYM_DATA;
	    else
		error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
		      n, special);
	    if (special[n]) {
		struct tokenval tokval;
		expr *e;
		int fwd = FALSE;
		char *saveme=stdscan_bufptr;  /* bugfix? fbk 8/10/00 */

		if (!bsd) {
		    error(ERR_NONFATAL, "Linux a.out does not support"
			  " symbol size information");
		} else {
		    while (special[n] && isspace(special[n]))
			n++;
		    /*
		     * We have a size expression; attempt to
		     * evaluate it.
		     */
		    sym->type |= SYM_WITH_SIZE;
		    stdscan_reset();
		    stdscan_bufptr = special+n;
		    tokval.t_type = TOKEN_INVALID;
		    e = evaluate(stdscan, NULL, &tokval, &fwd, 0, error, NULL);
		    if (fwd) {
			sym->nextfwd = fwds;
			fwds = sym;
			sym->name = nasm_strdup(name);
		    } else if (e) {
			if (!is_simple(e))
			    error (ERR_NONFATAL, "cannot use relocatable"
				   " expression as symbol size");
			else
			    sym->size = reloc_value(e);
		    }
		}
		stdscan_bufptr=saveme;     /* bugfix? fbk 8/10/00 */
	    }
	    special_used = TRUE;
	}
    }

    /*
     * define the references from external-symbol segment numbers
     * to these symbol records.
     */
    if (segment != NO_SEG && segment != stext.index &&
	segment != sdata.index && segment != sbss.index)
	bsym = raa_write (bsym, segment, nsyms);
    sym->symnum = nsyms;

    nsyms++;
    if (sym->type & SYM_WITH_SIZE)
	nsyms++;		       /* and another for the size */

    if (special && !special_used)
	error(ERR_NONFATAL, "no special symbol features supported here");
}
Пример #28
0
static void elf_write(void)
{
    int nsections, align;
    int scount;
    char *p;
    int commlen;
    char comment[64];
    int i;

    struct SAA *symtab;
    long symtablen, symtablocal;

    /*
     * Work out how many sections we will have. We have SHN_UNDEF,
     * then the flexible user sections, then the four fixed
     * sections `.comment', `.shstrtab', `.symtab' and `.strtab',
     * then optionally relocation sections for the user sections.
     */
    if (of_elf.current_dfmt == &df_stabs)
        nsections = 8;
    else
        nsections = 5;          /* SHN_UNDEF and the fixed ones */

    add_sectname("", ".comment");
    add_sectname("", ".shstrtab");
    add_sectname("", ".symtab");
    add_sectname("", ".strtab");
    for (i = 0; i < nsects; i++) {
        nsections++;            /* for the section itself */
        if (sects[i]->head) {
            nsections++;        /* for its relocations */
            add_sectname(".rel", sects[i]->name);
        }
    }

    if (of_elf.current_dfmt == &df_stabs) {
        /* in case the debug information is wanted, just add these three sections... */
        add_sectname("", ".stab");
        add_sectname("", ".stabstr");
        add_sectname(".rel", ".stab");
    }

    /*
     * Do the comment.
     */
    *comment = '\0';
    commlen =
        2 + sprintf(comment + 1, "The Netwide Assembler %s", NASM_VER);

    /*
     * Output the ELF header.
     */
    fwrite("\177ELF\1\1\1\0\0\0\0\0\0\0\0\0", 16, 1, elffp);
    fwriteshort(1, elffp);      /* ET_REL relocatable file */
    fwriteshort(3, elffp);      /* EM_386 processor ID */
    fwritelong(1L, elffp);      /* EV_CURRENT file format version */
    fwritelong(0L, elffp);      /* no entry point */
    fwritelong(0L, elffp);      /* no program header table */
    fwritelong(0x40L, elffp);   /* section headers straight after
                                 * ELF header plus alignment */
    fwritelong(0L, elffp);      /* 386 defines no special flags */
    fwriteshort(0x34, elffp);   /* size of ELF header */
    fwriteshort(0, elffp);      /* no program header table, again */
    fwriteshort(0, elffp);      /* still no program header table */
    fwriteshort(0x28, elffp);   /* size of section header */
    fwriteshort(nsections, elffp);      /* number of sections */
    fwriteshort(nsects + 2, elffp);     /* string table section index for
                                         * section header table */
    fwritelong(0L, elffp);      /* align to 0x40 bytes */
    fwritelong(0L, elffp);
    fwritelong(0L, elffp);

    /*
     * Build the symbol table and relocation tables.
     */
    symtab = elf_build_symtab(&symtablen, &symtablocal);
    for (i = 0; i < nsects; i++)
        if (sects[i]->head)
            sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
                                             sects[i]->head);

    /*
     * Now output the section header table.
     */

    elf_foffs = 0x40 + 0x28 * nsections;
    align = ((elf_foffs + SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
    elf_foffs += align;
    elf_nsect = 0;
    elf_sects = nasm_malloc(sizeof(*elf_sects) * (2 * nsects + 10));

    elf_section_header(0, 0, 0, NULL, FALSE, 0L, 0, 0, 0, 0);   /* SHN_UNDEF */
    scount = 1;                 /* needed for the stabs debugging to track the symtable section */
    p = shstrtab + 1;
    for (i = 0; i < nsects; i++) {
        elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
                           (sects[i]->type == SHT_PROGBITS ?
                            sects[i]->data : NULL), TRUE,
                           sects[i]->len, 0, 0, sects[i]->align, 0);
        p += strlen(p) + 1;
        scount++;               /* dito */
    }
    elf_section_header(p - shstrtab, 1, 0, comment, FALSE, (long)commlen, 0, 0, 1, 0);  /* .comment */
    scount++;                   /* dito */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 3, 0, shstrtab, FALSE, (long)shstrtablen, 0, 0, 1, 0);     /* .shstrtab */
    scount++;                   /* dito */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 2, 0, symtab, TRUE, symtablen, nsects + 4, symtablocal, 4, 16);    /* .symtab */
    symtabsection = scount;     /* now we got the symtab section index in the ELF file */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 3, 0, strs, TRUE, strslen, 0, 0, 1, 0);    /* .strtab */
    for (i = 0; i < nsects; i++)
        if (sects[i]->head) {
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, 9, 0, sects[i]->rel, TRUE,
                               sects[i]->rellen, nsects + 3, i + 1, 4, 8);
        }
    if (of_elf.current_dfmt == &df_stabs) {
        /* for debugging information, create the last three sections
           which are the .stab , .stabstr and .rel.stab sections respectively */

        /* this function call creates the stab sections in memory */
        stabs_generate();

        if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, 1, 0, stabbuf, 0, stablen,
                               nsections - 2, 0, 4, 12);

            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, 3, 0, stabstrbuf, 0,
                               stabstrlen, 0, 0, 4, 0);

            p += strlen(p) + 1;
            /* link -> symtable  info -> section to refer to */
            elf_section_header(p - shstrtab, 9, 0, stabrelbuf, 0,
                               stabrellen, symtabsection, nsections - 3, 4,
                               8);
        }
    }
    fwrite(align_str, align, 1, elffp);

    /*
     * Now output the sections.
     */
    elf_write_sections();

    nasm_free(elf_sects);
    saa_free(symtab);
}
Пример #29
0
static void freemembuf(memorybuffer *b)
{
  if (!b) return;
  freemembuf(b->next);
  nasm_free(b);
}
Пример #30
0
void stabs_generate(void)
{
    int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
    unsigned char *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
    char **allfiles;
    int *fileidx;

    struct linelist *ptr;

    ptr = stabslines;

    allfiles = (char **)nasm_malloc(numlinestabs * sizeof(char *));
    for (i = 0; i < numlinestabs; i++)
        allfiles[i] = 0;
    numfiles = 0;
    while (ptr) {
        if (numfiles == 0) {
            allfiles[0] = ptr->filename;
            numfiles++;
        } else {
            for (i = 0; i < numfiles; i++) {
                if (!strcmp(allfiles[i], ptr->filename))
                    break;
            }
            if (i >= numfiles) {
                allfiles[i] = ptr->filename;
                numfiles++;
            }
        }
        ptr = ptr->next;
    }
    strsize = 1;
    fileidx = (int *)nasm_malloc(numfiles * sizeof(int));
    for (i = 0; i < numfiles; i++) {
        fileidx[i] = strsize;
        strsize += strlen(allfiles[i]) + 1;
    }
    mainfileindex = 0;
    for (i = 0; i < numfiles; i++) {
        if (!strcmp(allfiles[i], elf_module)) {
            mainfileindex = i;
            break;
        }
    }

    /* worst case size of the stab buffer would be:
       the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
     */
    sbuf =
        (unsigned char *)nasm_malloc((numlinestabs * 2 + 3) *
                                     sizeof(struct stabentry));

    ssbuf = (unsigned char *)nasm_malloc(strsize);

    rbuf = (unsigned char *)nasm_malloc(numlinestabs * 8 * (2 + 3));
    rptr = rbuf;

    for (i = 0; i < numfiles; i++) {
        strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
    }
    ssbuf[0] = 0;

    stabstrlen = strsize;       /* set global variable for length of stab strings */

    sptr = sbuf;
    /* this is the first stab, its strx points to the filename of the
       the source-file, the n_desc field should be set to the number
       of remaining stabs
     */
    WRITE_STAB(sptr, fileidx[0], 0, 0, 0, strlen(allfiles[0] + 12));

    ptr = stabslines;
    numstabs = 0;

    if (ptr) {
        /* this is the stab for the main source file */
        WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);

        /* relocation stuff */
        /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */
        WRITELONG(rptr, (sptr - sbuf) - 4);
        WRITELONG(rptr, ((ptr->info.section + 3) << 8) | R_386_32);

        numstabs++;
        currfile = mainfileindex;
    }

    while (ptr) {
        if (strcmp(allfiles[currfile], ptr->filename)) {
            /* oops file has changed... */
            for (i = 0; i < numfiles; i++)
                if (!strcmp(allfiles[i], ptr->filename))
                    break;
            currfile = i;
            WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
                       ptr->info.offset);
            numstabs++;

            /* relocation stuff */
            /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */
            WRITELONG(rptr, (sptr - sbuf) - 4);
            WRITELONG(rptr, ((ptr->info.section + 3) << 8) | R_386_32);
        }

        WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
        numstabs++;

        /* relocation stuff */
        /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */
        WRITELONG(rptr, (sptr - sbuf) - 4);
        WRITELONG(rptr, ((ptr->info.section + 3) << 8) | R_386_32);

        ptr = ptr->next;

    }

    ((struct stabentry *)sbuf)->n_desc = numstabs;

    nasm_free(allfiles);
    nasm_free(fileidx);

    stablen = (sptr - sbuf);
    stabrellen = (rptr - rbuf);
    stabrelbuf = rbuf;
    stabbuf = sbuf;
    stabstrbuf = ssbuf;
}