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); }
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); }
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(); } }
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); } }
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; }
static void dbg_cleanup(void) { dfmt->cleanup(); while (dbgsect) { struct Section *tmp = dbgsect; dbgsect = dbgsect->next; nasm_free(tmp->name); nasm_free(tmp); } }
static void dbg_cleanup(void) { while (dbgsect) { struct Section *tmp = dbgsect; dbgsect = dbgsect->next; nasm_free (tmp->name); nasm_free (tmp); } fclose(dbgf); }
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); }
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); } }
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); } }
static void freenode(struct segtabnode *n) { if (!n) return; freenode(n->left); freenode(n->right); nasm_free(n); }
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); }
void cleanup_insn (insn *i) { extop *e; while (i->eops) { e = i->eops; i->eops = i->eops->next; nasm_free (e); } }
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); }
void cleanup_labels(void) { union label *lptr, *lhold; initialized = false; hash_free(<ab); 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); } }
static void list_cleanup(void) { if (!listp) return; while (mistack) { MacroInhibit *temp = mistack; mistack = temp->next; nasm_free(temp); } list_emit(); fclose(listfp); }
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); } }
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); }
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); } }
/* * 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(<ab, 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++; }
/* * 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); } }
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; }
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"); }
/* * 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); }
static void stdscan_pop(void) { nasm_free(stdscan_tempstorage[--stdscan_templen]); }
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; }
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"); }
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(§s[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); }
static void freemembuf(memorybuffer *b) { if (!b) return; freemembuf(b->next); nasm_free(b); }
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; }