History

tccpe: load dll on the fly

grischka committed 17 years ago

Commit 1df662c1 parent 9fda4f45 files · +313 −227Browse files

Unified · Split

5 files
  1. libtcc.c +127 −86
  2. tcc.h +0 −1
  3. tccelf.c +2 −0
  4. tccpe.c +89 −52
  5. win32/tools/tiny_impdef.c +95 −88
libtcc.c+127−86
@@ -212,9 +212,7 @@ static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); · 211 unmodified lines
212212 int tcc_output_coff(TCCState *s1, FILE *f);
213213
214214 /* tccpe.c */
215−int pe_load_def_file(struct TCCState *s1, int fd);
216−int pe_test_res_file(void *v, int size);
217−int pe_load_res_file(struct TCCState *s1, int fd);
215+int pe_load_file(struct TCCState *s1, const char *filename, int fd);
218216 int pe_output_file(struct TCCState *s1, const char *filename);
219217
220218 /* tccasm.c */
@@ -277,6 +275,7 @@ static int tcc_compile(TCCState *s1); · 56 unmodified lines
277275 void expect(const char *msg);
278276 void skip(int c);
279277 static void test_lvalue(void);
278+void *resolve_sym(TCCState *s1, const char *sym);
280279
281280 static inline int isid(int c)
282281 {
@@ -303,8 +302,6 @@ static inline int toup(int c) · 20 unmodified lines
303302 return c;
304303 }
305304
306−void *resolve_sym(TCCState *s1, const char *sym);
307−
308305 /********************************************************/
309306
310307 #ifdef TCC_TARGET_I386
@@ -352,6 +349,43 @@ static void asm_global_instr(void) · 41 unmodified lines
352349 #include "tccpe.c"
353350 #endif
354351
352+/********************************************************/
353+#ifdef _WIN32
354+char *normalize_slashes(char *path)
355+{
356+ char *p;
357+ for (p = path; *p; ++p)
358+ if (*p == '\\')
359+ *p = '/';
360+ return path;
361+}
362+
363+HMODULE tcc_module;
364+
365+/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
366+void tcc_set_lib_path_w32(TCCState *s)
367+{
368+ char path[1024], *p;
369+ GetModuleFileNameA(tcc_module, path, sizeof path);
370+ p = tcc_basename(normalize_slashes(strlwr(path)));
371+ if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
372+ p -= 5;
373+ else if (p > path)
374+ p--;
375+ *p = 0;
376+ tcc_set_lib_path(s, path);
377+}
378+
379+#ifdef LIBTCC_AS_DLL
380+BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
381+{
382+ if (DLL_PROCESS_ATTACH == dwReason)
383+ tcc_module = hDll;
384+ return TRUE;
385+}
386+#endif
387+#endif
388+
355389 /********************************************************/
356390 #ifdef CONFIG_TCC_STATIC
357391
@@ -393,7 +427,7 @@ static TCCSyms tcc_syms[] = { · 35 unmodified lines
393427 { NULL, NULL },
394428 };
395429
396−void *resolve_sym(TCCState *s1, const char *symbol, int type)
430+void *resolve_sym(TCCState *s1, const char *symbol)
397431 {
398432 TCCSyms *p;
399433 p = tcc_syms;
@@ -405,8 +439,10 @@ void *resolve_sym(TCCState *s1, const char *symbol, int type) · 5 unmodified lines
405439 return NULL;
406440 }
407441
408−#elif !defined(_WIN32)
442+#elif defined(_WIN32)
443+#define dlclose FreeLibrary
409444
445+#else
410446 #include <dlfcn.h>
411447
412448 void *resolve_sym(TCCState *s1, const char *sym)
@@ -1982,9 +2018,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1569 unmodified lines
19822018 {
19832019 const char *ext;
19842020 ElfW(Ehdr) ehdr;
1985− int fd, ret;
2021+ int fd, ret, size;
19862022 BufferedFile *saved_file;
19872023
2024+ ret = -1;
2025+
19882026 /* find source file type with extension */
19892027 ext = tcc_fileextension(filename);
19902028 if (ext[0])
@@ -1994,104 +2032,103 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 3 unmodified lines
19942032 saved_file = file;
19952033 file = tcc_open(s1, filename);
19962034 if (!file) {
1997− if (flags & AFF_PRINT_ERROR) {
2035+ if (flags & AFF_PRINT_ERROR)
19982036 error_noabort("file '%s' not found", filename);
1999− }
2000− ret = -1;
2001− goto fail1;
2037+ goto the_end;
20022038 }
20032039
20042040 if (flags & AFF_PREPROCESS) {
20052041 ret = tcc_preprocess(s1);
2006− } else if (!ext[0] || !PATHCMP(ext, "c")) {
2042+ goto the_end;
2043+ }
2044+
2045+ if (!ext[0] || !PATHCMP(ext, "c")) {
20072046 /* C file assumed */
20082047 ret = tcc_compile(s1);
2009− } else
2048+ goto the_end;
2049+ }
2050+
20102051 #ifdef CONFIG_TCC_ASM
20112052 if (!strcmp(ext, "S")) {
20122053 /* preprocessed assembler */
20132054 ret = tcc_assemble(s1, 1);
2014− } else if (!strcmp(ext, "s")) {
2055+ goto the_end;
2056+ }
2057+
2058+ if (!strcmp(ext, "s")) {
20152059 /* non preprocessed assembler */
20162060 ret = tcc_assemble(s1, 0);
2017− } else
2018−#endif
2019−#ifdef TCC_TARGET_PE
2020− if (!PATHCMP(ext, "def")) {
2021− ret = pe_load_def_file(s1, file->fd);
2022− } else
2061+ goto the_end;
2062+ }
20232063 #endif
2024− {
2025− fd = file->fd;
2026− /* assume executable format: auto guess file type */
2027− ret = read(fd, &ehdr, sizeof(ehdr));
2028− lseek(fd, 0, SEEK_SET);
2029− if (ret <= 0) {
2030− error_noabort("could not read header");
2031− goto fail;
2032− } else if (ret != sizeof(ehdr)) {
2033− goto try_load_script;
2034− }
20352064
2036− if (ehdr.e_ident[0] == ELFMAG0 &&
2037− ehdr.e_ident[1] == ELFMAG1 &&
2038− ehdr.e_ident[2] == ELFMAG2 &&
2039− ehdr.e_ident[3] == ELFMAG3) {
2040− file->line_num = 0; /* do not display line number if error */
2041− if (ehdr.e_type == ET_REL) {
2042− ret = tcc_load_object_file(s1, fd, 0);
2043− } else if (ehdr.e_type == ET_DYN) {
2044− if (s1->output_type == TCC_OUTPUT_MEMORY) {
2045−#ifdef TCC_TARGET_PE
2046− ret = -1;
2047−#else
2048− void *h;
2049− h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
2050− if (h)
2051− ret = 0;
2052− else
2053− ret = -1;
2054−#endif
2055− } else {
2056− ret = tcc_load_dll(s1, fd, filename,
2057− (flags & AFF_REFERENCED_DLL) != 0);
2058− }
2065+ fd = file->fd;
2066+ /* assume executable format: auto guess file type */
2067+ size = read(fd, &ehdr, sizeof(ehdr));
2068+ lseek(fd, 0, SEEK_SET);
2069+ if (size <= 0) {
2070+ error_noabort("could not read header");
2071+ goto the_end;
2072+ }
2073+
2074+ if (size == sizeof(ehdr) &&
2075+ ehdr.e_ident[0] == ELFMAG0 &&
2076+ ehdr.e_ident[1] == ELFMAG1 &&
2077+ ehdr.e_ident[2] == ELFMAG2 &&
2078+ ehdr.e_ident[3] == ELFMAG3) {
2079+
2080+ /* do not display line number if error */
2081+ file->line_num = 0;
2082+ if (ehdr.e_type == ET_REL) {
2083+ ret = tcc_load_object_file(s1, fd, 0);
2084+ goto the_end;
2085+
2086+ }
2087+#ifndef TCC_TARGET_PE
2088+ if (ehdr.e_type == ET_DYN) {
2089+ if (s1->output_type == TCC_OUTPUT_MEMORY) {
2090+ void *h;
2091+ h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
2092+ if (h)
2093+ ret = 0;
20592094 } else {
2060− error_noabort("unrecognized ELF file");
2061− goto fail;
2095+ ret = tcc_load_dll(s1, fd, filename,
2096+ (flags & AFF_REFERENCED_DLL) != 0);
20622097 }
2063− } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
2064− file->line_num = 0; /* do not display line number if error */
2065− ret = tcc_load_archive(s1, fd);
2066− } else
2098+ goto the_end;
2099+ }
2100+#endif
2101+ error_noabort("unrecognized ELF file");
2102+ goto the_end;
2103+ }
2104+
2105+ if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
2106+ file->line_num = 0; /* do not display line number if error */
2107+ ret = tcc_load_archive(s1, fd);
2108+ goto the_end;
2109+ }
2110+
20672111 #ifdef TCC_TARGET_COFF
2068− if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
2069− ret = tcc_load_coff(s1, fd);
2070− } else
2112+ if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
2113+ ret = tcc_load_coff(s1, fd);
2114+ goto the_end;
2115+ }
20712116 #endif
2117+
20722118 #ifdef TCC_TARGET_PE
2073− if (pe_test_res_file(&ehdr, ret)) {
2074− ret = pe_load_res_file(s1, fd);
2075− } else
2119+ ret = pe_load_file(s1, filename, fd);
2120+#else
2121+ /* as GNU ld, consider it is an ld script if not recognized */
2122+ ret = tcc_load_ldscript(s1);
20762123 #endif
2077− {
2078− /* as GNU ld, consider it is an ld script if not recognized */
2079− try_load_script:
2080− ret = tcc_load_ldscript(s1);
2081− if (ret < 0) {
2082− error_noabort("unrecognized file type");
2083− goto fail;
2084− }
2085− }
2086− }
2087− the_end:
2088− tcc_close(file);
2089− fail1:
2124+ if (ret < 0)
2125+ error_noabort("unrecognized file type");
2126+
2127+the_end:
2128+ if (file)
2129+ tcc_close(file);
20902130 file = saved_file;
20912131 return ret;
2092− fail:
2093− ret = -1;
2094− goto the_end;
20952132 }
20962133
20972134 int tcc_add_file(TCCState *s, const char *filename)
@@ -2136,14 +2173,14 @@ int tcc_add_library(TCCState *s, const char *libraryname) · 38 unmodified lines
21362173 /* first we look for the dynamic library if not static linking */
21372174 if (!s->static_link) {
21382175 #ifdef TCC_TARGET_PE
2139− snprintf(buf, sizeof(buf), "%s.def", libraryname);
2176+ if (pe_add_dll(s, libraryname) == 0)
2177+ return 0;
21402178 #else
21412179 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
2142−#endif
21432180 if (tcc_add_dll(s, buf, 0) == 0)
21442181 return 0;
2182+#endif
21452183 }
2146−
21472184 /* then we look for the static library */
21482185 for(i = 0; i < s->nb_library_paths; i++) {
21492186 snprintf(buf, sizeof(buf), "%s/lib%s.a",
@@ -2225,6 +2262,10 @@ int tcc_set_output_type(TCCState *s, int output_type) · 75 unmodified lines
22252262 #ifdef TCC_TARGET_PE
22262263 snprintf(buf, sizeof(buf), "%s/lib", s->tcc_lib_path);
22272264 tcc_add_library_path(s, buf);
2265+#ifdef _WIN32
2266+ if (GetSystemDirectory(buf, sizeof buf))
2267+ tcc_add_library_path(s, buf);
2268+#endif
22282269 #endif
22292270
22302271 return 0;
tcc.h+0−1
@@ -46,7 +46,6 @@ · 45 unmodified lines
4646 #include <direct.h> /* getcwd */
4747 #define inline __inline
4848 #define inp next_inp
49−#define dlclose FreeLibrary
5049 #ifdef _MSC_VER
5150 #define __aligned(n) __declspec(align(n))
5251 #endif
tccelf.c+2−0
@@ -2424,6 +2424,7 @@ static int tcc_load_archive(TCCState *s1, int fd) · 2423 unmodified lines
24242424 return 0;
24252425 }
24262426
2427+#ifndef TCC_TARGET_PE
24272428 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
24282429 is referenced by the user (so it should be added as DT_NEEDED in
24292430 the generated ELF file) */
@@ -2740,3 +2741,4 @@ static int tcc_load_ldscript(TCCState *s1) · 310 unmodified lines
27402741 }
27412742 return 0;
27422743 }
2744+#endif
tccpe.c+89−52
@@ -46,6 +46,19 @@ · 45 unmodified lines
4646 #define TCC_IS_NATIVE
4747 #endif
4848
49+#ifdef _WIN32
50+void dbg_printf (const char *fmt, ...)
51+{
52+ char buffer[4000];
53+ va_list arg;
54+ int x;
55+ va_start(arg, fmt);
56+ x = vsprintf (buffer, fmt, arg);
57+ strcpy(buffer+x, "\n");
58+ OutputDebugString(buffer);
59+}
60+#endif
61+
4962 /* ----------------------------------------------------------- */
5063 #ifndef IMAGE_NT_SIGNATURE
5164 /* ----------------------------------------------------------- */
@@ -442,29 +455,12 @@ struct pe_info { · 390 unmodified lines
442455 int imp_count;
443456 };
444457
445−/* ------------------------------------------------------------- */
446−
447458 #define PE_NUL 0
448459 #define PE_DLL 1
449460 #define PE_GUI 2
450461 #define PE_EXE 3
451462 #define PE_RUN 4
452463
453−void error_noabort(const char *, ...);
454−
455−#ifdef _WIN32
456−void dbg_printf (const char *fmt, ...)
457−{
458− char buffer[4000];
459− va_list arg;
460− int x;
461− va_start(arg, fmt);
462− x = vsprintf (buffer, fmt, arg);
463− strcpy(buffer+x, "\n");
464− OutputDebugString(buffer);
465−}
466−#endif
467−
468464 /* --------------------------------------------*/
469465
470466 ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
@@ -1355,62 +1351,55 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname) · 884 unmodified lines
13551351 }
13561352 #endif
13571353
1358−/* -------------------------------------------------------------
1359− * This is for compiled windows resources in 'coff' format
1360− * as generated by 'windres.exe -O coff ...'.
1361− */
1354+/* ------------------------------------------------------------- */
13621355
1363−PUB_FN int pe_test_res_file(void *v, int size)
1356+ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
13641357 {
1365− struct pe_rsrc_header *p = (struct pe_rsrc_header *)v;
1366− return
1367− size >= IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_SHORT_NAME /* = 28 */
1368− && p->filehdr.Machine == 0x014C
1369− && 1 == p->filehdr.NumberOfSections
1370− && 0 == strcmp(p->sectionhdr.Name, ".rsrc")
1371− ;
1358+ fseek(fp, offset, 0);
1359+ return len == fread(buffer, 1, len, fp);
13721360 }
13731361
1374−ST_FN int read_n(int fd, void *ptr, unsigned size)
1375−{
1376− return size == read(fd, ptr, size);
1377−}
1362+/* -------------------------------------------------------------
1363+ * This is for compiled windows resources in 'coff' format
1364+ * as generated by 'windres.exe -O coff ...'.
1365+ */
13781366
1379−PUB_FN int pe_load_res_file(TCCState *s1, int fd)
1367+ST_FN int pe_load_res(TCCState *s1, FILE *fp)
13801368 {
13811369 struct pe_rsrc_header hdr;
13821370 Section *rsrc_section;
13831371 int i, ret = -1;
13841372 BYTE *ptr;
1373+ unsigned offs;
13851374
1386− lseek (fd, 0, SEEK_SET);
1387− if (!read_n(fd, &hdr, sizeof hdr))
1375+ if (!read_mem(fp, 0, &hdr, sizeof hdr))
13881376 goto quit;
1389− if (!pe_test_res_file(&hdr, sizeof hdr))
1377+
1378+ if (hdr.filehdr.Machine != 0x014C
1379+ || hdr.filehdr.NumberOfSections != 1
1380+ || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0)
13901381 goto quit;
13911382
13921383 rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC);
13931384 ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData);
1394− lseek (fd, hdr.sectionhdr.PointerToRawData, SEEK_SET);
1395− if (!read_n(fd, ptr, hdr.sectionhdr.SizeOfRawData))
1385+ offs = hdr.sectionhdr.PointerToRawData;
1386+ if (!read_mem(fp, offs, ptr, hdr.sectionhdr.SizeOfRawData))
13961387 goto quit;
1397−
1398− lseek (fd, hdr.sectionhdr.PointerToRelocations, SEEK_SET);
1388+ offs = hdr.sectionhdr.PointerToRelocations;
13991389 for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
14001390 {
14011391 struct pe_rsrc_reloc rel;
1402− if (!read_n(fd, &rel, sizeof rel))
1392+ if (!read_mem(fp, offs, &rel, sizeof rel))
14031393 goto quit;
14041394 // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
14051395 if (rel.type != 7) /* DIR32NB */
14061396 goto quit;
14071397 put_elf_reloc(symtab_section, rsrc_section,
14081398 rel.offset, R_XXX_RELATIVE, 0);
1399+ offs += sizeof rel;
14091400 }
14101401 ret = 0;
14111402 quit:
1412− if (ret)
1413− error_noabort("unrecognized resource file format");
14141403 return ret;
14151404 }
14161405
@@ -1439,15 +1428,11 @@ ST_FN char *get_line(char *line, int size, FILE *fp) · 22 unmodified lines
14391428 }
14401429
14411430 /* ------------------------------------------------------------- */
1442−PUB_FN int pe_load_def_file(TCCState *s1, int fd)
1431+ST_FN int pe_load_def(TCCState *s1, FILE *fp)
14431432 {
14441433 DLLReference *dllref;
14451434 int state = 0, ret = -1;
14461435 char line[400], dllname[80], *p;
1447− FILE *fp = fdopen(dup(fd), "rb");
1448−
1449− if (NULL == fp)
1450− goto quit;
14511436
14521437 for (;;) {
14531438 p = get_line(line, sizeof line, fp);
@@ -1485,13 +1470,65 @@ PUB_FN int pe_load_def_file(TCCState *s1, int fd) · 31 unmodified lines
14851470 }
14861471 ret = 0;
14871472 quit:
1488− if (fp)
1473+ return ret;
1474+}
1475+
1476+/* ------------------------------------------------------------- */
1477+#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
1478+#include "win32/tools/tiny_impdef.c"
1479+
1480+ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
1481+{
1482+ int i = 0;
1483+ char *p, *q;
1484+ p = get_export_names(fp);
1485+ if (p) {
1486+ DLLReference *dllref;
1487+ dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
1488+ strcpy(dllref->name, dllname);
1489+ dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1490+ for (q = p, i = 0; *q; ++i) {
1491+ add_elf_sym(s1->dynsymtab_section,
1492+ s1->nb_loaded_dlls, 0,
1493+ ELFW_ST_INFO(STB_GLOBAL, STT_FUNC), 0,
1494+ text_section->sh_num, q);
1495+ q += 1 + strlen(q);
1496+ }
1497+ tcc_free(p);
1498+ }
1499+ return i ? 0 : -1;
1500+}
1501+
1502+/* ------------------------------------------------------------- */
1503+PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)
1504+{
1505+ FILE *fp = fdopen(dup(fd), "rb");
1506+ int ret = -1;
1507+ char buf[10];
1508+ if (fp) {
1509+ if (0 == strcmp(tcc_fileextension(filename), ".def"))
1510+ ret = pe_load_def(s1, fp);
1511+ else if (pe_load_res(s1, fp) == 0)
1512+ ret = 0;
1513+ else if (read_mem(fp, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
1514+ ret = pe_load_dll(s1, filename, fp);
14891515 fclose(fp);
1490− if (ret)
1491− error_noabort("unrecognized export definition file format");
1516+ }
14921517 return ret;
14931518 }
14941519
1520+int pe_add_dll(struct TCCState *s, const char *libraryname)
1521+{
1522+ char buf[MAX_PATH];
1523+ snprintf(buf, sizeof(buf), "%s.def", libraryname);
1524+ if (tcc_add_dll(s, buf, 0) == 0)
1525+ return 0;
1526+ snprintf(buf, sizeof(buf), "%s.dll", libraryname);
1527+ if (tcc_add_dll(s, buf, 0) == 0)
1528+ return 0;
1529+ return -1;
1530+}
1531+
14951532 /* ------------------------------------------------------------- */
14961533 #ifdef TCC_TARGET_X86_64
14971534 #define PE_STDSYM(n,s) n
win32/tools/tiny_impdef.c+95−88
@@ -20,100 +20,19 @@ · 19 unmodified lines
2020 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2121 */
2222
23+#ifndef TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
24+
2325 #define WIN32_LEAN_AND_MEAN
2426 #include <windows.h>
2527 #include <stdio.h>
2628 #include <malloc.h>
2729 #include "../../config.h"
2830
29−int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
30−{
31− fseek(fp, offset, 0);
32− return len == fread(buffer, 1, len, fp);
33−}
34−
35−char *get_export_names(FILE *fp)
36−{
37− int l, i, n, n0;
38− char *p;
39−
40− IMAGE_SECTION_HEADER ish;
41− IMAGE_EXPORT_DIRECTORY ied;
42− IMAGE_DOS_HEADER dh;
43− IMAGE_FILE_HEADER ih;
44− DWORD sig, ref, addr, ptr, namep;
45−#ifdef TCC_TARGET_X86_64
46− IMAGE_OPTIONAL_HEADER64 oh;
47− const int MACHINE = 0x8664;
48−#else
49− IMAGE_OPTIONAL_HEADER32 oh;
50− const int MACHINE = 0x014C;
51−#endif
52− int pef_hdroffset, opt_hdroffset, sec_hdroffset;
53−
54− n = n0 = 0;
55− p = NULL;
56−
57− if (!read_mem(fp, 0, &dh, sizeof dh))
58− goto the_end;
59− if (!read_mem(fp, dh.e_lfanew, &sig, sizeof sig))
60− goto the_end;
61− if (sig != 0x00004550)
62− goto the_end;
63− pef_hdroffset = dh.e_lfanew + sizeof sig;
64− if (!read_mem(fp, pef_hdroffset, &ih, sizeof ih))
65− goto the_end;
66− if (MACHINE != ih.Machine)
67− goto the_end;
68− opt_hdroffset = pef_hdroffset + sizeof ih;
69− sec_hdroffset = opt_hdroffset + sizeof oh;
70− if (!read_mem(fp, opt_hdroffset, &oh, sizeof oh))
71− goto the_end;
72−
73− if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
74− goto the_end;
75−
76− addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
77− //printf("addr: %08x\n", addr);
78− for (i = 0; i < ih.NumberOfSections; ++i) {
79− if (!read_mem(fp, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
80− goto the_end;
81− //printf("vaddr: %08x\n", ish.VirtualAddress);
82− if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
83− goto found;
84− }
85− goto the_end;
86−
87−found:
88− ref = ish.VirtualAddress - ish.PointerToRawData;
89− if (!read_mem(fp, addr - ref, &ied, sizeof ied))
90− goto the_end;
91−
92− namep = ied.AddressOfNames - ref;
93− for (i = 0; i < ied.NumberOfNames; ++i) {
94− if (!read_mem(fp, namep, &ptr, sizeof ptr))
95− goto the_end;
96− namep += sizeof ptr;
97− for (l = 0;;) {
98− if (n+1 >= n0)
99− p = realloc(p, n0 = n0 ? n0 * 2 : 256);
100− if (!read_mem(fp, ptr - ref + l, p + n, 1) || ++l >= 80) {
101− free(p), p = NULL;
102− goto the_end;
103− }
104− if (p[n++] == 0)
105− break;
106− }
107− }
108− if (p)
109− p[n] = 0;
110−the_end:
111− return p;
112−}
31+char *get_export_names(FILE *fp);
32+#define tcc_free free
33+#define tcc_realloc realloc
11334
114−/* -------------------------------------------------------------- */
11535 /* extract the basename of a file */
116−
11736 static char *file_basename(const char *name)
11837 {
11938 const char *p = strchr(name, 0);
@@ -125,8 +44,6 @@ static char *file_basename(const char *name) · 5 unmodified lines
12544 return (char*)p;
12645 }
12746
128−/* -------------------------------------------------------------- */
129−
13047 int main(int argc, char **argv)
13148 {
13249 int ret, v, i;
@@ -232,3 +149,93 @@ the_end: · 99 unmodified lines
232149 }
233150
234151 /* -------------------------------------------------------------- */
152+
153+int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
154+{
155+ fseek(fp, offset, 0);
156+ return len == fread(buffer, 1, len, fp);
157+}
158+
159+/* -------------------------------------------------------------- */
160+#endif
161+
162+char *get_export_names(FILE *fp)
163+{
164+ int l, i, n, n0;
165+ char *p;
166+
167+ IMAGE_SECTION_HEADER ish;
168+ IMAGE_EXPORT_DIRECTORY ied;
169+ IMAGE_DOS_HEADER dh;
170+ IMAGE_FILE_HEADER ih;
171+ DWORD sig, ref, addr, ptr, namep;
172+#ifdef TCC_TARGET_X86_64
173+ IMAGE_OPTIONAL_HEADER64 oh;
174+ const int MACHINE = 0x8664;
175+#else
176+ IMAGE_OPTIONAL_HEADER32 oh;
177+ const int MACHINE = 0x014C;
178+#endif
179+ int pef_hdroffset, opt_hdroffset, sec_hdroffset;
180+
181+ n = n0 = 0;
182+ p = NULL;
183+
184+ if (!read_mem(fp, 0, &dh, sizeof dh))
185+ goto the_end;
186+ if (!read_mem(fp, dh.e_lfanew, &sig, sizeof sig))
187+ goto the_end;
188+ if (sig != 0x00004550)
189+ goto the_end;
190+ pef_hdroffset = dh.e_lfanew + sizeof sig;
191+ if (!read_mem(fp, pef_hdroffset, &ih, sizeof ih))
192+ goto the_end;
193+ if (MACHINE != ih.Machine)
194+ goto the_end;
195+ opt_hdroffset = pef_hdroffset + sizeof ih;
196+ sec_hdroffset = opt_hdroffset + sizeof oh;
197+ if (!read_mem(fp, opt_hdroffset, &oh, sizeof oh))
198+ goto the_end;
199+
200+ if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
201+ goto the_end;
202+
203+ addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
204+ //printf("addr: %08x\n", addr);
205+ for (i = 0; i < ih.NumberOfSections; ++i) {
206+ if (!read_mem(fp, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
207+ goto the_end;
208+ //printf("vaddr: %08x\n", ish.VirtualAddress);
209+ if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
210+ goto found;
211+ }
212+ goto the_end;
213+
214+found:
215+ ref = ish.VirtualAddress - ish.PointerToRawData;
216+ if (!read_mem(fp, addr - ref, &ied, sizeof ied))
217+ goto the_end;
218+
219+ namep = ied.AddressOfNames - ref;
220+ for (i = 0; i < ied.NumberOfNames; ++i) {
221+ if (!read_mem(fp, namep, &ptr, sizeof ptr))
222+ goto the_end;
223+ namep += sizeof ptr;
224+ for (l = 0;;) {
225+ if (n+1 >= n0)
226+ p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
227+ if (!read_mem(fp, ptr - ref + l, p + n, 1) || ++l >= 80) {
228+ tcc_free(p), p = NULL;
229+ goto the_end;
230+ }
231+ if (p[n++] == 0)
232+ break;
233+ }
234+ }
235+ if (p)
236+ p[n] = 0;
237+the_end:
238+ return p;
239+}
240+
241+/* -------------------------------------------------------------- */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t