Alien-TinyCCx

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
src/tests/exsymtab/36-two-contexts-typedef-share.c
src/tests/exsymtab/40-two-contexts-func-decl-share.c
src/tests/exsymtab/41-two-contexts-inline-func-share.c
src/tests/exsymtab/42-three-contexts-func-share.c
src/tests/exsymtab/43-three-contexts-inline-func-share.c
src/tests/exsymtab/47-many-consuming-contexts-func-share.c
src/tests/exsymtab/48-many-consuming-contexts-delete.c
src/tests/exsymtab/49-many-consuming-contexts-early-delete.c
src/tests/exsymtab/50-two-contexts-mixup.c
src/tests/exsymtab/51-many-consuming-contexts-with-constants-early-delete.c
src/tests/exsymtab/60-two-contexts-globals.c
src/tests/exsymtab/61-two-contexts-const-globals.c
src/tests/exsymtab/62-two-contexts-static-globals.c
src/tests/exsymtab/63-two-contexts-enum.c
src/tests/exsymtab/70-symtab-use-check.c
src/tests/exsymtab/80-cache-defines.c
src/tests/exsymtab/81-cache-struct.c
src/tests/exsymtab/82-cache-func-decl.c
src/tests/exsymtab/83-cache-func-decl-with-args.c
src/tests/exsymtab/84-cache-func-decl-with-pointer-args.c
src/tests/exsymtab/85-cache-inline-func.c
src/tests/exsymtab/dump-elf-syms.c
src/tests/exsymtab/mytest.pl

inc/My/Build/Windows.pm  view on Meta::CPAN

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        if (not $self->notes('build_state')) {
                # move into the source directory and invoke the custom Windows build
                chdir 'src\\win32';
                system('build-tcc.bat');
                chdir '..\\..';
                 
                # check if there was a mishap:
                $ENV{ERRORLEVEL} and die 'build-tcc.bat failed';
                 
                # Copy the files to the distribution's share dir
                File::Copy::Recursive::rcopy_glob('src\\win32\\*' => 'share\\');
                 
                # Note that we've built it.
                $self->notes('build_state', 'built');
        }
         
        $self->SUPER::ACTION_code;
}
 
sub my_clean {}

src/Changelog  view on Meta::CPAN

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
- add va_* macro implementation for ARM (Thomas Preud'homme)
- define __ARM_EABI__, __ARMEL__ and __ARM_PCS_VFP (Thomas Preud'homme)
- provide a runtime library for ARM (Thomas Preud'homme)
- vastly improved support for ARM hard float calling convention
(Thomas Preud'homme, Daniel Glöckner)
- tcc can uses libtcc1 on ARM (Thomas Preud'homme)
- use __fixdfdi for all float to integer conversion (grischka)
- simplify startup code for unix platforms (grischka)
- improve ELF generated on ARM (Thomas Preud'homme)
- add support for thumb to ARM relocation (Thomas Preud'homme)
- fix globbing to match MSVC on Windows (Thomas Preud'homme)
- deprecate FPA and OABI support for ARM (Thomas Preud'homme)
- warn about softfloat not being supported on ARM (Thomas Preud'homme)
 
Bug fixes:
- many code clean up (Urs Janssen, grischka)
- fixes of other's patches (grischka, Ramsay Jones, Michael Matz)
- fix documentation about __TINYC__ (Urs Janssen)
- improve build of documentation (Urs Janssen)
- improve build instructions (Jov)
- switch from texi2html to makeinfo --html to build tcc-doc.html (James Lyon)

src/Changelog  view on Meta::CPAN

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  469: Fix symbol visibility problems in the linker (Vincent Pit)
  468: Allow && and || involving pointer arguments (Rob Landley)
  455: Optimize case labels with no code in between (Zdenek Pavlas)
  450: Implement alloca for x86 (grischka)
  415: Parse unicode escape sequences (Axel Liljencrantz)
  407: Add a simple va_copy() in stdarg.h (Hasso Tepper)
  400: Allow typedef names as symbols (Dave Dodge)
 
- Import some changesets from Rob Landley's fork (part 1):
  462: Use LGPL with bcheck.c and il-gen.c
  458: Fix global compound literals (in unary: case '&':) (Andrew Johnson)
  456: Use return code from tcc_output_file in main() (Michael Somos)
  442: Fix indirections with function pointers (***fn)() (grischka)
  441: Fix LL left shift in libtcc1.c:__shldi3 (grischka)
  440: Pass structures and function ptrs through ?: (grischka)
  439: Keep rvalue in bit assignment (bit2 = bit1 = x) (grischka)
  438: Degrade nonportable pointer assignment to warning (grischka)
  437: Call 'saveregs()' before jumping with logical and/or/not (grischka)
  435: Put local static variables into global memory (grischka)
  432/434: Cast double and ptr to bool (grischka)
  420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
  417: Make 'sizeof' unsigned (Rob Landley)
  397: Fix save_reg for longlongs (Daniel Glöckner)
  396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
 
- ignore AS_NEEDED ld command
- mark executable sections as executable when running in memory
- added support for win32 wchar_t (Filip Navara)
- segment override prefix support (Filip Navara)

src/Changelog  view on Meta::CPAN

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
version 0.9.19:
 
- "alacarte" linking (Dave Long)
- simpler function call
- more strict type checks
- added 'const' and 'volatile' support and associated warnings
- added -Werror, -Wunsupported, -Wwrite-strings, -Wall.
- added __builtin_types_compatible_p() and __builtin_constant_p()
- chars support in assembler (Dave Long)
- .string, .globl, .section, .text, .data and .bss asm directive
  support (Dave Long)
- man page generated from tcc-doc.texi
- fixed macro argument substitution
- fixed zero argument macro parsing
- changed license to LGPL
- added -rdynamic option support
 
version 0.9.18:
 
- header fix (time.h)

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

1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
        c = vtop->c.i & 0x1f;
        o(opc|(c<<7)|(fr<<12));
      } else {
        fr=intr(gv(RC_INT));
        c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
        o(opc|(c<<12)|(fr<<8)|0x10);
      }
      vtop--;
      break;
    case 3:
      vpush_global_sym(&func_old_type, func);
      vrott(3);
      gfunc_call(2);
      vpushi(0);
      vtop->r = retreg;
      break;
    default:
      tcc_error("gen_opi %i unimplemented!",op);
  }
}

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

2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
#else
    } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
#endif
      func_type = &func_double_type;
      if(vtop->type.t & VT_UNSIGNED)
        func=TOK___floatundidf;
      else
        func=TOK___floatdidf;
    }
    if(func_type) {
      vpush_global_sym(func_type, func);
      vswap();
      gfunc_call(1);
      vpushi(0);
      vtop->r=TREG_F0;
      return;
    }
  }
  tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
}

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

2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
#if LDOUBLE_SIZE != 8
    else if(r2 == VT_LDOUBLE)
      func=TOK___fixxfdi;
    else if(r2 == VT_DOUBLE)
#else
    else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
#endif
      func=TOK___fixdfdi;
  }
  if(func) {
    vpush_global_sym(&func_old_type, func);
    vswap();
    gfunc_call(1);
    vpushi(0);
    if(t == VT_LLONG)
      vtop->r2 = REG_LRET;
    vtop->r = REG_IRET;
    return;
  }
  tcc_error("unimplemented gen_cvt_ftoi!");
}

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

1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
b2 = ind; o(0x14000000); // b lab2
// lab1:
write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
if (hfa == 1 || fsize == 16)
    o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
else {
    // We need to change the layout of this HFA.
    // Get some space on the stack using global variable "loc":
    loc = (loc - size) & -(uint32_t)align;
    o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
    arm64_movimm(r1, loc);
    o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
    o(0x4c402bdc | (uint32_t)fsize << 7 |
      (uint32_t)(hfa == 2) << 15 |
      (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
    o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
      (uint32_t)(hfa != 2) << 13 |
      (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]

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

1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
case '-': func = TOK___subtf3; break;
case '/': func = TOK___divtf3; break;
case TOK_EQ: func = TOK___eqtf2; cond = 1; break;
case TOK_NE: func = TOK___netf2; cond = 0; break;
case TOK_LT: func = TOK___lttf2; cond = 10; break;
case TOK_GE: func = TOK___getf2; cond = 11; break;
case TOK_LE: func = TOK___letf2; cond = 12; break;
case TOK_GT: func = TOK___gttf2; cond = 13; break;
default: assert(0); break;
}
vpush_global_sym(&func_old_type, func);
vrott(3);
gfunc_call(2);
vpushi(0);
vtop->r = cond < 0 ? REG_FRET : REG_IRET;
if (cond < 0)
    vtop->type = type;
else {
    o(0x7100001f); // cmp w0,#0
    o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
}

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

1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
    o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
}
 
ST_FUNC void gen_cvt_itof(int t)
{
    if (t == VT_LDOUBLE) {
        int f = vtop->type.t;
        int func = (f & VT_BTYPE) == VT_LLONG ?
          (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
          (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
        vpush_global_sym(&func_old_type, func);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->type.t = t;
        vtop->r = REG_FRET;
        return;
    }
    else {
        int d, n = intr(gv(RC_INT));
        int s = !(vtop->type.t & VT_UNSIGNED);

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

1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
          l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
    }
}
 
ST_FUNC void gen_cvt_ftoi(int t)
{
    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
        int func = (t & VT_BTYPE) == VT_LLONG ?
          (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
          (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
        vpush_global_sym(&func_old_type, func);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->type.t = t;
        vtop->r = REG_IRET;
        return;
    }
    else {
        int d, n = fltr(gv(RC_FLOAT));
        uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);

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

1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
int f = vtop[0].type.t;
assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
if (t == f)
    return;
 
if (t == VT_LDOUBLE || f == VT_LDOUBLE) {
    int func = (t == VT_LDOUBLE) ?
        (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
        (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
    vpush_global_sym(&func_old_type, func);
    vrott(2);
    gfunc_call(1);
    vpushi(0);
    vtop->type.t = t;
    vtop->r = REG_FRET;
}
else {
    int x, a;
    gv(RC_FLOAT);
    assert(vtop[0].r < VT_CONST);

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

2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
    fr = vtop[0].r;
    vtop--;
    C67_SHR(fr, r);         // arithmetic shift
    break;
 
case '/':
    t = TOK__divi;
  call_func:
    vswap();
    /* call generic idiv function */
    vpush_global_sym(&func_old_type, t);
    vrott(3);
    gfunc_call(2);
    vpushi(0);
    vtop->r = REG_IRET;
    vtop->r2 = VT_CONST;
    break;
case TOK_UDIV:
case TOK_PDIV:
    t = TOK__divu;
    goto call_func;

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

2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
    } else {
        C67_MPYSP(r, fr);       // MPY  fr,r,fr
        C67_NOP(3);
    }
    vtop--;
} else if (op == '/') {
    if ((ft & VT_BTYPE) == VT_DOUBLE) {
        // must call intrinsic DP floating point divide
        vswap();
        /* call generic idiv function */
        vpush_global_sym(&func_old_type, TOK__divd);
        vrott(3);
        gfunc_call(2);
        vpushi(0);
        vtop->r = REG_FRET;
        vtop->r2 = REG_LRET;
 
    } else {
        // must call intrinsic SP floating point divide
        vswap();
        /* call generic idiv function */
        vpush_global_sym(&func_old_type, TOK__divf);
        vrott(3);
        gfunc_call(2);
        vpushi(0);
        vtop->r = REG_FRET;
        vtop->r2 = VT_CONST;
    }
} else
    ALWAYS_ASSERT(FALSE);

src/conftest.c  view on Meta::CPAN

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# define TRIPLET_ABI "gnu"
#endif
 
#ifdef __GNU__
# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
#else
# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
#endif
 
#if defined(_WIN32)
int _CRT_glob = 0;
#endif
 
int main(int argc, char *argv[])
{
    switch(argc == 2 ? argv[1][0] : 0) {
        case 'b':
        {
            volatile unsigned foo = 0x01234567;
            puts(*(unsigned char*)&foo == 0x67 ? "no" : "yes");
            break;

src/elf.h  view on Meta::CPAN

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
#define VER_DEF_NONE    0               /* No version */
#define VER_DEF_CURRENT 1               /* Current version */
#define VER_DEF_NUM     2               /* Given version number */
 
/* Legal values for vd_flags (version information flags).  */
#define VER_FLG_BASE    0x1             /* Version definition of file itself */
#define VER_FLG_WEAK    0x2             /* Weak version identifier */
 
/* Versym symbol index values.  */
#define VER_NDX_LOCAL           0       /* Symbol is local.  */
#define VER_NDX_GLOBAL          1       /* Symbol is global.  */
#define VER_NDX_LORESERVE       0xff00  /* Beginning of reserved entries.  */
#define VER_NDX_ELIMINATE       0xff01  /* Symbol is to be eliminated.  */
 
/* Auxialiary version information.  */
 
typedef struct
{
  Elf32_Word    vda_name;               /* Version or dependency names */
  Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
                                           entry */

src/elf.h  view on Meta::CPAN

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
#define AT_IGNOREPPC    22              /* Entry should be ignored.  */
 
#define AT_SECURE       23              /* Boolean, was exec setuid-like?  */
 
#define AT_BASE_PLATFORM 24             /* String identifying real platforms.*/
 
#define AT_RANDOM       25              /* Address of 16 random bytes.  */
 
#define AT_EXECFN       31              /* Filename of executable.  */
 
/* Pointer to the global system page used for system calls and other
   nice things.  */
#define AT_SYSINFO      32
#define AT_SYSINFO_EHDR 33
 
/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
   log2 of line size; mask those to get cache size.  */
#define AT_L1I_CACHESHAPE       34
#define AT_L1D_CACHESHAPE       35
#define AT_L2_CACHESHAPE        36
#define AT_L3_CACHESHAPE        37

src/elf.h  view on Meta::CPAN

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
#define SHT_MIPS_PIXIE         0x70000023
#define SHT_MIPS_XLATE         0x70000024
#define SHT_MIPS_XLATE_DEBUG   0x70000025
#define SHT_MIPS_WHIRL         0x70000026
#define SHT_MIPS_EH_REGION     0x70000027
#define SHT_MIPS_XLATE_OLD     0x70000028
#define SHT_MIPS_PDR_EXCEPTION 0x70000029
 
/* Legal values for sh_flags field of Elf32_Shdr.  */
 
#define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
#define SHF_MIPS_MERGE   0x20000000
#define SHF_MIPS_ADDR    0x40000000
#define SHF_MIPS_STRINGS 0x80000000
#define SHF_MIPS_NOSTRIP 0x08000000
#define SHF_MIPS_LOCAL   0x04000000
#define SHF_MIPS_NAMES   0x02000000
#define SHF_MIPS_NODUPE  0x01000000
 
 
/* Symbol tables.  */

src/elf.h  view on Meta::CPAN

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
} Elf32_RegInfo;
 
/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
 
typedef struct
{
  unsigned char kind;           /* Determines interpretation of the
                                   variable part of descriptor.  */
  unsigned char size;           /* Size of descriptor, including header.  */
  Elf32_Section section;        /* Section header index of section affected,
                                   0 for global options.  */
  Elf32_Word info;              /* Kind-specific information.  */
} Elf_Options;
 
/* Values for `kind' field in Elf_Options.  */
 
#define ODK_NULL        0       /* Undefined.  */
#define ODK_REGINFO     1       /* Register usage information.  */
#define ODK_EXCEPTIONS  2       /* Exception processing options.  */
#define ODK_PAD         3       /* Section padding options.  */
#define ODK_HWPATCH     4       /* Hardware workarounds performed */

src/elf.h  view on Meta::CPAN

2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
#define R_ARM_THM_MOVW_ABS_NC   47
#define R_ARM_THM_MOVT_ABS      48
#define R_ARM_TLS_GOTDESC       90
#define R_ARM_TLS_CALL          91
#define R_ARM_TLS_DESCSEQ       92
#define R_ARM_THM_TLS_CALL      93
#define R_ARM_GNU_VTENTRY       100
#define R_ARM_GNU_VTINHERIT     101
#define R_ARM_THM_PC11          102     /* thumb unconditional branch */
#define R_ARM_THM_PC9           103     /* thumb conditional branch */
#define R_ARM_TLS_GD32          104     /* PC-rel 32 bit for global dynamic
                                           thread local data */
#define R_ARM_TLS_LDM32         105     /* PC-rel 32 bit for local dynamic
                                           thread local data */
#define R_ARM_TLS_LDO32         106     /* 32 bit offset relative to TLS
                                           block */
#define R_ARM_TLS_IE32          107     /* PC-rel 32 bit for GOT entry of
                                           static TLS block offset */
#define R_ARM_TLS_LE32          108     /* 32 bit offset relative to static
                                           TLS block */
#define R_ARM_THM_TLS_DESCSEQ   129

src/elf.h  view on Meta::CPAN

2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
#define R_MN10300_GOTOFF16      14      /* 16-bit offset from GOT.  */
#define R_MN10300_PLT32         15      /* 32-bit PCrel to PLT entry.  */
#define R_MN10300_PLT16         16      /* 16-bit PCrel to PLT entry.  */
#define R_MN10300_GOT32         17      /* 32-bit offset to GOT entry.  */
#define R_MN10300_GOT24         18      /* 24-bit offset to GOT entry.  */
#define R_MN10300_GOT16         19      /* 16-bit offset to GOT entry.  */
#define R_MN10300_COPY          20      /* Copy symbol at runtime.  */
#define R_MN10300_GLOB_DAT      21      /* Create GOT entry.  */
#define R_MN10300_JMP_SLOT      22      /* Create PLT entry.  */
#define R_MN10300_RELATIVE      23      /* Adjust by program base.  */
#define R_MN10300_TLS_GD        24      /* 32-bit offset for global dynamic.  */
#define R_MN10300_TLS_LD        25      /* 32-bit offset for local dynamic.  */
#define R_MN10300_TLS_LDO       26      /* Module-relative offset.  */
#define R_MN10300_TLS_GOTIE     27      /* GOT offset for static TLS block
                                           offset.  */
#define R_MN10300_TLS_IE        28      /* GOT address for static TLS block
                                           offset.  */
#define R_MN10300_TLS_LE        29      /* Offset relative to static TLS
                                           block.  */
#define R_MN10300_TLS_DTPMOD    30      /* ID of module containing symbol.  */
#define R_MN10300_TLS_DTPOFF    31      /* Offset in module TLS block.  */

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

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
        g(val);
    } else {
        oad(0xc481, val); /* add $xxx, %esp */
    }
}
 
static void gen_static_call(int v)
{
    Sym *sym;
 
    sym = external_global_sym(v, &func_old_type, 0);
    oad(0xe8, -4);
    greloc(cur_text_section, sym, ind-4, R_386_PC32);
}
 
/* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(int is_jmp)
{
    int r;
    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
        int rt;

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

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
    gv(RC_FLOAT);
    save_reg(TREG_EAX);
    save_reg(TREG_EDX);
    gen_static_call(TOK___tcc_cvt_ftol);
    vtop->r = TREG_EAX; /* mark reg as used */
    if (t == VT_LLONG)
        vtop->r2 = TREG_EDX;
#else
    int bt = vtop->type.t & VT_BTYPE;
    if (bt == VT_FLOAT)
        vpush_global_sym(&func_old_type, TOK___fixsfdi);
    else if (bt == VT_LDOUBLE)
        vpush_global_sym(&func_old_type, TOK___fixxfdi);
    else
        vpush_global_sym(&func_old_type, TOK___fixdfdi);
    vswap();
    gfunc_call(1);
    vpushi(0);
    vtop->r = REG_IRET;
    vtop->r2 = REG_LRET;
#endif
}
 
/* convert from one floating point type to another */
ST_FUNC void gen_cvt_ftof(int t)

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

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
    case 16: func = TOK___bound_ptr_indir16; break;
    default:
        tcc_error("unhandled size when dereferencing bounded pointer");
        func = 0;
        break;
    }
 
    /* patch relocation */
    /* XXX: find a better solution ? */
    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
    sym = external_global_sym(func, &func_old_type, 0);
    if (!sym->c)
        put_extern_sym(sym, NULL, 0, 0);
    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
}
#endif
 
/* Save the stack pointer onto the stack */
ST_FUNC void gen_vla_sp_save(int addr) {
    /* mov %esp,addr(%ebp)*/
    o(0x89);

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

1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
/* Restore the SP from a location on the stack */
ST_FUNC void gen_vla_sp_restore(int addr) {
    o(0x8b);
    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
}
 
/* Subtract from the stack pointer, and push the resulting value onto the stack */
ST_FUNC void gen_vla_alloc(CType *type, int align) {
#ifdef TCC_TARGET_PE
    /* alloca does more than just adjust %rsp on Windows */
    vpush_global_sym(&func_old_type, TOK_alloca);
    vswap(); /* Move alloca ref past allocation size */
    gfunc_call(1);
#else
    int r;
    r = gv(RC_INT); /* allocation size */
    /* sub r,%rsp */
    o(0x2b);
    o(0xe0 | r);
    /* We align to 16 bytes rather than align */
    /* and ~15, %esp */

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

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    } else {
        if (fc >= 0 && fc <= 4) {
            out_op(IL_OP_LDLOC_0 + fc);
        } else if (fc <= 0xff) {
            out_opb(IL_OP_LDLOC_S, fc);
        } else {
            out_opi(IL_OP_LDLOC, fc);
        }
    }
} else if (v == VT_CONST) {
        /* XXX: handle globals */
        out_opi(IL_OP_LDSFLD, 0);
} else {
    if ((ft & VT_BTYPE) == VT_FLOAT) {
        out_op(IL_OP_LDIND_R4);
    } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
        out_op(IL_OP_LDIND_R8);
    } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
        out_op(IL_OP_LDIND_R8);
    } else if ((ft & VT_TYPE) == VT_BYTE)
        out_op(IL_OP_LDIND_I1);

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

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
            out_op(IL_OP_LDIND_U1);
        else if ((ft & VT_TYPE) == VT_SHORT)
            out_op(IL_OP_LDIND_I2);
        else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
            out_op(IL_OP_LDIND_U2);
        else
            out_op(IL_OP_LDIND_I4);
    }
} else {
    if (v == VT_CONST) {
        /* XXX: handle globals */
        if (fc >= -1 && fc <= 8) {
            out_op(IL_OP_LDC_I4_M1 + fc + 1);
        } else {
            out_opi(IL_OP_LDC_I4, fc);
        }
    } else if (v == VT_LOCAL) {
        if (fc >= ARG_BASE) {
            fc -= ARG_BASE;
            if (fc <= 0xff) {
                out_opb(IL_OP_LDARGA_S, fc);

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

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    } else {
        if (fc >= 0 && fc <= 4) {
            out_op(IL_OP_STLOC_0 + fc);
        } else if (fc <= 0xff) {
            out_opb(IL_OP_STLOC_S, fc);
        } else {
            out_opi(IL_OP_STLOC, fc);
        }
    }
} else if (v == VT_CONST) {
    /* XXX: handle globals */
    out_opi(IL_OP_STSFLD, 0);
} else {
    if ((ft & VT_BTYPE) == VT_FLOAT)
        out_op(IL_OP_STIND_R4);
    else if ((ft & VT_BTYPE) == VT_DOUBLE)
        out_op(IL_OP_STIND_R8);
    else if ((ft & VT_BTYPE) == VT_LDOUBLE)
        out_op(IL_OP_STIND_R8);
    else if ((ft & VT_BTYPE) == VT_BYTE)
        out_op(IL_OP_STIND_I1);

src/lib/alloca-arm.S  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
        .text
        .align  2
        .global alloca
        .type   alloca, %function
alloca:
        rsb     sp, r0, sp
        bic     sp, sp, #7
        mov     r0, sp
        mov     pc, lr
        .size   alloca, .-alloca
        .section        .note.GNU-stack,"",%progbits

src/lib/alloca86-bt.S  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* ---------------------------------------------- */
/* alloca86-bt.S */
 
.globl __bound_alloca
 
__bound_alloca:
    pop     %edx
    pop     %eax
    mov     %eax, %ecx
    add     $3,%eax
    and     $-4,%eax
    jz      p6
 
#ifdef TCC_TARGET_PE

src/lib/alloca86.S  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* ---------------------------------------------- */
/* alloca86.S */
 
.globl alloca
 
alloca:
    pop     %edx
    pop     %eax
    add     $3,%eax
    and     $-4,%eax
    jz      p3
 
#ifdef TCC_TARGET_PE
p1:

src/lib/alloca86_64-bt.S  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
/* ---------------------------------------------- */
/* alloca86_64.S */
 
.globl __bound_alloca
__bound_alloca:
 
#ifdef TCC_TARGET_PE
    # bound checking is not implemented
    pop     %rdx
    mov     %rcx,%rax
    add     $15,%rax
    and     $-16,%rax
    jz      p3

src/lib/alloca86_64.S  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* ---------------------------------------------- */
/* alloca86_64.S */
 
.globl alloca
 
alloca:
    pop     %rdx
#ifdef TCC_TARGET_PE
    mov     %rcx,%rax
#else
    mov     %rdi,%rax
#endif
    add     $15,%rax
    and     $-16,%rax

src/libtcc.c  view on Meta::CPAN

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
* Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
#include "tcc.h"
 
/********************************************************/
/* global variables */
 
/* use GNU C extensions */
ST_DATA int gnu_ext = 1;
 
/* use TinyCC extensions */
ST_DATA int tcc_ext = 1;
 
/* XXX: get rid of this ASAP */
ST_DATA struct TCCState *tcc_state;

src/libtcc.c  view on Meta::CPAN

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "tccpe.c"
#endif
#endif /* ONE_SOURCE */
 
/********************************************************/
#ifndef CONFIG_TCC_ASM
ST_FUNC void asm_instr(void)
{
    tcc_error("inline asm() not supported");
}
ST_FUNC void asm_global_instr(void)
{
    tcc_error("inline asm() not supported");
}
#endif
 
/********************************************************/
#ifdef _WIN32
ST_FUNC char *normalize_slashes(char *path)
{
    char *p;

src/libtcc.c  view on Meta::CPAN

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
            tcc_serialize_extended_symtab(s1->exsymtab, s1->symtab_serialize_outfile);
        /* Output the symbol names */
        if (s1->dump_identifier_names_outfile)
            tcc_dump_identifier_names(s1->exsymtab, s1->dump_identifier_names_outfile);
    }
/* #endif */
 
    free_inline_functions(s1);
    /* reset define stack, but keep -D and built-ins */
    free_defines(define_start);
    sym_pop(&global_stack, NULL);
    sym_pop(&local_stack, NULL);
    return s1->nb_errors != 0 ? -1 : 0;
}
 
/* #ifdef CONFIG_TCC_EXSYMTAB */
LIBTCCAPI int tcc_compile_string_ex(TCCState *s, const char *str, int len, const char * filename, int line_num)
{
    int ret;
 
    /* Open the buffer and copy the contents */

src/tcc-doc.texi  view on Meta::CPAN

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
Generate a shared library instead of an executable.
 
@item -soname name
set name for shared library to be used at runtime
 
@item -static
Generate a statically linked executable (default is a shared linked
executable).
 
@item -rdynamic
Export global symbols to the dynamic linker. It is useful when a library
opened with @code{dlopen()} needs to access executable symbols.
 
@item -r
Generate an object file combining all input files.
 
@item -Wl,-rpath=path
Put custom search path for dynamic libraries into executable.
 
@item -Wl,--oformat=fmt
Use @var{fmt} as output format. The supported output formats are:

src/tcc-doc.texi  view on Meta::CPAN

716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
@cindex directives, assembler
@cindex align directive
@cindex skip directive
@cindex space directive
@cindex byte directive
@cindex word directive
@cindex short directive
@cindex int directive
@cindex long directive
@cindex quad directive
@cindex globl directive
@cindex global directive
@cindex section directive
@cindex text directive
@cindex data directive
@cindex bss directive
@cindex fill directive
@cindex org directive
@cindex previous directive
@cindex string directive
@cindex asciz directive
@cindex ascii directive

src/tcc-doc.texi  view on Meta::CPAN

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
@itemize
@item .align n[,value]
@item .skip n[,value]
@item .space n[,value]
@item .byte value1[,...]
@item .word value1[,...]
@item .short value1[,...]
@item .int value1[,...]
@item .long value1[,...]
@item .quad immediate_value1[,...]
@item .globl symbol
@item .global symbol
@item .section section
@item .text
@item .data
@item .bss
@item .fill repeat[,size[,value]]
@item .org n
@item .previous
@item .string string[,...]
@item .asciz string[,...]
@item .ascii string[,...]

src/tcc-doc.texi  view on Meta::CPAN

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
@table @asis
 
@item Invalid range with standard string function:
@example
@{
    char tab[10];
    memset(tab, 0, 11);
@}
@end example
 
@item Out of bounds-error in global or local arrays:
@example
@{
    int tab[10];
    for(i=0;i<11;i++) @{
        sum += tab[i];
    @}
@}
@end example
 
@item Out of bounds-error in malloc'ed data:

src/tcc-doc.texi  view on Meta::CPAN

904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
@node Libtcc
@chapter The @code{libtcc} library
 
The @code{libtcc} library enables you to use TCC as a backend for
dynamic code generation.
 
Read the @file{libtcc.h} to have an overview of the API. Read
@file{libtcc_test.c} to have a very simple example.
 
The idea consists in giving a C string containing the program you want
to compile directly to @code{libtcc}. Then you can access to any global
symbol (function or variable) defined.
 
@node devel
@chapter Developer's guide
 
This chapter gives some hints to understand how TCC works. You can skip
it if you do not intend to modify the TCC code.
 
@section File reading

src/tcc-doc.texi  view on Meta::CPAN

1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
Variable length array types use @code{Sym.c} as a location on the stack
which holds the runtime sizeof for the type.
 
Four main symbol stacks are defined:
 
@table @code
 
@item define_stack
for the macros (@code{#define}s).
 
@item global_stack
for the global variables, functions and types.
 
@item local_stack
for the local variables, functions and types.
 
@item global_label_stack
for the local labels (for @code{goto}).
 
@item label_stack
for GCC block local labels (see the @code{__label__} keyword).
 
@end table
 
@code{sym_push()} is used to add a new symbol in the local symbol
stack. If no local symbol stack is active, it is added in the global
symbol stack.
 
@code{sym_pop(st,b)} pops symbols from the symbol stack @var{st} until
the symbol @var{b} is on the top of stack. If @var{b} is NULL, the stack
is emptied.
 
@code{sym_find(v)} return the symbol associated to the identifier
@var{v}. The local stack is searched first from top to bottom, then the
global stack.
 
@section Sections
 
The generated code and datas are written in sections. The structure
@code{Section} contains all the necessary information for a given
section. @code{new_section()} creates a new section. ELF file semantics
is assumed for each section.
 
The following sections are predefined:

src/tcc.c  view on Meta::CPAN

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
           "  -Dsym[=val] define 'sym' with value 'val'\n"
           "  -Usym       undefine 'sym'\n"
           "  -E          preprocess only\n"
           "  -P[1]       no / alternative #line output with -E\n"
           "  -dD -dM     output #define directives with -E\n"
           "Linker options:\n"
           "  -Ldir       add library path 'dir'\n"
           "  -llib       link with dynamic or static library 'lib'\n"
           "  -pthread    link with -lpthread and -D_REENTRANT (POSIX Linux)\n"
           "  -r          generate (relocatable) object file\n"
           "  -rdynamic   export all global symbols to dynamic linker\n"
           "  -shared     generate a shared library\n"
           "  -soname     set name for shared library to be used at runtime\n"
           "  -static     static linking\n"
           "  -Wl,-opt[=val]  set linker option (see manual)\n"
           "Debugger options:\n"
           "  -g          generate runtime debug info\n"
#ifdef CONFIG_TCC_BCHECK
           "  -b          compile with built-in memory and bounds checker (implies -g)\n"
#endif
#ifdef CONFIG_TCC_BACKTRACE

src/tcc.h  view on Meta::CPAN

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
ST_FUNC void cstr_free(CString *cstr);
ST_FUNC void cstr_reset(CString *cstr);
 
ST_INLN void sym_free(Sym *sym);
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
ST_FUNC Sym *sym_find2(Sym *s, int v);
ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
ST_FUNC void sym_pop(Sym **ptop, Sym *b);
ST_INLN Sym *struct_find(int v);
ST_INLN Sym *sym_find(int v);
ST_FUNC Sym *global_identifier_push(int v, int t, int c);
 
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
ST_FUNC int tcc_open(TCCState *s1, const char *filename);
ST_FUNC void tcc_close(void);
 
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
/* flags: */
#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
#define AFF_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
#define AFF_PREPROCESS      0x40 /* preprocess file */

src/tcc.h  view on Meta::CPAN

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
}
 
/* ------------ tccgen.c ------------ */
 
#define SYM_POOL_NB (8192 / sizeof(Sym))
ST_DATA Sym *sym_free_first;
ST_DATA void **sym_pools;
ST_DATA int nb_sym_pools;
 
ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack;
ST_DATA Sym *local_label_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *define_stack;
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
#define vstack  (__vstack + 1)
ST_DATA int rsym, anon_sym, ind, loc;
 
ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic */
ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname;
 
ST_FUNC void tccgen_start(TCCState *s1);
ST_FUNC void tccgen_end(TCCState *s1);
ST_FUNC void free_inline_functions(TCCState *s);
ST_FUNC void check_vstack(void);
 
ST_INLN int is_float(int t);
ST_FUNC int ieee_finite(double d);
ST_FUNC void test_lvalue(void);
ST_FUNC void swap(int *p, int *q);
ST_FUNC void vpushi(int v);
ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
ST_FUNC void vset(CType *type, int r, int v);
ST_FUNC void vswap(void);
ST_FUNC void vpush_global_sym(CType *type, int v);
ST_FUNC void vrote(SValue *e, int n);
ST_FUNC void vrott(int n);
ST_FUNC void vrotb(int n);
#ifdef TCC_TARGET_ARM
ST_FUNC int get_reg_ex(int rc, int rc2);
ST_FUNC void lexpand_nr(void);
#endif
ST_FUNC void vpushv(SValue *v);
ST_FUNC void save_reg(int r);
ST_FUNC void save_reg_upstack(int r, int n);

src/tcc.h  view on Meta::CPAN

1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
    unsigned int n_value;        /* value of symbol */
} Stab_Sym;
 
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
ST_DATA Section *cur_text_section; /* current section where function code is generated */
#ifdef CONFIG_TCC_ASM
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
#endif
#ifdef CONFIG_TCC_BCHECK
/* bound check related sections */
ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */
ST_FUNC void tccelf_bounds_new(TCCState *s);
#endif
/* symbol sections */
ST_DATA Section *symtab_section, *strtab_section;
/* debug sections */
ST_DATA Section *stab_section, *stabstr_section;
 
ST_FUNC void tccelf_new(TCCState *s);
ST_FUNC void tccelf_delete(TCCState *s);

src/tcc.h  view on Meta::CPAN

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
/* ------------ tcccoff.c ------------ */
 
#ifdef TCC_TARGET_COFF
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
#endif
 
/* ------------ tccasm.c ------------ */
ST_FUNC void asm_instr(void);
ST_FUNC void asm_global_instr(void);
#ifdef CONFIG_TCC_ASM
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
ST_FUNC int asm_int_expr(TCCState *s1);
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
/* ------------ i386-asm.c ------------ */
ST_FUNC void gen_expr32(ExprValue *pe);
ST_FUNC void asm_opcode(TCCState *s1, int opcode);
ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);

src/tccasm.c  view on Meta::CPAN

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    sym_dot.r = cur_text_section->sh_num;
    sym_dot.jnext = ind;
    next();
    break;
default:
    if (tok >= TOK_IDENT) {
        /* label case : if the label was not found, add one */
        sym = label_find(tok);
        if (!sym) {
            sym = label_push(&s1->asm_labels, tok, 0);
            /* NOTE: by default, the symbol is global */
            sym->type.t = VT_VOID;
        }
        if (sym->r == SHN_ABS) {
            /* if absolute symbol, no need to put a symbol value */
            pe->v = sym->jnext;
            pe->sym = NULL;
        } else {
            pe->v = 0;
            pe->sym = sym;
        }

src/tccasm.c  view on Meta::CPAN

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
        next();
        /* XXX: handle section symbols too */
        n = asm_int_expr(s1);
        if (n < ind)
            tcc_error("attempt to .org backwards");
        v = 0;
        size = n - ind;
        goto zero_pad;
    }
    break;
case TOK_ASMDIR_globl:
case TOK_ASMDIR_global:
case TOK_ASMDIR_weak:
case TOK_ASMDIR_hidden:
tok1 = tok;
    do {
        Sym *sym;
 
        next();
        sym = label_find(tok);
        if (!sym) {
            sym = label_push(&s1->asm_labels, tok, 0);

src/tccasm.c  view on Meta::CPAN

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
    asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
    next();
    skip(':');
    goto redo;
} else if (tok >= TOK_IDENT) {
    /* instruction or label */
    opcode = tok;
    next();
    if (tok == ':') {
        /* handle "extern void vide(void); __asm__("vide: ret");" as
        "__asm__("globl vide\nvide: ret");" */
        Sym *sym = sym_find(opcode);
        if (sym && (sym->type.t & VT_EXTERN) && nocode_wanted) {
            sym = label_find(opcode);
            if (!sym) {
                sym = label_push(&s1->asm_labels, opcode, 0);
                sym->type.t = VT_VOID;
            }
        }
        /* new label */
        asm_new_label(s1, opcode, 0);

src/tccasm.c  view on Meta::CPAN

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
    /* free everything */
    for(i=0;i<nb_operands;i++) {
        ASMOperand *op;
        op = &operands[i];
        tcc_free(op->constraint);
        vpop();
    }
    cstr_free(&astr1);
}
 
ST_FUNC void asm_global_instr(void)
{
    CString astr;
 
    next();
    parse_asm_str(&astr);
    skip(')');
    /* NOTE: we do not eat the ';' so that we can restore the current
       token after the assembler parsing */
    if (tok != ';')
        expect("';'");
     
#ifdef ASM_DEBUG
    printf("asm_global: \"%s\"\n", (char *)astr.data);
#endif
    cur_text_section = text_section;
    ind = cur_text_section->data_offset;
 
    /* assemble the string with tcc internal assembler */
    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
     
    cur_text_section->data_offset = ind;
 
    /* restore the current C token */

src/tcccoff.c  view on Meta::CPAN

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
        // put relocations data
        if (coff_sec->s_nreloc > 0) {
            fwrite(tcc_sect->reloc,
                   coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
        }
    }
}
 
 
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
 
if (s1->do_debug)
    SortSymbolTable();
 
// write line no data
 
for (i = 1; i < s1->nb_sections; i++) {
    coff_sec = &section_header[i];
    tcc_sect = s1->sections[i];

src/tcccoff.c  view on Meta::CPAN

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
        tcc_free(Coff_str_table);
    }
 
    return 0;
}
 
 
 
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
 
void SortSymbolTable(void)
{
    int i, j, k, n = 0;
    Elf32_Sym *p, *p2, *NewTable;
    char *name, *name2;
 
    NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
 
    p = (Elf32_Sym *) symtab_section->data;

src/tccelf.c  view on Meta::CPAN

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
* License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
#include "tcc.h"
 
/* Define this to get some debug output during relocation processing.  */
#undef DEBUG_RELOC
 
/********************************************************/
/* global variables */
 
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
ST_DATA Section *cur_text_section; /* current section where function code is generated */
#ifdef CONFIG_TCC_ASM
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
#endif
#ifdef CONFIG_TCC_BCHECK
/* bound check related sections */
ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */
#endif
/* symbol sections */
ST_DATA Section *symtab_section, *strtab_section;
/* debug sections */
ST_DATA Section *stab_section, *stabstr_section;
 
/* XXX: avoid static variable */
static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */

src/tccelf.c  view on Meta::CPAN

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
    sym->st_size = size;
    sym->st_info = info;
    sym->st_other = other;
    sym->st_shndx = shndx;
    sym_index = sym - (ElfW(Sym) *)s->data;
    hs = s->hash;
    if (hs) {
        int *ptr, *base;
        ptr = section_ptr_add(hs, sizeof(int));
        base = (int *)hs->data;
        /* only add global or weak symbols */
        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
            /* add another hashing entry */
            nbuckets = base[0];
            h = elf_hash((unsigned char *) name) % nbuckets;
            *ptr = base[2 + h];
            base[2 + h] = sym_index;
            base[1]++;
            /* we resize the hash table */
            hs->nb_hashed_syms++;
            if (hs->nb_hashed_syms > 2 * nbuckets) {
                rebuild_hash(s, 2 * nbuckets);
            }
        } else {
            *ptr = 0;
            base[1]++;
        }
    }
    return sym_index;
}
 
/* find global ELF symbol 'name' and return its index. Return 0 if not
   found. */
ST_FUNC int find_elf_sym(Section *s, const char *name)
{
    ElfW(Sym) *sym;
    Section *hs;
    int nbuckets, sym_index, h;
    const char *name1;
 
    hs = s->hash;
    if (!hs)

src/tccelf.c  view on Meta::CPAN

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
{
    ElfW(Sym) *esym;
    int sym_bind, sym_index, sym_type, esym_bind;
    unsigned char sym_vis, esym_vis, new_vis;
 
    sym_bind = ELFW(ST_BIND)(info);
    sym_type = ELFW(ST_TYPE)(info);
    sym_vis = ELFW(ST_VISIBILITY)(other);
 
    if (sym_bind != STB_LOCAL) {
        /* we search global or weak symbols */
        sym_index = find_elf_sym(s, name);
        if (!sym_index)
            goto do_def;
        esym = &((ElfW(Sym) *)s->data)[sym_index];
        if (esym->st_shndx != SHN_UNDEF) {
            esym_bind = ELFW(ST_BIND)(esym->st_info);
            /* propagate the most constraining visibility */
            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
            esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
            if (esym_vis == STV_DEFAULT) {

src/tccelf.c  view on Meta::CPAN

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
} else {
    new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
}
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
                 | new_vis;
other = esym->st_other; /* in case we have to patch esym */
if (sh_num == SHN_UNDEF) {
    /* ignore adding of undefined symbol if the
       corresponding symbol is already defined */
} else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
    /* global overrides weak, so patch */
    goto do_patch;
} else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
    /* weak is ignored if already global */
} else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
    /* keep first-found weak definition, ignore subsequents */
} else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
    /* ignore hidden symbols after */
} else if ((esym->st_shndx == SHN_COMMON
                || esym->st_shndx == bss_section->sh_num)
            && (sh_num < SHN_LORESERVE
                && sh_num != bss_section->sh_num)) {
    /* data symbol gets precedence over common/bss */
    goto do_patch;

src/tccelf.c  view on Meta::CPAN

537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    put_stabs(NULL, type, other, desc, 0);
}
 
/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
   using variable <elem> */
#define for_each_elem(sec, startoff, elem, type) \
    for (elem = (type *) sec->data + startoff; \
         elem < (type *) (sec->data + sec->data_offset); elem++)
 
/* In an ELF file symbol table, the local symbols must appear below
   the global and weak ones. Since TCC cannot sort it while generating
   the code, we must do it after. All the relocation tables are also
   modified to take into account the symbol table sorting */
static void sort_syms(TCCState *s1, Section *s)
{
    int *old_to_new_syms;
    ElfW(Sym) *new_syms;
    int nb_syms, i;
    ElfW(Sym) *p, *q;
    ElfW_Rel *rel;
    Section *sr;

src/tccelf.c  view on Meta::CPAN

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
                            sym->st_info, 0, sym->st_shndx, name);
        } else if (esym->st_shndx == SHN_UNDEF) {
            /* weak symbols can stay undefined */
            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
                tcc_warning("undefined dynamic symbol '%s'", name);
        }
    }
}
 
/* Export all non local symbols (for shared libraries) */
static void export_global_syms(TCCState *s1)
{
    int nb_syms, dynindex, index;
    const char *name;
    ElfW(Sym) *sym;
 
    nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
    s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
            name = (char *) symtab_section->link->data + sym->st_name;

src/tccelf.c  view on Meta::CPAN

2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
if (file_type == TCC_OUTPUT_EXE) {
    bind_exe_dynsyms(s1);
 
    if (s1->nb_errors) {
        ret = -1;
        goto the_end;
    }
 
    bind_libs_dynsyms(s1);
} else /* shared library case: simply export all global symbols */
    export_global_syms(s1);
 
build_got_entries(s1);
 
/* add a list of needed dlls */
for(i = 0; i < s1->nb_loaded_dlls; i++) {
    DLLReference *dllref = s1->loaded_dlls[i];
    if (dllref->level == 0)
        put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
}

src/tccexsymtab.c  view on Meta::CPAN

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
        if (curr_sym->type.t & VT_CONSTANT) fprintf(out_fh, "constant ");
 
        /* type */
        btype = curr_sym->type.t & VT_BTYPE;
        fprintf(out_fh, "%s\n", type_lookup_table[btype]);
    }
    fclose(out_fh);
}
 
/* tcc_get_next_extended_symbol_name: a simple mechanism for getting the names
 * of all of the global symbols known to the extended symbol table. */
 
char * tcc_get_next_extended_symbol_name(extended_symtab * symtab, int * poffset)
{
    /* Increment the counter to get to the next TokenSym */
    for ((*poffset)++; symtab->tokenSym_list + *poffset < symtab->tokenSym_last; (*poffset)++)
    {
        TokenSym * ts = symtab->tokenSym_list[*poffset];
        if (ts->sym_identifier) return ts->str;
    }

src/tccexsymtab.c  view on Meta::CPAN

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
Sym * get_new_symtab_pointer (Sym * old, ram_hash * rh)
{
    void ** Sym_ref;
    Sym * to_return;
    int btype;
 
    /* Handle the null case up-front */
    if (old == NULL) return NULL;
 
    /* Check the global symbol stack. */
    Sym_ref = ram_hash_get_ref(rh, old);
    to_return = *Sym_ref;
    if (NULL != to_return) return to_return;
 
    /* Create new sym. Note that mallocz sets lots of things to null
     * for me. :-) */
    to_return = *Sym_ref = tcc_mallocz(sizeof(Sym));
 
    /* See tcc.h around line 425 for descriptions of some of the fields.
     * See also tccgen.c line 5987 to see what needs to happen for function

src/tccexsymtab.c  view on Meta::CPAN

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
to_return->r = old->r;
 
/* Set the type. Judging by the constants in tcc.h and code that
 * uses this field, I'm pretty sure that the low bits in the .t field
 * tells tcc how to load the data into a register. The high bits seem to
 * indicate storage details, such as VT_EXTERN. Since that is not
 * something that can be extended at runtime, I should be able to copy
 * the value as-is and add an extern flag for variables and functions. */
to_return->type.t = old->type.t;
 
/* After compilation, functions and global variables point to hard
 * locations in memory. Consuming contexts should think of these as
 * having external storage, which is reflected in the VT_EXTERN bit of
 * the type.t field. */
btype = old->type.t & VT_BTYPE;
if (btype == VT_FUNC || to_return->r & (VT_SYM | VT_LVAL))
    to_return->type.t |= VT_EXTERN;
 
/* Remove static indicator from functions */
if ((btype == VT_FUNC) && (old->type.t & VT_STATIC))
    to_return->type.t &= ~VT_STATIC;

src/tccexsymtab.c  view on Meta::CPAN

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
/* Copy the c field, the "associated number." According to tcc-doc.texi
 * as well as the comments just above the definition of put_extern_sym2,
 * the c field will (for some Syms) point to an external symbol in an
 * associated section. But this is not true for all Syms. For structs,
 * this is the size (in bytes), and for struct members it is the byte
 * offset of the member, according to the end of struct_decl(). For
 * variable length arrays, this is "the location on the stack that holds
 * the runtime sizeof for the type." For functions, I believe this is
 * one of FUNC_NEW, FUNC_OLD, or FUNC_ELLIPSIS. At any rate, everything
 * seems to work if I simply set it to zero for functions and global
 * variables and copy it otherwise, so I'm going with that. This probably
 * needs to be more nuanced. */
if (btype == VT_FUNC || to_return->r & (VT_SYM | VT_LVAL))
    to_return->c = 0;
else
    to_return->c = old->c;
 
/* Copy the next symbol field. Labels and gotos are tracked in a
 * separate stack, so for these Symbols we focus on next, not
 * jnext. The next field (I seem to recall) is used in storing

src/tccgen.c  view on Meta::CPAN

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
* Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
#include "tcc.h"
 
/********************************************************/
/* global variables */
 
/* loc : local variable index
   ind : output code index
   rsym: return symbol
   anon_sym: anonymous symbol index
*/
ST_DATA int rsym, anon_sym, ind, loc;
 
ST_DATA Sym *sym_free_first;
ST_DATA void **sym_pools;
ST_DATA int nb_sym_pools;
 
ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack;
ST_DATA Sym *define_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *local_label_stack;
static int local_scope;
static int in_sizeof;
static int section_sym;
 
ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
 
ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
 
ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname;
 
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
 
ST_DATA struct switch_t {
    struct case_t {

src/tccgen.c  view on Meta::CPAN

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
    if (local_stack)
        ps = &local_stack;
    else {
/* #ifdef CONFIG_TCC_EXSYMTAB */
        /* Global symbol stack. This is OK for the local symbol stack, but don't allow
         * this for symbols that are in the extended symbol stack. There seem to be
         * some issues associated with copying *all* TokenSyms, so this needs to be
         * ironed out. For now, I'm removing the check. */
         //
         // if (v & SYM_EXTENDED) {
         //     tcc_error("Cannot use name '%s' as a global variable, it is already in the "
         //               "extended symbol table.", get_tok_str(v, 0));
         // }
/* #endif */
        ps = &global_stack;
    }
/* #ifdef CONFIG_TCC_EXSYMTAB */
    v &= ~SYM_EXTENDED;
/* #endif */
    s = sym_push2(ps, v, type->t, c);
    s->type.ref = type->ref;
    s->r = r;
    /* don't record fields or anonymous symbols */
    /* XXX: simplify */
    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {

src/tccgen.c  view on Meta::CPAN

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
        s->prev_tok = *ps;
        *ps = s;
        s->scope = local_scope;
        if (s->prev_tok && s->prev_tok->scope == s->scope)
            tcc_error("redeclaration of '%s'",
                get_tok_str(v & ~SYM_STRUCT, NULL));
    }
    return s;
}
 
/* push a global identifier */
ST_FUNC Sym *global_identifier_push(int v, int t, int c)
{
    Sym *s, **ps;
    s = sym_push2(&global_stack, v, t, c);
    /* don't record anonymous symbol */
/* #ifdef CONFIG_TCC_EXSYMTAB */
    if ((v & ~SYM_EXTENDED) < SYM_FIRST_ANOM) {
        ps = &table_ident[(v & ~SYM_EXTENDED) - TOK_IDENT]->sym_identifier;
/* #else
    if (v < SYM_FIRST_ANOM) {
        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
#endif */
        /* modify the top most local identifier, so that
           sym_identifier will point to 's' when popped */
        while (*ps != NULL)
            ps = &(*ps)->prev_tok;
        s->prev_tok = NULL;
        *ps = s;
    }
/* #ifdef CONFIG_TCC_EXSYMTAB */
    if (v & SYM_EXTENDED) {
        tcc_warning("pushing global identifier with name from extended symbol table '%s'",
               get_tok_str(v, 0));
    }
/* #endif */
    return s;
}
 
/* pop symbols until top reaches 'b' */
ST_FUNC void sym_pop(Sym **ptop, Sym *b)
{
    Sym *s, *ss, **ps;

src/tccgen.c  view on Meta::CPAN

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
    vtop->sym = sym;
}
 
/* Return a static symbol pointing to a section */
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{
    int v;
    Sym *sym;
 
    v = anon_sym++;
    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
    sym->type.ref = type->ref;
    sym->r = VT_CONST | VT_SYM;
    put_extern_sym(sym, sec, offset, size);
    return sym;
}
 
/* push a reference to a section offset by adding a dummy symbol */
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{
    vpushsym(type, get_sym_ref(type, sec, offset, size)); 
}
 
/* define a new external reference to a symbol 'v' of type 'u' */
ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
{
    Sym *s;
 
    s = sym_find(v);
    if (!s) {
        /* push forward reference */
        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
        s->type.ref = type->ref;
        s->r = r | VT_CONST | VT_SYM;
    }
    return s;
}
 
/* define a new external reference to a symbol 'v' */
static Sym *external_sym(int v, CType *type, int r)
{
    Sym *s;

src/tccgen.c  view on Meta::CPAN

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
    /* Merge some storage attributes.  */
    if (type->t & VT_WEAK)
        weaken_symbol(s);
 
    if (type->t & VT_VIS_MASK)
        apply_visibility(s, type);
 
    return s;
}
 
/* push a reference to global symbol v */
ST_FUNC void vpush_global_sym(CType *type, int v)
{
    vpushsym(type, external_global_sym(v, type, 0));
}
 
ST_FUNC void vset(CType *type, int r, int v)
{
    CValue cval;
 
    cval.i = v;
    vsetc(type, r, &cval);
}

src/tccgen.c  view on Meta::CPAN

1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
        goto gen_mod_func;
    case TOK_UMOD:
        func = TOK___umoddi3;
    gen_mod_func:
#ifdef TCC_ARM_EABI
        reg_iret = TREG_R2;
        reg_lret = TREG_R3;
#endif
    gen_func:
        /* call generic long long function */
        vpush_global_sym(&func_old_type, func);
        vrott(3);
        gfunc_call(2);
        vpushi(0);
        vtop->r = reg_iret;
        vtop->r2 = reg_lret;
        break;
    case '^':
    case '&':
    case '|':
    case '*':

src/tccgen.c  view on Meta::CPAN

2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
/* generic itof for unsigned long long case */
static void gen_cvt_itof1(int t)
{
#ifdef TCC_TARGET_ARM64
    gen_cvt_itof(t);
#else
    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
        (VT_LLONG | VT_UNSIGNED)) {
 
        if (t == VT_FLOAT)
            vpush_global_sym(&func_old_type, TOK___floatundisf);
#if LDOUBLE_SIZE != 8
        else if (t == VT_LDOUBLE)
            vpush_global_sym(&func_old_type, TOK___floatundixf);
#endif
        else
            vpush_global_sym(&func_old_type, TOK___floatundidf);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->r = reg_fret(t);
    } else {
        gen_cvt_itof(t);
    }
#endif
}
#endif

src/tccgen.c  view on Meta::CPAN

2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
{
#ifdef TCC_TARGET_ARM64
    gen_cvt_ftoi(t);
#else
    int st;
 
    if (t == (VT_LLONG | VT_UNSIGNED)) {
        /* not handled natively */
        st = vtop->type.t & VT_BTYPE;
        if (st == VT_FLOAT)
            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
#if LDOUBLE_SIZE != 8
        else if (st == VT_LDOUBLE)
            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
#endif
        else
            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->r = REG_IRET;
        vtop->r2 = REG_LRET;
    } else {
        gen_cvt_ftoi(t);
    }
#endif
}

src/tccgen.c  view on Meta::CPAN

2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
            size = type_size(&vtop->type, &align);
 
            /* destination */
            vswap();
            vtop->type.t = VT_PTR;
            gaddrof();
 
            /* address of memcpy() */
#ifdef TCC_ARM_EABI
            if(!(align & 7))
                vpush_global_sym(&func_old_type, TOK_memcpy8);
            else if(!(align & 3))
                vpush_global_sym(&func_old_type, TOK_memcpy4);
            else
#endif
            /* Use memmove, rather than memcpy, as dest and src may be same: */
            vpush_global_sym(&func_old_type, TOK_memmove);
 
            vswap();
            /* source */
            vpushv(vtop - 2);
            vtop->type.t = VT_PTR;
            gaddrof();
            /* type size */
            vpushi(size);
            gfunc_call(3);
        } else {

src/tccgen.c  view on Meta::CPAN

4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
    break;
case '(':
    next();
    /* cast ? */
    if (parse_btype(&type, &ad)) {
        type_decl(&type, &ad, &n, TYPE_ABSTRACT);
        skip(')');
        /* check ISOC99 compound literal */
        if (tok == '{') {
                /* data is allocated locally by default */
            if (global_expr)
                r = VT_CONST;
            else
                r = VT_LOCAL;
            /* all except arrays are lvalues */
            if (!(type.t & VT_ARRAY))
                r |= lvalue_type(type.t);
            memset(&ad, 0, sizeof(AttributeDef));
            decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
        } else {
            if (sizeof_caller) {

src/tccgen.c  view on Meta::CPAN

4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
            skip(')');
            vpushi(classify_x86_64_va_arg(&type));
        }
        break;
#endif
#endif
 
#ifdef TCC_TARGET_ARM64
    case TOK___va_start: {
        if (nocode_wanted)
            tcc_error("statement in global scope");
        next();
        skip('(');
        expr_eq();
        skip(',');
        expr_eq();
        skip(')');
        //xx check types
        gen_va_start();
        vpushi(0);
        vtop->type.t = VT_VOID;
        break;
    }
    case TOK___va_arg: {
        CType type;
        if (nocode_wanted)
            tcc_error("statement in global scope");
        next();
        skip('(');
        expr_eq();
        skip(',');
        parse_type(&type);
        skip(')');
        //xx check types
        gen_va_arg(&type);
        vtop->type = type;
        break;

src/tccgen.c  view on Meta::CPAN

4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
    break;
case TOK_LAND:
    if (!gnu_ext)
        goto tok_identifier;
    next();
    /* allow to take the address of a label */
    if (tok < TOK_UIDENT)
        expect("label identifier");
    s = label_find(tok);
    if (!s) {
        s = label_push(&global_label_stack, tok, LABEL_FORWARD);
    } else {
        if (s->r == LABEL_DECLARED)
            s->r = LABEL_FORWARD;
    }
    if (!s->type.t) {
        s->type.t = VT_VOID;
        mk_pointer(&s->type);
        s->type.t |= VT_STATIC;
    }
    vpushsym(&s->type, s);

src/tccgen.c  view on Meta::CPAN

4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
            /* for simple function calls, we tolerate undeclared
               external reference to int() function */
            if (tcc_state->warn_implicit_function_declaration
#ifdef TCC_TARGET_PE
                /* people must be warned about using undeclared WINAPI functions
                   (which usually start with uppercase letter) */
                || (name[0] >= 'A' && name[0] <= 'Z')
#endif
            )
                tcc_warning("implicit declaration of function '%s'", name);
            s = external_global_sym(t, &func_old_type, 0);
        }
        if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
            (VT_STATIC | VT_INLINE | VT_FUNC)) {
            /* if referencing an inline function, then we generate a
               symbol to it if not already done. It will have the
               effect to generate code for it at the end of the
               compilation unit. Inline function as always
               generated in the text section. */
            if (!s->c)
                put_extern_sym(s, text_section, 0, 0);

src/tccgen.c  view on Meta::CPAN

5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
    /* computed goto */
    next();
    gexpr();
    if ((vtop->type.t & VT_BTYPE) != VT_PTR)
        expect("pointer");
    ggoto();
} else if (tok >= TOK_UIDENT) {
    s = label_find(tok);
    /* put forward definition if needed */
    if (!s) {
        s = label_push(&global_label_stack, tok, LABEL_FORWARD);
    } else {
        if (s->r == LABEL_DECLARED)
            s->r = LABEL_FORWARD;
    }
    vla_sp_restore_root();
    if (s->r & LABEL_FORWARD)
        s->jnext = gjmp(s->jnext);
    else
        gjmp_addr(s->jnext);
    next();

src/tccgen.c  view on Meta::CPAN

5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
b = is_label();
if (b) {
    /* label case */
    s = label_find(b);
    if (s) {
        if (s->r == LABEL_DEFINED)
            tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
        gsym(s->jnext);
        s->r = LABEL_DEFINED;
    } else {
        s = label_push(&global_label_stack, b, LABEL_DEFINED);
    }
    s->jnext = ind;
    vla_sp_restore();
    /* we accept this, but it is a mistake */
block_after_label:
    if (tok == '}') {
        tcc_warning("deprecated use of label at end of compound statement");
    } else {
        if (is_expr)
            vpop();

src/tccgen.c  view on Meta::CPAN

5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
            dst += elem_size;
            memcpy(dst, src, elem_size);
        }
    }
}
 
#define EXPR_VAL   0
#define EXPR_CONST 1
#define EXPR_ANY   2
 
/* store a value or an expression directly in global data or in local array */
static void init_putv(CType *type, Section *sec, unsigned long c,
                      int v, int expr_type)
{
    int saved_global_expr, bt, bit_pos, bit_size;
    void *ptr;
    unsigned long long bit_mask;
    CType dtype;
 
    switch(expr_type) {
    case EXPR_VAL:
        vpushi(v);
        break;
    case EXPR_CONST:
        /* compound literals must be allocated globally in this case */
        saved_global_expr = global_expr;
        global_expr = 1;
        expr_const1();
        global_expr = saved_global_expr;
        /* NOTE: symbols are accepted */
        if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
            tcc_error("initializer element is not constant");
        break;
    case EXPR_ANY:
        expr_eq();
        break;
    }
     
    dtype = *type;

src/tccgen.c  view on Meta::CPAN

5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
        vswap();
        vstore();
        vpop();
    }
}
 
/* put zeros for variable based init */
static void init_putz(CType *t, Section *sec, unsigned long c, int size)
{
    if (sec) {
        /* nothing to do because globals are already set to zero */
    } else {
        vpush_global_sym(&func_old_type, TOK_memset);
        vseti(VT_LOCAL, c);
#ifdef TCC_TARGET_ARM
        vpushs(size);
        vpushi(0);
#else
        vpushi(0);
        vpushs(size);
#endif
        gfunc_call(3);
    }

src/tccgen.c  view on Meta::CPAN

6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
else
    cstr_len = tokc.str.size / sizeof(nwchar_t);
cstr_len--;
nb = cstr_len;
if (n >= 0 && nb > (n - array_length))
    nb = n - array_length;
if (!size_only) {
    if (cstr_len > nb)
        tcc_warning("initializer-string for array is too long");
    /* in order to go faster for common case (char
       string in global variable, we handle it
       specifically */
    if (sec && tok == TOK_STR && size1 == 1) {
        memcpy(sec->data + c + array_length, tokc.str.data, nb);
    } else {
        for(i=0;i<nb;i++) {
            if (tok == TOK_STR)
                ch = ((unsigned char *)tokc.str.data)[i];
            else
                ch = ((nwchar_t *)tokc.str.data)[i];
            init_putv(t1, sec, c + (array_length + i) * size1,

src/tccgen.c  view on Meta::CPAN

6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
            else if (tok == '{')
                parlevel1++;
            else if (tok == '}') {
                if (parlevel == 0 && parlevel1 == 0)
                    break;
                parlevel1--;
            }
            next();
        }
    } else {
        /* currently, we always use constant expression for globals
           (may change for scripting case) */
        expr_type = EXPR_CONST;
        if (!sec)
            expr_type = EXPR_ANY;
        init_putv(type, sec, c, 0, expr_type);
    }
}
 
/* parse an initializer for type 't' if 'has_init' is non zero, and
   allocate space in local or global data space ('r' is either
   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
   variable 'v' of scope 'scope' is declared before initializers
   are parsed. If 'v' is zero, then a reference to the new object
   is put in the value stack. If 'has_init' is 2, a special parsing
   is done to handle string constants. */
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
                                   int has_init, int v, int scope)
{
    int size, align, addr, data_offset;
    int level;

src/tccgen.c  view on Meta::CPAN

6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
        while (field->next)
            field = field->next;
        if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
            flexible_array = field;
    }
}
 
size = type_size(type, &align);
/* If unknown size, we must evaluate it before
   evaluating initializers because
   initializers can generate global data too
   (e.g. string pointers or ISOC99 compound
   literals). It also simplifies local
   initializers handling */
if (size < 0 || (flexible_array && has_init)) {
    if (!has_init)
        tcc_error("unknown type size");
    /* get all init string */
    init_str = tok_str_alloc();
    if (has_init == 2) {
        /* only get strings */

src/tccgen.c  view on Meta::CPAN

6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
            /* if the variable is extern, it was not allocated */
            sym->type.t &= ~VT_EXTERN;
            /* set array size if it was omitted in extern
               declaration */
            if ((sym->type.t & VT_ARRAY) &&
                sym->type.ref->c < 0 &&
                type->ref->c >= 0)
                sym->type.ref->c = type->ref->c;
        } else {
            /* we accept several definitions of the same
               global variable. this is tricky, because we
               must play with the SHN_COMMON type of the symbol */
            /* XXX: should check if the variable was already
               initialized. It is incorrect to initialized it
               twice */
            /* no init data, we won't add more to the symbol */
            if (!has_init)
                goto no_alloc;
        }
    }
}

src/tccgen.c  view on Meta::CPAN

6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
        if (!sec) {
            if (has_init)
                sec = data_section;
            else if (tcc_state->nocommon)
                sec = bss_section;
        }
        if (sec) {
            data_offset = sec->data_offset;
            data_offset = (data_offset + align - 1) & -align;
            addr = data_offset;
            /* very important to increment global pointer at this time
               because initializers themselves can create new initializers */
            data_offset += size;
#ifdef CONFIG_TCC_BCHECK
            /* add padding if bound check */
            if (tcc_state->do_bounds_check)
                data_offset++;
#endif
            sec->data_offset = data_offset;
            /* allocate section space to put the data */
            if (sec->sh_type != SHT_NOBITS &&

src/tccgen.c  view on Meta::CPAN

6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
                put_extern_sym(sym, sec, addr, size);
            } else {
                ElfW(Sym) *esym;
                /* put a common area */
                put_extern_sym(sym, NULL, align, size);
                /* XXX: find a nicer way */
                esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
                esym->st_shndx = SHN_COMMON;
            }
        } else {
            /* push global reference */
            sym = get_sym_ref(type, sec, addr, size);
            vpushsym(type, sym);
        }
        /* patch symbol weakness */
        if (type->t & VT_WEAK)
            weaken_symbol(sym);
        apply_visibility(sym, type);
#ifdef CONFIG_TCC_BCHECK
        /* handles bounds now because the symbol must be defined
           before for the relocation */
        if (tcc_state->do_bounds_check) {
            addr_t *bounds_ptr;
 
            greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
            /* then add global bound info */
            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
            bounds_ptr[0] = 0; /* relocated */
            bounds_ptr[1] = size;
        }
#endif
    }
    if (has_init || (type->t & VT_VLA)) {
        decl_initializer(type, sec, addr, 1, 0);
        /* patch flexible array member size back to -1, */
        /* for possible subsequent similar declarations */

src/tccgen.c  view on Meta::CPAN

6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
sym_push2(&local_stack, SYM_FIELD, 0, 0);
local_scope = 1; /* for function parameters */
gfunc_prolog(&sym->type);
local_scope = 0;
 
rsym = 0;
block(NULL, NULL, 0);
gsym(rsym);
gfunc_epilog();
cur_text_section->data_offset = ind;
label_pop(&global_label_stack, NULL);
/* reset local stack */
local_scope = 0;
sym_pop(&local_stack, NULL);
/* end of function */
/* patch symbol size */
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
    ind - func_ind;
/* patch symbol weakness (this definition overrules any prototype) */
if (sym->type.t & VT_WEAK)
    weaken_symbol(sym);

src/tccgen.c  view on Meta::CPAN

6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
    if (is_for_loop_init)
        return 0;
    /* skip redundant ';' */
    /* XXX: find more elegant solution */
    if (tok == ';') {
        next();
        continue;
    }
    if (l == VT_CONST &&
        (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
        /* global asm block */
        asm_global_instr();
        continue;
    }
    /* special test for old K&R protos without explicit int
       type. Only accepted when defining global data */
    if (l == VT_LOCAL || tok < TOK_UIDENT)
        break;
    btype.t = VT_INT;
}
if (((btype.t & VT_BTYPE) == VT_ENUM ||
     (btype.t & VT_BTYPE) == VT_STRUCT) &&
    tok == ';') {
    if ((btype.t & VT_BTYPE) == VT_STRUCT) {
        int v = btype.ref->v;
        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)

src/tccgen.c  view on Meta::CPAN

6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
    if (!is_compatible_types(&sym->type, &type)) {
    func_error1:
        tcc_error("incompatible types for redefinition of '%s'",
              get_tok_str(v, NULL));
    }
    type.ref->a.func_proto = 0;
    /* if symbol is already defined, then put complete type */
    sym->type = type;
} else {
    /* put function symbol */
    sym = global_identifier_push(v, type.t, 0);
    sym->type.ref = type.ref;
}
 
/* static inline functions are just recorded as a kind
   of macro. Their code will be emitted at the end of
   the compilation unit only if they are used */
if ((type.t & (VT_INLINE | VT_STATIC)) ==
    (VT_INLINE | VT_STATIC)) {
    int block_level;
    struct InlineFunc *fn;

src/tccgen.c  view on Meta::CPAN

6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
    /* not lvalue if array */
    r |= lvalue_type(type.t);
}
has_init = (tok == '=');
if (has_init && (type.t & VT_VLA))
    tcc_error("Variable length array cannot be initialized");
if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
    ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
     !has_init && l == VT_CONST && type.ref->c < 0)) {
    /* external variable or function */
    /* NOTE: as GCC, uninitialized global static
       arrays of null size are considered as
       extern */
    sym = external_sym(v, &type, r);
    sym->asm_label = ad.asm_label;
 
    if (ad.alias_target) {
        Section tsec;
        Elf32_Sym *esym;
        Sym *alias_target;

src/tccpp.c  view on Meta::CPAN

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
* Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
#include "tcc.h"
 
/********************************************************/
/* global variables */
 
ST_DATA int tok_flags;
ST_DATA int parse_flags;
 
ST_DATA struct BufferedFile *file;
ST_DATA int ch, tok;
ST_DATA CValue tokc;
ST_DATA const int *macro_ptr;
ST_DATA CString tokcstr; /* current parsed string, if any */

src/tccpp.c  view on Meta::CPAN

1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
{
    Sym *s, **ps;
/* #ifdef CONFIG_TCC_EXSYMTAB */
    v &= ~SYM_EXTENDED;
/* #endif */
    s = sym_push2(ptop, v, 0, 0);
    s->r = flags;
    ps = &table_ident[v - TOK_IDENT]->sym_label;
    if (ptop == &global_label_stack) {
        /* modify the top most local identifier, so that
           sym_identifier will point to 's' when popped */
        while (*ps != NULL)
            ps = &(*ps)->prev_tok;
    }
    s->prev_tok = *ps;
    *ps = s;
    return s;
}

src/tcctok.h  view on Meta::CPAN

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
DEF_ASMDIR(byte)              /* must be first directive */
DEF_ASMDIR(word)
DEF_ASMDIR(align)
DEF_ASMDIR(p2align)
DEF_ASMDIR(skip)
DEF_ASMDIR(space)
DEF_ASMDIR(string)
DEF_ASMDIR(asciz)
DEF_ASMDIR(ascii)
DEF_ASMDIR(file)
DEF_ASMDIR(globl)
DEF_ASMDIR(global)
DEF_ASMDIR(weak)
DEF_ASMDIR(hidden)
DEF_ASMDIR(ident)
DEF_ASMDIR(size)
DEF_ASMDIR(type)
DEF_ASMDIR(text)
DEF_ASMDIR(data)
DEF_ASMDIR(bss)
DEF_ASMDIR(previous)
DEF_ASMDIR(fill)

src/tests/asmtest.S  view on Meta::CPAN

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
call 0x1000
call L4
#ifdef __i386__
call *%eax
#else
call *%rax
#endif
call *0x1000
call func1
 
.global L5,L6
 
L5:
L6:
 
#ifdef __i386__
lcall $0x100, $0x1000
#else
lcall *0x100
lcall *(%rax)
#endif

src/tests/exsymtab/60-two-contexts-globals.c  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Declare a global variable in one context and access it in another context.
 */
 
/* uncomment to enable diagnostic output */
//      #define DIAG(...) diag(__VA_ARGS__)
 
#include "test_setup.h"
 
char first_code[] =
"unsigned int test_var;\n"
"unsigned int get_test_var () {\n"

src/tests/exsymtab/60-two-contexts-globals.c  view on Meta::CPAN

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
int main(int argc, char **argv)
{
    /* ---- Compile the first code string and setup the callback data ---- */
 
    TCCState *s1 = tcc_new();
    extended_symtab_p my_symtab;
    setup_and_compile_s1(my_symtab, first_code);
    SETUP_SECOND_CALLBACK_DATA();
 
    /* ---- Make sure the getter and setter actually modify global state ---- */
    unsigned int (*first_get)() = tcc_get_symbol(s1, "get_test_var");
    void (*first_set)(unsigned int) = tcc_get_symbol(s1, "set_test_var");
    first_set(42);
    is_i(first_get(), 42, "first_set/first_get work");
    first_set(439);
    is_i(first_get(), 439, "first_set/first_get really work");
 
    /* ---- Compile code string that depends on the function and global variable ---- */
 
    TCCState *s2 = tcc_new();
    setup_and_compile_second_state(s2, second_code);
    relocate_second_state(s2);
 
    /* ---- Check indirect getter and setter ---- */
    unsigned int (*indirect_get)() = tcc_get_symbol(s2, "indirect_get");
    void (*indirect_set)(unsigned int) = tcc_get_symbol(s2, "indirect_set");
    is_i(indirect_get(), 439, "indirect_get seems to work");
    indirect_set(276);

src/tests/exsymtab/61-two-contexts-const-globals.c  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Declare a global variable in one context and access it in another context.
 */
 
/* uncomment to enable diagnostic output */
//      #define DIAG(...) diag(__VA_ARGS__)
 
#include "test_setup.h"
 
char first_code[] =
"const unsigned int test_var = 42;\n"
"unsigned int get_test_var () {\n"

src/tests/exsymtab/61-two-contexts-const-globals.c  view on Meta::CPAN

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int main(int argc, char **argv)
{
    /* ---- Compile the first code string and setup the callback data ---- */
 
    TCCState *s1 = tcc_new();
    extended_symtab_p my_symtab;
    setup_and_compile_s1(my_symtab, first_code);
    SETUP_SECOND_CALLBACK_DATA();
 
    /* ---- Make sure the getter and setter actually modify global state ---- */
    unsigned int (*first_get)() = tcc_get_symbol(s1, "get_test_var");
    is_i(first_get(), 42, "first_set/first_get work");
 
    /* ---- Compile code string that depends on the function and global variable ---- */
 
    TCCState *s2 = tcc_new();
    setup_and_compile_second_state(s2, second_code);
    relocate_second_state(s2);
 
    /* ---- Check indirect getter and setter ---- */
    unsigned int (*indirect_get)() = tcc_get_symbol(s2, "indirect_get");
    is_i(indirect_get(), 42, "indirect_get seems to work");
 
    /* ---- Check direct getter and setter ---- */

src/tests/exsymtab/62-two-contexts-static-globals.c  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Declare a global variable in one context and access it in another context.
 */
 
/* uncomment to enable diagnostic output */
//      #define DIAG(...) diag(__VA_ARGS__)
 
#include "test_setup.h"
#include <string.h>
 
/* Create a custom error handler that merely tracks that the correct
 * error was thrown. */

src/tests/exsymtab/62-two-contexts-static-globals.c  view on Meta::CPAN

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
int main(int argc, char **argv)
{
    /* ---- Compile the first code string and setup the callback data ---- */
 
    TCCState *s1 = tcc_new();
    extended_symtab_p my_symtab;
    setup_and_compile_s1(my_symtab, first_code);
    SETUP_SECOND_CALLBACK_DATA();
 
    /* ---- Make sure the getter and setter actually modify global state ---- */
    unsigned int (*first_get)() = tcc_get_symbol(s1, "get_test_var");
    is_i(first_get(), 42, "first_set/first_get work");
 
    /* ---- Check for errors during dependent compilation ---- */
 
    TCCState *s2 = tcc_new();
    if (!s2) return 1;
    if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
        tcc_set_lib_path(s2, argv[1]+9);
    else
        tcc_set_lib_path(s2, "../..");
 
    tcc_set_output_type(s2, TCC_OUTPUT_MEMORY);
    tcc_set_error_func(s2, my_error_func, my_error_func);
    callback_data.second_context = s2;
    tcc_set_extended_symtab_callbacks(s2, &lookup_by_name, &sym_used, &prep_table, &callback_data);
    tcc_compile_string(s2, second_code);
    tcc_relocate(s2, TCC_RELOCATE_AUTO);
 
    /* See if the error was thrown */
    is_i(error_thrown, 1, "Static global variables do not bleed scope");
 
    /* ---- clean up the memory ---- */
 
    tcc_delete_extended_symbol_table(my_symtab);
    tcc_delete(s1);
    tcc_delete(s2);
    pass("cleanup");
 
    return done_testing();
}



( run in 0.801 second using v1.01-cache-2.11-cpan-9b1e4054eb1 )