Alien-TinyCCx

 view release on metacpan or  search on metacpan

src/Changelog  view on Meta::CPAN

- work around a wine cmd bug when building tcc on Windows (Austin English)
- reenable some bound check tests (grischka)
- boundtest.c lookup honors VPATH (grischka)
- diff compared to CC in test[123]b? are now errors (grischka)
- fix test3 on Windows (grischka)
- prevent gcc from building (non functional) libtcc.a (grischka)
- fix warning related to PE file generation on x86-64 (grischka)
- stop mixing ordinary and implicit rule in Makefile (Iavael)
- fix integer to double conversion on ARM (Thomas Preud'homme)
- fix parameter passing of structure < 4 bytes on ARM (Thomas Preud'homme)
- disable builtin_frame_address test on ARM due to gcc bug (Thomas Preud'homme)
- fix initialization of struct on ARM (Thomas Preud'homme)
- fix parameter passing of (unsigned) long long bitfield (Thomas Preud'homme)
- improve float to integer tests (Thomas Preud'homme)
- fix relocation of Thumb branch to ARM function (Thomas Preud'homme)
- fix char wrong compatibility with [un]signed char (Thomas Preud'homme)
- choose the code to compile based on target in libtcc1 (Thomas Preud'homme)
- fix various clang warnings (Thomas Preud'homme)
- don't hardcode tcc in Makefile for tests (Thomas Preud'homme)
- fix relocation of __bound_init bound checking code (Thomas Preud'homme)
- accept only one basic type for a given variable (Thomas Preud'homme)

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

            gv(RC_FRET);
        break;
    default:
      assert(0);
    }
}

ST_FUNC void gfunc_epilog(void)
{
    if (loc) {
        // Insert instructions to subtract size of stack frame from SP.
        unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
        uint64_t diff = (-loc + 15) & ~15;
        if (!(diff >> 24)) {
            if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
                write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
            if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12
                write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10);
        }
        else {
            // In this case we may subtract more than necessary,

src/elf.h  view on Meta::CPAN

#define	PT_NULL		0		/* Program header table entry unused */
#define PT_LOAD		1		/* Loadable program segment */
#define PT_DYNAMIC	2		/* Dynamic linking information */
#define PT_INTERP	3		/* Program interpreter */
#define PT_NOTE		4		/* Auxiliary information */
#define PT_SHLIB	5		/* Reserved */
#define PT_PHDR		6		/* Entry for header table itself */
#define PT_TLS		7		/* Thread-local storage segment */
#define	PT_NUM		8		/* Number of defined types */
#define PT_LOOS		0x60000000	/* Start of OS-specific */
#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
#define PT_LOSUNW	0x6ffffffa
#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
#define PT_HISUNW	0x6fffffff
#define PT_HIOS		0x6fffffff	/* End of OS-specific */
#define PT_LOPROC	0x70000000	/* Start of processor-specific */
#define PT_HIPROC	0x7fffffff	/* End of processor-specific */

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);
#ifdef TCC_TARGET_PE
        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
#endif
    }

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

        char *overflow_arg_area;
    };
    char *reg_save_area;
} __va_list_struct;

typedef __va_list_struct va_list[1];

void __va_start(__va_list_struct *ap, void *fp);
void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);

#define va_start(ap, last) __va_start(ap, __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) = *(src))
#define va_end(ap)

/* avoid conflicting definition for va_list on Macs. */
#define _VA_LIST_T

#else /* _WIN64 */
typedef char *va_list;

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 = (size_t)__builtin_frame_address(1);\
}

/* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1) 
{
    size_t addr, size, fp, *p = p1;

    dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
    GET_CALLER_FP(fp);
    for(;;) {

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/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:
    case TOK_builtin_return_address:
        {
            int tok1 = tok;
            int level;
            CType type;
            next();
            skip('(');
            if (tok != TOK_CINT) {
                tcc_error("%s only takes positive integers",
                          tok1 == TOK_builtin_return_address ?
                          "__builtin_return_address" :
                          "__builtin_frame_address");
            }
            level = (uint32_t)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 */
            }
            if (tok1 == TOK_builtin_return_address) {
                // assume return address is just above frame pointer on stack
                vpushi(PTR_SIZE);
                gen_op('+');
                mk_pointer(&vtop->type);
                indir();
            }
        }
        break;
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
    case TOK_builtin_va_start:

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 */
        --local_scope;
        sym_pop(&local_stack, s);
        
        /* Pop VLA frames and restore stack pointer if required */
        if (vlas_in_scope > saved_vlas_in_scope) {
            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
            vla_sp_restore();
        }
        vlas_in_scope = saved_vlas_in_scope;
        
        next();
    } else if (tok == TOK_RETURN) {
        next();
        if (tok != ';') {

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__) || defined(__DragonFly__)
        *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__) || defined(__DragonFly__)

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

    }
    return EXCEPTION_EXECUTE_HANDLER;
}

/* Generate a stack backtrace when a CPU exception occurs. */
static void set_exception_handler(void)
{
    SetUnhandledExceptionFilter(cpu_exception_handler);
}

/* 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_word, "__word__")

     DEF(TOK_DLLEXPORT, "dllexport")
     DEF(TOK_DLLIMPORT, "dllimport")
     DEF(TOK_NORETURN1, "noreturn")
     DEF(TOK_NORETURN2, "__noreturn__")
     DEF(TOK_VISIBILITY1, "visibility")
     DEF(TOK_VISIBILITY2, "__visibility__")
     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")
     DEF(TOK_builtin_return_address, "__builtin_return_address")
     DEF(TOK_builtin_expect, "__builtin_expect")
#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")

src/tests/tcctest.c  view on Meta::CPAN

void typeof_test(void);
void local_label_test(void);
void statement_expr_test(void);
void asm_test(void);
void builtin_test(void);
void weak_test(void);
void global_data_test(void);
void cmp_comparison_test(void);
void math_cmp_test(void);
void callsave_test(void);
void builtin_frame_address_test(void);

int fib(int n);
void num(int n);
void forward_ref(void);
int isid(int c);

/* Line joining happens before tokenization, so the following
   must be parsed as ellipsis.  */
void funny_line_continuation (int, ..\
. );

src/tests/tcctest.c  view on Meta::CPAN

    local_label_test();
    asm_test();
    builtin_test();
#ifndef _WIN32
    weak_test();
#endif
    global_data_test();
    cmp_comparison_test();
    math_cmp_test();
    callsave_test();
    builtin_frame_address_test();
    intdiv_test();
    if (via_volatile (42) != 42)
      printf ("via_volatile broken\n");
    return 0; 
}

int tab[3];
int tab2[3][2];

int g;

src/tests/tcctest.c  view on Meta::CPAN

     with the high 32 bit set (which is likely on x86-64) the access
     generates a segfault.  */
  i = d[0] > get100 ();
  printf ("%d\n", i);
#endif
}


void bfa3(ptrdiff_t str_offset)
{
    printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
}
void bfa2(ptrdiff_t str_offset)
{
    printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
    bfa3(str_offset);
}
void bfa1(ptrdiff_t str_offset)
{
    printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
    bfa2(str_offset);
}

void builtin_frame_address_test(void)
{
/* builtin_frame_address fails on ARM with gcc which make test3 fail */
#ifndef __arm__
    char str[] = "__builtin_frame_address";
    char *fp0 = __builtin_frame_address(0);

    printf("str: %s\n", str);
    bfa1(str-fp0);
#endif
}

char via_volatile (char i)
{
  char volatile vi;
  vi = i;

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, 0); /* call __chkstk, (does the stackframe too) */
        greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
        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 1.871 second using v1.01-cache-2.11-cpan-df04353d9ac )