1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2018 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * outmacho.c output routines for the Netwide Assembler to produce
36 * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
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 relocations numbers */
75 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
76 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
78 /* Our internal relocation types */
80 RL_ABS
, /* Absolute relocation */
81 RL_REL
, /* Relative relocation */
82 RL_TLV
, /* Thread local */
83 RL_BRANCH
, /* Relative direct branch */
84 RL_SUB
, /* X86_64_RELOC_SUBTRACT */
85 RL_GOT
, /* X86_64_RELOC_GOT */
86 RL_GOTLOAD
/* X86_64_RELOC_GOT_LOAD */
88 #define RL_MAX_32 RL_TLV
89 #define RL_MAX_64 RL_GOTLOAD
92 uint32_t ptrsize
; /* Pointer size in bytes */
93 uint32_t mh_magic
; /* Which magic number to use */
94 uint32_t cpu_type
; /* Which CPU type */
95 uint32_t lc_segment
; /* Which segment load command */
96 uint32_t header_size
; /* Header size */
97 uint32_t segcmd_size
; /* Segment command size */
98 uint32_t sectcmd_size
; /* Section command size */
99 uint32_t nlist_size
; /* Nlist (symbol) size */
100 enum reltype maxreltype
; /* Maximum entry in enum reltype permitted */
101 uint32_t reloc_abs
; /* Absolute relocation type */
102 uint32_t reloc_rel
; /* Relative relocation type */
103 uint32_t reloc_tlv
; /* Thread local relocation type */
104 bool forcesym
; /* Always use "external" (symbol-relative) relocations */
107 static struct macho_fmt fmt
;
109 static void fwriteptr(uint64_t data
, FILE * fp
)
111 fwriteaddr(data
, fmt
.ptrsize
, fp
);
115 /* nasm internal data */
116 struct section
*next
;
118 int32_t index
; /* Main section index */
119 int32_t subsection
; /* Current subsection index */
121 struct reloc
*relocs
;
122 struct rbtree
*syms
[2]; /* All/global symbols symbols in section */
124 bool by_name
; /* This section was specified by full MachO name */
125 char namestr
[34]; /* segment,section as a C string */
127 /* data that goes into the file */
128 char sectname
[16]; /* what this section is called */
129 char segname
[16]; /* segment this section will be in */
130 uint64_t addr
; /* in-memory address (subject to alignment) */
131 uint64_t size
; /* in-memory and -file size */
132 uint64_t offset
; /* in-file offset */
133 uint32_t pad
; /* padding bytes before section */
134 uint32_t nreloc
; /* relocation entry count */
135 uint32_t flags
; /* type and attributes (masked) */
136 uint32_t extreloc
; /* external relocations */
139 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
141 /* fake section for absolute symbols, *not* part of the section linked list */
142 static struct section absolute_sect
;
145 /* nasm internal data */
148 /* data that goes into the file */
149 int32_t addr
; /* op's offset in section */
150 uint32_t snum
:24, /* contains symbol index if
151 ** ext otherwise in-file
153 pcrel
:1, /* relative relocation */
154 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
155 ext
:1, /* external symbol referenced */
156 type
:4; /* reloc type */
160 /* nasm internal data */
161 struct rbtree symv
[2]; /* All/global symbol rbtrees; "key" contains the
163 struct symbol
*next
; /* next symbol in the list */
164 char *name
; /* name of this symbol */
165 int32_t initial_snum
; /* symbol number used above in reloc */
166 int32_t snum
; /* true snum for reloc */
168 /* data that goes into the file */
169 uint32_t strx
; /* string table index */
170 uint8_t type
; /* symbol type */
171 uint8_t sect
; /* NO_SECT or section number */
172 uint16_t desc
; /* for stab debugging, 0 for us */
175 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
177 static struct section
*sects
, **sectstail
, **sectstab
;
178 static struct symbol
*syms
, **symstail
;
179 static uint32_t nsyms
;
181 /* These variables are set by macho_layout_symbols() to organize
182 the symbol table and string table in order the dynamic linker
183 expects. They are then used in macho_write() to put out the
184 symbols and strings in that order.
186 The order of the symbol table is:
188 defined external symbols (sorted by name)
189 undefined external symbols (sorted by name)
191 The order of the string table is:
192 strings for external symbols
193 strings for local symbols
195 static uint32_t ilocalsym
= 0;
196 static uint32_t iextdefsym
= 0;
197 static uint32_t iundefsym
= 0;
198 static uint32_t nlocalsym
;
199 static uint32_t nextdefsym
;
200 static uint32_t nundefsym
;
201 static struct symbol
**extdefsyms
= NULL
;
202 static struct symbol
**undefsyms
= NULL
;
204 static struct RAA
*extsyms
;
205 static struct SAA
*strs
;
206 static uint32_t strslen
;
208 /* Global file information. This should be cleaned up into either
209 a structure or as function arguments. */
210 static uint32_t head_ncmds
= 0;
211 static uint32_t head_sizeofcmds
= 0;
212 static uint32_t head_flags
= 0;
213 static uint64_t seg_filesize
= 0;
214 static uint64_t seg_vmsize
= 0;
215 static uint32_t seg_nsects
= 0;
216 static uint64_t rel_padcnt
= 0;
219 * Functions for handling fixed-length zero-padded string
220 * fields, that may or may not be null-terminated.
223 /* Copy a string into a zero-padded fixed-length field */
224 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
226 /* Compare a fixed-length field with a string */
227 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
229 #define alignint32_t(x) \
230 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
232 #define alignint64_t(x) \
233 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
235 #define alignptr(x) \
236 ALIGN(x, fmt.ptrsize) /* align x to output format width */
238 static struct hash_table section_by_name
;
239 static struct RAA
*section_by_index
;
241 static struct section
* never_null
242 find_or_add_section(const char *segname
, const char *sectname
)
244 struct hash_insert hi
;
249 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
251 sp
= hash_find(§ion_by_name
, sect
, &hi
);
253 return (struct section
*)(*sp
);
255 s
= nasm_zalloc(sizeof *s
);
256 xstrncpy(s
->segname
, segname
);
257 xstrncpy(s
->sectname
, sectname
);
258 xstrncpy(s
->namestr
, sect
);
259 hash_add(&hi
, s
->namestr
, s
);
261 s
->index
= s
->subsection
= seg_alloc();
262 section_by_index
= raa_write_ptr(section_by_index
, s
->index
>> 1, s
);
267 static inline bool is_new_section(const struct section
*s
)
272 static struct section
*get_section_by_name(const char *segname
,
273 const char *sectname
)
278 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
280 sp
= hash_find(§ion_by_name
, sect
, NULL
);
281 return sp
? (struct section
*)(*sp
) : NULL
;
284 static struct section
*get_section_by_index(int32_t index
)
286 if (index
< 0 || index
>= SEG_ABS
|| (index
& 1))
289 return raa_read_ptr(section_by_index
, index
>> 1);
293 struct dir_list
*next
;
294 struct dir_list
*last
;
295 const char *dir_name
;
300 struct file_list
*next
;
301 struct file_list
*last
;
302 const char *file_name
;
304 struct dir_list
*dir
;
307 struct dw_sect_list
{
313 struct dw_sect_list
*next
;
314 struct dw_sect_list
*last
;
317 struct section_info
{
322 #define DW_LN_BASE (-5)
323 #define DW_LN_RANGE 14
324 #define DW_OPCODE_BASE 13
325 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
326 #define DW_MAX_SP_OPCODE 256
328 static struct file_list
*dw_head_file
= 0, *dw_cur_file
= 0, **dw_last_file_next
= NULL
;
329 static struct dir_list
*dw_head_dir
= 0, **dw_last_dir_next
= NULL
;
330 static struct dw_sect_list
*dw_head_sect
= 0, *dw_cur_sect
= 0, *dw_last_sect
= 0;
331 static uint32_t cur_line
= 0, dw_num_files
= 0, dw_num_dirs
= 0, dw_num_sects
= 0;
332 static bool dbg_immcall
= false;
333 static const char *module_name
= NULL
;
336 * Special section numbers which are used to define Mach-O special
337 * symbols, which can be used with WRT to provide PIC relocation
340 static int32_t macho_tlvp_sect
;
341 static int32_t macho_gotpcrel_sect
;
343 static void macho_init(void)
345 module_name
= inname
;
349 /* Fake section for absolute symbols */
350 absolute_sect
.index
= NO_SEG
;
359 extsyms
= raa_init();
362 section_by_index
= raa_init();
364 /* string table starts with a zero byte so index 0 is an empty string */
365 saa_wbytes(strs
, zero_buffer
, 1);
368 /* add special symbol for TLVP */
369 macho_tlvp_sect
= seg_alloc() + 1;
370 backend_label("..tlvp", macho_tlvp_sect
, 0L);
373 static void sect_write(struct section
*sect
,
374 const uint8_t *data
, uint32_t len
)
376 saa_wbytes(sect
->data
, data
, len
);
381 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
383 static struct symbol
*macho_find_sym(struct section
*s
, uint64_t offset
,
384 bool global
, bool exact
)
388 srb
= rb_search(s
->syms
[global
], offset
);
390 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
391 nasm_error(ERR_NONFATAL
, "unable to find a suitable%s%s symbol"
392 " for this reference",
393 global
? " global" : "",
394 s
== &absolute_sect
? " absolute " : "");
398 return container_of(srb
- global
, struct symbol
, symv
);
401 static int64_t add_reloc(struct section
*sect
, int32_t section
,
403 enum reltype reltype
, int bytes
)
410 /* Double check this is a valid relocation type for this platform */
411 nasm_assert(reltype
<= fmt
.maxreltype
);
413 /* the current end of the section will be the symbol's address for
414 ** now, might have to be fixed by macho_fixup_relocs() later on. make
415 ** sure we don't make the symbol scattered by setting the highest
416 ** bit by accident */
417 r
= nasm_malloc(sizeof(struct reloc
));
418 r
->addr
= sect
->size
& ~R_SCATTERED
;
422 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
423 r
->length
= ilog2_32(bytes
);
425 /* set default relocation values */
426 r
->type
= fmt
.reloc_abs
;
430 s
= get_section_by_index(section
);
431 fi
= s
? s
->fileindex
: NO_SECT
;
433 /* absolute relocation */
436 if (section
== NO_SEG
) {
437 /* absolute (can this even happen?) */
439 } else if (fi
== NO_SECT
) {
441 r
->snum
= raa_read(extsyms
, section
);
451 r
->type
= fmt
.reloc_rel
;
453 if (section
== NO_SEG
) {
454 /* may optionally be converted below by fmt.forcesym */
456 } else if (fi
== NO_SECT
) {
459 r
->snum
= raa_read(extsyms
, section
);
460 if (reltype
== RL_BRANCH
)
461 r
->type
= X86_64_RELOC_BRANCH
;
466 if (reltype
== RL_BRANCH
)
467 r
->type
= X86_64_RELOC_BRANCH
;
471 case RL_SUB
: /* obsolete */
472 nasm_warn(WARN_OTHER
, "relcation with subtraction"
473 "becomes to be obsolete");
475 r
->type
= X86_64_RELOC_SUBTRACTOR
;
479 r
->type
= X86_64_RELOC_GOT
;
483 r
->type
= X86_64_RELOC_GOT_LOAD
;
487 r
->type
= fmt
.reloc_tlv
;
491 r
->pcrel
= (fmt
.ptrsize
== 8 ? 1 : 0);
492 if (section
== NO_SEG
) {
493 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
495 } else if (fi
== NO_SECT
) {
497 r
->snum
= raa_read(extsyms
, section
);
499 /* internal - GOTPCREL doesn't need to be in global */
500 struct symbol
*sym
= macho_find_sym(s
, offset
,
501 false, /* reltype != RL_TLV */
504 nasm_error(ERR_NONFATAL
, "Symbol for WRT not found");
508 adjust
-= sym
->symv
[0].key
;
509 r
->snum
= sym
->initial_snum
;
515 * For 64-bit Mach-O, force a symbol reference if at all possible
516 * Allow for r->snum == R_ABS by searching absolute_sect
518 if (!r
->ext
&& fmt
.forcesym
) {
519 struct symbol
*sym
= macho_find_sym(s
? s
: &absolute_sect
,
520 offset
, false, false);
522 adjust
-= sym
->symv
[0].key
;
523 r
->snum
= sym
->initial_snum
;
529 adjust
+= ((r
->ext
&& fmt
.ptrsize
== 8) ? bytes
: -(int64_t)sect
->size
);
531 /* NeXT as puts relocs in reversed order (address-wise) into the
532 ** files, so we do the same, doesn't seem to make much of a
533 ** difference either way */
534 r
->next
= sect
->relocs
;
547 static void macho_output(int32_t secto
, const void *data
,
548 enum out_type type
, uint64_t size
,
549 int32_t section
, int32_t wrt
)
552 int64_t addr
, offset
;
553 uint8_t mydata
[16], *p
;
555 enum reltype reltype
;
557 s
= get_section_by_index(secto
);
559 nasm_warn(WARN_OTHER
, "attempt to assemble code in"
560 " section %d: defaulting to `.text'", secto
);
561 s
= get_section_by_name("__TEXT", "__text");
563 /* should never happen */
565 nasm_panic("text section not found");
568 /* debug code generation only for sections tagged with
569 * instruction attribute */
570 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
572 struct section_info sinfo
;
573 sinfo
.size
= s
->size
;
575 dfmt
->debug_output(0, &sinfo
);
578 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
580 if (is_bss
&& type
!= OUT_RESERVE
) {
581 nasm_warn(WARN_OTHER
, "attempt to initialize memory in "
582 "BSS section: ignored");
584 nasm_warn(WARN_OTHER
, "section size may be negative"
585 "with address symbols");
586 s
->size
+= realsize(type
, size
);
590 memset(mydata
, 0, sizeof(mydata
));
595 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
596 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
598 sect_write(s
, NULL
, size
);
605 sect_write(s
, data
, size
);
610 int asize
= abs((int)size
);
612 addr
= *(int64_t *)data
;
613 if (section
!= NO_SEG
) {
615 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
616 " section base references");
617 } else if (wrt
== NO_SEG
) {
618 if (fmt
.ptrsize
== 8 && asize
!= 8) {
619 nasm_error(ERR_NONFATAL
,
620 "Mach-O 64-bit format does not support"
621 " 32-bit absolute addresses");
623 addr
+= add_reloc(s
, section
, addr
, RL_ABS
, asize
);
625 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
!= 8 &&
626 asize
== (int) fmt
.ptrsize
) {
627 addr
+= add_reloc(s
, section
, addr
, RL_TLV
, asize
);
629 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
635 WRITEADDR(p
, addr
, asize
);
636 sect_write(s
, mydata
, asize
);
644 offset
= *(int64_t *)data
;
645 addr
= offset
- size
;
647 if (section
!= NO_SEG
&& section
% 2) {
648 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
649 " section base references");
650 } else if (fmt
.ptrsize
== 8) {
651 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
652 " Macho-O relocation [2]");
653 } else if (wrt
!= NO_SEG
) {
654 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
656 wrt
= NO_SEG
; /* we can at least _try_ to continue */
658 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
,
659 type
== OUT_REL1ADR
? 1 : 2);
663 sect_write(s
, mydata
, type
== OUT_REL1ADR
? 1 : 2);
670 offset
= *(int64_t *)data
;
671 addr
= offset
- size
;
674 if (section
!= NO_SEG
&& section
% 2) {
675 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
676 " section base references");
677 } else if (wrt
== NO_SEG
) {
678 if (fmt
.ptrsize
== 8 &&
679 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
682 opcode
[0] = opcode
[1] = 0;
684 /* HACK: Retrieve instruction opcode */
685 if (likely(s
->data
->datalen
>= 2)) {
686 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
687 } else if (s
->data
->datalen
== 1) {
688 saa_fread(s
->data
, 0, opcode
+1, 1);
691 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
692 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
693 /* Direct call, jmp, or jcc */
697 } else if (wrt
== macho_gotpcrel_sect
) {
700 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
701 s
->data
->datalen
>= 3) {
704 /* HACK: Retrieve instruction opcode */
705 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
706 if ((gotload
[0] & 0xf8) == 0x48 &&
707 gotload
[1] == 0x8b &&
708 (gotload
[2] & 0307) == 0005) {
709 /* movq <reg>,[rel sym wrt ..gotpcrel] */
710 reltype
= RL_GOTLOAD
;
713 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
== 8) {
716 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
718 /* continue with RL_REL */
721 addr
+= add_reloc(s
, section
, offset
, reltype
,
722 type
== OUT_REL4ADR
? 4 : 8);
724 sect_write(s
, mydata
, type
== OUT_REL4ADR
? 4 : 8);
728 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
733 #define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
734 #define NO_TYPE S_NASM_TYPE_MASK
736 /* Translation table from traditional Unix section names to Mach-O */
737 static const struct macho_known_section
{
738 const char *nasmsect
;
740 const char *sectname
;
741 const uint32_t flags
;
742 } known_sections
[] = {
743 { ".text", "__TEXT", "__text", S_CODE
},
744 { ".data", "__DATA", "__data", S_REGULAR
},
745 { ".rodata", "__DATA", "__const", S_REGULAR
},
746 { ".bss", "__DATA", "__bss", S_ZEROFILL
},
747 { ".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
748 { ".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
749 { ".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
750 { ".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
753 /* Section type or attribute directives */
754 static const struct macho_known_section_attr
{
758 { "data", S_REGULAR
},
760 { "mixed", S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
},
761 { "bss", S_ZEROFILL
},
762 { "zerofill", S_ZEROFILL
},
763 { "no_dead_strip", NO_TYPE
| S_ATTR_NO_DEAD_STRIP
},
764 { "live_support", NO_TYPE
| S_ATTR_LIVE_SUPPORT
},
765 { "strip_static_syms", NO_TYPE
| S_ATTR_STRIP_STATIC_SYMS
},
766 { "debug", NO_TYPE
| S_ATTR_DEBUG
},
770 static const struct macho_known_section
*
771 lookup_known_section(const char *name
, bool by_sectname
)
775 if (name
&& name
[0]) {
776 for (i
= 0; i
< ARRAY_SIZE(known_sections
); i
++) {
777 const char *p
= by_sectname
?
778 known_sections
[i
].sectname
:
779 known_sections
[i
].nasmsect
;
780 if (!strcmp(name
, p
))
781 return &known_sections
[i
];
788 static int32_t macho_section(char *name
, int *bits
)
790 const struct macho_known_section
*known_section
;
791 const struct macho_known_section_attr
*sa
;
792 char *sectionAttributes
;
794 const char *section
, *segment
;
796 char *currentAttribute
;
801 /* Default to the appropriate number of bits. */
803 *bits
= fmt
.ptrsize
<< 3;
805 sectionAttributes
= NULL
;
807 sectionAttributes
= name
;
808 name
= nasm_strsep(§ionAttributes
, " \t");
811 section
= segment
= NULL
;
814 comma
= strchr(name
, ',');
822 len
= strlen(segment
);
824 nasm_error(ERR_NONFATAL
, "empty segment name\n");
825 } else if (len
> 16) {
826 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
829 len
= strlen(section
);
831 nasm_error(ERR_NONFATAL
, "empty section name\n");
832 } else if (len
> 16) {
833 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
836 known_section
= lookup_known_section(section
, true);
838 flags
= known_section
->flags
;
842 known_section
= lookup_known_section(name
, false);
843 if (!known_section
) {
844 nasm_error(ERR_NONFATAL
, "unknown section name %s\n", name
);
848 segment
= known_section
->segname
;
849 section
= known_section
->sectname
;
850 flags
= known_section
->flags
;
853 /* try to find section with that name, or create it */
854 s
= find_or_add_section(segment
, section
);
855 new_seg
= is_new_section(s
);
857 /* initialize it if it is a brand new section */
860 sectstail
= &s
->next
;
862 s
->data
= saa_init(1L);
863 s
->fileindex
= ++seg_nsects
;
875 *comma
= ','; /* Restore comma */
877 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
881 while (sectionAttributes
&&
882 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
883 if (!*currentAttribute
)
886 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
888 int newAlignment
, value
;
890 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
891 newAlignment
= alignlog2_32(value
);
894 nasm_error(ERR_NONFATAL
,
895 "unknown or missing alignment value \"%s\" "
896 "specified for section \"%s\"",
897 currentAttribute
+ 6,
899 } else if (0 > newAlignment
) {
900 nasm_error(ERR_NONFATAL
,
901 "alignment of %d (for section \"%s\") is not "
907 if (s
->align
< newAlignment
)
908 s
->align
= newAlignment
;
910 for (sa
= sect_attribs
; sa
->name
; sa
++) {
911 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
912 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
913 flags
= (flags
& ~S_NASM_TYPE_MASK
)
914 | (sa
->flags
& S_NASM_TYPE_MASK
);
916 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
922 nasm_error(ERR_NONFATAL
,
923 "unknown section attribute %s for section %s",
924 currentAttribute
, name
);
929 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
930 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
931 nasm_error(ERR_NONFATAL
,
932 "inconsistent section attributes for section %s\n",
935 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
938 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
941 return s
->subsection
;
944 static int32_t macho_herelabel(const char *name
, enum label_type type
,
945 int32_t section
, int32_t *subsection
,
952 if (!(head_flags
& MH_SUBSECTIONS_VIA_SYMBOLS
))
955 /* No subsection only for local labels */
956 if (type
== LBL_LOCAL
)
959 s
= get_section_by_index(section
);
963 subsec
= *subsection
;
964 if (subsec
== NO_SEG
) {
965 /* Allocate a new subsection index */
966 subsec
= *subsection
= seg_alloc();
967 section_by_index
= raa_write_ptr(section_by_index
, subsec
>> 1, s
);
970 s
->subsection
= subsec
;
971 *copyoffset
= true; /* Maintain previous offset */
975 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
976 int is_global
, char *special
)
980 bool special_used
= false;
982 #if defined(DEBUG) && DEBUG>2
983 nasm_error(ERR_DEBUG
,
984 " macho_symdef: %s, pass=%"PRId64
" type %s, sec=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
985 name
, pass_count(), pass_types
[pass_type()],
986 section
, offset
, is_global
, special
);
989 if (is_global
== 3) {
991 int n
= strcspn(special
, " \t");
993 if (!nasm_strnicmp(special
, "private_extern", n
)) {
994 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
995 if (!strcmp(name
, sym
->name
)) {
996 if (sym
->type
& N_PEXT
)
997 return; /* nothing to be done */
1004 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
1005 "(yet) support forward reference fixups.");
1009 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1011 * This is a NASM special symbol. We never allow it into
1012 * the Macho-O symbol table, even if it's a valid one. If it
1013 * _isn't_ a valid one, we should barf immediately.
1015 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1016 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1020 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1022 symstail
= &sym
->next
;
1025 sym
->strx
= strslen
;
1028 sym
->symv
[0].key
= offset
;
1029 sym
->symv
[1].key
= offset
;
1030 sym
->initial_snum
= -1;
1032 /* external and common symbols get N_EXT */
1033 if (is_global
!= 0) {
1036 if (is_global
== 1) {
1037 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1039 int n
= strcspn(special
, " \t");
1041 if (!nasm_strnicmp(special
, "private_extern", n
))
1042 sym
->type
|= N_PEXT
;
1044 nasm_error(ERR_NONFATAL
, "unrecognised symbol type `%.*s'", n
, special
);
1046 special_used
= true;
1049 /* track the initially allocated symbol number for use in future fix-ups */
1050 sym
->initial_snum
= nsyms
;
1052 if (section
== NO_SEG
) {
1053 /* symbols in no section get absolute */
1055 sym
->sect
= NO_SECT
;
1059 s
= get_section_by_index(section
);
1061 sym
->type
|= N_SECT
;
1063 /* get the in-file index of the section the symbol was defined in */
1064 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1067 /* remember symbol number of references to external
1068 ** symbols, this works because every external symbol gets
1069 ** its own section number allocated internally by nasm and
1070 ** can so be used as a key */
1071 extsyms
= raa_write(extsyms
, section
, nsyms
);
1073 switch (is_global
) {
1076 /* there isn't actually a difference between global
1077 ** and common symbols, both even have their size in
1078 ** sym->symv[0].key */
1083 /* give an error on unfound section if it's not an
1084 ** external or common symbol (assemble_file() does a
1085 ** seg_alloc() on every call for them) */
1086 nasm_panic("in-file index for section %d not found, is_global = %d", section
, is_global
);
1093 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1095 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1100 if (special
&& !special_used
)
1101 nasm_error(ERR_NONFATAL
, "no special symbol features supported here");
1104 static void macho_sectalign(int32_t seg
, unsigned int value
)
1109 nasm_assert(!(seg
& 1));
1111 s
= get_section_by_index(seg
);
1113 if (!s
|| !is_power2(value
))
1116 align
= alignlog2_32(value
);
1117 if (s
->align
< align
)
1121 extern macros_t macho_stdmac
[];
1123 /* Comparison function for qsort symbol layout. */
1124 static int layout_compare (const struct symbol
**s1
,
1125 const struct symbol
**s2
)
1127 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1130 /* The native assembler does a few things in a similar function
1132 * Remove temporary labels
1133 * Sort symbols according to local, external, undefined (by name)
1134 * Order the string table
1136 We do not remove temporary labels right now.
1138 numsyms is the total number of symbols we have. strtabsize is the
1139 number entries in the string table. */
1141 static void macho_layout_symbols (uint32_t *numsyms
,
1142 uint32_t *strtabsize
)
1144 struct symbol
*sym
, **symp
;
1148 *strtabsize
= sizeof (char);
1152 while ((sym
= *symp
)) {
1153 /* Undefined symbols are now external. */
1154 if (sym
->type
== N_UNDF
)
1157 if ((sym
->type
& N_EXT
) == 0) {
1158 sym
->snum
= *numsyms
;
1159 *numsyms
= *numsyms
+ 1;
1163 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1169 /* If we handle debug info we'll want
1170 to check for it here instead of just
1171 adding the symbol to the string table. */
1172 sym
->strx
= *strtabsize
;
1173 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1174 *strtabsize
+= strlen(sym
->name
) + 1;
1176 symp
= &(sym
->next
);
1179 /* Next, sort the symbols. Most of this code is a direct translation from
1180 the Apple cctools symbol layout. We need to keep compatibility with that. */
1181 /* Set the indexes for symbol groups into the symbol table */
1183 iextdefsym
= nlocalsym
;
1184 iundefsym
= nlocalsym
+ nextdefsym
;
1186 /* allocate arrays for sorting externals by name */
1187 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1188 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1195 while ((sym
= *symp
)) {
1197 if((sym
->type
& N_EXT
) == 0) {
1198 sym
->strx
= *strtabsize
;
1199 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1200 *strtabsize
+= strlen(sym
->name
) + 1;
1203 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1204 extdefsyms
[i
++] = sym
;
1206 undefsyms
[j
++] = sym
;
1209 symp
= &(sym
->next
);
1212 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1213 (int (*)(const void *, const void *))layout_compare
);
1214 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1215 (int (*)(const void *, const void *))layout_compare
);
1217 for(i
= 0; i
< nextdefsym
; i
++) {
1218 extdefsyms
[i
]->snum
= *numsyms
;
1221 for(j
= 0; j
< nundefsym
; j
++) {
1222 undefsyms
[j
]->snum
= *numsyms
;
1227 /* Calculate some values we'll need for writing later. */
1229 static void macho_calculate_sizes (void)
1234 /* count sections and calculate in-memory and in-file offsets */
1235 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1238 /* recalculate segment address based on alignment and vm size */
1239 s
->addr
= seg_vmsize
;
1241 /* we need section alignment to calculate final section address */
1243 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1245 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1248 seg_vmsize
= newaddr
+ s
->size
;
1250 /* zerofill sections aren't actually written to the file */
1251 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1253 * LLVM/Xcode as always aligns the section data to 4
1254 * bytes; there is a comment in the LLVM source code that
1255 * perhaps aligning to pointer size would be better.
1257 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1258 s
->offset
= seg_filesize
+ s
->pad
;
1259 seg_filesize
+= s
->size
+ s
->pad
;
1261 /* filesize and vmsize needs to be aligned */
1262 seg_vmsize
+= s
->pad
;
1266 /* calculate size of all headers, load commands and sections to
1267 ** get a pointer to the start of all the raw data */
1268 if (seg_nsects
> 0) {
1270 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1275 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1278 if (seg_nsects
> MAX_SECT
) {
1279 nasm_fatal("MachO output is limited to %d sections\n",
1283 /* Create a table of sections by file index to avoid linear search */
1284 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1285 sectstab
[NO_SECT
] = &absolute_sect
;
1286 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1290 /* Write out the header information for the file. */
1292 static void macho_write_header (void)
1294 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1295 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1296 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1297 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1298 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1299 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1300 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1301 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1304 /* Write out the segment load command at offset. */
1306 static uint32_t macho_write_segment (uint64_t offset
)
1308 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1309 uint32_t s_reloff
= 0;
1312 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1314 /* size of load command including section load commands */
1315 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1318 /* in an MH_OBJECT file all sections are in one unnamed (name
1319 ** all zeros) segment */
1320 fwritezero(16, ofile
);
1321 fwriteptr(0, ofile
); /* in-memory offset */
1322 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1323 fwriteptr(offset
, ofile
); /* in-file offset to data */
1324 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1325 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1326 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1327 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1328 fwriteint32_t(0, ofile
); /* no flags */
1330 /* emit section headers */
1331 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1333 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1334 s
->flags
|= S_ATTR_LOC_RELOC
;
1336 s
->flags
|= S_ATTR_EXT_RELOC
;
1337 } else if (!xstrncmp(s
->segname
, "__DATA") &&
1338 !xstrncmp(s
->sectname
, "__const") &&
1340 !get_section_by_name("__TEXT", "__const")) {
1342 * The MachO equivalent to .rodata can be either
1343 * __DATA,__const or __TEXT,__const; the latter only if
1344 * there are no relocations. However, when mixed it is
1345 * better to specify the segments explicitly.
1347 xstrncpy(s
->segname
, "__TEXT");
1350 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1351 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1352 fwriteptr(s
->addr
, ofile
);
1353 fwriteptr(s
->size
, ofile
);
1355 /* dummy data for zerofill sections or proper values */
1356 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1357 nasm_assert(s
->pad
!= (uint32_t)-1);
1359 fwriteint32_t(offset
, ofile
);
1361 /* Write out section alignment, as a power of two.
1362 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1363 fwriteint32_t(s
->align
, ofile
);
1364 /* To be compatible with cctools as we emit
1365 a zero reloff if we have no relocations. */
1366 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1367 fwriteint32_t(s
->nreloc
, ofile
);
1369 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1371 fwriteint32_t(0, ofile
);
1372 fwriteint32_t(s
->align
, ofile
);
1373 fwriteint32_t(0, ofile
);
1374 fwriteint32_t(0, ofile
);
1377 fwriteint32_t(s
->flags
, ofile
); /* flags */
1378 fwriteint32_t(0, ofile
); /* reserved */
1379 fwriteptr(0, ofile
); /* reserved */
1382 rel_padcnt
= rel_base
- offset
;
1383 offset
= rel_base
+ s_reloff
;
1388 /* For a given chain of relocs r, write out the entire relocation
1389 chain to the object file. */
1391 static void macho_write_relocs (struct reloc
*r
)
1396 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1399 word2
|= r
->pcrel
<< 24;
1400 word2
|= r
->length
<< 25;
1401 word2
|= r
->ext
<< 27;
1402 word2
|= r
->type
<< 28;
1403 fwriteint32_t(word2
, ofile
); /* reloc data */
1408 /* Write out the section data. */
1409 static void macho_write_section (void)
1421 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1422 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1425 /* Like a.out Mach-O references things in the data or bss
1426 * sections by addresses which are actually relative to the
1427 * start of the _text_ section, in the _file_. See outaout.c
1428 * for more information. */
1429 saa_rewind(s
->data
);
1430 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1431 len
= (uint32_t)1 << r
->length
;
1432 if (len
> 4) /* Can this ever be an issue?! */
1435 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1437 /* get offset based on relocation type */
1438 #ifdef WORDS_LITTLEENDIAN
1442 l
+= ((int64_t)blk
.buf
[1]) << 8;
1443 l
+= ((int64_t)blk
.buf
[2]) << 16;
1444 l
+= ((int64_t)blk
.buf
[3]) << 24;
1445 l
+= ((int64_t)blk
.buf
[4]) << 32;
1446 l
+= ((int64_t)blk
.buf
[5]) << 40;
1447 l
+= ((int64_t)blk
.buf
[6]) << 48;
1448 l
+= ((int64_t)blk
.buf
[7]) << 56;
1451 /* If the relocation is internal add to the current section
1452 offset. Otherwise the only value we need is the symbol
1453 offset which we already have. The linker takes care
1454 of the rest of the address. */
1456 /* generate final address by section address and offset */
1457 nasm_assert(r
->snum
<= seg_nsects
);
1458 l
+= sectstab
[r
->snum
]->addr
;
1461 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1465 /* write new offset back */
1468 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1471 /* dump the section data to file */
1472 fwritezero(s
->pad
, ofile
);
1473 saa_fpwrite(s
->data
, ofile
);
1476 /* pad last section up to reloc entries on pointer boundary */
1477 fwritezero(rel_padcnt
, ofile
);
1479 /* emit relocation entries */
1480 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1481 macho_write_relocs (s
->relocs
);
1484 /* Write out the symbol table. We should already have sorted this
1486 static void macho_write_symtab (void)
1491 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1493 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1494 if ((sym
->type
& N_EXT
) == 0) {
1495 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1496 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1497 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1498 fwriteint16_t(sym
->desc
, ofile
); /* description */
1500 /* Fix up the symbol value now that we know the final section
1502 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1503 nasm_assert(sym
->sect
<= seg_nsects
);
1504 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1507 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1511 for (i
= 0; i
< nextdefsym
; i
++) {
1512 sym
= extdefsyms
[i
];
1513 fwriteint32_t(sym
->strx
, ofile
);
1514 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1515 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1516 fwriteint16_t(sym
->desc
, ofile
); /* description */
1518 /* Fix up the symbol value now that we know the final section
1520 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1521 nasm_assert(sym
->sect
<= seg_nsects
);
1522 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1525 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1528 for (i
= 0; i
< nundefsym
; i
++) {
1530 fwriteint32_t(sym
->strx
, ofile
);
1531 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1532 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1533 fwriteint16_t(sym
->desc
, ofile
); /* description */
1535 /* Fix up the symbol value now that we know the final section
1537 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1538 nasm_assert(sym
->sect
<= seg_nsects
);
1539 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1542 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1547 /* Fixup the snum in the relocation entries, we should be
1548 doing this only for externally referenced symbols. */
1549 static void macho_fixup_relocs (struct reloc
*r
)
1555 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1556 if (sym
->initial_snum
== r
->snum
) {
1557 r
->snum
= sym
->snum
;
1566 /* Write out the object file. */
1568 static void macho_write (void)
1570 uint64_t offset
= 0;
1572 /* mach-o object file structure:
1578 ** uint32_t mach file type
1579 ** uint32_t number of load commands
1580 ** uint32_t size of all load commands
1581 ** (includes section struct size of segment command)
1585 ** uint32_t command type == LC_SEGMENT[_64]
1586 ** uint32_t size of load command
1587 ** (including section load commands)
1588 ** char[16] segment name
1589 ** pointer in-memory offset
1590 ** pointer in-memory size
1591 ** pointer in-file offset to data area
1592 ** pointer in-file size
1593 ** (in-memory size excluding zerofill sections)
1594 ** int maximum vm protection
1595 ** int initial vm protection
1596 ** uint32_t number of sections
1600 ** char[16] section name
1601 ** char[16] segment name
1602 ** pointer in-memory offset
1603 ** pointer in-memory size
1604 ** uint32_t in-file offset
1605 ** uint32_t alignment
1606 ** (irrelevant in MH_OBJECT)
1607 ** uint32_t in-file offset of relocation entires
1608 ** uint32_t number of relocations
1610 ** uint32_t reserved
1611 ** uint32_t reserved
1613 ** symbol table command
1614 ** uint32_t command type == LC_SYMTAB
1615 ** uint32_t size of load command
1616 ** uint32_t symbol table offset
1617 ** uint32_t number of symbol table entries
1618 ** uint32_t string table offset
1619 ** uint32_t string table size
1623 ** padding to pointer boundary
1625 ** relocation data (struct reloc)
1627 ** uint data (symbolnum, pcrel, length, extern, type)
1629 ** symbol table data (struct nlist)
1630 ** int32_t string table entry number
1632 ** (extern, absolute, defined in section)
1634 ** (0 for global symbols, section number of definition (>= 1, <=
1635 ** 254) for local symbols, size of variable for common symbols
1636 ** [type == extern])
1637 ** int16_t description
1638 ** (for stab debugging format)
1639 ** pointer value (i.e. file offset) of symbol or stab offset
1641 ** string table data
1642 ** list of null-terminated strings
1645 /* Emit the Mach-O header. */
1646 macho_write_header();
1648 offset
= fmt
.header_size
+ head_sizeofcmds
;
1650 /* emit the segment load command */
1652 offset
= macho_write_segment (offset
);
1654 nasm_warn(WARN_OTHER
, "no sections?");
1657 /* write out symbol command */
1658 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1659 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1660 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1661 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1663 offset
+= nsyms
* fmt
.nlist_size
;
1664 fwriteint32_t(offset
, ofile
); /* string table offset */
1665 fwriteint32_t(strslen
, ofile
); /* string table size */
1668 /* emit section data */
1670 macho_write_section ();
1672 /* emit symbol table if we have symbols */
1674 macho_write_symtab ();
1676 /* we don't need to pad here, we are already aligned */
1678 /* emit string table */
1679 saa_fpwrite(strs
, ofile
);
1681 /* We do quite a bit here, starting with finalizing all of the data
1682 for the object file, writing, and then freeing all of the data from
1685 static void macho_cleanup(void)
1693 /* Sort all symbols. */
1694 macho_layout_symbols (&nsyms
, &strslen
);
1696 /* Fixup relocation entries */
1697 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1698 macho_fixup_relocs (s
->relocs
);
1701 /* First calculate and finalize needed values. */
1702 macho_calculate_sizes();
1705 /* free up everything */
1706 while (sects
->next
) {
1708 sects
= sects
->next
;
1711 while (s
->relocs
!= NULL
) {
1713 s
->relocs
= s
->relocs
->next
;
1730 nasm_free(extdefsyms
);
1731 nasm_free(undefsyms
);
1732 nasm_free(sectstab
);
1733 raa_free(section_by_index
);
1734 hash_free(§ion_by_name
);
1737 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1743 if (lookup_label(label
, &nasm_seg
, &offset
) == LBL_none
) {
1744 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1748 s
= get_section_by_index(nasm_seg
);
1750 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1759 * Mark a symbol for no dead stripping
1761 static enum directive_result
macho_no_dead_strip(const char *labels
)
1765 enum directive_result rv
= DIRR_ERROR
;
1767 p
= s
= nasm_strdup(labels
);
1769 ep
= nasm_skip_identifier(p
);
1771 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1775 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1776 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1780 if (!pass_first()) {
1781 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1785 p
= nasm_skip_spaces(ep
);
1787 p
= nasm_skip_spaces(++p
);
1800 static enum directive_result
1801 macho_pragma(const struct pragma
*pragma
)
1803 switch (pragma
->opcode
) {
1804 case D_SUBSECTIONS_VIA_SYMBOLS
:
1806 return DIRR_BADPARAM
;
1809 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1811 /* Jmp-match optimization conflicts */
1812 optimizing
.flag
|= OPTIM_DISABLE_JMP_MATCH
;
1816 case D_NO_DEAD_STRIP
:
1817 return macho_no_dead_strip(pragma
->tail
);
1820 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1824 static const struct pragma_facility macho_pragma_list
[] = {
1825 { "macho", macho_pragma
},
1826 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1829 static void macho_dbg_generate(void)
1831 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1832 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1833 struct section
*p_section
= NULL
;
1834 /* calculated at debug_str and referenced at debug_info */
1835 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1837 /* debug section defines */
1840 macho_section(".debug_abbrev", &bits
);
1841 macho_section(".debug_info", &bits
);
1842 macho_section(".debug_line", &bits
);
1843 macho_section(".debug_str", &bits
);
1846 /* dw section walk to find high_addr and total_len */
1848 struct dw_sect_list
*p_sect
;
1850 list_for_each(p_sect
, dw_head_sect
) {
1851 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1852 struct SAA
*p_linep
= p_sect
->psaa
;
1854 saa_write8(p_linep
, 2); /* std op 2 */
1855 saa_write8(p_linep
, offset
- p_sect
->offset
);
1856 saa_write8(p_linep
, DW_LNS_extended_op
);
1857 saa_write8(p_linep
, 1); /* operand length */
1858 saa_write8(p_linep
, DW_LNE_end_sequence
);
1860 total_len
+= p_linep
->datalen
;
1861 high_addr
+= offset
;
1867 struct dw_sect_list
*p_sect
;
1868 size_t linep_off
, buf_size
;
1869 struct SAA
*p_lines
= saa_init(1L);
1870 struct dir_list
*p_dir
;
1871 struct file_list
*p_file
;
1873 p_section
= get_section_by_name("__DWARF", "__debug_line");
1874 nasm_assert(p_section
!= NULL
);
1876 saa_write8(p_lines
, 1); /* minimum instruction length */
1877 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1878 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1879 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1880 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1881 saa_write8(p_lines
, 0); /* std opcode 1 length */
1882 saa_write8(p_lines
, 1); /* std opcode 2 length */
1883 saa_write8(p_lines
, 1); /* std opcode 3 length */
1884 saa_write8(p_lines
, 1); /* std opcode 4 length */
1885 saa_write8(p_lines
, 1); /* std opcode 5 length */
1886 saa_write8(p_lines
, 0); /* std opcode 6 length */
1887 saa_write8(p_lines
, 0); /* std opcode 7 length */
1888 saa_write8(p_lines
, 0); /* std opcode 8 length */
1889 saa_write8(p_lines
, 1); /* std opcode 9 length */
1890 saa_write8(p_lines
, 0); /* std opcode 10 length */
1891 saa_write8(p_lines
, 0); /* std opcode 11 length */
1892 saa_write8(p_lines
, 1); /* std opcode 12 length */
1893 list_for_each(p_dir
, dw_head_dir
) {
1894 saa_wcstring(p_lines
, p_dir
->dir_name
);
1896 saa_write8(p_lines
, 0); /* end of table */
1898 list_for_each(p_file
, dw_head_file
) {
1899 saa_wcstring(p_lines
, p_file
->file_name
);
1900 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1901 saa_write8(p_lines
, 0); /* time */
1902 saa_write8(p_lines
, 0); /* size */
1904 saa_write8(p_lines
, 0); /* end of table */
1906 linep_off
= p_lines
->datalen
;
1907 /* 10 bytes for initial & prolong length, and dwarf version info */
1908 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1909 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1911 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1912 WRITESHORT(p_buf
, 2); /* dwarf version */
1913 WRITELONG(p_buf
, linep_off
); /* prolong length */
1915 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1919 list_for_each(p_sect
, dw_head_sect
) {
1920 struct SAA
*p_linep
= p_sect
->psaa
;
1922 saa_len
= p_linep
->datalen
;
1923 saa_rnbytes(p_linep
, p_buf
, saa_len
);
1929 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
1931 nasm_free(p_buf_base
);
1934 /* string section */
1936 struct SAA
*p_str
= saa_init(1L);
1937 char *cur_path
= nasm_realpath(module_name
);
1938 char *cur_file
= nasm_basename(cur_path
);
1939 char *cur_dir
= nasm_dirname(cur_path
);
1941 p_section
= get_section_by_name("__DWARF", "__debug_str");
1942 nasm_assert(p_section
!= NULL
);
1944 producer_str_offset
= 0;
1945 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature());
1946 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
1947 saa_wcstring(p_str
, cur_dir
);
1949 saa_len
= p_str
->datalen
;
1950 p_buf
= nasm_malloc(saa_len
);
1951 saa_rnbytes(p_str
, p_buf
, saa_len
);
1952 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
1954 nasm_free(cur_path
);
1955 nasm_free(cur_file
);
1963 struct SAA
*p_info
= saa_init(1L);
1965 p_section
= get_section_by_name("__DWARF", "__debug_info");
1966 nasm_assert(p_section
!= NULL
);
1968 /* size will be overwritten once determined, so skip in p_info layout */
1969 saa_write16(p_info
, 2); /* dwarf version */
1970 saa_write32(p_info
, 0); /* offset info abbrev */
1971 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
1973 saa_write8(p_info
, 1); /* abbrev entry number */
1975 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
1976 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
1977 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
1978 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
1979 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
1981 if (ofmt
== &of_macho64
) {
1982 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1983 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
1985 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1986 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
1989 saa_write8(p_info
, 2); /* abbrev entry number */
1991 if (ofmt
== &of_macho64
) {
1992 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1993 saa_write64(p_info
, 0); /* DW_AT_frame_base */
1995 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1996 saa_write32(p_info
, 0); /* DW_AT_frame_base */
1998 saa_write8(p_info
, DW_END_default
);
2000 saa_len
= p_info
->datalen
;
2001 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
2003 WRITELONG(p_buf
, saa_len
);
2004 saa_rnbytes(p_info
, p_buf
, saa_len
);
2005 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
2008 nasm_free(p_buf_base
);
2011 /* abbrev section */
2013 struct SAA
*p_abbrev
= saa_init(1L);
2015 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
2016 nasm_assert(p_section
!= NULL
);
2018 saa_write8(p_abbrev
, 1); /* entry number */
2020 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2021 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2023 saa_write8(p_abbrev
, DW_AT_producer
);
2024 saa_write8(p_abbrev
, DW_FORM_strp
);
2026 saa_write8(p_abbrev
, DW_AT_language
);
2027 saa_write8(p_abbrev
, DW_FORM_data2
);
2029 saa_write8(p_abbrev
, DW_AT_name
);
2030 saa_write8(p_abbrev
, DW_FORM_strp
);
2032 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2033 saa_write8(p_abbrev
, DW_FORM_strp
);
2035 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2036 saa_write8(p_abbrev
, DW_FORM_data4
);
2038 saa_write8(p_abbrev
, DW_AT_low_pc
);
2039 saa_write8(p_abbrev
, DW_FORM_addr
);
2041 saa_write8(p_abbrev
, DW_AT_high_pc
);
2042 saa_write8(p_abbrev
, DW_FORM_addr
);
2044 saa_write16(p_abbrev
, DW_END_default
);
2046 saa_write8(p_abbrev
, 2); /* entry number */
2048 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2049 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2051 saa_write8(p_abbrev
, DW_AT_low_pc
);
2052 saa_write8(p_abbrev
, DW_FORM_addr
);
2054 saa_write8(p_abbrev
, DW_AT_frame_base
);
2055 saa_write8(p_abbrev
, DW_FORM_addr
);
2057 saa_write16(p_abbrev
, DW_END_default
);
2059 saa_write8(p_abbrev
, 0); /* Terminal zero entry */
2061 saa_len
= p_abbrev
->datalen
;
2063 p_buf
= nasm_malloc(saa_len
);
2065 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2066 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2073 static void new_file_list (const char *file_name
, const char *dir_name
)
2075 struct dir_list
*dir_list
;
2076 bool need_new_dir_list
= true;
2078 nasm_new(dw_cur_file
);
2079 dw_cur_file
->file
= ++dw_num_files
;
2080 dw_cur_file
->file_name
= file_name
;
2082 dw_head_file
= dw_cur_file
;
2084 *dw_last_file_next
= dw_cur_file
;
2086 dw_last_file_next
= &(dw_cur_file
->next
);
2089 list_for_each(dir_list
, dw_head_dir
) {
2090 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2091 dw_cur_file
->dir
= dir_list
;
2092 need_new_dir_list
= false;
2098 if(need_new_dir_list
)
2101 dir_list
->dir
= dw_num_dirs
++;
2102 dir_list
->dir_name
= dir_name
;
2104 dw_head_dir
= dir_list
;
2106 *dw_last_dir_next
= dir_list
;
2108 dw_last_dir_next
= &(dir_list
->next
);
2109 dw_cur_file
->dir
= dir_list
;
2113 static void macho_dbg_init(void)
2117 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2119 bool need_new_list
= true;
2120 const char *cur_file
= nasm_basename(file_name
);
2121 const char *cur_dir
= nasm_dirname(file_name
);
2124 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2125 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2127 struct file_list
*match
;
2129 list_for_each(match
, dw_head_file
) {
2130 if(!(strcmp(cur_file
, match
->file_name
)) &&
2131 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2132 dw_cur_file
= match
;
2133 dw_cur_file
->dir
= match
->dir
;
2134 need_new_list
= false;
2141 new_file_list(cur_file
, cur_dir
);
2146 cur_line
= line_num
;
2149 static void macho_dbg_output(int type
, void *param
)
2151 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2152 int32_t secto
= sinfo_param
->secto
;
2153 bool need_new_sect
= false;
2154 struct SAA
*p_linep
= NULL
;
2157 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2158 need_new_sect
= true;
2160 struct dw_sect_list
*match
= dw_head_sect
;
2163 for(; idx
< dw_num_sects
; idx
++) {
2164 if(match
->section
== secto
) {
2165 dw_cur_sect
= match
;
2166 need_new_sect
= false;
2169 match
= match
->next
;
2175 nasm_new(dw_cur_sect
);
2177 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2178 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2179 dw_cur_sect
->offset
= 0;
2180 dw_cur_sect
->next
= NULL
;
2181 dw_cur_sect
->section
= secto
;
2183 saa_write8(p_linep
, DW_LNS_extended_op
);
2184 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2185 saa_write8(p_linep
, DW_LNE_set_address
);
2186 if (ofmt
== &of_macho64
) {
2187 saa_write64(p_linep
, 0);
2189 saa_write32(p_linep
, 0);
2193 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2195 dw_last_sect
->next
= dw_cur_sect
;
2196 dw_last_sect
= dw_cur_sect
;
2200 if(dbg_immcall
== true) {
2201 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2202 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2203 uint32_t cur_file
= dw_cur_file
->file
;
2204 p_linep
= dw_cur_sect
->psaa
;
2206 if(cur_file
!= dw_cur_sect
->file
) {
2207 saa_write8(p_linep
, DW_LNS_set_file
);
2208 saa_write8(p_linep
, cur_file
);
2209 dw_cur_sect
->file
= cur_file
;
2213 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2216 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2217 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2218 saa_write8(p_linep
, special_opcode
);
2220 saa_write8(p_linep
, DW_LNS_advance_line
);
2221 saa_wleb128s(p_linep
, line_delta
);
2223 saa_write8(p_linep
, DW_LNS_advance_pc
);
2224 saa_wleb128u(p_linep
, offset_delta
);
2226 saa_write8(p_linep
, DW_LNS_copy
);
2229 dw_cur_sect
->line
= cur_line
;
2230 dw_cur_sect
->offset
= sinfo_param
->size
;
2233 dbg_immcall
= false;
2237 static void macho_dbg_cleanup(void)
2239 /* dwarf sectors generation */
2240 macho_dbg_generate();
2243 struct dw_sect_list
*p_sect
= dw_head_sect
;
2244 struct file_list
*p_file
= dw_head_file
;
2247 for(; idx
< dw_num_sects
; idx
++) {
2248 struct dw_sect_list
*next
= p_sect
->next
;
2253 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2254 struct file_list
*next
= p_file
->next
;
2262 static const struct macho_fmt macho32_fmt
= {
2272 GENERIC_RELOC_VANILLA
,
2273 GENERIC_RELOC_VANILLA
,
2275 false /* Allow segment-relative relocations */
2278 static void macho32_init(void)
2283 macho_gotpcrel_sect
= NO_SEG
;
2286 static const struct dfmt macho32_df_dwarf
= {
2287 "Mach-O i386 dwarf for Darwin/MacOS",
2291 null_debug_deflabel
,
2292 null_debug_directive
,
2293 null_debug_typevalue
,
2296 NULL
/*pragma list*/
2299 static const struct dfmt
* const macho32_df_arr
[2] =
2300 { &macho32_df_dwarf
, NULL
};
2302 const struct ofmt of_macho32
= {
2303 "Mach-O i386 (Mach, including MacOS X and variants)",
2313 nasm_do_legacy_output
,
2327 static const struct macho_fmt macho64_fmt
= {
2332 MACHO_HEADER64_SIZE
,
2333 MACHO_SEGCMD64_SIZE
,
2334 MACHO_SECTCMD64_SIZE
,
2337 X86_64_RELOC_UNSIGNED
,
2338 X86_64_RELOC_SIGNED
,
2340 true /* Force symbol-relative relocations */
2343 static void macho64_init(void)
2348 /* add special symbol for ..gotpcrel */
2349 macho_gotpcrel_sect
= seg_alloc() + 1;
2350 backend_label("..gotpcrel", macho_gotpcrel_sect
, 0L);
2353 static const struct dfmt macho64_df_dwarf
= {
2354 "Mach-O x86-64 dwarf for Darwin/MacOS",
2358 null_debug_deflabel
,
2359 null_debug_directive
,
2360 null_debug_typevalue
,
2363 NULL
/*pragma list*/
2366 static const struct dfmt
* const macho64_df_arr
[2] =
2367 { &macho64_df_dwarf
, NULL
};
2369 const struct ofmt of_macho64
= {
2370 "Mach-O x86-64 (Mach, including MacOS X and variants)",
2380 nasm_do_legacy_output
,