From 2d3b9559bf569f137cefb7f8386a0dc58e33c81f Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 18 Feb 2017 09:55:34 +0100 Subject: 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) --- win32/tools/tiny_impdef.c | 249 --------------------------------------- win32/tools/tiny_libmaker.c | 278 -------------------------------------------- 2 files changed, 527 deletions(-) delete mode 100644 win32/tools/tiny_impdef.c delete mode 100644 win32/tools/tiny_libmaker.c (limited to 'win32/tools') diff --git a/win32/tools/tiny_impdef.c b/win32/tools/tiny_impdef.c deleted file mode 100644 index b6debe6..0000000 --- a/win32/tools/tiny_impdef.c +++ /dev/null @@ -1,249 +0,0 @@ -/* -------------------------------------------------------------- */ -/* - * tiny_impdef creates an export definition file (.def) from a dll - * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]" - * - * Copyright (c) 2005,2007 grischka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef TINY_IMPDEF_GET_EXPORT_NAMES_ONLY - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include - -static char *get_export_names(int fd); -#define tcc_free free -#define tcc_realloc realloc - -/* extract the basename of a file */ -static char *file_basename(const char *name) -{ - const char *p = strchr(name, 0); - while (p > name - && p[-1] != '/' - && p[-1] != '\\' - ) - --p; - return (char*)p; -} - -int main(int argc, char **argv) -{ - int ret, v, i; - char infile[MAX_PATH]; - char outfile[MAX_PATH]; - - static const char *ext[] = { ".dll", ".exe", NULL }; - const char *file, **pp; - char path[MAX_PATH], *p, *q; - FILE *fp, *op; - - infile[0] = 0; - outfile[0] = 0; - fp = op = NULL; - v = 0; - ret = 1; - p = NULL; - - for (i = 1; i < argc; ++i) { - const char *a = argv[i]; - if ('-' == a[0]) { - if (0 == strcmp(a, "-v")) { - v = 1; - } else if (0 == strcmp(a, "-o")) { - if (++i == argc) - goto usage; - strcpy(outfile, argv[i]); - } else - goto usage; - } else if (0 == infile[0]) - strcpy(infile, a); - else - goto usage; - } - - if (0 == infile[0]) { -usage: - fprintf(stderr, - "tiny_impdef: create export definition file (.def) from a dll\n" - "Usage: tiny_impdef library.dll [-o outputfile]\n" - ); - goto the_end; - } - - if (0 == outfile[0]) - { - strcpy(outfile, file_basename(infile)); - q = strrchr(outfile, '.'); - if (NULL == q) - q = strchr(outfile, 0); - strcpy(q, ".def"); - } - - file = infile; - -#ifdef _WIN32 - pp = ext; - do if (SearchPath(NULL, file, *pp, sizeof path, path, NULL)) { - file = path; - break; - } while (*pp++); -#endif - - fp = fopen(file, "rb"); - if (NULL == fp) { - fprintf(stderr, "tiny_impdef: no such file: %s\n", infile); - goto the_end; - } - if (v) - printf("--> %s\n", file); - - p = get_export_names(fileno(fp)); - if (NULL == p) { - fprintf(stderr, "tiny_impdef: could not get exported function names.\n"); - goto the_end; - } - - op = fopen(outfile, "w"); - if (NULL == op) { - fprintf(stderr, "tiny_impdef: could not create output file: %s\n", outfile); - goto the_end; - } - - fprintf(op, "LIBRARY %s\n\nEXPORTS\n", file_basename(file)); - for (q = p, i = 0; *q; ++i) { - fprintf(op, "%s\n", q); - q += strlen(q) + 1; - } - - if (v) { - printf("<-- %s\n", outfile); - printf("%d symbol(s) found\n", i); - } - - ret = 0; - -the_end: - if (p) - free(p); - if (fp) - fclose(fp); - if (op) - fclose(op); - return ret; -} - -int read_mem(int fd, unsigned offset, void *buffer, unsigned len) -{ - lseek(fd, offset, SEEK_SET); - return len == read(fd, buffer, len); -} - -/* -------------------------------------------------------------- */ - -#if defined TCC_TARGET_X86_64 -# define IMAGE_FILE_MACHINE 0x8664 -#elif defined TCC_TARGET_ARM -# define IMAGE_FILE_MACHINE 0x01C0 -#elif 1 /* defined TCC_TARGET_I386 */ -# define IMAGE_FILE_MACHINE 0x014C -#endif - -/* -------------------------------------------------------------- */ -#endif - -static char *get_export_names(int fd) -{ - int l, i, n, n0; - char *p; - - 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; - - 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) - 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; - - 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; - -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: - return p; -} - -/* -------------------------------------------------------------- */ diff --git a/win32/tools/tiny_libmaker.c b/win32/tools/tiny_libmaker.c deleted file mode 100644 index a694915..0000000 --- a/win32/tools/tiny_libmaker.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * This program is for making libtcc1.a without ar - * tiny_libmaker - tiny elf lib maker - * usage: tiny_libmaker [lib] files... - * Copyright (c) 2007 Timppa - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include "../../elf.h" - -#ifdef TCC_TARGET_X86_64 -# define ELFCLASSW ELFCLASS64 -# define ElfW(type) Elf##64##_##type -# define ELFW(type) ELF##64##_##type -#else -# define ELFCLASSW ELFCLASS32 -# define ElfW(type) Elf##32##_##type -# define ELFW(type) ELF##32##_##type -#endif - -#define ARMAG "!\n" -#define ARFMAG "`\n" - -typedef struct ArHdr { - char ar_name[16]; - char ar_date[12]; - char ar_uid[6]; - char ar_gid[6]; - char ar_mode[8]; - char ar_size[10]; - char ar_fmag[2]; -} ArHdr; - -unsigned long le2belong(unsigned long ul) { - return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) + - ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8); -} - -ArHdr arhdr = { - "/ ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -ArHdr arhdro = { - " ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -/* Returns 1 if s contains any of the chars of list, else 0 */ -int contains_any(const char *s, const char *list) { - const char *l; - for (; *s; s++) { - for (l = list; *l; l++) { - if (*s == *l) - return 1; - } - } - return 0; -} - -int usage(int ret) { - fprintf(stderr, "usage: tiny_libmaker [rcsv] lib file...\n"); - fprintf(stderr, "Always creates a new lib. [abdioptxN] are explicitly rejected.\n"); - return ret; -} - -int main(int argc, char **argv) -{ - FILE *fi, *fh = NULL, *fo = NULL; - ElfW(Ehdr) *ehdr; - ElfW(Shdr) *shdr; - ElfW(Sym) *sym; - int i, fsize, i_lib, i_obj; - char *buf, *shstr, *symtab = NULL, *strtab = NULL; - int symtabsize = 0;//, strtabsize = 0; - char *anames = NULL; - int *afpos = NULL; - int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs; - char tfile[260], stmp[20]; - char *file, *name; - int ret = 2; - char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored. - int verbose = 0; - - i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj - for (i = 1; i < argc; i++) { - const char *a = argv[i]; - if (*a == '-' && strstr(a, ".")) - return usage(1); // -x.y is always invalid (same as gnu ar) - if ((*a == '-') || (i == 1 && !strstr(a, "."))) { // options argument - if (contains_any(a, ops_conflict)) - return usage(1); - if (strstr(a, "v")) - verbose = 1; - } else { // lib or obj files: don't abort - keep validating all args. - if (!i_lib) // first file is the lib - i_lib = i; - else if (!i_obj) // second file is the first obj - i_obj = i; - } - } - if (!i_obj) // i_obj implies also i_lib. we require both. - return usage(1); - - if ((fh = fopen(argv[i_lib], "wb")) == NULL) - { - fprintf(stderr, "Can't open file %s \n", argv[i_lib]); - goto the_end; - } - - sprintf(tfile, "%s.tmp", argv[i_lib]); - if ((fo = fopen(tfile, "wb+")) == NULL) - { - fprintf(stderr, "Can't create temporary file %s\n", tfile); - goto the_end; - } - - funcmax = 250; - afpos = realloc(NULL, funcmax * sizeof *afpos); // 250 func - memcpy(&arhdro.ar_mode, "100666", 6); - - // i_obj = first input object file - while (i_obj < argc) - { - if (*argv[i_obj] == '-') { // by now, all options start with '-' - i_obj++; - continue; - } - if (verbose) - printf("a - %s\n", argv[i_obj]); - - if ((fi = fopen(argv[i_obj], "rb")) == NULL) - { - fprintf(stderr, "Can't open file %s \n", argv[i_obj]); - goto the_end; - } - fseek(fi, 0, SEEK_END); - fsize = ftell(fi); - fseek(fi, 0, SEEK_SET); - buf = malloc(fsize + 1); - fread(buf, fsize, 1, fi); - fclose(fi); - - // elf header - ehdr = (ElfW(Ehdr) *)buf; - if (ehdr->e_ident[4] != ELFCLASSW) - { - fprintf(stderr, "Unsupported Elf Class: %s\n", argv[i_obj]); - goto the_end; - } - - shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); - shstr = (char *)(buf + shdr->sh_offset); - for (i = 0; i < ehdr->e_shnum; i++) - { - shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize); - if (!shdr->sh_offset) - continue; - if (shdr->sh_type == SHT_SYMTAB) - { - symtab = (char *)(buf + shdr->sh_offset); - symtabsize = shdr->sh_size; - } - if (shdr->sh_type == SHT_STRTAB) - { - if (!strcmp(shstr + shdr->sh_name, ".strtab")) - { - strtab = (char *)(buf + shdr->sh_offset); - //strtabsize = shdr->sh_size; - } - } - } - - if (symtab && symtabsize) - { - int nsym = symtabsize / sizeof(ElfW(Sym)); - //printf("symtab: info size shndx name\n"); - for (i = 1; i < nsym; i++) - { - sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym))); - if (sym->st_shndx && - (sym->st_info == 0x10 - || sym->st_info == 0x11 - || sym->st_info == 0x12 - )) { - //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name); - istrlen = strlen(strtab + sym->st_name)+1; - anames = realloc(anames, strpos+istrlen); - strcpy(anames + strpos, strtab + sym->st_name); - strpos += istrlen; - if (++funccnt >= funcmax) { - funcmax += 250; - afpos = realloc(afpos, funcmax * sizeof *afpos); // 250 func more - } - afpos[funccnt] = fpos; - } - } - } - - file = argv[i_obj]; - for (name = strchr(file, 0); - name > file && name[-1] != '/' && name[-1] != '\\'; - --name); - istrlen = strlen(name); - if (istrlen >= sizeof(arhdro.ar_name)) - istrlen = sizeof(arhdro.ar_name) - 1; - memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name)); - memcpy(arhdro.ar_name, name, istrlen); - arhdro.ar_name[istrlen] = '/'; - sprintf(stmp, "%-10d", fsize); - memcpy(&arhdro.ar_size, stmp, 10); - fwrite(&arhdro, sizeof(arhdro), 1, fo); - fwrite(buf, fsize, 1, fo); - free(buf); - i_obj++; - fpos += (fsize + sizeof(arhdro)); - } - hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int); - fpos = 0; - if ((hofs & 1)) // align - hofs++, fpos = 1; - // write header - fwrite("!\n", 8, 1, fh); - sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int))); - memcpy(&arhdr.ar_size, stmp, 10); - fwrite(&arhdr, sizeof(arhdr), 1, fh); - afpos[0] = le2belong(funccnt); - for (i=1; i<=funccnt; i++) - afpos[i] = le2belong(afpos[i] + hofs); - fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh); - fwrite(anames, strpos, 1, fh); - if (fpos) - fwrite("", 1, 1, fh); - // write objects - fseek(fo, 0, SEEK_END); - fsize = ftell(fo); - fseek(fo, 0, SEEK_SET); - buf = malloc(fsize + 1); - fread(buf, fsize, 1, fo); - fwrite(buf, fsize, 1, fh); - free(buf); - ret = 0; -the_end: - if (anames) - free(anames); - if (afpos) - free(afpos); - if (fh) - fclose(fh); - if (fo) - fclose(fo), remove(tfile); - return ret; -} -- cgit v1.3.1