outmacho: dwarf debug (4/4)
[nasm.git] / output / outmacho.c
blob173706b9e43dd990f0b10c3d3e67f058a2137138
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2017 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * outmacho.c output routines for the Netwide Assembler to produce
36 * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
39 #include "compiler.h"
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
46 #include "nasm.h"
47 #include "nasmlib.h"
48 #include "labels.h"
49 #include "error.h"
50 #include "saa.h"
51 #include "raa.h"
52 #include "rbtree.h"
53 #include "outform.h"
54 #include "outlib.h"
55 #include "ver.h"
56 #include "dwarf.h"
58 #if defined(OF_MACHO) || defined(OF_MACHO64)
60 /* Mach-O in-file header structure sizes */
61 #define MACHO_HEADER_SIZE 28
62 #define MACHO_SEGCMD_SIZE 56
63 #define MACHO_SECTCMD_SIZE 68
64 #define MACHO_SYMCMD_SIZE 24
65 #define MACHO_NLIST_SIZE 12
66 #define MACHO_RELINFO_SIZE 8
68 #define MACHO_HEADER64_SIZE 32
69 #define MACHO_SEGCMD64_SIZE 72
70 #define MACHO_SECTCMD64_SIZE 80
71 #define MACHO_NLIST64_SIZE 16
73 /* Mach-O file header values */
74 #define MH_MAGIC 0xfeedface
75 #define MH_MAGIC_64 0xfeedfacf
76 #define CPU_TYPE_I386 7 /* x86 platform */
77 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
78 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
79 #define MH_OBJECT 0x1 /* object file */
81 /* Mach-O header flags */
82 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
84 /* Mach-O load commands */
85 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
86 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
87 #define LC_SYMTAB 0x2 /* symbol table load command */
89 /* Mach-O relocations numbers */
91 /* Generic relocs, used by i386 Mach-O */
92 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
93 #define GENERIC_RELOC_TLV 5 /* Thread local */
95 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
96 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
97 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
98 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
99 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
100 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
101 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
102 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
103 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
104 #define X86_64_RELOC_TLV 9 /* Thread local */
106 /* Mach-O VM permission constants */
107 #define VM_PROT_NONE (0x00)
108 #define VM_PROT_READ (0x01)
109 #define VM_PROT_WRITE (0x02)
110 #define VM_PROT_EXECUTE (0x04)
112 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
113 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
115 /* Our internal relocation types */
116 enum reltype {
117 RL_ABS, /* Absolute relocation */
118 RL_REL, /* Relative relocation */
119 RL_TLV, /* Thread local */
120 RL_BRANCH, /* Relative direct branch */
121 RL_SUB, /* X86_64_RELOC_SUBTRACT */
122 RL_GOT, /* X86_64_RELOC_GOT */
123 RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
125 #define RL_MAX_32 RL_TLV
126 #define RL_MAX_64 RL_GOTLOAD
128 struct macho_fmt {
129 uint32_t ptrsize; /* Pointer size in bytes */
130 uint32_t mh_magic; /* Which magic number to use */
131 uint32_t cpu_type; /* Which CPU type */
132 uint32_t lc_segment; /* Which segment load command */
133 uint32_t header_size; /* Header size */
134 uint32_t segcmd_size; /* Segment command size */
135 uint32_t sectcmd_size; /* Section command size */
136 uint32_t nlist_size; /* Nlist (symbol) size */
137 enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
138 uint32_t reloc_abs; /* Absolute relocation type */
139 uint32_t reloc_rel; /* Relative relocation type */
140 uint32_t reloc_tlv; /* Thread local relocation type */
143 static struct macho_fmt fmt;
145 static void fwriteptr(uint64_t data, FILE * fp)
147 fwriteaddr(data, fmt.ptrsize, fp);
150 struct section {
151 /* nasm internal data */
152 struct section *next;
153 struct SAA *data;
154 int32_t index;
155 int32_t fileindex;
156 struct reloc *relocs;
157 struct rbtree *gsyms; /* Global symbols in section */
158 int align;
159 bool by_name; /* This section was specified by full MachO name */
161 /* data that goes into the file */
162 char sectname[16]; /* what this section is called */
163 char segname[16]; /* segment this section will be in */
164 uint64_t addr; /* in-memory address (subject to alignment) */
165 uint64_t size; /* in-memory and -file size */
166 uint64_t offset; /* in-file offset */
167 uint32_t pad; /* padding bytes before section */
168 uint32_t nreloc; /* relocation entry count */
169 uint32_t flags; /* type and attributes (masked) */
170 uint32_t extreloc; /* external relocations */
173 #define SECTION_TYPE 0x000000ff /* section type mask */
175 #define S_REGULAR (0x0) /* standard section */
176 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
178 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
179 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
180 machine instructions */
181 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
182 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
183 #define S_ATTR_DEBUG 0x02000000
184 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
185 #define S_ATTR_LIVE_SUPPORT 0x08000000
186 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
187 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
188 #define S_ATTR_NO_TOC 0x40000000
189 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
190 #define S_ATTR_DEBUG 0x02000000 /* debug section */
192 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
194 /* fake section for absolute symbols, *not* part of the section linked list */
195 static struct section absolute_sect;
197 struct reloc {
198 /* nasm internal data */
199 struct reloc *next;
201 /* data that goes into the file */
202 int32_t addr; /* op's offset in section */
203 uint32_t snum:24, /* contains symbol index if
204 ** ext otherwise in-file
205 ** section number */
206 pcrel:1, /* relative relocation */
207 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
208 ext:1, /* external symbol referenced */
209 type:4; /* reloc type */
212 #define R_ABS 0 /* absolute relocation */
213 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
214 ** highest bit == 1 */
216 struct symbol {
217 /* nasm internal data */
218 struct rbtree symv; /* Global symbol rbtree; "key" contains the
219 symbol offset. */
220 struct symbol *next; /* next symbol in the list */
221 char *name; /* name of this symbol */
222 int32_t initial_snum; /* symbol number used above in reloc */
223 int32_t snum; /* true snum for reloc */
225 /* data that goes into the file */
226 uint32_t strx; /* string table index */
227 uint8_t type; /* symbol type */
228 uint8_t sect; /* NO_SECT or section number */
229 uint16_t desc; /* for stab debugging, 0 for us */
232 /* symbol type bits */
233 #define N_EXT 0x01 /* global or external symbol */
235 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
236 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
237 #define N_SECT 0xe /* defined symbol, n_sect holds
238 ** section number */
240 #define N_TYPE 0x0e /* type bit mask */
242 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
244 /* special section number values */
245 #define NO_SECT 0 /* no section, invalid */
246 #define MAX_SECT 255 /* maximum number of sections */
248 static struct section *sects, **sectstail, **sectstab;
249 static struct symbol *syms, **symstail;
250 static uint32_t nsyms;
252 /* These variables are set by macho_layout_symbols() to organize
253 the symbol table and string table in order the dynamic linker
254 expects. They are then used in macho_write() to put out the
255 symbols and strings in that order.
257 The order of the symbol table is:
258 local symbols
259 defined external symbols (sorted by name)
260 undefined external symbols (sorted by name)
262 The order of the string table is:
263 strings for external symbols
264 strings for local symbols
266 static uint32_t ilocalsym = 0;
267 static uint32_t iextdefsym = 0;
268 static uint32_t iundefsym = 0;
269 static uint32_t nlocalsym;
270 static uint32_t nextdefsym;
271 static uint32_t nundefsym;
272 static struct symbol **extdefsyms = NULL;
273 static struct symbol **undefsyms = NULL;
275 static struct RAA *extsyms;
276 static struct SAA *strs;
277 static uint32_t strslen;
279 /* Global file information. This should be cleaned up into either
280 a structure or as function arguments. */
281 static uint32_t head_ncmds = 0;
282 static uint32_t head_sizeofcmds = 0;
283 static uint32_t head_flags = 0;
284 static uint64_t seg_filesize = 0;
285 static uint64_t seg_vmsize = 0;
286 static uint32_t seg_nsects = 0;
287 static uint64_t rel_padcnt = 0;
289 #define xstrncpy(xdst, xsrc) \
290 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
291 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
292 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
294 #define alignint32_t(x) \
295 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
297 #define alignint64_t(x) \
298 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
300 #define alignptr(x) \
301 ALIGN(x, fmt.ptrsize) /* align x to output format width */
303 static struct section *get_section_by_name(const char *segname,
304 const char *sectname)
306 struct section *s;
308 for (s = sects; s != NULL; s = s->next)
309 if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
310 break;
312 return s;
315 static struct section *get_section_by_index(const int32_t index)
317 struct section *s;
319 for (s = sects; s != NULL; s = s->next)
320 if (index == s->index)
321 break;
323 return s;
326 struct file_list {
327 struct file_list *next;
328 struct file_list *last;
329 char *file_name;
330 uint32_t file;
333 struct dw_sect_list {
334 struct SAA *psaa;
335 int32_t section;
336 uint32_t line;
337 uint64_t offset;
338 uint32_t file;
339 struct dw_sect_list *next;
340 struct dw_sect_list *last;
343 struct section_info {
344 uint64_t size;
345 int32_t secto;
348 #define DW_LN_BASE (-5)
349 #define DW_LN_RANGE 14
350 #define DW_OPCODE_BASE 13
351 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
352 #define DW_MAX_SP_OPCODE 256
354 static struct file_list *dw_head_list = 0, *dw_cur_list = 0, *dw_last_list = 0;
355 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
356 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_sects = 0;
357 static bool dbg_immcall = false;
360 * Special section numbers which are used to define Mach-O special
361 * symbols, which can be used with WRT to provide PIC relocation
362 * types.
364 static int32_t macho_tlvp_sect;
365 static int32_t macho_gotpcrel_sect;
367 static void macho_init(void)
369 sects = NULL;
370 sectstail = &sects;
372 /* Fake section for absolute symbols */
373 absolute_sect.index = NO_SEG;
375 syms = NULL;
376 symstail = &syms;
377 nsyms = 0;
378 nlocalsym = 0;
379 nextdefsym = 0;
380 nundefsym = 0;
382 extsyms = raa_init();
383 strs = saa_init(1L);
385 /* string table starts with a zero byte so index 0 is an empty string */
386 saa_wbytes(strs, zero_buffer, 1);
387 strslen = 1;
389 /* add special symbol for TLVP */
390 macho_tlvp_sect = seg_alloc() + 1;
391 define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
395 static void sect_write(struct section *sect,
396 const uint8_t *data, uint32_t len)
398 saa_wbytes(sect->data, data, len);
399 sect->size += len;
403 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
405 static struct symbol *macho_find_gsym(struct section *s,
406 uint64_t offset, bool exact)
408 struct rbtree *srb;
410 srb = rb_search(s->gsyms, offset);
412 if (!srb || (exact && srb->key != offset)) {
413 nasm_error(ERR_NONFATAL, "unable to find a suitable %s symbol"
414 " for this reference",
415 s == &absolute_sect ? "absolute" : "global");
416 return NULL;
419 return container_of(srb, struct symbol, symv);
422 static int64_t add_reloc(struct section *sect, int32_t section,
423 int64_t offset,
424 enum reltype reltype, int bytes)
426 struct reloc *r;
427 struct section *s;
428 int32_t fi;
429 int64_t adjust;
431 /* Double check this is a valid relocation type for this platform */
432 nasm_assert(reltype <= fmt.maxreltype);
434 /* the current end of the section will be the symbol's address for
435 ** now, might have to be fixed by macho_fixup_relocs() later on. make
436 ** sure we don't make the symbol scattered by setting the highest
437 ** bit by accident */
438 r = nasm_malloc(sizeof(struct reloc));
439 r->addr = sect->size & ~R_SCATTERED;
440 r->ext = 1;
441 adjust = bytes;
443 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
444 r->length = ilog2_32(bytes);
446 /* set default relocation values */
447 r->type = fmt.reloc_abs;
448 r->pcrel = 0;
449 r->snum = R_ABS;
451 s = NULL;
452 if (section != NO_SEG)
453 s = get_section_by_index(section);
454 fi = s ? s->fileindex : NO_SECT;
456 /* absolute relocation */
457 switch (reltype) {
458 case RL_ABS:
459 if (section == NO_SEG) {
460 /* absolute (can this even happen?) */
461 r->ext = 0;
462 r->snum = R_ABS;
463 } else if (fi == NO_SECT) {
464 /* external */
465 r->snum = raa_read(extsyms, section);
466 } else {
467 /* local */
468 r->ext = 0;
469 r->snum = fi;
470 adjust = -sect->size;
472 break;
474 case RL_REL:
475 case RL_BRANCH:
476 r->type = fmt.reloc_rel;
477 r->pcrel = 1;
478 if (section == NO_SEG) {
479 /* absolute - seems to produce garbage no matter what */
480 nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
481 "references to absolute addresses");
482 goto bail;
483 #if 0
484 /* This "seems" to be how it ought to work... */
486 struct symbol *sym = macho_find_gsym(&absolute_sect,
487 offset, false);
488 if (!sym)
489 goto bail;
491 sect->extreloc = 1;
492 r->snum = NO_SECT;
493 adjust = -sect->size;
494 #endif
495 } else if (fi == NO_SECT) {
496 /* external */
497 sect->extreloc = 1;
498 r->snum = raa_read(extsyms, section);
499 if (reltype == RL_BRANCH)
500 r->type = X86_64_RELOC_BRANCH;
501 else if (r->type == GENERIC_RELOC_VANILLA)
502 adjust = -sect->size;
503 } else {
504 /* local */
505 r->ext = 0;
506 r->snum = fi;
507 adjust = -sect->size;
509 break;
511 case RL_SUB:
512 r->pcrel = 0;
513 r->type = X86_64_RELOC_SUBTRACTOR;
514 break;
516 case RL_GOT:
517 r->type = X86_64_RELOC_GOT;
518 goto needsym;
520 case RL_GOTLOAD:
521 r->type = X86_64_RELOC_GOT_LOAD;
522 goto needsym;
524 case RL_TLV:
525 r->type = fmt.reloc_tlv;
526 goto needsym;
528 needsym:
529 r->pcrel = 1;
530 if (section == NO_SEG) {
531 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
532 } else if (fi == NO_SECT) {
533 /* external */
534 r->snum = raa_read(extsyms, section);
535 } else {
536 /* internal */
537 struct symbol *sym = macho_find_gsym(s, offset, reltype != RL_TLV);
538 if (!sym)
539 goto bail;
540 r->snum = sym->initial_snum;
542 break;
545 /* NeXT as puts relocs in reversed order (address-wise) into the
546 ** files, so we do the same, doesn't seem to make much of a
547 ** difference either way */
548 r->next = sect->relocs;
549 sect->relocs = r;
550 if (r->ext)
551 sect->extreloc = 1;
552 ++sect->nreloc;
554 return adjust;
556 bail:
557 nasm_free(r);
558 return 0;
561 static void macho_output(int32_t secto, const void *data,
562 enum out_type type, uint64_t size,
563 int32_t section, int32_t wrt)
565 struct section *s;
566 int64_t addr, offset;
567 uint8_t mydata[16], *p;
568 bool is_bss;
569 enum reltype reltype;
571 if (secto == NO_SEG) {
572 if (type != OUT_RESERVE)
573 nasm_error(ERR_NONFATAL, "attempt to assemble code in "
574 "[ABSOLUTE] space");
575 return;
578 s = get_section_by_index(secto);
580 if (s == NULL) {
581 nasm_error(ERR_WARNING, "attempt to assemble code in"
582 " section %d: defaulting to `.text'", secto);
583 s = get_section_by_name("__TEXT", "__text");
585 /* should never happen */
586 if (s == NULL)
587 nasm_panic(0, "text section not found");
590 /* debug code generation only for sections tagged with
591 * instruction attribute */
592 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
594 struct section_info sinfo;
595 sinfo.size = s->size;
596 sinfo.secto = secto;
597 dfmt->debug_output(0, &sinfo);
600 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
602 if (is_bss && type != OUT_RESERVE) {
603 nasm_error(ERR_WARNING, "attempt to initialize memory in "
604 "BSS section: ignored");
605 s->size += realsize(type, size);
606 return;
609 memset(mydata, 0, sizeof(mydata));
611 switch (type) {
612 case OUT_RESERVE:
613 if (!is_bss) {
614 nasm_error(ERR_WARNING, "uninitialized space declared in"
615 " %s,%s section: zeroing", s->segname, s->sectname);
617 sect_write(s, NULL, size);
618 } else
619 s->size += size;
621 break;
623 case OUT_RAWDATA:
624 if (section != NO_SEG)
625 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
627 sect_write(s, data, size);
628 break;
630 case OUT_ADDRESS:
632 int asize = abs((int)size);
634 addr = *(int64_t *)data;
635 if (section != NO_SEG) {
636 if (section % 2) {
637 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
638 " section base references");
639 } else if (wrt == NO_SEG) {
640 if (fmt.ptrsize == 8 && asize != 8) {
641 nasm_error(ERR_NONFATAL,
642 "Mach-O 64-bit format does not support"
643 " 32-bit absolute addresses");
644 } else {
645 add_reloc(s, section, addr, RL_ABS, asize);
647 } else {
648 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
649 " this use of WRT");
653 p = mydata;
654 WRITEADDR(p, addr, asize);
655 sect_write(s, mydata, asize);
656 break;
659 case OUT_REL2ADR:
660 nasm_assert(section != secto);
662 p = mydata;
663 offset = *(int64_t *)data;
664 addr = offset - size;
666 if (section != NO_SEG && section % 2) {
667 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
668 " section base references");
669 } else if (fmt.ptrsize == 8) {
670 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
671 " Macho-O relocation [2]");
672 } else if (wrt != NO_SEG) {
673 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
674 " this use of WRT");
675 wrt = NO_SEG; /* we can at least _try_ to continue */
676 } else {
677 addr += add_reloc(s, section, addr+size, RL_REL, 2);
680 WRITESHORT(p, addr);
681 sect_write(s, mydata, 2);
682 break;
684 case OUT_REL4ADR:
685 nasm_assert(section != secto);
687 p = mydata;
688 offset = *(int64_t *)data;
689 addr = offset - size;
690 reltype = RL_REL;
692 if (section != NO_SEG && 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 &&
697 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
698 uint8_t opcode[2];
700 opcode[0] = opcode[1] = 0;
702 /* HACK: Retrieve instruction opcode */
703 if (likely(s->data->datalen >= 2)) {
704 saa_fread(s->data, s->data->datalen-2, opcode, 2);
705 } else if (s->data->datalen == 1) {
706 saa_fread(s->data, 0, opcode+1, 1);
709 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
710 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
711 /* Direct call, jmp, or jcc */
712 reltype = RL_BRANCH;
715 } else if (wrt == macho_gotpcrel_sect) {
716 reltype = RL_GOT;
718 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
719 s->data->datalen >= 3) {
720 uint8_t gotload[3];
722 /* HACK: Retrieve instruction opcode */
723 saa_fread(s->data, s->data->datalen-3, gotload, 3);
724 if ((gotload[0] & 0xf8) == 0x48 &&
725 gotload[1] == 0x8b &&
726 (gotload[2] & 0307) == 0005) {
727 /* movq <reg>,[rel sym wrt ..gotpcrel] */
728 reltype = RL_GOTLOAD;
731 } else if (wrt == macho_tlvp_sect) {
732 reltype = RL_TLV;
733 } else {
734 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
735 " this use of WRT");
736 /* continue with RL_REL */
739 addr += add_reloc(s, section, offset, reltype, 4);
740 WRITELONG(p, addr);
741 sect_write(s, mydata, 4);
742 break;
744 default:
745 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
746 break;
750 /* Translation table from traditional Unix section names to Mach-O */
751 static const struct sectmap {
752 const char *nasmsect;
753 const char *segname;
754 const char *sectname;
755 const uint32_t flags;
756 } sectmap[] = {
757 {".text", "__TEXT", "__text",
758 S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
759 {".data", "__DATA", "__data", S_REGULAR},
760 {".rodata", "__DATA", "__const", S_REGULAR},
761 {".bss", "__DATA", "__bss", S_ZEROFILL},
762 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
763 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
764 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
765 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
766 {NULL, NULL, NULL, 0}
769 #define NO_TYPE S_NASM_TYPE_MASK
771 /* Section type or attribute directives */
772 static const struct sect_attribs {
773 const char *name;
774 uint32_t flags;
775 } sect_attribs[] = {
776 { "data", S_REGULAR },
777 { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
778 { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
779 { "bss", S_ZEROFILL },
780 { "zerofill", S_ZEROFILL },
781 { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
782 { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
783 { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
784 { NULL, 0 }
787 static int32_t macho_section(char *name, int pass, int *bits)
789 char *sectionAttributes;
790 const struct sectmap *sm;
791 struct section *s;
792 const char *section, *segment;
793 uint32_t flags;
794 const struct sect_attribs *sa;
795 char *currentAttribute;
796 char *comma;
798 bool new_seg;
800 (void)pass;
802 /* Default to the appropriate number of bits. */
803 if (!name) {
804 *bits = fmt.ptrsize << 3;
805 name = ".text";
806 sectionAttributes = NULL;
807 } else {
808 sectionAttributes = name;
809 name = nasm_strsep(&sectionAttributes, " \t");
812 section = segment = NULL;
813 flags = 0;
815 comma = strchr(name, ',');
816 if (comma) {
817 int len;
819 *comma = '\0';
820 segment = name;
821 section = comma+1;
823 len = strlen(segment);
824 if (len == 0) {
825 nasm_error(ERR_NONFATAL, "empty segment name\n");
826 } else if (len >= 16) {
827 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
830 len = strlen(section);
831 if (len == 0) {
832 nasm_error(ERR_NONFATAL, "empty section name\n");
833 } else if (len >= 16) {
834 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
837 if (!strcmp(section, "__text")) {
838 flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
839 S_ATTR_PURE_INSTRUCTIONS;
840 } else if (!strcmp(section, "__bss")) {
841 flags = S_ZEROFILL;
842 } else {
843 flags = S_REGULAR;
845 } else {
846 for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
847 /* make lookup into section name translation table */
848 if (!strcmp(name, sm->nasmsect)) {
849 segment = sm->segname;
850 section = sm->sectname;
851 flags = sm->flags;
852 goto found;
855 nasm_error(ERR_NONFATAL, "unknown section name\n");
856 return NO_SEG;
859 found:
860 /* try to find section with that name */
861 s = get_section_by_name(segment, section);
863 /* create it if it doesn't exist yet */
864 if (!s) {
865 new_seg = true;
867 s = *sectstail = nasm_zalloc(sizeof(struct section));
868 sectstail = &s->next;
870 s->data = saa_init(1L);
871 s->index = seg_alloc();
872 s->fileindex = ++seg_nsects;
873 s->align = -1;
874 s->pad = -1;
875 s->offset = -1;
876 s->by_name = false;
878 xstrncpy(s->segname, segment);
879 xstrncpy(s->sectname, section);
880 s->size = 0;
881 s->nreloc = 0;
882 s->flags = flags;
883 } else {
884 new_seg = false;
887 if (comma)
888 *comma = ','; /* Restore comma */
890 s->by_name = s->by_name || comma; /* Was specified by name */
892 flags = NO_TYPE;
894 while (sectionAttributes &&
895 (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
896 if (!*currentAttribute)
897 continue;
899 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
900 char *end;
901 int newAlignment, value;
903 value = strtoul(currentAttribute + 6, (char**)&end, 0);
904 newAlignment = alignlog2_32(value);
906 if (0 != *end) {
907 nasm_error(ERR_NONFATAL,
908 "unknown or missing alignment value \"%s\" "
909 "specified for section \"%s\"",
910 currentAttribute + 6,
911 name);
912 } else if (0 > newAlignment) {
913 nasm_error(ERR_NONFATAL,
914 "alignment of %d (for section \"%s\") is not "
915 "a power of two",
916 value,
917 name);
920 if (s->align < newAlignment)
921 s->align = newAlignment;
922 } else {
923 for (sa = sect_attribs; sa->name; sa++) {
924 if (!nasm_stricmp(sa->name, currentAttribute)) {
925 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
926 flags = (flags & ~S_NASM_TYPE_MASK)
927 | (sa->flags & S_NASM_TYPE_MASK);
929 flags |= sa->flags & ~S_NASM_TYPE_MASK;
930 break;
934 if (!sa->name) {
935 nasm_error(ERR_NONFATAL,
936 "unknown section attribute %s for section %s",
937 currentAttribute, name);
942 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
943 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
944 nasm_error(ERR_NONFATAL,
945 "inconsistent section attributes for section %s\n",
946 name);
947 } else {
948 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
950 } else {
951 s->flags |= flags & ~S_NASM_TYPE_MASK;
954 return s->index;
957 static void macho_symdef(char *name, int32_t section, int64_t offset,
958 int is_global, char *special)
960 struct symbol *sym;
962 if (special) {
963 nasm_error(ERR_NONFATAL, "The Mach-O output format does "
964 "not support any special symbol types");
965 return;
968 if (is_global == 3) {
969 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
970 "(yet) support forward reference fixups.");
971 return;
974 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
976 * This is a NASM special symbol. We never allow it into
977 * the Macho-O symbol table, even if it's a valid one. If it
978 * _isn't_ a valid one, we should barf immediately.
980 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
981 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
982 return;
985 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
986 sym->next = NULL;
987 symstail = &sym->next;
989 sym->name = name;
990 sym->strx = strslen;
991 sym->type = 0;
992 sym->desc = 0;
993 sym->symv.key = offset;
994 sym->initial_snum = -1;
996 /* external and common symbols get N_EXT */
997 if (is_global != 0) {
998 sym->type |= N_EXT;
1001 if (section == NO_SEG) {
1002 /* symbols in no section get absolute */
1003 sym->type |= N_ABS;
1004 sym->sect = NO_SECT;
1006 /* all absolute symbols are available to use as references */
1007 absolute_sect.gsyms = rb_insert(absolute_sect.gsyms, &sym->symv);
1008 } else {
1009 struct section *s = get_section_by_index(section);
1011 sym->type |= N_SECT;
1013 /* get the in-file index of the section the symbol was defined in */
1014 sym->sect = s ? s->fileindex : NO_SECT;
1016 /* track the initially allocated symbol number for use in future fix-ups */
1017 sym->initial_snum = nsyms;
1019 if (!s) {
1020 /* remember symbol number of references to external
1021 ** symbols, this works because every external symbol gets
1022 ** its own section number allocated internally by nasm and
1023 ** can so be used as a key */
1024 extsyms = raa_write(extsyms, section, nsyms);
1026 switch (is_global) {
1027 case 1:
1028 case 2:
1029 /* there isn't actually a difference between global
1030 ** and common symbols, both even have their size in
1031 ** sym->symv.key */
1032 sym->type = N_EXT;
1033 break;
1035 default:
1036 /* give an error on unfound section if it's not an
1037 ** external or common symbol (assemble_file() does a
1038 ** seg_alloc() on every call for them) */
1039 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1040 break;
1042 } else if (is_global) {
1043 s->gsyms = rb_insert(s->gsyms, &sym->symv);
1046 ++nsyms;
1049 static void macho_sectalign(int32_t seg, unsigned int value)
1051 struct section *s;
1052 int align;
1054 nasm_assert(!(seg & 1));
1056 s = get_section_by_index(seg);
1058 if (!s || !is_power2(value))
1059 return;
1061 align = alignlog2_32(value);
1062 if (s->align < align)
1063 s->align = align;
1066 static int32_t macho_segbase(int32_t section)
1068 return section;
1071 static void macho_filename(char *inname, char *outname)
1073 standard_extension(inname, outname, ".o");
1076 extern macros_t macho_stdmac[];
1078 /* Comparison function for qsort symbol layout. */
1079 static int layout_compare (const struct symbol **s1,
1080 const struct symbol **s2)
1082 return (strcmp ((*s1)->name, (*s2)->name));
1085 /* The native assembler does a few things in a similar function
1087 * Remove temporary labels
1088 * Sort symbols according to local, external, undefined (by name)
1089 * Order the string table
1091 We do not remove temporary labels right now.
1093 numsyms is the total number of symbols we have. strtabsize is the
1094 number entries in the string table. */
1096 static void macho_layout_symbols (uint32_t *numsyms,
1097 uint32_t *strtabsize)
1099 struct symbol *sym, **symp;
1100 uint32_t i,j;
1102 *numsyms = 0;
1103 *strtabsize = sizeof (char);
1105 symp = &syms;
1107 while ((sym = *symp)) {
1108 /* Undefined symbols are now external. */
1109 if (sym->type == N_UNDF)
1110 sym->type |= N_EXT;
1112 if ((sym->type & N_EXT) == 0) {
1113 sym->snum = *numsyms;
1114 *numsyms = *numsyms + 1;
1115 nlocalsym++;
1117 else {
1118 if ((sym->type & N_TYPE) != N_UNDF) {
1119 nextdefsym++;
1120 } else {
1121 nundefsym++;
1124 /* If we handle debug info we'll want
1125 to check for it here instead of just
1126 adding the symbol to the string table. */
1127 sym->strx = *strtabsize;
1128 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1129 *strtabsize += strlen(sym->name) + 1;
1131 symp = &(sym->next);
1134 /* Next, sort the symbols. Most of this code is a direct translation from
1135 the Apple cctools symbol layout. We need to keep compatibility with that. */
1136 /* Set the indexes for symbol groups into the symbol table */
1137 ilocalsym = 0;
1138 iextdefsym = nlocalsym;
1139 iundefsym = nlocalsym + nextdefsym;
1141 /* allocate arrays for sorting externals by name */
1142 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1143 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1145 i = 0;
1146 j = 0;
1148 symp = &syms;
1150 while ((sym = *symp)) {
1152 if((sym->type & N_EXT) == 0) {
1153 sym->strx = *strtabsize;
1154 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1155 *strtabsize += strlen(sym->name) + 1;
1157 else {
1158 if ((sym->type & N_TYPE) != N_UNDF) {
1159 extdefsyms[i++] = sym;
1160 } else {
1161 undefsyms[j++] = sym;
1164 symp = &(sym->next);
1167 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1168 (int (*)(const void *, const void *))layout_compare);
1169 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1170 (int (*)(const void *, const void *))layout_compare);
1172 for(i = 0; i < nextdefsym; i++) {
1173 extdefsyms[i]->snum = *numsyms;
1174 *numsyms += 1;
1176 for(j = 0; j < nundefsym; j++) {
1177 undefsyms[j]->snum = *numsyms;
1178 *numsyms += 1;
1182 /* Calculate some values we'll need for writing later. */
1184 static void macho_calculate_sizes (void)
1186 struct section *s;
1187 int fi;
1189 /* count sections and calculate in-memory and in-file offsets */
1190 for (s = sects; s != NULL; s = s->next) {
1191 uint64_t newaddr;
1193 /* recalculate segment address based on alignment and vm size */
1194 s->addr = seg_vmsize;
1196 /* we need section alignment to calculate final section address */
1197 if (s->align == -1)
1198 s->align = DEFAULT_SECTION_ALIGNMENT;
1200 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1201 s->addr = newaddr;
1203 seg_vmsize = newaddr + s->size;
1205 /* zerofill sections aren't actually written to the file */
1206 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1208 * LLVM/Xcode as always aligns the section data to 4
1209 * bytes; there is a comment in the LLVM source code that
1210 * perhaps aligning to pointer size would be better.
1212 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1213 s->offset = seg_filesize + s->pad;
1214 seg_filesize += s->size + s->pad;
1216 /* filesize and vmsize needs to be aligned */
1217 seg_vmsize += s->pad;
1221 /* calculate size of all headers, load commands and sections to
1222 ** get a pointer to the start of all the raw data */
1223 if (seg_nsects > 0) {
1224 ++head_ncmds;
1225 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1228 if (nsyms > 0) {
1229 ++head_ncmds;
1230 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1233 if (seg_nsects > MAX_SECT) {
1234 nasm_fatal(0, "MachO output is limited to %d sections\n",
1235 MAX_SECT);
1238 /* Create a table of sections by file index to avoid linear search */
1239 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1240 sectstab[NO_SECT] = &absolute_sect;
1241 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1242 sectstab[fi] = s;
1245 /* Write out the header information for the file. */
1247 static void macho_write_header (void)
1249 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1250 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1251 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1252 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1253 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1254 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1255 fwriteint32_t(head_flags, ofile); /* flags, if any */
1256 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1259 /* Write out the segment load command at offset. */
1261 static uint32_t macho_write_segment (uint64_t offset)
1263 uint64_t rel_base = alignptr(offset + seg_filesize);
1264 uint32_t s_reloff = 0;
1265 struct section *s;
1267 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1269 /* size of load command including section load commands */
1270 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1271 ofile);
1273 /* in an MH_OBJECT file all sections are in one unnamed (name
1274 ** all zeros) segment */
1275 fwritezero(16, ofile);
1276 fwriteptr(0, ofile); /* in-memory offset */
1277 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1278 fwriteptr(offset, ofile); /* in-file offset to data */
1279 fwriteptr(seg_filesize, ofile); /* in-file size */
1280 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1281 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1282 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1283 fwriteint32_t(0, ofile); /* no flags */
1285 /* emit section headers */
1286 for (s = sects; s != NULL; s = s->next) {
1287 if (s->nreloc) {
1288 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1289 s->flags |= S_ATTR_LOC_RELOC;
1290 if (s->extreloc)
1291 s->flags |= S_ATTR_EXT_RELOC;
1292 } else if (!strcmp(s->segname, "__DATA") &&
1293 !strcmp(s->sectname, "__const") &&
1294 !s->by_name &&
1295 !get_section_by_name("__TEXT", "__const")) {
1297 * The MachO equivalent to .rodata can be either
1298 * __DATA,__const or __TEXT,__const; the latter only if
1299 * there are no relocations. However, when mixed it is
1300 * better to specify the segments explicitly.
1302 xstrncpy(s->segname, "__TEXT");
1305 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1306 nasm_write(s->segname, sizeof(s->segname), ofile);
1307 fwriteptr(s->addr, ofile);
1308 fwriteptr(s->size, ofile);
1310 /* dummy data for zerofill sections or proper values */
1311 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1312 nasm_assert(s->pad != (uint32_t)-1);
1313 offset += s->pad;
1314 fwriteint32_t(offset, ofile);
1315 offset += s->size;
1316 /* Write out section alignment, as a power of two.
1317 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1318 fwriteint32_t(s->align, ofile);
1319 /* To be compatible with cctools as we emit
1320 a zero reloff if we have no relocations. */
1321 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1322 fwriteint32_t(s->nreloc, ofile);
1324 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1325 } else {
1326 fwriteint32_t(0, ofile);
1327 fwriteint32_t(s->align, ofile);
1328 fwriteint32_t(0, ofile);
1329 fwriteint32_t(0, ofile);
1332 fwriteint32_t(s->flags, ofile); /* flags */
1333 fwriteint32_t(0, ofile); /* reserved */
1334 fwriteptr(0, ofile); /* reserved */
1337 rel_padcnt = rel_base - offset;
1338 offset = rel_base + s_reloff;
1340 return offset;
1343 /* For a given chain of relocs r, write out the entire relocation
1344 chain to the object file. */
1346 static void macho_write_relocs (struct reloc *r)
1348 while (r) {
1349 uint32_t word2;
1351 fwriteint32_t(r->addr, ofile); /* reloc offset */
1353 word2 = r->snum;
1354 word2 |= r->pcrel << 24;
1355 word2 |= r->length << 25;
1356 word2 |= r->ext << 27;
1357 word2 |= r->type << 28;
1358 fwriteint32_t(word2, ofile); /* reloc data */
1359 r = r->next;
1363 /* Write out the section data. */
1364 static void macho_write_section (void)
1366 struct section *s;
1367 struct reloc *r;
1368 uint8_t *p;
1369 int32_t len;
1370 int64_t l;
1371 union offset {
1372 uint64_t val;
1373 uint8_t buf[8];
1374 } blk;
1376 for (s = sects; s != NULL; s = s->next) {
1377 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1378 continue;
1380 /* Like a.out Mach-O references things in the data or bss
1381 * sections by addresses which are actually relative to the
1382 * start of the _text_ section, in the _file_. See outaout.c
1383 * for more information. */
1384 saa_rewind(s->data);
1385 for (r = s->relocs; r != NULL; r = r->next) {
1386 len = (uint32_t)1 << r->length;
1387 if (len > 4) /* Can this ever be an issue?! */
1388 len = 8;
1389 blk.val = 0;
1390 saa_fread(s->data, r->addr, blk.buf, len);
1392 /* get offset based on relocation type */
1393 #ifdef WORDS_LITTLEENDIAN
1394 l = blk.val;
1395 #else
1396 l = blk.buf[0];
1397 l += ((int64_t)blk.buf[1]) << 8;
1398 l += ((int64_t)blk.buf[2]) << 16;
1399 l += ((int64_t)blk.buf[3]) << 24;
1400 l += ((int64_t)blk.buf[4]) << 32;
1401 l += ((int64_t)blk.buf[5]) << 40;
1402 l += ((int64_t)blk.buf[6]) << 48;
1403 l += ((int64_t)blk.buf[7]) << 56;
1404 #endif
1406 /* If the relocation is internal add to the current section
1407 offset. Otherwise the only value we need is the symbol
1408 offset which we already have. The linker takes care
1409 of the rest of the address. */
1410 if (!r->ext) {
1411 /* generate final address by section address and offset */
1412 nasm_assert(r->snum <= seg_nsects);
1413 l += sectstab[r->snum]->addr;
1414 if (r->pcrel)
1415 l -= s->addr;
1416 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1417 l -= s->addr;
1420 /* write new offset back */
1421 p = blk.buf;
1422 WRITEDLONG(p, l);
1423 saa_fwrite(s->data, r->addr, blk.buf, len);
1426 /* dump the section data to file */
1427 fwritezero(s->pad, ofile);
1428 saa_fpwrite(s->data, ofile);
1431 /* pad last section up to reloc entries on pointer boundary */
1432 fwritezero(rel_padcnt, ofile);
1434 /* emit relocation entries */
1435 for (s = sects; s != NULL; s = s->next)
1436 macho_write_relocs (s->relocs);
1439 /* Write out the symbol table. We should already have sorted this
1440 before now. */
1441 static void macho_write_symtab (void)
1443 struct symbol *sym;
1444 uint64_t i;
1446 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1448 for (sym = syms; sym != NULL; sym = sym->next) {
1449 if ((sym->type & N_EXT) == 0) {
1450 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1451 nasm_write(&sym->type, 1, ofile); /* symbol type */
1452 nasm_write(&sym->sect, 1, ofile); /* section */
1453 fwriteint16_t(sym->desc, ofile); /* description */
1455 /* Fix up the symbol value now that we know the final section
1456 sizes. */
1457 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1458 nasm_assert(sym->sect <= seg_nsects);
1459 sym->symv.key += sectstab[sym->sect]->addr;
1462 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1466 for (i = 0; i < nextdefsym; i++) {
1467 sym = extdefsyms[i];
1468 fwriteint32_t(sym->strx, ofile);
1469 nasm_write(&sym->type, 1, ofile); /* symbol type */
1470 nasm_write(&sym->sect, 1, ofile); /* section */
1471 fwriteint16_t(sym->desc, ofile); /* description */
1473 /* Fix up the symbol value now that we know the final section
1474 sizes. */
1475 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1476 nasm_assert(sym->sect <= seg_nsects);
1477 sym->symv.key += sectstab[sym->sect]->addr;
1480 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1483 for (i = 0; i < nundefsym; i++) {
1484 sym = undefsyms[i];
1485 fwriteint32_t(sym->strx, ofile);
1486 nasm_write(&sym->type, 1, ofile); /* symbol type */
1487 nasm_write(&sym->sect, 1, ofile); /* section */
1488 fwriteint16_t(sym->desc, ofile); /* description */
1490 /* Fix up the symbol value now that we know the final section
1491 sizes. */
1492 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1493 nasm_assert(sym->sect <= seg_nsects);
1494 sym->symv.key += sectstab[sym->sect]->addr;
1497 fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
1502 /* Fixup the snum in the relocation entries, we should be
1503 doing this only for externally referenced symbols. */
1504 static void macho_fixup_relocs (struct reloc *r)
1506 struct symbol *sym;
1508 while (r != NULL) {
1509 if (r->ext) {
1510 for (sym = syms; sym != NULL; sym = sym->next) {
1511 if (sym->initial_snum == r->snum) {
1512 r->snum = sym->snum;
1513 break;
1517 r = r->next;
1521 /* Write out the object file. */
1523 static void macho_write (void)
1525 uint64_t offset = 0;
1527 /* mach-o object file structure:
1529 ** mach header
1530 ** uint32_t magic
1531 ** int cpu type
1532 ** int cpu subtype
1533 ** uint32_t mach file type
1534 ** uint32_t number of load commands
1535 ** uint32_t size of all load commands
1536 ** (includes section struct size of segment command)
1537 ** uint32_t flags
1539 ** segment command
1540 ** uint32_t command type == LC_SEGMENT[_64]
1541 ** uint32_t size of load command
1542 ** (including section load commands)
1543 ** char[16] segment name
1544 ** pointer in-memory offset
1545 ** pointer in-memory size
1546 ** pointer in-file offset to data area
1547 ** pointer in-file size
1548 ** (in-memory size excluding zerofill sections)
1549 ** int maximum vm protection
1550 ** int initial vm protection
1551 ** uint32_t number of sections
1552 ** uint32_t flags
1554 ** section commands
1555 ** char[16] section name
1556 ** char[16] segment name
1557 ** pointer in-memory offset
1558 ** pointer in-memory size
1559 ** uint32_t in-file offset
1560 ** uint32_t alignment
1561 ** (irrelevant in MH_OBJECT)
1562 ** uint32_t in-file offset of relocation entires
1563 ** uint32_t number of relocations
1564 ** uint32_t flags
1565 ** uint32_t reserved
1566 ** uint32_t reserved
1568 ** symbol table command
1569 ** uint32_t command type == LC_SYMTAB
1570 ** uint32_t size of load command
1571 ** uint32_t symbol table offset
1572 ** uint32_t number of symbol table entries
1573 ** uint32_t string table offset
1574 ** uint32_t string table size
1576 ** raw section data
1578 ** padding to pointer boundary
1580 ** relocation data (struct reloc)
1581 ** int32_t offset
1582 ** uint data (symbolnum, pcrel, length, extern, type)
1584 ** symbol table data (struct nlist)
1585 ** int32_t string table entry number
1586 ** uint8_t type
1587 ** (extern, absolute, defined in section)
1588 ** uint8_t section
1589 ** (0 for global symbols, section number of definition (>= 1, <=
1590 ** 254) for local symbols, size of variable for common symbols
1591 ** [type == extern])
1592 ** int16_t description
1593 ** (for stab debugging format)
1594 ** pointer value (i.e. file offset) of symbol or stab offset
1596 ** string table data
1597 ** list of null-terminated strings
1600 /* Emit the Mach-O header. */
1601 macho_write_header();
1603 offset = fmt.header_size + head_sizeofcmds;
1605 /* emit the segment load command */
1606 if (seg_nsects > 0)
1607 offset = macho_write_segment (offset);
1608 else
1609 nasm_error(ERR_WARNING, "no sections?");
1611 if (nsyms > 0) {
1612 /* write out symbol command */
1613 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1614 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1615 fwriteint32_t(offset, ofile); /* symbol table offset */
1616 fwriteint32_t(nsyms, ofile); /* number of symbol
1617 ** table entries */
1618 offset += nsyms * fmt.nlist_size;
1619 fwriteint32_t(offset, ofile); /* string table offset */
1620 fwriteint32_t(strslen, ofile); /* string table size */
1623 /* emit section data */
1624 if (seg_nsects > 0)
1625 macho_write_section ();
1627 /* emit symbol table if we have symbols */
1628 if (nsyms > 0)
1629 macho_write_symtab ();
1631 /* we don't need to pad here, we are already aligned */
1633 /* emit string table */
1634 saa_fpwrite(strs, ofile);
1636 /* We do quite a bit here, starting with finalizing all of the data
1637 for the object file, writing, and then freeing all of the data from
1638 the file. */
1640 static void macho_cleanup(void)
1642 struct section *s;
1643 struct reloc *r;
1644 struct symbol *sym;
1646 dfmt->cleanup();
1648 /* Sort all symbols. */
1649 macho_layout_symbols (&nsyms, &strslen);
1651 /* Fixup relocation entries */
1652 for (s = sects; s != NULL; s = s->next) {
1653 macho_fixup_relocs (s->relocs);
1656 /* First calculate and finalize needed values. */
1657 macho_calculate_sizes();
1658 macho_write();
1660 /* free up everything */
1661 while (sects->next) {
1662 s = sects;
1663 sects = sects->next;
1665 saa_free(s->data);
1666 while (s->relocs != NULL) {
1667 r = s->relocs;
1668 s->relocs = s->relocs->next;
1669 nasm_free(r);
1672 nasm_free(s);
1675 saa_free(strs);
1676 raa_free(extsyms);
1678 while (syms) {
1679 sym = syms;
1680 syms = syms->next;
1681 nasm_free (sym);
1684 nasm_free(extdefsyms);
1685 nasm_free(undefsyms);
1686 nasm_free(sectstab);
1689 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1691 struct section *s;
1692 int32_t nasm_seg;
1693 int64_t offset;
1695 if (!lookup_label(label, &nasm_seg, &offset)) {
1696 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1697 return false;
1700 s = get_section_by_index(nasm_seg);
1701 if (!s) {
1702 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1703 return false;
1706 s->flags |= flags;
1707 return true;
1711 * Mark a symbol for no dead stripping
1713 static enum directive_result macho_no_dead_strip(const char *labels)
1715 char *s, *p, *ep;
1716 char ec;
1717 enum directive_result rv = DIRR_ERROR;
1718 bool real = passn > 1;
1720 p = s = nasm_strdup(labels);
1721 while (*p) {
1722 ep = nasm_skip_identifier(p);
1723 if (!ep) {
1724 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1725 goto err;
1727 ec = *ep;
1728 if (ec && ec != ',' && !nasm_isspace(ec)) {
1729 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1730 goto err;
1732 *ep = '\0';
1733 if (real) {
1734 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1735 rv = DIRR_ERROR;
1737 *ep = ec;
1738 p = nasm_skip_spaces(ep);
1739 if (*p == ',')
1740 p = nasm_skip_spaces(++p);
1743 rv = DIRR_OK;
1745 err:
1746 nasm_free(s);
1747 return rv;
1751 * Mach-O pragmas
1753 static enum directive_result
1754 macho_pragma(const struct pragma *pragma)
1756 bool real = passn > 1;
1758 switch (pragma->opcode) {
1759 case D_SUBSECTIONS_VIA_SYMBOLS:
1760 if (*pragma->tail)
1761 return DIRR_BADPARAM;
1763 if (real)
1764 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1766 return DIRR_OK;
1768 case D_NO_DEAD_STRIP:
1769 return macho_no_dead_strip(pragma->tail);
1771 default:
1772 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1776 static const struct pragma_facility macho_pragma_list[] = {
1777 { "macho", macho_pragma },
1778 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1781 static void macho_dbg_generate(void)
1783 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1784 size_t saa_len = 0, high_addr = 0, total_len = 0;
1785 struct section *p_section = NULL;
1786 /* calculated at debug_str and referenced at debug_info */
1787 uint32_t producer_str_offset = 0, module_str_offset = 0;
1789 /* debug section defines */
1791 int bits = 0;
1792 macho_section(".debug_abbrev", 0, &bits);
1793 macho_section(".debug_info", 0, &bits);
1794 macho_section(".debug_line", 0, &bits);
1795 macho_section(".debug_str", 0, &bits);
1798 /* dw section walk to find high_addr and total_len */
1800 struct dw_sect_list *p_sect = dw_head_sect;
1801 uint32_t idx = 0;
1802 for(; idx < dw_num_sects; idx++) {
1803 uint64_t offset = get_section_by_index(p_sect->section)->size;
1804 struct SAA *p_linep = p_sect->psaa;
1806 saa_write8(p_linep, 2); /* std op 2 */
1807 saa_write8(p_linep, offset - p_sect->offset);
1808 saa_write8(p_linep, DW_LNS_extended_op);
1809 saa_write8(p_linep, 1); /* operand length */
1810 saa_write8(p_linep, DW_LNE_end_sequence);
1812 total_len += p_linep->datalen;
1813 high_addr += offset;
1814 p_sect = p_sect->next;
1818 /* debug line */
1820 struct file_list *p_file = dw_head_list;
1821 struct dw_sect_list *p_sect = dw_head_sect;
1822 size_t linep_off = 0;
1823 uint32_t idx = 0, buf_size = 0;
1824 struct SAA *p_lines = saa_init(1L);
1825 nasm_assert(p_lines != NULL);
1827 p_section = get_section_by_name("__DWARF", "__debug_line");
1828 nasm_assert(p_section != NULL);
1830 saa_write8(p_lines, 1); /* minimum instruction length */
1831 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1832 saa_write8(p_lines, DW_LN_BASE); /* line base */
1833 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1834 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1835 saa_write8(p_lines, 0); /* std opcode 1 length */
1836 saa_write8(p_lines, 1); /* std opcode 2 length */
1837 saa_write8(p_lines, 1); /* std opcode 3 length */
1838 saa_write8(p_lines, 1); /* std opcode 4 length */
1839 saa_write8(p_lines, 1); /* std opcode 5 length */
1840 saa_write8(p_lines, 0); /* std opcode 6 length */
1841 saa_write8(p_lines, 0); /* std opcode 7 length */
1842 saa_write8(p_lines, 0); /* std opcode 8 length */
1843 saa_write8(p_lines, 1); /* std opcode 9 length */
1844 saa_write8(p_lines, 0); /* std opcode 10 length */
1845 saa_write8(p_lines, 0); /* std opcode 11 length */
1846 saa_write8(p_lines, 1); /* std opcode 12 length */
1847 saa_write8(p_lines, 0); /* end of table */
1849 for(idx = 0; idx < dw_num_files; idx++) {
1850 saa_wbytes(p_lines, p_file->file_name, (int32_t)(strlen(p_file->file_name) +1));
1851 saa_write8(p_lines, 0); /* directory */
1852 saa_write8(p_lines, 0); /* time */
1853 saa_write8(p_lines, 0); /* size */
1854 p_file = p_file->next;
1856 saa_write8(p_lines, 0); /* end of table */
1858 linep_off = p_lines->datalen;
1859 /* 10 bytes for initial & prolong length, and dwarf version info */
1860 buf_size = saa_len = linep_off + total_len + 10;
1861 p_buf_base = p_buf = nasm_malloc(buf_size);
1863 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1864 WRITESHORT(p_buf, 2); /* dwarf version */
1865 WRITELONG(p_buf, linep_off); /* prolong length */
1867 saa_rnbytes(p_lines, p_buf, linep_off);
1868 p_buf += linep_off;
1869 saa_free(p_lines);
1871 for(idx = 0; idx < dw_num_sects; idx++) {
1872 struct SAA *p_linep = p_sect->psaa;
1873 saa_len = p_linep->datalen;
1874 saa_rnbytes(p_linep, p_buf, saa_len);
1875 p_buf += saa_len;
1876 saa_free(p_linep);
1877 p_sect = p_sect->next;
1880 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1884 /* string section */
1886 struct file_list *p_file = dw_head_list;
1887 uint32_t idx = 0;
1888 struct SAA *p_str = saa_init(1L);
1889 nasm_assert(p_str != NULL);
1891 p_section = get_section_by_name("__DWARF", "__debug_str");
1892 nasm_assert(p_section != NULL);
1894 producer_str_offset = 0;
1895 saa_wbytes(p_str, nasm_signature, strlen(nasm_signature) + 1);
1897 module_str_offset = producer_str_offset + strlen(nasm_signature) + 1;
1898 for(; idx < dw_num_files; idx++) {
1899 saa_wbytes(p_str, p_file->file_name, (int32_t)(strlen(p_file->file_name) + 1));
1900 p_file = p_file->next;
1903 saa_len = p_str->datalen;
1905 p_buf = nasm_malloc(saa_len);
1906 saa_rnbytes(p_str, p_buf, saa_len);
1907 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1909 saa_free(p_str);
1912 /* debug info */
1914 struct SAA *p_info = saa_init(1L);
1915 nasm_assert(p_info != NULL);
1917 p_section = get_section_by_name("__DWARF", "__debug_info");
1918 nasm_assert(p_section != NULL);
1920 /* size will be overwritten once determined, so skip in p_info layout */
1921 saa_write16(p_info, 2); /* dwarf version */
1922 saa_write32(p_info, 0); /* offset info abbrev */
1923 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1925 saa_write8(p_info, 1); /* abbrev entry number */
1927 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1928 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1929 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1930 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1932 if (ofmt == &of_macho64) {
1933 saa_write64(p_info, 0); /* DW_AT_low_pc */
1934 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1935 } else {
1936 saa_write32(p_info, 0); /* DW_AT_low_pc */
1937 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1940 saa_write8(p_info, 2); /* abbrev entry number */
1942 if (ofmt == &of_macho64) {
1943 saa_write64(p_info, 0); /* DW_AT_low_pc */
1944 saa_write64(p_info, 0); /* DW_AT_frame_base */
1945 } else {
1946 saa_write32(p_info, 0); /* DW_AT_low_pc */
1947 saa_write32(p_info, 0); /* DW_AT_frame_base */
1949 saa_write8(p_info, DW_END_default);
1951 saa_len = p_info->datalen;
1952 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1954 WRITELONG(p_buf, saa_len);
1955 saa_rnbytes(p_info, p_buf, saa_len);
1956 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1958 saa_free(p_info);
1961 /* abbrev section */
1963 struct SAA *p_abbrev = saa_init(1L);
1964 nasm_assert(p_abbrev != NULL);
1966 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
1967 nasm_assert(p_section != NULL);
1969 saa_write8(p_abbrev, 1); /* entry number */
1971 saa_write8(p_abbrev, DW_TAG_compile_unit);
1972 saa_write8(p_abbrev, DW_CHILDREN_yes);
1974 saa_write8(p_abbrev, DW_AT_producer);
1975 saa_write8(p_abbrev, DW_FORM_strp);
1977 saa_write8(p_abbrev, DW_AT_language);
1978 saa_write8(p_abbrev, DW_FORM_data2);
1980 saa_write8(p_abbrev, DW_AT_name);
1981 saa_write8(p_abbrev, DW_FORM_strp);
1983 saa_write8(p_abbrev, DW_AT_stmt_list);
1984 saa_write8(p_abbrev, DW_FORM_data4);
1986 saa_write8(p_abbrev, DW_AT_low_pc);
1987 saa_write8(p_abbrev, DW_FORM_addr);
1989 saa_write8(p_abbrev, DW_AT_high_pc);
1990 saa_write8(p_abbrev, DW_FORM_addr);
1992 saa_write16(p_abbrev, DW_END_default);
1994 saa_write8(p_abbrev, 2); /* entry number */
1996 saa_write8(p_abbrev, DW_TAG_subprogram);
1997 saa_write8(p_abbrev, DW_CHILDREN_no);
1999 saa_write8(p_abbrev, DW_AT_low_pc);
2000 saa_write8(p_abbrev, DW_FORM_addr);
2002 saa_write8(p_abbrev, DW_AT_frame_base);
2003 saa_write8(p_abbrev, DW_FORM_addr);
2005 saa_write16(p_abbrev, DW_END_default);
2007 saa_len = p_abbrev->datalen;
2009 p_buf = nasm_malloc(saa_len);
2011 saa_rnbytes(p_abbrev, p_buf, saa_len);
2012 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2014 saa_free(p_abbrev);
2018 static void macho_dbg_init(void)
2022 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2024 bool need_new_list = true;
2025 (void)segto;
2027 if(!dw_cur_list || strcmp(file_name, dw_cur_list->file_name)) {
2028 if(dw_head_list) {
2029 struct file_list *match = dw_head_list;
2030 uint32_t idx = 0;
2032 for (; idx < dw_num_files; idx++ ) {
2033 if(!(strcmp(file_name, match->file_name))) {
2034 dw_cur_list = match;
2035 need_new_list = false;
2036 break;
2038 match = match->next;
2042 if(need_new_list) {
2043 nasm_new(dw_cur_list);
2044 dw_cur_list->file = ++dw_num_files;
2045 dw_cur_list->file_name = (char*) file_name;
2047 if(!dw_head_list) {
2048 dw_head_list = dw_last_list = dw_cur_list;
2049 } else {
2050 dw_last_list->next = dw_cur_list;
2051 dw_last_list = dw_cur_list;
2056 dbg_immcall = true;
2057 cur_line = line_num;
2060 static void macho_dbg_output(int type, void *param)
2062 struct section_info *sinfo_param = (struct section_info *)param;
2063 int32_t secto = sinfo_param->secto;
2064 bool need_new_sect = false;
2065 struct SAA *p_linep = NULL;
2066 (void)type;
2068 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2069 need_new_sect = true;
2070 if(dw_head_sect) {
2071 struct dw_sect_list *match = dw_head_sect;
2072 uint32_t idx = 0;
2074 for(; idx < dw_num_sects; idx++) {
2075 if(match->section == secto) {
2076 dw_cur_sect = match;
2077 need_new_sect = false;
2078 break;
2080 match = match->next;
2085 if(need_new_sect) {
2086 nasm_new(dw_cur_sect);
2087 dw_num_sects ++;
2088 p_linep = dw_cur_sect->psaa = saa_init(1L);
2089 dw_cur_sect->line = dw_cur_sect->file = 1;
2090 dw_cur_sect->offset = 0;
2091 dw_cur_sect->next = NULL;
2092 dw_cur_sect->section = secto;
2094 saa_write8(p_linep, DW_LNS_extended_op);
2095 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2096 saa_write8(p_linep, DW_LNE_set_address);
2097 if (ofmt == &of_macho64) {
2098 saa_write64(p_linep, 0);
2099 } else {
2100 saa_write32(p_linep, 0);
2103 if(!dw_head_sect) {
2104 dw_head_sect = dw_last_sect = dw_cur_sect;
2105 } else {
2106 dw_last_sect->next = dw_cur_sect;
2107 dw_last_sect = dw_cur_sect;
2111 if(dbg_immcall == true) {
2112 int32_t line_delta = cur_line - dw_cur_sect->line;
2113 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2114 uint32_t cur_file = dw_cur_list->file;
2115 p_linep = dw_cur_sect->psaa;
2117 if(cur_file != dw_cur_sect->file) {
2118 saa_write8(p_linep, DW_LNS_set_file);
2119 saa_write8(p_linep, cur_file);
2120 dw_cur_sect->file = cur_file;
2123 if(line_delta) {
2124 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2125 DW_OPCODE_BASE;
2127 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2128 (special_opcode < DW_MAX_SP_OPCODE)) {
2129 saa_write8(p_linep, special_opcode);
2130 } else {
2131 saa_write8(p_linep, DW_LNS_advance_line);
2132 saa_wleb128s(p_linep, line_delta);
2133 if(offset_delta) {
2134 saa_write8(p_linep, DW_LNS_advance_pc);
2135 saa_wleb128u(p_linep, offset_delta);
2137 saa_write8(p_linep, DW_LNS_copy);
2140 dw_cur_sect->line = cur_line;
2141 dw_cur_sect->offset = sinfo_param->size;
2144 dbg_immcall = false;
2148 static void macho_dbg_cleanup(void)
2150 /* dwarf sectors generation */
2151 macho_dbg_generate();
2154 struct dw_sect_list *p_sect = dw_head_sect;
2155 struct file_list *p_file = dw_head_list;
2156 uint32_t idx = 0;
2158 for(; idx < dw_num_sects; idx++) {
2159 struct dw_sect_list *next = p_sect->next;
2160 nasm_free(p_sect);
2161 p_sect = next;
2164 for(idx = 0; idx < dw_num_files; idx++) {
2165 struct file_list *next = p_file->next;
2166 nasm_free(p_file);
2167 p_file = next;
2172 #ifdef OF_MACHO32
2173 static const struct macho_fmt macho32_fmt = {
2175 MH_MAGIC,
2176 CPU_TYPE_I386,
2177 LC_SEGMENT,
2178 MACHO_HEADER_SIZE,
2179 MACHO_SEGCMD_SIZE,
2180 MACHO_SECTCMD_SIZE,
2181 MACHO_NLIST_SIZE,
2182 RL_MAX_32,
2183 GENERIC_RELOC_VANILLA,
2184 GENERIC_RELOC_VANILLA,
2185 GENERIC_RELOC_TLV
2188 static void macho32_init(void)
2190 fmt = macho32_fmt;
2191 macho_init();
2193 macho_gotpcrel_sect = NO_SEG;
2196 static const struct dfmt macho32_df_dwarf = {
2197 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2198 "dwarf",
2199 macho_dbg_init,
2200 macho_dbg_linenum,
2201 null_debug_deflabel,
2202 null_debug_directive,
2203 null_debug_typevalue,
2204 macho_dbg_output,
2205 macho_dbg_cleanup,
2206 NULL /*pragma list*/
2209 static const struct dfmt * const macho32_df_arr[2] =
2210 { &macho32_df_dwarf, NULL };
2212 const struct ofmt of_macho32 = {
2213 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2214 "macho32",
2217 macho32_df_arr,
2218 &macho32_df_dwarf,
2219 macho_stdmac,
2220 macho32_init,
2221 nasm_do_legacy_output,
2222 macho_output,
2223 macho_symdef,
2224 macho_section,
2225 macho_sectalign,
2226 macho_segbase,
2227 null_directive,
2228 macho_filename,
2229 macho_cleanup,
2230 macho_pragma_list,
2232 #endif
2234 #ifdef OF_MACHO64
2235 static const struct macho_fmt macho64_fmt = {
2237 MH_MAGIC_64,
2238 CPU_TYPE_X86_64,
2239 LC_SEGMENT_64,
2240 MACHO_HEADER64_SIZE,
2241 MACHO_SEGCMD64_SIZE,
2242 MACHO_SECTCMD64_SIZE,
2243 MACHO_NLIST64_SIZE,
2244 RL_MAX_64,
2245 X86_64_RELOC_UNSIGNED,
2246 X86_64_RELOC_SIGNED,
2247 X86_64_RELOC_TLV
2250 static void macho64_init(void)
2252 fmt = macho64_fmt;
2253 macho_init();
2255 /* add special symbol for ..gotpcrel */
2256 macho_gotpcrel_sect = seg_alloc() + 1;
2257 define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2260 static const struct dfmt macho64_df_dwarf = {
2261 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2262 "dwarf",
2263 macho_dbg_init,
2264 macho_dbg_linenum,
2265 null_debug_deflabel,
2266 null_debug_directive,
2267 null_debug_typevalue,
2268 macho_dbg_output,
2269 macho_dbg_cleanup,
2270 NULL /*pragma list*/
2273 static const struct dfmt * const macho64_df_arr[2] =
2274 { &macho64_df_dwarf, NULL };
2276 const struct ofmt of_macho64 = {
2277 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2278 "macho64",
2281 macho64_df_arr,
2282 &macho64_df_dwarf,
2283 macho_stdmac,
2284 macho64_init,
2285 nasm_do_legacy_output,
2286 macho_output,
2287 macho_symdef,
2288 macho_section,
2289 macho_sectalign,
2290 macho_segbase,
2291 null_directive,
2292 macho_filename,
2293 macho_cleanup,
2294 macho_pragma_list,
2296 #endif
2298 #endif
2301 * Local Variables:
2302 * mode:c
2303 * c-basic-offset:4
2304 * End:
2306 * end of file */