13db21947Sgrischka/*
288a3ccabSgrischka *  TCC - Tiny C Compiler - Support for -run switch
33db21947Sgrischka *
43db21947Sgrischka *  Copyright (c) 2001-2004 Fabrice Bellard
53db21947Sgrischka *
63db21947Sgrischka * This library is free software; you can redistribute it and/or
73db21947Sgrischka * modify it under the terms of the GNU Lesser General Public
83db21947Sgrischka * License as published by the Free Software Foundation; either
93db21947Sgrischka * version 2 of the License, or (at your option) any later version.
103db21947Sgrischka *
113db21947Sgrischka * This library is distributed in the hope that it will be useful,
123db21947Sgrischka * but WITHOUT ANY WARRANTY; without even the implied warranty of
133db21947Sgrischka * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
143db21947Sgrischka * Lesser General Public License for more details.
153db21947Sgrischka *
163db21947Sgrischka * You should have received a copy of the GNU Lesser General Public
173db21947Sgrischka * License along with this library; if not, write to the Free Software
183db21947Sgrischka * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
193db21947Sgrischka */
203db21947Sgrischka
2188a3ccabSgrischka#include "tcc.h"
223db21947Sgrischka
23a35b3059Sgrischka/* only native compiler supports -run */
24a35b3059Sgrischka#ifdef TCC_IS_NATIVE
25a35b3059Sgrischka
2674a24d77Sgrischka#ifdef CONFIG_TCC_BACKTRACE
27ef42295fSgrtypedef struct rt_context
2872729d8eSgrischka{
29ef42295fSgr    /* --> tccelf.c:tcc_add_btstub wants those below in that order: */
30ef42295fSgr    Stab_Sym *stab_sym, *stab_sym_end;
31ef42295fSgr    char *stab_str;
32ef42295fSgr    ElfW(Sym) *esym_start, *esym_end;
33ef42295fSgr    char *elf_str;
34ef42295fSgr    addr_t prog_base;
35ef42295fSgr    void *bounds_start;
36ef42295fSgr    struct rt_context *next;
37ef42295fSgr    /* <-- */
38ef42295fSgr    int num_callers;
39ef42295fSgr    addr_t ip, fp, sp;
40ef42295fSgr    void *top_func;
41ef42295fSgr    jmp_buf jmp_buf;
42ef42295fSgr    char do_jmp;
43ef42295fSgr} rt_context;
44ef42295fSgr
45ef42295fSgrstatic rt_context g_rtctxt;
46ef42295fSgrstatic void set_exception_handler(void);
47ef42295fSgrstatic int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
48ef42295fSgrstatic void rt_exit(int code);
49ef42295fSgr#endif /* CONFIG_TCC_BACKTRACE */
50ef42295fSgr
51d79e1deeSgrischka/* defined when included from lib/bt-exe.c */
52ef42295fSgr#ifndef CONFIG_TCC_BACKTRACE_ONLY
53ef42295fSgr
54ef42295fSgr#ifndef _WIN32
55ef42295fSgr# include <sys/mman.h>
567fa712e0Sgrischka#endif
573db21947Sgrischka
5872729d8eSgrischkastatic void set_pages_executable(TCCState *s1, void *ptr, unsigned long length);
59da8c62f7Sgrischkastatic int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
603db21947Sgrischka
615775911dSAndrew Mulbrook#ifdef _WIN64
62bfd1c08dSgrischkastatic void *win64_add_function_table(TCCState *s1);
63bfd1c08dSgrischkastatic void win64_del_function_table(void *);
64df4c0892Sgrischka#endif
65df4c0892Sgrischka
667fa712e0Sgrischka/* ------------------------------------------------------------- */
677fa712e0Sgrischka/* Do all relocations (needed before using tcc_get_symbol())
687fa712e0Sgrischka   Returns -1 on error. */
693db21947Sgrischka
70ca38792dSgrischkaLIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
713db21947Sgrischka{
72ea2c36c5Sgrischka    int size;
73da8c62f7Sgrischka    addr_t ptr_diff = 0;
74ca38792dSgrischka
75ca38792dSgrischka    if (TCC_RELOCATE_AUTO != ptr)
76da8c62f7Sgrischka        return tcc_relocate_ex(s1, ptr, 0);
77ca38792dSgrischka
78da8c62f7Sgrischka    size = tcc_relocate_ex(s1, NULL, 0);
79bfd1c08dSgrischka    if (size < 0)
80bfd1c08dSgrischka        return -1;
8105108a3bSgrischka
822ab42855SHenry Kroll III#ifdef HAVE_SELINUX
83da8c62f7Sgrischka{
84da8c62f7Sgrischka    /* Using mmap instead of malloc */
85da8c62f7Sgrischka    void *prx;
86da8c62f7Sgrischka    char tmpfname[] = "/tmp/.tccrunXXXXXX";
87da8c62f7Sgrischka    int fd = mkstemp(tmpfname);
88da8c62f7Sgrischka    unlink(tmpfname);
89da8c62f7Sgrischka    ftruncate(fd, size);
90da8c62f7Sgrischka
91da8c62f7Sgrischka    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
92da8c62f7Sgrischka    prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
93da8c62f7Sgrischka    if (ptr == MAP_FAILED || prx == MAP_FAILED)
94da8c62f7Sgrischka	tcc_error("tccrun: could not map memory");
95ea2c36c5Sgrischka    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
96da8c62f7Sgrischka    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
97da8c62f7Sgrischka    ptr_diff = (char*)prx - (char*)ptr;
9838776187Sherman ten brugge    close(fd);
99da8c62f7Sgrischka}
1002ab42855SHenry Kroll III#else
101ea2c36c5Sgrischka    ptr = tcc_malloc(size);
1022ab42855SHenry Kroll III#endif
103da8c62f7Sgrischka    tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
104ea2c36c5Sgrischka    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
105bfd1c08dSgrischka    return 0;
106bfd1c08dSgrischka}
107bfd1c08dSgrischka
108bfd1c08dSgrischkaST_FUNC void tcc_run_free(TCCState *s1)
109bfd1c08dSgrischka{
110bfd1c08dSgrischka    int i;
111bfd1c08dSgrischka
112bfd1c08dSgrischka    for (i = 0; i < s1->nb_runtime_mem; ++i) {
113bfd1c08dSgrischka#ifdef HAVE_SELINUX
114ea2c36c5Sgrischka        unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
115da8c62f7Sgrischka        munmap(s1->runtime_mem[i++], size);
116ea2c36c5Sgrischka        munmap(s1->runtime_mem[i], size);
117bfd1c08dSgrischka#else
118ea2c36c5Sgrischka#ifdef _WIN64
119bfd1c08dSgrischka        win64_del_function_table(*(void**)s1->runtime_mem[i]);
120ea2c36c5Sgrischka#endif
121bfd1c08dSgrischka        tcc_free(s1->runtime_mem[i]);
122bfd1c08dSgrischka#endif
123bfd1c08dSgrischka    }
124bfd1c08dSgrischka    tcc_free(s1->runtime_mem);
125ef42295fSgr}
126ef42295fSgr
127ef42295fSgrstatic void run_cdtors(TCCState *s1, const char *start, const char *end)
128ef42295fSgr{
129ef42295fSgr    void **a = tcc_get_symbol(s1, start);
130ef42295fSgr    void **b = tcc_get_symbol(s1, end);
131ef42295fSgr    while (a != b)
132ef42295fSgr        ((void(*)(void))*a++)();
1333db21947Sgrischka}
1343db21947Sgrischka
1357fa712e0Sgrischka/* launch the compiled program with the given arguments */
13674a24d77SgrischkaLIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
1373db21947Sgrischka{
138ef42295fSgr    int (*prog_main)(int, char **), ret;
139ef42295fSgr#ifdef CONFIG_TCC_BACKTRACE
140ef42295fSgr    rt_context *rc = &g_rtctxt;
14138776187Sherman ten brugge#endif
1422ab42855SHenry Kroll III
143fa0ef91aSZiga Lenarcic    s1->runtime_main = s1->nostdlib ? "_start" : "main";
1440cc24d0eSgrischka    if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
1450cc24d0eSgrischka        return 0;
146ef42295fSgr#ifdef CONFIG_TCC_BACKTRACE
147ef42295fSgr    if (s1->do_debug)
148ef42295fSgr        tcc_add_symbol(s1, "exit", rt_exit);
149ef42295fSgr#endif
150ca38792dSgrischka    if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
1517fa712e0Sgrischka        return -1;
15273faaea2Sgrischka    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
1533db21947Sgrischka
1547fa712e0Sgrischka#ifdef CONFIG_TCC_BACKTRACE
155ef42295fSgr    memset(rc, 0, sizeof *rc);
156d483ab32Sgrischka    if (s1->do_debug) {
157ef42295fSgr        void *p;
158ef42295fSgr        rc->stab_sym = (Stab_Sym *)stab_section->data;
159ef42295fSgr        rc->stab_sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
160ef42295fSgr        rc->stab_str = (char *)stab_section->link->data;
161ef42295fSgr        rc->esym_start = (ElfW(Sym) *)(symtab_section->data);
162ef42295fSgr        rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
163ef42295fSgr        rc->elf_str = (char *)symtab_section->link->data;
1642b7cffacSgrischka#if PTR_SIZE == 8
1652b7cffacSgrischka        rc->prog_base = text_section->sh_addr & 0xffffffff00000000ULL;
1662b7cffacSgrischka#endif
167ef42295fSgr        rc->top_func = tcc_get_symbol(s1, "main");
168ef42295fSgr        rc->num_callers = s1->rt_num_callers;
169ef42295fSgr        rc->do_jmp = 1;
170ef42295fSgr        if ((p = tcc_get_symbol(s1, "__rt_error")))
171ef42295fSgr            *(void**)p = _rt_error;
172ef42295fSgr#ifdef CONFIG_TCC_BCHECK
173ef42295fSgr        if (s1->do_bounds_check) {
174ef42295fSgr            if ((p = tcc_get_symbol(s1, "__bound_init")))
175ef42295fSgr                ((void(*)(void*))p)(bounds_section->data);
176ef42295fSgr        }
177ef42295fSgr#endif
1787fa712e0Sgrischka        set_exception_handler();
179d483ab32Sgrischka    }
1803db21947Sgrischka#endif
1813db21947Sgrischka
1829c5bb164Sgrischka    errno = 0; /* clean errno value */
183ef42295fSgr    fflush(stdout);
184ef42295fSgr    fflush(stderr);
185ef42295fSgr    run_cdtors(s1, "__init_array_start", "__init_array_end");
186ef42295fSgr#ifdef CONFIG_TCC_BACKTRACE
187ef42295fSgr    if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf)))
18838776187Sherman ten brugge#endif
189ef42295fSgr    {
190ef42295fSgr        ret = prog_main(argc, argv);
191cde79a80Sseyko    }
192ef42295fSgr    run_cdtors(s1, "__fini_array_start", "__fini_array_end");
193ef42295fSgr    if ((s1->dflag & 16) && ret)
194ef42295fSgr        fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
19538776187Sherman ten brugge    return ret;
1963db21947Sgrischka}
1973db21947Sgrischka
19885fca9e9Sgrischka#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1998f6fcb70Sgrischka/* To avoid that x86 processors would reload cached instructions
2008f6fcb70Sgrischka   each time when data is written in the near, we need to make
2018f6fcb70Sgrischka   sure that code and data do not share the same 64 byte unit */
2025420bb8aSDavid Mertens #define RUN_SECTION_ALIGNMENT 63
2035d1bc3fbSDavid Mertens#else
2048f6fcb70Sgrischka #define RUN_SECTION_ALIGNMENT 0
2055d1bc3fbSDavid Mertens#endif
2065d1bc3fbSDavid Mertens
2077fa712e0Sgrischka/* relocate code. Return -1 on error, required size if ptr is NULL,
2087fa712e0Sgrischka   otherwise copy code into buffer passed by the caller */
209da8c62f7Sgrischkastatic int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
2107fa712e0Sgrischka{
2117fa712e0Sgrischka    Section *s;
2128f6fcb70Sgrischka    unsigned offset, length, align, max_align, i, k, f;
2138f6fcb70Sgrischka    addr_t mem, addr;
2147fa712e0Sgrischka
21505108a3bSgrischka    if (NULL == ptr) {
2167fa712e0Sgrischka        s1->nb_errors = 0;
2177fa712e0Sgrischka#ifdef TCC_TARGET_PE
2187fa712e0Sgrischka        pe_output_file(s1, NULL);
2193db21947Sgrischka#else
2207fa712e0Sgrischka        tcc_add_runtime(s1);
2211a4d4b76Sgrischka	resolve_common_syms(s1);
2227fa712e0Sgrischka        build_got_entries(s1);
2237fa712e0Sgrischka#endif
2247fa712e0Sgrischka        if (s1->nb_errors)
2257fa712e0Sgrischka            return -1;
2267fa712e0Sgrischka    }
2273db21947Sgrischka
2288f6fcb70Sgrischka    offset = max_align = 0, mem = (addr_t)ptr;
229bfd1c08dSgrischka#ifdef _WIN64
2308f6fcb70Sgrischka    offset += sizeof (void*); /* space for function_table pointer */
231bfd1c08dSgrischka#endif
23285fca9e9Sgrischka    for (k = 0; k < 2; ++k) {
2338f6fcb70Sgrischka        f = 0, addr = k ? mem : mem + ptr_diff;
23485fca9e9Sgrischka        for(i = 1; i < s1->nb_sections; i++) {
23585fca9e9Sgrischka            s = s1->sections[i];
23685fca9e9Sgrischka            if (0 == (s->sh_flags & SHF_ALLOC))
23785fca9e9Sgrischka                continue;
23885fca9e9Sgrischka            if (k != !(s->sh_flags & SHF_EXECINSTR))
23985fca9e9Sgrischka                continue;
2408f6fcb70Sgrischka            align = s->sh_addralign - 1;
2418f6fcb70Sgrischka            if (++f == 1 && align < RUN_SECTION_ALIGNMENT)
2428f6fcb70Sgrischka                align = RUN_SECTION_ALIGNMENT;
2438f6fcb70Sgrischka            if (max_align < align)
2448f6fcb70Sgrischka                max_align = align;
2458f6fcb70Sgrischka            offset += -(addr + offset) & align;
2468f6fcb70Sgrischka            s->sh_addr = mem ? addr + offset : 0;
2478f6fcb70Sgrischka            offset += s->data_offset;
24885fca9e9Sgrischka#if 0
24985fca9e9Sgrischka            if (mem)
2508f6fcb70Sgrischka                printf("%-16s %p  len %04x  align %2d\n",
2518f6fcb70Sgrischka                    s->name, (void*)s->sh_addr, (unsigned)s->data_offset, align + 1);
25285fca9e9Sgrischka#endif
25385fca9e9Sgrischka        }
2547fa712e0Sgrischka    }
2557fa712e0Sgrischka
2567fa712e0Sgrischka    /* relocate symbols */
2574caa9a4cSwanjochan    relocate_syms(s1, s1->symtab, !(s1->nostdlib));
2587fa712e0Sgrischka    if (s1->nb_errors)
2597fa712e0Sgrischka        return -1;
2607fa712e0Sgrischka
2617fa712e0Sgrischka    if (0 == mem)
2628f6fcb70Sgrischka        return offset + max_align;
2637fa712e0Sgrischka
264d348a9a5Sgrischka#ifdef TCC_TARGET_PE
265d348a9a5Sgrischka    s1->pe_imagebase = mem;
266d348a9a5Sgrischka#endif
267d348a9a5Sgrischka
2687fa712e0Sgrischka    /* relocate each section */
2697fa712e0Sgrischka    for(i = 1; i < s1->nb_sections; i++) {
2707fa712e0Sgrischka        s = s1->sections[i];
2717fa712e0Sgrischka        if (s->reloc)
2727fa712e0Sgrischka            relocate_section(s1, s);
2737fa712e0Sgrischka    }
274df349ddcSgrischka#ifndef TCC_TARGET_PE
2759750d0b7SMichael Matz    relocate_plt(s1);
276df349ddcSgrischka#endif
2777fa712e0Sgrischka
2787fa712e0Sgrischka    for(i = 1; i < s1->nb_sections; i++) {
2797fa712e0Sgrischka        s = s1->sections[i];
2807fa712e0Sgrischka        if (0 == (s->sh_flags & SHF_ALLOC))
2817fa712e0Sgrischka            continue;
2827fa712e0Sgrischka        length = s->data_offset;
28382bcbd02Sgrischka        ptr = (void*)s->sh_addr;
284da8c62f7Sgrischka        if (s->sh_flags & SHF_EXECINSTR)
28526904250Sherman ten brugge            ptr = (char*)((addr_t)ptr - ptr_diff);
2867fa712e0Sgrischka        if (NULL == s->data || s->sh_type == SHT_NOBITS)
2877fa712e0Sgrischka            memset(ptr, 0, length);
2887fa712e0Sgrischka        else
2897fa712e0Sgrischka            memcpy(ptr, s->data, length);
2907fa712e0Sgrischka        /* mark executable sections as executable in memory */
2917fa712e0Sgrischka        if (s->sh_flags & SHF_EXECINSTR)
29226904250Sherman ten brugge            set_pages_executable(s1, (char*)((addr_t)ptr + ptr_diff), length);
2937fa712e0Sgrischka    }
29432c9b514Sjanus.lt
29532c9b514Sjanus.lt#ifdef _WIN64
29632c9b514Sjanus.lt    *(void**)mem = win64_add_function_table(s1);
29732c9b514Sjanus.lt#endif
29832c9b514Sjanus.lt
2997fa712e0Sgrischka    return 0;
3003db21947Sgrischka}
3013db21947Sgrischka
3027fa712e0Sgrischka/* ------------------------------------------------------------- */
3037fa712e0Sgrischka/* allow to run code in memory */
3043db21947Sgrischka
30572729d8eSgrischkastatic void set_pages_executable(TCCState *s1, void *ptr, unsigned long length)
3067fa712e0Sgrischka{
3077fa712e0Sgrischka#ifdef _WIN32
3087fa712e0Sgrischka    unsigned long old_protect;
3097fa712e0Sgrischka    VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
3107fa712e0Sgrischka#else
311ea2c36c5Sgrischka    void __clear_cache(void *beginning, void *end);
312da8c62f7Sgrischka# ifndef HAVE_SELINUX
313ea2c36c5Sgrischka    addr_t start, end;
314da8c62f7Sgrischka#  ifndef PAGESIZE
315da8c62f7Sgrischka#   define PAGESIZE 4096
316da8c62f7Sgrischka#  endif
31782bcbd02Sgrischka    start = (addr_t)ptr & ~(PAGESIZE - 1);
31882bcbd02Sgrischka    end = (addr_t)ptr + length;
3197fa712e0Sgrischka    end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
32002642bc9Sgrischka    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
32102642bc9Sgrischka        tcc_error("mprotect failed: did you mean to configure --with-selinux?");
322da8c62f7Sgrischka# endif
323ea2c36c5Sgrischka# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
324ea2c36c5Sgrischka    __clear_cache(ptr, (char *)ptr + length);
325ea2c36c5Sgrischka# endif
3267fa712e0Sgrischka#endif
3277fa712e0Sgrischka}
3283db21947Sgrischka
329bfd1c08dSgrischka#ifdef _WIN64
330bfd1c08dSgrischkastatic void *win64_add_function_table(TCCState *s1)
331bfd1c08dSgrischka{
332bfd1c08dSgrischka    void *p = NULL;
333bfd1c08dSgrischka    if (s1->uw_pdata) {
334bfd1c08dSgrischka        p = (void*)s1->uw_pdata->sh_addr;
3354af25aedSThomas Stalder        RtlAddFunctionTable(
336bfd1c08dSgrischka            (RUNTIME_FUNCTION*)p,
337bfd1c08dSgrischka            s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
338d348a9a5Sgrischka            s1->pe_imagebase
339bfd1c08dSgrischka            );
340bfd1c08dSgrischka        s1->uw_pdata = NULL;
341bfd1c08dSgrischka    }
342d348a9a5Sgrischka    return p;
343bfd1c08dSgrischka}
344bfd1c08dSgrischka
345bfd1c08dSgrischkastatic void win64_del_function_table(void *p)
346bfd1c08dSgrischka{
347bfd1c08dSgrischka    if (p) {
348bfd1c08dSgrischka        RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
349bfd1c08dSgrischka    }
350bfd1c08dSgrischka}
351bfd1c08dSgrischka#endif
352ef42295fSgr#endif //ndef CONFIG_TCC_BACKTRACE_ONLY
3537fa712e0Sgrischka/* ------------------------------------------------------------- */
3543db21947Sgrischka#ifdef CONFIG_TCC_BACKTRACE
3553db21947Sgrischka
35665f74a4dSgrischkastatic int rt_vprintf(const char *fmt, va_list ap)
35765f74a4dSgrischka{
35865f74a4dSgrischka    int ret = vfprintf(stderr, fmt, ap);
35965f74a4dSgrischka    fflush(stderr);
36065f74a4dSgrischka    return ret;
36165f74a4dSgrischka}
36265f74a4dSgrischka
36365f74a4dSgrischkastatic int rt_printf(const char *fmt, ...)
36465f74a4dSgrischka{
36565f74a4dSgrischka    va_list ap;
36665f74a4dSgrischka    int r;
36765f74a4dSgrischka    va_start(ap, fmt);
36865f74a4dSgrischka    r = rt_vprintf(fmt, ap);
36965f74a4dSgrischka    va_end(ap);
37065f74a4dSgrischka    return r;
37165f74a4dSgrischka}
37265f74a4dSgrischka
373ef42295fSgr#define INCLUDE_STACK_SIZE 32
374ef42295fSgr
3753db21947Sgrischka/* print the position in the source file of PC value 'pc' by reading
3763db21947Sgrischka   the stabs debug information */
377ef42295fSgrstatic addr_t rt_printline (rt_context *rc, addr_t wanted_pc,
378ef42295fSgr    const char *msg, const char *skip)
3793db21947Sgrischka{
38065f74a4dSgrischka    char func_name[128];
38182bcbd02Sgrischka    addr_t func_addr, last_pc, pc;
3823db21947Sgrischka    const char *incl_files[INCLUDE_STACK_SIZE];
38365f74a4dSgrischka    int incl_index, last_incl_index, len, last_line_num, i;
3843db21947Sgrischka    const char *str, *p;
385ef42295fSgr    ElfW(Sym) *esym;
386ef42295fSgr    Stab_Sym *sym;
3873db21947Sgrischka
388ef42295fSgrnext:
3893db21947Sgrischka    func_name[0] = '\0';
3903db21947Sgrischka    func_addr = 0;
3913db21947Sgrischka    incl_index = 0;
39282bcbd02Sgrischka    last_pc = (addr_t)-1;
3933db21947Sgrischka    last_line_num = 1;
394