| @@ -109,6 +109,7 @@ typedef int BOOL; · 108 unmodified lines |
| 109 | 109 | #define IFDEF_STACK_SIZE 64 |
| 110 | 110 | #define VSTACK_SIZE 256 |
| 111 | 111 | #define STRING_MAX_SIZE 1024 |
| 112 | +#define PACK_STACK_SIZE 8 |
| 112 | 113 | |
| 113 | 114 | #define TOK_HASH_SIZE 8192 /* must be a power of two */ |
| 114 | 115 | #define TOK_ALLOC_INCR 512 /* must be a power of two */ |
| @@ -481,6 +482,10 @@ struct TCCState { · 366 unmodified lines |
| 481 | 482 | |
| 482 | 483 | /* see cached_includes */ |
| 483 | 484 | int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; |
| 485 | + |
| 486 | + /* pack stack */ |
| 487 | + int pack_stack[PACK_STACK_SIZE]; |
| 488 | + int *pack_stack_ptr; |
| 484 | 489 | }; |
| 485 | 490 | |
| 486 | 491 | /* The current value can be: */ |
| @@ -789,7 +794,7 @@ static int put_elf_sym(Section *s, · 302 unmodified lines |
| 789 | 794 | unsigned long value, unsigned long size, |
| 790 | 795 | int info, int other, int shndx, const char *name); |
| 791 | 796 | static int add_elf_sym(Section *s, unsigned long value, unsigned long size, |
| 792 | | − int info, int sh_num, const char *name); |
| 797 | + int info, int other, int sh_num, const char *name); |
| 793 | 798 | static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, |
| 794 | 799 | int type, int symbol); |
| 795 | 800 | static void put_stabs(const char *str, int type, int other, int desc, |
| @@ -1251,7 +1256,7 @@ static void put_extern_sym(Sym *sym, Section *section, · 455 unmodified lines |
| 1251 | 1256 | } |
| 1252 | 1257 | #endif |
| 1253 | 1258 | info = ELF32_ST_INFO(sym_bind, sym_type); |
| 1254 | | − sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name); |
| 1259 | + sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name); |
| 1255 | 1260 | } else { |
| 1256 | 1261 | esym = &((Elf32_Sym *)symtab_section->data)[sym->c]; |
| 1257 | 1262 | esym->st_value = value; |
| @@ -2702,6 +2707,52 @@ static inline void add_cached_include(TCCState *s1, int type, · 1444 unmodified lines |
| 2702 | 2707 | s1->cached_includes_hash[h] = s1->nb_cached_includes; |
| 2703 | 2708 | } |
| 2704 | 2709 | |
| 2710 | +static void pragma_parse(TCCState *s1) |
| 2711 | +{ |
| 2712 | + int val; |
| 2713 | + |
| 2714 | + next(); |
| 2715 | + if (tok == TOK_pack) { |
| 2716 | + /* |
| 2717 | + This may be: |
| 2718 | + #pragma pack(1) // set |
| 2719 | + #pragma pack() // reset to default |
| 2720 | + #pragma pack(push,1) // push & set |
| 2721 | + #pragma pack(pop) // restore previous |
| 2722 | + */ |
| 2723 | + skip('('); |
| 2724 | + if (tok == TOK_ASM_pop) { |
| 2725 | + next(); |
| 2726 | + if (s1->pack_stack_ptr <= s1->pack_stack) { |
| 2727 | + stk_error: |
| 2728 | + error("out of pack stack"); |
| 2729 | + } |
| 2730 | + s1->pack_stack_ptr--; |
| 2731 | + } else { |
| 2732 | + val = 0; |
| 2733 | + if (tok != ')') { |
| 2734 | + if (tok == TOK_ASM_push) { |
| 2735 | + next(); |
| 2736 | + if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1) |
| 2737 | + goto stk_error; |
| 2738 | + s1->pack_stack_ptr++; |
| 2739 | + skip(','); |
| 2740 | + } |
| 2741 | + if (tok != TOK_CINT) { |
| 2742 | + pack_error: |
| 2743 | + error("invalid pack pragma"); |
| 2744 | + } |
| 2745 | + val = tokc.i; |
| 2746 | + if (val < 1 || val > 16 || (val & (val - 1)) != 0) |
| 2747 | + goto pack_error; |
| 2748 | + next(); |
| 2749 | + } |
| 2750 | + *s1->pack_stack_ptr = val; |
| 2751 | + skip(')'); |
| 2752 | + } |
| 2753 | + } |
| 2754 | +} |
| 2755 | + |
| 2705 | 2756 | /* is_bof is true if first non space token at beginning of file */ |
| 2706 | 2757 | static void preprocess(int is_bof) |
| 2707 | 2758 | { |
| @@ -2958,7 +3009,7 @@ static void preprocess(int is_bof) · 250 unmodified lines |
| 2958 | 3009 | warning("#warning %s", buf); |
| 2959 | 3010 | break; |
| 2960 | 3011 | case TOK_PRAGMA: |
| 2961 | | − /* ignored */ |
| 3012 | + pragma_parse(s1); |
| 2962 | 3013 | break; |
| 2963 | 3014 | default: |
| 2964 | 3015 | if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { |
| @@ -6437,6 +6488,9 @@ static void struct_decl(CType *type, int u) · 3472 unmodified lines |
| 6437 | 6488 | align = ad.aligned; |
| 6438 | 6489 | } else if (ad.packed) { |
| 6439 | 6490 | align = 1; |
| 6491 | + } else if (*tcc_state->pack_stack_ptr) { |
| 6492 | + if (align > *tcc_state->pack_stack_ptr) |
| 6493 | + align = *tcc_state->pack_stack_ptr; |
| 6440 | 6494 | } |
| 6441 | 6495 | lbit_pos = 0; |
| 6442 | 6496 | if (bit_size >= 0) { |
| @@ -8971,6 +9025,11 @@ static void decl(int l) · 2528 unmodified lines |
| 8971 | 9025 | cur_text_section = text_section; |
| 8972 | 9026 | sym->r = VT_SYM | VT_CONST; |
| 8973 | 9027 | gen_function(sym); |
| 9028 | +#ifdef TCC_TARGET_PE |
| 9029 | + if (ad.dllexport) { |
| 9030 | + ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1; |
| 9031 | + } |
| 9032 | +#endif |
| 8974 | 9033 | } |
| 8975 | 9034 | break; |
| 8976 | 9035 | } else { |
| @@ -9032,6 +9091,8 @@ static void preprocess_init(TCCState *s1) · 55 unmodified lines |
| 9032 | 9091 | |
| 9033 | 9092 | /* XXX: not ANSI compliant: bound checking says error */ |
| 9034 | 9093 | vtop = vstack - 1; |
| 9094 | + s1->pack_stack[0] = 0; |
| 9095 | + s1->pack_stack_ptr = s1->pack_stack; |
| 9035 | 9096 | } |
| 9036 | 9097 | |
| 9037 | 9098 | /* compile the C file opened in 'file'. Return non zero if errors. */ |
| @@ -9903,7 +9964,7 @@ int tcc_add_library(TCCState *s, const char *libraryname) · 865 unmodified lines |
| 9903 | 9964 | int tcc_add_symbol(TCCState *s, const char *name, unsigned long val) |
| 9904 | 9965 | { |
| 9905 | 9966 | add_elf_sym(symtab_section, val, 0, |
| 9906 | | − ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), |
| 9967 | + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, |
| 9907 | 9968 | SHN_ABS, name); |
| 9908 | 9969 | return 0; |
| 9909 | 9970 | } |