Example #1
0
static struct SAA *elf_build_reltab(long *len, struct Reloc *r)
{
    struct SAA *s;
    unsigned char *p, entry[8];

    if (!r)
        return NULL;

    s = saa_init(1L);
    *len = 0;

    while (r) {
        long sym = r->symbol;

        if (sym >= GLOBAL_TEMP_BASE)
            sym += -GLOBAL_TEMP_BASE + (nsects + 3) + nlocals;

        p = entry;
        WRITELONG(p, r->address);
        WRITELONG(p, (sym << 8) + r->type);
        saa_wbytes(s, entry, 8L);
        *len += 8;

        r = r->next;
    }

    return s;
}
Example #2
0
/*
 * a.out files have the curious property that all references to
 * things in the data or bss sections are done by addresses which
 * are actually relative to the start of the _text_ section, in the
 * _file_. (No relation to what happens after linking. No idea why
 * this should be so. It's very strange.) So we have to go through
 * the relocation table, _after_ the final size of each section is
 * known, and fix up the relocations pointed to.
 */
static void aout_fixup_relocs(struct Section *sect) 
{
    struct Reloc *r;

    saa_rewind (sect->data);
    for (r = sect->head; r; r = r->next) {
	unsigned char *p, *q, blk[4];
	long l;

	saa_fread (sect->data, r->address, blk, (long)r->bytes);
	p = q = blk;
	l = *p++;
	if (r->bytes > 1) {
	    l += ((long)*p++) << 8;
	    if (r->bytes == 4) {
		l += ((long)*p++) << 16;
		l += ((long)*p++) << 24;
	    }
	}
	if (r->symbol == -SECT_DATA)
	    l += stext.len;
	else if (r->symbol == -SECT_BSS)
	    l += stext.len + sdata.len;
	if (r->bytes == 4)
	    WRITELONG(q, l);
	else if (r->bytes == 2)
	    WRITESHORT(q, l);
	else
	    *q++ = l & 0xFF;
	saa_fwrite (sect->data, r->address, blk, (long)r->bytes);
    }
}
Example #3
0
static void elf_out(long segto, const void *data, unsigned long type,
                    long segment, long wrt)
{
    struct Section *s;
    long realbytes = type & OUT_SIZMASK;
    long addr;
    unsigned char mydata[4], *p;
    int i;
    static struct symlininfo sinfo;

    type &= OUT_TYPMASK;

    /*
     * handle absolute-assembly (structure definitions)
     */
    if (segto == NO_SEG) {
        if (type != OUT_RESERVE)
            error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
                  " space");
        return;
    }

    s = NULL;
    for (i = 0; i < nsects; i++)
        if (segto == sects[i]->index) {
            s = sects[i];
            break;
        }
    if (!s) {
        int tempint;            /* ignored */
        if (segto != elf_section_names(".text", 2, &tempint))
            error(ERR_PANIC, "strange segment conditions in ELF driver");
        else {
            s = sects[nsects - 1];
            i = nsects - 1;
        }
    }

    /* again some stabs debugging stuff */
    if (of_elf.current_dfmt) {
        sinfo.offset = s->len;
        sinfo.section = i;
        sinfo.name = s->name;
        of_elf.current_dfmt->debug_output(TY_STABSSYMLIN, &sinfo);
    }
    /* end of debugging stuff */

    if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
        error(ERR_WARNING, "attempt to initialise memory in"
              " BSS section `%s': ignored", s->name);
        if (type == OUT_REL2ADR)
            realbytes = 2;
        else if (type == OUT_REL4ADR)
            realbytes = 4;
        s->len += realbytes;
        return;
    }

    if (type == OUT_RESERVE) {
        if (s->type == SHT_PROGBITS) {
            error(ERR_WARNING, "uninitialised space declared in"
                  " non-BSS section `%s': zeroing", s->name);
            elf_sect_write(s, NULL, realbytes);
        } else
            s->len += realbytes;
    } else if (type == OUT_RAWDATA) {
        if (segment != NO_SEG)
            error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
        elf_sect_write(s, data, realbytes);
    } else if (type == OUT_ADDRESS) {
        int gnu16 = 0;
        addr = *(long *)data;
        if (segment != NO_SEG) {
            if (segment % 2) {
                error(ERR_NONFATAL, "ELF format does not support"
                      " segment base references");
            } else {
                if (wrt == NO_SEG) {
                    if (realbytes == 2) {
                        gnu16 = 1;
                        elf_add_reloc(s, segment, R_386_16);
                    } else {
                        elf_add_reloc(s, segment, R_386_32);
                    }
                } else if (wrt == elf_gotpc_sect + 1) {
                    /*
                     * The user will supply GOT relative to $$. ELF
                     * will let us have GOT relative to $. So we
                     * need to fix up the data item by $-$$.
                     */
                    addr += s->len;
                    elf_add_reloc(s, segment, R_386_GOTPC);
                } else if (wrt == elf_gotoff_sect + 1) {
                    elf_add_reloc(s, segment, R_386_GOTOFF);
                } else if (wrt == elf_got_sect + 1) {
                    addr = elf_add_gsym_reloc(s, segment, addr,
                                              R_386_GOT32, TRUE);
                } else if (wrt == elf_sym_sect + 1) {
                    if (realbytes == 2) {
                        gnu16 = 1;
                        addr = elf_add_gsym_reloc(s, segment, addr,
                                                  R_386_16, FALSE);
                    } else {
                        addr = elf_add_gsym_reloc(s, segment, addr,
                                                  R_386_32, FALSE);
                    }
                } else if (wrt == elf_plt_sect + 1) {
                    error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
                          "relative PLT references");
                } else {
                    error(ERR_NONFATAL, "ELF format does not support this"
                          " use of WRT");
                    wrt = NO_SEG;       /* we can at least _try_ to continue */
                }
            }
        }
        p = mydata;
        if (gnu16) {
            error(ERR_WARNING | ERR_WARN_GNUELF,
                  "16-bit relocations in ELF is a GNU extension");
            WRITESHORT(p, addr);
        } else {
            if (realbytes != 4 && segment != NO_SEG) {
                error(ERR_NONFATAL,
                      "Unsupported non-32-bit ELF relocation");
            }
            WRITELONG(p, addr);
        }
        elf_sect_write(s, mydata, realbytes);
    } else if (type == OUT_REL2ADR) {
        if (segment == segto)
            error(ERR_PANIC, "intra-segment OUT_REL2ADR");
        if (segment != NO_SEG && segment % 2) {
            error(ERR_NONFATAL, "ELF format does not support"
                  " segment base references");
        } else {
            if (wrt == NO_SEG) {
                error(ERR_WARNING | ERR_WARN_GNUELF,
                      "16-bit relocations in ELF is a GNU extension");
                elf_add_reloc(s, segment, R_386_PC16);
            } else {
                error(ERR_NONFATAL,
                      "Unsupported non-32-bit ELF relocation");
            }
        }
        p = mydata;
        WRITESHORT(p, *(long *)data - realbytes);
        elf_sect_write(s, mydata, 2L);
    } else if (type == OUT_REL4ADR) {
        if (segment == segto)
            error(ERR_PANIC, "intra-segment OUT_REL4ADR");
        if (segment != NO_SEG && segment % 2) {
            error(ERR_NONFATAL, "ELF format does not support"
                  " segment base references");
        } else {
            if (wrt == NO_SEG) {
                elf_add_reloc(s, segment, R_386_PC32);
            } else if (wrt == elf_plt_sect + 1) {
                elf_add_reloc(s, segment, R_386_PLT32);
            } else if (wrt == elf_gotpc_sect + 1 ||
                       wrt == elf_gotoff_sect + 1 ||
                       wrt == elf_got_sect + 1) {
                error(ERR_NONFATAL, "ELF format cannot produce PC-"
                      "relative GOT references");
            } else {
                error(ERR_NONFATAL, "ELF format does not support this"
                      " use of WRT");
                wrt = NO_SEG;   /* we can at least _try_ to continue */
            }
        }
        p = mydata;
        WRITELONG(p, *(long *)data - realbytes);
        elf_sect_write(s, mydata, 4L);
    }
}
Example #4
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;
}
Example #5
0
static struct SAA *elf_build_symtab(long *len, long *local)
{
    struct SAA *s = saa_init(1L);
    struct Symbol *sym;
    unsigned char entry[16], *p;
    int i;

    *len = *local = 0;

    /*
     * First, an all-zeros entry, required by the ELF spec.
     */
    saa_wbytes(s, NULL, 16L);   /* null symbol table entry */
    *len += 16;
    (*local)++;

    /*
     * Next, an entry for the file name.
     */
    p = entry;
    WRITELONG(p, 1);            /* we know it's 1st thing in strtab */
    WRITELONG(p, 0);            /* no value */
    WRITELONG(p, 0);            /* no size either */
    WRITESHORT(p, 4);           /* type FILE */
    WRITESHORT(p, SHN_ABS);
    saa_wbytes(s, entry, 16L);
    *len += 16;
    (*local)++;

    /*
     * Now some standard symbols defining the segments, for relocation
     * purposes.
     */
    for (i = 1; i <= nsects + 1; i++) {
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITELONG(p, 0);        /* offset zero */
        WRITELONG(p, 0);        /* size zero */
        WRITESHORT(p, 3);       /* local section-type thing */
        WRITESHORT(p, (i == 1 ? SHN_ABS : i - 1));      /* the section id */
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*local)++;
    }

    /*
     * Now the other local symbols.
     */
    saa_rewind(syms);
    while ((sym = saa_rstruct(syms))) {
        if (sym->type & SYM_GLOBAL)
            continue;
        p = entry;
        WRITELONG(p, sym->strpos);
        WRITELONG(p, sym->value);
        WRITELONG(p, sym->size);
        WRITESHORT(p, sym->type);       /* local non-typed thing */
        WRITESHORT(p, sym->section);
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*local)++;
    }

    /*
     * Now the global symbols.
     */
    saa_rewind(syms);
    while ((sym = saa_rstruct(syms))) {
        if (!(sym->type & SYM_GLOBAL))
            continue;
        p = entry;
        WRITELONG(p, sym->strpos);
        WRITELONG(p, sym->value);
        WRITELONG(p, sym->size);
        WRITESHORT(p, sym->type);       /* global non-typed thing */
        WRITESHORT(p, sym->section);
        saa_wbytes(s, entry, 16L);
        *len += 16;
    }

    return s;
}
Example #6
0
static void aout_out (long segto, const void *data, unsigned long type,
		      long segment, long wrt) 
{
    struct Section *s;
    long realbytes = type & OUT_SIZMASK;
    long addr;
    unsigned char mydata[4], *p;

    type &= OUT_TYPMASK;

    /*
     * handle absolute-assembly (structure definitions)
     */
    if (segto == NO_SEG) {
	if (type != OUT_RESERVE)
	    error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
		   " space");
	return;
    }

    if (segto == stext.index)
	s = &stext;
    else if (segto == sdata.index)
	s = &sdata;
    else if (segto == sbss.index)
	s = NULL;
    else {
	error(ERR_WARNING, "attempt to assemble code in"
	      " segment %d: defaulting to `.text'", segto);
	s = &stext;
    }

    if (!s && type != OUT_RESERVE) {
	error(ERR_WARNING, "attempt to initialise memory in the"
	      " BSS section: ignored");
	if (type == OUT_REL2ADR)
	    realbytes = 2;
	else if (type == OUT_REL4ADR)
	    realbytes = 4;
	sbss.len += realbytes;
	return;
    }

    if (type == OUT_RESERVE) {
	if (s) {
	    error(ERR_WARNING, "uninitialised space declared in"
		  " %s section: zeroing",
		  (segto == stext.index ? "code" : "data"));
	    aout_sect_write (s, NULL, realbytes);
	} else
	    sbss.len += realbytes;
    } else if (type == OUT_RAWDATA) {
	if (segment != NO_SEG)
	    error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
	aout_sect_write (s, data, realbytes);
    } else if (type == OUT_ADDRESS) {
	addr = *(long *)data;
	if (segment != NO_SEG) {
	    if (segment % 2) {
		error(ERR_NONFATAL, "a.out format does not support"
		      " segment base references");
	    } else {
		if (wrt == NO_SEG) {
		    aout_add_reloc (s, segment, RELTYPE_ABSOLUTE, realbytes);
		} else if (!bsd) {
		    error (ERR_NONFATAL, "Linux a.out format does not support"
			   " any use of WRT");
		    wrt = NO_SEG;      /* we can at least _try_ to continue */
		} else if (wrt == aout_gotpc_sect+1) {
		    is_pic = 0x40;
		    aout_add_reloc (s, segment, RELTYPE_GOTPC, realbytes);
		} else if (wrt == aout_gotoff_sect+1) {
		    is_pic = 0x40;
		    addr = aout_add_gotoff_reloc (s, segment,
						  addr, realbytes);
		} else if (wrt == aout_got_sect+1) {
		    is_pic = 0x40;
		    addr = aout_add_gsym_reloc (s, segment, addr, RELTYPE_GOT,
						realbytes, TRUE);
		} else if (wrt == aout_sym_sect+1) {
		    addr = aout_add_gsym_reloc (s, segment, addr,
						RELTYPE_ABSOLUTE, realbytes,
						FALSE);
		} else if (wrt == aout_plt_sect+1) {
		    is_pic = 0x40;
		    error(ERR_NONFATAL, "a.out format cannot produce non-PC-"
			  "relative PLT references");
		} else {
		    error (ERR_NONFATAL, "a.out format does not support this"
			   " use of WRT");
		    wrt = NO_SEG;      /* we can at least _try_ to continue */
		}
	    }
	}
	p = mydata;
	if (realbytes == 2)
	    WRITESHORT (p, addr);
	else
	    WRITELONG (p, addr);
	aout_sect_write (s, mydata, realbytes);
    } else if (type == OUT_REL2ADR) {
	if (segment == segto)
	    error(ERR_PANIC, "intra-segment OUT_REL2ADR");
	if (segment != NO_SEG && segment % 2) {
	    error(ERR_NONFATAL, "a.out format does not support"
		  " segment base references");
	} else {
	    if (wrt == NO_SEG) {
		aout_add_reloc (s, segment, RELTYPE_RELATIVE, 2);
	    } else if (!bsd) {
		error (ERR_NONFATAL, "Linux a.out format does not support"
		       " any use of WRT");
		wrt = NO_SEG;      /* we can at least _try_ to continue */
	    } else if (wrt == aout_plt_sect+1) {
		is_pic = 0x40;
		aout_add_reloc (s, segment, RELTYPE_PLT, 2);
	    } else if (wrt == aout_gotpc_sect+1 ||
		       wrt == aout_gotoff_sect+1 ||
		       wrt == aout_got_sect+1) {
		error(ERR_NONFATAL, "a.out format cannot produce PC-"
		      "relative GOT references");
	    } else {
		error (ERR_NONFATAL, "a.out format does not support this"
		       " use of WRT");
		wrt = NO_SEG;      /* we can at least _try_ to continue */
	    }
	}
	p = mydata;
	WRITESHORT (p, *(long*)data-(realbytes + s->len));
	aout_sect_write (s, mydata, 2L);
    } else if (type == OUT_REL4ADR) {
	if (segment == segto)
	    error(ERR_PANIC, "intra-segment OUT_REL4ADR");
	if (segment != NO_SEG && segment % 2) {
	    error(ERR_NONFATAL, "a.out format does not support"
		  " segment base references");
	} else {
	    if (wrt == NO_SEG) {
		aout_add_reloc (s, segment, RELTYPE_RELATIVE, 4);
	    } else if (!bsd) {
		error (ERR_NONFATAL, "Linux a.out format does not support"
		       " any use of WRT");
		wrt = NO_SEG;      /* we can at least _try_ to continue */
	    } else if (wrt == aout_plt_sect+1) {
		is_pic = 0x40;
		aout_add_reloc (s, segment, RELTYPE_PLT, 4);
	    } else if (wrt == aout_gotpc_sect+1 ||
		       wrt == aout_gotoff_sect+1 ||
		       wrt == aout_got_sect+1) {
		error(ERR_NONFATAL, "a.out format cannot produce PC-"
		      "relative GOT references");
	    } else {
		error (ERR_NONFATAL, "a.out format does not support this"
		       " use of WRT");
		wrt = NO_SEG;      /* we can at least _try_ to continue */
	    }
	}
	p = mydata;
	WRITELONG (p, *(long*)data-(realbytes + s->len));
	aout_sect_write (s, mydata, 4L);
    }
}
static void as86_out(int32_t segto, const void *data,
		     enum out_type type, uint64_t size,
                     int32_t segment, int32_t wrt)
{
    struct Section *s;
    int32_t offset;
    uint8_t mydata[4], *p;

    if (wrt != NO_SEG) {
        wrt = NO_SEG;           /* continue to do _something_ */
        nasm_error(ERR_NONFATAL, "WRT not supported by as86 output format");
    }

    /*
     * handle absolute-assembly (structure definitions)
     */
    if (segto == NO_SEG) {
        if (type != OUT_RESERVE)
            nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
                  " space");
        return;
    }

    if (segto == stext.index)
        s = &stext;
    else if (segto == sdata.index)
        s = &sdata;
    else if (segto == bssindex)
        s = NULL;
    else {
        nasm_error(ERR_WARNING, "attempt to assemble code in"
              " segment %d: defaulting to `.text'", segto);
        s = &stext;
    }

    if (!s && type != OUT_RESERVE) {
        nasm_error(ERR_WARNING, "attempt to initialize memory in the"
              " BSS section: ignored");
	bsslen += realsize(type, size);
        return;
    }

    memset(mydata, 0, sizeof(mydata));

    if (type == OUT_RESERVE) {
        if (s) {
            nasm_error(ERR_WARNING, "uninitialized space declared in"
                  " %s section: zeroing",
                  (segto == stext.index ? "code" : "data"));
            as86_sect_write(s, NULL, size);
            as86_add_piece(s, 0, 0L, 0L, size, 0);
        } else
            bsslen += size;
    } else if (type == OUT_RAWDATA) {
        if (segment != NO_SEG)
            nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
        as86_sect_write(s, data, size);
        as86_add_piece(s, 0, 0L, 0L, size, 0);
    } else if (type == OUT_ADDRESS) {
        int asize = abs((int)size);
        if (segment != NO_SEG) {
            if (segment % 2) {
                nasm_error(ERR_NONFATAL, "as86 format does not support"
                      " segment base references");
            } else {
                offset = *(int64_t *)data;
                as86_add_piece(s, 1, offset, segment, asize, 0);
            }
        } else {
            p = mydata;
            WRITELONG(p, *(int64_t *)data);
            as86_sect_write(s, data, asize);
            as86_add_piece(s, 0, 0L, 0L, asize, 0);
        }
    } else if (type == OUT_REL2ADR) {
        if (segment == segto)
            nasm_panic(0, "intra-segment OUT_REL2ADR");
        if (segment != NO_SEG) {
            if (segment % 2) {
                nasm_error(ERR_NONFATAL, "as86 format does not support"
                      " segment base references");
            } else {
                offset = *(int64_t *)data;
                as86_add_piece(s, 1, offset - size + 2, segment, 2L,
                               1);
            }
        }
    } else if (type == OUT_REL4ADR) {
        if (segment == segto)
            nasm_panic(0, "intra-segment OUT_REL4ADR");
        if (segment != NO_SEG) {
            if (segment % 2) {
                nasm_error(ERR_NONFATAL, "as86 format does not support"
                      " segment base references");
            } else {
                offset = *(int64_t *)data;
                as86_add_piece(s, 1, offset - size + 4, segment, 4L,
                               1);
            }
        }
    }
}
Example #8
0
static void coff_out (long segto, void *data, unsigned long type,
		      long segment, long wrt) 
{
    struct Section *s;
    long realbytes = type & OUT_SIZMASK;
    unsigned char mydata[4], *p;
    int i;

    if (wrt != NO_SEG) {
	wrt = NO_SEG;		       /* continue to do _something_ */
	error (ERR_NONFATAL, "WRT not supported by COFF output formats");
    }

    type &= OUT_TYPMASK;

    /*
     * handle absolute-assembly (structure definitions)
     */
    if (segto == NO_SEG) {
	if (type != OUT_RESERVE)
	    error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
		   " space");
	return;
    }

    s = NULL;
    for (i=0; i<nsects; i++)
	if (segto == sects[i]->index) {
	    s = sects[i];
	    break;
	}
    if (!s) {
	int tempint;		       /* ignored */
	if (segto != coff_section_names (".text", 2, &tempint))
	    error (ERR_PANIC, "strange segment conditions in COFF driver");
	else
	    s = sects[nsects-1];
    }

    if (!s->data && type != OUT_RESERVE) {
	error(ERR_WARNING, "attempt to initialise memory in"
	      " BSS section `%s': ignored", s->name);
	if (type == OUT_REL2ADR)
	    realbytes = 2;
	else if (type == OUT_REL4ADR)
	    realbytes = 4;
	s->len += realbytes;
	return;
    }

    if (type == OUT_RESERVE) {
	if (s->data) {
	    error(ERR_WARNING, "uninitialised space declared in"
		  " non-BSS section `%s': zeroing", s->name);
	    coff_sect_write (s, NULL, realbytes);
	} else
	    s->len += realbytes;
    } else if (type == OUT_RAWDATA) {
	if (segment != NO_SEG)
	    error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
	coff_sect_write (s, data, realbytes);
    } else if (type == OUT_ADDRESS) {
	if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG))
	    error(ERR_NONFATAL, "COFF format does not support non-32-bit"
		  " relocations");
	else {
	    long fix = 0;
	    if (segment != NO_SEG || wrt != NO_SEG) {
		if (wrt != NO_SEG) {
		    error(ERR_NONFATAL, "COFF format does not support"
			  " WRT types");
		} else if (segment % 2) {
		    error(ERR_NONFATAL, "COFF format does not support"
			  " segment base references");
		} else
		    fix = coff_add_reloc (s, segment, FALSE);
	    }
	    p = mydata;
	    WRITELONG (p, *(long *)data + fix);
	    coff_sect_write (s, mydata, realbytes);
	}
    } else if (type == OUT_REL2ADR) {
	error(ERR_NONFATAL, "COFF format does not support 16-bit"
	      " relocations");
    } else if (type == OUT_REL4ADR) {
	if (segment == segto)
	    error(ERR_PANIC, "intra-segment OUT_REL4ADR");
	else if (segment == NO_SEG && win32)
	    error(ERR_NONFATAL, "Win32 COFF does not correctly support"
		  " relative references to absolute addresses");
	else {
	    long fix = 0;
	    if (segment != NO_SEG && segment % 2) {
		error(ERR_NONFATAL, "COFF format does not support"
		      " segment base references");
	    } else
		fix = coff_add_reloc (s, segment, TRUE);
	    p = mydata;
	    if (win32) {
		WRITELONG (p, *(long*)data + 4 - realbytes + fix);
	    } else {
		WRITELONG (p, *(long*)data-(realbytes + s->len) + fix);
	    }
	    coff_sect_write (s, mydata, 4L);
	}
    }
}
Example #9
0
static void as86_out (long segto, void *data, unsigned long type,
		      long segment, long wrt) 
{
    struct Section *s;
    long realbytes = type & OUT_SIZMASK;
    long offset;
    unsigned char mydata[4], *p;

    if (wrt != NO_SEG) {
	wrt = NO_SEG;		       /* continue to do _something_ */
	error (ERR_NONFATAL, "WRT not supported by as86 output format");
    }

    type &= OUT_TYPMASK;

    /*
     * handle absolute-assembly (structure definitions)
     */
    if (segto == NO_SEG) {
	if (type != OUT_RESERVE)
	    error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
		   " space");
	return;
    }

    if (segto == stext.index)
	s = &stext;
    else if (segto == sdata.index)
	s = &sdata;
    else if (segto == bssindex)
	s = NULL;
    else {
	error(ERR_WARNING, "attempt to assemble code in"
	      " segment %d: defaulting to `.text'", segto);
	s = &stext;
    }

    if (!s && type != OUT_RESERVE) {
	error(ERR_WARNING, "attempt to initialise memory in the"
	      " BSS section: ignored");
	if (type == OUT_REL2ADR)
	    realbytes = 2;
	else if (type == OUT_REL4ADR)
	    realbytes = 4;
	bsslen += realbytes;
	return;
    }

    if (type == OUT_RESERVE) {
	if (s) {
	    error(ERR_WARNING, "uninitialised space declared in"
		  " %s section: zeroing",
		  (segto == stext.index ? "code" : "data"));
	    as86_sect_write (s, NULL, realbytes);
	    as86_add_piece (s, 0, 0L, 0L, realbytes, 0);
	} else
	    bsslen += realbytes;
    } else if (type == OUT_RAWDATA) {
	if (segment != NO_SEG)
	    error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
	as86_sect_write (s, data, realbytes);
	as86_add_piece (s, 0, 0L, 0L, realbytes, 0);
    } else if (type == OUT_ADDRESS) {
	if (segment != NO_SEG) {
	    if (segment % 2) {
		error(ERR_NONFATAL, "as86 format does not support"
		      " segment base references");
	    } else{
		offset = * (long *) data;
		as86_add_piece (s, 1, offset, segment, realbytes, 0);
	    }
	} else {
	    p = mydata;
	    WRITELONG (p, * (long *) data);
	    as86_sect_write (s, data, realbytes);
	    as86_add_piece (s, 0, 0L, 0L, realbytes, 0);
	}
    } else if (type == OUT_REL2ADR) {
	if (segment == segto)
	    error(ERR_PANIC, "intra-segment OUT_REL2ADR");
	if (segment != NO_SEG) {
	    if (segment % 2) {
		error(ERR_NONFATAL, "as86 format does not support"
		      " segment base references");
	    } else {
		offset = * (long *) data;
		as86_add_piece (s, 1, offset-realbytes+2, segment, 2L, 1);
	    }
	}
    } else if (type == OUT_REL4ADR) {
	if (segment == segto)
	    error(ERR_PANIC, "intra-segment OUT_REL4ADR");
	if (segment != NO_SEG) {
	    if (segment % 2) {
		error(ERR_NONFATAL, "as86 format does not support"
		      " segment base references");
	    } else {
		offset = * (long *) data;
		as86_add_piece (s, 1, offset-realbytes+4, segment, 4L, 1);
	    }
	}
    }
}
Example #10
0
File: listing.c Project: aosm/nasm
static void list_output(long offset, const void *data, unsigned long type)
{
    unsigned long typ, size;

    if (!listp || suppress || user_nolist)      /* fbk - 9/2/00 */
        return;

    typ = type & OUT_TYPMASK;
    size = type & OUT_SIZMASK;

    if (typ == OUT_RAWDATA) {
        unsigned char const *p = data;
        char q[3];
        while (size--) {
            HEX(q, *p);
            q[2] = '\0';
            list_out(offset++, q);
            p++;
        }
    } else if (typ == OUT_ADDRESS) {
        unsigned long d = *(long *)data;
        char q[11];
        unsigned char p[4], *r = p;
        if (size == 4) {
            q[0] = '[';
            q[9] = ']';
            q[10] = '\0';
            WRITELONG(r, d);
            HEX(q + 1, p[0]);
            HEX(q + 3, p[1]);
            HEX(q + 5, p[2]);
            HEX(q + 7, p[3]);
            list_out(offset, q);
        } else {
            q[0] = '[';
            q[5] = ']';
            q[6] = '\0';
            WRITESHORT(r, d);
            HEX(q + 1, p[0]);
            HEX(q + 3, p[1]);
            list_out(offset, q);
        }
    } else if (typ == OUT_REL2ADR) {
        unsigned long d = *(long *)data;
        char q[11];
        unsigned char p[4], *r = p;
        q[0] = '(';
        q[5] = ')';
        q[6] = '\0';
        WRITESHORT(r, d);
        HEX(q + 1, p[0]);
        HEX(q + 3, p[1]);
        list_out(offset, q);
    } else if (typ == OUT_REL4ADR) {
        unsigned long d = *(long *)data;
        char q[11];
        unsigned char p[4], *r = p;
        q[0] = '(';
        q[9] = ')';
        q[10] = '\0';
        WRITELONG(r, d);
        HEX(q + 1, p[0]);
        HEX(q + 3, p[1]);
        HEX(q + 5, p[2]);
        HEX(q + 7, p[3]);
        list_out(offset, q);
    } else if (typ == OUT_RESERVE) {
        char q[20];
        snprintf(q, sizeof(q), "<res %08lX>", size);
        list_out(offset, q);
    }
}