regularized spelling of license to match name of LICENSE file
[platform/upstream/nasm.git] / output / outmacho.c
1 /* outmacho.c   output routines for the Netwide Assembler to produce
2  *              NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
3  *
4  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5  * Julian Hall. All rights reserved. The software is
6  * redistributable under the license given in the file "LICENSE"
7  * distributed in the NASM archive.
8  */
9
10 /* Most of this file is, like Mach-O itself, based on a.out. For more
11  * guidelines see outaout.c.  */
12
13 #include "compiler.h"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <inttypes.h>
20
21 #include "nasm.h"
22 #include "nasmlib.h"
23 #include "outform.h"
24 #include "compiler.h"
25
26 #if defined(OF_MACHO)
27
28 /* Mach-O in-file header structure sizes */
29 #define MACHO_HEADER_SIZE       (28)
30 #define MACHO_SEGCMD_SIZE       (56)
31 #define MACHO_SECTCMD_SIZE      (68)
32 #define MACHO_SYMCMD_SIZE       (24)
33 #define MACHO_NLIST_SIZE        (12)
34 #define MACHO_RELINFO_SIZE      (8)
35
36 /* Mach-O file header values */
37 #define MH_MAGIC                (0xfeedface)
38 #define CPU_TYPE_I386           (7)     /* x86 platform */
39 #define CPU_SUBTYPE_I386_ALL    (3)     /* all-x86 compatible */
40 #define MH_OBJECT               (0x1)   /* object file */
41
42 #define LC_SEGMENT              (0x1)   /* segment load command */
43 #define LC_SYMTAB               (0x2)   /* symbol table load command */
44
45 #define VM_PROT_NONE    (0x00)
46 #define VM_PROT_READ    (0x01)
47 #define VM_PROT_WRITE   (0x02)
48 #define VM_PROT_EXECUTE (0x04)
49
50 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
51 #define VM_PROT_ALL     (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
52
53 struct section {
54     /* nasm internal data */
55     struct section *next;
56     struct SAA *data;
57     int32_t index;
58     struct reloc *relocs;
59     int align;
60
61     /* data that goes into the file */
62     char sectname[16];          /* what this section is called */
63     char segname[16];           /* segment this section will be in */
64     uint32_t size;         /* in-memory and -file size  */
65     uint32_t nreloc;       /* relocation entry count */
66     uint32_t flags;        /* type and attributes (masked) */
67 };
68
69 #define SECTION_TYPE    0x000000ff      /* section type mask */
70
71 #define S_REGULAR       (0x0)   /* standard section */
72 #define S_ZEROFILL      (0x1)   /* zerofill, in-memory only */
73
74 #define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* system setable attributes */
75 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* section contains some
76                                                    machine instructions */
77 #define S_ATTR_EXT_RELOC         0x00000200     /* section has external
78                                                    relocation entries */
79 #define S_ATTR_LOC_RELOC         0x00000100     /* section has local
80                                                    relocation entries */
81
82
83 static struct sectmap {
84     const char *nasmsect;
85     const char *segname;
86     const char *sectname;
87     const int32_t flags;
88 } sectmap[] = {
89     {".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS},
90     {".data", "__DATA", "__data", S_REGULAR},
91     {".rodata", "__DATA", "__const", S_REGULAR},
92     {".bss", "__DATA", "__bss", S_ZEROFILL},
93     {NULL, NULL, NULL, 0}
94 };
95
96 struct reloc {
97     /* nasm internal data */
98     struct reloc *next;
99
100     /* data that goes into the file */
101     int32_t addr;                  /* op's offset in section */
102     unsigned int snum:24,       /* contains symbol index if
103                                 ** ext otherwise in-file
104                                 ** section number */
105         pcrel:1,                /* relative relocation */
106         length:2,               /* 0=byte, 1=word, 2=int32_t */
107         ext:1,                  /* external symbol referenced */
108         type:4;                 /* reloc type, 0 for us */
109 };
110
111 #define R_ABS           0       /* absolute relocation */
112 #define R_SCATTERED     0x80000000      /* reloc entry is scattered if
113                                         ** highest bit == 1 */
114
115 struct symbol {
116     /* nasm internal data */
117     struct symbol *next;        /* next symbol in the list */
118     char *name;                 /* name of this symbol */
119     int32_t initial_snum;               /* symbol number used above in
120                                    reloc */
121     int32_t snum;                       /* true snum for reloc */
122
123     /* data that goes into the file */
124     int32_t strx;                  /* string table index */
125     uint8_t type;         /* symbol type */
126     uint8_t sect;         /* NO_SECT or section number */
127     int16_t desc;                 /* for stab debugging, 0 for us */
128     uint32_t value;        /* offset of symbol in section */
129 };
130
131 /* symbol type bits */
132 #define N_EXT   0x01            /* global or external symbol */
133
134 #define N_UNDF  0x0             /* undefined symbol | n_sect == */
135 #define N_ABS   0x2             /* absolute symbol  |  NO_SECT */
136 #define N_SECT  0xe             /* defined symbol, n_sect holds
137                                 ** section number */
138
139 #define N_TYPE  0x0e            /* type bit mask */
140
141 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
142
143 /* special section number values */
144 #define NO_SECT         0       /* no section, invalid */
145 #define MAX_SECT        255     /* maximum number of sections */
146
147 static struct section *sects, **sectstail;
148 static struct symbol *syms, **symstail;
149 static uint32_t nsyms;
150
151 /* These variables are set by macho_layout_symbols() to organize
152    the symbol table and string table in order the dynamic linker
153    expects.  They are then used in macho_write() to put out the
154    symbols and strings in that order.
155
156    The order of the symbol table is:
157      local symbols
158      defined external symbols (sorted by name)
159      undefined external symbols (sorted by name)
160
161    The order of the string table is:
162      strings for external symbols
163      strings for local symbols
164  */
165 static uint32_t ilocalsym = 0;
166 static uint32_t iextdefsym = 0;
167 static uint32_t iundefsym = 0;
168 static uint32_t nlocalsym;
169 static uint32_t nextdefsym;
170 static uint32_t nundefsym;
171 static struct symbol **extdefsyms = NULL;
172 static struct symbol **undefsyms = NULL;
173
174 static struct RAA *extsyms;
175 static struct SAA *strs;
176 static uint32_t strslen;
177
178 static FILE *machofp;
179 static efunc error;
180 static evalfunc evaluate;
181
182 extern struct ofmt of_macho;
183
184 /* Global file information. This should be cleaned up into either
185    a structure or as function arguments.  */
186 uint32_t head_ncmds = 0;
187 uint32_t head_sizeofcmds = 0;
188 uint32_t seg_filesize = 0;
189 uint32_t seg_vmsize = 0;
190 uint32_t seg_nsects = 0;
191 uint32_t rel_padcnt = 0;
192
193
194 #define xstrncpy(xdst, xsrc)                                            \
195     memset(xdst, '\0', sizeof(xdst));   /* zero out whole buffer */     \
196     strncpy(xdst, xsrc, sizeof(xdst));  /* copy over string */          \
197     xdst[sizeof(xdst) - 1] = '\0';      /* proper null-termination */
198
199 #define align(x, y)                                                     \
200     (((x) + (y) - 1) & ~((y) - 1))      /* align x to multiple of y */
201
202 #define alignint32_t(x)                                                 \
203     align(x, sizeof(int32_t))      /* align x to int32_t boundary */
204
205 static void debug_reloc (struct reloc *);
206 static void debug_section_relocs (struct section *) _unused;
207
208 static int exact_log2 (uint32_t align)
209 {
210     if (align == 0) {
211         return 0;
212     } else if (align & (align-1)) {
213         return -1;              /* Not a power of 2 */
214     } else {
215 #ifdef HAVE_GNUC_4
216         return __builtin_ctzl (align);
217 #else
218         uint32_t result = 0;
219
220         /* We know exactly one bit is set at this point. */
221         if (align & 0xffff0000)
222             result |= 16;
223         if (align & 0xff00ff00)
224             result |= 8;
225         if (align & 0xf0f0f0f0)
226             result |= 4;
227         if (align & 0xcccccccc)
228             result |= 2;
229         if (align & 0xaaaaaaaa)
230             result |= 1;
231
232         return result;
233 #endif
234     }
235 }
236
237 static struct section *get_section_by_name(const char *segname,
238                                            const char *sectname)
239 {
240     struct section *s;
241
242     for (s = sects; s != NULL; s = s->next)
243         if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
244             break;
245
246     return s;
247 }
248
249 static struct section *get_section_by_index(const int32_t index)
250 {
251     struct section *s;
252
253     for (s = sects; s != NULL; s = s->next)
254         if (index == s->index)
255             break;
256
257     return s;
258 }
259
260 static int32_t get_section_index_by_name(const char *segname,
261                                       const char *sectname)
262 {
263     struct section *s;
264
265     for (s = sects; s != NULL; s = s->next)
266         if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
267             return s->index;
268
269     return -1;
270 }
271
272 static char *get_section_name_by_index(const int32_t index)
273 {
274     struct section *s;
275
276     for (s = sects; s != NULL; s = s->next)
277         if (index == s->index)
278             return s->sectname;
279
280     return NULL;
281 }
282
283 static uint8_t get_section_fileindex_by_index(const int32_t index)
284 {
285     struct section *s;
286     uint8_t i = 1;
287
288     for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
289         if (index == s->index)
290             return i;
291
292     if (i == MAX_SECT)
293         error(ERR_WARNING,
294               "too many sections (>255) - clipped by fileindex");
295
296     return NO_SECT;
297 }
298
299 static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
300                        evalfunc eval)
301 {
302     char zero = 0;
303
304     machofp = fp;
305     error = errfunc;
306     evaluate = eval;
307
308     (void)ldef;                 /* placate optimisers */
309
310     sects = NULL;
311     sectstail = &sects;
312
313     syms = NULL;
314     symstail = &syms;
315     nsyms = 0;
316     nlocalsym = 0;
317     nextdefsym = 0;
318     nundefsym = 0;
319
320     extsyms = raa_init();
321     strs = saa_init(1L);
322
323     /* string table starts with a zero byte - don't ask why */
324     saa_wbytes(strs, &zero, sizeof(char));
325     strslen = 1;
326 }
327
328 static int macho_setinfo(enum geninfo type, char **val)
329 {
330     (void)type;
331     (void)val;
332     return 0;
333 }
334
335 static void sect_write(struct section *sect,
336                        const uint8_t *data, uint32_t len)
337 {
338     saa_wbytes(sect->data, data, len);
339     sect->size += len;
340 }
341
342 static void add_reloc(struct section *sect, int32_t section,
343                       int pcrel, int bytes)
344 {
345     struct reloc *r;
346     int32_t fi;
347
348     /* NeXT as puts relocs in reversed order (address-wise) into the
349      ** files, so we do the same, doesn't seem to make much of a
350      ** difference either way */
351     r = nasm_malloc(sizeof(struct reloc));
352     r->next = sect->relocs;
353     sect->relocs = r;
354
355     /* the current end of the section will be the symbol's address for
356      ** now, might have to be fixed by macho_fixup_relocs() later on. make
357      ** sure we don't make the symbol scattered by setting the highest
358      ** bit by accident */
359     r->addr = sect->size & ~R_SCATTERED;
360     r->ext = 0;
361     r->pcrel = pcrel;
362
363     /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */
364     r->length = bytes >> 1;
365
366     /* vanilla relocation (GENERIC_RELOC_VANILLA) */
367     r->type = 0;
368
369     if (section == NO_SEG) {
370         /* absolute local symbol if no section index given */
371         r->snum = R_ABS;
372     } else {
373         fi = get_section_fileindex_by_index(section);
374
375         if (fi == NO_SECT) {
376             /* external symbol if no section with that index known,
377              ** symbol number was saved in macho_symdef() */
378             r->snum = raa_read(extsyms, section);
379             r->ext = 1;
380         } else {
381             /* local symbol in section fi */
382             r->snum = fi;
383         }
384     }
385
386     ++sect->nreloc;
387 }
388
389 static void macho_output(int32_t secto, const void *data,
390                          enum out_type type, uint64_t size,
391                          int32_t section, int32_t wrt)
392 {
393     struct section *s, *sbss;
394     int32_t addr;
395     uint8_t mydata[4], *p;
396
397     if (wrt != NO_SEG) {
398         wrt = NO_SEG;
399         error(ERR_NONFATAL, "WRT not supported by Mach-O output format");
400         /* continue to do _something_ */
401     }
402
403     if (secto == NO_SEG) {
404         if (type != OUT_RESERVE)
405             error(ERR_NONFATAL, "attempt to assemble code in "
406                   "[ABSOLUTE] space");
407
408         return;
409     }
410
411     s = get_section_by_index(secto);
412
413     if (s == NULL) {
414         error(ERR_WARNING, "attempt to assemble code in"
415               " section %d: defaulting to `.text'", secto);
416         s = get_section_by_name("__TEXT", "__text");
417
418         /* should never happen */
419         if (s == NULL)
420             error(ERR_PANIC, "text section not found");
421     }
422
423     sbss = get_section_by_name("__DATA", "__bss");
424
425     if (s == sbss && type != OUT_RESERVE) {
426         error(ERR_WARNING, "attempt to initialize memory in the"
427               " BSS section: ignored");
428
429         switch (type) {
430         case OUT_REL2ADR:
431             size = 2;
432             break;
433
434         case OUT_REL4ADR:
435             size = 4;
436             break;
437
438         default:
439             break;
440         }
441
442         s->size += size;
443         return;
444     }
445
446     switch (type) {
447     case OUT_RESERVE:
448         if (s != sbss) {
449             error(ERR_WARNING, "uninitialized space declared in"
450                   " %s section: zeroing",
451                   get_section_name_by_index(secto));
452
453             sect_write(s, NULL, size);
454         } else
455             s->size += size;
456
457         break;
458
459     case OUT_RAWDATA:
460         if (section != NO_SEG)
461             error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
462
463         sect_write(s, data, size);
464         break;
465
466     case OUT_ADDRESS:
467         addr = *(int64_t *)data;
468
469         if (section != NO_SEG) {
470             if (section % 2) {
471                 error(ERR_NONFATAL, "Mach-O format does not support"
472                       " section base references");
473             } else
474                 add_reloc(s, section, 0, size);
475         }
476
477         p = mydata;
478         WRITEADDR(p, addr, size);
479         sect_write(s, mydata, size);
480         break;
481
482     case OUT_REL2ADR:
483         if (section == secto)
484             error(ERR_PANIC, "intra-section OUT_REL2ADR");
485
486         if (section != NO_SEG && section % 2) {
487             error(ERR_NONFATAL, "Mach-O format does not support"
488                   " section base references");
489         } else
490             add_reloc(s, section, 1, 2);
491
492         p = mydata;
493         WRITESHORT(p, *(int32_t *)data - (size + s->size));
494         sect_write(s, mydata, 2L);
495         break;
496
497     case OUT_REL4ADR:
498         if (section == secto)
499             error(ERR_PANIC, "intra-section OUT_REL4ADR");
500
501         if (section != NO_SEG && section % 2) {
502             error(ERR_NONFATAL, "Mach-O format does not support"
503                   " section base references");
504         } else
505             add_reloc(s, section, 1, 4);
506
507         p = mydata;
508         WRITELONG(p, *(int32_t *)data - (size + s->size));
509         sect_write(s, mydata, 4L);
510         break;
511
512     default:
513         error(ERR_PANIC, "unknown output type?");
514         break;
515     }
516 }
517
518 static int32_t macho_section(char *name, int pass, int *bits)
519 {
520     int32_t index, originalIndex;
521     char *sectionAttributes;
522     struct sectmap *sm;
523     struct section *s;
524
525     (void)pass;
526
527     /* Default to 32 bits. */
528     if (!name) {
529         *bits = 32;
530         name = ".text";
531         sectionAttributes = NULL;
532     } else {
533         sectionAttributes = name;
534         name = nasm_strsep(&sectionAttributes, " \t");
535     }
536
537     for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
538         /* make lookup into section name translation table */
539         if (!strcmp(name, sm->nasmsect)) {
540             char *currentAttribute;
541
542             /* try to find section with that name */
543             originalIndex = index = get_section_index_by_name(sm->segname,
544                                                               sm->sectname);
545
546             /* create it if it doesn't exist yet */
547             if (index == -1) {
548                 s = *sectstail = nasm_malloc(sizeof(struct section));
549                 s->next = NULL;
550                 sectstail = &s->next;
551
552                 s->data = saa_init(1L);
553                 s->index = seg_alloc();
554                 s->relocs = NULL;
555                 s->align = -1;
556
557                 xstrncpy(s->segname, sm->segname);
558                 xstrncpy(s->sectname, sm->sectname);
559                 s->size = 0;
560                 s->nreloc = 0;
561                 s->flags = sm->flags;
562
563                 index = s->index;
564             } else {
565                 s = get_section_by_index(index);
566             }
567
568             while ((NULL != sectionAttributes)
569                    && (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
570                 if (0 != *currentAttribute) {
571                     if (!nasm_strnicmp("align=", currentAttribute, 6)) {
572                         char *end;
573                         int newAlignment, value;
574
575                         value = strtoul(currentAttribute + 6, (char**)&end, 0);
576                         newAlignment = exact_log2(value);
577
578                         if (0 != *end) {
579                             error(ERR_PANIC,
580                                   "unknown or missing alignment value \"%s\" "
581                                       "specified for section \"%s\"",
582                                   currentAttribute + 6,
583                                   name);
584                             return NO_SEG;
585                         } else if (0 > newAlignment) {
586                             error(ERR_PANIC,
587                                   "alignment of %d (for section \"%s\") is not "
588                                       "a power of two",
589                                   value,
590                                   name);
591                             return NO_SEG;
592                         }
593
594                         if ((-1 != originalIndex)
595                             && (s->align != newAlignment)
596                            && (s->align != -1)) {
597                             error(ERR_PANIC,
598                                   "section \"%s\" has already been specified "
599                                       "with alignment %d, conflicts with new "
600                                       "alignment of %d",
601                             name,
602                             (1 << s->align),
603                             value);
604                             return NO_SEG;
605                         }
606
607                         s->align = newAlignment;
608                     } else if (!nasm_stricmp("data", currentAttribute)) {
609                         /* Do nothing; 'data' is implicit */
610                     } else {
611                         error(ERR_PANIC,
612                               "unknown section attribute %s for section %s",
613                               currentAttribute,
614                               name);
615                         return NO_SEG;
616                     }
617                 }
618             }
619
620             return index;
621         }
622     }
623
624     error(ERR_PANIC, "invalid section name %s", name);
625     return NO_SEG;
626 }
627
628 static void macho_symdef(char *name, int32_t section, int64_t offset,
629                          int is_global, char *special)
630 {
631     struct symbol *sym;
632
633     if (special) {
634         error(ERR_NONFATAL, "The Mach-O output format does "
635               "not support any special symbol types");
636         return;
637     }
638
639     if (is_global == 3) {
640         error(ERR_NONFATAL, "The Mach-O format does not "
641               "(yet) support forward reference fixups.");
642         return;
643     }
644
645     sym = *symstail = nasm_malloc(sizeof(struct symbol));
646     sym->next = NULL;
647     symstail = &sym->next;
648
649     sym->name = name;
650     sym->strx = strslen;
651     sym->type = 0;
652     sym->desc = 0;
653     sym->value = offset;
654     sym->initial_snum = -1;
655
656     /* external and common symbols get N_EXT */
657     if (is_global != 0)
658         sym->type |= N_EXT;
659
660     if (section == NO_SEG) {
661         /* symbols in no section get absolute */
662         sym->type |= N_ABS;
663         sym->sect = NO_SECT;
664     } else {
665         sym->type |= N_SECT;
666
667         /* get the in-file index of the section the symbol was defined in */
668         sym->sect = get_section_fileindex_by_index(section);
669
670         if (sym->sect == NO_SECT) {
671             /* remember symbol number of references to external
672              ** symbols, this works because every external symbol gets
673              ** its own section number allocated internally by nasm and
674              ** can so be used as a key */
675             extsyms = raa_write(extsyms, section, nsyms);
676             sym->initial_snum = nsyms;
677
678             switch (is_global) {
679             case 1:
680             case 2:
681                 /* there isn't actually a difference between global
682                  ** and common symbols, both even have their size in
683                  ** sym->value */
684                 sym->type = N_EXT;
685                 break;
686
687             default:
688                 /* give an error on unfound section if it's not an
689                  ** external or common symbol (assemble_file() does a
690                  ** seg_alloc() on every call for them) */
691                 error(ERR_PANIC, "in-file index for section %d not found",
692                       section);
693             }
694         }
695     }
696
697     ++nsyms;
698 }
699
700 static int32_t macho_segbase(int32_t section)
701 {
702     return section;
703 }
704
705 static int macho_directive(char *directive, char *value, int pass)
706 {
707     (void)directive;
708     (void)value;
709     (void)pass;
710     return 0;
711 }
712
713 static void macho_filename(char *inname, char *outname, efunc error)
714 {
715     standard_extension(inname, outname, ".o", error);
716 }
717
718 static const char *macho_stdmac[] = {
719     "%define __SECT__ [section .text]",
720     "%macro __NASM_CDecl__ 1",
721     "%endmacro",
722     NULL
723 };
724
725 /* Comparison function for qsort symbol layout.  */
726 static int layout_compare (const struct symbol **s1,
727                            const struct symbol **s2)
728 {
729     return (strcmp ((*s1)->name, (*s2)->name));
730 }
731
732 /* The native assembler does a few things in a similar function
733
734         * Remove temporary labels
735         * Sort symbols according to local, external, undefined (by name)
736         * Order the string table
737
738    We do not remove temporary labels right now.
739
740    numsyms is the total number of symbols we have. strtabsize is the
741    number entries in the string table.  */
742
743 static void macho_layout_symbols (uint32_t *numsyms,
744                                   uint32_t *strtabsize)
745 {
746     struct symbol *sym, **symp;
747     uint32_t i,j;
748
749     *numsyms = 0;
750     *strtabsize = sizeof (char);
751
752     symp = &syms;
753
754     while ((sym = *symp)) {
755         /* Undefined symbols are now external.  */
756         if (sym->type == N_UNDF)
757             sym->type |= N_EXT;
758
759         if ((sym->type & N_EXT) == 0) {
760             sym->snum = *numsyms;
761             *numsyms = *numsyms + 1;
762             nlocalsym++;
763         }
764         else {
765             if ((sym->type & N_TYPE) != N_UNDF)
766                 nextdefsym++;
767             else
768                 nundefsym++;
769
770             /* If we handle debug info we'll want
771                to check for it here instead of just
772                adding the symbol to the string table.  */
773             sym->strx = *strtabsize;
774             saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
775             *strtabsize += strlen(sym->name) + 1;
776         }
777         symp = &(sym->next);
778     }
779
780     /* Next, sort the symbols.  Most of this code is a direct translation from
781        the Apple cctools symbol layout. We need to keep compatibility with that.  */
782     /* Set the indexes for symbol groups into the symbol table */
783     ilocalsym = 0;
784     iextdefsym = nlocalsym;
785     iundefsym = nlocalsym + nextdefsym;
786
787     /* allocate arrays for sorting externals by name */
788     extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
789     undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
790
791     i = 0;
792     j = 0;
793
794     symp = &syms;
795
796     while ((sym = *symp)) {
797
798         if((sym->type & N_EXT) == 0) {
799             sym->strx = *strtabsize;
800             saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
801             *strtabsize += strlen(sym->name) + 1;
802         }
803         else {
804             if((sym->type & N_TYPE) != N_UNDF)
805                 extdefsyms[i++] = sym;
806             else
807                 undefsyms[j++] = sym;
808         }
809         symp = &(sym->next);
810     }
811
812     qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
813           (int (*)(const void *, const void *))layout_compare);
814     qsort(undefsyms, nundefsym, sizeof(struct symbol *),
815           (int (*)(const void *, const void *))layout_compare);
816
817     for(i = 0; i < nextdefsym; i++) {
818         extdefsyms[i]->snum = *numsyms;
819         *numsyms += 1;
820     }
821     for(j = 0; j < nundefsym; j++) {
822         undefsyms[j]->snum = *numsyms;
823         *numsyms += 1;
824     }
825 }
826
827 /* Calculate some values we'll need for writing later.  */
828
829 static void macho_calculate_sizes (void)
830 {
831     struct section *s;
832
833     /* count sections and calculate in-memory and in-file offsets */
834     for (s = sects; s != NULL; s = s->next) {
835         /* zerofill sections aren't actually written to the file */
836         if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
837             seg_filesize += s->size;
838
839         seg_vmsize += s->size;
840         ++seg_nsects;
841     }
842
843     /* calculate size of all headers, load commands and sections to
844     ** get a pointer to the start of all the raw data */
845     if (seg_nsects > 0) {
846         ++head_ncmds;
847         head_sizeofcmds +=
848             MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE;
849     }
850
851     if (nsyms > 0) {
852         ++head_ncmds;
853         head_sizeofcmds += MACHO_SYMCMD_SIZE;
854     }
855 }
856
857 /* Write out the header information for the file.  */
858
859 static void macho_write_header (void)
860 {
861     fwriteint32_t(MH_MAGIC, machofp);   /* magic */
862     fwriteint32_t(CPU_TYPE_I386, machofp);      /* CPU type */
863     fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp);       /* CPU subtype */
864     fwriteint32_t(MH_OBJECT, machofp);  /* Mach-O file type */
865     fwriteint32_t(head_ncmds, machofp); /* number of load commands */
866     fwriteint32_t(head_sizeofcmds, machofp);    /* size of load commands */
867     fwriteint32_t(0, machofp);  /* no flags */
868 }
869
870 /* Write out the segment load command at offset.  */
871
872 static uint32_t macho_write_segment (uint32_t offset)
873 {
874     uint32_t s_addr = 0;
875     uint32_t rel_base = alignint32_t (offset + seg_filesize);
876     uint32_t s_reloff = 0;
877     struct section *s;
878
879     fwriteint32_t(LC_SEGMENT, machofp);        /* cmd == LC_SEGMENT */
880
881     /* size of load command including section load commands */
882     fwriteint32_t(MACHO_SEGCMD_SIZE + seg_nsects *
883                MACHO_SECTCMD_SIZE, machofp);
884
885     /* in an MH_OBJECT file all sections are in one unnamed (name
886     ** all zeros) segment */
887     fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 1, machofp);
888     fwriteint32_t(0, machofp); /* in-memory offset */
889     fwriteint32_t(seg_vmsize, machofp);        /* in-memory size */
890     fwriteint32_t(offset, machofp);    /* in-file offset to data */
891     fwriteint32_t(seg_filesize, machofp);      /* in-file size */
892     fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* maximum vm protection */
893     fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* initial vm protection */
894     fwriteint32_t(seg_nsects, machofp);        /* number of sections */
895     fwriteint32_t(0, machofp); /* no flags */
896
897     /* emit section headers */
898     for (s = sects; s != NULL; s = s->next) {
899         fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
900         fwrite(s->segname, sizeof(s->segname), 1, machofp);
901         fwriteint32_t(s_addr, machofp);
902         fwriteint32_t(s->size, machofp);
903
904         /* dummy data for zerofill sections or proper values */
905         if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
906             fwriteint32_t(offset, machofp);
907             /* Write out section alignment, as a power of two.
908                e.g. 32-bit word alignment would be 2 (2^^2 = 4).  */
909             if (s->align == -1)
910                 s->align = DEFAULT_SECTION_ALIGNMENT;
911             fwriteint32_t(s->align, machofp);
912             /* To be compatible with cctools as we emit
913                a zero reloff if we have no relocations.  */
914             fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp);
915             fwriteint32_t(s->nreloc, machofp);
916
917             offset += s->size;
918             s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
919         } else {
920             fwriteint32_t(0, machofp);
921             fwriteint32_t(0, machofp);
922             fwriteint32_t(0, machofp);
923             fwriteint32_t(0, machofp);
924         }
925
926         fwriteint32_t(s->flags, machofp);      /* flags */
927         fwriteint32_t(0, machofp);     /* reserved */
928         fwriteint32_t(0, machofp);     /* reserved */
929
930         s_addr += s->size;
931     }
932
933     rel_padcnt = rel_base - offset;
934     offset = rel_base + s_reloff;
935
936     return offset;
937 }
938
939 /* For a given chain of relocs r, write out the entire relocation
940    chain to the object file.  */
941
942 static void macho_write_relocs (struct reloc *r)
943 {
944     while (r) {
945         uint32_t word2;
946
947         fwriteint32_t(r->addr, machofp); /* reloc offset */
948
949         word2 = r->snum;
950         word2 |= r->pcrel << 24;
951         word2 |= r->length << 25;
952         word2 |= r->ext << 27;
953         word2 |= r->type << 28;
954         fwriteint32_t(word2, machofp); /* reloc data */
955
956         r = r->next;
957     }
958 }
959
960 /* Write out the section data.  */
961 static void macho_write_section (void)
962 {
963     struct section *s, *s2;
964     struct reloc *r;
965     char *rel_paddata = "\0\0\0";
966     uint8_t fi, *p, *q, blk[4];
967     int32_t l;
968
969     for (s = sects; s != NULL; s = s->next) {
970         if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
971             continue;
972
973         /* no padding needs to be done to the sections */
974
975         /* Like a.out Mach-O references things in the data or bss
976          * sections by addresses which are actually relative to the
977          * start of the _text_ section, in the _file_. See outaout.c
978          * for more information. */
979         saa_rewind(s->data);
980         for (r = s->relocs; r != NULL; r = r->next) {
981             saa_fread(s->data, r->addr, blk, (int32_t)r->length << 1);
982             p = q = blk;
983             l = *p++;
984
985             /* get offset based on relocation type */
986             if (r->length > 0) {
987                 l += ((int32_t)*p++) << 8;
988
989                 if (r->length == 2) {
990                     l += ((int32_t)*p++) << 16;
991                     l += ((int32_t)*p++) << 24;
992                 }
993             }
994
995             /* If the relocation is internal add to the current section
996                offset. Otherwise the only value we need is the symbol
997                offset which we already have. The linker takes care
998                of the rest of the address.  */
999             if (!r->ext) {
1000            /* add sizes of previous sections to current offset */
1001            for (s2 = sects, fi = 1;
1002                 s2 != NULL && fi < r->snum; s2 = s2->next, fi++)
1003                l += s2->size;
1004             }
1005
1006             /* write new offset back */
1007             if (r->length == 2)
1008                 WRITELONG(q, l);
1009             else if (r->length == 1)
1010                 WRITESHORT(q, l);
1011             else
1012                 *q++ = l & 0xFF;
1013
1014             saa_fwrite(s->data, r->addr, blk, (int32_t)r->length << 1);
1015         }
1016
1017         /* dump the section data to file */
1018         saa_fpwrite(s->data, machofp);
1019     }
1020
1021     /* pad last section up to reloc entries on int32_t boundary */
1022     fwrite(rel_paddata, rel_padcnt, 1, machofp);
1023
1024     /* emit relocation entries */
1025     for (s = sects; s != NULL; s = s->next)
1026         macho_write_relocs (s->relocs);
1027 }
1028
1029 /* Write out the symbol table. We should already have sorted this
1030    before now.  */
1031 static void macho_write_symtab (void)
1032 {
1033     struct symbol *sym;
1034     struct section *s;
1035     int32_t fi;
1036     uint32_t i;
1037
1038     /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1039
1040     for (sym = syms; sym != NULL; sym = sym->next) {
1041         if ((sym->type & N_EXT) == 0) {
1042             fwriteint32_t(sym->strx, machofp);          /* string table entry number */
1043             fwrite(&sym->type, 1, 1, machofp);  /* symbol type */
1044             fwrite(&sym->sect, 1, 1, machofp);  /* section */
1045             fwriteint16_t(sym->desc, machofp);  /* description */
1046
1047             /* Fix up the symbol value now that we know the final section
1048                sizes.  */
1049             if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1050                 for (s = sects, fi = 1;
1051                      s != NULL && fi < sym->sect; s = s->next, ++fi)
1052                     sym->value += s->size;
1053             }
1054
1055             fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */
1056         }
1057     }
1058
1059     for (i = 0; i < nextdefsym; i++) {
1060         sym = extdefsyms[i];
1061         fwriteint32_t(sym->strx, machofp);
1062         fwrite(&sym->type, 1, 1, machofp);      /* symbol type */
1063         fwrite(&sym->sect, 1, 1, machofp);      /* section */
1064         fwriteint16_t(sym->desc, machofp);      /* description */
1065
1066         /* Fix up the symbol value now that we know the final section
1067            sizes.  */
1068         if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1069             for (s = sects, fi = 1;
1070                  s != NULL && fi < sym->sect; s = s->next, ++fi)
1071                 sym->value += s->size;
1072         }
1073
1074         fwriteint32_t(sym->value, machofp);     /* value (i.e. offset) */
1075     }
1076
1077      for (i = 0; i < nundefsym; i++) {
1078          sym = undefsyms[i];
1079          fwriteint32_t(sym->strx, machofp);
1080          fwrite(&sym->type, 1, 1, machofp);     /* symbol type */
1081          fwrite(&sym->sect, 1, 1, machofp);     /* section */
1082          fwriteint16_t(sym->desc, machofp);     /* description */
1083
1084          /* Fix up the symbol value now that we know the final section
1085             sizes.  */
1086          if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1087              for (s = sects, fi = 1;
1088                   s != NULL && fi < sym->sect; s = s->next, ++fi)
1089                  sym->value += s->size;
1090          }
1091
1092          fwriteint32_t(sym->value, machofp);    /* value (i.e. offset) */
1093      }
1094 }
1095
1096 /* Fixup the snum in the relocation entries, we should be
1097    doing this only for externally undefined symbols. */
1098 static void macho_fixup_relocs (struct reloc *r)
1099 {
1100     struct symbol *sym;
1101     uint32_t i;
1102
1103     while (r != NULL) {
1104         if (r->ext) {
1105             for (i = 0; i < nundefsym; i++) {
1106                 sym = undefsyms[i];
1107                 if (sym->initial_snum == r->snum) {
1108                     r->snum = sym->snum;
1109                    break;
1110                 }
1111             }
1112         }
1113         r = r->next;
1114     }
1115 }
1116
1117 /* Write out the object file.  */
1118
1119 static void macho_write (void)
1120 {
1121     uint32_t offset = 0;
1122
1123     /* mach-o object file structure:
1124     **
1125     ** mach header
1126     **  uint32_t magic
1127     **  int   cpu type
1128     **  int   cpu subtype
1129     **  uint32_t mach file type
1130     **  uint32_t number of load commands
1131     **  uint32_t size of all load commands
1132     **   (includes section struct size of segment command)
1133     **  uint32_t flags
1134     **
1135     ** segment command
1136     **  uint32_t command type == LC_SEGMENT
1137     **  uint32_t size of load command
1138     **   (including section load commands)
1139     **  char[16] segment name
1140     **  uint32_t in-memory offset
1141     **  uint32_t in-memory size
1142     **  uint32_t in-file offset to data area
1143     **  uint32_t in-file size
1144     **   (in-memory size excluding zerofill sections)
1145     **  int   maximum vm protection
1146     **  int   initial vm protection
1147     **  uint32_t number of sections
1148     **  uint32_t flags
1149     **
1150     ** section commands
1151     **   char[16] section name
1152     **   char[16] segment name
1153     **   uint32_t in-memory offset
1154     **   uint32_t in-memory size
1155     **   uint32_t in-file offset
1156     **   uint32_t alignment
1157     **    (irrelevant in MH_OBJECT)
1158     **   uint32_t in-file offset of relocation entires
1159     **   uint32_t number of relocations
1160     **   uint32_t flags
1161     **   uint32_t reserved
1162     **   uint32_t reserved
1163     **
1164     ** symbol table command
1165     **  uint32_t command type == LC_SYMTAB
1166     **  uint32_t size of load command
1167     **  uint32_t symbol table offset
1168     **  uint32_t number of symbol table entries
1169     **  uint32_t string table offset
1170     **  uint32_t string table size
1171     **
1172     ** raw section data
1173     **
1174     ** padding to int32_t boundary
1175     **
1176     ** relocation data (struct reloc)
1177     ** int32_t offset
1178     **  uint data (symbolnum, pcrel, length, extern, type)
1179     **
1180     ** symbol table data (struct nlist)
1181     **  int32_t  string table entry number
1182     **  uint8_t type
1183     **   (extern, absolute, defined in section)
1184     **  uint8_t section
1185     **   (0 for global symbols, section number of definition (>= 1, <=
1186     **   254) for local symbols, size of variable for common symbols
1187     **   [type == extern])
1188     **  int16_t description
1189     **   (for stab debugging format)
1190     **  uint32_t value (i.e. file offset) of symbol or stab offset
1191     **
1192     ** string table data
1193     **  list of null-terminated strings
1194     */
1195
1196     /* Emit the Mach-O header.  */
1197     macho_write_header();
1198
1199     offset = MACHO_HEADER_SIZE + head_sizeofcmds;
1200
1201     /* emit the segment load command */
1202     if (seg_nsects > 0)
1203         offset = macho_write_segment (offset);
1204     else
1205         error(ERR_WARNING, "no sections?");
1206
1207     if (nsyms > 0) {
1208         /* write out symbol command */
1209         fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
1210         fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
1211         fwriteint32_t(offset, machofp);    /* symbol table offset */
1212         fwriteint32_t(nsyms, machofp);     /* number of symbol
1213                                          ** table entries */
1214
1215         offset += nsyms * MACHO_NLIST_SIZE;
1216         fwriteint32_t(offset, machofp);    /* string table offset */
1217         fwriteint32_t(strslen, machofp);   /* string table size */
1218     }
1219
1220     /* emit section data */
1221     if (seg_nsects > 0)
1222         macho_write_section ();
1223
1224     /* emit symbol table if we have symbols */
1225     if (nsyms > 0)
1226         macho_write_symtab ();
1227
1228     /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */
1229
1230     /* emit string table */
1231     saa_fpwrite(strs, machofp);
1232 }
1233 /* We do quite a bit here, starting with finalizing all of the data
1234    for the object file, writing, and then freeing all of the data from
1235    the file.  */
1236
1237 static void macho_cleanup(int debuginfo)
1238 {
1239     struct section *s;
1240     struct reloc *r;
1241     struct symbol *sym;
1242
1243     (void)debuginfo;
1244
1245     /* Sort all symbols.  */
1246     macho_layout_symbols (&nsyms, &strslen);
1247
1248     /* Fixup relocation entries */
1249     for (s = sects; s != NULL; s = s->next) {
1250         macho_fixup_relocs (s->relocs);
1251     }
1252
1253     /* First calculate and finalize needed values.  */
1254     macho_calculate_sizes();
1255     macho_write();
1256
1257     /* done - yay! */
1258     fclose(machofp);
1259
1260     /* free up everything */
1261     while (sects->next) {
1262         s = sects;
1263         sects = sects->next;
1264
1265         saa_free(s->data);
1266         while (s->relocs != NULL) {
1267             r = s->relocs;
1268             s->relocs = s->relocs->next;
1269             nasm_free(r);
1270         }
1271
1272         nasm_free(s);
1273     }
1274
1275     saa_free(strs);
1276     raa_free(extsyms);
1277
1278     if (syms) {
1279     while (syms->next) {
1280        sym = syms;
1281        syms = syms->next;
1282
1283        nasm_free (sym);
1284     }
1285 }
1286 }
1287
1288 /* Debugging routines.  */
1289 static void debug_reloc (struct reloc *r)
1290 {
1291     fprintf (stdout, "reloc:\n");
1292     fprintf (stdout, "\taddr: %"PRId32"\n", r->addr);
1293     fprintf (stdout, "\tsnum: %d\n", r->snum);
1294     fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
1295     fprintf (stdout, "\tlength: %d\n", r->length);
1296     fprintf (stdout, "\text: %d\n", r->ext);
1297     fprintf (stdout, "\ttype: %d\n", r->type);
1298 }
1299
1300 static void debug_section_relocs (struct section *s)
1301 {
1302     struct reloc *r = s->relocs;
1303
1304     fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
1305
1306     while (r != NULL) {
1307         debug_reloc (r);
1308         r = r->next;
1309     }
1310 }
1311
1312 struct ofmt of_macho = {
1313     "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files",
1314     "macho",
1315     NULL,
1316     null_debug_arr,
1317     &null_debug_form,
1318     macho_stdmac,
1319     macho_init,
1320     macho_setinfo,
1321     macho_output,
1322     macho_symdef,
1323     macho_section,
1324     macho_segbase,
1325     macho_directive,
1326     macho_filename,
1327     macho_cleanup
1328 };
1329
1330 #endif
1331
1332 /*
1333  * Local Variables:
1334  * mode:c
1335  * c-basic-offset:4
1336  * End:
1337  *
1338  * end of file */