aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tcc.c31
-rw-r--r--tccelf.c11
-rw-r--r--tccpe.c85
-rw-r--r--win32/readme.txt204
4 files changed, 186 insertions, 145 deletions
diff --git a/tcc.c b/tcc.c
index 85bf503..2a59808 100644
--- a/tcc.c
+++ b/tcc.c
@@ -711,9 +711,12 @@ int __stdcall FreeConsole(void);
#define snprintf _snprintf
#define vsnprintf _vsnprintf
+#ifndef __GNUC__
+ #define strtold (long double)strtod
+ #define strtof (float)strtod
+ #define strtoll (long long)strtol
#endif
-
-#if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
+#elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
/* currently incorrect */
long double strtold(const char *nptr, char **endptr)
{
@@ -2730,6 +2733,7 @@ static void pragma_parse(TCCState *s1)
#pragma pack(push,1) // push & set
#pragma pack(pop) // restore previous
*/
+ next();
skip('(');
if (tok == TOK_ASM_pop) {
next();
@@ -10514,8 +10518,10 @@ int main(int argc, char **argv)
GetModuleFileNameA(NULL, path, sizeof path);
p = d = strlwr(path);
while (*d)
- if (*d++ == '\\')
- (p = d)[-1] = '/';
+ {
+ if (*d == '\\') *d = '/', p = d;
+ ++d;
+ }
*p = '\0';
tcc_lib_path = path;
}
@@ -10555,23 +10561,28 @@ int main(int argc, char **argv)
error("cannot specify libraries with -c");
}
+ if (output_type != TCC_OUTPUT_MEMORY) {
+ if (!outfile) {
/* compute default outfile name */
- if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
- if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
- char *ext;
- /* strip path */
pstrcpy(objfilename, sizeof(objfilename) - 1,
+ /* strip path */
tcc_basename(files[0]));
- /* add .o extension */
- ext = strrchr(objfilename, '.');
+#ifdef TCC_TARGET_PE
+ pe_guess_outfile(objfilename, output_type);
+#else
+ if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
+ char *ext = strrchr(objfilename, '.');
if (!ext)
goto default_outfile;
+ /* add .o extension */
strcpy(ext + 1, "o");
} else {
default_outfile:
pstrcpy(objfilename, sizeof(objfilename), "a.out");
}
+#endif
outfile = objfilename;
+ }
}
if (do_bench) {
diff --git a/tccelf.c b/tccelf.c
index e1ca901..0e52185 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -2095,7 +2095,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{
Elf32_Ehdr ehdr;
Elf32_Shdr *shdr, *sh, *sh1;
- int i, nb_syms, nb_dts, sym_bind, ret, other;
+ int i, nb_syms, nb_dts, sym_bind, ret;
Elf32_Sym *sym, *dynsym;
Elf32_Dyn *dt, *dynamic;
unsigned char *dynstr;
@@ -2175,15 +2175,8 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
if (sym_bind == STB_LOCAL)
continue;
name = dynstr + sym->st_name;
-#ifdef TCC_TARGET_PE
- /* in the PE format we need to know the DLL from which the
- symbol comes. XXX: add a new array for that ? */
- other = s1->nb_loaded_dlls - 1;
-#else
- other = sym->st_other;
-#endif
add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
- sym->st_info, other, sym->st_shndx, name);
+ sym->st_info, sym->st_other, sym->st_shndx, name);
}
/* load all referenced DLLs */
diff --git a/tccpe.c b/tccpe.c
index 611019e..5911296 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -742,24 +742,38 @@ ST void pe_build_imports(struct pe_info *pe)
}
/* ------------------------------------------------------------- */
+ST int sym_cmp(const void *va, const void *vb)
+{
+ Elf32_Sym *sa = (Elf32_Sym *)symtab_section->data + *(int*)va;
+ Elf32_Sym *sb = (Elf32_Sym *)symtab_section->data + *(int*)vb;
+ const char *ca = symtab_section->link->data + sa->st_name;
+ const char *cb = symtab_section->link->data + sb->st_name;
+ return strcmp(ca, cb);
+}
+
ST void pe_build_exports(struct pe_info *pe)
{
Elf32_Sym *sym;
- DWORD func_offset;
- DWORD voffset = pe->thunk->sh_addr - pe->imagebase;
+ DWORD func_offset, voffset;
struct pe_export_header *hdr;
- int sym_count = 0, ordinal = 0;
+ int sym_count, n, ord, *sorted;
+
+ voffset = pe->thunk->sh_addr - pe->imagebase;
+ sym_count = 0, n = 1, sorted = NULL;
// for simplicity only functions are exported
for_sym_in_symtab(sym)
- if (sym->st_shndx != text_section->sh_num)
- sym->st_other &= ~1;
- else if (sym->st_other & 1)
- ++sym_count;
+ {
+ if ((sym->st_other & 1)
+ && sym->st_shndx == text_section->sh_num)
+ dynarray_add((void***)&sorted, &sym_count, (void*)n);
+ ++n;
+ }
if (0 == sym_count)
return;
+ qsort (sorted, sym_count, sizeof sorted[0], sym_cmp);
pe_align_section(pe->thunk, 16);
pe->exp_offs = pe->thunk->data_offset;
@@ -774,30 +788,28 @@ ST void pe_build_exports(struct pe_info *pe)
hdr->NumberOfFunctions = sym_count;
hdr->NumberOfNames = sym_count;
hdr->AddressOfFunctions = func_offset + voffset;
- hdr->AddressOfNames =
- hdr->AddressOfFunctions + sym_count * sizeof(DWORD);
- hdr->AddressOfNameOrdinals =
- hdr->AddressOfNames + sym_count * sizeof(DWORD);
+ hdr->AddressOfNames = hdr->AddressOfFunctions + sym_count * sizeof(DWORD);
+ hdr->AddressOfNameOrdinals = hdr->AddressOfNames + sym_count * sizeof(DWORD);
hdr->Name = pe->thunk->data_offset + voffset;
put_elf_str(pe->thunk, tcc_basename(pe->filename));
- for_sym_in_symtab(sym)
- if (sym->st_other & 1) {
- char *name = symtab_section->link->data + sym->st_name;
- DWORD *p = (DWORD *) (pe->thunk->data + func_offset);
- DWORD *pfunc = p + ordinal;
- DWORD *pname = p + sym_count + ordinal;
- WORD *pord = (WORD *) (p + 2 * sym_count) + ordinal;
- *pfunc =
- sym->st_value + pe->s1->sections[sym->st_shndx]->sh_addr -
- pe->imagebase;
+ for (ord = 0; ord < sym_count; ++ord)
+ {
+ char *name; DWORD *p, *pfunc, *pname; WORD *pord;
+ sym = (Elf32_Sym *)symtab_section->data + sorted[ord];
+ name = symtab_section->link->data + sym->st_name;
+ p = (DWORD*)(pe->thunk->data + func_offset);
+ pfunc = p + ord;
+ pname = p + sym_count + ord;
+ pord = (WORD *)(p + 2*sym_count) + ord;
+ *pfunc = sym->st_value + pe->s1->sections[sym->st_shndx]->sh_addr - pe->imagebase;
*pname = pe->thunk->data_offset + voffset;
- *pord = ordinal;
+ *pord = ord;
put_elf_str(pe->thunk, name);
/* printf("export: %s\n", name); */
- ++ordinal;
}
pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
+ tcc_free(sorted);
}
/* ------------------------------------------------------------- */
@@ -1120,6 +1132,24 @@ int pe_load_def_file(TCCState * s1, FILE * fp)
}
/* ------------------------------------------------------------- */
+void pe_guess_outfile(char *objfilename, int output_type)
+{
+ char *ext = strrchr(objfilename, '.');
+ if (NULL == ext)
+ ext = strchr(objfilename, 0);
+ if (output_type == TCC_OUTPUT_DLL)
+ strcpy(ext, ".dll");
+ else
+ if (output_type == TCC_OUTPUT_EXE)
+ strcpy(ext, ".exe");
+ else
+ if (output_type == TCC_OUTPUT_OBJ && strcmp(ext, ".o"))
+ strcpy(ext, ".o");
+ else
+ error("no outputfile given");
+}
+
+/* ------------------------------------------------------------- */
unsigned long pe_add_runtime(TCCState * s1)
{
const char *start_symbol;
@@ -1127,6 +1157,13 @@ unsigned long pe_add_runtime(TCCState * s1)
if (find_elf_sym(symtab_section, "WinMain"))
pe_type = PE_GUI;
+ else
+ if (TCC_OUTPUT_DLL == s1->output_type)
+ {
+ pe_type = PE_DLL;
+ // need this for 'tccelf.c:relocate_section()'
+ s1->output_type = TCC_OUTPUT_EXE;
+ }
start_symbol =
TCC_OUTPUT_MEMORY == s1->output_type
@@ -1192,7 +1229,7 @@ int tcc_output_pe(TCCState * s1, const char *filename)
{
Section *s;
FILE *f;
- f = fopen("tccpe.log", "wb");
+ f = fopen("tccpe.log", "wt");
for (i = 1; i < s1->nb_sections; ++i) {
s = s1->sections[i];
pe_print_section(f, s);
diff --git a/win32/readme.txt b/win32/readme.txt
index 6941696..e4db70b 100644
--- a/win32/readme.txt
+++ b/win32/readme.txt
@@ -1,102 +1,102 @@
-
- TinyCC-PE
- ---------
-
- TinyCC (aka TCC) is a small but hyperfast C compiler,
- written by Fabrice Bellard,
-
-
- TinyCC-PE is the TinyCC compiler with an extension to
- write PE executables for MS-Windows.
-
-
- Features:
- ---------
-
- TinyCC-PE can produce console applications, native windows
- GUI programs and DLL's.
-
- Most of the features pointed out by Fabrice Bellard for the
- original version are still valid, i.e:
-
- - SMALL! The package with ~400kb includes a complete C-compiler
- with header files for console and GUI applications.
-
- - With the -run switch you can run C-sources without any
- linking directly from the command line.
-
- - TCC can of course compile itself.
-
-
- Installation:
- -------------
-
- Just unzip the package to a directory anywhere on your computer.
-
-
- Examples:
- ---------
-
- For the 'Fibonacci' console example type from the command line:
-
- tcc examples\fib.c
-
-
- For the 'Hello Windows' GUI example:
-
- tcc examples\hello_win.c
-
-
- For the 'Hello DLL' example:
-
- tcc -shared examples\dll.c
- tcc examples\hello_dll.c examples\dll.def
-
-
- Import Definitions:
- -------------------
-
- TinyCC-PE searches and reads import definition files similar
- to libraries.
-
- The included 'tiny_impdef' program may be used to make .def files
- for any DLL, e.g for an 'opengl32.def':
-
- tiny_impdef.exe opengl32.dll
-
- or to the same effect:
-
- tcc -lkernel32 -run tiny_impdef.c opengl32.dll
-
-
- Header Files:
- -------------
-
- The system header files, except '_mingw.h', are from the
- 2.0 mingw distribution. See also: http://www.mingw.org/
-
-
- Compile TCC:
- ------------
-
- With TCC itself just say:
-
- tcc src\tcc.c -lkernel32 -o tcc.new.exe
-
- Other compilers like mingw-gcc or msvc work as well.
- To make libtcc1.a, you need 'ar' from the mingw binutils.
-
-
- Documentation and License:
- --------------------------
-
- TCC is distributed under the GNU Lesser General Public License
- (see COPYING file).
-
- Please read the original tcc-doc.html to have all the features
- of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
-
-
- --------------------------------------------
- 09.Apr.2005 - grischka@users.sourceforge.net
-
+
+ TinyCC-PE
+ ---------
+
+ TinyCC (aka TCC) is a small but hyperfast C compiler,
+ written by Fabrice Bellard,
+
+
+ TinyCC-PE is the TinyCC compiler with an extension to
+ write PE executables for MS-Windows.
+
+
+ Features:
+ ---------
+
+ TinyCC-PE can produce console applications, native windows
+ GUI programs and DLL's.
+
+ Most of the features pointed out by Fabrice Bellard for the
+ original version are still valid, i.e:
+
+ - SMALL! The package with ~400kb includes a complete C-compiler
+ with header files for console and GUI applications.
+
+ - With the -run switch you can run C-sources without any
+ linking directly from the command line.
+
+ - TCC can of course compile itself.
+
+
+ Installation:
+ -------------
+
+ Just unzip the package to a directory anywhere on your computer.
+
+
+ Examples:
+ ---------
+
+ For the 'Fibonacci' console example type from the command line:
+
+ tcc examples\fib.c
+
+
+ For the 'Hello Windows' GUI example:
+
+ tcc examples\hello_win.c
+
+
+ For the 'Hello DLL' example:
+
+ tcc -shared examples\dll.c
+ tcc examples\hello_dll.c examples\dll.def
+
+
+ Import Definitions:
+ -------------------
+
+ TinyCC-PE searches and reads import definition files similar
+ to libraries.
+
+ The included 'tiny_impdef' program may be used to make .def files
+ for any DLL, e.g for an 'opengl32.def':
+
+ tiny_impdef.exe opengl32.dll
+
+ or to the same effect:
+
+ tcc -lkernel32 -run tiny_impdef.c opengl32.dll
+
+
+ Header Files:
+ -------------
+
+ The system header files, except '_mingw.h', are from the
+ 2.0 mingw distribution. See also: http://www.mingw.org/
+
+
+ Compile TCC:
+ ------------
+
+ With TCC itself just say:
+
+ tcc src\tcc.c -lkernel32 -o tcc.new.exe
+
+ Other compilers like mingw-gcc or msvc work as well.
+ To make libtcc1.a, you need 'ar' from the mingw binutils.
+
+
+ Documentation and License:
+ --------------------------
+
+ TCC is distributed under the GNU Lesser General Public License
+ (see COPYING file).
+
+ Please read the original tcc-doc.html to have all the features
+ of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
+
+
+ --------------------------------------------
+ 09.Apr.2005 - grischka@users.sourceforge.net
+