diff --git a/libtcc.c b/libtcc.c
index 93493481..5e497c92 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -425,7 +425,7 @@ ST_FUNC Section *find_section(TCCState *s1, const char *name)
 /* update sym->c so that it points to an external symbol in section
    'section' with value 'value' */
 ST_FUNC void put_extern_sym2(Sym *sym, Section *section, 
-                            unsigned long value, unsigned long size,
+                            uplong value, unsigned long size,
                             int can_add_underscore)
 {
     int sym_type, sym_bind, sh_num, info, other;
@@ -529,7 +529,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
 }
 
 ST_FUNC void put_extern_sym(Sym *sym, Section *section, 
-                           unsigned long value, unsigned long size)
+                           uplong value, unsigned long size)
 {
     put_extern_sym2(sym, section, value, size, 1);
 }
@@ -1494,7 +1494,7 @@ PUB_FUNC const char * tcc_set_linker(TCCState *s, char *option, int multi)
             if (s->warn_unsupported)
                 tcc_warning("ignoring -fini %s", p);
         } else if (link_option(option, "image-base=", &p)) {
-            s->text_addr = strtoul(p, &end, 16);
+            s->text_addr = strtoull(p, &end, 16);
             s->has_text_addr = 1;
         } else if (link_option(option, "init=", &p)) {
             s->init_symbol = p;
@@ -1563,9 +1563,8 @@ PUB_FUNC const char * tcc_set_linker(TCCState *s, char *option, int multi)
 #endif
 
         } else if (link_option(option, "Ttext=", &p)) {
-            s->text_addr = strtoul(p, &end, 16);
+            s->text_addr = strtoull(p, &end, 16);
             s->has_text_addr = 1;
-
         } else {
             return option;
         }
diff --git a/tcc.h b/tcc.h
index d158829a..18a6b91c 100644
--- a/tcc.h
+++ b/tcc.h
@@ -313,8 +313,8 @@ typedef struct Section {
     int sh_addralign;        /* elf section alignment */
     int sh_entsize;          /* elf entry size */
     unsigned long sh_size;   /* section size (only used during output) */
-    unsigned long sh_addr;      /* address at which the section is relocated */
-    unsigned long sh_offset;    /* file offset */
+    uplong sh_addr;          /* address at which the section is relocated */
+    unsigned long sh_offset; /* file offset */
     int nb_hashed_syms;      /* used to resize the hash table */
     struct Section *link;    /* link to another section */
     struct Section *reloc;   /* corresponding section for relocation, if any */
@@ -531,7 +531,7 @@ struct TCCState {
     int alacarte_link;
 
     /* address of text section */
-    unsigned long text_addr;
+    uplong text_addr;
     int has_text_addr;
 
     /* symbols to call at load-time / unload-time */
@@ -872,6 +872,7 @@ enum tcc_token {
   #define strtold (long double)strtod
   #define strtof (float)strtod
   #define strtoll (long long)strtol
+  #define strtoull (unsigned long long)strtoull
 #endif
 #else
 /* XXX: need to define this to use them in non ISOC99 context */
@@ -992,8 +993,8 @@ ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
 ST_FUNC void section_reserve(Section *sec, unsigned long size);
 ST_FUNC Section *find_section(TCCState *s1, const char *name);
 
-ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
-ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long value, unsigned long size);
+ST_FUNC void put_extern_sym2(Sym *sym, Section *section, uplong value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, uplong value, unsigned long size);
 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
 
 ST_INLN void sym_free(Sym *sym);
diff --git a/tccelf.c b/tccelf.c
index 40c88ab1..0c764ba9 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1153,7 +1153,7 @@ ST_FUNC Section *new_symtab(TCCState *s1,
 }
 
 /* put dynamic tag */
-static void put_dt(Section *dynamic, int dt, unsigned long val)
+static void put_dt(Section *dynamic, int dt, uplong val)
 {
     ElfW(Dyn) *dyn;
     dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
@@ -1381,7 +1381,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
 	section_reserve(s1->got, offset + PTR_SIZE);
 #ifdef TCC_TARGET_X86_64
 	/* only works for x86-64 */
-	put32(s1->got->data + offset, sym->st_value >> 32);
+	put32(s1->got->data + offset + 4, sym->st_value >> 32);
 #endif
 	put32(s1->got->data + offset, sym->st_value & 0xffffffff);
 }
@@ -1421,8 +1421,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
     FILE *f;
     int fd, mode, ret;
     int *section_order;
-    int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
-    unsigned long addr;
+    int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
+    long long tmp;
+    uplong addr;
     Section *strsec, *s;
     ElfW(Shdr) shdr, *sh;
     ElfW(Phdr) *phdr, *ph;
@@ -1430,9 +1431,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
     unsigned long saved_dynamic_data_offset;
     ElfW(Sym) *sym;
     int type, file_type;
-    unsigned long rel_addr, rel_size;
+    uplong rel_addr, rel_size;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    unsigned long bss_addr, bss_size;
+    uplong bss_addr, bss_size;
 #endif
 
     file_type = s1->output_type;
@@ -1747,7 +1748,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
             addr = s1->text_addr;
             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
                ELF_PAGE_SIZE */
-            a_offset = addr & (s1->section_align - 1);
+            a_offset = (int) (addr & (s1->section_align - 1));
             p_offset = file_offset & (s1->section_align - 1);
             if (a_offset < p_offset) 
                 a_offset += s1->section_align;
@@ -1821,7 +1822,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
                     tmp = addr;
                     addr = (addr + s->sh_addralign - 1) & 
                         ~(s->sh_addralign - 1);
-                    file_offset += addr - tmp;
+                    file_offset += (int) ( addr - tmp );
                     s->sh_offset = file_offset;
                     s->sh_addr = addr;