From fcedfddf00b3f994e4f4e40332ac7fc192c63244 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 5 Oct 2025 21:56:51 +0700 Subject: claude is gud --- vere/ext/nasm/output/codeview.c | 820 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 820 insertions(+) create mode 100644 vere/ext/nasm/output/codeview.c (limited to 'vere/ext/nasm/output/codeview.c') diff --git a/vere/ext/nasm/output/codeview.c b/vere/ext/nasm/output/codeview.c new file mode 100644 index 0000000..d1011fc --- /dev/null +++ b/vere/ext/nasm/output/codeview.c @@ -0,0 +1,820 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * codeview.c Codeview Debug Format support for COFF + */ + +#include "version.h" +#include "compiler.h" + + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "preproc.h" +#include "saa.h" +#include "hashtbl.h" +#include "outlib.h" +#include "pecoff.h" +#include "md5.h" + +static void cv8_init(void); +static void cv8_linenum(const char *filename, int32_t linenumber, + int32_t segto); +static void cv8_deflabel(char *name, int32_t segment, int64_t offset, + int is_global, char *special); +static void cv8_typevalue(int32_t type); +static void cv8_output(int type, void *param); +static void cv8_cleanup(void); + +const struct dfmt df_cv8 = { + "Codeview 8+", /* .fullname */ + "cv8", /* .shortname */ + cv8_init, /* .init */ + cv8_linenum, /* .linenum */ + cv8_deflabel, /* .debug_deflabel */ + NULL, /* .debug_smacros */ + NULL, /* .debug_include */ + NULL, /* .debug_mmacros */ + null_debug_directive, /* .debug_directive */ + cv8_typevalue, /* .debug_typevalue */ + cv8_output, /* .debug_output */ + cv8_cleanup, /* .cleanup */ + NULL /* pragma list */ +}; + +/******************************************************************************* + * dfmt callbacks + ******************************************************************************/ +struct source_file; + +struct source_file { + const char *filename; + char *fullname; + uint32_t fullnamelen; + + struct source_file *next; + + uint32_t filetbl_off; + uint32_t sourcetbl_off; + + struct SAA *lines; + uint32_t num_lines; + + unsigned char md5sum[MD5_HASHBYTES]; +}; + +struct linepair { + uint32_t file_offset; + uint32_t linenumber; +}; + +enum symbol_type { + SYMTYPE_CODE, + SYMTYPE_PROC, + SYMTYPE_LDATA, + SYMTYPE_GDATA, + + SYMTYPE_MAX +}; + +struct cv8_symbol { + enum symbol_type type; + char *name; + + uint32_t secrel; + uint16_t section; + uint32_t size; + uint32_t typeindex; + + enum symtype { + TYPE_UNREGISTERED = 0x0000, /* T_NOTYPE */ + TYPE_BYTE = 0x0020, + TYPE_WORD = 0x0021, + TYPE_DWORD= 0x0022, + TYPE_QUAD = 0x0023, + + TYPE_REAL32 = 0x0040, + TYPE_REAL64 = 0x0041, + TYPE_REAL80 = 0x0042, + TYPE_REAL128= 0x0043, + TYPE_REAL256= 0x0044, + TYPE_REAL512= 0x0045 + } symtype; +}; + +struct cv8_state { + int symbol_sect; + int type_sect; + + uint32_t text_offset; + + struct source_file *source_files, **source_files_tail; + const char *last_filename; + struct source_file *last_source_file; + struct hash_table file_hash; + unsigned num_files; + uint32_t total_filename_len; + + + unsigned total_lines; + + struct SAA *symbols; + struct cv8_symbol *last_sym; + unsigned num_syms[SYMTYPE_MAX]; + unsigned symbol_lengths; + unsigned total_syms; + + struct { + char *name; + size_t namebytes; + } outfile; +}; +struct cv8_state cv8_state; + +static void cv8_init(void) +{ + const uint32_t sect_flags = IMAGE_SCN_MEM_READ | + IMAGE_SCN_MEM_DISCARDABLE | + IMAGE_SCN_CNT_INITIALIZED_DATA | + IMAGE_SCN_ALIGN_1BYTES; + + cv8_state.symbol_sect = coff_make_section(".debug$S", sect_flags); + cv8_state.type_sect = coff_make_section(".debug$T", sect_flags); + + cv8_state.text_offset = 0; + + cv8_state.source_files = NULL; + cv8_state.source_files_tail = &cv8_state.source_files; + + cv8_state.num_files = 0; + cv8_state.total_filename_len = 0; + + cv8_state.total_lines = 0; + + cv8_state.symbols = saa_init(sizeof(struct cv8_symbol)); + cv8_state.last_sym = NULL; +} + +static struct source_file *register_file(const char *filename); +static struct coff_Section *find_section(int32_t segto); + +static void cv8_linenum(const char *filename, int32_t linenumber, + int32_t segto) +{ + struct coff_Section *s; + struct linepair *li; + struct source_file *file; + + file = register_file(filename); + + s = find_section(segto); + if (s == NULL) + return; + + if ((s->flags & IMAGE_SCN_MEM_EXECUTE) == 0) + return; + + li = saa_wstruct(file->lines); + li->file_offset = cv8_state.text_offset; + li->linenumber = linenumber; + + file->num_lines++; + cv8_state.total_lines++; +} + +static void cv8_deflabel(char *name, int32_t segment, int64_t offset, + int is_global, char *special) +{ + struct cv8_symbol *sym; + struct coff_Section *s; + + (void)special; + + s = find_section(segment); + if (s == NULL) + return; + + sym = saa_wstruct(cv8_state.symbols); + + if (s->flags & IMAGE_SCN_MEM_EXECUTE) + sym->type = is_global ? SYMTYPE_PROC : SYMTYPE_CODE; + else + sym->type = is_global ? SYMTYPE_GDATA : SYMTYPE_LDATA; + cv8_state.num_syms[sym->type]++; + cv8_state.total_syms++; + + sym->section = segment; + sym->secrel = offset; + sym->symtype = TYPE_UNREGISTERED; + sym->size = 0; + sym->typeindex = 0; + + sym->name = nasm_strdup(name); + cv8_state.symbol_lengths += strlen(sym->name) + 1; + + if (cv8_state.last_sym && cv8_state.last_sym->section == segment) + cv8_state.last_sym->size = offset - cv8_state.last_sym->secrel; + cv8_state.last_sym = sym; +} + +static void cv8_typevalue(int32_t type) +{ + if (!cv8_state.last_sym) + return; + if (cv8_state.last_sym->symtype != TYPE_UNREGISTERED) + return; + + switch (TYM_TYPE(type)) { + case TY_BYTE: + cv8_state.last_sym->symtype = TYPE_BYTE; + break; + case TY_WORD: + cv8_state.last_sym->symtype = TYPE_WORD; + break; + case TY_DWORD: + cv8_state.last_sym->symtype = TYPE_DWORD; + break; + case TY_QWORD: + cv8_state.last_sym->symtype = TYPE_QUAD; + break; + case TY_FLOAT: + cv8_state.last_sym->symtype = TYPE_REAL32; + break; + case TY_TBYTE: + cv8_state.last_sym->symtype = TYPE_REAL80; + break; + case TY_OWORD: + cv8_state.last_sym->symtype = TYPE_REAL128; + break; + case TY_YWORD: + cv8_state.last_sym->symtype = TYPE_REAL256; + break; + case TY_ZWORD: + cv8_state.last_sym->symtype = TYPE_REAL512; + break; + case TY_UNKNOWN: + break; + case TY_LABEL: + break; + } +} + +static void cv8_output(int type, void *param) +{ + struct coff_DebugInfo *dinfo = param; + + (void)type; + + if (dinfo->section && dinfo->section->name && + !strncmp(dinfo->section->name, ".text", 5)) + cv8_state.text_offset += dinfo->size; +} + +static void build_symbol_table(struct coff_Section *const sect); +static void build_type_table(struct coff_Section *const sect); + +static void cv8_cleanup(void) +{ + struct cv8_symbol *sym; + struct source_file *file, *ftmp; + + struct coff_Section *symbol_sect = coff_sects[cv8_state.symbol_sect]; + struct coff_Section *type_sect = coff_sects[cv8_state.type_sect]; + + cv8_state.outfile.name = nasm_realpath(outname); + cv8_state.outfile.namebytes = strlen(cv8_state.outfile.name) + 1; + + build_symbol_table(symbol_sect); + build_type_table(type_sect); + + list_for_each_safe(file, ftmp, cv8_state.source_files) { + nasm_free(file->fullname); + saa_free(file->lines); + nasm_free(file); + } + hash_free(&cv8_state.file_hash); + + saa_rewind(cv8_state.symbols); + while ((sym = saa_rstruct(cv8_state.symbols))) + nasm_free(sym->name); + saa_free(cv8_state.symbols); + + nasm_free(cv8_state.outfile.name); +} + +/******************************************************************************* + * implementation + ******************************************************************************/ +static void calc_md5(const char *const filename, + unsigned char sum[MD5_HASHBYTES]) +{ + int success = 0; + unsigned char *file_buf; + FILE *f; + MD5_CTX ctx; + + f = pp_input_fopen(filename, NF_BINARY); + if (!f) + goto done; + + file_buf = nasm_zalloc(BUFSIZ); + + MD5Init(&ctx); + while (!feof(f)) { + size_t i = fread(file_buf, 1, BUFSIZ, f); + if (ferror(f)) + goto done_0; + else if (i == 0) + break; + MD5Update(&ctx, file_buf, i); + } + MD5Final(sum, &ctx); + + success = 1; +done_0: + nasm_free(file_buf); + fclose(f); +done: + if (!success) { + nasm_nonfatal("unable to hash file %s. " + "Debug information may be unavailable.", + filename); + } + return; +} + +static struct source_file *register_file(const char *filename) +{ + struct source_file *file; + void **filep; + char *fullpath; + struct hash_insert hi; + + /* + * The common case is that we are invoked with the same filename + * as we were last time. Make this a pointer comparison: this is + * safe because the NASM core code allocates each filename once + * and never frees it. + */ + if (likely(cv8_state.last_filename == filename)) + return cv8_state.last_source_file; + + cv8_state.last_filename = filename; + + filep = hash_find(&cv8_state.file_hash, filename, &hi); + if (likely(filep)) { + file = *filep; + } else { + /* New filename encounter */ + + fullpath = nasm_realpath(filename); + + nasm_new(file); + file->filename = filename; + file->fullname = fullpath; + file->fullnamelen = strlen(fullpath); + file->lines = saa_init(sizeof(struct linepair)); + *cv8_state.source_files_tail = file; + cv8_state.source_files_tail = &file->next; + calc_md5(fullpath, file->md5sum); + + hash_add(&hi, filename, file); + + cv8_state.num_files++; + cv8_state.total_filename_len += file->fullnamelen + 1; + } + + cv8_state.last_source_file = file; + return file; +} + +static struct coff_Section *find_section(int32_t segto) +{ + int i; + + for (i = 0; i < coff_nsects; i++) { + struct coff_Section *sec; + + sec = coff_sects[i]; + if (segto == sec->index) + return sec; + } + return NULL; +} + +static void register_reloc(struct coff_Section *const sect, + char *sym, uint32_t addr, uint16_t type) +{ + struct coff_Reloc *r; + struct coff_Section *sec; + uint32_t i; + + r = *sect->tail = nasm_malloc(sizeof(struct coff_Reloc)); + sect->tail = &r->next; + r->next = NULL; + sect->nrelocs++; + + r->address = addr; + r->symbase = SECT_SYMBOLS; + r->type = type; + + r->symbol = 0; + for (i = 0; i < (uint32_t)coff_nsects; i++) { + sec = coff_sects[i]; + if (!strcmp(sym, sec->name)) { + return; + } + r->symbol += 2; + } + + saa_rewind(coff_syms); + for (i = 0; i < coff_nsyms; i++) { + struct coff_Symbol *s = saa_rstruct(coff_syms); + r->symbol++; + if (s->strpos == -1 && !strcmp(sym, s->name)) { + return; + } else if (s->strpos != -1) { + int res; + char *symname; + + symname = nasm_malloc(s->namlen + 1); + saa_fread(coff_strs, s->strpos-4, symname, s->namlen); + symname[s->namlen] = '\0'; + res = strcmp(sym, symname); + nasm_free(symname); + if (!res) + return; + } + } + nasm_panic("codeview: relocation for unregistered symbol: %s", sym); +} + +static inline void section_write32(struct coff_Section *sect, uint32_t val) +{ + saa_write32(sect->data, val); + sect->len += 4; +} + +static inline void section_write16(struct coff_Section *sect, uint16_t val) +{ + saa_write16(sect->data, val); + sect->len += 2; +} + +static inline void section_write8(struct coff_Section *sect, uint8_t val) +{ + saa_write8(sect->data, val); + sect->len++; +} + +static inline void section_wbytes(struct coff_Section *sect, const void *buf, + size_t len) +{ + saa_wbytes(sect->data, buf, len); + sect->len += len; +} + +static void write_filename_table(struct coff_Section *const sect) +{ + uint32_t field_length; + uint32_t tbl_off = 1; /* offset starts at 1 to skip NULL entry */ + struct source_file *file; + + nasm_assert(cv8_state.source_files != NULL); + nasm_assert(cv8_state.num_files > 0); + nasm_assert(cv8_state.total_filename_len > 0); + + field_length = 1 + cv8_state.total_filename_len; + + section_write32(sect, 0x000000F3); + section_write32(sect, field_length); + + section_write8(sect, 0); + + list_for_each(file, cv8_state.source_files) { + section_wbytes(sect, file->fullname, file->fullnamelen + 1); + file->filetbl_off = tbl_off; + tbl_off += file->fullnamelen + 1; + } +} + +static void write_sourcefile_table(struct coff_Section *const sect) +{ + const uint32_t entry_size = 4 + 2 + MD5_HASHBYTES + 2; + + uint32_t field_length = 0; + uint32_t tbl_off = 0; + struct source_file *file; + + field_length = entry_size * cv8_state.num_files; + + section_write32(sect, 0x000000F4); + section_write32(sect, field_length); + + list_for_each(file, cv8_state.source_files) { + nasm_assert(file->filetbl_off > 0); + section_write32(sect, file->filetbl_off); + section_write16(sect, 0x0110); + section_wbytes(sect, file->md5sum, MD5_HASHBYTES); + section_write16(sect, 0); + + file->sourcetbl_off = tbl_off; + tbl_off += entry_size; + } +} + +static void write_linenumber_table(struct coff_Section *const sect) +{ + const uint32_t file_field_len = 12; + const uint32_t line_field_len = 8; + + int i; + uint32_t field_length = 0; + size_t field_base; + struct source_file *file; + struct coff_Section *s; + + for (i = 0; i < coff_nsects; i++) { + if (!strncmp(coff_sects[i]->name, ".text", 5)) + break; + } + + if (i == coff_nsects) + return; + s = coff_sects[i]; + + field_length = 12; + field_length += (cv8_state.num_files * file_field_len); + field_length += (cv8_state.total_lines * line_field_len); + + section_write32(sect, 0x000000F2); + section_write32(sect, field_length); + + field_base = sect->len; + section_write32(sect, 0); /* SECREL, updated by relocation */ + section_write16(sect, 0); /* SECTION, updated by relocation*/ + section_write16(sect, 0); /* pad */ + section_write32(sect, s->len); + + register_reloc(sect, ".text", field_base, + win64 ? IMAGE_REL_AMD64_SECREL : IMAGE_REL_I386_SECREL); + + register_reloc(sect, ".text", field_base + 4, + win64 ? IMAGE_REL_AMD64_SECTION : IMAGE_REL_I386_SECTION); + + list_for_each(file, cv8_state.source_files) { + struct linepair *li; + + /* source mapping */ + section_write32(sect, file->sourcetbl_off); + section_write32(sect, file->num_lines); + section_write32(sect, file_field_len + (file->num_lines * line_field_len)); + + /* the pairs */ + saa_rewind(file->lines); + while ((li = saa_rstruct(file->lines))) { + section_write32(sect, li->file_offset); + section_write32(sect, li->linenumber |= 0x80000000); + } + } +} + +static uint32_t write_symbolinfo_obj(struct coff_Section *sect) +{ + uint32_t obj_len; + + obj_len = 2 + 4 + cv8_state.outfile.namebytes; + + section_write16(sect, obj_len); + section_write16(sect, 0x1101); + section_write32(sect, 0); /* ASM language */ + section_wbytes(sect, cv8_state.outfile.name, cv8_state.outfile.namebytes); + + return obj_len; +} + +static uint32_t write_symbolinfo_properties(struct coff_Section *sect, + const char *const creator_str) +{ + /* https://github.com/Microsoft/microsoft-pdb/blob/1d60e041/include/cvinfo.h#L3313 */ + uint32_t creator_len; + + creator_len = 2 + 4 + 2 + 3*2 + 3*2 + strlen(creator_str)+1 + 2; + + /* + * We used to use a language ID of 3 for "MASM", since it's closest of the + * options available; however, BinScope from WACK (the Windows Application + * Certification Kit) tests for specific minimum MASM versions and trying to + * match an increasing sequence of random MASM version/build numbers seems + * like a fool's errand. + * + * Instead, use a different language ID (NASM is, after all, not MASM + * syntax) and just write the actual NASM version number. BinScope appears + * to be happy with that. + */ + + section_write16(sect, creator_len); + section_write16(sect, 0x1116); + section_write32(sect, 'N'); /* language: 'N' (0x4e) for "NASM"; flags are 0 */ + if (win64) + section_write16(sect, 0x00D0); /* machine */ + else if (win32) + section_write16(sect, 0x0006); /* machine */ + else + nasm_panic("neither win32 nor win64 are set!"); + section_write16(sect, 0); /* verFEMajor */ + section_write16(sect, 0); /* verFEMinor */ + section_write16(sect, 0); /* verFEBuild */ + + /* BinScope/WACK insist on version >= 8.0.50727 */ + section_write16(sect, NASM_MAJOR_VER); /* verMajor */ + section_write16(sect, NASM_MINOR_VER); /* verMinor */ + section_write16(sect, NASM_SUBMINOR_VER*100 + NASM_PATCHLEVEL_VER); /* verBuild */ + + section_wbytes(sect, creator_str, strlen(creator_str)+1); /* verSt */ + /* + * normally there would be key/value pairs here, but they aren't + * necessary. They are terminated by 2B + */ + section_write16(sect, 0); + + return creator_len; +} + +static uint32_t write_symbolinfo_symbols(struct coff_Section *sect) +{ + uint32_t len = 0, field_len; + uint32_t field_base; + struct cv8_symbol *sym; + + saa_rewind(cv8_state.symbols); + while ((sym = saa_rstruct(cv8_state.symbols))) { + switch (sym->type) { + case SYMTYPE_LDATA: + case SYMTYPE_GDATA: + field_len = 12 + strlen(sym->name) + 1; + len += field_len - 2; + section_write16(sect, field_len); + if (sym->type == SYMTYPE_LDATA) + section_write16(sect, 0x110C); + else + section_write16(sect, 0x110D); + section_write32(sect, sym->symtype); + + field_base = sect->len; + section_write32(sect, 0); /* SECREL */ + section_write16(sect, 0); /* SECTION */ + break; + case SYMTYPE_PROC: + case SYMTYPE_CODE: + field_len = 9 + strlen(sym->name) + 1; + len += field_len - 2; + section_write16(sect, field_len); + section_write16(sect, 0x1105); + + field_base = sect->len; + section_write32(sect, 0); /* SECREL */ + section_write16(sect, 0); /* SECTION */ + section_write8(sect, 0); /* FLAG */ + break; + default: + nasm_panic("unknown symbol type"); + } + + section_wbytes(sect, sym->name, strlen(sym->name) + 1); + + register_reloc(sect, sym->name, field_base, + win64 ? IMAGE_REL_AMD64_SECREL : + IMAGE_REL_I386_SECREL); + register_reloc(sect, sym->name, field_base + 4, + win64 ? IMAGE_REL_AMD64_SECTION : + IMAGE_REL_I386_SECTION); + } + + return len; +} + +static void write_symbolinfo_table(struct coff_Section *const sect) +{ + static const char creator_str[] = "The Netwide Assembler " NASM_VER; + uint32_t obj_length, creator_length, sym_length; + uint32_t field_length = 0, out_len; + + nasm_assert(cv8_state.outfile.namebytes); + + /* signature, language, outfile NULL */ + obj_length = 2 + 4 + cv8_state.outfile.namebytes; + creator_length = 2 + 4 + 2 + 3*2 + 3*2 + strlen(creator_str)+1 + 2; + + sym_length = ( cv8_state.num_syms[SYMTYPE_CODE] * 7) + + ( cv8_state.num_syms[SYMTYPE_PROC] * 7) + + ( cv8_state.num_syms[SYMTYPE_LDATA] * 10) + + ( cv8_state.num_syms[SYMTYPE_GDATA] * 10) + + cv8_state.symbol_lengths; + + field_length = 2 + obj_length + + 2 + creator_length + + (4 * cv8_state.total_syms) + sym_length; + + section_write32(sect, 0x000000F1); + section_write32(sect, field_length); + + /* for sub fields, length proceeds type */ + + out_len = write_symbolinfo_obj(sect); + nasm_assert(out_len == obj_length); + + out_len = write_symbolinfo_properties(sect, creator_str); + nasm_assert(out_len == creator_length); + + out_len = write_symbolinfo_symbols(sect); + nasm_assert(out_len == sym_length); +} + +static inline void align4_table(struct coff_Section *const sect) +{ + unsigned diff; + uint32_t zero = 0; + struct SAA *data = sect->data; + + if (data->wptr % 4 == 0) + return; + + diff = 4 - (data->wptr % 4); + if (diff) + section_wbytes(sect, &zero, diff); +} + +static void build_symbol_table(struct coff_Section *const sect) +{ + section_write32(sect, 0x00000004); + + write_filename_table(sect); + align4_table(sect); + write_sourcefile_table(sect); + align4_table(sect); + write_linenumber_table(sect); + align4_table(sect); + write_symbolinfo_table(sect); + align4_table(sect); +} + +static void build_type_table(struct coff_Section *const sect) +{ + uint32_t field_len; + uint32_t typeindex = 0x1000; + uint32_t idx_arglist; + + section_write32(sect, 0x00000004); + + /* empty argument list type */ + field_len = 2 + 4; + section_write16(sect, field_len); + section_write16(sect, 0x1201); /* ARGLIST */ + section_write32(sect, 0); /* num params */ + idx_arglist = typeindex++; + + /* procedure type: void proc(void) */ + field_len = 2 + 4 + 1 + 1 + 2 + 4; + section_write16(sect, field_len); + section_write16(sect, 0x1008); /* PROC type */ + + section_write32(sect, 0x00000003); /* return type VOID */ + section_write8(sect, 0); /* calling convention (default) */ + section_write8(sect, 0); /* function attributes */ + section_write16(sect, 0); /* # params */ + section_write32(sect, idx_arglist); /* argument list type */ + /* idx_voidfunc = typeindex++; */ +} -- cgit v1.2.3