outmacho: fix dwarf line number information (debug_line section)
[nasm.git] / output / outmacho.c
blobc9a931d4a6952d4370d3eac7630a294817660cf8
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 dir_list {
327 struct dir_list *next;
328 struct dir_list *last;
329 const char *dir_name;
330 uint32_t dir;
333 struct file_list {
334 struct file_list *next;
335 struct file_list *last;
336 const char *file_name;
337 uint32_t file;
338 struct dir_list *dir;
341 struct dw_sect_list {
342 struct SAA *psaa;
343 int32_t section;
344 uint32_t line;
345 uint64_t offset;
346 uint32_t file;
347 struct dw_sect_list *next;
348 struct dw_sect_list *last;
351 struct section_info {
352 uint64_t size;
353 int32_t secto;
356 #define DW_LN_BASE (-5)
357 #define DW_LN_RANGE 14
358 #define DW_OPCODE_BASE 13
359 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
360 #define DW_MAX_SP_OPCODE 256
362 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
363 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
364 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
365 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
366 static bool dbg_immcall = false;
367 static const char *module_name = NULL;
370 * Special section numbers which are used to define Mach-O special
371 * symbols, which can be used with WRT to provide PIC relocation
372 * types.
374 static int32_t macho_tlvp_sect;
375 static int32_t macho_gotpcrel_sect;
377 static void macho_init(void)
379 sects = NULL;
380 sectstail = &sects;
382 /* Fake section for absolute symbols */
383 absolute_sect.index = NO_SEG;
385 syms = NULL;
386 symstail = &syms;
387 nsyms = 0;
388 nlocalsym = 0;
389 nextdefsym = 0;
390 nundefsym = 0;
392 extsyms = raa_init();
393 strs = saa_init(1L);
395 /* string table starts with a zero byte so index 0 is an empty string */
396 saa_wbytes(strs, zero_buffer, 1);
397 strslen = 1;
399 /* add special symbol for TLVP */
400 macho_tlvp_sect = seg_alloc() + 1;
401 define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
405 static void sect_write(struct section *sect,
406 const uint8_t *data, uint32_t len)
408 saa_wbytes(sect->data, data, len);
409 sect->size += len;
413 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
415 static struct symbol *macho_find_gsym(struct section *s,
416 uint64_t offset, bool exact)
418 struct rbtree *srb;
420 srb = rb_search(s->gsyms, offset);
422 if (!srb || (exact && srb->key != offset)) {
423 nasm_error(ERR_NONFATAL, "unable to find a suitable %s symbol"
424 " for this reference",
425 s == &absolute_sect ? "absolute" : "global");
426 return NULL;
429 return container_of(srb, struct symbol, symv);
432 static int64_t add_reloc(struct section *sect, int32_t section,
433 int64_t offset,
434 enum reltype reltype, int bytes)
436 struct reloc *r;
437 struct section *s;
438 int32_t fi;
439 int64_t adjust;
441 /* Double check this is a valid relocation type for this platform */
442 nasm_assert(reltype <= fmt.maxreltype);
444 /* the current end of the section will be the symbol's address for
445 ** now, might have to be fixed by macho_fixup_relocs() later on. make
446 ** sure we don't make the symbol scattered by setting the highest
447 ** bit by accident */
448 r = nasm_malloc(sizeof(struct reloc));
449 r->addr = sect->size & ~R_SCATTERED;
450 r->ext = 1;
451 adjust = bytes;
453 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
454 r->length = ilog2_32(bytes);
456 /* set default relocation values */
457 r->type = fmt.reloc_abs;
458 r->pcrel = 0;
459 r->snum = R_ABS;
461 s = NULL;
462 if (section != NO_SEG)
463 s = get_section_by_index(section);
464 fi = s ? s->fileindex : NO_SECT;
466 /* absolute relocation */
467 switch (reltype) {
468 case RL_ABS:
469 if (section == NO_SEG) {
470 /* absolute (can this even happen?) */
471 r->ext = 0;
472 r->snum = R_ABS;
473 } else if (fi == NO_SECT) {
474 /* external */
475 r->snum = raa_read(extsyms, section);
476 } else {
477 /* local */
478 r->ext = 0;
479 r->snum = fi;
480 adjust = -sect->size;
482 break;
484 case RL_REL:
485 case RL_BRANCH:
486 r->type = fmt.reloc_rel;
487 r->pcrel = 1;
488 if (section == NO_SEG) {
489 /* absolute - seems to produce garbage no matter what */
490 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
491 "references to absolute addresses");
492 goto bail;
493 #if 0
494 /* This "seems" to be how it ought to work... */
496 struct symbol *sym = macho_find_gsym(&absolute_sect,
497 offset, false);
498 if (!sym)
499 goto bail;
501 sect->extreloc = 1;
502 r->snum = NO_SECT;
503 adjust = -sect->size;
504 #endif
505 } else if (fi == NO_SECT) {
506 /* external */
507 sect->extreloc = 1;
508 r->snum = raa_read(extsyms, section);
509 if (reltype == RL_BRANCH)
510 r->type = X86_64_RELOC_BRANCH;
511 else if (r->type == GENERIC_RELOC_VANILLA)
512 adjust = -sect->size;
513 } else {
514 /* local */
515 r->ext = 0;
516 r->snum = fi;
517 adjust = -sect->size;
519 break;
521 case RL_SUB:
522 r->pcrel = 0;
523 r->type = X86_64_RELOC_SUBTRACTOR;
524 break;
526 case RL_GOT:
527 r->type = X86_64_RELOC_GOT;
528 goto needsym;
530 case RL_GOTLOAD:
531 r->type = X86_64_RELOC_GOT_LOAD;
532 goto needsym;
534 case RL_TLV:
535 r->type = fmt.reloc_tlv;
536 goto needsym;
538 needsym:
539 r->pcrel = 1;
540 if (section == NO_SEG) {
541 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
542 } else if (fi == NO_SECT) {
543 /* external */
544 r->snum = raa_read(extsyms, section);
545 } else {
546 /* internal */
547 struct symbol *sym = macho_find_gsym(s, offset, reltype != RL_TLV);
548 if (!sym)
549 goto bail;
550 r->snum = sym->initial_snum;
552 break;
555 /* NeXT as puts relocs in reversed order (address-wise) into the
556 ** files, so we do the same, doesn't seem to make much of a
557 ** difference either way */
558 r->next = sect->relocs;
559 sect->relocs = r;
560 if (r->ext)
561 sect->extreloc = 1;
562 ++sect->nreloc;
564 return adjust;
566 bail:
567 nasm_free(r);
568 return 0;
571 static void macho_output(int32_t secto, const void *data,
572 enum out_type type, uint64_t size,
573 int32_t section, int32_t wrt)
575 struct section *s;
576 int64_t addr, offset;
577 uint8_t mydata[16], *p;
578 bool is_bss;
579 enum reltype reltype;
581 if (secto == NO_SEG) {
582 if (type != OUT_RESERVE)
583 nasm_error(ERR_NONFATAL, "attempt to assemble code in "
584 "[ABSOLUTE] space");
585 return;
588 s = get_section_by_index(secto);
590 if (s == NULL) {
591 nasm_error(ERR_WARNING, "attempt to assemble code in"
592 " section %d: defaulting to `.text'", secto);
593 s = get_section_by_name("__TEXT", "__text");
595 /* should never happen */
596 if (s == NULL)
597 nasm_panic(0, "text section not found");
600 /* debug code generation only for sections tagged with
601 * instruction attribute */
602 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
604 struct section_info sinfo;
605 sinfo.size = s->size;
606 sinfo.secto = secto;
607 dfmt->debug_output(0, &sinfo);
610 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
612 if (is_bss && type != OUT_RESERVE) {
613 nasm_error(ERR_WARNING, "attempt to initialize memory in "
614 "BSS section: ignored");
615 s->size += realsize(type, size);
616 return;
619 memset(mydata, 0, sizeof(mydata));
621 switch (type) {
622 case OUT_RESERVE:
623 if (!is_bss) {
624 nasm_error(ERR_WARNING, "uninitialized space declared in"
625 " %s,%s section: zeroing", s->segname, s->sectname);
627 sect_write(s, NULL, size);
628 } else
629 s->size += size;
631 break;
633 case OUT_RAWDATA:
634 if (section != NO_SEG)
635 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
637 sect_write(s, data, size);
638 break;
640 case OUT_ADDRESS:
642 int asize = abs((int)size);
644 addr = *(int64_t *)data;
645 if (section != NO_SEG) {
646 if (section % 2) {
647 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
648 " section base references");
649 } else if (wrt == NO_SEG) {
650 if (fmt.ptrsize == 8 && asize != 8) {
651 nasm_error(ERR_NONFATAL,
652 "Mach-O 64-bit format does not support"
653 " 32-bit absolute addresses");
654 } else {
655 add_reloc(s, section, addr, RL_ABS, asize);
657 } else {
658 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
659 " this use of WRT");
663 p = mydata;
664 WRITEADDR(p, addr, asize);
665 sect_write(s, mydata, asize);
666 break;
669 case OUT_REL2ADR:
670 nasm_assert(section != secto);
672 p = mydata;
673 offset = *(int64_t *)data;
674 addr = offset - size;
676 if (section != NO_SEG && section % 2) {
677 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
678 " section base references");
679 } else if (fmt.ptrsize == 8) {
680 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
681 " Macho-O relocation [2]");
682 } else if (wrt != NO_SEG) {
683 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
684 " this use of WRT");
685 wrt = NO_SEG; /* we can at least _try_ to continue */
686 } else {
687 addr += add_reloc(s, section, addr+size, RL_REL, 2);
690 WRITESHORT(p, addr);
691 sect_write(s, mydata, 2);
692 break;
694 case OUT_REL4ADR:
695 nasm_assert(section != secto);
697 p = mydata;
698 offset = *(int64_t *)data;
699 addr = offset - size;
700 reltype = RL_REL;
702 if (section != NO_SEG && section % 2) {
703 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
704 " section base references");
705 } else if (wrt == NO_SEG) {
706 if (fmt.ptrsize == 8 &&
707 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
708 uint8_t opcode[2];
710 opcode[0] = opcode[1] = 0;
712 /* HACK: Retrieve instruction opcode */
713 if (likely(s->data->datalen >= 2)) {
714 saa_fread(s->data, s->data->datalen-2, opcode, 2);
715 } else if (s->data->datalen == 1) {
716 saa_fread(s->data, 0, opcode+1, 1);
719 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
720 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
721 /* Direct call, jmp, or jcc */
722 reltype = RL_BRANCH;
725 } else if (wrt == macho_gotpcrel_sect) {
726 reltype = RL_GOT;
728 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
729 s->data->datalen >= 3) {
730 uint8_t gotload[3];
732 /* HACK: Retrieve instruction opcode */
733 saa_fread(s->data, s->data->datalen-3, gotload, 3);
734 if ((gotload[0] & 0xf8) == 0x48 &&
735 gotload[1] == 0x8b &&
736 (gotload[2] & 0307) == 0005) {
737 /* movq <reg>,[rel sym wrt ..gotpcrel] */
738 reltype = RL_GOTLOAD;
741 } else if (wrt == macho_tlvp_sect) {
742 reltype = RL_TLV;
743 } else {
744 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
745 " this use of WRT");
746 /* continue with RL_REL */
749 addr += add_reloc(s, section, offset, reltype, 4);
750 WRITELONG(p, addr);
751 sect_write(s, mydata, 4);
752 break;
754 default:
755 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
756 break;
760 /* Translation table from traditional Unix section names to Mach-O */
761 static const struct sectmap {
762 const char *nasmsect;
763 const char *segname;
764 const char *sectname;
765 const uint32_t flags;
766 } sectmap[] = {
767 {".text", "__TEXT", "__text",
768 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
769 {".data", "__DATA", "__data", S_REGULAR},
770 {".rodata", "__DATA", "__const", S_REGULAR},
771 {".bss", "__DATA", "__bss", S_ZEROFILL},
772 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
773 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
774 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
775 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
776 {NULL, NULL, NULL, 0}
779 #define NO_TYPE S_NASM_TYPE_MASK
781 /* Section type or attribute directives */
782 static const struct sect_attribs {
783 const char *name;
784 uint32_t flags;
785 } sect_attribs[] = {
786 { "data", S_REGULAR },
787 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
788 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
789 { "bss", S_ZEROFILL },
790 { "zerofill", S_ZEROFILL },
791 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
792 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
793 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
794 { NULL, 0 }
797 static int32_t macho_section(char *name, int pass, int *bits)
799 char *sectionAttributes;
800 const struct sectmap *sm;
801 struct section *s;
802 const char *section, *segment;
803 uint32_t flags;
804 const struct sect_attribs *sa;
805 char *currentAttribute;
806 char *comma;
808 bool new_seg;
810 (void)pass;
812 /* Default to the appropriate number of bits. */
813 if (!name) {
814 *bits = fmt.ptrsize << 3;
815 name = ".text";
816 sectionAttributes = NULL;
817 } else {
818 sectionAttributes = name;
819 name = nasm_strsep(&sectionAttributes, " \t");
822 section = segment = NULL;
823 flags = 0;
825 comma = strchr(name, ',');
826 if (comma) {
827 int len;
829 *comma = '\0';
830 segment = name;
831 section = comma+1;
833 len = strlen(segment);
834 if (len == 0) {
835 nasm_error(ERR_NONFATAL, "empty segment name\n");
836 } else if (len >= 16) {
837 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
840 len = strlen(section);
841 if (len == 0) {
842 nasm_error(ERR_NONFATAL, "empty section name\n");
843 } else if (len >= 16) {
844 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
847 if (!strcmp(section, "__text")) {
848 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
849 S_ATTR_PURE_INSTRUCTIONS;
850 } else if (!strcmp(section, "__bss")) {
851 flags = S_ZEROFILL;
852 } else {
853 flags = S_REGULAR;
855 } else {
856 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
857 /* make lookup into section name translation table */
858 if (!strcmp(name, sm->nasmsect)) {
859 segment = sm->segname;
860 section = sm->sectname;
861 flags = sm->flags;
862 goto found;
865 nasm_error(ERR_NONFATAL, "unknown section name\n");
866 return NO_SEG;
869 found:
870 /* try to find section with that name */
871 s = get_section_by_name(segment, section);
873 /* create it if it doesn't exist yet */
874 if (!s) {
875 new_seg = true;
877 s = *sectstail = nasm_zalloc(sizeof(struct section));
878 sectstail = &s->next;
880 s->data = saa_init(1L);
881 s->index = seg_alloc();
882 s->fileindex = ++seg_nsects;
883 s->align = -1;
884 s->pad = -1;
885 s->offset = -1;
886 s->by_name = false;
888 xstrncpy(s->segname, segment);
889 xstrncpy(s->sectname, section);
890 s->size = 0;
891 s->nreloc = 0;
892 s->flags = flags;
893 } else {
894 new_seg = false;
897 if (comma)
898 *comma = ','; /* Restore comma */
900 s->by_name = s->by_name || comma; /* Was specified by name */
902 flags = NO_TYPE;
904 while (sectionAttributes &&
905 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
906 if (!*currentAttribute)
907 continue;
909 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
910 char *end;
911 int newAlignment, value;
913 value = strtoul(currentAttribute + 6, (char**)&end, 0);
914 newAlignment = alignlog2_32(value);
916 if (0 != *end) {
917 nasm_error(ERR_NONFATAL,
918 "unknown or missing alignment value \"%s\" "
919 "specified for section \"%s\"",
920 currentAttribute + 6,
921 name);
922 } else if (0 > newAlignment) {
923 nasm_error(ERR_NONFATAL,
924 "alignment of %d (for section \"%s\") is not "
925 "a power of two",
926 value,
927 name);
930 if (s->align < newAlignment)
931 s->align = newAlignment;
932 } else {
933 for (sa = sect_attribs; sa->name; sa++) {
934 if (!nasm_stricmp(sa->name, currentAttribute)) {
935 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
936 flags = (flags & ~S_NASM_TYPE_MASK)
937 | (sa->flags & S_NASM_TYPE_MASK);
939 flags |= sa->flags & ~S_NASM_TYPE_MASK;
940 break;
944 if (!sa->name) {
945 nasm_error(ERR_NONFATAL,
946 "unknown section attribute %s for section %s",
947 currentAttribute, name);
952 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
953 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
954 nasm_error(ERR_NONFATAL,
955 "inconsistent section attributes for section %s\n",
956 name);
957 } else {
958 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
960 } else {
961 s->flags |= flags & ~S_NASM_TYPE_MASK;
964 return s->index;
967 static void macho_symdef(char *name, int32_t section, int64_t offset,
968 int is_global, char *special)
970 struct symbol *sym;
972 if (special) {
973 nasm_error(ERR_NONFATAL, "The Mach-O output format does "
974 "not support any special symbol types");
975 return;
978 if (is_global == 3) {
979 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
980 "(yet) support forward reference fixups.");
981 return;
984 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
986 * This is a NASM special symbol. We never allow it into
987 * the Macho-O symbol table, even if it's a valid one. If it
988 * _isn't_ a valid one, we should barf immediately.
990 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
991 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
992 return;
995 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
996 sym->next = NULL;
997 symstail = &sym->next;
999 sym->name = name;
1000 sym->strx = strslen;
1001 sym->type = 0;
1002 sym->desc = 0;
1003 sym->symv.key = offset;
1004 sym->initial_snum = -1;
1006 /* external and common symbols get N_EXT */
1007 if (is_global != 0) {
1008 sym->type |= N_EXT;
1011 if (section == NO_SEG) {
1012 /* symbols in no section get absolute */
1013 sym->type |= N_ABS;
1014 sym->sect = NO_SECT;
1016 /* all absolute symbols are available to use as references */
1017 absolute_sect.gsyms = rb_insert(absolute_sect.gsyms, &sym->symv);
1018 } else {
1019 struct section *s = get_section_by_index(section);
1021 sym->type |= N_SECT;
1023 /* get the in-file index of the section the symbol was defined in */
1024 sym->sect = s ? s->fileindex : NO_SECT;
1026 /* track the initially allocated symbol number for use in future fix-ups */
1027 sym->initial_snum = nsyms;
1029 if (!s) {
1030 /* remember symbol number of references to external
1031 ** symbols, this works because every external symbol gets
1032 ** its own section number allocated internally by nasm and
1033 ** can so be used as a key */
1034 extsyms = raa_write(extsyms, section, nsyms);
1036 switch (is_global) {
1037 case 1:
1038 case 2:
1039 /* there isn't actually a difference between global
1040 ** and common symbols, both even have their size in
1041 ** sym->symv.key */
1042 sym->type = N_EXT;
1043 break;
1045 default:
1046 /* give an error on unfound section if it's not an
1047 ** external or common symbol (assemble_file() does a
1048 ** seg_alloc() on every call for them) */
1049 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1050 break;
1052 } else if (is_global) {
1053 s->gsyms = rb_insert(s->gsyms, &sym->symv);
1056 ++nsyms;
1059 static void macho_sectalign(int32_t seg, unsigned int value)
1061 struct section *s;
1062 int align;
1064 nasm_assert(!(seg & 1));
1066 s = get_section_by_index(seg);
1068 if (!s || !is_power2(value))
1069 return;
1071 align = alignlog2_32(value);
1072 if (s->align < align)
1073 s->align = align;
1076 static int32_t macho_segbase(int32_t section)
1078 return section;
1081 static void macho_filename(char *inname, char *outname)
1083 standard_extension(inname, outname, ".o");
1084 module_name = inname;
1087 extern macros_t macho_stdmac[];
1089 /* Comparison function for qsort symbol layout. */
1090 static int layout_compare (const struct symbol **s1,
1091 const struct symbol **s2)
1093 return (strcmp ((*s1)->name, (*s2)->name));
1096 /* The native assembler does a few things in a similar function
1098 * Remove temporary labels
1099 * Sort symbols according to local, external, undefined (by name)
1100 * Order the string table
1102 We do not remove temporary labels right now.
1104 numsyms is the total number of symbols we have. strtabsize is the
1105 number entries in the string table. */
1107 static void macho_layout_symbols (uint32_t *numsyms,
1108 uint32_t *strtabsize)
1110 struct symbol *sym, **symp;
1111 uint32_t i,j;
1113 *numsyms = 0;
1114 *strtabsize = sizeof (char);
1116 symp = &syms;
1118 while ((sym = *symp)) {
1119 /* Undefined symbols are now external. */
1120 if (sym->type == N_UNDF)
1121 sym->type |= N_EXT;
1123 if ((sym->type & N_EXT) == 0) {
1124 sym->snum = *numsyms;
1125 *numsyms = *numsyms + 1;
1126 nlocalsym++;
1128 else {
1129 if ((sym->type & N_TYPE) != N_UNDF) {
1130 nextdefsym++;
1131 } else {
1132 nundefsym++;
1135 /* If we handle debug info we'll want
1136 to check for it here instead of just
1137 adding the symbol to the string table. */
1138 sym->strx = *strtabsize;
1139 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1140 *strtabsize += strlen(sym->name) + 1;
1142 symp = &(sym->next);
1145 /* Next, sort the symbols. Most of this code is a direct translation from
1146 the Apple cctools symbol layout. We need to keep compatibility with that. */
1147 /* Set the indexes for symbol groups into the symbol table */
1148 ilocalsym = 0;
1149 iextdefsym = nlocalsym;
1150 iundefsym = nlocalsym + nextdefsym;
1152 /* allocate arrays for sorting externals by name */
1153 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1154 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1156 i = 0;
1157 j = 0;
1159 symp = &syms;
1161 while ((sym = *symp)) {
1163 if((sym->type & N_EXT) == 0) {
1164 sym->strx = *strtabsize;
1165 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1166 *strtabsize += strlen(sym->name) + 1;
1168 else {
1169 if ((sym->type & N_TYPE) != N_UNDF) {
1170 extdefsyms[i++] = sym;
1171 } else {
1172 undefsyms[j++] = sym;
1175 symp = &(sym->next);
1178 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1179 (int (*)(const void *, const void *))layout_compare);
1180 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1181 (int (*)(const void *, const void *))layout_compare);
1183 for(i = 0; i < nextdefsym; i++) {
1184 extdefsyms[i]->snum = *numsyms;
1185 *numsyms += 1;
1187 for(j = 0; j < nundefsym; j++) {
1188 undefsyms[j]->snum = *numsyms;
1189 *numsyms += 1;
1193 /* Calculate some values we'll need for writing later. */
1195 static void macho_calculate_sizes (void)
1197 struct section *s;
1198 int fi;
1200 /* count sections and calculate in-memory and in-file offsets */
1201 for (s = sects; s != NULL; s = s->next) {
1202 uint64_t newaddr;
1204 /* recalculate segment address based on alignment and vm size */
1205 s->addr = seg_vmsize;
1207 /* we need section alignment to calculate final section address */
1208 if (s->align == -1)
1209 s->align = DEFAULT_SECTION_ALIGNMENT;
1211 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1212 s->addr = newaddr;
1214 seg_vmsize = newaddr + s->size;
1216 /* zerofill sections aren't actually written to the file */
1217 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1219 * LLVM/Xcode as always aligns the section data to 4
1220 * bytes; there is a comment in the LLVM source code that
1221 * perhaps aligning to pointer size would be better.
1223 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1224 s->offset = seg_filesize + s->pad;
1225 seg_filesize += s->size + s->pad;
1227 /* filesize and vmsize needs to be aligned */
1228 seg_vmsize += s->pad;
1232 /* calculate size of all headers, load commands and sections to
1233 ** get a pointer to the start of all the raw data */
1234 if (seg_nsects > 0) {
1235 ++head_ncmds;
1236 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1239 if (nsyms > 0) {
1240 ++head_ncmds;
1241 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1244 if (seg_nsects > MAX_SECT) {
1245 nasm_fatal(0, "MachO output is limited to %d sections\n",
1246 MAX_SECT);
1249 /* Create a table of sections by file index to avoid linear search */
1250 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1251 sectstab[NO_SECT] = &absolute_sect;
1252 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1253 sectstab[fi] = s;
1256 /* Write out the header information for the file. */
1258 static void macho_write_header (void)
1260 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1261 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1262 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1263 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1264 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1265 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1266 fwriteint32_t(head_flags, ofile); /* flags, if any */
1267 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1270 /* Write out the segment load command at offset. */
1272 static uint32_t macho_write_segment (uint64_t offset)
1274 uint64_t rel_base = alignptr(offset + seg_filesize);
1275 uint32_t s_reloff = 0;
1276 struct section *s;
1278 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1280 /* size of load command including section load commands */
1281 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1282 ofile);
1284 /* in an MH_OBJECT file all sections are in one unnamed (name
1285 ** all zeros) segment */
1286 fwritezero(16, ofile);
1287 fwriteptr(0, ofile); /* in-memory offset */
1288 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1289 fwriteptr(offset, ofile); /* in-file offset to data */
1290 fwriteptr(seg_filesize, ofile); /* in-file size */
1291 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1292 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1293 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1294 fwriteint32_t(0, ofile); /* no flags */
1296 /* emit section headers */
1297 for (s = sects; s != NULL; s = s->next) {
1298 if (s->nreloc) {
1299 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1300 s->flags |= S_ATTR_LOC_RELOC;
1301 if (s->extreloc)
1302 s->flags |= S_ATTR_EXT_RELOC;
1303 } else if (!strcmp(s->segname, "__DATA") &&
1304 !strcmp(s->sectname, "__const") &&
1305 !s->by_name &&
1306 !get_section_by_name("__TEXT", "__const")) {
1308 * The MachO equivalent to .rodata can be either
1309 * __DATA,__const or __TEXT,__const; the latter only if
1310 * there are no relocations. However, when mixed it is
1311 * better to specify the segments explicitly.
1313 xstrncpy(s->segname, "__TEXT");
1316 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1317 nasm_write(s->segname, sizeof(s->segname), ofile);
1318 fwriteptr(s->addr, ofile);
1319 fwriteptr(s->size, ofile);
1321 /* dummy data for zerofill sections or proper values */
1322 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1323 nasm_assert(s->pad != (uint32_t)-1);
1324 offset += s->pad;
1325 fwriteint32_t(offset, ofile);
1326 offset += s->size;
1327 /* Write out section alignment, as a power of two.
1328 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1329 fwriteint32_t(s->align, ofile);
1330 /* To be compatible with cctools as we emit
1331 a zero reloff if we have no relocations. */
1332 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1333 fwriteint32_t(s->nreloc, ofile);
1335 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1336 } else {
1337 fwriteint32_t(0, ofile);
1338 fwriteint32_t(s->align, ofile);
1339 fwriteint32_t(0, ofile);
1340 fwriteint32_t(0, ofile);
1343 fwriteint32_t(s->flags, ofile); /* flags */
1344 fwriteint32_t(0, ofile); /* reserved */
1345 fwriteptr(0, ofile); /* reserved */
1348 rel_padcnt = rel_base - offset;
1349 offset = rel_base + s_reloff;
1351 return offset;
1354 /* For a given chain of relocs r, write out the entire relocation
1355 chain to the object file. */
1357 static void macho_write_relocs (struct reloc *r)
1359 while (r) {
1360 uint32_t word2;
1362 fwriteint32_t(r->addr, ofile); /* reloc offset */
1364 word2 = r->snum;
1365 word2 |= r->pcrel << 24;
1366 word2 |= r->length << 25;
1367 word2 |= r->ext << 27;
1368 word2 |= r->type << 28;
1369 fwriteint32_t(word2, ofile); /* reloc data */
1370 r = r->next;
1374 /* Write out the section data. */
1375 static void macho_write_section (void)
1377 struct section *s;
1378 struct reloc *r;
1379 uint8_t *p;
1380 int32_t len;
1381 int64_t l;
1382 union offset {
1383 uint64_t val;
1384 uint8_t buf[8];
1385 } blk;
1387 for (s = sects; s != NULL; s = s->next) {
1388 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1389 continue;
1391 /* Like a.out Mach-O references things in the data or bss
1392 * sections by addresses which are actually relative to the
1393 * start of the _text_ section, in the _file_. See outaout.c
1394 * for more information. */
1395 saa_rewind(s->data);
1396 for (r = s->relocs; r != NULL; r = r->next) {
1397 len = (uint32_t)1 << r->length;
1398 if (len > 4) /* Can this ever be an issue?! */
1399 len = 8;
1400 blk.val = 0;
1401 saa_fread(s->data, r->addr, blk.buf, len);
1403 /* get offset based on relocation type */
1404 #ifdef WORDS_LITTLEENDIAN
1405 l = blk.val;
1406 #else
1407 l = blk.buf[0];
1408 l += ((int64_t)blk.buf[1]) << 8;
1409 l += ((int64_t)blk.buf[2]) << 16;
1410 l += ((int64_t)blk.buf[3]) << 24;
1411 l += ((int64_t)blk.buf[4]) << 32;
1412 l += ((int64_t)blk.buf[5]) << 40;
1413 l += ((int64_t)blk.buf[6]) << 48;
1414 l += ((int64_t)blk.buf[7]) << 56;
1415 #endif
1417 /* If the relocation is internal add to the current section
1418 offset. Otherwise the only value we need is the symbol
1419 offset which we already have. The linker takes care
1420 of the rest of the address. */
1421 if (!r->ext) {
1422 /* generate final address by section address and offset */
1423 nasm_assert(r->snum <= seg_nsects);
1424 l += sectstab[r->snum]->addr;
1425 if (r->pcrel)
1426 l -= s->addr;
1427 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1428 l -= s->addr;
1431 /* write new offset back */
1432 p = blk.buf;
1433 WRITEDLONG(p, l);
1434 saa_fwrite(s->data, r->addr, blk.buf, len);
1437 /* dump the section data to file */
1438 fwritezero(s->pad, ofile);
1439 saa_fpwrite(s->data, ofile);
1442 /* pad last section up to reloc entries on pointer boundary */
1443 fwritezero(rel_padcnt, ofile);
1445 /* emit relocation entries */
1446 for (s = sects; s != NULL; s = s->next)
1447 macho_write_relocs (s->relocs);
1450 /* Write out the symbol table. We should already have sorted this
1451 before now. */
1452 static void macho_write_symtab (void)
1454 struct symbol *sym;
1455 uint64_t i;
1457 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1459 for (sym = syms; sym != NULL; sym = sym->next) {
1460 if ((sym->type & N_EXT) == 0) {
1461 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1462 nasm_write(&sym->type, 1, ofile); /* symbol type */
1463 nasm_write(&sym->sect, 1, ofile); /* section */
1464 fwriteint16_t(sym->desc, ofile); /* description */
1466 /* Fix up the symbol value now that we know the final section
1467 sizes. */
1468 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1469 nasm_assert(sym->sect <= seg_nsects);
1470 sym->symv.key += sectstab[sym->sect]->addr;
1473 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1477 for (i = 0; i < nextdefsym; i++) {
1478 sym = extdefsyms[i];
1479 fwriteint32_t(sym->strx, ofile);
1480 nasm_write(&sym->type, 1, ofile); /* symbol type */
1481 nasm_write(&sym->sect, 1, ofile); /* section */
1482 fwriteint16_t(sym->desc, ofile); /* description */
1484 /* Fix up the symbol value now that we know the final section
1485 sizes. */
1486 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1487 nasm_assert(sym->sect <= seg_nsects);
1488 sym->symv.key += sectstab[sym->sect]->addr;
1491 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1494 for (i = 0; i < nundefsym; i++) {
1495 sym = undefsyms[i];
1496 fwriteint32_t(sym->strx, ofile);
1497 nasm_write(&sym->type, 1, ofile); /* symbol type */
1498 nasm_write(&sym->sect, 1, ofile); /* section */
1499 fwriteint16_t(sym->desc, ofile); /* description */
1501 /* Fix up the symbol value now that we know the final section
1502 sizes. */
1503 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1504 nasm_assert(sym->sect <= seg_nsects);
1505 sym->symv.key += sectstab[sym->sect]->addr;
1508 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1513 /* Fixup the snum in the relocation entries, we should be
1514 doing this only for externally referenced symbols. */
1515 static void macho_fixup_relocs (struct reloc *r)
1517 struct symbol *sym;
1519 while (r != NULL) {
1520 if (r->ext) {
1521 for (sym = syms; sym != NULL; sym = sym->next) {
1522 if (sym->initial_snum == r->snum) {
1523 r->snum = sym->snum;
1524 break;
1528 r = r->next;
1532 /* Write out the object file. */
1534 static void macho_write (void)
1536 uint64_t offset = 0;
1538 /* mach-o object file structure:
1540 ** mach header
1541 ** uint32_t magic
1542 ** int cpu type
1543 ** int cpu subtype
1544 ** uint32_t mach file type
1545 ** uint32_t number of load commands
1546 ** uint32_t size of all load commands
1547 ** (includes section struct size of segment command)
1548 ** uint32_t flags
1550 ** segment command
1551 ** uint32_t command type == LC_SEGMENT[_64]
1552 ** uint32_t size of load command
1553 ** (including section load commands)
1554 ** char[16] segment name
1555 ** pointer in-memory offset
1556 ** pointer in-memory size
1557 ** pointer in-file offset to data area
1558 ** pointer in-file size
1559 ** (in-memory size excluding zerofill sections)
1560 ** int maximum vm protection
1561 ** int initial vm protection
1562 ** uint32_t number of sections
1563 ** uint32_t flags
1565 ** section commands
1566 ** char[16] section name
1567 ** char[16] segment name
1568 ** pointer in-memory offset
1569 ** pointer in-memory size
1570 ** uint32_t in-file offset
1571 ** uint32_t alignment
1572 ** (irrelevant in MH_OBJECT)
1573 ** uint32_t in-file offset of relocation entires
1574 ** uint32_t number of relocations
1575 ** uint32_t flags
1576 ** uint32_t reserved
1577 ** uint32_t reserved
1579 ** symbol table command
1580 ** uint32_t command type == LC_SYMTAB
1581 ** uint32_t size of load command
1582 ** uint32_t symbol table offset
1583 ** uint32_t number of symbol table entries
1584 ** uint32_t string table offset
1585 ** uint32_t string table size
1587 ** raw section data
1589 ** padding to pointer boundary
1591 ** relocation data (struct reloc)
1592 ** int32_t offset
1593 ** uint data (symbolnum, pcrel, length, extern, type)
1595 ** symbol table data (struct nlist)
1596 ** int32_t string table entry number
1597 ** uint8_t type
1598 ** (extern, absolute, defined in section)
1599 ** uint8_t section
1600 ** (0 for global symbols, section number of definition (>= 1, <=
1601 ** 254) for local symbols, size of variable for common symbols
1602 ** [type == extern])
1603 ** int16_t description
1604 ** (for stab debugging format)
1605 ** pointer value (i.e. file offset) of symbol or stab offset
1607 ** string table data
1608 ** list of null-terminated strings
1611 /* Emit the Mach-O header. */
1612 macho_write_header();
1614 offset = fmt.header_size + head_sizeofcmds;
1616 /* emit the segment load command */
1617 if (seg_nsects > 0)
1618 offset = macho_write_segment (offset);
1619 else
1620 nasm_error(ERR_WARNING, "no sections?");
1622 if (nsyms > 0) {
1623 /* write out symbol command */
1624 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1625 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1626 fwriteint32_t(offset, ofile); /* symbol table offset */
1627 fwriteint32_t(nsyms, ofile); /* number of symbol
1628 ** table entries */
1629 offset += nsyms * fmt.nlist_size;
1630 fwriteint32_t(offset, ofile); /* string table offset */
1631 fwriteint32_t(strslen, ofile); /* string table size */
1634 /* emit section data */
1635 if (seg_nsects > 0)
1636 macho_write_section ();
1638 /* emit symbol table if we have symbols */
1639 if (nsyms > 0)
1640 macho_write_symtab ();
1642 /* we don't need to pad here, we are already aligned */
1644 /* emit string table */
1645 saa_fpwrite(strs, ofile);
1647 /* We do quite a bit here, starting with finalizing all of the data
1648 for the object file, writing, and then freeing all of the data from
1649 the file. */
1651 static void macho_cleanup(void)
1653 struct section *s;
1654 struct reloc *r;
1655 struct symbol *sym;
1657 dfmt->cleanup();
1659 /* Sort all symbols. */
1660 macho_layout_symbols (&nsyms, &strslen);
1662 /* Fixup relocation entries */
1663 for (s = sects; s != NULL; s = s->next) {
1664 macho_fixup_relocs (s->relocs);
1667 /* First calculate and finalize needed values. */
1668 macho_calculate_sizes();
1669 macho_write();
1671 /* free up everything */
1672 while (sects->next) {
1673 s = sects;
1674 sects = sects->next;
1676 saa_free(s->data);
1677 while (s->relocs != NULL) {
1678 r = s->relocs;
1679 s->relocs = s->relocs->next;
1680 nasm_free(r);
1683 nasm_free(s);
1686 saa_free(strs);
1687 raa_free(extsyms);
1689 while (syms) {
1690 sym = syms;
1691 syms = syms->next;
1692 nasm_free (sym);
1695 nasm_free(extdefsyms);
1696 nasm_free(undefsyms);
1697 nasm_free(sectstab);
1700 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1702 struct section *s;
1703 int32_t nasm_seg;
1704 int64_t offset;
1706 if (!lookup_label(label, &nasm_seg, &offset)) {
1707 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1708 return false;
1711 s = get_section_by_index(nasm_seg);
1712 if (!s) {
1713 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1714 return false;
1717 s->flags |= flags;
1718 return true;
1722 * Mark a symbol for no dead stripping
1724 static enum directive_result macho_no_dead_strip(const char *labels)
1726 char *s, *p, *ep;
1727 char ec;
1728 enum directive_result rv = DIRR_ERROR;
1729 bool real = passn > 1;
1731 p = s = nasm_strdup(labels);
1732 while (*p) {
1733 ep = nasm_skip_identifier(p);
1734 if (!ep) {
1735 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1736 goto err;
1738 ec = *ep;
1739 if (ec && ec != ',' && !nasm_isspace(ec)) {
1740 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1741 goto err;
1743 *ep = '\0';
1744 if (real) {
1745 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1746 rv = DIRR_ERROR;
1748 *ep = ec;
1749 p = nasm_skip_spaces(ep);
1750 if (*p == ',')
1751 p = nasm_skip_spaces(++p);
1754 rv = DIRR_OK;
1756 err:
1757 nasm_free(s);
1758 return rv;
1762 * Mach-O pragmas
1764 static enum directive_result
1765 macho_pragma(const struct pragma *pragma)
1767 bool real = passn > 1;
1769 switch (pragma->opcode) {
1770 case D_SUBSECTIONS_VIA_SYMBOLS:
1771 if (*pragma->tail)
1772 return DIRR_BADPARAM;
1774 if (real)
1775 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1777 return DIRR_OK;
1779 case D_NO_DEAD_STRIP:
1780 return macho_no_dead_strip(pragma->tail);
1782 default:
1783 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1787 static const struct pragma_facility macho_pragma_list[] = {
1788 { "macho", macho_pragma },
1789 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1792 static void macho_dbg_generate(void)
1794 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1795 size_t saa_len = 0, high_addr = 0, total_len = 0;
1796 struct section *p_section = NULL;
1797 /* calculated at debug_str and referenced at debug_info */
1798 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1800 /* debug section defines */
1802 int bits = 0;
1803 macho_section(".debug_abbrev", 0, &bits);
1804 macho_section(".debug_info", 0, &bits);
1805 macho_section(".debug_line", 0, &bits);
1806 macho_section(".debug_str", 0, &bits);
1809 /* dw section walk to find high_addr and total_len */
1811 struct dw_sect_list *p_sect;
1813 list_for_each(p_sect, dw_head_sect) {
1814 uint64_t offset = get_section_by_index(p_sect->section)->size;
1815 struct SAA *p_linep = p_sect->psaa;
1817 saa_write8(p_linep, 2); /* std op 2 */
1818 saa_write8(p_linep, offset - p_sect->offset);
1819 saa_write8(p_linep, DW_LNS_extended_op);
1820 saa_write8(p_linep, 1); /* operand length */
1821 saa_write8(p_linep, DW_LNE_end_sequence);
1823 total_len += p_linep->datalen;
1824 high_addr += offset;
1828 /* debug line */
1830 struct dw_sect_list *p_sect;
1831 size_t linep_off, buf_size;
1832 struct SAA *p_lines = saa_init(1L);
1833 struct dir_list *p_dir;
1834 struct file_list *p_file;
1836 p_section = get_section_by_name("__DWARF", "__debug_line");
1837 nasm_assert(p_section != NULL);
1839 saa_write8(p_lines, 1); /* minimum instruction length */
1840 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1841 saa_write8(p_lines, DW_LN_BASE); /* line base */
1842 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1843 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1844 saa_write8(p_lines, 0); /* std opcode 1 length */
1845 saa_write8(p_lines, 1); /* std opcode 2 length */
1846 saa_write8(p_lines, 1); /* std opcode 3 length */
1847 saa_write8(p_lines, 1); /* std opcode 4 length */
1848 saa_write8(p_lines, 1); /* std opcode 5 length */
1849 saa_write8(p_lines, 0); /* std opcode 6 length */
1850 saa_write8(p_lines, 0); /* std opcode 7 length */
1851 saa_write8(p_lines, 0); /* std opcode 8 length */
1852 saa_write8(p_lines, 1); /* std opcode 9 length */
1853 saa_write8(p_lines, 0); /* std opcode 10 length */
1854 saa_write8(p_lines, 0); /* std opcode 11 length */
1855 saa_write8(p_lines, 1); /* std opcode 12 length */
1856 list_for_each(p_dir, dw_head_dir) {
1857 saa_wcstring(p_lines, p_dir->dir_name);
1859 saa_write8(p_lines, 0); /* end of table */
1861 list_for_each(p_file, dw_head_file) {
1862 saa_wcstring(p_lines, p_file->file_name);
1863 saa_write8(p_lines, p_file->dir->dir); /* directory id */
1864 saa_write8(p_lines, 0); /* time */
1865 saa_write8(p_lines, 0); /* size */
1867 saa_write8(p_lines, 0); /* end of table */
1869 linep_off = p_lines->datalen;
1870 /* 10 bytes for initial & prolong length, and dwarf version info */
1871 buf_size = saa_len = linep_off + total_len + 10;
1872 p_buf_base = p_buf = nasm_malloc(buf_size);
1874 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1875 WRITESHORT(p_buf, 2); /* dwarf version */
1876 WRITELONG(p_buf, linep_off); /* prolong length */
1878 saa_rnbytes(p_lines, p_buf, linep_off);
1879 p_buf += linep_off;
1880 saa_free(p_lines);
1882 list_for_each(p_sect, dw_head_sect) {
1883 struct SAA *p_linep = p_sect->psaa;
1885 saa_len = p_linep->datalen;
1886 saa_rnbytes(p_linep, p_buf, saa_len);
1887 p_buf += saa_len;
1889 saa_free(p_linep);
1892 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1894 nasm_free(p_buf_base);
1897 /* string section */
1899 struct SAA *p_str = saa_init(1L);
1900 char *cur_path = nasm_realpath(module_name);
1901 char *cur_file = nasm_basename(cur_path);
1902 char *cur_dir = nasm_dirname(cur_path);
1904 p_section = get_section_by_name("__DWARF", "__debug_str");
1905 nasm_assert(p_section != NULL);
1907 producer_str_offset = 0;
1908 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
1909 dir_str_offset += saa_wcstring(p_str, cur_file);
1910 saa_wcstring(p_str, cur_dir);
1912 saa_len = p_str->datalen;
1913 p_buf = nasm_malloc(saa_len);
1914 saa_rnbytes(p_str, p_buf, saa_len);
1915 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1917 nasm_free(cur_path);
1918 nasm_free(cur_file);
1919 nasm_free(cur_dir);
1920 saa_free(p_str);
1921 nasm_free(p_buf);
1924 /* debug info */
1926 struct SAA *p_info = saa_init(1L);
1928 p_section = get_section_by_name("__DWARF", "__debug_info");
1929 nasm_assert(p_section != NULL);
1931 /* size will be overwritten once determined, so skip in p_info layout */
1932 saa_write16(p_info, 2); /* dwarf version */
1933 saa_write32(p_info, 0); /* offset info abbrev */
1934 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1936 saa_write8(p_info, 1); /* abbrev entry number */
1938 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1939 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1940 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1941 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1942 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1944 if (ofmt == &of_macho64) {
1945 saa_write64(p_info, 0); /* DW_AT_low_pc */
1946 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1947 } else {
1948 saa_write32(p_info, 0); /* DW_AT_low_pc */
1949 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1952 saa_write8(p_info, 2); /* abbrev entry number */
1954 if (ofmt == &of_macho64) {
1955 saa_write64(p_info, 0); /* DW_AT_low_pc */
1956 saa_write64(p_info, 0); /* DW_AT_frame_base */
1957 } else {
1958 saa_write32(p_info, 0); /* DW_AT_low_pc */
1959 saa_write32(p_info, 0); /* DW_AT_frame_base */
1961 saa_write8(p_info, DW_END_default);
1963 saa_len = p_info->datalen;
1964 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1966 WRITELONG(p_buf, saa_len);
1967 saa_rnbytes(p_info, p_buf, saa_len);
1968 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1970 saa_free(p_info);
1971 nasm_free(p_buf_base);
1974 /* abbrev section */
1976 struct SAA *p_abbrev = saa_init(1L);
1978 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
1979 nasm_assert(p_section != NULL);
1981 saa_write8(p_abbrev, 1); /* entry number */
1983 saa_write8(p_abbrev, DW_TAG_compile_unit);
1984 saa_write8(p_abbrev, DW_CHILDREN_yes);
1986 saa_write8(p_abbrev, DW_AT_producer);
1987 saa_write8(p_abbrev, DW_FORM_strp);
1989 saa_write8(p_abbrev, DW_AT_language);
1990 saa_write8(p_abbrev, DW_FORM_data2);
1992 saa_write8(p_abbrev, DW_AT_name);
1993 saa_write8(p_abbrev, DW_FORM_strp);
1995 saa_write8(p_abbrev, DW_AT_comp_dir);
1996 saa_write8(p_abbrev, DW_FORM_strp);
1998 saa_write8(p_abbrev, DW_AT_stmt_list);
1999 saa_write8(p_abbrev, DW_FORM_data4);
2001 saa_write8(p_abbrev, DW_AT_low_pc);
2002 saa_write8(p_abbrev, DW_FORM_addr);
2004 saa_write8(p_abbrev, DW_AT_high_pc);
2005 saa_write8(p_abbrev, DW_FORM_addr);
2007 saa_write16(p_abbrev, DW_END_default);
2009 saa_write8(p_abbrev, 2); /* entry number */
2011 saa_write8(p_abbrev, DW_TAG_subprogram);
2012 saa_write8(p_abbrev, DW_CHILDREN_no);
2014 saa_write8(p_abbrev, DW_AT_low_pc);
2015 saa_write8(p_abbrev, DW_FORM_addr);
2017 saa_write8(p_abbrev, DW_AT_frame_base);
2018 saa_write8(p_abbrev, DW_FORM_addr);
2020 saa_write16(p_abbrev, DW_END_default);
2022 saa_len = p_abbrev->datalen;
2024 p_buf = nasm_malloc(saa_len);
2026 saa_rnbytes(p_abbrev, p_buf, saa_len);
2027 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2029 saa_free(p_abbrev);
2030 nasm_free(p_buf);
2034 static void new_file_list (const char *file_name, const char *dir_name)
2036 struct dir_list *dir_list;
2037 bool need_new_dir_list = true;
2039 nasm_new(dw_cur_file);
2040 dw_cur_file->file = ++dw_num_files;
2041 dw_cur_file->file_name = file_name;
2042 if(!dw_head_file) {
2043 dw_head_file = dw_cur_file;
2044 } else {
2045 *dw_last_file_next = dw_cur_file;
2047 dw_last_file_next = &(dw_cur_file->next);
2049 if(dw_head_dir) {
2050 list_for_each(dir_list, dw_head_dir) {
2051 if(!(strcmp(dir_name, dir_list->dir_name))) {
2052 dw_cur_file->dir = dir_list;
2053 need_new_dir_list = false;
2054 break;
2059 if(need_new_dir_list)
2061 nasm_new(dir_list);
2062 dir_list->dir = dw_num_dirs++;
2063 dir_list->dir_name = dir_name;
2064 if(!dw_head_dir) {
2065 dw_head_dir = dir_list;
2066 } else {
2067 *dw_last_dir_next = dir_list;
2069 dw_last_dir_next = &(dir_list->next);
2070 dw_cur_file->dir = dir_list;
2074 static void macho_dbg_init(void)
2078 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2080 bool need_new_list = true;
2081 const char *cur_file = nasm_basename(file_name);
2082 const char *cur_dir = nasm_dirname(file_name);
2083 (void)segto;
2085 if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2086 strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2087 if(dw_head_file) {
2088 struct file_list *match;
2090 list_for_each(match, dw_head_file) {
2091 if(!(strcmp(cur_file, match->file_name)) &&
2092 !(strcmp(cur_dir, match->dir->dir_name))) {
2093 dw_cur_file = match;
2094 dw_cur_file->dir = match->dir;
2095 need_new_list = false;
2096 break;
2101 if(need_new_list) {
2102 new_file_list(cur_file, cur_dir);
2106 dbg_immcall = true;
2107 cur_line = line_num;
2110 static void macho_dbg_output(int type, void *param)
2112 struct section_info *sinfo_param = (struct section_info *)param;
2113 int32_t secto = sinfo_param->secto;
2114 bool need_new_sect = false;
2115 struct SAA *p_linep = NULL;
2116 (void)type;
2118 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2119 need_new_sect = true;
2120 if(dw_head_sect) {
2121 struct dw_sect_list *match = dw_head_sect;
2122 uint32_t idx = 0;
2124 for(; idx < dw_num_sects; idx++) {
2125 if(match->section == secto) {
2126 dw_cur_sect = match;
2127 need_new_sect = false;
2128 break;
2130 match = match->next;
2135 if(need_new_sect) {
2136 nasm_new(dw_cur_sect);
2137 dw_num_sects ++;
2138 p_linep = dw_cur_sect->psaa = saa_init(1L);
2139 dw_cur_sect->line = dw_cur_sect->file = 1;
2140 dw_cur_sect->offset = 0;
2141 dw_cur_sect->next = NULL;
2142 dw_cur_sect->section = secto;
2144 saa_write8(p_linep, DW_LNS_extended_op);
2145 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2146 saa_write8(p_linep, DW_LNE_set_address);
2147 if (ofmt == &of_macho64) {
2148 saa_write64(p_linep, 0);
2149 } else {
2150 saa_write32(p_linep, 0);
2153 if(!dw_head_sect) {
2154 dw_head_sect = dw_last_sect = dw_cur_sect;
2155 } else {
2156 dw_last_sect->next = dw_cur_sect;
2157 dw_last_sect = dw_cur_sect;
2161 if(dbg_immcall == true) {
2162 int32_t line_delta = cur_line - dw_cur_sect->line;
2163 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2164 uint32_t cur_file = dw_cur_file->file;
2165 p_linep = dw_cur_sect->psaa;
2167 if(cur_file != dw_cur_sect->file) {
2168 saa_write8(p_linep, DW_LNS_set_file);
2169 saa_write8(p_linep, cur_file);
2170 dw_cur_sect->file = cur_file;
2173 if(line_delta) {
2174 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2175 DW_OPCODE_BASE;
2177 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2178 (special_opcode < DW_MAX_SP_OPCODE)) {
2179 saa_write8(p_linep, special_opcode);
2180 } else {
2181 saa_write8(p_linep, DW_LNS_advance_line);
2182 saa_wleb128s(p_linep, line_delta);
2183 if(offset_delta) {
2184 saa_write8(p_linep, DW_LNS_advance_pc);
2185 saa_wleb128u(p_linep, offset_delta);
2187 saa_write8(p_linep, DW_LNS_copy);
2190 dw_cur_sect->line = cur_line;
2191 dw_cur_sect->offset = sinfo_param->size;
2194 dbg_immcall = false;
2198 static void macho_dbg_cleanup(void)
2200 /* dwarf sectors generation */
2201 macho_dbg_generate();
2204 struct dw_sect_list *p_sect = dw_head_sect;
2205 struct file_list *p_file = dw_head_file;
2206 uint32_t idx = 0;
2208 for(; idx < dw_num_sects; idx++) {
2209 struct dw_sect_list *next = p_sect->next;
2210 nasm_free(p_sect);
2211 p_sect = next;
2214 for(idx = 0; idx < dw_num_files; idx++) {
2215 struct file_list *next = p_file->next;
2216 nasm_free(p_file);
2217 p_file = next;
2222 #ifdef OF_MACHO32
2223 static const struct macho_fmt macho32_fmt = {
2225 MH_MAGIC,
2226 CPU_TYPE_I386,
2227 LC_SEGMENT,
2228 MACHO_HEADER_SIZE,
2229 MACHO_SEGCMD_SIZE,
2230 MACHO_SECTCMD_SIZE,
2231 MACHO_NLIST_SIZE,
2232 RL_MAX_32,
2233 GENERIC_RELOC_VANILLA,
2234 GENERIC_RELOC_VANILLA,
2235 GENERIC_RELOC_TLV
2238 static void macho32_init(void)
2240 fmt = macho32_fmt;
2241 macho_init();
2243 macho_gotpcrel_sect = NO_SEG;
2246 static const struct dfmt macho32_df_dwarf = {
2247 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2248 "dwarf",
2249 macho_dbg_init,
2250 macho_dbg_linenum,
2251 null_debug_deflabel,
2252 null_debug_directive,
2253 null_debug_typevalue,
2254 macho_dbg_output,
2255 macho_dbg_cleanup,
2256 NULL /*pragma list*/
2259 static const struct dfmt * const macho32_df_arr[2] =
2260 { &macho32_df_dwarf, NULL };
2262 const struct ofmt of_macho32 = {
2263 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2264 "macho32",
2267 macho32_df_arr,
2268 &macho32_df_dwarf,
2269 macho_stdmac,
2270 macho32_init,
2271 nasm_do_legacy_output,
2272 macho_output,
2273 macho_symdef,
2274 macho_section,
2275 macho_sectalign,
2276 macho_segbase,
2277 null_directive,
2278 macho_filename,
2279 macho_cleanup,
2280 macho_pragma_list,
2282 #endif
2284 #ifdef OF_MACHO64
2285 static const struct macho_fmt macho64_fmt = {
2287 MH_MAGIC_64,
2288 CPU_TYPE_X86_64,
2289 LC_SEGMENT_64,
2290 MACHO_HEADER64_SIZE,
2291 MACHO_SEGCMD64_SIZE,
2292 MACHO_SECTCMD64_SIZE,
2293 MACHO_NLIST64_SIZE,
2294 RL_MAX_64,
2295 X86_64_RELOC_UNSIGNED,
2296 X86_64_RELOC_SIGNED,
2297 X86_64_RELOC_TLV
2300 static void macho64_init(void)
2302 fmt = macho64_fmt;
2303 macho_init();
2305 /* add special symbol for ..gotpcrel */
2306 macho_gotpcrel_sect = seg_alloc() + 1;
2307 define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2310 static const struct dfmt macho64_df_dwarf = {
2311 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2312 "dwarf",
2313 macho_dbg_init,
2314 macho_dbg_linenum,
2315 null_debug_deflabel,
2316 null_debug_directive,
2317 null_debug_typevalue,
2318 macho_dbg_output,
2319 macho_dbg_cleanup,
2320 NULL /*pragma list*/
2323 static const struct dfmt * const macho64_df_arr[2] =
2324 { &macho64_df_dwarf, NULL };
2326 const struct ofmt of_macho64 = {
2327 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2328 "macho64",
2331 macho64_df_arr,
2332 &macho64_df_dwarf,
2333 macho_stdmac,
2334 macho64_init,
2335 nasm_do_legacy_output,
2336 macho_output,
2337 macho_symdef,
2338 macho_section,
2339 macho_sectalign,
2340 macho_segbase,
2341 null_directive,
2342 macho_filename,
2343 macho_cleanup,
2344 macho_pragma_list,
2346 #endif
2348 #endif
2351 * Local Variables:
2352 * mode:c
2353 * c-basic-offset:4
2354 * End:
2356 * end of file */