aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/yasm/modules/dbgfmts/codeview
diff options
context:
space:
mode:
authorsomov <somov@yandex-team.ru>2022-02-10 16:45:47 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:47 +0300
commita5950576e397b1909261050b8c7da16db58f10b1 (patch)
tree7ba7677f6a4c3e19e2cefab34d16df2c8963b4d4 /contrib/tools/yasm/modules/dbgfmts/codeview
parent81eddc8c0b55990194e112b02d127b87d54164a9 (diff)
downloadydb-a5950576e397b1909261050b8c7da16db58f10b1.tar.gz
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/yasm/modules/dbgfmts/codeview')
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c214
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.h116
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/codeview/cv-symline.c2204
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/codeview/cv-type.c1556
4 files changed, 2045 insertions, 2045 deletions
diff --git a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c
index 9b06fe3495..285478dbb6 100644
--- a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c
+++ b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c
@@ -1,107 +1,107 @@
-/*
- * CodeView debugging formats implementation for Yasm
- *
- * Copyright (C) 2006-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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 AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
- */
-#include <util.h>
-
-#include <libyasm.h>
-
-#include "cv-dbgfmt.h"
-
-yasm_dbgfmt_module yasm_cv8_LTX_dbgfmt;
-
-
-static /*@null@*/ /*@only@*/ yasm_dbgfmt *
-cv_dbgfmt_create(yasm_object *object, yasm_dbgfmt_module *module, int version)
-{
- yasm_dbgfmt_cv *dbgfmt_cv = yasm_xmalloc(sizeof(yasm_dbgfmt_cv));
- size_t i;
-
- dbgfmt_cv->dbgfmt.module = module;
-
- dbgfmt_cv->filenames_allocated = 32;
- dbgfmt_cv->filenames_size = 0;
- dbgfmt_cv->filenames =
- yasm_xmalloc(sizeof(cv_filename)*dbgfmt_cv->filenames_allocated);
- for (i=0; i<dbgfmt_cv->filenames_allocated; i++) {
- dbgfmt_cv->filenames[i].pathname = NULL;
- dbgfmt_cv->filenames[i].filename = NULL;
- dbgfmt_cv->filenames[i].str_off = 0;
- dbgfmt_cv->filenames[i].info_off = 0;
- }
-
- dbgfmt_cv->version = version;
-
- return (yasm_dbgfmt *)dbgfmt_cv;
-}
-
-static /*@null@*/ /*@only@*/ yasm_dbgfmt *
-cv8_dbgfmt_create(yasm_object *object)
-{
- return cv_dbgfmt_create(object, &yasm_cv8_LTX_dbgfmt, 8);
-}
-
-static void
-cv_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
-{
- yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)dbgfmt;
- size_t i;
- for (i=0; i<dbgfmt_cv->filenames_size; i++) {
- if (dbgfmt_cv->filenames[i].pathname)
- yasm_xfree(dbgfmt_cv->filenames[i].pathname);
- }
- yasm_xfree(dbgfmt_cv->filenames);
- yasm_xfree(dbgfmt);
-}
-
-/* Add a bytecode to a section, updating offset on insertion;
- * no optimization necessary.
- */
-yasm_bytecode *
-yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc)
-{
- yasm_bytecode *precbc = yasm_section_bcs_last(sect);
- bc->offset = yasm_bc_next_offset(precbc);
- yasm_section_bcs_append(sect, bc);
- return precbc;
-}
-
-static void
-cv_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
-{
- yasm_cv__generate_symline(object, linemap, errwarns);
- yasm_cv__generate_type(object);
-}
-
-/* Define dbgfmt structure -- see dbgfmt.h for details */
-yasm_dbgfmt_module yasm_cv8_LTX_dbgfmt = {
- "CodeView debugging format for VC8",
- "cv8",
- NULL, /* no directives */
- cv8_dbgfmt_create,
- cv_dbgfmt_destroy,
- cv_dbgfmt_generate
-};
+/*
+ * CodeView debugging formats implementation for Yasm
+ *
+ * Copyright (C) 2006-2007 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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 AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
+ */
+#include <util.h>
+
+#include <libyasm.h>
+
+#include "cv-dbgfmt.h"
+
+yasm_dbgfmt_module yasm_cv8_LTX_dbgfmt;
+
+
+static /*@null@*/ /*@only@*/ yasm_dbgfmt *
+cv_dbgfmt_create(yasm_object *object, yasm_dbgfmt_module *module, int version)
+{
+ yasm_dbgfmt_cv *dbgfmt_cv = yasm_xmalloc(sizeof(yasm_dbgfmt_cv));
+ size_t i;
+
+ dbgfmt_cv->dbgfmt.module = module;
+
+ dbgfmt_cv->filenames_allocated = 32;
+ dbgfmt_cv->filenames_size = 0;
+ dbgfmt_cv->filenames =
+ yasm_xmalloc(sizeof(cv_filename)*dbgfmt_cv->filenames_allocated);
+ for (i=0; i<dbgfmt_cv->filenames_allocated; i++) {
+ dbgfmt_cv->filenames[i].pathname = NULL;
+ dbgfmt_cv->filenames[i].filename = NULL;
+ dbgfmt_cv->filenames[i].str_off = 0;
+ dbgfmt_cv->filenames[i].info_off = 0;
+ }
+
+ dbgfmt_cv->version = version;
+
+ return (yasm_dbgfmt *)dbgfmt_cv;
+}
+
+static /*@null@*/ /*@only@*/ yasm_dbgfmt *
+cv8_dbgfmt_create(yasm_object *object)
+{
+ return cv_dbgfmt_create(object, &yasm_cv8_LTX_dbgfmt, 8);
+}
+
+static void
+cv_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
+{
+ yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)dbgfmt;
+ size_t i;
+ for (i=0; i<dbgfmt_cv->filenames_size; i++) {
+ if (dbgfmt_cv->filenames[i].pathname)
+ yasm_xfree(dbgfmt_cv->filenames[i].pathname);
+ }
+ yasm_xfree(dbgfmt_cv->filenames);
+ yasm_xfree(dbgfmt);
+}
+
+/* Add a bytecode to a section, updating offset on insertion;
+ * no optimization necessary.
+ */
+yasm_bytecode *
+yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc)
+{
+ yasm_bytecode *precbc = yasm_section_bcs_last(sect);
+ bc->offset = yasm_bc_next_offset(precbc);
+ yasm_section_bcs_append(sect, bc);
+ return precbc;
+}
+
+static void
+cv_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ yasm_cv__generate_symline(object, linemap, errwarns);
+ yasm_cv__generate_type(object);
+}
+
+/* Define dbgfmt structure -- see dbgfmt.h for details */
+yasm_dbgfmt_module yasm_cv8_LTX_dbgfmt = {
+ "CodeView debugging format for VC8",
+ "cv8",
+ NULL, /* no directives */
+ cv8_dbgfmt_create,
+ cv_dbgfmt_destroy,
+ cv_dbgfmt_generate
+};
diff --git a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.h b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.h
index 134b0b885b..d3bbb024e0 100644
--- a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.h
+++ b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.h
@@ -1,58 +1,58 @@
-/*
- * CodeView debugging formats implementation for Yasm
- *
- * Copyright (C) 2006-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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 AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
- */
-#ifndef YASM_CV_DBGFMT_H
-#define YASM_CV_DBGFMT_H
-
-typedef struct {
- char *pathname; /* full pathname (drive+basepath+filename) */
- char *filename; /* filename as yasm knows it internally */
- unsigned long str_off; /* offset into pathname string table */
- unsigned long info_off; /* offset into source info table */
- unsigned char digest[16]; /* MD5 digest of source file */
-} cv_filename;
-
-/* Global data */
-typedef struct yasm_dbgfmt_cv {
- yasm_dbgfmt_base dbgfmt; /* base structure */
-
- cv_filename *filenames;
- size_t filenames_size;
- size_t filenames_allocated;
-
- int version;
-} yasm_dbgfmt_cv;
-
-yasm_bytecode *yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc);
-
-/* Symbol/Line number functions */
-yasm_section *yasm_cv__generate_symline
- (yasm_object *object, yasm_linemap *linemap, yasm_errwarns *errwarns);
-
-/* Type functions */
-yasm_section *yasm_cv__generate_type(yasm_object *object);
-
-#endif
+/*
+ * CodeView debugging formats implementation for Yasm
+ *
+ * Copyright (C) 2006-2007 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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 AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
+ */
+#ifndef YASM_CV_DBGFMT_H
+#define YASM_CV_DBGFMT_H
+
+typedef struct {
+ char *pathname; /* full pathname (drive+basepath+filename) */
+ char *filename; /* filename as yasm knows it internally */
+ unsigned long str_off; /* offset into pathname string table */
+ unsigned long info_off; /* offset into source info table */
+ unsigned char digest[16]; /* MD5 digest of source file */
+} cv_filename;
+
+/* Global data */
+typedef struct yasm_dbgfmt_cv {
+ yasm_dbgfmt_base dbgfmt; /* base structure */
+
+ cv_filename *filenames;
+ size_t filenames_size;
+ size_t filenames_allocated;
+
+ int version;
+} yasm_dbgfmt_cv;
+
+yasm_bytecode *yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc);
+
+/* Symbol/Line number functions */
+yasm_section *yasm_cv__generate_symline
+ (yasm_object *object, yasm_linemap *linemap, yasm_errwarns *errwarns);
+
+/* Type functions */
+yasm_section *yasm_cv__generate_type(yasm_object *object);
+
+#endif
diff --git a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-symline.c b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-symline.c
index 8d7030221f..396def57e2 100644
--- a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-symline.c
+++ b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-symline.c
@@ -1,1102 +1,1102 @@
-/*
- * CodeView debugging format - symbol and line information
- *
- * Copyright (C) 2006-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the author nor the names of other contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
- */
-#include <util.h>
-
-#include <libyasm.h>
-
-#include "cv-dbgfmt.h"
-
-enum cv8_symheadtype {
- CV8_DEBUG_SYMS = 0xF1, /* CV5 symbol information */
- CV8_LINE_NUMS = 0xF2, /* line numbers for a section */
- CV8_FILE_STRTAB = 0xF3, /* filename string table */
- CV8_FILE_INFO = 0xF4 /* source file info */
-};
-
-enum cv_symtype {
- /* Non-modal Symbols */
- CV_S_COMPILE = 0x0001, /* Compile Flag */
- CV_S_REGISTER = 0x0002, /* Register */
- CV_S_CONSTANT = 0x0003, /* Constant */
- CV_S_UDT = 0x0004, /* User-defined Type */
- CV_S_SSEARCH = 0x0005, /* Start Search */
- CV_S_END = 0x0006, /* End of Block */
- CV_S_SKIP = 0x0007, /* Skip Record */
- CV_S_OBJNAME = 0x0009, /* Object File Name */
- CV_S_ENDARG = 0x000a, /* End of Arguments */
- CV_S_COBOLUDT = 0x000b, /* COBOL User-defined Type */
- CV_S_MANYREG = 0x000c, /* Many Registers */
- CV_S_RETURN = 0x000d, /* Function Return */
- CV_S_ENTRYTHIS = 0x000e, /* "this" at Method Entry */
-
- /* Symbols for 16:16 Segmented Architectures */
- CV_S_BPREL16 = 0x0100, /* BP Relative 16:16 */
- CV_S_LDATA16 = 0x0101, /* Local Data 16:16 */
- CV_S_GDATA16 = 0x0102, /* Global Data Symbol 16:16 */
- CV_S_PUB16 = 0x0103, /* Public Symbol 16:16 */
- CV_S_LPROC16 = 0x0104, /* Local Start 16:16 */
- CV_S_GPROC16 = 0x0105, /* Global Start 16:16 */
- CV_S_THUNK16 = 0x0106, /* Thunk Start 16:16 */
- CV_S_BLOCK16 = 0x0107, /* Block Start 16:16 */
- CV_S_WITH16 = 0x0108, /* With Start 16:16 */
- CV_S_LABEL16 = 0x0109, /* Code Label 16:16 */
- CV_S_CEXMODEL16 = 0x0110, /* Change Execution Model 16:16 */
- CV_S_VFTPATH16 = 0x010b, /* Virtual Function Table Path 16:16 */
- CV_S_REGREL16 = 0x010c, /* Register Relative 16:16 */
-
- /* Symbols for 16:32 Segmented Architectures */
- CV_S_BPREL32 = 0x0200, /* BP Relative 16:32 */
- CV_S_LDATA32 = 0x0201, /* Local Data 16:32 */
- CV_S_GDATA32 = 0x0202, /* Global Data Symbol 16:32 */
- CV_S_PUB32 = 0x0203, /* Public Symbol 16:32 */
- CV_S_LPROC32 = 0x0204, /* Local Start 16:32 */
- CV_S_GPROC32 = 0x0205, /* Global Start 16:32 */
- CV_S_THUNK32 = 0x0206, /* Thunk Start 16:32 */
- CV_S_BLOCK32 = 0x0207, /* Block Start 16:32 */
- CV_S_WITH32 = 0x0208, /* With Start 16:32 */
- CV_S_LABEL32 = 0x0209, /* Code Label 16:32 */
- CV_S_CEXMODEL32 = 0x0210, /* Change Execution Model 16:32 */
- CV_S_VFTPATH32 = 0x020b, /* Virtual Function Table Path 16:32 */
- CV_S_REGREL32 = 0x020c, /* Register Relative 16:32 */
- CV_S_LTHREAD32 = 0x020d, /* Local Thread Storage 16:32 */
- CV_S_GTHREAD32 = 0x020e, /* Global Thread Storage 16:32 */
-
- /* Symbols for MIPS */
- CV_S_LPROCMIPS = 0x0300, /* Local procedure start MIPS */
- CV_S_GPROCMIPS = 0x0301, /* Global procedure start MIPS */
-
- /* Symbols for CV8 - strings are 0 terminated rather than length-prefix.
- * Incomplete and unofficial.
- */
- CV8_S_OBJNAME = 0x1101, /* Object File Name */
- CV8_S_LABEL32 = 0x1105, /* Code Label 16:32 */
- CV8_S_LDATA32 = 0x110c, /* Local Data 16:32 */
- CV8_S_GDATA32 = 0x110d, /* Global Data 16:32 */
- CV8_S_LPROC32 = 0x1110, /* Local Start 16:32 */
- CV8_S_COMPILE = 0x1116 /* Compile Flag */
-};
-
-typedef struct cv8_symhead {
- enum cv8_symheadtype type;
- yasm_bytecode *start_prevbc;
- yasm_bytecode *end_prevbc;
- int first; /* nonzero if first symhead in section */
-} cv8_symhead;
-
-typedef struct cv8_fileinfo {
- const cv_filename *fn;
-} cv8_fileinfo;
-
-/* Note: each line number group is associated with a file AND a section */
-typedef struct cv8_linepair {
- unsigned long offset;
- unsigned long line;
-} cv8_linepair;
-
-/* Decrease linked list overhead a bit doing it this way */
-typedef struct cv8_lineset {
- STAILQ_ENTRY(cv8_lineset) link;
- cv8_linepair pairs[126];
- size_t num_pairs;
-} cv8_lineset;
-
-/* Note: Due to line number sorting requirements (by section offset it seems)
- * one file may need more than one record per section. */
-typedef struct cv8_lineinfo {
- STAILQ_ENTRY(cv8_lineinfo) link;
- const cv_filename *fn; /* filename associated with line numbers */
- yasm_section *sect; /* section line numbers are for */
- yasm_symrec *sectsym; /* symbol for beginning of sect */
- unsigned long num_linenums;
- int first_in_sect; /* First lineinfo for this section. */
- STAILQ_HEAD(cv8_lineset_head, cv8_lineset) linesets;
-} cv8_lineinfo;
-
-/* Symbols use a bit of meta-programming to encode formats: each character
- * of format represents the output generated, as follows:
- * 'b' : 1 byte value (integer)
- * 'h' : 2 byte value (integer)
- * 'w' : 4 byte value (integer)
- * 'Y' : symrec SECREL+SECTION (pointer)
- * 'T' : type index (integer)
- * 'S' : length-prefixed string (pointer)
- * 'Z' : 0-terminated string (pointer)
- */
-typedef struct cv_sym {
- enum cv_symtype type;
- const char *format;
- union {
- unsigned long i;
- void *p;
- } args[10];
-} cv_sym;
-
-/* Bytecode callback function prototypes */
-static void cv8_symhead_bc_destroy(void *contents);
-static void cv8_symhead_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int cv8_symhead_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int cv8_symhead_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static void cv8_fileinfo_bc_destroy(void *contents);
-static void cv8_fileinfo_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int cv8_fileinfo_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int cv8_fileinfo_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static void cv8_lineinfo_bc_destroy(void *contents);
-static void cv8_lineinfo_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int cv8_lineinfo_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int cv8_lineinfo_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static void cv_sym_bc_destroy(void *contents);
-static void cv_sym_bc_print(const void *contents, FILE *f, int indent_level);
-static int cv_sym_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int cv_sym_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- /*@null@*/ yasm_output_reloc_func output_reloc);
-
-/* Bytecode callback structures */
-static const yasm_bytecode_callback cv8_symhead_bc_callback = {
- cv8_symhead_bc_destroy,
- cv8_symhead_bc_print,
- yasm_bc_finalize_common,
- NULL,
- cv8_symhead_bc_calc_len,
- yasm_bc_expand_common,
- cv8_symhead_bc_tobytes,
- 0
-};
-
-static const yasm_bytecode_callback cv8_fileinfo_bc_callback = {
- cv8_fileinfo_bc_destroy,
- cv8_fileinfo_bc_print,
- yasm_bc_finalize_common,
- NULL,
- cv8_fileinfo_bc_calc_len,
- yasm_bc_expand_common,
- cv8_fileinfo_bc_tobytes,
- 0
-};
-
-static const yasm_bytecode_callback cv8_lineinfo_bc_callback = {
- cv8_lineinfo_bc_destroy,
- cv8_lineinfo_bc_print,
- yasm_bc_finalize_common,
- NULL,
- cv8_lineinfo_bc_calc_len,
- yasm_bc_expand_common,
- cv8_lineinfo_bc_tobytes,
- 0
-};
-
-static const yasm_bytecode_callback cv_sym_bc_callback = {
- cv_sym_bc_destroy,
- cv_sym_bc_print,
- yasm_bc_finalize_common,
- NULL,
- cv_sym_bc_calc_len,
- yasm_bc_expand_common,
- cv_sym_bc_tobytes,
- 0
-};
-
-static cv8_symhead *cv8_add_symhead(yasm_section *sect, unsigned long type,
- int first);
-static void cv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc);
-
-static yasm_bytecode *cv8_add_fileinfo
- (yasm_section *sect, const cv_filename *fn);
-
-static unsigned long cv_sym_size(const cv_sym *cvs);
-
-
-static cv_sym *
-cv8_add_sym_objname(yasm_section *sect, /*@keep@*/ char *objname)
-{
- yasm_bytecode *bc;
- cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
- cvs->type = CV8_S_OBJNAME;
- cvs->format = "wZ";
- cvs->args[0].i = 0; /* signature (0=asm) */
- cvs->args[1].p = objname; /* object filename */
-
- bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
- bc->len = cv_sym_size(cvs);
- yasm_cv__append_bc(sect, bc);
- return cvs;
-}
-
-static cv_sym *
-cv8_add_sym_compile(yasm_object *object, yasm_section *sect,
- /*@keep@*/ char *creator)
-{
- yasm_bytecode *bc;
- cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
- cvs->type = CV8_S_COMPILE;
- cvs->format = "wwwwZh";
- cvs->args[0].i = 3; /* language (3=Masm) */
-
- /* target processor; 0xD0 = AMD64 */
- if (strcmp(yasm_arch_keyword(object->arch), "x86") == 0) {
- if (strcmp(yasm_arch_get_machine(object->arch), "amd64") == 0)
- cvs->args[1].i = 0xD0;
- else
- cvs->args[1].i = 0x6; /* 686, FIXME */
- } else
- cvs->args[1].i = 0; /* XXX: unknown */
-
- cvs->args[2].i = 0; /* flags (assume 0 for now) */
- cvs->args[3].i = 0; /* creator version number (assume 0 for now) */
- cvs->args[4].p = creator; /* creator string */
- cvs->args[5].i = 0; /* no pairs of key/value */
-
- bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
- bc->len = cv_sym_size(cvs);
- yasm_cv__append_bc(sect, bc);
- return cvs;
-}
-
-static cv_sym *
-cv8_add_sym_label(yasm_section *sect, yasm_symrec *sym)
-{
- yasm_bytecode *bc;
- cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
- cvs->type = CV8_S_LABEL32;
- cvs->format = "YbZ";
- cvs->args[0].p = sym; /* symrec for label */
- cvs->args[1].i = 0; /* flags (assume 0 for now) */
- cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
-
- bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
- bc->len = cv_sym_size(cvs);
- yasm_cv__append_bc(sect, bc);
- return cvs;
-}
-
-static cv_sym *
-cv8_add_sym_data(yasm_section *sect, unsigned long type, yasm_symrec *sym,
- int is_global)
-{
- yasm_bytecode *bc;
- cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
- cvs->type = is_global ? CV8_S_GDATA32 : CV8_S_LDATA32;
- cvs->format = "wYZ";
- cvs->args[0].i = type; /* type index */
- cvs->args[1].p = sym; /* symrec for label */
- cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
-
- bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
- bc->len = cv_sym_size(cvs);
- yasm_cv__append_bc(sect, bc);
- return cvs;
-}
-
-static size_t
-cv_dbgfmt_add_file(yasm_dbgfmt_cv *dbgfmt_cv, size_t filenum,
- const char *filename)
-{
- char *pathname;
- size_t i;
- yasm_md5_context context;
- FILE *f;
- unsigned char *buf;
- size_t len;
-
- /* Put the filename into the filename table */
- if (filenum == 0) {
- /* Look to see if we already have that filename in the table */
- for (; filenum<dbgfmt_cv->filenames_size; filenum++) {
- if (!dbgfmt_cv->filenames[filenum].filename ||
- strcmp(dbgfmt_cv->filenames[filenum].filename, filename) == 0)
- break;
- }
- } else
- filenum--; /* array index is 0-based */
-
- /* Realloc table if necessary */
- if (filenum >= dbgfmt_cv->filenames_allocated) {
- size_t old_allocated = dbgfmt_cv->filenames_allocated;
- dbgfmt_cv->filenames_allocated = filenum+32;
- dbgfmt_cv->filenames = yasm_xrealloc(dbgfmt_cv->filenames,
- sizeof(cv_filename)*dbgfmt_cv->filenames_allocated);
- for (i=old_allocated; i<dbgfmt_cv->filenames_allocated; i++) {
- dbgfmt_cv->filenames[i].pathname = NULL;
- dbgfmt_cv->filenames[i].filename = NULL;
- dbgfmt_cv->filenames[i].str_off = 0;
- dbgfmt_cv->filenames[i].info_off = 0;
- }
- }
-
- /* Calculate MD5 checksum of file */
- buf = yasm_xmalloc(1024);
- yasm_md5_init(&context);
- f = fopen(filename, "rb");
- if (!f)
- yasm__fatal(N_("codeview: could not open source file"));
- while ((len = fread(buf, 1, 1024, f)) > 0)
- yasm_md5_update(&context, buf, (unsigned long)len);
- yasm_md5_final(dbgfmt_cv->filenames[filenum].digest, &context);
- fclose(f);
- yasm_xfree(buf);
-
- /* Actually save in table */
- if (dbgfmt_cv->filenames[filenum].pathname)
- yasm_xfree(dbgfmt_cv->filenames[filenum].pathname);
- if (dbgfmt_cv->filenames[filenum].filename)
- yasm_xfree(dbgfmt_cv->filenames[filenum].filename);
-
- pathname = yasm__abspath(filename);
- dbgfmt_cv->filenames[filenum].pathname = pathname;
- dbgfmt_cv->filenames[filenum].filename = yasm__xstrdup(filename);
-
- /* Update table size */
- if (filenum >= dbgfmt_cv->filenames_size)
- dbgfmt_cv->filenames_size = filenum + 1;
-
- return filenum;
-}
-
-static yasm_bytecode *
-cv_append_str(yasm_section *sect, const char *str)
-{
- yasm_datavalhead dvs;
- yasm_bytecode *bc;
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str),
- strlen(str)));
- bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0);
- yasm_bc_finalize(bc, yasm_cv__append_bc(sect, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
- return bc;
-}
-
-typedef struct cv_line_info {
- yasm_section *debug_symline;
- yasm_object *object;
- yasm_dbgfmt_cv *dbgfmt_cv;
- yasm_linemap *linemap;
- yasm_errwarns *errwarns;
- unsigned int num_lineinfos;
- STAILQ_HEAD(cv8_lineinfo_head, cv8_lineinfo) cv8_lineinfos;
- /*@null@*/ cv8_lineinfo *cv8_cur_li;
- /*@null@*/ cv8_lineset *cv8_cur_ls;
-} cv_line_info;
-
-static int
-cv_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
-{
- cv_line_info *info = (cv_line_info *)d;
- yasm_dbgfmt_cv *dbgfmt_cv = info->dbgfmt_cv;
- size_t i;
- const char *filename;
- unsigned long line;
- /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
- yasm_section *sect = yasm_bc_get_section(bc);
-
- if (nextbc && bc->offset == nextbc->offset)
- return 0;
-
- yasm_linemap_lookup(info->linemap, bc->line, &filename, &line);
-
- if (!info->cv8_cur_li
- || strcmp(filename, info->cv8_cur_li->fn->filename) != 0) {
- yasm_bytecode *sectbc;
- char symname[8];
- int first_in_sect = !info->cv8_cur_li;
-
- /* Find file */
- for (i=0; i<dbgfmt_cv->filenames_size; i++) {
- if (strcmp(filename, dbgfmt_cv->filenames[i].filename) == 0)
- break;
- }
- if (i >= dbgfmt_cv->filenames_size)
- yasm_internal_error(N_("could not find filename in table"));
-
- /* and create new lineinfo structure */
- info->cv8_cur_li = yasm_xmalloc(sizeof(cv8_lineinfo));
- info->cv8_cur_li->fn = &dbgfmt_cv->filenames[i];
- info->cv8_cur_li->sect = sect;
- info->cv8_cur_li->first_in_sect = first_in_sect;
- sectbc = yasm_section_bcs_first(sect);
- if (sectbc->symrecs && sectbc->symrecs[0])
- info->cv8_cur_li->sectsym = sectbc->symrecs[0];
- else {
- sprintf(symname, ".%06u", info->num_lineinfos++);
- info->cv8_cur_li->sectsym =
- yasm_symtab_define_label(info->object->symtab, symname, sectbc,
- 1, 0);
- }
- info->cv8_cur_li->num_linenums = 0;
- STAILQ_INIT(&info->cv8_cur_li->linesets);
- STAILQ_INSERT_TAIL(&info->cv8_lineinfos, info->cv8_cur_li, link);
- info->cv8_cur_ls = NULL;
- }
-
- /* build new lineset if necessary */
- if (!info->cv8_cur_ls || info->cv8_cur_ls->num_pairs >= 126) {
- info->cv8_cur_ls = yasm_xmalloc(sizeof(cv8_lineset));
- info->cv8_cur_ls->num_pairs = 0;
- STAILQ_INSERT_TAIL(&info->cv8_cur_li->linesets, info->cv8_cur_ls, link);
- }
-
- /* add linepair for this bytecode */
- info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].offset = bc->offset;
- info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].line =
- 0x80000000 | line;
- info->cv8_cur_ls->num_pairs++;
- info->cv8_cur_li->num_linenums++;
-
- return 0;
-}
-
-static int
-cv_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
-{
- cv_line_info *info = (cv_line_info *)d;
-
- if (!yasm_section_is_code(sect))
- return 0; /* not code, so no line data for this section */
-
- info->cv8_cur_li = NULL;
- info->cv8_cur_ls = NULL;
-
- yasm_section_bcs_traverse(sect, info->errwarns, info, cv_generate_line_bc);
-
- return 0;
-}
-
-static int
-cv_generate_filename(const char *filename, void *d)
-{
- cv_dbgfmt_add_file((yasm_dbgfmt_cv *)d, 0, filename);
- return 0;
-}
-
-static int
-cv_generate_sym(yasm_symrec *sym, void *d)
-{
- cv_line_info *info = (cv_line_info *)d;
- yasm_bytecode *precbc;
- const char *name = yasm_symrec_get_name(sym);
-
- /* only care about labels (for now). Don't put in symbols starting with
- * ".", as these are typically internally generated ones (like section
- * symbols).
- */
- if (name[0] == '.' || !yasm_symrec_get_label(sym, &precbc))
- return 0;
-
- /* TODO: add data types; until then, just mark everything as UBYTE */
- if (yasm_section_is_code(yasm_bc_get_section(precbc)))
- cv8_add_sym_label(info->debug_symline, sym);
- else
- cv8_add_sym_data(info->debug_symline, 0x20, sym,
- yasm_symrec_get_visibility(sym) & YASM_SYM_GLOBAL?1:0);
- return 0;
-}
-
-yasm_section *
-yasm_cv__generate_symline(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
-{
- yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)object->dbgfmt;
- cv_line_info info;
- int new;
- size_t i;
- cv8_symhead *head;
- cv8_lineinfo *li;
- yasm_bytecode *bc;
- unsigned long off;
-
- /* Generate filenames based on linemap */
- yasm_linemap_traverse_filenames(linemap, dbgfmt_cv,
- cv_generate_filename);
-
- info.object = object;
- info.dbgfmt_cv = dbgfmt_cv;
- info.linemap = linemap;
- info.errwarns = errwarns;
- info.debug_symline =
- yasm_object_get_general(object, ".debug$S", 1, 0, 0, &new, 0);
- info.num_lineinfos = 0;
- STAILQ_INIT(&info.cv8_lineinfos);
- info.cv8_cur_li = NULL;
- info.cv8_cur_ls = NULL;
-
- /* source filenames string table */
- head = cv8_add_symhead(info.debug_symline, CV8_FILE_STRTAB, 1);
- cv_append_str(info.debug_symline, "");
- off = 1;
- for (i=0; i<dbgfmt_cv->filenames_size; i++) {
- if (!dbgfmt_cv->filenames[i].pathname) {
- yasm_error_set(YASM_ERROR_GENERAL,
- N_("codeview file number %d unassigned"), i+1);
- yasm_errwarn_propagate(errwarns, 0);
- continue;
- }
- bc = cv_append_str(info.debug_symline,
- dbgfmt_cv->filenames[i].pathname);
- dbgfmt_cv->filenames[i].str_off = off;
- off += bc->len;
- }
- cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
-
- /* Align 4 */
- bc = yasm_bc_create_align
- (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
- NULL, NULL, NULL, 0);
- yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-
- /* source file info table */
- head = cv8_add_symhead(info.debug_symline, CV8_FILE_INFO, 0);
- off = 0;
- for (i=0; i<dbgfmt_cv->filenames_size; i++) {
- if (!dbgfmt_cv->filenames[i].pathname)
- continue;
- bc = cv8_add_fileinfo(info.debug_symline, &dbgfmt_cv->filenames[i]);
- dbgfmt_cv->filenames[i].info_off = off;
- off += bc->len;
- }
- cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
-
- /* Already aligned 4 */
-
- /* Generate line numbers for sections */
- yasm_object_sections_traverse(object, (void *)&info,
- cv_generate_line_section);
-
- /* Output line numbers for sections */
- head = NULL;
- STAILQ_FOREACH(li, &info.cv8_lineinfos, link) {
- if (li->first_in_sect) {
- if (head)
- cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
- head = cv8_add_symhead(info.debug_symline, CV8_LINE_NUMS, 0);
- }
- bc = yasm_bc_create_common(&cv8_lineinfo_bc_callback, li, 0);
- bc->len = (li->first_in_sect ? 24 : 12) + li->num_linenums*8;
- yasm_cv__append_bc(info.debug_symline, bc);
- }
- if (head)
- cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
-
- /* Already aligned 4 */
-
- /* Output debugging symbols */
- head = cv8_add_symhead(info.debug_symline, CV8_DEBUG_SYMS, 0);
- /* add object and compile flag first */
- cv8_add_sym_objname(info.debug_symline,
- yasm__abspath(object->obj_filename));
- if (getenv("YASM_TEST_SUITE"))
- cv8_add_sym_compile(object, info.debug_symline,
- yasm__xstrdup("yasm HEAD"));
- else
- cv8_add_sym_compile(object, info.debug_symline,
- yasm__xstrdup(PACKAGE_STRING));
- /* then iterate through symbol table */
- yasm_symtab_traverse(object->symtab, &info, cv_generate_sym);
- cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
-
- /* Align 4 at end */
- bc = yasm_bc_create_align
- (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
- NULL, NULL, NULL, 0);
- yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-
- return info.debug_symline;
-}
-
-static void
-cv_out_sym(yasm_symrec *sym, unsigned long off, yasm_bytecode *bc,
- unsigned char **bufp, void *d, yasm_output_value_func output_value)
-{
- yasm_value val;
-
- /* sym in its section */
- yasm_value_init_sym(&val, sym, 32);
- val.section_rel = 1;
- output_value(&val, *bufp, 4, off, bc, 0, d);
- *bufp += 4;
-
- /* section index */
- yasm_value_init_sym(&val, sym, 16);
- val.seg_of = 1;
- output_value(&val, *bufp, 2, off+4, bc, 0, d);
- *bufp += 2;
-}
-
-static cv8_symhead *
-cv8_add_symhead(yasm_section *sect, unsigned long type, int first)
-{
- cv8_symhead *head;
- yasm_bytecode *bc;
-
- head = yasm_xmalloc(sizeof(cv8_symhead));
- head->type = type;
- head->first = first;
- head->start_prevbc = yasm_section_bcs_last(sect);
-
- bc = yasm_bc_create_common(&cv8_symhead_bc_callback, head, 0);
- if (first)
- bc->len = 12;
- else
- bc->len = 8;
-
- head->end_prevbc = bc;
- yasm_cv__append_bc(sect, bc);
- return head;
-}
-
-static void
-cv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc)
-{
- head->end_prevbc = end_prevbc;
-}
-
-static void
-cv8_symhead_bc_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-cv8_symhead_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-cv8_symhead_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to calc_len a codeview symhead bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-cv8_symhead_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- yasm_object *object = yasm_section_get_object(bc->section);
- cv8_symhead *head = (cv8_symhead *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *intn, *cval;
-
- cval = yasm_intnum_create_uint(4);
- /* Output "version" if first */
- if (head->first) {
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
- }
-
- /* Type contained - 4 bytes */
- yasm_intnum_set_uint(cval, head->type);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* Total length of info (following this field) - 4 bytes */
- yasm_intnum_set_uint(cval, bc->len);
- intn = yasm_calc_bc_dist(head->start_prevbc, head->end_prevbc);
- yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
- yasm_arch_intnum_tobytes(object->arch, intn, buf, 4, 32, 0, bc, 0);
- buf += 4;
- yasm_intnum_destroy(intn);
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
-
-static yasm_bytecode *
-cv8_add_fileinfo(yasm_section *sect, const cv_filename *fn)
-{
- cv8_fileinfo *fi;
- yasm_bytecode *bc;
-
- fi = yasm_xmalloc(sizeof(cv8_fileinfo));
- fi->fn = fn;
-
- bc = yasm_bc_create_common(&cv8_fileinfo_bc_callback, fi, 0);
- bc->len = 24;
-
- yasm_cv__append_bc(sect, bc);
- return bc;
-}
-
-static void
-cv8_fileinfo_bc_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-cv8_fileinfo_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-cv8_fileinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to calc_len a codeview fileinfo bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-cv8_fileinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- yasm_object *object = yasm_section_get_object(bc->section);
- cv8_fileinfo *fi = (cv8_fileinfo *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *cval;
- int i;
-
- /* Offset in filename string table */
- cval = yasm_intnum_create_uint(fi->fn->str_off);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* Checksum type/length */
- yasm_intnum_set_uint(cval, 0x0110);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
- buf += 2;
-
- /* Checksum */
- for (i=0; i<16; i++)
- YASM_WRITE_8(buf, fi->fn->digest[i]);
-
- /* Pad */
- YASM_WRITE_8(buf, 0);
- YASM_WRITE_8(buf, 0);
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
-
-static void
-cv8_lineinfo_bc_destroy(void *contents)
-{
- cv8_lineinfo *li = (cv8_lineinfo *)contents;
- cv8_lineset *ls1, *ls2;
-
- /* delete line sets */
- ls1 = STAILQ_FIRST(&li->linesets);
- while (ls1) {
- ls2 = STAILQ_NEXT(ls1, link);
- yasm_xfree(ls1);
- ls1 = ls2;
- }
-
- yasm_xfree(contents);
-}
-
-static void
-cv8_lineinfo_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-cv8_lineinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to calc_len a codeview linehead bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-cv8_lineinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- yasm_object *object = yasm_section_get_object(bc->section);
- cv8_lineinfo *li = (cv8_lineinfo *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *cval;
- unsigned long i;
- cv8_lineset *ls;
-
- if (li->first_in_sect) {
- /* start offset and section */
- cv_out_sym(li->sectsym, (unsigned long)(buf - bufstart), bc, &buf,
- d, output_value);
-
- /* Two bytes of pad/alignment */
- YASM_WRITE_8(buf, 0);
- YASM_WRITE_8(buf, 0);
-
- /* Section length covered by line number info */
- cval = yasm_calc_bc_dist(yasm_section_bcs_first(li->sect),
- yasm_section_bcs_last(li->sect));
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- yasm_intnum_destroy(cval);
- buf += 4;
- }
-
- /* Offset of source file in info table */
- cval = yasm_intnum_create_uint(li->fn->info_off);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* Number of line number pairs */
- yasm_intnum_set_uint(cval, li->num_linenums);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* Number of bytes of line number pairs + 12 (no, I don't know why) */
- yasm_intnum_set_uint(cval, li->num_linenums*8+12);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* Offset / line number pairs */
- i = 0;
- STAILQ_FOREACH(ls, &li->linesets, link) {
- unsigned long j;
- for (j=0; i<li->num_linenums && j<126; i++, j++) {
- /* offset in section */
- yasm_intnum_set_uint(cval, ls->pairs[j].offset);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
-
- /* line number in file */
- yasm_intnum_set_uint(cval, ls->pairs[j].line);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
- }
- }
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
-
-static unsigned long
-cv_sym_size(const cv_sym *cvs)
-{
- const char *ch = cvs->format;
- unsigned long len = 4; /* sym length and type */
- unsigned long slen;
- int arg = 0;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- len++;
- arg++;
- break;
- case 'h':
- len += 2;
- arg++;
- break;
- case 'w':
- len += 4;
- arg++;
- break;
- case 'Y':
- len += 6; /* XXX: will be 4 in 16-bit version */
- arg++;
- break;
- case 'T':
- len += 4; /* XXX: will be 2 in CV4 */
- arg++;
- break;
- case 'S':
- len += 1; /* XXX: is this 1 or 2? */
- slen = (unsigned long)strlen((const char *)cvs->args[arg++].p);
- len += slen <= 0xff ? slen : 0xff;
- break;
- case 'Z':
- len +=
- (unsigned long)strlen((const char *)cvs->args[arg++].p) + 1;
- break;
- default:
- yasm_internal_error(N_("unknown sym format character"));
- }
- ch++;
- }
-
- return len;
-}
-
-static void
-cv_sym_bc_destroy(void *contents)
-{
- cv_sym *cvs = (cv_sym *)contents;
- const char *ch = cvs->format;
- int arg = 0;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- case 'h':
- case 'w':
- case 'Y':
- case 'T':
- arg++;
- break; /* nothing to destroy */
- case 'S':
- case 'Z':
- yasm_xfree(cvs->args[arg++].p);
- break;
- default:
- yasm_internal_error(N_("unknown sym format character"));
- }
- ch++;
- }
-
- yasm_xfree(contents);
-}
-
-static void
-cv_sym_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-cv_sym_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to calc_len a codeview sym bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-cv_sym_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- yasm_object *object = yasm_section_get_object(bc->section);
- cv_sym *cvs = (cv_sym *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *cval;
- const char *ch = cvs->format;
- size_t len;
- int arg = 0;
-
- /* Total length of record (following this field) - 2 bytes */
- cval = yasm_intnum_create_uint(bc->len-2);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1);
- buf += 2;
-
- /* Type contained - 2 bytes */
- yasm_intnum_set_uint(cval, cvs->type);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
- buf += 2;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- YASM_WRITE_8(buf, cvs->args[arg].i);
- arg++;
- break;
- case 'h':
- yasm_intnum_set_uint(cval, cvs->args[arg++].i);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0,
- bc, 0);
- buf += 2;
- break;
- case 'w':
- yasm_intnum_set_uint(cval, cvs->args[arg++].i);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
- bc, 0);
- buf += 4;
- break;
- case 'Y':
- cv_out_sym((yasm_symrec *)cvs->args[arg++].p,
- (unsigned long)(buf-bufstart), bc, &buf, d,
- output_value);
- break;
- case 'T':
- yasm_intnum_set_uint(cval, cvs->args[arg++].i);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
- bc, 0);
- buf += 4; /* XXX: will be 2 in CV4 */
- break;
- case 'S':
- len = strlen((char *)cvs->args[arg].p);
- len = len <= 0xff ? len : 0xff;
- YASM_WRITE_8(buf, len);
- memcpy(buf, (char *)cvs->args[arg].p, len);
- buf += len;
- arg++;
- break;
- case 'Z':
- len = strlen((char *)cvs->args[arg].p)+1;
- memcpy(buf, (char *)cvs->args[arg].p, len);
- buf += len;
- arg++;
- break;
- default:
- yasm_internal_error(N_("unknown leaf format character"));
- }
- ch++;
- }
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
+/*
+ * CodeView debugging format - symbol and line information
+ *
+ * Copyright (C) 2006-2007 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the author nor the names of other contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
+ */
+#include <util.h>
+
+#include <libyasm.h>
+
+#include "cv-dbgfmt.h"
+
+enum cv8_symheadtype {
+ CV8_DEBUG_SYMS = 0xF1, /* CV5 symbol information */
+ CV8_LINE_NUMS = 0xF2, /* line numbers for a section */
+ CV8_FILE_STRTAB = 0xF3, /* filename string table */
+ CV8_FILE_INFO = 0xF4 /* source file info */
+};
+
+enum cv_symtype {
+ /* Non-modal Symbols */
+ CV_S_COMPILE = 0x0001, /* Compile Flag */
+ CV_S_REGISTER = 0x0002, /* Register */
+ CV_S_CONSTANT = 0x0003, /* Constant */
+ CV_S_UDT = 0x0004, /* User-defined Type */
+ CV_S_SSEARCH = 0x0005, /* Start Search */
+ CV_S_END = 0x0006, /* End of Block */
+ CV_S_SKIP = 0x0007, /* Skip Record */
+ CV_S_OBJNAME = 0x0009, /* Object File Name */
+ CV_S_ENDARG = 0x000a, /* End of Arguments */
+ CV_S_COBOLUDT = 0x000b, /* COBOL User-defined Type */
+ CV_S_MANYREG = 0x000c, /* Many Registers */
+ CV_S_RETURN = 0x000d, /* Function Return */
+ CV_S_ENTRYTHIS = 0x000e, /* "this" at Method Entry */
+
+ /* Symbols for 16:16 Segmented Architectures */
+ CV_S_BPREL16 = 0x0100, /* BP Relative 16:16 */
+ CV_S_LDATA16 = 0x0101, /* Local Data 16:16 */
+ CV_S_GDATA16 = 0x0102, /* Global Data Symbol 16:16 */
+ CV_S_PUB16 = 0x0103, /* Public Symbol 16:16 */
+ CV_S_LPROC16 = 0x0104, /* Local Start 16:16 */
+ CV_S_GPROC16 = 0x0105, /* Global Start 16:16 */
+ CV_S_THUNK16 = 0x0106, /* Thunk Start 16:16 */
+ CV_S_BLOCK16 = 0x0107, /* Block Start 16:16 */
+ CV_S_WITH16 = 0x0108, /* With Start 16:16 */
+ CV_S_LABEL16 = 0x0109, /* Code Label 16:16 */
+ CV_S_CEXMODEL16 = 0x0110, /* Change Execution Model 16:16 */
+ CV_S_VFTPATH16 = 0x010b, /* Virtual Function Table Path 16:16 */
+ CV_S_REGREL16 = 0x010c, /* Register Relative 16:16 */
+
+ /* Symbols for 16:32 Segmented Architectures */
+ CV_S_BPREL32 = 0x0200, /* BP Relative 16:32 */
+ CV_S_LDATA32 = 0x0201, /* Local Data 16:32 */
+ CV_S_GDATA32 = 0x0202, /* Global Data Symbol 16:32 */
+ CV_S_PUB32 = 0x0203, /* Public Symbol 16:32 */
+ CV_S_LPROC32 = 0x0204, /* Local Start 16:32 */
+ CV_S_GPROC32 = 0x0205, /* Global Start 16:32 */
+ CV_S_THUNK32 = 0x0206, /* Thunk Start 16:32 */
+ CV_S_BLOCK32 = 0x0207, /* Block Start 16:32 */
+ CV_S_WITH32 = 0x0208, /* With Start 16:32 */
+ CV_S_LABEL32 = 0x0209, /* Code Label 16:32 */
+ CV_S_CEXMODEL32 = 0x0210, /* Change Execution Model 16:32 */
+ CV_S_VFTPATH32 = 0x020b, /* Virtual Function Table Path 16:32 */
+ CV_S_REGREL32 = 0x020c, /* Register Relative 16:32 */
+ CV_S_LTHREAD32 = 0x020d, /* Local Thread Storage 16:32 */
+ CV_S_GTHREAD32 = 0x020e, /* Global Thread Storage 16:32 */
+
+ /* Symbols for MIPS */
+ CV_S_LPROCMIPS = 0x0300, /* Local procedure start MIPS */
+ CV_S_GPROCMIPS = 0x0301, /* Global procedure start MIPS */
+
+ /* Symbols for CV8 - strings are 0 terminated rather than length-prefix.
+ * Incomplete and unofficial.
+ */
+ CV8_S_OBJNAME = 0x1101, /* Object File Name */
+ CV8_S_LABEL32 = 0x1105, /* Code Label 16:32 */
+ CV8_S_LDATA32 = 0x110c, /* Local Data 16:32 */
+ CV8_S_GDATA32 = 0x110d, /* Global Data 16:32 */
+ CV8_S_LPROC32 = 0x1110, /* Local Start 16:32 */
+ CV8_S_COMPILE = 0x1116 /* Compile Flag */
+};
+
+typedef struct cv8_symhead {
+ enum cv8_symheadtype type;
+ yasm_bytecode *start_prevbc;
+ yasm_bytecode *end_prevbc;
+ int first; /* nonzero if first symhead in section */
+} cv8_symhead;
+
+typedef struct cv8_fileinfo {
+ const cv_filename *fn;
+} cv8_fileinfo;
+
+/* Note: each line number group is associated with a file AND a section */
+typedef struct cv8_linepair {
+ unsigned long offset;
+ unsigned long line;
+} cv8_linepair;
+
+/* Decrease linked list overhead a bit doing it this way */
+typedef struct cv8_lineset {
+ STAILQ_ENTRY(cv8_lineset) link;
+ cv8_linepair pairs[126];
+ size_t num_pairs;
+} cv8_lineset;
+
+/* Note: Due to line number sorting requirements (by section offset it seems)
+ * one file may need more than one record per section. */
+typedef struct cv8_lineinfo {
+ STAILQ_ENTRY(cv8_lineinfo) link;
+ const cv_filename *fn; /* filename associated with line numbers */
+ yasm_section *sect; /* section line numbers are for */
+ yasm_symrec *sectsym; /* symbol for beginning of sect */
+ unsigned long num_linenums;
+ int first_in_sect; /* First lineinfo for this section. */
+ STAILQ_HEAD(cv8_lineset_head, cv8_lineset) linesets;
+} cv8_lineinfo;
+
+/* Symbols use a bit of meta-programming to encode formats: each character
+ * of format represents the output generated, as follows:
+ * 'b' : 1 byte value (integer)
+ * 'h' : 2 byte value (integer)
+ * 'w' : 4 byte value (integer)
+ * 'Y' : symrec SECREL+SECTION (pointer)
+ * 'T' : type index (integer)
+ * 'S' : length-prefixed string (pointer)
+ * 'Z' : 0-terminated string (pointer)
+ */
+typedef struct cv_sym {
+ enum cv_symtype type;
+ const char *format;
+ union {
+ unsigned long i;
+ void *p;
+ } args[10];
+} cv_sym;
+
+/* Bytecode callback function prototypes */
+static void cv8_symhead_bc_destroy(void *contents);
+static void cv8_symhead_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int cv8_symhead_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int cv8_symhead_bc_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void cv8_fileinfo_bc_destroy(void *contents);
+static void cv8_fileinfo_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int cv8_fileinfo_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int cv8_fileinfo_bc_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void cv8_lineinfo_bc_destroy(void *contents);
+static void cv8_lineinfo_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int cv8_lineinfo_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int cv8_lineinfo_bc_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void cv_sym_bc_destroy(void *contents);
+static void cv_sym_bc_print(const void *contents, FILE *f, int indent_level);
+static int cv_sym_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int cv_sym_bc_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+static const yasm_bytecode_callback cv8_symhead_bc_callback = {
+ cv8_symhead_bc_destroy,
+ cv8_symhead_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ cv8_symhead_bc_calc_len,
+ yasm_bc_expand_common,
+ cv8_symhead_bc_tobytes,
+ 0
+};
+
+static const yasm_bytecode_callback cv8_fileinfo_bc_callback = {
+ cv8_fileinfo_bc_destroy,
+ cv8_fileinfo_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ cv8_fileinfo_bc_calc_len,
+ yasm_bc_expand_common,
+ cv8_fileinfo_bc_tobytes,
+ 0
+};
+
+static const yasm_bytecode_callback cv8_lineinfo_bc_callback = {
+ cv8_lineinfo_bc_destroy,
+ cv8_lineinfo_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ cv8_lineinfo_bc_calc_len,
+ yasm_bc_expand_common,
+ cv8_lineinfo_bc_tobytes,
+ 0
+};
+
+static const yasm_bytecode_callback cv_sym_bc_callback = {
+ cv_sym_bc_destroy,
+ cv_sym_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ cv_sym_bc_calc_len,
+ yasm_bc_expand_common,
+ cv_sym_bc_tobytes,
+ 0
+};
+
+static cv8_symhead *cv8_add_symhead(yasm_section *sect, unsigned long type,
+ int first);
+static void cv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc);
+
+static yasm_bytecode *cv8_add_fileinfo
+ (yasm_section *sect, const cv_filename *fn);
+
+static unsigned long cv_sym_size(const cv_sym *cvs);
+
+
+static cv_sym *
+cv8_add_sym_objname(yasm_section *sect, /*@keep@*/ char *objname)
+{
+ yasm_bytecode *bc;
+ cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
+ cvs->type = CV8_S_OBJNAME;
+ cvs->format = "wZ";
+ cvs->args[0].i = 0; /* signature (0=asm) */
+ cvs->args[1].p = objname; /* object filename */
+
+ bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
+ bc->len = cv_sym_size(cvs);
+ yasm_cv__append_bc(sect, bc);
+ return cvs;
+}
+
+static cv_sym *
+cv8_add_sym_compile(yasm_object *object, yasm_section *sect,
+ /*@keep@*/ char *creator)
+{
+ yasm_bytecode *bc;
+ cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
+ cvs->type = CV8_S_COMPILE;
+ cvs->format = "wwwwZh";
+ cvs->args[0].i = 3; /* language (3=Masm) */
+
+ /* target processor; 0xD0 = AMD64 */
+ if (strcmp(yasm_arch_keyword(object->arch), "x86") == 0) {
+ if (strcmp(yasm_arch_get_machine(object->arch), "amd64") == 0)
+ cvs->args[1].i = 0xD0;
+ else
+ cvs->args[1].i = 0x6; /* 686, FIXME */
+ } else
+ cvs->args[1].i = 0; /* XXX: unknown */
+
+ cvs->args[2].i = 0; /* flags (assume 0 for now) */
+ cvs->args[3].i = 0; /* creator version number (assume 0 for now) */
+ cvs->args[4].p = creator; /* creator string */
+ cvs->args[5].i = 0; /* no pairs of key/value */
+
+ bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
+ bc->len = cv_sym_size(cvs);
+ yasm_cv__append_bc(sect, bc);
+ return cvs;
+}
+
+static cv_sym *
+cv8_add_sym_label(yasm_section *sect, yasm_symrec *sym)
+{
+ yasm_bytecode *bc;
+ cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
+ cvs->type = CV8_S_LABEL32;
+ cvs->format = "YbZ";
+ cvs->args[0].p = sym; /* symrec for label */
+ cvs->args[1].i = 0; /* flags (assume 0 for now) */
+ cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
+
+ bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
+ bc->len = cv_sym_size(cvs);
+ yasm_cv__append_bc(sect, bc);
+ return cvs;
+}
+
+static cv_sym *
+cv8_add_sym_data(yasm_section *sect, unsigned long type, yasm_symrec *sym,
+ int is_global)
+{
+ yasm_bytecode *bc;
+ cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
+ cvs->type = is_global ? CV8_S_GDATA32 : CV8_S_LDATA32;
+ cvs->format = "wYZ";
+ cvs->args[0].i = type; /* type index */
+ cvs->args[1].p = sym; /* symrec for label */
+ cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
+
+ bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
+ bc->len = cv_sym_size(cvs);
+ yasm_cv__append_bc(sect, bc);
+ return cvs;
+}
+
+static size_t
+cv_dbgfmt_add_file(yasm_dbgfmt_cv *dbgfmt_cv, size_t filenum,
+ const char *filename)
+{
+ char *pathname;
+ size_t i;
+ yasm_md5_context context;
+ FILE *f;
+ unsigned char *buf;
+ size_t len;
+
+ /* Put the filename into the filename table */
+ if (filenum == 0) {
+ /* Look to see if we already have that filename in the table */
+ for (; filenum<dbgfmt_cv->filenames_size; filenum++) {
+ if (!dbgfmt_cv->filenames[filenum].filename ||
+ strcmp(dbgfmt_cv->filenames[filenum].filename, filename) == 0)
+ break;
+ }
+ } else
+ filenum--; /* array index is 0-based */
+
+ /* Realloc table if necessary */
+ if (filenum >= dbgfmt_cv->filenames_allocated) {
+ size_t old_allocated = dbgfmt_cv->filenames_allocated;
+ dbgfmt_cv->filenames_allocated = filenum+32;
+ dbgfmt_cv->filenames = yasm_xrealloc(dbgfmt_cv->filenames,
+ sizeof(cv_filename)*dbgfmt_cv->filenames_allocated);
+ for (i=old_allocated; i<dbgfmt_cv->filenames_allocated; i++) {
+ dbgfmt_cv->filenames[i].pathname = NULL;
+ dbgfmt_cv->filenames[i].filename = NULL;
+ dbgfmt_cv->filenames[i].str_off = 0;
+ dbgfmt_cv->filenames[i].info_off = 0;
+ }
+ }
+
+ /* Calculate MD5 checksum of file */
+ buf = yasm_xmalloc(1024);
+ yasm_md5_init(&context);
+ f = fopen(filename, "rb");
+ if (!f)
+ yasm__fatal(N_("codeview: could not open source file"));
+ while ((len = fread(buf, 1, 1024, f)) > 0)
+ yasm_md5_update(&context, buf, (unsigned long)len);
+ yasm_md5_final(dbgfmt_cv->filenames[filenum].digest, &context);
+ fclose(f);
+ yasm_xfree(buf);
+
+ /* Actually save in table */
+ if (dbgfmt_cv->filenames[filenum].pathname)
+ yasm_xfree(dbgfmt_cv->filenames[filenum].pathname);
+ if (dbgfmt_cv->filenames[filenum].filename)
+ yasm_xfree(dbgfmt_cv->filenames[filenum].filename);
+
+ pathname = yasm__abspath(filename);
+ dbgfmt_cv->filenames[filenum].pathname = pathname;
+ dbgfmt_cv->filenames[filenum].filename = yasm__xstrdup(filename);
+
+ /* Update table size */
+ if (filenum >= dbgfmt_cv->filenames_size)
+ dbgfmt_cv->filenames_size = filenum + 1;
+
+ return filenum;
+}
+
+static yasm_bytecode *
+cv_append_str(yasm_section *sect, const char *str)
+{
+ yasm_datavalhead dvs;
+ yasm_bytecode *bc;
+
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str),
+ strlen(str)));
+ bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0);
+ yasm_bc_finalize(bc, yasm_cv__append_bc(sect, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+ return bc;
+}
+
+typedef struct cv_line_info {
+ yasm_section *debug_symline;
+ yasm_object *object;
+ yasm_dbgfmt_cv *dbgfmt_cv;
+ yasm_linemap *linemap;
+ yasm_errwarns *errwarns;
+ unsigned int num_lineinfos;
+ STAILQ_HEAD(cv8_lineinfo_head, cv8_lineinfo) cv8_lineinfos;
+ /*@null@*/ cv8_lineinfo *cv8_cur_li;
+ /*@null@*/ cv8_lineset *cv8_cur_ls;
+} cv_line_info;
+
+static int
+cv_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
+{
+ cv_line_info *info = (cv_line_info *)d;
+ yasm_dbgfmt_cv *dbgfmt_cv = info->dbgfmt_cv;
+ size_t i;
+ const char *filename;
+ unsigned long line;
+ /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
+ yasm_section *sect = yasm_bc_get_section(bc);
+
+ if (nextbc && bc->offset == nextbc->offset)
+ return 0;
+
+ yasm_linemap_lookup(info->linemap, bc->line, &filename, &line);
+
+ if (!info->cv8_cur_li
+ || strcmp(filename, info->cv8_cur_li->fn->filename) != 0) {
+ yasm_bytecode *sectbc;
+ char symname[8];
+ int first_in_sect = !info->cv8_cur_li;
+
+ /* Find file */
+ for (i=0; i<dbgfmt_cv->filenames_size; i++) {
+ if (strcmp(filename, dbgfmt_cv->filenames[i].filename) == 0)
+ break;
+ }
+ if (i >= dbgfmt_cv->filenames_size)
+ yasm_internal_error(N_("could not find filename in table"));
+
+ /* and create new lineinfo structure */
+ info->cv8_cur_li = yasm_xmalloc(sizeof(cv8_lineinfo));
+ info->cv8_cur_li->fn = &dbgfmt_cv->filenames[i];
+ info->cv8_cur_li->sect = sect;
+ info->cv8_cur_li->first_in_sect = first_in_sect;
+ sectbc = yasm_section_bcs_first(sect);
+ if (sectbc->symrecs && sectbc->symrecs[0])
+ info->cv8_cur_li->sectsym = sectbc->symrecs[0];
+ else {
+ sprintf(symname, ".%06u", info->num_lineinfos++);
+ info->cv8_cur_li->sectsym =
+ yasm_symtab_define_label(info->object->symtab, symname, sectbc,
+ 1, 0);
+ }
+ info->cv8_cur_li->num_linenums = 0;
+ STAILQ_INIT(&info->cv8_cur_li->linesets);
+ STAILQ_INSERT_TAIL(&info->cv8_lineinfos, info->cv8_cur_li, link);
+ info->cv8_cur_ls = NULL;
+ }
+
+ /* build new lineset if necessary */
+ if (!info->cv8_cur_ls || info->cv8_cur_ls->num_pairs >= 126) {
+ info->cv8_cur_ls = yasm_xmalloc(sizeof(cv8_lineset));
+ info->cv8_cur_ls->num_pairs = 0;
+ STAILQ_INSERT_TAIL(&info->cv8_cur_li->linesets, info->cv8_cur_ls, link);
+ }
+
+ /* add linepair for this bytecode */
+ info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].offset = bc->offset;
+ info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].line =
+ 0x80000000 | line;
+ info->cv8_cur_ls->num_pairs++;
+ info->cv8_cur_li->num_linenums++;
+
+ return 0;
+}
+
+static int
+cv_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
+{
+ cv_line_info *info = (cv_line_info *)d;
+
+ if (!yasm_section_is_code(sect))
+ return 0; /* not code, so no line data for this section */
+
+ info->cv8_cur_li = NULL;
+ info->cv8_cur_ls = NULL;
+
+ yasm_section_bcs_traverse(sect, info->errwarns, info, cv_generate_line_bc);
+
+ return 0;
+}
+
+static int
+cv_generate_filename(const char *filename, void *d)
+{
+ cv_dbgfmt_add_file((yasm_dbgfmt_cv *)d, 0, filename);
+ return 0;
+}
+
+static int
+cv_generate_sym(yasm_symrec *sym, void *d)
+{
+ cv_line_info *info = (cv_line_info *)d;
+ yasm_bytecode *precbc;
+ const char *name = yasm_symrec_get_name(sym);
+
+ /* only care about labels (for now). Don't put in symbols starting with
+ * ".", as these are typically internally generated ones (like section
+ * symbols).
+ */
+ if (name[0] == '.' || !yasm_symrec_get_label(sym, &precbc))
+ return 0;
+
+ /* TODO: add data types; until then, just mark everything as UBYTE */
+ if (yasm_section_is_code(yasm_bc_get_section(precbc)))
+ cv8_add_sym_label(info->debug_symline, sym);
+ else
+ cv8_add_sym_data(info->debug_symline, 0x20, sym,
+ yasm_symrec_get_visibility(sym) & YASM_SYM_GLOBAL?1:0);
+ return 0;
+}
+
+yasm_section *
+yasm_cv__generate_symline(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)object->dbgfmt;
+ cv_line_info info;
+ int new;
+ size_t i;
+ cv8_symhead *head;
+ cv8_lineinfo *li;
+ yasm_bytecode *bc;
+ unsigned long off;
+
+ /* Generate filenames based on linemap */
+ yasm_linemap_traverse_filenames(linemap, dbgfmt_cv,
+ cv_generate_filename);
+
+ info.object = object;
+ info.dbgfmt_cv = dbgfmt_cv;
+ info.linemap = linemap;
+ info.errwarns = errwarns;
+ info.debug_symline =
+ yasm_object_get_general(object, ".debug$S", 1, 0, 0, &new, 0);
+ info.num_lineinfos = 0;
+ STAILQ_INIT(&info.cv8_lineinfos);
+ info.cv8_cur_li = NULL;
+ info.cv8_cur_ls = NULL;
+
+ /* source filenames string table */
+ head = cv8_add_symhead(info.debug_symline, CV8_FILE_STRTAB, 1);
+ cv_append_str(info.debug_symline, "");
+ off = 1;
+ for (i=0; i<dbgfmt_cv->filenames_size; i++) {
+ if (!dbgfmt_cv->filenames[i].pathname) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("codeview file number %d unassigned"), i+1);
+ yasm_errwarn_propagate(errwarns, 0);
+ continue;
+ }
+ bc = cv_append_str(info.debug_symline,
+ dbgfmt_cv->filenames[i].pathname);
+ dbgfmt_cv->filenames[i].str_off = off;
+ off += bc->len;
+ }
+ cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
+
+ /* Align 4 */
+ bc = yasm_bc_create_align
+ (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
+ NULL, NULL, NULL, 0);
+ yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+
+ /* source file info table */
+ head = cv8_add_symhead(info.debug_symline, CV8_FILE_INFO, 0);
+ off = 0;
+ for (i=0; i<dbgfmt_cv->filenames_size; i++) {
+ if (!dbgfmt_cv->filenames[i].pathname)
+ continue;
+ bc = cv8_add_fileinfo(info.debug_symline, &dbgfmt_cv->filenames[i]);
+ dbgfmt_cv->filenames[i].info_off = off;
+ off += bc->len;
+ }
+ cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
+
+ /* Already aligned 4 */
+
+ /* Generate line numbers for sections */
+ yasm_object_sections_traverse(object, (void *)&info,
+ cv_generate_line_section);
+
+ /* Output line numbers for sections */
+ head = NULL;
+ STAILQ_FOREACH(li, &info.cv8_lineinfos, link) {
+ if (li->first_in_sect) {
+ if (head)
+ cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
+ head = cv8_add_symhead(info.debug_symline, CV8_LINE_NUMS, 0);
+ }
+ bc = yasm_bc_create_common(&cv8_lineinfo_bc_callback, li, 0);
+ bc->len = (li->first_in_sect ? 24 : 12) + li->num_linenums*8;
+ yasm_cv__append_bc(info.debug_symline, bc);
+ }
+ if (head)
+ cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
+
+ /* Already aligned 4 */
+
+ /* Output debugging symbols */
+ head = cv8_add_symhead(info.debug_symline, CV8_DEBUG_SYMS, 0);
+ /* add object and compile flag first */
+ cv8_add_sym_objname(info.debug_symline,
+ yasm__abspath(object->obj_filename));
+ if (getenv("YASM_TEST_SUITE"))
+ cv8_add_sym_compile(object, info.debug_symline,
+ yasm__xstrdup("yasm HEAD"));
+ else
+ cv8_add_sym_compile(object, info.debug_symline,
+ yasm__xstrdup(PACKAGE_STRING));
+ /* then iterate through symbol table */
+ yasm_symtab_traverse(object->symtab, &info, cv_generate_sym);
+ cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
+
+ /* Align 4 at end */
+ bc = yasm_bc_create_align
+ (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
+ NULL, NULL, NULL, 0);
+ yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+
+ return info.debug_symline;
+}
+
+static void
+cv_out_sym(yasm_symrec *sym, unsigned long off, yasm_bytecode *bc,
+ unsigned char **bufp, void *d, yasm_output_value_func output_value)
+{
+ yasm_value val;
+
+ /* sym in its section */
+ yasm_value_init_sym(&val, sym, 32);
+ val.section_rel = 1;
+ output_value(&val, *bufp, 4, off, bc, 0, d);
+ *bufp += 4;
+
+ /* section index */
+ yasm_value_init_sym(&val, sym, 16);
+ val.seg_of = 1;
+ output_value(&val, *bufp, 2, off+4, bc, 0, d);
+ *bufp += 2;
+}
+
+static cv8_symhead *
+cv8_add_symhead(yasm_section *sect, unsigned long type, int first)
+{
+ cv8_symhead *head;
+ yasm_bytecode *bc;
+
+ head = yasm_xmalloc(sizeof(cv8_symhead));
+ head->type = type;
+ head->first = first;
+ head->start_prevbc = yasm_section_bcs_last(sect);
+
+ bc = yasm_bc_create_common(&cv8_symhead_bc_callback, head, 0);
+ if (first)
+ bc->len = 12;
+ else
+ bc->len = 8;
+
+ head->end_prevbc = bc;
+ yasm_cv__append_bc(sect, bc);
+ return head;
+}
+
+static void
+cv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc)
+{
+ head->end_prevbc = end_prevbc;
+}
+
+static void
+cv8_symhead_bc_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+cv8_symhead_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+cv8_symhead_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to calc_len a codeview symhead bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+cv8_symhead_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ yasm_object *object = yasm_section_get_object(bc->section);
+ cv8_symhead *head = (cv8_symhead *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *intn, *cval;
+
+ cval = yasm_intnum_create_uint(4);
+ /* Output "version" if first */
+ if (head->first) {
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+ }
+
+ /* Type contained - 4 bytes */
+ yasm_intnum_set_uint(cval, head->type);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* Total length of info (following this field) - 4 bytes */
+ yasm_intnum_set_uint(cval, bc->len);
+ intn = yasm_calc_bc_dist(head->start_prevbc, head->end_prevbc);
+ yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
+ yasm_arch_intnum_tobytes(object->arch, intn, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+ yasm_intnum_destroy(intn);
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
+
+static yasm_bytecode *
+cv8_add_fileinfo(yasm_section *sect, const cv_filename *fn)
+{
+ cv8_fileinfo *fi;
+ yasm_bytecode *bc;
+
+ fi = yasm_xmalloc(sizeof(cv8_fileinfo));
+ fi->fn = fn;
+
+ bc = yasm_bc_create_common(&cv8_fileinfo_bc_callback, fi, 0);
+ bc->len = 24;
+
+ yasm_cv__append_bc(sect, bc);
+ return bc;
+}
+
+static void
+cv8_fileinfo_bc_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+cv8_fileinfo_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+cv8_fileinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to calc_len a codeview fileinfo bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+cv8_fileinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ yasm_object *object = yasm_section_get_object(bc->section);
+ cv8_fileinfo *fi = (cv8_fileinfo *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *cval;
+ int i;
+
+ /* Offset in filename string table */
+ cval = yasm_intnum_create_uint(fi->fn->str_off);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* Checksum type/length */
+ yasm_intnum_set_uint(cval, 0x0110);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
+ buf += 2;
+
+ /* Checksum */
+ for (i=0; i<16; i++)
+ YASM_WRITE_8(buf, fi->fn->digest[i]);
+
+ /* Pad */
+ YASM_WRITE_8(buf, 0);
+ YASM_WRITE_8(buf, 0);
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
+
+static void
+cv8_lineinfo_bc_destroy(void *contents)
+{
+ cv8_lineinfo *li = (cv8_lineinfo *)contents;
+ cv8_lineset *ls1, *ls2;
+
+ /* delete line sets */
+ ls1 = STAILQ_FIRST(&li->linesets);
+ while (ls1) {
+ ls2 = STAILQ_NEXT(ls1, link);
+ yasm_xfree(ls1);
+ ls1 = ls2;
+ }
+
+ yasm_xfree(contents);
+}
+
+static void
+cv8_lineinfo_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+cv8_lineinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to calc_len a codeview linehead bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+cv8_lineinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ yasm_object *object = yasm_section_get_object(bc->section);
+ cv8_lineinfo *li = (cv8_lineinfo *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *cval;
+ unsigned long i;
+ cv8_lineset *ls;
+
+ if (li->first_in_sect) {
+ /* start offset and section */
+ cv_out_sym(li->sectsym, (unsigned long)(buf - bufstart), bc, &buf,
+ d, output_value);
+
+ /* Two bytes of pad/alignment */
+ YASM_WRITE_8(buf, 0);
+ YASM_WRITE_8(buf, 0);
+
+ /* Section length covered by line number info */
+ cval = yasm_calc_bc_dist(yasm_section_bcs_first(li->sect),
+ yasm_section_bcs_last(li->sect));
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ yasm_intnum_destroy(cval);
+ buf += 4;
+ }
+
+ /* Offset of source file in info table */
+ cval = yasm_intnum_create_uint(li->fn->info_off);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* Number of line number pairs */
+ yasm_intnum_set_uint(cval, li->num_linenums);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* Number of bytes of line number pairs + 12 (no, I don't know why) */
+ yasm_intnum_set_uint(cval, li->num_linenums*8+12);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* Offset / line number pairs */
+ i = 0;
+ STAILQ_FOREACH(ls, &li->linesets, link) {
+ unsigned long j;
+ for (j=0; i<li->num_linenums && j<126; i++, j++) {
+ /* offset in section */
+ yasm_intnum_set_uint(cval, ls->pairs[j].offset);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+
+ /* line number in file */
+ yasm_intnum_set_uint(cval, ls->pairs[j].line);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+ }
+ }
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
+
+static unsigned long
+cv_sym_size(const cv_sym *cvs)
+{
+ const char *ch = cvs->format;
+ unsigned long len = 4; /* sym length and type */
+ unsigned long slen;
+ int arg = 0;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ len++;
+ arg++;
+ break;
+ case 'h':
+ len += 2;
+ arg++;
+ break;
+ case 'w':
+ len += 4;
+ arg++;
+ break;
+ case 'Y':
+ len += 6; /* XXX: will be 4 in 16-bit version */
+ arg++;
+ break;
+ case 'T':
+ len += 4; /* XXX: will be 2 in CV4 */
+ arg++;
+ break;
+ case 'S':
+ len += 1; /* XXX: is this 1 or 2? */
+ slen = (unsigned long)strlen((const char *)cvs->args[arg++].p);
+ len += slen <= 0xff ? slen : 0xff;
+ break;
+ case 'Z':
+ len +=
+ (unsigned long)strlen((const char *)cvs->args[arg++].p) + 1;
+ break;
+ default:
+ yasm_internal_error(N_("unknown sym format character"));
+ }
+ ch++;
+ }
+
+ return len;
+}
+
+static void
+cv_sym_bc_destroy(void *contents)
+{
+ cv_sym *cvs = (cv_sym *)contents;
+ const char *ch = cvs->format;
+ int arg = 0;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'Y':
+ case 'T':
+ arg++;
+ break; /* nothing to destroy */
+ case 'S':
+ case 'Z':
+ yasm_xfree(cvs->args[arg++].p);
+ break;
+ default:
+ yasm_internal_error(N_("unknown sym format character"));
+ }
+ ch++;
+ }
+
+ yasm_xfree(contents);
+}
+
+static void
+cv_sym_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+cv_sym_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to calc_len a codeview sym bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+cv_sym_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ yasm_object *object = yasm_section_get_object(bc->section);
+ cv_sym *cvs = (cv_sym *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *cval;
+ const char *ch = cvs->format;
+ size_t len;
+ int arg = 0;
+
+ /* Total length of record (following this field) - 2 bytes */
+ cval = yasm_intnum_create_uint(bc->len-2);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1);
+ buf += 2;
+
+ /* Type contained - 2 bytes */
+ yasm_intnum_set_uint(cval, cvs->type);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
+ buf += 2;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ YASM_WRITE_8(buf, cvs->args[arg].i);
+ arg++;
+ break;
+ case 'h':
+ yasm_intnum_set_uint(cval, cvs->args[arg++].i);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0,
+ bc, 0);
+ buf += 2;
+ break;
+ case 'w':
+ yasm_intnum_set_uint(cval, cvs->args[arg++].i);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
+ bc, 0);
+ buf += 4;
+ break;
+ case 'Y':
+ cv_out_sym((yasm_symrec *)cvs->args[arg++].p,
+ (unsigned long)(buf-bufstart), bc, &buf, d,
+ output_value);
+ break;
+ case 'T':
+ yasm_intnum_set_uint(cval, cvs->args[arg++].i);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
+ bc, 0);
+ buf += 4; /* XXX: will be 2 in CV4 */
+ break;
+ case 'S':
+ len = strlen((char *)cvs->args[arg].p);
+ len = len <= 0xff ? len : 0xff;
+ YASM_WRITE_8(buf, len);
+ memcpy(buf, (char *)cvs->args[arg].p, len);
+ buf += len;
+ arg++;
+ break;
+ case 'Z':
+ len = strlen((char *)cvs->args[arg].p)+1;
+ memcpy(buf, (char *)cvs->args[arg].p, len);
+ buf += len;
+ arg++;
+ break;
+ default:
+ yasm_internal_error(N_("unknown leaf format character"));
+ }
+ ch++;
+ }
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
diff --git a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-type.c b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-type.c
index 2a52f18436..ebccbdeda9 100644
--- a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-type.c
+++ b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-type.c
@@ -1,778 +1,778 @@
-/*
- * CodeView debugging format - type information
- *
- * Copyright (C) 2006-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the author nor the names of other contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
- */
-#include <util.h>
-
-#include <libyasm.h>
-
-#include "cv-dbgfmt.h"
-
-enum cv_reservedtype {
- /* Bitfields representation - type */
- CV_TYPE_SPECIAL = 0x00<<4, /* Special */
- CV_TYPE_SIGNED = 0x01<<4, /* Signed integral value */
- CV_TYPE_UNSIGNED = 0x02<<4, /* Unsigned integral value */
- CV_TYPE_BOOLEAN = 0x03<<4, /* Boolean */
- CV_TYPE_REAL = 0x04<<4, /* Real */
- CV_TYPE_COMPLEX = 0x05<<4, /* Complex */
- CV_TYPE_SPECIAL2 = 0x06<<4, /* Special2 */
- CV_TYPE_REALINT = 0x07<<4, /* Really int value */
-
- /* "size" of CV_TYPE_SPECIAL */
- CV_SPECIAL_NOTYPE = 0x00<<0, /* No type */
- CV_SPECIAL_ABS = 0x01<<0, /* Absolute symbol */
- CV_SPECIAL_SEG = 0x02<<0, /* Segment */
- CV_SPECIAL_VOID = 0x03<<0, /* Void */
- CV_SPECIAL_CURRENCY = 0x04<<0, /* Basic 8-byte currency value */
- CV_SPECIAL_NEARBSTR = 0x05<<0, /* Near Basic string */
- CV_SPECIAL_FARBSTR = 0x06<<0, /* Far Basic string */
-
- /* Size of CV_TYPE_SIGNED, CV_TYPE_UNSIGNED, and CV_TYPE_BOOLEAN */
- CV_INTEGER_1BYTE = 0x00<<0, /* 1 byte */
- CV_INTEGER_2BYTE = 0x01<<0, /* 2 byte */
- CV_INTEGER_4BYTE = 0x02<<0, /* 4 byte */
- CV_INTEGER_8BYTE = 0x03<<0, /* 8 byte */
-
- /* Size of CV_TYPE_REAL and CV_TYPE_COMPLEX */
- CV_REAL_32BIT = 0x00<<0, /* 32 bit */
- CV_REAL_64BIT = 0x01<<0, /* 64 bit */
- CV_REAL_80BIT = 0x02<<0, /* 80 bit */
- CV_REAL_128BIT = 0x03<<0, /* 128 bit */
- CV_REAL_48BIT = 0x04<<0, /* 48 bit */
-
- /* "size" of CV_TYPE_SPECIAL2 */
- CV_SPECIAL2_BIT = 0x00<<0, /* Bit */
- CV_SPECIAL2_PASCHAR = 0x01<<0, /* Pascal CHAR */
-
- /* Size of CV_TYPE_REALINT */
- CV_REALINT_CHAR = 0x00<<0, /* Char */
- CV_REALINT_WCHAR = 0x01<<0, /* Wide character */
- CV_REALINT_S2BYTE = 0x02<<0, /* 2-byte signed integer */
- CV_REALINT_U2BYTE = 0x03<<0, /* 2-byte unsigned integer */
- CV_REALINT_S4BYTE = 0x04<<0, /* 4-byte signed integer */
- CV_REALINT_U4BYTE = 0x05<<0, /* 4-byte unsigned integer */
- CV_REALINT_S8BYTE = 0x06<<0, /* 8-byte signed integer */
- CV_REALINT_U8BYTE = 0x07<<0, /* 8-byte unsigned integer */
-
- /* Mode */
- CV_MODE_DIRECT = 0x00<<8, /* Direct; not a pointer */
- CV_MODE_NEAR = 0x01<<8, /* Near pointer */
- CV_MODE_FAR = 0x02<<8, /* Far pointer */
- CV_MODE_HUGE = 0x03<<8, /* Huge pointer */
- CV_MODE_NEAR32 = 0x04<<8, /* 32-bit near pointer */
- CV_MODE_FAR32 = 0x05<<8, /* 32-bit far pointer */
- CV_MODE_NEAR64 = 0x06<<8, /* 64-bit near pointer */
-
- /* Pure primitive type listing - based on above bitfields */
-
- /* Special Types */
- CV_T_NOTYPE = 0x0000, /* Uncharacterized type (no type) */
- CV_T_ABS = 0x0001, /* Absolute symbol */
- CV_T_SEGMENT = 0x0002, /* Segment type */
- CV_T_VOID = 0x0003, /* Void */
- CV_T_PVOID = 0x0103, /* Near pointer to void */
- CV_T_PFVOID = 0x0203, /* Far pointer to void */
- CV_T_PHVOID = 0x0303, /* Huge pointer to void */
- CV_T_32PVOID = 0x0403, /* 32-bit near pointer to void */
- CV_T_32PFVOID = 0x0503, /* 32-bit far pointer to void */
- CV_T_CURRENCY = 0x0004, /* Basic 8-byte currency value */
- CV_T_NBASICSTR = 0x0005, /* Near Basic string */
- CV_T_FBASICSTR = 0x0006, /* Far Basic string */
- CV_T_BIT = 0x0060, /* Bit */
- CV_T_PASCHAR = 0x0061, /* Pascal CHAR */
- /* Character Types */
- CV_T_CHAR = 0x0010, /* 8-bit signed */
- CV_T_UCHAR = 0x0020, /* 8-bit unsigned */
- CV_T_PCHAR = 0x0110, /* Near pointer to 8-bit signed */
- CV_T_PUCHAR = 0x0120, /* Near pointer to 8-bit unsigned */
- CV_T_PFCHAR = 0x0210, /* Far pointer to 8-bit signed */
- CV_T_PFUCHAR = 0x0220, /* Far pointer to 8-bit unsigned */
- CV_T_PHCHAR = 0x0310, /* Huge pointer to 8-bit signed */
- CV_T_PHUCHAR = 0x0320, /* Huge pointer to 8-bit unsigned */
- CV_T_32PCHAR = 0x0410, /* 16:32 near pointer to 8-bit signed */
- CV_T_32PUCHAR = 0x0420, /* 16:32 near pointer to 8-bit unsigned */
- CV_T_32PFCHAR = 0x0510, /* 16:32 far pointer to 8-bit signed */
- CV_T_32PFUCHAR = 0x0520, /* 16:32 far pointer to 8-bit unsigned */
- /* Real Character Types */
- CV_T_RCHAR = 0x0070, /* Real char */
- CV_T_PRCHAR = 0x0170, /* Near pointer to a real char */
- CV_T_PFRCHAR = 0x0270, /* Far pointer to a real char */
- CV_T_PHRCHAR = 0x0370, /* Huge pointer to a real char */
- CV_T_32PRCHAR = 0x0470, /* 16:32 near pointer to a real char */
- CV_T_32PFRCHAR = 0x0570, /* 16:32 far pointer to a real char */
- /* Wide Character Types */
- CV_T_WCHAR = 0x0071, /* Wide char */
- CV_T_PWCHAR = 0x0171, /* Near pointer to a wide char */
- CV_T_PFWCHAR = 0x0271, /* Far pointer to a wide char */
- CV_T_PHWCHAR = 0x0371, /* Huge pointer to a wide char */
- CV_T_32PWCHAR = 0x0471, /* 16:32 near pointer to a wide char */
- CV_T_32PFWCHAR = 0x0571, /* 16:32 far pointer to a wide char */
- /* Real 16-bit Integer Types */
- CV_T_INT2 = 0x0072, /* Real 16-bit signed int */
- CV_T_UINT2 = 0x0073, /* Real 16-bit unsigned int */
- CV_T_PINT2 = 0x0172, /* Near pointer to 16-bit signed int */
- CV_T_PUINT2 = 0x0173, /* Near pointer to 16-bit unsigned int */
- CV_T_PFINT2 = 0x0272, /* Far pointer to 16-bit signed int */
- CV_T_PFUINT2 = 0x0273, /* Far pointer to 16-bit unsigned int */
- CV_T_PHINT2 = 0x0372, /* Huge pointer to 16-bit signed int */
- CV_T_PHUINT2 = 0x0373, /* Huge pointer to 16-bit unsigned int */
- CV_T_32PINT2 = 0x0472, /* 16:32 near pointer to 16-bit signed int */
- CV_T_32PUINT2 = 0x0473, /* 16:32 near pointer to 16-bit unsigned int */
- CV_T_32PFINT2 = 0x0572, /* 16:32 far pointer to 16-bit signed int */
- CV_T_32PFUINT2 = 0x0573, /* 16:32 far pointer to 16-bit unsigned int */
- /* 16-bit Short Types */
- CV_T_SHORT = 0x0011, /* 16-bit signed */
- CV_T_USHORT = 0x0021, /* 16-bit unsigned */
- CV_T_PSHORT = 0x0111, /* Near pointer to 16-bit signed */
- CV_T_PUSHORT = 0x0121, /* Near pointer to 16-bit unsigned */
- CV_T_PFSHORT = 0x0211, /* Far pointer to 16-bit signed */
- CV_T_PFUSHORT = 0x0221, /* Far pointer to 16-bit unsigned */
- CV_T_PHSHORT = 0x0311, /* Huge pointer to 16-bit signed */
- CV_T_PHUSHORT = 0x0321, /* Huge pointer to 16-bit unsigned */
- CV_T_32PSHORT = 0x0411, /* 16:32 near pointer to 16-bit signed */
- CV_T_32PUSHORT = 0x0421, /* 16:32 near pointer to 16-bit unsigned */
- CV_T_32PFSHORT = 0x0511, /* 16:32 far pointer to 16-bit signed */
- CV_T_32PFUSHORT = 0x0521, /* 16:32 far pointer to 16-bit unsigned */
- /* Real 32-bit Integer Types */
- CV_T_INT4 = 0x0074, /* Real 32-bit signed int */
- CV_T_UINT4 = 0x0075, /* Real 32-bit unsigned int */
- CV_T_PINT4 = 0x0174, /* Near pointer to 32-bit signed int */
- CV_T_PUINT4 = 0x0175, /* Near pointer to 32-bit unsigned int */
- CV_T_PFINT4 = 0x0274, /* Far pointer to 32-bit signed int */
- CV_T_PFUINT4 = 0x0275, /* Far pointer to 32-bit unsigned int */
- CV_T_PHINT4 = 0x0374, /* Huge pointer to 32-bit signed int */
- CV_T_PHUINT4 = 0x0375, /* Huge pointer to 32-bit unsigned int */
- CV_T_32PINT4 = 0x0474, /* 16:32 near pointer to 32-bit signed int */
- CV_T_32PUINT4 = 0x0475, /* 16:32 near pointer to 32-bit unsigned int */
- CV_T_32PFINT4 = 0x0574, /* 16:32 far pointer to 32-bit signed int */
- CV_T_32PFUINT4 = 0x0575, /* 16:32 far pointer to 32-bit unsigned int */
- /* 32-bit Long Types */
- CV_T_LONG = 0x0012, /* 32-bit signed */
- CV_T_ULONG = 0x0022, /* 32-bit unsigned */
- CV_T_PLONG = 0x0112, /* Near pointer to 32-bit signed */
- CV_T_PULONG = 0x0122, /* Near pointer to 32-bit unsigned */
- CV_T_PFLONG = 0x0212, /* Far pointer to 32-bit signed */
- CV_T_PFULONG = 0x0222, /* Far pointer to 32-bit unsigned */
- CV_T_PHLONG = 0x0312, /* Huge pointer to 32-bit signed */
- CV_T_PHULONG = 0x0322, /* Huge pointer to 32-bit unsigned */
- CV_T_32PLONG = 0x0412, /* 16:32 near pointer to 32-bit signed */
- CV_T_32PULONG = 0x0422, /* 16:32 near pointer to 32-bit unsigned */
- CV_T_32PFLONG = 0x0512, /* 16:32 far pointer to 32-bit signed */
- CV_T_32PFULONG = 0x0522, /* 16:32 far pointer to 32-bit unsigned */
- /* Real 64-bit int Types */
- CV_T_INT8 = 0x0076, /* 64-bit signed int */
- CV_T_UINT8 = 0x0077, /* 64-bit unsigned int */
- CV_T_PINT8 = 0x0176, /* Near pointer to 64-bit signed int */
- CV_T_PUINT8 = 0x0177, /* Near pointer to 64-bit unsigned int */
- CV_T_PFINT8 = 0x0276, /* Far pointer to 64-bit signed int */
- CV_T_PFUINT8 = 0x0277, /* Far pointer to 64-bit unsigned int */
- CV_T_PHINT8 = 0x0376, /* Huge pointer to 64-bit signed int */
- CV_T_PHUINT8 = 0x0377, /* Huge pointer to 64-bit unsigned int */
- CV_T_32PINT8 = 0x0476, /* 16:32 near pointer to 64-bit signed int */
- CV_T_32PUINT8 = 0x0477, /* 16:32 near pointer to 64-bit unsigned int */
- CV_T_32PFINT8 = 0x0576, /* 16:32 far pointer to 64-bit signed int */
- CV_T_32PFUINT8 = 0x0577, /* 16:32 far pointer to 64-bit unsigned int */
- /* 64-bit Integral Types */
- CV_T_QUAD = 0x0013, /* 64-bit signed */
- CV_T_UQUAD = 0x0023, /* 64-bit unsigned */
- CV_T_PQUAD = 0x0113, /* Near pointer to 64-bit signed */
- CV_T_PUQUAD = 0x0123, /* Near pointer to 64-bit unsigned */
- CV_T_PFQUAD = 0x0213, /* Far pointer to 64-bit signed */
- CV_T_PFUQUAD = 0x0223, /* Far pointer to 64-bit unsigned */
- CV_T_PHQUAD = 0x0313, /* Huge pointer to 64-bit signed */
- CV_T_PHUQUAD = 0x0323, /* Huge pointer to 64-bit unsigned */
- CV_T_32PQUAD = 0x0413, /* 16:32 near pointer to 64-bit signed */
- CV_T_32PUQUAD = 0x0423, /* 16:32 near pointer to 64-bit unsigned */
- CV_T_32PFQUAD = 0x0513, /* 16:32 far pointer to 64-bit signed */
- CV_T_32PFUQUAD = 0x0523, /* 16:32 far pointer to 64-bit unsigned */
- /* 32-bit Real Types */
- CV_T_REAL32 = 0x0040, /* 32-bit real */
- CV_T_PREAL32 = 0x0140, /* Near pointer to 32-bit real */
- CV_T_PFREAL32 = 0x0240, /* Far pointer to 32-bit real */
- CV_T_PHREAL32 = 0x0340, /* Huge pointer to 32-bit real */
- CV_T_32PREAL32 = 0x0440, /* 16:32 near pointer to 32-bit real */
- CV_T_32PFREAL32 = 0x0540, /* 16:32 far pointer to 32-bit real */
- /* 48-bit Real Types */
- CV_T_REAL48 = 0x0044, /* 48-bit real */
- CV_T_PREAL48 = 0x0144, /* Near pointer to 48-bit real */
- CV_T_PFREAL48 = 0x0244, /* Far pointer to 48-bit real */
- CV_T_PHREAL48 = 0x0344, /* Huge pointer to 48-bit real */
- CV_T_32PREAL48 = 0x0444, /* 16:32 near pointer to 48-bit real */
- CV_T_32PFREAL48 = 0x0544, /* 16:32 far pointer to 48-bit real */
- /* 64-bit Real Types */
- CV_T_REAL64 = 0x0041, /* 64-bit real */
- CV_T_PREAL64 = 0x0141, /* Near pointer to 64-bit real */
- CV_T_PFREAL64 = 0x0241, /* Far pointer to 64-bit real */
- CV_T_PHREAL64 = 0x0341, /* Huge pointer to 64-bit real */
- CV_T_32PREAL64 = 0x0441, /* 16:32 near pointer to 64-bit real */
- CV_T_32PFREAL64 = 0x0541, /* 16:32 far pointer to 64-bit real */
- /* 80-bit Real Types */
- CV_T_REAL80 = 0x0042, /* 80-bit real */
- CV_T_PREAL80 = 0x0142, /* Near pointer to 80-bit real */
- CV_T_PFREAL80 = 0x0242, /* Far pointer to 80-bit real */
- CV_T_PHREAL80 = 0x0342, /* Huge pointer to 80-bit real */
- CV_T_32PREAL80 = 0x0442, /* 16:32 near pointer to 80-bit real */
- CV_T_32PFREAL80 = 0x0542, /* 16:32 far pointer to 80-bit real */
- /* 128-bit Real Types */
- CV_T_REAL128 = 0x0043, /* 128-bit real */
- CV_T_PREAL128 = 0x0143, /* Near pointer to 128-bit real */
- CV_T_PFREAL128 = 0x0243, /* Far pointer to 128-bit real */
- CV_T_PHREAL128 = 0x0343, /* Huge pointer to 128-bit real */
- CV_T_32PREAL128 = 0x0443, /* 16:32 near pointer to 128-bit real */
- CV_T_32PFREAL128 = 0x0543, /* 16:32 far pointer to 128-bit real */
- /* 32-bit Complex Types */
- CV_T_CPLX32 = 0x0050, /* 32-bit complex */
- CV_T_PCPLX32 = 0x0150, /* Near pointer to 32-bit complex */
- CV_T_PFCPLX32 = 0x0250, /* Far pointer to 32-bit complex */
- CV_T_PHCPLX32 = 0x0350, /* Huge pointer to 32-bit complex */
- CV_T_32PCPLX32 = 0x0450, /* 16:32 near pointer to 32-bit complex */
- CV_T_32PFCPLX32 = 0x0550, /* 16:32 far pointer to 32-bit complex */
- /* 64-bit Complex Types */
- CV_T_CPLX64 = 0x0051, /* 64-bit complex */
- CV_T_PCPLX64 = 0x0151, /* Near pointer to 64-bit complex */
- CV_T_PFCPLX64 = 0x0251, /* Far pointer to 64-bit complex */
- CV_T_PHCPLX64 = 0x0351, /* Huge pointer to 64-bit complex */
- CV_T_32PCPLX64 = 0x0451, /* 16:32 near pointer to 64-bit complex */
- CV_T_32PFCPLX64 = 0x0551, /* 16:32 far pointer to 64-bit complex */
- /* 80-bit Complex Types */
- CV_T_CPLX80 = 0x0052, /* 80-bit complex */
- CV_T_PCPLX80 = 0x0152, /* Near pointer to 80-bit complex */
- CV_T_PFCPLX80 = 0x0252, /* Far pointer to 80-bit complex */
- CV_T_PHCPLX80 = 0x0352, /* Huge pointer to 80-bit complex */
- CV_T_32PCPLX80 = 0x0452, /* 16:32 near pointer to 80-bit complex */
- CV_T_32PFCPLX80 = 0x0552, /* 16:32 far pointer to 80-bit complex */
- /* 128-bit Complex Types */
- CV_T_CPLX128 = 0x0053, /* 128-bit complex */
- CV_T_PCPLX128 = 0x0153, /* Near pointer to 128-bit complex */
- CV_T_PFCPLX128 = 0x0253, /* Far pointer to 128-bit complex */
- CV_T_PHCPLX128 = 0x0353, /* Huge pointer to 128-bit real */
- CV_T_32PCPLX128 = 0x0453, /* 16:32 near pointer to 128-bit complex */
- CV_T_32PFCPLX128 = 0x0553, /* 16:32 far pointer to 128-bit complex */
- /* Boolean Types */
- CV_T_BOOL08 = 0x0030, /* 8-bit Boolean */
- CV_T_BOOL16 = 0x0031, /* 16-bit Boolean */
- CV_T_BOOL32 = 0x0032, /* 32-bit Boolean */
- CV_T_BOOL64 = 0x0033, /* 64-bit Boolean */
- CV_T_PBOOL08 = 0x0130, /* Near pointer to 8-bit Boolean */
- CV_T_PBOOL16 = 0x0131, /* Near pointer to 16-bit Boolean */
- CV_T_PBOOL32 = 0x0132, /* Near pointer to 32-bit Boolean */
- CV_T_PBOOL64 = 0x0133, /* Near pointer to 64-bit Boolean */
- CV_T_PFBOOL08 = 0x0230, /* Far pointer to 8-bit Boolean */
- CV_T_PFBOOL16 = 0x0231, /* Far pointer to 16-bit Boolean */
- CV_T_PFBOOL32 = 0x0232, /* Far pointer to 32-bit Boolean */
- CV_T_PFBOOL64 = 0x0233, /* Far pointer to 64-bit Boolean */
- CV_T_PHBOOL08 = 0x0330, /* Huge pointer to 8-bit Boolean */
- CV_T_PHBOOL16 = 0x0331, /* Huge pointer to 16-bit Boolean */
- CV_T_PHBOOL32 = 0x0332, /* Huge pointer to 32-bit Boolean */
- CV_T_PHBOOL64 = 0x0333, /* Huge pointer to 64-bit Boolean */
- CV_T_32PBOOL08 = 0x0430, /* 16:32 near pointer to 8-bit Boolean */
- CV_T_32PBOOL16 = 0x0431, /* 16:32 near pointer to 16-bit Boolean */
- CV_T_32PBOOL32 = 0x0432, /* 16:32 near pointer to 32-bit Boolean */
- CV_T_32PBOOL64 = 0x0433, /* 16:32 near pointer to 64-bit Boolean */
- CV_T_32PFBOOL08 = 0x0530, /* 16:32 far pointer to 8-bit Boolean */
- CV_T_32PFBOOL16 = 0x0531, /* 16:32 far pointer to 16-bit Boolean */
- CV_T_32PFBOOL32 = 0x0532, /* 16:32 far pointer to 32-bit Boolean */
- CV_T_32PFBOOL64 = 0x0533, /* 16:32 far pointer to 64-bit Boolean */
-
- /* Non-primitive types are stored in the TYPES section (generated in
- * cv-type.c) and start at this index (e.g. 0x1000 is the first type
- * in TYPES, 0x1001 the second, etc.
- */
- CV_FIRST_NONPRIM = 0x1000
-};
-
-enum cv_leaftype {
- /* Leaf indices for type records that can be referenced from symbols */
- CV4_LF_MODIFIER = 0x0001, /* Type Modifier */
- CV4_LF_POINTER = 0x0002, /* Pointer */
- CV4_LF_ARRAY = 0x0003, /* Simple Array */
- CV4_LF_CLASS = 0x0004, /* Classes */
- CV4_LF_STRUCTURE = 0x0005, /* Structures */
- CV4_LF_UNION = 0x0006, /* Unions */
- CV4_LF_ENUM = 0x0007, /* Enumeration */
- CV4_LF_PROCEDURE = 0x0008, /* Procedure */
- CV4_LF_MFUNCTION = 0x0009, /* Member Function */
- CV4_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */
- CV4_LF_BARRAY = 0x000d, /* Basic Array */
- CV4_LF_LABEL = 0x000e, /* Label */
- CV4_LF_NULL = 0x000f, /* Null */
- CV4_LF_DIMARRAY = 0x0011, /* Multiply Dimensioned Array */
- CV4_LF_VFTPATH = 0x0012, /* Path to Virtual Function Table */
- CV4_LF_PRECOMP = 0x0013, /* Reference Precompiled Types */
- CV4_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */
-
- /* CodeView 5.0 version */
- CV5_LF_MODIFIER = 0x1001, /* Type Modifier */
- CV5_LF_POINTER = 0x1002, /* Pointer */
- CV5_LF_ARRAY = 0x1003, /* Simple Array */
- CV5_LF_CLASS = 0x1004, /* Classes */
- CV5_LF_STRUCTURE = 0x1005, /* Structures */
- CV5_LF_UNION = 0x1006, /* Unions */
- CV5_LF_ENUM = 0x1007, /* Enumeration */
- CV5_LF_PROCEDURE = 0x1008, /* Procedure */
- CV5_LF_MFUNCTION = 0x1009, /* Member Function */
- CV5_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */
- CV5_LF_BARRAY = 0x100d, /* Basic Array */
- CV5_LF_LABEL = 0x000e, /* Label */
- CV5_LF_NULL = 0x000f, /* Null */
- CV5_LF_DIMARRAY = 0x100c, /* Multiply Dimensioned Array */
- CV5_LF_VFTPATH = 0x100d, /* Path to Virtual Function Table */
- CV5_LF_PRECOMP = 0x100e, /* Reference Precompiled Types */
- CV5_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */
- CV5_LF_TYPESERVER = 0x0016, /* Reference Typeserver */
-
- /* Leaf indices for type records that can be referenced from other type
- * records
- */
- CV4_LF_SKIP = 0x0200, /* Skip */
- CV4_LF_ARGLIST = 0x0201, /* Argument List */
- CV4_LF_DEFARG = 0x0202, /* Default Argument */
- CV4_LF_LIST = 0x0203, /* Arbitrary List */
- CV4_LF_FIELDLIST = 0x0204, /* Field List */
- CV4_LF_DERIVED = 0x0205, /* Derived Classes */
- CV4_LF_BITFIELD = 0x0206, /* Bit Fields */
- CV4_LF_METHODLIST = 0x0207, /* Method List */
- CV4_LF_DIMCONU = 0x0208, /* Dimensioned Array with Constant Upper Bound */
- CV4_LF_DIMCONLU = 0x0209, /* Dimensioned Array with Constant Lower and Upper Bounds */
- CV4_LF_DIMVARU = 0x020a, /* Dimensioned Array with Variable Upper Bound */
- CV4_LF_DIMVARLU = 0x020b, /* Dimensioned Array with Variable Lower and Upper Bounds */
- CV4_LF_REFSYM = 0x020c, /* Referenced Symbol */
-
- /* CodeView 5.0 version */
- CV5_LF_SKIP = 0x1200, /* Skip */
- CV5_LF_ARGLIST = 0x1201, /* Argument List */
- CV5_LF_DEFARG = 0x1202, /* Default Argument */
- CV5_LF_FIELDLIST = 0x1203, /* Field List */
- CV5_LF_DERIVED = 0x1204, /* Derived Classes */
- CV5_LF_BITFIELD = 0x1205, /* Bit Fields */
- CV5_LF_METHODLIST = 0x1206, /* Method List */
- CV5_LF_DIMCONU = 0x1207, /* Dimensioned Array with Constant Upper Bound */
- CV5_LF_DIMCONLU = 0x1208, /* Dimensioned Array with Constant Lower and Upper Bounds */
- CV5_LF_DIMVARU = 0x1209, /* Dimensioned Array with Variable Upper Bound */
- CV5_LF_DIMVARLU = 0x120a, /* Dimensioned Array with Variable Lower and Upper Bounds */
- CV5_LF_REFSYM = 0x020c, /* Referenced Symbol */
-
- /* Leaf indices for fields of complex lists */
- CV4_LF_BCLASS = 0x0400, /* Real Base Class */
- CV4_LF_VBCLASS = 0x0401, /* Direct Virtual Base Class */
- CV4_LF_IVBCLASS = 0x0402, /* Indirect Virtual Base Class */
- CV4_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */
- CV4_LF_FRIENDFCN = 0x0404, /* Friend Function */
- CV4_LF_INDEX = 0x0405, /* Index To Another Type Record */
- CV4_LF_MEMBER = 0x0406, /* Data Member */
- CV4_LF_STMEMBER = 0x0407, /* Static Data Member */
- CV4_LF_METHOD = 0x0408, /* Method */
- CV4_LF_NESTTYPE = 0x0409, /* Nested Type Definition */
- CV4_LF_VFUNCTAB = 0x040a, /* Virtual Function Table Pointer */
- CV4_LF_FRIENDCLS = 0x040b, /* Friend Class */
- CV4_LF_ONEMETHOD = 0x040c, /* One Method */
- CV4_LF_VFUNCOFF = 0x040d, /* Virtual Function Offset */
-
- /* CodeView 5.0 version */
- CV5_LF_BCLASS = 0x1400, /* Real Base Class */
- CV5_LF_VBCLASS = 0x1401, /* Direct Virtual Base Class */
- CV5_LF_IVBCLASS = 0x1402, /* Indirect Virtual Base Class */
- CV5_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */
- CV5_LF_FRIENDFCN = 0x1403, /* Friend Function */
- CV5_LF_INDEX = 0x1404, /* Index To Another Type Record */
- CV5_LF_MEMBER = 0x1405, /* Data Member */
- CV5_LF_STMEMBER = 0x1406, /* Static Data Member */
- CV5_LF_METHOD = 0x1407, /* Method */
- CV5_LF_NESTTYPE = 0x1408, /* Nested Type Definition */
- CV5_LF_VFUNCTAB = 0x1409, /* Virtual Function Table Pointer */
- CV5_LF_FRIENDCLS = 0x140a, /* Friend Class */
- CV5_LF_ONEMETHOD = 0x140b, /* One Method */
- CV5_LF_VFUNCOFF = 0x140c, /* Virtual Function Offset */
- CV5_LF_NESTTYPEEX = 0x140d, /* Nested Type Extended Definition */
- CV5_LF_MEMBERMODIFY = 0x140e, /* Member Modification */
- /* XXX: CodeView 5.0 spec also lists 0x040f as LF_MEMBERMODIFY? */
-
- /* Leaf indices for numeric fields of symbols and type records */
- CV_LF_NUMERIC = 0x8000,
- CV_LF_CHAR = 0x8000, /* Signed Char (8-bit) */
- CV_LF_SHORT = 0x8001, /* Signed Short (16-bit) */
- CV_LF_USHORT = 0x8002, /* Unsigned Short (16-bit) */
- CV_LF_LONG = 0x8003, /* Signed Long (32-bit) */
- CV_LF_ULONG = 0x8004, /* Unsigned Long (32-bit) */
- CV_LF_REAL32 = 0x8005, /* 32-bit Float */
- CV_LF_REAL64 = 0x8006, /* 64-bit Float */
- CV_LF_REAL80 = 0x8007, /* 80-bit Float */
- CV_LF_REAL128 = 0x8008, /* 128-bit Float */
- CV_LF_QUADWORD = 0x8009, /* Signed Quad Word (64-bit) */
- CV_LF_UQUADWORD = 0x800a, /* Unsigned Quad Word (64-bit) */
- CV_LF_REAL48 = 0x800b, /* 48-bit Float */
- CV_LF_COMPLEX32 = 0x800c, /* 32-bit Complex */
- CV_LF_COMPLEX64 = 0x800d, /* 64-bit Complex */
- CV_LF_COMPLEX80 = 0x800e, /* 80-bit Complex */
- CV_LF_COMPLEX128 = 0x800f, /* 128-bit Complex */
- CV_LF_VARSTRING = 0x8010, /* Variable-length String */
-
- /* Leaf padding bytes */
- CV_LF_PAD0 = 0xf0,
- CV_LF_PAD1 = 0xf1,
- CV_LF_PAD2 = 0xf2,
- CV_LF_PAD3 = 0xf3,
- CV_LF_PAD4 = 0xf4,
- CV_LF_PAD5 = 0xf5,
- CV_LF_PAD6 = 0xf6,
- CV_LF_PAD7 = 0xf7,
- CV_LF_PAD8 = 0xf8,
- CV_LF_PAD9 = 0xf9,
- CV_LF_PAD10 = 0xfa,
- CV_LF_PAD11 = 0xfb,
- CV_LF_PAD12 = 0xfc,
- CV_LF_PAD13 = 0xfc,
- CV_LF_PAD14 = 0xfe,
- CV_LF_PAD15 = 0xff
-};
-
-/* Leaves use a bit of meta-programming to encode formats: each character
- * of format represents the output generated, as follows:
- * 'b' : 1 byte value (integer)
- * 'h' : 2 byte value (integer)
- * 'w' : 4 byte value (integer)
- * 'L' : subleaf, recurses into cv_leaf (pointer)
- * 'T' : 4 byte type index, pulls cv_type.index from cv_type (pointer)
- * 'S' : length-prefixed string (pointer)
- */
-typedef struct cv_leaf {
- enum cv_leaftype type;
- const char *format; /* format of args */
- union {
- unsigned long i;
- void *p;
- } args[6];
-} cv_leaf;
-
-typedef struct cv_type {
- unsigned long indx; /* type # (must be same as output order) */
- size_t num_leaves;
- /*@null@*/ /*@only@*/ cv_leaf **leaves;
-} cv_type;
-
-/* Bytecode callback function prototypes */
-static void cv_type_bc_destroy(void *contents);
-static void cv_type_bc_print(const void *contents, FILE *f, int indent_level);
-static int cv_type_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int cv_type_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- /*@null@*/ yasm_output_reloc_func output_reloc);
-
-/* Bytecode callback structures */
-static const yasm_bytecode_callback cv_type_bc_callback = {
- cv_type_bc_destroy,
- cv_type_bc_print,
- yasm_bc_finalize_common,
- NULL,
- cv_type_bc_calc_len,
- yasm_bc_expand_common,
- cv_type_bc_tobytes,
- 0
-};
-
-static cv_type *cv_type_create(unsigned long indx);
-static void cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf);
-
-
-static cv_leaf *
-cv_leaf_create_label(int is_far)
-{
- cv_leaf *leaf = yasm_xmalloc(sizeof(cv_leaf));
- leaf->type = CV5_LF_LABEL;
- leaf->format = "h";
- leaf->args[0].i = is_far ? 4 : 0;
- return leaf;
-}
-
-yasm_section *
-yasm_cv__generate_type(yasm_object *object)
-{
- int new;
- unsigned long indx = CV_FIRST_NONPRIM;
- yasm_section *debug_type;
- yasm_bytecode *bc;
- cv_type *type;
-
- debug_type =
- yasm_object_get_general(object, ".debug$T", 1, 0, 0, &new, 0);
-
- /* Add label type */
- type = cv_type_create(indx++);
- cv_type_append_leaf(type, cv_leaf_create_label(0));
- bc = yasm_bc_create_common(&cv_type_bc_callback, type, 0);
- yasm_bc_finalize(bc, yasm_cv__append_bc(debug_type, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-
- return debug_type;
-}
-
-static void
-cv_leaf_destroy(cv_leaf *leaf)
-{
- const char *ch = leaf->format;
- int arg = 0;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- case 'h':
- case 'w':
- arg++;
- break; /* nothing to destroy */
- case 'L':
- cv_leaf_destroy((cv_leaf *)leaf->args[arg++].p);
- break;
- case 'T':
- arg++; /* nothing to destroy */
- break;
- case 'S':
- yasm_xfree(leaf->args[arg++].p);
- break;
- default:
- yasm_internal_error(N_("unknown leaf format character"));
- }
- ch++;
- }
-}
-
-static unsigned long
-cv_leaf_size(const cv_leaf *leaf)
-{
- const char *ch = leaf->format;
- unsigned long len = 2; /* leaf type */
- unsigned long slen;
- int arg = 0;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- len++;
- arg++;
- break;
- case 'h':
- len += 2;
- arg++;
- break;
- case 'w':
- len += 4;
- arg++;
- break;
- case 'L':
- len += cv_leaf_size((const cv_leaf *)leaf->args[arg++].p);
- break;
- case 'T':
- len += 4; /* XXX: will be 2 in CV4 */
- arg++;
- break;
- case 'S':
- len += 1; /* XXX: is this 1 or 2? */
- slen = (unsigned long)strlen((const char *)leaf->args[arg++].p);
- len += slen <= 0xff ? slen : 0xff;
- break;
- default:
- yasm_internal_error(N_("unknown leaf format character"));
- }
- ch++;
- }
-
- return len;
-}
-
-static void
-cv_leaf_tobytes(const cv_leaf *leaf, yasm_bytecode *bc, yasm_arch *arch,
- unsigned char **bufp, yasm_intnum *cval)
-{
- unsigned char *buf = *bufp;
- const char *ch = leaf->format;
- size_t len;
- int arg = 0;
-
- /* leaf type */
- yasm_intnum_set_uint(cval, leaf->type);
- yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
- buf += 2;
-
- while (*ch) {
- switch (*ch) {
- case 'b':
- YASM_WRITE_8(buf, leaf->args[arg].i);
- arg++;
- break;
- case 'h':
- yasm_intnum_set_uint(cval, leaf->args[arg++].i);
- yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
- buf += 2;
- break;
- case 'w':
- yasm_intnum_set_uint(cval, leaf->args[arg++].i);
- yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4;
- break;
- case 'L':
- cv_leaf_tobytes((const cv_leaf *)leaf->args[arg++].p, bc, arch,
- &buf, cval);
- break;
- case 'T':
- yasm_intnum_set_uint(cval,
- ((const cv_type *)leaf->args[arg++].p)->indx);
- yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
- buf += 4; /* XXX: will be 2 in CV4 */
- break;
- case 'S':
- len = strlen((const char *)leaf->args[arg].p);
- len = len <= 0xff ? len : 0xff;
- YASM_WRITE_8(buf, len);
- memcpy(buf, (const char *)leaf->args[arg].p, len);
- buf += len;
- arg++;
- break;
- default:
- yasm_internal_error(N_("unknown leaf format character"));
- }
- ch++;
- }
-
- *bufp = buf;
-}
-
-static cv_type *
-cv_type_create(unsigned long indx)
-{
- cv_type *type = yasm_xmalloc(sizeof(cv_type));
-
- type->indx = indx;
- type->num_leaves = 0;
- type->leaves = NULL;
-
- return type;
-}
-
-static void
-cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf)
-{
- type->num_leaves++;
-
- /* This is inefficient for large numbers of leaves, but that won't happen
- * until we add structure support.
- */
- type->leaves = yasm_xrealloc(type->leaves,
- type->num_leaves*sizeof(cv_leaf *));
-
- type->leaves[type->num_leaves-1] = leaf;
-}
-
-static void
-cv_type_bc_destroy(void *contents)
-{
- cv_type *type = (cv_type *)contents;
- size_t i;
-
- for (i=0; i<type->num_leaves; i++)
- cv_leaf_destroy(type->leaves[i]);
- if (type->leaves)
- yasm_xfree(type->leaves);
- yasm_xfree(contents);
-}
-
-static void
-cv_type_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-cv_type_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- cv_type *type = (cv_type *)bc->contents;
- size_t i;
-
- if (type->indx == CV_FIRST_NONPRIM)
- bc->len = 4+2;
- else
- bc->len = 2;
-
- for (i=0; i<type->num_leaves; i++)
- bc->len += cv_leaf_size(type->leaves[i]);
-
- /* Pad to multiple of 4 */
- if (bc->len & 0x3)
- bc->len += 4-(bc->len & 0x3);
-
- return 0;
-}
-
-static int
-cv_type_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- yasm_object *object = yasm_section_get_object(bc->section);
- cv_type *type = (cv_type *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *cval;
- size_t i;
- unsigned long reclen = bc->len - 2;
-
- cval = yasm_intnum_create_uint(4); /* version */
- if (type->indx == CV_FIRST_NONPRIM) {
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 1);
- buf += 4;
- reclen -= 4;
- }
-
- /* Total length of record (following this field) - 2 bytes */
- yasm_intnum_set_uint(cval, reclen);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1);
- buf += 2;
-
- /* Leaves */
- for (i=0; i<type->num_leaves; i++)
- cv_leaf_tobytes(type->leaves[i], bc, object->arch, &buf, cval);
-
- /* Pad to multiple of 4 */
- switch ((buf-(*bufp)) & 0x3) {
- case 3:
- YASM_WRITE_8(buf, CV_LF_PAD3);
- case 2:
- YASM_WRITE_8(buf, CV_LF_PAD2);
- case 1:
- YASM_WRITE_8(buf, CV_LF_PAD1);
- case 0:
- break;
- }
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
+/*
+ * CodeView debugging format - type information
+ *
+ * Copyright (C) 2006-2007 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the author nor the names of other contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER 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 AUTHOR OR OTHER 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.
+ */
+#include <util.h>
+
+#include <libyasm.h>
+
+#include "cv-dbgfmt.h"
+
+enum cv_reservedtype {
+ /* Bitfields representation - type */
+ CV_TYPE_SPECIAL = 0x00<<4, /* Special */
+ CV_TYPE_SIGNED = 0x01<<4, /* Signed integral value */
+ CV_TYPE_UNSIGNED = 0x02<<4, /* Unsigned integral value */
+ CV_TYPE_BOOLEAN = 0x03<<4, /* Boolean */
+ CV_TYPE_REAL = 0x04<<4, /* Real */
+ CV_TYPE_COMPLEX = 0x05<<4, /* Complex */
+ CV_TYPE_SPECIAL2 = 0x06<<4, /* Special2 */
+ CV_TYPE_REALINT = 0x07<<4, /* Really int value */
+
+ /* "size" of CV_TYPE_SPECIAL */
+ CV_SPECIAL_NOTYPE = 0x00<<0, /* No type */
+ CV_SPECIAL_ABS = 0x01<<0, /* Absolute symbol */
+ CV_SPECIAL_SEG = 0x02<<0, /* Segment */
+ CV_SPECIAL_VOID = 0x03<<0, /* Void */
+ CV_SPECIAL_CURRENCY = 0x04<<0, /* Basic 8-byte currency value */
+ CV_SPECIAL_NEARBSTR = 0x05<<0, /* Near Basic string */
+ CV_SPECIAL_FARBSTR = 0x06<<0, /* Far Basic string */
+
+ /* Size of CV_TYPE_SIGNED, CV_TYPE_UNSIGNED, and CV_TYPE_BOOLEAN */
+ CV_INTEGER_1BYTE = 0x00<<0, /* 1 byte */
+ CV_INTEGER_2BYTE = 0x01<<0, /* 2 byte */
+ CV_INTEGER_4BYTE = 0x02<<0, /* 4 byte */
+ CV_INTEGER_8BYTE = 0x03<<0, /* 8 byte */
+
+ /* Size of CV_TYPE_REAL and CV_TYPE_COMPLEX */
+ CV_REAL_32BIT = 0x00<<0, /* 32 bit */
+ CV_REAL_64BIT = 0x01<<0, /* 64 bit */
+ CV_REAL_80BIT = 0x02<<0, /* 80 bit */
+ CV_REAL_128BIT = 0x03<<0, /* 128 bit */
+ CV_REAL_48BIT = 0x04<<0, /* 48 bit */
+
+ /* "size" of CV_TYPE_SPECIAL2 */
+ CV_SPECIAL2_BIT = 0x00<<0, /* Bit */
+ CV_SPECIAL2_PASCHAR = 0x01<<0, /* Pascal CHAR */
+
+ /* Size of CV_TYPE_REALINT */
+ CV_REALINT_CHAR = 0x00<<0, /* Char */
+ CV_REALINT_WCHAR = 0x01<<0, /* Wide character */
+ CV_REALINT_S2BYTE = 0x02<<0, /* 2-byte signed integer */
+ CV_REALINT_U2BYTE = 0x03<<0, /* 2-byte unsigned integer */
+ CV_REALINT_S4BYTE = 0x04<<0, /* 4-byte signed integer */
+ CV_REALINT_U4BYTE = 0x05<<0, /* 4-byte unsigned integer */
+ CV_REALINT_S8BYTE = 0x06<<0, /* 8-byte signed integer */
+ CV_REALINT_U8BYTE = 0x07<<0, /* 8-byte unsigned integer */
+
+ /* Mode */
+ CV_MODE_DIRECT = 0x00<<8, /* Direct; not a pointer */
+ CV_MODE_NEAR = 0x01<<8, /* Near pointer */
+ CV_MODE_FAR = 0x02<<8, /* Far pointer */
+ CV_MODE_HUGE = 0x03<<8, /* Huge pointer */
+ CV_MODE_NEAR32 = 0x04<<8, /* 32-bit near pointer */
+ CV_MODE_FAR32 = 0x05<<8, /* 32-bit far pointer */
+ CV_MODE_NEAR64 = 0x06<<8, /* 64-bit near pointer */
+
+ /* Pure primitive type listing - based on above bitfields */
+
+ /* Special Types */
+ CV_T_NOTYPE = 0x0000, /* Uncharacterized type (no type) */
+ CV_T_ABS = 0x0001, /* Absolute symbol */
+ CV_T_SEGMENT = 0x0002, /* Segment type */
+ CV_T_VOID = 0x0003, /* Void */
+ CV_T_PVOID = 0x0103, /* Near pointer to void */
+ CV_T_PFVOID = 0x0203, /* Far pointer to void */
+ CV_T_PHVOID = 0x0303, /* Huge pointer to void */
+ CV_T_32PVOID = 0x0403, /* 32-bit near pointer to void */
+ CV_T_32PFVOID = 0x0503, /* 32-bit far pointer to void */
+ CV_T_CURRENCY = 0x0004, /* Basic 8-byte currency value */
+ CV_T_NBASICSTR = 0x0005, /* Near Basic string */
+ CV_T_FBASICSTR = 0x0006, /* Far Basic string */
+ CV_T_BIT = 0x0060, /* Bit */
+ CV_T_PASCHAR = 0x0061, /* Pascal CHAR */
+ /* Character Types */
+ CV_T_CHAR = 0x0010, /* 8-bit signed */
+ CV_T_UCHAR = 0x0020, /* 8-bit unsigned */
+ CV_T_PCHAR = 0x0110, /* Near pointer to 8-bit signed */
+ CV_T_PUCHAR = 0x0120, /* Near pointer to 8-bit unsigned */
+ CV_T_PFCHAR = 0x0210, /* Far pointer to 8-bit signed */
+ CV_T_PFUCHAR = 0x0220, /* Far pointer to 8-bit unsigned */
+ CV_T_PHCHAR = 0x0310, /* Huge pointer to 8-bit signed */
+ CV_T_PHUCHAR = 0x0320, /* Huge pointer to 8-bit unsigned */
+ CV_T_32PCHAR = 0x0410, /* 16:32 near pointer to 8-bit signed */
+ CV_T_32PUCHAR = 0x0420, /* 16:32 near pointer to 8-bit unsigned */
+ CV_T_32PFCHAR = 0x0510, /* 16:32 far pointer to 8-bit signed */
+ CV_T_32PFUCHAR = 0x0520, /* 16:32 far pointer to 8-bit unsigned */
+ /* Real Character Types */
+ CV_T_RCHAR = 0x0070, /* Real char */
+ CV_T_PRCHAR = 0x0170, /* Near pointer to a real char */
+ CV_T_PFRCHAR = 0x0270, /* Far pointer to a real char */
+ CV_T_PHRCHAR = 0x0370, /* Huge pointer to a real char */
+ CV_T_32PRCHAR = 0x0470, /* 16:32 near pointer to a real char */
+ CV_T_32PFRCHAR = 0x0570, /* 16:32 far pointer to a real char */
+ /* Wide Character Types */
+ CV_T_WCHAR = 0x0071, /* Wide char */
+ CV_T_PWCHAR = 0x0171, /* Near pointer to a wide char */
+ CV_T_PFWCHAR = 0x0271, /* Far pointer to a wide char */
+ CV_T_PHWCHAR = 0x0371, /* Huge pointer to a wide char */
+ CV_T_32PWCHAR = 0x0471, /* 16:32 near pointer to a wide char */
+ CV_T_32PFWCHAR = 0x0571, /* 16:32 far pointer to a wide char */
+ /* Real 16-bit Integer Types */
+ CV_T_INT2 = 0x0072, /* Real 16-bit signed int */
+ CV_T_UINT2 = 0x0073, /* Real 16-bit unsigned int */
+ CV_T_PINT2 = 0x0172, /* Near pointer to 16-bit signed int */
+ CV_T_PUINT2 = 0x0173, /* Near pointer to 16-bit unsigned int */
+ CV_T_PFINT2 = 0x0272, /* Far pointer to 16-bit signed int */
+ CV_T_PFUINT2 = 0x0273, /* Far pointer to 16-bit unsigned int */
+ CV_T_PHINT2 = 0x0372, /* Huge pointer to 16-bit signed int */
+ CV_T_PHUINT2 = 0x0373, /* Huge pointer to 16-bit unsigned int */
+ CV_T_32PINT2 = 0x0472, /* 16:32 near pointer to 16-bit signed int */
+ CV_T_32PUINT2 = 0x0473, /* 16:32 near pointer to 16-bit unsigned int */
+ CV_T_32PFINT2 = 0x0572, /* 16:32 far pointer to 16-bit signed int */
+ CV_T_32PFUINT2 = 0x0573, /* 16:32 far pointer to 16-bit unsigned int */
+ /* 16-bit Short Types */
+ CV_T_SHORT = 0x0011, /* 16-bit signed */
+ CV_T_USHORT = 0x0021, /* 16-bit unsigned */
+ CV_T_PSHORT = 0x0111, /* Near pointer to 16-bit signed */
+ CV_T_PUSHORT = 0x0121, /* Near pointer to 16-bit unsigned */
+ CV_T_PFSHORT = 0x0211, /* Far pointer to 16-bit signed */
+ CV_T_PFUSHORT = 0x0221, /* Far pointer to 16-bit unsigned */
+ CV_T_PHSHORT = 0x0311, /* Huge pointer to 16-bit signed */
+ CV_T_PHUSHORT = 0x0321, /* Huge pointer to 16-bit unsigned */
+ CV_T_32PSHORT = 0x0411, /* 16:32 near pointer to 16-bit signed */
+ CV_T_32PUSHORT = 0x0421, /* 16:32 near pointer to 16-bit unsigned */
+ CV_T_32PFSHORT = 0x0511, /* 16:32 far pointer to 16-bit signed */
+ CV_T_32PFUSHORT = 0x0521, /* 16:32 far pointer to 16-bit unsigned */
+ /* Real 32-bit Integer Types */
+ CV_T_INT4 = 0x0074, /* Real 32-bit signed int */
+ CV_T_UINT4 = 0x0075, /* Real 32-bit unsigned int */
+ CV_T_PINT4 = 0x0174, /* Near pointer to 32-bit signed int */
+ CV_T_PUINT4 = 0x0175, /* Near pointer to 32-bit unsigned int */
+ CV_T_PFINT4 = 0x0274, /* Far pointer to 32-bit signed int */
+ CV_T_PFUINT4 = 0x0275, /* Far pointer to 32-bit unsigned int */
+ CV_T_PHINT4 = 0x0374, /* Huge pointer to 32-bit signed int */
+ CV_T_PHUINT4 = 0x0375, /* Huge pointer to 32-bit unsigned int */
+ CV_T_32PINT4 = 0x0474, /* 16:32 near pointer to 32-bit signed int */
+ CV_T_32PUINT4 = 0x0475, /* 16:32 near pointer to 32-bit unsigned int */
+ CV_T_32PFINT4 = 0x0574, /* 16:32 far pointer to 32-bit signed int */
+ CV_T_32PFUINT4 = 0x0575, /* 16:32 far pointer to 32-bit unsigned int */
+ /* 32-bit Long Types */
+ CV_T_LONG = 0x0012, /* 32-bit signed */
+ CV_T_ULONG = 0x0022, /* 32-bit unsigned */
+ CV_T_PLONG = 0x0112, /* Near pointer to 32-bit signed */
+ CV_T_PULONG = 0x0122, /* Near pointer to 32-bit unsigned */
+ CV_T_PFLONG = 0x0212, /* Far pointer to 32-bit signed */
+ CV_T_PFULONG = 0x0222, /* Far pointer to 32-bit unsigned */
+ CV_T_PHLONG = 0x0312, /* Huge pointer to 32-bit signed */
+ CV_T_PHULONG = 0x0322, /* Huge pointer to 32-bit unsigned */
+ CV_T_32PLONG = 0x0412, /* 16:32 near pointer to 32-bit signed */
+ CV_T_32PULONG = 0x0422, /* 16:32 near pointer to 32-bit unsigned */
+ CV_T_32PFLONG = 0x0512, /* 16:32 far pointer to 32-bit signed */
+ CV_T_32PFULONG = 0x0522, /* 16:32 far pointer to 32-bit unsigned */
+ /* Real 64-bit int Types */
+ CV_T_INT8 = 0x0076, /* 64-bit signed int */
+ CV_T_UINT8 = 0x0077, /* 64-bit unsigned int */
+ CV_T_PINT8 = 0x0176, /* Near pointer to 64-bit signed int */
+ CV_T_PUINT8 = 0x0177, /* Near pointer to 64-bit unsigned int */
+ CV_T_PFINT8 = 0x0276, /* Far pointer to 64-bit signed int */
+ CV_T_PFUINT8 = 0x0277, /* Far pointer to 64-bit unsigned int */
+ CV_T_PHINT8 = 0x0376, /* Huge pointer to 64-bit signed int */
+ CV_T_PHUINT8 = 0x0377, /* Huge pointer to 64-bit unsigned int */
+ CV_T_32PINT8 = 0x0476, /* 16:32 near pointer to 64-bit signed int */
+ CV_T_32PUINT8 = 0x0477, /* 16:32 near pointer to 64-bit unsigned int */
+ CV_T_32PFINT8 = 0x0576, /* 16:32 far pointer to 64-bit signed int */
+ CV_T_32PFUINT8 = 0x0577, /* 16:32 far pointer to 64-bit unsigned int */
+ /* 64-bit Integral Types */
+ CV_T_QUAD = 0x0013, /* 64-bit signed */
+ CV_T_UQUAD = 0x0023, /* 64-bit unsigned */
+ CV_T_PQUAD = 0x0113, /* Near pointer to 64-bit signed */
+ CV_T_PUQUAD = 0x0123, /* Near pointer to 64-bit unsigned */
+ CV_T_PFQUAD = 0x0213, /* Far pointer to 64-bit signed */
+ CV_T_PFUQUAD = 0x0223, /* Far pointer to 64-bit unsigned */
+ CV_T_PHQUAD = 0x0313, /* Huge pointer to 64-bit signed */
+ CV_T_PHUQUAD = 0x0323, /* Huge pointer to 64-bit unsigned */
+ CV_T_32PQUAD = 0x0413, /* 16:32 near pointer to 64-bit signed */
+ CV_T_32PUQUAD = 0x0423, /* 16:32 near pointer to 64-bit unsigned */
+ CV_T_32PFQUAD = 0x0513, /* 16:32 far pointer to 64-bit signed */
+ CV_T_32PFUQUAD = 0x0523, /* 16:32 far pointer to 64-bit unsigned */
+ /* 32-bit Real Types */
+ CV_T_REAL32 = 0x0040, /* 32-bit real */
+ CV_T_PREAL32 = 0x0140, /* Near pointer to 32-bit real */
+ CV_T_PFREAL32 = 0x0240, /* Far pointer to 32-bit real */
+ CV_T_PHREAL32 = 0x0340, /* Huge pointer to 32-bit real */
+ CV_T_32PREAL32 = 0x0440, /* 16:32 near pointer to 32-bit real */
+ CV_T_32PFREAL32 = 0x0540, /* 16:32 far pointer to 32-bit real */
+ /* 48-bit Real Types */
+ CV_T_REAL48 = 0x0044, /* 48-bit real */
+ CV_T_PREAL48 = 0x0144, /* Near pointer to 48-bit real */
+ CV_T_PFREAL48 = 0x0244, /* Far pointer to 48-bit real */
+ CV_T_PHREAL48 = 0x0344, /* Huge pointer to 48-bit real */
+ CV_T_32PREAL48 = 0x0444, /* 16:32 near pointer to 48-bit real */
+ CV_T_32PFREAL48 = 0x0544, /* 16:32 far pointer to 48-bit real */
+ /* 64-bit Real Types */
+ CV_T_REAL64 = 0x0041, /* 64-bit real */
+ CV_T_PREAL64 = 0x0141, /* Near pointer to 64-bit real */
+ CV_T_PFREAL64 = 0x0241, /* Far pointer to 64-bit real */
+ CV_T_PHREAL64 = 0x0341, /* Huge pointer to 64-bit real */
+ CV_T_32PREAL64 = 0x0441, /* 16:32 near pointer to 64-bit real */
+ CV_T_32PFREAL64 = 0x0541, /* 16:32 far pointer to 64-bit real */
+ /* 80-bit Real Types */
+ CV_T_REAL80 = 0x0042, /* 80-bit real */
+ CV_T_PREAL80 = 0x0142, /* Near pointer to 80-bit real */
+ CV_T_PFREAL80 = 0x0242, /* Far pointer to 80-bit real */
+ CV_T_PHREAL80 = 0x0342, /* Huge pointer to 80-bit real */
+ CV_T_32PREAL80 = 0x0442, /* 16:32 near pointer to 80-bit real */
+ CV_T_32PFREAL80 = 0x0542, /* 16:32 far pointer to 80-bit real */
+ /* 128-bit Real Types */
+ CV_T_REAL128 = 0x0043, /* 128-bit real */
+ CV_T_PREAL128 = 0x0143, /* Near pointer to 128-bit real */
+ CV_T_PFREAL128 = 0x0243, /* Far pointer to 128-bit real */
+ CV_T_PHREAL128 = 0x0343, /* Huge pointer to 128-bit real */
+ CV_T_32PREAL128 = 0x0443, /* 16:32 near pointer to 128-bit real */
+ CV_T_32PFREAL128 = 0x0543, /* 16:32 far pointer to 128-bit real */
+ /* 32-bit Complex Types */
+ CV_T_CPLX32 = 0x0050, /* 32-bit complex */
+ CV_T_PCPLX32 = 0x0150, /* Near pointer to 32-bit complex */
+ CV_T_PFCPLX32 = 0x0250, /* Far pointer to 32-bit complex */
+ CV_T_PHCPLX32 = 0x0350, /* Huge pointer to 32-bit complex */
+ CV_T_32PCPLX32 = 0x0450, /* 16:32 near pointer to 32-bit complex */
+ CV_T_32PFCPLX32 = 0x0550, /* 16:32 far pointer to 32-bit complex */
+ /* 64-bit Complex Types */
+ CV_T_CPLX64 = 0x0051, /* 64-bit complex */
+ CV_T_PCPLX64 = 0x0151, /* Near pointer to 64-bit complex */
+ CV_T_PFCPLX64 = 0x0251, /* Far pointer to 64-bit complex */
+ CV_T_PHCPLX64 = 0x0351, /* Huge pointer to 64-bit complex */
+ CV_T_32PCPLX64 = 0x0451, /* 16:32 near pointer to 64-bit complex */
+ CV_T_32PFCPLX64 = 0x0551, /* 16:32 far pointer to 64-bit complex */
+ /* 80-bit Complex Types */
+ CV_T_CPLX80 = 0x0052, /* 80-bit complex */
+ CV_T_PCPLX80 = 0x0152, /* Near pointer to 80-bit complex */
+ CV_T_PFCPLX80 = 0x0252, /* Far pointer to 80-bit complex */
+ CV_T_PHCPLX80 = 0x0352, /* Huge pointer to 80-bit complex */
+ CV_T_32PCPLX80 = 0x0452, /* 16:32 near pointer to 80-bit complex */
+ CV_T_32PFCPLX80 = 0x0552, /* 16:32 far pointer to 80-bit complex */
+ /* 128-bit Complex Types */
+ CV_T_CPLX128 = 0x0053, /* 128-bit complex */
+ CV_T_PCPLX128 = 0x0153, /* Near pointer to 128-bit complex */
+ CV_T_PFCPLX128 = 0x0253, /* Far pointer to 128-bit complex */
+ CV_T_PHCPLX128 = 0x0353, /* Huge pointer to 128-bit real */
+ CV_T_32PCPLX128 = 0x0453, /* 16:32 near pointer to 128-bit complex */
+ CV_T_32PFCPLX128 = 0x0553, /* 16:32 far pointer to 128-bit complex */
+ /* Boolean Types */
+ CV_T_BOOL08 = 0x0030, /* 8-bit Boolean */
+ CV_T_BOOL16 = 0x0031, /* 16-bit Boolean */
+ CV_T_BOOL32 = 0x0032, /* 32-bit Boolean */
+ CV_T_BOOL64 = 0x0033, /* 64-bit Boolean */
+ CV_T_PBOOL08 = 0x0130, /* Near pointer to 8-bit Boolean */
+ CV_T_PBOOL16 = 0x0131, /* Near pointer to 16-bit Boolean */
+ CV_T_PBOOL32 = 0x0132, /* Near pointer to 32-bit Boolean */
+ CV_T_PBOOL64 = 0x0133, /* Near pointer to 64-bit Boolean */
+ CV_T_PFBOOL08 = 0x0230, /* Far pointer to 8-bit Boolean */
+ CV_T_PFBOOL16 = 0x0231, /* Far pointer to 16-bit Boolean */
+ CV_T_PFBOOL32 = 0x0232, /* Far pointer to 32-bit Boolean */
+ CV_T_PFBOOL64 = 0x0233, /* Far pointer to 64-bit Boolean */
+ CV_T_PHBOOL08 = 0x0330, /* Huge pointer to 8-bit Boolean */
+ CV_T_PHBOOL16 = 0x0331, /* Huge pointer to 16-bit Boolean */
+ CV_T_PHBOOL32 = 0x0332, /* Huge pointer to 32-bit Boolean */
+ CV_T_PHBOOL64 = 0x0333, /* Huge pointer to 64-bit Boolean */
+ CV_T_32PBOOL08 = 0x0430, /* 16:32 near pointer to 8-bit Boolean */
+ CV_T_32PBOOL16 = 0x0431, /* 16:32 near pointer to 16-bit Boolean */
+ CV_T_32PBOOL32 = 0x0432, /* 16:32 near pointer to 32-bit Boolean */
+ CV_T_32PBOOL64 = 0x0433, /* 16:32 near pointer to 64-bit Boolean */
+ CV_T_32PFBOOL08 = 0x0530, /* 16:32 far pointer to 8-bit Boolean */
+ CV_T_32PFBOOL16 = 0x0531, /* 16:32 far pointer to 16-bit Boolean */
+ CV_T_32PFBOOL32 = 0x0532, /* 16:32 far pointer to 32-bit Boolean */
+ CV_T_32PFBOOL64 = 0x0533, /* 16:32 far pointer to 64-bit Boolean */
+
+ /* Non-primitive types are stored in the TYPES section (generated in
+ * cv-type.c) and start at this index (e.g. 0x1000 is the first type
+ * in TYPES, 0x1001 the second, etc.
+ */
+ CV_FIRST_NONPRIM = 0x1000
+};
+
+enum cv_leaftype {
+ /* Leaf indices for type records that can be referenced from symbols */
+ CV4_LF_MODIFIER = 0x0001, /* Type Modifier */
+ CV4_LF_POINTER = 0x0002, /* Pointer */
+ CV4_LF_ARRAY = 0x0003, /* Simple Array */
+ CV4_LF_CLASS = 0x0004, /* Classes */
+ CV4_LF_STRUCTURE = 0x0005, /* Structures */
+ CV4_LF_UNION = 0x0006, /* Unions */
+ CV4_LF_ENUM = 0x0007, /* Enumeration */
+ CV4_LF_PROCEDURE = 0x0008, /* Procedure */
+ CV4_LF_MFUNCTION = 0x0009, /* Member Function */
+ CV4_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */
+ CV4_LF_BARRAY = 0x000d, /* Basic Array */
+ CV4_LF_LABEL = 0x000e, /* Label */
+ CV4_LF_NULL = 0x000f, /* Null */
+ CV4_LF_DIMARRAY = 0x0011, /* Multiply Dimensioned Array */
+ CV4_LF_VFTPATH = 0x0012, /* Path to Virtual Function Table */
+ CV4_LF_PRECOMP = 0x0013, /* Reference Precompiled Types */
+ CV4_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */
+
+ /* CodeView 5.0 version */
+ CV5_LF_MODIFIER = 0x1001, /* Type Modifier */
+ CV5_LF_POINTER = 0x1002, /* Pointer */
+ CV5_LF_ARRAY = 0x1003, /* Simple Array */
+ CV5_LF_CLASS = 0x1004, /* Classes */
+ CV5_LF_STRUCTURE = 0x1005, /* Structures */
+ CV5_LF_UNION = 0x1006, /* Unions */
+ CV5_LF_ENUM = 0x1007, /* Enumeration */
+ CV5_LF_PROCEDURE = 0x1008, /* Procedure */
+ CV5_LF_MFUNCTION = 0x1009, /* Member Function */
+ CV5_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */
+ CV5_LF_BARRAY = 0x100d, /* Basic Array */
+ CV5_LF_LABEL = 0x000e, /* Label */
+ CV5_LF_NULL = 0x000f, /* Null */
+ CV5_LF_DIMARRAY = 0x100c, /* Multiply Dimensioned Array */
+ CV5_LF_VFTPATH = 0x100d, /* Path to Virtual Function Table */
+ CV5_LF_PRECOMP = 0x100e, /* Reference Precompiled Types */
+ CV5_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */
+ CV5_LF_TYPESERVER = 0x0016, /* Reference Typeserver */
+
+ /* Leaf indices for type records that can be referenced from other type
+ * records
+ */
+ CV4_LF_SKIP = 0x0200, /* Skip */
+ CV4_LF_ARGLIST = 0x0201, /* Argument List */
+ CV4_LF_DEFARG = 0x0202, /* Default Argument */
+ CV4_LF_LIST = 0x0203, /* Arbitrary List */
+ CV4_LF_FIELDLIST = 0x0204, /* Field List */
+ CV4_LF_DERIVED = 0x0205, /* Derived Classes */
+ CV4_LF_BITFIELD = 0x0206, /* Bit Fields */
+ CV4_LF_METHODLIST = 0x0207, /* Method List */
+ CV4_LF_DIMCONU = 0x0208, /* Dimensioned Array with Constant Upper Bound */
+ CV4_LF_DIMCONLU = 0x0209, /* Dimensioned Array with Constant Lower and Upper Bounds */
+ CV4_LF_DIMVARU = 0x020a, /* Dimensioned Array with Variable Upper Bound */
+ CV4_LF_DIMVARLU = 0x020b, /* Dimensioned Array with Variable Lower and Upper Bounds */
+ CV4_LF_REFSYM = 0x020c, /* Referenced Symbol */
+
+ /* CodeView 5.0 version */
+ CV5_LF_SKIP = 0x1200, /* Skip */
+ CV5_LF_ARGLIST = 0x1201, /* Argument List */
+ CV5_LF_DEFARG = 0x1202, /* Default Argument */
+ CV5_LF_FIELDLIST = 0x1203, /* Field List */
+ CV5_LF_DERIVED = 0x1204, /* Derived Classes */
+ CV5_LF_BITFIELD = 0x1205, /* Bit Fields */
+ CV5_LF_METHODLIST = 0x1206, /* Method List */
+ CV5_LF_DIMCONU = 0x1207, /* Dimensioned Array with Constant Upper Bound */
+ CV5_LF_DIMCONLU = 0x1208, /* Dimensioned Array with Constant Lower and Upper Bounds */
+ CV5_LF_DIMVARU = 0x1209, /* Dimensioned Array with Variable Upper Bound */
+ CV5_LF_DIMVARLU = 0x120a, /* Dimensioned Array with Variable Lower and Upper Bounds */
+ CV5_LF_REFSYM = 0x020c, /* Referenced Symbol */
+
+ /* Leaf indices for fields of complex lists */
+ CV4_LF_BCLASS = 0x0400, /* Real Base Class */
+ CV4_LF_VBCLASS = 0x0401, /* Direct Virtual Base Class */
+ CV4_LF_IVBCLASS = 0x0402, /* Indirect Virtual Base Class */
+ CV4_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */
+ CV4_LF_FRIENDFCN = 0x0404, /* Friend Function */
+ CV4_LF_INDEX = 0x0405, /* Index To Another Type Record */
+ CV4_LF_MEMBER = 0x0406, /* Data Member */
+ CV4_LF_STMEMBER = 0x0407, /* Static Data Member */
+ CV4_LF_METHOD = 0x0408, /* Method */
+ CV4_LF_NESTTYPE = 0x0409, /* Nested Type Definition */
+ CV4_LF_VFUNCTAB = 0x040a, /* Virtual Function Table Pointer */
+ CV4_LF_FRIENDCLS = 0x040b, /* Friend Class */
+ CV4_LF_ONEMETHOD = 0x040c, /* One Method */
+ CV4_LF_VFUNCOFF = 0x040d, /* Virtual Function Offset */
+
+ /* CodeView 5.0 version */
+ CV5_LF_BCLASS = 0x1400, /* Real Base Class */
+ CV5_LF_VBCLASS = 0x1401, /* Direct Virtual Base Class */
+ CV5_LF_IVBCLASS = 0x1402, /* Indirect Virtual Base Class */
+ CV5_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */
+ CV5_LF_FRIENDFCN = 0x1403, /* Friend Function */
+ CV5_LF_INDEX = 0x1404, /* Index To Another Type Record */
+ CV5_LF_MEMBER = 0x1405, /* Data Member */
+ CV5_LF_STMEMBER = 0x1406, /* Static Data Member */
+ CV5_LF_METHOD = 0x1407, /* Method */
+ CV5_LF_NESTTYPE = 0x1408, /* Nested Type Definition */
+ CV5_LF_VFUNCTAB = 0x1409, /* Virtual Function Table Pointer */
+ CV5_LF_FRIENDCLS = 0x140a, /* Friend Class */
+ CV5_LF_ONEMETHOD = 0x140b, /* One Method */
+ CV5_LF_VFUNCOFF = 0x140c, /* Virtual Function Offset */
+ CV5_LF_NESTTYPEEX = 0x140d, /* Nested Type Extended Definition */
+ CV5_LF_MEMBERMODIFY = 0x140e, /* Member Modification */
+ /* XXX: CodeView 5.0 spec also lists 0x040f as LF_MEMBERMODIFY? */
+
+ /* Leaf indices for numeric fields of symbols and type records */
+ CV_LF_NUMERIC = 0x8000,
+ CV_LF_CHAR = 0x8000, /* Signed Char (8-bit) */
+ CV_LF_SHORT = 0x8001, /* Signed Short (16-bit) */
+ CV_LF_USHORT = 0x8002, /* Unsigned Short (16-bit) */
+ CV_LF_LONG = 0x8003, /* Signed Long (32-bit) */
+ CV_LF_ULONG = 0x8004, /* Unsigned Long (32-bit) */
+ CV_LF_REAL32 = 0x8005, /* 32-bit Float */
+ CV_LF_REAL64 = 0x8006, /* 64-bit Float */
+ CV_LF_REAL80 = 0x8007, /* 80-bit Float */
+ CV_LF_REAL128 = 0x8008, /* 128-bit Float */
+ CV_LF_QUADWORD = 0x8009, /* Signed Quad Word (64-bit) */
+ CV_LF_UQUADWORD = 0x800a, /* Unsigned Quad Word (64-bit) */
+ CV_LF_REAL48 = 0x800b, /* 48-bit Float */
+ CV_LF_COMPLEX32 = 0x800c, /* 32-bit Complex */
+ CV_LF_COMPLEX64 = 0x800d, /* 64-bit Complex */
+ CV_LF_COMPLEX80 = 0x800e, /* 80-bit Complex */
+ CV_LF_COMPLEX128 = 0x800f, /* 128-bit Complex */
+ CV_LF_VARSTRING = 0x8010, /* Variable-length String */
+
+ /* Leaf padding bytes */
+ CV_LF_PAD0 = 0xf0,
+ CV_LF_PAD1 = 0xf1,
+ CV_LF_PAD2 = 0xf2,
+ CV_LF_PAD3 = 0xf3,
+ CV_LF_PAD4 = 0xf4,
+ CV_LF_PAD5 = 0xf5,
+ CV_LF_PAD6 = 0xf6,
+ CV_LF_PAD7 = 0xf7,
+ CV_LF_PAD8 = 0xf8,
+ CV_LF_PAD9 = 0xf9,
+ CV_LF_PAD10 = 0xfa,
+ CV_LF_PAD11 = 0xfb,
+ CV_LF_PAD12 = 0xfc,
+ CV_LF_PAD13 = 0xfc,
+ CV_LF_PAD14 = 0xfe,
+ CV_LF_PAD15 = 0xff
+};
+
+/* Leaves use a bit of meta-programming to encode formats: each character
+ * of format represents the output generated, as follows:
+ * 'b' : 1 byte value (integer)
+ * 'h' : 2 byte value (integer)
+ * 'w' : 4 byte value (integer)
+ * 'L' : subleaf, recurses into cv_leaf (pointer)
+ * 'T' : 4 byte type index, pulls cv_type.index from cv_type (pointer)
+ * 'S' : length-prefixed string (pointer)
+ */
+typedef struct cv_leaf {
+ enum cv_leaftype type;
+ const char *format; /* format of args */
+ union {
+ unsigned long i;
+ void *p;
+ } args[6];
+} cv_leaf;
+
+typedef struct cv_type {
+ unsigned long indx; /* type # (must be same as output order) */
+ size_t num_leaves;
+ /*@null@*/ /*@only@*/ cv_leaf **leaves;
+} cv_type;
+
+/* Bytecode callback function prototypes */
+static void cv_type_bc_destroy(void *contents);
+static void cv_type_bc_print(const void *contents, FILE *f, int indent_level);
+static int cv_type_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int cv_type_bc_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+static const yasm_bytecode_callback cv_type_bc_callback = {
+ cv_type_bc_destroy,
+ cv_type_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ cv_type_bc_calc_len,
+ yasm_bc_expand_common,
+ cv_type_bc_tobytes,
+ 0
+};
+
+static cv_type *cv_type_create(unsigned long indx);
+static void cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf);
+
+
+static cv_leaf *
+cv_leaf_create_label(int is_far)
+{
+ cv_leaf *leaf = yasm_xmalloc(sizeof(cv_leaf));
+ leaf->type = CV5_LF_LABEL;
+ leaf->format = "h";
+ leaf->args[0].i = is_far ? 4 : 0;
+ return leaf;
+}
+
+yasm_section *
+yasm_cv__generate_type(yasm_object *object)
+{
+ int new;
+ unsigned long indx = CV_FIRST_NONPRIM;
+ yasm_section *debug_type;
+ yasm_bytecode *bc;
+ cv_type *type;
+
+ debug_type =
+ yasm_object_get_general(object, ".debug$T", 1, 0, 0, &new, 0);
+
+ /* Add label type */
+ type = cv_type_create(indx++);
+ cv_type_append_leaf(type, cv_leaf_create_label(0));
+ bc = yasm_bc_create_common(&cv_type_bc_callback, type, 0);
+ yasm_bc_finalize(bc, yasm_cv__append_bc(debug_type, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+
+ return debug_type;
+}
+
+static void
+cv_leaf_destroy(cv_leaf *leaf)
+{
+ const char *ch = leaf->format;
+ int arg = 0;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ case 'h':
+ case 'w':
+ arg++;
+ break; /* nothing to destroy */
+ case 'L':
+ cv_leaf_destroy((cv_leaf *)leaf->args[arg++].p);
+ break;
+ case 'T':
+ arg++; /* nothing to destroy */
+ break;
+ case 'S':
+ yasm_xfree(leaf->args[arg++].p);
+ break;
+ default:
+ yasm_internal_error(N_("unknown leaf format character"));
+ }
+ ch++;
+ }
+}
+
+static unsigned long
+cv_leaf_size(const cv_leaf *leaf)
+{
+ const char *ch = leaf->format;
+ unsigned long len = 2; /* leaf type */
+ unsigned long slen;
+ int arg = 0;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ len++;
+ arg++;
+ break;
+ case 'h':
+ len += 2;
+ arg++;
+ break;
+ case 'w':
+ len += 4;
+ arg++;
+ break;
+ case 'L':
+ len += cv_leaf_size((const cv_leaf *)leaf->args[arg++].p);
+ break;
+ case 'T':
+ len += 4; /* XXX: will be 2 in CV4 */
+ arg++;
+ break;
+ case 'S':
+ len += 1; /* XXX: is this 1 or 2? */
+ slen = (unsigned long)strlen((const char *)leaf->args[arg++].p);
+ len += slen <= 0xff ? slen : 0xff;
+ break;
+ default:
+ yasm_internal_error(N_("unknown leaf format character"));
+ }
+ ch++;
+ }
+
+ return len;
+}
+
+static void
+cv_leaf_tobytes(const cv_leaf *leaf, yasm_bytecode *bc, yasm_arch *arch,
+ unsigned char **bufp, yasm_intnum *cval)
+{
+ unsigned char *buf = *bufp;
+ const char *ch = leaf->format;
+ size_t len;
+ int arg = 0;
+
+ /* leaf type */
+ yasm_intnum_set_uint(cval, leaf->type);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
+ buf += 2;
+
+ while (*ch) {
+ switch (*ch) {
+ case 'b':
+ YASM_WRITE_8(buf, leaf->args[arg].i);
+ arg++;
+ break;
+ case 'h':
+ yasm_intnum_set_uint(cval, leaf->args[arg++].i);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
+ buf += 2;
+ break;
+ case 'w':
+ yasm_intnum_set_uint(cval, leaf->args[arg++].i);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4;
+ break;
+ case 'L':
+ cv_leaf_tobytes((const cv_leaf *)leaf->args[arg++].p, bc, arch,
+ &buf, cval);
+ break;
+ case 'T':
+ yasm_intnum_set_uint(cval,
+ ((const cv_type *)leaf->args[arg++].p)->indx);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
+ buf += 4; /* XXX: will be 2 in CV4 */
+ break;
+ case 'S':
+ len = strlen((const char *)leaf->args[arg].p);
+ len = len <= 0xff ? len : 0xff;
+ YASM_WRITE_8(buf, len);
+ memcpy(buf, (const char *)leaf->args[arg].p, len);
+ buf += len;
+ arg++;
+ break;
+ default:
+ yasm_internal_error(N_("unknown leaf format character"));
+ }
+ ch++;
+ }
+
+ *bufp = buf;
+}
+
+static cv_type *
+cv_type_create(unsigned long indx)
+{
+ cv_type *type = yasm_xmalloc(sizeof(cv_type));
+
+ type->indx = indx;
+ type->num_leaves = 0;
+ type->leaves = NULL;
+
+ return type;
+}
+
+static void
+cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf)
+{
+ type->num_leaves++;
+
+ /* This is inefficient for large numbers of leaves, but that won't happen
+ * until we add structure support.
+ */
+ type->leaves = yasm_xrealloc(type->leaves,
+ type->num_leaves*sizeof(cv_leaf *));
+
+ type->leaves[type->num_leaves-1] = leaf;
+}
+
+static void
+cv_type_bc_destroy(void *contents)
+{
+ cv_type *type = (cv_type *)contents;
+ size_t i;
+
+ for (i=0; i<type->num_leaves; i++)
+ cv_leaf_destroy(type->leaves[i]);
+ if (type->leaves)
+ yasm_xfree(type->leaves);
+ yasm_xfree(contents);
+}
+
+static void
+cv_type_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+cv_type_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ cv_type *type = (cv_type *)bc->contents;
+ size_t i;
+
+ if (type->indx == CV_FIRST_NONPRIM)
+ bc->len = 4+2;
+ else
+ bc->len = 2;
+
+ for (i=0; i<type->num_leaves; i++)
+ bc->len += cv_leaf_size(type->leaves[i]);
+
+ /* Pad to multiple of 4 */
+ if (bc->len & 0x3)
+ bc->len += 4-(bc->len & 0x3);
+
+ return 0;
+}
+
+static int
+cv_type_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ yasm_object *object = yasm_section_get_object(bc->section);
+ cv_type *type = (cv_type *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *cval;
+ size_t i;
+ unsigned long reclen = bc->len - 2;
+
+ cval = yasm_intnum_create_uint(4); /* version */
+ if (type->indx == CV_FIRST_NONPRIM) {
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 1);
+ buf += 4;
+ reclen -= 4;
+ }
+
+ /* Total length of record (following this field) - 2 bytes */
+ yasm_intnum_set_uint(cval, reclen);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1);
+ buf += 2;
+
+ /* Leaves */
+ for (i=0; i<type->num_leaves; i++)
+ cv_leaf_tobytes(type->leaves[i], bc, object->arch, &buf, cval);
+
+ /* Pad to multiple of 4 */
+ switch ((buf-(*bufp)) & 0x3) {
+ case 3:
+ YASM_WRITE_8(buf, CV_LF_PAD3);
+ case 2:
+ YASM_WRITE_8(buf, CV_LF_PAD2);
+ case 1:
+ YASM_WRITE_8(buf, CV_LF_PAD1);
+ case 0:
+ break;
+ }
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}