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