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
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
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 */
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
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
);
154 /* nasm internal data */
155 struct section
*next
;
157 int32_t index
; /* Main section index */
158 int32_t subsection
; /* Current subsection index */
160 struct reloc
*relocs
;
161 struct rbtree
*syms
[2]; /* All/global symbols symbols in section */
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
;
203 /* nasm internal data */
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
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 */
222 /* nasm internal data */
223 struct rbtree symv
[2]; /* All/global symbol rbtrees; "key" contains the
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
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:
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 RAAPTR
*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
;
326 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
328 sp
= hash_find(§ion_by_name
, sect
, &hi
);
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
);
344 static inline bool is_new_section(const struct section
*s
)
349 static struct section
*get_section_by_name(const char *segname
,
350 const char *sectname
)
355 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
357 sp
= hash_find(§ion_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))
366 return raa_read_ptr(section_by_index
, index
>> 1);
370 struct dir_list
*next
;
371 struct dir_list
*last
;
372 const char *dir_name
;
377 struct file_list
*next
;
378 struct file_list
*last
;
379 const char *file_name
;
381 struct dir_list
*dir
;
384 struct dw_sect_list
{
390 struct dw_sect_list
*next
;
391 struct dw_sect_list
*last
;
394 struct section_info
{
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
417 static int32_t macho_tlvp_sect
;
418 static int32_t macho_gotpcrel_sect
;
420 static void macho_init(void)
422 module_name
= inname
;
426 /* Fake section for absolute symbols */
427 absolute_sect
.index
= NO_SEG
;
436 extsyms
= raa_init();
439 section_by_index
= raa_init_ptr();
440 hash_init(§ion_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);
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
);
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
)
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 " : "");
476 return container_of(srb
- global
, struct symbol
, symv
);
479 static int64_t add_reloc(struct section
*sect
, int32_t section
,
481 enum reltype reltype
, int bytes
)
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
;
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
;
508 s
= get_section_by_index(section
);
509 fi
= s
? s
->fileindex
: NO_SECT
;
511 /* absolute relocation */
514 if (section
== NO_SEG
) {
515 /* absolute (can this even happen?) */
517 } else if (fi
== NO_SECT
) {
519 r
->snum
= raa_read(extsyms
, section
);
529 r
->type
= fmt
.reloc_rel
;
531 if (section
== NO_SEG
) {
532 /* may optionally be converted below by fmt.forcesym */
534 } else if (fi
== NO_SECT
) {
537 r
->snum
= raa_read(extsyms
, section
);
538 if (reltype
== RL_BRANCH
)
539 r
->type
= X86_64_RELOC_BRANCH
;
544 if (reltype
== RL_BRANCH
)
545 r
->type
= X86_64_RELOC_BRANCH
;
549 case RL_SUB
: /* obsolete */
550 nasm_error(ERR_WARNING
, "relcation with subtraction"
551 "becomes to be obsolete");
553 r
->type
= X86_64_RELOC_SUBTRACTOR
;
557 r
->type
= X86_64_RELOC_GOT
;
561 r
->type
= X86_64_RELOC_GOT_LOAD
;
565 r
->type
= fmt
.reloc_tlv
;
569 r
->pcrel
= (fmt
.ptrsize
== 8 ? 1 : 0);
570 if (section
== NO_SEG
) {
571 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
573 } else if (fi
== NO_SECT
) {
575 r
->snum
= raa_read(extsyms
, section
);
577 /* internal - GOTPCREL doesn't need to be in global */
578 struct symbol
*sym
= macho_find_sym(s
, offset
,
579 false, /* reltype != RL_TLV */
582 nasm_error(ERR_NONFATAL
, "Symbol for WRT not found");
586 adjust
-= sym
->symv
[0].key
;
587 r
->snum
= sym
->initial_snum
;
593 * For 64-bit Mach-O, force a symbol reference if at all possible
594 * Allow for r->snum == R_ABS by searching absolute_sect
596 if (!r
->ext
&& fmt
.forcesym
) {
597 struct symbol
*sym
= macho_find_sym(s
? s
: &absolute_sect
,
598 offset
, false, false);
600 adjust
-= sym
->symv
[0].key
;
601 r
->snum
= sym
->initial_snum
;
607 adjust
+= ((r
->ext
&& fmt
.ptrsize
== 8) ? bytes
: -(int64_t)sect
->size
);
609 /* NeXT as puts relocs in reversed order (address-wise) into the
610 ** files, so we do the same, doesn't seem to make much of a
611 ** difference either way */
612 r
->next
= sect
->relocs
;
625 static void macho_output(int32_t secto
, const void *data
,
626 enum out_type type
, uint64_t size
,
627 int32_t section
, int32_t wrt
)
630 int64_t addr
, offset
;
631 uint8_t mydata
[16], *p
;
633 enum reltype reltype
;
635 if (secto
== NO_SEG
) {
636 if (type
!= OUT_RESERVE
)
637 nasm_error(ERR_NONFATAL
, "attempt to assemble code in "
642 s
= get_section_by_index(secto
);
644 nasm_error(ERR_WARNING
, "attempt to assemble code in"
645 " section %d: defaulting to `.text'", secto
);
646 s
= get_section_by_name("__TEXT", "__text");
648 /* should never happen */
650 nasm_panic(0, "text section not found");
653 /* debug code generation only for sections tagged with
654 * instruction attribute */
655 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
657 struct section_info sinfo
;
658 sinfo
.size
= s
->size
;
660 dfmt
->debug_output(0, &sinfo
);
663 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
665 if (is_bss
&& type
!= OUT_RESERVE
) {
666 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
667 "BSS section: ignored");
668 s
->size
+= realsize(type
, size
);
672 memset(mydata
, 0, sizeof(mydata
));
677 nasm_error(ERR_WARNING
, "uninitialized space declared in"
678 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
680 sect_write(s
, NULL
, size
);
687 if (section
!= NO_SEG
)
688 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
690 sect_write(s
, data
, size
);
695 int asize
= abs((int)size
);
697 addr
= *(int64_t *)data
;
698 if (section
!= NO_SEG
) {
700 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
701 " section base references");
702 } else if (wrt
== NO_SEG
) {
703 if (fmt
.ptrsize
== 8 && asize
!= 8) {
704 nasm_error(ERR_NONFATAL
,
705 "Mach-O 64-bit format does not support"
706 " 32-bit absolute addresses");
708 addr
+= add_reloc(s
, section
, addr
, RL_ABS
, asize
);
710 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
!= 8 &&
711 asize
== (int) fmt
.ptrsize
) {
712 addr
+= add_reloc(s
, section
, addr
, RL_TLV
, asize
);
714 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
720 WRITEADDR(p
, addr
, asize
);
721 sect_write(s
, mydata
, asize
);
729 offset
= *(int64_t *)data
;
730 addr
= offset
- size
;
732 if (section
!= NO_SEG
&& section
% 2) {
733 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
734 " section base references");
735 } else if (fmt
.ptrsize
== 8) {
736 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
737 " Macho-O relocation [2]");
738 } else if (wrt
!= NO_SEG
) {
739 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
741 wrt
= NO_SEG
; /* we can at least _try_ to continue */
743 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
,
744 type
== OUT_REL1ADR
? 1 : 2);
748 sect_write(s
, mydata
, type
== OUT_REL1ADR
? 1 : 2);
755 offset
= *(int64_t *)data
;
756 addr
= offset
- size
;
759 if (section
!= NO_SEG
&& section
% 2) {
760 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
761 " section base references");
762 } else if (wrt
== NO_SEG
) {
763 if (fmt
.ptrsize
== 8 &&
764 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
767 opcode
[0] = opcode
[1] = 0;
769 /* HACK: Retrieve instruction opcode */
770 if (likely(s
->data
->datalen
>= 2)) {
771 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
772 } else if (s
->data
->datalen
== 1) {
773 saa_fread(s
->data
, 0, opcode
+1, 1);
776 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
777 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
778 /* Direct call, jmp, or jcc */
782 } else if (wrt
== macho_gotpcrel_sect
) {
785 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
786 s
->data
->datalen
>= 3) {
789 /* HACK: Retrieve instruction opcode */
790 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
791 if ((gotload
[0] & 0xf8) == 0x48 &&
792 gotload
[1] == 0x8b &&
793 (gotload
[2] & 0307) == 0005) {
794 /* movq <reg>,[rel sym wrt ..gotpcrel] */
795 reltype
= RL_GOTLOAD
;
798 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
== 8) {
801 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
803 /* continue with RL_REL */
806 addr
+= add_reloc(s
, section
, offset
, reltype
,
807 type
== OUT_REL4ADR
? 4 : 8);
809 sect_write(s
, mydata
, type
== OUT_REL4ADR
? 4 : 8);
813 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
818 /* Translation table from traditional Unix section names to Mach-O */
819 static const struct sectmap
{
820 const char *nasmsect
;
822 const char *sectname
;
823 const uint32_t flags
;
825 {".text", "__TEXT", "__text",
826 S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
827 {".data", "__DATA", "__data", S_REGULAR
},
828 {".rodata", "__DATA", "__const", S_REGULAR
},
829 {".bss", "__DATA", "__bss", S_ZEROFILL
},
830 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
831 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
832 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
833 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
834 {NULL
, NULL
, NULL
, 0}
837 #define NO_TYPE S_NASM_TYPE_MASK
839 /* Section type or attribute directives */
840 static const struct sect_attribs
{
844 { "data", S_REGULAR
},
845 { "code", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
846 { "mixed", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
847 { "bss", S_ZEROFILL
},
848 { "zerofill", S_ZEROFILL
},
849 { "no_dead_strip", NO_TYPE
|S_ATTR_NO_DEAD_STRIP
},
850 { "live_support", NO_TYPE
|S_ATTR_LIVE_SUPPORT
},
851 { "strip_static_syms", NO_TYPE
|S_ATTR_STRIP_STATIC_SYMS
},
852 { "debug", NO_TYPE
|S_ATTR_DEBUG
},
856 static int32_t macho_section(char *name
, int pass
, int *bits
)
858 char *sectionAttributes
;
859 const struct sectmap
*sm
;
861 const char *section
, *segment
;
863 const struct sect_attribs
*sa
;
864 char *currentAttribute
;
871 /* Default to the appropriate number of bits. */
873 *bits
= fmt
.ptrsize
<< 3;
875 sectionAttributes
= NULL
;
877 sectionAttributes
= name
;
878 name
= nasm_strsep(§ionAttributes
, " \t");
881 section
= segment
= NULL
;
884 comma
= strchr(name
, ',');
892 len
= strlen(segment
);
894 nasm_error(ERR_NONFATAL
, "empty segment name\n");
895 } else if (len
> 16) {
896 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
899 len
= strlen(section
);
901 nasm_error(ERR_NONFATAL
, "empty section name\n");
902 } else if (len
> 16) {
903 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
906 if (!strcmp(section
, "__text")) {
907 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
908 S_ATTR_PURE_INSTRUCTIONS
;
909 } else if (!strcmp(section
, "__bss")) {
915 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
916 /* make lookup into section name translation table */
917 if (!strcmp(name
, sm
->nasmsect
)) {
918 segment
= sm
->segname
;
919 section
= sm
->sectname
;
924 nasm_error(ERR_NONFATAL
, "unknown section name\n");
929 /* try to find section with that name, or create it */
930 s
= find_or_add_section(segment
, section
);
931 new_seg
= is_new_section(s
);
933 /* initialize it if it is a brand new section */
936 sectstail
= &s
->next
;
938 s
->data
= saa_init(1L);
939 s
->fileindex
= ++seg_nsects
;
951 *comma
= ','; /* Restore comma */
953 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
957 while (sectionAttributes
&&
958 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
959 if (!*currentAttribute
)
962 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
964 int newAlignment
, value
;
966 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
967 newAlignment
= alignlog2_32(value
);
970 nasm_error(ERR_NONFATAL
,
971 "unknown or missing alignment value \"%s\" "
972 "specified for section \"%s\"",
973 currentAttribute
+ 6,
975 } else if (0 > newAlignment
) {
976 nasm_error(ERR_NONFATAL
,
977 "alignment of %d (for section \"%s\") is not "
983 if (s
->align
< newAlignment
)
984 s
->align
= newAlignment
;
986 for (sa
= sect_attribs
; sa
->name
; sa
++) {
987 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
988 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
989 flags
= (flags
& ~S_NASM_TYPE_MASK
)
990 | (sa
->flags
& S_NASM_TYPE_MASK
);
992 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
998 nasm_error(ERR_NONFATAL
,
999 "unknown section attribute %s for section %s",
1000 currentAttribute
, name
);
1005 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
1006 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
1007 nasm_error(ERR_NONFATAL
,
1008 "inconsistent section attributes for section %s\n",
1011 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
1014 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
1017 return s
->subsection
;
1020 static int32_t macho_herelabel(const char *name
, enum label_type type
,
1021 int32_t section
, int32_t *subsection
,
1028 if (!(head_flags
& MH_SUBSECTIONS_VIA_SYMBOLS
))
1031 /* No subsection only for local labels */
1032 if (type
== LBL_LOCAL
)
1035 s
= get_section_by_index(section
);
1039 subsec
= *subsection
;
1040 if (subsec
== NO_SEG
) {
1041 /* Allocate a new subsection index */
1042 subsec
= *subsection
= seg_alloc();
1043 section_by_index
= raa_write_ptr(section_by_index
, subsec
>> 1, s
);
1046 s
->subsection
= subsec
;
1047 *copyoffset
= true; /* Maintain previous offset */
1051 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
1052 int is_global
, char *special
)
1056 bool special_used
= false;
1058 #if defined(DEBUG) && DEBUG>2
1059 nasm_error(ERR_DEBUG
,
1060 " macho_symdef: %s, pass0=%d, passn=%"PRId64
", sec=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
1061 name
, pass0
, passn
, section
, offset
, is_global
, special
);
1064 if (is_global
== 3) {
1066 int n
= strcspn(special
, " \t");
1068 if (!nasm_strnicmp(special
, "private_extern", n
)) {
1069 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1070 if (!strcmp(name
, sym
->name
)) {
1071 if (sym
->type
& N_PEXT
)
1072 return; /* nothing to be done */
1079 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
1080 "(yet) support forward reference fixups.");
1084 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1086 * This is a NASM special symbol. We never allow it into
1087 * the Macho-O symbol table, even if it's a valid one. If it
1088 * _isn't_ a valid one, we should barf immediately.
1090 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1091 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1095 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1097 symstail
= &sym
->next
;
1100 sym
->strx
= strslen
;
1103 sym
->symv
[0].key
= offset
;
1104 sym
->symv
[1].key
= offset
;
1105 sym
->initial_snum
= -1;
1107 /* external and common symbols get N_EXT */
1108 if (is_global
!= 0) {
1111 if (is_global
== 1) {
1112 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1114 int n
= strcspn(special
, " \t");
1116 if (!nasm_strnicmp(special
, "private_extern", n
))
1117 sym
->type
|= N_PEXT
;
1119 nasm_error(ERR_NONFATAL
, "unrecognised symbol type `%.*s'", n
, special
);
1121 special_used
= true;
1124 /* track the initially allocated symbol number for use in future fix-ups */
1125 sym
->initial_snum
= nsyms
;
1127 if (section
== NO_SEG
) {
1128 /* symbols in no section get absolute */
1130 sym
->sect
= NO_SECT
;
1134 s
= get_section_by_index(section
);
1136 sym
->type
|= N_SECT
;
1138 /* get the in-file index of the section the symbol was defined in */
1139 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1142 /* remember symbol number of references to external
1143 ** symbols, this works because every external symbol gets
1144 ** its own section number allocated internally by nasm and
1145 ** can so be used as a key */
1146 extsyms
= raa_write(extsyms
, section
, nsyms
);
1148 switch (is_global
) {
1151 /* there isn't actually a difference between global
1152 ** and common symbols, both even have their size in
1153 ** sym->symv[0].key */
1158 /* give an error on unfound section if it's not an
1159 ** external or common symbol (assemble_file() does a
1160 ** seg_alloc() on every call for them) */
1161 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section
, is_global
);
1168 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1170 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1175 if (special
&& !special_used
)
1176 nasm_error(ERR_NONFATAL
, "no special symbol features supported here");
1179 static void macho_sectalign(int32_t seg
, unsigned int value
)
1184 nasm_assert(!(seg
& 1));
1186 s
= get_section_by_index(seg
);
1188 if (!s
|| !is_power2(value
))
1191 align
= alignlog2_32(value
);
1192 if (s
->align
< align
)
1196 static int32_t macho_segbase(int32_t section
)
1201 extern macros_t macho_stdmac
[];
1203 /* Comparison function for qsort symbol layout. */
1204 static int layout_compare (const struct symbol
**s1
,
1205 const struct symbol
**s2
)
1207 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1210 /* The native assembler does a few things in a similar function
1212 * Remove temporary labels
1213 * Sort symbols according to local, external, undefined (by name)
1214 * Order the string table
1216 We do not remove temporary labels right now.
1218 numsyms is the total number of symbols we have. strtabsize is the
1219 number entries in the string table. */
1221 static void macho_layout_symbols (uint32_t *numsyms
,
1222 uint32_t *strtabsize
)
1224 struct symbol
*sym
, **symp
;
1228 *strtabsize
= sizeof (char);
1232 while ((sym
= *symp
)) {
1233 /* Undefined symbols are now external. */
1234 if (sym
->type
== N_UNDF
)
1237 if ((sym
->type
& N_EXT
) == 0) {
1238 sym
->snum
= *numsyms
;
1239 *numsyms
= *numsyms
+ 1;
1243 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1249 /* If we handle debug info we'll want
1250 to check for it here instead of just
1251 adding the symbol to the string table. */
1252 sym
->strx
= *strtabsize
;
1253 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1254 *strtabsize
+= strlen(sym
->name
) + 1;
1256 symp
= &(sym
->next
);
1259 /* Next, sort the symbols. Most of this code is a direct translation from
1260 the Apple cctools symbol layout. We need to keep compatibility with that. */
1261 /* Set the indexes for symbol groups into the symbol table */
1263 iextdefsym
= nlocalsym
;
1264 iundefsym
= nlocalsym
+ nextdefsym
;
1266 /* allocate arrays for sorting externals by name */
1267 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1268 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1275 while ((sym
= *symp
)) {
1277 if((sym
->type
& N_EXT
) == 0) {
1278 sym
->strx
= *strtabsize
;
1279 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1280 *strtabsize
+= strlen(sym
->name
) + 1;
1283 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1284 extdefsyms
[i
++] = sym
;
1286 undefsyms
[j
++] = sym
;
1289 symp
= &(sym
->next
);
1292 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1293 (int (*)(const void *, const void *))layout_compare
);
1294 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1295 (int (*)(const void *, const void *))layout_compare
);
1297 for(i
= 0; i
< nextdefsym
; i
++) {
1298 extdefsyms
[i
]->snum
= *numsyms
;
1301 for(j
= 0; j
< nundefsym
; j
++) {
1302 undefsyms
[j
]->snum
= *numsyms
;
1307 /* Calculate some values we'll need for writing later. */
1309 static void macho_calculate_sizes (void)
1314 /* count sections and calculate in-memory and in-file offsets */
1315 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1318 /* recalculate segment address based on alignment and vm size */
1319 s
->addr
= seg_vmsize
;
1321 /* we need section alignment to calculate final section address */
1323 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1325 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1328 seg_vmsize
= newaddr
+ s
->size
;
1330 /* zerofill sections aren't actually written to the file */
1331 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1333 * LLVM/Xcode as always aligns the section data to 4
1334 * bytes; there is a comment in the LLVM source code that
1335 * perhaps aligning to pointer size would be better.
1337 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1338 s
->offset
= seg_filesize
+ s
->pad
;
1339 seg_filesize
+= s
->size
+ s
->pad
;
1341 /* filesize and vmsize needs to be aligned */
1342 seg_vmsize
+= s
->pad
;
1346 /* calculate size of all headers, load commands and sections to
1347 ** get a pointer to the start of all the raw data */
1348 if (seg_nsects
> 0) {
1350 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1355 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1358 if (seg_nsects
> MAX_SECT
) {
1359 nasm_fatal(0, "MachO output is limited to %d sections\n",
1363 /* Create a table of sections by file index to avoid linear search */
1364 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1365 sectstab
[NO_SECT
] = &absolute_sect
;
1366 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1370 /* Write out the header information for the file. */
1372 static void macho_write_header (void)
1374 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1375 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1376 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1377 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1378 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1379 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1380 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1381 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1384 /* Write out the segment load command at offset. */
1386 static uint32_t macho_write_segment (uint64_t offset
)
1388 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1389 uint32_t s_reloff
= 0;
1392 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1394 /* size of load command including section load commands */
1395 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1398 /* in an MH_OBJECT file all sections are in one unnamed (name
1399 ** all zeros) segment */
1400 fwritezero(16, ofile
);
1401 fwriteptr(0, ofile
); /* in-memory offset */
1402 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1403 fwriteptr(offset
, ofile
); /* in-file offset to data */
1404 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1405 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1406 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1407 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1408 fwriteint32_t(0, ofile
); /* no flags */
1410 /* emit section headers */
1411 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1413 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1414 s
->flags
|= S_ATTR_LOC_RELOC
;
1416 s
->flags
|= S_ATTR_EXT_RELOC
;
1417 } else if (!xstrncmp(s
->segname
, "__DATA") &&
1418 !xstrncmp(s
->sectname
, "__const") &&
1420 !get_section_by_name("__TEXT", "__const")) {
1422 * The MachO equivalent to .rodata can be either
1423 * __DATA,__const or __TEXT,__const; the latter only if
1424 * there are no relocations. However, when mixed it is
1425 * better to specify the segments explicitly.
1427 xstrncpy(s
->segname
, "__TEXT");
1430 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1431 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1432 fwriteptr(s
->addr
, ofile
);
1433 fwriteptr(s
->size
, ofile
);
1435 /* dummy data for zerofill sections or proper values */
1436 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1437 nasm_assert(s
->pad
!= (uint32_t)-1);
1439 fwriteint32_t(offset
, ofile
);
1441 /* Write out section alignment, as a power of two.
1442 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1443 fwriteint32_t(s
->align
, ofile
);
1444 /* To be compatible with cctools as we emit
1445 a zero reloff if we have no relocations. */
1446 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1447 fwriteint32_t(s
->nreloc
, ofile
);
1449 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1451 fwriteint32_t(0, ofile
);
1452 fwriteint32_t(s
->align
, ofile
);
1453 fwriteint32_t(0, ofile
);
1454 fwriteint32_t(0, ofile
);
1457 fwriteint32_t(s
->flags
, ofile
); /* flags */
1458 fwriteint32_t(0, ofile
); /* reserved */
1459 fwriteptr(0, ofile
); /* reserved */
1462 rel_padcnt
= rel_base
- offset
;
1463 offset
= rel_base
+ s_reloff
;
1468 /* For a given chain of relocs r, write out the entire relocation
1469 chain to the object file. */
1471 static void macho_write_relocs (struct reloc
*r
)
1476 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1479 word2
|= r
->pcrel
<< 24;
1480 word2
|= r
->length
<< 25;
1481 word2
|= r
->ext
<< 27;
1482 word2
|= r
->type
<< 28;
1483 fwriteint32_t(word2
, ofile
); /* reloc data */
1488 /* Write out the section data. */
1489 static void macho_write_section (void)
1501 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1502 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1505 /* Like a.out Mach-O references things in the data or bss
1506 * sections by addresses which are actually relative to the
1507 * start of the _text_ section, in the _file_. See outaout.c
1508 * for more information. */
1509 saa_rewind(s
->data
);
1510 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1511 len
= (uint32_t)1 << r
->length
;
1512 if (len
> 4) /* Can this ever be an issue?! */
1515 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1517 /* get offset based on relocation type */
1518 #ifdef WORDS_LITTLEENDIAN
1522 l
+= ((int64_t)blk
.buf
[1]) << 8;
1523 l
+= ((int64_t)blk
.buf
[2]) << 16;
1524 l
+= ((int64_t)blk
.buf
[3]) << 24;
1525 l
+= ((int64_t)blk
.buf
[4]) << 32;
1526 l
+= ((int64_t)blk
.buf
[5]) << 40;
1527 l
+= ((int64_t)blk
.buf
[6]) << 48;
1528 l
+= ((int64_t)blk
.buf
[7]) << 56;
1531 /* If the relocation is internal add to the current section
1532 offset. Otherwise the only value we need is the symbol
1533 offset which we already have. The linker takes care
1534 of the rest of the address. */
1536 /* generate final address by section address and offset */
1537 nasm_assert(r
->snum
<= seg_nsects
);
1538 l
+= sectstab
[r
->snum
]->addr
;
1541 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1545 /* write new offset back */
1548 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1551 /* dump the section data to file */
1552 fwritezero(s
->pad
, ofile
);
1553 saa_fpwrite(s
->data
, ofile
);
1556 /* pad last section up to reloc entries on pointer boundary */
1557 fwritezero(rel_padcnt
, ofile
);
1559 /* emit relocation entries */
1560 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1561 macho_write_relocs (s
->relocs
);
1564 /* Write out the symbol table. We should already have sorted this
1566 static void macho_write_symtab (void)
1571 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1573 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1574 if ((sym
->type
& N_EXT
) == 0) {
1575 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1576 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1577 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1578 fwriteint16_t(sym
->desc
, ofile
); /* description */
1580 /* Fix up the symbol value now that we know the final section
1582 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1583 nasm_assert(sym
->sect
<= seg_nsects
);
1584 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1587 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1591 for (i
= 0; i
< nextdefsym
; i
++) {
1592 sym
= extdefsyms
[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
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) */
1608 for (i
= 0; i
< nundefsym
; i
++) {
1610 fwriteint32_t(sym
->strx
, ofile
);
1611 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1612 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1613 fwriteint16_t(sym
->desc
, ofile
); /* description */
1615 /* Fix up the symbol value now that we know the final section
1617 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1618 nasm_assert(sym
->sect
<= seg_nsects
);
1619 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1622 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1627 /* Fixup the snum in the relocation entries, we should be
1628 doing this only for externally referenced symbols. */
1629 static void macho_fixup_relocs (struct reloc
*r
)
1635 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1636 if (sym
->initial_snum
== r
->snum
) {
1637 r
->snum
= sym
->snum
;
1646 /* Write out the object file. */
1648 static void macho_write (void)
1650 uint64_t offset
= 0;
1652 /* mach-o object file structure:
1658 ** uint32_t mach file type
1659 ** uint32_t number of load commands
1660 ** uint32_t size of all load commands
1661 ** (includes section struct size of segment command)
1665 ** uint32_t command type == LC_SEGMENT[_64]
1666 ** uint32_t size of load command
1667 ** (including section load commands)
1668 ** char[16] segment name
1669 ** pointer in-memory offset
1670 ** pointer in-memory size
1671 ** pointer in-file offset to data area
1672 ** pointer in-file size
1673 ** (in-memory size excluding zerofill sections)
1674 ** int maximum vm protection
1675 ** int initial vm protection
1676 ** uint32_t number of sections
1680 ** char[16] section name
1681 ** char[16] segment name
1682 ** pointer in-memory offset
1683 ** pointer in-memory size
1684 ** uint32_t in-file offset
1685 ** uint32_t alignment
1686 ** (irrelevant in MH_OBJECT)
1687 ** uint32_t in-file offset of relocation entires
1688 ** uint32_t number of relocations
1690 ** uint32_t reserved
1691 ** uint32_t reserved
1693 ** symbol table command
1694 ** uint32_t command type == LC_SYMTAB
1695 ** uint32_t size of load command
1696 ** uint32_t symbol table offset
1697 ** uint32_t number of symbol table entries
1698 ** uint32_t string table offset
1699 ** uint32_t string table size
1703 ** padding to pointer boundary
1705 ** relocation data (struct reloc)
1707 ** uint data (symbolnum, pcrel, length, extern, type)
1709 ** symbol table data (struct nlist)
1710 ** int32_t string table entry number
1712 ** (extern, absolute, defined in section)
1714 ** (0 for global symbols, section number of definition (>= 1, <=
1715 ** 254) for local symbols, size of variable for common symbols
1716 ** [type == extern])
1717 ** int16_t description
1718 ** (for stab debugging format)
1719 ** pointer value (i.e. file offset) of symbol or stab offset
1721 ** string table data
1722 ** list of null-terminated strings
1725 /* Emit the Mach-O header. */
1726 macho_write_header();
1728 offset
= fmt
.header_size
+ head_sizeofcmds
;
1730 /* emit the segment load command */
1732 offset
= macho_write_segment (offset
);
1734 nasm_error(ERR_WARNING
, "no sections?");
1737 /* write out symbol command */
1738 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1739 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1740 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1741 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1743 offset
+= nsyms
* fmt
.nlist_size
;
1744 fwriteint32_t(offset
, ofile
); /* string table offset */
1745 fwriteint32_t(strslen
, ofile
); /* string table size */
1748 /* emit section data */
1750 macho_write_section ();
1752 /* emit symbol table if we have symbols */
1754 macho_write_symtab ();
1756 /* we don't need to pad here, we are already aligned */
1758 /* emit string table */
1759 saa_fpwrite(strs
, ofile
);
1761 /* We do quite a bit here, starting with finalizing all of the data
1762 for the object file, writing, and then freeing all of the data from
1765 static void macho_cleanup(void)
1773 /* Sort all symbols. */
1774 macho_layout_symbols (&nsyms
, &strslen
);
1776 /* Fixup relocation entries */
1777 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1778 macho_fixup_relocs (s
->relocs
);
1781 /* First calculate and finalize needed values. */
1782 macho_calculate_sizes();
1785 /* free up everything */
1786 while (sects
->next
) {
1788 sects
= sects
->next
;
1791 while (s
->relocs
!= NULL
) {
1793 s
->relocs
= s
->relocs
->next
;
1810 nasm_free(extdefsyms
);
1811 nasm_free(undefsyms
);
1812 nasm_free(sectstab
);
1813 raa_free_ptr(section_by_index
);
1814 hash_free(§ion_by_name
);
1817 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1823 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1824 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1828 s
= get_section_by_index(nasm_seg
);
1830 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1839 * Mark a symbol for no dead stripping
1841 static enum directive_result
macho_no_dead_strip(const char *labels
)
1845 enum directive_result rv
= DIRR_ERROR
;
1846 bool real
= passn
> 1;
1848 p
= s
= nasm_strdup(labels
);
1850 ep
= nasm_skip_identifier(p
);
1852 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1856 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1857 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1862 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1866 p
= nasm_skip_spaces(ep
);
1868 p
= nasm_skip_spaces(++p
);
1881 static enum directive_result
1882 macho_pragma(const struct pragma
*pragma
)
1884 bool real
= passn
> 1;
1886 switch (pragma
->opcode
) {
1887 case D_SUBSECTIONS_VIA_SYMBOLS
:
1889 return DIRR_BADPARAM
;
1892 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1894 /* Jmp-match optimization conflicts */
1895 optimizing
.flag
|= OPTIM_DISABLE_JMP_MATCH
;
1899 case D_NO_DEAD_STRIP
:
1900 return macho_no_dead_strip(pragma
->tail
);
1903 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1907 static const struct pragma_facility macho_pragma_list
[] = {
1908 { "macho", macho_pragma
},
1909 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1912 static void macho_dbg_generate(void)
1914 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1915 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1916 struct section
*p_section
= NULL
;
1917 /* calculated at debug_str and referenced at debug_info */
1918 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1920 /* debug section defines */
1923 macho_section(".debug_abbrev", 0, &bits
);
1924 macho_section(".debug_info", 0, &bits
);
1925 macho_section(".debug_line", 0, &bits
);
1926 macho_section(".debug_str", 0, &bits
);
1929 /* dw section walk to find high_addr and total_len */
1931 struct dw_sect_list
*p_sect
;
1933 list_for_each(p_sect
, dw_head_sect
) {
1934 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1935 struct SAA
*p_linep
= p_sect
->psaa
;
1937 saa_write8(p_linep
, 2); /* std op 2 */
1938 saa_write8(p_linep
, offset
- p_sect
->offset
);
1939 saa_write8(p_linep
, DW_LNS_extended_op
);
1940 saa_write8(p_linep
, 1); /* operand length */
1941 saa_write8(p_linep
, DW_LNE_end_sequence
);
1943 total_len
+= p_linep
->datalen
;
1944 high_addr
+= offset
;
1950 struct dw_sect_list
*p_sect
;
1951 size_t linep_off
, buf_size
;
1952 struct SAA
*p_lines
= saa_init(1L);
1953 struct dir_list
*p_dir
;
1954 struct file_list
*p_file
;
1956 p_section
= get_section_by_name("__DWARF", "__debug_line");
1957 nasm_assert(p_section
!= NULL
);
1959 saa_write8(p_lines
, 1); /* minimum instruction length */
1960 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1961 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1962 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1963 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1964 saa_write8(p_lines
, 0); /* std opcode 1 length */
1965 saa_write8(p_lines
, 1); /* std opcode 2 length */
1966 saa_write8(p_lines
, 1); /* std opcode 3 length */
1967 saa_write8(p_lines
, 1); /* std opcode 4 length */
1968 saa_write8(p_lines
, 1); /* std opcode 5 length */
1969 saa_write8(p_lines
, 0); /* std opcode 6 length */
1970 saa_write8(p_lines
, 0); /* std opcode 7 length */
1971 saa_write8(p_lines
, 0); /* std opcode 8 length */
1972 saa_write8(p_lines
, 1); /* std opcode 9 length */
1973 saa_write8(p_lines
, 0); /* std opcode 10 length */
1974 saa_write8(p_lines
, 0); /* std opcode 11 length */
1975 saa_write8(p_lines
, 1); /* std opcode 12 length */
1976 list_for_each(p_dir
, dw_head_dir
) {
1977 saa_wcstring(p_lines
, p_dir
->dir_name
);
1979 saa_write8(p_lines
, 0); /* end of table */
1981 list_for_each(p_file
, dw_head_file
) {
1982 saa_wcstring(p_lines
, p_file
->file_name
);
1983 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1984 saa_write8(p_lines
, 0); /* time */
1985 saa_write8(p_lines
, 0); /* size */
1987 saa_write8(p_lines
, 0); /* end of table */
1989 linep_off
= p_lines
->datalen
;
1990 /* 10 bytes for initial & prolong length, and dwarf version info */
1991 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1992 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1994 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1995 WRITESHORT(p_buf
, 2); /* dwarf version */
1996 WRITELONG(p_buf
, linep_off
); /* prolong length */
1998 saa_rnbytes(p_lines
, p_buf
, linep_off
);
2002 list_for_each(p_sect
, dw_head_sect
) {
2003 struct SAA
*p_linep
= p_sect
->psaa
;
2005 saa_len
= p_linep
->datalen
;
2006 saa_rnbytes(p_linep
, p_buf
, saa_len
);
2012 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
2014 nasm_free(p_buf_base
);
2017 /* string section */
2019 struct SAA
*p_str
= saa_init(1L);
2020 char *cur_path
= nasm_realpath(module_name
);
2021 char *cur_file
= nasm_basename(cur_path
);
2022 char *cur_dir
= nasm_dirname(cur_path
);
2024 p_section
= get_section_by_name("__DWARF", "__debug_str");
2025 nasm_assert(p_section
!= NULL
);
2027 producer_str_offset
= 0;
2028 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
2029 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
2030 saa_wcstring(p_str
, cur_dir
);
2032 saa_len
= p_str
->datalen
;
2033 p_buf
= nasm_malloc(saa_len
);
2034 saa_rnbytes(p_str
, p_buf
, saa_len
);
2035 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2037 nasm_free(cur_path
);
2038 nasm_free(cur_file
);
2046 struct SAA
*p_info
= saa_init(1L);
2048 p_section
= get_section_by_name("__DWARF", "__debug_info");
2049 nasm_assert(p_section
!= NULL
);
2051 /* size will be overwritten once determined, so skip in p_info layout */
2052 saa_write16(p_info
, 2); /* dwarf version */
2053 saa_write32(p_info
, 0); /* offset info abbrev */
2054 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
2056 saa_write8(p_info
, 1); /* abbrev entry number */
2058 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
2059 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
2060 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
2061 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
2062 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
2064 if (ofmt
== &of_macho64
) {
2065 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2066 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
2068 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2069 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
2072 saa_write8(p_info
, 2); /* abbrev entry number */
2074 if (ofmt
== &of_macho64
) {
2075 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2076 saa_write64(p_info
, 0); /* DW_AT_frame_base */
2078 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2079 saa_write32(p_info
, 0); /* DW_AT_frame_base */
2081 saa_write8(p_info
, DW_END_default
);
2083 saa_len
= p_info
->datalen
;
2084 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
2086 WRITELONG(p_buf
, saa_len
);
2087 saa_rnbytes(p_info
, p_buf
, saa_len
);
2088 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
2091 nasm_free(p_buf_base
);
2094 /* abbrev section */
2096 struct SAA
*p_abbrev
= saa_init(1L);
2098 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
2099 nasm_assert(p_section
!= NULL
);
2101 saa_write8(p_abbrev
, 1); /* entry number */
2103 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2104 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2106 saa_write8(p_abbrev
, DW_AT_producer
);
2107 saa_write8(p_abbrev
, DW_FORM_strp
);
2109 saa_write8(p_abbrev
, DW_AT_language
);
2110 saa_write8(p_abbrev
, DW_FORM_data2
);
2112 saa_write8(p_abbrev
, DW_AT_name
);
2113 saa_write8(p_abbrev
, DW_FORM_strp
);
2115 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2116 saa_write8(p_abbrev
, DW_FORM_strp
);
2118 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2119 saa_write8(p_abbrev
, DW_FORM_data4
);
2121 saa_write8(p_abbrev
, DW_AT_low_pc
);
2122 saa_write8(p_abbrev
, DW_FORM_addr
);
2124 saa_write8(p_abbrev
, DW_AT_high_pc
);
2125 saa_write8(p_abbrev
, DW_FORM_addr
);
2127 saa_write16(p_abbrev
, DW_END_default
);
2129 saa_write8(p_abbrev
, 2); /* entry number */
2131 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2132 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2134 saa_write8(p_abbrev
, DW_AT_low_pc
);
2135 saa_write8(p_abbrev
, DW_FORM_addr
);
2137 saa_write8(p_abbrev
, DW_AT_frame_base
);
2138 saa_write8(p_abbrev
, DW_FORM_addr
);
2140 saa_write16(p_abbrev
, DW_END_default
);
2142 saa_write8(p_abbrev
, 0); /* Terminal zero entry */
2144 saa_len
= p_abbrev
->datalen
;
2146 p_buf
= nasm_malloc(saa_len
);
2148 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2149 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2156 static void new_file_list (const char *file_name
, const char *dir_name
)
2158 struct dir_list
*dir_list
;
2159 bool need_new_dir_list
= true;
2161 nasm_new(dw_cur_file
);
2162 dw_cur_file
->file
= ++dw_num_files
;
2163 dw_cur_file
->file_name
= file_name
;
2165 dw_head_file
= dw_cur_file
;
2167 *dw_last_file_next
= dw_cur_file
;
2169 dw_last_file_next
= &(dw_cur_file
->next
);
2172 list_for_each(dir_list
, dw_head_dir
) {
2173 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2174 dw_cur_file
->dir
= dir_list
;
2175 need_new_dir_list
= false;
2181 if(need_new_dir_list
)
2184 dir_list
->dir
= dw_num_dirs
++;
2185 dir_list
->dir_name
= dir_name
;
2187 dw_head_dir
= dir_list
;
2189 *dw_last_dir_next
= dir_list
;
2191 dw_last_dir_next
= &(dir_list
->next
);
2192 dw_cur_file
->dir
= dir_list
;
2196 static void macho_dbg_init(void)
2200 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2202 bool need_new_list
= true;
2203 const char *cur_file
= nasm_basename(file_name
);
2204 const char *cur_dir
= nasm_dirname(file_name
);
2207 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2208 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2210 struct file_list
*match
;
2212 list_for_each(match
, dw_head_file
) {
2213 if(!(strcmp(cur_file
, match
->file_name
)) &&
2214 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2215 dw_cur_file
= match
;
2216 dw_cur_file
->dir
= match
->dir
;
2217 need_new_list
= false;
2224 new_file_list(cur_file
, cur_dir
);
2229 cur_line
= line_num
;
2232 static void macho_dbg_output(int type
, void *param
)
2234 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2235 int32_t secto
= sinfo_param
->secto
;
2236 bool need_new_sect
= false;
2237 struct SAA
*p_linep
= NULL
;
2240 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2241 need_new_sect
= true;
2243 struct dw_sect_list
*match
= dw_head_sect
;
2246 for(; idx
< dw_num_sects
; idx
++) {
2247 if(match
->section
== secto
) {
2248 dw_cur_sect
= match
;
2249 need_new_sect
= false;
2252 match
= match
->next
;
2258 nasm_new(dw_cur_sect
);
2260 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2261 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2262 dw_cur_sect
->offset
= 0;
2263 dw_cur_sect
->next
= NULL
;
2264 dw_cur_sect
->section
= secto
;
2266 saa_write8(p_linep
, DW_LNS_extended_op
);
2267 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2268 saa_write8(p_linep
, DW_LNE_set_address
);
2269 if (ofmt
== &of_macho64
) {
2270 saa_write64(p_linep
, 0);
2272 saa_write32(p_linep
, 0);
2276 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2278 dw_last_sect
->next
= dw_cur_sect
;
2279 dw_last_sect
= dw_cur_sect
;
2283 if(dbg_immcall
== true) {
2284 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2285 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2286 uint32_t cur_file
= dw_cur_file
->file
;
2287 p_linep
= dw_cur_sect
->psaa
;
2289 if(cur_file
!= dw_cur_sect
->file
) {
2290 saa_write8(p_linep
, DW_LNS_set_file
);
2291 saa_write8(p_linep
, cur_file
);
2292 dw_cur_sect
->file
= cur_file
;
2296 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2299 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2300 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2301 saa_write8(p_linep
, special_opcode
);
2303 saa_write8(p_linep
, DW_LNS_advance_line
);
2304 saa_wleb128s(p_linep
, line_delta
);
2306 saa_write8(p_linep
, DW_LNS_advance_pc
);
2307 saa_wleb128u(p_linep
, offset_delta
);
2309 saa_write8(p_linep
, DW_LNS_copy
);
2312 dw_cur_sect
->line
= cur_line
;
2313 dw_cur_sect
->offset
= sinfo_param
->size
;
2316 dbg_immcall
= false;
2320 static void macho_dbg_cleanup(void)
2322 /* dwarf sectors generation */
2323 macho_dbg_generate();
2326 struct dw_sect_list
*p_sect
= dw_head_sect
;
2327 struct file_list
*p_file
= dw_head_file
;
2330 for(; idx
< dw_num_sects
; idx
++) {
2331 struct dw_sect_list
*next
= p_sect
->next
;
2336 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2337 struct file_list
*next
= p_file
->next
;
2345 static const struct macho_fmt macho32_fmt
= {
2355 GENERIC_RELOC_VANILLA
,
2356 GENERIC_RELOC_VANILLA
,
2358 false /* Allow segment-relative relocations */
2361 static void macho32_init(void)
2366 macho_gotpcrel_sect
= NO_SEG
;
2369 static const struct dfmt macho32_df_dwarf
= {
2370 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2374 null_debug_deflabel
,
2375 null_debug_directive
,
2376 null_debug_typevalue
,
2379 NULL
/*pragma list*/
2382 static const struct dfmt
* const macho32_df_arr
[2] =
2383 { &macho32_df_dwarf
, NULL
};
2385 const struct ofmt of_macho32
= {
2386 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2396 nasm_do_legacy_output
,
2410 static const struct macho_fmt macho64_fmt
= {
2415 MACHO_HEADER64_SIZE
,
2416 MACHO_SEGCMD64_SIZE
,
2417 MACHO_SECTCMD64_SIZE
,
2420 X86_64_RELOC_UNSIGNED
,
2421 X86_64_RELOC_SIGNED
,
2423 true /* Force symbol-relative relocations */
2426 static void macho64_init(void)
2431 /* add special symbol for ..gotpcrel */
2432 macho_gotpcrel_sect
= seg_alloc() + 1;
2433 backend_label("..gotpcrel", macho_gotpcrel_sect
, 0L);
2436 static const struct dfmt macho64_df_dwarf
= {
2437 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2441 null_debug_deflabel
,
2442 null_debug_directive
,
2443 null_debug_typevalue
,
2446 NULL
/*pragma list*/
2449 static const struct dfmt
* const macho64_df_arr
[2] =
2450 { &macho64_df_dwarf
, NULL
};
2452 const struct ofmt of_macho64
= {
2453 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2463 nasm_do_legacy_output
,