Exemple #1
0
static void coff_write_relocs (struct Section *s) 
{
    struct Reloc *r;

    for (r = s->head; r; r = r->next) {
	fwritelong (r->address, coffp);
	fwritelong (r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
				 r->symbase == ABS_SYMBOL ? initsym-1 :
				 r->symbase == SECT_SYMBOLS ? 2 : 0), coffp);
	/*
	 * Strange: Microsoft's COFF documentation says 0x03 for an
	 * absolute relocation, but both Visual C++ and DJGPP agree
	 * that in fact it's 0x06. I'll use 0x06 until someone
	 * argues.
	 */
	fwriteshort (r->relative ? 0x14 : 0x06, coffp);
    }
}
Exemple #2
0
static void aout_write_relocs (struct Reloc *r) {
    while (r) {
	unsigned long word2;

	fwritelong (r->address, aoutfp);

	if (r->symbol >= 0)
	    word2 = r->symbol;
	else
	    word2 = -r->symbol;
	word2 |= r->reltype << 24;
	word2 |= (r->bytes == 1 ? 0 :
		  r->bytes == 2 ? 0x2000000L : 0x4000000L);
	fwritelong (word2, aoutfp);

	r = r->next;
    }
}
Exemple #3
0
static void coff_symbol (char *name, long strpos, long value,
			 int section, int type, int aux) 
{
    char padname[8];

    if (name) {
	memset (padname, 0, 8);
	strncpy (padname, name, 8);
	fwrite (padname, 8, 1, coffp);
    } else {
	fwritelong (0L, coffp);
	fwritelong (strpos, coffp);
    }
    fwritelong (value, coffp);
    fwriteshort (section, coffp);
    fwriteshort (0, coffp);
    fputc (type, coffp);
    fputc (aux, coffp);
}
Exemple #4
0
static void aout_write_syms (void) 
{
    unsigned long i;

    saa_rewind (syms);
    for (i = 0; i < nsyms; i++) {
	struct Symbol *sym = saa_rstruct(syms);
	fwritelong (sym->strpos, aoutfp);
	fwritelong ((long)sym->type & ~SYM_WITH_SIZE, aoutfp);
	/*
	 * Fix up the symbol value now we know the final section
	 * sizes.
	 */
	if ((sym->type & SECT_MASK) == SECT_DATA)
	    sym->value += stext.len;
	if ((sym->type & SECT_MASK) == SECT_BSS)
	    sym->value += stext.len + sdata.len;
	fwritelong (sym->value, aoutfp);
	/*
	 * Output a size record if necessary.
	 */
	if (sym->type & SYM_WITH_SIZE) {
	    fwritelong(sym->strpos, aoutfp);
	    fwritelong(0x0DL, aoutfp);  /* special value: means size */
	    fwritelong(sym->size, aoutfp);
	    i++;		       /* use up another of `nsyms' */
	}
    }
}
Exemple #5
0
static void elf_section_header(int name, int type, int flags,
                               void *data, int is_saa, long datalen,
                               int link, int info, int align, int eltsize)
{
    elf_sects[elf_nsect].data = data;
    elf_sects[elf_nsect].len = datalen;
    elf_sects[elf_nsect].is_saa = is_saa;
    elf_nsect++;

    fwritelong((long)name, elffp);
    fwritelong((long)type, elffp);
    fwritelong((long)flags, elffp);
    fwritelong(0L, elffp);      /* no address, ever, in object files */
    fwritelong(type == 0 ? 0L : elf_foffs, elffp);
    fwritelong(datalen, elffp);
    if (data)
        elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1;
    fwritelong((long)link, elffp);
    fwritelong((long)info, elffp);
    fwritelong((long)align, elffp);
    fwritelong((long)eltsize, elffp);
}
Exemple #6
0
static void aout_write(void) 
{
    /*
     * Emit the a.out header.
     */
    /* OMAGIC, M_386 or MID_I386, no flags */
    fwritelong (bsd ? 0x07018600 | is_pic : 0x640107L, aoutfp);
    fwritelong (stext.len, aoutfp);
    fwritelong (sdata.len, aoutfp);
    fwritelong (sbss.len, aoutfp);
    fwritelong (nsyms * 12, aoutfp);   /* length of symbol table */
    fwritelong (0L, aoutfp);	       /* object files have no entry point */
    fwritelong (stext.nrelocs * 8, aoutfp);   /* size of text relocs */
    fwritelong (sdata.nrelocs * 8, aoutfp);   /* size of data relocs */

    /*
     * Write out the code section and the data section.
     */
    saa_fpwrite (stext.data, aoutfp);
    saa_fpwrite (sdata.data, aoutfp);

    /*
     * Write out the relocations.
     */
    aout_write_relocs (stext.head);
    aout_write_relocs (sdata.head);

    /*
     * Write the symbol table.
     */
    aout_write_syms ();

    /*
     * And the string table.
     */
    fwritelong (strslen+4, aoutfp);    /* length includes length count */
    saa_fpwrite (strs, aoutfp);
}
Exemple #7
0
static void coff_write_symbols (void) 
{
    char filename[18];
    int i;

    /*
     * The `.file' record, and the file name auxiliary record.
     */
    coff_symbol (".file", 0L, 0L, -2, 0x67, 1);
    memset (filename, 0, 18);
    strncpy (filename, coff_infile, 18);
    fwrite (filename, 18, 1, coffp);

    /*
     * The section records, with their auxiliaries.
     */
    memset (filename, 0, 18);	       /* useful zeroed buffer */

    for (i=0; i<nsects; i++) {
	coff_symbol (sects[i]->name, 0L, 0L, i+1, 3, 1);
	fwritelong (sects[i]->len, coffp);
	fwriteshort (sects[i]->nrelocs, coffp);
	fwrite (filename, 12, 1, coffp);
    }

    /*
     * The absolute symbol, for relative-to-absolute relocations.
     */
    coff_symbol (".absolut", 0L, 0L, -1, 3, 0);

    /*
     * The real symbols.
     */
    saa_rewind (syms);
    for (i=0; i<nsyms; i++) {
	struct Symbol *sym = saa_rstruct (syms);
	coff_symbol (sym->strpos == -1 ? sym->name : NULL,
		     sym->strpos, sym->value, sym->section,
		     sym->is_global ? 2 : 3, 0);
    }
}
Exemple #8
0
static void coff_section_header (char *name, long vsize,
				 long datalen, long datapos,
				 long relpos, int nrelocs, long flags) 
{
    char padname[8];

    memset (padname, 0, 8);
    strncpy (padname, name, 8);
    fwrite (padname, 8, 1, coffp);
    fwritelong (vsize, coffp);
    fwritelong (0L, coffp);	       /* RVA/offset - we ignore */
    fwritelong (datalen, coffp);
    fwritelong (datapos, coffp);
    fwritelong (relpos, coffp);
    fwritelong (0L, coffp);	       /* no line numbers - we don't do 'em */
    fwriteshort (nrelocs, coffp);
    fwriteshort (0, coffp);	       /* again, no line numbers */
    fwritelong (flags, coffp);
}
Exemple #9
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);
}
Exemple #10
0
static void coff_write (void) 
{
    long pos, sympos, vsize;
    int i;

    /*
     * Work out how big the file will get. Calculate the start of
     * the `real' symbols at the same time.
     */
    pos = 0x14 + 0x28 * nsects;
    initsym = 3;		       /* two for the file, one absolute */
    for (i=0; i<nsects; i++) {
	if (sects[i]->data) {
	    sects[i]->pos = pos;
	    pos += sects[i]->len;
	    sects[i]->relpos = pos;
	    pos += 10 * sects[i]->nrelocs;
	} else
	    sects[i]->pos = sects[i]->relpos = 0L;
	initsym += 2;		       /* two for each section */
    }
    sympos = pos;

    /*
     * Output the COFF header.
     */
    fwriteshort (0x14C, coffp);	       /* MACHINE_i386 */
    fwriteshort (nsects, coffp);       /* number of sections */
    fwritelong (time(NULL), coffp);    /* time stamp */
    fwritelong (sympos, coffp);
    fwritelong (nsyms + initsym, coffp);
    fwriteshort (0, coffp);	       /* no optional header */
    /* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */
    fwriteshort (win32 ? 0 : 0x104, coffp);

    /*
     * Output the section headers.
     */
    vsize = 0L;
    for (i=0; i<nsects; i++) {
	coff_section_header (sects[i]->name, vsize, sects[i]->len,
			     sects[i]->pos, sects[i]->relpos,
			     sects[i]->nrelocs, sects[i]->flags);
	vsize += sects[i]->len;
    }

    /*
     * Output the sections and their relocations.
     */
    for (i=0; i<nsects; i++)
	if (sects[i]->data) {
	    saa_fpwrite (sects[i]->data, coffp);
	    coff_write_relocs (sects[i]);
	}

    /*
     * Output the symbol and string tables.
     */
    coff_write_symbols();
    fwritelong (strslen+4, coffp);     /* length includes length count */
    saa_fpwrite (strs, coffp);
}
Exemple #11
0
static void as86_write_section (struct Section *sect, int index) 
{
    struct Piece *p;
    unsigned long s;
    long length;

    fputc (0x20+index, as86fp);	       /* select the right section */

    saa_rewind (sect->data);

    for (p = sect->head; p; p = p->next)
	switch (p->type) {
	  case 0:
	    /*
	     * Absolute data. Emit it in chunks of at most 64
	     * bytes.
	     */
	    length = p->bytes;
	    do {
		char buf[64];
		long tmplen = (length > 64 ? 64 : length);
		fputc (0x40 | (tmplen & 0x3F), as86fp);
		saa_rnbytes (sect->data, buf, tmplen);
		fwrite (buf, 1, tmplen, as86fp);
		length -= tmplen;
	    } while (length > 0);
	    break;
	  case 1:
	    /*
	     * A segment-type relocation. First fix up the BSS.
	     */
	    if (p->number == SECT_BSS)
		p->number = SECT_DATA, p->offset += sdata.len;
	    as86_set_rsize (p->bytes);
	    fputc (0x80 | (p->relative ? 0x20 : 0) | p->number, as86fp);
	    if (as86_reloc_size == 2)
		fwriteshort (p->offset, as86fp);
	    else
		fwritelong (p->offset, as86fp);
	    break;
	  case 2:
	    /*
	     * A symbol-type relocation.
	     */
	    as86_set_rsize (p->bytes);
	    s = p->offset;
	    if (s > 65535L)
		s = 3;
	    else if (s > 255)
		s = 2;
	    else if (s > 0)
		s = 1;
	    else
		s = 0;
	    fputc (0xC0 |
		   (p->relative ? 0x20 : 0) |
		   (p->number > 255 ? 0x04 : 0) | s, as86fp);
	    if (p->number > 255)
		fwriteshort (p->number, as86fp);
	    else
		fputc (p->number, as86fp);
	    switch ((int)s) {
	      case 0: break;
	      case 1: fputc (p->offset, as86fp); break;
	      case 2: fwriteshort (p->offset, as86fp); break;
	      case 3: fwritelong (p->offset, as86fp); break;
	    }
	    break;
	}
}
Exemple #12
0
static void as86_write(void) 
{
    int i;
    long symlen, seglen, segsize;

    /*
     * First, go through the symbol records working out how big
     * each will be. Also fix up BSS references at this time, and
     * set the flags words up completely.
     */
    symlen = 0;
    saa_rewind (syms);
    for (i = 0; i < nsyms; i++) {
	struct Symbol *sym = saa_rstruct (syms);
	if (sym->segment == SECT_BSS)
	    sym->segment = SECT_DATA, sym->value += sdata.len;
	sym->flags |= sym->segment;
	if (sym->value == 0)
	    sym->flags |= 0 << 14, symlen += 4;
	else if (sym->value >= 0 && sym->value <= 255)
	    sym->flags |= 1 << 14, symlen += 5;
	else if (sym->value >= 0 && sym->value <= 65535L)
	    sym->flags |= 2 << 14, symlen += 6;
	else
	    sym->flags |= 3 << 14, symlen += 8;
    }

    /*
     * Now do the same for the segments, and get the segment size
     * descriptor word at the same time.
     */
    seglen = segsize = 0;
    if ((unsigned long) stext.len > 65535L)
	segsize |= 0x03000000L, seglen += 4;
    else
	segsize |= 0x02000000L, seglen += 2;
    if ((unsigned long) sdata.len > 65535L)
	segsize |= 0xC0000000L, seglen += 4;
    else
	segsize |= 0x80000000L, seglen += 2;

    /*
     * Emit the as86 header.
     */
    fwritelong (0x000186A3L, as86fp);
    fputc (0x2A, as86fp);
    fwritelong (27+symlen+seglen+strslen, as86fp);   /* header length */
    fwritelong (stext.len+sdata.len, as86fp);
    fwriteshort (strslen, as86fp);
    fwriteshort (0, as86fp);	       /* class = revision = 0 */
    fwritelong (0x55555555L, as86fp);   /* segment max sizes: always this */
    fwritelong (segsize, as86fp);      /* segment size descriptors */
    if (segsize & 0x01000000L)
	fwritelong (stext.len, as86fp);
    else
	fwriteshort (stext.len, as86fp);
    if (segsize & 0x40000000L)
	fwritelong (sdata.len, as86fp);
    else
	fwriteshort (sdata.len, as86fp);
    fwriteshort (nsyms, as86fp);

    /*
     * Write the symbol table.
     */
    saa_rewind (syms);
    for (i = 0; i < nsyms; i++) {
	struct Symbol *sym = saa_rstruct (syms);
	fwriteshort (sym->strpos, as86fp);
	fwriteshort (sym->flags, as86fp);
	switch (sym->flags & (3<<14)) {
	  case 0<<14: break;
	  case 1<<14: fputc (sym->value, as86fp); break;
	  case 2<<14: fwriteshort (sym->value, as86fp); break;
	  case 3<<14: fwritelong (sym->value, as86fp); break;
	}
    }

    /*
     * Write out the string table.
     */
    saa_fpwrite (strs, as86fp);

    /*
     * Write the program text.
     */
    as86_reloc_size = -1;
    as86_write_section (&stext, SECT_TEXT);
    as86_write_section (&sdata, SECT_DATA);
    fputc (0, as86fp);		       /* termination */
}