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