145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Stabs debugging format
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2003-2007  Michael Urman
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 *
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h>
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h>
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef enum {
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_UNDF = 0x00,      /* Undefined */
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_GSYM = 0x20,      /* Global symbol */
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_FNAME = 0x22,     /* Function name (BSD Fortran) */
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_FUN = 0x24,       /* Function name or Text segment variable */
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_STSYM = 0x26,     /* Data segment file-scope variable */
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_LCSYM = 0x28,     /* BSS segment file-scope variable */
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_MAIN = 0x2a,      /* Name of main routine */
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_ROSYM = 0x2c,     /* Variable in .rodata section */
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_PC = 0x30,        /* Global symbol (Pascal) */
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SYMS = 0x32,      /* Number of symbols (Ultrix V4.0) */
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NOMAP = 0x34,     /* No DST map */
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_OBJ = 0x38,       /* Object file (Solaris2) */
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_OPT = 0x3c,       /* Debugger options (Solaris2) */
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_RSYM = 0x40,      /* Register variable */
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_M2C = 0x42,       /* Modula-2 compilation unit */
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SLINE = 0x44,     /* Line numbers in .text segment */
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_DSLINE = 0x46,    /* Line numbers in .data segment */
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_BSLINE = 0x48,    /* Line numbers in .bss segment */
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_BROWS = 0x48,     /* Source code .cb file's path */
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_DEFD = 0x4a,      /* GNU Modula-2 definition module dependency */
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_FLINE = 0x4c,     /* Function start/body/end line numbers (Solaris2) */
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_EHDECL = 0x50,    /* GNU C++ exception variable */
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_MOD2 = 0x50,      /* Modula2 info for imc (Ultrix V4.0) */
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_CATCH = 0x54,     /* GNU C++ catch clause */
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SSYM = 0x60,      /* Structure or union element */
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_ENDM = 0x62,      /* Last stab for module (Solaris2) */
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SO = 0x64,        /* Path and name of source files */
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_LSYM = 0x80,      /* Stack variable */
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_BINCL = 0x84,     /* Beginning of include file */
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SOL = 0x84,       /* Name of include file */
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_PSYM = 0xa0,      /* Parameter variable */
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_EINCL = 0xa2,     /* End of include file */
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_ENTRY = 0xa4,     /* Alternate entry point */
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_LBRAC = 0xc0,     /* Beginning of lexical block */
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_EXCL = 0xc2,      /* Placeholder for a deleted include file */
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_SCOPE = 0xc4,     /* Modula 2 scope info (Sun) */
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_RBRAC = 0xe0,     /* End of lexical block */
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_BCOMM = 0xe2,     /* Begin named common block */
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_ECOMM = 0xe4,     /* End named common block */
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_ECOML = 0xe8,     /* Member of common block */
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_WITH = 0xea,      /* Pascal with statement: type,,0,0,offset (Solaris2) */
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NBTEXT = 0xf0,    /* Gould non-base registers */
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NBDATA = 0xf2,    /* Gould non-base registers */
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NBBSS = 0xf4,     /* Gould non-base registers */
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NBSTS = 0xf6,     /* Gould non-base registers */
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    N_NBLCS = 0xf8      /* Gould non-base registers */
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} stabs_stab_type;
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_dbgfmt_stabs {
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dbgfmt_base dbgfmt;        /* base structure */
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_dbgfmt_stabs;
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct {
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long lastline;     /* track line and file of bytecodes */
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long curline;
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *lastfile;
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *curfile;
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned int stablen;       /* size of a stab for current machine */
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long stabcount;    /* count stored stabs; doesn't include first */
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *stab;         /* sections to which stabs, stabstrs appended */
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *stabstr;
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *basebc;      /* base bytecode from which to track SLINEs */
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object;
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_linemap *linemap;
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_errwarns *errwarns;
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} stabs_info;
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct {
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ yasm_bytecode *bcstr;    /* bytecode in stabstr for string */
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_stab_type type;               /* stab type: N_* */
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char other;                /* unused, but stored here anyway */
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned short desc;                /* description element of a stab */
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ yasm_symrec *symvalue;   /* value element needing relocation */
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/yasm_bytecode *bcvalue;   /* relocated stab's bytecode */
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long value;                /* fallthrough value if above NULL */
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} stabs_stab;
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Bytecode callback function prototypes */
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void stabs_bc_str_destroy(void *contents);
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void stabs_bc_str_print(const void *contents, FILE *f, int
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               indent_level);
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int stabs_bc_str_calc_len
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int stabs_bc_str_tobytes
121d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void stabs_bc_stab_destroy(void *contents);
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void stabs_bc_stab_print(const void *contents, FILE *f, int
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                indent_level);
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int stabs_bc_stab_calc_len
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int stabs_bc_stab_tobytes
131d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     yasm_output_value_func output_value,
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     /*@null@*/ yasm_output_reloc_func output_reloc);
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Bytecode callback structures */
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback stabs_bc_str_callback = {
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_str_destroy,
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_str_print,
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_str_calc_len,
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_str_tobytes,
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback stabs_bc_stab_callback = {
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_stab_destroy,
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_stab_print,
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_stab_calc_len,
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_expand_common,
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_bc_stab_tobytes,
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dbgfmt_module yasm_stabs_LTX_dbgfmt;
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@null@*/ /*@only@*/ yasm_dbgfmt *
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_create(yasm_object *object)
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_dbgfmt_stabs *dbgfmt_stabs = yasm_xmalloc(sizeof(yasm_dbgfmt_stabs));
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgfmt_stabs->dbgfmt.module = &yasm_stabs_LTX_dbgfmt;
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (yasm_dbgfmt *)dbgfmt_stabs;
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(dbgfmt);
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Create and add a new strtab-style string bytecode to a section, updating
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * offset on insertion; no optimization necessary */
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Copies the string, so you must still free yours as normal */
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_bytecode *
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_append_bcstr(yasm_section *sect, const char *str)
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&stabs_bc_str_callback, yasm__xstrdup(str), 0);
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = (unsigned long)(strlen(str)+1);
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section_bcs_append(sect, bc);
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return bc;
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Create and add a new stab bytecode to a section, updating offset on
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * insertion; no optimization necessary. */
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Requires a string bytecode, or NULL, for its string entry */
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic stabs_stab *
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_append_stab(stabs_info *info, yasm_section *sect,
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         /*@null@*/ yasm_bytecode *bcstr, stabs_stab_type type,
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         unsigned long desc, /*@null@*/ yasm_symrec *symvalue,
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         /*@null@*/ yasm_bytecode *bcvalue, unsigned long value)
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *bc;
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_stab *stab = yasm_xmalloc(sizeof(stabs_stab));
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->other = 0;
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->bcstr = bcstr;
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->type = type;
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->desc = (unsigned short)desc;
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->symvalue = symvalue;
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->bcvalue = bcvalue;
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->value = value;
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc = yasm_bc_create_common(&stabs_bc_stab_callback, stab,
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               bcvalue ? bcvalue->line : 0);
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len = info->stablen;
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->offset = yasm_bc_next_offset(yasm_section_bcs_last(sect));
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section_bcs_append(sect, bc);
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->stabcount++;
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return stab;
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_generate_n_fun(stabs_info *info, yasm_bytecode *bc)
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* check all syms at this bc for potential function syms */
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int bcsym;
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (bcsym=0; bc->symrecs && bc->symrecs[bcsym]; bcsym++)
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *str;
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_symrec *sym = bc->symrecs[bcsym];
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        const char *name = yasm_symrec_get_name(sym);
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* best guess algorithm - ignore labels containing a . or $ */
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (strchr(name, '.') || strchr(name, '$'))
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            continue;
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* if a function, update basebc, and output a funcname:F1 stab */
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->basebc = bc;
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        str = yasm_xmalloc(strlen(name)+4);
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        strcpy(str, name);
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        strcat(str, ":F1");
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stabs_dbgfmt_append_stab(info, info->stab,
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 stabs_dbgfmt_append_bcstr(info->stabstr, str),
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 N_FUN, 0, sym, info->basebc, 0);
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(str);
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break;
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d)
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_info *info = (stabs_info *)d;
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_linemap_lookup(info->linemap, bc->line, &info->curfile,
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        &info->curline);
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* check for new function */
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_generate_n_fun(info, bc);
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (info->lastfile != info->curfile) {
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->lastline = 0; /* new file, so line changes */
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /*stabs_dbgfmt_append_stab(info, info->stab,
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            stabs_dbgfmt_append_bcstr(info->stabstr, info->curfile),
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            N_SOL, 0, NULL, bc, 0);*/
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* output new line stabs if there's a basebc (known function) */
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (info->basebc != NULL && info->curline != info->lastline) {
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info->lastline = bc->line;
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stabs_dbgfmt_append_stab(info, info->stab, NULL, N_SLINE,
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 info->curline, NULL, NULL,
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 bc->offset - info->basebc->offset);
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->lastline = info->curline;
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->lastfile = info->curfile;
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d)
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_info *info = (stabs_info *)d;
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *sectname=yasm_section_get_name(sect);
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* each section has a different base symbol */
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info->basebc = NULL;
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* handle first (pseudo) bc separately */
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_generate_n_fun(d, yasm_section_bcs_first(sect));
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section_bcs_traverse(sect, info->errwarns, d,
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                              stabs_dbgfmt_generate_bcs);
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm__strcasecmp(sectname, ".text")==0) {
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* Close out last function by appending a null SO stab after last bc */
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_bytecode *bc = yasm_section_bcs_last(sect);
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_symrec *sym =
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_symtab_define_label(info->object->symtab, ".n_so", bc, 1,
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                     bc->line);
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stabs_dbgfmt_append_stab(info, info->stab, 0, N_SO, 0, sym, bc, 0);
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 1;
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      yasm_errwarns *errwarns)
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_info info;
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int new;
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *dbgbc;
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_stab *stab;
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *filebc, *nullbc, *laststr, *firstbc;
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_symrec *firstsym;
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section *stext;
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Stablen is determined by arch/machine */
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (yasm__strcasecmp(yasm_arch_keyword(object->arch), "x86") == 0) {
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        info.stablen = 12;
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else /* unknown machine; generate nothing */
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return;
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.object = object;
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.linemap = linemap;
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.errwarns = errwarns;
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.lastline = 0;
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.stabcount = 0;
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.stab = yasm_object_get_general(object, ".stab", 4, 0, 0, &new, 0);
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!new) {
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_bytecode *last = yasm_section_bcs_last(info.stab);
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (last == NULL) {
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set(YASM_ERROR_GENERAL,
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                N_("stabs debugging conflicts with user-defined section .stab"));
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(errwarns,
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   yasm_section_bcs_first(info.stab)->line);
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        } else {
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_warn_set(YASM_WARN_GENERAL,
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                N_("stabs debugging overrides empty section .stab"));
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(errwarns, 0);
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    info.stabstr =
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_object_get_general(object, ".stabstr", 1, 0, 0, &new, 0);
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!new) {
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (last == NULL) {
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set(YASM_ERROR_GENERAL,
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                N_("stabs debugging conflicts with user-defined section .stabstr"));
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(errwarns,
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   yasm_section_bcs_first(info.stab)->line);
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        } else {
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_warn_set(YASM_WARN_GENERAL,
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                N_("stabs debugging overrides empty section .stabstr"));
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_errwarn_propagate(errwarns, 0);
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* initial pseudo-stab */
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab = yasm_xmalloc(sizeof(stabs_stab));
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgbc = yasm_bc_create_common(&stabs_bc_stab_callback, stab, 0);
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgbc->len = info.stablen;
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dbgbc->offset = 0;
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_section_bcs_append(info.stab, dbgbc);
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* initial strtab bytecodes */
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nullbc = stabs_dbgfmt_append_bcstr(info.stabstr, "");
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    filebc = stabs_dbgfmt_append_bcstr(info.stabstr, object->src_filename);
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stext = yasm_object_find_general(object, ".text");
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    firstsym = yasm_symtab_use(object->symtab, ".text", 0);
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    firstbc = yasm_section_bcs_first(stext);
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* N_SO file stab */
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_append_stab(&info, info.stab, filebc, N_SO, 0,
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                             firstsym, firstbc, 0);
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object_sections_traverse(object, (void *)&info,
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  stabs_dbgfmt_generate_sections);
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* fill initial pseudo-stab's fields */
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    laststr = yasm_section_bcs_last(info.stabstr);
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (laststr == NULL)
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_internal_error(".stabstr has no entries");
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->bcvalue = NULL;
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->symvalue = NULL;
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->value = yasm_bc_next_offset(laststr);
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->bcstr = filebc;
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->type = N_UNDF;
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stab->other = 0;
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (info.stabcount > 0xffff) {
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_warn_set(YASM_WARN_GENERAL, N_("over 65535 stabs"));
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_errwarn_propagate(errwarns, 0);
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stab->desc = 0xffff;
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stab->desc = (unsigned short)info.stabcount;
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
407d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgstabs_bc_stab_tobytes(yasm_bytecode *bc, unsigned char **bufp,
408d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                      unsigned char *bufstart, void *d,
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      yasm_output_value_func output_value,
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      yasm_output_reloc_func output_reloc)
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* This entire function, essentially the core of rendering stabs to a file,
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * needs to become endian aware.  Size appears not to be an issue, as known
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * 64-bit systems use truncated values in 32-bit fields. */
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const stabs_stab *stab = (const stabs_stab *)bc->contents;
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_32_L(buf, stab->bcstr ? stab->bcstr->offset : 0);
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, stab->type);
42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_8(buf, stab->other);
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_16_L(buf, stab->desc);
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (stab->symvalue != NULL) {
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc->offset += 8;
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        output_reloc(stab->symvalue, bc, buf, 4, 32, 0, d);
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bc->offset -= 8;
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        buf += 4;
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else if (stab->bcvalue != NULL) {
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_WRITE_32_L(buf, stab->bcvalue->offset);
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else {
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_WRITE_32_L(buf, stab->value);
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
442d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgstabs_bc_str_tobytes(yasm_bytecode *bc, unsigned char **bufp,
443d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                     unsigned char *bufstart, void *d,
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     yasm_output_value_func output_value,
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     yasm_output_reloc_func output_reloc)
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *str = (const char *)bc->contents;
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char *buf = *bufp;
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    strcpy((char *)buf, str);
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    buf += strlen(str)+1;
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp = buf;
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_stab_destroy(void *contents)
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_str_destroy(void *contents)
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_stab_print(const void *contents, FILE *f, int indent_level)
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const stabs_stab *stab = (const stabs_stab *)contents;
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *str = "";
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            indent_level, "", str, stab->type, stab->other, stab->desc,
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            stab->bcvalue ? stab->bcvalue->offset : stab->value);
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_str_print(const void *contents, FILE *f, int indent_level)
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*s\"%s\"\n", indent_level, "", (const char *)contents);
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_stab_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       void *add_span_data)
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to resolve a stabs stab bytecode"));
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstabs_bc_str_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      void *add_span_data)
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_internal_error(N_("tried to resolve a stabs str bytecode"));
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@notreached@*/
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define dbgfmt structure -- see dbgfmt.h for details */
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dbgfmt_module yasm_stabs_LTX_dbgfmt = {
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "Stabs debugging format",
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "stabs",
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,       /* no directives */
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_create,
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_destroy,
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stabs_dbgfmt_generate
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
512