1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 1996-2018 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33 
34 /*
35  * outmacho.c	output routines for the Netwide Assembler to produce
36  *		NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
37  */
38 
39 #include "compiler.h"
40 
41 #include "nctype.h"
42 
43 #include "nasm.h"
44 #include "nasmlib.h"
45 #include "ilog2.h"
46 #include "labels.h"
47 #include "error.h"
48 #include "saa.h"
49 #include "raa.h"
50 #include "rbtree.h"
51 #include "hashtbl.h"
52 #include "outform.h"
53 #include "outlib.h"
54 #include "ver.h"
55 #include "dwarf.h"
56 #include "macho.h"
57 
58 #if defined(OF_MACHO) || defined(OF_MACHO64)
59 
60 /* Mach-O in-file header structure sizes */
61 #define MACHO_HEADER_SIZE		28
62 #define MACHO_SEGCMD_SIZE		56
63 #define MACHO_SECTCMD_SIZE		68
64 #define MACHO_SYMCMD_SIZE		24
65 #define MACHO_NLIST_SIZE		12
66 #define MACHO_RELINFO_SIZE		8
67 
68 #define MACHO_HEADER64_SIZE		32
69 #define MACHO_SEGCMD64_SIZE		72
70 #define MACHO_SECTCMD64_SIZE		80
71 #define MACHO_NLIST64_SIZE		16
72 
73 /* Mach-O relocations numbers */
74 
75 #define VM_PROT_DEFAULT	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
76 #define VM_PROT_ALL	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
77 
78 /* Our internal relocation types */
79 enum reltype {
80     RL_ABS,			/* Absolute relocation */
81     RL_REL,			/* Relative relocation */
82     RL_TLV,			/* Thread local */
83     RL_BRANCH,			/* Relative direct branch */
84     RL_SUB,			/* X86_64_RELOC_SUBTRACT */
85     RL_GOT,			/* X86_64_RELOC_GOT */
86     RL_GOTLOAD			/* X86_64_RELOC_GOT_LOAD */
87 };
88 #define RL_MAX_32	RL_TLV
89 #define RL_MAX_64	RL_GOTLOAD
90 
91 struct macho_fmt {
92     uint32_t ptrsize;		/* Pointer size in bytes */
93     uint32_t mh_magic;		/* Which magic number to use */
94     uint32_t cpu_type;		/* Which CPU type */
95     uint32_t lc_segment;	/* Which segment load command */
96     uint32_t header_size;	/* Header size */
97     uint32_t segcmd_size;	/* Segment command size */
98     uint32_t sectcmd_size;	/* Section command size */
99     uint32_t nlist_size;	/* Nlist (symbol) size */
100     enum reltype maxreltype;	/* Maximum entry in enum reltype permitted */
101     uint32_t reloc_abs;		/* Absolute relocation type */
102     uint32_t reloc_rel;		/* Relative relocation type */
103     uint32_t reloc_tlv;		/* Thread local relocation type */
104     bool forcesym;		/* Always use "external" (symbol-relative) relocations */
105 };
106 
107 static struct macho_fmt fmt;
108 
fwriteptr(uint64_t data,FILE * fp)109 static void fwriteptr(uint64_t data, FILE * fp)
110 {
111     fwriteaddr(data, fmt.ptrsize, fp);
112 }
113 
114 struct section {
115     /* nasm internal data */
116     struct section *next;
117     struct SAA *data;
118     int32_t index;		/* Main section index */
119     int32_t subsection;		/* Current subsection index */
120     int32_t fileindex;
121     struct reloc *relocs;
122     struct rbtree *syms[2]; /* All/global symbols symbols in section */
123     int align;
124     bool by_name;	    /* This section was specified by full MachO name */
125     char namestr[34];	    /* segment,section as a C string */
126 
127     /* data that goes into the file */
128     char sectname[16];     /* what this section is called */
129     char segname[16];      /* segment this section will be in */
130     uint64_t addr;         /* in-memory address (subject to alignment) */
131     uint64_t size;         /* in-memory and -file size  */
132     uint64_t offset;	   /* in-file offset */
133     uint32_t pad;          /* padding bytes before section */
134     uint32_t nreloc;       /* relocation entry count */
135     uint32_t flags;        /* type and attributes (masked) */
136     uint32_t extreloc;     /* external relocations */
137 };
138 
139 #define S_NASM_TYPE_MASK	 0x800004ff	/* we consider these bits "section type" */
140 
141 /* fake section for absolute symbols, *not* part of the section linked list */
142 static struct section absolute_sect;
143 
144 struct reloc {
145     /* nasm internal data */
146     struct reloc *next;
147 
148     /* data that goes into the file */
149     int32_t addr;		/* op's offset in section */
150     uint32_t snum:24,		/* contains symbol index if
151 				 ** ext otherwise in-file
152 				 ** section number */
153 	pcrel:1,                /* relative relocation */
154 	length:2,               /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
155 	ext:1,                  /* external symbol referenced */
156 	type:4;                 /* reloc type */
157 };
158 
159 struct symbol {
160     /* nasm internal data */
161     struct rbtree symv[2];	/* All/global symbol rbtrees; "key" contains the
162 				   symbol offset. */
163     struct symbol *next;	/* next symbol in the list */
164     char *name;			/* name of this symbol */
165     int32_t initial_snum;	/* symbol number used above in reloc */
166     int32_t snum;		/* true snum for reloc */
167 
168     /* data that goes into the file */
169     uint32_t strx;              /* string table index */
170     uint8_t type;		/* symbol type */
171     uint8_t sect;		/* NO_SECT or section number */
172     uint16_t desc;		/* for stab debugging, 0 for us */
173 };
174 
175 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
176 
177 static struct section *sects, **sectstail, **sectstab;
178 static struct symbol *syms, **symstail;
179 static uint32_t nsyms;
180 
181 /* These variables are set by macho_layout_symbols() to organize
182    the symbol table and string table in order the dynamic linker
183    expects.  They are then used in macho_write() to put out the
184    symbols and strings in that order.
185 
186    The order of the symbol table is:
187      local symbols
188      defined external symbols (sorted by name)
189      undefined external symbols (sorted by name)
190 
191    The order of the string table is:
192      strings for external symbols
193      strings for local symbols
194  */
195 static uint32_t ilocalsym = 0;
196 static uint32_t iextdefsym = 0;
197 static uint32_t iundefsym = 0;
198 static uint32_t nlocalsym;
199 static uint32_t nextdefsym;
200 static uint32_t nundefsym;
201 static struct symbol **extdefsyms = NULL;
202 static struct symbol **undefsyms = NULL;
203 
204 static struct RAA *extsyms;
205 static struct SAA *strs;
206 static uint32_t strslen;
207 
208 /* Global file information. This should be cleaned up into either
209    a structure or as function arguments.  */
210 static uint32_t head_ncmds = 0;
211 static uint32_t head_sizeofcmds = 0;
212 static uint32_t head_flags = 0;
213 static uint64_t seg_filesize = 0;
214 static uint64_t seg_vmsize = 0;
215 static uint32_t seg_nsects = 0;
216 static uint64_t rel_padcnt = 0;
217 
218 /*
219  * Functions for handling fixed-length zero-padded string
220  * fields, that may or may not be null-terminated.
221  */
222 
223 /* Copy a string into a zero-padded fixed-length field */
224 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
225 
226 /* Compare a fixed-length field with a string */
227 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
228 
229 #define alignint32_t(x)							\
230     ALIGN(x, sizeof(int32_t))	/* align x to int32_t boundary */
231 
232 #define alignint64_t(x)							\
233     ALIGN(x, sizeof(int64_t))	/* align x to int64_t boundary */
234 
235 #define alignptr(x) \
236     ALIGN(x, fmt.ptrsize)	/* align x to output format width */
237 
238 static struct hash_table section_by_name;
239 static struct RAA *section_by_index;
240 
241 static struct section * never_null
find_or_add_section(const char * segname,const char * sectname)242 find_or_add_section(const char *segname, const char *sectname)
243 {
244     struct hash_insert hi;
245     void **sp;
246     struct section *s;
247     char sect[34];
248 
249     snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
250 
251     sp = hash_find(&section_by_name, sect, &hi);
252     if (sp)
253 	return (struct section *)(*sp);
254 
255     s = nasm_zalloc(sizeof *s);
256     xstrncpy(s->segname, segname);
257     xstrncpy(s->sectname, sectname);
258     xstrncpy(s->namestr, sect);
259     hash_add(&hi, s->namestr, s);
260 
261     s->index = s->subsection = seg_alloc();
262     section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
263 
264     return s;
265 }
266 
is_new_section(const struct section * s)267 static inline bool is_new_section(const struct section *s)
268 {
269     return !s->data;
270 }
271 
get_section_by_name(const char * segname,const char * sectname)272 static struct section *get_section_by_name(const char *segname,
273                                            const char *sectname)
274 {
275     char sect[34];
276     void **sp;
277 
278     snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
279 
280     sp = hash_find(&section_by_name, sect, NULL);
281     return sp ? (struct section *)(*sp) : NULL;
282 }
283 
get_section_by_index(int32_t index)284 static struct section *get_section_by_index(int32_t index)
285 {
286     if (index < 0 || index >= SEG_ABS || (index & 1))
287 	return NULL;
288 
289     return raa_read_ptr(section_by_index, index >> 1);
290 }
291 
292 struct dir_list {
293     struct dir_list *next;
294     struct dir_list *last;
295     const char *dir_name;
296     uint32_t dir;
297 };
298 
299 struct file_list {
300     struct file_list *next;
301     struct file_list *last;
302     const char *file_name;
303     uint32_t file;
304     struct dir_list *dir;
305 };
306 
307 struct dw_sect_list {
308     struct SAA *psaa;
309     int32_t section;
310     uint32_t line;
311     uint64_t offset;
312     uint32_t file;
313     struct dw_sect_list *next;
314     struct dw_sect_list *last;
315 };
316 
317 struct section_info {
318     uint64_t size;
319     int32_t secto;
320 };
321 
322 #define DW_LN_BASE (-5)
323 #define DW_LN_RANGE 14
324 #define DW_OPCODE_BASE 13
325 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
326 #define DW_MAX_SP_OPCODE 256
327 
328 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
329 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
330 static struct dw_sect_list  *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
331 static uint32_t  cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
332 static bool  dbg_immcall = false;
333 static const char *module_name = NULL;
334 
335 /*
336  * Special section numbers which are used to define Mach-O special
337  * symbols, which can be used with WRT to provide PIC relocation
338  * types.
339  */
340 static int32_t macho_tlvp_sect;
341 static int32_t macho_gotpcrel_sect;
342 
macho_init(void)343 static void macho_init(void)
344 {
345     module_name = inname;
346     sects = NULL;
347     sectstail = &sects;
348 
349     /* Fake section for absolute symbols */
350     absolute_sect.index = NO_SEG;
351 
352     syms = NULL;
353     symstail = &syms;
354     nsyms = 0;
355     nlocalsym = 0;
356     nextdefsym = 0;
357     nundefsym = 0;
358 
359     extsyms = raa_init();
360     strs = saa_init(1L);
361 
362     section_by_index = raa_init();
363 
364     /* string table starts with a zero byte so index 0 is an empty string */
365     saa_wbytes(strs, zero_buffer, 1);
366     strslen = 1;
367 
368     /* add special symbol for TLVP */
369     macho_tlvp_sect = seg_alloc() + 1;
370     backend_label("..tlvp", macho_tlvp_sect, 0L);
371 }
372 
sect_write(struct section * sect,const uint8_t * data,uint32_t len)373 static void sect_write(struct section *sect,
374                        const uint8_t *data, uint32_t len)
375 {
376     saa_wbytes(sect->data, data, len);
377     sect->size += len;
378 }
379 
380 /*
381  * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
382  */
macho_find_sym(struct section * s,uint64_t offset,bool global,bool exact)383 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
384 				     bool global, bool exact)
385 {
386     struct rbtree *srb;
387 
388     srb = rb_search(s->syms[global], offset);
389 
390     if (!srb || (exact && srb->key != offset)) {
391         nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
392 		   " for this reference",
393 		   global ? " global" : "",
394 		   s == &absolute_sect ? " absolute " : "");
395         return NULL;
396     }
397 
398     return container_of(srb - global, struct symbol, symv);
399 }
400 
add_reloc(struct section * sect,int32_t section,int64_t offset,enum reltype reltype,int bytes)401 static int64_t add_reloc(struct section *sect, int32_t section,
402 			 int64_t offset,
403 			 enum reltype reltype, int bytes)
404 {
405     struct reloc *r;
406     struct section *s;
407     int32_t fi;
408     int64_t adjust;
409 
410     /* Double check this is a valid relocation type for this platform */
411     nasm_assert(reltype <= fmt.maxreltype);
412 
413     /* the current end of the section will be the symbol's address for
414      ** now, might have to be fixed by macho_fixup_relocs() later on. make
415      ** sure we don't make the symbol scattered by setting the highest
416      ** bit by accident */
417     r = nasm_malloc(sizeof(struct reloc));
418     r->addr = sect->size & ~R_SCATTERED;
419     r->ext = 1;
420     adjust = 0;
421 
422     /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
423     r->length = ilog2_32(bytes);
424 
425     /* set default relocation values */
426     r->type = fmt.reloc_abs;
427     r->pcrel = 0;
428     r->snum = R_ABS;
429 
430     s = get_section_by_index(section);
431     fi = s ? s->fileindex : NO_SECT;
432 
433     /* absolute relocation */
434     switch (reltype) {
435     case RL_ABS:
436 	if (section == NO_SEG) {
437 	    /* absolute (can this even happen?) */
438 	    r->ext = 0;
439 	} else if (fi == NO_SECT) {
440 	    /* external */
441 	    r->snum = raa_read(extsyms, section);
442 	} else {
443 	    /* local */
444 	    r->ext = 0;
445 	    r->snum = fi;
446 	}
447 	break;
448 
449     case RL_REL:
450     case RL_BRANCH:
451 	r->type = fmt.reloc_rel;
452 	r->pcrel = 1;
453 	if (section == NO_SEG) {
454 	    /* may optionally be converted below by fmt.forcesym */
455 	    r->ext = 0;
456 	} else if (fi == NO_SECT) {
457 	    /* external */
458 	    sect->extreloc = 1;
459 	    r->snum = raa_read(extsyms, section);
460 	    if (reltype == RL_BRANCH)
461 		r->type = X86_64_RELOC_BRANCH;
462 	} else {
463 	    /* local */
464 	    r->ext = 0;
465 	    r->snum = fi;
466 	    if (reltype == RL_BRANCH)
467 		r->type = X86_64_RELOC_BRANCH;
468 	}
469 	break;
470 
471     case RL_SUB: /* obsolete */
472 	nasm_warn(WARN_OTHER, "relcation with subtraction"
473 		   "becomes to be obsolete");
474 	r->ext = 0;
475 	r->type = X86_64_RELOC_SUBTRACTOR;
476 	break;
477 
478     case RL_GOT:
479 	r->type = X86_64_RELOC_GOT;
480 	goto needsym;
481 
482     case RL_GOTLOAD:
483 	r->type = X86_64_RELOC_GOT_LOAD;
484 	goto needsym;
485 
486     case RL_TLV:
487 	r->type = fmt.reloc_tlv;
488 	goto needsym;
489 
490     needsym:
491 	r->pcrel = (fmt.ptrsize == 8 ? 1 : 0);
492 	if (section == NO_SEG) {
493 	    nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
494 	    goto bail;
495 	} else if (fi == NO_SECT) {
496 	    /* external */
497 	    r->snum = raa_read(extsyms, section);
498 	} else {
499 	    /* internal - GOTPCREL doesn't need to be in global */
500 	    struct symbol *sym = macho_find_sym(s, offset,
501 						false, /* reltype != RL_TLV */
502 						true);
503 	    if (!sym) {
504 		nasm_error(ERR_NONFATAL, "Symbol for WRT not found");
505 		goto bail;
506 	    }
507 
508 	    adjust -= sym->symv[0].key;
509 	    r->snum = sym->initial_snum;
510 	}
511 	break;
512     }
513 
514     /*
515      * For 64-bit Mach-O, force a symbol reference if at all possible
516      * Allow for r->snum == R_ABS by searching absolute_sect
517      */
518     if (!r->ext && fmt.forcesym) {
519 	struct symbol *sym = macho_find_sym(s ? s : &absolute_sect,
520 					    offset, false, false);
521 	if (sym) {
522 	    adjust -= sym->symv[0].key;
523 	    r->snum = sym->initial_snum;
524 	    r->ext = 1;
525 	}
526     }
527 
528     if (r->pcrel)
529 	adjust += ((r->ext && fmt.ptrsize == 8) ? bytes : -(int64_t)sect->size);
530 
531     /* NeXT as puts relocs in reversed order (address-wise) into the
532      ** files, so we do the same, doesn't seem to make much of a
533      ** difference either way */
534     r->next = sect->relocs;
535     sect->relocs = r;
536     if (r->ext)
537 	sect->extreloc = 1;
538     ++sect->nreloc;
539 
540     return adjust;
541 
542  bail:
543     nasm_free(r);
544     return 0;
545 }
546 
macho_output(int32_t secto,const void * data,enum out_type type,uint64_t size,int32_t section,int32_t wrt)547 static void macho_output(int32_t secto, const void *data,
548 			 enum out_type type, uint64_t size,
549                          int32_t section, int32_t wrt)
550 {
551     struct section *s;
552     int64_t addr, offset;
553     uint8_t mydata[16], *p;
554     bool is_bss;
555     enum reltype reltype;
556 
557     s = get_section_by_index(secto);
558     if (!s) {
559         nasm_warn(WARN_OTHER, "attempt to assemble code in"
560               " section %d: defaulting to `.text'", secto);
561         s = get_section_by_name("__TEXT", "__text");
562 
563         /* should never happen */
564         if (!s)
565             nasm_panic("text section not found");
566     }
567 
568     /* debug code generation only for sections tagged with
569      * instruction attribute */
570     if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
571     {
572         struct section_info sinfo;
573         sinfo.size = s->size;
574         sinfo.secto = secto;
575         dfmt->debug_output(0, &sinfo);
576     }
577 
578     is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
579 
580     if (is_bss && type != OUT_RESERVE) {
581         nasm_warn(WARN_OTHER, "attempt to initialize memory in "
582               "BSS section: ignored");
583         /* FIXME */
584         nasm_warn(WARN_OTHER, "section size may be negative"
585             "with address symbols");
586         s->size += realsize(type, size);
587         return;
588     }
589 
590     memset(mydata, 0, sizeof(mydata));
591 
592     switch (type) {
593     case OUT_RESERVE:
594         if (!is_bss) {
595             nasm_warn(WARN_ZEROING, "uninitialized space declared in"
596 		       " %s,%s section: zeroing", s->segname, s->sectname);
597 
598             sect_write(s, NULL, size);
599         } else
600             s->size += size;
601 
602         break;
603 
604     case OUT_RAWDATA:
605         sect_write(s, data, size);
606         break;
607 
608     case OUT_ADDRESS:
609     {
610 	int asize = abs((int)size);
611 
612         addr = *(int64_t *)data;
613         if (section != NO_SEG) {
614             if (section % 2) {
615                 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
616 			   " section base references");
617             } else if (wrt == NO_SEG) {
618 		if (fmt.ptrsize == 8 && asize != 8) {
619 		    nasm_error(ERR_NONFATAL,
620 			       "Mach-O 64-bit format does not support"
621 			       " 32-bit absolute addresses");
622 		} else {
623 		    addr += add_reloc(s, section, addr, RL_ABS, asize);
624 		}
625 	    } else if (wrt == macho_tlvp_sect && fmt.ptrsize != 8 &&
626 		       asize == (int) fmt.ptrsize) {
627 		addr += add_reloc(s, section, addr, RL_TLV, asize);
628 	    } else {
629 		nasm_error(ERR_NONFATAL, "Mach-O format does not support"
630 			   " this use of WRT");
631 	    }
632 	}
633 
634         p = mydata;
635 	WRITEADDR(p, addr, asize);
636         sect_write(s, mydata, asize);
637         break;
638     }
639 
640     case OUT_REL1ADR:
641     case OUT_REL2ADR:
642 
643         p = mydata;
644 	offset = *(int64_t *)data;
645         addr = offset - size;
646 
647         if (section != NO_SEG && section % 2) {
648             nasm_error(ERR_NONFATAL, "Mach-O format does not support"
649 		       " section base references");
650 	} else if (fmt.ptrsize == 8) {
651 	    nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
652 		       " Macho-O relocation [2]");
653 	} else if (wrt != NO_SEG) {
654 	    nasm_error(ERR_NONFATAL, "Mach-O format does not support"
655 		       " this use of WRT");
656 	    wrt = NO_SEG;	/* we can at least _try_ to continue */
657 	} else {
658 	    addr += add_reloc(s, section, addr+size, RL_REL,
659                               type == OUT_REL1ADR ? 1 : 2);
660 	}
661 
662         WRITESHORT(p, addr);
663         sect_write(s, mydata, type == OUT_REL1ADR ? 1 : 2);
664         break;
665 
666     case OUT_REL4ADR:
667     case OUT_REL8ADR:
668 
669         p = mydata;
670 	offset = *(int64_t *)data;
671         addr = offset - size;
672 	reltype = RL_REL;
673 
674         if (section != NO_SEG && section % 2) {
675             nasm_error(ERR_NONFATAL, "Mach-O format does not support"
676 		       " section base references");
677         } else if (wrt == NO_SEG) {
678 	    if (fmt.ptrsize == 8 &&
679 		(s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
680 		uint8_t opcode[2];
681 
682 		opcode[0] = opcode[1] = 0;
683 
684 		/* HACK: Retrieve instruction opcode */
685 		if (likely(s->data->datalen >= 2)) {
686 		    saa_fread(s->data, s->data->datalen-2, opcode, 2);
687 		} else if (s->data->datalen == 1) {
688 		    saa_fread(s->data, 0, opcode+1, 1);
689 		}
690 
691 		if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
692 		    (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
693 		    /* Direct call, jmp, or jcc */
694 		    reltype = RL_BRANCH;
695 		}
696 	    }
697 	} else if (wrt == macho_gotpcrel_sect) {
698 	    reltype = RL_GOT;
699 
700 	    if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
701 		s->data->datalen >= 3) {
702 		uint8_t gotload[3];
703 
704 		/* HACK: Retrieve instruction opcode */
705 		saa_fread(s->data, s->data->datalen-3, gotload, 3);
706 		if ((gotload[0] & 0xf8) == 0x48 &&
707 		    gotload[1] == 0x8b &&
708 		    (gotload[2] & 0307) == 0005) {
709 		    /* movq <reg>,[rel sym wrt ..gotpcrel] */
710 		    reltype = RL_GOTLOAD;
711 		}
712 	    }
713 	} else if (wrt == macho_tlvp_sect && fmt.ptrsize == 8) {
714 	    reltype = RL_TLV;
715 	} else {
716 	    nasm_error(ERR_NONFATAL, "Mach-O format does not support"
717 		       " this use of WRT");
718 	    /* continue with RL_REL */
719 	}
720 
721 	addr += add_reloc(s, section, offset, reltype,
722                           type == OUT_REL4ADR ? 4 : 8);
723         WRITELONG(p, addr);
724         sect_write(s, mydata, type == OUT_REL4ADR ? 4 : 8);
725         break;
726 
727     default:
728         nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
729         break;
730     }
731 }
732 
733 #define S_CODE  (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
734 #define NO_TYPE S_NASM_TYPE_MASK
735 
736 /* Translation table from traditional Unix section names to Mach-O */
737 static const struct macho_known_section {
738     const char      *nasmsect;
739     const char      *segname;
740     const char      *sectname;
741     const uint32_t  flags;
742 } known_sections[] = {
743     { ".text",          "__TEXT",   "__text",           S_CODE          },
744     { ".data",          "__DATA",   "__data",           S_REGULAR       },
745     { ".rodata",        "__DATA",   "__const",          S_REGULAR       },
746     { ".bss",           "__DATA",   "__bss",            S_ZEROFILL      },
747     { ".debug_abbrev",  "__DWARF",  "__debug_abbrev",   S_ATTR_DEBUG    },
748     { ".debug_info",    "__DWARF",  "__debug_info",     S_ATTR_DEBUG    },
749     { ".debug_line",    "__DWARF",  "__debug_line",     S_ATTR_DEBUG    },
750     { ".debug_str",     "__DWARF",  "__debug_str",      S_ATTR_DEBUG    },
751 };
752 
753 /* Section type or attribute directives */
754 static const struct macho_known_section_attr {
755     const char      *name;
756     uint32_t        flags;
757 } sect_attribs[] = {
758     { "data",               S_REGULAR                               },
759     { "code",               S_CODE                                  },
760     { "mixed",              S_REGULAR | S_ATTR_SOME_INSTRUCTIONS    },
761     { "bss",                S_ZEROFILL                              },
762     { "zerofill",           S_ZEROFILL                              },
763     { "no_dead_strip",      NO_TYPE | S_ATTR_NO_DEAD_STRIP          },
764     { "live_support",       NO_TYPE | S_ATTR_LIVE_SUPPORT           },
765     { "strip_static_syms",  NO_TYPE | S_ATTR_STRIP_STATIC_SYMS      },
766     { "debug",              NO_TYPE | S_ATTR_DEBUG                  },
767     { NULL, 0 }
768 };
769 
770 static const struct macho_known_section *
lookup_known_section(const char * name,bool by_sectname)771 lookup_known_section(const char *name, bool by_sectname)
772 {
773     size_t i;
774 
775     if (name && name[0]) {
776             for (i = 0; i < ARRAY_SIZE(known_sections); i++) {
777                 const char *p = by_sectname ?
778                     known_sections[i].sectname :
779                     known_sections[i].nasmsect;
780                 if (!strcmp(name, p))
781                     return &known_sections[i];
782             }
783     }
784 
785     return NULL;
786 }
787 
macho_section(char * name,int * bits)788 static int32_t macho_section(char *name, int *bits)
789 {
790     const struct macho_known_section *known_section;
791     const struct macho_known_section_attr *sa;
792     char *sectionAttributes;
793     struct section *s;
794     const char *section, *segment;
795     uint32_t flags;
796     char *currentAttribute;
797     char *comma;
798 
799     bool new_seg;
800 
801     /* Default to the appropriate number of bits. */
802     if (!name) {
803         *bits = fmt.ptrsize << 3;
804         name = ".text";
805         sectionAttributes = NULL;
806     } else {
807         sectionAttributes = name;
808         name = nasm_strsep(&sectionAttributes, " \t");
809     }
810 
811     section = segment = NULL;
812     flags = 0;
813 
814     comma = strchr(name, ',');
815     if (comma) {
816 	int len;
817 
818 	*comma = '\0';
819 	segment = name;
820 	section = comma+1;
821 
822 	len = strlen(segment);
823 	if (len == 0) {
824 	    nasm_error(ERR_NONFATAL, "empty segment name\n");
825 	} else if (len > 16) {
826 	    nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
827 	}
828 
829 	len = strlen(section);
830 	if (len == 0) {
831 	    nasm_error(ERR_NONFATAL, "empty section name\n");
832 	} else if (len > 16) {
833 	    nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
834 	}
835 
836         known_section = lookup_known_section(section, true);
837         if (known_section)
838             flags = known_section->flags;
839         else
840             flags = S_REGULAR;
841     } else {
842         known_section = lookup_known_section(name, false);
843         if (!known_section) {
844             nasm_error(ERR_NONFATAL, "unknown section name %s\n", name);
845             return NO_SEG;
846         }
847 
848         segment = known_section->segname;
849         section = known_section->sectname;
850         flags = known_section->flags;
851     }
852 
853     /* try to find section with that name, or create it */
854     s = find_or_add_section(segment, section);
855     new_seg = is_new_section(s);
856 
857     /* initialize it if it is a brand new section */
858     if (new_seg) {
859 	*sectstail = s;
860 	sectstail = &s->next;
861 
862 	s->data = saa_init(1L);
863 	s->fileindex = ++seg_nsects;
864 	s->align = -1;
865 	s->pad = -1;
866 	s->offset = -1;
867 	s->by_name = false;
868 
869 	s->size = 0;
870 	s->nreloc = 0;
871 	s->flags = flags;
872     }
873 
874     if (comma)
875 	*comma = ',';		/* Restore comma */
876 
877     s->by_name = s->by_name || comma; /* Was specified by name */
878 
879     flags = NO_TYPE;
880 
881     while (sectionAttributes &&
882 	   (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
883 	if (!*currentAttribute)
884 	    continue;
885 
886 	if (!nasm_strnicmp("align=", currentAttribute, 6)) {
887 	    char *end;
888 	    int newAlignment, value;
889 
890 	    value = strtoul(currentAttribute + 6, (char**)&end, 0);
891 	    newAlignment = alignlog2_32(value);
892 
893 	    if (0 != *end) {
894 		nasm_error(ERR_NONFATAL,
895 			   "unknown or missing alignment value \"%s\" "
896 			   "specified for section \"%s\"",
897 			   currentAttribute + 6,
898 			   name);
899 	    } else if (0 > newAlignment) {
900 		nasm_error(ERR_NONFATAL,
901 			   "alignment of %d (for section \"%s\") is not "
902 			   "a power of two",
903 			   value,
904 			   name);
905 	    }
906 
907 	    if (s->align < newAlignment)
908 		s->align = newAlignment;
909 	} else {
910 	    for (sa = sect_attribs; sa->name; sa++) {
911 		if (!nasm_stricmp(sa->name, currentAttribute)) {
912 		    if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
913 			flags = (flags & ~S_NASM_TYPE_MASK)
914 			    | (sa->flags & S_NASM_TYPE_MASK);
915 		    }
916 		    flags |= sa->flags & ~S_NASM_TYPE_MASK;
917 		    break;
918 		}
919 	    }
920 
921 	    if (!sa->name) {
922 		nasm_error(ERR_NONFATAL,
923 			   "unknown section attribute %s for section %s",
924 			   currentAttribute, name);
925 	    }
926 	}
927     }
928 
929     if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
930 	if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
931 	    nasm_error(ERR_NONFATAL,
932 		       "inconsistent section attributes for section %s\n",
933 		       name);
934 	} else {
935 	    s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
936 	}
937     } else {
938 	s->flags |= flags & ~S_NASM_TYPE_MASK;
939     }
940 
941     return s->subsection;
942 }
943 
macho_herelabel(const char * name,enum label_type type,int32_t section,int32_t * subsection,bool * copyoffset)944 static int32_t macho_herelabel(const char *name, enum label_type type,
945 			       int32_t section, int32_t *subsection,
946 			       bool *copyoffset)
947 {
948     struct section *s;
949     int32_t subsec;
950     (void)name;
951 
952     if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
953 	return section;
954 
955     /* No subsection only for local labels */
956     if (type == LBL_LOCAL)
957 	return section;
958 
959     s = get_section_by_index(section);
960     if (!s)
961 	return section;
962 
963     subsec = *subsection;
964     if (subsec == NO_SEG) {
965 	/* Allocate a new subsection index */
966 	subsec = *subsection = seg_alloc();
967 	section_by_index = raa_write_ptr(section_by_index, subsec >> 1, s);
968     }
969 
970     s->subsection = subsec;
971     *copyoffset = true;		/* Maintain previous offset */
972     return subsec;
973 }
974 
macho_symdef(char * name,int32_t section,int64_t offset,int is_global,char * special)975 static void macho_symdef(char *name, int32_t section, int64_t offset,
976                          int is_global, char *special)
977 {
978     struct symbol *sym;
979     struct section *s;
980     bool special_used = false;
981 
982 #if defined(DEBUG) && DEBUG>2
983     nasm_error(ERR_DEBUG,
984             " macho_symdef: %s, pass=%"PRId64" type %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
985 	       name, pass_count(), pass_types[pass_type()],
986 	       section, offset, is_global, special);
987 #endif
988 
989     if (is_global == 3) {
990         if (special) {
991             int n = strcspn(special, " \t");
992 
993             if (!nasm_strnicmp(special, "private_extern", n)) {
994                 for (sym = syms; sym != NULL; sym = sym->next) {
995                     if (!strcmp(name, sym->name)) {
996                         if (sym->type & N_PEXT)
997                             return; /* nothing to be done */
998                         else
999                             break;
1000                     }
1001                 }
1002             }
1003         }
1004         nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1005               "(yet) support forward reference fixups.");
1006         return;
1007     }
1008 
1009     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1010 	/*
1011 	 * This is a NASM special symbol. We never allow it into
1012 	 * the Macho-O symbol table, even if it's a valid one. If it
1013 	 * _isn't_ a valid one, we should barf immediately.
1014 	 */
1015 	if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1016             nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1017 	return;
1018     }
1019 
1020     sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1021     sym->next = NULL;
1022     symstail = &sym->next;
1023 
1024     sym->name = name;
1025     sym->strx = strslen;
1026     sym->type = 0;
1027     sym->desc = 0;
1028     sym->symv[0].key = offset;
1029     sym->symv[1].key = offset;
1030     sym->initial_snum = -1;
1031 
1032     /* external and common symbols get N_EXT */
1033     if (is_global != 0) {
1034         sym->type |= N_EXT;
1035     }
1036     if (is_global == 1) {
1037         /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1038         if (special) {
1039             int n = strcspn(special, " \t");
1040 
1041             if (!nasm_strnicmp(special, "private_extern", n))
1042                 sym->type |= N_PEXT;
1043             else
1044                 nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'", n, special);
1045         }
1046         special_used = true;
1047     }
1048 
1049     /* track the initially allocated symbol number for use in future fix-ups */
1050     sym->initial_snum = nsyms;
1051 
1052     if (section == NO_SEG) {
1053         /* symbols in no section get absolute */
1054         sym->type |= N_ABS;
1055         sym->sect = NO_SECT;
1056 
1057 	s = &absolute_sect;
1058     } else {
1059 	s = get_section_by_index(section);
1060 
1061         sym->type |= N_SECT;
1062 
1063         /* get the in-file index of the section the symbol was defined in */
1064         sym->sect = s ? s->fileindex : NO_SECT;
1065 
1066         if (!s) {
1067             /* remember symbol number of references to external
1068              ** symbols, this works because every external symbol gets
1069              ** its own section number allocated internally by nasm and
1070              ** can so be used as a key */
1071 	    extsyms = raa_write(extsyms, section, nsyms);
1072 
1073             switch (is_global) {
1074             case 1:
1075             case 2:
1076                 /* there isn't actually a difference between global
1077                  ** and common symbols, both even have their size in
1078                  ** sym->symv[0].key */
1079                 sym->type = N_EXT;
1080                 break;
1081 
1082             default:
1083                 /* give an error on unfound section if it's not an
1084                  ** external or common symbol (assemble_file() does a
1085                  ** seg_alloc() on every call for them) */
1086                 nasm_panic("in-file index for section %d not found, is_global = %d", section, is_global);
1087 		break;
1088             }
1089 	}
1090     }
1091 
1092     if (s) {
1093 	s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1094 	if (is_global)
1095 	    s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1096     }
1097 
1098     ++nsyms;
1099 
1100     if (special && !special_used)
1101         nasm_error(ERR_NONFATAL, "no special symbol features supported here");
1102 }
1103 
macho_sectalign(int32_t seg,unsigned int value)1104 static void macho_sectalign(int32_t seg, unsigned int value)
1105 {
1106     struct section *s;
1107     int align;
1108 
1109     nasm_assert(!(seg & 1));
1110 
1111     s = get_section_by_index(seg);
1112 
1113     if (!s || !is_power2(value))
1114         return;
1115 
1116     align = alignlog2_32(value);
1117     if (s->align < align)
1118         s->align = align;
1119 }
1120 
1121 extern macros_t macho_stdmac[];
1122 
1123 /* Comparison function for qsort symbol layout.  */
layout_compare(const struct symbol ** s1,const struct symbol ** s2)1124 static int layout_compare (const struct symbol **s1,
1125 			   const struct symbol **s2)
1126 {
1127     return (strcmp ((*s1)->name, (*s2)->name));
1128 }
1129 
1130 /* The native assembler does a few things in a similar function
1131 
1132 	* Remove temporary labels
1133 	* Sort symbols according to local, external, undefined (by name)
1134 	* Order the string table
1135 
1136    We do not remove temporary labels right now.
1137 
1138    numsyms is the total number of symbols we have. strtabsize is the
1139    number entries in the string table.  */
1140 
macho_layout_symbols(uint32_t * numsyms,uint32_t * strtabsize)1141 static void macho_layout_symbols (uint32_t *numsyms,
1142 				  uint32_t *strtabsize)
1143 {
1144     struct symbol *sym, **symp;
1145     uint32_t i,j;
1146 
1147     *numsyms = 0;
1148     *strtabsize = sizeof (char);
1149 
1150     symp = &syms;
1151 
1152     while ((sym = *symp)) {
1153 	/* Undefined symbols are now external.  */
1154 	if (sym->type == N_UNDF)
1155 	    sym->type |= N_EXT;
1156 
1157 	if ((sym->type & N_EXT) == 0) {
1158 	    sym->snum = *numsyms;
1159 	    *numsyms = *numsyms + 1;
1160 	    nlocalsym++;
1161 	}
1162 	else {
1163 	    if ((sym->type & N_TYPE) != N_UNDF) {
1164 		nextdefsym++;
1165 	    } else {
1166 		nundefsym++;
1167 	    }
1168 
1169 	    /* If we handle debug info we'll want
1170 	       to check for it here instead of just
1171 	       adding the symbol to the string table.  */
1172 	    sym->strx = *strtabsize;
1173 	    saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1174 	    *strtabsize += strlen(sym->name) + 1;
1175 	}
1176 	symp = &(sym->next);
1177     }
1178 
1179     /* Next, sort the symbols.  Most of this code is a direct translation from
1180        the Apple cctools symbol layout. We need to keep compatibility with that.  */
1181     /* Set the indexes for symbol groups into the symbol table */
1182     ilocalsym = 0;
1183     iextdefsym = nlocalsym;
1184     iundefsym = nlocalsym + nextdefsym;
1185 
1186     /* allocate arrays for sorting externals by name */
1187     extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1188     undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1189 
1190     i = 0;
1191     j = 0;
1192 
1193     symp = &syms;
1194 
1195     while ((sym = *symp)) {
1196 
1197 	if((sym->type & N_EXT) == 0) {
1198 	    sym->strx = *strtabsize;
1199 	    saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1200 	    *strtabsize += strlen(sym->name) + 1;
1201 	}
1202 	else {
1203 	    if ((sym->type & N_TYPE) != N_UNDF) {
1204 		extdefsyms[i++] = sym;
1205 	    } else {
1206 		undefsyms[j++] = sym;
1207 	    }
1208 	}
1209 	symp = &(sym->next);
1210     }
1211 
1212     qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1213 	  (int (*)(const void *, const void *))layout_compare);
1214     qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1215 	  (int (*)(const void *, const void *))layout_compare);
1216 
1217     for(i = 0; i < nextdefsym; i++) {
1218 	extdefsyms[i]->snum = *numsyms;
1219 	*numsyms += 1;
1220     }
1221     for(j = 0; j < nundefsym; j++) {
1222 	undefsyms[j]->snum = *numsyms;
1223 	*numsyms += 1;
1224     }
1225 }
1226 
1227 /* Calculate some values we'll need for writing later.  */
1228 
macho_calculate_sizes(void)1229 static void macho_calculate_sizes (void)
1230 {
1231     struct section *s;
1232     int fi;
1233 
1234     /* count sections and calculate in-memory and in-file offsets */
1235     for (s = sects; s != NULL; s = s->next) {
1236         uint64_t newaddr;
1237 
1238         /* recalculate segment address based on alignment and vm size */
1239         s->addr = seg_vmsize;
1240 
1241         /* we need section alignment to calculate final section address */
1242         if (s->align == -1)
1243             s->align = DEFAULT_SECTION_ALIGNMENT;
1244 
1245         newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1246         s->addr = newaddr;
1247 
1248         seg_vmsize = newaddr + s->size;
1249 
1250         /* zerofill sections aren't actually written to the file */
1251         if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1252 	    /*
1253 	     * LLVM/Xcode as always aligns the section data to 4
1254 	     * bytes; there is a comment in the LLVM source code that
1255 	     * perhaps aligning to pointer size would be better.
1256 	     */
1257 	    s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1258 	    s->offset = seg_filesize + s->pad;
1259             seg_filesize += s->size + s->pad;
1260 
1261             /* filesize and vmsize needs to be aligned */
1262             seg_vmsize += s->pad;
1263 	}
1264     }
1265 
1266     /* calculate size of all headers, load commands and sections to
1267     ** get a pointer to the start of all the raw data */
1268     if (seg_nsects > 0) {
1269         ++head_ncmds;
1270         head_sizeofcmds += fmt.segcmd_size  + seg_nsects * fmt.sectcmd_size;
1271     }
1272 
1273     if (nsyms > 0) {
1274 	++head_ncmds;
1275 	head_sizeofcmds += MACHO_SYMCMD_SIZE;
1276     }
1277 
1278     if (seg_nsects > MAX_SECT) {
1279 	nasm_fatal("MachO output is limited to %d sections\n",
1280 		   MAX_SECT);
1281     }
1282 
1283     /* Create a table of sections by file index to avoid linear search */
1284     sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1285     sectstab[NO_SECT] = &absolute_sect;
1286     for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1287 	sectstab[fi] = s;
1288 }
1289 
1290 /* Write out the header information for the file.  */
1291 
macho_write_header(void)1292 static void macho_write_header (void)
1293 {
1294     fwriteint32_t(fmt.mh_magic, ofile);	/* magic */
1295     fwriteint32_t(fmt.cpu_type, ofile);	/* CPU type */
1296     fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile);	/* CPU subtype */
1297     fwriteint32_t(MH_OBJECT, ofile);	/* Mach-O file type */
1298     fwriteint32_t(head_ncmds, ofile);	/* number of load commands */
1299     fwriteint32_t(head_sizeofcmds, ofile);	/* size of load commands */
1300     fwriteint32_t(head_flags, ofile);		/* flags, if any */
1301     fwritezero(fmt.header_size - 7*4, ofile);	/* reserved fields */
1302 }
1303 
1304 /* Write out the segment load command at offset.  */
1305 
macho_write_segment(uint64_t offset)1306 static uint32_t macho_write_segment (uint64_t offset)
1307 {
1308     uint64_t rel_base = alignptr(offset + seg_filesize);
1309     uint32_t s_reloff = 0;
1310     struct section *s;
1311 
1312     fwriteint32_t(fmt.lc_segment, ofile);        /* cmd == LC_SEGMENT_64 */
1313 
1314     /* size of load command including section load commands */
1315     fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1316 		  ofile);
1317 
1318     /* in an MH_OBJECT file all sections are in one unnamed (name
1319     ** all zeros) segment */
1320     fwritezero(16, ofile);
1321     fwriteptr(0, ofile);		     /* in-memory offset */
1322     fwriteptr(seg_vmsize, ofile);	     /* in-memory size */
1323     fwriteptr(offset, ofile);	             /* in-file offset to data */
1324     fwriteptr(seg_filesize, ofile);	     /* in-file size */
1325     fwriteint32_t(VM_PROT_DEFAULT, ofile);   /* maximum vm protection */
1326     fwriteint32_t(VM_PROT_DEFAULT, ofile);   /* initial vm protection */
1327     fwriteint32_t(seg_nsects, ofile);        /* number of sections */
1328     fwriteint32_t(0, ofile);		     /* no flags */
1329 
1330     /* emit section headers */
1331     for (s = sects; s != NULL; s = s->next) {
1332 	if (s->nreloc) {
1333 	    nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1334 	    s->flags |= S_ATTR_LOC_RELOC;
1335 	    if (s->extreloc)
1336 		s->flags |= S_ATTR_EXT_RELOC;
1337 	} else if (!xstrncmp(s->segname, "__DATA") &&
1338 		   !xstrncmp(s->sectname, "__const") &&
1339 		   !s->by_name &&
1340 		   !get_section_by_name("__TEXT", "__const")) {
1341 	    /*
1342 	     * The MachO equivalent to .rodata can be either
1343 	     * __DATA,__const or __TEXT,__const; the latter only if
1344 	     * there are no relocations.  However, when mixed it is
1345 	     * better to specify the segments explicitly.
1346 	     */
1347 	    xstrncpy(s->segname, "__TEXT");
1348 	}
1349 
1350         nasm_write(s->sectname, sizeof(s->sectname), ofile);
1351         nasm_write(s->segname, sizeof(s->segname), ofile);
1352         fwriteptr(s->addr, ofile);
1353         fwriteptr(s->size, ofile);
1354 
1355         /* dummy data for zerofill sections or proper values */
1356         if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1357 	    nasm_assert(s->pad != (uint32_t)-1);
1358 	    offset += s->pad;
1359             fwriteint32_t(offset, ofile);
1360 	    offset += s->size;
1361             /* Write out section alignment, as a power of two.
1362             e.g. 32-bit word alignment would be 2 (2^2 = 4).  */
1363             fwriteint32_t(s->align, ofile);
1364             /* To be compatible with cctools as we emit
1365             a zero reloff if we have no relocations.  */
1366             fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1367             fwriteint32_t(s->nreloc, ofile);
1368 
1369             s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1370         } else {
1371             fwriteint32_t(0, ofile);
1372             fwriteint32_t(s->align, ofile);
1373             fwriteint32_t(0, ofile);
1374             fwriteint32_t(0, ofile);
1375         }
1376 
1377         fwriteint32_t(s->flags, ofile);      /* flags */
1378         fwriteint32_t(0, ofile);	     /* reserved */
1379         fwriteptr(0, ofile);		     /* reserved */
1380     }
1381 
1382     rel_padcnt = rel_base - offset;
1383     offset = rel_base + s_reloff;
1384 
1385     return offset;
1386 }
1387 
1388 /* For a given chain of relocs r, write out the entire relocation
1389    chain to the object file.  */
1390 
macho_write_relocs(struct reloc * r)1391 static void macho_write_relocs (struct reloc *r)
1392 {
1393     while (r) {
1394 	uint32_t word2;
1395 
1396 	fwriteint32_t(r->addr, ofile); /* reloc offset */
1397 
1398 	word2 = r->snum;
1399 	word2 |= r->pcrel << 24;
1400 	word2 |= r->length << 25;
1401 	word2 |= r->ext << 27;
1402 	word2 |= r->type << 28;
1403 	fwriteint32_t(word2, ofile); /* reloc data */
1404 	r = r->next;
1405     }
1406 }
1407 
1408 /* Write out the section data.  */
macho_write_section(void)1409 static void macho_write_section (void)
1410 {
1411     struct section *s;
1412     struct reloc *r;
1413     uint8_t *p;
1414     int32_t len;
1415     int64_t l;
1416     union offset {
1417 	uint64_t val;
1418 	uint8_t buf[8];
1419     } blk;
1420 
1421     for (s = sects; s != NULL; s = s->next) {
1422 	if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1423 	    continue;
1424 
1425 	/* Like a.out Mach-O references things in the data or bss
1426 	 * sections by addresses which are actually relative to the
1427 	 * start of the _text_ section, in the _file_. See outaout.c
1428 	 * for more information. */
1429 	saa_rewind(s->data);
1430 	for (r = s->relocs; r != NULL; r = r->next) {
1431 	    len = (uint32_t)1 << r->length;
1432 	    if (len > 4)	/* Can this ever be an issue?! */
1433 		len = 8;
1434 	    blk.val = 0;
1435 	    saa_fread(s->data, r->addr, blk.buf, len);
1436 
1437 	    /* get offset based on relocation type */
1438 #ifdef WORDS_LITTLEENDIAN
1439 	    l = blk.val;
1440 #else
1441 	    l  = blk.buf[0];
1442 	    l += ((int64_t)blk.buf[1]) << 8;
1443 	    l += ((int64_t)blk.buf[2]) << 16;
1444 	    l += ((int64_t)blk.buf[3]) << 24;
1445 	    l += ((int64_t)blk.buf[4]) << 32;
1446 	    l += ((int64_t)blk.buf[5]) << 40;
1447 	    l += ((int64_t)blk.buf[6]) << 48;
1448 	    l += ((int64_t)blk.buf[7]) << 56;
1449 #endif
1450 
1451 	    /* If the relocation is internal add to the current section
1452 	       offset. Otherwise the only value we need is the symbol
1453 	       offset which we already have. The linker takes care
1454 	       of the rest of the address.  */
1455 	    if (!r->ext) {
1456 		/* generate final address by section address and offset */
1457 		nasm_assert(r->snum <= seg_nsects);
1458 		l += sectstab[r->snum]->addr;
1459 		if (r->pcrel)
1460 		    l -= s->addr;
1461 	    } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1462 		l -= s->addr;
1463 	    }
1464 
1465 	    /* write new offset back */
1466 	    p = blk.buf;
1467 	    WRITEDLONG(p, l);
1468 	    saa_fwrite(s->data, r->addr, blk.buf, len);
1469 	}
1470 
1471 	/* dump the section data to file */
1472 	fwritezero(s->pad, ofile);
1473 	saa_fpwrite(s->data, ofile);
1474     }
1475 
1476     /* pad last section up to reloc entries on pointer boundary */
1477     fwritezero(rel_padcnt, ofile);
1478 
1479     /* emit relocation entries */
1480     for (s = sects; s != NULL; s = s->next)
1481 	macho_write_relocs (s->relocs);
1482 }
1483 
1484 /* Write out the symbol table. We should already have sorted this
1485    before now.  */
macho_write_symtab(void)1486 static void macho_write_symtab (void)
1487 {
1488     struct symbol *sym;
1489     uint64_t i;
1490 
1491     /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1492 
1493     for (sym = syms; sym != NULL; sym = sym->next) {
1494 	if ((sym->type & N_EXT) == 0) {
1495 	    fwriteint32_t(sym->strx, ofile);		/* string table entry number */
1496 	    nasm_write(&sym->type, 1, ofile);		/* symbol type */
1497 	    nasm_write(&sym->sect, 1, ofile);		/* section */
1498 	    fwriteint16_t(sym->desc, ofile);		/* description */
1499 
1500 	    /* Fix up the symbol value now that we know the final section
1501 	       sizes.  */
1502 	    if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1503 		nasm_assert(sym->sect <= seg_nsects);
1504 		sym->symv[0].key += sectstab[sym->sect]->addr;
1505 	    }
1506 
1507 	    fwriteptr(sym->symv[0].key, ofile);	/* value (i.e. offset) */
1508 	}
1509     }
1510 
1511     for (i = 0; i < nextdefsym; i++) {
1512 	sym = extdefsyms[i];
1513 	fwriteint32_t(sym->strx, ofile);
1514 	nasm_write(&sym->type, 1, ofile);	/* symbol type */
1515 	nasm_write(&sym->sect, 1, ofile);	/* section */
1516 	fwriteint16_t(sym->desc, ofile);	/* description */
1517 
1518 	/* Fix up the symbol value now that we know the final section
1519 	   sizes.  */
1520 	if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1521 	    nasm_assert(sym->sect <= seg_nsects);
1522 	    sym->symv[0].key += sectstab[sym->sect]->addr;
1523 	}
1524 
1525 	fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1526     }
1527 
1528      for (i = 0; i < nundefsym; i++) {
1529 	 sym = undefsyms[i];
1530 	 fwriteint32_t(sym->strx, ofile);
1531 	 nasm_write(&sym->type, 1, ofile);	/* symbol type */
1532 	 nasm_write(&sym->sect, 1, ofile);	/* section */
1533 	 fwriteint16_t(sym->desc, ofile);	/* description */
1534 
1535 	/* Fix up the symbol value now that we know the final section
1536 	   sizes.  */
1537 	 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1538 	    nasm_assert(sym->sect <= seg_nsects);
1539 	    sym->symv[0].key += sectstab[sym->sect]->addr;
1540 	 }
1541 
1542 	 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1543      }
1544 
1545 }
1546 
1547 /* Fixup the snum in the relocation entries, we should be
1548    doing this only for externally referenced symbols. */
macho_fixup_relocs(struct reloc * r)1549 static void macho_fixup_relocs (struct reloc *r)
1550 {
1551     struct symbol *sym;
1552 
1553     while (r != NULL) {
1554 	if (r->ext) {
1555 	    for (sym = syms; sym != NULL; sym = sym->next) {
1556 		if (sym->initial_snum == r->snum) {
1557 		    r->snum = sym->snum;
1558 		    break;
1559 		}
1560 	    }
1561 	}
1562 	r = r->next;
1563     }
1564 }
1565 
1566 /* Write out the object file.  */
1567 
macho_write(void)1568 static void macho_write (void)
1569 {
1570     uint64_t offset = 0;
1571 
1572     /* mach-o object file structure:
1573     **
1574     ** mach header
1575     **  uint32_t magic
1576     **  int   cpu type
1577     **  int   cpu subtype
1578     **  uint32_t mach file type
1579     **  uint32_t number of load commands
1580     **  uint32_t size of all load commands
1581     **   (includes section struct size of segment command)
1582     **  uint32_t flags
1583     **
1584     ** segment command
1585     **  uint32_t command type == LC_SEGMENT[_64]
1586     **  uint32_t size of load command
1587     **   (including section load commands)
1588     **  char[16] segment name
1589     **  pointer  in-memory offset
1590     **  pointer  in-memory size
1591     **  pointer  in-file offset to data area
1592     **  pointer  in-file size
1593     **   (in-memory size excluding zerofill sections)
1594     **  int   maximum vm protection
1595     **  int   initial vm protection
1596     **  uint32_t number of sections
1597     **  uint32_t flags
1598     **
1599     ** section commands
1600     **   char[16] section name
1601     **   char[16] segment name
1602     **   pointer  in-memory offset
1603     **   pointer  in-memory size
1604     **   uint32_t in-file offset
1605     **   uint32_t alignment
1606     **    (irrelevant in MH_OBJECT)
1607     **   uint32_t in-file offset of relocation entires
1608     **   uint32_t number of relocations
1609     **   uint32_t flags
1610     **   uint32_t reserved
1611     **   uint32_t reserved
1612     **
1613     ** symbol table command
1614     **  uint32_t command type == LC_SYMTAB
1615     **  uint32_t size of load command
1616     **  uint32_t symbol table offset
1617     **  uint32_t number of symbol table entries
1618     **  uint32_t string table offset
1619     **  uint32_t string table size
1620     **
1621     ** raw section data
1622     **
1623     ** padding to pointer boundary
1624     **
1625     ** relocation data (struct reloc)
1626     ** int32_t offset
1627     **  uint data (symbolnum, pcrel, length, extern, type)
1628     **
1629     ** symbol table data (struct nlist)
1630     **  int32_t  string table entry number
1631     **  uint8_t type
1632     **   (extern, absolute, defined in section)
1633     **  uint8_t section
1634     **   (0 for global symbols, section number of definition (>= 1, <=
1635     **   254) for local symbols, size of variable for common symbols
1636     **   [type == extern])
1637     **  int16_t description
1638     **   (for stab debugging format)
1639     **  pointer value (i.e. file offset) of symbol or stab offset
1640     **
1641     ** string table data
1642     **  list of null-terminated strings
1643     */
1644 
1645     /* Emit the Mach-O header.  */
1646     macho_write_header();
1647 
1648     offset = fmt.header_size + head_sizeofcmds;
1649 
1650     /* emit the segment load command */
1651     if (seg_nsects > 0)
1652 	offset = macho_write_segment (offset);
1653     else
1654         nasm_warn(WARN_OTHER, "no sections?");
1655 
1656     if (nsyms > 0) {
1657         /* write out symbol command */
1658         fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1659         fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1660         fwriteint32_t(offset, ofile);    /* symbol table offset */
1661         fwriteint32_t(nsyms, ofile);     /* number of symbol
1662                                          ** table entries */
1663         offset += nsyms * fmt.nlist_size;
1664         fwriteint32_t(offset, ofile);    /* string table offset */
1665         fwriteint32_t(strslen, ofile);   /* string table size */
1666     }
1667 
1668     /* emit section data */
1669     if (seg_nsects > 0)
1670 	macho_write_section ();
1671 
1672     /* emit symbol table if we have symbols */
1673     if (nsyms > 0)
1674 	macho_write_symtab ();
1675 
1676     /* we don't need to pad here, we are already aligned */
1677 
1678     /* emit string table */
1679     saa_fpwrite(strs, ofile);
1680 }
1681 /* We do quite a bit here, starting with finalizing all of the data
1682    for the object file, writing, and then freeing all of the data from
1683    the file.  */
1684 
macho_cleanup(void)1685 static void macho_cleanup(void)
1686 {
1687     struct section *s;
1688     struct reloc *r;
1689     struct symbol *sym;
1690 
1691     dfmt->cleanup();
1692 
1693     /* Sort all symbols.  */
1694     macho_layout_symbols (&nsyms, &strslen);
1695 
1696     /* Fixup relocation entries */
1697     for (s = sects; s != NULL; s = s->next) {
1698 	macho_fixup_relocs (s->relocs);
1699     }
1700 
1701     /* First calculate and finalize needed values.  */
1702     macho_calculate_sizes();
1703     macho_write();
1704 
1705     /* free up everything */
1706     while (sects->next) {
1707         s = sects;
1708         sects = sects->next;
1709 
1710         saa_free(s->data);
1711         while (s->relocs != NULL) {
1712             r = s->relocs;
1713             s->relocs = s->relocs->next;
1714             nasm_free(r);
1715         }
1716 
1717         nasm_free(s);
1718     }
1719 
1720     saa_free(strs);
1721 
1722     raa_free(extsyms);
1723 
1724     while (syms) {
1725        sym = syms;
1726        syms = syms->next;
1727        nasm_free (sym);
1728     }
1729 
1730     nasm_free(extdefsyms);
1731     nasm_free(undefsyms);
1732     nasm_free(sectstab);
1733     raa_free(section_by_index);
1734     hash_free(&section_by_name);
1735 }
1736 
macho_set_section_attribute_by_symbol(const char * label,uint32_t flags)1737 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1738 {
1739     struct section *s;
1740     int32_t nasm_seg;
1741     int64_t offset;
1742 
1743     if (lookup_label(label, &nasm_seg, &offset) == LBL_none) {
1744 	nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1745 	return false;
1746     }
1747 
1748     s = get_section_by_index(nasm_seg);
1749     if (!s) {
1750 	nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1751 	return false;
1752     }
1753 
1754     s->flags |= flags;
1755     return true;
1756 }
1757 
1758 /*
1759  * Mark a symbol for no dead stripping
1760  */
macho_no_dead_strip(const char * labels)1761 static enum directive_result macho_no_dead_strip(const char *labels)
1762 {
1763     char *s, *p, *ep;
1764     char ec;
1765     enum directive_result rv = DIRR_ERROR;
1766 
1767     p = s = nasm_strdup(labels);
1768     while (*p) {
1769 	ep = nasm_skip_identifier(p);
1770 	if (!ep) {
1771 	    nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1772 	    goto err;
1773 	}
1774 	ec = *ep;
1775 	if (ec && ec != ',' && !nasm_isspace(ec)) {
1776 	    nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1777 	    goto err;
1778 	}
1779 	*ep = '\0';
1780 	if (!pass_first()) {
1781 	    if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1782 		rv = DIRR_ERROR;
1783 	}
1784 	*ep = ec;
1785 	p = nasm_skip_spaces(ep);
1786 	if (*p == ',')
1787 	    p = nasm_skip_spaces(++p);
1788     }
1789 
1790     rv = DIRR_OK;
1791 
1792 err:
1793     nasm_free(s);
1794     return rv;
1795 }
1796 
1797 /*
1798  * Mach-O pragmas
1799  */
1800 static enum directive_result
macho_pragma(const struct pragma * pragma)1801 macho_pragma(const struct pragma *pragma)
1802 {
1803     switch (pragma->opcode) {
1804     case D_SUBSECTIONS_VIA_SYMBOLS:
1805 	if (*pragma->tail)
1806 	    return DIRR_BADPARAM;
1807 
1808 	if (!pass_first())
1809 	    head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1810 
1811         /* Jmp-match optimization conflicts */
1812         optimizing.flag |= OPTIM_DISABLE_JMP_MATCH;
1813 
1814 	return DIRR_OK;
1815 
1816     case D_NO_DEAD_STRIP:
1817 	return macho_no_dead_strip(pragma->tail);
1818 
1819     default:
1820 	return DIRR_UNKNOWN;	/* Not a Mach-O directive */
1821     }
1822 }
1823 
1824 static const struct pragma_facility macho_pragma_list[] = {
1825     { "macho", macho_pragma },
1826     { NULL, macho_pragma }	/* Implements macho32/macho64 namespaces */
1827 };
1828 
macho_dbg_generate(void)1829 static void macho_dbg_generate(void)
1830 {
1831     uint8_t *p_buf = NULL, *p_buf_base = NULL;
1832     size_t saa_len = 0, high_addr = 0, total_len = 0;
1833     struct section *p_section = NULL;
1834     /* calculated at debug_str and referenced at debug_info */
1835     uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1836 
1837     /* debug section defines */
1838     {
1839         int bits = 0;
1840         macho_section(".debug_abbrev", &bits);
1841         macho_section(".debug_info", &bits);
1842         macho_section(".debug_line", &bits);
1843         macho_section(".debug_str", &bits);
1844     }
1845 
1846     /* dw section walk to find high_addr and total_len */
1847     {
1848         struct dw_sect_list *p_sect;
1849 
1850         list_for_each(p_sect, dw_head_sect) {
1851             uint64_t offset = get_section_by_index(p_sect->section)->size;
1852             struct SAA *p_linep = p_sect->psaa;
1853 
1854             saa_write8(p_linep, 2); /* std op 2 */
1855             saa_write8(p_linep, offset - p_sect->offset);
1856             saa_write8(p_linep, DW_LNS_extended_op);
1857             saa_write8(p_linep, 1); /* operand length */
1858             saa_write8(p_linep, DW_LNE_end_sequence);
1859 
1860             total_len += p_linep->datalen;
1861             high_addr += offset;
1862         }
1863     }
1864 
1865     /* debug line */
1866     {
1867         struct dw_sect_list *p_sect;
1868         size_t linep_off, buf_size;
1869         struct SAA *p_lines = saa_init(1L);
1870         struct dir_list *p_dir;
1871         struct file_list *p_file;
1872 
1873         p_section = get_section_by_name("__DWARF", "__debug_line");
1874         nasm_assert(p_section != NULL);
1875 
1876         saa_write8(p_lines, 1); /* minimum instruction length */
1877         saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1878         saa_write8(p_lines, DW_LN_BASE); /* line base */
1879         saa_write8(p_lines, DW_LN_RANGE); /* line range */
1880         saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1881         saa_write8(p_lines, 0); /* std opcode 1 length */
1882         saa_write8(p_lines, 1); /* std opcode 2 length */
1883         saa_write8(p_lines, 1); /* std opcode 3 length */
1884         saa_write8(p_lines, 1); /* std opcode 4 length */
1885         saa_write8(p_lines, 1); /* std opcode 5 length */
1886         saa_write8(p_lines, 0); /* std opcode 6 length */
1887         saa_write8(p_lines, 0); /* std opcode 7 length */
1888         saa_write8(p_lines, 0); /* std opcode 8 length */
1889         saa_write8(p_lines, 1); /* std opcode 9 length */
1890         saa_write8(p_lines, 0); /* std opcode 10 length */
1891         saa_write8(p_lines, 0); /* std opcode 11 length */
1892         saa_write8(p_lines, 1); /* std opcode 12 length */
1893         list_for_each(p_dir, dw_head_dir) {
1894             saa_wcstring(p_lines, p_dir->dir_name);
1895         }
1896         saa_write8(p_lines, 0); /* end of table */
1897 
1898         list_for_each(p_file, dw_head_file) {
1899             saa_wcstring(p_lines, p_file->file_name);
1900             saa_write8(p_lines, p_file->dir->dir); /* directory id */
1901             saa_write8(p_lines, 0); /* time */
1902             saa_write8(p_lines, 0); /* size */
1903         }
1904         saa_write8(p_lines, 0); /* end of table */
1905 
1906         linep_off = p_lines->datalen;
1907         /* 10 bytes for initial & prolong length, and dwarf version info */
1908         buf_size = saa_len = linep_off + total_len + 10;
1909         p_buf_base = p_buf = nasm_malloc(buf_size);
1910 
1911         WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1912         WRITESHORT(p_buf, 2); /* dwarf version */
1913         WRITELONG(p_buf, linep_off); /* prolong length */
1914 
1915         saa_rnbytes(p_lines, p_buf, linep_off);
1916         p_buf += linep_off;
1917         saa_free(p_lines);
1918 
1919         list_for_each(p_sect, dw_head_sect) {
1920             struct SAA *p_linep = p_sect->psaa;
1921 
1922             saa_len = p_linep->datalen;
1923             saa_rnbytes(p_linep, p_buf, saa_len);
1924             p_buf += saa_len;
1925 
1926             saa_free(p_linep);
1927         }
1928 
1929         macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1930 
1931         nasm_free(p_buf_base);
1932     }
1933 
1934     /* string section */
1935     {
1936         struct SAA *p_str = saa_init(1L);
1937         char *cur_path = nasm_realpath(module_name);
1938         char *cur_file = nasm_basename(cur_path);
1939         char *cur_dir = nasm_dirname(cur_path);
1940 
1941         p_section = get_section_by_name("__DWARF", "__debug_str");
1942         nasm_assert(p_section != NULL);
1943 
1944         producer_str_offset = 0;
1945         module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature());
1946         dir_str_offset += saa_wcstring(p_str, cur_file);
1947         saa_wcstring(p_str, cur_dir);
1948 
1949         saa_len = p_str->datalen;
1950         p_buf = nasm_malloc(saa_len);
1951         saa_rnbytes(p_str, p_buf, saa_len);
1952         macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1953 
1954         nasm_free(cur_path);
1955         nasm_free(cur_file);
1956         nasm_free(cur_dir);
1957         saa_free(p_str);
1958         nasm_free(p_buf);
1959     }
1960 
1961     /* debug info */
1962     {
1963         struct SAA *p_info = saa_init(1L);
1964 
1965         p_section = get_section_by_name("__DWARF", "__debug_info");
1966         nasm_assert(p_section != NULL);
1967 
1968         /* size will be overwritten once determined, so skip in p_info layout */
1969         saa_write16(p_info, 2); /* dwarf version */
1970         saa_write32(p_info, 0); /* offset info abbrev */
1971         saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4);   /* pointer size  */
1972 
1973         saa_write8(p_info, 1);   /* abbrev entry number  */
1974 
1975         saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer  */
1976         saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language  */
1977         saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name  */
1978         saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1979         saa_write32(p_info, 0); /* DW_AT_stmt_list  */
1980 
1981         if (ofmt == &of_macho64) {
1982             saa_write64(p_info, 0); /* DW_AT_low_pc */
1983             saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1984         } else  {
1985             saa_write32(p_info, 0); /* DW_AT_low_pc */
1986             saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1987         }
1988 
1989         saa_write8(p_info, 2);   /* abbrev entry number */
1990 
1991         if (ofmt == &of_macho64) {
1992             saa_write64(p_info, 0); /* DW_AT_low_pc */
1993             saa_write64(p_info, 0); /* DW_AT_frame_base */
1994         } else  {
1995             saa_write32(p_info, 0); /* DW_AT_low_pc */
1996             saa_write32(p_info, 0); /* DW_AT_frame_base */
1997         }
1998         saa_write8(p_info, DW_END_default);
1999 
2000         saa_len = p_info->datalen;
2001         p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
2002 
2003         WRITELONG(p_buf, saa_len);
2004         saa_rnbytes(p_info, p_buf, saa_len);
2005         macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
2006 
2007         saa_free(p_info);
2008         nasm_free(p_buf_base);
2009     }
2010 
2011     /* abbrev section */
2012     {
2013         struct SAA *p_abbrev = saa_init(1L);
2014 
2015         p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2016         nasm_assert(p_section != NULL);
2017 
2018         saa_write8(p_abbrev, 1); /* entry number */
2019 
2020         saa_write8(p_abbrev, DW_TAG_compile_unit);
2021         saa_write8(p_abbrev, DW_CHILDREN_yes);
2022 
2023         saa_write8(p_abbrev, DW_AT_producer);
2024         saa_write8(p_abbrev, DW_FORM_strp);
2025 
2026         saa_write8(p_abbrev, DW_AT_language);
2027         saa_write8(p_abbrev, DW_FORM_data2);
2028 
2029         saa_write8(p_abbrev, DW_AT_name);
2030         saa_write8(p_abbrev, DW_FORM_strp);
2031 
2032         saa_write8(p_abbrev, DW_AT_comp_dir);
2033         saa_write8(p_abbrev, DW_FORM_strp);
2034 
2035         saa_write8(p_abbrev, DW_AT_stmt_list);
2036         saa_write8(p_abbrev, DW_FORM_data4);
2037 
2038         saa_write8(p_abbrev, DW_AT_low_pc);
2039         saa_write8(p_abbrev, DW_FORM_addr);
2040 
2041         saa_write8(p_abbrev, DW_AT_high_pc);
2042         saa_write8(p_abbrev, DW_FORM_addr);
2043 
2044         saa_write16(p_abbrev, DW_END_default);
2045 
2046         saa_write8(p_abbrev, 2); /* entry number */
2047 
2048         saa_write8(p_abbrev, DW_TAG_subprogram);
2049         saa_write8(p_abbrev, DW_CHILDREN_no);
2050 
2051         saa_write8(p_abbrev, DW_AT_low_pc);
2052         saa_write8(p_abbrev, DW_FORM_addr);
2053 
2054         saa_write8(p_abbrev, DW_AT_frame_base);
2055         saa_write8(p_abbrev, DW_FORM_addr);
2056 
2057         saa_write16(p_abbrev, DW_END_default);
2058 
2059 	saa_write8(p_abbrev, 0); /* Terminal zero entry */
2060 
2061         saa_len = p_abbrev->datalen;
2062 
2063         p_buf = nasm_malloc(saa_len);
2064 
2065         saa_rnbytes(p_abbrev, p_buf, saa_len);
2066         macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2067 
2068         saa_free(p_abbrev);
2069         nasm_free(p_buf);
2070     }
2071 }
2072 
new_file_list(const char * file_name,const char * dir_name)2073 static void new_file_list (const char *file_name, const char *dir_name)
2074 {
2075     struct dir_list *dir_list;
2076     bool need_new_dir_list = true;
2077 
2078     nasm_new(dw_cur_file);
2079     dw_cur_file->file = ++dw_num_files;
2080     dw_cur_file->file_name = file_name;
2081     if(!dw_head_file) {
2082         dw_head_file = dw_cur_file;
2083     } else {
2084         *dw_last_file_next = dw_cur_file;
2085     }
2086     dw_last_file_next = &(dw_cur_file->next);
2087 
2088     if(dw_head_dir) {
2089         list_for_each(dir_list, dw_head_dir) {
2090             if(!(strcmp(dir_name, dir_list->dir_name))) {
2091                 dw_cur_file->dir = dir_list;
2092                 need_new_dir_list = false;
2093                 break;
2094             }
2095         }
2096     }
2097 
2098     if(need_new_dir_list)
2099     {
2100         nasm_new(dir_list);
2101         dir_list->dir = dw_num_dirs++;
2102         dir_list->dir_name = dir_name;
2103         if(!dw_head_dir) {
2104             dw_head_dir = dir_list;
2105         } else {
2106             *dw_last_dir_next = dir_list;
2107         }
2108         dw_last_dir_next = &(dir_list->next);
2109         dw_cur_file->dir = dir_list;
2110     }
2111 }
2112 
macho_dbg_init(void)2113 static void macho_dbg_init(void)
2114 {
2115 }
2116 
macho_dbg_linenum(const char * file_name,int32_t line_num,int32_t segto)2117 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2118 {
2119     bool need_new_list = true;
2120     const char *cur_file = nasm_basename(file_name);
2121     const char *cur_dir  = nasm_dirname(file_name);
2122     (void)segto;
2123 
2124     if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2125         strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2126         if(dw_head_file) {
2127             struct file_list *match;
2128 
2129             list_for_each(match, dw_head_file) {
2130                 if(!(strcmp(cur_file, match->file_name)) &&
2131                     !(strcmp(cur_dir, match->dir->dir_name))) {
2132                     dw_cur_file = match;
2133                     dw_cur_file->dir = match->dir;
2134                     need_new_list = false;
2135                     break;
2136                 }
2137             }
2138         }
2139 
2140         if(need_new_list) {
2141             new_file_list(cur_file, cur_dir);
2142         }
2143     }
2144 
2145     dbg_immcall = true;
2146     cur_line = line_num;
2147 }
2148 
macho_dbg_output(int type,void * param)2149 static void macho_dbg_output(int type, void *param)
2150 {
2151     struct section_info *sinfo_param = (struct section_info *)param;
2152     int32_t secto = sinfo_param->secto;
2153     bool need_new_sect = false;
2154     struct SAA *p_linep = NULL;
2155     (void)type;
2156 
2157     if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2158         need_new_sect = true;
2159         if(dw_head_sect) {
2160             struct dw_sect_list *match = dw_head_sect;
2161             uint32_t idx = 0;
2162 
2163             for(; idx < dw_num_sects; idx++) {
2164                 if(match->section == secto) {
2165                     dw_cur_sect = match;
2166                     need_new_sect = false;
2167                     break;
2168                 }
2169                 match = match->next;
2170             }
2171         }
2172     }
2173 
2174     if(need_new_sect) {
2175         nasm_new(dw_cur_sect);
2176         dw_num_sects ++;
2177         p_linep = dw_cur_sect->psaa = saa_init(1L);
2178         dw_cur_sect->line = dw_cur_sect->file = 1;
2179         dw_cur_sect->offset = 0;
2180         dw_cur_sect->next = NULL;
2181         dw_cur_sect->section = secto;
2182 
2183         saa_write8(p_linep, DW_LNS_extended_op);
2184         saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2185         saa_write8(p_linep, DW_LNE_set_address);
2186         if (ofmt == &of_macho64) {
2187             saa_write64(p_linep, 0);
2188         } else {
2189             saa_write32(p_linep, 0);
2190         }
2191 
2192         if(!dw_head_sect) {
2193             dw_head_sect = dw_last_sect = dw_cur_sect;
2194         } else {
2195             dw_last_sect->next = dw_cur_sect;
2196             dw_last_sect = dw_cur_sect;
2197         }
2198     }
2199 
2200     if(dbg_immcall == true) {
2201         int32_t line_delta = cur_line - dw_cur_sect->line;
2202         int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2203         uint32_t cur_file = dw_cur_file->file;
2204         p_linep = dw_cur_sect->psaa;
2205 
2206         if(cur_file != dw_cur_sect->file) {
2207             saa_write8(p_linep, DW_LNS_set_file);
2208             saa_write8(p_linep, cur_file);
2209             dw_cur_sect->file = cur_file;
2210         }
2211 
2212         if(line_delta) {
2213             int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2214                                              DW_OPCODE_BASE;
2215 
2216             if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2217                 (special_opcode < DW_MAX_SP_OPCODE)) {
2218                 saa_write8(p_linep, special_opcode);
2219             } else {
2220                 saa_write8(p_linep, DW_LNS_advance_line);
2221                 saa_wleb128s(p_linep, line_delta);
2222                 if(offset_delta) {
2223                     saa_write8(p_linep, DW_LNS_advance_pc);
2224                     saa_wleb128u(p_linep, offset_delta);
2225                 }
2226                 saa_write8(p_linep, DW_LNS_copy);
2227             }
2228 
2229             dw_cur_sect->line = cur_line;
2230             dw_cur_sect->offset = sinfo_param->size;
2231         }
2232 
2233         dbg_immcall = false;
2234     }
2235 }
2236 
macho_dbg_cleanup(void)2237 static void macho_dbg_cleanup(void)
2238 {
2239     /* dwarf sectors generation */
2240     macho_dbg_generate();
2241 
2242     {
2243         struct dw_sect_list *p_sect = dw_head_sect;
2244         struct file_list *p_file = dw_head_file;
2245         uint32_t idx = 0;
2246 
2247         for(; idx < dw_num_sects; idx++) {
2248             struct dw_sect_list *next = p_sect->next;
2249             nasm_free(p_sect);
2250             p_sect = next;
2251         }
2252 
2253         for(idx = 0; idx < dw_num_files; idx++) {
2254             struct file_list *next = p_file->next;
2255             nasm_free(p_file);
2256             p_file = next;
2257         }
2258     }
2259 }
2260 
2261 #ifdef OF_MACHO32
2262 static const struct macho_fmt macho32_fmt = {
2263     4,
2264     MH_MAGIC,
2265     CPU_TYPE_I386,
2266     LC_SEGMENT,
2267     MACHO_HEADER_SIZE,
2268     MACHO_SEGCMD_SIZE,
2269     MACHO_SECTCMD_SIZE,
2270     MACHO_NLIST_SIZE,
2271     RL_MAX_32,
2272     GENERIC_RELOC_VANILLA,
2273     GENERIC_RELOC_VANILLA,
2274     GENERIC_RELOC_TLV,
2275     false			/* Allow segment-relative relocations */
2276 };
2277 
macho32_init(void)2278 static void macho32_init(void)
2279 {
2280     fmt = macho32_fmt;
2281     macho_init();
2282 
2283     macho_gotpcrel_sect = NO_SEG;
2284 }
2285 
2286 static const struct dfmt macho32_df_dwarf = {
2287     "Mach-O i386 dwarf for Darwin/MacOS",
2288     "dwarf",
2289     macho_dbg_init,
2290     macho_dbg_linenum,
2291     null_debug_deflabel,
2292     null_debug_directive,
2293     null_debug_typevalue,
2294     macho_dbg_output,
2295     macho_dbg_cleanup,
2296     NULL /*pragma list*/
2297 };
2298 
2299 static const struct dfmt * const macho32_df_arr[2] =
2300  { &macho32_df_dwarf, NULL };
2301 
2302 const struct ofmt of_macho32 = {
2303     "Mach-O i386 (Mach, including MacOS X and variants)",
2304     "macho32",
2305     ".o",
2306     0,
2307     32,
2308     macho32_df_arr,
2309     &macho32_df_dwarf,
2310     macho_stdmac,
2311     macho32_init,
2312     null_reset,
2313     nasm_do_legacy_output,
2314     macho_output,
2315     macho_symdef,
2316     macho_section,
2317     macho_herelabel,
2318     macho_sectalign,
2319     null_segbase,
2320     null_directive,
2321     macho_cleanup,
2322     macho_pragma_list
2323 };
2324 #endif
2325 
2326 #ifdef OF_MACHO64
2327 static const struct macho_fmt macho64_fmt = {
2328     8,
2329     MH_MAGIC_64,
2330     CPU_TYPE_X86_64,
2331     LC_SEGMENT_64,
2332     MACHO_HEADER64_SIZE,
2333     MACHO_SEGCMD64_SIZE,
2334     MACHO_SECTCMD64_SIZE,
2335     MACHO_NLIST64_SIZE,
2336     RL_MAX_64,
2337     X86_64_RELOC_UNSIGNED,
2338     X86_64_RELOC_SIGNED,
2339     X86_64_RELOC_TLV,
2340     true			/* Force symbol-relative relocations */
2341 };
2342 
macho64_init(void)2343 static void macho64_init(void)
2344 {
2345     fmt = macho64_fmt;
2346     macho_init();
2347 
2348     /* add special symbol for ..gotpcrel */
2349     macho_gotpcrel_sect = seg_alloc() + 1;
2350     backend_label("..gotpcrel", macho_gotpcrel_sect, 0L);
2351 }
2352 
2353 static const struct dfmt macho64_df_dwarf = {
2354     "Mach-O x86-64 dwarf for Darwin/MacOS",
2355     "dwarf",
2356     macho_dbg_init,
2357     macho_dbg_linenum,
2358     null_debug_deflabel,
2359     null_debug_directive,
2360     null_debug_typevalue,
2361     macho_dbg_output,
2362     macho_dbg_cleanup,
2363     NULL /*pragma list*/
2364 };
2365 
2366 static const struct dfmt * const macho64_df_arr[2] =
2367  { &macho64_df_dwarf, NULL };
2368 
2369 const struct ofmt of_macho64 = {
2370     "Mach-O x86-64 (Mach, including MacOS X and variants)",
2371     "macho64",
2372     ".o",
2373     0,
2374     64,
2375     macho64_df_arr,
2376     &macho64_df_dwarf,
2377     macho_stdmac,
2378     macho64_init,
2379     null_reset,
2380     nasm_do_legacy_output,
2381     macho_output,
2382     macho_symdef,
2383     macho_section,
2384     macho_herelabel,
2385     macho_sectalign,
2386     null_segbase,
2387     null_directive,
2388     macho_cleanup,
2389     macho_pragma_list,
2390 };
2391 #endif
2392 
2393 #endif
2394 
2395 /*
2396  * Local Variables:
2397  * mode:c
2398  * c-basic-offset:4
2399  * End:
2400  *
2401  * end of file */
2402