diff --git a/libtcc.c b/libtcc.c
index e00c776..1feb741 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -1335,6 +1335,8 @@ static int tcc_set_linker(TCCState *s, const char *option)
             s->symbolic = 1;
         } else if (link_option(option, "nostdlib", &p)) {
             s->nostdlib = 1;
+        } else if (link_option(option, "e=", &p)) {
+            copy_linker_arg(&s->elf_entryname, p, 0);
         } else if (link_option(option, "fini=", &p)) {
             copy_linker_arg(&s->fini_symbol, p, 0);
             ignoring = 1;
diff --git a/tcc.h b/tcc.h
index 8a46210..1ea1856 100644
--- a/tcc.h
+++ b/tcc.h
@@ -961,6 +961,8 @@ struct TCCState {
     Section *verneed_section;
 #endif
 
+    char *elf_entryname;
+
 #ifdef TCC_IS_NATIVE
     const char *runtime_main;
     void **runtime_mem;
diff --git a/tccelf.c b/tccelf.c
index 1dcbc38..9e860b5 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -2322,11 +2322,17 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
     default:
     case TCC_OUTPUT_EXE:
         ehdr.e_type = ET_EXEC;
-        ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
+        ehdr.e_entry = get_sym_addr(s1,
+                                    s1->elf_entryname ?
+                                        s1->elf_entryname : "_start",
+                                    1, 0);
         break;
     case TCC_OUTPUT_DLL:
         ehdr.e_type = ET_DYN;
-        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
+        ehdr.e_entry = s1->elf_entryname ?
+                            get_sym_addr(s1,s1->elf_entryname,1,0) :
+                            text_section->sh_addr;
+                            /* XXX: is it correct ? */
         break;
     case TCC_OUTPUT_OBJ:
         ehdr.e_type = ET_REL;
