tcctools.c: integrate tiny_libmaker/_impdef
usage:
tcc -ar [rcsv] lib files...
tcc -impdef lib.dll [-v] [-o lib.def]
also:
- support more files with -c: tcc -c f1.c f2.c ...
- fix a bug which caused tcc f1.c f2.S to produce no asm
- allow tcc -ar @listfile too
- change prototype: _void_ tcc_set_options(...)
- apply -Wl,-whole-archive when a librariy is given
as libxxx.a also (not just for -lxxx)
This commit is contained in:
122
tccpe.c
122
tccpe.c
@ -962,7 +962,7 @@ static void pe_build_exports(struct pe_info *pe)
|
||||
} else {
|
||||
fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
|
||||
if (pe->s1->verbose)
|
||||
printf("<- %s (%d symbols)\n", buf, sym_count);
|
||||
printf("<- %s (%d symbol%s)\n", buf, sym_count, "s" + (sym_count < 2));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1543,6 +1543,102 @@ static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
|
||||
return len == read(fd, buffer, len);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
{
|
||||
int l, i, n, n0, ret;
|
||||
char *p;
|
||||
int fd;
|
||||
|
||||
IMAGE_SECTION_HEADER ish;
|
||||
IMAGE_EXPORT_DIRECTORY ied;
|
||||
IMAGE_DOS_HEADER dh;
|
||||
IMAGE_FILE_HEADER ih;
|
||||
DWORD sig, ref, addr, ptr, namep;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
IMAGE_OPTIONAL_HEADER64 oh;
|
||||
#else
|
||||
IMAGE_OPTIONAL_HEADER32 oh;
|
||||
#endif
|
||||
int pef_hdroffset, opt_hdroffset, sec_hdroffset;
|
||||
|
||||
n = n0 = 0;
|
||||
p = NULL;
|
||||
ret = -1;
|
||||
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
goto the_end_1;
|
||||
ret = 1;
|
||||
|
||||
if (!read_mem(fd, 0, &dh, sizeof dh))
|
||||
goto the_end;
|
||||
if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
|
||||
goto the_end;
|
||||
if (sig != 0x00004550)
|
||||
goto the_end;
|
||||
pef_hdroffset = dh.e_lfanew + sizeof sig;
|
||||
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
||||
goto the_end;
|
||||
if (IMAGE_FILE_MACHINE != ih.Machine) {
|
||||
if (ih.Machine == 0x014C)
|
||||
ret = 32;
|
||||
else if (ih.Machine == 0x8664)
|
||||
ret = 64;
|
||||
goto the_end;
|
||||
}
|
||||
opt_hdroffset = pef_hdroffset + sizeof ih;
|
||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||
goto the_end;
|
||||
|
||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||
goto the_end_0;
|
||||
|
||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
//printf("addr: %08x\n", addr);
|
||||
for (i = 0; i < ih.NumberOfSections; ++i) {
|
||||
if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
|
||||
goto the_end;
|
||||
//printf("vaddr: %08x\n", ish.VirtualAddress);
|
||||
if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
|
||||
goto found;
|
||||
}
|
||||
goto the_end_0;
|
||||
|
||||
found:
|
||||
ref = ish.VirtualAddress - ish.PointerToRawData;
|
||||
if (!read_mem(fd, addr - ref, &ied, sizeof ied))
|
||||
goto the_end;
|
||||
|
||||
namep = ied.AddressOfNames - ref;
|
||||
for (i = 0; i < ied.NumberOfNames; ++i) {
|
||||
if (!read_mem(fd, namep, &ptr, sizeof ptr))
|
||||
goto the_end;
|
||||
namep += sizeof ptr;
|
||||
for (l = 0;;) {
|
||||
if (n+1 >= n0)
|
||||
p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
|
||||
if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
|
||||
tcc_free(p), p = NULL;
|
||||
goto the_end;
|
||||
}
|
||||
if (p[n++] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p)
|
||||
p[n] = 0;
|
||||
the_end_0:
|
||||
ret = 0;
|
||||
the_end:
|
||||
close(fd);
|
||||
the_end_1:
|
||||
*pp = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
* This is for compiled windows resources in 'coff' format
|
||||
* as generated by 'windres.exe -O coff ...'.
|
||||
@ -1660,20 +1756,20 @@ quit:
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
|
||||
#include "win32/tools/tiny_impdef.c"
|
||||
|
||||
static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
|
||||
static int pe_load_dll(TCCState *s1, const char *filename)
|
||||
{
|
||||
char *p, *q;
|
||||
int index;
|
||||
p = get_export_names(fd);
|
||||
if (!p)
|
||||
int index, ret;
|
||||
|
||||
ret = tcc_get_dllexports(filename, &p);
|
||||
if (ret) {
|
||||
return -1;
|
||||
index = add_dllref(s1, dllname);
|
||||
for (q = p; *q; q += 1 + strlen(q))
|
||||
pe_putimport(s1, index, q, 0);
|
||||
tcc_free(p);
|
||||
} else if (p) {
|
||||
index = add_dllref(s1, tcc_basename(filename));
|
||||
for (q = p; *q; q += 1 + strlen(q))
|
||||
pe_putimport(s1, index, q, 0);
|
||||
tcc_free(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1687,7 +1783,7 @@ ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
|
||||
else if (pe_load_res(s1, fd) == 0)
|
||||
ret = 0;
|
||||
else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
|
||||
ret = pe_load_dll(s1, tcc_basename(filename), fd);
|
||||
ret = pe_load_dll(s1, filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user