Merge remote-tracking branch 'origin/nasm-2.13.xx'
[nasm.git] / output / outmacho.c
blob4aefe3f3717db792154d7926188f985a32effb46
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 "ilog2.h"
49 #include "labels.h"
50 #include "error.h"
51 #include "saa.h"
52 #include "raa.h"
53 #include "rbtree.h"
54 #include "outform.h"
55 #include "outlib.h"
56 #include "ver.h"
57 #include "dwarf.h"
59 #if defined(OF_MACHO) || defined(OF_MACHO64)
61 /* Mach-O in-file header structure sizes */
62 #define MACHO_HEADER_SIZE 28
63 #define MACHO_SEGCMD_SIZE 56
64 #define MACHO_SECTCMD_SIZE 68
65 #define MACHO_SYMCMD_SIZE 24
66 #define MACHO_NLIST_SIZE 12
67 #define MACHO_RELINFO_SIZE 8
69 #define MACHO_HEADER64_SIZE 32
70 #define MACHO_SEGCMD64_SIZE 72
71 #define MACHO_SECTCMD64_SIZE 80
72 #define MACHO_NLIST64_SIZE 16
74 /* Mach-O file header values */
75 #define MH_MAGIC 0xfeedface
76 #define MH_MAGIC_64 0xfeedfacf
77 #define CPU_TYPE_I386 7 /* x86 platform */
78 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
79 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
80 #define MH_OBJECT 0x1 /* object file */
82 /* Mach-O header flags */
83 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
85 /* Mach-O load commands */
86 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
87 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
88 #define LC_SYMTAB 0x2 /* symbol table load command */
90 /* Mach-O relocations numbers */
92 /* Generic relocs, used by i386 Mach-O */
93 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
94 #define GENERIC_RELOC_TLV 5 /* Thread local */
96 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
97 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
98 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
99 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
100 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
101 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
102 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
103 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
104 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
105 #define X86_64_RELOC_TLV 9 /* Thread local */
107 /* Mach-O VM permission constants */
108 #define VM_PROT_NONE (0x00)
109 #define VM_PROT_READ (0x01)
110 #define VM_PROT_WRITE (0x02)
111 #define VM_PROT_EXECUTE (0x04)
113 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
114 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
116 /* Our internal relocation types */
117 enum reltype {
118 RL_ABS, /* Absolute relocation */
119 RL_REL, /* Relative relocation */
120 RL_TLV, /* Thread local */
121 RL_BRANCH, /* Relative direct branch */
122 RL_SUB, /* X86_64_RELOC_SUBTRACT */
123 RL_GOT, /* X86_64_RELOC_GOT */
124 RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
126 #define RL_MAX_32 RL_TLV
127 #define RL_MAX_64 RL_GOTLOAD
129 struct macho_fmt {
130 uint32_t ptrsize; /* Pointer size in bytes */
131 uint32_t mh_magic; /* Which magic number to use */
132 uint32_t cpu_type; /* Which CPU type */
133 uint32_t lc_segment; /* Which segment load command */
134 uint32_t header_size; /* Header size */
135 uint32_t segcmd_size; /* Segment command size */
136 uint32_t sectcmd_size; /* Section command size */
137 uint32_t nlist_size; /* Nlist (symbol) size */
138 enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
139 uint32_t reloc_abs; /* Absolute relocation type */
140 uint32_t reloc_rel; /* Relative relocation type */
141 uint32_t reloc_tlv; /* Thread local relocation type */
142 bool forcesym; /* Always use "external" (symbol-relative) relocations */
145 static struct macho_fmt fmt;
147 static void fwriteptr(uint64_t data, FILE * fp)
149 fwriteaddr(data, fmt.ptrsize, fp);
152 struct section {
153 /* nasm internal data */
154 struct section *next;
155 struct SAA *data;
156 int32_t index;
157 int32_t fileindex;
158 struct reloc *relocs;
159 struct rbtree *syms[2]; /* All/global symbols symbols in section */
160 int align;
161 bool by_name; /* This section was specified by full MachO name */
163 /* data that goes into the file */
164 char sectname[16]; /* what this section is called */
165 char segname[16]; /* segment this section will be in */
166 uint64_t addr; /* in-memory address (subject to alignment) */
167 uint64_t size; /* in-memory and -file size */
168 uint64_t offset; /* in-file offset */
169 uint32_t pad; /* padding bytes before section */
170 uint32_t nreloc; /* relocation entry count */
171 uint32_t flags; /* type and attributes (masked) */
172 uint32_t extreloc; /* external relocations */
175 #define SECTION_TYPE 0x000000ff /* section type mask */
177 #define S_REGULAR (0x0) /* standard section */
178 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
180 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
181 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
182 machine instructions */
183 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
184 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
185 #define S_ATTR_DEBUG 0x02000000
186 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
187 #define S_ATTR_LIVE_SUPPORT 0x08000000
188 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
189 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
190 #define S_ATTR_NO_TOC 0x40000000
191 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
192 #define S_ATTR_DEBUG 0x02000000 /* debug section */
194 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
196 /* fake section for absolute symbols, *not* part of the section linked list */
197 static struct section absolute_sect;
199 struct reloc {
200 /* nasm internal data */
201 struct reloc *next;
203 /* data that goes into the file */
204 int32_t addr; /* op's offset in section */
205 uint32_t snum:24, /* contains symbol index if
206 ** ext otherwise in-file
207 ** section number */
208 pcrel:1, /* relative relocation */
209 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
210 ext:1, /* external symbol referenced */
211 type:4; /* reloc type */
214 #define R_ABS 0 /* absolute relocation */
215 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
216 ** highest bit == 1 */
218 struct symbol {
219 /* nasm internal data */
220 struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
221 symbol offset. */
222 struct symbol *next; /* next symbol in the list */
223 char *name; /* name of this symbol */
224 int32_t initial_snum; /* symbol number used above in reloc */
225 int32_t snum; /* true snum for reloc */
227 /* data that goes into the file */
228 uint32_t strx; /* string table index */
229 uint8_t type; /* symbol type */
230 uint8_t sect; /* NO_SECT or section number */
231 uint16_t desc; /* for stab debugging, 0 for us */
234 /* symbol type bits */
235 #define N_EXT 0x01 /* global or external symbol */
237 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
238 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
239 #define N_SECT 0xe /* defined symbol, n_sect holds
240 ** section number */
242 #define N_TYPE 0x0e /* type bit mask */
244 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
246 /* special section number values */
247 #define NO_SECT 0 /* no section, invalid */
248 #define MAX_SECT 255 /* maximum number of sections */
250 static struct section *sects, **sectstail, **sectstab;
251 static struct symbol *syms, **symstail;
252 static uint32_t nsyms;
254 /* These variables are set by macho_layout_symbols() to organize
255 the symbol table and string table in order the dynamic linker
256 expects. They are then used in macho_write() to put out the
257 symbols and strings in that order.
259 The order of the symbol table is:
260 local symbols
261 defined external symbols (sorted by name)
262 undefined external symbols (sorted by name)
264 The order of the string table is:
265 strings for external symbols
266 strings for local symbols
268 static uint32_t ilocalsym = 0;
269 static uint32_t iextdefsym = 0;
270 static uint32_t iundefsym = 0;
271 static uint32_t nlocalsym;
272 static uint32_t nextdefsym;
273 static uint32_t nundefsym;
274 static struct symbol **extdefsyms = NULL;
275 static struct symbol **undefsyms = NULL;
277 static struct RAA *extsyms;
278 static struct SAA *strs;
279 static uint32_t strslen;
281 /* Global file information. This should be cleaned up into either
282 a structure or as function arguments. */
283 static uint32_t head_ncmds = 0;
284 static uint32_t head_sizeofcmds = 0;
285 static uint32_t head_flags = 0;
286 static uint64_t seg_filesize = 0;
287 static uint64_t seg_vmsize = 0;
288 static uint32_t seg_nsects = 0;
289 static uint64_t rel_padcnt = 0;
292 * Functions for handling fixed-length zero-padded string
293 * fields, that may or may not be null-terminated.
296 /* Copy a string into a zero-padded fixed-length field */
297 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
299 /* Compare a fixed-length field with a string */
300 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
302 #define alignint32_t(x) \
303 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
305 #define alignint64_t(x) \
306 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
308 #define alignptr(x) \
309 ALIGN(x, fmt.ptrsize) /* align x to output format width */
311 static struct section *get_section_by_name(const char *segname,
312 const char *sectname)
314 struct section *s;
316 for (s = sects; s != NULL; s = s->next)
317 if (!xstrncmp(s->segname, segname) && !xstrncmp(s->sectname, sectname))
318 break;
320 return s;
323 static struct section *get_section_by_index(const int32_t index)
325 struct section *s;
327 for (s = sects; s != NULL; s = s->next)
328 if (index == s->index)
329 break;
331 return s;
334 struct dir_list {
335 struct dir_list *next;
336 struct dir_list *last;
337 const char *dir_name;
338 uint32_t dir;
341 struct file_list {
342 struct file_list *next;
343 struct file_list *last;
344 const char *file_name;
345 uint32_t file;
346 struct dir_list *dir;
349 struct dw_sect_list {
350 struct SAA *psaa;
351 int32_t section;
352 uint32_t line;
353 uint64_t offset;
354 uint32_t file;
355 struct dw_sect_list *next;
356 struct dw_sect_list *last;
359 struct section_info {
360 uint64_t size;
361 int32_t secto;
364 #define DW_LN_BASE (-5)
365 #define DW_LN_RANGE 14
366 #define DW_OPCODE_BASE 13
367 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
368 #define DW_MAX_SP_OPCODE 256
370 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
371 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
372 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
373 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
374 static bool dbg_immcall = false;
375 static const char *module_name = NULL;
378 * Special section numbers which are used to define Mach-O special
379 * symbols, which can be used with WRT to provide PIC relocation
380 * types.
382 static int32_t macho_tlvp_sect;
383 static int32_t macho_gotpcrel_sect;
385 static void macho_init(void)
387 sects = NULL;
388 sectstail = &sects;
390 /* Fake section for absolute symbols */
391 absolute_sect.index = NO_SEG;
393 syms = NULL;
394 symstail = &syms;
395 nsyms = 0;
396 nlocalsym = 0;
397 nextdefsym = 0;
398 nundefsym = 0;
400 extsyms = raa_init();
401 strs = saa_init(1L);
403 /* string table starts with a zero byte so index 0 is an empty string */
404 saa_wbytes(strs, zero_buffer, 1);
405 strslen = 1;
407 /* add special symbol for TLVP */
408 macho_tlvp_sect = seg_alloc() + 1;
409 define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
413 static void sect_write(struct section *sect,
414 const uint8_t *data, uint32_t len)
416 saa_wbytes(sect->data, data, len);
417 sect->size += len;
421 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
423 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
424 bool global, bool exact)
426 struct rbtree *srb;
428 srb = rb_search(s->syms[global], offset);
430 if (!srb || (exact && srb->key != offset)) {
431 nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
432 " for this reference",
433 global ? " global" : "",
434 s == &absolute_sect ? " absolute " : "");
435 return NULL;
438 return container_of(srb - global, struct symbol, symv);
441 static int64_t add_reloc(struct section *sect, int32_t section,
442 int64_t offset,
443 enum reltype reltype, int bytes)
445 struct reloc *r;
446 struct section *s;
447 int32_t fi;
448 int64_t adjust;
450 /* Double check this is a valid relocation type for this platform */
451 nasm_assert(reltype <= fmt.maxreltype);
453 /* the current end of the section will be the symbol's address for
454 ** now, might have to be fixed by macho_fixup_relocs() later on. make
455 ** sure we don't make the symbol scattered by setting the highest
456 ** bit by accident */
457 r = nasm_malloc(sizeof(struct reloc));
458 r->addr = sect->size & ~R_SCATTERED;
459 r->ext = 1;
460 adjust = bytes;
462 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
463 r->length = ilog2_32(bytes);
465 /* set default relocation values */
466 r->type = fmt.reloc_abs;
467 r->pcrel = 0;
468 r->snum = R_ABS;
470 s = NULL;
471 if (section != NO_SEG)
472 s = get_section_by_index(section);
473 fi = s ? s->fileindex : NO_SECT;
475 /* absolute relocation */
476 switch (reltype) {
477 case RL_ABS:
478 if (section == NO_SEG) {
479 /* absolute (can this even happen?) */
480 r->ext = 0;
481 r->snum = NO_SECT;
482 } else if (fi == NO_SECT) {
483 /* external */
484 r->snum = raa_read(extsyms, section);
485 } else {
486 /* local */
487 r->ext = 0;
488 r->snum = fi;
489 adjust = -sect->size;
491 break;
493 case RL_REL:
494 case RL_BRANCH:
495 r->type = fmt.reloc_rel;
496 r->pcrel = 1;
497 if (section == NO_SEG) {
498 /* absolute - seems to produce garbage no matter what */
499 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
500 "references to absolute addresses");
501 goto bail;
502 #if 0
503 /* This "seems" to be how it ought to work... */
505 struct symbol *sym = macho_find_sym(&absolute_sect, offset,
506 false, false);
507 if (!sym)
508 goto bail;
510 sect->extreloc = 1;
511 r->snum = NO_SECT;
512 adjust = -sect->size;
513 #endif
514 } else if (fi == NO_SECT) {
515 /* external */
516 sect->extreloc = 1;
517 r->snum = raa_read(extsyms, section);
518 if (reltype == RL_BRANCH)
519 r->type = X86_64_RELOC_BRANCH;
520 else if (r->type == GENERIC_RELOC_VANILLA)
521 adjust = -sect->size;
522 } else {
523 /* local */
524 r->ext = 0;
525 r->snum = fi;
526 adjust = -sect->size;
528 break;
530 case RL_SUB:
531 r->pcrel = 0;
532 r->type = X86_64_RELOC_SUBTRACTOR;
533 break;
535 case RL_GOT:
536 r->type = X86_64_RELOC_GOT;
537 goto needsym;
539 case RL_GOTLOAD:
540 r->type = X86_64_RELOC_GOT_LOAD;
541 goto needsym;
543 case RL_TLV:
544 r->type = fmt.reloc_tlv;
545 goto needsym;
547 needsym:
548 r->pcrel = 1;
549 if (section == NO_SEG) {
550 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
551 } else if (fi == NO_SECT) {
552 /* external */
553 r->snum = raa_read(extsyms, section);
554 } else {
555 /* internal - does it really need to be global? */
556 struct symbol *sym = macho_find_sym(s, offset, true,
557 reltype != RL_TLV);
558 if (!sym)
559 goto bail;
561 r->snum = sym->initial_snum;
563 break;
566 /* For 64-bit Mach-O, force a symbol reference if at all possible */
567 if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
568 struct symbol *sym = macho_find_sym(s, offset, false, false);
569 if (sym) {
570 adjust = bytes - sym->symv[0].key;
571 r->snum = sym->initial_snum;
572 r->ext = 1;
576 /* NeXT as puts relocs in reversed order (address-wise) into the
577 ** files, so we do the same, doesn't seem to make much of a
578 ** difference either way */
579 r->next = sect->relocs;
580 sect->relocs = r;
581 if (r->ext)
582 sect->extreloc = 1;
583 ++sect->nreloc;
585 return adjust;
587 bail:
588 nasm_free(r);
589 return 0;
592 static void macho_output(int32_t secto, const void *data,
593 enum out_type type, uint64_t size,
594 int32_t section, int32_t wrt)
596 struct section *s;
597 int64_t addr, offset;
598 uint8_t mydata[16], *p;
599 bool is_bss;
600 enum reltype reltype;
602 if (secto == NO_SEG) {
603 if (type != OUT_RESERVE)
604 nasm_error(ERR_NONFATAL, "attempt to assemble code in "
605 "[ABSOLUTE] space");
606 return;
609 s = get_section_by_index(secto);
611 if (s == NULL) {
612 nasm_error(ERR_WARNING, "attempt to assemble code in"
613 " section %d: defaulting to `.text'", secto);
614 s = get_section_by_name("__TEXT", "__text");
616 /* should never happen */
617 if (s == NULL)
618 nasm_panic(0, "text section not found");
621 /* debug code generation only for sections tagged with
622 * instruction attribute */
623 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
625 struct section_info sinfo;
626 sinfo.size = s->size;
627 sinfo.secto = secto;
628 dfmt->debug_output(0, &sinfo);
631 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
633 if (is_bss && type != OUT_RESERVE) {
634 nasm_error(ERR_WARNING, "attempt to initialize memory in "
635 "BSS section: ignored");
636 s->size += realsize(type, size);
637 return;
640 memset(mydata, 0, sizeof(mydata));
642 switch (type) {
643 case OUT_RESERVE:
644 if (!is_bss) {
645 nasm_error(ERR_WARNING, "uninitialized space declared in"
646 " %s,%s section: zeroing", s->segname, s->sectname);
648 sect_write(s, NULL, size);
649 } else
650 s->size += size;
652 break;
654 case OUT_RAWDATA:
655 if (section != NO_SEG)
656 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
658 sect_write(s, data, size);
659 break;
661 case OUT_ADDRESS:
663 int asize = abs((int)size);
665 addr = *(int64_t *)data;
666 if (section != NO_SEG) {
667 if (section % 2) {
668 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
669 " section base references");
670 } else if (wrt == NO_SEG) {
671 if (fmt.ptrsize == 8 && asize != 8) {
672 nasm_error(ERR_NONFATAL,
673 "Mach-O 64-bit format does not support"
674 " 32-bit absolute addresses");
675 } else {
676 add_reloc(s, section, addr, RL_ABS, asize);
678 } else {
679 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
680 " this use of WRT");
684 p = mydata;
685 WRITEADDR(p, addr, asize);
686 sect_write(s, mydata, asize);
687 break;
690 case OUT_REL2ADR:
691 nasm_assert(section != secto);
693 p = mydata;
694 offset = *(int64_t *)data;
695 addr = offset - size;
697 if (section != NO_SEG && section % 2) {
698 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
699 " section base references");
700 } else if (fmt.ptrsize == 8) {
701 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
702 " Macho-O relocation [2]");
703 } else if (wrt != NO_SEG) {
704 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
705 " this use of WRT");
706 wrt = NO_SEG; /* we can at least _try_ to continue */
707 } else {
708 addr += add_reloc(s, section, addr+size, RL_REL, 2);
711 WRITESHORT(p, addr);
712 sect_write(s, mydata, 2);
713 break;
715 case OUT_REL4ADR:
716 nasm_assert(section != secto);
718 p = mydata;
719 offset = *(int64_t *)data;
720 addr = offset - size;
721 reltype = RL_REL;
723 if (section != NO_SEG && section % 2) {
724 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
725 " section base references");
726 } else if (wrt == NO_SEG) {
727 if (fmt.ptrsize == 8 &&
728 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
729 uint8_t opcode[2];
731 opcode[0] = opcode[1] = 0;
733 /* HACK: Retrieve instruction opcode */
734 if (likely(s->data->datalen >= 2)) {
735 saa_fread(s->data, s->data->datalen-2, opcode, 2);
736 } else if (s->data->datalen == 1) {
737 saa_fread(s->data, 0, opcode+1, 1);
740 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
741 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
742 /* Direct call, jmp, or jcc */
743 reltype = RL_BRANCH;
746 } else if (wrt == macho_gotpcrel_sect) {
747 reltype = RL_GOT;
749 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
750 s->data->datalen >= 3) {
751 uint8_t gotload[3];
753 /* HACK: Retrieve instruction opcode */
754 saa_fread(s->data, s->data->datalen-3, gotload, 3);
755 if ((gotload[0] & 0xf8) == 0x48 &&
756 gotload[1] == 0x8b &&
757 (gotload[2] & 0307) == 0005) {
758 /* movq <reg>,[rel sym wrt ..gotpcrel] */
759 reltype = RL_GOTLOAD;
762 } else if (wrt == macho_tlvp_sect) {
763 reltype = RL_TLV;
764 } else {
765 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
766 " this use of WRT");
767 /* continue with RL_REL */
770 addr += add_reloc(s, section, offset, reltype, 4);
771 WRITELONG(p, addr);
772 sect_write(s, mydata, 4);
773 break;
775 default:
776 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
777 break;
781 /* Translation table from traditional Unix section names to Mach-O */
782 static const struct sectmap {
783 const char *nasmsect;
784 const char *segname;
785 const char *sectname;
786 const uint32_t flags;
787 } sectmap[] = {
788 {".text", "__TEXT", "__text",
789 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
790 {".data", "__DATA", "__data", S_REGULAR},
791 {".rodata", "__DATA", "__const", S_REGULAR},
792 {".bss", "__DATA", "__bss", S_ZEROFILL},
793 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
794 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
795 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
796 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
797 {NULL, NULL, NULL, 0}
800 #define NO_TYPE S_NASM_TYPE_MASK
802 /* Section type or attribute directives */
803 static const struct sect_attribs {
804 const char *name;
805 uint32_t flags;
806 } sect_attribs[] = {
807 { "data", S_REGULAR },
808 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
809 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
810 { "bss", S_ZEROFILL },
811 { "zerofill", S_ZEROFILL },
812 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
813 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
814 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
815 { "debug", NO_TYPE|S_ATTR_DEBUG },
816 { NULL, 0 }
819 static int32_t macho_section(char *name, int pass, int *bits)
821 char *sectionAttributes;
822 const struct sectmap *sm;
823 struct section *s;
824 const char *section, *segment;
825 uint32_t flags;
826 const struct sect_attribs *sa;
827 char *currentAttribute;
828 char *comma;
830 bool new_seg;
832 (void)pass;
834 /* Default to the appropriate number of bits. */
835 if (!name) {
836 *bits = fmt.ptrsize << 3;
837 name = ".text";
838 sectionAttributes = NULL;
839 } else {
840 sectionAttributes = name;
841 name = nasm_strsep(&sectionAttributes, " \t");
844 section = segment = NULL;
845 flags = 0;
847 comma = strchr(name, ',');
848 if (comma) {
849 int len;
851 *comma = '\0';
852 segment = name;
853 section = comma+1;
855 len = strlen(segment);
856 if (len == 0) {
857 nasm_error(ERR_NONFATAL, "empty segment name\n");
858 } else if (len > 16) {
859 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
862 len = strlen(section);
863 if (len == 0) {
864 nasm_error(ERR_NONFATAL, "empty section name\n");
865 } else if (len > 16) {
866 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
869 if (!strcmp(section, "__text")) {
870 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
871 S_ATTR_PURE_INSTRUCTIONS;
872 } else if (!strcmp(section, "__bss")) {
873 flags = S_ZEROFILL;
874 } else {
875 flags = S_REGULAR;
877 } else {
878 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
879 /* make lookup into section name translation table */
880 if (!strcmp(name, sm->nasmsect)) {
881 segment = sm->segname;
882 section = sm->sectname;
883 flags = sm->flags;
884 goto found;
887 nasm_error(ERR_NONFATAL, "unknown section name\n");
888 return NO_SEG;
891 found:
892 /* try to find section with that name */
893 s = get_section_by_name(segment, section);
895 /* create it if it doesn't exist yet */
896 if (!s) {
897 new_seg = true;
899 s = *sectstail = nasm_zalloc(sizeof(struct section));
900 sectstail = &s->next;
902 s->data = saa_init(1L);
903 s->index = seg_alloc();
904 s->fileindex = ++seg_nsects;
905 s->align = -1;
906 s->pad = -1;
907 s->offset = -1;
908 s->by_name = false;
910 xstrncpy(s->segname, segment);
911 xstrncpy(s->sectname, section);
912 s->size = 0;
913 s->nreloc = 0;
914 s->flags = flags;
915 } else {
916 new_seg = false;
919 if (comma)
920 *comma = ','; /* Restore comma */
922 s->by_name = s->by_name || comma; /* Was specified by name */
924 flags = NO_TYPE;
926 while (sectionAttributes &&
927 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
928 if (!*currentAttribute)
929 continue;
931 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
932 char *end;
933 int newAlignment, value;
935 value = strtoul(currentAttribute + 6, (char**)&end, 0);
936 newAlignment = alignlog2_32(value);
938 if (0 != *end) {
939 nasm_error(ERR_NONFATAL,
940 "unknown or missing alignment value \"%s\" "
941 "specified for section \"%s\"",
942 currentAttribute + 6,
943 name);
944 } else if (0 > newAlignment) {
945 nasm_error(ERR_NONFATAL,
946 "alignment of %d (for section \"%s\") is not "
947 "a power of two",
948 value,
949 name);
952 if (s->align < newAlignment)
953 s->align = newAlignment;
954 } else {
955 for (sa = sect_attribs; sa->name; sa++) {
956 if (!nasm_stricmp(sa->name, currentAttribute)) {
957 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
958 flags = (flags & ~S_NASM_TYPE_MASK)
959 | (sa->flags & S_NASM_TYPE_MASK);
961 flags |= sa->flags & ~S_NASM_TYPE_MASK;
962 break;
966 if (!sa->name) {
967 nasm_error(ERR_NONFATAL,
968 "unknown section attribute %s for section %s",
969 currentAttribute, name);
974 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
975 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
976 nasm_error(ERR_NONFATAL,
977 "inconsistent section attributes for section %s\n",
978 name);
979 } else {
980 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
982 } else {
983 s->flags |= flags & ~S_NASM_TYPE_MASK;
986 return s->index;
989 static void macho_symdef(char *name, int32_t section, int64_t offset,
990 int is_global, char *special)
992 struct symbol *sym;
993 struct section *s;
995 if (special) {
996 nasm_error(ERR_NONFATAL, "The Mach-O output format does "
997 "not support any special symbol types");
998 return;
1001 if (is_global == 3) {
1002 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1003 "(yet) support forward reference fixups.");
1004 return;
1007 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1009 * This is a NASM special symbol. We never allow it into
1010 * the Macho-O symbol table, even if it's a valid one. If it
1011 * _isn't_ a valid one, we should barf immediately.
1013 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1014 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1015 return;
1018 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1019 sym->next = NULL;
1020 symstail = &sym->next;
1022 sym->name = name;
1023 sym->strx = strslen;
1024 sym->type = 0;
1025 sym->desc = 0;
1026 sym->symv[0].key = offset;
1027 sym->symv[1].key = offset;
1028 sym->initial_snum = -1;
1030 /* external and common symbols get N_EXT */
1031 if (is_global != 0) {
1032 sym->type |= N_EXT;
1035 if (section == NO_SEG) {
1036 /* symbols in no section get absolute */
1037 sym->type |= N_ABS;
1038 sym->sect = NO_SECT;
1040 s = &absolute_sect;
1041 } else {
1042 s = get_section_by_index(section);
1044 sym->type |= N_SECT;
1046 /* get the in-file index of the section the symbol was defined in */
1047 sym->sect = s ? s->fileindex : NO_SECT;
1049 /* track the initially allocated symbol number for use in future fix-ups */
1050 sym->initial_snum = nsyms;
1052 if (!s) {
1053 /* remember symbol number of references to external
1054 ** symbols, this works because every external symbol gets
1055 ** its own section number allocated internally by nasm and
1056 ** can so be used as a key */
1057 extsyms = raa_write(extsyms, section, nsyms);
1059 switch (is_global) {
1060 case 1:
1061 case 2:
1062 /* there isn't actually a difference between global
1063 ** and common symbols, both even have their size in
1064 ** sym->symv[0].key */
1065 sym->type = N_EXT;
1066 break;
1068 default:
1069 /* give an error on unfound section if it's not an
1070 ** external or common symbol (assemble_file() does a
1071 ** seg_alloc() on every call for them) */
1072 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1073 break;
1078 if (s) {
1079 s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1080 if (is_global)
1081 s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1084 ++nsyms;
1087 static void macho_sectalign(int32_t seg, unsigned int value)
1089 struct section *s;
1090 int align;
1092 nasm_assert(!(seg & 1));
1094 s = get_section_by_index(seg);
1096 if (!s || !is_power2(value))
1097 return;
1099 align = alignlog2_32(value);
1100 if (s->align < align)
1101 s->align = align;
1104 static int32_t macho_segbase(int32_t section)
1106 return section;
1109 static void macho_filename(char *inname, char *outname)
1111 standard_extension(inname, outname, ".o");
1112 module_name = inname;
1115 extern macros_t macho_stdmac[];
1117 /* Comparison function for qsort symbol layout. */
1118 static int layout_compare (const struct symbol **s1,
1119 const struct symbol **s2)
1121 return (strcmp ((*s1)->name, (*s2)->name));
1124 /* The native assembler does a few things in a similar function
1126 * Remove temporary labels
1127 * Sort symbols according to local, external, undefined (by name)
1128 * Order the string table
1130 We do not remove temporary labels right now.
1132 numsyms is the total number of symbols we have. strtabsize is the
1133 number entries in the string table. */
1135 static void macho_layout_symbols (uint32_t *numsyms,
1136 uint32_t *strtabsize)
1138 struct symbol *sym, **symp;
1139 uint32_t i,j;
1141 *numsyms = 0;
1142 *strtabsize = sizeof (char);
1144 symp = &syms;
1146 while ((sym = *symp)) {
1147 /* Undefined symbols are now external. */
1148 if (sym->type == N_UNDF)
1149 sym->type |= N_EXT;
1151 if ((sym->type & N_EXT) == 0) {
1152 sym->snum = *numsyms;
1153 *numsyms = *numsyms + 1;
1154 nlocalsym++;
1156 else {
1157 if ((sym->type & N_TYPE) != N_UNDF) {
1158 nextdefsym++;
1159 } else {
1160 nundefsym++;
1163 /* If we handle debug info we'll want
1164 to check for it here instead of just
1165 adding the symbol to the string table. */
1166 sym->strx = *strtabsize;
1167 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1168 *strtabsize += strlen(sym->name) + 1;
1170 symp = &(sym->next);
1173 /* Next, sort the symbols. Most of this code is a direct translation from
1174 the Apple cctools symbol layout. We need to keep compatibility with that. */
1175 /* Set the indexes for symbol groups into the symbol table */
1176 ilocalsym = 0;
1177 iextdefsym = nlocalsym;
1178 iundefsym = nlocalsym + nextdefsym;
1180 /* allocate arrays for sorting externals by name */
1181 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1182 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1184 i = 0;
1185 j = 0;
1187 symp = &syms;
1189 while ((sym = *symp)) {
1191 if((sym->type & N_EXT) == 0) {
1192 sym->strx = *strtabsize;
1193 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1194 *strtabsize += strlen(sym->name) + 1;
1196 else {
1197 if ((sym->type & N_TYPE) != N_UNDF) {
1198 extdefsyms[i++] = sym;
1199 } else {
1200 undefsyms[j++] = sym;
1203 symp = &(sym->next);
1206 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1207 (int (*)(const void *, const void *))layout_compare);
1208 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1209 (int (*)(const void *, const void *))layout_compare);
1211 for(i = 0; i < nextdefsym; i++) {
1212 extdefsyms[i]->snum = *numsyms;
1213 *numsyms += 1;
1215 for(j = 0; j < nundefsym; j++) {
1216 undefsyms[j]->snum = *numsyms;
1217 *numsyms += 1;
1221 /* Calculate some values we'll need for writing later. */
1223 static void macho_calculate_sizes (void)
1225 struct section *s;
1226 int fi;
1228 /* count sections and calculate in-memory and in-file offsets */
1229 for (s = sects; s != NULL; s = s->next) {
1230 uint64_t newaddr;
1232 /* recalculate segment address based on alignment and vm size */
1233 s->addr = seg_vmsize;
1235 /* we need section alignment to calculate final section address */
1236 if (s->align == -1)
1237 s->align = DEFAULT_SECTION_ALIGNMENT;
1239 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1240 s->addr = newaddr;
1242 seg_vmsize = newaddr + s->size;
1244 /* zerofill sections aren't actually written to the file */
1245 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1247 * LLVM/Xcode as always aligns the section data to 4
1248 * bytes; there is a comment in the LLVM source code that
1249 * perhaps aligning to pointer size would be better.
1251 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1252 s->offset = seg_filesize + s->pad;
1253 seg_filesize += s->size + s->pad;
1255 /* filesize and vmsize needs to be aligned */
1256 seg_vmsize += s->pad;
1260 /* calculate size of all headers, load commands and sections to
1261 ** get a pointer to the start of all the raw data */
1262 if (seg_nsects > 0) {
1263 ++head_ncmds;
1264 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1267 if (nsyms > 0) {
1268 ++head_ncmds;
1269 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1272 if (seg_nsects > MAX_SECT) {
1273 nasm_fatal(0, "MachO output is limited to %d sections\n",
1274 MAX_SECT);
1277 /* Create a table of sections by file index to avoid linear search */
1278 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1279 sectstab[NO_SECT] = &absolute_sect;
1280 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1281 sectstab[fi] = s;
1284 /* Write out the header information for the file. */
1286 static void macho_write_header (void)
1288 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1289 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1290 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1291 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1292 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1293 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1294 fwriteint32_t(head_flags, ofile); /* flags, if any */
1295 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1298 /* Write out the segment load command at offset. */
1300 static uint32_t macho_write_segment (uint64_t offset)
1302 uint64_t rel_base = alignptr(offset + seg_filesize);
1303 uint32_t s_reloff = 0;
1304 struct section *s;
1306 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1308 /* size of load command including section load commands */
1309 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1310 ofile);
1312 /* in an MH_OBJECT file all sections are in one unnamed (name
1313 ** all zeros) segment */
1314 fwritezero(16, ofile);
1315 fwriteptr(0, ofile); /* in-memory offset */
1316 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1317 fwriteptr(offset, ofile); /* in-file offset to data */
1318 fwriteptr(seg_filesize, ofile); /* in-file size */
1319 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1320 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1321 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1322 fwriteint32_t(0, ofile); /* no flags */
1324 /* emit section headers */
1325 for (s = sects; s != NULL; s = s->next) {
1326 if (s->nreloc) {
1327 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1328 s->flags |= S_ATTR_LOC_RELOC;
1329 if (s->extreloc)
1330 s->flags |= S_ATTR_EXT_RELOC;
1331 } else if (!xstrncmp(s->segname, "__DATA") &&
1332 !xstrncmp(s->sectname, "__const") &&
1333 !s->by_name &&
1334 !get_section_by_name("__TEXT", "__const")) {
1336 * The MachO equivalent to .rodata can be either
1337 * __DATA,__const or __TEXT,__const; the latter only if
1338 * there are no relocations. However, when mixed it is
1339 * better to specify the segments explicitly.
1341 xstrncpy(s->segname, "__TEXT");
1344 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1345 nasm_write(s->segname, sizeof(s->segname), ofile);
1346 fwriteptr(s->addr, ofile);
1347 fwriteptr(s->size, ofile);
1349 /* dummy data for zerofill sections or proper values */
1350 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1351 nasm_assert(s->pad != (uint32_t)-1);
1352 offset += s->pad;
1353 fwriteint32_t(offset, ofile);
1354 offset += s->size;
1355 /* Write out section alignment, as a power of two.
1356 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1357 fwriteint32_t(s->align, ofile);
1358 /* To be compatible with cctools as we emit
1359 a zero reloff if we have no relocations. */
1360 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1361 fwriteint32_t(s->nreloc, ofile);
1363 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1364 } else {
1365 fwriteint32_t(0, ofile);
1366 fwriteint32_t(s->align, ofile);
1367 fwriteint32_t(0, ofile);
1368 fwriteint32_t(0, ofile);
1371 fwriteint32_t(s->flags, ofile); /* flags */
1372 fwriteint32_t(0, ofile); /* reserved */
1373 fwriteptr(0, ofile); /* reserved */
1376 rel_padcnt = rel_base - offset;
1377 offset = rel_base + s_reloff;
1379 return offset;
1382 /* For a given chain of relocs r, write out the entire relocation
1383 chain to the object file. */
1385 static void macho_write_relocs (struct reloc *r)
1387 while (r) {
1388 uint32_t word2;
1390 fwriteint32_t(r->addr, ofile); /* reloc offset */
1392 word2 = r->snum;
1393 word2 |= r->pcrel << 24;
1394 word2 |= r->length << 25;
1395 word2 |= r->ext << 27;
1396 word2 |= r->type << 28;
1397 fwriteint32_t(word2, ofile); /* reloc data */
1398 r = r->next;
1402 /* Write out the section data. */
1403 static void macho_write_section (void)
1405 struct section *s;
1406 struct reloc *r;
1407 uint8_t *p;
1408 int32_t len;
1409 int64_t l;
1410 union offset {
1411 uint64_t val;
1412 uint8_t buf[8];
1413 } blk;
1415 for (s = sects; s != NULL; s = s->next) {
1416 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1417 continue;
1419 /* Like a.out Mach-O references things in the data or bss
1420 * sections by addresses which are actually relative to the
1421 * start of the _text_ section, in the _file_. See outaout.c
1422 * for more information. */
1423 saa_rewind(s->data);
1424 for (r = s->relocs; r != NULL; r = r->next) {
1425 len = (uint32_t)1 << r->length;
1426 if (len > 4) /* Can this ever be an issue?! */
1427 len = 8;
1428 blk.val = 0;
1429 saa_fread(s->data, r->addr, blk.buf, len);
1431 /* get offset based on relocation type */
1432 #ifdef WORDS_LITTLEENDIAN
1433 l = blk.val;
1434 #else
1435 l = blk.buf[0];
1436 l += ((int64_t)blk.buf[1]) << 8;
1437 l += ((int64_t)blk.buf[2]) << 16;
1438 l += ((int64_t)blk.buf[3]) << 24;
1439 l += ((int64_t)blk.buf[4]) << 32;
1440 l += ((int64_t)blk.buf[5]) << 40;
1441 l += ((int64_t)blk.buf[6]) << 48;
1442 l += ((int64_t)blk.buf[7]) << 56;
1443 #endif
1445 /* If the relocation is internal add to the current section
1446 offset. Otherwise the only value we need is the symbol
1447 offset which we already have. The linker takes care
1448 of the rest of the address. */
1449 if (!r->ext) {
1450 /* generate final address by section address and offset */
1451 nasm_assert(r->snum <= seg_nsects);
1452 l += sectstab[r->snum]->addr;
1453 if (r->pcrel)
1454 l -= s->addr;
1455 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1456 l -= s->addr;
1459 /* write new offset back */
1460 p = blk.buf;
1461 WRITEDLONG(p, l);
1462 saa_fwrite(s->data, r->addr, blk.buf, len);
1465 /* dump the section data to file */
1466 fwritezero(s->pad, ofile);
1467 saa_fpwrite(s->data, ofile);
1470 /* pad last section up to reloc entries on pointer boundary */
1471 fwritezero(rel_padcnt, ofile);
1473 /* emit relocation entries */
1474 for (s = sects; s != NULL; s = s->next)
1475 macho_write_relocs (s->relocs);
1478 /* Write out the symbol table. We should already have sorted this
1479 before now. */
1480 static void macho_write_symtab (void)
1482 struct symbol *sym;
1483 uint64_t i;
1485 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1487 for (sym = syms; sym != NULL; sym = sym->next) {
1488 if ((sym->type & N_EXT) == 0) {
1489 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1490 nasm_write(&sym->type, 1, ofile); /* symbol type */
1491 nasm_write(&sym->sect, 1, ofile); /* section */
1492 fwriteint16_t(sym->desc, ofile); /* description */
1494 /* Fix up the symbol value now that we know the final section
1495 sizes. */
1496 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1497 nasm_assert(sym->sect <= seg_nsects);
1498 sym->symv[0].key += sectstab[sym->sect]->addr;
1501 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1505 for (i = 0; i < nextdefsym; i++) {
1506 sym = extdefsyms[i];
1507 fwriteint32_t(sym->strx, ofile);
1508 nasm_write(&sym->type, 1, ofile); /* symbol type */
1509 nasm_write(&sym->sect, 1, ofile); /* section */
1510 fwriteint16_t(sym->desc, ofile); /* description */
1512 /* Fix up the symbol value now that we know the final section
1513 sizes. */
1514 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1515 nasm_assert(sym->sect <= seg_nsects);
1516 sym->symv[0].key += sectstab[sym->sect]->addr;
1519 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1522 for (i = 0; i < nundefsym; i++) {
1523 sym = undefsyms[i];
1524 fwriteint32_t(sym->strx, ofile);
1525 nasm_write(&sym->type, 1, ofile); /* symbol type */
1526 nasm_write(&sym->sect, 1, ofile); /* section */
1527 fwriteint16_t(sym->desc, ofile); /* description */
1529 /* Fix up the symbol value now that we know the final section
1530 sizes. */
1531 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1532 nasm_assert(sym->sect <= seg_nsects);
1533 sym->symv[0].key += sectstab[sym->sect]->addr;
1536 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1541 /* Fixup the snum in the relocation entries, we should be
1542 doing this only for externally referenced symbols. */
1543 static void macho_fixup_relocs (struct reloc *r)
1545 struct symbol *sym;
1547 while (r != NULL) {
1548 if (r->ext) {
1549 for (sym = syms; sym != NULL; sym = sym->next) {
1550 if (sym->initial_snum == r->snum) {
1551 r->snum = sym->snum;
1552 break;
1556 r = r->next;
1560 /* Write out the object file. */
1562 static void macho_write (void)
1564 uint64_t offset = 0;
1566 /* mach-o object file structure:
1568 ** mach header
1569 ** uint32_t magic
1570 ** int cpu type
1571 ** int cpu subtype
1572 ** uint32_t mach file type
1573 ** uint32_t number of load commands
1574 ** uint32_t size of all load commands
1575 ** (includes section struct size of segment command)
1576 ** uint32_t flags
1578 ** segment command
1579 ** uint32_t command type == LC_SEGMENT[_64]
1580 ** uint32_t size of load command
1581 ** (including section load commands)
1582 ** char[16] segment name
1583 ** pointer in-memory offset
1584 ** pointer in-memory size
1585 ** pointer in-file offset to data area
1586 ** pointer in-file size
1587 ** (in-memory size excluding zerofill sections)
1588 ** int maximum vm protection
1589 ** int initial vm protection
1590 ** uint32_t number of sections
1591 ** uint32_t flags
1593 ** section commands
1594 ** char[16] section name
1595 ** char[16] segment name
1596 ** pointer in-memory offset
1597 ** pointer in-memory size
1598 ** uint32_t in-file offset
1599 ** uint32_t alignment
1600 ** (irrelevant in MH_OBJECT)
1601 ** uint32_t in-file offset of relocation entires
1602 ** uint32_t number of relocations
1603 ** uint32_t flags
1604 ** uint32_t reserved
1605 ** uint32_t reserved
1607 ** symbol table command
1608 ** uint32_t command type == LC_SYMTAB
1609 ** uint32_t size of load command
1610 ** uint32_t symbol table offset
1611 ** uint32_t number of symbol table entries
1612 ** uint32_t string table offset
1613 ** uint32_t string table size
1615 ** raw section data
1617 ** padding to pointer boundary
1619 ** relocation data (struct reloc)
1620 ** int32_t offset
1621 ** uint data (symbolnum, pcrel, length, extern, type)
1623 ** symbol table data (struct nlist)
1624 ** int32_t string table entry number
1625 ** uint8_t type
1626 ** (extern, absolute, defined in section)
1627 ** uint8_t section
1628 ** (0 for global symbols, section number of definition (>= 1, <=
1629 ** 254) for local symbols, size of variable for common symbols
1630 ** [type == extern])
1631 ** int16_t description
1632 ** (for stab debugging format)
1633 ** pointer value (i.e. file offset) of symbol or stab offset
1635 ** string table data
1636 ** list of null-terminated strings
1639 /* Emit the Mach-O header. */
1640 macho_write_header();
1642 offset = fmt.header_size + head_sizeofcmds;
1644 /* emit the segment load command */
1645 if (seg_nsects > 0)
1646 offset = macho_write_segment (offset);
1647 else
1648 nasm_error(ERR_WARNING, "no sections?");
1650 if (nsyms > 0) {
1651 /* write out symbol command */
1652 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1653 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1654 fwriteint32_t(offset, ofile); /* symbol table offset */
1655 fwriteint32_t(nsyms, ofile); /* number of symbol
1656 ** table entries */
1657 offset += nsyms * fmt.nlist_size;
1658 fwriteint32_t(offset, ofile); /* string table offset */
1659 fwriteint32_t(strslen, ofile); /* string table size */
1662 /* emit section data */
1663 if (seg_nsects > 0)
1664 macho_write_section ();
1666 /* emit symbol table if we have symbols */
1667 if (nsyms > 0)
1668 macho_write_symtab ();
1670 /* we don't need to pad here, we are already aligned */
1672 /* emit string table */
1673 saa_fpwrite(strs, ofile);
1675 /* We do quite a bit here, starting with finalizing all of the data
1676 for the object file, writing, and then freeing all of the data from
1677 the file. */
1679 static void macho_cleanup(void)
1681 struct section *s;
1682 struct reloc *r;
1683 struct symbol *sym;
1685 dfmt->cleanup();
1687 /* Sort all symbols. */
1688 macho_layout_symbols (&nsyms, &strslen);
1690 /* Fixup relocation entries */
1691 for (s = sects; s != NULL; s = s->next) {
1692 macho_fixup_relocs (s->relocs);
1695 /* First calculate and finalize needed values. */
1696 macho_calculate_sizes();
1697 macho_write();
1699 /* free up everything */
1700 while (sects->next) {
1701 s = sects;
1702 sects = sects->next;
1704 saa_free(s->data);
1705 while (s->relocs != NULL) {
1706 r = s->relocs;
1707 s->relocs = s->relocs->next;
1708 nasm_free(r);
1711 nasm_free(s);
1714 saa_free(strs);
1715 raa_free(extsyms);
1717 while (syms) {
1718 sym = syms;
1719 syms = syms->next;
1720 nasm_free (sym);
1723 nasm_free(extdefsyms);
1724 nasm_free(undefsyms);
1725 nasm_free(sectstab);
1728 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1730 struct section *s;
1731 int32_t nasm_seg;
1732 int64_t offset;
1734 if (!lookup_label(label, &nasm_seg, &offset)) {
1735 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1736 return false;
1739 s = get_section_by_index(nasm_seg);
1740 if (!s) {
1741 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1742 return false;
1745 s->flags |= flags;
1746 return true;
1750 * Mark a symbol for no dead stripping
1752 static enum directive_result macho_no_dead_strip(const char *labels)
1754 char *s, *p, *ep;
1755 char ec;
1756 enum directive_result rv = DIRR_ERROR;
1757 bool real = passn > 1;
1759 p = s = nasm_strdup(labels);
1760 while (*p) {
1761 ep = nasm_skip_identifier(p);
1762 if (!ep) {
1763 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1764 goto err;
1766 ec = *ep;
1767 if (ec && ec != ',' && !nasm_isspace(ec)) {
1768 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1769 goto err;
1771 *ep = '\0';
1772 if (real) {
1773 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1774 rv = DIRR_ERROR;
1776 *ep = ec;
1777 p = nasm_skip_spaces(ep);
1778 if (*p == ',')
1779 p = nasm_skip_spaces(++p);
1782 rv = DIRR_OK;
1784 err:
1785 nasm_free(s);
1786 return rv;
1790 * Mach-O pragmas
1792 static enum directive_result
1793 macho_pragma(const struct pragma *pragma)
1795 bool real = passn > 1;
1797 switch (pragma->opcode) {
1798 case D_SUBSECTIONS_VIA_SYMBOLS:
1799 if (*pragma->tail)
1800 return DIRR_BADPARAM;
1802 if (real)
1803 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1805 return DIRR_OK;
1807 case D_NO_DEAD_STRIP:
1808 return macho_no_dead_strip(pragma->tail);
1810 default:
1811 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1815 static const struct pragma_facility macho_pragma_list[] = {
1816 { "macho", macho_pragma },
1817 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1820 static void macho_dbg_generate(void)
1822 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1823 size_t saa_len = 0, high_addr = 0, total_len = 0;
1824 struct section *p_section = NULL;
1825 /* calculated at debug_str and referenced at debug_info */
1826 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1828 /* debug section defines */
1830 int bits = 0;
1831 macho_section(".debug_abbrev", 0, &bits);
1832 macho_section(".debug_info", 0, &bits);
1833 macho_section(".debug_line", 0, &bits);
1834 macho_section(".debug_str", 0, &bits);
1837 /* dw section walk to find high_addr and total_len */
1839 struct dw_sect_list *p_sect;
1841 list_for_each(p_sect, dw_head_sect) {
1842 uint64_t offset = get_section_by_index(p_sect->section)->size;
1843 struct SAA *p_linep = p_sect->psaa;
1845 saa_write8(p_linep, 2); /* std op 2 */
1846 saa_write8(p_linep, offset - p_sect->offset);
1847 saa_write8(p_linep, DW_LNS_extended_op);
1848 saa_write8(p_linep, 1); /* operand length */
1849 saa_write8(p_linep, DW_LNE_end_sequence);
1851 total_len += p_linep->datalen;
1852 high_addr += offset;
1856 /* debug line */
1858 struct dw_sect_list *p_sect;
1859 size_t linep_off, buf_size;
1860 struct SAA *p_lines = saa_init(1L);
1861 struct dir_list *p_dir;
1862 struct file_list *p_file;
1864 p_section = get_section_by_name("__DWARF", "__debug_line");
1865 nasm_assert(p_section != NULL);
1867 saa_write8(p_lines, 1); /* minimum instruction length */
1868 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1869 saa_write8(p_lines, DW_LN_BASE); /* line base */
1870 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1871 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1872 saa_write8(p_lines, 0); /* std opcode 1 length */
1873 saa_write8(p_lines, 1); /* std opcode 2 length */
1874 saa_write8(p_lines, 1); /* std opcode 3 length */
1875 saa_write8(p_lines, 1); /* std opcode 4 length */
1876 saa_write8(p_lines, 1); /* std opcode 5 length */
1877 saa_write8(p_lines, 0); /* std opcode 6 length */
1878 saa_write8(p_lines, 0); /* std opcode 7 length */
1879 saa_write8(p_lines, 0); /* std opcode 8 length */
1880 saa_write8(p_lines, 1); /* std opcode 9 length */
1881 saa_write8(p_lines, 0); /* std opcode 10 length */
1882 saa_write8(p_lines, 0); /* std opcode 11 length */
1883 saa_write8(p_lines, 1); /* std opcode 12 length */
1884 list_for_each(p_dir, dw_head_dir) {
1885 saa_wcstring(p_lines, p_dir->dir_name);
1887 saa_write8(p_lines, 0); /* end of table */
1889 list_for_each(p_file, dw_head_file) {
1890 saa_wcstring(p_lines, p_file->file_name);
1891 saa_write8(p_lines, p_file->dir->dir); /* directory id */
1892 saa_write8(p_lines, 0); /* time */
1893 saa_write8(p_lines, 0); /* size */
1895 saa_write8(p_lines, 0); /* end of table */
1897 linep_off = p_lines->datalen;
1898 /* 10 bytes for initial & prolong length, and dwarf version info */
1899 buf_size = saa_len = linep_off + total_len + 10;
1900 p_buf_base = p_buf = nasm_malloc(buf_size);
1902 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1903 WRITESHORT(p_buf, 2); /* dwarf version */
1904 WRITELONG(p_buf, linep_off); /* prolong length */
1906 saa_rnbytes(p_lines, p_buf, linep_off);
1907 p_buf += linep_off;
1908 saa_free(p_lines);
1910 list_for_each(p_sect, dw_head_sect) {
1911 struct SAA *p_linep = p_sect->psaa;
1913 saa_len = p_linep->datalen;
1914 saa_rnbytes(p_linep, p_buf, saa_len);
1915 p_buf += saa_len;
1917 saa_free(p_linep);
1920 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1922 nasm_free(p_buf_base);
1925 /* string section */
1927 struct SAA *p_str = saa_init(1L);
1928 char *cur_path = nasm_realpath(module_name);
1929 char *cur_file = nasm_basename(cur_path);
1930 char *cur_dir = nasm_dirname(cur_path);
1932 p_section = get_section_by_name("__DWARF", "__debug_str");
1933 nasm_assert(p_section != NULL);
1935 producer_str_offset = 0;
1936 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
1937 dir_str_offset += saa_wcstring(p_str, cur_file);
1938 saa_wcstring(p_str, cur_dir);
1940 saa_len = p_str->datalen;
1941 p_buf = nasm_malloc(saa_len);
1942 saa_rnbytes(p_str, p_buf, saa_len);
1943 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1945 nasm_free(cur_path);
1946 nasm_free(cur_file);
1947 nasm_free(cur_dir);
1948 saa_free(p_str);
1949 nasm_free(p_buf);
1952 /* debug info */
1954 struct SAA *p_info = saa_init(1L);
1956 p_section = get_section_by_name("__DWARF", "__debug_info");
1957 nasm_assert(p_section != NULL);
1959 /* size will be overwritten once determined, so skip in p_info layout */
1960 saa_write16(p_info, 2); /* dwarf version */
1961 saa_write32(p_info, 0); /* offset info abbrev */
1962 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1964 saa_write8(p_info, 1); /* abbrev entry number */
1966 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1967 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1968 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1969 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1970 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1972 if (ofmt == &of_macho64) {
1973 saa_write64(p_info, 0); /* DW_AT_low_pc */
1974 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1975 } else {
1976 saa_write32(p_info, 0); /* DW_AT_low_pc */
1977 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1980 saa_write8(p_info, 2); /* abbrev entry number */
1982 if (ofmt == &of_macho64) {
1983 saa_write64(p_info, 0); /* DW_AT_low_pc */
1984 saa_write64(p_info, 0); /* DW_AT_frame_base */
1985 } else {
1986 saa_write32(p_info, 0); /* DW_AT_low_pc */
1987 saa_write32(p_info, 0); /* DW_AT_frame_base */
1989 saa_write8(p_info, DW_END_default);
1991 saa_len = p_info->datalen;
1992 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1994 WRITELONG(p_buf, saa_len);
1995 saa_rnbytes(p_info, p_buf, saa_len);
1996 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1998 saa_free(p_info);
1999 nasm_free(p_buf_base);
2002 /* abbrev section */
2004 struct SAA *p_abbrev = saa_init(1L);
2006 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2007 nasm_assert(p_section != NULL);
2009 saa_write8(p_abbrev, 1); /* entry number */
2011 saa_write8(p_abbrev, DW_TAG_compile_unit);
2012 saa_write8(p_abbrev, DW_CHILDREN_yes);
2014 saa_write8(p_abbrev, DW_AT_producer);
2015 saa_write8(p_abbrev, DW_FORM_strp);
2017 saa_write8(p_abbrev, DW_AT_language);
2018 saa_write8(p_abbrev, DW_FORM_data2);
2020 saa_write8(p_abbrev, DW_AT_name);
2021 saa_write8(p_abbrev, DW_FORM_strp);
2023 saa_write8(p_abbrev, DW_AT_comp_dir);
2024 saa_write8(p_abbrev, DW_FORM_strp);
2026 saa_write8(p_abbrev, DW_AT_stmt_list);
2027 saa_write8(p_abbrev, DW_FORM_data4);
2029 saa_write8(p_abbrev, DW_AT_low_pc);
2030 saa_write8(p_abbrev, DW_FORM_addr);
2032 saa_write8(p_abbrev, DW_AT_high_pc);
2033 saa_write8(p_abbrev, DW_FORM_addr);
2035 saa_write16(p_abbrev, DW_END_default);
2037 saa_write8(p_abbrev, 2); /* entry number */
2039 saa_write8(p_abbrev, DW_TAG_subprogram);
2040 saa_write8(p_abbrev, DW_CHILDREN_no);
2042 saa_write8(p_abbrev, DW_AT_low_pc);
2043 saa_write8(p_abbrev, DW_FORM_addr);
2045 saa_write8(p_abbrev, DW_AT_frame_base);
2046 saa_write8(p_abbrev, DW_FORM_addr);
2048 saa_write16(p_abbrev, DW_END_default);
2050 saa_write8(p_abbrev, 0); /* Terminal zero entry */
2052 saa_len = p_abbrev->datalen;
2054 p_buf = nasm_malloc(saa_len);
2056 saa_rnbytes(p_abbrev, p_buf, saa_len);
2057 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2059 saa_free(p_abbrev);
2060 nasm_free(p_buf);
2064 static void new_file_list (const char *file_name, const char *dir_name)
2066 struct dir_list *dir_list;
2067 bool need_new_dir_list = true;
2069 nasm_new(dw_cur_file);
2070 dw_cur_file->file = ++dw_num_files;
2071 dw_cur_file->file_name = file_name;
2072 if(!dw_head_file) {
2073 dw_head_file = dw_cur_file;
2074 } else {
2075 *dw_last_file_next = dw_cur_file;
2077 dw_last_file_next = &(dw_cur_file->next);
2079 if(dw_head_dir) {
2080 list_for_each(dir_list, dw_head_dir) {
2081 if(!(strcmp(dir_name, dir_list->dir_name))) {
2082 dw_cur_file->dir = dir_list;
2083 need_new_dir_list = false;
2084 break;
2089 if(need_new_dir_list)
2091 nasm_new(dir_list);
2092 dir_list->dir = dw_num_dirs++;
2093 dir_list->dir_name = dir_name;
2094 if(!dw_head_dir) {
2095 dw_head_dir = dir_list;
2096 } else {
2097 *dw_last_dir_next = dir_list;
2099 dw_last_dir_next = &(dir_list->next);
2100 dw_cur_file->dir = dir_list;
2104 static void macho_dbg_init(void)
2108 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2110 bool need_new_list = true;
2111 const char *cur_file = nasm_basename(file_name);
2112 const char *cur_dir = nasm_dirname(file_name);
2113 (void)segto;
2115 if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2116 strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2117 if(dw_head_file) {
2118 struct file_list *match;
2120 list_for_each(match, dw_head_file) {
2121 if(!(strcmp(cur_file, match->file_name)) &&
2122 !(strcmp(cur_dir, match->dir->dir_name))) {
2123 dw_cur_file = match;
2124 dw_cur_file->dir = match->dir;
2125 need_new_list = false;
2126 break;
2131 if(need_new_list) {
2132 new_file_list(cur_file, cur_dir);
2136 dbg_immcall = true;
2137 cur_line = line_num;
2140 static void macho_dbg_output(int type, void *param)
2142 struct section_info *sinfo_param = (struct section_info *)param;
2143 int32_t secto = sinfo_param->secto;
2144 bool need_new_sect = false;
2145 struct SAA *p_linep = NULL;
2146 (void)type;
2148 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2149 need_new_sect = true;
2150 if(dw_head_sect) {
2151 struct dw_sect_list *match = dw_head_sect;
2152 uint32_t idx = 0;
2154 for(; idx < dw_num_sects; idx++) {
2155 if(match->section == secto) {
2156 dw_cur_sect = match;
2157 need_new_sect = false;
2158 break;
2160 match = match->next;
2165 if(need_new_sect) {
2166 nasm_new(dw_cur_sect);
2167 dw_num_sects ++;
2168 p_linep = dw_cur_sect->psaa = saa_init(1L);
2169 dw_cur_sect->line = dw_cur_sect->file = 1;
2170 dw_cur_sect->offset = 0;
2171 dw_cur_sect->next = NULL;
2172 dw_cur_sect->section = secto;
2174 saa_write8(p_linep, DW_LNS_extended_op);
2175 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2176 saa_write8(p_linep, DW_LNE_set_address);
2177 if (ofmt == &of_macho64) {
2178 saa_write64(p_linep, 0);
2179 } else {
2180 saa_write32(p_linep, 0);
2183 if(!dw_head_sect) {
2184 dw_head_sect = dw_last_sect = dw_cur_sect;
2185 } else {
2186 dw_last_sect->next = dw_cur_sect;
2187 dw_last_sect = dw_cur_sect;
2191 if(dbg_immcall == true) {
2192 int32_t line_delta = cur_line - dw_cur_sect->line;
2193 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2194 uint32_t cur_file = dw_cur_file->file;
2195 p_linep = dw_cur_sect->psaa;
2197 if(cur_file != dw_cur_sect->file) {
2198 saa_write8(p_linep, DW_LNS_set_file);
2199 saa_write8(p_linep, cur_file);
2200 dw_cur_sect->file = cur_file;
2203 if(line_delta) {
2204 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2205 DW_OPCODE_BASE;
2207 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2208 (special_opcode < DW_MAX_SP_OPCODE)) {
2209 saa_write8(p_linep, special_opcode);
2210 } else {
2211 saa_write8(p_linep, DW_LNS_advance_line);
2212 saa_wleb128s(p_linep, line_delta);
2213 if(offset_delta) {
2214 saa_write8(p_linep, DW_LNS_advance_pc);
2215 saa_wleb128u(p_linep, offset_delta);
2217 saa_write8(p_linep, DW_LNS_copy);
2220 dw_cur_sect->line = cur_line;
2221 dw_cur_sect->offset = sinfo_param->size;
2224 dbg_immcall = false;
2228 static void macho_dbg_cleanup(void)
2230 /* dwarf sectors generation */
2231 macho_dbg_generate();
2234 struct dw_sect_list *p_sect = dw_head_sect;
2235 struct file_list *p_file = dw_head_file;
2236 uint32_t idx = 0;
2238 for(; idx < dw_num_sects; idx++) {
2239 struct dw_sect_list *next = p_sect->next;
2240 nasm_free(p_sect);
2241 p_sect = next;
2244 for(idx = 0; idx < dw_num_files; idx++) {
2245 struct file_list *next = p_file->next;
2246 nasm_free(p_file);
2247 p_file = next;
2252 #ifdef OF_MACHO32
2253 static const struct macho_fmt macho32_fmt = {
2255 MH_MAGIC,
2256 CPU_TYPE_I386,
2257 LC_SEGMENT,
2258 MACHO_HEADER_SIZE,
2259 MACHO_SEGCMD_SIZE,
2260 MACHO_SECTCMD_SIZE,
2261 MACHO_NLIST_SIZE,
2262 RL_MAX_32,
2263 GENERIC_RELOC_VANILLA,
2264 GENERIC_RELOC_VANILLA,
2265 GENERIC_RELOC_TLV,
2266 false /* Allow segment-relative relocations */
2269 static void macho32_init(void)
2271 fmt = macho32_fmt;
2272 macho_init();
2274 macho_gotpcrel_sect = NO_SEG;
2277 static const struct dfmt macho32_df_dwarf = {
2278 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2279 "dwarf",
2280 macho_dbg_init,
2281 macho_dbg_linenum,
2282 null_debug_deflabel,
2283 null_debug_directive,
2284 null_debug_typevalue,
2285 macho_dbg_output,
2286 macho_dbg_cleanup,
2287 NULL /*pragma list*/
2290 static const struct dfmt * const macho32_df_arr[2] =
2291 { &macho32_df_dwarf, NULL };
2293 const struct ofmt of_macho32 = {
2294 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2295 "macho32",
2298 macho32_df_arr,
2299 &macho32_df_dwarf,
2300 macho_stdmac,
2301 macho32_init,
2302 nasm_do_legacy_output,
2303 macho_output,
2304 macho_symdef,
2305 macho_section,
2306 macho_sectalign,
2307 macho_segbase,
2308 null_directive,
2309 macho_filename,
2310 macho_cleanup,
2311 macho_pragma_list
2313 #endif
2315 #ifdef OF_MACHO64
2316 static const struct macho_fmt macho64_fmt = {
2318 MH_MAGIC_64,
2319 CPU_TYPE_X86_64,
2320 LC_SEGMENT_64,
2321 MACHO_HEADER64_SIZE,
2322 MACHO_SEGCMD64_SIZE,
2323 MACHO_SECTCMD64_SIZE,
2324 MACHO_NLIST64_SIZE,
2325 RL_MAX_64,
2326 X86_64_RELOC_UNSIGNED,
2327 X86_64_RELOC_SIGNED,
2328 X86_64_RELOC_TLV,
2329 true /* Force symbol-relative relocations */
2332 static void macho64_init(void)
2334 fmt = macho64_fmt;
2335 macho_init();
2337 /* add special symbol for ..gotpcrel */
2338 macho_gotpcrel_sect = seg_alloc() + 1;
2339 define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2342 static const struct dfmt macho64_df_dwarf = {
2343 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2344 "dwarf",
2345 macho_dbg_init,
2346 macho_dbg_linenum,
2347 null_debug_deflabel,
2348 null_debug_directive,
2349 null_debug_typevalue,
2350 macho_dbg_output,
2351 macho_dbg_cleanup,
2352 NULL /*pragma list*/
2355 static const struct dfmt * const macho64_df_arr[2] =
2356 { &macho64_df_dwarf, NULL };
2358 const struct ofmt of_macho64 = {
2359 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2360 "macho64",
2363 macho64_df_arr,
2364 &macho64_df_dwarf,
2365 macho_stdmac,
2366 macho64_init,
2367 nasm_do_legacy_output,
2368 macho_output,
2369 macho_symdef,
2370 macho_section,
2371 macho_sectalign,
2372 macho_segbase,
2373 null_directive,
2374 macho_filename,
2375 macho_cleanup,
2376 macho_pragma_list,
2378 #endif
2380 #endif
2383 * Local Variables:
2384 * mode:c
2385 * c-basic-offset:4
2386 * End:
2388 * end of file */