History

macos: Tidy code

Michael Matz committed 6 years ago

Commit ac86fb51 parent c86760c1 file · +195 −231Browse files

Unified · Split

tccmacho.c+195−231
@@ -1,5 +1,5 @@
11 /*
2− * Mach-O file handling for TCC
2+ * Mach-O file handling for TCC
33 *
44 * This library is free software; you can redistribute it and/or
55 * modify it under the terms of the GNU Lesser General Public
@@ -20,14 +20,32 @@ · 14 unmodified lines
2020 #define DEBUG_MACHO 0
2121 #define dprintf if (DEBUG_MACHO) printf
2222
23+struct fat_header {
24+ uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
25+ uint32_t nfat_arch; /* number of structs that follow */
26+};
27+
28+struct fat_arch {
29+ int cputype; /* cpu specifier (int) */
30+ int cpusubtype; /* machine specifier (int) */
31+ uint32_t offset; /* file offset to this object file */
32+ uint32_t size; /* size of this object file */
33+ uint32_t align; /* alignment as a power of 2 */
34+};
35+
36+#define FAT_MAGIC 0xcafebabe
37+#define FAT_CIGAM 0xbebafeca
38+#define FAT_MAGIC_64 0xcafebabf
39+#define FAT_CIGAM_64 0xbfbafeca
40+
2341 struct mach_header {
24− uint32_t magic; /* mach magic number identifier */
25− int cputype; /* cpu specifier */
26− int cpusubtype; /* machine specifier */
27− uint32_t filetype; /* type of file */
28− uint32_t ncmds; /* number of load commands */
29− uint32_t sizeofcmds; /* the size of all the load commands */
30− uint32_t flags; /* flags */
42+ uint32_t magic; /* mach magic number identifier */
43+ int cputype; /* cpu specifier */
44+ int cpusubtype; /* machine specifier */
45+ uint32_t filetype; /* type of file */
46+ uint32_t ncmds; /* number of load commands */
47+ uint32_t sizeofcmds; /* the size of all the load commands */
48+ uint32_t flags; /* flags */
3149 };
3250
3351 struct mach_header_64 {
@@ -42,95 +60,86 @@ struct mach_header_64 { · 8 unmodified lines
4260 #define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */
4361
4462 struct load_command {
45− uint32_t cmd; /* type of load command */
46− uint32_t cmdsize; /* total size of command in bytes */
63+ uint32_t cmd; /* type of load command */
64+ uint32_t cmdsize; /* total size of command in bytes */
4765 };
4866
49−typedef int vm_prot_t;
67+#define LC_REQ_DYLD 0x80000000
68+#define LC_SYMTAB 0x2
69+#define LC_DYSYMTAB 0xb
70+#define LC_LOAD_DYLIB 0xc
71+#define LC_ID_DYLIB 0xd
72+#define LC_LOAD_DYLINKER 0xe
73+#define LC_SEGMENT_64 0x19
74+#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
75+#define LC_MAIN (0x28|LC_REQ_DYLD)
5076
51−struct segment_command { /* for 32-bit architectures */
52− uint32_t cmd; /* LC_SEGMENT */
53− uint32_t cmdsize; /* includes sizeof section structs */
54− char segname[16]; /* segment name */
55− uint32_t vmaddr; /* memory address of this segment */
56− uint32_t vmsize; /* memory size of this segment */
57− uint32_t fileoff; /* file offset of this segment */
58− uint32_t filesize; /* amount to map from the file */
59− vm_prot_t maxprot; /* maximum VM protection */
60− vm_prot_t initprot; /* initial VM protection */
61− uint32_t nsects; /* number of sections in segment */
62− uint32_t flags; /* flags */
63−};
77+typedef int vm_prot_t;
6478
6579 struct segment_command_64 { /* for 64-bit architectures */
66− uint32_t cmd; /* LC_SEGMENT_64 */
67− uint32_t cmdsize; /* includes sizeof section_64 structs */
68− char segname[16]; /* segment name */
69− uint64_t vmaddr; /* memory address of this segment */
70− uint64_t vmsize; /* memory size of this segment */
71− uint64_t fileoff; /* file offset of this segment */
72− uint64_t filesize; /* amount to map from the file */
73− vm_prot_t maxprot; /* maximum VM protection */
74− vm_prot_t initprot; /* initial VM protection */
75− uint32_t nsects; /* number of sections in segment */
76− uint32_t flags; /* flags */
77−};
78−
79−struct section { /* for 32-bit architectures */
80− char sectname[16]; /* name of this section */
81− char segname[16]; /* segment this section goes in */
82− uint32_t addr; /* memory address of this section */
83− uint32_t size; /* size in bytes of this section */
84− uint32_t offset; /* file offset of this section */
85− uint32_t align; /* section alignment (power of 2) */
86− uint32_t reloff; /* file offset of relocation entries */
87− uint32_t nreloc; /* number of relocation entries */
88− uint32_t flags; /* flags (section type and attributes)*/
89− uint32_t reserved1; /* reserved (for offset or index) */
90− uint32_t reserved2; /* reserved (for count or sizeof) */
80+ uint32_t cmd; /* LC_SEGMENT_64 */
81+ uint32_t cmdsize; /* includes sizeof section_64 structs */
82+ char segname[16]; /* segment name */
83+ uint64_t vmaddr; /* memory address of this segment */
84+ uint64_t vmsize; /* memory size of this segment */
85+ uint64_t fileoff; /* file offset of this segment */
86+ uint64_t filesize; /* amount to map from the file */
87+ vm_prot_t maxprot; /* maximum VM protection */
88+ vm_prot_t initprot; /* initial VM protection */
89+ uint32_t nsects; /* number of sections in segment */
90+ uint32_t flags; /* flags */
9191 };
9292
9393 struct section_64 { /* for 64-bit architectures */
94− char sectname[16]; /* name of this section */
95− char segname[16]; /* segment this section goes in */
96− uint64_t addr; /* memory address of this section */
97− uint64_t size; /* size in bytes of this section */
98− uint32_t offset; /* file offset of this section */
99− uint32_t align; /* section alignment (power of 2) */
100− uint32_t reloff; /* file offset of relocation entries */
101− uint32_t nreloc; /* number of relocation entries */
102− uint32_t flags; /* flags (section type and attributes)*/
103− uint32_t reserved1; /* reserved (for offset or index) */
104− uint32_t reserved2; /* reserved (for count or sizeof) */
105− uint32_t reserved3; /* reserved */
94+ char sectname[16]; /* name of this section */
95+ char segname[16]; /* segment this section goes in */
96+ uint64_t addr; /* memory address of this section */
97+ uint64_t size; /* size in bytes of this section */
98+ uint32_t offset; /* file offset of this section */
99+ uint32_t align; /* section alignment (power of 2) */
100+ uint32_t reloff; /* file offset of relocation entries */
101+ uint32_t nreloc; /* number of relocation entries */
102+ uint32_t flags; /* flags (section type and attributes)*/
103+ uint32_t reserved1; /* reserved (for offset or index) */
104+ uint32_t reserved2; /* reserved (for count or sizeof) */
105+ uint32_t reserved3; /* reserved */
106106 };
107107
108+#define S_REGULAR 0x0
109+#define S_ZEROFILL 0x1
110+#define S_NON_LAZY_SYMBOL_POINTERS 0x6
111+#define S_MOD_INIT_FUNC_POINTERS 0x9
112+#define S_MOD_TERM_FUNC_POINTERS 0xa
113+
114+#define S_ATTR_PURE_INSTRUCTIONS 0x80000000
115+#define S_ATTR_SOME_INSTRUCTIONS 0x00000400
116+
108117 typedef uint32_t lc_str;
109118
110119 struct dylib_command {
111− uint32_t cmd; /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB,
112− LC_REEXPORT_DYLIB */
113− uint32_t cmdsize; /* includes pathname string */
114− lc_str name; /* library's path name */
115− uint32_t timestamp; /* library's build time stamp */
116− uint32_t current_version; /* library's current version number */
117− uint32_t compatibility_version; /* library's compatibility vers number*/
120+ uint32_t cmd; /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB,
121+ LC_REEXPORT_DYLIB */
122+ uint32_t cmdsize; /* includes pathname string */
123+ lc_str name; /* library's path name */
124+ uint32_t timestamp; /* library's build time stamp */
125+ uint32_t current_version; /* library's current version number */
126+ uint32_t compatibility_version; /* library's compatibility vers number*/
118127 };
119128
120129 struct dylinker_command {
121− uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
122− LC_DYLD_ENVIRONMENT */
123− uint32_t cmdsize; /* includes pathname string */
124− lc_str name; /* dynamic linker's path name */
130+ uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
131+ LC_DYLD_ENVIRONMENT */
132+ uint32_t cmdsize; /* includes pathname string */
133+ lc_str name; /* dynamic linker's path name */
125134 };
126135
127136 struct symtab_command {
128− uint32_t cmd; /* LC_SYMTAB */
129− uint32_t cmdsize; /* sizeof(struct symtab_command) */
130− uint32_t symoff; /* symbol table offset */
131− uint32_t nsyms; /* number of symbol table entries */
132− uint32_t stroff; /* string table offset */
133− uint32_t strsize; /* string table size in bytes */
137+ uint32_t cmd; /* LC_SYMTAB */
138+ uint32_t cmdsize; /* sizeof(struct symtab_command) */
139+ uint32_t symoff; /* symbol table offset */
140+ uint32_t nsyms; /* number of symbol table entries */
141+ uint32_t stroff; /* string table offset */
142+ uint32_t strsize; /* string table size in bytes */
134143 };
135144
136145 struct dysymtab_command {
@@ -152,28 +161,19 @@ struct dysymtab_command { · 15 unmodified lines
152161 uint32_t modtaboff; /* file offset to module table */
153162 uint32_t nmodtab; /* number of module table entries */
154163
155− uint32_t extrefsymoff; /* offset to referenced symbol table */
156− uint32_t nextrefsyms; /* number of referenced symbol table entries */
164+ uint32_t extrefsymoff; /* offset to referenced symbol table */
165+ uint32_t nextrefsyms; /* number of referenced symbol table entries */
157166
158− uint32_t indirectsymoff; /* file offset to the indirect symbol table */
159− uint32_t nindirectsyms; /* number of indirect symbol table entries */
167+ uint32_t indirectsymoff;/* file offset to the indirect symbol table */
168+ uint32_t nindirectsyms; /* number of indirect symbol table entries */
160169
161170 uint32_t extreloff; /* offset to external relocation entries */
162171 uint32_t nextrel; /* number of external relocation entries */
163172 uint32_t locreloff; /* offset to local relocation entries */
164173 uint32_t nlocrel; /* number of local relocation entries */
165−
166174 };
167175
168−struct linkedit_data_command {
169− uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
170− LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
171− LC_DYLIB_CODE_SIGN_DRS or
172− LC_LINKER_OPTIMIZATION_HINT. */
173− uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */
174− uint32_t dataoff; /* file offset of data in __LINKEDIT segment */
175− uint32_t datasize; /* file size of data in __LINKEDIT segment */
176−};
176+#define INDIRECT_SYMBOL_LOCAL 0x80000000
177177
178178 struct entry_point_command {
179179 uint32_t cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */
@@ -207,20 +207,24 @@ struct nlist_64 { · 27 unmodified lines
207207 uint64_t n_value; /* value of this symbol (or stab offset) */
208208 };
209209
210+#define N_UNDF 0x0
211+#define N_ABS 0x2
212+#define N_EXT 0x1
213+#define N_SECT 0xe
214+
210215 struct macho {
211216 struct mach_header_64 mh;
212− struct segment_command_64 *seg[4];
213− int nseg;
217+ int seg2lc[4], nseg;
214218 struct load_command **lc;
219+ struct entry_point_command *ep;
215220 int nlc;
216− struct entry_point_command ep;
217221 struct {
218222 Section *s;
219223 int machosect;
220224 } sk_to_sect[sk_last];
221225 int *elfsectomacho;
222226 int *e2msym;
223− Section *linkedit, *symtab, *strtab, *wdata, *indirsyms, *stubs;
227+ Section *symtab, *strtab, *wdata, *indirsyms, *stubs;
224228 int stubsym;
225229 uint32_t ilocal, iextdef, iundef;
226230 };
@@ -228,33 +232,29 @@ struct macho { · 1 unmodified line
228232 #define SHT_LINKEDIT (SHT_LOOS + 42)
229233 #define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */
230234
231−#define LC_REQ_DYLD 0x80000000
232−#define LC_SYMTAB 0x2
233−#define LC_DYSYMTAB 0xb
234−#define LC_LOAD_DYLIB 0xc
235−#define LC_ID_DYLIB 0xd
236−#define LC_LOAD_DYLINKER 0xe
237−#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
238−#define LC_MAIN (0x28|LC_REQ_DYLD)
239−
240−/* Hack for now, 46_grep.c needs fopen, but due to aliasing games
241− in darwin headers it's searching for _fopen also via dlsym. */
242−FILE *_fopen(const char*, const char*);
243−FILE *_fopen(const char * filename, const char *mode)
235+static void * add_lc(struct macho *mo, uint32_t cmd, uint32_t cmdsize)
244236 {
245− return fopen(filename, mode);
237+ struct load_command *lc = tcc_mallocz(cmdsize);
238+ lc->cmd = cmd;
239+ lc->cmdsize = cmdsize;
240+ mo->lc = tcc_realloc(mo->lc, sizeof(mo->lc[0]) * (mo->nlc + 1));
241+ mo->lc[mo->nlc++] = lc;
242+ return lc;
246243 }
247244
248245 static struct segment_command_64 * add_segment(struct macho *mo, char *name)
249246 {
250− struct segment_command_64 *sc = tcc_mallocz(sizeof *sc);
247+ struct segment_command_64 *sc = add_lc(mo, LC_SEGMENT_64, sizeof(*sc));
251248 strncpy(sc->segname, name, 16);
252− sc->cmd = 0x19; // LC_SEGMENT_64
253− sc->cmdsize = sizeof(*sc);
254− mo->seg[mo->nseg++] = sc;
249+ mo->seg2lc[mo->nseg++] = mo->nlc - 1;
255250 return sc;
256251 }
257252
253+static struct segment_command_64 * get_segment(struct macho *mo, int i)
254+{
255+ return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]);
256+}
257+
258258 static int add_section(struct macho *mo, struct segment_command_64 **_seg, char *name)
259259 {
260260 struct segment_command_64 *seg = *_seg;
@@ -273,31 +273,20 @@ static int add_section(struct macho *mo, struct segment_command_64 **_seg, char · 12 unmodified lines
273273
274274 static struct section_64 *get_section(struct segment_command_64 *seg, int i)
275275 {
276− struct section_64 *sec;
277− sec = (struct section_64*)((char*)seg + sizeof(*seg)) + i;
278− return sec;
279−}
280−
281−static void * add_lc(struct macho *mo, void *lc)
282−{
283− mo->lc = tcc_realloc(mo->lc, sizeof(mo->lc[0]) * (mo->nlc + 1));
284− mo->lc[mo->nlc++] = lc;
285− return lc;
276+ return (struct section_64*)((char*)seg + sizeof(*seg)) + i;
286277 }
287278
288279 static void * add_dylib(struct macho *mo, char *name)
289280 {
290281 struct dylib_command *lc;
291282 int sz = (sizeof(*lc) + strlen(name) + 1 + 7) & -8;
292− lc = tcc_mallocz(sz);
293− lc->cmd = LC_LOAD_DYLIB;
294− lc->cmdsize = sz;
283+ lc = add_lc(mo, LC_LOAD_DYLIB, sz);
295284 lc->name = sizeof(*lc);
296285 strcpy((char*)lc + lc->name, name);
297286 lc->timestamp = 2;
298287 lc->current_version = 1 << 16;
299288 lc->compatibility_version = 1 << 16;
300− return add_lc(mo, lc);
289+ return lc;
301290 }
302291
303292 static void check_relocs(TCCState *s1, struct macho *mo)
@@ -335,10 +324,10 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 31 unmodified lines
335324 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
336325 if (sym->st_shndx == SHN_UNDEF)
337326 tcc_error("undefined local symbol???");
338− *pi = 0x80000000; /* INDIRECT_SYMBOL_LOCAL */
327+ *pi = INDIRECT_SYMBOL_LOCAL;
339328 /* The pointer slot we generated must point to the
340329 symbol, whose address is only known after layout,
341− so register a simply relocation for that. */
330+ so register a simple relocation for that. */
342331 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
343332 R_DATA_PTR, sym_index);
344333 } else
@@ -422,10 +411,10 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 77 unmodified lines
422411 case STT_OBJECT:
423412 case STT_FUNC:
424413 case STT_SECTION:
425− n.n_type = 0xe; /* default type is N_SECT */
414+ n.n_type = N_SECT;
426415 break;
427416 case STT_FILE:
428− n.n_type = 2; /* N_ABS */
417+ n.n_type = N_ABS;
429418 break;
430419 default:
431420 tcc_error("unhandled ELF symbol type %d %s",
@@ -434,9 +423,9 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 2 unmodified lines
434423 if (sym->st_shndx == SHN_UNDEF)
435424 tcc_error("should have been rewritten to SHN_FROMDLL");
436425 else if (sym->st_shndx == SHN_FROMDLL)
437− n.n_type = 0 /* N_UNDF */, n.n_sect = 0;
426+ n.n_type = N_UNDF, n.n_sect = 0;
438427 else if (sym->st_shndx == SHN_ABS)
439− n.n_type = 2 /* N_ABS */, n.n_sect = 0;
428+ n.n_type = N_ABS, n.n_sect = 0;
440429 else if (sym->st_shndx >= SHN_LORESERVE)
441430 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);
442431 else if (!mo->elfsectomacho[sym->st_shndx])
@@ -445,7 +434,7 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 2 unmodified lines
445434 else
446435 n.n_sect = mo->elfsectomacho[sym->st_shndx];
447436 if (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL)
448− n.n_type |= 1; /* N_EXT */
437+ n.n_type |= N_EXT;
449438 else if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
450439 tcc_error("weak symbol %s unhandled", name);
451440 n.n_strx = pn->n_strx;
@@ -455,13 +444,9 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 3 unmodified lines
455444
456445 static void convert_symbols(TCCState *s1, struct macho *mo)
457446 {
458− int sym_index, sym_end;
459− struct nlist_64 *pn = (struct nlist_64 *)mo->symtab->data;
460−
461− sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
462− for (sym_index = 1; sym_index < sym_end; ++sym_index) {
463− convert_symbol(s1, mo, pn + sym_index - 1);
464− }
447+ struct nlist_64 *pn;
448+ for_each_elem(mo->symtab, 0, pn, struct nlist_64)
449+ convert_symbol(s1, mo, pn);
465450 }
466451
467452 static int machosymcmp(const void *_a, const void *_b)
@@ -472,6 +457,8 @@ static int machosymcmp(const void *_a, const void *_b) · 4 unmodified lines
472457 ElfSym *sa = (ElfSym *)symtab_section->data + ea;
473458 ElfSym *sb = (ElfSym *)symtab_section->data + eb;
474459 int r;
460+ /* locals, then defined externals, then undefined externals, the
461+ last two sections also by name, otherwise stable sort */
475462 r = (ELFW(ST_BIND)(sb->st_info) == STB_LOCAL)
476463 - (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL);
477464 if (r)
@@ -498,7 +485,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 20 unmodified lines
498485 the symbol now, so its included in the sorting. */
499486 mo->stubs = new_section(s1, "__stubs", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
500487 mo->stubsym = put_elf_sym(s1->symtab, 0, 0,
501− ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE), 0,
488+ ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
502489 mo->stubs->sh_num, ".__stubs");
503490
504491 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
@@ -527,14 +514,15 @@ struct { · 22 unmodified lines
527514 uint32_t flags;
528515 char *name;
529516 } skinfo[sk_last] = {
530− [sk_text] = { 1, 0x80000400, "__text" },
531− [sk_ro_data] = { 1, 0x0, "__rodata" },
532− [sk_nl_ptr] = { 2, 0x6, "__got" }, /* S_NON_LAZY_SYMBOL_POINTERS */
533− [sk_init] = { 2, 0x9, "__mod_init_func" }, /* S_MOD_INIT_FUNC_POINTERS */
534− [sk_fini] = { 2, 0xa, "__mod_term_func" }, /* S_MOD_TERM_FUNC_POINTERS */
535− [sk_rw_data] = { 2, 0x0, "__data" },
536− [sk_bss] = { 2, 0x1, "__bss" }, /* S_ZEROFILL */
537− [sk_linkedit] = { 3, 0x0, NULL },
517+ [sk_text] = { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
518+ | S_ATTR_SOME_INSTRUCTIONS, "__text" },
519+ [sk_ro_data] = { 1, S_REGULAR, "__rodata" },
520+ [sk_nl_ptr] = { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
521+ [sk_init] = { 2, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
522+ [sk_fini] = { 2, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
523+ [sk_rw_data] = { 2, S_REGULAR, "__data" },
524+ [sk_bss] = { 2, S_ZEROFILL, "__bss" },
525+ [sk_linkedit] = { 3, S_REGULAR, NULL },
538526 };
539527
540528 static void collect_sections(TCCState *s1, struct macho *mo)
@@ -547,46 +535,36 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
547535 struct symtab_command *symlc;
548536 struct dysymtab_command *dysymlc;
549537 char *str;
550− //struct segment_command_64 *zc, *tc, *sc, *lc;
551− add_segment(mo, "__PAGEZERO");
552− add_segment(mo, "__TEXT");
553− add_segment(mo, "__DATA");
554− add_segment(mo, "__LINKEDIT");
555− mo->seg[0]->vmsize = (uint64_t)1 << 32;
556− mo->seg[1]->vmaddr = (uint64_t)1 << 32;
557− mo->seg[1]->maxprot = 7; // rwx
558− mo->seg[1]->initprot = 5; // r-x
559− mo->seg[2]->vmaddr = -1;
560− mo->seg[2]->maxprot = 7; // rwx
561− mo->seg[2]->initprot = 3; // rw-
562− mo->seg[3]->vmaddr = -1;
563− mo->seg[3]->maxprot = 7; // rwx
564− mo->seg[3]->initprot = 1; // r--
565−
566− mo->ep.cmd = LC_MAIN;
567− mo->ep.cmdsize = sizeof(mo->ep);
568− mo->ep.entryoff = 4096;
569− mo->ep.stacksize = 0;
570− add_lc(mo, &mo->ep);
538+
539+ seg = add_segment(mo, "__PAGEZERO");
540+ seg->vmsize = (uint64_t)1 << 32;
541+
542+ seg = add_segment(mo, "__TEXT");
543+ seg->vmaddr = (uint64_t)1 << 32;
544+ seg->maxprot = 7; // rwx
545+ seg->initprot = 5; // r-x
546+
547+ seg = add_segment(mo, "__DATA");
548+ seg->vmaddr = -1;
549+ seg->maxprot = 7; // rwx
550+ seg->initprot = 3; // rw-
551+
552+ seg = add_segment(mo, "__LINKEDIT");
553+ seg->vmaddr = -1;
554+ seg->maxprot = 7; // rwx
555+ seg->initprot = 1; // r--
556+
557+ mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
558+ mo->ep->entryoff = 4096;
571559
572560 i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
573− dyldlc = tcc_mallocz(i);
574− dyldlc->cmd = LC_LOAD_DYLINKER;
575− dyldlc->cmdsize = i;
561+ dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
576562 dyldlc->name = sizeof(*dyldlc);
577563 str = (char*)dyldlc + dyldlc->name;
578564 strcpy(str, "/usr/lib/dyld");
579− add_lc(mo, dyldlc);
580565
581− symlc = tcc_mallocz(sizeof(*symlc));
582− symlc->cmd = LC_SYMTAB;
583− symlc->cmdsize = sizeof(*symlc);
584− add_lc(mo, symlc);
585−
586− dysymlc = tcc_mallocz(sizeof(*dysymlc));
587− dysymlc->cmd = LC_DYSYMTAB;
588− dysymlc->cmdsize = sizeof(*dysymlc);
589− add_lc(mo, dysymlc);
566+ symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
567+ dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
590568
591569 for(i = 0; i < s1->nb_loaded_dlls; i++) {
592570 DLLReference *dllref = s1->loaded_dlls[i];
@@ -594,14 +572,9 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 1 unmodified line
594572 add_dylib(mo, dllref->name);
595573 }
596574
597− mo->linkedit = new_section(s1, "LINKEDIT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
598− /* LINKEDIT can't be empty (XXX remove once we have symbol table) */
599− section_ptr_add(mo->linkedit, 256);
600−
601− /* dyld requires a writable segment, but ignores zero-sized segments
602− for this, so force to have some data. */
603− mo->wdata = new_section(s1, " wdata", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
604− section_ptr_add(mo->wdata, 64);
575+ /* dyld requires a writable segment with classic Mach-O, but it ignores
576+ zero-sized segments for this, so force to have some data. */
577+ section_ptr_add(data_section, 1);
605578 memset (mo->sk_to_sect, 0, sizeof(mo->sk_to_sect));
606579 for (i = s1->nb_sections; i-- > 1;) {
607580 int type, flags;
@@ -636,7 +609,7 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 28 unmodified lines
636609 mo->sk_to_sect[sk].s = s;
637610 }
638611 fileofs = 4096; /* leave space for mach-o headers */
639− curaddr = mo->seg[1]->vmaddr;
612+ curaddr = get_segment(mo, 1)->vmaddr;
640613 curaddr += 4096;
641614 seg = NULL;
642615 numsec = 0;
@@ -650,11 +623,11 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 7 unmodified lines
650623 if (skinfo[sk].seg && mo->sk_to_sect[sk].s) {
651624 uint64_t al = 0;
652625 int si;
653− seg = mo->seg[skinfo[sk].seg];
626+ seg = get_segment(mo, skinfo[sk].seg);
654627 if (skinfo[sk].name) {
655628 si = add_section(mo, &seg, skinfo[sk].name);
656629 numsec++;
657− mo->seg[skinfo[sk].seg] = seg;
630+ mo->lc[mo->seg2lc[skinfo[sk].seg]] = (struct load_command*)seg;
658631 mo->sk_to_sect[sk].machosect = si;
659632 sec = get_section(seg, si);
660633 sec->flags = skinfo[sk].flags;
@@ -755,19 +728,13 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 94 unmodified lines
755728 mo->mh.mh.cpusubtype = 0x80000003;// all | CPU_SUBTYPE_LIB64
756729 mo->mh.mh.filetype = 2; // MH_EXECUTE
757730 mo->mh.mh.flags = 4; // DYLDLINK
758− mo->mh.mh.ncmds = mo->nseg + mo->nlc;
731+ mo->mh.mh.ncmds = mo->nlc;
759732 mo->mh.mh.sizeofcmds = 0;
760− for (i = 0; i < mo->nseg; i++)
761− mo->mh.mh.sizeofcmds += mo->seg[i]->cmdsize;
762733 for (i = 0; i < mo->nlc; i++)
763734 mo->mh.mh.sizeofcmds += mo->lc[i]->cmdsize;
764735
765736 fwrite(&mo->mh, 1, sizeof(mo->mh), fp);
766737 fileofs += sizeof(mo->mh);
767− for (i = 0; i < mo->nseg; i++) {
768− fwrite(mo->seg[i], 1, mo->seg[i]->cmdsize, fp);
769− fileofs += mo->seg[i]->cmdsize;
770− }
771738 for (i = 0; i < mo->nlc; i++) {
772739 fwrite(mo->lc[i], 1, mo->lc[i]->cmdsize, fp);
773740 fileofs += mo->lc[i]->cmdsize;
@@ -775,13 +742,9 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 1 unmodified line
775742
776743 for (sk = sk_unknown; sk < sk_last; sk++) {
777744 struct segment_command_64 *seg;
778− //struct section_64 *sec;
779745 if (!skinfo[sk].seg || !mo->sk_to_sect[sk].s)
780746 continue;
781− seg = mo->seg[skinfo[sk].seg];
782− /*sec = get_section(seg, mo->sk_to_sect[sk].machosect);
783− while (fileofs < sec->offset)
784− fputc(0, fp), fileofs++;*/
747+ seg = get_segment(mo, skinfo[sk].seg);
785748 for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
786749 if (s->sh_type != SHT_NOBITS) {
787750 while (fileofs < s->sh_offset)
@@ -827,7 +790,8 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 39 unmodified lines
827790 Section *s;
828791 collect_sections(s1, &mo);
829792 relocate_syms(s1, s1->symtab, 0);
830− mo.ep.entryoff = get_sym_addr(s1, "_main", 1, 0) - mo.seg[1]->vmaddr;
793+ mo.ep->entryoff = get_sym_addr(s1, "_main", 1, 0)
794+ - get_segment(&mo, 1)->vmaddr;
831795 if (s1->nb_errors)
832796 goto do_ret;
833797
@@ -847,25 +811,12 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 13 unmodified lines
847811 return ret;
848812 }
849813
850−#define FAT_MAGIC 0xcafebabe
851−#define FAT_CIGAM 0xbebafeca
852−#define FAT_MAGIC_64 0xcafebabf
853−#define FAT_CIGAM_64 0xbfbafeca
854−
855−struct fat_header {
856− uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
857− uint32_t nfat_arch; /* number of structs that follow */
858−};
859−
860−struct fat_arch {
861− int cputype; /* cpu specifier (int) */
862− int cpusubtype; /* machine specifier (int) */
863− uint32_t offset; /* file offset to this object file */
864− uint32_t size; /* size of this object file */
865− uint32_t align; /* alignment as a power of 2 */
866−};
814+static uint32_t swap32(uint32_t x)
815+{
816+ return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);
817+}
818+#define SWAP(x) (swap ? swap32(x) : (x))
867819
868−#define SWAP(x) (swap ? ntohl(x) : (x))
869820 ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev)
870821 {
871822 unsigned char buf[sizeof(struct mach_header_64)];
@@ -917,19 +868,27 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev) · 45 unmodified lines
917868 buf2 = load_data(fd, machofs + sizeof(struct mach_header_64), mh.sizeofcmds);
918869 for (i = 0, lc = buf2; i < mh.ncmds; i++) {
919870 dprintf("lc %2d: 0x%08x\n", i, lc->cmd);
920− if (lc->cmd == LC_SYMTAB) {
871+ switch (lc->cmd) {
872+ case LC_SYMTAB:
873+ {
921874 struct symtab_command *sc = (struct symtab_command*)lc;
922875 nsyms = sc->nsyms;
923876 symtab = load_data(fd, machofs + sc->symoff, nsyms * sizeof(*symtab));
924877 strsize = sc->strsize;
925878 strtab = load_data(fd, machofs + sc->stroff, strsize);
926− } else if (lc->cmd == LC_ID_DYLIB) {
879+ break;
880+ }
881+ case LC_ID_DYLIB:
882+ {
927883 struct dylib_command *dc = (struct dylib_command*)lc;
928884 soname = (char*)lc + dc->name;
929885 dprintf(" ID_DYLIB %d 0x%x 0x%x %s\n",
930886 dc->timestamp, dc->current_version,
931887 dc->compatibility_version, soname);
932− } else if (lc->cmd == LC_REEXPORT_DYLIB) {
888+ break;
889+ }
890+ case LC_REEXPORT_DYLIB:
891+ {
933892 struct dylib_command *dc = (struct dylib_command*)lc;
934893 char *name = (char*)lc + dc->name;
935894 dprintf(" REEXPORT %s\n", name);
@@ -942,10 +901,15 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev) · 6 unmodified lines
942901 macho_load_dll(s1, subfd, name, lev + 1);
943902 close(subfd);
944903 }
945− } else if (lc->cmd == LC_DYSYMTAB) {
904+ break;
905+ }
906+ case LC_DYSYMTAB:
907+ {
946908 struct dysymtab_command *dc = (struct dysymtab_command*)lc;
947909 iextdef = dc->iextdefsym;
948910 nextdef = dc->nextdefsym;
911+ break;
912+ }
949913 }
950914 lc = (struct load_command*) ((char*)lc + lc->cmdsize);
951915 }

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