insns.pl: use less cantankerous string expansion; better error info
[nasm.git] / output / outmacho.c
blob6d9059be7bfc5155a3327ed4d099e9237a8c5d59
1 /* ----------------------------------------------------------------------- *
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.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
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.
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.
32 * ----------------------------------------------------------------------- */
35 * outmacho.c output routines for the Netwide Assembler to produce
36 * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
39 #include "compiler.h"
41 #include "nctype.h"
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"
58 #if defined(OF_MACHO) || defined(OF_MACHO64)
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
68 #define MACHO_HEADER64_SIZE 32
69 #define MACHO_SEGCMD64_SIZE 72
70 #define MACHO_SECTCMD64_SIZE 80
71 #define MACHO_NLIST64_SIZE 16
73 /* Mach-O relocations numbers */
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)
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 */
88 #define RL_MAX_32 RL_TLV
89 #define RL_MAX_64 RL_GOTLOAD
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 */
107 static struct macho_fmt fmt;
109 static void fwriteptr(uint64_t data, FILE * fp)
111 fwriteaddr(data, fmt.ptrsize, fp);
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 */
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 */
139 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
141 /* fake section for absolute symbols, *not* part of the section linked list */
142 static struct section absolute_sect;
144 struct reloc {
145 /* nasm internal data */
146 struct reloc *next;
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 */
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 */
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 */
175 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
177 static struct section *sects, **sectstail, **sectstab;
178 static struct symbol *syms, **symstail;
179 static uint32_t nsyms;
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.
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)
191 The order of the string table is:
192 strings for external symbols
193 strings for local symbols
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;
204 static struct RAA *extsyms;
205 static struct SAA *strs;
206 static uint32_t strslen;
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;
219 * Functions for handling fixed-length zero-padded string
220 * fields, that may or may not be null-terminated.
223 /* Copy a string into a zero-padded fixed-length field */
224 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
226 /* Compare a fixed-length field with a string */
227 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
229 #define alignint32_t(x) \
230 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
232 #define alignint64_t(x) \
233 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
235 #define alignptr(x) \
236 ALIGN(x, fmt.ptrsize) /* align x to output format width */
238 static struct hash_table section_by_name;
239 static struct RAA *section_by_index;
241 static struct section * never_null
242 find_or_add_section(const char *segname, const char *sectname)
244 struct hash_insert hi;
245 void **sp;
246 struct section *s;
247 char sect[34];
249 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
251 sp = hash_find(&section_by_name, sect, &hi);
252 if (sp)
253 return (struct section *)(*sp);
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);
261 s->index = s->subsection = seg_alloc();
262 section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
264 return s;
267 static inline bool is_new_section(const struct section *s)
269 return !s->data;
272 static struct section *get_section_by_name(const char *segname,
273 const char *sectname)
275 char sect[34];
276 void **sp;
278 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
280 sp = hash_find(&section_by_name, sect, NULL);
281 return sp ? (struct section *)(*sp) : NULL;
284 static struct section *get_section_by_index(int32_t index)
286 if (index < 0 || index >= SEG_ABS || (index & 1))
287 return NULL;
289 return raa_read_ptr(section_by_index, index >> 1);
292 struct dir_list {
293 struct dir_list *next;
294 struct dir_list *last;
295 const char *dir_name;
296 uint32_t dir;
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;
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;
317 struct section_info {
318 uint64_t size;
319 int32_t secto;
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
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;
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.
340 static int32_t macho_tlvp_sect;
341 static int32_t macho_gotpcrel_sect;
343 static void macho_init(void)
345 module_name = inname;
346 sects = NULL;
347 sectstail = &sects;
349 /* Fake section for absolute symbols */
350 absolute_sect.index = NO_SEG;
352 syms = NULL;
353 symstail = &syms;
354 nsyms = 0;
355 nlocalsym = 0;
356 nextdefsym = 0;
357 nundefsym = 0;
359 extsyms = raa_init();
360 strs = saa_init(1L);
362 section_by_index = raa_init();
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;
368 /* add special symbol for TLVP */
369 macho_tlvp_sect = seg_alloc() + 1;
370 backend_label("..tlvp", macho_tlvp_sect, 0L);
373 static void sect_write(struct section *sect,
374 const uint8_t *data, uint32_t len)
376 saa_wbytes(sect->data, data, len);
377 sect->size += len;
381 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
383 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
384 bool global, bool exact)
386 struct rbtree *srb;
388 srb = rb_search(s->syms[global], offset);
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;
398 return container_of(srb - global, struct symbol, symv);
401 static int64_t add_reloc(struct section *sect, int32_t section,
402 int64_t offset,
403 enum reltype reltype, int bytes)
405 struct reloc *r;
406 struct section *s;
407 int32_t fi;
408 int64_t adjust;
410 /* Double check this is a valid relocation type for this platform */
411 nasm_assert(reltype <= fmt.maxreltype);
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;
422 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
423 r->length = ilog2_32(bytes);
425 /* set default relocation values */
426 r->type = fmt.reloc_abs;
427 r->pcrel = 0;
428 r->snum = R_ABS;
430 s = get_section_by_index(section);
431 fi = s ? s->fileindex : NO_SECT;
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;
447 break;
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;
469 break;
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;
478 case RL_GOT:
479 r->type = X86_64_RELOC_GOT;
480 goto needsym;
482 case RL_GOTLOAD:
483 r->type = X86_64_RELOC_GOT_LOAD;
484 goto needsym;
486 case RL_TLV:
487 r->type = fmt.reloc_tlv;
488 goto needsym;
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;
508 adjust -= sym->symv[0].key;
509 r->snum = sym->initial_snum;
511 break;
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
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;
528 if (r->pcrel)
529 adjust += ((r->ext && fmt.ptrsize == 8) ? bytes : -(int64_t)sect->size);
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;
540 return adjust;
542 bail:
543 nasm_free(r);
544 return 0;
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)
551 struct section *s;
552 int64_t addr, offset;
553 uint8_t mydata[16], *p;
554 bool is_bss;
555 enum reltype reltype;
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");
563 /* should never happen */
564 if (!s)
565 nasm_panic("text section not found");
568 /* debug code generation only for sections tagged with
569 * instruction attribute */
570 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
572 struct section_info sinfo;
573 sinfo.size = s->size;
574 sinfo.secto = secto;
575 dfmt->debug_output(0, &sinfo);
578 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
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;
590 memset(mydata, 0, sizeof(mydata));
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);
598 sect_write(s, NULL, size);
599 } else
600 s->size += size;
602 break;
604 case OUT_RAWDATA:
605 sect_write(s, data, size);
606 break;
608 case OUT_ADDRESS:
610 int asize = abs((int)size);
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);
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");
634 p = mydata;
635 WRITEADDR(p, addr, asize);
636 sect_write(s, mydata, asize);
637 break;
640 case OUT_REL1ADR:
641 case OUT_REL2ADR:
643 p = mydata;
644 offset = *(int64_t *)data;
645 addr = offset - size;
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);
662 WRITESHORT(p, addr);
663 sect_write(s, mydata, type == OUT_REL1ADR ? 1 : 2);
664 break;
666 case OUT_REL4ADR:
667 case OUT_REL8ADR:
669 p = mydata;
670 offset = *(int64_t *)data;
671 addr = offset - size;
672 reltype = RL_REL;
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];
682 opcode[0] = opcode[1] = 0;
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);
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;
697 } else if (wrt == macho_gotpcrel_sect) {
698 reltype = RL_GOT;
700 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
701 s->data->datalen >= 3) {
702 uint8_t gotload[3];
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;
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 */
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;
727 default:
728 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
729 break;
733 #define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
734 #define NO_TYPE S_NASM_TYPE_MASK
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 },
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 }
770 static const struct macho_known_section *
771 lookup_known_section(const char *name, bool by_sectname)
773 size_t i;
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];
785 return NULL;
788 static int32_t macho_section(char *name, int *bits)
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;
799 bool new_seg;
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");
811 section = segment = NULL;
812 flags = 0;
814 comma = strchr(name, ',');
815 if (comma) {
816 int len;
818 *comma = '\0';
819 segment = name;
820 section = comma+1;
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);
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);
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;
848 segment = known_section->segname;
849 section = known_section->sectname;
850 flags = known_section->flags;
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);
857 /* initialize it if it is a brand new section */
858 if (new_seg) {
859 *sectstail = s;
860 sectstail = &s->next;
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;
869 s->size = 0;
870 s->nreloc = 0;
871 s->flags = flags;
874 if (comma)
875 *comma = ','; /* Restore comma */
877 s->by_name = s->by_name || comma; /* Was specified by name */
879 flags = NO_TYPE;
881 while (sectionAttributes &&
882 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
883 if (!*currentAttribute)
884 continue;
886 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
887 char *end;
888 int newAlignment, value;
890 value = strtoul(currentAttribute + 6, (char**)&end, 0);
891 newAlignment = alignlog2_32(value);
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);
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);
916 flags |= sa->flags & ~S_NASM_TYPE_MASK;
917 break;
921 if (!sa->name) {
922 nasm_error(ERR_NONFATAL,
923 "unknown section attribute %s for section %s",
924 currentAttribute, name);
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;
937 } else {
938 s->flags |= flags & ~S_NASM_TYPE_MASK;
941 return s->subsection;
944 static int32_t macho_herelabel(const char *name, enum label_type type,
945 int32_t section, int32_t *subsection,
946 bool *copyoffset)
948 struct section *s;
949 int32_t subsec;
950 (void)name;
952 if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
953 return section;
955 /* No subsection only for local labels */
956 if (type == LBL_LOCAL)
957 return section;
959 s = get_section_by_index(section);
960 if (!s)
961 return section;
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);
970 s->subsection = subsec;
971 *copyoffset = true; /* Maintain previous offset */
972 return subsec;
975 static void macho_symdef(char *name, int32_t section, int64_t offset,
976 int is_global, char *special)
978 struct symbol *sym;
979 struct section *s;
980 bool special_used = false;
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
989 if (is_global == 3) {
990 if (special) {
991 int n = strcspn(special, " \t");
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;
1004 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1005 "(yet) support forward reference fixups.");
1006 return;
1009 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
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.
1015 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1016 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1017 return;
1020 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1021 sym->next = NULL;
1022 symstail = &sym->next;
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;
1032 /* external and common symbols get N_EXT */
1033 if (is_global != 0) {
1034 sym->type |= N_EXT;
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");
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);
1046 special_used = true;
1049 /* track the initially allocated symbol number for use in future fix-ups */
1050 sym->initial_snum = nsyms;
1052 if (section == NO_SEG) {
1053 /* symbols in no section get absolute */
1054 sym->type |= N_ABS;
1055 sym->sect = NO_SECT;
1057 s = &absolute_sect;
1058 } else {
1059 s = get_section_by_index(section);
1061 sym->type |= N_SECT;
1063 /* get the in-file index of the section the symbol was defined in */
1064 sym->sect = s ? s->fileindex : NO_SECT;
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);
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;
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;
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]);
1098 ++nsyms;
1100 if (special && !special_used)
1101 nasm_error(ERR_NONFATAL, "no special symbol features supported here");
1104 static void macho_sectalign(int32_t seg, unsigned int value)
1106 struct section *s;
1107 int align;
1109 nasm_assert(!(seg & 1));
1111 s = get_section_by_index(seg);
1113 if (!s || !is_power2(value))
1114 return;
1116 align = alignlog2_32(value);
1117 if (s->align < align)
1118 s->align = align;
1121 extern macros_t macho_stdmac[];
1123 /* Comparison function for qsort symbol layout. */
1124 static int layout_compare (const struct symbol **s1,
1125 const struct symbol **s2)
1127 return (strcmp ((*s1)->name, (*s2)->name));
1130 /* The native assembler does a few things in a similar function
1132 * Remove temporary labels
1133 * Sort symbols according to local, external, undefined (by name)
1134 * Order the string table
1136 We do not remove temporary labels right now.
1138 numsyms is the total number of symbols we have. strtabsize is the
1139 number entries in the string table. */
1141 static void macho_layout_symbols (uint32_t *numsyms,
1142 uint32_t *strtabsize)
1144 struct symbol *sym, **symp;
1145 uint32_t i,j;
1147 *numsyms = 0;
1148 *strtabsize = sizeof (char);
1150 symp = &syms;
1152 while ((sym = *symp)) {
1153 /* Undefined symbols are now external. */
1154 if (sym->type == N_UNDF)
1155 sym->type |= N_EXT;
1157 if ((sym->type & N_EXT) == 0) {
1158 sym->snum = *numsyms;
1159 *numsyms = *numsyms + 1;
1160 nlocalsym++;
1162 else {
1163 if ((sym->type & N_TYPE) != N_UNDF) {
1164 nextdefsym++;
1165 } else {
1166 nundefsym++;
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;
1176 symp = &(sym->next);
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;
1186 /* allocate arrays for sorting externals by name */
1187 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1188 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1190 i = 0;
1191 j = 0;
1193 symp = &syms;
1195 while ((sym = *symp)) {
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;
1202 else {
1203 if ((sym->type & N_TYPE) != N_UNDF) {
1204 extdefsyms[i++] = sym;
1205 } else {
1206 undefsyms[j++] = sym;
1209 symp = &(sym->next);
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);
1217 for(i = 0; i < nextdefsym; i++) {
1218 extdefsyms[i]->snum = *numsyms;
1219 *numsyms += 1;
1221 for(j = 0; j < nundefsym; j++) {
1222 undefsyms[j]->snum = *numsyms;
1223 *numsyms += 1;
1227 /* Calculate some values we'll need for writing later. */
1229 static void macho_calculate_sizes (void)
1231 struct section *s;
1232 int fi;
1234 /* count sections and calculate in-memory and in-file offsets */
1235 for (s = sects; s != NULL; s = s->next) {
1236 uint64_t newaddr;
1238 /* recalculate segment address based on alignment and vm size */
1239 s->addr = seg_vmsize;
1241 /* we need section alignment to calculate final section address */
1242 if (s->align == -1)
1243 s->align = DEFAULT_SECTION_ALIGNMENT;
1245 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1246 s->addr = newaddr;
1248 seg_vmsize = newaddr + s->size;
1250 /* zerofill sections aren't actually written to the file */
1251 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
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.
1257 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1258 s->offset = seg_filesize + s->pad;
1259 seg_filesize += s->size + s->pad;
1261 /* filesize and vmsize needs to be aligned */
1262 seg_vmsize += s->pad;
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;
1273 if (nsyms > 0) {
1274 ++head_ncmds;
1275 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1278 if (seg_nsects > MAX_SECT) {
1279 nasm_fatal("MachO output is limited to %d sections\n",
1280 MAX_SECT);
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;
1290 /* Write out the header information for the file. */
1292 static void macho_write_header (void)
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 */
1304 /* Write out the segment load command at offset. */
1306 static uint32_t macho_write_segment (uint64_t offset)
1308 uint64_t rel_base = alignptr(offset + seg_filesize);
1309 uint32_t s_reloff = 0;
1310 struct section *s;
1312 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1314 /* size of load command including section load commands */
1315 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1316 ofile);
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 */
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")) {
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.
1347 xstrncpy(s->segname, "__TEXT");
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);
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);
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);
1377 fwriteint32_t(s->flags, ofile); /* flags */
1378 fwriteint32_t(0, ofile); /* reserved */
1379 fwriteptr(0, ofile); /* reserved */
1382 rel_padcnt = rel_base - offset;
1383 offset = rel_base + s_reloff;
1385 return offset;
1388 /* For a given chain of relocs r, write out the entire relocation
1389 chain to the object file. */
1391 static void macho_write_relocs (struct reloc *r)
1393 while (r) {
1394 uint32_t word2;
1396 fwriteint32_t(r->addr, ofile); /* reloc offset */
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;
1408 /* Write out the section data. */
1409 static void macho_write_section (void)
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;
1421 for (s = sects; s != NULL; s = s->next) {
1422 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1423 continue;
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);
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
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;
1465 /* write new offset back */
1466 p = blk.buf;
1467 WRITEDLONG(p, l);
1468 saa_fwrite(s->data, r->addr, blk.buf, len);
1471 /* dump the section data to file */
1472 fwritezero(s->pad, ofile);
1473 saa_fpwrite(s->data, ofile);
1476 /* pad last section up to reloc entries on pointer boundary */
1477 fwritezero(rel_padcnt, ofile);
1479 /* emit relocation entries */
1480 for (s = sects; s != NULL; s = s->next)
1481 macho_write_relocs (s->relocs);
1484 /* Write out the symbol table. We should already have sorted this
1485 before now. */
1486 static void macho_write_symtab (void)
1488 struct symbol *sym;
1489 uint64_t i;
1491 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
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 */
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;
1507 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
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 */
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;
1525 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
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 */
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;
1542 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1547 /* Fixup the snum in the relocation entries, we should be
1548 doing this only for externally referenced symbols. */
1549 static void macho_fixup_relocs (struct reloc *r)
1551 struct symbol *sym;
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;
1562 r = r->next;
1566 /* Write out the object file. */
1568 static void macho_write (void)
1570 uint64_t offset = 0;
1572 /* mach-o object file structure:
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
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
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
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
1621 ** raw section data
1623 ** padding to pointer boundary
1625 ** relocation data (struct reloc)
1626 ** int32_t offset
1627 ** uint data (symbolnum, pcrel, length, extern, type)
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
1641 ** string table data
1642 ** list of null-terminated strings
1645 /* Emit the Mach-O header. */
1646 macho_write_header();
1648 offset = fmt.header_size + head_sizeofcmds;
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?");
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 */
1668 /* emit section data */
1669 if (seg_nsects > 0)
1670 macho_write_section ();
1672 /* emit symbol table if we have symbols */
1673 if (nsyms > 0)
1674 macho_write_symtab ();
1676 /* we don't need to pad here, we are already aligned */
1678 /* emit string table */
1679 saa_fpwrite(strs, ofile);
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. */
1685 static void macho_cleanup(void)
1687 struct section *s;
1688 struct reloc *r;
1689 struct symbol *sym;
1691 dfmt->cleanup();
1693 /* Sort all symbols. */
1694 macho_layout_symbols (&nsyms, &strslen);
1696 /* Fixup relocation entries */
1697 for (s = sects; s != NULL; s = s->next) {
1698 macho_fixup_relocs (s->relocs);
1701 /* First calculate and finalize needed values. */
1702 macho_calculate_sizes();
1703 macho_write();
1705 /* free up everything */
1706 while (sects->next) {
1707 s = sects;
1708 sects = sects->next;
1710 saa_free(s->data);
1711 while (s->relocs != NULL) {
1712 r = s->relocs;
1713 s->relocs = s->relocs->next;
1714 nasm_free(r);
1717 nasm_free(s);
1720 saa_free(strs);
1722 raa_free(extsyms);
1724 while (syms) {
1725 sym = syms;
1726 syms = syms->next;
1727 nasm_free (sym);
1730 nasm_free(extdefsyms);
1731 nasm_free(undefsyms);
1732 nasm_free(sectstab);
1733 raa_free(section_by_index);
1734 hash_free(&section_by_name);
1737 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1739 struct section *s;
1740 int32_t nasm_seg;
1741 int64_t offset;
1743 if (!lookup_label(label, &nasm_seg, &offset)) {
1744 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1745 return false;
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;
1754 s->flags |= flags;
1755 return true;
1759 * Mark a symbol for no dead stripping
1761 static enum directive_result macho_no_dead_strip(const char *labels)
1763 char *s, *p, *ep;
1764 char ec;
1765 enum directive_result rv = DIRR_ERROR;
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;
1774 ec = *ep;
1775 if (ec && ec != ',' && !nasm_isspace(ec)) {
1776 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1777 goto err;
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;
1784 *ep = ec;
1785 p = nasm_skip_spaces(ep);
1786 if (*p == ',')
1787 p = nasm_skip_spaces(++p);
1790 rv = DIRR_OK;
1792 err:
1793 nasm_free(s);
1794 return rv;
1798 * Mach-O pragmas
1800 static enum directive_result
1801 macho_pragma(const struct pragma *pragma)
1803 switch (pragma->opcode) {
1804 case D_SUBSECTIONS_VIA_SYMBOLS:
1805 if (*pragma->tail)
1806 return DIRR_BADPARAM;
1808 if (!pass_first())
1809 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1811 /* Jmp-match optimization conflicts */
1812 optimizing.flag |= OPTIM_DISABLE_JMP_MATCH;
1814 return DIRR_OK;
1816 case D_NO_DEAD_STRIP:
1817 return macho_no_dead_strip(pragma->tail);
1819 default:
1820 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1824 static const struct pragma_facility macho_pragma_list[] = {
1825 { "macho", macho_pragma },
1826 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1829 static void macho_dbg_generate(void)
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;
1837 /* debug section defines */
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);
1846 /* dw section walk to find high_addr and total_len */
1848 struct dw_sect_list *p_sect;
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;
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);
1860 total_len += p_linep->datalen;
1861 high_addr += offset;
1865 /* debug line */
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;
1873 p_section = get_section_by_name("__DWARF", "__debug_line");
1874 nasm_assert(p_section != NULL);
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);
1896 saa_write8(p_lines, 0); /* end of table */
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 */
1904 saa_write8(p_lines, 0); /* end of table */
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);
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 */
1915 saa_rnbytes(p_lines, p_buf, linep_off);
1916 p_buf += linep_off;
1917 saa_free(p_lines);
1919 list_for_each(p_sect, dw_head_sect) {
1920 struct SAA *p_linep = p_sect->psaa;
1922 saa_len = p_linep->datalen;
1923 saa_rnbytes(p_linep, p_buf, saa_len);
1924 p_buf += saa_len;
1926 saa_free(p_linep);
1929 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1931 nasm_free(p_buf_base);
1934 /* string section */
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);
1941 p_section = get_section_by_name("__DWARF", "__debug_str");
1942 nasm_assert(p_section != NULL);
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);
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);
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);
1961 /* debug info */
1963 struct SAA *p_info = saa_init(1L);
1965 p_section = get_section_by_name("__DWARF", "__debug_info");
1966 nasm_assert(p_section != NULL);
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 */
1973 saa_write8(p_info, 1); /* abbrev entry number */
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 */
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 */
1989 saa_write8(p_info, 2); /* abbrev entry number */
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 */
1998 saa_write8(p_info, DW_END_default);
2000 saa_len = p_info->datalen;
2001 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
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);
2007 saa_free(p_info);
2008 nasm_free(p_buf_base);
2011 /* abbrev section */
2013 struct SAA *p_abbrev = saa_init(1L);
2015 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2016 nasm_assert(p_section != NULL);
2018 saa_write8(p_abbrev, 1); /* entry number */
2020 saa_write8(p_abbrev, DW_TAG_compile_unit);
2021 saa_write8(p_abbrev, DW_CHILDREN_yes);
2023 saa_write8(p_abbrev, DW_AT_producer);
2024 saa_write8(p_abbrev, DW_FORM_strp);
2026 saa_write8(p_abbrev, DW_AT_language);
2027 saa_write8(p_abbrev, DW_FORM_data2);
2029 saa_write8(p_abbrev, DW_AT_name);
2030 saa_write8(p_abbrev, DW_FORM_strp);
2032 saa_write8(p_abbrev, DW_AT_comp_dir);
2033 saa_write8(p_abbrev, DW_FORM_strp);
2035 saa_write8(p_abbrev, DW_AT_stmt_list);
2036 saa_write8(p_abbrev, DW_FORM_data4);
2038 saa_write8(p_abbrev, DW_AT_low_pc);
2039 saa_write8(p_abbrev, DW_FORM_addr);
2041 saa_write8(p_abbrev, DW_AT_high_pc);
2042 saa_write8(p_abbrev, DW_FORM_addr);
2044 saa_write16(p_abbrev, DW_END_default);
2046 saa_write8(p_abbrev, 2); /* entry number */
2048 saa_write8(p_abbrev, DW_TAG_subprogram);
2049 saa_write8(p_abbrev, DW_CHILDREN_no);
2051 saa_write8(p_abbrev, DW_AT_low_pc);
2052 saa_write8(p_abbrev, DW_FORM_addr);
2054 saa_write8(p_abbrev, DW_AT_frame_base);
2055 saa_write8(p_abbrev, DW_FORM_addr);
2057 saa_write16(p_abbrev, DW_END_default);
2059 saa_write8(p_abbrev, 0); /* Terminal zero entry */
2061 saa_len = p_abbrev->datalen;
2063 p_buf = nasm_malloc(saa_len);
2065 saa_rnbytes(p_abbrev, p_buf, saa_len);
2066 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2068 saa_free(p_abbrev);
2069 nasm_free(p_buf);
2073 static void new_file_list (const char *file_name, const char *dir_name)
2075 struct dir_list *dir_list;
2076 bool need_new_dir_list = true;
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;
2086 dw_last_file_next = &(dw_cur_file->next);
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;
2098 if(need_new_dir_list)
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;
2108 dw_last_dir_next = &(dir_list->next);
2109 dw_cur_file->dir = dir_list;
2113 static void macho_dbg_init(void)
2117 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
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;
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;
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;
2140 if(need_new_list) {
2141 new_file_list(cur_file, cur_dir);
2145 dbg_immcall = true;
2146 cur_line = line_num;
2149 static void macho_dbg_output(int type, void *param)
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;
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;
2163 for(; idx < dw_num_sects; idx++) {
2164 if(match->section == secto) {
2165 dw_cur_sect = match;
2166 need_new_sect = false;
2167 break;
2169 match = match->next;
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;
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);
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;
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;
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;
2212 if(line_delta) {
2213 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2214 DW_OPCODE_BASE;
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);
2226 saa_write8(p_linep, DW_LNS_copy);
2229 dw_cur_sect->line = cur_line;
2230 dw_cur_sect->offset = sinfo_param->size;
2233 dbg_immcall = false;
2237 static void macho_dbg_cleanup(void)
2239 /* dwarf sectors generation */
2240 macho_dbg_generate();
2243 struct dw_sect_list *p_sect = dw_head_sect;
2244 struct file_list *p_file = dw_head_file;
2245 uint32_t idx = 0;
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;
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;
2261 #ifdef OF_MACHO32
2262 static const struct macho_fmt macho32_fmt = {
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 */
2278 static void macho32_init(void)
2280 fmt = macho32_fmt;
2281 macho_init();
2283 macho_gotpcrel_sect = NO_SEG;
2286 static const struct dfmt macho32_df_dwarf = {
2287 "MachO32 (i386) dwarf debug format 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*/
2299 static const struct dfmt * const macho32_df_arr[2] =
2300 { &macho32_df_dwarf, NULL };
2302 const struct ofmt of_macho32 = {
2303 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2304 "macho32",
2305 ".o",
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
2324 #endif
2326 #ifdef OF_MACHO64
2327 static const struct macho_fmt macho64_fmt = {
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 */
2343 static void macho64_init(void)
2345 fmt = macho64_fmt;
2346 macho_init();
2348 /* add special symbol for ..gotpcrel */
2349 macho_gotpcrel_sect = seg_alloc() + 1;
2350 backend_label("..gotpcrel", macho_gotpcrel_sect, 0L);
2353 static const struct dfmt macho64_df_dwarf = {
2354 "MachO64 (x86-64) dwarf debug format 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*/
2366 static const struct dfmt * const macho64_df_arr[2] =
2367 { &macho64_df_dwarf, NULL };
2369 const struct ofmt of_macho64 = {
2370 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2371 "macho64",
2372 ".o",
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,
2391 #endif
2393 #endif
2396 * Local Variables:
2397 * mode:c
2398 * c-basic-offset:4
2399 * End:
2401 * end of file */