output: remove ABSOLUTE handling, OUT_RAWDATA asserts
[nasm.git] / output / outmacho.c
blob4d41a1f7464a00f356e68f8129c0dc15d261eae5
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2018 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * outmacho.c output routines for the Netwide Assembler to produce
36 * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
39 #include "compiler.h"
41 #include <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 "hashtbl.h"
55 #include "outform.h"
56 #include "outlib.h"
57 #include "ver.h"
58 #include "dwarf.h"
60 #if defined(OF_MACHO) || defined(OF_MACHO64)
62 /* Mach-O in-file header structure sizes */
63 #define MACHO_HEADER_SIZE 28
64 #define MACHO_SEGCMD_SIZE 56
65 #define MACHO_SECTCMD_SIZE 68
66 #define MACHO_SYMCMD_SIZE 24
67 #define MACHO_NLIST_SIZE 12
68 #define MACHO_RELINFO_SIZE 8
70 #define MACHO_HEADER64_SIZE 32
71 #define MACHO_SEGCMD64_SIZE 72
72 #define MACHO_SECTCMD64_SIZE 80
73 #define MACHO_NLIST64_SIZE 16
75 /* Mach-O file header values */
76 #define MH_MAGIC 0xfeedface
77 #define MH_MAGIC_64 0xfeedfacf
78 #define CPU_TYPE_I386 7 /* x86 platform */
79 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
80 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
81 #define MH_OBJECT 0x1 /* object file */
83 /* Mach-O header flags */
84 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
86 /* Mach-O load commands */
87 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
88 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
89 #define LC_SYMTAB 0x2 /* symbol table load command */
91 /* Mach-O relocations numbers */
93 /* Generic relocs, used by i386 Mach-O */
94 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
95 #define GENERIC_RELOC_TLV 5 /* Thread local */
97 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
98 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
99 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
100 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
101 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
102 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
103 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
104 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
105 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
106 #define X86_64_RELOC_TLV 9 /* Thread local */
108 /* Mach-O VM permission constants */
109 #define VM_PROT_NONE (0x00)
110 #define VM_PROT_READ (0x01)
111 #define VM_PROT_WRITE (0x02)
112 #define VM_PROT_EXECUTE (0x04)
114 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
115 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
117 /* Our internal relocation types */
118 enum reltype {
119 RL_ABS, /* Absolute relocation */
120 RL_REL, /* Relative relocation */
121 RL_TLV, /* Thread local */
122 RL_BRANCH, /* Relative direct branch */
123 RL_SUB, /* X86_64_RELOC_SUBTRACT */
124 RL_GOT, /* X86_64_RELOC_GOT */
125 RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
127 #define RL_MAX_32 RL_TLV
128 #define RL_MAX_64 RL_GOTLOAD
130 struct macho_fmt {
131 uint32_t ptrsize; /* Pointer size in bytes */
132 uint32_t mh_magic; /* Which magic number to use */
133 uint32_t cpu_type; /* Which CPU type */
134 uint32_t lc_segment; /* Which segment load command */
135 uint32_t header_size; /* Header size */
136 uint32_t segcmd_size; /* Segment command size */
137 uint32_t sectcmd_size; /* Section command size */
138 uint32_t nlist_size; /* Nlist (symbol) size */
139 enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
140 uint32_t reloc_abs; /* Absolute relocation type */
141 uint32_t reloc_rel; /* Relative relocation type */
142 uint32_t reloc_tlv; /* Thread local relocation type */
143 bool forcesym; /* Always use "external" (symbol-relative) relocations */
146 static struct macho_fmt fmt;
148 static void fwriteptr(uint64_t data, FILE * fp)
150 fwriteaddr(data, fmt.ptrsize, fp);
153 struct section {
154 /* nasm internal data */
155 struct section *next;
156 struct SAA *data;
157 int32_t index; /* Main section index */
158 int32_t subsection; /* Current subsection index */
159 int32_t fileindex;
160 struct reloc *relocs;
161 struct rbtree *syms[2]; /* All/global symbols symbols in section */
162 int align;
163 bool by_name; /* This section was specified by full MachO name */
164 char namestr[34]; /* segment,section as a C string */
166 /* data that goes into the file */
167 char sectname[16]; /* what this section is called */
168 char segname[16]; /* segment this section will be in */
169 uint64_t addr; /* in-memory address (subject to alignment) */
170 uint64_t size; /* in-memory and -file size */
171 uint64_t offset; /* in-file offset */
172 uint32_t pad; /* padding bytes before section */
173 uint32_t nreloc; /* relocation entry count */
174 uint32_t flags; /* type and attributes (masked) */
175 uint32_t extreloc; /* external relocations */
178 #define SECTION_TYPE 0x000000ff /* section type mask */
180 #define S_REGULAR (0x0) /* standard section */
181 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
183 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
184 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
185 machine instructions */
186 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
187 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
188 #define S_ATTR_DEBUG 0x02000000
189 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
190 #define S_ATTR_LIVE_SUPPORT 0x08000000
191 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
192 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
193 #define S_ATTR_NO_TOC 0x40000000
194 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
195 #define S_ATTR_DEBUG 0x02000000 /* debug section */
197 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
199 /* fake section for absolute symbols, *not* part of the section linked list */
200 static struct section absolute_sect;
202 struct reloc {
203 /* nasm internal data */
204 struct reloc *next;
206 /* data that goes into the file */
207 int32_t addr; /* op's offset in section */
208 uint32_t snum:24, /* contains symbol index if
209 ** ext otherwise in-file
210 ** section number */
211 pcrel:1, /* relative relocation */
212 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
213 ext:1, /* external symbol referenced */
214 type:4; /* reloc type */
217 #define R_ABS 0 /* absolute relocation */
218 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
219 ** highest bit == 1 */
221 struct symbol {
222 /* nasm internal data */
223 struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
224 symbol offset. */
225 struct symbol *next; /* next symbol in the list */
226 char *name; /* name of this symbol */
227 int32_t initial_snum; /* symbol number used above in reloc */
228 int32_t snum; /* true snum for reloc */
230 /* data that goes into the file */
231 uint32_t strx; /* string table index */
232 uint8_t type; /* symbol type */
233 uint8_t sect; /* NO_SECT or section number */
234 uint16_t desc; /* for stab debugging, 0 for us */
237 /* symbol type bits */
238 #define N_EXT 0x01 /* global or external symbol */
239 #define N_PEXT 0x10 /* private external symbol */
241 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
242 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
243 #define N_SECT 0xe /* defined symbol, n_sect holds
244 ** section number */
246 #define N_TYPE 0x0e /* type bit mask */
248 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
250 /* special section number values */
251 #define NO_SECT 0 /* no section, invalid */
252 #define MAX_SECT 255 /* maximum number of sections */
254 static struct section *sects, **sectstail, **sectstab;
255 static struct symbol *syms, **symstail;
256 static uint32_t nsyms;
258 /* These variables are set by macho_layout_symbols() to organize
259 the symbol table and string table in order the dynamic linker
260 expects. They are then used in macho_write() to put out the
261 symbols and strings in that order.
263 The order of the symbol table is:
264 local symbols
265 defined external symbols (sorted by name)
266 undefined external symbols (sorted by name)
268 The order of the string table is:
269 strings for external symbols
270 strings for local symbols
272 static uint32_t ilocalsym = 0;
273 static uint32_t iextdefsym = 0;
274 static uint32_t iundefsym = 0;
275 static uint32_t nlocalsym;
276 static uint32_t nextdefsym;
277 static uint32_t nundefsym;
278 static struct symbol **extdefsyms = NULL;
279 static struct symbol **undefsyms = NULL;
281 static struct RAA *extsyms;
282 static struct SAA *strs;
283 static uint32_t strslen;
285 /* Global file information. This should be cleaned up into either
286 a structure or as function arguments. */
287 static uint32_t head_ncmds = 0;
288 static uint32_t head_sizeofcmds = 0;
289 static uint32_t head_flags = 0;
290 static uint64_t seg_filesize = 0;
291 static uint64_t seg_vmsize = 0;
292 static uint32_t seg_nsects = 0;
293 static uint64_t rel_padcnt = 0;
296 * Functions for handling fixed-length zero-padded string
297 * fields, that may or may not be null-terminated.
300 /* Copy a string into a zero-padded fixed-length field */
301 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
303 /* Compare a fixed-length field with a string */
304 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
306 #define alignint32_t(x) \
307 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
309 #define alignint64_t(x) \
310 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
312 #define alignptr(x) \
313 ALIGN(x, fmt.ptrsize) /* align x to output format width */
315 static struct hash_table section_by_name;
316 static struct RAA *section_by_index;
318 static struct section * never_null
319 find_or_add_section(const char *segname, const char *sectname)
321 struct hash_insert hi;
322 void **sp;
323 struct section *s;
324 char sect[34];
326 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
328 sp = hash_find(&section_by_name, sect, &hi);
329 if (sp)
330 return (struct section *)(*sp);
332 s = nasm_zalloc(sizeof *s);
333 xstrncpy(s->segname, segname);
334 xstrncpy(s->sectname, sectname);
335 xstrncpy(s->namestr, sect);
336 hash_add(&hi, s->namestr, s);
338 s->index = s->subsection = seg_alloc();
339 section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
341 return s;
344 static inline bool is_new_section(const struct section *s)
346 return !s->data;
349 static struct section *get_section_by_name(const char *segname,
350 const char *sectname)
352 char sect[34];
353 void **sp;
355 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
357 sp = hash_find(&section_by_name, sect, NULL);
358 return sp ? (struct section *)(*sp) : NULL;
361 static struct section *get_section_by_index(int32_t index)
363 if (index < 0 || index >= SEG_ABS || (index & 1))
364 return NULL;
366 return (struct section *)raa_read(section_by_index, index >> 1);
369 struct dir_list {
370 struct dir_list *next;
371 struct dir_list *last;
372 const char *dir_name;
373 uint32_t dir;
376 struct file_list {
377 struct file_list *next;
378 struct file_list *last;
379 const char *file_name;
380 uint32_t file;
381 struct dir_list *dir;
384 struct dw_sect_list {
385 struct SAA *psaa;
386 int32_t section;
387 uint32_t line;
388 uint64_t offset;
389 uint32_t file;
390 struct dw_sect_list *next;
391 struct dw_sect_list *last;
394 struct section_info {
395 uint64_t size;
396 int32_t secto;
399 #define DW_LN_BASE (-5)
400 #define DW_LN_RANGE 14
401 #define DW_OPCODE_BASE 13
402 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
403 #define DW_MAX_SP_OPCODE 256
405 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
406 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
407 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
408 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
409 static bool dbg_immcall = false;
410 static const char *module_name = NULL;
413 * Special section numbers which are used to define Mach-O special
414 * symbols, which can be used with WRT to provide PIC relocation
415 * types.
417 static int32_t macho_tlvp_sect;
418 static int32_t macho_gotpcrel_sect;
420 static void macho_init(void)
422 module_name = inname;
423 sects = NULL;
424 sectstail = &sects;
426 /* Fake section for absolute symbols */
427 absolute_sect.index = NO_SEG;
429 syms = NULL;
430 symstail = &syms;
431 nsyms = 0;
432 nlocalsym = 0;
433 nextdefsym = 0;
434 nundefsym = 0;
436 extsyms = raa_init();
437 strs = saa_init(1L);
439 section_by_index = raa_init();
440 hash_init(&section_by_name, HASH_MEDIUM);
442 /* string table starts with a zero byte so index 0 is an empty string */
443 saa_wbytes(strs, zero_buffer, 1);
444 strslen = 1;
446 /* add special symbol for TLVP */
447 macho_tlvp_sect = seg_alloc() + 1;
448 backend_label("..tlvp", macho_tlvp_sect, 0L);
451 static void sect_write(struct section *sect,
452 const uint8_t *data, uint32_t len)
454 saa_wbytes(sect->data, data, len);
455 sect->size += len;
459 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
461 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
462 bool global, bool exact)
464 struct rbtree *srb;
466 srb = rb_search(s->syms[global], offset);
468 if (!srb || (exact && srb->key != offset)) {
469 nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
470 " for this reference",
471 global ? " global" : "",
472 s == &absolute_sect ? " absolute " : "");
473 return NULL;
476 return container_of(srb - global, struct symbol, symv);
479 static int64_t add_reloc(struct section *sect, int32_t section,
480 int64_t offset,
481 enum reltype reltype, int bytes)
483 struct reloc *r;
484 struct section *s;
485 int32_t fi;
486 int64_t adjust;
488 /* Double check this is a valid relocation type for this platform */
489 nasm_assert(reltype <= fmt.maxreltype);
491 /* the current end of the section will be the symbol's address for
492 ** now, might have to be fixed by macho_fixup_relocs() later on. make
493 ** sure we don't make the symbol scattered by setting the highest
494 ** bit by accident */
495 r = nasm_malloc(sizeof(struct reloc));
496 r->addr = sect->size & ~R_SCATTERED;
497 r->ext = 1;
498 adjust = bytes;
500 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
501 r->length = ilog2_32(bytes);
503 /* set default relocation values */
504 r->type = fmt.reloc_abs;
505 r->pcrel = 0;
506 r->snum = R_ABS;
508 s = get_section_by_index(section);
509 fi = s ? s->fileindex : NO_SECT;
511 /* absolute relocation */
512 switch (reltype) {
513 case RL_ABS:
514 if (section == NO_SEG) {
515 /* absolute (can this even happen?) */
516 r->ext = 0;
517 r->snum = NO_SECT;
518 } else if (fi == NO_SECT) {
519 /* external */
520 r->snum = raa_read(extsyms, section);
521 } else {
522 /* local */
523 r->ext = 0;
524 r->snum = fi;
525 adjust = -sect->size;
527 break;
529 case RL_REL:
530 case RL_BRANCH:
531 r->type = fmt.reloc_rel;
532 r->pcrel = 1;
533 if (section == NO_SEG) {
534 /* absolute - seems to produce garbage no matter what */
535 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
536 "references to absolute addresses");
537 goto bail;
538 #if 0
539 /* This "seems" to be how it ought to work... */
541 struct symbol *sym = macho_find_sym(&absolute_sect, offset,
542 false, false);
543 if (!sym)
544 goto bail;
546 sect->extreloc = 1;
547 r->snum = NO_SECT;
548 adjust = -sect->size;
549 #endif
550 } else if (fi == NO_SECT) {
551 /* external */
552 sect->extreloc = 1;
553 r->snum = raa_read(extsyms, section);
554 if (reltype == RL_BRANCH)
555 r->type = X86_64_RELOC_BRANCH;
556 else if (r->type == GENERIC_RELOC_VANILLA)
557 adjust = -sect->size;
558 } else {
559 /* local */
560 r->ext = 0;
561 r->snum = fi;
562 adjust = -sect->size;
564 break;
566 case RL_SUB:
567 r->pcrel = 0;
568 r->type = X86_64_RELOC_SUBTRACTOR;
569 break;
571 case RL_GOT:
572 r->type = X86_64_RELOC_GOT;
573 goto needsym;
575 case RL_GOTLOAD:
576 r->type = X86_64_RELOC_GOT_LOAD;
577 goto needsym;
579 case RL_TLV:
580 r->type = fmt.reloc_tlv;
581 goto needsym;
583 needsym:
584 r->pcrel = 1;
585 if (section == NO_SEG) {
586 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
587 } else if (fi == NO_SECT) {
588 /* external */
589 r->snum = raa_read(extsyms, section);
590 } else {
591 /* internal - does it really need to be global? */
592 struct symbol *sym = macho_find_sym(s, offset, true,
593 reltype != RL_TLV);
594 if (!sym)
595 goto bail;
597 r->snum = sym->initial_snum;
599 break;
602 /* For 64-bit Mach-O, force a symbol reference if at all possible */
603 if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
604 struct symbol *sym = macho_find_sym(s, offset, false, false);
605 if (sym) {
606 adjust = bytes - sym->symv[0].key;
607 r->snum = sym->initial_snum;
608 r->ext = 1;
612 /* NeXT as puts relocs in reversed order (address-wise) into the
613 ** files, so we do the same, doesn't seem to make much of a
614 ** difference either way */
615 r->next = sect->relocs;
616 sect->relocs = r;
617 if (r->ext)
618 sect->extreloc = 1;
619 ++sect->nreloc;
621 return adjust;
623 bail:
624 nasm_free(r);
625 return 0;
628 static void macho_output(int32_t secto, const void *data,
629 enum out_type type, uint64_t size,
630 int32_t section, int32_t wrt)
632 struct section *s;
633 int64_t addr, offset;
634 uint8_t mydata[16], *p;
635 bool is_bss;
636 enum reltype reltype;
638 s = get_section_by_index(secto);
639 if (!s) {
640 nasm_error(ERR_WARNING, "attempt to assemble code in"
641 " section %d: defaulting to `.text'", secto);
642 s = get_section_by_name("__TEXT", "__text");
644 /* should never happen */
645 if (!s)
646 nasm_panic(0, "text section not found");
649 /* debug code generation only for sections tagged with
650 * instruction attribute */
651 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
653 struct section_info sinfo;
654 sinfo.size = s->size;
655 sinfo.secto = secto;
656 dfmt->debug_output(0, &sinfo);
659 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
661 if (is_bss && type != OUT_RESERVE) {
662 nasm_error(ERR_WARNING, "attempt to initialize memory in "
663 "BSS section: ignored");
664 s->size += realsize(type, size);
665 return;
668 memset(mydata, 0, sizeof(mydata));
670 switch (type) {
671 case OUT_RESERVE:
672 if (!is_bss) {
673 nasm_error(ERR_WARNING, "uninitialized space declared in"
674 " %s,%s section: zeroing", s->segname, s->sectname);
676 sect_write(s, NULL, size);
677 } else
678 s->size += size;
680 break;
682 case OUT_RAWDATA:
683 sect_write(s, data, size);
684 break;
686 case OUT_ADDRESS:
688 int asize = abs((int)size);
690 addr = *(int64_t *)data;
691 if (section != NO_SEG) {
692 if (section % 2) {
693 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
694 " section base references");
695 } else if (wrt == NO_SEG) {
696 if (fmt.ptrsize == 8 && asize != 8) {
697 nasm_error(ERR_NONFATAL,
698 "Mach-O 64-bit format does not support"
699 " 32-bit absolute addresses");
700 } else {
701 add_reloc(s, section, addr, RL_ABS, asize);
703 } else {
704 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
705 " this use of WRT");
709 p = mydata;
710 WRITEADDR(p, addr, asize);
711 sect_write(s, mydata, asize);
712 break;
715 case OUT_REL1ADR:
716 case OUT_REL2ADR:
718 p = mydata;
719 offset = *(int64_t *)data;
720 addr = offset - size;
722 if (section != NO_SEG && section % 2) {
723 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
724 " section base references");
725 } else if (fmt.ptrsize == 8) {
726 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
727 " Macho-O relocation [2]");
728 } else if (wrt != NO_SEG) {
729 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
730 " this use of WRT");
731 wrt = NO_SEG; /* we can at least _try_ to continue */
732 } else {
733 addr += add_reloc(s, section, addr+size, RL_REL,
734 type == OUT_REL1ADR ? 1 : 2);
737 WRITESHORT(p, addr);
738 sect_write(s, mydata, type == OUT_REL1ADR ? 1 : 2);
739 break;
741 case OUT_REL4ADR:
742 case OUT_REL8ADR:
744 p = mydata;
745 offset = *(int64_t *)data;
746 addr = offset - size;
747 reltype = RL_REL;
749 if (section != NO_SEG && section % 2) {
750 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
751 " section base references");
752 } else if (wrt == NO_SEG) {
753 if (fmt.ptrsize == 8 &&
754 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
755 uint8_t opcode[2];
757 opcode[0] = opcode[1] = 0;
759 /* HACK: Retrieve instruction opcode */
760 if (likely(s->data->datalen >= 2)) {
761 saa_fread(s->data, s->data->datalen-2, opcode, 2);
762 } else if (s->data->datalen == 1) {
763 saa_fread(s->data, 0, opcode+1, 1);
766 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
767 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
768 /* Direct call, jmp, or jcc */
769 reltype = RL_BRANCH;
772 } else if (wrt == macho_gotpcrel_sect) {
773 reltype = RL_GOT;
775 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
776 s->data->datalen >= 3) {
777 uint8_t gotload[3];
779 /* HACK: Retrieve instruction opcode */
780 saa_fread(s->data, s->data->datalen-3, gotload, 3);
781 if ((gotload[0] & 0xf8) == 0x48 &&
782 gotload[1] == 0x8b &&
783 (gotload[2] & 0307) == 0005) {
784 /* movq <reg>,[rel sym wrt ..gotpcrel] */
785 reltype = RL_GOTLOAD;
788 } else if (wrt == macho_tlvp_sect) {
789 reltype = RL_TLV;
790 } else {
791 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
792 " this use of WRT");
793 /* continue with RL_REL */
796 addr += add_reloc(s, section, offset, reltype,
797 type == OUT_REL4ADR ? 4 : 8);
798 WRITELONG(p, addr);
799 sect_write(s, mydata, type == OUT_REL4ADR ? 4 : 8);
800 break;
802 default:
803 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
804 break;
808 /* Translation table from traditional Unix section names to Mach-O */
809 static const struct sectmap {
810 const char *nasmsect;
811 const char *segname;
812 const char *sectname;
813 const uint32_t flags;
814 } sectmap[] = {
815 {".text", "__TEXT", "__text",
816 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
817 {".data", "__DATA", "__data", S_REGULAR},
818 {".rodata", "__DATA", "__const", S_REGULAR},
819 {".bss", "__DATA", "__bss", S_ZEROFILL},
820 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
821 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
822 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
823 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
824 {NULL, NULL, NULL, 0}
827 #define NO_TYPE S_NASM_TYPE_MASK
829 /* Section type or attribute directives */
830 static const struct sect_attribs {
831 const char *name;
832 uint32_t flags;
833 } sect_attribs[] = {
834 { "data", S_REGULAR },
835 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
836 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
837 { "bss", S_ZEROFILL },
838 { "zerofill", S_ZEROFILL },
839 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
840 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
841 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
842 { "debug", NO_TYPE|S_ATTR_DEBUG },
843 { NULL, 0 }
846 static int32_t macho_section(char *name, int pass, int *bits)
848 char *sectionAttributes;
849 const struct sectmap *sm;
850 struct section *s;
851 const char *section, *segment;
852 uint32_t flags;
853 const struct sect_attribs *sa;
854 char *currentAttribute;
855 char *comma;
857 bool new_seg;
859 (void)pass;
861 /* Default to the appropriate number of bits. */
862 if (!name) {
863 *bits = fmt.ptrsize << 3;
864 name = ".text";
865 sectionAttributes = NULL;
866 } else {
867 sectionAttributes = name;
868 name = nasm_strsep(&sectionAttributes, " \t");
871 section = segment = NULL;
872 flags = 0;
874 comma = strchr(name, ',');
875 if (comma) {
876 int len;
878 *comma = '\0';
879 segment = name;
880 section = comma+1;
882 len = strlen(segment);
883 if (len == 0) {
884 nasm_error(ERR_NONFATAL, "empty segment name\n");
885 } else if (len > 16) {
886 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
889 len = strlen(section);
890 if (len == 0) {
891 nasm_error(ERR_NONFATAL, "empty section name\n");
892 } else if (len > 16) {
893 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
896 if (!strcmp(section, "__text")) {
897 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
898 S_ATTR_PURE_INSTRUCTIONS;
899 } else if (!strcmp(section, "__bss")) {
900 flags = S_ZEROFILL;
901 } else {
902 flags = S_REGULAR;
904 } else {
905 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
906 /* make lookup into section name translation table */
907 if (!strcmp(name, sm->nasmsect)) {
908 segment = sm->segname;
909 section = sm->sectname;
910 flags = sm->flags;
911 goto found;
914 nasm_error(ERR_NONFATAL, "unknown section name\n");
915 return NO_SEG;
918 found:
919 /* try to find section with that name, or create it */
920 s = find_or_add_section(segment, section);
921 new_seg = is_new_section(s);
923 /* initialize it if it is a brand new section */
924 if (new_seg) {
925 *sectstail = s;
926 sectstail = &s->next;
928 s->data = saa_init(1L);
929 s->fileindex = ++seg_nsects;
930 s->align = -1;
931 s->pad = -1;
932 s->offset = -1;
933 s->by_name = false;
935 s->size = 0;
936 s->nreloc = 0;
937 s->flags = flags;
940 if (comma)
941 *comma = ','; /* Restore comma */
943 s->by_name = s->by_name || comma; /* Was specified by name */
945 flags = NO_TYPE;
947 while (sectionAttributes &&
948 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
949 if (!*currentAttribute)
950 continue;
952 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
953 char *end;
954 int newAlignment, value;
956 value = strtoul(currentAttribute + 6, (char**)&end, 0);
957 newAlignment = alignlog2_32(value);
959 if (0 != *end) {
960 nasm_error(ERR_NONFATAL,
961 "unknown or missing alignment value \"%s\" "
962 "specified for section \"%s\"",
963 currentAttribute + 6,
964 name);
965 } else if (0 > newAlignment) {
966 nasm_error(ERR_NONFATAL,
967 "alignment of %d (for section \"%s\") is not "
968 "a power of two",
969 value,
970 name);
973 if (s->align < newAlignment)
974 s->align = newAlignment;
975 } else {
976 for (sa = sect_attribs; sa->name; sa++) {
977 if (!nasm_stricmp(sa->name, currentAttribute)) {
978 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
979 flags = (flags & ~S_NASM_TYPE_MASK)
980 | (sa->flags & S_NASM_TYPE_MASK);
982 flags |= sa->flags & ~S_NASM_TYPE_MASK;
983 break;
987 if (!sa->name) {
988 nasm_error(ERR_NONFATAL,
989 "unknown section attribute %s for section %s",
990 currentAttribute, name);
995 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
996 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
997 nasm_error(ERR_NONFATAL,
998 "inconsistent section attributes for section %s\n",
999 name);
1000 } else {
1001 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
1003 } else {
1004 s->flags |= flags & ~S_NASM_TYPE_MASK;
1007 return s->subsection;
1010 static int32_t macho_herelabel(const char *name, enum label_type type,
1011 int32_t section, int32_t *subsection)
1013 struct section *s;
1014 int32_t subsec;
1015 (void)name;
1017 if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
1018 return section;
1020 /* No subsection only for local labels */
1021 if (type == LBL_LOCAL)
1022 return section;
1024 s = get_section_by_index(section);
1025 if (!s)
1026 return section;
1028 subsec = *subsection;
1029 if (subsec == NO_SEG) {
1030 /* Allocate a new subsection index */
1031 subsec = *subsection = seg_alloc();
1032 section_by_index = raa_write_ptr(section_by_index, subsec >> 1, s);
1035 s->subsection = subsec;
1036 return subsec;
1039 static void macho_symdef(char *name, int32_t section, int64_t offset,
1040 int is_global, char *special)
1042 struct symbol *sym;
1043 struct section *s;
1044 bool special_used = false;
1046 #if defined(DEBUG) && DEBUG>2
1047 nasm_error(ERR_DEBUG,
1048 " macho_symdef: %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
1049 name, section, offset, is_global, special);
1050 #endif
1052 if (is_global == 3) {
1053 if (special) {
1054 int n = strcspn(special, " \t");
1056 if (!nasm_strnicmp(special, "private_extern", n)) {
1057 for (sym = syms; sym != NULL; sym = sym->next) {
1058 if (!strcmp(name, sym->name)) {
1059 if (sym->type & N_PEXT)
1060 return; /* nothing to be done */
1061 else
1062 break;
1067 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1068 "(yet) support forward reference fixups.");
1069 return;
1072 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1074 * This is a NASM special symbol. We never allow it into
1075 * the Macho-O symbol table, even if it's a valid one. If it
1076 * _isn't_ a valid one, we should barf immediately.
1078 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1079 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1080 return;
1083 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1084 sym->next = NULL;
1085 symstail = &sym->next;
1087 sym->name = name;
1088 sym->strx = strslen;
1089 sym->type = 0;
1090 sym->desc = 0;
1091 sym->symv[0].key = offset;
1092 sym->symv[1].key = offset;
1093 sym->initial_snum = -1;
1095 /* external and common symbols get N_EXT */
1096 if (is_global != 0) {
1097 sym->type |= N_EXT;
1099 if (is_global == 1) {
1100 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1101 if (special) {
1102 int n = strcspn(special, " \t");
1104 if (!nasm_strnicmp(special, "private_extern", n))
1105 sym->type |= N_PEXT;
1106 else
1107 nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'", n, special);
1109 special_used = true;
1112 if (section == NO_SEG) {
1113 /* symbols in no section get absolute */
1114 sym->type |= N_ABS;
1115 sym->sect = NO_SECT;
1117 s = &absolute_sect;
1118 } else {
1119 s = get_section_by_index(section);
1121 sym->type |= N_SECT;
1123 /* get the in-file index of the section the symbol was defined in */
1124 sym->sect = s ? s->fileindex : NO_SECT;
1126 /* track the initially allocated symbol number for use in future fix-ups */
1127 sym->initial_snum = nsyms;
1129 if (!s) {
1130 /* remember symbol number of references to external
1131 ** symbols, this works because every external symbol gets
1132 ** its own section number allocated internally by nasm and
1133 ** can so be used as a key */
1134 extsyms = raa_write(extsyms, section, nsyms);
1136 switch (is_global) {
1137 case 1:
1138 case 2:
1139 /* there isn't actually a difference between global
1140 ** and common symbols, both even have their size in
1141 ** sym->symv[0].key */
1142 sym->type = N_EXT;
1143 break;
1145 default:
1146 /* give an error on unfound section if it's not an
1147 ** external or common symbol (assemble_file() does a
1148 ** seg_alloc() on every call for them) */
1149 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1150 break;
1155 if (s) {
1156 s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1157 if (is_global)
1158 s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1161 ++nsyms;
1163 if (special && !special_used)
1164 nasm_error(ERR_NONFATAL, "no special symbol features supported here");
1167 static void macho_sectalign(int32_t seg, unsigned int value)
1169 struct section *s;
1170 int align;
1172 nasm_assert(!(seg & 1));
1174 s = get_section_by_index(seg);
1176 if (!s || !is_power2(value))
1177 return;
1179 align = alignlog2_32(value);
1180 if (s->align < align)
1181 s->align = align;
1184 extern macros_t macho_stdmac[];
1186 /* Comparison function for qsort symbol layout. */
1187 static int layout_compare (const struct symbol **s1,
1188 const struct symbol **s2)
1190 return (strcmp ((*s1)->name, (*s2)->name));
1193 /* The native assembler does a few things in a similar function
1195 * Remove temporary labels
1196 * Sort symbols according to local, external, undefined (by name)
1197 * Order the string table
1199 We do not remove temporary labels right now.
1201 numsyms is the total number of symbols we have. strtabsize is the
1202 number entries in the string table. */
1204 static void macho_layout_symbols (uint32_t *numsyms,
1205 uint32_t *strtabsize)
1207 struct symbol *sym, **symp;
1208 uint32_t i,j;
1210 *numsyms = 0;
1211 *strtabsize = sizeof (char);
1213 symp = &syms;
1215 while ((sym = *symp)) {
1216 /* Undefined symbols are now external. */
1217 if (sym->type == N_UNDF)
1218 sym->type |= N_EXT;
1220 if ((sym->type & N_EXT) == 0) {
1221 sym->snum = *numsyms;
1222 *numsyms = *numsyms + 1;
1223 nlocalsym++;
1225 else {
1226 if ((sym->type & N_TYPE) != N_UNDF) {
1227 nextdefsym++;
1228 } else {
1229 nundefsym++;
1232 /* If we handle debug info we'll want
1233 to check for it here instead of just
1234 adding the symbol to the string table. */
1235 sym->strx = *strtabsize;
1236 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1237 *strtabsize += strlen(sym->name) + 1;
1239 symp = &(sym->next);
1242 /* Next, sort the symbols. Most of this code is a direct translation from
1243 the Apple cctools symbol layout. We need to keep compatibility with that. */
1244 /* Set the indexes for symbol groups into the symbol table */
1245 ilocalsym = 0;
1246 iextdefsym = nlocalsym;
1247 iundefsym = nlocalsym + nextdefsym;
1249 /* allocate arrays for sorting externals by name */
1250 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1251 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1253 i = 0;
1254 j = 0;
1256 symp = &syms;
1258 while ((sym = *symp)) {
1260 if((sym->type & N_EXT) == 0) {
1261 sym->strx = *strtabsize;
1262 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1263 *strtabsize += strlen(sym->name) + 1;
1265 else {
1266 if ((sym->type & N_TYPE) != N_UNDF) {
1267 extdefsyms[i++] = sym;
1268 } else {
1269 undefsyms[j++] = sym;
1272 symp = &(sym->next);
1275 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1276 (int (*)(const void *, const void *))layout_compare);
1277 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1278 (int (*)(const void *, const void *))layout_compare);
1280 for(i = 0; i < nextdefsym; i++) {
1281 extdefsyms[i]->snum = *numsyms;
1282 *numsyms += 1;
1284 for(j = 0; j < nundefsym; j++) {
1285 undefsyms[j]->snum = *numsyms;
1286 *numsyms += 1;
1290 /* Calculate some values we'll need for writing later. */
1292 static void macho_calculate_sizes (void)
1294 struct section *s;
1295 int fi;
1297 /* count sections and calculate in-memory and in-file offsets */
1298 for (s = sects; s != NULL; s = s->next) {
1299 uint64_t newaddr;
1301 /* recalculate segment address based on alignment and vm size */
1302 s->addr = seg_vmsize;
1304 /* we need section alignment to calculate final section address */
1305 if (s->align == -1)
1306 s->align = DEFAULT_SECTION_ALIGNMENT;
1308 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1309 s->addr = newaddr;
1311 seg_vmsize = newaddr + s->size;
1313 /* zerofill sections aren't actually written to the file */
1314 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1316 * LLVM/Xcode as always aligns the section data to 4
1317 * bytes; there is a comment in the LLVM source code that
1318 * perhaps aligning to pointer size would be better.
1320 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1321 s->offset = seg_filesize + s->pad;
1322 seg_filesize += s->size + s->pad;
1324 /* filesize and vmsize needs to be aligned */
1325 seg_vmsize += s->pad;
1329 /* calculate size of all headers, load commands and sections to
1330 ** get a pointer to the start of all the raw data */
1331 if (seg_nsects > 0) {
1332 ++head_ncmds;
1333 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1336 if (nsyms > 0) {
1337 ++head_ncmds;
1338 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1341 if (seg_nsects > MAX_SECT) {
1342 nasm_fatal(0, "MachO output is limited to %d sections\n",
1343 MAX_SECT);
1346 /* Create a table of sections by file index to avoid linear search */
1347 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1348 sectstab[NO_SECT] = &absolute_sect;
1349 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1350 sectstab[fi] = s;
1353 /* Write out the header information for the file. */
1355 static void macho_write_header (void)
1357 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1358 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1359 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1360 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1361 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1362 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1363 fwriteint32_t(head_flags, ofile); /* flags, if any */
1364 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1367 /* Write out the segment load command at offset. */
1369 static uint32_t macho_write_segment (uint64_t offset)
1371 uint64_t rel_base = alignptr(offset + seg_filesize);
1372 uint32_t s_reloff = 0;
1373 struct section *s;
1375 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1377 /* size of load command including section load commands */
1378 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1379 ofile);
1381 /* in an MH_OBJECT file all sections are in one unnamed (name
1382 ** all zeros) segment */
1383 fwritezero(16, ofile);
1384 fwriteptr(0, ofile); /* in-memory offset */
1385 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1386 fwriteptr(offset, ofile); /* in-file offset to data */
1387 fwriteptr(seg_filesize, ofile); /* in-file size */
1388 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1389 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1390 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1391 fwriteint32_t(0, ofile); /* no flags */
1393 /* emit section headers */
1394 for (s = sects; s != NULL; s = s->next) {
1395 if (s->nreloc) {
1396 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1397 s->flags |= S_ATTR_LOC_RELOC;
1398 if (s->extreloc)
1399 s->flags |= S_ATTR_EXT_RELOC;
1400 } else if (!xstrncmp(s->segname, "__DATA") &&
1401 !xstrncmp(s->sectname, "__const") &&
1402 !s->by_name &&
1403 !get_section_by_name("__TEXT", "__const")) {
1405 * The MachO equivalent to .rodata can be either
1406 * __DATA,__const or __TEXT,__const; the latter only if
1407 * there are no relocations. However, when mixed it is
1408 * better to specify the segments explicitly.
1410 xstrncpy(s->segname, "__TEXT");
1413 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1414 nasm_write(s->segname, sizeof(s->segname), ofile);
1415 fwriteptr(s->addr, ofile);
1416 fwriteptr(s->size, ofile);
1418 /* dummy data for zerofill sections or proper values */
1419 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1420 nasm_assert(s->pad != (uint32_t)-1);
1421 offset += s->pad;
1422 fwriteint32_t(offset, ofile);
1423 offset += s->size;
1424 /* Write out section alignment, as a power of two.
1425 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1426 fwriteint32_t(s->align, ofile);
1427 /* To be compatible with cctools as we emit
1428 a zero reloff if we have no relocations. */
1429 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1430 fwriteint32_t(s->nreloc, ofile);
1432 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1433 } else {
1434 fwriteint32_t(0, ofile);
1435 fwriteint32_t(s->align, ofile);
1436 fwriteint32_t(0, ofile);
1437 fwriteint32_t(0, ofile);
1440 fwriteint32_t(s->flags, ofile); /* flags */
1441 fwriteint32_t(0, ofile); /* reserved */
1442 fwriteptr(0, ofile); /* reserved */
1445 rel_padcnt = rel_base - offset;
1446 offset = rel_base + s_reloff;
1448 return offset;
1451 /* For a given chain of relocs r, write out the entire relocation
1452 chain to the object file. */
1454 static void macho_write_relocs (struct reloc *r)
1456 while (r) {
1457 uint32_t word2;
1459 fwriteint32_t(r->addr, ofile); /* reloc offset */
1461 word2 = r->snum;
1462 word2 |= r->pcrel << 24;
1463 word2 |= r->length << 25;
1464 word2 |= r->ext << 27;
1465 word2 |= r->type << 28;
1466 fwriteint32_t(word2, ofile); /* reloc data */
1467 r = r->next;
1471 /* Write out the section data. */
1472 static void macho_write_section (void)
1474 struct section *s;
1475 struct reloc *r;
1476 uint8_t *p;
1477 int32_t len;
1478 int64_t l;
1479 union offset {
1480 uint64_t val;
1481 uint8_t buf[8];
1482 } blk;
1484 for (s = sects; s != NULL; s = s->next) {
1485 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1486 continue;
1488 /* Like a.out Mach-O references things in the data or bss
1489 * sections by addresses which are actually relative to the
1490 * start of the _text_ section, in the _file_. See outaout.c
1491 * for more information. */
1492 saa_rewind(s->data);
1493 for (r = s->relocs; r != NULL; r = r->next) {
1494 len = (uint32_t)1 << r->length;
1495 if (len > 4) /* Can this ever be an issue?! */
1496 len = 8;
1497 blk.val = 0;
1498 saa_fread(s->data, r->addr, blk.buf, len);
1500 /* get offset based on relocation type */
1501 #ifdef WORDS_LITTLEENDIAN
1502 l = blk.val;
1503 #else
1504 l = blk.buf[0];
1505 l += ((int64_t)blk.buf[1]) << 8;
1506 l += ((int64_t)blk.buf[2]) << 16;
1507 l += ((int64_t)blk.buf[3]) << 24;
1508 l += ((int64_t)blk.buf[4]) << 32;
1509 l += ((int64_t)blk.buf[5]) << 40;
1510 l += ((int64_t)blk.buf[6]) << 48;
1511 l += ((int64_t)blk.buf[7]) << 56;
1512 #endif
1514 /* If the relocation is internal add to the current section
1515 offset. Otherwise the only value we need is the symbol
1516 offset which we already have. The linker takes care
1517 of the rest of the address. */
1518 if (!r->ext) {
1519 /* generate final address by section address and offset */
1520 nasm_assert(r->snum <= seg_nsects);
1521 l += sectstab[r->snum]->addr;
1522 if (r->pcrel)
1523 l -= s->addr;
1524 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1525 l -= s->addr;
1528 /* write new offset back */
1529 p = blk.buf;
1530 WRITEDLONG(p, l);
1531 saa_fwrite(s->data, r->addr, blk.buf, len);
1534 /* dump the section data to file */
1535 fwritezero(s->pad, ofile);
1536 saa_fpwrite(s->data, ofile);
1539 /* pad last section up to reloc entries on pointer boundary */
1540 fwritezero(rel_padcnt, ofile);
1542 /* emit relocation entries */
1543 for (s = sects; s != NULL; s = s->next)
1544 macho_write_relocs (s->relocs);
1547 /* Write out the symbol table. We should already have sorted this
1548 before now. */
1549 static void macho_write_symtab (void)
1551 struct symbol *sym;
1552 uint64_t i;
1554 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1556 for (sym = syms; sym != NULL; sym = sym->next) {
1557 if ((sym->type & N_EXT) == 0) {
1558 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1559 nasm_write(&sym->type, 1, ofile); /* symbol type */
1560 nasm_write(&sym->sect, 1, ofile); /* section */
1561 fwriteint16_t(sym->desc, ofile); /* description */
1563 /* Fix up the symbol value now that we know the final section
1564 sizes. */
1565 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1566 nasm_assert(sym->sect <= seg_nsects);
1567 sym->symv[0].key += sectstab[sym->sect]->addr;
1570 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1574 for (i = 0; i < nextdefsym; i++) {
1575 sym = extdefsyms[i];
1576 fwriteint32_t(sym->strx, ofile);
1577 nasm_write(&sym->type, 1, ofile); /* symbol type */
1578 nasm_write(&sym->sect, 1, ofile); /* section */
1579 fwriteint16_t(sym->desc, ofile); /* description */
1581 /* Fix up the symbol value now that we know the final section
1582 sizes. */
1583 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1584 nasm_assert(sym->sect <= seg_nsects);
1585 sym->symv[0].key += sectstab[sym->sect]->addr;
1588 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1591 for (i = 0; i < nundefsym; i++) {
1592 sym = undefsyms[i];
1593 fwriteint32_t(sym->strx, ofile);
1594 nasm_write(&sym->type, 1, ofile); /* symbol type */
1595 nasm_write(&sym->sect, 1, ofile); /* section */
1596 fwriteint16_t(sym->desc, ofile); /* description */
1598 /* Fix up the symbol value now that we know the final section
1599 sizes. */
1600 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1601 nasm_assert(sym->sect <= seg_nsects);
1602 sym->symv[0].key += sectstab[sym->sect]->addr;
1605 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1610 /* Fixup the snum in the relocation entries, we should be
1611 doing this only for externally referenced symbols. */
1612 static void macho_fixup_relocs (struct reloc *r)
1614 struct symbol *sym;
1616 while (r != NULL) {
1617 if (r->ext) {
1618 for (sym = syms; sym != NULL; sym = sym->next) {
1619 if (sym->initial_snum == r->snum) {
1620 r->snum = sym->snum;
1621 break;
1625 r = r->next;
1629 /* Write out the object file. */
1631 static void macho_write (void)
1633 uint64_t offset = 0;
1635 /* mach-o object file structure:
1637 ** mach header
1638 ** uint32_t magic
1639 ** int cpu type
1640 ** int cpu subtype
1641 ** uint32_t mach file type
1642 ** uint32_t number of load commands
1643 ** uint32_t size of all load commands
1644 ** (includes section struct size of segment command)
1645 ** uint32_t flags
1647 ** segment command
1648 ** uint32_t command type == LC_SEGMENT[_64]
1649 ** uint32_t size of load command
1650 ** (including section load commands)
1651 ** char[16] segment name
1652 ** pointer in-memory offset
1653 ** pointer in-memory size
1654 ** pointer in-file offset to data area
1655 ** pointer in-file size
1656 ** (in-memory size excluding zerofill sections)
1657 ** int maximum vm protection
1658 ** int initial vm protection
1659 ** uint32_t number of sections
1660 ** uint32_t flags
1662 ** section commands
1663 ** char[16] section name
1664 ** char[16] segment name
1665 ** pointer in-memory offset
1666 ** pointer in-memory size
1667 ** uint32_t in-file offset
1668 ** uint32_t alignment
1669 ** (irrelevant in MH_OBJECT)
1670 ** uint32_t in-file offset of relocation entires
1671 ** uint32_t number of relocations
1672 ** uint32_t flags
1673 ** uint32_t reserved
1674 ** uint32_t reserved
1676 ** symbol table command
1677 ** uint32_t command type == LC_SYMTAB
1678 ** uint32_t size of load command
1679 ** uint32_t symbol table offset
1680 ** uint32_t number of symbol table entries
1681 ** uint32_t string table offset
1682 ** uint32_t string table size
1684 ** raw section data
1686 ** padding to pointer boundary
1688 ** relocation data (struct reloc)
1689 ** int32_t offset
1690 ** uint data (symbolnum, pcrel, length, extern, type)
1692 ** symbol table data (struct nlist)
1693 ** int32_t string table entry number
1694 ** uint8_t type
1695 ** (extern, absolute, defined in section)
1696 ** uint8_t section
1697 ** (0 for global symbols, section number of definition (>= 1, <=
1698 ** 254) for local symbols, size of variable for common symbols
1699 ** [type == extern])
1700 ** int16_t description
1701 ** (for stab debugging format)
1702 ** pointer value (i.e. file offset) of symbol or stab offset
1704 ** string table data
1705 ** list of null-terminated strings
1708 /* Emit the Mach-O header. */
1709 macho_write_header();
1711 offset = fmt.header_size + head_sizeofcmds;
1713 /* emit the segment load command */
1714 if (seg_nsects > 0)
1715 offset = macho_write_segment (offset);
1716 else
1717 nasm_error(ERR_WARNING, "no sections?");
1719 if (nsyms > 0) {
1720 /* write out symbol command */
1721 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1722 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1723 fwriteint32_t(offset, ofile); /* symbol table offset */
1724 fwriteint32_t(nsyms, ofile); /* number of symbol
1725 ** table entries */
1726 offset += nsyms * fmt.nlist_size;
1727 fwriteint32_t(offset, ofile); /* string table offset */
1728 fwriteint32_t(strslen, ofile); /* string table size */
1731 /* emit section data */
1732 if (seg_nsects > 0)
1733 macho_write_section ();
1735 /* emit symbol table if we have symbols */
1736 if (nsyms > 0)
1737 macho_write_symtab ();
1739 /* we don't need to pad here, we are already aligned */
1741 /* emit string table */
1742 saa_fpwrite(strs, ofile);
1744 /* We do quite a bit here, starting with finalizing all of the data
1745 for the object file, writing, and then freeing all of the data from
1746 the file. */
1748 static void macho_cleanup(void)
1750 struct section *s;
1751 struct reloc *r;
1752 struct symbol *sym;
1754 dfmt->cleanup();
1756 /* Sort all symbols. */
1757 macho_layout_symbols (&nsyms, &strslen);
1759 /* Fixup relocation entries */
1760 for (s = sects; s != NULL; s = s->next) {
1761 macho_fixup_relocs (s->relocs);
1764 /* First calculate and finalize needed values. */
1765 macho_calculate_sizes();
1766 macho_write();
1768 /* free up everything */
1769 while (sects->next) {
1770 s = sects;
1771 sects = sects->next;
1773 saa_free(s->data);
1774 while (s->relocs != NULL) {
1775 r = s->relocs;
1776 s->relocs = s->relocs->next;
1777 nasm_free(r);
1780 nasm_free(s);
1783 saa_free(strs);
1785 raa_free(extsyms);
1787 while (syms) {
1788 sym = syms;
1789 syms = syms->next;
1790 nasm_free (sym);
1793 nasm_free(extdefsyms);
1794 nasm_free(undefsyms);
1795 nasm_free(sectstab);
1796 raa_free(section_by_index);
1797 hash_free(&section_by_name);
1800 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1802 struct section *s;
1803 int32_t nasm_seg;
1804 int64_t offset;
1806 if (!lookup_label(label, &nasm_seg, &offset)) {
1807 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1808 return false;
1811 s = get_section_by_index(nasm_seg);
1812 if (!s) {
1813 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1814 return false;
1817 s->flags |= flags;
1818 return true;
1822 * Mark a symbol for no dead stripping
1824 static enum directive_result macho_no_dead_strip(const char *labels)
1826 char *s, *p, *ep;
1827 char ec;
1828 enum directive_result rv = DIRR_ERROR;
1829 bool real = passn > 1;
1831 p = s = nasm_strdup(labels);
1832 while (*p) {
1833 ep = nasm_skip_identifier(p);
1834 if (!ep) {
1835 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1836 goto err;
1838 ec = *ep;
1839 if (ec && ec != ',' && !nasm_isspace(ec)) {
1840 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1841 goto err;
1843 *ep = '\0';
1844 if (real) {
1845 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1846 rv = DIRR_ERROR;
1848 *ep = ec;
1849 p = nasm_skip_spaces(ep);
1850 if (*p == ',')
1851 p = nasm_skip_spaces(++p);
1854 rv = DIRR_OK;
1856 err:
1857 nasm_free(s);
1858 return rv;
1862 * Mach-O pragmas
1864 static enum directive_result
1865 macho_pragma(const struct pragma *pragma)
1867 bool real = passn > 1;
1869 switch (pragma->opcode) {
1870 case D_SUBSECTIONS_VIA_SYMBOLS:
1871 if (*pragma->tail)
1872 return DIRR_BADPARAM;
1874 if (real)
1875 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1877 return DIRR_OK;
1879 case D_NO_DEAD_STRIP:
1880 return macho_no_dead_strip(pragma->tail);
1882 default:
1883 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1887 static const struct pragma_facility macho_pragma_list[] = {
1888 { "macho", macho_pragma },
1889 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1892 static void macho_dbg_generate(void)
1894 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1895 size_t saa_len = 0, high_addr = 0, total_len = 0;
1896 struct section *p_section = NULL;
1897 /* calculated at debug_str and referenced at debug_info */
1898 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1900 /* debug section defines */
1902 int bits = 0;
1903 macho_section(".debug_abbrev", 0, &bits);
1904 macho_section(".debug_info", 0, &bits);
1905 macho_section(".debug_line", 0, &bits);
1906 macho_section(".debug_str", 0, &bits);
1909 /* dw section walk to find high_addr and total_len */
1911 struct dw_sect_list *p_sect;
1913 list_for_each(p_sect, dw_head_sect) {
1914 uint64_t offset = get_section_by_index(p_sect->section)->size;
1915 struct SAA *p_linep = p_sect->psaa;
1917 saa_write8(p_linep, 2); /* std op 2 */
1918 saa_write8(p_linep, offset - p_sect->offset);
1919 saa_write8(p_linep, DW_LNS_extended_op);
1920 saa_write8(p_linep, 1); /* operand length */
1921 saa_write8(p_linep, DW_LNE_end_sequence);
1923 total_len += p_linep->datalen;
1924 high_addr += offset;
1928 /* debug line */
1930 struct dw_sect_list *p_sect;
1931 size_t linep_off, buf_size;
1932 struct SAA *p_lines = saa_init(1L);
1933 struct dir_list *p_dir;
1934 struct file_list *p_file;
1936 p_section = get_section_by_name("__DWARF", "__debug_line");
1937 nasm_assert(p_section != NULL);
1939 saa_write8(p_lines, 1); /* minimum instruction length */
1940 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1941 saa_write8(p_lines, DW_LN_BASE); /* line base */
1942 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1943 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1944 saa_write8(p_lines, 0); /* std opcode 1 length */
1945 saa_write8(p_lines, 1); /* std opcode 2 length */
1946 saa_write8(p_lines, 1); /* std opcode 3 length */
1947 saa_write8(p_lines, 1); /* std opcode 4 length */
1948 saa_write8(p_lines, 1); /* std opcode 5 length */
1949 saa_write8(p_lines, 0); /* std opcode 6 length */
1950 saa_write8(p_lines, 0); /* std opcode 7 length */
1951 saa_write8(p_lines, 0); /* std opcode 8 length */
1952 saa_write8(p_lines, 1); /* std opcode 9 length */
1953 saa_write8(p_lines, 0); /* std opcode 10 length */
1954 saa_write8(p_lines, 0); /* std opcode 11 length */
1955 saa_write8(p_lines, 1); /* std opcode 12 length */
1956 list_for_each(p_dir, dw_head_dir) {
1957 saa_wcstring(p_lines, p_dir->dir_name);
1959 saa_write8(p_lines, 0); /* end of table */
1961 list_for_each(p_file, dw_head_file) {
1962 saa_wcstring(p_lines, p_file->file_name);
1963 saa_write8(p_lines, p_file->dir->dir); /* directory id */
1964 saa_write8(p_lines, 0); /* time */
1965 saa_write8(p_lines, 0); /* size */
1967 saa_write8(p_lines, 0); /* end of table */
1969 linep_off = p_lines->datalen;
1970 /* 10 bytes for initial & prolong length, and dwarf version info */
1971 buf_size = saa_len = linep_off + total_len + 10;
1972 p_buf_base = p_buf = nasm_malloc(buf_size);
1974 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1975 WRITESHORT(p_buf, 2); /* dwarf version */
1976 WRITELONG(p_buf, linep_off); /* prolong length */
1978 saa_rnbytes(p_lines, p_buf, linep_off);
1979 p_buf += linep_off;
1980 saa_free(p_lines);
1982 list_for_each(p_sect, dw_head_sect) {
1983 struct SAA *p_linep = p_sect->psaa;
1985 saa_len = p_linep->datalen;
1986 saa_rnbytes(p_linep, p_buf, saa_len);
1987 p_buf += saa_len;
1989 saa_free(p_linep);
1992 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1994 nasm_free(p_buf_base);
1997 /* string section */
1999 struct SAA *p_str = saa_init(1L);
2000 char *cur_path = nasm_realpath(module_name);
2001 char *cur_file = nasm_basename(cur_path);
2002 char *cur_dir = nasm_dirname(cur_path);
2004 p_section = get_section_by_name("__DWARF", "__debug_str");
2005 nasm_assert(p_section != NULL);
2007 producer_str_offset = 0;
2008 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
2009 dir_str_offset += saa_wcstring(p_str, cur_file);
2010 saa_wcstring(p_str, cur_dir);
2012 saa_len = p_str->datalen;
2013 p_buf = nasm_malloc(saa_len);
2014 saa_rnbytes(p_str, p_buf, saa_len);
2015 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2017 nasm_free(cur_path);
2018 nasm_free(cur_file);
2019 nasm_free(cur_dir);
2020 saa_free(p_str);
2021 nasm_free(p_buf);
2024 /* debug info */
2026 struct SAA *p_info = saa_init(1L);
2028 p_section = get_section_by_name("__DWARF", "__debug_info");
2029 nasm_assert(p_section != NULL);
2031 /* size will be overwritten once determined, so skip in p_info layout */
2032 saa_write16(p_info, 2); /* dwarf version */
2033 saa_write32(p_info, 0); /* offset info abbrev */
2034 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
2036 saa_write8(p_info, 1); /* abbrev entry number */
2038 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
2039 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
2040 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
2041 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
2042 saa_write32(p_info, 0); /* DW_AT_stmt_list */
2044 if (ofmt == &of_macho64) {
2045 saa_write64(p_info, 0); /* DW_AT_low_pc */
2046 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
2047 } else {
2048 saa_write32(p_info, 0); /* DW_AT_low_pc */
2049 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
2052 saa_write8(p_info, 2); /* abbrev entry number */
2054 if (ofmt == &of_macho64) {
2055 saa_write64(p_info, 0); /* DW_AT_low_pc */
2056 saa_write64(p_info, 0); /* DW_AT_frame_base */
2057 } else {
2058 saa_write32(p_info, 0); /* DW_AT_low_pc */
2059 saa_write32(p_info, 0); /* DW_AT_frame_base */
2061 saa_write8(p_info, DW_END_default);
2063 saa_len = p_info->datalen;
2064 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
2066 WRITELONG(p_buf, saa_len);
2067 saa_rnbytes(p_info, p_buf, saa_len);
2068 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
2070 saa_free(p_info);
2071 nasm_free(p_buf_base);
2074 /* abbrev section */
2076 struct SAA *p_abbrev = saa_init(1L);
2078 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2079 nasm_assert(p_section != NULL);
2081 saa_write8(p_abbrev, 1); /* entry number */
2083 saa_write8(p_abbrev, DW_TAG_compile_unit);
2084 saa_write8(p_abbrev, DW_CHILDREN_yes);
2086 saa_write8(p_abbrev, DW_AT_producer);
2087 saa_write8(p_abbrev, DW_FORM_strp);
2089 saa_write8(p_abbrev, DW_AT_language);
2090 saa_write8(p_abbrev, DW_FORM_data2);
2092 saa_write8(p_abbrev, DW_AT_name);
2093 saa_write8(p_abbrev, DW_FORM_strp);
2095 saa_write8(p_abbrev, DW_AT_comp_dir);
2096 saa_write8(p_abbrev, DW_FORM_strp);
2098 saa_write8(p_abbrev, DW_AT_stmt_list);
2099 saa_write8(p_abbrev, DW_FORM_data4);
2101 saa_write8(p_abbrev, DW_AT_low_pc);
2102 saa_write8(p_abbrev, DW_FORM_addr);
2104 saa_write8(p_abbrev, DW_AT_high_pc);
2105 saa_write8(p_abbrev, DW_FORM_addr);
2107 saa_write16(p_abbrev, DW_END_default);
2109 saa_write8(p_abbrev, 2); /* entry number */
2111 saa_write8(p_abbrev, DW_TAG_subprogram);
2112 saa_write8(p_abbrev, DW_CHILDREN_no);
2114 saa_write8(p_abbrev, DW_AT_low_pc);
2115 saa_write8(p_abbrev, DW_FORM_addr);
2117 saa_write8(p_abbrev, DW_AT_frame_base);
2118 saa_write8(p_abbrev, DW_FORM_addr);
2120 saa_write16(p_abbrev, DW_END_default);
2122 saa_write8(p_abbrev, 0); /* Terminal zero entry */
2124 saa_len = p_abbrev->datalen;
2126 p_buf = nasm_malloc(saa_len);
2128 saa_rnbytes(p_abbrev, p_buf, saa_len);
2129 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2131 saa_free(p_abbrev);
2132 nasm_free(p_buf);
2136 static void new_file_list (const char *file_name, const char *dir_name)
2138 struct dir_list *dir_list;
2139 bool need_new_dir_list = true;
2141 nasm_new(dw_cur_file);
2142 dw_cur_file->file = ++dw_num_files;
2143 dw_cur_file->file_name = file_name;
2144 if(!dw_head_file) {
2145 dw_head_file = dw_cur_file;
2146 } else {
2147 *dw_last_file_next = dw_cur_file;
2149 dw_last_file_next = &(dw_cur_file->next);
2151 if(dw_head_dir) {
2152 list_for_each(dir_list, dw_head_dir) {
2153 if(!(strcmp(dir_name, dir_list->dir_name))) {
2154 dw_cur_file->dir = dir_list;
2155 need_new_dir_list = false;
2156 break;
2161 if(need_new_dir_list)
2163 nasm_new(dir_list);
2164 dir_list->dir = dw_num_dirs++;
2165 dir_list->dir_name = dir_name;
2166 if(!dw_head_dir) {
2167 dw_head_dir = dir_list;
2168 } else {
2169 *dw_last_dir_next = dir_list;
2171 dw_last_dir_next = &(dir_list->next);
2172 dw_cur_file->dir = dir_list;
2176 static void macho_dbg_init(void)
2180 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2182 bool need_new_list = true;
2183 const char *cur_file = nasm_basename(file_name);
2184 const char *cur_dir = nasm_dirname(file_name);
2185 (void)segto;
2187 if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2188 strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2189 if(dw_head_file) {
2190 struct file_list *match;
2192 list_for_each(match, dw_head_file) {
2193 if(!(strcmp(cur_file, match->file_name)) &&
2194 !(strcmp(cur_dir, match->dir->dir_name))) {
2195 dw_cur_file = match;
2196 dw_cur_file->dir = match->dir;
2197 need_new_list = false;
2198 break;
2203 if(need_new_list) {
2204 new_file_list(cur_file, cur_dir);
2208 dbg_immcall = true;
2209 cur_line = line_num;
2212 static void macho_dbg_output(int type, void *param)
2214 struct section_info *sinfo_param = (struct section_info *)param;
2215 int32_t secto = sinfo_param->secto;
2216 bool need_new_sect = false;
2217 struct SAA *p_linep = NULL;
2218 (void)type;
2220 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2221 need_new_sect = true;
2222 if(dw_head_sect) {
2223 struct dw_sect_list *match = dw_head_sect;
2224 uint32_t idx = 0;
2226 for(; idx < dw_num_sects; idx++) {
2227 if(match->section == secto) {
2228 dw_cur_sect = match;
2229 need_new_sect = false;
2230 break;
2232 match = match->next;
2237 if(need_new_sect) {
2238 nasm_new(dw_cur_sect);
2239 dw_num_sects ++;
2240 p_linep = dw_cur_sect->psaa = saa_init(1L);
2241 dw_cur_sect->line = dw_cur_sect->file = 1;
2242 dw_cur_sect->offset = 0;
2243 dw_cur_sect->next = NULL;
2244 dw_cur_sect->section = secto;
2246 saa_write8(p_linep, DW_LNS_extended_op);
2247 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2248 saa_write8(p_linep, DW_LNE_set_address);
2249 if (ofmt == &of_macho64) {
2250 saa_write64(p_linep, 0);
2251 } else {
2252 saa_write32(p_linep, 0);
2255 if(!dw_head_sect) {
2256 dw_head_sect = dw_last_sect = dw_cur_sect;
2257 } else {
2258 dw_last_sect->next = dw_cur_sect;
2259 dw_last_sect = dw_cur_sect;
2263 if(dbg_immcall == true) {
2264 int32_t line_delta = cur_line - dw_cur_sect->line;
2265 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2266 uint32_t cur_file = dw_cur_file->file;
2267 p_linep = dw_cur_sect->psaa;
2269 if(cur_file != dw_cur_sect->file) {
2270 saa_write8(p_linep, DW_LNS_set_file);
2271 saa_write8(p_linep, cur_file);
2272 dw_cur_sect->file = cur_file;
2275 if(line_delta) {
2276 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2277 DW_OPCODE_BASE;
2279 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2280 (special_opcode < DW_MAX_SP_OPCODE)) {
2281 saa_write8(p_linep, special_opcode);
2282 } else {
2283 saa_write8(p_linep, DW_LNS_advance_line);
2284 saa_wleb128s(p_linep, line_delta);
2285 if(offset_delta) {
2286 saa_write8(p_linep, DW_LNS_advance_pc);
2287 saa_wleb128u(p_linep, offset_delta);
2289 saa_write8(p_linep, DW_LNS_copy);
2292 dw_cur_sect->line = cur_line;
2293 dw_cur_sect->offset = sinfo_param->size;
2296 dbg_immcall = false;
2300 static void macho_dbg_cleanup(void)
2302 /* dwarf sectors generation */
2303 macho_dbg_generate();
2306 struct dw_sect_list *p_sect = dw_head_sect;
2307 struct file_list *p_file = dw_head_file;
2308 uint32_t idx = 0;
2310 for(; idx < dw_num_sects; idx++) {
2311 struct dw_sect_list *next = p_sect->next;
2312 nasm_free(p_sect);
2313 p_sect = next;
2316 for(idx = 0; idx < dw_num_files; idx++) {
2317 struct file_list *next = p_file->next;
2318 nasm_free(p_file);
2319 p_file = next;
2324 #ifdef OF_MACHO32
2325 static const struct macho_fmt macho32_fmt = {
2327 MH_MAGIC,
2328 CPU_TYPE_I386,
2329 LC_SEGMENT,
2330 MACHO_HEADER_SIZE,
2331 MACHO_SEGCMD_SIZE,
2332 MACHO_SECTCMD_SIZE,
2333 MACHO_NLIST_SIZE,
2334 RL_MAX_32,
2335 GENERIC_RELOC_VANILLA,
2336 GENERIC_RELOC_VANILLA,
2337 GENERIC_RELOC_TLV,
2338 false /* Allow segment-relative relocations */
2341 static void macho32_init(void)
2343 fmt = macho32_fmt;
2344 macho_init();
2346 macho_gotpcrel_sect = NO_SEG;
2349 static const struct dfmt macho32_df_dwarf = {
2350 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2351 "dwarf",
2352 macho_dbg_init,
2353 macho_dbg_linenum,
2354 null_debug_deflabel,
2355 null_debug_directive,
2356 null_debug_typevalue,
2357 macho_dbg_output,
2358 macho_dbg_cleanup,
2359 NULL /*pragma list*/
2362 static const struct dfmt * const macho32_df_arr[2] =
2363 { &macho32_df_dwarf, NULL };
2365 const struct ofmt of_macho32 = {
2366 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2367 "macho32",
2368 ".o",
2371 macho32_df_arr,
2372 &macho32_df_dwarf,
2373 macho_stdmac,
2374 macho32_init,
2375 null_reset,
2376 nasm_do_legacy_output,
2377 macho_output,
2378 macho_symdef,
2379 macho_section,
2380 macho_herelabel,
2381 macho_sectalign,
2382 null_segbase,
2383 null_directive,
2384 macho_cleanup,
2385 macho_pragma_list
2387 #endif
2389 #ifdef OF_MACHO64
2390 static const struct macho_fmt macho64_fmt = {
2392 MH_MAGIC_64,
2393 CPU_TYPE_X86_64,
2394 LC_SEGMENT_64,
2395 MACHO_HEADER64_SIZE,
2396 MACHO_SEGCMD64_SIZE,
2397 MACHO_SECTCMD64_SIZE,
2398 MACHO_NLIST64_SIZE,
2399 RL_MAX_64,
2400 X86_64_RELOC_UNSIGNED,
2401 X86_64_RELOC_SIGNED,
2402 X86_64_RELOC_TLV,
2403 true /* Force symbol-relative relocations */
2406 static void macho64_init(void)
2408 fmt = macho64_fmt;
2409 macho_init();
2411 /* add special symbol for ..gotpcrel */
2412 macho_gotpcrel_sect = seg_alloc() + 1;
2413 backend_label("..gotpcrel", macho_gotpcrel_sect, 0L);
2416 static const struct dfmt macho64_df_dwarf = {
2417 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2418 "dwarf",
2419 macho_dbg_init,
2420 macho_dbg_linenum,
2421 null_debug_deflabel,
2422 null_debug_directive,
2423 null_debug_typevalue,
2424 macho_dbg_output,
2425 macho_dbg_cleanup,
2426 NULL /*pragma list*/
2429 static const struct dfmt * const macho64_df_arr[2] =
2430 { &macho64_df_dwarf, NULL };
2432 const struct ofmt of_macho64 = {
2433 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2434 "macho64",
2435 ".o",
2438 macho64_df_arr,
2439 &macho64_df_dwarf,
2440 macho_stdmac,
2441 macho64_init,
2442 null_reset,
2443 nasm_do_legacy_output,
2444 macho_output,
2445 macho_symdef,
2446 macho_section,
2447 macho_herelabel,
2448 macho_sectalign,
2449 null_segbase,
2450 null_directive,
2451 macho_cleanup,
2452 macho_pragma_list,
2454 #endif
2456 #endif
2459 * Local Variables:
2460 * mode:c
2461 * c-basic-offset:4
2462 * End:
2464 * end of file */