tccpe: build IAT vector with with -run too
[tinycc/k1w1.git] / win32 / tools / tiny_libmaker.c
blobcf9ac67bc0241b6aa38be7edd941ad97e0eff2b5
1 /*
2 * This program is for making libtcc1.a without ar
3 * tiny_libmaker - tiny elf lib maker
4 * usage: tiny_libmaker [lib] files...
5 * Copyright (c) 2007 Timppa
7 * This program is free software but WITHOUT ANY WARRANTY
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #ifdef _WIN32
13 #include <io.h> /* for mktemp */
14 #endif
16 /* #include "ar-elf.h" */
17 /* "ar-elf.h" */
18 /* ELF_v1.2.pdf */
19 typedef unsigned short int Elf32_Half;
20 typedef int Elf32_Sword;
21 typedef unsigned int Elf32_Word;
22 typedef unsigned int Elf32_Addr;
23 typedef unsigned int Elf32_Off;
24 typedef unsigned short int Elf32_Section;
26 #define EI_NIDENT 16
27 typedef struct {
28 unsigned char e_ident[EI_NIDENT];
29 Elf32_Half e_type;
30 Elf32_Half e_machine;
31 Elf32_Word e_version;
32 Elf32_Addr e_entry;
33 Elf32_Off e_phoff;
34 Elf32_Off e_shoff;
35 Elf32_Word e_flags;
36 Elf32_Half e_ehsize;
37 Elf32_Half e_phentsize;
38 Elf32_Half e_phnum;
39 Elf32_Half e_shentsize;
40 Elf32_Half e_shnum;
41 Elf32_Half e_shstrndx;
42 } Elf32_Ehdr;
44 typedef struct {
45 Elf32_Word sh_name;
46 Elf32_Word sh_type;
47 Elf32_Word sh_flags;
48 Elf32_Addr sh_addr;
49 Elf32_Off sh_offset;
50 Elf32_Word sh_size;
51 Elf32_Word sh_link;
52 Elf32_Word sh_info;
53 Elf32_Word sh_addralign;
54 Elf32_Word sh_entsize;
55 } Elf32_Shdr;
57 #define SHT_NULL 0
58 #define SHT_PROGBITS 1
59 #define SHT_SYMTAB 2
60 #define SHT_STRTAB 3
61 #define SHT_RELA 4
62 #define SHT_HASH 5
63 #define SHT_DYNAMIC 6
64 #define SHT_NOTE 7
65 #define SHT_NOBITS 8
66 #define SHT_REL 9
67 #define SHT_SHLIB 10
68 #define SHT_DYNSYM 11
70 typedef struct {
71 Elf32_Word st_name;
72 Elf32_Addr st_value;
73 Elf32_Word st_size;
74 unsigned char st_info;
75 unsigned char st_other;
76 Elf32_Half st_shndx;
77 } Elf32_Sym;
79 #define ELF32_ST_BIND(i) ((i)>>4)
80 #define ELF32_ST_TYPE(i) ((i)&0xf)
81 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
83 #define STT_NOTYPE 0
84 #define STT_OBJECT 1
85 #define STT_FUNC 2
86 #define STT_SECTION 3
87 #define STT_FILE 4
88 #define STT_LOPROC 13
89 #define STT_HIPROC 15
91 #define STB_LOCAL 0
92 #define STB_GLOBAL 1
93 #define STB_WEAK 2
94 #define STB_LOPROC 13
95 #define STB_HIPROC 15
97 typedef struct {
98 Elf32_Word p_type;
99 Elf32_Off p_offset;
100 Elf32_Addr p_vaddr;
101 Elf32_Addr p_paddr;
102 Elf32_Word p_filesz;
103 Elf32_Word p_memsz;
104 Elf32_Word p_flags;
105 Elf32_Word p_align;
106 } Elf32_Phdr;
107 /* "ar-elf.h" ends */
109 #define ARMAG "!<arch>\n"
110 #define ARFMAG "`\n"
112 typedef struct ArHdr {
113 char ar_name[16];
114 char ar_date[12];
115 char ar_uid[6];
116 char ar_gid[6];
117 char ar_mode[8];
118 char ar_size[10];
119 char ar_fmag[2];
120 } ArHdr;
123 unsigned long le2belong(unsigned long ul) {
124 return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
125 ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
128 ArHdr arhdr = {
129 "/ ",
130 " ",
131 "0 ",
132 "0 ",
133 "0 ",
134 " ",
135 ARFMAG
138 ArHdr arhdro = {
139 " ",
140 " ",
141 "0 ",
142 "0 ",
143 "0 ",
144 " ",
145 ARFMAG
148 int main(int argc, char **argv)
150 FILE *fi, *fh, *fo;
151 Elf32_Ehdr *ehdr;
152 Elf32_Shdr *shdr;
153 Elf32_Sym *sym;
154 int i, fsize, iarg;
155 char *buf, *shstr, *symtab = NULL, *strtab = NULL;
156 int symtabsize = 0, strtabsize = 0;
157 char *anames = NULL;
158 int *afpos = NULL;
159 int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
160 char afile[260], tfile[260], stmp[20];
163 strcpy(afile, "ar_test.a");
164 iarg = 1;
166 if (argc < 2)
168 printf("usage: tiny_libmaker [lib] file...\n");
169 return 1;
171 for (i=1; i<argc; i++) {
172 istrlen = strlen(argv[i]);
173 if (argv[i][istrlen-2] == '.') {
174 if(argv[i][istrlen-1] == 'a')
175 strcpy(afile, argv[i]);
176 else if(argv[i][istrlen-1] == 'o') {
177 iarg = i;
178 break;
183 strcpy(tfile, "./XXXXXX");
184 if (!mktemp(tfile) || (fo = fopen(tfile, "wb+")) == NULL)
186 fprintf(stderr, "Can't open temporary file %s\n", tfile);
187 return 2;
190 if ((fh = fopen(afile, "wb")) == NULL)
192 fprintf(stderr, "Can't open file %s \n", afile);
193 remove(tfile);
194 return 2;
197 funcmax = 250;
198 afpos = realloc(NULL, funcmax * sizeof *afpos); // 250 func
199 memcpy(&arhdro.ar_mode, "100666", 6);
201 //iarg = 1;
202 while (iarg < argc)
204 if (!strcmp(argv[iarg], "rcs")) {
205 iarg++;
206 continue;
208 if ((fi = fopen(argv[iarg], "rb")) == NULL)
210 fprintf(stderr, "Can't open file %s \n", argv[iarg]);
211 remove(tfile);
212 return 2;
214 fseek(fi, 0, SEEK_END);
215 fsize = ftell(fi);
216 fseek(fi, 0, SEEK_SET);
217 buf = malloc(fsize + 1);
218 fread(buf, fsize, 1, fi);
219 fclose(fi);
221 printf("%s:\n", argv[iarg]);
222 // elf header
223 ehdr = (Elf32_Ehdr *)buf;
224 shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
225 shstr = (char *)(buf + shdr->sh_offset);
226 for (i = 0; i < ehdr->e_shnum; i++)
228 shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
229 if (!shdr->sh_offset) continue;
230 if (shdr->sh_type == SHT_SYMTAB)
232 symtab = (char *)(buf + shdr->sh_offset);
233 symtabsize = shdr->sh_size;
235 if (shdr->sh_type == SHT_STRTAB)
237 if (!strcmp(shstr + shdr->sh_name, ".strtab"))
239 strtab = (char *)(buf + shdr->sh_offset);
240 strtabsize = shdr->sh_size;
245 if (symtab && symtabsize)
247 int nsym = symtabsize / sizeof(Elf32_Sym);
248 //printf("symtab: info size shndx name\n");
249 for (i = 1; i < nsym; i++)
251 sym = (Elf32_Sym *) (symtab + i * sizeof(Elf32_Sym));
252 if (sym->st_shndx && (sym->st_info == 0x11 || sym->st_info == 0x12)) {
253 //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
254 istrlen = strlen(strtab + sym->st_name)+1;
255 anames = realloc(anames, strpos+istrlen);
256 strcpy(anames + strpos, strtab + sym->st_name);
257 strpos += istrlen;
258 if (++funccnt >= funcmax) {
259 funcmax += 250;
260 afpos = realloc(afpos, funcmax * sizeof *afpos); // 250 func more
262 afpos[funccnt] = fpos;
266 memset(&arhdro.ar_name, ' ', sizeof(arhdr.ar_name));
267 strcpy(arhdro.ar_name, argv[iarg]);
268 arhdro.ar_name[strlen(argv[iarg])] = '/';
269 sprintf(stmp, "%-10d", fsize);
270 memcpy(&arhdro.ar_size, stmp, 10);
271 fwrite(&arhdro, sizeof(arhdro), 1, fo);
272 fwrite(buf, fsize, 1, fo);
273 free(buf);
274 iarg++;
275 fpos += (fsize + sizeof(arhdro));
277 hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
278 if ((hofs & 1)) { // align
279 hofs++;
280 fpos = 1;
281 } else fpos = 0;
282 // write header
283 fwrite("!<arch>\n", 8, 1, fh);
284 sprintf(stmp, "%-10d", strpos + (funccnt+1) * sizeof(int));
285 memcpy(&arhdr.ar_size, stmp, 10);
286 fwrite(&arhdr, sizeof(arhdr), 1, fh);
287 afpos[0] = le2belong(funccnt);
288 for (i=1; i<=funccnt; i++) {
289 afpos[i] = le2belong(afpos[i] + hofs);
291 fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
292 fwrite(anames, strpos, 1, fh);
293 if (fpos) fwrite("", 1, 1, fh);
294 // write objects
295 fseek(fo, 0, SEEK_END);
296 fsize = ftell(fo);
297 fseek(fo, 0, SEEK_SET);
298 buf = malloc(fsize + 1);
299 fread(buf, fsize, 1, fo);
300 fclose(fo);
301 fwrite(buf, fsize, 1, fh);
302 fclose(fh);
303 free(buf);
304 if (anames)
305 free(anames);
306 if (afpos)
307 free(afpos);
308 remove(tfile);
309 return 0;