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
58 #if defined(OF_MACHO) || defined(OF_MACHO64)
60 /* Mach-O in-file header structure sizes */
61 #define MACHO_HEADER_SIZE 28
62 #define MACHO_SEGCMD_SIZE 56
63 #define MACHO_SECTCMD_SIZE 68
64 #define MACHO_SYMCMD_SIZE 24
65 #define MACHO_NLIST_SIZE 12
66 #define MACHO_RELINFO_SIZE 8
68 #define MACHO_HEADER64_SIZE 32
69 #define MACHO_SEGCMD64_SIZE 72
70 #define MACHO_SECTCMD64_SIZE 80
71 #define MACHO_NLIST64_SIZE 16
73 /* Mach-O file header values */
74 #define MH_MAGIC 0xfeedface
75 #define MH_MAGIC_64 0xfeedfacf
76 #define CPU_TYPE_I386 7 /* x86 platform */
77 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
78 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
79 #define MH_OBJECT 0x1 /* object file */
81 /* Mach-O header flags */
82 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
84 /* Mach-O load commands */
85 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
86 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
87 #define LC_SYMTAB 0x2 /* symbol table load command */
89 /* Mach-O relocations numbers */
91 /* Generic relocs, used by i386 Mach-O */
92 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
93 #define GENERIC_RELOC_TLV 5 /* Thread local */
95 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
96 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
97 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
98 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
99 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
100 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
101 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
102 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
103 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
104 #define X86_64_RELOC_TLV 9 /* Thread local */
106 /* Mach-O VM permission constants */
107 #define VM_PROT_NONE (0x00)
108 #define VM_PROT_READ (0x01)
109 #define VM_PROT_WRITE (0x02)
110 #define VM_PROT_EXECUTE (0x04)
112 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
113 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
115 /* Our internal relocation types */
117 RL_ABS
, /* Absolute relocation */
118 RL_REL
, /* Relative relocation */
119 RL_TLV
, /* Thread local */
120 RL_BRANCH
, /* Relative direct branch */
121 RL_SUB
, /* X86_64_RELOC_SUBTRACT */
122 RL_GOT
, /* X86_64_RELOC_GOT */
123 RL_GOTLOAD
/* X86_64_RELOC_GOT_LOAD */
125 #define RL_MAX_32 RL_TLV
126 #define RL_MAX_64 RL_GOTLOAD
129 uint32_t ptrsize
; /* Pointer size in bytes */
130 uint32_t mh_magic
; /* Which magic number to use */
131 uint32_t cpu_type
; /* Which CPU type */
132 uint32_t lc_segment
; /* Which segment load command */
133 uint32_t header_size
; /* Header size */
134 uint32_t segcmd_size
; /* Segment command size */
135 uint32_t sectcmd_size
; /* Section command size */
136 uint32_t nlist_size
; /* Nlist (symbol) size */
137 enum reltype maxreltype
; /* Maximum entry in enum reltype permitted */
138 uint32_t reloc_abs
; /* Absolute relocation type */
139 uint32_t reloc_rel
; /* Relative relocation type */
140 uint32_t reloc_tlv
; /* Thread local relocation type */
141 bool forcesym
; /* Always use "external" (symbol-relative) relocations */
144 static struct macho_fmt fmt
;
146 static void fwriteptr(uint64_t data
, FILE * fp
)
148 fwriteaddr(data
, fmt
.ptrsize
, fp
);
152 /* nasm internal data */
153 struct section
*next
;
157 struct reloc
*relocs
;
158 struct rbtree
*syms
[2]; /* All/global symbols symbols in section */
160 bool by_name
; /* This section was specified by full MachO name */
162 /* data that goes into the file */
163 char sectname
[16]; /* what this section is called */
164 char segname
[16]; /* segment this section will be in */
165 uint64_t addr
; /* in-memory address (subject to alignment) */
166 uint64_t size
; /* in-memory and -file size */
167 uint64_t offset
; /* in-file offset */
168 uint32_t pad
; /* padding bytes before section */
169 uint32_t nreloc
; /* relocation entry count */
170 uint32_t flags
; /* type and attributes (masked) */
171 uint32_t extreloc
; /* external relocations */
174 #define SECTION_TYPE 0x000000ff /* section type mask */
176 #define S_REGULAR (0x0) /* standard section */
177 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
179 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
180 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
181 machine instructions */
182 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
183 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
184 #define S_ATTR_DEBUG 0x02000000
185 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
186 #define S_ATTR_LIVE_SUPPORT 0x08000000
187 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
188 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
189 #define S_ATTR_NO_TOC 0x40000000
190 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
191 #define S_ATTR_DEBUG 0x02000000 /* debug section */
193 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
195 /* fake section for absolute symbols, *not* part of the section linked list */
196 static struct section absolute_sect
;
199 /* nasm internal data */
202 /* data that goes into the file */
203 int32_t addr
; /* op's offset in section */
204 uint32_t snum
:24, /* contains symbol index if
205 ** ext otherwise in-file
207 pcrel
:1, /* relative relocation */
208 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
209 ext
:1, /* external symbol referenced */
210 type
:4; /* reloc type */
213 #define R_ABS 0 /* absolute relocation */
214 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
215 ** highest bit == 1 */
218 /* nasm internal data */
219 struct rbtree symv
[2]; /* All/global symbol rbtrees; "key" contains the
221 struct symbol
*next
; /* next symbol in the list */
222 char *name
; /* name of this symbol */
223 int32_t initial_snum
; /* symbol number used above in reloc */
224 int32_t snum
; /* true snum for reloc */
226 /* data that goes into the file */
227 uint32_t strx
; /* string table index */
228 uint8_t type
; /* symbol type */
229 uint8_t sect
; /* NO_SECT or section number */
230 uint16_t desc
; /* for stab debugging, 0 for us */
233 /* symbol type bits */
234 #define N_EXT 0x01 /* global or external symbol */
236 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
237 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
238 #define N_SECT 0xe /* defined symbol, n_sect holds
241 #define N_TYPE 0x0e /* type bit mask */
243 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
245 /* special section number values */
246 #define NO_SECT 0 /* no section, invalid */
247 #define MAX_SECT 255 /* maximum number of sections */
249 static struct section
*sects
, **sectstail
, **sectstab
;
250 static struct symbol
*syms
, **symstail
;
251 static uint32_t nsyms
;
253 /* These variables are set by macho_layout_symbols() to organize
254 the symbol table and string table in order the dynamic linker
255 expects. They are then used in macho_write() to put out the
256 symbols and strings in that order.
258 The order of the symbol table is:
260 defined external symbols (sorted by name)
261 undefined external symbols (sorted by name)
263 The order of the string table is:
264 strings for external symbols
265 strings for local symbols
267 static uint32_t ilocalsym
= 0;
268 static uint32_t iextdefsym
= 0;
269 static uint32_t iundefsym
= 0;
270 static uint32_t nlocalsym
;
271 static uint32_t nextdefsym
;
272 static uint32_t nundefsym
;
273 static struct symbol
**extdefsyms
= NULL
;
274 static struct symbol
**undefsyms
= NULL
;
276 static struct RAA
*extsyms
;
277 static struct SAA
*strs
;
278 static uint32_t strslen
;
280 /* Global file information. This should be cleaned up into either
281 a structure or as function arguments. */
282 static uint32_t head_ncmds
= 0;
283 static uint32_t head_sizeofcmds
= 0;
284 static uint32_t head_flags
= 0;
285 static uint64_t seg_filesize
= 0;
286 static uint64_t seg_vmsize
= 0;
287 static uint32_t seg_nsects
= 0;
288 static uint64_t rel_padcnt
= 0;
290 #define xstrncpy(xdst, xsrc) \
291 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
292 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
293 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
295 #define alignint32_t(x) \
296 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
298 #define alignint64_t(x) \
299 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
301 #define alignptr(x) \
302 ALIGN(x, fmt.ptrsize) /* align x to output format width */
304 static struct section
*get_section_by_name(const char *segname
,
305 const char *sectname
)
309 for (s
= sects
; s
!= NULL
; s
= s
->next
)
310 if (!strcmp(s
->segname
, segname
) && !strcmp(s
->sectname
, sectname
))
316 static struct section
*get_section_by_index(const int32_t index
)
320 for (s
= sects
; s
!= NULL
; s
= s
->next
)
321 if (index
== s
->index
)
328 struct dir_list
*next
;
329 struct dir_list
*last
;
330 const char *dir_name
;
335 struct file_list
*next
;
336 struct file_list
*last
;
337 const char *file_name
;
339 struct dir_list
*dir
;
342 struct dw_sect_list
{
348 struct dw_sect_list
*next
;
349 struct dw_sect_list
*last
;
352 struct section_info
{
357 #define DW_LN_BASE (-5)
358 #define DW_LN_RANGE 14
359 #define DW_OPCODE_BASE 13
360 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
361 #define DW_MAX_SP_OPCODE 256
363 static struct file_list
*dw_head_file
= 0, *dw_cur_file
= 0, **dw_last_file_next
= NULL
;
364 static struct dir_list
*dw_head_dir
= 0, **dw_last_dir_next
= NULL
;
365 static struct dw_sect_list
*dw_head_sect
= 0, *dw_cur_sect
= 0, *dw_last_sect
= 0;
366 static uint32_t cur_line
= 0, dw_num_files
= 0, dw_num_dirs
= 0, dw_num_sects
= 0;
367 static bool dbg_immcall
= false;
368 static const char *module_name
= NULL
;
371 * Special section numbers which are used to define Mach-O special
372 * symbols, which can be used with WRT to provide PIC relocation
375 static int32_t macho_tlvp_sect
;
376 static int32_t macho_gotpcrel_sect
;
378 static void macho_init(void)
383 /* Fake section for absolute symbols */
384 absolute_sect
.index
= NO_SEG
;
393 extsyms
= raa_init();
396 /* string table starts with a zero byte so index 0 is an empty string */
397 saa_wbytes(strs
, zero_buffer
, 1);
400 /* add special symbol for TLVP */
401 macho_tlvp_sect
= seg_alloc() + 1;
402 define_label("..tlvp", macho_tlvp_sect
, 0L, NULL
, false, false);
406 static void sect_write(struct section
*sect
,
407 const uint8_t *data
, uint32_t len
)
409 saa_wbytes(sect
->data
, data
, len
);
414 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
416 static struct symbol
*macho_find_sym(struct section
*s
, uint64_t offset
,
417 bool global
, bool exact
)
421 srb
= rb_search(s
->syms
[global
], offset
);
423 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
424 nasm_error(ERR_NONFATAL
, "unable to find a suitable%s%s symbol"
425 " for this reference",
426 global
? " global" : "",
427 s
== &absolute_sect
? " absolute " : "");
431 return container_of(srb
- global
, struct symbol
, symv
);
434 static int64_t add_reloc(struct section
*sect
, int32_t section
,
436 enum reltype reltype
, int bytes
)
443 /* Double check this is a valid relocation type for this platform */
444 nasm_assert(reltype
<= fmt
.maxreltype
);
446 /* the current end of the section will be the symbol's address for
447 ** now, might have to be fixed by macho_fixup_relocs() later on. make
448 ** sure we don't make the symbol scattered by setting the highest
449 ** bit by accident */
450 r
= nasm_malloc(sizeof(struct reloc
));
451 r
->addr
= sect
->size
& ~R_SCATTERED
;
455 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
456 r
->length
= ilog2_32(bytes
);
458 /* set default relocation values */
459 r
->type
= fmt
.reloc_abs
;
464 if (section
!= NO_SEG
)
465 s
= get_section_by_index(section
);
466 fi
= s
? s
->fileindex
: NO_SECT
;
468 /* absolute relocation */
471 if (section
== NO_SEG
) {
472 /* absolute (can this even happen?) */
475 } else if (fi
== NO_SECT
) {
477 r
->snum
= raa_read(extsyms
, section
);
482 adjust
= -sect
->size
;
488 r
->type
= fmt
.reloc_rel
;
490 if (section
== NO_SEG
) {
491 /* absolute - seems to produce garbage no matter what */
492 nasm_error(ERR_NONFATAL
, "Mach-O does not support relative "
493 "references to absolute addresses");
496 /* This "seems" to be how it ought to work... */
498 struct symbol
*sym
= macho_find_sym(&absolute_sect
, offset
,
505 adjust
= -sect
->size
;
507 } else if (fi
== NO_SECT
) {
510 r
->snum
= raa_read(extsyms
, section
);
511 if (reltype
== RL_BRANCH
)
512 r
->type
= X86_64_RELOC_BRANCH
;
513 else if (r
->type
== GENERIC_RELOC_VANILLA
)
514 adjust
= -sect
->size
;
519 adjust
= -sect
->size
;
525 r
->type
= X86_64_RELOC_SUBTRACTOR
;
529 r
->type
= X86_64_RELOC_GOT
;
533 r
->type
= X86_64_RELOC_GOT_LOAD
;
537 r
->type
= fmt
.reloc_tlv
;
542 if (section
== NO_SEG
) {
543 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
544 } else if (fi
== NO_SECT
) {
546 r
->snum
= raa_read(extsyms
, section
);
548 /* internal - does it really need to be global? */
549 struct symbol
*sym
= macho_find_sym(s
, offset
, true,
554 r
->snum
= sym
->initial_snum
;
559 /* For 64-bit Mach-O, force a symbol reference if at all possible */
560 if (!r
->ext
&& r
->snum
!= NO_SECT
&& fmt
.forcesym
) {
561 struct symbol
*sym
= macho_find_sym(s
, offset
, false, false);
563 adjust
= bytes
- sym
->symv
[0].key
;
564 r
->snum
= sym
->initial_snum
;
569 /* NeXT as puts relocs in reversed order (address-wise) into the
570 ** files, so we do the same, doesn't seem to make much of a
571 ** difference either way */
572 r
->next
= sect
->relocs
;
585 static void macho_output(int32_t secto
, const void *data
,
586 enum out_type type
, uint64_t size
,
587 int32_t section
, int32_t wrt
)
590 int64_t addr
, offset
;
591 uint8_t mydata
[16], *p
;
593 enum reltype reltype
;
595 if (secto
== NO_SEG
) {
596 if (type
!= OUT_RESERVE
)
597 nasm_error(ERR_NONFATAL
, "attempt to assemble code in "
602 s
= get_section_by_index(secto
);
605 nasm_error(ERR_WARNING
, "attempt to assemble code in"
606 " section %d: defaulting to `.text'", secto
);
607 s
= get_section_by_name("__TEXT", "__text");
609 /* should never happen */
611 nasm_panic(0, "text section not found");
614 /* debug code generation only for sections tagged with
615 * instruction attribute */
616 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
618 struct section_info sinfo
;
619 sinfo
.size
= s
->size
;
621 dfmt
->debug_output(0, &sinfo
);
624 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
626 if (is_bss
&& type
!= OUT_RESERVE
) {
627 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
628 "BSS section: ignored");
629 s
->size
+= realsize(type
, size
);
633 memset(mydata
, 0, sizeof(mydata
));
638 nasm_error(ERR_WARNING
, "uninitialized space declared in"
639 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
641 sect_write(s
, NULL
, size
);
648 if (section
!= NO_SEG
)
649 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
651 sect_write(s
, data
, size
);
656 int asize
= abs((int)size
);
658 addr
= *(int64_t *)data
;
659 if (section
!= NO_SEG
) {
661 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
662 " section base references");
663 } else if (wrt
== NO_SEG
) {
664 if (fmt
.ptrsize
== 8 && asize
!= 8) {
665 nasm_error(ERR_NONFATAL
,
666 "Mach-O 64-bit format does not support"
667 " 32-bit absolute addresses");
669 add_reloc(s
, section
, addr
, RL_ABS
, asize
);
672 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
678 WRITEADDR(p
, addr
, asize
);
679 sect_write(s
, mydata
, asize
);
684 nasm_assert(section
!= secto
);
687 offset
= *(int64_t *)data
;
688 addr
= offset
- size
;
690 if (section
!= NO_SEG
&& section
% 2) {
691 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
692 " section base references");
693 } else if (fmt
.ptrsize
== 8) {
694 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
695 " Macho-O relocation [2]");
696 } else if (wrt
!= NO_SEG
) {
697 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
699 wrt
= NO_SEG
; /* we can at least _try_ to continue */
701 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
, 2);
705 sect_write(s
, mydata
, 2);
709 nasm_assert(section
!= secto
);
712 offset
= *(int64_t *)data
;
713 addr
= offset
- size
;
716 if (section
!= NO_SEG
&& section
% 2) {
717 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
718 " section base references");
719 } else if (wrt
== NO_SEG
) {
720 if (fmt
.ptrsize
== 8 &&
721 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
724 opcode
[0] = opcode
[1] = 0;
726 /* HACK: Retrieve instruction opcode */
727 if (likely(s
->data
->datalen
>= 2)) {
728 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
729 } else if (s
->data
->datalen
== 1) {
730 saa_fread(s
->data
, 0, opcode
+1, 1);
733 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
734 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
735 /* Direct call, jmp, or jcc */
739 } else if (wrt
== macho_gotpcrel_sect
) {
742 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
743 s
->data
->datalen
>= 3) {
746 /* HACK: Retrieve instruction opcode */
747 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
748 if ((gotload
[0] & 0xf8) == 0x48 &&
749 gotload
[1] == 0x8b &&
750 (gotload
[2] & 0307) == 0005) {
751 /* movq <reg>,[rel sym wrt ..gotpcrel] */
752 reltype
= RL_GOTLOAD
;
755 } else if (wrt
== macho_tlvp_sect
) {
758 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
760 /* continue with RL_REL */
763 addr
+= add_reloc(s
, section
, offset
, reltype
, 4);
765 sect_write(s
, mydata
, 4);
769 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
774 /* Translation table from traditional Unix section names to Mach-O */
775 static const struct sectmap
{
776 const char *nasmsect
;
778 const char *sectname
;
779 const uint32_t flags
;
781 {".text", "__TEXT", "__text",
782 S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
783 {".data", "__DATA", "__data", S_REGULAR
},
784 {".rodata", "__DATA", "__const", S_REGULAR
},
785 {".bss", "__DATA", "__bss", S_ZEROFILL
},
786 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
787 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
788 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
789 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
790 {NULL
, NULL
, NULL
, 0}
793 #define NO_TYPE S_NASM_TYPE_MASK
795 /* Section type or attribute directives */
796 static const struct sect_attribs
{
800 { "data", S_REGULAR
},
801 { "code", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
802 { "mixed", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
803 { "bss", S_ZEROFILL
},
804 { "zerofill", S_ZEROFILL
},
805 { "no_dead_strip", NO_TYPE
|S_ATTR_NO_DEAD_STRIP
},
806 { "live_support", NO_TYPE
|S_ATTR_LIVE_SUPPORT
},
807 { "strip_static_syms", NO_TYPE
|S_ATTR_STRIP_STATIC_SYMS
},
811 static int32_t macho_section(char *name
, int pass
, int *bits
)
813 char *sectionAttributes
;
814 const struct sectmap
*sm
;
816 const char *section
, *segment
;
818 const struct sect_attribs
*sa
;
819 char *currentAttribute
;
826 /* Default to the appropriate number of bits. */
828 *bits
= fmt
.ptrsize
<< 3;
830 sectionAttributes
= NULL
;
832 sectionAttributes
= name
;
833 name
= nasm_strsep(§ionAttributes
, " \t");
836 section
= segment
= NULL
;
839 comma
= strchr(name
, ',');
847 len
= strlen(segment
);
849 nasm_error(ERR_NONFATAL
, "empty segment name\n");
850 } else if (len
>= 16) {
851 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
854 len
= strlen(section
);
856 nasm_error(ERR_NONFATAL
, "empty section name\n");
857 } else if (len
>= 16) {
858 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
861 if (!strcmp(section
, "__text")) {
862 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
863 S_ATTR_PURE_INSTRUCTIONS
;
864 } else if (!strcmp(section
, "__bss")) {
870 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
871 /* make lookup into section name translation table */
872 if (!strcmp(name
, sm
->nasmsect
)) {
873 segment
= sm
->segname
;
874 section
= sm
->sectname
;
879 nasm_error(ERR_NONFATAL
, "unknown section name\n");
884 /* try to find section with that name */
885 s
= get_section_by_name(segment
, section
);
887 /* create it if it doesn't exist yet */
891 s
= *sectstail
= nasm_zalloc(sizeof(struct section
));
892 sectstail
= &s
->next
;
894 s
->data
= saa_init(1L);
895 s
->index
= seg_alloc();
896 s
->fileindex
= ++seg_nsects
;
902 xstrncpy(s
->segname
, segment
);
903 xstrncpy(s
->sectname
, section
);
912 *comma
= ','; /* Restore comma */
914 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
918 while (sectionAttributes
&&
919 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
920 if (!*currentAttribute
)
923 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
925 int newAlignment
, value
;
927 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
928 newAlignment
= alignlog2_32(value
);
931 nasm_error(ERR_NONFATAL
,
932 "unknown or missing alignment value \"%s\" "
933 "specified for section \"%s\"",
934 currentAttribute
+ 6,
936 } else if (0 > newAlignment
) {
937 nasm_error(ERR_NONFATAL
,
938 "alignment of %d (for section \"%s\") is not "
944 if (s
->align
< newAlignment
)
945 s
->align
= newAlignment
;
947 for (sa
= sect_attribs
; sa
->name
; sa
++) {
948 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
949 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
950 flags
= (flags
& ~S_NASM_TYPE_MASK
)
951 | (sa
->flags
& S_NASM_TYPE_MASK
);
953 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
959 nasm_error(ERR_NONFATAL
,
960 "unknown section attribute %s for section %s",
961 currentAttribute
, name
);
966 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
967 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
968 nasm_error(ERR_NONFATAL
,
969 "inconsistent section attributes for section %s\n",
972 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
975 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
981 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
982 int is_global
, char *special
)
988 nasm_error(ERR_NONFATAL
, "The Mach-O output format does "
989 "not support any special symbol types");
993 if (is_global
== 3) {
994 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
995 "(yet) support forward reference fixups.");
999 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1001 * This is a NASM special symbol. We never allow it into
1002 * the Macho-O symbol table, even if it's a valid one. If it
1003 * _isn't_ a valid one, we should barf immediately.
1005 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1006 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1010 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1012 symstail
= &sym
->next
;
1015 sym
->strx
= strslen
;
1018 sym
->symv
[0].key
= offset
;
1019 sym
->symv
[1].key
= offset
;
1020 sym
->initial_snum
= -1;
1022 /* external and common symbols get N_EXT */
1023 if (is_global
!= 0) {
1027 if (section
== NO_SEG
) {
1028 /* symbols in no section get absolute */
1030 sym
->sect
= NO_SECT
;
1034 s
= get_section_by_index(section
);
1036 sym
->type
|= N_SECT
;
1038 /* get the in-file index of the section the symbol was defined in */
1039 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1041 /* track the initially allocated symbol number for use in future fix-ups */
1042 sym
->initial_snum
= nsyms
;
1045 /* remember symbol number of references to external
1046 ** symbols, this works because every external symbol gets
1047 ** its own section number allocated internally by nasm and
1048 ** can so be used as a key */
1049 extsyms
= raa_write(extsyms
, section
, nsyms
);
1051 switch (is_global
) {
1054 /* there isn't actually a difference between global
1055 ** and common symbols, both even have their size in
1056 ** sym->symv[0].key */
1061 /* give an error on unfound section if it's not an
1062 ** external or common symbol (assemble_file() does a
1063 ** seg_alloc() on every call for them) */
1064 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section
, is_global
);
1071 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1073 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1079 static void macho_sectalign(int32_t seg
, unsigned int value
)
1084 nasm_assert(!(seg
& 1));
1086 s
= get_section_by_index(seg
);
1088 if (!s
|| !is_power2(value
))
1091 align
= alignlog2_32(value
);
1092 if (s
->align
< align
)
1096 static int32_t macho_segbase(int32_t section
)
1101 static void macho_filename(char *inname
, char *outname
)
1103 standard_extension(inname
, outname
, ".o");
1104 module_name
= inname
;
1107 extern macros_t macho_stdmac
[];
1109 /* Comparison function for qsort symbol layout. */
1110 static int layout_compare (const struct symbol
**s1
,
1111 const struct symbol
**s2
)
1113 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1116 /* The native assembler does a few things in a similar function
1118 * Remove temporary labels
1119 * Sort symbols according to local, external, undefined (by name)
1120 * Order the string table
1122 We do not remove temporary labels right now.
1124 numsyms is the total number of symbols we have. strtabsize is the
1125 number entries in the string table. */
1127 static void macho_layout_symbols (uint32_t *numsyms
,
1128 uint32_t *strtabsize
)
1130 struct symbol
*sym
, **symp
;
1134 *strtabsize
= sizeof (char);
1138 while ((sym
= *symp
)) {
1139 /* Undefined symbols are now external. */
1140 if (sym
->type
== N_UNDF
)
1143 if ((sym
->type
& N_EXT
) == 0) {
1144 sym
->snum
= *numsyms
;
1145 *numsyms
= *numsyms
+ 1;
1149 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1155 /* If we handle debug info we'll want
1156 to check for it here instead of just
1157 adding the symbol to the string table. */
1158 sym
->strx
= *strtabsize
;
1159 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1160 *strtabsize
+= strlen(sym
->name
) + 1;
1162 symp
= &(sym
->next
);
1165 /* Next, sort the symbols. Most of this code is a direct translation from
1166 the Apple cctools symbol layout. We need to keep compatibility with that. */
1167 /* Set the indexes for symbol groups into the symbol table */
1169 iextdefsym
= nlocalsym
;
1170 iundefsym
= nlocalsym
+ nextdefsym
;
1172 /* allocate arrays for sorting externals by name */
1173 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1174 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1181 while ((sym
= *symp
)) {
1183 if((sym
->type
& N_EXT
) == 0) {
1184 sym
->strx
= *strtabsize
;
1185 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1186 *strtabsize
+= strlen(sym
->name
) + 1;
1189 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1190 extdefsyms
[i
++] = sym
;
1192 undefsyms
[j
++] = sym
;
1195 symp
= &(sym
->next
);
1198 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1199 (int (*)(const void *, const void *))layout_compare
);
1200 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1201 (int (*)(const void *, const void *))layout_compare
);
1203 for(i
= 0; i
< nextdefsym
; i
++) {
1204 extdefsyms
[i
]->snum
= *numsyms
;
1207 for(j
= 0; j
< nundefsym
; j
++) {
1208 undefsyms
[j
]->snum
= *numsyms
;
1213 /* Calculate some values we'll need for writing later. */
1215 static void macho_calculate_sizes (void)
1220 /* count sections and calculate in-memory and in-file offsets */
1221 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1224 /* recalculate segment address based on alignment and vm size */
1225 s
->addr
= seg_vmsize
;
1227 /* we need section alignment to calculate final section address */
1229 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1231 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1234 seg_vmsize
= newaddr
+ s
->size
;
1236 /* zerofill sections aren't actually written to the file */
1237 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1239 * LLVM/Xcode as always aligns the section data to 4
1240 * bytes; there is a comment in the LLVM source code that
1241 * perhaps aligning to pointer size would be better.
1243 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1244 s
->offset
= seg_filesize
+ s
->pad
;
1245 seg_filesize
+= s
->size
+ s
->pad
;
1247 /* filesize and vmsize needs to be aligned */
1248 seg_vmsize
+= s
->pad
;
1252 /* calculate size of all headers, load commands and sections to
1253 ** get a pointer to the start of all the raw data */
1254 if (seg_nsects
> 0) {
1256 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1261 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1264 if (seg_nsects
> MAX_SECT
) {
1265 nasm_fatal(0, "MachO output is limited to %d sections\n",
1269 /* Create a table of sections by file index to avoid linear search */
1270 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1271 sectstab
[NO_SECT
] = &absolute_sect
;
1272 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1276 /* Write out the header information for the file. */
1278 static void macho_write_header (void)
1280 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1281 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1282 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1283 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1284 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1285 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1286 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1287 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1290 /* Write out the segment load command at offset. */
1292 static uint32_t macho_write_segment (uint64_t offset
)
1294 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1295 uint32_t s_reloff
= 0;
1298 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1300 /* size of load command including section load commands */
1301 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1304 /* in an MH_OBJECT file all sections are in one unnamed (name
1305 ** all zeros) segment */
1306 fwritezero(16, ofile
);
1307 fwriteptr(0, ofile
); /* in-memory offset */
1308 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1309 fwriteptr(offset
, ofile
); /* in-file offset to data */
1310 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1311 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1312 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1313 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1314 fwriteint32_t(0, ofile
); /* no flags */
1316 /* emit section headers */
1317 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1319 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1320 s
->flags
|= S_ATTR_LOC_RELOC
;
1322 s
->flags
|= S_ATTR_EXT_RELOC
;
1323 } else if (!strcmp(s
->segname
, "__DATA") &&
1324 !strcmp(s
->sectname
, "__const") &&
1326 !get_section_by_name("__TEXT", "__const")) {
1328 * The MachO equivalent to .rodata can be either
1329 * __DATA,__const or __TEXT,__const; the latter only if
1330 * there are no relocations. However, when mixed it is
1331 * better to specify the segments explicitly.
1333 xstrncpy(s
->segname
, "__TEXT");
1336 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1337 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1338 fwriteptr(s
->addr
, ofile
);
1339 fwriteptr(s
->size
, ofile
);
1341 /* dummy data for zerofill sections or proper values */
1342 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1343 nasm_assert(s
->pad
!= (uint32_t)-1);
1345 fwriteint32_t(offset
, ofile
);
1347 /* Write out section alignment, as a power of two.
1348 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1349 fwriteint32_t(s
->align
, ofile
);
1350 /* To be compatible with cctools as we emit
1351 a zero reloff if we have no relocations. */
1352 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1353 fwriteint32_t(s
->nreloc
, ofile
);
1355 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1357 fwriteint32_t(0, ofile
);
1358 fwriteint32_t(s
->align
, ofile
);
1359 fwriteint32_t(0, ofile
);
1360 fwriteint32_t(0, ofile
);
1363 fwriteint32_t(s
->flags
, ofile
); /* flags */
1364 fwriteint32_t(0, ofile
); /* reserved */
1365 fwriteptr(0, ofile
); /* reserved */
1368 rel_padcnt
= rel_base
- offset
;
1369 offset
= rel_base
+ s_reloff
;
1374 /* For a given chain of relocs r, write out the entire relocation
1375 chain to the object file. */
1377 static void macho_write_relocs (struct reloc
*r
)
1382 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1385 word2
|= r
->pcrel
<< 24;
1386 word2
|= r
->length
<< 25;
1387 word2
|= r
->ext
<< 27;
1388 word2
|= r
->type
<< 28;
1389 fwriteint32_t(word2
, ofile
); /* reloc data */
1394 /* Write out the section data. */
1395 static void macho_write_section (void)
1407 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1408 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1411 /* Like a.out Mach-O references things in the data or bss
1412 * sections by addresses which are actually relative to the
1413 * start of the _text_ section, in the _file_. See outaout.c
1414 * for more information. */
1415 saa_rewind(s
->data
);
1416 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1417 len
= (uint32_t)1 << r
->length
;
1418 if (len
> 4) /* Can this ever be an issue?! */
1421 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1423 /* get offset based on relocation type */
1424 #ifdef WORDS_LITTLEENDIAN
1428 l
+= ((int64_t)blk
.buf
[1]) << 8;
1429 l
+= ((int64_t)blk
.buf
[2]) << 16;
1430 l
+= ((int64_t)blk
.buf
[3]) << 24;
1431 l
+= ((int64_t)blk
.buf
[4]) << 32;
1432 l
+= ((int64_t)blk
.buf
[5]) << 40;
1433 l
+= ((int64_t)blk
.buf
[6]) << 48;
1434 l
+= ((int64_t)blk
.buf
[7]) << 56;
1437 /* If the relocation is internal add to the current section
1438 offset. Otherwise the only value we need is the symbol
1439 offset which we already have. The linker takes care
1440 of the rest of the address. */
1442 /* generate final address by section address and offset */
1443 nasm_assert(r
->snum
<= seg_nsects
);
1444 l
+= sectstab
[r
->snum
]->addr
;
1447 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1451 /* write new offset back */
1454 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1457 /* dump the section data to file */
1458 fwritezero(s
->pad
, ofile
);
1459 saa_fpwrite(s
->data
, ofile
);
1462 /* pad last section up to reloc entries on pointer boundary */
1463 fwritezero(rel_padcnt
, ofile
);
1465 /* emit relocation entries */
1466 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1467 macho_write_relocs (s
->relocs
);
1470 /* Write out the symbol table. We should already have sorted this
1472 static void macho_write_symtab (void)
1477 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1479 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1480 if ((sym
->type
& N_EXT
) == 0) {
1481 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1482 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1483 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1484 fwriteint16_t(sym
->desc
, ofile
); /* description */
1486 /* Fix up the symbol value now that we know the final section
1488 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1489 nasm_assert(sym
->sect
<= seg_nsects
);
1490 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1493 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1497 for (i
= 0; i
< nextdefsym
; i
++) {
1498 sym
= extdefsyms
[i
];
1499 fwriteint32_t(sym
->strx
, ofile
);
1500 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1501 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1502 fwriteint16_t(sym
->desc
, ofile
); /* description */
1504 /* Fix up the symbol value now that we know the final section
1506 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1507 nasm_assert(sym
->sect
<= seg_nsects
);
1508 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1511 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1514 for (i
= 0; i
< nundefsym
; i
++) {
1516 fwriteint32_t(sym
->strx
, ofile
);
1517 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1518 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1519 fwriteint16_t(sym
->desc
, ofile
); /* description */
1521 /* Fix up the symbol value now that we know the final section
1523 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1524 nasm_assert(sym
->sect
<= seg_nsects
);
1525 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1528 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1533 /* Fixup the snum in the relocation entries, we should be
1534 doing this only for externally referenced symbols. */
1535 static void macho_fixup_relocs (struct reloc
*r
)
1541 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1542 if (sym
->initial_snum
== r
->snum
) {
1543 r
->snum
= sym
->snum
;
1552 /* Write out the object file. */
1554 static void macho_write (void)
1556 uint64_t offset
= 0;
1558 /* mach-o object file structure:
1564 ** uint32_t mach file type
1565 ** uint32_t number of load commands
1566 ** uint32_t size of all load commands
1567 ** (includes section struct size of segment command)
1571 ** uint32_t command type == LC_SEGMENT[_64]
1572 ** uint32_t size of load command
1573 ** (including section load commands)
1574 ** char[16] segment name
1575 ** pointer in-memory offset
1576 ** pointer in-memory size
1577 ** pointer in-file offset to data area
1578 ** pointer in-file size
1579 ** (in-memory size excluding zerofill sections)
1580 ** int maximum vm protection
1581 ** int initial vm protection
1582 ** uint32_t number of sections
1586 ** char[16] section name
1587 ** char[16] segment name
1588 ** pointer in-memory offset
1589 ** pointer in-memory size
1590 ** uint32_t in-file offset
1591 ** uint32_t alignment
1592 ** (irrelevant in MH_OBJECT)
1593 ** uint32_t in-file offset of relocation entires
1594 ** uint32_t number of relocations
1596 ** uint32_t reserved
1597 ** uint32_t reserved
1599 ** symbol table command
1600 ** uint32_t command type == LC_SYMTAB
1601 ** uint32_t size of load command
1602 ** uint32_t symbol table offset
1603 ** uint32_t number of symbol table entries
1604 ** uint32_t string table offset
1605 ** uint32_t string table size
1609 ** padding to pointer boundary
1611 ** relocation data (struct reloc)
1613 ** uint data (symbolnum, pcrel, length, extern, type)
1615 ** symbol table data (struct nlist)
1616 ** int32_t string table entry number
1618 ** (extern, absolute, defined in section)
1620 ** (0 for global symbols, section number of definition (>= 1, <=
1621 ** 254) for local symbols, size of variable for common symbols
1622 ** [type == extern])
1623 ** int16_t description
1624 ** (for stab debugging format)
1625 ** pointer value (i.e. file offset) of symbol or stab offset
1627 ** string table data
1628 ** list of null-terminated strings
1631 /* Emit the Mach-O header. */
1632 macho_write_header();
1634 offset
= fmt
.header_size
+ head_sizeofcmds
;
1636 /* emit the segment load command */
1638 offset
= macho_write_segment (offset
);
1640 nasm_error(ERR_WARNING
, "no sections?");
1643 /* write out symbol command */
1644 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1645 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1646 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1647 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1649 offset
+= nsyms
* fmt
.nlist_size
;
1650 fwriteint32_t(offset
, ofile
); /* string table offset */
1651 fwriteint32_t(strslen
, ofile
); /* string table size */
1654 /* emit section data */
1656 macho_write_section ();
1658 /* emit symbol table if we have symbols */
1660 macho_write_symtab ();
1662 /* we don't need to pad here, we are already aligned */
1664 /* emit string table */
1665 saa_fpwrite(strs
, ofile
);
1667 /* We do quite a bit here, starting with finalizing all of the data
1668 for the object file, writing, and then freeing all of the data from
1671 static void macho_cleanup(void)
1679 /* Sort all symbols. */
1680 macho_layout_symbols (&nsyms
, &strslen
);
1682 /* Fixup relocation entries */
1683 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1684 macho_fixup_relocs (s
->relocs
);
1687 /* First calculate and finalize needed values. */
1688 macho_calculate_sizes();
1691 /* free up everything */
1692 while (sects
->next
) {
1694 sects
= sects
->next
;
1697 while (s
->relocs
!= NULL
) {
1699 s
->relocs
= s
->relocs
->next
;
1715 nasm_free(extdefsyms
);
1716 nasm_free(undefsyms
);
1717 nasm_free(sectstab
);
1720 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1726 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1727 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1731 s
= get_section_by_index(nasm_seg
);
1733 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1742 * Mark a symbol for no dead stripping
1744 static enum directive_result
macho_no_dead_strip(const char *labels
)
1748 enum directive_result rv
= DIRR_ERROR
;
1749 bool real
= passn
> 1;
1751 p
= s
= nasm_strdup(labels
);
1753 ep
= nasm_skip_identifier(p
);
1755 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1759 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1760 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1765 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1769 p
= nasm_skip_spaces(ep
);
1771 p
= nasm_skip_spaces(++p
);
1784 static enum directive_result
1785 macho_pragma(const struct pragma
*pragma
)
1787 bool real
= passn
> 1;
1789 switch (pragma
->opcode
) {
1790 case D_SUBSECTIONS_VIA_SYMBOLS
:
1792 return DIRR_BADPARAM
;
1795 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1799 case D_NO_DEAD_STRIP
:
1800 return macho_no_dead_strip(pragma
->tail
);
1803 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1807 static const struct pragma_facility macho_pragma_list
[] = {
1808 { "macho", macho_pragma
},
1809 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1812 static void macho_dbg_generate(void)
1814 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1815 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1816 struct section
*p_section
= NULL
;
1817 /* calculated at debug_str and referenced at debug_info */
1818 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1820 /* debug section defines */
1823 macho_section(".debug_abbrev", 0, &bits
);
1824 macho_section(".debug_info", 0, &bits
);
1825 macho_section(".debug_line", 0, &bits
);
1826 macho_section(".debug_str", 0, &bits
);
1829 /* dw section walk to find high_addr and total_len */
1831 struct dw_sect_list
*p_sect
;
1833 list_for_each(p_sect
, dw_head_sect
) {
1834 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1835 struct SAA
*p_linep
= p_sect
->psaa
;
1837 saa_write8(p_linep
, 2); /* std op 2 */
1838 saa_write8(p_linep
, offset
- p_sect
->offset
);
1839 saa_write8(p_linep
, DW_LNS_extended_op
);
1840 saa_write8(p_linep
, 1); /* operand length */
1841 saa_write8(p_linep
, DW_LNE_end_sequence
);
1843 total_len
+= p_linep
->datalen
;
1844 high_addr
+= offset
;
1850 struct dw_sect_list
*p_sect
;
1851 size_t linep_off
, buf_size
;
1852 struct SAA
*p_lines
= saa_init(1L);
1853 struct dir_list
*p_dir
;
1854 struct file_list
*p_file
;
1856 p_section
= get_section_by_name("__DWARF", "__debug_line");
1857 nasm_assert(p_section
!= NULL
);
1859 saa_write8(p_lines
, 1); /* minimum instruction length */
1860 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1861 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1862 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1863 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1864 saa_write8(p_lines
, 0); /* std opcode 1 length */
1865 saa_write8(p_lines
, 1); /* std opcode 2 length */
1866 saa_write8(p_lines
, 1); /* std opcode 3 length */
1867 saa_write8(p_lines
, 1); /* std opcode 4 length */
1868 saa_write8(p_lines
, 1); /* std opcode 5 length */
1869 saa_write8(p_lines
, 0); /* std opcode 6 length */
1870 saa_write8(p_lines
, 0); /* std opcode 7 length */
1871 saa_write8(p_lines
, 0); /* std opcode 8 length */
1872 saa_write8(p_lines
, 1); /* std opcode 9 length */
1873 saa_write8(p_lines
, 0); /* std opcode 10 length */
1874 saa_write8(p_lines
, 0); /* std opcode 11 length */
1875 saa_write8(p_lines
, 1); /* std opcode 12 length */
1876 list_for_each(p_dir
, dw_head_dir
) {
1877 saa_wcstring(p_lines
, p_dir
->dir_name
);
1879 saa_write8(p_lines
, 0); /* end of table */
1881 list_for_each(p_file
, dw_head_file
) {
1882 saa_wcstring(p_lines
, p_file
->file_name
);
1883 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1884 saa_write8(p_lines
, 0); /* time */
1885 saa_write8(p_lines
, 0); /* size */
1887 saa_write8(p_lines
, 0); /* end of table */
1889 linep_off
= p_lines
->datalen
;
1890 /* 10 bytes for initial & prolong length, and dwarf version info */
1891 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1892 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1894 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1895 WRITESHORT(p_buf
, 2); /* dwarf version */
1896 WRITELONG(p_buf
, linep_off
); /* prolong length */
1898 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1902 list_for_each(p_sect
, dw_head_sect
) {
1903 struct SAA
*p_linep
= p_sect
->psaa
;
1905 saa_len
= p_linep
->datalen
;
1906 saa_rnbytes(p_linep
, p_buf
, saa_len
);
1912 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
1914 nasm_free(p_buf_base
);
1917 /* string section */
1919 struct SAA
*p_str
= saa_init(1L);
1920 char *cur_path
= nasm_realpath(module_name
);
1921 char *cur_file
= nasm_basename(cur_path
);
1922 char *cur_dir
= nasm_dirname(cur_path
);
1924 p_section
= get_section_by_name("__DWARF", "__debug_str");
1925 nasm_assert(p_section
!= NULL
);
1927 producer_str_offset
= 0;
1928 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
1929 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
1930 saa_wcstring(p_str
, cur_dir
);
1932 saa_len
= p_str
->datalen
;
1933 p_buf
= nasm_malloc(saa_len
);
1934 saa_rnbytes(p_str
, p_buf
, saa_len
);
1935 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
1937 nasm_free(cur_path
);
1938 nasm_free(cur_file
);
1946 struct SAA
*p_info
= saa_init(1L);
1948 p_section
= get_section_by_name("__DWARF", "__debug_info");
1949 nasm_assert(p_section
!= NULL
);
1951 /* size will be overwritten once determined, so skip in p_info layout */
1952 saa_write16(p_info
, 2); /* dwarf version */
1953 saa_write32(p_info
, 0); /* offset info abbrev */
1954 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
1956 saa_write8(p_info
, 1); /* abbrev entry number */
1958 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
1959 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
1960 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
1961 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
1962 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
1964 if (ofmt
== &of_macho64
) {
1965 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1966 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
1968 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1969 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
1972 saa_write8(p_info
, 2); /* abbrev entry number */
1974 if (ofmt
== &of_macho64
) {
1975 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1976 saa_write64(p_info
, 0); /* DW_AT_frame_base */
1978 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1979 saa_write32(p_info
, 0); /* DW_AT_frame_base */
1981 saa_write8(p_info
, DW_END_default
);
1983 saa_len
= p_info
->datalen
;
1984 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
1986 WRITELONG(p_buf
, saa_len
);
1987 saa_rnbytes(p_info
, p_buf
, saa_len
);
1988 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
1991 nasm_free(p_buf_base
);
1994 /* abbrev section */
1996 struct SAA
*p_abbrev
= saa_init(1L);
1998 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
1999 nasm_assert(p_section
!= NULL
);
2001 saa_write8(p_abbrev
, 1); /* entry number */
2003 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2004 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2006 saa_write8(p_abbrev
, DW_AT_producer
);
2007 saa_write8(p_abbrev
, DW_FORM_strp
);
2009 saa_write8(p_abbrev
, DW_AT_language
);
2010 saa_write8(p_abbrev
, DW_FORM_data2
);
2012 saa_write8(p_abbrev
, DW_AT_name
);
2013 saa_write8(p_abbrev
, DW_FORM_strp
);
2015 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2016 saa_write8(p_abbrev
, DW_FORM_strp
);
2018 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2019 saa_write8(p_abbrev
, DW_FORM_data4
);
2021 saa_write8(p_abbrev
, DW_AT_low_pc
);
2022 saa_write8(p_abbrev
, DW_FORM_addr
);
2024 saa_write8(p_abbrev
, DW_AT_high_pc
);
2025 saa_write8(p_abbrev
, DW_FORM_addr
);
2027 saa_write16(p_abbrev
, DW_END_default
);
2029 saa_write8(p_abbrev
, 2); /* entry number */
2031 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2032 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2034 saa_write8(p_abbrev
, DW_AT_low_pc
);
2035 saa_write8(p_abbrev
, DW_FORM_addr
);
2037 saa_write8(p_abbrev
, DW_AT_frame_base
);
2038 saa_write8(p_abbrev
, DW_FORM_addr
);
2040 saa_write16(p_abbrev
, DW_END_default
);
2042 saa_len
= p_abbrev
->datalen
;
2044 p_buf
= nasm_malloc(saa_len
);
2046 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2047 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2054 static void new_file_list (const char *file_name
, const char *dir_name
)
2056 struct dir_list
*dir_list
;
2057 bool need_new_dir_list
= true;
2059 nasm_new(dw_cur_file
);
2060 dw_cur_file
->file
= ++dw_num_files
;
2061 dw_cur_file
->file_name
= file_name
;
2063 dw_head_file
= dw_cur_file
;
2065 *dw_last_file_next
= dw_cur_file
;
2067 dw_last_file_next
= &(dw_cur_file
->next
);
2070 list_for_each(dir_list
, dw_head_dir
) {
2071 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2072 dw_cur_file
->dir
= dir_list
;
2073 need_new_dir_list
= false;
2079 if(need_new_dir_list
)
2082 dir_list
->dir
= dw_num_dirs
++;
2083 dir_list
->dir_name
= dir_name
;
2085 dw_head_dir
= dir_list
;
2087 *dw_last_dir_next
= dir_list
;
2089 dw_last_dir_next
= &(dir_list
->next
);
2090 dw_cur_file
->dir
= dir_list
;
2094 static void macho_dbg_init(void)
2098 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2100 bool need_new_list
= true;
2101 const char *cur_file
= nasm_basename(file_name
);
2102 const char *cur_dir
= nasm_dirname(file_name
);
2105 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2106 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2108 struct file_list
*match
;
2110 list_for_each(match
, dw_head_file
) {
2111 if(!(strcmp(cur_file
, match
->file_name
)) &&
2112 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2113 dw_cur_file
= match
;
2114 dw_cur_file
->dir
= match
->dir
;
2115 need_new_list
= false;
2122 new_file_list(cur_file
, cur_dir
);
2127 cur_line
= line_num
;
2130 static void macho_dbg_output(int type
, void *param
)
2132 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2133 int32_t secto
= sinfo_param
->secto
;
2134 bool need_new_sect
= false;
2135 struct SAA
*p_linep
= NULL
;
2138 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2139 need_new_sect
= true;
2141 struct dw_sect_list
*match
= dw_head_sect
;
2144 for(; idx
< dw_num_sects
; idx
++) {
2145 if(match
->section
== secto
) {
2146 dw_cur_sect
= match
;
2147 need_new_sect
= false;
2150 match
= match
->next
;
2156 nasm_new(dw_cur_sect
);
2158 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2159 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2160 dw_cur_sect
->offset
= 0;
2161 dw_cur_sect
->next
= NULL
;
2162 dw_cur_sect
->section
= secto
;
2164 saa_write8(p_linep
, DW_LNS_extended_op
);
2165 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2166 saa_write8(p_linep
, DW_LNE_set_address
);
2167 if (ofmt
== &of_macho64
) {
2168 saa_write64(p_linep
, 0);
2170 saa_write32(p_linep
, 0);
2174 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2176 dw_last_sect
->next
= dw_cur_sect
;
2177 dw_last_sect
= dw_cur_sect
;
2181 if(dbg_immcall
== true) {
2182 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2183 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2184 uint32_t cur_file
= dw_cur_file
->file
;
2185 p_linep
= dw_cur_sect
->psaa
;
2187 if(cur_file
!= dw_cur_sect
->file
) {
2188 saa_write8(p_linep
, DW_LNS_set_file
);
2189 saa_write8(p_linep
, cur_file
);
2190 dw_cur_sect
->file
= cur_file
;
2194 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2197 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2198 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2199 saa_write8(p_linep
, special_opcode
);
2201 saa_write8(p_linep
, DW_LNS_advance_line
);
2202 saa_wleb128s(p_linep
, line_delta
);
2204 saa_write8(p_linep
, DW_LNS_advance_pc
);
2205 saa_wleb128u(p_linep
, offset_delta
);
2207 saa_write8(p_linep
, DW_LNS_copy
);
2210 dw_cur_sect
->line
= cur_line
;
2211 dw_cur_sect
->offset
= sinfo_param
->size
;
2214 dbg_immcall
= false;
2218 static void macho_dbg_cleanup(void)
2220 /* dwarf sectors generation */
2221 macho_dbg_generate();
2224 struct dw_sect_list
*p_sect
= dw_head_sect
;
2225 struct file_list
*p_file
= dw_head_file
;
2228 for(; idx
< dw_num_sects
; idx
++) {
2229 struct dw_sect_list
*next
= p_sect
->next
;
2234 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2235 struct file_list
*next
= p_file
->next
;
2243 static const struct macho_fmt macho32_fmt
= {
2253 GENERIC_RELOC_VANILLA
,
2254 GENERIC_RELOC_VANILLA
,
2256 false /* Allow segment-relative relocations */
2259 static void macho32_init(void)
2264 macho_gotpcrel_sect
= NO_SEG
;
2267 static const struct dfmt macho32_df_dwarf
= {
2268 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2272 null_debug_deflabel
,
2273 null_debug_directive
,
2274 null_debug_typevalue
,
2277 NULL
/*pragma list*/
2280 static const struct dfmt
* const macho32_df_arr
[2] =
2281 { &macho32_df_dwarf
, NULL
};
2283 const struct ofmt of_macho32
= {
2284 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2292 nasm_do_legacy_output
,
2306 static const struct macho_fmt macho64_fmt
= {
2311 MACHO_HEADER64_SIZE
,
2312 MACHO_SEGCMD64_SIZE
,
2313 MACHO_SECTCMD64_SIZE
,
2316 X86_64_RELOC_UNSIGNED
,
2317 X86_64_RELOC_SIGNED
,
2319 true /* Force symbol-relative relocations */
2322 static void macho64_init(void)
2327 /* add special symbol for ..gotpcrel */
2328 macho_gotpcrel_sect
= seg_alloc() + 1;
2329 define_label("..gotpcrel", macho_gotpcrel_sect
, 0L, NULL
, false, false);
2332 static const struct dfmt macho64_df_dwarf
= {
2333 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2337 null_debug_deflabel
,
2338 null_debug_directive
,
2339 null_debug_typevalue
,
2342 NULL
/*pragma list*/
2345 static const struct dfmt
* const macho64_df_arr
[2] =
2346 { &macho64_df_dwarf
, NULL
};
2348 const struct ofmt of_macho64
= {
2349 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2357 nasm_do_legacy_output
,