mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
win32 merge (grischka)
This commit is contained in:
parent
09f4ce9857
commit
fe9b1f60ce
31
tcc.c
31
tcc.c
@ -711,9 +711,12 @@ int __stdcall FreeConsole(void);
|
|||||||
|
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#define strtold (long double)strtod
|
||||||
|
#define strtof (float)strtod
|
||||||
|
#define strtoll (long long)strtol
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
|
||||||
#if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
|
|
||||||
/* currently incorrect */
|
/* currently incorrect */
|
||||||
long double strtold(const char *nptr, char **endptr)
|
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(push,1) // push & set
|
||||||
#pragma pack(pop) // restore previous
|
#pragma pack(pop) // restore previous
|
||||||
*/
|
*/
|
||||||
|
next();
|
||||||
skip('(');
|
skip('(');
|
||||||
if (tok == TOK_ASM_pop) {
|
if (tok == TOK_ASM_pop) {
|
||||||
next();
|
next();
|
||||||
@ -10514,8 +10518,10 @@ int main(int argc, char **argv)
|
|||||||
GetModuleFileNameA(NULL, path, sizeof path);
|
GetModuleFileNameA(NULL, path, sizeof path);
|
||||||
p = d = strlwr(path);
|
p = d = strlwr(path);
|
||||||
while (*d)
|
while (*d)
|
||||||
if (*d++ == '\\')
|
{
|
||||||
(p = d)[-1] = '/';
|
if (*d == '\\') *d = '/', p = d;
|
||||||
|
++d;
|
||||||
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
tcc_lib_path = path;
|
tcc_lib_path = path;
|
||||||
}
|
}
|
||||||
@ -10555,24 +10561,29 @@ int main(int argc, char **argv)
|
|||||||
error("cannot specify libraries with -c");
|
error("cannot specify libraries with -c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output_type != TCC_OUTPUT_MEMORY) {
|
||||||
|
if (!outfile) {
|
||||||
/* compute default outfile name */
|
/* 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,
|
pstrcpy(objfilename, sizeof(objfilename) - 1,
|
||||||
|
/* strip path */
|
||||||
tcc_basename(files[0]));
|
tcc_basename(files[0]));
|
||||||
/* add .o extension */
|
#ifdef TCC_TARGET_PE
|
||||||
ext = strrchr(objfilename, '.');
|
pe_guess_outfile(objfilename, output_type);
|
||||||
|
#else
|
||||||
|
if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
|
||||||
|
char *ext = strrchr(objfilename, '.');
|
||||||
if (!ext)
|
if (!ext)
|
||||||
goto default_outfile;
|
goto default_outfile;
|
||||||
|
/* add .o extension */
|
||||||
strcpy(ext + 1, "o");
|
strcpy(ext + 1, "o");
|
||||||
} else {
|
} else {
|
||||||
default_outfile:
|
default_outfile:
|
||||||
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
outfile = objfilename;
|
outfile = objfilename;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (do_bench) {
|
if (do_bench) {
|
||||||
start_time = getclock_us();
|
start_time = getclock_us();
|
||||||
|
11
tccelf.c
11
tccelf.c
@ -2095,7 +2095,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
|||||||
{
|
{
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Shdr *shdr, *sh, *sh1;
|
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_Sym *sym, *dynsym;
|
||||||
Elf32_Dyn *dt, *dynamic;
|
Elf32_Dyn *dt, *dynamic;
|
||||||
unsigned char *dynstr;
|
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)
|
if (sym_bind == STB_LOCAL)
|
||||||
continue;
|
continue;
|
||||||
name = dynstr + sym->st_name;
|
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,
|
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 */
|
/* load all referenced DLLs */
|
||||||
|
85
tccpe.c
85
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)
|
ST void pe_build_exports(struct pe_info *pe)
|
||||||
{
|
{
|
||||||
Elf32_Sym *sym;
|
Elf32_Sym *sym;
|
||||||
DWORD func_offset;
|
DWORD func_offset, voffset;
|
||||||
DWORD voffset = pe->thunk->sh_addr - pe->imagebase;
|
|
||||||
struct pe_export_header *hdr;
|
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 simplicity only functions are exported
|
||||||
for_sym_in_symtab(sym)
|
for_sym_in_symtab(sym)
|
||||||
if (sym->st_shndx != text_section->sh_num)
|
{
|
||||||
sym->st_other &= ~1;
|
if ((sym->st_other & 1)
|
||||||
else if (sym->st_other & 1)
|
&& sym->st_shndx == text_section->sh_num)
|
||||||
++sym_count;
|
dynarray_add((void***)&sorted, &sym_count, (void*)n);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
if (0 == sym_count)
|
if (0 == sym_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
qsort (sorted, sym_count, sizeof sorted[0], sym_cmp);
|
||||||
pe_align_section(pe->thunk, 16);
|
pe_align_section(pe->thunk, 16);
|
||||||
|
|
||||||
pe->exp_offs = pe->thunk->data_offset;
|
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->NumberOfFunctions = sym_count;
|
||||||
hdr->NumberOfNames = sym_count;
|
hdr->NumberOfNames = sym_count;
|
||||||
hdr->AddressOfFunctions = func_offset + voffset;
|
hdr->AddressOfFunctions = func_offset + voffset;
|
||||||
hdr->AddressOfNames =
|
hdr->AddressOfNames = hdr->AddressOfFunctions + sym_count * sizeof(DWORD);
|
||||||
hdr->AddressOfFunctions + sym_count * sizeof(DWORD);
|
hdr->AddressOfNameOrdinals = hdr->AddressOfNames + sym_count * sizeof(DWORD);
|
||||||
hdr->AddressOfNameOrdinals =
|
|
||||||
hdr->AddressOfNames + sym_count * sizeof(DWORD);
|
|
||||||
hdr->Name = pe->thunk->data_offset + voffset;
|
hdr->Name = pe->thunk->data_offset + voffset;
|
||||||
put_elf_str(pe->thunk, tcc_basename(pe->filename));
|
put_elf_str(pe->thunk, tcc_basename(pe->filename));
|
||||||
|
|
||||||
for_sym_in_symtab(sym)
|
for (ord = 0; ord < sym_count; ++ord)
|
||||||
if (sym->st_other & 1) {
|
{
|
||||||
char *name = symtab_section->link->data + sym->st_name;
|
char *name; DWORD *p, *pfunc, *pname; WORD *pord;
|
||||||
DWORD *p = (DWORD *) (pe->thunk->data + func_offset);
|
sym = (Elf32_Sym *)symtab_section->data + sorted[ord];
|
||||||
DWORD *pfunc = p + ordinal;
|
name = symtab_section->link->data + sym->st_name;
|
||||||
DWORD *pname = p + sym_count + ordinal;
|
p = (DWORD*)(pe->thunk->data + func_offset);
|
||||||
WORD *pord = (WORD *) (p + 2 * sym_count) + ordinal;
|
pfunc = p + ord;
|
||||||
*pfunc =
|
pname = p + sym_count + ord;
|
||||||
sym->st_value + pe->s1->sections[sym->st_shndx]->sh_addr -
|
pord = (WORD *)(p + 2*sym_count) + ord;
|
||||||
pe->imagebase;
|
*pfunc = sym->st_value + pe->s1->sections[sym->st_shndx]->sh_addr - pe->imagebase;
|
||||||
*pname = pe->thunk->data_offset + voffset;
|
*pname = pe->thunk->data_offset + voffset;
|
||||||
*pord = ordinal;
|
*pord = ord;
|
||||||
put_elf_str(pe->thunk, name);
|
put_elf_str(pe->thunk, name);
|
||||||
/* printf("export: %s\n", name); */
|
/* printf("export: %s\n", name); */
|
||||||
++ordinal;
|
|
||||||
}
|
}
|
||||||
pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
|
pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
|
||||||
|
tcc_free(sorted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
@ -1119,6 +1131,24 @@ int pe_load_def_file(TCCState * s1, FILE * fp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------- */
|
||||||
|
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)
|
unsigned long pe_add_runtime(TCCState * s1)
|
||||||
{
|
{
|
||||||
@ -1127,6 +1157,13 @@ unsigned long pe_add_runtime(TCCState * s1)
|
|||||||
|
|
||||||
if (find_elf_sym(symtab_section, "WinMain"))
|
if (find_elf_sym(symtab_section, "WinMain"))
|
||||||
pe_type = PE_GUI;
|
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 =
|
start_symbol =
|
||||||
TCC_OUTPUT_MEMORY == s1->output_type
|
TCC_OUTPUT_MEMORY == s1->output_type
|
||||||
@ -1192,7 +1229,7 @@ int tcc_output_pe(TCCState * s1, const char *filename)
|
|||||||
{
|
{
|
||||||
Section *s;
|
Section *s;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
f = fopen("tccpe.log", "wb");
|
f = fopen("tccpe.log", "wt");
|
||||||
for (i = 1; i < s1->nb_sections; ++i) {
|
for (i = 1; i < s1->nb_sections; ++i) {
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
pe_print_section(f, s);
|
pe_print_section(f, s);
|
||||||
|
Loading…
Reference in New Issue
Block a user