NASM 2.13rc22
[nasm/externdefs2.git] / output / outmacho.c
blobc6774d11d7dc88a4f6c81ed6fea6231c9f9f68c5
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 */
143 static struct macho_fmt fmt;
145 static void fwriteptr(uint64_t data, FILE * fp)
147 fwriteaddr(data, fmt.ptrsize, fp);
150 struct section {
151 /* nasm internal data */
152 struct section *next;
153 struct SAA *data;
154 int32_t index;
155 int32_t fileindex;
156 struct reloc *relocs;
157 struct rbtree *gsyms; /* Global symbols in section */
158 int align;
159 bool by_name; /* This section was specified by full MachO name */
161 /* data that goes into the file */
162 char sectname[16]; /* what this section is called */
163 char segname[16]; /* segment this section will be in */
164 uint64_t addr; /* in-memory address (subject to alignment) */
165 uint64_t size; /* in-memory and -file size */
166 uint64_t offset; /* in-file offset */
167 uint32_t pad; /* padding bytes before section */
168 uint32_t nreloc; /* relocation entry count */
169 uint32_t flags; /* type and attributes (masked) */
170 uint32_t extreloc; /* external relocations */
173 #define SECTION_TYPE 0x000000ff /* section type mask */
175 #define S_REGULAR (0x0) /* standard section */
176 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
178 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
179 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
180 machine instructions */
181 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
182 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
183 #define S_ATTR_DEBUG 0x02000000
184 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
185 #define S_ATTR_LIVE_SUPPORT 0x08000000
186 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
187 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
188 #define S_ATTR_NO_TOC 0x40000000
189 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
190 #define S_ATTR_DEBUG 0x02000000 /* debug section */
192 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
194 /* fake section for absolute symbols, *not* part of the section linked list */
195 static struct section absolute_sect;
197 struct reloc {
198 /* nasm internal data */
199 struct reloc *next;
201 /* data that goes into the file */
202 int32_t addr; /* op's offset in section */
203 uint32_t snum:24, /* contains symbol index if
204 ** ext otherwise in-file
205 ** section number */
206 pcrel:1, /* relative relocation */
207 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
208 ext:1, /* external symbol referenced */
209 type:4; /* reloc type */
212 #define R_ABS 0 /* absolute relocation */
213 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
214 ** highest bit == 1 */
216 struct symbol {
217 /* nasm internal data */
218 struct rbtree symv; /* Global symbol rbtree; "key" contains the
219 symbol offset. */
220 struct symbol *next; /* next symbol in the list */
221 char *name; /* name of this symbol */
222 int32_t initial_snum; /* symbol number used above in reloc */
223 int32_t snum; /* true snum for reloc */
225 /* data that goes into the file */
226 uint32_t strx; /* string table index */
227 uint8_t type; /* symbol type */
228 uint8_t sect; /* NO_SECT or section number */
229 uint16_t desc; /* for stab debugging, 0 for us */
232 /* symbol type bits */
233 #define N_EXT 0x01 /* global or external symbol */
235 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
236 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
237 #define N_SECT 0xe /* defined symbol, n_sect holds
238 ** section number */
240 #define N_TYPE 0x0e /* type bit mask */
242 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
244 /* special section number values */
245 #define NO_SECT 0 /* no section, invalid */
246 #define MAX_SECT 255 /* maximum number of sections */
248 static struct section *sects, **sectstail, **sectstab;
249 static struct symbol *syms, **symstail;
250 static uint32_t nsyms;
252 /* These variables are set by macho_layout_symbols() to organize
253 the symbol table and string table in order the dynamic linker
254 expects. They are then used in macho_write() to put out the
255 symbols and strings in that order.
257 The order of the symbol table is:
258 local symbols
259 defined external symbols (sorted by name)
260 undefined external symbols (sorted by name)
262 The order of the string table is:
263 strings for external symbols
264 strings for local symbols
266 static uint32_t ilocalsym = 0;
267 static uint32_t iextdefsym = 0;
268 static uint32_t iundefsym = 0;
269 static uint32_t nlocalsym;
270 static uint32_t nextdefsym;
271 static uint32_t nundefsym;
272 static struct symbol **extdefsyms = NULL;
273 static struct symbol **undefsyms = NULL;
275 static struct RAA *extsyms;
276 static struct SAA *strs;
277 static uint32_t strslen;
279 /* Global file information. This should be cleaned up into either
280 a structure or as function arguments. */
281 static uint32_t head_ncmds = 0;
282 static uint32_t head_sizeofcmds = 0;
283 static uint32_t head_flags = 0;
284 static uint64_t seg_filesize = 0;
285 static uint64_t seg_vmsize = 0;
286 static uint32_t seg_nsects = 0;
287 static uint64_t rel_padcnt = 0;
289 #define xstrncpy(xdst, xsrc) \
290 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
291 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
292 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
294 #define alignint32_t(x) \
295 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
297 #define alignint64_t(x) \
298 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
300 #define alignptr(x) \
301 ALIGN(x, fmt.ptrsize) /* align x to output format width */
303 static struct section *get_section_by_name(const char *segname,
304 const char *sectname)
306 struct section *s;
308 for (s = sects; s != NULL; s = s->next)
309 if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
310 break;
312 return s;
315 static struct section *get_section_by_index(const int32_t index)
317 struct section *s;
319 for (s = sects; s != NULL; s = s->next)
320 if (index == s->index)
321 break;
323 return s;
326 struct file_list {
327 struct file_list *next;
328 struct file_list *last;
329 char *file_name;
330 uint32_t file;
333 struct dw_sect_list {
334 struct SAA *psaa;
335 int32_t section;
336 uint32_t line;
337 uint64_t offset;
338 uint32_t file;
339 struct dw_sect_list *next;
340 struct dw_sect_list *last;
343 struct section_info {
344 uint64_t size;
345 int32_t secto;
348 #define DW_LN_BASE (-5)
349 #define DW_LN_RANGE 14
350 #define DW_OPCODE_BASE 13
351 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
352 #define DW_MAX_SP_OPCODE 256
354 static struct file_list *dw_head_list = 0, *dw_cur_list = 0, *dw_last_list = 0;
355 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
356 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_sects = 0;
357 static bool dbg_immcall = false;
358 static const char *module_name = NULL;
361 * Special section numbers which are used to define Mach-O special
362 * symbols, which can be used with WRT to provide PIC relocation
363 * types.
365 static int32_t macho_tlvp_sect;
366 static int32_t macho_gotpcrel_sect;
368 static void macho_init(void)
370 sects = NULL;
371 sectstail = &sects;
373 /* Fake section for absolute symbols */
374 absolute_sect.index = NO_SEG;
376 syms = NULL;
377 symstail = &syms;
378 nsyms = 0;
379 nlocalsym = 0;
380 nextdefsym = 0;
381 nundefsym = 0;
383 extsyms = raa_init();
384 strs = saa_init(1L);
386 /* string table starts with a zero byte so index 0 is an empty string */
387 saa_wbytes(strs, zero_buffer, 1);
388 strslen = 1;
390 /* add special symbol for TLVP */
391 macho_tlvp_sect = seg_alloc() + 1;
392 define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
396 static void sect_write(struct section *sect,
397 const uint8_t *data, uint32_t len)
399 saa_wbytes(sect->data, data, len);
400 sect->size += len;
404 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
406 static struct symbol *macho_find_gsym(struct section *s,
407 uint64_t offset, bool exact)
409 struct rbtree *srb;
411 srb = rb_search(s->gsyms, offset);
413 if (!srb || (exact && srb->key != offset)) {
414 nasm_error(ERR_NONFATAL, "unable to find a suitable %s symbol"
415 " for this reference",
416 s == &absolute_sect ? "absolute" : "global");
417 return NULL;
420 return container_of(srb, struct symbol, symv);
423 static int64_t add_reloc(struct section *sect, int32_t section,
424 int64_t offset,
425 enum reltype reltype, int bytes)
427 struct reloc *r;
428 struct section *s;
429 int32_t fi;
430 int64_t adjust;
432 /* Double check this is a valid relocation type for this platform */
433 nasm_assert(reltype <= fmt.maxreltype);
435 /* the current end of the section will be the symbol's address for
436 ** now, might have to be fixed by macho_fixup_relocs() later on. make
437 ** sure we don't make the symbol scattered by setting the highest
438 ** bit by accident */
439 r = nasm_malloc(sizeof(struct reloc));
440 r->addr = sect->size & ~R_SCATTERED;
441 r->ext = 1;
442 adjust = bytes;
444 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
445 r->length = ilog2_32(bytes);
447 /* set default relocation values */
448 r->type = fmt.reloc_abs;
449 r->pcrel = 0;
450 r->snum = R_ABS;
452 s = NULL;
453 if (section != NO_SEG)
454 s = get_section_by_index(section);
455 fi = s ? s->fileindex : NO_SECT;
457 /* absolute relocation */
458 switch (reltype) {
459 case RL_ABS:
460 if (section == NO_SEG) {
461 /* absolute (can this even happen?) */
462 r->ext = 0;
463 r->snum = R_ABS;
464 } else if (fi == NO_SECT) {
465 /* external */
466 r->snum = raa_read(extsyms, section);
467 } else {
468 /* local */
469 r->ext = 0;
470 r->snum = fi;
471 adjust = -sect->size;
473 break;
475 case RL_REL:
476 case RL_BRANCH:
477 r->type = fmt.reloc_rel;
478 r->pcrel = 1;
479 if (section == NO_SEG) {
480 /* absolute - seems to produce garbage no matter what */
481 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
482 "references to absolute addresses");
483 goto bail;
484 #if 0
485 /* This "seems" to be how it ought to work... */
487 struct symbol *sym = macho_find_gsym(&absolute_sect,
488 offset, false);
489 if (!sym)
490 goto bail;
492 sect->extreloc = 1;
493 r->snum = NO_SECT;
494 adjust = -sect->size;
495 #endif
496 } else if (fi == NO_SECT) {
497 /* external */
498 sect->extreloc = 1;
499 r->snum = raa_read(extsyms, section);
500 if (reltype == RL_BRANCH)
501 r->type = X86_64_RELOC_BRANCH;
502 else if (r->type == GENERIC_RELOC_VANILLA)
503 adjust = -sect->size;
504 } else {
505 /* local */
506 r->ext = 0;
507 r->snum = fi;
508 adjust = -sect->size;
510 break;
512 case RL_SUB:
513 r->pcrel = 0;
514 r->type = X86_64_RELOC_SUBTRACTOR;
515 break;
517 case RL_GOT:
518 r->type = X86_64_RELOC_GOT;
519 goto needsym;
521 case RL_GOTLOAD:
522 r->type = X86_64_RELOC_GOT_LOAD;
523 goto needsym;
525 case RL_TLV:
526 r->type = fmt.reloc_tlv;
527 goto needsym;
529 needsym:
530 r->pcrel = 1;
531 if (section == NO_SEG) {
532 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
533 } else if (fi == NO_SECT) {
534 /* external */
535 r->snum = raa_read(extsyms, section);
536 } else {
537 /* internal */
538 struct symbol *sym = macho_find_gsym(s, offset, reltype != RL_TLV);
539 if (!sym)
540 goto bail;
541 r->snum = sym->initial_snum;
543 break;
546 /* NeXT as puts relocs in reversed order (address-wise) into the
547 ** files, so we do the same, doesn't seem to make much of a
548 ** difference either way */
549 r->next = sect->relocs;
550 sect->relocs = r;
551 if (r->ext)
552 sect->extreloc = 1;
553 ++sect->nreloc;
555 return adjust;
557 bail:
558 nasm_free(r);
559 return 0;
562 static void macho_output(int32_t secto, const void *data,
563 enum out_type type, uint64_t size,
564 int32_t section, int32_t wrt)
566 struct section *s;
567 int64_t addr, offset;
568 uint8_t mydata[16], *p;
569 bool is_bss;
570 enum reltype reltype;
572 if (secto == NO_SEG) {
573 if (type != OUT_RESERVE)
574 nasm_error(ERR_NONFATAL, "attempt to assemble code in "
575 "[ABSOLUTE] space");
576 return;
579 s = get_section_by_index(secto);
581 if (s == NULL) {
582 nasm_error(ERR_WARNING, "attempt to assemble code in"
583 " section %d: defaulting to `.text'", secto);
584 s = get_section_by_name("__TEXT", "__text");
586 /* should never happen */
587 if (s == NULL)
588 nasm_panic(0, "text section not found");
591 /* debug code generation only for sections tagged with
592 * instruction attribute */
593 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
595 struct section_info sinfo;
596 sinfo.size = s->size;
597 sinfo.secto = secto;
598 dfmt->debug_output(0, &sinfo);
601 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
603 if (is_bss && type != OUT_RESERVE) {
604 nasm_error(ERR_WARNING, "attempt to initialize memory in "
605 "BSS section: ignored");
606 s->size += realsize(type, size);
607 return;
610 memset(mydata, 0, sizeof(mydata));
612 switch (type) {
613 case OUT_RESERVE:
614 if (!is_bss) {
615 nasm_error(ERR_WARNING, "uninitialized space declared in"
616 " %s,%s section: zeroing", s->segname, s->sectname);
618 sect_write(s, NULL, size);
619 } else
620 s->size += size;
622 break;
624 case OUT_RAWDATA:
625 if (section != NO_SEG)
626 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
628 sect_write(s, data, size);
629 break;
631 case OUT_ADDRESS:
633 int asize = abs((int)size);
635 addr = *(int64_t *)data;
636 if (section != NO_SEG) {
637 if (section % 2) {
638 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
639 " section base references");
640 } else if (wrt == NO_SEG) {
641 if (fmt.ptrsize == 8 && asize != 8) {
642 nasm_error(ERR_NONFATAL,
643 "Mach-O 64-bit format does not support"
644 " 32-bit absolute addresses");
645 } else {
646 add_reloc(s, section, addr, RL_ABS, asize);
648 } else {
649 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
650 " this use of WRT");
654 p = mydata;
655 WRITEADDR(p, addr, asize);
656 sect_write(s, mydata, asize);
657 break;
660 case OUT_REL2ADR:
661 nasm_assert(section != secto);
663 p = mydata;
664 offset = *(int64_t *)data;
665 addr = offset - size;
667 if (section != NO_SEG && section % 2) {
668 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
669 " section base references");
670 } else if (fmt.ptrsize == 8) {
671 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
672 " Macho-O relocation [2]");
673 } else if (wrt != NO_SEG) {
674 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
675 " this use of WRT");
676 wrt = NO_SEG; /* we can at least _try_ to continue */
677 } else {
678 addr += add_reloc(s, section, addr+size, RL_REL, 2);
681 WRITESHORT(p, addr);
682 sect_write(s, mydata, 2);
683 break;
685 case OUT_REL4ADR:
686 nasm_assert(section != secto);
688 p = mydata;
689 offset = *(int64_t *)data;
690 addr = offset - size;
691 reltype = RL_REL;
693 if (section != NO_SEG && section % 2) {
694 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
695 " section base references");
696 } else if (wrt == NO_SEG) {
697 if (fmt.ptrsize == 8 &&
698 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
699 uint8_t opcode[2];
701 opcode[0] = opcode[1] = 0;
703 /* HACK: Retrieve instruction opcode */
704 if (likely(s->data->datalen >= 2)) {
705 saa_fread(s->data, s->data->datalen-2, opcode, 2);
706 } else if (s->data->datalen == 1) {
707 saa_fread(s->data, 0, opcode+1, 1);
710 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
711 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
712 /* Direct call, jmp, or jcc */
713 reltype = RL_BRANCH;
716 } else if (wrt == macho_gotpcrel_sect) {
717 reltype = RL_GOT;
719 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
720 s->data->datalen >= 3) {
721 uint8_t gotload[3];
723 /* HACK: Retrieve instruction opcode */
724 saa_fread(s->data, s->data->datalen-3, gotload, 3);
725 if ((gotload[0] & 0xf8) == 0x48 &&
726 gotload[1] == 0x8b &&
727 (gotload[2] & 0307) == 0005) {
728 /* movq <reg>,[rel sym wrt ..gotpcrel] */
729 reltype = RL_GOTLOAD;
732 } else if (wrt == macho_tlvp_sect) {
733 reltype = RL_TLV;
734 } else {
735 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
736 " this use of WRT");
737 /* continue with RL_REL */
740 addr += add_reloc(s, section, offset, reltype, 4);
741 WRITELONG(p, addr);
742 sect_write(s, mydata, 4);
743 break;
745 default:
746 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
747 break;
751 /* Translation table from traditional Unix section names to Mach-O */
752 static const struct sectmap {
753 const char *nasmsect;
754 const char *segname;
755 const char *sectname;
756 const uint32_t flags;
757 } sectmap[] = {
758 {".text", "__TEXT", "__text",
759 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
760 {".data", "__DATA", "__data", S_REGULAR},
761 {".rodata", "__DATA", "__const", S_REGULAR},
762 {".bss", "__DATA", "__bss", S_ZEROFILL},
763 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
764 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
765 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
766 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
767 {NULL, NULL, NULL, 0}
770 #define NO_TYPE S_NASM_TYPE_MASK
772 /* Section type or attribute directives */
773 static const struct sect_attribs {
774 const char *name;
775 uint32_t flags;
776 } sect_attribs[] = {
777 { "data", S_REGULAR },
778 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
779 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
780 { "bss", S_ZEROFILL },
781 { "zerofill", S_ZEROFILL },
782 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
783 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
784 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
785 { NULL, 0 }
788 static int32_t macho_section(char *name, int pass, int *bits)
790 char *sectionAttributes;
791 const struct sectmap *sm;
792 struct section *s;
793 const char *section, *segment;
794 uint32_t flags;
795 const struct sect_attribs *sa;
796 char *currentAttribute;
797 char *comma;
799 bool new_seg;
801 (void)pass;
803 /* Default to the appropriate number of bits. */
804 if (!name) {
805 *bits = fmt.ptrsize << 3;
806 name = ".text";
807 sectionAttributes = NULL;
808 } else {
809 sectionAttributes = name;
810 name = nasm_strsep(&sectionAttributes, " \t");
813 section = segment = NULL;
814 flags = 0;
816 comma = strchr(name, ',');
817 if (comma) {
818 int len;
820 *comma = '\0';
821 segment = name;
822 section = comma+1;
824 len = strlen(segment);
825 if (len == 0) {
826 nasm_error(ERR_NONFATAL, "empty segment name\n");
827 } else if (len >= 16) {
828 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
831 len = strlen(section);
832 if (len == 0) {
833 nasm_error(ERR_NONFATAL, "empty section name\n");
834 } else if (len >= 16) {
835 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
838 if (!strcmp(section, "__text")) {
839 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
840 S_ATTR_PURE_INSTRUCTIONS;
841 } else if (!strcmp(section, "__bss")) {
842 flags = S_ZEROFILL;
843 } else {
844 flags = S_REGULAR;
846 } else {
847 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
848 /* make lookup into section name translation table */
849 if (!strcmp(name, sm->nasmsect)) {
850 segment = sm->segname;
851 section = sm->sectname;
852 flags = sm->flags;
853 goto found;
856 nasm_error(ERR_NONFATAL, "unknown section name\n");
857 return NO_SEG;
860 found:
861 /* try to find section with that name */
862 s = get_section_by_name(segment, section);
864 /* create it if it doesn't exist yet */
865 if (!s) {
866 new_seg = true;
868 s = *sectstail = nasm_zalloc(sizeof(struct section));
869 sectstail = &s->next;
871 s->data = saa_init(1L);
872 s->index = seg_alloc();
873 s->fileindex = ++seg_nsects;
874 s->align = -1;
875 s->pad = -1;
876 s->offset = -1;
877 s->by_name = false;
879 xstrncpy(s->segname, segment);
880 xstrncpy(s->sectname, section);
881 s->size = 0;
882 s->nreloc = 0;
883 s->flags = flags;
884 } else {
885 new_seg = false;
888 if (comma)
889 *comma = ','; /* Restore comma */
891 s->by_name = s->by_name || comma; /* Was specified by name */
893 flags = NO_TYPE;
895 while (sectionAttributes &&
896 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
897 if (!*currentAttribute)
898 continue;
900 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
901 char *end;
902 int newAlignment, value;
904 value = strtoul(currentAttribute + 6, (char**)&end, 0);
905 newAlignment = alignlog2_32(value);
907 if (0 != *end) {
908 nasm_error(ERR_NONFATAL,
909 "unknown or missing alignment value \"%s\" "
910 "specified for section \"%s\"",
911 currentAttribute + 6,
912 name);
913 } else if (0 > newAlignment) {
914 nasm_error(ERR_NONFATAL,
915 "alignment of %d (for section \"%s\") is not "
916 "a power of two",
917 value,
918 name);
921 if (s->align < newAlignment)
922 s->align = newAlignment;
923 } else {
924 for (sa = sect_attribs; sa->name; sa++) {
925 if (!nasm_stricmp(sa->name, currentAttribute)) {
926 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
927 flags = (flags & ~S_NASM_TYPE_MASK)
928 | (sa->flags & S_NASM_TYPE_MASK);
930 flags |= sa->flags & ~S_NASM_TYPE_MASK;
931 break;
935 if (!sa->name) {
936 nasm_error(ERR_NONFATAL,
937 "unknown section attribute %s for section %s",
938 currentAttribute, name);
943 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
944 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
945 nasm_error(ERR_NONFATAL,
946 "inconsistent section attributes for section %s\n",
947 name);
948 } else {
949 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
951 } else {
952 s->flags |= flags & ~S_NASM_TYPE_MASK;
955 return s->index;
958 static void macho_symdef(char *name, int32_t section, int64_t offset,
959 int is_global, char *special)
961 struct symbol *sym;
963 if (special) {
964 nasm_error(ERR_NONFATAL, "The Mach-O output format does "
965 "not support any special symbol types");
966 return;
969 if (is_global == 3) {
970 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
971 "(yet) support forward reference fixups.");
972 return;
975 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
977 * This is a NASM special symbol. We never allow it into
978 * the Macho-O symbol table, even if it's a valid one. If it
979 * _isn't_ a valid one, we should barf immediately.
981 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
982 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
983 return;
986 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
987 sym->next = NULL;
988 symstail = &sym->next;
990 sym->name = name;
991 sym->strx = strslen;
992 sym->type = 0;
993 sym->desc = 0;
994 sym->symv.key = offset;
995 sym->initial_snum = -1;
997 /* external and common symbols get N_EXT */
998 if (is_global != 0) {
999 sym->type |= N_EXT;
1002 if (section == NO_SEG) {
1003 /* symbols in no section get absolute */
1004 sym->type |= N_ABS;
1005 sym->sect = NO_SECT;
1007 /* all absolute symbols are available to use as references */
1008 absolute_sect.gsyms = rb_insert(absolute_sect.gsyms, &sym->symv);
1009 } else {
1010 struct section *s = get_section_by_index(section);
1012 sym->type |= N_SECT;
1014 /* get the in-file index of the section the symbol was defined in */
1015 sym->sect = s ? s->fileindex : NO_SECT;
1017 /* track the initially allocated symbol number for use in future fix-ups */
1018 sym->initial_snum = nsyms;
1020 if (!s) {
1021 /* remember symbol number of references to external
1022 ** symbols, this works because every external symbol gets
1023 ** its own section number allocated internally by nasm and
1024 ** can so be used as a key */
1025 extsyms = raa_write(extsyms, section, nsyms);
1027 switch (is_global) {
1028 case 1:
1029 case 2:
1030 /* there isn't actually a difference between global
1031 ** and common symbols, both even have their size in
1032 ** sym->symv.key */
1033 sym->type = N_EXT;
1034 break;
1036 default:
1037 /* give an error on unfound section if it's not an
1038 ** external or common symbol (assemble_file() does a
1039 ** seg_alloc() on every call for them) */
1040 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1041 break;
1043 } else if (is_global) {
1044 s->gsyms = rb_insert(s->gsyms, &sym->symv);
1047 ++nsyms;
1050 static void macho_sectalign(int32_t seg, unsigned int value)
1052 struct section *s;
1053 int align;
1055 nasm_assert(!(seg & 1));
1057 s = get_section_by_index(seg);
1059 if (!s || !is_power2(value))
1060 return;
1062 align = alignlog2_32(value);
1063 if (s->align < align)
1064 s->align = align;
1067 static int32_t macho_segbase(int32_t section)
1069 return section;
1072 static void macho_filename(char *inname, char *outname)
1074 standard_extension(inname, outname, ".o");
1075 module_name = inname;
1078 extern macros_t macho_stdmac[];
1080 /* Comparison function for qsort symbol layout. */
1081 static int layout_compare (const struct symbol **s1,
1082 const struct symbol **s2)
1084 return (strcmp ((*s1)->name, (*s2)->name));
1087 /* The native assembler does a few things in a similar function
1089 * Remove temporary labels
1090 * Sort symbols according to local, external, undefined (by name)
1091 * Order the string table
1093 We do not remove temporary labels right now.
1095 numsyms is the total number of symbols we have. strtabsize is the
1096 number entries in the string table. */
1098 static void macho_layout_symbols (uint32_t *numsyms,
1099 uint32_t *strtabsize)
1101 struct symbol *sym, **symp;
1102 uint32_t i,j;
1104 *numsyms = 0;
1105 *strtabsize = sizeof (char);
1107 symp = &syms;
1109 while ((sym = *symp)) {
1110 /* Undefined symbols are now external. */
1111 if (sym->type == N_UNDF)
1112 sym->type |= N_EXT;
1114 if ((sym->type & N_EXT) == 0) {
1115 sym->snum = *numsyms;
1116 *numsyms = *numsyms + 1;
1117 nlocalsym++;
1119 else {
1120 if ((sym->type & N_TYPE) != N_UNDF) {
1121 nextdefsym++;
1122 } else {
1123 nundefsym++;
1126 /* If we handle debug info we'll want
1127 to check for it here instead of just
1128 adding the symbol to the string table. */
1129 sym->strx = *strtabsize;
1130 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1131 *strtabsize += strlen(sym->name) + 1;
1133 symp = &(sym->next);
1136 /* Next, sort the symbols. Most of this code is a direct translation from
1137 the Apple cctools symbol layout. We need to keep compatibility with that. */
1138 /* Set the indexes for symbol groups into the symbol table */
1139 ilocalsym = 0;
1140 iextdefsym = nlocalsym;
1141 iundefsym = nlocalsym + nextdefsym;
1143 /* allocate arrays for sorting externals by name */
1144 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1145 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1147 i = 0;
1148 j = 0;
1150 symp = &syms;
1152 while ((sym = *symp)) {
1154 if((sym->type & N_EXT) == 0) {
1155 sym->strx = *strtabsize;
1156 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1157 *strtabsize += strlen(sym->name) + 1;
1159 else {
1160 if ((sym->type & N_TYPE) != N_UNDF) {
1161 extdefsyms[i++] = sym;
1162 } else {
1163 undefsyms[j++] = sym;
1166 symp = &(sym->next);
1169 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1170 (int (*)(const void *, const void *))layout_compare);
1171 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1172 (int (*)(const void *, const void *))layout_compare);
1174 for(i = 0; i < nextdefsym; i++) {
1175 extdefsyms[i]->snum = *numsyms;
1176 *numsyms += 1;
1178 for(j = 0; j < nundefsym; j++) {
1179 undefsyms[j]->snum = *numsyms;
1180 *numsyms += 1;
1184 /* Calculate some values we'll need for writing later. */
1186 static void macho_calculate_sizes (void)
1188 struct section *s;
1189 int fi;
1191 /* count sections and calculate in-memory and in-file offsets */
1192 for (s = sects; s != NULL; s = s->next) {
1193 uint64_t newaddr;
1195 /* recalculate segment address based on alignment and vm size */
1196 s->addr = seg_vmsize;
1198 /* we need section alignment to calculate final section address */
1199 if (s->align == -1)
1200 s->align = DEFAULT_SECTION_ALIGNMENT;
1202 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1203 s->addr = newaddr;
1205 seg_vmsize = newaddr + s->size;
1207 /* zerofill sections aren't actually written to the file */
1208 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1210 * LLVM/Xcode as always aligns the section data to 4
1211 * bytes; there is a comment in the LLVM source code that
1212 * perhaps aligning to pointer size would be better.
1214 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1215 s->offset = seg_filesize + s->pad;
1216 seg_filesize += s->size + s->pad;
1218 /* filesize and vmsize needs to be aligned */
1219 seg_vmsize += s->pad;
1223 /* calculate size of all headers, load commands and sections to
1224 ** get a pointer to the start of all the raw data */
1225 if (seg_nsects > 0) {
1226 ++head_ncmds;
1227 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1230 if (nsyms > 0) {
1231 ++head_ncmds;
1232 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1235 if (seg_nsects > MAX_SECT) {
1236 nasm_fatal(0, "MachO output is limited to %d sections\n",
1237 MAX_SECT);
1240 /* Create a table of sections by file index to avoid linear search */
1241 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1242 sectstab[NO_SECT] = &absolute_sect;
1243 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1244 sectstab[fi] = s;
1247 /* Write out the header information for the file. */
1249 static void macho_write_header (void)
1251 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1252 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1253 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1254 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1255 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1256 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1257 fwriteint32_t(head_flags, ofile); /* flags, if any */
1258 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1261 /* Write out the segment load command at offset. */
1263 static uint32_t macho_write_segment (uint64_t offset)
1265 uint64_t rel_base = alignptr(offset + seg_filesize);
1266 uint32_t s_reloff = 0;
1267 struct section *s;
1269 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1271 /* size of load command including section load commands */
1272 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1273 ofile);
1275 /* in an MH_OBJECT file all sections are in one unnamed (name
1276 ** all zeros) segment */
1277 fwritezero(16, ofile);
1278 fwriteptr(0, ofile); /* in-memory offset */
1279 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1280 fwriteptr(offset, ofile); /* in-file offset to data */
1281 fwriteptr(seg_filesize, ofile); /* in-file size */
1282 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1283 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1284 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1285 fwriteint32_t(0, ofile); /* no flags */
1287 /* emit section headers */
1288 for (s = sects; s != NULL; s = s->next) {
1289 if (s->nreloc) {
1290 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1291 s->flags |= S_ATTR_LOC_RELOC;
1292 if (s->extreloc)
1293 s->flags |= S_ATTR_EXT_RELOC;
1294 } else if (!strcmp(s->segname, "__DATA") &&
1295 !strcmp(s->sectname, "__const") &&
1296 !s->by_name &&
1297 !get_section_by_name("__TEXT", "__const")) {
1299 * The MachO equivalent to .rodata can be either
1300 * __DATA,__const or __TEXT,__const; the latter only if
1301 * there are no relocations. However, when mixed it is
1302 * better to specify the segments explicitly.
1304 xstrncpy(s->segname, "__TEXT");
1307 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1308 nasm_write(s->segname, sizeof(s->segname), ofile);
1309 fwriteptr(s->addr, ofile);
1310 fwriteptr(s->size, ofile);
1312 /* dummy data for zerofill sections or proper values */
1313 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1314 nasm_assert(s->pad != (uint32_t)-1);
1315 offset += s->pad;
1316 fwriteint32_t(offset, ofile);
1317 offset += s->size;
1318 /* Write out section alignment, as a power of two.
1319 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1320 fwriteint32_t(s->align, ofile);
1321 /* To be compatible with cctools as we emit
1322 a zero reloff if we have no relocations. */
1323 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1324 fwriteint32_t(s->nreloc, ofile);
1326 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1327 } else {
1328 fwriteint32_t(0, ofile);
1329 fwriteint32_t(s->align, ofile);
1330 fwriteint32_t(0, ofile);
1331 fwriteint32_t(0, ofile);
1334 fwriteint32_t(s->flags, ofile); /* flags */
1335 fwriteint32_t(0, ofile); /* reserved */
1336 fwriteptr(0, ofile); /* reserved */
1339 rel_padcnt = rel_base - offset;
1340 offset = rel_base + s_reloff;
1342 return offset;
1345 /* For a given chain of relocs r, write out the entire relocation
1346 chain to the object file. */
1348 static void macho_write_relocs (struct reloc *r)
1350 while (r) {
1351 uint32_t word2;
1353 fwriteint32_t(r->addr, ofile); /* reloc offset */
1355 word2 = r->snum;
1356 word2 |= r->pcrel << 24;
1357 word2 |= r->length << 25;
1358 word2 |= r->ext << 27;
1359 word2 |= r->type << 28;
1360 fwriteint32_t(word2, ofile); /* reloc data */
1361 r = r->next;
1365 /* Write out the section data. */
1366 static void macho_write_section (void)
1368 struct section *s;
1369 struct reloc *r;
1370 uint8_t *p;
1371 int32_t len;
1372 int64_t l;
1373 union offset {
1374 uint64_t val;
1375 uint8_t buf[8];
1376 } blk;
1378 for (s = sects; s != NULL; s = s->next) {
1379 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1380 continue;
1382 /* Like a.out Mach-O references things in the data or bss
1383 * sections by addresses which are actually relative to the
1384 * start of the _text_ section, in the _file_. See outaout.c
1385 * for more information. */
1386 saa_rewind(s->data);
1387 for (r = s->relocs; r != NULL; r = r->next) {
1388 len = (uint32_t)1 << r->length;
1389 if (len > 4) /* Can this ever be an issue?! */
1390 len = 8;
1391 blk.val = 0;
1392 saa_fread(s->data, r->addr, blk.buf, len);
1394 /* get offset based on relocation type */
1395 #ifdef WORDS_LITTLEENDIAN
1396 l = blk.val;
1397 #else
1398 l = blk.buf[0];
1399 l += ((int64_t)blk.buf[1]) << 8;
1400 l += ((int64_t)blk.buf[2]) << 16;
1401 l += ((int64_t)blk.buf[3]) << 24;
1402 l += ((int64_t)blk.buf[4]) << 32;
1403 l += ((int64_t)blk.buf[5]) << 40;
1404 l += ((int64_t)blk.buf[6]) << 48;
1405 l += ((int64_t)blk.buf[7]) << 56;
1406 #endif
1408 /* If the relocation is internal add to the current section
1409 offset. Otherwise the only value we need is the symbol
1410 offset which we already have. The linker takes care
1411 of the rest of the address. */
1412 if (!r->ext) {
1413 /* generate final address by section address and offset */
1414 nasm_assert(r->snum <= seg_nsects);
1415 l += sectstab[r->snum]->addr;
1416 if (r->pcrel)
1417 l -= s->addr;
1418 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1419 l -= s->addr;
1422 /* write new offset back */
1423 p = blk.buf;
1424 WRITEDLONG(p, l);
1425 saa_fwrite(s->data, r->addr, blk.buf, len);
1428 /* dump the section data to file */
1429 fwritezero(s->pad, ofile);
1430 saa_fpwrite(s->data, ofile);
1433 /* pad last section up to reloc entries on pointer boundary */
1434 fwritezero(rel_padcnt, ofile);
1436 /* emit relocation entries */
1437 for (s = sects; s != NULL; s = s->next)
1438 macho_write_relocs (s->relocs);
1441 /* Write out the symbol table. We should already have sorted this
1442 before now. */
1443 static void macho_write_symtab (void)
1445 struct symbol *sym;
1446 uint64_t i;
1448 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1450 for (sym = syms; sym != NULL; sym = sym->next) {
1451 if ((sym->type & N_EXT) == 0) {
1452 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1453 nasm_write(&sym->type, 1, ofile); /* symbol type */
1454 nasm_write(&sym->sect, 1, ofile); /* section */
1455 fwriteint16_t(sym->desc, ofile); /* description */
1457 /* Fix up the symbol value now that we know the final section
1458 sizes. */
1459 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1460 nasm_assert(sym->sect <= seg_nsects);
1461 sym->symv.key += sectstab[sym->sect]->addr;
1464 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1468 for (i = 0; i < nextdefsym; i++) {
1469 sym = extdefsyms[i];
1470 fwriteint32_t(sym->strx, ofile);
1471 nasm_write(&sym->type, 1, ofile); /* symbol type */
1472 nasm_write(&sym->sect, 1, ofile); /* section */
1473 fwriteint16_t(sym->desc, ofile); /* description */
1475 /* Fix up the symbol value now that we know the final section
1476 sizes. */
1477 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1478 nasm_assert(sym->sect <= seg_nsects);
1479 sym->symv.key += sectstab[sym->sect]->addr;
1482 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1485 for (i = 0; i < nundefsym; i++) {
1486 sym = undefsyms[i];
1487 fwriteint32_t(sym->strx, ofile);
1488 nasm_write(&sym->type, 1, ofile); /* symbol type */
1489 nasm_write(&sym->sect, 1, ofile); /* section */
1490 fwriteint16_t(sym->desc, ofile); /* description */
1492 /* Fix up the symbol value now that we know the final section
1493 sizes. */
1494 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1495 nasm_assert(sym->sect <= seg_nsects);
1496 sym->symv.key += sectstab[sym->sect]->addr;
1499 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1504 /* Fixup the snum in the relocation entries, we should be
1505 doing this only for externally referenced symbols. */
1506 static void macho_fixup_relocs (struct reloc *r)
1508 struct symbol *sym;
1510 while (r != NULL) {
1511 if (r->ext) {
1512 for (sym = syms; sym != NULL; sym = sym->next) {
1513 if (sym->initial_snum == r->snum) {
1514 r->snum = sym->snum;
1515 break;
1519 r = r->next;
1523 /* Write out the object file. */
1525 static void macho_write (void)
1527 uint64_t offset = 0;
1529 /* mach-o object file structure:
1531 ** mach header
1532 ** uint32_t magic
1533 ** int cpu type
1534 ** int cpu subtype
1535 ** uint32_t mach file type
1536 ** uint32_t number of load commands
1537 ** uint32_t size of all load commands
1538 ** (includes section struct size of segment command)
1539 ** uint32_t flags
1541 ** segment command
1542 ** uint32_t command type == LC_SEGMENT[_64]
1543 ** uint32_t size of load command
1544 ** (including section load commands)
1545 ** char[16] segment name
1546 ** pointer in-memory offset
1547 ** pointer in-memory size
1548 ** pointer in-file offset to data area
1549 ** pointer in-file size
1550 ** (in-memory size excluding zerofill sections)
1551 ** int maximum vm protection
1552 ** int initial vm protection
1553 ** uint32_t number of sections
1554 ** uint32_t flags
1556 ** section commands
1557 ** char[16] section name
1558 ** char[16] segment name
1559 ** pointer in-memory offset
1560 ** pointer in-memory size
1561 ** uint32_t in-file offset
1562 ** uint32_t alignment
1563 ** (irrelevant in MH_OBJECT)
1564 ** uint32_t in-file offset of relocation entires
1565 ** uint32_t number of relocations
1566 ** uint32_t flags
1567 ** uint32_t reserved
1568 ** uint32_t reserved
1570 ** symbol table command
1571 ** uint32_t command type == LC_SYMTAB
1572 ** uint32_t size of load command
1573 ** uint32_t symbol table offset
1574 ** uint32_t number of symbol table entries
1575 ** uint32_t string table offset
1576 ** uint32_t string table size
1578 ** raw section data
1580 ** padding to pointer boundary
1582 ** relocation data (struct reloc)
1583 ** int32_t offset
1584 ** uint data (symbolnum, pcrel, length, extern, type)
1586 ** symbol table data (struct nlist)
1587 ** int32_t string table entry number
1588 ** uint8_t type
1589 ** (extern, absolute, defined in section)
1590 ** uint8_t section
1591 ** (0 for global symbols, section number of definition (>= 1, <=
1592 ** 254) for local symbols, size of variable for common symbols
1593 ** [type == extern])
1594 ** int16_t description
1595 ** (for stab debugging format)
1596 ** pointer value (i.e. file offset) of symbol or stab offset
1598 ** string table data
1599 ** list of null-terminated strings
1602 /* Emit the Mach-O header. */
1603 macho_write_header();
1605 offset = fmt.header_size + head_sizeofcmds;
1607 /* emit the segment load command */
1608 if (seg_nsects > 0)
1609 offset = macho_write_segment (offset);
1610 else
1611 nasm_error(ERR_WARNING, "no sections?");
1613 if (nsyms > 0) {
1614 /* write out symbol command */
1615 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1616 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1617 fwriteint32_t(offset, ofile); /* symbol table offset */
1618 fwriteint32_t(nsyms, ofile); /* number of symbol
1619 ** table entries */
1620 offset += nsyms * fmt.nlist_size;
1621 fwriteint32_t(offset, ofile); /* string table offset */
1622 fwriteint32_t(strslen, ofile); /* string table size */
1625 /* emit section data */
1626 if (seg_nsects > 0)
1627 macho_write_section ();
1629 /* emit symbol table if we have symbols */
1630 if (nsyms > 0)
1631 macho_write_symtab ();
1633 /* we don't need to pad here, we are already aligned */
1635 /* emit string table */
1636 saa_fpwrite(strs, ofile);
1638 /* We do quite a bit here, starting with finalizing all of the data
1639 for the object file, writing, and then freeing all of the data from
1640 the file. */
1642 static void macho_cleanup(void)
1644 struct section *s;
1645 struct reloc *r;
1646 struct symbol *sym;
1648 dfmt->cleanup();
1650 /* Sort all symbols. */
1651 macho_layout_symbols (&nsyms, &strslen);
1653 /* Fixup relocation entries */
1654 for (s = sects; s != NULL; s = s->next) {
1655 macho_fixup_relocs (s->relocs);
1658 /* First calculate and finalize needed values. */
1659 macho_calculate_sizes();
1660 macho_write();
1662 /* free up everything */
1663 while (sects->next) {
1664 s = sects;
1665 sects = sects->next;
1667 saa_free(s->data);
1668 while (s->relocs != NULL) {
1669 r = s->relocs;
1670 s->relocs = s->relocs->next;
1671 nasm_free(r);
1674 nasm_free(s);
1677 saa_free(strs);
1678 raa_free(extsyms);
1680 while (syms) {
1681 sym = syms;
1682 syms = syms->next;
1683 nasm_free (sym);
1686 nasm_free(extdefsyms);
1687 nasm_free(undefsyms);
1688 nasm_free(sectstab);
1691 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1693 struct section *s;
1694 int32_t nasm_seg;
1695 int64_t offset;
1697 if (!lookup_label(label, &nasm_seg, &offset)) {
1698 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1699 return false;
1702 s = get_section_by_index(nasm_seg);
1703 if (!s) {
1704 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1705 return false;
1708 s->flags |= flags;
1709 return true;
1713 * Mark a symbol for no dead stripping
1715 static enum directive_result macho_no_dead_strip(const char *labels)
1717 char *s, *p, *ep;
1718 char ec;
1719 enum directive_result rv = DIRR_ERROR;
1720 bool real = passn > 1;
1722 p = s = nasm_strdup(labels);
1723 while (*p) {
1724 ep = nasm_skip_identifier(p);
1725 if (!ep) {
1726 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1727 goto err;
1729 ec = *ep;
1730 if (ec && ec != ',' && !nasm_isspace(ec)) {
1731 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1732 goto err;
1734 *ep = '\0';
1735 if (real) {
1736 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1737 rv = DIRR_ERROR;
1739 *ep = ec;
1740 p = nasm_skip_spaces(ep);
1741 if (*p == ',')
1742 p = nasm_skip_spaces(++p);
1745 rv = DIRR_OK;
1747 err:
1748 nasm_free(s);
1749 return rv;
1753 * Mach-O pragmas
1755 static enum directive_result
1756 macho_pragma(const struct pragma *pragma)
1758 bool real = passn > 1;
1760 switch (pragma->opcode) {
1761 case D_SUBSECTIONS_VIA_SYMBOLS:
1762 if (*pragma->tail)
1763 return DIRR_BADPARAM;
1765 if (real)
1766 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1768 return DIRR_OK;
1770 case D_NO_DEAD_STRIP:
1771 return macho_no_dead_strip(pragma->tail);
1773 default:
1774 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1778 static const struct pragma_facility macho_pragma_list[] = {
1779 { "macho", macho_pragma },
1780 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1783 static void macho_dbg_generate(void)
1785 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1786 size_t saa_len = 0, high_addr = 0, total_len = 0;
1787 struct section *p_section = NULL;
1788 /* calculated at debug_str and referenced at debug_info */
1789 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1791 /* debug section defines */
1793 int bits = 0;
1794 macho_section(".debug_abbrev", 0, &bits);
1795 macho_section(".debug_info", 0, &bits);
1796 macho_section(".debug_line", 0, &bits);
1797 macho_section(".debug_str", 0, &bits);
1800 /* dw section walk to find high_addr and total_len */
1802 struct dw_sect_list *p_sect;
1804 list_for_each(p_sect, dw_head_sect) {
1805 uint64_t offset = get_section_by_index(p_sect->section)->size;
1806 struct SAA *p_linep = p_sect->psaa;
1808 saa_write8(p_linep, 2); /* std op 2 */
1809 saa_write8(p_linep, offset - p_sect->offset);
1810 saa_write8(p_linep, DW_LNS_extended_op);
1811 saa_write8(p_linep, 1); /* operand length */
1812 saa_write8(p_linep, DW_LNE_end_sequence);
1814 total_len += p_linep->datalen;
1815 high_addr += offset;
1819 /* debug line */
1821 struct dw_sect_list *p_sect;
1822 size_t linep_off, buf_size;
1823 struct SAA *p_lines = saa_init(1L);
1825 p_section = get_section_by_name("__DWARF", "__debug_line");
1826 nasm_assert(p_section != NULL);
1828 saa_write8(p_lines, 1); /* minimum instruction length */
1829 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1830 saa_write8(p_lines, DW_LN_BASE); /* line base */
1831 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1832 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1833 saa_write8(p_lines, 0); /* std opcode 1 length */
1834 saa_write8(p_lines, 1); /* std opcode 2 length */
1835 saa_write8(p_lines, 1); /* std opcode 3 length */
1836 saa_write8(p_lines, 1); /* std opcode 4 length */
1837 saa_write8(p_lines, 1); /* std opcode 5 length */
1838 saa_write8(p_lines, 0); /* std opcode 6 length */
1839 saa_write8(p_lines, 0); /* std opcode 7 length */
1840 saa_write8(p_lines, 0); /* std opcode 8 length */
1841 saa_write8(p_lines, 1); /* std opcode 9 length */
1842 saa_write8(p_lines, 0); /* std opcode 10 length */
1843 saa_write8(p_lines, 0); /* std opcode 11 length */
1844 saa_write8(p_lines, 1); /* std opcode 12 length */
1845 saa_write8(p_lines, 0); /* end of table */
1847 saa_wcstring(p_lines, module_name);
1848 saa_write8(p_lines, 0); /* directory */
1849 saa_write8(p_lines, 0); /* time */
1850 saa_write8(p_lines, 0); /* size */
1851 saa_write8(p_lines, 0); /* end of table */
1853 linep_off = p_lines->datalen;
1854 /* 10 bytes for initial & prolong length, and dwarf version info */
1855 buf_size = saa_len = linep_off + total_len + 10;
1856 p_buf_base = p_buf = nasm_malloc(buf_size);
1858 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1859 WRITESHORT(p_buf, 2); /* dwarf version */
1860 WRITELONG(p_buf, linep_off); /* prolong length */
1862 saa_rnbytes(p_lines, p_buf, linep_off);
1863 p_buf += linep_off;
1864 saa_free(p_lines);
1866 list_for_each(p_sect, dw_head_sect) {
1867 struct SAA *p_linep = p_sect->psaa;
1869 saa_len = p_linep->datalen;
1870 saa_rnbytes(p_linep, p_buf, saa_len);
1871 p_buf += saa_len;
1873 saa_free(p_linep);
1876 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1878 nasm_free(p_buf_base);
1881 /* string section */
1883 struct SAA *p_str = saa_init(1L);
1884 char *cur_path = nasm_realpath(module_name);
1885 char *cur_file = nasm_basename(cur_path);
1886 char *cur_dir = nasm_dirname(cur_path);
1888 p_section = get_section_by_name("__DWARF", "__debug_str");
1889 nasm_assert(p_section != NULL);
1891 producer_str_offset = 0;
1892 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
1893 dir_str_offset += saa_wcstring(p_str, cur_file);
1894 saa_wcstring(p_str, cur_dir);
1896 saa_len = p_str->datalen;
1897 p_buf = nasm_malloc(saa_len);
1898 saa_rnbytes(p_str, p_buf, saa_len);
1899 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1901 nasm_free(cur_path);
1902 nasm_free(cur_file);
1903 nasm_free(cur_dir);
1904 saa_free(p_str);
1905 nasm_free(p_buf);
1908 /* debug info */
1910 struct SAA *p_info = saa_init(1L);
1912 p_section = get_section_by_name("__DWARF", "__debug_info");
1913 nasm_assert(p_section != NULL);
1915 /* size will be overwritten once determined, so skip in p_info layout */
1916 saa_write16(p_info, 2); /* dwarf version */
1917 saa_write32(p_info, 0); /* offset info abbrev */
1918 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1920 saa_write8(p_info, 1); /* abbrev entry number */
1922 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1923 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1924 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1925 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1926 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1928 if (ofmt == &of_macho64) {
1929 saa_write64(p_info, 0); /* DW_AT_low_pc */
1930 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1931 } else {
1932 saa_write32(p_info, 0); /* DW_AT_low_pc */
1933 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1936 saa_write8(p_info, 2); /* abbrev entry number */
1938 if (ofmt == &of_macho64) {
1939 saa_write64(p_info, 0); /* DW_AT_low_pc */
1940 saa_write64(p_info, 0); /* DW_AT_frame_base */
1941 } else {
1942 saa_write32(p_info, 0); /* DW_AT_low_pc */
1943 saa_write32(p_info, 0); /* DW_AT_frame_base */
1945 saa_write8(p_info, DW_END_default);
1947 saa_len = p_info->datalen;
1948 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1950 WRITELONG(p_buf, saa_len);
1951 saa_rnbytes(p_info, p_buf, saa_len);
1952 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1954 saa_free(p_info);
1955 nasm_free(p_buf_base);
1958 /* abbrev section */
1960 struct SAA *p_abbrev = saa_init(1L);
1962 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
1963 nasm_assert(p_section != NULL);
1965 saa_write8(p_abbrev, 1); /* entry number */
1967 saa_write8(p_abbrev, DW_TAG_compile_unit);
1968 saa_write8(p_abbrev, DW_CHILDREN_yes);
1970 saa_write8(p_abbrev, DW_AT_producer);
1971 saa_write8(p_abbrev, DW_FORM_strp);
1973 saa_write8(p_abbrev, DW_AT_language);
1974 saa_write8(p_abbrev, DW_FORM_data2);
1976 saa_write8(p_abbrev, DW_AT_name);
1977 saa_write8(p_abbrev, DW_FORM_strp);
1979 saa_write8(p_abbrev, DW_AT_comp_dir);
1980 saa_write8(p_abbrev, DW_FORM_strp);
1982 saa_write8(p_abbrev, DW_AT_stmt_list);
1983 saa_write8(p_abbrev, DW_FORM_data4);
1985 saa_write8(p_abbrev, DW_AT_low_pc);
1986 saa_write8(p_abbrev, DW_FORM_addr);
1988 saa_write8(p_abbrev, DW_AT_high_pc);
1989 saa_write8(p_abbrev, DW_FORM_addr);
1991 saa_write16(p_abbrev, DW_END_default);
1993 saa_write8(p_abbrev, 2); /* entry number */
1995 saa_write8(p_abbrev, DW_TAG_subprogram);
1996 saa_write8(p_abbrev, DW_CHILDREN_no);
1998 saa_write8(p_abbrev, DW_AT_low_pc);
1999 saa_write8(p_abbrev, DW_FORM_addr);
2001 saa_write8(p_abbrev, DW_AT_frame_base);
2002 saa_write8(p_abbrev, DW_FORM_addr);
2004 saa_write16(p_abbrev, DW_END_default);
2006 saa_len = p_abbrev->datalen;
2008 p_buf = nasm_malloc(saa_len);
2010 saa_rnbytes(p_abbrev, p_buf, saa_len);
2011 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2013 saa_free(p_abbrev);
2014 nasm_free(p_buf);
2018 static void macho_dbg_init(void)
2022 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2024 bool need_new_list = true;
2025 (void)segto;
2027 if(!dw_cur_list || strcmp(file_name, dw_cur_list->file_name)) {
2028 if(dw_head_list) {
2029 struct file_list *match;
2031 list_for_each(match, dw_head_list) {
2032 if(!(strcmp(file_name, match->file_name))) {
2033 dw_cur_list = match;
2034 need_new_list = false;
2035 break;
2040 if(need_new_list) {
2041 nasm_new(dw_cur_list);
2042 dw_cur_list->file = ++dw_num_files;
2043 dw_cur_list->file_name = (char*) file_name;
2045 if(!dw_head_list) {
2046 dw_head_list = dw_last_list = dw_cur_list;
2047 } else {
2048 dw_last_list->next = dw_cur_list;
2049 dw_last_list = dw_cur_list;
2054 dbg_immcall = true;
2055 cur_line = line_num;
2058 static void macho_dbg_output(int type, void *param)
2060 struct section_info *sinfo_param = (struct section_info *)param;
2061 int32_t secto = sinfo_param->secto;
2062 bool need_new_sect = false;
2063 struct SAA *p_linep = NULL;
2064 (void)type;
2066 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2067 need_new_sect = true;
2068 if(dw_head_sect) {
2069 struct dw_sect_list *match = dw_head_sect;
2070 uint32_t idx = 0;
2072 for(; idx < dw_num_sects; idx++) {
2073 if(match->section == secto) {
2074 dw_cur_sect = match;
2075 need_new_sect = false;
2076 break;
2078 match = match->next;
2083 if(need_new_sect) {
2084 nasm_new(dw_cur_sect);
2085 dw_num_sects ++;
2086 p_linep = dw_cur_sect->psaa = saa_init(1L);
2087 dw_cur_sect->line = dw_cur_sect->file = 1;
2088 dw_cur_sect->offset = 0;
2089 dw_cur_sect->next = NULL;
2090 dw_cur_sect->section = secto;
2092 saa_write8(p_linep, DW_LNS_extended_op);
2093 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2094 saa_write8(p_linep, DW_LNE_set_address);
2095 if (ofmt == &of_macho64) {
2096 saa_write64(p_linep, 0);
2097 } else {
2098 saa_write32(p_linep, 0);
2101 if(!dw_head_sect) {
2102 dw_head_sect = dw_last_sect = dw_cur_sect;
2103 } else {
2104 dw_last_sect->next = dw_cur_sect;
2105 dw_last_sect = dw_cur_sect;
2109 if(dbg_immcall == true) {
2110 int32_t line_delta = cur_line - dw_cur_sect->line;
2111 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2112 uint32_t cur_file = dw_cur_list->file;
2113 p_linep = dw_cur_sect->psaa;
2115 if(cur_file != dw_cur_sect->file) {
2116 saa_write8(p_linep, DW_LNS_set_file);
2117 saa_write8(p_linep, cur_file);
2118 dw_cur_sect->file = cur_file;
2121 if(line_delta) {
2122 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2123 DW_OPCODE_BASE;
2125 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2126 (special_opcode < DW_MAX_SP_OPCODE)) {
2127 saa_write8(p_linep, special_opcode);
2128 } else {
2129 saa_write8(p_linep, DW_LNS_advance_line);
2130 saa_wleb128s(p_linep, line_delta);
2131 if(offset_delta) {
2132 saa_write8(p_linep, DW_LNS_advance_pc);
2133 saa_wleb128u(p_linep, offset_delta);
2135 saa_write8(p_linep, DW_LNS_copy);
2138 dw_cur_sect->line = cur_line;
2139 dw_cur_sect->offset = sinfo_param->size;
2142 dbg_immcall = false;
2146 static void macho_dbg_cleanup(void)
2148 /* dwarf sectors generation */
2149 macho_dbg_generate();
2152 struct dw_sect_list *p_sect = dw_head_sect;
2153 struct file_list *p_file = dw_head_list;
2154 uint32_t idx = 0;
2156 for(; idx < dw_num_sects; idx++) {
2157 struct dw_sect_list *next = p_sect->next;
2158 nasm_free(p_sect);
2159 p_sect = next;
2162 for(idx = 0; idx < dw_num_files; idx++) {
2163 struct file_list *next = p_file->next;
2164 nasm_free(p_file);
2165 p_file = next;
2170 #ifdef OF_MACHO32
2171 static const struct macho_fmt macho32_fmt = {
2173 MH_MAGIC,
2174 CPU_TYPE_I386,
2175 LC_SEGMENT,
2176 MACHO_HEADER_SIZE,
2177 MACHO_SEGCMD_SIZE,
2178 MACHO_SECTCMD_SIZE,
2179 MACHO_NLIST_SIZE,
2180 RL_MAX_32,
2181 GENERIC_RELOC_VANILLA,
2182 GENERIC_RELOC_VANILLA,
2183 GENERIC_RELOC_TLV
2186 static void macho32_init(void)
2188 fmt = macho32_fmt;
2189 macho_init();
2191 macho_gotpcrel_sect = NO_SEG;
2194 static const struct dfmt macho32_df_dwarf = {
2195 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2196 "dwarf",
2197 macho_dbg_init,
2198 macho_dbg_linenum,
2199 null_debug_deflabel,
2200 null_debug_directive,
2201 null_debug_typevalue,
2202 macho_dbg_output,
2203 macho_dbg_cleanup,
2204 NULL /*pragma list*/
2207 static const struct dfmt * const macho32_df_arr[2] =
2208 { &macho32_df_dwarf, NULL };
2210 const struct ofmt of_macho32 = {
2211 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2212 "macho32",
2215 macho32_df_arr,
2216 &macho32_df_dwarf,
2217 macho_stdmac,
2218 macho32_init,
2219 nasm_do_legacy_output,
2220 macho_output,
2221 macho_symdef,
2222 macho_section,
2223 macho_sectalign,
2224 macho_segbase,
2225 null_directive,
2226 macho_filename,
2227 macho_cleanup,
2228 macho_pragma_list,
2230 #endif
2232 #ifdef OF_MACHO64
2233 static const struct macho_fmt macho64_fmt = {
2235 MH_MAGIC_64,
2236 CPU_TYPE_X86_64,
2237 LC_SEGMENT_64,
2238 MACHO_HEADER64_SIZE,
2239 MACHO_SEGCMD64_SIZE,
2240 MACHO_SECTCMD64_SIZE,
2241 MACHO_NLIST64_SIZE,
2242 RL_MAX_64,
2243 X86_64_RELOC_UNSIGNED,
2244 X86_64_RELOC_SIGNED,
2245 X86_64_RELOC_TLV
2248 static void macho64_init(void)
2250 fmt = macho64_fmt;
2251 macho_init();
2253 /* add special symbol for ..gotpcrel */
2254 macho_gotpcrel_sect = seg_alloc() + 1;
2255 define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2258 static const struct dfmt macho64_df_dwarf = {
2259 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2260 "dwarf",
2261 macho_dbg_init,
2262 macho_dbg_linenum,
2263 null_debug_deflabel,
2264 null_debug_directive,
2265 null_debug_typevalue,
2266 macho_dbg_output,
2267 macho_dbg_cleanup,
2268 NULL /*pragma list*/
2271 static const struct dfmt * const macho64_df_arr[2] =
2272 { &macho64_df_dwarf, NULL };
2274 const struct ofmt of_macho64 = {
2275 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2276 "macho64",
2279 macho64_df_arr,
2280 &macho64_df_dwarf,
2281 macho_stdmac,
2282 macho64_init,
2283 nasm_do_legacy_output,
2284 macho_output,
2285 macho_symdef,
2286 macho_section,
2287 macho_sectalign,
2288 macho_segbase,
2289 null_directive,
2290 macho_filename,
2291 macho_cleanup,
2292 macho_pragma_list,
2294 #endif
2296 #endif
2299 * Local Variables:
2300 * mode:c
2301 * c-basic-offset:4
2302 * End:
2304 * end of file */