145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CodeView debugging format - symbol and line information
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2006-2007  Peter Johnson
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3. Neither the name of the author nor the names of other contributors
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    may be used to endorse or promote products derived from this
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    software without specific prior written permission.
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h>
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h>
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "cv-dbgfmt.h"
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum cv8_symheadtype {
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_DEBUG_SYMS      = 0xF1, /* CV5 symbol information */
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_LINE_NUMS       = 0xF2, /* line numbers for a section */
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_FILE_STRTAB     = 0xF3, /* filename string table */
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_FILE_INFO       = 0xF4  /* source file info */
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum cv_symtype {
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Non-modal Symbols */
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_COMPILE        = 0x0001,       /* Compile Flag */
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_REGISTER       = 0x0002,       /* Register */
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_CONSTANT       = 0x0003,       /* Constant */
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_UDT            = 0x0004,       /* User-defined Type */
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_SSEARCH        = 0x0005,       /* Start Search */
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_END            = 0x0006,       /* End of Block */
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_SKIP           = 0x0007,       /* Skip Record */
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_OBJNAME        = 0x0009,       /* Object File Name */
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_ENDARG         = 0x000a,       /* End of Arguments */
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_COBOLUDT       = 0x000b,       /* COBOL User-defined Type */
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_MANYREG        = 0x000c,       /* Many Registers */
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_RETURN         = 0x000d,       /* Function Return */
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_ENTRYTHIS      = 0x000e,       /* "this" at Method Entry */
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Symbols for 16:16 Segmented Architectures */
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_BPREL16        = 0x0100,       /* BP Relative 16:16 */
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LDATA16        = 0x0101,       /* Local Data 16:16 */
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GDATA16        = 0x0102,       /* Global Data Symbol 16:16 */
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_PUB16          = 0x0103,       /* Public Symbol 16:16 */
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LPROC16        = 0x0104,       /* Local Start 16:16 */
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GPROC16        = 0x0105,       /* Global Start 16:16 */
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_THUNK16        = 0x0106,       /* Thunk Start 16:16 */
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_BLOCK16        = 0x0107,       /* Block Start 16:16 */
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_WITH16         = 0x0108,       /* With Start 16:16 */
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LABEL16        = 0x0109,       /* Code Label 16:16 */
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_CEXMODEL16     = 0x0110,       /* Change Execution Model 16:16 */
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_VFTPATH16      = 0x010b,       /* Virtual Function Table Path 16:16 */
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_REGREL16       = 0x010c,       /* Register Relative 16:16 */
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Symbols for 16:32 Segmented Architectures */
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_BPREL32        = 0x0200,       /* BP Relative 16:32 */
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LDATA32        = 0x0201,       /* Local Data 16:32 */
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GDATA32        = 0x0202,       /* Global Data Symbol 16:32 */
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_PUB32          = 0x0203,       /* Public Symbol 16:32 */
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LPROC32        = 0x0204,       /* Local Start 16:32 */
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GPROC32        = 0x0205,       /* Global Start 16:32 */
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_THUNK32        = 0x0206,       /* Thunk Start 16:32 */
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_BLOCK32        = 0x0207,       /* Block Start 16:32 */
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_WITH32         = 0x0208,       /* With Start 16:32 */
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LABEL32        = 0x0209,       /* Code Label 16:32 */
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_CEXMODEL32     = 0x0210,       /* Change Execution Model 16:32 */
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_VFTPATH32      = 0x020b,       /* Virtual Function Table Path 16:32 */
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_REGREL32       = 0x020c,       /* Register Relative 16:32 */
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LTHREAD32      = 0x020d,       /* Local Thread Storage 16:32 */
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GTHREAD32      = 0x020e,       /* Global Thread Storage 16:32 */
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Symbols for MIPS */
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_LPROCMIPS      = 0x0300,       /* Local procedure start MIPS */
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV_S_GPROCMIPS      = 0x0301,       /* Global procedure start MIPS */
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Symbols for CV8 - strings are 0 terminated rather than length-prefix.
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * Incomplete and unofficial.
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_OBJNAME       = 0x1101,       /* Object File Name */
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_LABEL32       = 0x1105,       /* Code Label 16:32 */
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_LDATA32       = 0x110c,       /* Local Data 16:32 */
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_GDATA32       = 0x110d,       /* Global Data 16:32 */
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_LPROC32       = 0x1110,       /* Local Start 16:32 */
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    CV8_S_COMPILE       = 0x1116        /* Compile Flag */
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv8_symhead {
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum cv8_symheadtype type;
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *start_prevbc;
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *end_prevbc;
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int first;      /* nonzero if first symhead in section */
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv8_symhead;
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv8_fileinfo {
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const cv_filename *fn;
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv8_fileinfo;
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Note: each line number group is associated with a file AND a section */
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv8_linepair {
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long offset;
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long line;
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv8_linepair;
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Decrease linked list overhead a bit doing it this way */
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv8_lineset {
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_ENTRY(cv8_lineset) link;
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_linepair pairs[126];
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t num_pairs;
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv8_lineset;
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv8_lineinfo {
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_ENTRY(cv8_lineinfo) link;
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const cv_filename *fn;      /* filename associated with line numbers */
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *sect;         /* section line numbers are for */
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *sectsym;       /* symbol for beginning of sect */
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long num_linenums;
136a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    STAILQ_HEAD(cv8_lineset_head, cv8_lineset) linesets;
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv8_lineinfo;
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Symbols use a bit of meta-programming to encode formats: each character
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * of format represents the output generated, as follows:
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'b' : 1 byte value (integer)
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'h' : 2 byte value (integer)
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'w' : 4 byte value (integer)
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'Y' : symrec SECREL+SECTION (pointer)
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'T' : type index (integer)
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'S' : length-prefixed string (pointer)
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 'Z' : 0-terminated string (pointer)
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv_sym {
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum cv_symtype type;
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *format;
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    union {
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        unsigned long i;
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        void *p;
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } args[10];
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv_sym;
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Bytecode callback function prototypes */
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_symhead_bc_destroy(void *contents);
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_symhead_bc_print(const void *contents, FILE *f,
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 int indent_level);
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_symhead_bc_calc_len
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_symhead_bc_tobytes
165d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_fileinfo_bc_destroy(void *contents);
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_fileinfo_bc_print(const void *contents, FILE *f,
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  int indent_level);
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_fileinfo_bc_calc_len
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_fileinfo_bc_tobytes
175d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_lineinfo_bc_destroy(void *contents);
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_lineinfo_bc_print(const void *contents, FILE *f,
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  int indent_level);
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_lineinfo_bc_calc_len
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv8_lineinfo_bc_tobytes
185d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv_sym_bc_destroy(void *contents);
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv_sym_bc_print(const void *contents, FILE *f, int indent_level);
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv_sym_bc_calc_len
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int cv_sym_bc_tobytes
194d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Bytecode callback structures */
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback cv8_symhead_bc_callback = {
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead_bc_destroy,
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead_bc_print,
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead_bc_calc_len,
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead_bc_tobytes,
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback cv8_fileinfo_bc_callback = {
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo_bc_destroy,
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo_bc_print,
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo_bc_calc_len,
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo_bc_tobytes,
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback cv8_lineinfo_bc_callback = {
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo_bc_destroy,
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo_bc_print,
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo_bc_calc_len,
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo_bc_tobytes,
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback cv_sym_bc_callback = {
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym_bc_destroy,
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym_bc_print,
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym_bc_calc_len,
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym_bc_tobytes,
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv8_symhead *cv8_add_symhead(yasm_section *sect, unsigned long type,
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    int first);
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void cv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc);
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_bytecode *cv8_add_fileinfo
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_section *sect, const cv_filename *fn);
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned long cv_sym_size(const cv_sym *cvs);
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv_sym *
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_sym_objname(yasm_section *sect, /*@keep@*/ char *objname)
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->type = CV8_S_OBJNAME;
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->format = "wZ";
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[0].i = 0;         /* signature (0=asm) */
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[1].p = objname;   /* object filename */
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = cv_sym_size(cvs);
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return cvs;
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv_sym *
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_sym_compile(yasm_object *object, yasm_section *sect,
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    /*@keep@*/ char *creator)
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->type = CV8_S_COMPILE;
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->format = "wwwwZh";
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[0].i = 3;         /* language (3=Masm) */
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* target processor; 0xD0 = AMD64 */
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (strcmp(yasm_arch_keyword(object->arch), "x86") == 0) {
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (strcmp(yasm_arch_get_machine(object->arch), "amd64") == 0)
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            cvs->args[1].i = 0xD0;
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            cvs->args[1].i = 0x6;       /* 686, FIXME */
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cvs->args[1].i = 0;             /* XXX: unknown */
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[2].i = 0;         /* flags (assume 0 for now) */
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[3].i = 0;         /* creator version number (assume 0 for now) */
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[4].p = creator;   /* creator string */
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[5].i = 0;         /* no pairs of key/value */
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = cv_sym_size(cvs);
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return cvs;
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv_sym *
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_sym_label(yasm_section *sect, yasm_symrec *sym)
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->type = CV8_S_LABEL32;
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->format = "YbZ";
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[0].p = sym;       /* symrec for label */
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[1].i = 0;         /* flags (assume 0 for now) */
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = cv_sym_size(cvs);
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return cvs;
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv_sym *
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_sym_data(yasm_section *sect, unsigned long type, yasm_symrec *sym,
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                 int is_global)
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = yasm_xmalloc(sizeof(cv_sym));
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->type = is_global ? CV8_S_GDATA32 : CV8_S_LDATA32;
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->format = "wYZ";
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[0].i = type;      /* type index */
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[1].p = sym;       /* symrec for label */
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cvs->args[2].p = yasm__xstrdup(yasm_symrec_get_name(sym));
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv_sym_bc_callback, cvs, 0);
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = cv_sym_size(cvs);
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return cvs;
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic size_t
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_dbgfmt_add_file(yasm_dbgfmt_cv *dbgfmt_cv, size_t filenum,
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                   const char *filename)
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *pathname;
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t i;
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_md5_context context;
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    FILE *f;
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf;
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t len;
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Put the filename into the filename table */
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (filenum == 0) {
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* Look to see if we already have that filename in the table */
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (; filenum<dbgfmt_cv->filenames_size; filenum++) {
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (!dbgfmt_cv->filenames[filenum].filename ||
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                strcmp(dbgfmt_cv->filenames[filenum].filename, filename) == 0)
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        filenum--;      /* array index is 0-based */
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Realloc table if necessary */
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (filenum >= dbgfmt_cv->filenames_allocated) {
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        size_t old_allocated = dbgfmt_cv->filenames_allocated;
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        dbgfmt_cv->filenames_allocated = filenum+32;
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        dbgfmt_cv->filenames = yasm_xrealloc(dbgfmt_cv->filenames,
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sizeof(cv_filename)*dbgfmt_cv->filenames_allocated);
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (i=old_allocated; i<dbgfmt_cv->filenames_allocated; i++) {
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            dbgfmt_cv->filenames[i].pathname = NULL;
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            dbgfmt_cv->filenames[i].filename = NULL;
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            dbgfmt_cv->filenames[i].str_off = 0;
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            dbgfmt_cv->filenames[i].info_off = 0;
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Calculate MD5 checksum of file */
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf = yasm_xmalloc(1024);
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_md5_init(&context);
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    f = fopen(filename, "rb");
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!f)
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm__fatal(N_("codeview: could not open source file"));
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while ((len = fread(buf, 1, 1024, f)) > 0)
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_md5_update(&context, buf, (unsigned long)len);
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_md5_final(dbgfmt_cv->filenames[filenum].digest, &context);
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fclose(f);
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(buf);
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Actually save in table */
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (dbgfmt_cv->filenames[filenum].pathname)
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(dbgfmt_cv->filenames[filenum].pathname);
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (dbgfmt_cv->filenames[filenum].filename)
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(dbgfmt_cv->filenames[filenum].filename);
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pathname = yasm__abspath(filename);
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgfmt_cv->filenames[filenum].pathname = pathname;
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgfmt_cv->filenames[filenum].filename = yasm__xstrdup(filename);
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Update table size */
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (filenum >= dbgfmt_cv->filenames_size)
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        dbgfmt_cv->filenames_size = filenum + 1;
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return filenum;
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_bytecode *
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_append_str(yasm_section *sect, const char *str)
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_datavalhead dvs;
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dvs_initialize(&dvs);
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str),
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                                strlen(str)));
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0);
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize(bc, yasm_cv__append_bc(sect, bc));
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_calc_len(bc, NULL, NULL);
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return bc;
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct cv_line_info {
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *debug_symline;
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object;
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dbgfmt_cv *dbgfmt_cv;
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_linemap *linemap;
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_errwarns *errwarns;
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned int num_lineinfos;
421a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    STAILQ_HEAD(cv8_lineinfo_head, cv8_lineinfo) cv8_lineinfos;
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ cv8_lineinfo *cv8_cur_li;
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ cv8_lineset *cv8_cur_ls;
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} cv_line_info;
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_line_info *info = (cv_line_info *)d;
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dbgfmt_cv *dbgfmt_cv = info->dbgfmt_cv;
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t i;
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *filename;
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long line;
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *sect = yasm_bc_get_section(bc);
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (nextbc && bc->offset == nextbc->offset)
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_linemap_lookup(info->linemap, bc->line, &filename, &line);
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!info->cv8_cur_li
44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        || strcmp(filename, info->cv8_cur_li->fn->filename) != 0) {
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_bytecode *sectbc;
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char symname[8];
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* first see if we already have a lineinfo that is for this section and
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         * filename
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         */
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        STAILQ_FOREACH(info->cv8_cur_li, &info->cv8_lineinfos, link) {
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (sect == info->cv8_cur_li->sect
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                && strcmp(filename, info->cv8_cur_li->fn->filename) == 0)
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (info->cv8_cur_li) {
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            info->cv8_cur_ls = STAILQ_LAST(&info->cv8_cur_li->linesets,
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                           cv8_lineset, link);
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            goto done;          /* found one */
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* Nope; find file */
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (i=0; i<dbgfmt_cv->filenames_size; i++) {
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (strcmp(filename, dbgfmt_cv->filenames[i].filename) == 0)
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (i >= dbgfmt_cv->filenames_size)
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_internal_error(N_("could not find filename in table"));
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* and create new lineinfo structure */
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_li = yasm_xmalloc(sizeof(cv8_lineinfo));
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_li->fn = &dbgfmt_cv->filenames[i];
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_li->sect = sect;
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sectbc = yasm_section_bcs_first(sect);
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (sectbc->symrecs && sectbc->symrecs[0])
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            info->cv8_cur_li->sectsym = sectbc->symrecs[0];
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else {
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sprintf(symname, ".%06u", info->num_lineinfos++);
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            info->cv8_cur_li->sectsym =
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_symtab_define_label(info->object->symtab, symname, sectbc,
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         1, 0);
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_li->num_linenums = 0;
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        STAILQ_INIT(&info->cv8_cur_li->linesets);
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        STAILQ_INSERT_TAIL(&info->cv8_lineinfos, info->cv8_cur_li, link);
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_ls = NULL;
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdone:
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* build new lineset if necessary */
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!info->cv8_cur_ls || info->cv8_cur_ls->num_pairs >= 126) {
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_ls = yasm_xmalloc(sizeof(cv8_lineset));
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->cv8_cur_ls->num_pairs = 0;
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        STAILQ_INSERT_TAIL(&info->cv8_cur_li->linesets, info->cv8_cur_ls, link);
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* add linepair for this bytecode */
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].offset = bc->offset;
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_ls->pairs[info->cv8_cur_ls->num_pairs].line =
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        0x80000000 | line;
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_ls->num_pairs++;
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_li->num_linenums++;
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_line_info *info = (cv_line_info *)d;
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!yasm_section_is_code(sect))
51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;       /* not code, so no line data for this section */
51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_li = NULL;
51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->cv8_cur_ls = NULL;
51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section_bcs_traverse(sect, info->errwarns, info, cv_generate_line_bc);
51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_generate_filename(const char *filename, void *d)
52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_dbgfmt_add_file((yasm_dbgfmt_cv *)d, 0, filename);
52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_generate_sym(yasm_symrec *sym, void *d)
53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_line_info *info = (cv_line_info *)d;
53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *precbc;
53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *name = yasm_symrec_get_name(sym);
53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* only care about labels (for now).  Don't put in symbols starting with
53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * ".", as these are typically internally generated ones (like section
53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * symbols).
54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (name[0] == '.' || !yasm_symrec_get_label(sym, &precbc))
54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* TODO: add data types; until then, just mark everything as UBYTE */
54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm_section_is_code(yasm_bc_get_section(precbc)))
54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cv8_add_sym_label(info->debug_symline, sym);
54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else
54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cv8_add_sym_data(info->debug_symline, 0x20, sym,
54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_symrec_get_visibility(sym) & YASM_SYM_GLOBAL?1:0);
55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_section *
55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_cv__generate_symline(yasm_object *object, yasm_linemap *linemap,
55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          yasm_errwarns *errwarns)
55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)object->dbgfmt;
55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_line_info info;
55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int new;
56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t i;
56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead *head;
56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo *li;
56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long off;
56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Generate filenames based on linemap */
56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_linemap_traverse_filenames(linemap, dbgfmt_cv,
56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    cv_generate_filename);
56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.object = object;
57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.dbgfmt_cv = dbgfmt_cv;
57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.linemap = linemap;
57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.errwarns = errwarns;
57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.debug_symline =
57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_object_get_general(object, ".debug$S", 1, 0, 0, &new, 0);
57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.num_lineinfos = 0;
57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_INIT(&info.cv8_lineinfos);
57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.cv8_cur_li = NULL;
57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.cv8_cur_ls = NULL;
58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* source filenames string table */
58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head = cv8_add_symhead(info.debug_symline, CV8_FILE_STRTAB, 1);
58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_append_str(info.debug_symline, "");
58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    off = 1;
58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<dbgfmt_cv->filenames_size; i++) {
58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!dbgfmt_cv->filenames[i].pathname) {
58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set(YASM_ERROR_GENERAL,
58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           N_("codeview file number %d unassigned"), i+1);
58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(errwarns, 0);
59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            continue;
59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc = cv_append_str(info.debug_symline,
59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           dbgfmt_cv->filenames[i].pathname);
59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        dbgfmt_cv->filenames[i].str_off = off;
59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        off += bc->len;
59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Align 4 */
60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_align
60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         NULL, NULL, NULL, 0);
60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_calc_len(bc, NULL, NULL);
60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* source file info table */
60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head = cv8_add_symhead(info.debug_symline, CV8_FILE_INFO, 0);
60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    off = 0;
60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<dbgfmt_cv->filenames_size; i++) {
61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!dbgfmt_cv->filenames[i].pathname)
61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            continue;
61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc = cv8_add_fileinfo(info.debug_symline, &dbgfmt_cv->filenames[i]);
61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        dbgfmt_cv->filenames[i].info_off = off;
61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        off += bc->len;
61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Already aligned 4 */
61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Generate line numbers for sections */
62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object_sections_traverse(object, (void *)&info,
62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  cv_generate_line_section);
62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Output line numbers for sections */
62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_FOREACH(li, &info.cv8_lineinfos, link) {
62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        head = cv8_add_symhead(info.debug_symline, CV8_LINE_NUMS, 0);
62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc = yasm_bc_create_common(&cv8_lineinfo_bc_callback, li, 0);
62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc->len = 24+li->num_linenums*8;
62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_cv__append_bc(info.debug_symline, bc);
63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Already aligned 4 */
63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Output debugging symbols */
63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head = cv8_add_symhead(info.debug_symline, CV8_DEBUG_SYMS, 0);
63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* add object and compile flag first */
63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_add_sym_objname(info.debug_symline,
63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        yasm__abspath(object->obj_filename));
640d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    if (getenv("YASM_TEST_SUITE"))
641d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org        cv8_add_sym_compile(object, info.debug_symline,
642d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                            yasm__xstrdup("yasm HEAD"));
643d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    else
644d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org        cv8_add_sym_compile(object, info.debug_symline,
645d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                            yasm__xstrdup(PACKAGE_STRING));
64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* then iterate through symbol table */
64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symtab_traverse(object->symtab, &info, cv_generate_sym);
64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_set_symhead_end(head, yasm_section_bcs_last(info.debug_symline));
64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Align 4 at end */
65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_align
65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)), 0),
65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         NULL, NULL, NULL, 0);
65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize(bc, yasm_cv__append_bc(info.debug_symline, bc));
65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_calc_len(bc, NULL, NULL);
65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return info.debug_symline;
65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_out_sym(yasm_symrec *sym, unsigned long off, yasm_bytecode *bc,
66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org           unsigned char **bufp, void *d, yasm_output_value_func output_value)
66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_value val;
66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* sym in its section */
66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_value_init_sym(&val, sym, 32);
66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    val.section_rel = 1;
66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    output_value(&val, *bufp, 4, off, bc, 0, d);
67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp += 4;
67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* section index */
67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_value_init_sym(&val, sym, 16);
67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    val.seg_of = 1;
67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    output_value(&val, *bufp, 2, off+4, bc, 0, d);
67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp += 2;
67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic cv8_symhead *
68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_symhead(yasm_section *sect, unsigned long type, int first)
68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead *head;
68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head = yasm_xmalloc(sizeof(cv8_symhead));
68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head->type = type;
68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head->first = first;
68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head->start_prevbc = yasm_section_bcs_last(sect);
68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv8_symhead_bc_callback, head, 0);
69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (first)
69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc->len = 12;
69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else
69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc->len = 8;
69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head->end_prevbc = bc;
69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return head;
69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_set_symhead_end(cv8_symhead *head, yasm_bytecode *end_prevbc)
70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    head->end_prevbc = end_prevbc;
70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_symhead_bc_destroy(void *contents)
70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_symhead_bc_print(const void *contents, FILE *f, int indent_level)
71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* TODO */
71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_symhead_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        void *add_span_data)
72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to calc_len a codeview symhead bytecode"));
72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
729d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgcv8_symhead_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
730d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                       unsigned char *bufstart, void *d,
73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       yasm_output_value_func output_value,
73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       yasm_output_reloc_func output_reloc)
73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = yasm_section_get_object(bc->section);
73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_symhead *head = (cv8_symhead *)bc->contents;
73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *intn, *cval;
73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cval = yasm_intnum_create_uint(4);
74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Output "version" if first */
74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (head->first) {
74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        buf += 4;
74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
74545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Type contained - 4 bytes */
74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, head->type);
74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Total length of info (following this field) - 4 bytes */
75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, bc->len);
75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    intn = yasm_calc_bc_dist(head->start_prevbc, head->end_prevbc);
75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, intn, buf, 4, 32, 0, bc, 0);
75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(intn);
75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(cval);
76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_bytecode *
76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_add_fileinfo(yasm_section *sect, const cv_filename *fn)
76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo *fi;
76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fi = yasm_xmalloc(sizeof(cv8_fileinfo));
77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fi->fn = fn;
77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&cv8_fileinfo_bc_callback, fi, 0);
77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = 24;
77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_cv__append_bc(sect, bc);
77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return bc;
77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_fileinfo_bc_destroy(void *contents)
78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_fileinfo_bc_print(const void *contents, FILE *f, int indent_level)
78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* TODO */
79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_fileinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *add_span_data)
79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to calc_len a codeview fileinfo bytecode"));
79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
803d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgcv8_fileinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
804d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                        unsigned char *bufstart, void *d,
80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        yasm_output_value_func output_value,
80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        yasm_output_reloc_func output_reloc)
80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = yasm_section_get_object(bc->section);
80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_fileinfo *fi = (cv8_fileinfo *)bc->contents;
81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *cval;
81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int i;
81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Offset in filename string table */
81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cval = yasm_intnum_create_uint(fi->fn->str_off);
81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Checksum type/length */
82045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, 0x0110);
82145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
82245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 2;
82345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Checksum */
82545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<16; i++)
82645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_WRITE_8(buf, fi->fn->digest[i]);
82745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Pad */
82945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, 0);
83045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, 0);
83145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
83245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
83345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
83445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(cval);
83545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
83645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
83745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
83845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
83945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_lineinfo_bc_destroy(void *contents)
84045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
84145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo *li = (cv8_lineinfo *)contents;
84245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineset *ls1, *ls2;
84345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
84445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* delete line sets */
84545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ls1 = STAILQ_FIRST(&li->linesets);
84645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (ls1) {
84745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ls2 = STAILQ_NEXT(ls1, link);
84845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(ls1);
84945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ls1 = ls2;
85045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
85145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
85245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
85345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
85445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
85545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
85645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_lineinfo_bc_print(const void *contents, FILE *f, int indent_level)
85745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
85845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* TODO */
85945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
86045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
86145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
86245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv8_lineinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
86345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *add_span_data)
86445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
86545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to calc_len a codeview linehead bytecode"));
86645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
86745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
86845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
86945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
87045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
871d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgcv8_lineinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
872d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                        unsigned char *bufstart, void *d,
87345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        yasm_output_value_func output_value,
87445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        yasm_output_reloc_func output_reloc)
87545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
87645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = yasm_section_get_object(bc->section);
87745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineinfo *li = (cv8_lineinfo *)bc->contents;
87845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
87945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *cval;
88045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long i;
88145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv8_lineset *ls;
88245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
88345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* start offset and section */
884d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    cv_out_sym(li->sectsym, (unsigned long)(buf - bufstart), bc, &buf,
885d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org               d, output_value);
88645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
88745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Two bytes of pad/alignment */
88845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, 0);
88945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, 0);
89045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
89145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Section length covered by line number info */
89245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cval = yasm_calc_bc_dist(yasm_section_bcs_first(li->sect),
89345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                             yasm_section_bcs_last(li->sect));
89445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
89545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
89645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
89745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Offset of source file in info table */
89845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, li->fn->info_off);
89945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
90045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
90145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
90245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Number of line number pairs */
90345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, li->num_linenums);
90445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
90545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
90645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
90745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Number of bytes of line number pairs + 12 (no, I don't know why) */
90845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, li->num_linenums*8+12);
90945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
91045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 4;
91145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
91245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Offset / line number pairs */
91345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    i = 0;
91445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_FOREACH(ls, &li->linesets, link) {
91545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        unsigned long j;
91645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (j=0; i<li->num_linenums && j<126; i++, j++) {
91745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /* offset in section */
91845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_intnum_set_uint(cval, ls->pairs[j].offset);
91945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
92045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            buf += 4;
92145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
92245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /* line number in file */
92345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_intnum_set_uint(cval, ls->pairs[j].line);
92445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 0);
92545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            buf += 4;
92645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
92745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
92845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
92945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
93045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
93145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(cval);
93245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
93345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
93445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
93545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned long
93645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_sym_size(const cv_sym *cvs)
93745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
93845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *ch = cvs->format;
93945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long len = 4;  /* sym length and type */
94045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long slen;
94145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int arg = 0;
94245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
94345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (*ch) {
94445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (*ch) {
94545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'b':
94645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len++;
94745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
94845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
94945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'h':
95045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += 2;
95145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
95245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
95345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'w':
95445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += 4;
95545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
95645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
95745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Y':
95845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += 6;       /* XXX: will be 4 in 16-bit version */
95945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
96045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
96145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'T':
96245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += 4;       /* XXX: will be 2 in CV4 */
96345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
96445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
96545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'S':
96645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += 1;       /* XXX: is this 1 or 2? */
96745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                slen = (unsigned long)strlen((const char *)cvs->args[arg++].p);
96845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len += slen <= 0xff ? slen : 0xff;
96945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
97045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Z':
97145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len +=
97245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    (unsigned long)strlen((const char *)cvs->args[arg++].p) + 1;
97345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
97445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            default:
97545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_internal_error(N_("unknown sym format character"));
97645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
97745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ch++;
97845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
97945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return len;
98145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
98245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
98445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_sym_bc_destroy(void *contents)
98545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
98645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = (cv_sym *)contents;
98745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *ch = cvs->format;
98845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int arg = 0;
98945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
99045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (*ch) {
99145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (*ch) {
99245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'b':
99345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'h':
99445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'w':
99545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Y':
99645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'T':
99745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
99845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;  /* nothing to destroy */
99945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'S':
100045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Z':
100145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_xfree(cvs->args[arg++].p);
100245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
100345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            default:
100445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_internal_error(N_("unknown sym format character"));
100545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
100645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ch++;
100745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
100845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
100945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
101045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
101145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
101245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
101345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_sym_bc_print(const void *contents, FILE *f, int indent_level)
101445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
101545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* TODO */
101645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
101745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
101845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
101945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcv_sym_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
102045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                   void *add_span_data)
102145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
102245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to calc_len a codeview sym bytecode"));
102345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
102445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
102545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
102645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
102745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
1028d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgcv_sym_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
1029d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                  unsigned char *bufstart, void *d,
103045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                  yasm_output_value_func output_value,
103145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                  yasm_output_reloc_func output_reloc)
103245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
103345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = yasm_section_get_object(bc->section);
103445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cv_sym *cvs = (cv_sym *)bc->contents;
103545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
103645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *cval;
103745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *ch = cvs->format;
103845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t len;
103945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int arg = 0;
104045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
104145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Total length of record (following this field) - 2 bytes */
104245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cval = yasm_intnum_create_uint(bc->len-2);
104345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1);
104445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 2;
104545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
104645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Type contained - 2 bytes */
104745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_set_uint(cval, cvs->type);
104845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 0);
104945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += 2;
105045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
105145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (*ch) {
105245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (*ch) {
105345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'b':
105445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                YASM_WRITE_8(buf, cvs->args[arg].i);
105545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
105645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
105745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'h':
105845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_intnum_set_uint(cval, cvs->args[arg++].i);
105945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0,
106045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         bc, 0);
106145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                buf += 2;
106245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
106345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'w':
106445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_intnum_set_uint(cval, cvs->args[arg++].i);
106545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
106645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         bc, 0);
106745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                buf += 4;
106845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
106945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Y':
107045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                cv_out_sym((yasm_symrec *)cvs->args[arg++].p,
1071d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                           (unsigned long)(buf-bufstart), bc, &buf, d,
107245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           output_value);
107345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
107445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'T':
107545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_intnum_set_uint(cval, cvs->args[arg++].i);
107645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0,
107745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         bc, 0);
107845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                buf += 4;       /* XXX: will be 2 in CV4 */
107945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
108045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'S':
108145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len = strlen((char *)cvs->args[arg].p);
108245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len = len <= 0xff ? len : 0xff;
108345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                YASM_WRITE_8(buf, len);
108445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                memcpy(buf, (char *)cvs->args[arg].p, len);
108545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                buf += len;
108645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
108745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
108845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case 'Z':
108945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                len = strlen((char *)cvs->args[arg].p)+1;
109045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                memcpy(buf, (char *)cvs->args[arg].p, len);
109145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                buf += len;
109245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg++;
109345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
109445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            default:
109545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_internal_error(N_("unknown leaf format character"));
109645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
109745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ch++;
109845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
109945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
110045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
110145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
110245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(cval);
110345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
110445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
1105