diff --git a/Changelog b/Changelog
index 56604af0..daca68c6 100644
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,21 @@
 version 0.9.24:
 
+- Import more changesets from Rob Landley's fork (part 2):
+  487: Handle long long constants in gen_opic() (Rob Landley)
+  484: Handle parentheses within __attribute__((...)) (Rob Landley)
+  480: Remove a goto in decl_initializer_alloc (Rob Landley)
+  475: Fix dereferences in inline assembly output (Joshua Phillips)
+  474: Cast ptrs to ints of different sizes correctly (Joshua Phillips)
+  473: Fix size of structs with empty array member (Joshua Phillips)
+  470: No warning for && and || with mixed pointers/integers (Rob Landley)
+  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)
diff --git a/Makefile b/Makefile
index b526fe57..dc01d464 100644
--- a/Makefile
+++ b/Makefile
@@ -176,6 +176,9 @@ else
 LIBTCC1_OBJS=libtcc1.o
 LIBTCC1_CC=$(CC)
 endif
+ifeq ($(ARCH),i386)
+LIBTCC1_OBJS+=alloca86.o alloca86-bt.o
+endif
 
 %.o: %.c
 	$(LIBTCC1_CC) -O2 -Wall -c -o $@ $<
@@ -237,7 +240,11 @@ libinstall: libtcc.a
 	$(INSTALL) -m644 libtcc.h "$(includedir)"
 
 libtcc.o: tcc.c i386-gen.c Makefile
+ifdef CONFIG_WIN32
+	$(CC) $(CFLAGS) -DTCC_TARGET_PE -DLIBTCC -c -o $@ $<
+else
 	$(CC) $(CFLAGS) -DLIBTCC -c -o $@ $<
+endif
 
 libtcc.a: libtcc.o 
 	$(AR) rcs $@ $^
@@ -282,11 +289,11 @@ cache: tcc_g
 
 # documentation and man page
 tcc-doc.html: tcc-doc.texi
-	texi2html -monolithic -number $<
+	-texi2html -monolithic -number $<
 
 tcc.1: tcc-doc.texi
-	./texi2pod.pl $< tcc.pod
-	pod2man --section=1 --center=" " --release=" " tcc.pod > $@
+	-./texi2pod.pl $< tcc.pod
+	-pod2man --section=1 --center=" " --release=" " tcc.pod > $@
 
 FILE=tcc-$(shell cat VERSION)
 
diff --git a/stddef.h b/stddef.h
index 89bd7b09..9965f89e 100644
--- a/stddef.h
+++ b/stddef.h
@@ -12,10 +12,15 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
    __GNUC__ ? */
 #if !defined(__int8_t_defined) && !defined(__dietlibc__)
 #define __int8_t_defined
-typedef	char int8_t;
-typedef	short int int16_t;
-typedef	int int32_t;
+typedef char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
 typedef long long int int64_t;
 #endif
 
+#ifdef __i386__
+void *_alloca(size_t);
+#define alloca _alloca
+#endif
+
 #endif
diff --git a/tcc.c b/tcc.c
index d8a02308..3d80a315 100644
--- a/tcc.c
+++ b/tcc.c
@@ -1290,6 +1290,7 @@ static void put_extern_sym2(Sym *sym, Section *section,
             case TOK_memset:
             case TOK_strlen:
             case TOK_strcpy:
+            case TOK__alloca:
                 strcpy(buf, "__bound_");
                 strcat(buf, name);
                 name = buf;
@@ -3123,6 +3124,8 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
                 c = n;
                 goto add_char_nonext;
             case 'x':
+            case 'u':
+            case 'U':
                 p++;
                 n = 0;
                 for(;;) {
@@ -4360,7 +4363,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list,
             ptr = (int *)macro_ptr;
             macro_ptr = ml.p;
             if (can_read_stream && *can_read_stream == &ml)
-                    *can_read_stream = ml.prev;
+                *can_read_stream = ml.prev;
             if (ret != 0)
                 goto no_subst;
         } else {
@@ -5298,8 +5301,8 @@ void gen_opl(int op)
 #if defined(TCC_TARGET_I386)
                 b = psym(0x850f, 0);
 #elif defined(TCC_TARGET_ARM)
-		b = ind;
-		o(0x1A000000 | encbranch(ind, 0, 1));
+                b = ind;
+                o(0x1A000000 | encbranch(ind, 0, 1));
 #elif defined(TCC_TARGET_C67)
                 error("not implemented");
 #else
@@ -5329,23 +5332,29 @@ void gen_opl(int op)
    independent opt */
 void gen_opic(int op)
 {
-    int fc, c1, c2, n;
+    int c1, c2, t1, t2, n, c;
     SValue *v1, *v2;
+    long long l1, l2, l;
+    typedef unsigned long long U;
 
     v1 = vtop - 1;
     v2 = vtop;
+    t1 = v1->type.t & VT_BTYPE;
+    t2 = v2->type.t & VT_BTYPE;
+    l1 = (t1 == VT_LLONG) ? v1->c.ll : v1->c.i;
+    l2 = (t2 == VT_LLONG) ? v2->c.ll : v2->c.i;
+
     /* currently, we cannot do computations with forward symbols */
     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     if (c1 && c2) {
-        fc = v2->c.i;
         switch(op) {
-        case '+': v1->c.i += fc; break;
-        case '-': v1->c.i -= fc; break;
-        case '&': v1->c.i &= fc; break;
-        case '^': v1->c.i ^= fc; break;
-        case '|': v1->c.i |= fc; break;
-        case '*': v1->c.i *= fc; break;
+        case '+': l1 += l2; break;
+        case '-': l1 -= l2; break;
+        case '&': l1 &= l2; break;
+        case '^': l1 ^= l2; break;
+        case '|': l1 |= l2; break;
+        case '*': l1 *= l2; break;
 
         case TOK_PDIV:
         case '/':
@@ -5353,66 +5362,68 @@ void gen_opic(int op)
         case TOK_UDIV:
         case TOK_UMOD:
             /* if division by zero, generate explicit division */
-            if (fc == 0) {
+            if (l2 == 0) {
                 if (const_wanted)
                     error("division by zero in constant");
                 goto general_case;
             }
             switch(op) {
-            default: v1->c.i /= fc; break;
-            case '%': v1->c.i %= fc; break;
-            case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
-            case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
+            default: l1 /= l2; break;
+            case '%': l1 %= l2; break;
+            case TOK_UDIV: l1 = (U)l1 / l2; break;
+            case TOK_UMOD: l1 = (U)l1 % l2; break;
             }
             break;
-        case TOK_SHL: v1->c.i <<= fc; break;
-        case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
-        case TOK_SAR: v1->c.i >>= fc; break;
+        case TOK_SHL: l1 <<= l2; break;
+        case TOK_SHR: l1 = (U)l1 >> l2; break;
+        case TOK_SAR: l1 >>= l2; break;
             /* tests */
-        case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
-        case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
-        case TOK_EQ: v1->c.i = v1->c.i == fc; break;
-        case TOK_NE: v1->c.i = v1->c.i != fc; break;
-        case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
-        case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
-        case TOK_LT: v1->c.i = v1->c.i < fc; break;
-        case TOK_GE: v1->c.i = v1->c.i >= fc; break;
-        case TOK_LE: v1->c.i = v1->c.i <= fc; break;
-        case TOK_GT: v1->c.i = v1->c.i > fc; break;
+        case TOK_ULT: l1 = (U)l1 < (U)l2; break;
+        case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
+        case TOK_EQ: l1 = l1 == l2; break;
+        case TOK_NE: l1 = l1 != l2; break;
+        case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
+        case TOK_UGT: l1 = (U)l1 > (U)l2; break;
+        case TOK_LT: l1 = l1 < l2; break;
+        case TOK_GE: l1 = l1 >= l2; break;
+        case TOK_LE: l1 = l1 <= l2; break;
+        case TOK_GT: l1 = l1 > l2; break;
             /* logical */
-        case TOK_LAND: v1->c.i = v1->c.i && fc; break;
-        case TOK_LOR: v1->c.i = v1->c.i || fc; break;
+        case TOK_LAND: l1 = l1 && l2; break;
+        case TOK_LOR: l1 = l1 || l2; break;
         default:
             goto general_case;
         }
+        v1->c.ll = l1;
         vtop--;
     } else {
         /* if commutative ops, put c2 as constant */
         if (c1 && (op == '+' || op == '&' || op == '^' || 
                    op == '|' || op == '*')) {
             vswap();
-            swap(&c1, &c2);
+            c = c1, c1 = c2, c2 = c;
+            l = l1, l1 = l2, l2 = l;
         }
-        fc = vtop->c.i;
+        /* Filter out NOP operations like x*1, x-0, x&-1... */
         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
                      op == TOK_PDIV) && 
-                    fc == 1) ||
+                    l2 == 1) ||
                    ((op == '+' || op == '-' || op == '|' || op == '^' || 
                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
-                    fc == 0) ||
+                    l2 == 0) ||
                    (op == '&' && 
-                    fc == -1))) {
+                    l2 == -1))) {
             /* nothing to do */
             vtop--;
         } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
             /* try to use shifts instead of muls or divs */
-            if (fc > 0 && (fc & (fc - 1)) == 0) {
+            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
                 n = -1;
-                while (fc) {
-                    fc >>= 1;
+                while (l2) {
+                    l2 >>= 1;
                     n++;
                 }
-                vtop->c.i = n;
+                vtop->c.ll = n;
                 if (op == '*')
                     op = TOK_SHL;
                 else if (op == TOK_PDIV)
@@ -5426,14 +5437,17 @@ void gen_opic(int op)
                    (VT_CONST | VT_SYM)) {
             /* symbol + constant case */
             if (op == '-')
-                fc = -fc;
+                l2 = -l2;
             vtop--;
-            vtop->c.i += fc;
+            vtop->c.ll += l2;
         } else {
         general_case:
             if (!nocode_wanted) {
                 /* call low level op generator */
-                gen_opi(op);
+                if (t1 == VT_LLONG || t2 == VT_LLONG) 
+                    gen_opl(op);
+                else
+                    gen_opi(op);
             } else {
                 vtop--;
             }
@@ -5540,7 +5554,8 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
     bt2 = type2->t & VT_BTYPE;
     /* accept comparison between pointer and integer with a warning */
     if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
-        warning("comparison between pointer and integer");
+        if (op != TOK_LOR && op != TOK_LAND )
+            warning("comparison between pointer and integer");
         return;
     }
 
@@ -5586,7 +5601,7 @@ void gen_op(int op)
     if (bt1 == VT_PTR || bt2 == VT_PTR) {
         /* at least one operand is a pointer */
         /* relationnal op: must be both pointers */
-        if (op >= TOK_ULT && op <= TOK_GT) {
+        if (op >= TOK_ULT && op <= TOK_LOR) {
             check_comparison_pointer_types(vtop - 1, vtop, op);
             /* pointers are handled are unsigned */
             t = VT_INT | VT_UNSIGNED;
@@ -5696,8 +5711,6 @@ void gen_op(int op)
         gen_cast(&type1);
         if (is_float(t))
             gen_opif(op);
-        else if ((t & VT_BTYPE) == VT_LLONG)
-            gen_opl(op);
         else
             gen_opic(op);
         if (op >= TOK_ULT && op <= TOK_GT) {
@@ -5947,6 +5960,11 @@ static void gen_cast(CType *type)
                the lvalue already contains the real type size (see
                VT_LVAL_xxx constants) */
         }
+    } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
+        /* if we are casting between pointer types,
+           we must update the VT_LVAL_xxx size */
+        vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+                  | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
     }
     vtop->type = *type;
 }
@@ -6502,12 +6520,15 @@ static void parse_attribute(AttributeDef *ad)
             if (tcc_state->warn_unsupported)
                 warning("'%s' attribute ignored", get_tok_str(t, NULL));
             /* skip parameters */
-            /* XXX: skip parenthesis too */
             if (tok == '(') {
-                next();
-                while (tok != ')' && tok != -1)
+                int parenthesis = 0;
+                do {
+                    if (tok == '(') 
+                        parenthesis++;
+                    else if (tok == ')') 
+                        parenthesis--;
                     next();
-                next();
+                } while (parenthesis && tok != -1);
             }
             break;
         }
@@ -6668,7 +6689,8 @@ static void struct_decl(CType *type, int u)
                             if (a == TOK_STRUCT) {
                                 c = (c + align - 1) & -align;
                                 offset = c;
-                                c += size;
+                                if (size > 0)
+                                    c += size;
                             } else {
                                 offset = 0;
                                 if (size > c)
@@ -6719,13 +6741,14 @@ static void struct_decl(CType *type, int u)
  */
 static int parse_btype(CType *type, AttributeDef *ad)
 {
-    int t, u, type_found, typespec_found;
+    int t, u, type_found, typespec_found, typedef_found;
     Sym *s;
     CType type1;
 
     memset(ad, 0, sizeof(AttributeDef));
     type_found = 0;
     typespec_found = 0;
+    typedef_found = 0;
     t = 0;
     while(1) {
         switch(tok) {
@@ -6809,9 +6832,9 @@ static int parse_btype(CType *type, AttributeDef *ad)
         case TOK_SIGNED2:
         case TOK_SIGNED3:
             typespec_found = 1;
-	    t |= VT_SIGNED;
-	    next();
-	    break;
+            t |= VT_SIGNED;
+            next();
+            break;
         case TOK_REGISTER:
         case TOK_AUTO:
         case TOK_RESTRICT1:
@@ -6858,11 +6881,12 @@ static int parse_btype(CType *type, AttributeDef *ad)
             parse_expr_type(&type1);
             goto basic_type2;
         default:
-            if (typespec_found)
+            if (typespec_found || typedef_found)
                 goto the_end;
             s = sym_find(tok);
             if (!s || !(s->type.t & VT_TYPEDEF))
                 goto the_end;
+            typedef_found = 1;
             t |= (s->type.t & ~VT_TYPEDEF);
             type->ref = s->type.ref;
             next();
@@ -8164,6 +8188,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
         int v1, v2;
         if (!case_sym)
             expect("switch");
+        /* since a case is like a label, we must skip it with a jmp */
+        b = gjmp(0);
+    next_case:
         next();
         v1 = expr_const();
         v2 = v1;
@@ -8173,24 +8200,26 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
             if (v2 < v1)
                 warning("empty case range");
         }
-        /* since a case is like a label, we must skip it with a jmp */
-        b = gjmp(0);
         gsym(*case_sym);
         vseti(case_reg, 0);
         vpushi(v1);
         if (v1 == v2) {
             gen_op(TOK_EQ);
-            *case_sym = gtst(1, 0);
+            *case_sym = 0;
         } else {
             gen_op(TOK_GE);
             *case_sym = gtst(1, 0);
             vseti(case_reg, 0);
             vpushi(v2);
             gen_op(TOK_LE);
-            *case_sym = gtst(1, *case_sym);
         }
-        gsym(b);
         skip(':');
+        if (tok == TOK_CASE) {
+            b = gtst(0, b);
+            goto next_case;
+        }
+        *case_sym = gtst(1, *case_sym);
+        gsym(b);
         is_expr = 0;
         goto block_after_label;
     } else 
@@ -8873,11 +8902,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
         }
 
         if (v) {
-            if (scope == VT_CONST) {
-                if (!sym)
-                    goto do_def;
-            } else {
-            do_def:
+            if (scope != VT_CONST || !sym) {
                 sym = sym_push(v, type, r | VT_SYM, 0);
             }
             /* update symbol definition */
diff --git a/tccasm.c b/tccasm.c
index 47324059..8834b53f 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -806,7 +806,7 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands,
             sv = *op->vt;
             if (op->reg >= 0) {
                 sv.r = op->reg;
-                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
                     sv.r |= VT_LVAL;
             }
             subst_asm_operand(out_str, &sv, modifier);
diff --git a/tccelf.c b/tccelf.c
index 4dfbcfed..73f84cc5 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -182,9 +182,11 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
 {
     Elf32_Sym *esym;
     int sym_bind, sym_index, sym_type, esym_bind;
+    unsigned char sym_vis, esym_vis, new_vis;
 
     sym_bind = ELF32_ST_BIND(info);
     sym_type = ELF32_ST_TYPE(info);
+    sym_vis = ELF32_ST_VISIBILITY(other);
         
     if (sym_bind != STB_LOCAL) {
         /* we search global or weak symbols */
@@ -194,6 +196,19 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
         esym = &((Elf32_Sym *)s->data)[sym_index];
         if (esym->st_shndx != SHN_UNDEF) {
             esym_bind = ELF32_ST_BIND(esym->st_info);
+            /* propagate the most constraining visibility */
+            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
+            esym_vis = ELF32_ST_VISIBILITY(esym->st_other);
+            if (esym_vis == STV_DEFAULT) {
+                new_vis = sym_vis;
+            } else if (sym_vis == STV_DEFAULT) {
+                new_vis = esym_vis;
+            } else {
+                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
+            }
+            esym->st_other = (esym->st_other & ~ELF32_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 */
@@ -202,6 +217,8 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
                 goto do_patch;
             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
                 /* weak is ignored if already global */
+            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
+                /* ignore hidden symbols after */
             } else {
 #if 0
                 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
@@ -1949,7 +1966,7 @@ static int tcc_load_object_file(TCCState *s1,
                 if (sym_index >= nb_syms)
                     goto invalid_reloc;
                 sym_index = old_to_new_syms[sym_index];
-               /* ignore link_once in rel section. */
+                /* ignore link_once in rel section. */
                 if (!sym_index && !sm->link_once) {
                 invalid_reloc:
                     error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
diff --git a/tcctok.h b/tcctok.h
index c88dcc98..dab59428 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -123,7 +123,6 @@
 /* builtin functions or variables */
      DEF(TOK_memcpy, "memcpy")
      DEF(TOK_memset, "memset")
-     DEF(TOK_alloca, "alloca")
      DEF(TOK___divdi3, "__divdi3")
      DEF(TOK___moddi3, "__moddi3")
      DEF(TOK___udivdi3, "__udivdi3")
@@ -188,6 +187,7 @@
      DEF(TOK_memmove, "memmove")
      DEF(TOK_strlen, "strlen")
      DEF(TOK_strcpy, "strcpy")
+     DEF(TOK__alloca, "_alloca")
 #endif
 
 /* Tiny Assembler */
diff --git a/win32/include/_mingw.h b/win32/include/_mingw.h
index 9623a72a..90a8b110 100644
--- a/win32/include/_mingw.h
+++ b/win32/include/_mingw.h
@@ -18,6 +18,8 @@
 #ifndef __MINGW_H
 #define __MINGW_H
 
+#include <stddef.h>
+
 #define __int64 long long
 #define __int32 long
 #define __int16 short
diff --git a/win32/include/stdarg.h b/win32/include/stdarg.h
index d562d6dd..a9b22b7b 100644
--- a/win32/include/stdarg.h
+++ b/win32/include/stdarg.h
@@ -6,6 +6,7 @@ typedef char *va_list;
 /* only correct for i386 */
 #define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
 #define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
 #define va_end(ap)
 
 /* fix a buggy dependency on GCC in libio.h */
diff --git a/win32/include/stddef.h b/win32/include/stddef.h
index 89bd7b09..9965f89e 100644
--- a/win32/include/stddef.h
+++ b/win32/include/stddef.h
@@ -12,10 +12,15 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
    __GNUC__ ? */
 #if !defined(__int8_t_defined) && !defined(__dietlibc__)
 #define __int8_t_defined
-typedef	char int8_t;
-typedef	short int int16_t;
-typedef	int int32_t;
+typedef char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
 typedef long long int int64_t;
 #endif
 
+#ifdef __i386__
+void *_alloca(size_t);
+#define alloca _alloca
+#endif
+
 #endif