nasm: new option -MW to emit Watcom-style Makefile rules
[nasm/externdefs2.git] / output / outmacho.c
blobaf0e61e7e0778f9ccb1e65d236b9137b1ddec09d
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2017 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 <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
46 #include "nasm.h"
47 #include "nasmlib.h"
48 #include "labels.h"
49 #include "error.h"
50 #include "saa.h"
51 #include "raa.h"
52 #include "rbtree.h"
53 #include "outform.h"
54 #include "outlib.h"
55 #include "ver.h"
56 #include "dwarf.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 file header values */
74 #define MH_MAGIC 0xfeedface
75 #define MH_MAGIC_64 0xfeedfacf
76 #define CPU_TYPE_I386 7 /* x86 platform */
77 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
78 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
79 #define MH_OBJECT 0x1 /* object file */
81 /* Mach-O header flags */
82 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
84 /* Mach-O load commands */
85 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
86 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
87 #define LC_SYMTAB 0x2 /* symbol table load command */
89 /* Mach-O relocations numbers */
91 /* Generic relocs, used by i386 Mach-O */
92 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
93 #define GENERIC_RELOC_TLV 5 /* Thread local */
95 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
96 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
97 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
98 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
99 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
100 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
101 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
102 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
103 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
104 #define X86_64_RELOC_TLV 9 /* Thread local */
106 /* Mach-O VM permission constants */
107 #define VM_PROT_NONE (0x00)
108 #define VM_PROT_READ (0x01)
109 #define VM_PROT_WRITE (0x02)
110 #define VM_PROT_EXECUTE (0x04)
112 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
113 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
115 /* Our internal relocation types */
116 enum reltype {
117 RL_ABS, /* Absolute relocation */
118 RL_REL, /* Relative relocation */
119 RL_TLV, /* Thread local */
120 RL_BRANCH, /* Relative direct branch */
121 RL_SUB, /* X86_64_RELOC_SUBTRACT */
122 RL_GOT, /* X86_64_RELOC_GOT */
123 RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
125 #define RL_MAX_32 RL_TLV
126 #define RL_MAX_64 RL_GOTLOAD
128 struct macho_fmt {
129 uint32_t ptrsize; /* Pointer size in bytes */
130 uint32_t mh_magic; /* Which magic number to use */
131 uint32_t cpu_type; /* Which CPU type */
132 uint32_t lc_segment; /* Which segment load command */
133 uint32_t header_size; /* Header size */
134 uint32_t segcmd_size; /* Segment command size */
135 uint32_t sectcmd_size; /* Section command size */
136 uint32_t nlist_size; /* Nlist (symbol) size */
137 enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
138 uint32_t reloc_abs; /* Absolute relocation type */
139 uint32_t reloc_rel; /* Relative relocation type */
140 uint32_t reloc_tlv; /* Thread local relocation type */
141 bool forcesym; /* Always use "external" (symbol-relative) relocations */
144 static struct macho_fmt fmt;
146 static void fwriteptr(uint64_t data, FILE * fp)
148 fwriteaddr(data, fmt.ptrsize, fp);
151 struct section {
152 /* nasm internal data */
153 struct section *next;
154 struct SAA *data;
155 int32_t index;
156 int32_t fileindex;
157 struct reloc *relocs;
158 struct rbtree *syms[2]; /* All/global symbols symbols in section */
159 int align;
160 bool by_name; /* This section was specified by full MachO name */
162 /* data that goes into the file */
163 char sectname[16]; /* what this section is called */
164 char segname[16]; /* segment this section will be in */
165 uint64_t addr; /* in-memory address (subject to alignment) */
166 uint64_t size; /* in-memory and -file size */
167 uint64_t offset; /* in-file offset */
168 uint32_t pad; /* padding bytes before section */
169 uint32_t nreloc; /* relocation entry count */
170 uint32_t flags; /* type and attributes (masked) */
171 uint32_t extreloc; /* external relocations */
174 #define SECTION_TYPE 0x000000ff /* section type mask */
176 #define S_REGULAR (0x0) /* standard section */
177 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
179 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
180 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
181 machine instructions */
182 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
183 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
184 #define S_ATTR_DEBUG 0x02000000
185 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
186 #define S_ATTR_LIVE_SUPPORT 0x08000000
187 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
188 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
189 #define S_ATTR_NO_TOC 0x40000000
190 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
191 #define S_ATTR_DEBUG 0x02000000 /* debug section */
193 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
195 /* fake section for absolute symbols, *not* part of the section linked list */
196 static struct section absolute_sect;
198 struct reloc {
199 /* nasm internal data */
200 struct reloc *next;
202 /* data that goes into the file */
203 int32_t addr; /* op's offset in section */
204 uint32_t snum:24, /* contains symbol index if
205 ** ext otherwise in-file
206 ** section number */
207 pcrel:1, /* relative relocation */
208 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
209 ext:1, /* external symbol referenced */
210 type:4; /* reloc type */
213 #define R_ABS 0 /* absolute relocation */
214 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
215 ** highest bit == 1 */
217 struct symbol {
218 /* nasm internal data */
219 struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
220 symbol offset. */
221 struct symbol *next; /* next symbol in the list */
222 char *name; /* name of this symbol */
223 int32_t initial_snum; /* symbol number used above in reloc */
224 int32_t snum; /* true snum for reloc */
226 /* data that goes into the file */
227 uint32_t strx; /* string table index */
228 uint8_t type; /* symbol type */
229 uint8_t sect; /* NO_SECT or section number */
230 uint16_t desc; /* for stab debugging, 0 for us */
233 /* symbol type bits */
234 #define N_EXT 0x01 /* global or external symbol */
236 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
237 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
238 #define N_SECT 0xe /* defined symbol, n_sect holds
239 ** section number */
241 #define N_TYPE 0x0e /* type bit mask */
243 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
245 /* special section number values */
246 #define NO_SECT 0 /* no section, invalid */
247 #define MAX_SECT 255 /* maximum number of sections */
249 static struct section *sects, **sectstail, **sectstab;
250 static struct symbol *syms, **symstail;
251 static uint32_t nsyms;
253 /* These variables are set by macho_layout_symbols() to organize
254 the symbol table and string table in order the dynamic linker
255 expects. They are then used in macho_write() to put out the
256 symbols and strings in that order.
258 The order of the symbol table is:
259 local symbols
260 defined external symbols (sorted by name)
261 undefined external symbols (sorted by name)
263 The order of the string table is:
264 strings for external symbols
265 strings for local symbols
267 static uint32_t ilocalsym = 0;
268 static uint32_t iextdefsym = 0;
269 static uint32_t iundefsym = 0;
270 static uint32_t nlocalsym;
271 static uint32_t nextdefsym;
272 static uint32_t nundefsym;
273 static struct symbol **extdefsyms = NULL;
274 static struct symbol **undefsyms = NULL;
276 static struct RAA *extsyms;
277 static struct SAA *strs;
278 static uint32_t strslen;
280 /* Global file information. This should be cleaned up into either
281 a structure or as function arguments. */
282 static uint32_t head_ncmds = 0;
283 static uint32_t head_sizeofcmds = 0;
284 static uint32_t head_flags = 0;
285 static uint64_t seg_filesize = 0;
286 static uint64_t seg_vmsize = 0;
287 static uint32_t seg_nsects = 0;
288 static uint64_t rel_padcnt = 0;
290 #define xstrncpy(xdst, xsrc) \
291 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
292 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
293 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
295 #define alignint32_t(x) \
296 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
298 #define alignint64_t(x) \
299 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
301 #define alignptr(x) \
302 ALIGN(x, fmt.ptrsize) /* align x to output format width */
304 static struct section *get_section_by_name(const char *segname,
305 const char *sectname)
307 struct section *s;
309 for (s = sects; s != NULL; s = s->next)
310 if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
311 break;
313 return s;
316 static struct section *get_section_by_index(const int32_t index)
318 struct section *s;
320 for (s = sects; s != NULL; s = s->next)
321 if (index == s->index)
322 break;
324 return s;
327 struct dir_list {
328 struct dir_list *next;
329 struct dir_list *last;
330 const char *dir_name;
331 uint32_t dir;
334 struct file_list {
335 struct file_list *next;
336 struct file_list *last;
337 const char *file_name;
338 uint32_t file;
339 struct dir_list *dir;
342 struct dw_sect_list {
343 struct SAA *psaa;
344 int32_t section;
345 uint32_t line;
346 uint64_t offset;
347 uint32_t file;
348 struct dw_sect_list *next;
349 struct dw_sect_list *last;
352 struct section_info {
353 uint64_t size;
354 int32_t secto;
357 #define DW_LN_BASE (-5)
358 #define DW_LN_RANGE 14
359 #define DW_OPCODE_BASE 13
360 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
361 #define DW_MAX_SP_OPCODE 256
363 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
364 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
365 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
366 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
367 static bool dbg_immcall = false;
368 static const char *module_name = NULL;
371 * Special section numbers which are used to define Mach-O special
372 * symbols, which can be used with WRT to provide PIC relocation
373 * types.
375 static int32_t macho_tlvp_sect;
376 static int32_t macho_gotpcrel_sect;
378 static void macho_init(void)
380 sects = NULL;
381 sectstail = &sects;
383 /* Fake section for absolute symbols */
384 absolute_sect.index = NO_SEG;
386 syms = NULL;
387 symstail = &syms;
388 nsyms = 0;
389 nlocalsym = 0;
390 nextdefsym = 0;
391 nundefsym = 0;
393 extsyms = raa_init();
394 strs = saa_init(1L);
396 /* string table starts with a zero byte so index 0 is an empty string */
397 saa_wbytes(strs, zero_buffer, 1);
398 strslen = 1;
400 /* add special symbol for TLVP */
401 macho_tlvp_sect = seg_alloc() + 1;
402 define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
406 static void sect_write(struct section *sect,
407 const uint8_t *data, uint32_t len)
409 saa_wbytes(sect->data, data, len);
410 sect->size += len;
414 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
416 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
417 bool global, bool exact)
419 struct rbtree *srb;
421 srb = rb_search(s->syms[global], offset);
423 if (!srb || (exact && srb->key != offset)) {
424 nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
425 " for this reference",
426 global ? " global" : "",
427 s == &absolute_sect ? " absolute " : "");
428 return NULL;
431 return container_of(srb - global, struct symbol, symv);
434 static int64_t add_reloc(struct section *sect, int32_t section,
435 int64_t offset,
436 enum reltype reltype, int bytes)
438 struct reloc *r;
439 struct section *s;
440 int32_t fi;
441 int64_t adjust;
443 /* Double check this is a valid relocation type for this platform */
444 nasm_assert(reltype <= fmt.maxreltype);
446 /* the current end of the section will be the symbol's address for
447 ** now, might have to be fixed by macho_fixup_relocs() later on. make
448 ** sure we don't make the symbol scattered by setting the highest
449 ** bit by accident */
450 r = nasm_malloc(sizeof(struct reloc));
451 r->addr = sect->size & ~R_SCATTERED;
452 r->ext = 1;
453 adjust = bytes;
455 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
456 r->length = ilog2_32(bytes);
458 /* set default relocation values */
459 r->type = fmt.reloc_abs;
460 r->pcrel = 0;
461 r->snum = R_ABS;
463 s = NULL;
464 if (section != NO_SEG)
465 s = get_section_by_index(section);
466 fi = s ? s->fileindex : NO_SECT;
468 /* absolute relocation */
469 switch (reltype) {
470 case RL_ABS:
471 if (section == NO_SEG) {
472 /* absolute (can this even happen?) */
473 r->ext = 0;
474 r->snum = NO_SECT;
475 } else if (fi == NO_SECT) {
476 /* external */
477 r->snum = raa_read(extsyms, section);
478 } else {
479 /* local */
480 r->ext = 0;
481 r->snum = fi;
482 adjust = -sect->size;
484 break;
486 case RL_REL:
487 case RL_BRANCH:
488 r->type = fmt.reloc_rel;
489 r->pcrel = 1;
490 if (section == NO_SEG) {
491 /* absolute - seems to produce garbage no matter what */
492 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
493 "references to absolute addresses");
494 goto bail;
495 #if 0
496 /* This "seems" to be how it ought to work... */
498 struct symbol *sym = macho_find_sym(&absolute_sect, offset,
499 false, false);
500 if (!sym)
501 goto bail;
503 sect->extreloc = 1;
504 r->snum = NO_SECT;
505 adjust = -sect->size;
506 #endif
507 } else if (fi == NO_SECT) {
508 /* external */
509 sect->extreloc = 1;
510 r->snum = raa_read(extsyms, section);
511 if (reltype == RL_BRANCH)
512 r->type = X86_64_RELOC_BRANCH;
513 else if (r->type == GENERIC_RELOC_VANILLA)
514 adjust = -sect->size;
515 } else {
516 /* local */
517 r->ext = 0;
518 r->snum = fi;
519 adjust = -sect->size;
521 break;
523 case RL_SUB:
524 r->pcrel = 0;
525 r->type = X86_64_RELOC_SUBTRACTOR;
526 break;
528 case RL_GOT:
529 r->type = X86_64_RELOC_GOT;
530 goto needsym;
532 case RL_GOTLOAD:
533 r->type = X86_64_RELOC_GOT_LOAD;
534 goto needsym;
536 case RL_TLV:
537 r->type = fmt.reloc_tlv;
538 goto needsym;
540 needsym:
541 r->pcrel = 1;
542 if (section == NO_SEG) {
543 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
544 } else if (fi == NO_SECT) {
545 /* external */
546 r->snum = raa_read(extsyms, section);
547 } else {
548 /* internal - does it really need to be global? */
549 struct symbol *sym = macho_find_sym(s, offset, true,
550 reltype != RL_TLV);
551 if (!sym)
552 goto bail;
554 r->snum = sym->initial_snum;
556 break;
559 /* For 64-bit Mach-O, force a symbol reference if at all possible */
560 if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
561 struct symbol *sym = macho_find_sym(s, offset, false, false);
562 if (sym) {
563 adjust = bytes - sym->symv[0].key;
564 r->snum = sym->initial_snum;
565 r->ext = 1;
569 /* NeXT as puts relocs in reversed order (address-wise) into the
570 ** files, so we do the same, doesn't seem to make much of a
571 ** difference either way */
572 r->next = sect->relocs;
573 sect->relocs = r;
574 if (r->ext)
575 sect->extreloc = 1;
576 ++sect->nreloc;
578 return adjust;
580 bail:
581 nasm_free(r);
582 return 0;
585 static void macho_output(int32_t secto, const void *data,
586 enum out_type type, uint64_t size,
587 int32_t section, int32_t wrt)
589 struct section *s;
590 int64_t addr, offset;
591 uint8_t mydata[16], *p;
592 bool is_bss;
593 enum reltype reltype;
595 if (secto == NO_SEG) {
596 if (type != OUT_RESERVE)
597 nasm_error(ERR_NONFATAL, "attempt to assemble code in "
598 "[ABSOLUTE] space");
599 return;
602 s = get_section_by_index(secto);
604 if (s == NULL) {
605 nasm_error(ERR_WARNING, "attempt to assemble code in"
606 " section %d: defaulting to `.text'", secto);
607 s = get_section_by_name("__TEXT", "__text");
609 /* should never happen */
610 if (s == NULL)
611 nasm_panic(0, "text section not found");
614 /* debug code generation only for sections tagged with
615 * instruction attribute */
616 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
618 struct section_info sinfo;
619 sinfo.size = s->size;
620 sinfo.secto = secto;
621 dfmt->debug_output(0, &sinfo);
624 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
626 if (is_bss && type != OUT_RESERVE) {
627 nasm_error(ERR_WARNING, "attempt to initialize memory in "
628 "BSS section: ignored");
629 s->size += realsize(type, size);
630 return;
633 memset(mydata, 0, sizeof(mydata));
635 switch (type) {
636 case OUT_RESERVE:
637 if (!is_bss) {
638 nasm_error(ERR_WARNING, "uninitialized space declared in"
639 " %s,%s section: zeroing", s->segname, s->sectname);
641 sect_write(s, NULL, size);
642 } else
643 s->size += size;
645 break;
647 case OUT_RAWDATA:
648 if (section != NO_SEG)
649 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
651 sect_write(s, data, size);
652 break;
654 case OUT_ADDRESS:
656 int asize = abs((int)size);
658 addr = *(int64_t *)data;
659 if (section != NO_SEG) {
660 if (section % 2) {
661 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
662 " section base references");
663 } else if (wrt == NO_SEG) {
664 if (fmt.ptrsize == 8 && asize != 8) {
665 nasm_error(ERR_NONFATAL,
666 "Mach-O 64-bit format does not support"
667 " 32-bit absolute addresses");
668 } else {
669 add_reloc(s, section, addr, RL_ABS, asize);
671 } else {
672 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
673 " this use of WRT");
677 p = mydata;
678 WRITEADDR(p, addr, asize);
679 sect_write(s, mydata, asize);
680 break;
683 case OUT_REL2ADR:
684 nasm_assert(section != secto);
686 p = mydata;
687 offset = *(int64_t *)data;
688 addr = offset - size;
690 if (section != NO_SEG && section % 2) {
691 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
692 " section base references");
693 } else if (fmt.ptrsize == 8) {
694 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
695 " Macho-O relocation [2]");
696 } else if (wrt != NO_SEG) {
697 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
698 " this use of WRT");
699 wrt = NO_SEG; /* we can at least _try_ to continue */
700 } else {
701 addr += add_reloc(s, section, addr+size, RL_REL, 2);
704 WRITESHORT(p, addr);
705 sect_write(s, mydata, 2);
706 break;
708 case OUT_REL4ADR:
709 nasm_assert(section != secto);
711 p = mydata;
712 offset = *(int64_t *)data;
713 addr = offset - size;
714 reltype = RL_REL;
716 if (section != NO_SEG && section % 2) {
717 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
718 " section base references");
719 } else if (wrt == NO_SEG) {
720 if (fmt.ptrsize == 8 &&
721 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
722 uint8_t opcode[2];
724 opcode[0] = opcode[1] = 0;
726 /* HACK: Retrieve instruction opcode */
727 if (likely(s->data->datalen >= 2)) {
728 saa_fread(s->data, s->data->datalen-2, opcode, 2);
729 } else if (s->data->datalen == 1) {
730 saa_fread(s->data, 0, opcode+1, 1);
733 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
734 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
735 /* Direct call, jmp, or jcc */
736 reltype = RL_BRANCH;
739 } else if (wrt == macho_gotpcrel_sect) {
740 reltype = RL_GOT;
742 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
743 s->data->datalen >= 3) {
744 uint8_t gotload[3];
746 /* HACK: Retrieve instruction opcode */
747 saa_fread(s->data, s->data->datalen-3, gotload, 3);
748 if ((gotload[0] & 0xf8) == 0x48 &&
749 gotload[1] == 0x8b &&
750 (gotload[2] & 0307) == 0005) {
751 /* movq <reg>,[rel sym wrt ..gotpcrel] */
752 reltype = RL_GOTLOAD;
755 } else if (wrt == macho_tlvp_sect) {
756 reltype = RL_TLV;
757 } else {
758 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
759 " this use of WRT");
760 /* continue with RL_REL */
763 addr += add_reloc(s, section, offset, reltype, 4);
764 WRITELONG(p, addr);
765 sect_write(s, mydata, 4);
766 break;
768 default:
769 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
770 break;
774 /* Translation table from traditional Unix section names to Mach-O */
775 static const struct sectmap {
776 const char *nasmsect;
777 const char *segname;
778 const char *sectname;
779 const uint32_t flags;
780 } sectmap[] = {
781 {".text", "__TEXT", "__text",
782 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
783 {".data", "__DATA", "__data", S_REGULAR},
784 {".rodata", "__DATA", "__const", S_REGULAR},
785 {".bss", "__DATA", "__bss", S_ZEROFILL},
786 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
787 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
788 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
789 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
790 {NULL, NULL, NULL, 0}
793 #define NO_TYPE S_NASM_TYPE_MASK
795 /* Section type or attribute directives */
796 static const struct sect_attribs {
797 const char *name;
798 uint32_t flags;
799 } sect_attribs[] = {
800 { "data", S_REGULAR },
801 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
802 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
803 { "bss", S_ZEROFILL },
804 { "zerofill", S_ZEROFILL },
805 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
806 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
807 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
808 { NULL, 0 }
811 static int32_t macho_section(char *name, int pass, int *bits)
813 char *sectionAttributes;
814 const struct sectmap *sm;
815 struct section *s;
816 const char *section, *segment;
817 uint32_t flags;
818 const struct sect_attribs *sa;
819 char *currentAttribute;
820 char *comma;
822 bool new_seg;
824 (void)pass;
826 /* Default to the appropriate number of bits. */
827 if (!name) {
828 *bits = fmt.ptrsize << 3;
829 name = ".text";
830 sectionAttributes = NULL;
831 } else {
832 sectionAttributes = name;
833 name = nasm_strsep(&sectionAttributes, " \t");
836 section = segment = NULL;
837 flags = 0;
839 comma = strchr(name, ',');
840 if (comma) {
841 int len;
843 *comma = '\0';
844 segment = name;
845 section = comma+1;
847 len = strlen(segment);
848 if (len == 0) {
849 nasm_error(ERR_NONFATAL, "empty segment name\n");
850 } else if (len >= 16) {
851 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
854 len = strlen(section);
855 if (len == 0) {
856 nasm_error(ERR_NONFATAL, "empty section name\n");
857 } else if (len >= 16) {
858 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
861 if (!strcmp(section, "__text")) {
862 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
863 S_ATTR_PURE_INSTRUCTIONS;
864 } else if (!strcmp(section, "__bss")) {
865 flags = S_ZEROFILL;
866 } else {
867 flags = S_REGULAR;
869 } else {
870 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
871 /* make lookup into section name translation table */
872 if (!strcmp(name, sm->nasmsect)) {
873 segment = sm->segname;
874 section = sm->sectname;
875 flags = sm->flags;
876 goto found;
879 nasm_error(ERR_NONFATAL, "unknown section name\n");
880 return NO_SEG;
883 found:
884 /* try to find section with that name */
885 s = get_section_by_name(segment, section);
887 /* create it if it doesn't exist yet */
888 if (!s) {
889 new_seg = true;
891 s = *sectstail = nasm_zalloc(sizeof(struct section));
892 sectstail = &s->next;
894 s->data = saa_init(1L);
895 s->index = seg_alloc();
896 s->fileindex = ++seg_nsects;
897 s->align = -1;
898 s->pad = -1;
899 s->offset = -1;
900 s->by_name = false;
902 xstrncpy(s->segname, segment);
903 xstrncpy(s->sectname, section);
904 s->size = 0;
905 s->nreloc = 0;
906 s->flags = flags;
907 } else {
908 new_seg = false;
911 if (comma)
912 *comma = ','; /* Restore comma */
914 s->by_name = s->by_name || comma; /* Was specified by name */
916 flags = NO_TYPE;
918 while (sectionAttributes &&
919 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
920 if (!*currentAttribute)
921 continue;
923 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
924 char *end;
925 int newAlignment, value;
927 value = strtoul(currentAttribute + 6, (char**)&end, 0);
928 newAlignment = alignlog2_32(value);
930 if (0 != *end) {
931 nasm_error(ERR_NONFATAL,
932 "unknown or missing alignment value \"%s\" "
933 "specified for section \"%s\"",
934 currentAttribute + 6,
935 name);
936 } else if (0 > newAlignment) {
937 nasm_error(ERR_NONFATAL,
938 "alignment of %d (for section \"%s\") is not "
939 "a power of two",
940 value,
941 name);
944 if (s->align < newAlignment)
945 s->align = newAlignment;
946 } else {
947 for (sa = sect_attribs; sa->name; sa++) {
948 if (!nasm_stricmp(sa->name, currentAttribute)) {
949 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
950 flags = (flags & ~S_NASM_TYPE_MASK)
951 | (sa->flags & S_NASM_TYPE_MASK);
953 flags |= sa->flags & ~S_NASM_TYPE_MASK;
954 break;
958 if (!sa->name) {
959 nasm_error(ERR_NONFATAL,
960 "unknown section attribute %s for section %s",
961 currentAttribute, name);
966 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
967 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
968 nasm_error(ERR_NONFATAL,
969 "inconsistent section attributes for section %s\n",
970 name);
971 } else {
972 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
974 } else {
975 s->flags |= flags & ~S_NASM_TYPE_MASK;
978 return s->index;
981 static void macho_symdef(char *name, int32_t section, int64_t offset,
982 int is_global, char *special)
984 struct symbol *sym;
985 struct section *s;
987 if (special) {
988 nasm_error(ERR_NONFATAL, "The Mach-O output format does "
989 "not support any special symbol types");
990 return;
993 if (is_global == 3) {
994 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
995 "(yet) support forward reference fixups.");
996 return;
999 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1001 * This is a NASM special symbol. We never allow it into
1002 * the Macho-O symbol table, even if it's a valid one. If it
1003 * _isn't_ a valid one, we should barf immediately.
1005 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1006 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1007 return;
1010 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1011 sym->next = NULL;
1012 symstail = &sym->next;
1014 sym->name = name;
1015 sym->strx = strslen;
1016 sym->type = 0;
1017 sym->desc = 0;
1018 sym->symv[0].key = offset;
1019 sym->symv[1].key = offset;
1020 sym->initial_snum = -1;
1022 /* external and common symbols get N_EXT */
1023 if (is_global != 0) {
1024 sym->type |= N_EXT;
1027 if (section == NO_SEG) {
1028 /* symbols in no section get absolute */
1029 sym->type |= N_ABS;
1030 sym->sect = NO_SECT;
1032 s = &absolute_sect;
1033 } else {
1034 s = get_section_by_index(section);
1036 sym->type |= N_SECT;
1038 /* get the in-file index of the section the symbol was defined in */
1039 sym->sect = s ? s->fileindex : NO_SECT;
1041 /* track the initially allocated symbol number for use in future fix-ups */
1042 sym->initial_snum = nsyms;
1044 if (!s) {
1045 /* remember symbol number of references to external
1046 ** symbols, this works because every external symbol gets
1047 ** its own section number allocated internally by nasm and
1048 ** can so be used as a key */
1049 extsyms = raa_write(extsyms, section, nsyms);
1051 switch (is_global) {
1052 case 1:
1053 case 2:
1054 /* there isn't actually a difference between global
1055 ** and common symbols, both even have their size in
1056 ** sym->symv[0].key */
1057 sym->type = N_EXT;
1058 break;
1060 default:
1061 /* give an error on unfound section if it's not an
1062 ** external or common symbol (assemble_file() does a
1063 ** seg_alloc() on every call for them) */
1064 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1065 break;
1070 if (s) {
1071 s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1072 if (is_global)
1073 s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1076 ++nsyms;
1079 static void macho_sectalign(int32_t seg, unsigned int value)
1081 struct section *s;
1082 int align;
1084 nasm_assert(!(seg & 1));
1086 s = get_section_by_index(seg);
1088 if (!s || !is_power2(value))
1089 return;
1091 align = alignlog2_32(value);
1092 if (s->align < align)
1093 s->align = align;
1096 static int32_t macho_segbase(int32_t section)
1098 return section;
1101 static void macho_filename(char *inname, char *outname)
1103 standard_extension(inname, outname, ".o");
1104 module_name = inname;
1107 extern macros_t macho_stdmac[];
1109 /* Comparison function for qsort symbol layout. */
1110 static int layout_compare (const struct symbol **s1,
1111 const struct symbol **s2)
1113 return (strcmp ((*s1)->name, (*s2)->name));
1116 /* The native assembler does a few things in a similar function
1118 * Remove temporary labels
1119 * Sort symbols according to local, external, undefined (by name)
1120 * Order the string table
1122 We do not remove temporary labels right now.
1124 numsyms is the total number of symbols we have. strtabsize is the
1125 number entries in the string table. */
1127 static void macho_layout_symbols (uint32_t *numsyms,
1128 uint32_t *strtabsize)
1130 struct symbol *sym, **symp;
1131 uint32_t i,j;
1133 *numsyms = 0;
1134 *strtabsize = sizeof (char);
1136 symp = &syms;
1138 while ((sym = *symp)) {
1139 /* Undefined symbols are now external. */
1140 if (sym->type == N_UNDF)
1141 sym->type |= N_EXT;
1143 if ((sym->type & N_EXT) == 0) {
1144 sym->snum = *numsyms;
1145 *numsyms = *numsyms + 1;
1146 nlocalsym++;
1148 else {
1149 if ((sym->type & N_TYPE) != N_UNDF) {
1150 nextdefsym++;
1151 } else {
1152 nundefsym++;
1155 /* If we handle debug info we'll want
1156 to check for it here instead of just
1157 adding the symbol to the string table. */
1158 sym->strx = *strtabsize;
1159 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1160 *strtabsize += strlen(sym->name) + 1;
1162 symp = &(sym->next);
1165 /* Next, sort the symbols. Most of this code is a direct translation from
1166 the Apple cctools symbol layout. We need to keep compatibility with that. */
1167 /* Set the indexes for symbol groups into the symbol table */
1168 ilocalsym = 0;
1169 iextdefsym = nlocalsym;
1170 iundefsym = nlocalsym + nextdefsym;
1172 /* allocate arrays for sorting externals by name */
1173 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1174 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1176 i = 0;
1177 j = 0;
1179 symp = &syms;
1181 while ((sym = *symp)) {
1183 if((sym->type & N_EXT) == 0) {
1184 sym->strx = *strtabsize;
1185 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1186 *strtabsize += strlen(sym->name) + 1;
1188 else {
1189 if ((sym->type & N_TYPE) != N_UNDF) {
1190 extdefsyms[i++] = sym;
1191 } else {
1192 undefsyms[j++] = sym;
1195 symp = &(sym->next);
1198 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1199 (int (*)(const void *, const void *))layout_compare);
1200 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1201 (int (*)(const void *, const void *))layout_compare);
1203 for(i = 0; i < nextdefsym; i++) {
1204 extdefsyms[i]->snum = *numsyms;
1205 *numsyms += 1;
1207 for(j = 0; j < nundefsym; j++) {
1208 undefsyms[j]->snum = *numsyms;
1209 *numsyms += 1;
1213 /* Calculate some values we'll need for writing later. */
1215 static void macho_calculate_sizes (void)
1217 struct section *s;
1218 int fi;
1220 /* count sections and calculate in-memory and in-file offsets */
1221 for (s = sects; s != NULL; s = s->next) {
1222 uint64_t newaddr;
1224 /* recalculate segment address based on alignment and vm size */
1225 s->addr = seg_vmsize;
1227 /* we need section alignment to calculate final section address */
1228 if (s->align == -1)
1229 s->align = DEFAULT_SECTION_ALIGNMENT;
1231 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1232 s->addr = newaddr;
1234 seg_vmsize = newaddr + s->size;
1236 /* zerofill sections aren't actually written to the file */
1237 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1239 * LLVM/Xcode as always aligns the section data to 4
1240 * bytes; there is a comment in the LLVM source code that
1241 * perhaps aligning to pointer size would be better.
1243 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1244 s->offset = seg_filesize + s->pad;
1245 seg_filesize += s->size + s->pad;
1247 /* filesize and vmsize needs to be aligned */
1248 seg_vmsize += s->pad;
1252 /* calculate size of all headers, load commands and sections to
1253 ** get a pointer to the start of all the raw data */
1254 if (seg_nsects > 0) {
1255 ++head_ncmds;
1256 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1259 if (nsyms > 0) {
1260 ++head_ncmds;
1261 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1264 if (seg_nsects > MAX_SECT) {
1265 nasm_fatal(0, "MachO output is limited to %d sections\n",
1266 MAX_SECT);
1269 /* Create a table of sections by file index to avoid linear search */
1270 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1271 sectstab[NO_SECT] = &absolute_sect;
1272 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1273 sectstab[fi] = s;
1276 /* Write out the header information for the file. */
1278 static void macho_write_header (void)
1280 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1281 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1282 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1283 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1284 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1285 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1286 fwriteint32_t(head_flags, ofile); /* flags, if any */
1287 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1290 /* Write out the segment load command at offset. */
1292 static uint32_t macho_write_segment (uint64_t offset)
1294 uint64_t rel_base = alignptr(offset + seg_filesize);
1295 uint32_t s_reloff = 0;
1296 struct section *s;
1298 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1300 /* size of load command including section load commands */
1301 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1302 ofile);
1304 /* in an MH_OBJECT file all sections are in one unnamed (name
1305 ** all zeros) segment */
1306 fwritezero(16, ofile);
1307 fwriteptr(0, ofile); /* in-memory offset */
1308 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1309 fwriteptr(offset, ofile); /* in-file offset to data */
1310 fwriteptr(seg_filesize, ofile); /* in-file size */
1311 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1312 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1313 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1314 fwriteint32_t(0, ofile); /* no flags */
1316 /* emit section headers */
1317 for (s = sects; s != NULL; s = s->next) {
1318 if (s->nreloc) {
1319 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1320 s->flags |= S_ATTR_LOC_RELOC;
1321 if (s->extreloc)
1322 s->flags |= S_ATTR_EXT_RELOC;
1323 } else if (!strcmp(s->segname, "__DATA") &&
1324 !strcmp(s->sectname, "__const") &&
1325 !s->by_name &&
1326 !get_section_by_name("__TEXT", "__const")) {
1328 * The MachO equivalent to .rodata can be either
1329 * __DATA,__const or __TEXT,__const; the latter only if
1330 * there are no relocations. However, when mixed it is
1331 * better to specify the segments explicitly.
1333 xstrncpy(s->segname, "__TEXT");
1336 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1337 nasm_write(s->segname, sizeof(s->segname), ofile);
1338 fwriteptr(s->addr, ofile);
1339 fwriteptr(s->size, ofile);
1341 /* dummy data for zerofill sections or proper values */
1342 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1343 nasm_assert(s->pad != (uint32_t)-1);
1344 offset += s->pad;
1345 fwriteint32_t(offset, ofile);
1346 offset += s->size;
1347 /* Write out section alignment, as a power of two.
1348 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1349 fwriteint32_t(s->align, ofile);
1350 /* To be compatible with cctools as we emit
1351 a zero reloff if we have no relocations. */
1352 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1353 fwriteint32_t(s->nreloc, ofile);
1355 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1356 } else {
1357 fwriteint32_t(0, ofile);
1358 fwriteint32_t(s->align, ofile);
1359 fwriteint32_t(0, ofile);
1360 fwriteint32_t(0, ofile);
1363 fwriteint32_t(s->flags, ofile); /* flags */
1364 fwriteint32_t(0, ofile); /* reserved */
1365 fwriteptr(0, ofile); /* reserved */
1368 rel_padcnt = rel_base - offset;
1369 offset = rel_base + s_reloff;
1371 return offset;
1374 /* For a given chain of relocs r, write out the entire relocation
1375 chain to the object file. */
1377 static void macho_write_relocs (struct reloc *r)
1379 while (r) {
1380 uint32_t word2;
1382 fwriteint32_t(r->addr, ofile); /* reloc offset */
1384 word2 = r->snum;
1385 word2 |= r->pcrel << 24;
1386 word2 |= r->length << 25;
1387 word2 |= r->ext << 27;
1388 word2 |= r->type << 28;
1389 fwriteint32_t(word2, ofile); /* reloc data */
1390 r = r->next;
1394 /* Write out the section data. */
1395 static void macho_write_section (void)
1397 struct section *s;
1398 struct reloc *r;
1399 uint8_t *p;
1400 int32_t len;
1401 int64_t l;
1402 union offset {
1403 uint64_t val;
1404 uint8_t buf[8];
1405 } blk;
1407 for (s = sects; s != NULL; s = s->next) {
1408 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1409 continue;
1411 /* Like a.out Mach-O references things in the data or bss
1412 * sections by addresses which are actually relative to the
1413 * start of the _text_ section, in the _file_. See outaout.c
1414 * for more information. */
1415 saa_rewind(s->data);
1416 for (r = s->relocs; r != NULL; r = r->next) {
1417 len = (uint32_t)1 << r->length;
1418 if (len > 4) /* Can this ever be an issue?! */
1419 len = 8;
1420 blk.val = 0;
1421 saa_fread(s->data, r->addr, blk.buf, len);
1423 /* get offset based on relocation type */
1424 #ifdef WORDS_LITTLEENDIAN
1425 l = blk.val;
1426 #else
1427 l = blk.buf[0];
1428 l += ((int64_t)blk.buf[1]) << 8;
1429 l += ((int64_t)blk.buf[2]) << 16;
1430 l += ((int64_t)blk.buf[3]) << 24;
1431 l += ((int64_t)blk.buf[4]) << 32;
1432 l += ((int64_t)blk.buf[5]) << 40;
1433 l += ((int64_t)blk.buf[6]) << 48;
1434 l += ((int64_t)blk.buf[7]) << 56;
1435 #endif
1437 /* If the relocation is internal add to the current section
1438 offset. Otherwise the only value we need is the symbol
1439 offset which we already have. The linker takes care
1440 of the rest of the address. */
1441 if (!r->ext) {
1442 /* generate final address by section address and offset */
1443 nasm_assert(r->snum <= seg_nsects);
1444 l += sectstab[r->snum]->addr;
1445 if (r->pcrel)
1446 l -= s->addr;
1447 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1448 l -= s->addr;
1451 /* write new offset back */
1452 p = blk.buf;
1453 WRITEDLONG(p, l);
1454 saa_fwrite(s->data, r->addr, blk.buf, len);
1457 /* dump the section data to file */
1458 fwritezero(s->pad, ofile);
1459 saa_fpwrite(s->data, ofile);
1462 /* pad last section up to reloc entries on pointer boundary */
1463 fwritezero(rel_padcnt, ofile);
1465 /* emit relocation entries */
1466 for (s = sects; s != NULL; s = s->next)
1467 macho_write_relocs (s->relocs);
1470 /* Write out the symbol table. We should already have sorted this
1471 before now. */
1472 static void macho_write_symtab (void)
1474 struct symbol *sym;
1475 uint64_t i;
1477 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1479 for (sym = syms; sym != NULL; sym = sym->next) {
1480 if ((sym->type & N_EXT) == 0) {
1481 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1482 nasm_write(&sym->type, 1, ofile); /* symbol type */
1483 nasm_write(&sym->sect, 1, ofile); /* section */
1484 fwriteint16_t(sym->desc, ofile); /* description */
1486 /* Fix up the symbol value now that we know the final section
1487 sizes. */
1488 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1489 nasm_assert(sym->sect <= seg_nsects);
1490 sym->symv[0].key += sectstab[sym->sect]->addr;
1493 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1497 for (i = 0; i < nextdefsym; i++) {
1498 sym = extdefsyms[i];
1499 fwriteint32_t(sym->strx, ofile);
1500 nasm_write(&sym->type, 1, ofile); /* symbol type */
1501 nasm_write(&sym->sect, 1, ofile); /* section */
1502 fwriteint16_t(sym->desc, ofile); /* description */
1504 /* Fix up the symbol value now that we know the final section
1505 sizes. */
1506 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1507 nasm_assert(sym->sect <= seg_nsects);
1508 sym->symv[0].key += sectstab[sym->sect]->addr;
1511 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1514 for (i = 0; i < nundefsym; i++) {
1515 sym = undefsyms[i];
1516 fwriteint32_t(sym->strx, ofile);
1517 nasm_write(&sym->type, 1, ofile); /* symbol type */
1518 nasm_write(&sym->sect, 1, ofile); /* section */
1519 fwriteint16_t(sym->desc, ofile); /* description */
1521 /* Fix up the symbol value now that we know the final section
1522 sizes. */
1523 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1524 nasm_assert(sym->sect <= seg_nsects);
1525 sym->symv[0].key += sectstab[sym->sect]->addr;
1528 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1533 /* Fixup the snum in the relocation entries, we should be
1534 doing this only for externally referenced symbols. */
1535 static void macho_fixup_relocs (struct reloc *r)
1537 struct symbol *sym;
1539 while (r != NULL) {
1540 if (r->ext) {
1541 for (sym = syms; sym != NULL; sym = sym->next) {
1542 if (sym->initial_snum == r->snum) {
1543 r->snum = sym->snum;
1544 break;
1548 r = r->next;
1552 /* Write out the object file. */
1554 static void macho_write (void)
1556 uint64_t offset = 0;
1558 /* mach-o object file structure:
1560 ** mach header
1561 ** uint32_t magic
1562 ** int cpu type
1563 ** int cpu subtype
1564 ** uint32_t mach file type
1565 ** uint32_t number of load commands
1566 ** uint32_t size of all load commands
1567 ** (includes section struct size of segment command)
1568 ** uint32_t flags
1570 ** segment command
1571 ** uint32_t command type == LC_SEGMENT[_64]
1572 ** uint32_t size of load command
1573 ** (including section load commands)
1574 ** char[16] segment name
1575 ** pointer in-memory offset
1576 ** pointer in-memory size
1577 ** pointer in-file offset to data area
1578 ** pointer in-file size
1579 ** (in-memory size excluding zerofill sections)
1580 ** int maximum vm protection
1581 ** int initial vm protection
1582 ** uint32_t number of sections
1583 ** uint32_t flags
1585 ** section commands
1586 ** char[16] section name
1587 ** char[16] segment name
1588 ** pointer in-memory offset
1589 ** pointer in-memory size
1590 ** uint32_t in-file offset
1591 ** uint32_t alignment
1592 ** (irrelevant in MH_OBJECT)
1593 ** uint32_t in-file offset of relocation entires
1594 ** uint32_t number of relocations
1595 ** uint32_t flags
1596 ** uint32_t reserved
1597 ** uint32_t reserved
1599 ** symbol table command
1600 ** uint32_t command type == LC_SYMTAB
1601 ** uint32_t size of load command
1602 ** uint32_t symbol table offset
1603 ** uint32_t number of symbol table entries
1604 ** uint32_t string table offset
1605 ** uint32_t string table size
1607 ** raw section data
1609 ** padding to pointer boundary
1611 ** relocation data (struct reloc)
1612 ** int32_t offset
1613 ** uint data (symbolnum, pcrel, length, extern, type)
1615 ** symbol table data (struct nlist)
1616 ** int32_t string table entry number
1617 ** uint8_t type
1618 ** (extern, absolute, defined in section)
1619 ** uint8_t section
1620 ** (0 for global symbols, section number of definition (>= 1, <=
1621 ** 254) for local symbols, size of variable for common symbols
1622 ** [type == extern])
1623 ** int16_t description
1624 ** (for stab debugging format)
1625 ** pointer value (i.e. file offset) of symbol or stab offset
1627 ** string table data
1628 ** list of null-terminated strings
1631 /* Emit the Mach-O header. */
1632 macho_write_header();
1634 offset = fmt.header_size + head_sizeofcmds;
1636 /* emit the segment load command */
1637 if (seg_nsects > 0)
1638 offset = macho_write_segment (offset);
1639 else
1640 nasm_error(ERR_WARNING, "no sections?");
1642 if (nsyms > 0) {
1643 /* write out symbol command */
1644 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1645 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1646 fwriteint32_t(offset, ofile); /* symbol table offset */
1647 fwriteint32_t(nsyms, ofile); /* number of symbol
1648 ** table entries */
1649 offset += nsyms * fmt.nlist_size;
1650 fwriteint32_t(offset, ofile); /* string table offset */
1651 fwriteint32_t(strslen, ofile); /* string table size */
1654 /* emit section data */
1655 if (seg_nsects > 0)
1656 macho_write_section ();
1658 /* emit symbol table if we have symbols */
1659 if (nsyms > 0)
1660 macho_write_symtab ();
1662 /* we don't need to pad here, we are already aligned */
1664 /* emit string table */
1665 saa_fpwrite(strs, ofile);
1667 /* We do quite a bit here, starting with finalizing all of the data
1668 for the object file, writing, and then freeing all of the data from
1669 the file. */
1671 static void macho_cleanup(void)
1673 struct section *s;
1674 struct reloc *r;
1675 struct symbol *sym;
1677 dfmt->cleanup();
1679 /* Sort all symbols. */
1680 macho_layout_symbols (&nsyms, &strslen);
1682 /* Fixup relocation entries */
1683 for (s = sects; s != NULL; s = s->next) {
1684 macho_fixup_relocs (s->relocs);
1687 /* First calculate and finalize needed values. */
1688 macho_calculate_sizes();
1689 macho_write();
1691 /* free up everything */
1692 while (sects->next) {
1693 s = sects;
1694 sects = sects->next;
1696 saa_free(s->data);
1697 while (s->relocs != NULL) {
1698 r = s->relocs;
1699 s->relocs = s->relocs->next;
1700 nasm_free(r);
1703 nasm_free(s);
1706 saa_free(strs);
1707 raa_free(extsyms);
1709 while (syms) {
1710 sym = syms;
1711 syms = syms->next;
1712 nasm_free (sym);
1715 nasm_free(extdefsyms);
1716 nasm_free(undefsyms);
1717 nasm_free(sectstab);
1720 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1722 struct section *s;
1723 int32_t nasm_seg;
1724 int64_t offset;
1726 if (!lookup_label(label, &nasm_seg, &offset)) {
1727 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1728 return false;
1731 s = get_section_by_index(nasm_seg);
1732 if (!s) {
1733 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1734 return false;
1737 s->flags |= flags;
1738 return true;
1742 * Mark a symbol for no dead stripping
1744 static enum directive_result macho_no_dead_strip(const char *labels)
1746 char *s, *p, *ep;
1747 char ec;
1748 enum directive_result rv = DIRR_ERROR;
1749 bool real = passn > 1;
1751 p = s = nasm_strdup(labels);
1752 while (*p) {
1753 ep = nasm_skip_identifier(p);
1754 if (!ep) {
1755 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1756 goto err;
1758 ec = *ep;
1759 if (ec && ec != ',' && !nasm_isspace(ec)) {
1760 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1761 goto err;
1763 *ep = '\0';
1764 if (real) {
1765 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1766 rv = DIRR_ERROR;
1768 *ep = ec;
1769 p = nasm_skip_spaces(ep);
1770 if (*p == ',')
1771 p = nasm_skip_spaces(++p);
1774 rv = DIRR_OK;
1776 err:
1777 nasm_free(s);
1778 return rv;
1782 * Mach-O pragmas
1784 static enum directive_result
1785 macho_pragma(const struct pragma *pragma)
1787 bool real = passn > 1;
1789 switch (pragma->opcode) {
1790 case D_SUBSECTIONS_VIA_SYMBOLS:
1791 if (*pragma->tail)
1792 return DIRR_BADPARAM;
1794 if (real)
1795 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1797 return DIRR_OK;
1799 case D_NO_DEAD_STRIP:
1800 return macho_no_dead_strip(pragma->tail);
1802 default:
1803 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1807 static const struct pragma_facility macho_pragma_list[] = {
1808 { "macho", macho_pragma },
1809 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1812 static void macho_dbg_generate(void)
1814 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1815 size_t saa_len = 0, high_addr = 0, total_len = 0;
1816 struct section *p_section = NULL;
1817 /* calculated at debug_str and referenced at debug_info */
1818 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1820 /* debug section defines */
1822 int bits = 0;
1823 macho_section(".debug_abbrev", 0, &bits);
1824 macho_section(".debug_info", 0, &bits);
1825 macho_section(".debug_line", 0, &bits);
1826 macho_section(".debug_str", 0, &bits);
1829 /* dw section walk to find high_addr and total_len */
1831 struct dw_sect_list *p_sect;
1833 list_for_each(p_sect, dw_head_sect) {
1834 uint64_t offset = get_section_by_index(p_sect->section)->size;
1835 struct SAA *p_linep = p_sect->psaa;
1837 saa_write8(p_linep, 2); /* std op 2 */
1838 saa_write8(p_linep, offset - p_sect->offset);
1839 saa_write8(p_linep, DW_LNS_extended_op);
1840 saa_write8(p_linep, 1); /* operand length */
1841 saa_write8(p_linep, DW_LNE_end_sequence);
1843 total_len += p_linep->datalen;
1844 high_addr += offset;
1848 /* debug line */
1850 struct dw_sect_list *p_sect;
1851 size_t linep_off, buf_size;
1852 struct SAA *p_lines = saa_init(1L);
1853 struct dir_list *p_dir;
1854 struct file_list *p_file;
1856 p_section = get_section_by_name("__DWARF", "__debug_line");
1857 nasm_assert(p_section != NULL);
1859 saa_write8(p_lines, 1); /* minimum instruction length */
1860 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1861 saa_write8(p_lines, DW_LN_BASE); /* line base */
1862 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1863 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1864 saa_write8(p_lines, 0); /* std opcode 1 length */
1865 saa_write8(p_lines, 1); /* std opcode 2 length */
1866 saa_write8(p_lines, 1); /* std opcode 3 length */
1867 saa_write8(p_lines, 1); /* std opcode 4 length */
1868 saa_write8(p_lines, 1); /* std opcode 5 length */
1869 saa_write8(p_lines, 0); /* std opcode 6 length */
1870 saa_write8(p_lines, 0); /* std opcode 7 length */
1871 saa_write8(p_lines, 0); /* std opcode 8 length */
1872 saa_write8(p_lines, 1); /* std opcode 9 length */
1873 saa_write8(p_lines, 0); /* std opcode 10 length */
1874 saa_write8(p_lines, 0); /* std opcode 11 length */
1875 saa_write8(p_lines, 1); /* std opcode 12 length */
1876 list_for_each(p_dir, dw_head_dir) {
1877 saa_wcstring(p_lines, p_dir->dir_name);
1879 saa_write8(p_lines, 0); /* end of table */
1881 list_for_each(p_file, dw_head_file) {
1882 saa_wcstring(p_lines, p_file->file_name);
1883 saa_write8(p_lines, p_file->dir->dir); /* directory id */
1884 saa_write8(p_lines, 0); /* time */
1885 saa_write8(p_lines, 0); /* size */
1887 saa_write8(p_lines, 0); /* end of table */
1889 linep_off = p_lines->datalen;
1890 /* 10 bytes for initial & prolong length, and dwarf version info */
1891 buf_size = saa_len = linep_off + total_len + 10;
1892 p_buf_base = p_buf = nasm_malloc(buf_size);
1894 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1895 WRITESHORT(p_buf, 2); /* dwarf version */
1896 WRITELONG(p_buf, linep_off); /* prolong length */
1898 saa_rnbytes(p_lines, p_buf, linep_off);
1899 p_buf += linep_off;
1900 saa_free(p_lines);
1902 list_for_each(p_sect, dw_head_sect) {
1903 struct SAA *p_linep = p_sect->psaa;
1905 saa_len = p_linep->datalen;
1906 saa_rnbytes(p_linep, p_buf, saa_len);
1907 p_buf += saa_len;
1909 saa_free(p_linep);
1912 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1914 nasm_free(p_buf_base);
1917 /* string section */
1919 struct SAA *p_str = saa_init(1L);
1920 char *cur_path = nasm_realpath(module_name);
1921 char *cur_file = nasm_basename(cur_path);
1922 char *cur_dir = nasm_dirname(cur_path);
1924 p_section = get_section_by_name("__DWARF", "__debug_str");
1925 nasm_assert(p_section != NULL);
1927 producer_str_offset = 0;
1928 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
1929 dir_str_offset += saa_wcstring(p_str, cur_file);
1930 saa_wcstring(p_str, cur_dir);
1932 saa_len = p_str->datalen;
1933 p_buf = nasm_malloc(saa_len);
1934 saa_rnbytes(p_str, p_buf, saa_len);
1935 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1937 nasm_free(cur_path);
1938 nasm_free(cur_file);
1939 nasm_free(cur_dir);
1940 saa_free(p_str);
1941 nasm_free(p_buf);
1944 /* debug info */
1946 struct SAA *p_info = saa_init(1L);
1948 p_section = get_section_by_name("__DWARF", "__debug_info");
1949 nasm_assert(p_section != NULL);
1951 /* size will be overwritten once determined, so skip in p_info layout */
1952 saa_write16(p_info, 2); /* dwarf version */
1953 saa_write32(p_info, 0); /* offset info abbrev */
1954 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1956 saa_write8(p_info, 1); /* abbrev entry number */
1958 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1959 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1960 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1961 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1962 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1964 if (ofmt == &of_macho64) {
1965 saa_write64(p_info, 0); /* DW_AT_low_pc */
1966 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1967 } else {
1968 saa_write32(p_info, 0); /* DW_AT_low_pc */
1969 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1972 saa_write8(p_info, 2); /* abbrev entry number */
1974 if (ofmt == &of_macho64) {
1975 saa_write64(p_info, 0); /* DW_AT_low_pc */
1976 saa_write64(p_info, 0); /* DW_AT_frame_base */
1977 } else {
1978 saa_write32(p_info, 0); /* DW_AT_low_pc */
1979 saa_write32(p_info, 0); /* DW_AT_frame_base */
1981 saa_write8(p_info, DW_END_default);
1983 saa_len = p_info->datalen;
1984 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1986 WRITELONG(p_buf, saa_len);
1987 saa_rnbytes(p_info, p_buf, saa_len);
1988 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1990 saa_free(p_info);
1991 nasm_free(p_buf_base);
1994 /* abbrev section */
1996 struct SAA *p_abbrev = saa_init(1L);
1998 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
1999 nasm_assert(p_section != NULL);
2001 saa_write8(p_abbrev, 1); /* entry number */
2003 saa_write8(p_abbrev, DW_TAG_compile_unit);
2004 saa_write8(p_abbrev, DW_CHILDREN_yes);
2006 saa_write8(p_abbrev, DW_AT_producer);
2007 saa_write8(p_abbrev, DW_FORM_strp);
2009 saa_write8(p_abbrev, DW_AT_language);
2010 saa_write8(p_abbrev, DW_FORM_data2);
2012 saa_write8(p_abbrev, DW_AT_name);
2013 saa_write8(p_abbrev, DW_FORM_strp);
2015 saa_write8(p_abbrev, DW_AT_comp_dir);
2016 saa_write8(p_abbrev, DW_FORM_strp);
2018 saa_write8(p_abbrev, DW_AT_stmt_list);
2019 saa_write8(p_abbrev, DW_FORM_data4);
2021 saa_write8(p_abbrev, DW_AT_low_pc);
2022 saa_write8(p_abbrev, DW_FORM_addr);
2024 saa_write8(p_abbrev, DW_AT_high_pc);
2025 saa_write8(p_abbrev, DW_FORM_addr);
2027 saa_write16(p_abbrev, DW_END_default);
2029 saa_write8(p_abbrev, 2); /* entry number */
2031 saa_write8(p_abbrev, DW_TAG_subprogram);
2032 saa_write8(p_abbrev, DW_CHILDREN_no);
2034 saa_write8(p_abbrev, DW_AT_low_pc);
2035 saa_write8(p_abbrev, DW_FORM_addr);
2037 saa_write8(p_abbrev, DW_AT_frame_base);
2038 saa_write8(p_abbrev, DW_FORM_addr);
2040 saa_write16(p_abbrev, DW_END_default);
2042 saa_len = p_abbrev->datalen;
2044 p_buf = nasm_malloc(saa_len);
2046 saa_rnbytes(p_abbrev, p_buf, saa_len);
2047 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2049 saa_free(p_abbrev);
2050 nasm_free(p_buf);
2054 static void new_file_list (const char *file_name, const char *dir_name)
2056 struct dir_list *dir_list;
2057 bool need_new_dir_list = true;
2059 nasm_new(dw_cur_file);
2060 dw_cur_file->file = ++dw_num_files;
2061 dw_cur_file->file_name = file_name;
2062 if(!dw_head_file) {
2063 dw_head_file = dw_cur_file;
2064 } else {
2065 *dw_last_file_next = dw_cur_file;
2067 dw_last_file_next = &(dw_cur_file->next);
2069 if(dw_head_dir) {
2070 list_for_each(dir_list, dw_head_dir) {
2071 if(!(strcmp(dir_name, dir_list->dir_name))) {
2072 dw_cur_file->dir = dir_list;
2073 need_new_dir_list = false;
2074 break;
2079 if(need_new_dir_list)
2081 nasm_new(dir_list);
2082 dir_list->dir = dw_num_dirs++;
2083 dir_list->dir_name = dir_name;
2084 if(!dw_head_dir) {
2085 dw_head_dir = dir_list;
2086 } else {
2087 *dw_last_dir_next = dir_list;
2089 dw_last_dir_next = &(dir_list->next);
2090 dw_cur_file->dir = dir_list;
2094 static void macho_dbg_init(void)
2098 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2100 bool need_new_list = true;
2101 const char *cur_file = nasm_basename(file_name);
2102 const char *cur_dir = nasm_dirname(file_name);
2103 (void)segto;
2105 if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2106 strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2107 if(dw_head_file) {
2108 struct file_list *match;
2110 list_for_each(match, dw_head_file) {
2111 if(!(strcmp(cur_file, match->file_name)) &&
2112 !(strcmp(cur_dir, match->dir->dir_name))) {
2113 dw_cur_file = match;
2114 dw_cur_file->dir = match->dir;
2115 need_new_list = false;
2116 break;
2121 if(need_new_list) {
2122 new_file_list(cur_file, cur_dir);
2126 dbg_immcall = true;
2127 cur_line = line_num;
2130 static void macho_dbg_output(int type, void *param)
2132 struct section_info *sinfo_param = (struct section_info *)param;
2133 int32_t secto = sinfo_param->secto;
2134 bool need_new_sect = false;
2135 struct SAA *p_linep = NULL;
2136 (void)type;
2138 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2139 need_new_sect = true;
2140 if(dw_head_sect) {
2141 struct dw_sect_list *match = dw_head_sect;
2142 uint32_t idx = 0;
2144 for(; idx < dw_num_sects; idx++) {
2145 if(match->section == secto) {
2146 dw_cur_sect = match;
2147 need_new_sect = false;
2148 break;
2150 match = match->next;
2155 if(need_new_sect) {
2156 nasm_new(dw_cur_sect);
2157 dw_num_sects ++;
2158 p_linep = dw_cur_sect->psaa = saa_init(1L);
2159 dw_cur_sect->line = dw_cur_sect->file = 1;
2160 dw_cur_sect->offset = 0;
2161 dw_cur_sect->next = NULL;
2162 dw_cur_sect->section = secto;
2164 saa_write8(p_linep, DW_LNS_extended_op);
2165 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2166 saa_write8(p_linep, DW_LNE_set_address);
2167 if (ofmt == &of_macho64) {
2168 saa_write64(p_linep, 0);
2169 } else {
2170 saa_write32(p_linep, 0);
2173 if(!dw_head_sect) {
2174 dw_head_sect = dw_last_sect = dw_cur_sect;
2175 } else {
2176 dw_last_sect->next = dw_cur_sect;
2177 dw_last_sect = dw_cur_sect;
2181 if(dbg_immcall == true) {
2182 int32_t line_delta = cur_line - dw_cur_sect->line;
2183 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2184 uint32_t cur_file = dw_cur_file->file;
2185 p_linep = dw_cur_sect->psaa;
2187 if(cur_file != dw_cur_sect->file) {
2188 saa_write8(p_linep, DW_LNS_set_file);
2189 saa_write8(p_linep, cur_file);
2190 dw_cur_sect->file = cur_file;
2193 if(line_delta) {
2194 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2195 DW_OPCODE_BASE;
2197 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2198 (special_opcode < DW_MAX_SP_OPCODE)) {
2199 saa_write8(p_linep, special_opcode);
2200 } else {
2201 saa_write8(p_linep, DW_LNS_advance_line);
2202 saa_wleb128s(p_linep, line_delta);
2203 if(offset_delta) {
2204 saa_write8(p_linep, DW_LNS_advance_pc);
2205 saa_wleb128u(p_linep, offset_delta);
2207 saa_write8(p_linep, DW_LNS_copy);
2210 dw_cur_sect->line = cur_line;
2211 dw_cur_sect->offset = sinfo_param->size;
2214 dbg_immcall = false;
2218 static void macho_dbg_cleanup(void)
2220 /* dwarf sectors generation */
2221 macho_dbg_generate();
2224 struct dw_sect_list *p_sect = dw_head_sect;
2225 struct file_list *p_file = dw_head_file;
2226 uint32_t idx = 0;
2228 for(; idx < dw_num_sects; idx++) {
2229 struct dw_sect_list *next = p_sect->next;
2230 nasm_free(p_sect);
2231 p_sect = next;
2234 for(idx = 0; idx < dw_num_files; idx++) {
2235 struct file_list *next = p_file->next;
2236 nasm_free(p_file);
2237 p_file = next;
2242 #ifdef OF_MACHO32
2243 static const struct macho_fmt macho32_fmt = {
2245 MH_MAGIC,
2246 CPU_TYPE_I386,
2247 LC_SEGMENT,
2248 MACHO_HEADER_SIZE,
2249 MACHO_SEGCMD_SIZE,
2250 MACHO_SECTCMD_SIZE,
2251 MACHO_NLIST_SIZE,
2252 RL_MAX_32,
2253 GENERIC_RELOC_VANILLA,
2254 GENERIC_RELOC_VANILLA,
2255 GENERIC_RELOC_TLV,
2256 false /* Allow segment-relative relocations */
2259 static void macho32_init(void)
2261 fmt = macho32_fmt;
2262 macho_init();
2264 macho_gotpcrel_sect = NO_SEG;
2267 static const struct dfmt macho32_df_dwarf = {
2268 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2269 "dwarf",
2270 macho_dbg_init,
2271 macho_dbg_linenum,
2272 null_debug_deflabel,
2273 null_debug_directive,
2274 null_debug_typevalue,
2275 macho_dbg_output,
2276 macho_dbg_cleanup,
2277 NULL /*pragma list*/
2280 static const struct dfmt * const macho32_df_arr[2] =
2281 { &macho32_df_dwarf, NULL };
2283 const struct ofmt of_macho32 = {
2284 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2285 "macho32",
2288 macho32_df_arr,
2289 &macho32_df_dwarf,
2290 macho_stdmac,
2291 macho32_init,
2292 nasm_do_legacy_output,
2293 macho_output,
2294 macho_symdef,
2295 macho_section,
2296 macho_sectalign,
2297 macho_segbase,
2298 null_directive,
2299 macho_filename,
2300 macho_cleanup,
2301 macho_pragma_list
2303 #endif
2305 #ifdef OF_MACHO64
2306 static const struct macho_fmt macho64_fmt = {
2308 MH_MAGIC_64,
2309 CPU_TYPE_X86_64,
2310 LC_SEGMENT_64,
2311 MACHO_HEADER64_SIZE,
2312 MACHO_SEGCMD64_SIZE,
2313 MACHO_SECTCMD64_SIZE,
2314 MACHO_NLIST64_SIZE,
2315 RL_MAX_64,
2316 X86_64_RELOC_UNSIGNED,
2317 X86_64_RELOC_SIGNED,
2318 X86_64_RELOC_TLV,
2319 true /* Force symbol-relative relocations */
2322 static void macho64_init(void)
2324 fmt = macho64_fmt;
2325 macho_init();
2327 /* add special symbol for ..gotpcrel */
2328 macho_gotpcrel_sect = seg_alloc() + 1;
2329 define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2332 static const struct dfmt macho64_df_dwarf = {
2333 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2334 "dwarf",
2335 macho_dbg_init,
2336 macho_dbg_linenum,
2337 null_debug_deflabel,
2338 null_debug_directive,
2339 null_debug_typevalue,
2340 macho_dbg_output,
2341 macho_dbg_cleanup,
2342 NULL /*pragma list*/
2345 static const struct dfmt * const macho64_df_arr[2] =
2346 { &macho64_df_dwarf, NULL };
2348 const struct ofmt of_macho64 = {
2349 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2350 "macho64",
2353 macho64_df_arr,
2354 &macho64_df_dwarf,
2355 macho_stdmac,
2356 macho64_init,
2357 nasm_do_legacy_output,
2358 macho_output,
2359 macho_symdef,
2360 macho_section,
2361 macho_sectalign,
2362 macho_segbase,
2363 null_directive,
2364 macho_filename,
2365 macho_cleanup,
2366 macho_pragma_list,
2368 #endif
2370 #endif
2373 * Local Variables:
2374 * mode:c
2375 * c-basic-offset:4
2376 * End:
2378 * end of file */