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 */
143 static struct macho_fmt fmt
;
145 static void fwriteptr(uint64_t data
, FILE * fp
)
147 fwriteaddr(data
, fmt
.ptrsize
, fp
);
151 /* nasm internal data */
152 struct section
*next
;
156 struct reloc
*relocs
;
157 struct rbtree
*gsyms
; /* Global symbols in section */
159 bool by_name
; /* This section was specified by full MachO name */
161 /* data that goes into the file */
162 char sectname
[16]; /* what this section is called */
163 char segname
[16]; /* segment this section will be in */
164 uint64_t addr
; /* in-memory address (subject to alignment) */
165 uint64_t size
; /* in-memory and -file size */
166 uint64_t offset
; /* in-file offset */
167 uint32_t pad
; /* padding bytes before section */
168 uint32_t nreloc
; /* relocation entry count */
169 uint32_t flags
; /* type and attributes (masked) */
170 uint32_t extreloc
; /* external relocations */
173 #define SECTION_TYPE 0x000000ff /* section type mask */
175 #define S_REGULAR (0x0) /* standard section */
176 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
178 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
179 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
180 machine instructions */
181 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
182 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
183 #define S_ATTR_DEBUG 0x02000000
184 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
185 #define S_ATTR_LIVE_SUPPORT 0x08000000
186 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
187 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
188 #define S_ATTR_NO_TOC 0x40000000
189 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
190 #define S_ATTR_DEBUG 0x02000000 /* debug section */
192 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
194 /* fake section for absolute symbols, *not* part of the section linked list */
195 static struct section absolute_sect
;
198 /* nasm internal data */
201 /* data that goes into the file */
202 int32_t addr
; /* op's offset in section */
203 uint32_t snum
:24, /* contains symbol index if
204 ** ext otherwise in-file
206 pcrel
:1, /* relative relocation */
207 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
208 ext
:1, /* external symbol referenced */
209 type
:4; /* reloc type */
212 #define R_ABS 0 /* absolute relocation */
213 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
214 ** highest bit == 1 */
217 /* nasm internal data */
218 struct rbtree symv
; /* Global symbol rbtree; "key" contains the
220 struct symbol
*next
; /* next symbol in the list */
221 char *name
; /* name of this symbol */
222 int32_t initial_snum
; /* symbol number used above in reloc */
223 int32_t snum
; /* true snum for reloc */
225 /* data that goes into the file */
226 uint32_t strx
; /* string table index */
227 uint8_t type
; /* symbol type */
228 uint8_t sect
; /* NO_SECT or section number */
229 uint16_t desc
; /* for stab debugging, 0 for us */
232 /* symbol type bits */
233 #define N_EXT 0x01 /* global or external symbol */
235 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
236 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
237 #define N_SECT 0xe /* defined symbol, n_sect holds
240 #define N_TYPE 0x0e /* type bit mask */
242 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
244 /* special section number values */
245 #define NO_SECT 0 /* no section, invalid */
246 #define MAX_SECT 255 /* maximum number of sections */
248 static struct section
*sects
, **sectstail
, **sectstab
;
249 static struct symbol
*syms
, **symstail
;
250 static uint32_t nsyms
;
252 /* These variables are set by macho_layout_symbols() to organize
253 the symbol table and string table in order the dynamic linker
254 expects. They are then used in macho_write() to put out the
255 symbols and strings in that order.
257 The order of the symbol table is:
259 defined external symbols (sorted by name)
260 undefined external symbols (sorted by name)
262 The order of the string table is:
263 strings for external symbols
264 strings for local symbols
266 static uint32_t ilocalsym
= 0;
267 static uint32_t iextdefsym
= 0;
268 static uint32_t iundefsym
= 0;
269 static uint32_t nlocalsym
;
270 static uint32_t nextdefsym
;
271 static uint32_t nundefsym
;
272 static struct symbol
**extdefsyms
= NULL
;
273 static struct symbol
**undefsyms
= NULL
;
275 static struct RAA
*extsyms
;
276 static struct SAA
*strs
;
277 static uint32_t strslen
;
279 /* Global file information. This should be cleaned up into either
280 a structure or as function arguments. */
281 static uint32_t head_ncmds
= 0;
282 static uint32_t head_sizeofcmds
= 0;
283 static uint32_t head_flags
= 0;
284 static uint64_t seg_filesize
= 0;
285 static uint64_t seg_vmsize
= 0;
286 static uint32_t seg_nsects
= 0;
287 static uint64_t rel_padcnt
= 0;
289 #define xstrncpy(xdst, xsrc) \
290 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
291 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
292 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
294 #define alignint32_t(x) \
295 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
297 #define alignint64_t(x) \
298 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
300 #define alignptr(x) \
301 ALIGN(x, fmt.ptrsize) /* align x to output format width */
303 static struct section
*get_section_by_name(const char *segname
,
304 const char *sectname
)
308 for (s
= sects
; s
!= NULL
; s
= s
->next
)
309 if (!strcmp(s
->segname
, segname
) && !strcmp(s
->sectname
, sectname
))
315 static struct section
*get_section_by_index(const int32_t index
)
319 for (s
= sects
; s
!= NULL
; s
= s
->next
)
320 if (index
== s
->index
)
327 struct file_list
*next
;
328 struct file_list
*last
;
333 struct dw_sect_list
{
339 struct dw_sect_list
*next
;
340 struct dw_sect_list
*last
;
343 struct section_info
{
348 #define DW_LN_BASE (-5)
349 #define DW_LN_RANGE 14
350 #define DW_OPCODE_BASE 13
351 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
352 #define DW_MAX_SP_OPCODE 256
354 static struct file_list
*dw_head_list
= 0, *dw_cur_list
= 0, *dw_last_list
= 0;
355 static struct dw_sect_list
*dw_head_sect
= 0, *dw_cur_sect
= 0, *dw_last_sect
= 0;
356 static uint32_t cur_line
= 0, dw_num_files
= 0, dw_num_sects
= 0;
357 static bool dbg_immcall
= false;
358 static const char *module_name
= NULL
;
361 * Special section numbers which are used to define Mach-O special
362 * symbols, which can be used with WRT to provide PIC relocation
365 static int32_t macho_tlvp_sect
;
366 static int32_t macho_gotpcrel_sect
;
368 static void macho_init(void)
373 /* Fake section for absolute symbols */
374 absolute_sect
.index
= NO_SEG
;
383 extsyms
= raa_init();
386 /* string table starts with a zero byte so index 0 is an empty string */
387 saa_wbytes(strs
, zero_buffer
, 1);
390 /* add special symbol for TLVP */
391 macho_tlvp_sect
= seg_alloc() + 1;
392 define_label("..tlvp", macho_tlvp_sect
, 0L, NULL
, false, false);
396 static void sect_write(struct section
*sect
,
397 const uint8_t *data
, uint32_t len
)
399 saa_wbytes(sect
->data
, data
, len
);
404 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
406 static struct symbol
*macho_find_gsym(struct section
*s
,
407 uint64_t offset
, bool exact
)
411 srb
= rb_search(s
->gsyms
, offset
);
413 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
414 nasm_error(ERR_NONFATAL
, "unable to find a suitable %s symbol"
415 " for this reference",
416 s
== &absolute_sect
? "absolute" : "global");
420 return container_of(srb
, struct symbol
, symv
);
423 static int64_t add_reloc(struct section
*sect
, int32_t section
,
425 enum reltype reltype
, int bytes
)
432 /* Double check this is a valid relocation type for this platform */
433 nasm_assert(reltype
<= fmt
.maxreltype
);
435 /* the current end of the section will be the symbol's address for
436 ** now, might have to be fixed by macho_fixup_relocs() later on. make
437 ** sure we don't make the symbol scattered by setting the highest
438 ** bit by accident */
439 r
= nasm_malloc(sizeof(struct reloc
));
440 r
->addr
= sect
->size
& ~R_SCATTERED
;
444 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
445 r
->length
= ilog2_32(bytes
);
447 /* set default relocation values */
448 r
->type
= fmt
.reloc_abs
;
453 if (section
!= NO_SEG
)
454 s
= get_section_by_index(section
);
455 fi
= s
? s
->fileindex
: NO_SECT
;
457 /* absolute relocation */
460 if (section
== NO_SEG
) {
461 /* absolute (can this even happen?) */
464 } else if (fi
== NO_SECT
) {
466 r
->snum
= raa_read(extsyms
, section
);
471 adjust
= -sect
->size
;
477 r
->type
= fmt
.reloc_rel
;
479 if (section
== NO_SEG
) {
480 /* absolute - seems to produce garbage no matter what */
481 nasm_error(ERR_NONFATAL
, "Mach-O does not support relative "
482 "references to absolute addresses");
485 /* This "seems" to be how it ought to work... */
487 struct symbol
*sym
= macho_find_gsym(&absolute_sect
,
494 adjust
= -sect
->size
;
496 } else if (fi
== NO_SECT
) {
499 r
->snum
= raa_read(extsyms
, section
);
500 if (reltype
== RL_BRANCH
)
501 r
->type
= X86_64_RELOC_BRANCH
;
502 else if (r
->type
== GENERIC_RELOC_VANILLA
)
503 adjust
= -sect
->size
;
508 adjust
= -sect
->size
;
514 r
->type
= X86_64_RELOC_SUBTRACTOR
;
518 r
->type
= X86_64_RELOC_GOT
;
522 r
->type
= X86_64_RELOC_GOT_LOAD
;
526 r
->type
= fmt
.reloc_tlv
;
531 if (section
== NO_SEG
) {
532 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
533 } else if (fi
== NO_SECT
) {
535 r
->snum
= raa_read(extsyms
, section
);
538 struct symbol
*sym
= macho_find_gsym(s
, offset
, reltype
!= RL_TLV
);
541 r
->snum
= sym
->initial_snum
;
546 /* NeXT as puts relocs in reversed order (address-wise) into the
547 ** files, so we do the same, doesn't seem to make much of a
548 ** difference either way */
549 r
->next
= sect
->relocs
;
562 static void macho_output(int32_t secto
, const void *data
,
563 enum out_type type
, uint64_t size
,
564 int32_t section
, int32_t wrt
)
567 int64_t addr
, offset
;
568 uint8_t mydata
[16], *p
;
570 enum reltype reltype
;
572 if (secto
== NO_SEG
) {
573 if (type
!= OUT_RESERVE
)
574 nasm_error(ERR_NONFATAL
, "attempt to assemble code in "
579 s
= get_section_by_index(secto
);
582 nasm_error(ERR_WARNING
, "attempt to assemble code in"
583 " section %d: defaulting to `.text'", secto
);
584 s
= get_section_by_name("__TEXT", "__text");
586 /* should never happen */
588 nasm_panic(0, "text section not found");
591 /* debug code generation only for sections tagged with
592 * instruction attribute */
593 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
595 struct section_info sinfo
;
596 sinfo
.size
= s
->size
;
598 dfmt
->debug_output(0, &sinfo
);
601 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
603 if (is_bss
&& type
!= OUT_RESERVE
) {
604 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
605 "BSS section: ignored");
606 s
->size
+= realsize(type
, size
);
610 memset(mydata
, 0, sizeof(mydata
));
615 nasm_error(ERR_WARNING
, "uninitialized space declared in"
616 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
618 sect_write(s
, NULL
, size
);
625 if (section
!= NO_SEG
)
626 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
628 sect_write(s
, data
, size
);
633 int asize
= abs((int)size
);
635 addr
= *(int64_t *)data
;
636 if (section
!= NO_SEG
) {
638 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
639 " section base references");
640 } else if (wrt
== NO_SEG
) {
641 if (fmt
.ptrsize
== 8 && asize
!= 8) {
642 nasm_error(ERR_NONFATAL
,
643 "Mach-O 64-bit format does not support"
644 " 32-bit absolute addresses");
646 add_reloc(s
, section
, addr
, RL_ABS
, asize
);
649 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
655 WRITEADDR(p
, addr
, asize
);
656 sect_write(s
, mydata
, asize
);
661 nasm_assert(section
!= secto
);
664 offset
= *(int64_t *)data
;
665 addr
= offset
- size
;
667 if (section
!= NO_SEG
&& section
% 2) {
668 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
669 " section base references");
670 } else if (fmt
.ptrsize
== 8) {
671 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
672 " Macho-O relocation [2]");
673 } else if (wrt
!= NO_SEG
) {
674 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
676 wrt
= NO_SEG
; /* we can at least _try_ to continue */
678 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
, 2);
682 sect_write(s
, mydata
, 2);
686 nasm_assert(section
!= secto
);
689 offset
= *(int64_t *)data
;
690 addr
= offset
- size
;
693 if (section
!= NO_SEG
&& section
% 2) {
694 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
695 " section base references");
696 } else if (wrt
== NO_SEG
) {
697 if (fmt
.ptrsize
== 8 &&
698 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
701 opcode
[0] = opcode
[1] = 0;
703 /* HACK: Retrieve instruction opcode */
704 if (likely(s
->data
->datalen
>= 2)) {
705 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
706 } else if (s
->data
->datalen
== 1) {
707 saa_fread(s
->data
, 0, opcode
+1, 1);
710 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
711 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
712 /* Direct call, jmp, or jcc */
716 } else if (wrt
== macho_gotpcrel_sect
) {
719 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
720 s
->data
->datalen
>= 3) {
723 /* HACK: Retrieve instruction opcode */
724 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
725 if ((gotload
[0] & 0xf8) == 0x48 &&
726 gotload
[1] == 0x8b &&
727 (gotload
[2] & 0307) == 0005) {
728 /* movq <reg>,[rel sym wrt ..gotpcrel] */
729 reltype
= RL_GOTLOAD
;
732 } else if (wrt
== macho_tlvp_sect
) {
735 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
737 /* continue with RL_REL */
740 addr
+= add_reloc(s
, section
, offset
, reltype
, 4);
742 sect_write(s
, mydata
, 4);
746 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
751 /* Translation table from traditional Unix section names to Mach-O */
752 static const struct sectmap
{
753 const char *nasmsect
;
755 const char *sectname
;
756 const uint32_t flags
;
758 {".text", "__TEXT", "__text",
759 S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
760 {".data", "__DATA", "__data", S_REGULAR
},
761 {".rodata", "__DATA", "__const", S_REGULAR
},
762 {".bss", "__DATA", "__bss", S_ZEROFILL
},
763 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
764 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
765 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
766 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
767 {NULL
, NULL
, NULL
, 0}
770 #define NO_TYPE S_NASM_TYPE_MASK
772 /* Section type or attribute directives */
773 static const struct sect_attribs
{
777 { "data", S_REGULAR
},
778 { "code", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
779 { "mixed", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
780 { "bss", S_ZEROFILL
},
781 { "zerofill", S_ZEROFILL
},
782 { "no_dead_strip", NO_TYPE
|S_ATTR_NO_DEAD_STRIP
},
783 { "live_support", NO_TYPE
|S_ATTR_LIVE_SUPPORT
},
784 { "strip_static_syms", NO_TYPE
|S_ATTR_STRIP_STATIC_SYMS
},
788 static int32_t macho_section(char *name
, int pass
, int *bits
)
790 char *sectionAttributes
;
791 const struct sectmap
*sm
;
793 const char *section
, *segment
;
795 const struct sect_attribs
*sa
;
796 char *currentAttribute
;
803 /* Default to the appropriate number of bits. */
805 *bits
= fmt
.ptrsize
<< 3;
807 sectionAttributes
= NULL
;
809 sectionAttributes
= name
;
810 name
= nasm_strsep(§ionAttributes
, " \t");
813 section
= segment
= NULL
;
816 comma
= strchr(name
, ',');
824 len
= strlen(segment
);
826 nasm_error(ERR_NONFATAL
, "empty segment name\n");
827 } else if (len
>= 16) {
828 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
831 len
= strlen(section
);
833 nasm_error(ERR_NONFATAL
, "empty section name\n");
834 } else if (len
>= 16) {
835 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
838 if (!strcmp(section
, "__text")) {
839 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
840 S_ATTR_PURE_INSTRUCTIONS
;
841 } else if (!strcmp(section
, "__bss")) {
847 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
848 /* make lookup into section name translation table */
849 if (!strcmp(name
, sm
->nasmsect
)) {
850 segment
= sm
->segname
;
851 section
= sm
->sectname
;
856 nasm_error(ERR_NONFATAL
, "unknown section name\n");
861 /* try to find section with that name */
862 s
= get_section_by_name(segment
, section
);
864 /* create it if it doesn't exist yet */
868 s
= *sectstail
= nasm_zalloc(sizeof(struct section
));
869 sectstail
= &s
->next
;
871 s
->data
= saa_init(1L);
872 s
->index
= seg_alloc();
873 s
->fileindex
= ++seg_nsects
;
879 xstrncpy(s
->segname
, segment
);
880 xstrncpy(s
->sectname
, section
);
889 *comma
= ','; /* Restore comma */
891 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
895 while (sectionAttributes
&&
896 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
897 if (!*currentAttribute
)
900 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
902 int newAlignment
, value
;
904 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
905 newAlignment
= alignlog2_32(value
);
908 nasm_error(ERR_NONFATAL
,
909 "unknown or missing alignment value \"%s\" "
910 "specified for section \"%s\"",
911 currentAttribute
+ 6,
913 } else if (0 > newAlignment
) {
914 nasm_error(ERR_NONFATAL
,
915 "alignment of %d (for section \"%s\") is not "
921 if (s
->align
< newAlignment
)
922 s
->align
= newAlignment
;
924 for (sa
= sect_attribs
; sa
->name
; sa
++) {
925 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
926 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
927 flags
= (flags
& ~S_NASM_TYPE_MASK
)
928 | (sa
->flags
& S_NASM_TYPE_MASK
);
930 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
936 nasm_error(ERR_NONFATAL
,
937 "unknown section attribute %s for section %s",
938 currentAttribute
, name
);
943 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
944 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
945 nasm_error(ERR_NONFATAL
,
946 "inconsistent section attributes for section %s\n",
949 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
952 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
958 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
959 int is_global
, char *special
)
964 nasm_error(ERR_NONFATAL
, "The Mach-O output format does "
965 "not support any special symbol types");
969 if (is_global
== 3) {
970 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
971 "(yet) support forward reference fixups.");
975 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
977 * This is a NASM special symbol. We never allow it into
978 * the Macho-O symbol table, even if it's a valid one. If it
979 * _isn't_ a valid one, we should barf immediately.
981 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
982 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
986 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
988 symstail
= &sym
->next
;
994 sym
->symv
.key
= offset
;
995 sym
->initial_snum
= -1;
997 /* external and common symbols get N_EXT */
998 if (is_global
!= 0) {
1002 if (section
== NO_SEG
) {
1003 /* symbols in no section get absolute */
1005 sym
->sect
= NO_SECT
;
1007 /* all absolute symbols are available to use as references */
1008 absolute_sect
.gsyms
= rb_insert(absolute_sect
.gsyms
, &sym
->symv
);
1010 struct section
*s
= get_section_by_index(section
);
1012 sym
->type
|= N_SECT
;
1014 /* get the in-file index of the section the symbol was defined in */
1015 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1017 /* track the initially allocated symbol number for use in future fix-ups */
1018 sym
->initial_snum
= nsyms
;
1021 /* remember symbol number of references to external
1022 ** symbols, this works because every external symbol gets
1023 ** its own section number allocated internally by nasm and
1024 ** can so be used as a key */
1025 extsyms
= raa_write(extsyms
, section
, nsyms
);
1027 switch (is_global
) {
1030 /* there isn't actually a difference between global
1031 ** and common symbols, both even have their size in
1037 /* give an error on unfound section if it's not an
1038 ** external or common symbol (assemble_file() does a
1039 ** seg_alloc() on every call for them) */
1040 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section
, is_global
);
1043 } else if (is_global
) {
1044 s
->gsyms
= rb_insert(s
->gsyms
, &sym
->symv
);
1050 static void macho_sectalign(int32_t seg
, unsigned int value
)
1055 nasm_assert(!(seg
& 1));
1057 s
= get_section_by_index(seg
);
1059 if (!s
|| !is_power2(value
))
1062 align
= alignlog2_32(value
);
1063 if (s
->align
< align
)
1067 static int32_t macho_segbase(int32_t section
)
1072 static void macho_filename(char *inname
, char *outname
)
1074 standard_extension(inname
, outname
, ".o");
1075 module_name
= inname
;
1078 extern macros_t macho_stdmac
[];
1080 /* Comparison function for qsort symbol layout. */
1081 static int layout_compare (const struct symbol
**s1
,
1082 const struct symbol
**s2
)
1084 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1087 /* The native assembler does a few things in a similar function
1089 * Remove temporary labels
1090 * Sort symbols according to local, external, undefined (by name)
1091 * Order the string table
1093 We do not remove temporary labels right now.
1095 numsyms is the total number of symbols we have. strtabsize is the
1096 number entries in the string table. */
1098 static void macho_layout_symbols (uint32_t *numsyms
,
1099 uint32_t *strtabsize
)
1101 struct symbol
*sym
, **symp
;
1105 *strtabsize
= sizeof (char);
1109 while ((sym
= *symp
)) {
1110 /* Undefined symbols are now external. */
1111 if (sym
->type
== N_UNDF
)
1114 if ((sym
->type
& N_EXT
) == 0) {
1115 sym
->snum
= *numsyms
;
1116 *numsyms
= *numsyms
+ 1;
1120 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1126 /* If we handle debug info we'll want
1127 to check for it here instead of just
1128 adding the symbol to the string table. */
1129 sym
->strx
= *strtabsize
;
1130 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1131 *strtabsize
+= strlen(sym
->name
) + 1;
1133 symp
= &(sym
->next
);
1136 /* Next, sort the symbols. Most of this code is a direct translation from
1137 the Apple cctools symbol layout. We need to keep compatibility with that. */
1138 /* Set the indexes for symbol groups into the symbol table */
1140 iextdefsym
= nlocalsym
;
1141 iundefsym
= nlocalsym
+ nextdefsym
;
1143 /* allocate arrays for sorting externals by name */
1144 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1145 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1152 while ((sym
= *symp
)) {
1154 if((sym
->type
& N_EXT
) == 0) {
1155 sym
->strx
= *strtabsize
;
1156 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1157 *strtabsize
+= strlen(sym
->name
) + 1;
1160 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1161 extdefsyms
[i
++] = sym
;
1163 undefsyms
[j
++] = sym
;
1166 symp
= &(sym
->next
);
1169 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1170 (int (*)(const void *, const void *))layout_compare
);
1171 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1172 (int (*)(const void *, const void *))layout_compare
);
1174 for(i
= 0; i
< nextdefsym
; i
++) {
1175 extdefsyms
[i
]->snum
= *numsyms
;
1178 for(j
= 0; j
< nundefsym
; j
++) {
1179 undefsyms
[j
]->snum
= *numsyms
;
1184 /* Calculate some values we'll need for writing later. */
1186 static void macho_calculate_sizes (void)
1191 /* count sections and calculate in-memory and in-file offsets */
1192 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1195 /* recalculate segment address based on alignment and vm size */
1196 s
->addr
= seg_vmsize
;
1198 /* we need section alignment to calculate final section address */
1200 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1202 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1205 seg_vmsize
= newaddr
+ s
->size
;
1207 /* zerofill sections aren't actually written to the file */
1208 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1210 * LLVM/Xcode as always aligns the section data to 4
1211 * bytes; there is a comment in the LLVM source code that
1212 * perhaps aligning to pointer size would be better.
1214 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1215 s
->offset
= seg_filesize
+ s
->pad
;
1216 seg_filesize
+= s
->size
+ s
->pad
;
1218 /* filesize and vmsize needs to be aligned */
1219 seg_vmsize
+= s
->pad
;
1223 /* calculate size of all headers, load commands and sections to
1224 ** get a pointer to the start of all the raw data */
1225 if (seg_nsects
> 0) {
1227 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1232 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1235 if (seg_nsects
> MAX_SECT
) {
1236 nasm_fatal(0, "MachO output is limited to %d sections\n",
1240 /* Create a table of sections by file index to avoid linear search */
1241 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1242 sectstab
[NO_SECT
] = &absolute_sect
;
1243 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1247 /* Write out the header information for the file. */
1249 static void macho_write_header (void)
1251 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1252 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1253 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1254 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1255 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1256 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1257 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1258 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1261 /* Write out the segment load command at offset. */
1263 static uint32_t macho_write_segment (uint64_t offset
)
1265 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1266 uint32_t s_reloff
= 0;
1269 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1271 /* size of load command including section load commands */
1272 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1275 /* in an MH_OBJECT file all sections are in one unnamed (name
1276 ** all zeros) segment */
1277 fwritezero(16, ofile
);
1278 fwriteptr(0, ofile
); /* in-memory offset */
1279 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1280 fwriteptr(offset
, ofile
); /* in-file offset to data */
1281 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1282 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1283 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1284 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1285 fwriteint32_t(0, ofile
); /* no flags */
1287 /* emit section headers */
1288 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1290 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1291 s
->flags
|= S_ATTR_LOC_RELOC
;
1293 s
->flags
|= S_ATTR_EXT_RELOC
;
1294 } else if (!strcmp(s
->segname
, "__DATA") &&
1295 !strcmp(s
->sectname
, "__const") &&
1297 !get_section_by_name("__TEXT", "__const")) {
1299 * The MachO equivalent to .rodata can be either
1300 * __DATA,__const or __TEXT,__const; the latter only if
1301 * there are no relocations. However, when mixed it is
1302 * better to specify the segments explicitly.
1304 xstrncpy(s
->segname
, "__TEXT");
1307 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1308 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1309 fwriteptr(s
->addr
, ofile
);
1310 fwriteptr(s
->size
, ofile
);
1312 /* dummy data for zerofill sections or proper values */
1313 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1314 nasm_assert(s
->pad
!= (uint32_t)-1);
1316 fwriteint32_t(offset
, ofile
);
1318 /* Write out section alignment, as a power of two.
1319 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1320 fwriteint32_t(s
->align
, ofile
);
1321 /* To be compatible with cctools as we emit
1322 a zero reloff if we have no relocations. */
1323 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1324 fwriteint32_t(s
->nreloc
, ofile
);
1326 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1328 fwriteint32_t(0, ofile
);
1329 fwriteint32_t(s
->align
, ofile
);
1330 fwriteint32_t(0, ofile
);
1331 fwriteint32_t(0, ofile
);
1334 fwriteint32_t(s
->flags
, ofile
); /* flags */
1335 fwriteint32_t(0, ofile
); /* reserved */
1336 fwriteptr(0, ofile
); /* reserved */
1339 rel_padcnt
= rel_base
- offset
;
1340 offset
= rel_base
+ s_reloff
;
1345 /* For a given chain of relocs r, write out the entire relocation
1346 chain to the object file. */
1348 static void macho_write_relocs (struct reloc
*r
)
1353 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1356 word2
|= r
->pcrel
<< 24;
1357 word2
|= r
->length
<< 25;
1358 word2
|= r
->ext
<< 27;
1359 word2
|= r
->type
<< 28;
1360 fwriteint32_t(word2
, ofile
); /* reloc data */
1365 /* Write out the section data. */
1366 static void macho_write_section (void)
1378 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1379 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1382 /* Like a.out Mach-O references things in the data or bss
1383 * sections by addresses which are actually relative to the
1384 * start of the _text_ section, in the _file_. See outaout.c
1385 * for more information. */
1386 saa_rewind(s
->data
);
1387 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1388 len
= (uint32_t)1 << r
->length
;
1389 if (len
> 4) /* Can this ever be an issue?! */
1392 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1394 /* get offset based on relocation type */
1395 #ifdef WORDS_LITTLEENDIAN
1399 l
+= ((int64_t)blk
.buf
[1]) << 8;
1400 l
+= ((int64_t)blk
.buf
[2]) << 16;
1401 l
+= ((int64_t)blk
.buf
[3]) << 24;
1402 l
+= ((int64_t)blk
.buf
[4]) << 32;
1403 l
+= ((int64_t)blk
.buf
[5]) << 40;
1404 l
+= ((int64_t)blk
.buf
[6]) << 48;
1405 l
+= ((int64_t)blk
.buf
[7]) << 56;
1408 /* If the relocation is internal add to the current section
1409 offset. Otherwise the only value we need is the symbol
1410 offset which we already have. The linker takes care
1411 of the rest of the address. */
1413 /* generate final address by section address and offset */
1414 nasm_assert(r
->snum
<= seg_nsects
);
1415 l
+= sectstab
[r
->snum
]->addr
;
1418 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1422 /* write new offset back */
1425 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1428 /* dump the section data to file */
1429 fwritezero(s
->pad
, ofile
);
1430 saa_fpwrite(s
->data
, ofile
);
1433 /* pad last section up to reloc entries on pointer boundary */
1434 fwritezero(rel_padcnt
, ofile
);
1436 /* emit relocation entries */
1437 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1438 macho_write_relocs (s
->relocs
);
1441 /* Write out the symbol table. We should already have sorted this
1443 static void macho_write_symtab (void)
1448 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1450 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1451 if ((sym
->type
& N_EXT
) == 0) {
1452 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1453 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1454 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1455 fwriteint16_t(sym
->desc
, ofile
); /* description */
1457 /* Fix up the symbol value now that we know the final section
1459 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1460 nasm_assert(sym
->sect
<= seg_nsects
);
1461 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1464 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1468 for (i
= 0; i
< nextdefsym
; i
++) {
1469 sym
= extdefsyms
[i
];
1470 fwriteint32_t(sym
->strx
, ofile
);
1471 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1472 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1473 fwriteint16_t(sym
->desc
, ofile
); /* description */
1475 /* Fix up the symbol value now that we know the final section
1477 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1478 nasm_assert(sym
->sect
<= seg_nsects
);
1479 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1482 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1485 for (i
= 0; i
< nundefsym
; i
++) {
1487 fwriteint32_t(sym
->strx
, ofile
);
1488 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1489 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1490 fwriteint16_t(sym
->desc
, ofile
); /* description */
1492 /* Fix up the symbol value now that we know the final section
1494 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1495 nasm_assert(sym
->sect
<= seg_nsects
);
1496 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1499 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1504 /* Fixup the snum in the relocation entries, we should be
1505 doing this only for externally referenced symbols. */
1506 static void macho_fixup_relocs (struct reloc
*r
)
1512 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1513 if (sym
->initial_snum
== r
->snum
) {
1514 r
->snum
= sym
->snum
;
1523 /* Write out the object file. */
1525 static void macho_write (void)
1527 uint64_t offset
= 0;
1529 /* mach-o object file structure:
1535 ** uint32_t mach file type
1536 ** uint32_t number of load commands
1537 ** uint32_t size of all load commands
1538 ** (includes section struct size of segment command)
1542 ** uint32_t command type == LC_SEGMENT[_64]
1543 ** uint32_t size of load command
1544 ** (including section load commands)
1545 ** char[16] segment name
1546 ** pointer in-memory offset
1547 ** pointer in-memory size
1548 ** pointer in-file offset to data area
1549 ** pointer in-file size
1550 ** (in-memory size excluding zerofill sections)
1551 ** int maximum vm protection
1552 ** int initial vm protection
1553 ** uint32_t number of sections
1557 ** char[16] section name
1558 ** char[16] segment name
1559 ** pointer in-memory offset
1560 ** pointer in-memory size
1561 ** uint32_t in-file offset
1562 ** uint32_t alignment
1563 ** (irrelevant in MH_OBJECT)
1564 ** uint32_t in-file offset of relocation entires
1565 ** uint32_t number of relocations
1567 ** uint32_t reserved
1568 ** uint32_t reserved
1570 ** symbol table command
1571 ** uint32_t command type == LC_SYMTAB
1572 ** uint32_t size of load command
1573 ** uint32_t symbol table offset
1574 ** uint32_t number of symbol table entries
1575 ** uint32_t string table offset
1576 ** uint32_t string table size
1580 ** padding to pointer boundary
1582 ** relocation data (struct reloc)
1584 ** uint data (symbolnum, pcrel, length, extern, type)
1586 ** symbol table data (struct nlist)
1587 ** int32_t string table entry number
1589 ** (extern, absolute, defined in section)
1591 ** (0 for global symbols, section number of definition (>= 1, <=
1592 ** 254) for local symbols, size of variable for common symbols
1593 ** [type == extern])
1594 ** int16_t description
1595 ** (for stab debugging format)
1596 ** pointer value (i.e. file offset) of symbol or stab offset
1598 ** string table data
1599 ** list of null-terminated strings
1602 /* Emit the Mach-O header. */
1603 macho_write_header();
1605 offset
= fmt
.header_size
+ head_sizeofcmds
;
1607 /* emit the segment load command */
1609 offset
= macho_write_segment (offset
);
1611 nasm_error(ERR_WARNING
, "no sections?");
1614 /* write out symbol command */
1615 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1616 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1617 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1618 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1620 offset
+= nsyms
* fmt
.nlist_size
;
1621 fwriteint32_t(offset
, ofile
); /* string table offset */
1622 fwriteint32_t(strslen
, ofile
); /* string table size */
1625 /* emit section data */
1627 macho_write_section ();
1629 /* emit symbol table if we have symbols */
1631 macho_write_symtab ();
1633 /* we don't need to pad here, we are already aligned */
1635 /* emit string table */
1636 saa_fpwrite(strs
, ofile
);
1638 /* We do quite a bit here, starting with finalizing all of the data
1639 for the object file, writing, and then freeing all of the data from
1642 static void macho_cleanup(void)
1650 /* Sort all symbols. */
1651 macho_layout_symbols (&nsyms
, &strslen
);
1653 /* Fixup relocation entries */
1654 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1655 macho_fixup_relocs (s
->relocs
);
1658 /* First calculate and finalize needed values. */
1659 macho_calculate_sizes();
1662 /* free up everything */
1663 while (sects
->next
) {
1665 sects
= sects
->next
;
1668 while (s
->relocs
!= NULL
) {
1670 s
->relocs
= s
->relocs
->next
;
1686 nasm_free(extdefsyms
);
1687 nasm_free(undefsyms
);
1688 nasm_free(sectstab
);
1691 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1697 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1698 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1702 s
= get_section_by_index(nasm_seg
);
1704 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1713 * Mark a symbol for no dead stripping
1715 static enum directive_result
macho_no_dead_strip(const char *labels
)
1719 enum directive_result rv
= DIRR_ERROR
;
1720 bool real
= passn
> 1;
1722 p
= s
= nasm_strdup(labels
);
1724 ep
= nasm_skip_identifier(p
);
1726 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1730 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1731 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1736 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1740 p
= nasm_skip_spaces(ep
);
1742 p
= nasm_skip_spaces(++p
);
1755 static enum directive_result
1756 macho_pragma(const struct pragma
*pragma
)
1758 bool real
= passn
> 1;
1760 switch (pragma
->opcode
) {
1761 case D_SUBSECTIONS_VIA_SYMBOLS
:
1763 return DIRR_BADPARAM
;
1766 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1770 case D_NO_DEAD_STRIP
:
1771 return macho_no_dead_strip(pragma
->tail
);
1774 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1778 static const struct pragma_facility macho_pragma_list
[] = {
1779 { "macho", macho_pragma
},
1780 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1783 static void macho_dbg_generate(void)
1785 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1786 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1787 struct section
*p_section
= NULL
;
1788 /* calculated at debug_str and referenced at debug_info */
1789 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1791 /* debug section defines */
1794 macho_section(".debug_abbrev", 0, &bits
);
1795 macho_section(".debug_info", 0, &bits
);
1796 macho_section(".debug_line", 0, &bits
);
1797 macho_section(".debug_str", 0, &bits
);
1800 /* dw section walk to find high_addr and total_len */
1802 struct dw_sect_list
*p_sect
;
1804 list_for_each(p_sect
, dw_head_sect
) {
1805 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1806 struct SAA
*p_linep
= p_sect
->psaa
;
1808 saa_write8(p_linep
, 2); /* std op 2 */
1809 saa_write8(p_linep
, offset
- p_sect
->offset
);
1810 saa_write8(p_linep
, DW_LNS_extended_op
);
1811 saa_write8(p_linep
, 1); /* operand length */
1812 saa_write8(p_linep
, DW_LNE_end_sequence
);
1814 total_len
+= p_linep
->datalen
;
1815 high_addr
+= offset
;
1821 struct dw_sect_list
*p_sect
;
1822 size_t linep_off
, buf_size
;
1823 struct SAA
*p_lines
= saa_init(1L);
1825 p_section
= get_section_by_name("__DWARF", "__debug_line");
1826 nasm_assert(p_section
!= NULL
);
1828 saa_write8(p_lines
, 1); /* minimum instruction length */
1829 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1830 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1831 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1832 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1833 saa_write8(p_lines
, 0); /* std opcode 1 length */
1834 saa_write8(p_lines
, 1); /* std opcode 2 length */
1835 saa_write8(p_lines
, 1); /* std opcode 3 length */
1836 saa_write8(p_lines
, 1); /* std opcode 4 length */
1837 saa_write8(p_lines
, 1); /* std opcode 5 length */
1838 saa_write8(p_lines
, 0); /* std opcode 6 length */
1839 saa_write8(p_lines
, 0); /* std opcode 7 length */
1840 saa_write8(p_lines
, 0); /* std opcode 8 length */
1841 saa_write8(p_lines
, 1); /* std opcode 9 length */
1842 saa_write8(p_lines
, 0); /* std opcode 10 length */
1843 saa_write8(p_lines
, 0); /* std opcode 11 length */
1844 saa_write8(p_lines
, 1); /* std opcode 12 length */
1845 saa_write8(p_lines
, 0); /* end of table */
1847 saa_wcstring(p_lines
, module_name
);
1848 saa_write8(p_lines
, 0); /* directory */
1849 saa_write8(p_lines
, 0); /* time */
1850 saa_write8(p_lines
, 0); /* size */
1851 saa_write8(p_lines
, 0); /* end of table */
1853 linep_off
= p_lines
->datalen
;
1854 /* 10 bytes for initial & prolong length, and dwarf version info */
1855 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1856 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1858 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1859 WRITESHORT(p_buf
, 2); /* dwarf version */
1860 WRITELONG(p_buf
, linep_off
); /* prolong length */
1862 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1866 list_for_each(p_sect
, dw_head_sect
) {
1867 struct SAA
*p_linep
= p_sect
->psaa
;
1869 saa_len
= p_linep
->datalen
;
1870 saa_rnbytes(p_linep
, p_buf
, saa_len
);
1876 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
1878 nasm_free(p_buf_base
);
1881 /* string section */
1883 struct SAA
*p_str
= saa_init(1L);
1884 char *cur_path
= nasm_realpath(module_name
);
1885 char *cur_file
= nasm_basename(cur_path
);
1886 char *cur_dir
= nasm_dirname(cur_path
);
1888 p_section
= get_section_by_name("__DWARF", "__debug_str");
1889 nasm_assert(p_section
!= NULL
);
1891 producer_str_offset
= 0;
1892 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
1893 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
1894 saa_wcstring(p_str
, cur_dir
);
1896 saa_len
= p_str
->datalen
;
1897 p_buf
= nasm_malloc(saa_len
);
1898 saa_rnbytes(p_str
, p_buf
, saa_len
);
1899 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
1901 nasm_free(cur_path
);
1902 nasm_free(cur_file
);
1910 struct SAA
*p_info
= saa_init(1L);
1912 p_section
= get_section_by_name("__DWARF", "__debug_info");
1913 nasm_assert(p_section
!= NULL
);
1915 /* size will be overwritten once determined, so skip in p_info layout */
1916 saa_write16(p_info
, 2); /* dwarf version */
1917 saa_write32(p_info
, 0); /* offset info abbrev */
1918 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
1920 saa_write8(p_info
, 1); /* abbrev entry number */
1922 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
1923 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
1924 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
1925 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
1926 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
1928 if (ofmt
== &of_macho64
) {
1929 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1930 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
1932 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1933 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
1936 saa_write8(p_info
, 2); /* abbrev entry number */
1938 if (ofmt
== &of_macho64
) {
1939 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1940 saa_write64(p_info
, 0); /* DW_AT_frame_base */
1942 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1943 saa_write32(p_info
, 0); /* DW_AT_frame_base */
1945 saa_write8(p_info
, DW_END_default
);
1947 saa_len
= p_info
->datalen
;
1948 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
1950 WRITELONG(p_buf
, saa_len
);
1951 saa_rnbytes(p_info
, p_buf
, saa_len
);
1952 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
1955 nasm_free(p_buf_base
);
1958 /* abbrev section */
1960 struct SAA
*p_abbrev
= saa_init(1L);
1962 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
1963 nasm_assert(p_section
!= NULL
);
1965 saa_write8(p_abbrev
, 1); /* entry number */
1967 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
1968 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
1970 saa_write8(p_abbrev
, DW_AT_producer
);
1971 saa_write8(p_abbrev
, DW_FORM_strp
);
1973 saa_write8(p_abbrev
, DW_AT_language
);
1974 saa_write8(p_abbrev
, DW_FORM_data2
);
1976 saa_write8(p_abbrev
, DW_AT_name
);
1977 saa_write8(p_abbrev
, DW_FORM_strp
);
1979 saa_write8(p_abbrev
, DW_AT_comp_dir
);
1980 saa_write8(p_abbrev
, DW_FORM_strp
);
1982 saa_write8(p_abbrev
, DW_AT_stmt_list
);
1983 saa_write8(p_abbrev
, DW_FORM_data4
);
1985 saa_write8(p_abbrev
, DW_AT_low_pc
);
1986 saa_write8(p_abbrev
, DW_FORM_addr
);
1988 saa_write8(p_abbrev
, DW_AT_high_pc
);
1989 saa_write8(p_abbrev
, DW_FORM_addr
);
1991 saa_write16(p_abbrev
, DW_END_default
);
1993 saa_write8(p_abbrev
, 2); /* entry number */
1995 saa_write8(p_abbrev
, DW_TAG_subprogram
);
1996 saa_write8(p_abbrev
, DW_CHILDREN_no
);
1998 saa_write8(p_abbrev
, DW_AT_low_pc
);
1999 saa_write8(p_abbrev
, DW_FORM_addr
);
2001 saa_write8(p_abbrev
, DW_AT_frame_base
);
2002 saa_write8(p_abbrev
, DW_FORM_addr
);
2004 saa_write16(p_abbrev
, DW_END_default
);
2006 saa_len
= p_abbrev
->datalen
;
2008 p_buf
= nasm_malloc(saa_len
);
2010 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2011 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2018 static void macho_dbg_init(void)
2022 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2024 bool need_new_list
= true;
2027 if(!dw_cur_list
|| strcmp(file_name
, dw_cur_list
->file_name
)) {
2029 struct file_list
*match
;
2031 list_for_each(match
, dw_head_list
) {
2032 if(!(strcmp(file_name
, match
->file_name
))) {
2033 dw_cur_list
= match
;
2034 need_new_list
= false;
2041 nasm_new(dw_cur_list
);
2042 dw_cur_list
->file
= ++dw_num_files
;
2043 dw_cur_list
->file_name
= (char*) file_name
;
2046 dw_head_list
= dw_last_list
= dw_cur_list
;
2048 dw_last_list
->next
= dw_cur_list
;
2049 dw_last_list
= dw_cur_list
;
2055 cur_line
= line_num
;
2058 static void macho_dbg_output(int type
, void *param
)
2060 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2061 int32_t secto
= sinfo_param
->secto
;
2062 bool need_new_sect
= false;
2063 struct SAA
*p_linep
= NULL
;
2066 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2067 need_new_sect
= true;
2069 struct dw_sect_list
*match
= dw_head_sect
;
2072 for(; idx
< dw_num_sects
; idx
++) {
2073 if(match
->section
== secto
) {
2074 dw_cur_sect
= match
;
2075 need_new_sect
= false;
2078 match
= match
->next
;
2084 nasm_new(dw_cur_sect
);
2086 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2087 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2088 dw_cur_sect
->offset
= 0;
2089 dw_cur_sect
->next
= NULL
;
2090 dw_cur_sect
->section
= secto
;
2092 saa_write8(p_linep
, DW_LNS_extended_op
);
2093 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2094 saa_write8(p_linep
, DW_LNE_set_address
);
2095 if (ofmt
== &of_macho64
) {
2096 saa_write64(p_linep
, 0);
2098 saa_write32(p_linep
, 0);
2102 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2104 dw_last_sect
->next
= dw_cur_sect
;
2105 dw_last_sect
= dw_cur_sect
;
2109 if(dbg_immcall
== true) {
2110 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2111 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2112 uint32_t cur_file
= dw_cur_list
->file
;
2113 p_linep
= dw_cur_sect
->psaa
;
2115 if(cur_file
!= dw_cur_sect
->file
) {
2116 saa_write8(p_linep
, DW_LNS_set_file
);
2117 saa_write8(p_linep
, cur_file
);
2118 dw_cur_sect
->file
= cur_file
;
2122 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2125 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2126 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2127 saa_write8(p_linep
, special_opcode
);
2129 saa_write8(p_linep
, DW_LNS_advance_line
);
2130 saa_wleb128s(p_linep
, line_delta
);
2132 saa_write8(p_linep
, DW_LNS_advance_pc
);
2133 saa_wleb128u(p_linep
, offset_delta
);
2135 saa_write8(p_linep
, DW_LNS_copy
);
2138 dw_cur_sect
->line
= cur_line
;
2139 dw_cur_sect
->offset
= sinfo_param
->size
;
2142 dbg_immcall
= false;
2146 static void macho_dbg_cleanup(void)
2148 /* dwarf sectors generation */
2149 macho_dbg_generate();
2152 struct dw_sect_list
*p_sect
= dw_head_sect
;
2153 struct file_list
*p_file
= dw_head_list
;
2156 for(; idx
< dw_num_sects
; idx
++) {
2157 struct dw_sect_list
*next
= p_sect
->next
;
2162 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2163 struct file_list
*next
= p_file
->next
;
2171 static const struct macho_fmt macho32_fmt
= {
2181 GENERIC_RELOC_VANILLA
,
2182 GENERIC_RELOC_VANILLA
,
2186 static void macho32_init(void)
2191 macho_gotpcrel_sect
= NO_SEG
;
2194 static const struct dfmt macho32_df_dwarf
= {
2195 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2199 null_debug_deflabel
,
2200 null_debug_directive
,
2201 null_debug_typevalue
,
2204 NULL
/*pragma list*/
2207 static const struct dfmt
* const macho32_df_arr
[2] =
2208 { &macho32_df_dwarf
, NULL
};
2210 const struct ofmt of_macho32
= {
2211 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2219 nasm_do_legacy_output
,
2233 static const struct macho_fmt macho64_fmt
= {
2238 MACHO_HEADER64_SIZE
,
2239 MACHO_SEGCMD64_SIZE
,
2240 MACHO_SECTCMD64_SIZE
,
2243 X86_64_RELOC_UNSIGNED
,
2244 X86_64_RELOC_SIGNED
,
2248 static void macho64_init(void)
2253 /* add special symbol for ..gotpcrel */
2254 macho_gotpcrel_sect
= seg_alloc() + 1;
2255 define_label("..gotpcrel", macho_gotpcrel_sect
, 0L, NULL
, false, false);
2258 static const struct dfmt macho64_df_dwarf
= {
2259 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2263 null_debug_deflabel
,
2264 null_debug_directive
,
2265 null_debug_typevalue
,
2268 NULL
/*pragma list*/
2271 static const struct dfmt
* const macho64_df_arr
[2] =
2272 { &macho64_df_dwarf
, NULL
};
2274 const struct ofmt of_macho64
= {
2275 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2283 nasm_do_legacy_output
,