Alien-TinyCC

 view release on metacpan or  search on metacpan

src/i386-gen.c  view on Meta::CPAN

        g(func_ret_sub >> 8);
    }
    /* align local size to word & save local variables */
    
    v = (-loc + 3) & -4; 
    saved_ind = ind;
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE
    if (v >= 4096) {
        oad(0xb8, v); /* mov stacksize, %eax */
        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
    } else
#endif
    {
        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
        o(0xec81);  /* sub esp, stacksize */
        gen_le32(v);
#if FUNC_PROLOG_SIZE == 10
        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
#endif
    }

src/include/stdarg.h  view on Meta::CPAN

#ifdef __x86_64__
#ifndef _WIN64

typedef void *va_list;

va_list __va_start(void *fp);
void *__va_arg(va_list ap, int arg_type, int size, int align);
va_list __va_copy(va_list src);
void __va_end(va_list ap);

#define va_start(ap, last) ((ap) = __va_start(__builtin_frame_address(0)))
#define va_arg(ap, type)                                                \
    (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type))))
#define va_copy(dest, src) ((dest) = __va_copy(src))
#define va_end(ap) __va_end(ap)

#else /* _WIN64 */
typedef char *va_list;
#define va_start(ap,last) __builtin_va_start(ap,last)
#define va_arg(ap,type) (ap += 8, sizeof(type)<=8 ? *(type*)ap : **(type**)ap)
#define va_copy(dest, src) ((dest) = (src))

src/lib/bcheck.c  view on Meta::CPAN

    return p + offset;                                                  \
}

BOUND_PTR_INDIR(1)
BOUND_PTR_INDIR(2)
BOUND_PTR_INDIR(4)
BOUND_PTR_INDIR(8)
BOUND_PTR_INDIR(12)
BOUND_PTR_INDIR(16)

/* return the frame pointer of the caller */
#define GET_CALLER_FP(fp)\
{\
    fp = (unsigned long)__builtin_frame_address(1);\
}

/* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1) 
{
    unsigned long addr, size, fp, *p = p1;
    GET_CALLER_FP(fp);
    for(;;) {
        addr = p[0];
        if (addr == 0)

src/stab.def  view on Meta::CPAN

   here.  */
__define_stab (N_CATCH, 0x54, "CATCH")

/* Structure or union element.  Value is offset in the structure.  */
__define_stab (N_SSYM, 0x60, "SSYM")

/* Name of main source file.
   Value is starting text address of the compilation.  */
__define_stab (N_SO, 0x64, "SO")

/* Automatic variable in the stack.  Value is offset from frame pointer.
   Also used for type descriptions.  */
__define_stab (N_LSYM, 0x80, "LSYM")

/* Beginning of an include file.  Only Sun uses this.
   In an object file, only the name is significant.
   The Sun linker puts data into some of the other fields.  */
__define_stab (N_BINCL, 0x82, "BINCL")

/* Name of sub-source file (#include file).
   Value is starting text address of the compilation.  */
__define_stab (N_SOL, 0x84, "SOL")

/* Parameter variable.  Value is offset from argument pointer.
   (On most machines the argument pointer is the same as the frame pointer.  */
__define_stab (N_PSYM, 0xa0, "PSYM")

/* End of an include file.  No name.
   This and N_BINCL act as brackets around the file's output.
   In an object file, there is no significant data in this entry.
   The Sun linker puts data into some of the fields.  */
__define_stab (N_EINCL, 0xa2, "EINCL")

/* Alternate entry point.  Value is its address.  */
__define_stab (N_ENTRY, 0xa4, "ENTRY")

src/tcc.h  view on Meta::CPAN

#define INT_ATTR(ad) (*(int*)(ad))

/* -------------------------------------------------- */

#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */

#define VLA_SP_LOC_SET     0x01 /* Location of SP on stack has been allocated */
#define VLA_SP_SAVED       0x02 /* SP has been saved to slot already */
#define VLA_NEED_NEW_FRAME 0x04 /* Needs new frame for next VLA */
#define VLA_IN_SCOPE       0x08 /* One or more VLAs are in scope */
#define VLA_SCOPE_FLAGS    (VLA_SP_SAVED|VLA_NEED_NEW_FRAME|VLA_IN_SCOPE) /* Flags which are saved and restored upon entering and exiting a block */

/* stored in 'Sym.c' field */
#define FUNC_NEW       1 /* ansi function prototype */
#define FUNC_OLD       2 /* old function prototype */
#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */

/* stored in 'Sym.r' field */
#define FUNC_CDECL     0 /* standard c call */

src/tcccoff.c  view on Meta::CPAN

    long size;
    long fileptr;
    long nextsym;
    short int dummy;
} AUXFUNC;

typedef struct {
    long regmask;
    unsigned short lineno;
    unsigned short nentries;
    int localframe;
    int nextentry;
    short int dummy;
} AUXBF;

typedef struct {
    long dummy;
    unsigned short lineno;
    unsigned short dummy1;
    int dummy2;
    int dummy3;

src/tcccoff.c  view on Meta::CPAN

		csym.n_type = 0;
		csym.n_sclass = C_FCN;
		csym.n_numaux = 1;
		fwrite(&csym, 18, 1, f);

		// now put aux info

		auxbf.regmask = 0;
		auxbf.lineno = 0;
		auxbf.nentries = FuncEntries[k];
		auxbf.localframe = 0;
		auxbf.nextentry = n + 6;
		auxbf.dummy = 0;
		fwrite(&auxbf, 18, 1, f);

		// put a .ef

		strcpy(csym._n._n_name, ".ef");
		csym.n_value = EndAddress[k];	// physical address  
		csym.n_scnum = CoffTextSectionNo;
		csym.n_type = 0;

src/tccgen.c  view on Meta::CPAN

            saved_nocode_wanted = nocode_wanted;
            nocode_wanted = 1;
            gexpr();
            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
            vpop();
            nocode_wanted = saved_nocode_wanted;
            skip(')');
            vpushi(res);
        }
        break;
    case TOK_builtin_frame_address:
        {
            int level;
            CType type;
            next();
            skip('(');
            if (tok != TOK_CINT || tokc.i < 0) {
                tcc_error("__builtin_frame_address only takes positive integers");
            }
            level = tokc.i;
            next();
            skip(')');
            type.t = VT_VOID;
            mk_pointer(&type);
            vset(&type, VT_LOCAL, 0);       /* local frame */
            while (level--) {
                mk_pointer(&vtop->type);
                indir();                    /* -> parent frame */
            }
        }
        break;
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
    case TOK_builtin_va_start:
        {
            next();
            skip('(');
            expr_eq();

src/tccgen.c  view on Meta::CPAN

	}
	unget_tok(last_tok);
      }
    decl(l);
}

static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
                  int case_reg, int is_expr)
{
    int a, b, c, d;
    Sym *s, *frame_bottom;

    /* generate line number info */
    if (tcc_state->do_debug &&
        (last_line_num != file->line_num || last_ind != ind)) {
        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
        last_ind = ind;
        last_line_num = file->line_num;
    }

    if (is_expr) {

src/tccgen.c  view on Meta::CPAN

        gjmp_addr(d);
        gsym(a);
        gsym_addr(b, d);
    } else if (tok == '{') {
        Sym *llabel;
        int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;

        next();
        /* record local declaration stack position */
        s = local_stack;
        frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
        frame_bottom->next = scope_stack_bottom;
        scope_stack_bottom = frame_bottom;
        llabel = local_label_stack;
        
        /* save VLA state */
        block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
        if (saved_vla_sp_loc != &vla_sp_root_loc)
          vla_sp_loc = &block_vla_sp_loc;

        saved_vla_flags = vla_flags;
        vla_flags |= VLA_NEED_NEW_FRAME;
        

src/tccgen.c  view on Meta::CPAN

            case VT_FUNC:
                for(p=vtop->type.ref;p;p=p->prev)
                    if(p->prev==s)
                        tcc_error("unsupported expression type");
            }
        }
        /* pop locally defined symbols */
        scope_stack_bottom = scope_stack_bottom->next;
        sym_pop(&local_stack, s);
        
        /* Pop VLA frames and restore stack pointer if required */
        if (saved_vla_sp_loc != &vla_sp_root_loc)
            *saved_vla_sp_loc = block_vla_sp_loc;
        if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
            vla_sp_loc = saved_vla_sp_loc;
            gen_vla_sp_restore(*vla_sp_loc);
        }
        vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
        
        next();
    } else if (tok == TOK_RETURN) {

src/tccgen.c  view on Meta::CPAN

        if (!csym)
            tcc_error("cannot continue");
        *csym = gjmp(*csym);
        next();
        skip(';');
    } else if (tok == TOK_FOR) {
        int e;
        next();
        skip('(');
        s = local_stack;
        frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
        frame_bottom->next = scope_stack_bottom;
        scope_stack_bottom = frame_bottom;
        if (tok != ';') {
            /* c99 for-loop init decl? */
            if (!decl0(VT_LOCAL, 1)) {
                /* no, regular for-loop init expr */
                gexpr();
                vpop();
            }
        }
        skip(';');
        d = ind;

src/tccpe.c  view on Meta::CPAN

#ifdef TCC_TARGET_X86_64
static unsigned pe_add_uwwind_info(TCCState *s1)
{
    if (NULL == s1->uw_pdata) {
        s1->uw_pdata = find_section(tcc_state, ".pdata");
        s1->uw_pdata->sh_addralign = 4;
        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL);
    }

    if (0 == s1->uw_offs) {
        /* As our functions all have the same stackframe, we use one entry for all */
        static const unsigned char uw_info[] = {
            0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
            0x04, // UBYTE Size of prolog
            0x02, // UBYTE Count of unwind codes
            0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
            // USHORT * n Unwind codes array
            // 0x0b, 0x01, 0xff, 0xff, // stack size
            0x04, 0x03, // set frame ptr (mov rsp -> rbp)
            0x01, 0x50  // push reg (rbp)
        };

        Section *s = text_section;
        unsigned char *p;

        section_ptr_add(s, -s->data_offset & 3); /* align */
        s1->uw_offs = s->data_offset;
        p = section_ptr_add(s, sizeof uw_info);
        memcpy(p, uw_info, sizeof uw_info);

src/tccrun.c  view on Meta::CPAN


/* ------------------------------------------------------------- */
#ifdef __i386__

/* fix for glibc 2.1 */
#ifndef REG_EIP
#define REG_EIP EIP
#define REG_EBP EBP
#endif

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp;
    int i;

    if (level == 0) {
#if defined(__APPLE__)
        *paddr = uc->uc_mcontext->__ss.__eip;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        *paddr = uc->uc_mcontext.mc_eip;

src/tccrun.c  view on Meta::CPAN

            fp = ((addr_t *)fp)[0];
        }
        *paddr = ((addr_t *)fp)[1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#elif defined(__x86_64__)

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp;
    int i;

    if (level == 0) {
        /* XXX: only support linux */
#if defined(__APPLE__)
        *paddr = uc->uc_mcontext->__ss.__rip;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 

src/tccrun.c  view on Meta::CPAN

            fp = ((addr_t *)fp)[0];
        }
        *paddr = ((addr_t *)fp)[1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#elif defined(__arm__)

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp, sp;
    int i;

    if (level == 0) {
        /* XXX: only supports linux */
#if defined(__linux__)
        *paddr = uc->uc_mcontext.arm_pc;
#else

src/tccrun.c  view on Meta::CPAN

        return 0;
    } else {
#if defined(__linux__)
        fp = uc->uc_mcontext.arm_fp;
        sp = uc->uc_mcontext.arm_sp;
        if (sp < 0x1000)
            sp = 0x1000;
#else
        return -1;
#endif
        /* XXX: specific to tinycc stack frames */
        if (fp < sp + 12 || fp & 3)
            return -1;
        for(i = 1; i < level; i++) {
            sp = ((addr_t *)fp)[-2];
            if (sp < fp || sp - fp > 16 || sp & 3)
                return -1;
            fp = ((addr_t *)fp)[-3];
            if (fp <= sp || fp - sp < 12 || fp & 3)
                return -1;
        }

src/tccrun.c  view on Meta::CPAN

static void win64_add_function_table(TCCState *s1)
{
    RtlAddFunctionTable(
        (RUNTIME_FUNCTION*)s1->uw_pdata->sh_addr,
        s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
        text_section->sh_addr
        );
}
#endif

/* return the PC at frame level 'level'. Return non zero if not found */
static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
{
    addr_t fp, pc;
    int i;
#ifdef _WIN64
    pc = uc->Rip;
    fp = uc->Rbp;
#else
    pc = uc->Eip;
    fp = uc->Ebp;

src/tcctok.h  view on Meta::CPAN

     DEF(TOK_MODE, "__mode__")
     DEF(TOK_MODE_DI, "__DI__")
     DEF(TOK_MODE_HI, "__HI__")
     DEF(TOK_MODE_SI, "__SI__")
     DEF(TOK_DLLEXPORT, "dllexport")
     DEF(TOK_DLLIMPORT, "dllimport")
     DEF(TOK_NORETURN1, "noreturn")
     DEF(TOK_NORETURN2, "__noreturn__")
     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
     DEF(TOK_builtin_frame_address, "__builtin_frame_address")
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
     DEF(TOK_builtin_va_start, "__builtin_va_start")
#else
     DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
#endif
#endif
     DEF(TOK_REGPARM1, "regparm")
     DEF(TOK_REGPARM2, "__regparm__")

src/win32/lib/chkstk.S  view on Meta::CPAN


/* ---------------------------------------------- */
#ifndef TCC_TARGET_X86_64
/* ---------------------------------------------- */

.globl __chkstk

__chkstk:
    xchg    (%esp),%ebp     /* store ebp, get ret.addr */
    push    %ebp            /* push ret.addr */
    lea     4(%esp),%ebp    /* setup frame ptr */
    push    %ecx            /* save ecx */
    mov     %ebp,%ecx
P0:
    sub     $4096,%ecx
    test    %eax,(%ecx)
    sub     $4096,%eax
    cmp     $4096,%eax
    jge     P0
    sub     %eax,%ecx
    test    %eax,(%ecx)

src/win32/lib/chkstk.S  view on Meta::CPAN


/* ---------------------------------------------- */
#else
/* ---------------------------------------------- */

.globl __chkstk

__chkstk:
    xchg    (%rsp),%rbp     /* store ebp, get ret.addr */
    push    %rbp            /* push ret.addr */
    lea     8(%rsp),%rbp    /* setup frame ptr */
    push    %rcx            /* save ecx */
    mov     %rbp,%rcx
    movslq  %eax,%rax
P0:
    sub     $4096,%rcx
    test    %rax,(%rcx)
    sub     $4096,%rax
    cmp     $4096,%rax
    jge     P0
    sub     %rax,%rcx

src/x86_64-gen.c  view on Meta::CPAN

    }

    saved_ind = ind;
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
    /* align local size to word & save local variables */
    v = (func_scratch + -loc + 15) & -16;

    if (v >= 4096) {
        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
        oad(0xb8, v); /* mov stacksize, %eax */
        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
        greloc(cur_text_section, sym, ind-4, R_X86_64_PC32);
        o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
    } else {
        o(0xe5894855);  /* push %rbp, mov %rsp, %rbp */
        o(0xec8148);  /* sub rsp, stacksize */
        gen_le32(v);
    }

    cur_text_section->data_offset = saved_ind;
    pe_add_unwind_data(ind, saved_ind, v);

src/x86_64-gen.c  view on Meta::CPAN

    sym = func_type->ref;
    addr = PTR_SIZE * 2;
    loc = 0;
    ind += FUNC_PROLOG_SIZE;
    func_sub_sp_offset = ind;
    func_ret_sub = 0;

    if (func_type->ref->c == FUNC_ELLIPSIS) {
        int seen_reg_num, seen_sse_num, seen_stack_size;
        seen_reg_num = seen_sse_num = 0;
        /* frame pointer and return address */
        seen_stack_size = PTR_SIZE * 2;
        /* count the number of seen parameters */
        sym = func_type->ref;
        while ((sym = sym->next) != NULL) {
            type = &sym->type;
            mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
            switch (mode) {
            default:
            stack_arg:
                seen_stack_size = ((seen_stack_size + align - 1) & -align) + size;



( run in 2.393 seconds using v1.01-cache-2.11-cpan-df04353d9ac )