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; }
/* * 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); } }
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); } }
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; }
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; }
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); } } } }
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); } } }
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); } } } }
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); } }