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' */ } } }
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); } }
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 as86_write(void) { uint32_t i; int32_t 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 ((uint32_t)stext.len > 65535L) segsize |= 0x03000000L, seglen += 4; else segsize |= 0x02000000L, seglen += 2; if ((uint32_t)sdata.len > 65535L) segsize |= 0xC0000000L, seglen += 4; else segsize |= 0x80000000L, seglen += 2; /* * Emit the as86 header. */ fwriteint32_t(0x000186A3L, ofile); fputc(0x2A, ofile); fwriteint32_t(27 + symlen + seglen + strslen, ofile); /* header length */ fwriteint32_t(stext.len + sdata.len + bsslen, ofile); fwriteint16_t(strslen, ofile); fwriteint16_t(0, ofile); /* class = revision = 0 */ fwriteint32_t(0x55555555L, ofile); /* segment max sizes: always this */ fwriteint32_t(segsize, ofile); /* segment size descriptors */ if (segsize & 0x01000000L) fwriteint32_t(stext.len, ofile); else fwriteint16_t(stext.len, ofile); if (segsize & 0x40000000L) fwriteint32_t(sdata.len + bsslen, ofile); else fwriteint16_t(sdata.len + bsslen, ofile); fwriteint16_t(nsyms, ofile); /* * Write the symbol table. */ saa_rewind(syms); for (i = 0; i < nsyms; i++) { struct Symbol *sym = saa_rstruct(syms); fwriteint16_t(sym->strpos, ofile); fwriteint16_t(sym->flags, ofile); switch (sym->flags & (3 << 14)) { case 0 << 14: break; case 1 << 14: fputc(sym->value, ofile); break; case 2 << 14: fwriteint16_t(sym->value, ofile); break; case 3 << 14: fwriteint32_t(sym->value, ofile); break; } } /* * Write out the string table. */ saa_fpwrite(strs, ofile); /* * Write the program text. */ as86_reloc_size = -1; as86_write_section(&stext, SECT_TEXT); as86_write_section(&sdata, SECT_DATA); /* * Append the BSS section to the .data section */ if (bsslen > 65535L) { fputc(0x13, ofile); fwriteint32_t(bsslen, ofile); } else if (bsslen > 255) { fputc(0x12, ofile); fwriteint16_t(bsslen, ofile); } else if (bsslen) { fputc(0x11, ofile); fputc(bsslen, ofile); } fputc(0, ofile); /* termination */ }