win32 merge (grischka)

tcc-xref
bellard 2005-04-17 13:15:54 +00:00
parent 09f4ce9857
commit fe9b1f60ce
4 changed files with 186 additions and 145 deletions

31
tcc.c
View File

@ -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();

View File

@ -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
View File

@ -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);