aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/yasm/modules/dbgfmts
diff options
context:
space:
mode:
authorsomov <somov@yandex-team.ru>2022-02-10 16:45:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:49 +0300
commit7489e4682331202b9c7d863c0898eb83d7b12c2b (patch)
tree9142afc54d335ea52910662635b898e79e192e49 /contrib/tools/yasm/modules/dbgfmts
parenta5950576e397b1909261050b8c7da16db58f10b1 (diff)
downloadydb-7489e4682331202b9c7d863c0898eb83d7b12c2b.tar.gz
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/yasm/modules/dbgfmts')
-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
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c250
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c696
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h262
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-info.c854
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-line.c2282
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/null/null-dbgfmt.c128
-rw-r--r--contrib/tools/yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c1020
11 files changed, 4791 insertions, 4791 deletions
diff --git a/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c b/contrib/tools/yasm/modules/dbgfmts/codeview/cv-dbgfmt.c
index 285478dbb6..9b06fe3495 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 d3bbb024e0..134b0b885b 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 396def57e2..8d7030221f 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 ebccbdeda9..2a52f18436 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;
+}
diff --git a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c
index a184a01575..f398b7fa72 100644
--- a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c
+++ b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c
@@ -1,125 +1,125 @@
-/*
- * DWARF2 debugging format - address range table
- *
- * 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 "dwarf2-dbgfmt.h"
-
-
-static void
-dwarf2_append_arange(yasm_section *debug_aranges, /*@only@*/ yasm_expr *start,
- /*@only@*/ yasm_expr *length, unsigned int sizeof_address)
-{
- yasm_datavalhead dvs;
- yasm_bytecode *bc;
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_expr(start));
- yasm_dvs_append(&dvs, yasm_dv_create_expr(length));
- bc = yasm_bc_create_data(&dvs, sizeof_address, 0, NULL, 0);
- yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-}
-
-typedef struct dwarf2_aranges_info {
- yasm_section *debug_aranges; /* section to which address ranges go */
- yasm_object *object;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
-} dwarf2_aranges_info;
-
-static int
-dwarf2_generate_aranges_section(yasm_section *sect, /*@null@*/ void *d)
-{
- dwarf2_aranges_info *info = (dwarf2_aranges_info *)d;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
- /*@null@*/ dwarf2_section_data *dsd;
- /*@only@*/ yasm_expr *start, *length;
-
- dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
- if (!dsd)
- return 0; /* no line data for this section */
-
- /* Create address range descriptor */
- start = yasm_expr_create_ident(
- yasm_expr_sym(yasm_dwarf2__bc_sym(info->object->symtab,
- yasm_section_bcs_first(sect))), 0);
- length = yasm_expr_create_ident(
- yasm_expr_int(yasm_calc_bc_dist(yasm_section_bcs_first(sect),
- yasm_section_bcs_last(sect))), 0);
- dwarf2_append_arange(info->debug_aranges, start, length,
- dbgfmt_dwarf2->sizeof_address);
-
- return 0;
-}
-
-yasm_section *
-yasm_dwarf2__generate_aranges(yasm_object *object, yasm_section *debug_info)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- int new;
- yasm_section *debug_aranges;
- yasm_bytecode *bc;
- dwarf2_head *head;
- dwarf2_aranges_info info;
-
- debug_aranges =
- yasm_object_get_general(object, ".debug_aranges",
- 2*dbgfmt_dwarf2->sizeof_address, 0, 0, &new,
- 0);
-
- /* header */
- head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_aranges, debug_info, 1,
- 1);
-
- /* align ranges to 2x address size (range size) */
- bc = yasm_bc_create_align(
- yasm_expr_create_ident(yasm_expr_int(
- yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_address*2)), 0),
- NULL, NULL, NULL, 0);
- yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-
- info.debug_aranges = debug_aranges;
- info.object = object;
- info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
-
- yasm_object_sections_traverse(object, (void *)&info,
- dwarf2_generate_aranges_section);
-
- /* Terminate with empty address range descriptor */
- dwarf2_append_arange(debug_aranges,
- yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
- yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
- dbgfmt_dwarf2->sizeof_address);
-
- /* mark end of aranges information */
- yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_aranges));
-
- return debug_aranges;
-}
-
+/*
+ * DWARF2 debugging format - address range table
+ *
+ * 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 "dwarf2-dbgfmt.h"
+
+
+static void
+dwarf2_append_arange(yasm_section *debug_aranges, /*@only@*/ yasm_expr *start,
+ /*@only@*/ yasm_expr *length, unsigned int sizeof_address)
+{
+ yasm_datavalhead dvs;
+ yasm_bytecode *bc;
+
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(start));
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(length));
+ bc = yasm_bc_create_data(&dvs, sizeof_address, 0, NULL, 0);
+ yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+}
+
+typedef struct dwarf2_aranges_info {
+ yasm_section *debug_aranges; /* section to which address ranges go */
+ yasm_object *object;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
+} dwarf2_aranges_info;
+
+static int
+dwarf2_generate_aranges_section(yasm_section *sect, /*@null@*/ void *d)
+{
+ dwarf2_aranges_info *info = (dwarf2_aranges_info *)d;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
+ /*@null@*/ dwarf2_section_data *dsd;
+ /*@only@*/ yasm_expr *start, *length;
+
+ dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
+ if (!dsd)
+ return 0; /* no line data for this section */
+
+ /* Create address range descriptor */
+ start = yasm_expr_create_ident(
+ yasm_expr_sym(yasm_dwarf2__bc_sym(info->object->symtab,
+ yasm_section_bcs_first(sect))), 0);
+ length = yasm_expr_create_ident(
+ yasm_expr_int(yasm_calc_bc_dist(yasm_section_bcs_first(sect),
+ yasm_section_bcs_last(sect))), 0);
+ dwarf2_append_arange(info->debug_aranges, start, length,
+ dbgfmt_dwarf2->sizeof_address);
+
+ return 0;
+}
+
+yasm_section *
+yasm_dwarf2__generate_aranges(yasm_object *object, yasm_section *debug_info)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ int new;
+ yasm_section *debug_aranges;
+ yasm_bytecode *bc;
+ dwarf2_head *head;
+ dwarf2_aranges_info info;
+
+ debug_aranges =
+ yasm_object_get_general(object, ".debug_aranges",
+ 2*dbgfmt_dwarf2->sizeof_address, 0, 0, &new,
+ 0);
+
+ /* header */
+ head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_aranges, debug_info, 1,
+ 1);
+
+ /* align ranges to 2x address size (range size) */
+ bc = yasm_bc_create_align(
+ yasm_expr_create_ident(yasm_expr_int(
+ yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_address*2)), 0),
+ NULL, NULL, NULL, 0);
+ yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+
+ info.debug_aranges = debug_aranges;
+ info.object = object;
+ info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
+
+ yasm_object_sections_traverse(object, (void *)&info,
+ dwarf2_generate_aranges_section);
+
+ /* Terminate with empty address range descriptor */
+ dwarf2_append_arange(debug_aranges,
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
+ dbgfmt_dwarf2->sizeof_address);
+
+ /* mark end of aranges information */
+ yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_aranges));
+
+ return debug_aranges;
+}
+
diff --git a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
index a8c2a548c7..5b66f8a70f 100644
--- a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
+++ b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
@@ -1,348 +1,348 @@
-/*
- * DWARF2 debugging format
- *
- * 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 "dwarf2-dbgfmt.h"
-
-struct dwarf2_head {
- yasm_bytecode *start_prevbc;
- yasm_bytecode *end_prevbc;
- /*@null@*/ yasm_section *debug_ptr;
- int with_address;
- int with_segment;
-};
-
-/* Bytecode callback function prototypes */
-static void dwarf2_head_bc_destroy(void *contents);
-static void dwarf2_head_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int dwarf2_head_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int dwarf2_head_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 dwarf2_head_bc_callback = {
- dwarf2_head_bc_destroy,
- dwarf2_head_bc_print,
- yasm_bc_finalize_common,
- NULL,
- dwarf2_head_bc_calc_len,
- yasm_bc_expand_common,
- dwarf2_head_bc_tobytes,
- 0
-};
-
-/* Section data callback function prototypes */
-static void dwarf2_section_data_destroy(void *data);
-static void dwarf2_section_data_print(void *data, FILE *f, int indent_level);
-
-/* Section data callback */
-const yasm_assoc_data_callback yasm_dwarf2__section_data_cb = {
- dwarf2_section_data_destroy,
- dwarf2_section_data_print
-};
-
-yasm_dbgfmt_module yasm_dwarf2_LTX_dbgfmt;
-
-
-static /*@null@*/ /*@only@*/ yasm_dbgfmt *
-dwarf2_dbgfmt_create(yasm_object *object)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 =
- yasm_xmalloc(sizeof(yasm_dbgfmt_dwarf2));
- size_t i;
-
- dbgfmt_dwarf2->dbgfmt.module = &yasm_dwarf2_LTX_dbgfmt;
-
- dbgfmt_dwarf2->dirs_allocated = 32;
- dbgfmt_dwarf2->dirs_size = 0;
- dbgfmt_dwarf2->dirs =
- yasm_xmalloc(sizeof(char *)*dbgfmt_dwarf2->dirs_allocated);
-
- dbgfmt_dwarf2->filenames_allocated = 32;
- dbgfmt_dwarf2->filenames_size = 0;
- dbgfmt_dwarf2->filenames =
- yasm_xmalloc(sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated);
- for (i=0; i<dbgfmt_dwarf2->filenames_allocated; i++) {
- dbgfmt_dwarf2->filenames[i].pathname = NULL;
- dbgfmt_dwarf2->filenames[i].filename = NULL;
- dbgfmt_dwarf2->filenames[i].dir = 0;
- }
-
- dbgfmt_dwarf2->format = DWARF2_FORMAT_32BIT; /* TODO: flexible? */
-
- dbgfmt_dwarf2->sizeof_address = yasm_arch_get_address_size(object->arch)/8;
- switch (dbgfmt_dwarf2->format) {
- case DWARF2_FORMAT_32BIT:
- dbgfmt_dwarf2->sizeof_offset = 4;
- break;
- case DWARF2_FORMAT_64BIT:
- dbgfmt_dwarf2->sizeof_offset = 8;
- break;
- }
- dbgfmt_dwarf2->min_insn_len = yasm_arch_min_insn_len(object->arch);
-
- return (yasm_dbgfmt *)dbgfmt_dwarf2;
-}
-
-static void
-dwarf2_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)dbgfmt;
- size_t i;
- for (i=0; i<dbgfmt_dwarf2->dirs_size; i++)
- if (dbgfmt_dwarf2->dirs[i])
- yasm_xfree(dbgfmt_dwarf2->dirs[i]);
- yasm_xfree(dbgfmt_dwarf2->dirs);
- for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
- if (dbgfmt_dwarf2->filenames[i].pathname)
- yasm_xfree(dbgfmt_dwarf2->filenames[i].pathname);
- if (dbgfmt_dwarf2->filenames[i].filename)
- yasm_xfree(dbgfmt_dwarf2->filenames[i].filename);
- }
- yasm_xfree(dbgfmt_dwarf2->filenames);
- yasm_xfree(dbgfmt);
-}
-
-/* Add a bytecode to a section, updating offset on insertion;
- * no optimization necessary.
- */
-yasm_bytecode *
-yasm_dwarf2__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
-dwarf2_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- size_t num_line_sections;
- /*@null@*/ yasm_section *debug_info, *debug_line, *main_code;
-
- /* If we don't have any .file directives, generate line information
- * based on the asm source.
- */
- debug_line = yasm_dwarf2__generate_line(object, linemap, errwarns,
- dbgfmt_dwarf2->filenames_size == 0,
- &main_code, &num_line_sections);
-
- /* If we don't have a .debug_info (or it's empty), generate the minimal
- * set of .debug_info, .debug_aranges, and .debug_abbrev so that the
- * .debug_line we're generating is actually useful.
- */
- debug_info = yasm_object_find_general(object, ".debug_info");
- if (num_line_sections > 0 &&
- (!debug_info || yasm_section_bcs_first(debug_info)
- == yasm_section_bcs_last(debug_info))) {
- debug_info = yasm_dwarf2__generate_info(object, debug_line, main_code);
- yasm_dwarf2__generate_aranges(object, debug_info);
- /*yasm_dwarf2__generate_pubnames(object, debug_info);*/
- }
-}
-
-yasm_symrec *
-yasm_dwarf2__bc_sym(yasm_symtab *symtab, yasm_bytecode *bc)
-{
- /*@dependent@*/ yasm_symrec *sym;
- if (bc->symrecs && bc->symrecs[0])
- sym = bc->symrecs[0];
- else
- sym = yasm_symtab_define_label(symtab, ".bcsym", bc, 0, 0);
- return sym;
-}
-
-dwarf2_head *
-yasm_dwarf2__add_head
- (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_section *sect,
- /*@null@*/ yasm_section *debug_ptr, int with_address, int with_segment)
-{
- dwarf2_head *head;
- yasm_bytecode *bc;
-
- head = yasm_xmalloc(sizeof(dwarf2_head));
- head->start_prevbc = yasm_section_bcs_last(sect);
-
- bc = yasm_bc_create_common(&dwarf2_head_bc_callback, head, 0);
- bc->len = dbgfmt_dwarf2->sizeof_offset + 2;
- if (dbgfmt_dwarf2->format == DWARF2_FORMAT_64BIT)
- bc->len += 4;
-
- if (debug_ptr) {
- head->debug_ptr = debug_ptr;
- bc->len += dbgfmt_dwarf2->sizeof_offset;
- } else
- head->debug_ptr = NULL;
-
- head->with_address = with_address;
- head->with_segment = with_segment;
- if (with_address)
- bc->len++;
- if (with_segment)
- bc->len++;
-
- head->end_prevbc = bc;
- yasm_dwarf2__append_bc(sect, bc);
- return head;
-}
-
-void
-yasm_dwarf2__set_head_end(dwarf2_head *head, yasm_bytecode *end_prevbc)
-{
- head->end_prevbc = end_prevbc;
-}
-
-static void
-dwarf2_head_bc_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-dwarf2_head_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-dwarf2_head_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 dwarf2 head bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-dwarf2_head_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);
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- dwarf2_head *head = (dwarf2_head *)bc->contents;
- unsigned char *buf = *bufp;
- yasm_intnum *intn, *cval;
-
- if (dbgfmt_dwarf2->format == DWARF2_FORMAT_64BIT) {
- YASM_WRITE_8(buf, 0xff);
- YASM_WRITE_8(buf, 0xff);
- YASM_WRITE_8(buf, 0xff);
- YASM_WRITE_8(buf, 0xff);
- }
-
- /* Total length of aranges info (following this field) */
- cval = yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_offset);
- 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,
- dbgfmt_dwarf2->sizeof_offset,
- dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
- buf += dbgfmt_dwarf2->sizeof_offset;
- yasm_intnum_destroy(intn);
-
- /* DWARF version */
- yasm_intnum_set_uint(cval, 2);
- yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
- buf += 2;
-
- /* Pointer to another debug section */
- if (head->debug_ptr) {
- yasm_value value;
- yasm_value_init_sym(&value,
- yasm_dwarf2__bc_sym(object->symtab,
- yasm_section_bcs_first(head->debug_ptr)),
- dbgfmt_dwarf2->sizeof_offset*8);
- output_value(&value, buf, dbgfmt_dwarf2->sizeof_offset,
- (unsigned long)(buf-bufstart), bc, 0, d);
- buf += dbgfmt_dwarf2->sizeof_offset;
- }
-
- /* Size of the offset portion of the address */
- if (head->with_address)
- YASM_WRITE_8(buf, dbgfmt_dwarf2->sizeof_address);
-
- /* Size of a segment descriptor. 0 = flat address space */
- if (head->with_segment)
- YASM_WRITE_8(buf, 0);
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
-
-static void
-dwarf2_section_data_destroy(void *data)
-{
- dwarf2_section_data *dsd = data;
- dwarf2_loc *n1, *n2;
-
- /* Delete locations */
- n1 = STAILQ_FIRST(&dsd->locs);
- while (n1) {
- n2 = STAILQ_NEXT(n1, link);
- yasm_xfree(n1);
- n1 = n2;
- }
-
- yasm_xfree(data);
-}
-
-static void
-dwarf2_section_data_print(void *data, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static const yasm_directive dwarf2_directives[] = {
- { ".loc", "gas", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
- { ".file", "gas", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
- { "loc", "nasm", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
- { "file", "nasm", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
- { NULL, NULL, NULL, 0 }
-};
-
-/* Define dbgfmt structure -- see dbgfmt.h for details */
-yasm_dbgfmt_module yasm_dwarf2_LTX_dbgfmt = {
- "DWARF2 debugging format",
- "dwarf2",
- dwarf2_directives,
- dwarf2_dbgfmt_create,
- dwarf2_dbgfmt_destroy,
- dwarf2_dbgfmt_generate
-};
+/*
+ * DWARF2 debugging format
+ *
+ * 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 "dwarf2-dbgfmt.h"
+
+struct dwarf2_head {
+ yasm_bytecode *start_prevbc;
+ yasm_bytecode *end_prevbc;
+ /*@null@*/ yasm_section *debug_ptr;
+ int with_address;
+ int with_segment;
+};
+
+/* Bytecode callback function prototypes */
+static void dwarf2_head_bc_destroy(void *contents);
+static void dwarf2_head_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int dwarf2_head_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int dwarf2_head_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 dwarf2_head_bc_callback = {
+ dwarf2_head_bc_destroy,
+ dwarf2_head_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ dwarf2_head_bc_calc_len,
+ yasm_bc_expand_common,
+ dwarf2_head_bc_tobytes,
+ 0
+};
+
+/* Section data callback function prototypes */
+static void dwarf2_section_data_destroy(void *data);
+static void dwarf2_section_data_print(void *data, FILE *f, int indent_level);
+
+/* Section data callback */
+const yasm_assoc_data_callback yasm_dwarf2__section_data_cb = {
+ dwarf2_section_data_destroy,
+ dwarf2_section_data_print
+};
+
+yasm_dbgfmt_module yasm_dwarf2_LTX_dbgfmt;
+
+
+static /*@null@*/ /*@only@*/ yasm_dbgfmt *
+dwarf2_dbgfmt_create(yasm_object *object)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 =
+ yasm_xmalloc(sizeof(yasm_dbgfmt_dwarf2));
+ size_t i;
+
+ dbgfmt_dwarf2->dbgfmt.module = &yasm_dwarf2_LTX_dbgfmt;
+
+ dbgfmt_dwarf2->dirs_allocated = 32;
+ dbgfmt_dwarf2->dirs_size = 0;
+ dbgfmt_dwarf2->dirs =
+ yasm_xmalloc(sizeof(char *)*dbgfmt_dwarf2->dirs_allocated);
+
+ dbgfmt_dwarf2->filenames_allocated = 32;
+ dbgfmt_dwarf2->filenames_size = 0;
+ dbgfmt_dwarf2->filenames =
+ yasm_xmalloc(sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated);
+ for (i=0; i<dbgfmt_dwarf2->filenames_allocated; i++) {
+ dbgfmt_dwarf2->filenames[i].pathname = NULL;
+ dbgfmt_dwarf2->filenames[i].filename = NULL;
+ dbgfmt_dwarf2->filenames[i].dir = 0;
+ }
+
+ dbgfmt_dwarf2->format = DWARF2_FORMAT_32BIT; /* TODO: flexible? */
+
+ dbgfmt_dwarf2->sizeof_address = yasm_arch_get_address_size(object->arch)/8;
+ switch (dbgfmt_dwarf2->format) {
+ case DWARF2_FORMAT_32BIT:
+ dbgfmt_dwarf2->sizeof_offset = 4;
+ break;
+ case DWARF2_FORMAT_64BIT:
+ dbgfmt_dwarf2->sizeof_offset = 8;
+ break;
+ }
+ dbgfmt_dwarf2->min_insn_len = yasm_arch_min_insn_len(object->arch);
+
+ return (yasm_dbgfmt *)dbgfmt_dwarf2;
+}
+
+static void
+dwarf2_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)dbgfmt;
+ size_t i;
+ for (i=0; i<dbgfmt_dwarf2->dirs_size; i++)
+ if (dbgfmt_dwarf2->dirs[i])
+ yasm_xfree(dbgfmt_dwarf2->dirs[i]);
+ yasm_xfree(dbgfmt_dwarf2->dirs);
+ for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
+ if (dbgfmt_dwarf2->filenames[i].pathname)
+ yasm_xfree(dbgfmt_dwarf2->filenames[i].pathname);
+ if (dbgfmt_dwarf2->filenames[i].filename)
+ yasm_xfree(dbgfmt_dwarf2->filenames[i].filename);
+ }
+ yasm_xfree(dbgfmt_dwarf2->filenames);
+ yasm_xfree(dbgfmt);
+}
+
+/* Add a bytecode to a section, updating offset on insertion;
+ * no optimization necessary.
+ */
+yasm_bytecode *
+yasm_dwarf2__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
+dwarf2_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ size_t num_line_sections;
+ /*@null@*/ yasm_section *debug_info, *debug_line, *main_code;
+
+ /* If we don't have any .file directives, generate line information
+ * based on the asm source.
+ */
+ debug_line = yasm_dwarf2__generate_line(object, linemap, errwarns,
+ dbgfmt_dwarf2->filenames_size == 0,
+ &main_code, &num_line_sections);
+
+ /* If we don't have a .debug_info (or it's empty), generate the minimal
+ * set of .debug_info, .debug_aranges, and .debug_abbrev so that the
+ * .debug_line we're generating is actually useful.
+ */
+ debug_info = yasm_object_find_general(object, ".debug_info");
+ if (num_line_sections > 0 &&
+ (!debug_info || yasm_section_bcs_first(debug_info)
+ == yasm_section_bcs_last(debug_info))) {
+ debug_info = yasm_dwarf2__generate_info(object, debug_line, main_code);
+ yasm_dwarf2__generate_aranges(object, debug_info);
+ /*yasm_dwarf2__generate_pubnames(object, debug_info);*/
+ }
+}
+
+yasm_symrec *
+yasm_dwarf2__bc_sym(yasm_symtab *symtab, yasm_bytecode *bc)
+{
+ /*@dependent@*/ yasm_symrec *sym;
+ if (bc->symrecs && bc->symrecs[0])
+ sym = bc->symrecs[0];
+ else
+ sym = yasm_symtab_define_label(symtab, ".bcsym", bc, 0, 0);
+ return sym;
+}
+
+dwarf2_head *
+yasm_dwarf2__add_head
+ (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_section *sect,
+ /*@null@*/ yasm_section *debug_ptr, int with_address, int with_segment)
+{
+ dwarf2_head *head;
+ yasm_bytecode *bc;
+
+ head = yasm_xmalloc(sizeof(dwarf2_head));
+ head->start_prevbc = yasm_section_bcs_last(sect);
+
+ bc = yasm_bc_create_common(&dwarf2_head_bc_callback, head, 0);
+ bc->len = dbgfmt_dwarf2->sizeof_offset + 2;
+ if (dbgfmt_dwarf2->format == DWARF2_FORMAT_64BIT)
+ bc->len += 4;
+
+ if (debug_ptr) {
+ head->debug_ptr = debug_ptr;
+ bc->len += dbgfmt_dwarf2->sizeof_offset;
+ } else
+ head->debug_ptr = NULL;
+
+ head->with_address = with_address;
+ head->with_segment = with_segment;
+ if (with_address)
+ bc->len++;
+ if (with_segment)
+ bc->len++;
+
+ head->end_prevbc = bc;
+ yasm_dwarf2__append_bc(sect, bc);
+ return head;
+}
+
+void
+yasm_dwarf2__set_head_end(dwarf2_head *head, yasm_bytecode *end_prevbc)
+{
+ head->end_prevbc = end_prevbc;
+}
+
+static void
+dwarf2_head_bc_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+dwarf2_head_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+dwarf2_head_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 dwarf2 head bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+dwarf2_head_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);
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ dwarf2_head *head = (dwarf2_head *)bc->contents;
+ unsigned char *buf = *bufp;
+ yasm_intnum *intn, *cval;
+
+ if (dbgfmt_dwarf2->format == DWARF2_FORMAT_64BIT) {
+ YASM_WRITE_8(buf, 0xff);
+ YASM_WRITE_8(buf, 0xff);
+ YASM_WRITE_8(buf, 0xff);
+ YASM_WRITE_8(buf, 0xff);
+ }
+
+ /* Total length of aranges info (following this field) */
+ cval = yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_offset);
+ 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,
+ dbgfmt_dwarf2->sizeof_offset,
+ dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
+ buf += dbgfmt_dwarf2->sizeof_offset;
+ yasm_intnum_destroy(intn);
+
+ /* DWARF version */
+ yasm_intnum_set_uint(cval, 2);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
+ buf += 2;
+
+ /* Pointer to another debug section */
+ if (head->debug_ptr) {
+ yasm_value value;
+ yasm_value_init_sym(&value,
+ yasm_dwarf2__bc_sym(object->symtab,
+ yasm_section_bcs_first(head->debug_ptr)),
+ dbgfmt_dwarf2->sizeof_offset*8);
+ output_value(&value, buf, dbgfmt_dwarf2->sizeof_offset,
+ (unsigned long)(buf-bufstart), bc, 0, d);
+ buf += dbgfmt_dwarf2->sizeof_offset;
+ }
+
+ /* Size of the offset portion of the address */
+ if (head->with_address)
+ YASM_WRITE_8(buf, dbgfmt_dwarf2->sizeof_address);
+
+ /* Size of a segment descriptor. 0 = flat address space */
+ if (head->with_segment)
+ YASM_WRITE_8(buf, 0);
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
+
+static void
+dwarf2_section_data_destroy(void *data)
+{
+ dwarf2_section_data *dsd = data;
+ dwarf2_loc *n1, *n2;
+
+ /* Delete locations */
+ n1 = STAILQ_FIRST(&dsd->locs);
+ while (n1) {
+ n2 = STAILQ_NEXT(n1, link);
+ yasm_xfree(n1);
+ n1 = n2;
+ }
+
+ yasm_xfree(data);
+}
+
+static void
+dwarf2_section_data_print(void *data, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static const yasm_directive dwarf2_directives[] = {
+ { ".loc", "gas", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
+ { ".file", "gas", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
+ { "loc", "nasm", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
+ { "file", "nasm", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
+ { NULL, NULL, NULL, 0 }
+};
+
+/* Define dbgfmt structure -- see dbgfmt.h for details */
+yasm_dbgfmt_module yasm_dwarf2_LTX_dbgfmt = {
+ "DWARF2 debugging format",
+ "dwarf2",
+ dwarf2_directives,
+ dwarf2_dbgfmt_create,
+ dwarf2_dbgfmt_destroy,
+ dwarf2_dbgfmt_generate
+};
diff --git a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
index 9f4b1e1d1c..03752345cd 100644
--- a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
+++ b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
@@ -1,131 +1,131 @@
-/*
- * DWARF2 debugging format
- *
- * 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_DWARF2_DBGFMT_H
-#define YASM_DWARF2_DBGFMT_H
-
-#define WITH_DWARF3 1
-
-typedef struct {
- char *pathname; /* full filename */
- char *filename; /* basename of full filename */
- unsigned long dir; /* index into directories array for relative path;
- * 0 for current directory. */
-} dwarf2_filename;
-
-/* Global data */
-typedef struct yasm_dbgfmt_dwarf2 {
- yasm_dbgfmt_base dbgfmt; /* base structure */
-
- char **dirs;
- unsigned long dirs_size;
- unsigned long dirs_allocated;
-
- dwarf2_filename *filenames;
- unsigned long filenames_size;
- unsigned long filenames_allocated;
-
- enum {
- DWARF2_FORMAT_32BIT,
- DWARF2_FORMAT_64BIT
- } format;
-
- unsigned int sizeof_address, sizeof_offset, min_insn_len;
-} yasm_dbgfmt_dwarf2;
-
-/* .loc directive data */
-typedef struct dwarf2_loc {
- /*@reldef@*/ STAILQ_ENTRY(dwarf2_loc) link;
-
- unsigned long vline; /* virtual line number of .loc directive */
-
- /* source information */
- unsigned long file; /* index into table of filenames */
- unsigned long line; /* source line number */
- unsigned long column; /* source column */
- unsigned long discriminator;
- int isa_change;
- unsigned long isa;
- enum {
- IS_STMT_NOCHANGE = 0,
- IS_STMT_SET,
- IS_STMT_CLEAR
- } is_stmt;
- int basic_block;
- int prologue_end;
- int epilogue_begin;
-
- yasm_bytecode *bc; /* first bytecode following */
- yasm_symrec *sym; /* last symbol preceding */
-} dwarf2_loc;
-
-/* Per-section data */
-typedef struct dwarf2_section_data {
- /* The locations set by the .loc directives in this section, in assembly
- * source order.
- */
- /*@reldef@*/ STAILQ_HEAD(dwarf2_lochead, dwarf2_loc) locs;
-} dwarf2_section_data;
-
-extern const yasm_assoc_data_callback yasm_dwarf2__section_data_cb;
-
-yasm_bytecode *yasm_dwarf2__append_bc(yasm_section *sect, yasm_bytecode *bc);
-
-/*@dependent@*/ yasm_symrec *yasm_dwarf2__bc_sym(yasm_symtab *symtab,
- yasm_bytecode *bc);
-
-typedef struct dwarf2_head dwarf2_head;
-dwarf2_head *yasm_dwarf2__add_head
- (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_section *sect,
- /*@null@*/ yasm_section *debug_ptr, int with_address, int with_segment);
-void yasm_dwarf2__set_head_end(dwarf2_head *head, yasm_bytecode *end_prevbc);
-
-/* Line number functions */
-yasm_section *yasm_dwarf2__generate_line
- (yasm_object *object, yasm_linemap *linemap, yasm_errwarns *errwarns,
- int asm_source, /*@out@*/ yasm_section **main_code,
- /*@out@*/ size_t *num_line_sections);
-void yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams,
- unsigned long line);
-void yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams,
- unsigned long line);
-
-/* Address range table functions */
-yasm_section *yasm_dwarf2__generate_aranges(yasm_object *object,
- yasm_section *debug_info);
-
-/* Name lookup table functions */
-yasm_section *yasm_dwarf2__generate_pubnames(yasm_object *object,
- yasm_section *debug_info);
-
-/* Information functions */
-yasm_section *yasm_dwarf2__generate_info
- (yasm_object *object, yasm_section *debug_line,
- /*@null@*/ yasm_section *main_code);
-
-#endif
+/*
+ * DWARF2 debugging format
+ *
+ * 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_DWARF2_DBGFMT_H
+#define YASM_DWARF2_DBGFMT_H
+
+#define WITH_DWARF3 1
+
+typedef struct {
+ char *pathname; /* full filename */
+ char *filename; /* basename of full filename */
+ unsigned long dir; /* index into directories array for relative path;
+ * 0 for current directory. */
+} dwarf2_filename;
+
+/* Global data */
+typedef struct yasm_dbgfmt_dwarf2 {
+ yasm_dbgfmt_base dbgfmt; /* base structure */
+
+ char **dirs;
+ unsigned long dirs_size;
+ unsigned long dirs_allocated;
+
+ dwarf2_filename *filenames;
+ unsigned long filenames_size;
+ unsigned long filenames_allocated;
+
+ enum {
+ DWARF2_FORMAT_32BIT,
+ DWARF2_FORMAT_64BIT
+ } format;
+
+ unsigned int sizeof_address, sizeof_offset, min_insn_len;
+} yasm_dbgfmt_dwarf2;
+
+/* .loc directive data */
+typedef struct dwarf2_loc {
+ /*@reldef@*/ STAILQ_ENTRY(dwarf2_loc) link;
+
+ unsigned long vline; /* virtual line number of .loc directive */
+
+ /* source information */
+ unsigned long file; /* index into table of filenames */
+ unsigned long line; /* source line number */
+ unsigned long column; /* source column */
+ unsigned long discriminator;
+ int isa_change;
+ unsigned long isa;
+ enum {
+ IS_STMT_NOCHANGE = 0,
+ IS_STMT_SET,
+ IS_STMT_CLEAR
+ } is_stmt;
+ int basic_block;
+ int prologue_end;
+ int epilogue_begin;
+
+ yasm_bytecode *bc; /* first bytecode following */
+ yasm_symrec *sym; /* last symbol preceding */
+} dwarf2_loc;
+
+/* Per-section data */
+typedef struct dwarf2_section_data {
+ /* The locations set by the .loc directives in this section, in assembly
+ * source order.
+ */
+ /*@reldef@*/ STAILQ_HEAD(dwarf2_lochead, dwarf2_loc) locs;
+} dwarf2_section_data;
+
+extern const yasm_assoc_data_callback yasm_dwarf2__section_data_cb;
+
+yasm_bytecode *yasm_dwarf2__append_bc(yasm_section *sect, yasm_bytecode *bc);
+
+/*@dependent@*/ yasm_symrec *yasm_dwarf2__bc_sym(yasm_symtab *symtab,
+ yasm_bytecode *bc);
+
+typedef struct dwarf2_head dwarf2_head;
+dwarf2_head *yasm_dwarf2__add_head
+ (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_section *sect,
+ /*@null@*/ yasm_section *debug_ptr, int with_address, int with_segment);
+void yasm_dwarf2__set_head_end(dwarf2_head *head, yasm_bytecode *end_prevbc);
+
+/* Line number functions */
+yasm_section *yasm_dwarf2__generate_line
+ (yasm_object *object, yasm_linemap *linemap, yasm_errwarns *errwarns,
+ int asm_source, /*@out@*/ yasm_section **main_code,
+ /*@out@*/ size_t *num_line_sections);
+void yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams,
+ unsigned long line);
+void yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams,
+ unsigned long line);
+
+/* Address range table functions */
+yasm_section *yasm_dwarf2__generate_aranges(yasm_object *object,
+ yasm_section *debug_info);
+
+/* Name lookup table functions */
+yasm_section *yasm_dwarf2__generate_pubnames(yasm_object *object,
+ yasm_section *debug_info);
+
+/* Information functions */
+yasm_section *yasm_dwarf2__generate_info
+ (yasm_object *object, yasm_section *debug_line,
+ /*@null@*/ yasm_section *main_code);
+
+#endif
diff --git a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-info.c b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-info.c
index fd8c406926..96d24db06a 100644
--- a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-info.c
+++ b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-info.c
@@ -1,438 +1,438 @@
-/*
- * DWARF2 debugging format - info and abbreviation tables
- *
- * 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 "dwarf2-dbgfmt.h"
-
-#define DW_LANG_Mips_Assembler 0x8001
-
-/* Tag encodings */
-typedef enum {
- DW_TAG_padding = 0x00,
- DW_TAG_array_type = 0x01,
- DW_TAG_class_type = 0x02,
- DW_TAG_entry_point = 0x03,
- DW_TAG_enumeration_type = 0x04,
- DW_TAG_formal_parameter = 0x05,
- DW_TAG_imported_declaration = 0x08,
- DW_TAG_label = 0x0a,
- DW_TAG_lexical_block = 0x0b,
- DW_TAG_member = 0x0d,
- DW_TAG_pointer_type = 0x0f,
- DW_TAG_reference_type = 0x10,
- DW_TAG_compile_unit = 0x11,
- DW_TAG_string_type = 0x12,
- DW_TAG_structure_type = 0x13,
- DW_TAG_subroutine_type = 0x15,
- DW_TAG_typedef = 0x16,
- DW_TAG_union_type = 0x17,
- DW_TAG_unspecified_parameters = 0x18,
- DW_TAG_variant = 0x19,
- DW_TAG_common_block = 0x1a,
- DW_TAG_common_inclusion = 0x1b,
- DW_TAG_inheritance = 0x1c,
- DW_TAG_inlined_subroutine = 0x1d,
- DW_TAG_module = 0x1e,
- DW_TAG_ptr_to_member_type = 0x1f,
- DW_TAG_set_type = 0x20,
- DW_TAG_subrange_type = 0x21,
- DW_TAG_with_stmt = 0x22,
- DW_TAG_access_declaration = 0x23,
- DW_TAG_base_type = 0x24,
- DW_TAG_catch_block = 0x25,
- DW_TAG_const_type = 0x26,
- DW_TAG_constant = 0x27,
- DW_TAG_enumerator = 0x28,
- DW_TAG_file_type = 0x29,
- DW_TAG_friend = 0x2a,
- DW_TAG_namelist = 0x2b,
- DW_TAG_namelist_item = 0x2c,
- DW_TAG_packed_type = 0x2d,
- DW_TAG_subprogram = 0x2e,
- DW_TAG_template_type_param = 0x2f,
- DW_TAG_template_value_param = 0x30,
- DW_TAG_thrown_type = 0x31,
- DW_TAG_try_block = 0x32,
- DW_TAG_variant_part = 0x33,
- DW_TAG_variable = 0x34,
- DW_TAG_volatile_type = 0x35
-} dwarf_tag;
-
-/* Attribute form encodings */
-typedef enum {
- DW_FORM_addr = 0x01,
- DW_FORM_block2 = 0x03,
- DW_FORM_block4 = 0x04,
- DW_FORM_data2 = 0x05,
- DW_FORM_data4 = 0x06,
- DW_FORM_data8 = 0x07,
- DW_FORM_string = 0x08,
- DW_FORM_block = 0x09,
- DW_FORM_block1 = 0x0a,
- DW_FORM_data1 = 0x0b,
- DW_FORM_flag = 0x0c,
- DW_FORM_sdata = 0x0d,
- DW_FORM_strp = 0x0e,
- DW_FORM_udata = 0x0f,
- DW_FORM_ref_addr = 0x10,
- DW_FORM_ref1 = 0x11,
- DW_FORM_ref2 = 0x12,
- DW_FORM_ref4 = 0x13,
- DW_FORM_ref8 = 0x14,
- DW_FORM_ref_udata = 0x15,
- DW_FORM_indirect = 0x16
-} dwarf_form;
-
-/* Attribute encodings */
-typedef enum {
- DW_AT_sibling = 0x01,
- DW_AT_location = 0x02,
- DW_AT_name = 0x03,
- DW_AT_ordering = 0x09,
- DW_AT_subscr_data = 0x0a,
- DW_AT_byte_size = 0x0b,
- DW_AT_bit_offset = 0x0c,
- DW_AT_bit_size = 0x0d,
- DW_AT_element_list = 0x0f,
- DW_AT_stmt_list = 0x10,
- DW_AT_low_pc = 0x11,
- DW_AT_high_pc = 0x12,
- DW_AT_language = 0x13,
- DW_AT_member = 0x14,
- DW_AT_discr = 0x15,
- DW_AT_discr_value = 0x16,
- DW_AT_visibility = 0x17,
- DW_AT_import = 0x18,
- DW_AT_string_length = 0x19,
- DW_AT_common_reference = 0x1a,
- DW_AT_comp_dir = 0x1b,
- DW_AT_const_value = 0x1c,
- DW_AT_containing_type = 0x1d,
- DW_AT_default_value = 0x1e,
- DW_AT_inline = 0x20,
- DW_AT_is_optional = 0x21,
- DW_AT_lower_bound = 0x22,
- DW_AT_producer = 0x25,
- DW_AT_prototyped = 0x27,
- DW_AT_return_addr = 0x2a,
- DW_AT_start_scope = 0x2c,
- DW_AT_stride_size = 0x2e,
- DW_AT_upper_bound = 0x2f,
- DW_AT_abstract_origin = 0x31,
- DW_AT_accessibility = 0x32,
- DW_AT_address_class = 0x33,
- DW_AT_artificial = 0x34,
- DW_AT_base_types = 0x35,
- DW_AT_calling_convention = 0x36,
- DW_AT_count = 0x37,
- DW_AT_data_member_location = 0x38,
- DW_AT_decl_column = 0x39,
- DW_AT_decl_file = 0x3a,
- DW_AT_decl_line = 0x3b,
- DW_AT_declaration = 0x3c,
- DW_AT_discr_list = 0x3d,
- DW_AT_encoding = 0x3e,
- DW_AT_external = 0x3f,
- DW_AT_frame_base = 0x40,
- DW_AT_friend = 0x41,
- DW_AT_identifier_case = 0x42,
- DW_AT_macro_info = 0x43,
- DW_AT_namelist_items = 0x44,
- DW_AT_priority = 0x45,
- DW_AT_segment = 0x46,
- DW_AT_specification = 0x47,
- DW_AT_static_link = 0x48,
- DW_AT_type = 0x49,
- DW_AT_use_location = 0x4a,
- DW_AT_variable_parameter = 0x4b,
- DW_AT_virtuality = 0x4c,
- DW_AT_vtable_elem_location = 0x4d
-} dwarf_attribute;
-
-typedef struct dwarf2_abbrev_attr {
- STAILQ_ENTRY(dwarf2_abbrev_attr) link;
- dwarf_attribute name;
- dwarf_form form;
-} dwarf2_abbrev_attr;
-
-typedef struct dwarf2_abbrev {
- unsigned long id;
- dwarf_tag tag;
- int has_children;
- STAILQ_HEAD(dwarf2_abbrev_attrhead, dwarf2_abbrev_attr) attrs;
-} dwarf2_abbrev;
-
-/* Bytecode callback function prototypes */
-
-static void dwarf2_abbrev_bc_destroy(void *contents);
-static void dwarf2_abbrev_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int dwarf2_abbrev_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int dwarf2_abbrev_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 dwarf2_abbrev_bc_callback = {
- dwarf2_abbrev_bc_destroy,
- dwarf2_abbrev_bc_print,
- yasm_bc_finalize_common,
- NULL,
- dwarf2_abbrev_bc_calc_len,
- yasm_bc_expand_common,
- dwarf2_abbrev_bc_tobytes,
- 0
-};
-
-
-static unsigned long
-dwarf2_add_abbrev_attr(dwarf2_abbrev *abbrev, dwarf_attribute name,
- dwarf_form form)
-{
- dwarf2_abbrev_attr *attr = yasm_xmalloc(sizeof(dwarf2_abbrev_attr));
- attr->name = name;
- attr->form = form;
- STAILQ_INSERT_TAIL(&abbrev->attrs, attr, link);
- return yasm_size_uleb128(name) + yasm_size_uleb128(form);
-}
-
-static void
-dwarf2_append_expr(yasm_section *sect, /*@only@*/ yasm_expr *expr,
- unsigned int size, int leb)
-{
- yasm_datavalhead dvs;
- yasm_bytecode *bc;
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_expr(expr));
- if (leb == 0)
- bc = yasm_bc_create_data(&dvs, size, 0, NULL, 0);
- else
- bc = yasm_bc_create_leb128(&dvs, leb<0, 0);
- yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-}
-
-static void
-dwarf2_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_dwarf2__append_bc(sect, bc));
- yasm_bc_calc_len(bc, NULL, NULL);
-}
-
-yasm_section *
-yasm_dwarf2__generate_info(yasm_object *object, yasm_section *debug_line,
- yasm_section *main_code)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- int new;
- yasm_bytecode *abc;
- dwarf2_abbrev *abbrev;
- dwarf2_head *head;
- char *buf;
- yasm_section *debug_abbrev =
- yasm_object_get_general(object, ".debug_abbrev", 4, 0, 0, &new, 0);
- yasm_section *debug_info =
- yasm_object_get_general(object, ".debug_info", 4, 0, 0, &new, 0);
-
- yasm_section_set_align(debug_abbrev, 0, 0);
- yasm_section_set_align(debug_info, 0, 0);
-
- /* Create abbreviation table entry for compilation unit */
- abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev));
- abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0);
- abbrev->id = 1;
- abbrev->tag = DW_TAG_compile_unit;
- abbrev->has_children = 0;
- abc->len = yasm_size_uleb128(abbrev->id) + yasm_size_uleb128(abbrev->tag)
- + 3;
- STAILQ_INIT(&abbrev->attrs);
- yasm_dwarf2__append_bc(debug_abbrev, abc);
-
- /* info header */
- head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_info, debug_abbrev, 1, 0);
-
- /* Generate abbreviations at the same time as info (since they're linked
- * and we're only generating one piece of info).
- */
-
- /* generating info using abbrev 1 */
- dwarf2_append_expr(debug_info,
- yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(1)), 0),
- 0, 1);
-
- /* statement list (line numbers) */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_stmt_list, DW_FORM_data4);
- dwarf2_append_expr(debug_info,
- yasm_expr_create_ident(yasm_expr_sym(
- yasm_dwarf2__bc_sym(object->symtab,
- yasm_section_bcs_first(debug_line))), 0),
- dbgfmt_dwarf2->sizeof_offset, 0);
-
- if (main_code) {
- yasm_symrec *first;
- first = yasm_dwarf2__bc_sym(object->symtab,
- yasm_section_bcs_first(main_code));
- /* All code is contiguous in one section */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_low_pc, DW_FORM_addr);
- dwarf2_append_expr(debug_info,
- yasm_expr_create_ident(yasm_expr_sym(first), 0),
- dbgfmt_dwarf2->sizeof_address, 0);
-
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_high_pc, DW_FORM_addr);
- dwarf2_append_expr(debug_info,
- yasm_expr_create(YASM_EXPR_ADD, yasm_expr_sym(first),
- yasm_expr_int(yasm_calc_bc_dist(
- yasm_section_bcs_first(main_code),
- yasm_section_bcs_last(main_code))), 0),
- dbgfmt_dwarf2->sizeof_address, 0);
- }
-
- /* input filename */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_name, DW_FORM_string);
+/*
+ * DWARF2 debugging format - info and abbreviation tables
+ *
+ * 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 "dwarf2-dbgfmt.h"
+
+#define DW_LANG_Mips_Assembler 0x8001
+
+/* Tag encodings */
+typedef enum {
+ DW_TAG_padding = 0x00,
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_param = 0x2f,
+ DW_TAG_template_value_param = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35
+} dwarf_tag;
+
+/* Attribute form encodings */
+typedef enum {
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16
+} dwarf_form;
+
+/* Attribute encodings */
+typedef enum {
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_stride_size = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_items = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d
+} dwarf_attribute;
+
+typedef struct dwarf2_abbrev_attr {
+ STAILQ_ENTRY(dwarf2_abbrev_attr) link;
+ dwarf_attribute name;
+ dwarf_form form;
+} dwarf2_abbrev_attr;
+
+typedef struct dwarf2_abbrev {
+ unsigned long id;
+ dwarf_tag tag;
+ int has_children;
+ STAILQ_HEAD(dwarf2_abbrev_attrhead, dwarf2_abbrev_attr) attrs;
+} dwarf2_abbrev;
+
+/* Bytecode callback function prototypes */
+
+static void dwarf2_abbrev_bc_destroy(void *contents);
+static void dwarf2_abbrev_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int dwarf2_abbrev_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int dwarf2_abbrev_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 dwarf2_abbrev_bc_callback = {
+ dwarf2_abbrev_bc_destroy,
+ dwarf2_abbrev_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ dwarf2_abbrev_bc_calc_len,
+ yasm_bc_expand_common,
+ dwarf2_abbrev_bc_tobytes,
+ 0
+};
+
+
+static unsigned long
+dwarf2_add_abbrev_attr(dwarf2_abbrev *abbrev, dwarf_attribute name,
+ dwarf_form form)
+{
+ dwarf2_abbrev_attr *attr = yasm_xmalloc(sizeof(dwarf2_abbrev_attr));
+ attr->name = name;
+ attr->form = form;
+ STAILQ_INSERT_TAIL(&abbrev->attrs, attr, link);
+ return yasm_size_uleb128(name) + yasm_size_uleb128(form);
+}
+
+static void
+dwarf2_append_expr(yasm_section *sect, /*@only@*/ yasm_expr *expr,
+ unsigned int size, int leb)
+{
+ yasm_datavalhead dvs;
+ yasm_bytecode *bc;
+
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(expr));
+ if (leb == 0)
+ bc = yasm_bc_create_data(&dvs, size, 0, NULL, 0);
+ else
+ bc = yasm_bc_create_leb128(&dvs, leb<0, 0);
+ yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+}
+
+static void
+dwarf2_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_dwarf2__append_bc(sect, bc));
+ yasm_bc_calc_len(bc, NULL, NULL);
+}
+
+yasm_section *
+yasm_dwarf2__generate_info(yasm_object *object, yasm_section *debug_line,
+ yasm_section *main_code)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ int new;
+ yasm_bytecode *abc;
+ dwarf2_abbrev *abbrev;
+ dwarf2_head *head;
+ char *buf;
+ yasm_section *debug_abbrev =
+ yasm_object_get_general(object, ".debug_abbrev", 4, 0, 0, &new, 0);
+ yasm_section *debug_info =
+ yasm_object_get_general(object, ".debug_info", 4, 0, 0, &new, 0);
+
+ yasm_section_set_align(debug_abbrev, 0, 0);
+ yasm_section_set_align(debug_info, 0, 0);
+
+ /* Create abbreviation table entry for compilation unit */
+ abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev));
+ abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0);
+ abbrev->id = 1;
+ abbrev->tag = DW_TAG_compile_unit;
+ abbrev->has_children = 0;
+ abc->len = yasm_size_uleb128(abbrev->id) + yasm_size_uleb128(abbrev->tag)
+ + 3;
+ STAILQ_INIT(&abbrev->attrs);
+ yasm_dwarf2__append_bc(debug_abbrev, abc);
+
+ /* info header */
+ head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_info, debug_abbrev, 1, 0);
+
+ /* Generate abbreviations at the same time as info (since they're linked
+ * and we're only generating one piece of info).
+ */
+
+ /* generating info using abbrev 1 */
+ dwarf2_append_expr(debug_info,
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(1)), 0),
+ 0, 1);
+
+ /* statement list (line numbers) */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_stmt_list, DW_FORM_data4);
+ dwarf2_append_expr(debug_info,
+ yasm_expr_create_ident(yasm_expr_sym(
+ yasm_dwarf2__bc_sym(object->symtab,
+ yasm_section_bcs_first(debug_line))), 0),
+ dbgfmt_dwarf2->sizeof_offset, 0);
+
+ if (main_code) {
+ yasm_symrec *first;
+ first = yasm_dwarf2__bc_sym(object->symtab,
+ yasm_section_bcs_first(main_code));
+ /* All code is contiguous in one section */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_low_pc, DW_FORM_addr);
+ dwarf2_append_expr(debug_info,
+ yasm_expr_create_ident(yasm_expr_sym(first), 0),
+ dbgfmt_dwarf2->sizeof_address, 0);
+
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_high_pc, DW_FORM_addr);
+ dwarf2_append_expr(debug_info,
+ yasm_expr_create(YASM_EXPR_ADD, yasm_expr_sym(first),
+ yasm_expr_int(yasm_calc_bc_dist(
+ yasm_section_bcs_first(main_code),
+ yasm_section_bcs_last(main_code))), 0),
+ dbgfmt_dwarf2->sizeof_address, 0);
+ }
+
+ /* input filename */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_name, DW_FORM_string);
if (!object->deb_filename) {
object->deb_filename = yasm_replace_path(
dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
object->src_filename, strlen(object->src_filename));
}
dwarf2_append_str(debug_info, object->deb_filename);
-
- /* compile directory (current working directory) */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_comp_dir, DW_FORM_string);
- buf = yasm__getcwd();
+
+ /* compile directory (current working directory) */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_comp_dir, DW_FORM_string);
+ buf = yasm__getcwd();
char * new_cwd_name = yasm_replace_path(
dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
buf, strlen(buf));
dwarf2_append_str(debug_info, new_cwd_name);
yasm_xfree(new_cwd_name);
- yasm_xfree(buf);
-
- /* producer - assembler name */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_producer, DW_FORM_string);
- if (getenv("YASM_TEST_SUITE"))
- dwarf2_append_str(debug_info, "yasm HEAD");
- else
- dwarf2_append_str(debug_info, PACKAGE_STRING);
-
- /* language - no standard code for assembler, use MIPS as a substitute */
- abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_language, DW_FORM_data2);
- dwarf2_append_expr(debug_info,
- yasm_expr_create_ident(yasm_expr_int(
- yasm_intnum_create_uint(DW_LANG_Mips_Assembler)), 0), 2, 0);
-
- /* Terminate list of abbreviations */
- abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev));
- abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0);
- abbrev->id = 0;
- abbrev->tag = 0;
- abbrev->has_children = 0;
- STAILQ_INIT(&abbrev->attrs);
- abc->len = 1;
- yasm_dwarf2__append_bc(debug_abbrev, abc);
-
- /* mark end of info */
- yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_info));
-
- return debug_info;
-}
-
-static void
-dwarf2_abbrev_bc_destroy(void *contents)
-{
- dwarf2_abbrev *abbrev = (dwarf2_abbrev *)contents;
- dwarf2_abbrev_attr *n1, *n2;
-
- /* Delete attributes */
- n1 = STAILQ_FIRST(&abbrev->attrs);
- while (n1) {
- n2 = STAILQ_NEXT(n1, link);
- yasm_xfree(n1);
- n1 = n2;
- }
-
- yasm_xfree(contents);
-}
-
-static void
-dwarf2_abbrev_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-dwarf2_abbrev_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 dwarf2 aranges head bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-dwarf2_abbrev_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)
-{
- dwarf2_abbrev *abbrev = (dwarf2_abbrev *)bc->contents;
- unsigned char *buf = *bufp;
- dwarf2_abbrev_attr *attr;
-
- if (abbrev->id == 0) {
- YASM_WRITE_8(buf, 0);
- *bufp = buf;
- return 0;
- }
-
- buf += yasm_get_uleb128(abbrev->id, buf);
- buf += yasm_get_uleb128(abbrev->tag, buf);
- YASM_WRITE_8(buf, abbrev->has_children);
-
- STAILQ_FOREACH(attr, &abbrev->attrs, link) {
- buf += yasm_get_uleb128(attr->name, buf);
- buf += yasm_get_uleb128(attr->form, buf);
- }
-
- YASM_WRITE_8(buf, 0);
- YASM_WRITE_8(buf, 0);
-
- *bufp = buf;
- return 0;
-}
-
+ yasm_xfree(buf);
+
+ /* producer - assembler name */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_producer, DW_FORM_string);
+ if (getenv("YASM_TEST_SUITE"))
+ dwarf2_append_str(debug_info, "yasm HEAD");
+ else
+ dwarf2_append_str(debug_info, PACKAGE_STRING);
+
+ /* language - no standard code for assembler, use MIPS as a substitute */
+ abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_language, DW_FORM_data2);
+ dwarf2_append_expr(debug_info,
+ yasm_expr_create_ident(yasm_expr_int(
+ yasm_intnum_create_uint(DW_LANG_Mips_Assembler)), 0), 2, 0);
+
+ /* Terminate list of abbreviations */
+ abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev));
+ abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0);
+ abbrev->id = 0;
+ abbrev->tag = 0;
+ abbrev->has_children = 0;
+ STAILQ_INIT(&abbrev->attrs);
+ abc->len = 1;
+ yasm_dwarf2__append_bc(debug_abbrev, abc);
+
+ /* mark end of info */
+ yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_info));
+
+ return debug_info;
+}
+
+static void
+dwarf2_abbrev_bc_destroy(void *contents)
+{
+ dwarf2_abbrev *abbrev = (dwarf2_abbrev *)contents;
+ dwarf2_abbrev_attr *n1, *n2;
+
+ /* Delete attributes */
+ n1 = STAILQ_FIRST(&abbrev->attrs);
+ while (n1) {
+ n2 = STAILQ_NEXT(n1, link);
+ yasm_xfree(n1);
+ n1 = n2;
+ }
+
+ yasm_xfree(contents);
+}
+
+static void
+dwarf2_abbrev_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+dwarf2_abbrev_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 dwarf2 aranges head bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+dwarf2_abbrev_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)
+{
+ dwarf2_abbrev *abbrev = (dwarf2_abbrev *)bc->contents;
+ unsigned char *buf = *bufp;
+ dwarf2_abbrev_attr *attr;
+
+ if (abbrev->id == 0) {
+ YASM_WRITE_8(buf, 0);
+ *bufp = buf;
+ return 0;
+ }
+
+ buf += yasm_get_uleb128(abbrev->id, buf);
+ buf += yasm_get_uleb128(abbrev->tag, buf);
+ YASM_WRITE_8(buf, abbrev->has_children);
+
+ STAILQ_FOREACH(attr, &abbrev->attrs, link) {
+ buf += yasm_get_uleb128(attr->name, buf);
+ buf += yasm_get_uleb128(attr->form, buf);
+ }
+
+ YASM_WRITE_8(buf, 0);
+ YASM_WRITE_8(buf, 0);
+
+ *bufp = buf;
+ return 0;
+}
+
diff --git a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-line.c b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-line.c
index e9f346b1ce..14639ca429 100644
--- a/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-line.c
+++ b/contrib/tools/yasm/modules/dbgfmts/dwarf2/dwarf2-line.c
@@ -1,1156 +1,1156 @@
-/*
- * DWARF2 debugging format - 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 "dwarf2-dbgfmt.h"
-
-/* DWARF line number opcodes */
-typedef enum {
- DW_LNS_extended_op = 0,
- DW_LNS_copy,
- DW_LNS_advance_pc,
- DW_LNS_advance_line,
- DW_LNS_set_file,
- DW_LNS_set_column,
- DW_LNS_negate_stmt,
- DW_LNS_set_basic_block,
- DW_LNS_const_add_pc,
- DW_LNS_fixed_advance_pc,
-#ifdef WITH_DWARF3
- /* DWARF 3 extensions */
- DW_LNS_set_prologue_end,
- DW_LNS_set_epilogue_begin,
- DW_LNS_set_isa,
-#endif
- DWARF2_LINE_OPCODE_BASE
-} dwarf_line_number_op;
-
-/* # of LEB128 operands needed for each of the above opcodes */
-static unsigned char line_opcode_num_operands[DWARF2_LINE_OPCODE_BASE-1] = {
- 0, /* DW_LNS_copy */
- 1, /* DW_LNS_advance_pc */
- 1, /* DW_LNS_advance_line */
- 1, /* DW_LNS_set_file */
- 1, /* DW_LNS_set_column */
- 0, /* DW_LNS_negate_stmt */
- 0, /* DW_LNS_set_basic_block */
- 0, /* DW_LNS_const_add_pc */
- 1, /* DW_LNS_fixed_advance_pc */
-#ifdef WITH_DWARF3
- 0, /* DW_LNS_set_prologue_end */
- 0, /* DW_LNS_set_epilogue_begin */
- 1 /* DW_LNS_set_isa */
-#endif
-};
-
-/* Line number extended opcodes */
-typedef enum {
- DW_LNE_end_sequence = 1,
- DW_LNE_set_address,
- DW_LNE_define_file,
- DW_LNE_set_discriminator
-} dwarf_line_number_ext_op;
-
-/* Base and range for line offsets in special opcodes */
-#define DWARF2_LINE_BASE -5
-#define DWARF2_LINE_RANGE 14
-
-#define DWARF2_MAX_SPECIAL_ADDR_DELTA \
- (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\
- dbgfmt_dwarf2->min_insn_len)
-
-/* Initial value of is_stmt register */
-#define DWARF2_LINE_DEFAULT_IS_STMT 1
-
-/* Line number state machine register state */
-typedef struct dwarf2_line_state {
- /* static configuration */
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
-
- /* DWARF2 state machine registers */
- unsigned long address;
- unsigned long file;
- unsigned long line;
- unsigned long column;
- unsigned long isa;
- int is_stmt;
-
- /* other state information */
- /*@null@*/ yasm_bytecode *precbc;
-} dwarf2_line_state;
-
-typedef struct dwarf2_spp {
- yasm_bytecode *line_start_prevbc;
- yasm_bytecode *line_end_prevbc;
-} dwarf2_spp;
-
-typedef struct dwarf2_line_op {
- dwarf_line_number_op opcode;
- /*@owned@*/ /*@null@*/ yasm_intnum *operand;
-
- /* extended opcode */
- dwarf_line_number_ext_op ext_opcode;
- /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */
- /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */
- unsigned long ext_operandsize;
-} dwarf2_line_op;
-
-/* Bytecode callback function prototypes */
-static void dwarf2_spp_bc_destroy(void *contents);
-static void dwarf2_spp_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int dwarf2_spp_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int dwarf2_spp_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 dwarf2_line_op_bc_destroy(void *contents);
-static void dwarf2_line_op_bc_print(const void *contents, FILE *f,
- int indent_level);
-static int dwarf2_line_op_bc_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int dwarf2_line_op_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 dwarf2_spp_bc_callback = {
- dwarf2_spp_bc_destroy,
- dwarf2_spp_bc_print,
- yasm_bc_finalize_common,
- NULL,
- dwarf2_spp_bc_calc_len,
- yasm_bc_expand_common,
- dwarf2_spp_bc_tobytes,
- 0
-};
-
-static const yasm_bytecode_callback dwarf2_line_op_bc_callback = {
- dwarf2_line_op_bc_destroy,
- dwarf2_line_op_bc_print,
- yasm_bc_finalize_common,
- NULL,
- dwarf2_line_op_bc_calc_len,
- yasm_bc_expand_common,
- dwarf2_line_op_bc_tobytes,
- 0
-};
-
-
-static size_t
-dwarf2_dbgfmt_add_file(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, unsigned long filenum,
- const char *pathname)
-{
- size_t dirlen;
- const char *filename;
- unsigned long i, dir;
-
- /* Put the directory into the directory table */
- dir = 0;
- dirlen = yasm__splitpath(pathname, &filename);
- if (dirlen > 0) {
- /* Look to see if we already have that dir in the table */
- for (dir=1; dir<dbgfmt_dwarf2->dirs_size+1; dir++) {
- if (strncmp(dbgfmt_dwarf2->dirs[dir-1], pathname, dirlen) == 0
- && dbgfmt_dwarf2->dirs[dir-1][dirlen] == '\0')
- break;
- }
- if (dir >= dbgfmt_dwarf2->dirs_size+1) {
- /* Not found in table, add to end, reallocing if necessary */
- if (dir >= dbgfmt_dwarf2->dirs_allocated+1) {
- dbgfmt_dwarf2->dirs_allocated = dir+32;
- dbgfmt_dwarf2->dirs = yasm_xrealloc(dbgfmt_dwarf2->dirs,
- sizeof(char *)*dbgfmt_dwarf2->dirs_allocated);
- }
- dbgfmt_dwarf2->dirs[dir-1] = yasm__xstrndup(pathname, dirlen);
- dbgfmt_dwarf2->dirs_size = dir;
- }
- }
-
- /* 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_dwarf2->filenames_size; filenum++) {
- if (!dbgfmt_dwarf2->filenames[filenum].filename ||
- (dbgfmt_dwarf2->filenames[filenum].dir == dir
- && strcmp(dbgfmt_dwarf2->filenames[filenum].filename,
- filename) == 0))
- break;
- }
- } else
- filenum--; /* array index is 0-based */
-
- /* Realloc table if necessary */
- if (filenum >= dbgfmt_dwarf2->filenames_allocated) {
- unsigned long old_allocated = dbgfmt_dwarf2->filenames_allocated;
- dbgfmt_dwarf2->filenames_allocated = filenum+32;
- dbgfmt_dwarf2->filenames = yasm_xrealloc(dbgfmt_dwarf2->filenames,
- sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated);
- for (i=old_allocated; i<dbgfmt_dwarf2->filenames_allocated; i++) {
- dbgfmt_dwarf2->filenames[i].pathname = NULL;
- dbgfmt_dwarf2->filenames[i].filename = NULL;
- dbgfmt_dwarf2->filenames[i].dir = 0;
- }
- }
-
- /* Actually save in table */
- if (dbgfmt_dwarf2->filenames[filenum].pathname)
- yasm_xfree(dbgfmt_dwarf2->filenames[filenum].pathname);
- if (dbgfmt_dwarf2->filenames[filenum].filename)
- yasm_xfree(dbgfmt_dwarf2->filenames[filenum].filename);
- dbgfmt_dwarf2->filenames[filenum].pathname = yasm__xstrdup(pathname);
- dbgfmt_dwarf2->filenames[filenum].filename = yasm__xstrdup(filename);
- dbgfmt_dwarf2->filenames[filenum].dir = dir;
-
- /* Update table size */
- if (filenum >= dbgfmt_dwarf2->filenames_size)
- dbgfmt_dwarf2->filenames_size = filenum + 1;
-
- return filenum;
-}
-
-/* Create and add a new line opcode to a section, updating offset on insertion;
- * no optimization necessary.
- */
-static yasm_bytecode *
-dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode,
- /*@only@*/ /*@null@*/ yasm_intnum *operand)
-{
- dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
- yasm_bytecode *bc;
-
- line_op->opcode = opcode;
- line_op->operand = operand;
- line_op->ext_opcode = 0;
- line_op->ext_operand = NULL;
- line_op->ext_operand_int = NULL;
- line_op->ext_operandsize = 0;
-
- bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
- bc->len = 1;
- if (operand)
- bc->len += yasm_intnum_size_leb128(operand,
- opcode == DW_LNS_advance_line);
-
- yasm_dwarf2__append_bc(sect, bc);
- return bc;
-}
-
-/* Create and add a new extended line opcode to a section, updating offset on
- * insertion; no optimization necessary.
- */
-static yasm_bytecode *
-dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect,
- dwarf_line_number_ext_op ext_opcode,
- unsigned long ext_operandsize,
- /*@null@*/ yasm_symrec *ext_operand)
-{
- dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
- yasm_bytecode *bc;
-
- line_op->opcode = DW_LNS_extended_op;
- line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
- line_op->ext_opcode = ext_opcode;
- line_op->ext_operand = ext_operand;
- line_op->ext_operand_int = NULL;
- line_op->ext_operandsize = ext_operandsize;
-
- bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
- bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
- ext_operandsize;
-
- yasm_dwarf2__append_bc(sect, bc);
- return bc;
-}
-
-static yasm_bytecode *
-dwarf2_dbgfmt_append_line_ext_op_int(yasm_section *sect,
- dwarf_line_number_ext_op ext_opcode,
- /*@only@*/ yasm_intnum *ext_operand)
-{
- dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
- unsigned long ext_operandsize = yasm_intnum_size_leb128(ext_operand, 0);
- yasm_bytecode *bc;
-
- line_op->opcode = DW_LNS_extended_op;
- line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
- line_op->ext_opcode = ext_opcode;
- line_op->ext_operand = NULL;
- line_op->ext_operand_int = ext_operand;
- line_op->ext_operandsize = ext_operandsize;
-
- bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
- bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
- ext_operandsize;
-
- yasm_dwarf2__append_bc(sect, bc);
- return bc;
-}
-
-static void
-dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd)
-{
- /*@dependent@*/ yasm_symrec *lastsym = NULL;
- /*@null@*/ yasm_bytecode *bc;
- /*@null@*/ dwarf2_loc *loc;
-
- bc = yasm_section_bcs_first(sect);
- STAILQ_FOREACH(loc, &dsd->locs, link) {
- /* Find the first bytecode following this loc by looking at
- * the virtual line numbers. XXX: this assumes the source file
- * order will be the same as the actual section order. If we ever
- * implement subsegs this will NOT necessarily be true and this logic
- * will need to be fixed to handle it!
- *
- * Keep track of last symbol seen prior to the loc.
- */
- while (bc && bc->line <= loc->vline) {
- if (bc->symrecs) {
- int i = 0;
- while (bc->symrecs[i]) {
- lastsym = bc->symrecs[i];
- i++;
- }
- }
- bc = yasm_bc__next(bc);
- }
- loc->sym = lastsym;
- loc->bc = bc;
- }
-}
-
-static int
-dwarf2_dbgfmt_gen_line_op(yasm_section *debug_line, dwarf2_line_state *state,
- const dwarf2_loc *loc,
- /*@null@*/ const dwarf2_loc *nextloc)
-{
- unsigned long addr_delta;
- long line_delta;
- int opcode1, opcode2;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = state->dbgfmt_dwarf2;
-
- if (state->file != loc->file) {
- state->file = loc->file;
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file,
- yasm_intnum_create_uint(state->file));
- }
- if (state->column != loc->column) {
- state->column = loc->column;
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column,
- yasm_intnum_create_uint(state->column));
- }
- if (loc->discriminator != 0) {
- dwarf2_dbgfmt_append_line_ext_op_int(debug_line,
- DW_LNE_set_discriminator,
- yasm_intnum_create_uint(loc->discriminator));
- }
-#ifdef WITH_DWARF3
- if (loc->isa_change) {
- state->isa = loc->isa;
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa,
- yasm_intnum_create_uint(state->isa));
- }
-#endif
- if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) {
- state->is_stmt = 1;
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
- } else if (state->is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) {
- state->is_stmt = 0;
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
- }
- if (loc->basic_block) {
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_basic_block, NULL);
- }
-#ifdef WITH_DWARF3
- if (loc->prologue_end) {
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_prologue_end, NULL);
- }
- if (loc->epilogue_begin) {
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_epilogue_begin,
- NULL);
- }
-#endif
-
- /* If multiple loc for the same location, use last */
- if (nextloc && nextloc->bc->offset == loc->bc->offset)
- return 0;
-
- if (!state->precbc) {
- /* Set the starting address for the section */
- if (!loc->sym) {
- /* shouldn't happen! */
- yasm_error_set(YASM_ERROR_GENERAL,
- N_("could not find label prior to loc"));
- return 1;
- }
- dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address,
- dbgfmt_dwarf2->sizeof_address, loc->sym);
- addr_delta = 0;
- } else if (loc->bc) {
- if (state->precbc->offset > loc->bc->offset)
- yasm_internal_error(N_("dwarf2 address went backwards?"));
- addr_delta = loc->bc->offset - state->precbc->offset;
- } else
- return 0; /* ran out of bytecodes! XXX: do something? */
-
- /* Generate appropriate opcode(s). Address can only increment,
- * whereas line number can go backwards.
- */
- line_delta = loc->line - state->line;
- state->line = loc->line;
-
- /* First handle the line delta */
- if (line_delta < DWARF2_LINE_BASE
- || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) {
- /* Won't fit in special opcode, use (signed) line advance */
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_line,
- yasm_intnum_create_int(line_delta));
- line_delta = 0;
- }
-
- /* Next handle the address delta */
- opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
- DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len);
- opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
- DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) /
- dbgfmt_dwarf2->min_insn_len);
- if (line_delta == 0 && addr_delta == 0) {
- /* Both line and addr deltas are 0: do DW_LNS_copy */
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
- } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA && opcode1 <= 255) {
- /* Addr delta in range of special opcode */
- dwarf2_dbgfmt_append_line_op(debug_line, opcode1, NULL);
- } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA
- && opcode2 <= 255) {
- /* Addr delta in range of const_add_pc + special */
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_const_add_pc, NULL);
- dwarf2_dbgfmt_append_line_op(debug_line, opcode2, NULL);
- } else {
- /* Need advance_pc */
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_pc,
- yasm_intnum_create_uint(addr_delta));
- /* Take care of any remaining line_delta and add entry to matrix */
- if (line_delta == 0)
- dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
- else {
- unsigned int opcode;
- opcode = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE;
- dwarf2_dbgfmt_append_line_op(debug_line, opcode, NULL);
- }
- }
- state->precbc = loc->bc;
- return 0;
-}
-
-typedef struct dwarf2_line_bc_info {
- yasm_section *debug_line;
- yasm_object *object;
- yasm_linemap *linemap;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
- dwarf2_line_state *state;
- dwarf2_loc loc;
- unsigned long lastfile;
-} dwarf2_line_bc_info;
-
-static int
-dwarf2_filename_equals(const dwarf2_filename *fn,
- char **dirs,
- const char *pathname,
- unsigned long dirlen,
- const char *filename)
-{
- /* check directory */
- if (fn->dir == 0) {
- if (dirlen != 0)
- return 0;
- } else {
- if (strncmp(dirs[fn->dir-1], pathname, dirlen) != 0 ||
- dirs[fn->dir-1][dirlen] != '\0')
- return 0;
- }
-
- /* check filename */
- return strcmp(fn->filename, filename) == 0;
-}
-
-static int
-dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
-{
- dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
- unsigned long i;
- size_t dirlen;
- const char *pathname, *filename;
- /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
-
- if (nextbc && bc->offset == nextbc->offset)
- return 0;
-
- info->loc.vline = bc->line;
- info->loc.bc = bc;
-
- /* Keep track of last symbol seen */
- if (bc->symrecs) {
- i = 0;
- while (bc->symrecs[i]) {
- info->loc.sym = bc->symrecs[i];
- i++;
- }
- }
-
- yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line);
- dirlen = yasm__splitpath(pathname, &filename);
+/*
+ * DWARF2 debugging format - 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 "dwarf2-dbgfmt.h"
+
+/* DWARF line number opcodes */
+typedef enum {
+ DW_LNS_extended_op = 0,
+ DW_LNS_copy,
+ DW_LNS_advance_pc,
+ DW_LNS_advance_line,
+ DW_LNS_set_file,
+ DW_LNS_set_column,
+ DW_LNS_negate_stmt,
+ DW_LNS_set_basic_block,
+ DW_LNS_const_add_pc,
+ DW_LNS_fixed_advance_pc,
+#ifdef WITH_DWARF3
+ /* DWARF 3 extensions */
+ DW_LNS_set_prologue_end,
+ DW_LNS_set_epilogue_begin,
+ DW_LNS_set_isa,
+#endif
+ DWARF2_LINE_OPCODE_BASE
+} dwarf_line_number_op;
+
+/* # of LEB128 operands needed for each of the above opcodes */
+static unsigned char line_opcode_num_operands[DWARF2_LINE_OPCODE_BASE-1] = {
+ 0, /* DW_LNS_copy */
+ 1, /* DW_LNS_advance_pc */
+ 1, /* DW_LNS_advance_line */
+ 1, /* DW_LNS_set_file */
+ 1, /* DW_LNS_set_column */
+ 0, /* DW_LNS_negate_stmt */
+ 0, /* DW_LNS_set_basic_block */
+ 0, /* DW_LNS_const_add_pc */
+ 1, /* DW_LNS_fixed_advance_pc */
+#ifdef WITH_DWARF3
+ 0, /* DW_LNS_set_prologue_end */
+ 0, /* DW_LNS_set_epilogue_begin */
+ 1 /* DW_LNS_set_isa */
+#endif
+};
+
+/* Line number extended opcodes */
+typedef enum {
+ DW_LNE_end_sequence = 1,
+ DW_LNE_set_address,
+ DW_LNE_define_file,
+ DW_LNE_set_discriminator
+} dwarf_line_number_ext_op;
+
+/* Base and range for line offsets in special opcodes */
+#define DWARF2_LINE_BASE -5
+#define DWARF2_LINE_RANGE 14
+
+#define DWARF2_MAX_SPECIAL_ADDR_DELTA \
+ (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\
+ dbgfmt_dwarf2->min_insn_len)
+
+/* Initial value of is_stmt register */
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+/* Line number state machine register state */
+typedef struct dwarf2_line_state {
+ /* static configuration */
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
+
+ /* DWARF2 state machine registers */
+ unsigned long address;
+ unsigned long file;
+ unsigned long line;
+ unsigned long column;
+ unsigned long isa;
+ int is_stmt;
+
+ /* other state information */
+ /*@null@*/ yasm_bytecode *precbc;
+} dwarf2_line_state;
+
+typedef struct dwarf2_spp {
+ yasm_bytecode *line_start_prevbc;
+ yasm_bytecode *line_end_prevbc;
+} dwarf2_spp;
+
+typedef struct dwarf2_line_op {
+ dwarf_line_number_op opcode;
+ /*@owned@*/ /*@null@*/ yasm_intnum *operand;
+
+ /* extended opcode */
+ dwarf_line_number_ext_op ext_opcode;
+ /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */
+ /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */
+ unsigned long ext_operandsize;
+} dwarf2_line_op;
+
+/* Bytecode callback function prototypes */
+static void dwarf2_spp_bc_destroy(void *contents);
+static void dwarf2_spp_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int dwarf2_spp_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int dwarf2_spp_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 dwarf2_line_op_bc_destroy(void *contents);
+static void dwarf2_line_op_bc_print(const void *contents, FILE *f,
+ int indent_level);
+static int dwarf2_line_op_bc_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int dwarf2_line_op_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 dwarf2_spp_bc_callback = {
+ dwarf2_spp_bc_destroy,
+ dwarf2_spp_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ dwarf2_spp_bc_calc_len,
+ yasm_bc_expand_common,
+ dwarf2_spp_bc_tobytes,
+ 0
+};
+
+static const yasm_bytecode_callback dwarf2_line_op_bc_callback = {
+ dwarf2_line_op_bc_destroy,
+ dwarf2_line_op_bc_print,
+ yasm_bc_finalize_common,
+ NULL,
+ dwarf2_line_op_bc_calc_len,
+ yasm_bc_expand_common,
+ dwarf2_line_op_bc_tobytes,
+ 0
+};
+
+
+static size_t
+dwarf2_dbgfmt_add_file(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, unsigned long filenum,
+ const char *pathname)
+{
+ size_t dirlen;
+ const char *filename;
+ unsigned long i, dir;
+
+ /* Put the directory into the directory table */
+ dir = 0;
+ dirlen = yasm__splitpath(pathname, &filename);
+ if (dirlen > 0) {
+ /* Look to see if we already have that dir in the table */
+ for (dir=1; dir<dbgfmt_dwarf2->dirs_size+1; dir++) {
+ if (strncmp(dbgfmt_dwarf2->dirs[dir-1], pathname, dirlen) == 0
+ && dbgfmt_dwarf2->dirs[dir-1][dirlen] == '\0')
+ break;
+ }
+ if (dir >= dbgfmt_dwarf2->dirs_size+1) {
+ /* Not found in table, add to end, reallocing if necessary */
+ if (dir >= dbgfmt_dwarf2->dirs_allocated+1) {
+ dbgfmt_dwarf2->dirs_allocated = dir+32;
+ dbgfmt_dwarf2->dirs = yasm_xrealloc(dbgfmt_dwarf2->dirs,
+ sizeof(char *)*dbgfmt_dwarf2->dirs_allocated);
+ }
+ dbgfmt_dwarf2->dirs[dir-1] = yasm__xstrndup(pathname, dirlen);
+ dbgfmt_dwarf2->dirs_size = dir;
+ }
+ }
+
+ /* 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_dwarf2->filenames_size; filenum++) {
+ if (!dbgfmt_dwarf2->filenames[filenum].filename ||
+ (dbgfmt_dwarf2->filenames[filenum].dir == dir
+ && strcmp(dbgfmt_dwarf2->filenames[filenum].filename,
+ filename) == 0))
+ break;
+ }
+ } else
+ filenum--; /* array index is 0-based */
+
+ /* Realloc table if necessary */
+ if (filenum >= dbgfmt_dwarf2->filenames_allocated) {
+ unsigned long old_allocated = dbgfmt_dwarf2->filenames_allocated;
+ dbgfmt_dwarf2->filenames_allocated = filenum+32;
+ dbgfmt_dwarf2->filenames = yasm_xrealloc(dbgfmt_dwarf2->filenames,
+ sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated);
+ for (i=old_allocated; i<dbgfmt_dwarf2->filenames_allocated; i++) {
+ dbgfmt_dwarf2->filenames[i].pathname = NULL;
+ dbgfmt_dwarf2->filenames[i].filename = NULL;
+ dbgfmt_dwarf2->filenames[i].dir = 0;
+ }
+ }
+
+ /* Actually save in table */
+ if (dbgfmt_dwarf2->filenames[filenum].pathname)
+ yasm_xfree(dbgfmt_dwarf2->filenames[filenum].pathname);
+ if (dbgfmt_dwarf2->filenames[filenum].filename)
+ yasm_xfree(dbgfmt_dwarf2->filenames[filenum].filename);
+ dbgfmt_dwarf2->filenames[filenum].pathname = yasm__xstrdup(pathname);
+ dbgfmt_dwarf2->filenames[filenum].filename = yasm__xstrdup(filename);
+ dbgfmt_dwarf2->filenames[filenum].dir = dir;
+
+ /* Update table size */
+ if (filenum >= dbgfmt_dwarf2->filenames_size)
+ dbgfmt_dwarf2->filenames_size = filenum + 1;
+
+ return filenum;
+}
+
+/* Create and add a new line opcode to a section, updating offset on insertion;
+ * no optimization necessary.
+ */
+static yasm_bytecode *
+dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode,
+ /*@only@*/ /*@null@*/ yasm_intnum *operand)
+{
+ dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
+ yasm_bytecode *bc;
+
+ line_op->opcode = opcode;
+ line_op->operand = operand;
+ line_op->ext_opcode = 0;
+ line_op->ext_operand = NULL;
+ line_op->ext_operand_int = NULL;
+ line_op->ext_operandsize = 0;
+
+ bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
+ bc->len = 1;
+ if (operand)
+ bc->len += yasm_intnum_size_leb128(operand,
+ opcode == DW_LNS_advance_line);
+
+ yasm_dwarf2__append_bc(sect, bc);
+ return bc;
+}
+
+/* Create and add a new extended line opcode to a section, updating offset on
+ * insertion; no optimization necessary.
+ */
+static yasm_bytecode *
+dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect,
+ dwarf_line_number_ext_op ext_opcode,
+ unsigned long ext_operandsize,
+ /*@null@*/ yasm_symrec *ext_operand)
+{
+ dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
+ yasm_bytecode *bc;
+
+ line_op->opcode = DW_LNS_extended_op;
+ line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
+ line_op->ext_opcode = ext_opcode;
+ line_op->ext_operand = ext_operand;
+ line_op->ext_operand_int = NULL;
+ line_op->ext_operandsize = ext_operandsize;
+
+ bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
+ bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
+ ext_operandsize;
+
+ yasm_dwarf2__append_bc(sect, bc);
+ return bc;
+}
+
+static yasm_bytecode *
+dwarf2_dbgfmt_append_line_ext_op_int(yasm_section *sect,
+ dwarf_line_number_ext_op ext_opcode,
+ /*@only@*/ yasm_intnum *ext_operand)
+{
+ dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
+ unsigned long ext_operandsize = yasm_intnum_size_leb128(ext_operand, 0);
+ yasm_bytecode *bc;
+
+ line_op->opcode = DW_LNS_extended_op;
+ line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
+ line_op->ext_opcode = ext_opcode;
+ line_op->ext_operand = NULL;
+ line_op->ext_operand_int = ext_operand;
+ line_op->ext_operandsize = ext_operandsize;
+
+ bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
+ bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
+ ext_operandsize;
+
+ yasm_dwarf2__append_bc(sect, bc);
+ return bc;
+}
+
+static void
+dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd)
+{
+ /*@dependent@*/ yasm_symrec *lastsym = NULL;
+ /*@null@*/ yasm_bytecode *bc;
+ /*@null@*/ dwarf2_loc *loc;
+
+ bc = yasm_section_bcs_first(sect);
+ STAILQ_FOREACH(loc, &dsd->locs, link) {
+ /* Find the first bytecode following this loc by looking at
+ * the virtual line numbers. XXX: this assumes the source file
+ * order will be the same as the actual section order. If we ever
+ * implement subsegs this will NOT necessarily be true and this logic
+ * will need to be fixed to handle it!
+ *
+ * Keep track of last symbol seen prior to the loc.
+ */
+ while (bc && bc->line <= loc->vline) {
+ if (bc->symrecs) {
+ int i = 0;
+ while (bc->symrecs[i]) {
+ lastsym = bc->symrecs[i];
+ i++;
+ }
+ }
+ bc = yasm_bc__next(bc);
+ }
+ loc->sym = lastsym;
+ loc->bc = bc;
+ }
+}
+
+static int
+dwarf2_dbgfmt_gen_line_op(yasm_section *debug_line, dwarf2_line_state *state,
+ const dwarf2_loc *loc,
+ /*@null@*/ const dwarf2_loc *nextloc)
+{
+ unsigned long addr_delta;
+ long line_delta;
+ int opcode1, opcode2;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = state->dbgfmt_dwarf2;
+
+ if (state->file != loc->file) {
+ state->file = loc->file;
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file,
+ yasm_intnum_create_uint(state->file));
+ }
+ if (state->column != loc->column) {
+ state->column = loc->column;
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column,
+ yasm_intnum_create_uint(state->column));
+ }
+ if (loc->discriminator != 0) {
+ dwarf2_dbgfmt_append_line_ext_op_int(debug_line,
+ DW_LNE_set_discriminator,
+ yasm_intnum_create_uint(loc->discriminator));
+ }
+#ifdef WITH_DWARF3
+ if (loc->isa_change) {
+ state->isa = loc->isa;
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa,
+ yasm_intnum_create_uint(state->isa));
+ }
+#endif
+ if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) {
+ state->is_stmt = 1;
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
+ } else if (state->is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) {
+ state->is_stmt = 0;
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
+ }
+ if (loc->basic_block) {
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_basic_block, NULL);
+ }
+#ifdef WITH_DWARF3
+ if (loc->prologue_end) {
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_prologue_end, NULL);
+ }
+ if (loc->epilogue_begin) {
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_epilogue_begin,
+ NULL);
+ }
+#endif
+
+ /* If multiple loc for the same location, use last */
+ if (nextloc && nextloc->bc->offset == loc->bc->offset)
+ return 0;
+
+ if (!state->precbc) {
+ /* Set the starting address for the section */
+ if (!loc->sym) {
+ /* shouldn't happen! */
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("could not find label prior to loc"));
+ return 1;
+ }
+ dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address,
+ dbgfmt_dwarf2->sizeof_address, loc->sym);
+ addr_delta = 0;
+ } else if (loc->bc) {
+ if (state->precbc->offset > loc->bc->offset)
+ yasm_internal_error(N_("dwarf2 address went backwards?"));
+ addr_delta = loc->bc->offset - state->precbc->offset;
+ } else
+ return 0; /* ran out of bytecodes! XXX: do something? */
+
+ /* Generate appropriate opcode(s). Address can only increment,
+ * whereas line number can go backwards.
+ */
+ line_delta = loc->line - state->line;
+ state->line = loc->line;
+
+ /* First handle the line delta */
+ if (line_delta < DWARF2_LINE_BASE
+ || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) {
+ /* Won't fit in special opcode, use (signed) line advance */
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_line,
+ yasm_intnum_create_int(line_delta));
+ line_delta = 0;
+ }
+
+ /* Next handle the address delta */
+ opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
+ DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len);
+ opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
+ DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) /
+ dbgfmt_dwarf2->min_insn_len);
+ if (line_delta == 0 && addr_delta == 0) {
+ /* Both line and addr deltas are 0: do DW_LNS_copy */
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
+ } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA && opcode1 <= 255) {
+ /* Addr delta in range of special opcode */
+ dwarf2_dbgfmt_append_line_op(debug_line, opcode1, NULL);
+ } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA
+ && opcode2 <= 255) {
+ /* Addr delta in range of const_add_pc + special */
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_const_add_pc, NULL);
+ dwarf2_dbgfmt_append_line_op(debug_line, opcode2, NULL);
+ } else {
+ /* Need advance_pc */
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_pc,
+ yasm_intnum_create_uint(addr_delta));
+ /* Take care of any remaining line_delta and add entry to matrix */
+ if (line_delta == 0)
+ dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
+ else {
+ unsigned int opcode;
+ opcode = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE;
+ dwarf2_dbgfmt_append_line_op(debug_line, opcode, NULL);
+ }
+ }
+ state->precbc = loc->bc;
+ return 0;
+}
+
+typedef struct dwarf2_line_bc_info {
+ yasm_section *debug_line;
+ yasm_object *object;
+ yasm_linemap *linemap;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
+ dwarf2_line_state *state;
+ dwarf2_loc loc;
+ unsigned long lastfile;
+} dwarf2_line_bc_info;
+
+static int
+dwarf2_filename_equals(const dwarf2_filename *fn,
+ char **dirs,
+ const char *pathname,
+ unsigned long dirlen,
+ const char *filename)
+{
+ /* check directory */
+ if (fn->dir == 0) {
+ if (dirlen != 0)
+ return 0;
+ } else {
+ if (strncmp(dirs[fn->dir-1], pathname, dirlen) != 0 ||
+ dirs[fn->dir-1][dirlen] != '\0')
+ return 0;
+ }
+
+ /* check filename */
+ return strcmp(fn->filename, filename) == 0;
+}
+
+static int
+dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
+{
+ dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
+ unsigned long i;
+ size_t dirlen;
+ const char *pathname, *filename;
+ /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
+
+ if (nextbc && bc->offset == nextbc->offset)
+ return 0;
+
+ info->loc.vline = bc->line;
+ info->loc.bc = bc;
+
+ /* Keep track of last symbol seen */
+ if (bc->symrecs) {
+ i = 0;
+ while (bc->symrecs[i]) {
+ info->loc.sym = bc->symrecs[i];
+ i++;
+ }
+ }
+
+ yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line);
+ dirlen = yasm__splitpath(pathname, &filename);
char * new_dir_name = yasm_replace_path(
dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
pathname, dirlen);
dirlen = strlen(new_dir_name);
-
- /* Find file index; just linear search it unless it was the last used */
- if (info->lastfile > 0
- && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1],
+
+ /* Find file index; just linear search it unless it was the last used */
+ if (info->lastfile > 0
+ && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1],
dbgfmt_dwarf2->dirs, new_dir_name, dirlen,
- filename))
- info->loc.file = info->lastfile;
- else {
- for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
- if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i],
+ filename))
+ info->loc.file = info->lastfile;
+ else {
+ for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
+ if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i],
dbgfmt_dwarf2->dirs, new_dir_name, dirlen,
- filename))
- break;
- }
- if (i >= dbgfmt_dwarf2->filenames_size)
- yasm_internal_error(N_("could not find filename in table"));
- info->loc.file = i+1;
- info->lastfile = i+1;
- }
+ filename))
+ break;
+ }
+ if (i >= dbgfmt_dwarf2->filenames_size)
+ yasm_internal_error(N_("could not find filename in table"));
+ info->loc.file = i+1;
+ info->lastfile = i+1;
+ }
yasm_xfree(new_dir_name);
- if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc,
- NULL))
- return 1;
- return 0;
-}
-
-typedef struct dwarf2_line_info {
- yasm_section *debug_line; /* section to which line number info goes */
- yasm_object *object;
- yasm_linemap *linemap;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
- yasm_errwarns *errwarns;
-
- /* Generate based on bytecodes (1) or locs (0)? Use bytecodes if we're
- * generating line numbers for the actual assembly source file.
- */
- int asm_source;
-
- /* number of sections line number info generated for */
- size_t num_sections;
- /* last section line number info generated for */
- /*@null@*/ yasm_section *last_code;
-} dwarf2_line_info;
-
-static int
-dwarf2_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
-{
- dwarf2_line_info *info = (dwarf2_line_info *)d;
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
- /*@null@*/ dwarf2_section_data *dsd;
- /*@null@*/ yasm_bytecode *bc;
- dwarf2_line_state state;
- unsigned long addr_delta;
-
- dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
- if (!dsd) {
- if (info->asm_source && yasm_section_is_code(sect)) {
- /* Create line data for asm code sections */
- dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
- STAILQ_INIT(&dsd->locs);
- yasm_section_add_data(sect, &yasm_dwarf2__section_data_cb, dsd);
- } else
- return 0; /* no line data for this section */
- }
-
- info->num_sections++;
- info->last_code = sect;
-
- /* initialize state machine registers for each sequence */
- state.dbgfmt_dwarf2 = dbgfmt_dwarf2;
- state.address = 0;
- state.file = 1;
- state.line = 1;
- state.column = 0;
- state.isa = 0;
- state.is_stmt = DWARF2_LINE_DEFAULT_IS_STMT;
- state.precbc = NULL;
-
- if (info->asm_source) {
- dwarf2_line_bc_info bcinfo;
-
- bcinfo.debug_line = info->debug_line;
- bcinfo.object = info->object;
- bcinfo.linemap = info->linemap;
- bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2;
- bcinfo.state = &state;
- bcinfo.lastfile = 0;
- bcinfo.loc.isa_change = 0;
- bcinfo.loc.column = 0;
- bcinfo.loc.discriminator = 0;
- bcinfo.loc.is_stmt = IS_STMT_NOCHANGE;
- bcinfo.loc.basic_block = 0;
- bcinfo.loc.prologue_end = 0;
- bcinfo.loc.epilogue_begin = 0;
- bcinfo.loc.sym = NULL;
-
- /* bcs_traverse() skips first "dummy" bytecode, so look at it
- * separately to determine the initial symrec.
- */
- bc = yasm_section_bcs_first(sect);
- if (bc->symrecs) {
- size_t i = 0;
- while (bc->symrecs[i]) {
- bcinfo.loc.sym = bc->symrecs[i];
- i++;
- }
- }
-
- yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo,
- dwarf2_generate_line_bc);
- } else {
- /*@null@*/ dwarf2_loc *loc;
-
- dwarf2_dbgfmt_finalize_locs(sect, dsd);
-
- STAILQ_FOREACH(loc, &dsd->locs, link) {
- if (dwarf2_dbgfmt_gen_line_op(info->debug_line, &state, loc,
- STAILQ_NEXT(loc, link)))
- return 1;
- }
- }
-
- /* End sequence: bring address to end of section, then output end
- * sequence opcode. Don't use a special opcode to do this as we don't
- * want an extra entry in the line matrix.
- */
- if (!state.precbc)
- state.precbc = yasm_section_bcs_first(sect);
- bc = yasm_section_bcs_last(sect);
- addr_delta = yasm_bc_next_offset(bc) - state.precbc->offset;
- if (addr_delta == DWARF2_MAX_SPECIAL_ADDR_DELTA)
- dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc,
- NULL);
- else if (addr_delta > 0)
- dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_pc,
- yasm_intnum_create_uint(addr_delta));
- dwarf2_dbgfmt_append_line_ext_op(info->debug_line, DW_LNE_end_sequence, 0,
- NULL);
-
- return 0;
-}
-
-static int
-dwarf2_generate_filename(const char *filename, void *d)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)d;
+ if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc,
+ NULL))
+ return 1;
+ return 0;
+}
+
+typedef struct dwarf2_line_info {
+ yasm_section *debug_line; /* section to which line number info goes */
+ yasm_object *object;
+ yasm_linemap *linemap;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
+ yasm_errwarns *errwarns;
+
+ /* Generate based on bytecodes (1) or locs (0)? Use bytecodes if we're
+ * generating line numbers for the actual assembly source file.
+ */
+ int asm_source;
+
+ /* number of sections line number info generated for */
+ size_t num_sections;
+ /* last section line number info generated for */
+ /*@null@*/ yasm_section *last_code;
+} dwarf2_line_info;
+
+static int
+dwarf2_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
+{
+ dwarf2_line_info *info = (dwarf2_line_info *)d;
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
+ /*@null@*/ dwarf2_section_data *dsd;
+ /*@null@*/ yasm_bytecode *bc;
+ dwarf2_line_state state;
+ unsigned long addr_delta;
+
+ dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
+ if (!dsd) {
+ if (info->asm_source && yasm_section_is_code(sect)) {
+ /* Create line data for asm code sections */
+ dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
+ STAILQ_INIT(&dsd->locs);
+ yasm_section_add_data(sect, &yasm_dwarf2__section_data_cb, dsd);
+ } else
+ return 0; /* no line data for this section */
+ }
+
+ info->num_sections++;
+ info->last_code = sect;
+
+ /* initialize state machine registers for each sequence */
+ state.dbgfmt_dwarf2 = dbgfmt_dwarf2;
+ state.address = 0;
+ state.file = 1;
+ state.line = 1;
+ state.column = 0;
+ state.isa = 0;
+ state.is_stmt = DWARF2_LINE_DEFAULT_IS_STMT;
+ state.precbc = NULL;
+
+ if (info->asm_source) {
+ dwarf2_line_bc_info bcinfo;
+
+ bcinfo.debug_line = info->debug_line;
+ bcinfo.object = info->object;
+ bcinfo.linemap = info->linemap;
+ bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2;
+ bcinfo.state = &state;
+ bcinfo.lastfile = 0;
+ bcinfo.loc.isa_change = 0;
+ bcinfo.loc.column = 0;
+ bcinfo.loc.discriminator = 0;
+ bcinfo.loc.is_stmt = IS_STMT_NOCHANGE;
+ bcinfo.loc.basic_block = 0;
+ bcinfo.loc.prologue_end = 0;
+ bcinfo.loc.epilogue_begin = 0;
+ bcinfo.loc.sym = NULL;
+
+ /* bcs_traverse() skips first "dummy" bytecode, so look at it
+ * separately to determine the initial symrec.
+ */
+ bc = yasm_section_bcs_first(sect);
+ if (bc->symrecs) {
+ size_t i = 0;
+ while (bc->symrecs[i]) {
+ bcinfo.loc.sym = bc->symrecs[i];
+ i++;
+ }
+ }
+
+ yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo,
+ dwarf2_generate_line_bc);
+ } else {
+ /*@null@*/ dwarf2_loc *loc;
+
+ dwarf2_dbgfmt_finalize_locs(sect, dsd);
+
+ STAILQ_FOREACH(loc, &dsd->locs, link) {
+ if (dwarf2_dbgfmt_gen_line_op(info->debug_line, &state, loc,
+ STAILQ_NEXT(loc, link)))
+ return 1;
+ }
+ }
+
+ /* End sequence: bring address to end of section, then output end
+ * sequence opcode. Don't use a special opcode to do this as we don't
+ * want an extra entry in the line matrix.
+ */
+ if (!state.precbc)
+ state.precbc = yasm_section_bcs_first(sect);
+ bc = yasm_section_bcs_last(sect);
+ addr_delta = yasm_bc_next_offset(bc) - state.precbc->offset;
+ if (addr_delta == DWARF2_MAX_SPECIAL_ADDR_DELTA)
+ dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc,
+ NULL);
+ else if (addr_delta > 0)
+ dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_pc,
+ yasm_intnum_create_uint(addr_delta));
+ dwarf2_dbgfmt_append_line_ext_op(info->debug_line, DW_LNE_end_sequence, 0,
+ NULL);
+
+ return 0;
+}
+
+static int
+dwarf2_generate_filename(const char *filename, void *d)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)d;
char *deb_name = yasm_replace_path(
dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
filename, strlen(filename));
dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, 0, deb_name);
yasm_xfree(deb_name);
- return 0;
-}
-
-yasm_section *
-yasm_dwarf2__generate_line(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns, int asm_source,
- /*@out@*/ yasm_section **main_code,
- /*@out@*/ size_t *num_line_sections)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- dwarf2_line_info info;
- int new;
- size_t i;
- yasm_bytecode *sppbc;
- dwarf2_spp *spp;
- dwarf2_head *head;
-
- if (asm_source) {
- /* Generate dirs and filenames based on linemap */
- yasm_linemap_traverse_filenames(linemap, dbgfmt_dwarf2,
- dwarf2_generate_filename);
- }
-
- info.num_sections = 0;
- info.last_code = NULL;
- info.asm_source = asm_source;
- info.object = object;
- info.linemap = linemap;
- info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
- info.debug_line = yasm_object_get_general(object, ".debug_line", 1, 0, 0,
- &new, 0);
-
- /* header */
- head = yasm_dwarf2__add_head(dbgfmt_dwarf2, info.debug_line, NULL, 0, 0);
-
- /* statement program prologue */
- spp = yasm_xmalloc(sizeof(dwarf2_spp));
- sppbc = yasm_bc_create_common(&dwarf2_spp_bc_callback, spp, 0);
- sppbc->len = dbgfmt_dwarf2->sizeof_offset + 5 +
- NELEMS(line_opcode_num_operands);
-
- /* directory list */
- for (i=0; i<dbgfmt_dwarf2->dirs_size; i++)
- sppbc->len += (unsigned long)strlen(dbgfmt_dwarf2->dirs[i])+1;
- sppbc->len++;
-
- /* filename list */
- for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
- if (!dbgfmt_dwarf2->filenames[i].filename) {
- yasm_error_set(YASM_ERROR_GENERAL,
- N_("dwarf2 file number %d unassigned"), i+1);
- yasm_errwarn_propagate(errwarns, 0);
- continue;
- }
- sppbc->len +=
- (unsigned long)strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 +
- yasm_size_uleb128(dbgfmt_dwarf2->filenames[i].dir) + 2;
- }
- sppbc->len++;
- yasm_dwarf2__append_bc(info.debug_line, sppbc);
-
- /* statement program */
- yasm_object_sections_traverse(object, (void *)&info,
- dwarf2_generate_line_section);
-
- /* mark end of line information */
- yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(info.debug_line));
-
- *num_line_sections = info.num_sections;
- if (info.num_sections == 1)
- *main_code = info.last_code;
- else
- *main_code = NULL;
- return info.debug_line;
-}
-
-static void
-dwarf2_spp_bc_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-dwarf2_spp_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-dwarf2_spp_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 dwarf2 spp bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-dwarf2_spp_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);
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- unsigned char *buf = *bufp;
- yasm_intnum *cval;
- size_t i, len;
-
- /* Prologue length (following this field) */
- cval = yasm_intnum_create_uint(bc->len - (unsigned long)(buf-*bufp) -
- dbgfmt_dwarf2->sizeof_offset);
- yasm_arch_intnum_tobytes(object->arch, cval, buf,
- dbgfmt_dwarf2->sizeof_offset,
- dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
- buf += dbgfmt_dwarf2->sizeof_offset;
-
- YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len); /* minimum_instr_len */
- YASM_WRITE_8(buf, DWARF2_LINE_DEFAULT_IS_STMT); /* default_is_stmt */
- YASM_WRITE_8(buf, DWARF2_LINE_BASE); /* line_base */
- YASM_WRITE_8(buf, DWARF2_LINE_RANGE); /* line_range */
- YASM_WRITE_8(buf, DWARF2_LINE_OPCODE_BASE); /* opcode_base */
-
- /* Standard opcode # operands array */
- for (i=0; i<NELEMS(line_opcode_num_operands); i++)
- YASM_WRITE_8(buf, line_opcode_num_operands[i]);
-
- /* directory list */
- for (i=0; i<dbgfmt_dwarf2->dirs_size; i++) {
- len = strlen(dbgfmt_dwarf2->dirs[i])+1;
- memcpy(buf, dbgfmt_dwarf2->dirs[i], len);
- buf += len;
- }
- /* finish with single 0 byte */
- YASM_WRITE_8(buf, 0);
-
- /* filename list */
- for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
- len = strlen(dbgfmt_dwarf2->filenames[i].filename)+1;
- memcpy(buf, dbgfmt_dwarf2->filenames[i].filename, len);
- buf += len;
-
- /* dir */
- buf += yasm_get_uleb128(dbgfmt_dwarf2->filenames[i].dir, buf);
- YASM_WRITE_8(buf, 0); /* time */
- YASM_WRITE_8(buf, 0); /* length */
- }
- /* finish with single 0 byte */
- YASM_WRITE_8(buf, 0);
-
- *bufp = buf;
-
- yasm_intnum_destroy(cval);
- return 0;
-}
-
-static void
-dwarf2_line_op_bc_destroy(void *contents)
-{
- dwarf2_line_op *line_op = (dwarf2_line_op *)contents;
- if (line_op->operand)
- yasm_intnum_destroy(line_op->operand);
- if (line_op->ext_operand_int)
- yasm_intnum_destroy(line_op->ext_operand_int);
- yasm_xfree(contents);
-}
-
-static void
-dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level)
-{
- /* TODO */
-}
-
-static int
-dwarf2_line_op_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 dwarf2 line_op bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-dwarf2_line_op_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)
-{
- dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents;
- unsigned char *buf = *bufp;
-
- YASM_WRITE_8(buf, line_op->opcode);
- if (line_op->operand)
- buf += yasm_intnum_get_leb128(line_op->operand, buf,
- line_op->opcode == DW_LNS_advance_line);
- if (line_op->ext_opcode > 0) {
- YASM_WRITE_8(buf, line_op->ext_opcode);
- if (line_op->ext_operand) {
- yasm_value value;
- yasm_value_init_sym(&value, line_op->ext_operand,
- line_op->ext_operandsize*8);
- output_value(&value, buf, line_op->ext_operandsize,
- (unsigned long)(buf-bufstart), bc, 0, d);
- buf += line_op->ext_operandsize;
- }
- if (line_op->ext_operand_int) {
- buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0);
- }
- }
-
- *bufp = buf;
- return 0;
-}
-
-void
-yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams, unsigned long line)
-{
- yasm_valparam *vp;
- int in_is_stmt = 0, in_isa = 0, in_discriminator = 0;
-
- /*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
- dwarf2_section_data *dsd;
- dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc));
-
- /* File number (required) */
- if (!valparams || !(vp = yasm_vps_first(valparams)) ||
- vp->val || vp->type != YASM_PARAM_EXPR) {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
- yasm_xfree(loc);
- return;
- }
- intn = yasm_expr_get_intnum(&vp->param.e, 0);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("file number is not a constant"));
- yasm_xfree(loc);
- return;
- }
- if (yasm_intnum_sign(intn) != 1) {
- yasm_error_set(YASM_ERROR_VALUE, N_("file number less than one"));
- yasm_xfree(loc);
- return;
- }
- loc->file = yasm_intnum_get_uint(intn);
-
- /* Line number (required) */
- vp = yasm_vps_next(vp);
- if (!vp || vp->val || vp->type != YASM_PARAM_EXPR) {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
- yasm_xfree(loc);
- return;
- }
- intn = yasm_expr_get_intnum(&vp->param.e, 0);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("line number is not a constant"));
- yasm_xfree(loc);
- return;
- }
- loc->line = yasm_intnum_get_uint(intn);
-
- /* Generate new section data if it doesn't already exist */
- if (!object->cur_section) {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("[%s] can only be used inside of a section"), "loc");
- yasm_xfree(loc);
- return;
- }
- dsd = yasm_section_get_data(object->cur_section,
- &yasm_dwarf2__section_data_cb);
- if (!dsd) {
- dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
- STAILQ_INIT(&dsd->locs);
- yasm_section_add_data(object->cur_section,
- &yasm_dwarf2__section_data_cb, dsd);
- }
-
- /* Defaults for optional settings */
- loc->column = 0;
- loc->discriminator = 0;
- loc->isa_change = 0;
- loc->isa = 0;
- loc->is_stmt = IS_STMT_NOCHANGE;
- loc->basic_block = 0;
- loc->prologue_end = 0;
- loc->epilogue_begin = 0;
-
- /* Optional column number */
- vp = yasm_vps_next(vp);
- if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) {
- intn = yasm_expr_get_intnum(&vp->param.e, 0);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("column number is not a constant"));
- yasm_xfree(loc);
- return;
- }
- loc->column = yasm_intnum_get_uint(intn);
- vp = yasm_vps_next(vp);
- }
-
- /* Other options; note for GAS compatibility we need to support both:
- * is_stmt=1 (NASM) and
- * is_stmt 1 (GAS)
- */
- while (vp) {
- /*@null@*/ /*@dependent@*/ const char *s;
- /*@null@*/ /*@only@*/ yasm_expr *e;
-
-restart:
- if (in_is_stmt) {
- in_is_stmt = 0;
- if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
- !(intn = yasm_expr_get_intnum(&e, 0))) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("is_stmt value is not a constant"));
- yasm_xfree(loc);
- if (e)
- yasm_expr_destroy(e);
- return;
- }
- if (yasm_intnum_is_zero(intn))
- loc->is_stmt = IS_STMT_SET;
- else if (yasm_intnum_is_pos1(intn))
- loc->is_stmt = IS_STMT_CLEAR;
- else {
- yasm_error_set(YASM_ERROR_VALUE,
- N_("is_stmt value not 0 or 1"));
- yasm_xfree(loc);
- yasm_expr_destroy(e);
- return;
- }
- yasm_expr_destroy(e);
- } else if (in_isa) {
- in_isa = 0;
- if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
- !(intn = yasm_expr_get_intnum(&e, 0))) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("isa value is not a constant"));
- yasm_xfree(loc);
- if (e)
- yasm_expr_destroy(e);
- return;
- }
- if (yasm_intnum_sign(intn) < 0) {
- yasm_error_set(YASM_ERROR_VALUE,
- N_("isa value less than zero"));
- yasm_xfree(loc);
- yasm_expr_destroy(e);
- return;
- }
- loc->isa_change = 1;
- loc->isa = yasm_intnum_get_uint(intn);
- yasm_expr_destroy(e);
- } else if (in_discriminator) {
- in_discriminator = 0;
- if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
- !(intn = yasm_expr_get_intnum(&e, 0))) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("discriminator value is not a constant"));
- yasm_xfree(loc);
- if (e)
- yasm_expr_destroy(e);
- return;
- }
- if (yasm_intnum_sign(intn) < 0) {
- yasm_error_set(YASM_ERROR_VALUE,
- N_("discriminator value less than zero"));
- yasm_xfree(loc);
- yasm_expr_destroy(e);
- return;
- }
- loc->discriminator = yasm_intnum_get_uint(intn);
- yasm_expr_destroy(e);
- } else if (!vp->val && (s = yasm_vp_id(vp))) {
- if (yasm__strcasecmp(s, "is_stmt") == 0)
- in_is_stmt = 1;
- else if (yasm__strcasecmp(s, "isa") == 0)
- in_isa = 1;
- else if (yasm__strcasecmp(s, "discriminator") == 0)
- in_discriminator = 1;
- else if (yasm__strcasecmp(s, "basic_block") == 0)
- loc->basic_block = 1;
- else if (yasm__strcasecmp(s, "prologue_end") == 0)
- loc->prologue_end = 1;
- else if (yasm__strcasecmp(s, "epilogue_begin") == 0)
- loc->epilogue_begin = 1;
- else
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("unrecognized loc option `%s'"), s);
- } else if (!vp->val) {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("unrecognized numeric qualifier"));
- } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
- in_is_stmt = 1;
- goto restart; /* don't go to the next valparam */
- } else if (yasm__strcasecmp(vp->val, "isa") == 0) {
- in_isa = 1;
- goto restart; /* don't go to the next valparam */
- } else if (yasm__strcasecmp(vp->val, "discriminator") == 0) {
- in_discriminator = 1;
- goto restart; /* don't go to the next valparam */
- } else
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("unrecognized loc option `%s'"), vp->val);
- vp = yasm_vps_next(vp);
- }
-
- if (in_is_stmt || in_isa || in_discriminator) {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"),
- in_is_stmt ? "is_stmt" :
- (in_isa ? "isa" : "discriminator"));
- yasm_xfree(loc);
- return;
- }
-
- /* Append new location */
- loc->vline = line;
- loc->bc = NULL;
- loc->sym = NULL;
- STAILQ_INSERT_TAIL(&dsd->locs, loc, link);
-}
-
-void
-yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams, unsigned long line)
-{
- yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
- yasm_valparam *vp;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn;
- unsigned long filenum;
-
- if (!valparams) {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
- "FILE");
- return;
- }
-
- vp = yasm_vps_first(valparams);
- if (yasm_vp_string(vp)) {
- /* Just a bare filename */
- yasm_object_set_source_fn(object, yasm_vp_string(vp));
+ return 0;
+}
+
+yasm_section *
+yasm_dwarf2__generate_line(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns, int asm_source,
+ /*@out@*/ yasm_section **main_code,
+ /*@out@*/ size_t *num_line_sections)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ dwarf2_line_info info;
+ int new;
+ size_t i;
+ yasm_bytecode *sppbc;
+ dwarf2_spp *spp;
+ dwarf2_head *head;
+
+ if (asm_source) {
+ /* Generate dirs and filenames based on linemap */
+ yasm_linemap_traverse_filenames(linemap, dbgfmt_dwarf2,
+ dwarf2_generate_filename);
+ }
+
+ info.num_sections = 0;
+ info.last_code = NULL;
+ info.asm_source = asm_source;
+ info.object = object;
+ info.linemap = linemap;
+ info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
+ info.debug_line = yasm_object_get_general(object, ".debug_line", 1, 0, 0,
+ &new, 0);
+
+ /* header */
+ head = yasm_dwarf2__add_head(dbgfmt_dwarf2, info.debug_line, NULL, 0, 0);
+
+ /* statement program prologue */
+ spp = yasm_xmalloc(sizeof(dwarf2_spp));
+ sppbc = yasm_bc_create_common(&dwarf2_spp_bc_callback, spp, 0);
+ sppbc->len = dbgfmt_dwarf2->sizeof_offset + 5 +
+ NELEMS(line_opcode_num_operands);
+
+ /* directory list */
+ for (i=0; i<dbgfmt_dwarf2->dirs_size; i++)
+ sppbc->len += (unsigned long)strlen(dbgfmt_dwarf2->dirs[i])+1;
+ sppbc->len++;
+
+ /* filename list */
+ for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
+ if (!dbgfmt_dwarf2->filenames[i].filename) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("dwarf2 file number %d unassigned"), i+1);
+ yasm_errwarn_propagate(errwarns, 0);
+ continue;
+ }
+ sppbc->len +=
+ (unsigned long)strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 +
+ yasm_size_uleb128(dbgfmt_dwarf2->filenames[i].dir) + 2;
+ }
+ sppbc->len++;
+ yasm_dwarf2__append_bc(info.debug_line, sppbc);
+
+ /* statement program */
+ yasm_object_sections_traverse(object, (void *)&info,
+ dwarf2_generate_line_section);
+
+ /* mark end of line information */
+ yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(info.debug_line));
+
+ *num_line_sections = info.num_sections;
+ if (info.num_sections == 1)
+ *main_code = info.last_code;
+ else
+ *main_code = NULL;
+ return info.debug_line;
+}
+
+static void
+dwarf2_spp_bc_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+dwarf2_spp_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+dwarf2_spp_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 dwarf2 spp bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+dwarf2_spp_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);
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ unsigned char *buf = *bufp;
+ yasm_intnum *cval;
+ size_t i, len;
+
+ /* Prologue length (following this field) */
+ cval = yasm_intnum_create_uint(bc->len - (unsigned long)(buf-*bufp) -
+ dbgfmt_dwarf2->sizeof_offset);
+ yasm_arch_intnum_tobytes(object->arch, cval, buf,
+ dbgfmt_dwarf2->sizeof_offset,
+ dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
+ buf += dbgfmt_dwarf2->sizeof_offset;
+
+ YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len); /* minimum_instr_len */
+ YASM_WRITE_8(buf, DWARF2_LINE_DEFAULT_IS_STMT); /* default_is_stmt */
+ YASM_WRITE_8(buf, DWARF2_LINE_BASE); /* line_base */
+ YASM_WRITE_8(buf, DWARF2_LINE_RANGE); /* line_range */
+ YASM_WRITE_8(buf, DWARF2_LINE_OPCODE_BASE); /* opcode_base */
+
+ /* Standard opcode # operands array */
+ for (i=0; i<NELEMS(line_opcode_num_operands); i++)
+ YASM_WRITE_8(buf, line_opcode_num_operands[i]);
+
+ /* directory list */
+ for (i=0; i<dbgfmt_dwarf2->dirs_size; i++) {
+ len = strlen(dbgfmt_dwarf2->dirs[i])+1;
+ memcpy(buf, dbgfmt_dwarf2->dirs[i], len);
+ buf += len;
+ }
+ /* finish with single 0 byte */
+ YASM_WRITE_8(buf, 0);
+
+ /* filename list */
+ for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
+ len = strlen(dbgfmt_dwarf2->filenames[i].filename)+1;
+ memcpy(buf, dbgfmt_dwarf2->filenames[i].filename, len);
+ buf += len;
+
+ /* dir */
+ buf += yasm_get_uleb128(dbgfmt_dwarf2->filenames[i].dir, buf);
+ YASM_WRITE_8(buf, 0); /* time */
+ YASM_WRITE_8(buf, 0); /* length */
+ }
+ /* finish with single 0 byte */
+ YASM_WRITE_8(buf, 0);
+
+ *bufp = buf;
+
+ yasm_intnum_destroy(cval);
+ return 0;
+}
+
+static void
+dwarf2_line_op_bc_destroy(void *contents)
+{
+ dwarf2_line_op *line_op = (dwarf2_line_op *)contents;
+ if (line_op->operand)
+ yasm_intnum_destroy(line_op->operand);
+ if (line_op->ext_operand_int)
+ yasm_intnum_destroy(line_op->ext_operand_int);
+ yasm_xfree(contents);
+}
+
+static void
+dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level)
+{
+ /* TODO */
+}
+
+static int
+dwarf2_line_op_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 dwarf2 line_op bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+dwarf2_line_op_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)
+{
+ dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents;
+ unsigned char *buf = *bufp;
+
+ YASM_WRITE_8(buf, line_op->opcode);
+ if (line_op->operand)
+ buf += yasm_intnum_get_leb128(line_op->operand, buf,
+ line_op->opcode == DW_LNS_advance_line);
+ if (line_op->ext_opcode > 0) {
+ YASM_WRITE_8(buf, line_op->ext_opcode);
+ if (line_op->ext_operand) {
+ yasm_value value;
+ yasm_value_init_sym(&value, line_op->ext_operand,
+ line_op->ext_operandsize*8);
+ output_value(&value, buf, line_op->ext_operandsize,
+ (unsigned long)(buf-bufstart), bc, 0, d);
+ buf += line_op->ext_operandsize;
+ }
+ if (line_op->ext_operand_int) {
+ buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0);
+ }
+ }
+
+ *bufp = buf;
+ return 0;
+}
+
+void
+yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_valparam *vp;
+ int in_is_stmt = 0, in_isa = 0, in_discriminator = 0;
+
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
+ dwarf2_section_data *dsd;
+ dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc));
+
+ /* File number (required) */
+ if (!valparams || !(vp = yasm_vps_first(valparams)) ||
+ vp->val || vp->type != YASM_PARAM_EXPR) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
+ yasm_xfree(loc);
+ return;
+ }
+ intn = yasm_expr_get_intnum(&vp->param.e, 0);
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("file number is not a constant"));
+ yasm_xfree(loc);
+ return;
+ }
+ if (yasm_intnum_sign(intn) != 1) {
+ yasm_error_set(YASM_ERROR_VALUE, N_("file number less than one"));
+ yasm_xfree(loc);
+ return;
+ }
+ loc->file = yasm_intnum_get_uint(intn);
+
+ /* Line number (required) */
+ vp = yasm_vps_next(vp);
+ if (!vp || vp->val || vp->type != YASM_PARAM_EXPR) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
+ yasm_xfree(loc);
+ return;
+ }
+ intn = yasm_expr_get_intnum(&vp->param.e, 0);
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("line number is not a constant"));
+ yasm_xfree(loc);
+ return;
+ }
+ loc->line = yasm_intnum_get_uint(intn);
+
+ /* Generate new section data if it doesn't already exist */
+ if (!object->cur_section) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("[%s] can only be used inside of a section"), "loc");
+ yasm_xfree(loc);
+ return;
+ }
+ dsd = yasm_section_get_data(object->cur_section,
+ &yasm_dwarf2__section_data_cb);
+ if (!dsd) {
+ dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
+ STAILQ_INIT(&dsd->locs);
+ yasm_section_add_data(object->cur_section,
+ &yasm_dwarf2__section_data_cb, dsd);
+ }
+
+ /* Defaults for optional settings */
+ loc->column = 0;
+ loc->discriminator = 0;
+ loc->isa_change = 0;
+ loc->isa = 0;
+ loc->is_stmt = IS_STMT_NOCHANGE;
+ loc->basic_block = 0;
+ loc->prologue_end = 0;
+ loc->epilogue_begin = 0;
+
+ /* Optional column number */
+ vp = yasm_vps_next(vp);
+ if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) {
+ intn = yasm_expr_get_intnum(&vp->param.e, 0);
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("column number is not a constant"));
+ yasm_xfree(loc);
+ return;
+ }
+ loc->column = yasm_intnum_get_uint(intn);
+ vp = yasm_vps_next(vp);
+ }
+
+ /* Other options; note for GAS compatibility we need to support both:
+ * is_stmt=1 (NASM) and
+ * is_stmt 1 (GAS)
+ */
+ while (vp) {
+ /*@null@*/ /*@dependent@*/ const char *s;
+ /*@null@*/ /*@only@*/ yasm_expr *e;
+
+restart:
+ if (in_is_stmt) {
+ in_is_stmt = 0;
+ if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
+ !(intn = yasm_expr_get_intnum(&e, 0))) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("is_stmt value is not a constant"));
+ yasm_xfree(loc);
+ if (e)
+ yasm_expr_destroy(e);
+ return;
+ }
+ if (yasm_intnum_is_zero(intn))
+ loc->is_stmt = IS_STMT_SET;
+ else if (yasm_intnum_is_pos1(intn))
+ loc->is_stmt = IS_STMT_CLEAR;
+ else {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("is_stmt value not 0 or 1"));
+ yasm_xfree(loc);
+ yasm_expr_destroy(e);
+ return;
+ }
+ yasm_expr_destroy(e);
+ } else if (in_isa) {
+ in_isa = 0;
+ if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
+ !(intn = yasm_expr_get_intnum(&e, 0))) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("isa value is not a constant"));
+ yasm_xfree(loc);
+ if (e)
+ yasm_expr_destroy(e);
+ return;
+ }
+ if (yasm_intnum_sign(intn) < 0) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("isa value less than zero"));
+ yasm_xfree(loc);
+ yasm_expr_destroy(e);
+ return;
+ }
+ loc->isa_change = 1;
+ loc->isa = yasm_intnum_get_uint(intn);
+ yasm_expr_destroy(e);
+ } else if (in_discriminator) {
+ in_discriminator = 0;
+ if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
+ !(intn = yasm_expr_get_intnum(&e, 0))) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("discriminator value is not a constant"));
+ yasm_xfree(loc);
+ if (e)
+ yasm_expr_destroy(e);
+ return;
+ }
+ if (yasm_intnum_sign(intn) < 0) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("discriminator value less than zero"));
+ yasm_xfree(loc);
+ yasm_expr_destroy(e);
+ return;
+ }
+ loc->discriminator = yasm_intnum_get_uint(intn);
+ yasm_expr_destroy(e);
+ } else if (!vp->val && (s = yasm_vp_id(vp))) {
+ if (yasm__strcasecmp(s, "is_stmt") == 0)
+ in_is_stmt = 1;
+ else if (yasm__strcasecmp(s, "isa") == 0)
+ in_isa = 1;
+ else if (yasm__strcasecmp(s, "discriminator") == 0)
+ in_discriminator = 1;
+ else if (yasm__strcasecmp(s, "basic_block") == 0)
+ loc->basic_block = 1;
+ else if (yasm__strcasecmp(s, "prologue_end") == 0)
+ loc->prologue_end = 1;
+ else if (yasm__strcasecmp(s, "epilogue_begin") == 0)
+ loc->epilogue_begin = 1;
+ else
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("unrecognized loc option `%s'"), s);
+ } else if (!vp->val) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("unrecognized numeric qualifier"));
+ } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
+ in_is_stmt = 1;
+ goto restart; /* don't go to the next valparam */
+ } else if (yasm__strcasecmp(vp->val, "isa") == 0) {
+ in_isa = 1;
+ goto restart; /* don't go to the next valparam */
+ } else if (yasm__strcasecmp(vp->val, "discriminator") == 0) {
+ in_discriminator = 1;
+ goto restart; /* don't go to the next valparam */
+ } else
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("unrecognized loc option `%s'"), vp->val);
+ vp = yasm_vps_next(vp);
+ }
+
+ if (in_is_stmt || in_isa || in_discriminator) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"),
+ in_is_stmt ? "is_stmt" :
+ (in_isa ? "isa" : "discriminator"));
+ yasm_xfree(loc);
+ return;
+ }
+
+ /* Append new location */
+ loc->vline = line;
+ loc->bc = NULL;
+ loc->sym = NULL;
+ STAILQ_INSERT_TAIL(&dsd->locs, loc, link);
+}
+
+void
+yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
+ yasm_valparam *vp;
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn;
+ unsigned long filenum;
+
+ if (!valparams) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
+ "FILE");
+ return;
+ }
+
+ vp = yasm_vps_first(valparams);
+ if (yasm_vp_string(vp)) {
+ /* Just a bare filename */
+ yasm_object_set_source_fn(object, yasm_vp_string(vp));
object->deb_filename = yasm_replace_path(
dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
yasm_vp_string(vp), strlen(yasm_vp_string(vp)));
- return;
- }
-
- /* Otherwise.. first vp is the file number */
- if (vp->type != YASM_PARAM_EXPR ||
- !(file_intn = yasm_expr_get_intnum(&vp->param.e, 0))) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("file number is not a constant"));
- return;
- }
- filenum = yasm_intnum_get_uint(file_intn);
-
- vp = yasm_vps_next(vp);
- if (!yasm_vp_string(vp)) {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("file number given but no filename"));
- return;
- }
-
- dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp));
-}
+ return;
+ }
+
+ /* Otherwise.. first vp is the file number */
+ if (vp->type != YASM_PARAM_EXPR ||
+ !(file_intn = yasm_expr_get_intnum(&vp->param.e, 0))) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("file number is not a constant"));
+ return;
+ }
+ filenum = yasm_intnum_get_uint(file_intn);
+
+ vp = yasm_vps_next(vp);
+ if (!yasm_vp_string(vp)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("file number given but no filename"));
+ return;
+ }
+
+ dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp));
+}
diff --git a/contrib/tools/yasm/modules/dbgfmts/null/null-dbgfmt.c b/contrib/tools/yasm/modules/dbgfmts/null/null-dbgfmt.c
index 3153a6a2d7..d2d1bed58e 100644
--- a/contrib/tools/yasm/modules/dbgfmts/null/null-dbgfmt.c
+++ b/contrib/tools/yasm/modules/dbgfmts/null/null-dbgfmt.c
@@ -1,64 +1,64 @@
-/*
- * Null debugging format (creates NO debugging information)
- *
- * Copyright (C) 2002-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>
-
-
-yasm_dbgfmt_module yasm_null_LTX_dbgfmt;
-
-
-static /*@null@*/ /*@only@*/ yasm_dbgfmt *
-null_dbgfmt_create(yasm_object *object)
-{
- yasm_dbgfmt_base *dbgfmt = yasm_xmalloc(sizeof(yasm_dbgfmt_base));
- dbgfmt->module = &yasm_null_LTX_dbgfmt;
- return (yasm_dbgfmt *)dbgfmt;
-}
-
-static void
-null_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
-{
- yasm_xfree(dbgfmt);
-}
-
-static void
-null_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
-{
-}
-
-
-/* Define dbgfmt structure -- see dbgfmt.h for details */
-yasm_dbgfmt_module yasm_null_LTX_dbgfmt = {
- "No debugging info",
- "null",
- NULL, /* no directives */
- null_dbgfmt_create,
- null_dbgfmt_destroy,
- null_dbgfmt_generate
-};
+/*
+ * Null debugging format (creates NO debugging information)
+ *
+ * Copyright (C) 2002-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>
+
+
+yasm_dbgfmt_module yasm_null_LTX_dbgfmt;
+
+
+static /*@null@*/ /*@only@*/ yasm_dbgfmt *
+null_dbgfmt_create(yasm_object *object)
+{
+ yasm_dbgfmt_base *dbgfmt = yasm_xmalloc(sizeof(yasm_dbgfmt_base));
+ dbgfmt->module = &yasm_null_LTX_dbgfmt;
+ return (yasm_dbgfmt *)dbgfmt;
+}
+
+static void
+null_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
+{
+ yasm_xfree(dbgfmt);
+}
+
+static void
+null_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+}
+
+
+/* Define dbgfmt structure -- see dbgfmt.h for details */
+yasm_dbgfmt_module yasm_null_LTX_dbgfmt = {
+ "No debugging info",
+ "null",
+ NULL, /* no directives */
+ null_dbgfmt_create,
+ null_dbgfmt_destroy,
+ null_dbgfmt_generate
+};
diff --git a/contrib/tools/yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c b/contrib/tools/yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c
index a506d96605..5c0cba6aeb 100644
--- a/contrib/tools/yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c
+++ b/contrib/tools/yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c
@@ -1,511 +1,511 @@
-/*
- * Stabs debugging format
- *
- * Copyright (C) 2003-2007 Michael Urman
- *
- * 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>
-
-typedef enum {
- N_UNDF = 0x00, /* Undefined */
- N_GSYM = 0x20, /* Global symbol */
- N_FNAME = 0x22, /* Function name (BSD Fortran) */
- N_FUN = 0x24, /* Function name or Text segment variable */
- N_STSYM = 0x26, /* Data segment file-scope variable */
- N_LCSYM = 0x28, /* BSS segment file-scope variable */
- N_MAIN = 0x2a, /* Name of main routine */
- N_ROSYM = 0x2c, /* Variable in .rodata section */
- N_PC = 0x30, /* Global symbol (Pascal) */
- N_SYMS = 0x32, /* Number of symbols (Ultrix V4.0) */
- N_NOMAP = 0x34, /* No DST map */
- N_OBJ = 0x38, /* Object file (Solaris2) */
- N_OPT = 0x3c, /* Debugger options (Solaris2) */
- N_RSYM = 0x40, /* Register variable */
- N_M2C = 0x42, /* Modula-2 compilation unit */
- N_SLINE = 0x44, /* Line numbers in .text segment */
- N_DSLINE = 0x46, /* Line numbers in .data segment */
- N_BSLINE = 0x48, /* Line numbers in .bss segment */
- N_BROWS = 0x48, /* Source code .cb file's path */
- N_DEFD = 0x4a, /* GNU Modula-2 definition module dependency */
- N_FLINE = 0x4c, /* Function start/body/end line numbers (Solaris2) */
- N_EHDECL = 0x50, /* GNU C++ exception variable */
- N_MOD2 = 0x50, /* Modula2 info for imc (Ultrix V4.0) */
- N_CATCH = 0x54, /* GNU C++ catch clause */
- N_SSYM = 0x60, /* Structure or union element */
- N_ENDM = 0x62, /* Last stab for module (Solaris2) */
- N_SO = 0x64, /* Path and name of source files */
- N_LSYM = 0x80, /* Stack variable */
- N_BINCL = 0x84, /* Beginning of include file */
- N_SOL = 0x84, /* Name of include file */
- N_PSYM = 0xa0, /* Parameter variable */
- N_EINCL = 0xa2, /* End of include file */
- N_ENTRY = 0xa4, /* Alternate entry point */
- N_LBRAC = 0xc0, /* Beginning of lexical block */
- N_EXCL = 0xc2, /* Placeholder for a deleted include file */
- N_SCOPE = 0xc4, /* Modula 2 scope info (Sun) */
- N_RBRAC = 0xe0, /* End of lexical block */
- N_BCOMM = 0xe2, /* Begin named common block */
- N_ECOMM = 0xe4, /* End named common block */
- N_ECOML = 0xe8, /* Member of common block */
- N_WITH = 0xea, /* Pascal with statement: type,,0,0,offset (Solaris2) */
- N_NBTEXT = 0xf0, /* Gould non-base registers */
- N_NBDATA = 0xf2, /* Gould non-base registers */
- N_NBBSS = 0xf4, /* Gould non-base registers */
- N_NBSTS = 0xf6, /* Gould non-base registers */
- N_NBLCS = 0xf8 /* Gould non-base registers */
-} stabs_stab_type;
-
-typedef struct yasm_dbgfmt_stabs {
- yasm_dbgfmt_base dbgfmt; /* base structure */
-} yasm_dbgfmt_stabs;
-
-typedef struct {
- unsigned long lastline; /* track line and file of bytecodes */
- unsigned long curline;
- const char *lastfile;
- const char *curfile;
-
- unsigned int stablen; /* size of a stab for current machine */
- unsigned long stabcount; /* count stored stabs; doesn't include first */
-
- yasm_section *stab; /* sections to which stabs, stabstrs appended */
- yasm_section *stabstr;
-
- yasm_bytecode *basebc; /* base bytecode from which to track SLINEs */
-
- yasm_object *object;
- yasm_linemap *linemap;
- yasm_errwarns *errwarns;
-} stabs_info;
-
-typedef struct {
- /*@null@*/ yasm_bytecode *bcstr; /* bytecode in stabstr for string */
- stabs_stab_type type; /* stab type: N_* */
- unsigned char other; /* unused, but stored here anyway */
- unsigned short desc; /* description element of a stab */
- /*@null@*/ yasm_symrec *symvalue; /* value element needing relocation */
- /*@null@*/yasm_bytecode *bcvalue; /* relocated stab's bytecode */
- unsigned long value; /* fallthrough value if above NULL */
-} stabs_stab;
-
-/* Bytecode callback function prototypes */
-
-static void stabs_bc_str_destroy(void *contents);
-static void stabs_bc_str_print(const void *contents, FILE *f, int
- indent_level);
-static int stabs_bc_str_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int stabs_bc_str_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 stabs_bc_stab_destroy(void *contents);
-static void stabs_bc_stab_print(const void *contents, FILE *f, int
- indent_level);
-static int stabs_bc_stab_calc_len
- (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
-static int stabs_bc_stab_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 stabs_bc_str_callback = {
- stabs_bc_str_destroy,
- stabs_bc_str_print,
- yasm_bc_finalize_common,
- NULL,
- stabs_bc_str_calc_len,
- yasm_bc_expand_common,
- stabs_bc_str_tobytes,
- 0
-};
-
-static const yasm_bytecode_callback stabs_bc_stab_callback = {
- stabs_bc_stab_destroy,
- stabs_bc_stab_print,
- yasm_bc_finalize_common,
- NULL,
- stabs_bc_stab_calc_len,
- yasm_bc_expand_common,
- stabs_bc_stab_tobytes,
- 0
-};
-
-yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt;
-
-
-static /*@null@*/ /*@only@*/ yasm_dbgfmt *
-stabs_dbgfmt_create(yasm_object *object)
-{
- yasm_dbgfmt_stabs *dbgfmt_stabs = yasm_xmalloc(sizeof(yasm_dbgfmt_stabs));
- dbgfmt_stabs->dbgfmt.module = &yasm_stabs_LTX_dbgfmt;
- return (yasm_dbgfmt *)dbgfmt_stabs;
-}
-
-static void
-stabs_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
-{
- yasm_xfree(dbgfmt);
-}
-
-/* Create and add a new strtab-style string bytecode to a section, updating
- * offset on insertion; no optimization necessary */
-/* Copies the string, so you must still free yours as normal */
-static yasm_bytecode *
-stabs_dbgfmt_append_bcstr(yasm_section *sect, const char *str)
-{
- yasm_bytecode *bc;
+/*
+ * Stabs debugging format
+ *
+ * Copyright (C) 2003-2007 Michael Urman
+ *
+ * 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>
+
+typedef enum {
+ N_UNDF = 0x00, /* Undefined */
+ N_GSYM = 0x20, /* Global symbol */
+ N_FNAME = 0x22, /* Function name (BSD Fortran) */
+ N_FUN = 0x24, /* Function name or Text segment variable */
+ N_STSYM = 0x26, /* Data segment file-scope variable */
+ N_LCSYM = 0x28, /* BSS segment file-scope variable */
+ N_MAIN = 0x2a, /* Name of main routine */
+ N_ROSYM = 0x2c, /* Variable in .rodata section */
+ N_PC = 0x30, /* Global symbol (Pascal) */
+ N_SYMS = 0x32, /* Number of symbols (Ultrix V4.0) */
+ N_NOMAP = 0x34, /* No DST map */
+ N_OBJ = 0x38, /* Object file (Solaris2) */
+ N_OPT = 0x3c, /* Debugger options (Solaris2) */
+ N_RSYM = 0x40, /* Register variable */
+ N_M2C = 0x42, /* Modula-2 compilation unit */
+ N_SLINE = 0x44, /* Line numbers in .text segment */
+ N_DSLINE = 0x46, /* Line numbers in .data segment */
+ N_BSLINE = 0x48, /* Line numbers in .bss segment */
+ N_BROWS = 0x48, /* Source code .cb file's path */
+ N_DEFD = 0x4a, /* GNU Modula-2 definition module dependency */
+ N_FLINE = 0x4c, /* Function start/body/end line numbers (Solaris2) */
+ N_EHDECL = 0x50, /* GNU C++ exception variable */
+ N_MOD2 = 0x50, /* Modula2 info for imc (Ultrix V4.0) */
+ N_CATCH = 0x54, /* GNU C++ catch clause */
+ N_SSYM = 0x60, /* Structure or union element */
+ N_ENDM = 0x62, /* Last stab for module (Solaris2) */
+ N_SO = 0x64, /* Path and name of source files */
+ N_LSYM = 0x80, /* Stack variable */
+ N_BINCL = 0x84, /* Beginning of include file */
+ N_SOL = 0x84, /* Name of include file */
+ N_PSYM = 0xa0, /* Parameter variable */
+ N_EINCL = 0xa2, /* End of include file */
+ N_ENTRY = 0xa4, /* Alternate entry point */
+ N_LBRAC = 0xc0, /* Beginning of lexical block */
+ N_EXCL = 0xc2, /* Placeholder for a deleted include file */
+ N_SCOPE = 0xc4, /* Modula 2 scope info (Sun) */
+ N_RBRAC = 0xe0, /* End of lexical block */
+ N_BCOMM = 0xe2, /* Begin named common block */
+ N_ECOMM = 0xe4, /* End named common block */
+ N_ECOML = 0xe8, /* Member of common block */
+ N_WITH = 0xea, /* Pascal with statement: type,,0,0,offset (Solaris2) */
+ N_NBTEXT = 0xf0, /* Gould non-base registers */
+ N_NBDATA = 0xf2, /* Gould non-base registers */
+ N_NBBSS = 0xf4, /* Gould non-base registers */
+ N_NBSTS = 0xf6, /* Gould non-base registers */
+ N_NBLCS = 0xf8 /* Gould non-base registers */
+} stabs_stab_type;
+
+typedef struct yasm_dbgfmt_stabs {
+ yasm_dbgfmt_base dbgfmt; /* base structure */
+} yasm_dbgfmt_stabs;
+
+typedef struct {
+ unsigned long lastline; /* track line and file of bytecodes */
+ unsigned long curline;
+ const char *lastfile;
+ const char *curfile;
+
+ unsigned int stablen; /* size of a stab for current machine */
+ unsigned long stabcount; /* count stored stabs; doesn't include first */
+
+ yasm_section *stab; /* sections to which stabs, stabstrs appended */
+ yasm_section *stabstr;
+
+ yasm_bytecode *basebc; /* base bytecode from which to track SLINEs */
+
+ yasm_object *object;
+ yasm_linemap *linemap;
+ yasm_errwarns *errwarns;
+} stabs_info;
+
+typedef struct {
+ /*@null@*/ yasm_bytecode *bcstr; /* bytecode in stabstr for string */
+ stabs_stab_type type; /* stab type: N_* */
+ unsigned char other; /* unused, but stored here anyway */
+ unsigned short desc; /* description element of a stab */
+ /*@null@*/ yasm_symrec *symvalue; /* value element needing relocation */
+ /*@null@*/yasm_bytecode *bcvalue; /* relocated stab's bytecode */
+ unsigned long value; /* fallthrough value if above NULL */
+} stabs_stab;
+
+/* Bytecode callback function prototypes */
+
+static void stabs_bc_str_destroy(void *contents);
+static void stabs_bc_str_print(const void *contents, FILE *f, int
+ indent_level);
+static int stabs_bc_str_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int stabs_bc_str_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 stabs_bc_stab_destroy(void *contents);
+static void stabs_bc_stab_print(const void *contents, FILE *f, int
+ indent_level);
+static int stabs_bc_stab_calc_len
+ (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
+static int stabs_bc_stab_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 stabs_bc_str_callback = {
+ stabs_bc_str_destroy,
+ stabs_bc_str_print,
+ yasm_bc_finalize_common,
+ NULL,
+ stabs_bc_str_calc_len,
+ yasm_bc_expand_common,
+ stabs_bc_str_tobytes,
+ 0
+};
+
+static const yasm_bytecode_callback stabs_bc_stab_callback = {
+ stabs_bc_stab_destroy,
+ stabs_bc_stab_print,
+ yasm_bc_finalize_common,
+ NULL,
+ stabs_bc_stab_calc_len,
+ yasm_bc_expand_common,
+ stabs_bc_stab_tobytes,
+ 0
+};
+
+yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt;
+
+
+static /*@null@*/ /*@only@*/ yasm_dbgfmt *
+stabs_dbgfmt_create(yasm_object *object)
+{
+ yasm_dbgfmt_stabs *dbgfmt_stabs = yasm_xmalloc(sizeof(yasm_dbgfmt_stabs));
+ dbgfmt_stabs->dbgfmt.module = &yasm_stabs_LTX_dbgfmt;
+ return (yasm_dbgfmt *)dbgfmt_stabs;
+}
+
+static void
+stabs_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
+{
+ yasm_xfree(dbgfmt);
+}
+
+/* Create and add a new strtab-style string bytecode to a section, updating
+ * offset on insertion; no optimization necessary */
+/* Copies the string, so you must still free yours as normal */
+static yasm_bytecode *
+stabs_dbgfmt_append_bcstr(yasm_section *sect, const char *str)
+{
+ yasm_bytecode *bc;
+
+ bc = yasm_bc_create_common(&stabs_bc_str_callback, yasm__xstrdup(str), 0);
+ bc->len = (unsigned long)(strlen(str)+1);
+ bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
+
+ yasm_section_bcs_append(sect, bc);
+
+ return bc;
+}
+
+/* Create and add a new stab bytecode to a section, updating offset on
+ * insertion; no optimization necessary. */
+/* Requires a string bytecode, or NULL, for its string entry */
+static stabs_stab *
+stabs_dbgfmt_append_stab(stabs_info *info, yasm_section *sect,
+ /*@null@*/ yasm_bytecode *bcstr, stabs_stab_type type,
+ unsigned long desc, /*@null@*/ yasm_symrec *symvalue,
+ /*@null@*/ yasm_bytecode *bcvalue, unsigned long value)
+{
+ yasm_bytecode *bc;
+ stabs_stab *stab = yasm_xmalloc(sizeof(stabs_stab));
+
+ stab->other = 0;
+ stab->bcstr = bcstr;
+ stab->type = type;
+ stab->desc = (unsigned short)desc;
+ stab->symvalue = symvalue;
+ stab->bcvalue = bcvalue;
+ stab->value = value;
+
+ bc = yasm_bc_create_common(&stabs_bc_stab_callback, stab,
+ bcvalue ? bcvalue->line : 0);
+ bc->len = info->stablen;
+ bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
+
+ yasm_section_bcs_append(sect, bc);
+
+ info->stabcount++;
+ return stab;
+}
+
+static void
+stabs_dbgfmt_generate_n_fun(stabs_info *info, yasm_bytecode *bc)
+{
+ /* check all syms at this bc for potential function syms */
+ int bcsym;
+ for (bcsym=0; bc->symrecs && bc->symrecs[bcsym]; bcsym++)
+ {
+ char *str;
+ yasm_symrec *sym = bc->symrecs[bcsym];
+ const char *name = yasm_symrec_get_name(sym);
+
+ /* best guess algorithm - ignore labels containing a . or $ */
+ if (strchr(name, '.') || strchr(name, '$'))
+ continue;
+
+ /* if a function, update basebc, and output a funcname:F1 stab */
+ info->basebc = bc;
+
+ str = yasm_xmalloc(strlen(name)+4);
+ strcpy(str, name);
+ strcat(str, ":F1");
+ stabs_dbgfmt_append_stab(info, info->stab,
+ stabs_dbgfmt_append_bcstr(info->stabstr, str),
+ N_FUN, 0, sym, info->basebc, 0);
+ yasm_xfree(str);
+ break;
+ }
+}
+
+static int
+stabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d)
+{
+ stabs_info *info = (stabs_info *)d;
+ yasm_linemap_lookup(info->linemap, bc->line, &info->curfile,
+ &info->curline);
+
+ /* check for new function */
+ stabs_dbgfmt_generate_n_fun(info, bc);
+
+ if (info->lastfile != info->curfile) {
+ info->lastline = 0; /* new file, so line changes */
+ /*stabs_dbgfmt_append_stab(info, info->stab,
+ stabs_dbgfmt_append_bcstr(info->stabstr, info->curfile),
+ N_SOL, 0, NULL, bc, 0);*/
+ }
+
+ /* output new line stabs if there's a basebc (known function) */
+ if (info->basebc != NULL && info->curline != info->lastline) {
+ info->lastline = bc->line;
+ stabs_dbgfmt_append_stab(info, info->stab, NULL, N_SLINE,
+ info->curline, NULL, NULL,
+ bc->offset - info->basebc->offset);
+ }
+
+ info->lastline = info->curline;
+ info->lastfile = info->curfile;
+
+ return 0;
+}
+
+static int
+stabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d)
+{
+ stabs_info *info = (stabs_info *)d;
+ const char *sectname=yasm_section_get_name(sect);
+
+ /* each section has a different base symbol */
+ info->basebc = NULL;
- bc = yasm_bc_create_common(&stabs_bc_str_callback, yasm__xstrdup(str), 0);
- bc->len = (unsigned long)(strlen(str)+1);
- bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
-
- yasm_section_bcs_append(sect, bc);
-
- return bc;
-}
-
-/* Create and add a new stab bytecode to a section, updating offset on
- * insertion; no optimization necessary. */
-/* Requires a string bytecode, or NULL, for its string entry */
-static stabs_stab *
-stabs_dbgfmt_append_stab(stabs_info *info, yasm_section *sect,
- /*@null@*/ yasm_bytecode *bcstr, stabs_stab_type type,
- unsigned long desc, /*@null@*/ yasm_symrec *symvalue,
- /*@null@*/ yasm_bytecode *bcvalue, unsigned long value)
-{
- yasm_bytecode *bc;
- stabs_stab *stab = yasm_xmalloc(sizeof(stabs_stab));
-
- stab->other = 0;
- stab->bcstr = bcstr;
- stab->type = type;
- stab->desc = (unsigned short)desc;
- stab->symvalue = symvalue;
- stab->bcvalue = bcvalue;
- stab->value = value;
-
- bc = yasm_bc_create_common(&stabs_bc_stab_callback, stab,
- bcvalue ? bcvalue->line : 0);
- bc->len = info->stablen;
- bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
-
- yasm_section_bcs_append(sect, bc);
-
- info->stabcount++;
- return stab;
-}
-
-static void
-stabs_dbgfmt_generate_n_fun(stabs_info *info, yasm_bytecode *bc)
-{
- /* check all syms at this bc for potential function syms */
- int bcsym;
- for (bcsym=0; bc->symrecs && bc->symrecs[bcsym]; bcsym++)
- {
- char *str;
- yasm_symrec *sym = bc->symrecs[bcsym];
- const char *name = yasm_symrec_get_name(sym);
-
- /* best guess algorithm - ignore labels containing a . or $ */
- if (strchr(name, '.') || strchr(name, '$'))
- continue;
-
- /* if a function, update basebc, and output a funcname:F1 stab */
- info->basebc = bc;
-
- str = yasm_xmalloc(strlen(name)+4);
- strcpy(str, name);
- strcat(str, ":F1");
- stabs_dbgfmt_append_stab(info, info->stab,
- stabs_dbgfmt_append_bcstr(info->stabstr, str),
- N_FUN, 0, sym, info->basebc, 0);
- yasm_xfree(str);
- break;
- }
-}
-
-static int
-stabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d)
-{
- stabs_info *info = (stabs_info *)d;
- yasm_linemap_lookup(info->linemap, bc->line, &info->curfile,
- &info->curline);
-
- /* check for new function */
- stabs_dbgfmt_generate_n_fun(info, bc);
-
- if (info->lastfile != info->curfile) {
- info->lastline = 0; /* new file, so line changes */
- /*stabs_dbgfmt_append_stab(info, info->stab,
- stabs_dbgfmt_append_bcstr(info->stabstr, info->curfile),
- N_SOL, 0, NULL, bc, 0);*/
- }
-
- /* output new line stabs if there's a basebc (known function) */
- if (info->basebc != NULL && info->curline != info->lastline) {
- info->lastline = bc->line;
- stabs_dbgfmt_append_stab(info, info->stab, NULL, N_SLINE,
- info->curline, NULL, NULL,
- bc->offset - info->basebc->offset);
- }
-
- info->lastline = info->curline;
- info->lastfile = info->curfile;
-
- return 0;
-}
-
-static int
-stabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d)
-{
- stabs_info *info = (stabs_info *)d;
- const char *sectname=yasm_section_get_name(sect);
-
- /* each section has a different base symbol */
- info->basebc = NULL;
-
- /* handle first (pseudo) bc separately */
- stabs_dbgfmt_generate_n_fun(d, yasm_section_bcs_first(sect));
-
- yasm_section_bcs_traverse(sect, info->errwarns, d,
- stabs_dbgfmt_generate_bcs);
-
- if (yasm__strcasecmp(sectname, ".text")==0) {
- /* Close out last function by appending a null SO stab after last bc */
- yasm_bytecode *bc = yasm_section_bcs_last(sect);
- yasm_symrec *sym =
- yasm_symtab_define_label(info->object->symtab, ".n_so", bc, 1,
- bc->line);
- stabs_dbgfmt_append_stab(info, info->stab, 0, N_SO, 0, sym, bc, 0);
- }
-
- return 1;
-}
-
-static void
-stabs_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
-{
- stabs_info info;
- int new;
- yasm_bytecode *dbgbc;
- stabs_stab *stab;
- yasm_bytecode *filebc, *laststr, *firstbc;
- yasm_symrec *firstsym;
- yasm_section *stext;
-
- /* Stablen is determined by arch/machine */
- if (yasm__strcasecmp(yasm_arch_keyword(object->arch), "x86") == 0) {
- info.stablen = 12;
- }
- else /* unknown machine; generate nothing */
- return;
-
- info.object = object;
- info.linemap = linemap;
- info.errwarns = errwarns;
- info.lastline = 0;
- info.stabcount = 0;
- info.stab = yasm_object_get_general(object, ".stab", 4, 0, 0, &new, 0);
- if (!new) {
- yasm_bytecode *last = yasm_section_bcs_last(info.stab);
- if (last == NULL) {
- yasm_error_set(YASM_ERROR_GENERAL,
- N_("stabs debugging conflicts with user-defined section .stab"));
- yasm_errwarn_propagate(errwarns,
- yasm_section_bcs_first(info.stab)->line);
- } else {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("stabs debugging overrides empty section .stab"));
- yasm_errwarn_propagate(errwarns, 0);
- }
- }
-
- info.stabstr =
- yasm_object_get_general(object, ".stabstr", 1, 0, 0, &new, 0);
- if (!new) {
- yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
- if (last == NULL) {
- yasm_error_set(YASM_ERROR_GENERAL,
- N_("stabs debugging conflicts with user-defined section .stabstr"));
- yasm_errwarn_propagate(errwarns,
- yasm_section_bcs_first(info.stab)->line);
- } else {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("stabs debugging overrides empty section .stabstr"));
- yasm_errwarn_propagate(errwarns, 0);
- }
- }
-
- /* initial pseudo-stab */
- stab = yasm_xmalloc(sizeof(stabs_stab));
- dbgbc = yasm_bc_create_common(&stabs_bc_stab_callback, stab, 0);
- dbgbc->len = info.stablen;
- dbgbc->offset = 0;
- yasm_section_bcs_append(info.stab, dbgbc);
-
- /* initial strtab bytecodes */
- stabs_dbgfmt_append_bcstr(info.stabstr, "");
- filebc = stabs_dbgfmt_append_bcstr(info.stabstr, object->src_filename);
-
- stext = yasm_object_find_general(object, ".text");
- firstsym = yasm_symtab_use(object->symtab, ".text", 0);
- firstbc = yasm_section_bcs_first(stext);
- /* N_SO file stab */
- stabs_dbgfmt_append_stab(&info, info.stab, filebc, N_SO, 0,
- firstsym, firstbc, 0);
-
- yasm_object_sections_traverse(object, (void *)&info,
- stabs_dbgfmt_generate_sections);
-
- /* fill initial pseudo-stab's fields */
- laststr = yasm_section_bcs_last(info.stabstr);
- if (laststr == NULL)
- yasm_internal_error(".stabstr has no entries");
-
- stab->bcvalue = NULL;
- stab->symvalue = NULL;
- stab->value = yasm_bc_next_offset(laststr);
- stab->bcstr = filebc;
- stab->type = N_UNDF;
- stab->other = 0;
- if (info.stabcount > 0xffff) {
- yasm_warn_set(YASM_WARN_GENERAL, N_("over 65535 stabs"));
- yasm_errwarn_propagate(errwarns, 0);
- stab->desc = 0xffff;
- } else
- stab->desc = (unsigned short)info.stabcount;
-}
-
-static int
-stabs_bc_stab_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- /* This entire function, essentially the core of rendering stabs to a file,
- * needs to become endian aware. Size appears not to be an issue, as known
- * 64-bit systems use truncated values in 32-bit fields. */
-
- const stabs_stab *stab = (const stabs_stab *)bc->contents;
- unsigned char *buf = *bufp;
-
- YASM_WRITE_32_L(buf, stab->bcstr ? stab->bcstr->offset : 0);
- YASM_WRITE_8(buf, stab->type);
- YASM_WRITE_8(buf, stab->other);
- YASM_WRITE_16_L(buf, stab->desc);
-
- if (stab->symvalue != NULL) {
- bc->offset += 8;
- output_reloc(stab->symvalue, bc, buf, 4, 32, 0, d);
- bc->offset -= 8;
- buf += 4;
- }
- else if (stab->bcvalue != NULL) {
- YASM_WRITE_32_L(buf, stab->bcvalue->offset);
- }
- else {
- YASM_WRITE_32_L(buf, stab->value);
- }
-
- *bufp = buf;
- return 0;
-}
-
-static int
-stabs_bc_str_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- unsigned char *bufstart, void *d,
- yasm_output_value_func output_value,
- yasm_output_reloc_func output_reloc)
-{
- const char *str = (const char *)bc->contents;
- unsigned char *buf = *bufp;
-
- strcpy((char *)buf, str);
- buf += strlen(str)+1;
-
- *bufp = buf;
- return 0;
-}
-
-static void
-stabs_bc_stab_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-stabs_bc_str_destroy(void *contents)
-{
- yasm_xfree(contents);
-}
-
-static void
-stabs_bc_stab_print(const void *contents, FILE *f, int indent_level)
-{
- const stabs_stab *stab = (const stabs_stab *)contents;
- const char *str = "";
- fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
- indent_level, "", str, stab->type, stab->other, stab->desc,
- stab->bcvalue ? stab->bcvalue->offset : stab->value);
-}
-
-static void
-stabs_bc_str_print(const void *contents, FILE *f, int indent_level)
-{
- fprintf(f, "%*s\"%s\"\n", indent_level, "", (const char *)contents);
-}
-
-static int
-stabs_bc_stab_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to resolve a stabs stab bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-static int
-stabs_bc_str_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
- void *add_span_data)
-{
- yasm_internal_error(N_("tried to resolve a stabs str bytecode"));
- /*@notreached@*/
- return 0;
-}
-
-/* Define dbgfmt structure -- see dbgfmt.h for details */
-yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt = {
- "Stabs debugging format",
- "stabs",
- NULL, /* no directives */
- stabs_dbgfmt_create,
- stabs_dbgfmt_destroy,
- stabs_dbgfmt_generate
-};
+ /* handle first (pseudo) bc separately */
+ stabs_dbgfmt_generate_n_fun(d, yasm_section_bcs_first(sect));
+
+ yasm_section_bcs_traverse(sect, info->errwarns, d,
+ stabs_dbgfmt_generate_bcs);
+
+ if (yasm__strcasecmp(sectname, ".text")==0) {
+ /* Close out last function by appending a null SO stab after last bc */
+ yasm_bytecode *bc = yasm_section_bcs_last(sect);
+ yasm_symrec *sym =
+ yasm_symtab_define_label(info->object->symtab, ".n_so", bc, 1,
+ bc->line);
+ stabs_dbgfmt_append_stab(info, info->stab, 0, N_SO, 0, sym, bc, 0);
+ }
+
+ return 1;
+}
+
+static void
+stabs_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ stabs_info info;
+ int new;
+ yasm_bytecode *dbgbc;
+ stabs_stab *stab;
+ yasm_bytecode *filebc, *laststr, *firstbc;
+ yasm_symrec *firstsym;
+ yasm_section *stext;
+
+ /* Stablen is determined by arch/machine */
+ if (yasm__strcasecmp(yasm_arch_keyword(object->arch), "x86") == 0) {
+ info.stablen = 12;
+ }
+ else /* unknown machine; generate nothing */
+ return;
+
+ info.object = object;
+ info.linemap = linemap;
+ info.errwarns = errwarns;
+ info.lastline = 0;
+ info.stabcount = 0;
+ info.stab = yasm_object_get_general(object, ".stab", 4, 0, 0, &new, 0);
+ if (!new) {
+ yasm_bytecode *last = yasm_section_bcs_last(info.stab);
+ if (last == NULL) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("stabs debugging conflicts with user-defined section .stab"));
+ yasm_errwarn_propagate(errwarns,
+ yasm_section_bcs_first(info.stab)->line);
+ } else {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("stabs debugging overrides empty section .stab"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
+ }
+
+ info.stabstr =
+ yasm_object_get_general(object, ".stabstr", 1, 0, 0, &new, 0);
+ if (!new) {
+ yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
+ if (last == NULL) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("stabs debugging conflicts with user-defined section .stabstr"));
+ yasm_errwarn_propagate(errwarns,
+ yasm_section_bcs_first(info.stab)->line);
+ } else {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("stabs debugging overrides empty section .stabstr"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
+ }
+
+ /* initial pseudo-stab */
+ stab = yasm_xmalloc(sizeof(stabs_stab));
+ dbgbc = yasm_bc_create_common(&stabs_bc_stab_callback, stab, 0);
+ dbgbc->len = info.stablen;
+ dbgbc->offset = 0;
+ yasm_section_bcs_append(info.stab, dbgbc);
+
+ /* initial strtab bytecodes */
+ stabs_dbgfmt_append_bcstr(info.stabstr, "");
+ filebc = stabs_dbgfmt_append_bcstr(info.stabstr, object->src_filename);
+
+ stext = yasm_object_find_general(object, ".text");
+ firstsym = yasm_symtab_use(object->symtab, ".text", 0);
+ firstbc = yasm_section_bcs_first(stext);
+ /* N_SO file stab */
+ stabs_dbgfmt_append_stab(&info, info.stab, filebc, N_SO, 0,
+ firstsym, firstbc, 0);
+
+ yasm_object_sections_traverse(object, (void *)&info,
+ stabs_dbgfmt_generate_sections);
+
+ /* fill initial pseudo-stab's fields */
+ laststr = yasm_section_bcs_last(info.stabstr);
+ if (laststr == NULL)
+ yasm_internal_error(".stabstr has no entries");
+
+ stab->bcvalue = NULL;
+ stab->symvalue = NULL;
+ stab->value = yasm_bc_next_offset(laststr);
+ stab->bcstr = filebc;
+ stab->type = N_UNDF;
+ stab->other = 0;
+ if (info.stabcount > 0xffff) {
+ yasm_warn_set(YASM_WARN_GENERAL, N_("over 65535 stabs"));
+ yasm_errwarn_propagate(errwarns, 0);
+ stab->desc = 0xffff;
+ } else
+ stab->desc = (unsigned short)info.stabcount;
+}
+
+static int
+stabs_bc_stab_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ /* This entire function, essentially the core of rendering stabs to a file,
+ * needs to become endian aware. Size appears not to be an issue, as known
+ * 64-bit systems use truncated values in 32-bit fields. */
+
+ const stabs_stab *stab = (const stabs_stab *)bc->contents;
+ unsigned char *buf = *bufp;
+
+ YASM_WRITE_32_L(buf, stab->bcstr ? stab->bcstr->offset : 0);
+ YASM_WRITE_8(buf, stab->type);
+ YASM_WRITE_8(buf, stab->other);
+ YASM_WRITE_16_L(buf, stab->desc);
+
+ if (stab->symvalue != NULL) {
+ bc->offset += 8;
+ output_reloc(stab->symvalue, bc, buf, 4, 32, 0, d);
+ bc->offset -= 8;
+ buf += 4;
+ }
+ else if (stab->bcvalue != NULL) {
+ YASM_WRITE_32_L(buf, stab->bcvalue->offset);
+ }
+ else {
+ YASM_WRITE_32_L(buf, stab->value);
+ }
+
+ *bufp = buf;
+ return 0;
+}
+
+static int
+stabs_bc_str_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
+ yasm_output_value_func output_value,
+ yasm_output_reloc_func output_reloc)
+{
+ const char *str = (const char *)bc->contents;
+ unsigned char *buf = *bufp;
+
+ strcpy((char *)buf, str);
+ buf += strlen(str)+1;
+
+ *bufp = buf;
+ return 0;
+}
+
+static void
+stabs_bc_stab_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+stabs_bc_str_destroy(void *contents)
+{
+ yasm_xfree(contents);
+}
+
+static void
+stabs_bc_stab_print(const void *contents, FILE *f, int indent_level)
+{
+ const stabs_stab *stab = (const stabs_stab *)contents;
+ const char *str = "";
+ fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
+ indent_level, "", str, stab->type, stab->other, stab->desc,
+ stab->bcvalue ? stab->bcvalue->offset : stab->value);
+}
+
+static void
+stabs_bc_str_print(const void *contents, FILE *f, int indent_level)
+{
+ fprintf(f, "%*s\"%s\"\n", indent_level, "", (const char *)contents);
+}
+
+static int
+stabs_bc_stab_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to resolve a stabs stab bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+static int
+stabs_bc_str_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
+ void *add_span_data)
+{
+ yasm_internal_error(N_("tried to resolve a stabs str bytecode"));
+ /*@notreached@*/
+ return 0;
+}
+
+/* Define dbgfmt structure -- see dbgfmt.h for details */
+yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt = {
+ "Stabs debugging format",
+ "stabs",
+ NULL, /* no directives */
+ stabs_dbgfmt_create,
+ stabs_dbgfmt_destroy,
+ stabs_dbgfmt_generate
+};