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
61 #if defined(OF_MACHO) || defined(OF_MACHO64)
63 /* Mach-O in-file header structure sizes */
64 #define MACHO_HEADER_SIZE 28
65 #define MACHO_SEGCMD_SIZE 56
66 #define MACHO_SECTCMD_SIZE 68
67 #define MACHO_SYMCMD_SIZE 24
68 #define MACHO_NLIST_SIZE 12
69 #define MACHO_RELINFO_SIZE 8
71 #define MACHO_HEADER64_SIZE 32
72 #define MACHO_SEGCMD64_SIZE 72
73 #define MACHO_SECTCMD64_SIZE 80
74 #define MACHO_NLIST64_SIZE 16
76 /* Mach-O relocations numbers */
78 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
79 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
81 /* Our internal relocation types */
83 RL_ABS
, /* Absolute relocation */
84 RL_REL
, /* Relative relocation */
85 RL_TLV
, /* Thread local */
86 RL_BRANCH
, /* Relative direct branch */
87 RL_SUB
, /* X86_64_RELOC_SUBTRACT */
88 RL_GOT
, /* X86_64_RELOC_GOT */
89 RL_GOTLOAD
/* X86_64_RELOC_GOT_LOAD */
91 #define RL_MAX_32 RL_TLV
92 #define RL_MAX_64 RL_GOTLOAD
95 uint32_t ptrsize
; /* Pointer size in bytes */
96 uint32_t mh_magic
; /* Which magic number to use */
97 uint32_t cpu_type
; /* Which CPU type */
98 uint32_t lc_segment
; /* Which segment load command */
99 uint32_t header_size
; /* Header size */
100 uint32_t segcmd_size
; /* Segment command size */
101 uint32_t sectcmd_size
; /* Section command size */
102 uint32_t nlist_size
; /* Nlist (symbol) size */
103 enum reltype maxreltype
; /* Maximum entry in enum reltype permitted */
104 uint32_t reloc_abs
; /* Absolute relocation type */
105 uint32_t reloc_rel
; /* Relative relocation type */
106 uint32_t reloc_tlv
; /* Thread local relocation type */
107 bool forcesym
; /* Always use "external" (symbol-relative) relocations */
110 static struct macho_fmt fmt
;
112 static void fwriteptr(uint64_t data
, FILE * fp
)
114 fwriteaddr(data
, fmt
.ptrsize
, fp
);
118 /* nasm internal data */
119 struct section
*next
;
121 int32_t index
; /* Main section index */
122 int32_t subsection
; /* Current subsection index */
124 struct reloc
*relocs
;
125 struct rbtree
*syms
[2]; /* All/global symbols symbols in section */
127 bool by_name
; /* This section was specified by full MachO name */
128 char namestr
[34]; /* segment,section as a C string */
130 /* data that goes into the file */
131 char sectname
[16]; /* what this section is called */
132 char segname
[16]; /* segment this section will be in */
133 uint64_t addr
; /* in-memory address (subject to alignment) */
134 uint64_t size
; /* in-memory and -file size */
135 uint64_t offset
; /* in-file offset */
136 uint32_t pad
; /* padding bytes before section */
137 uint32_t nreloc
; /* relocation entry count */
138 uint32_t flags
; /* type and attributes (masked) */
139 uint32_t extreloc
; /* external relocations */
142 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
144 /* fake section for absolute symbols, *not* part of the section linked list */
145 static struct section absolute_sect
;
148 /* nasm internal data */
151 /* data that goes into the file */
152 int32_t addr
; /* op's offset in section */
153 uint32_t snum
:24, /* contains symbol index if
154 ** ext otherwise in-file
156 pcrel
:1, /* relative relocation */
157 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
158 ext
:1, /* external symbol referenced */
159 type
:4; /* reloc type */
163 /* nasm internal data */
164 struct rbtree symv
[2]; /* All/global symbol rbtrees; "key" contains the
166 struct symbol
*next
; /* next symbol in the list */
167 char *name
; /* name of this symbol */
168 int32_t initial_snum
; /* symbol number used above in reloc */
169 int32_t snum
; /* true snum for reloc */
171 /* data that goes into the file */
172 uint32_t strx
; /* string table index */
173 uint8_t type
; /* symbol type */
174 uint8_t sect
; /* NO_SECT or section number */
175 uint16_t desc
; /* for stab debugging, 0 for us */
178 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
180 static struct section
*sects
, **sectstail
, **sectstab
;
181 static struct symbol
*syms
, **symstail
;
182 static uint32_t nsyms
;
184 /* These variables are set by macho_layout_symbols() to organize
185 the symbol table and string table in order the dynamic linker
186 expects. They are then used in macho_write() to put out the
187 symbols and strings in that order.
189 The order of the symbol table is:
191 defined external symbols (sorted by name)
192 undefined external symbols (sorted by name)
194 The order of the string table is:
195 strings for external symbols
196 strings for local symbols
198 static uint32_t ilocalsym
= 0;
199 static uint32_t iextdefsym
= 0;
200 static uint32_t iundefsym
= 0;
201 static uint32_t nlocalsym
;
202 static uint32_t nextdefsym
;
203 static uint32_t nundefsym
;
204 static struct symbol
**extdefsyms
= NULL
;
205 static struct symbol
**undefsyms
= NULL
;
207 static struct RAA
*extsyms
;
208 static struct SAA
*strs
;
209 static uint32_t strslen
;
211 /* Global file information. This should be cleaned up into either
212 a structure or as function arguments. */
213 static uint32_t head_ncmds
= 0;
214 static uint32_t head_sizeofcmds
= 0;
215 static uint32_t head_flags
= 0;
216 static uint64_t seg_filesize
= 0;
217 static uint64_t seg_vmsize
= 0;
218 static uint32_t seg_nsects
= 0;
219 static uint64_t rel_padcnt
= 0;
222 * Functions for handling fixed-length zero-padded string
223 * fields, that may or may not be null-terminated.
226 /* Copy a string into a zero-padded fixed-length field */
227 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
229 /* Compare a fixed-length field with a string */
230 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
232 #define alignint32_t(x) \
233 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
235 #define alignint64_t(x) \
236 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
238 #define alignptr(x) \
239 ALIGN(x, fmt.ptrsize) /* align x to output format width */
241 static struct hash_table section_by_name
;
242 static struct RAA
*section_by_index
;
244 static struct section
* never_null
245 find_or_add_section(const char *segname
, const char *sectname
)
247 struct hash_insert hi
;
252 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
254 sp
= hash_find(§ion_by_name
, sect
, &hi
);
256 return (struct section
*)(*sp
);
258 s
= nasm_zalloc(sizeof *s
);
259 xstrncpy(s
->segname
, segname
);
260 xstrncpy(s
->sectname
, sectname
);
261 xstrncpy(s
->namestr
, sect
);
262 hash_add(&hi
, s
->namestr
, s
);
264 s
->index
= s
->subsection
= seg_alloc();
265 section_by_index
= raa_write_ptr(section_by_index
, s
->index
>> 1, s
);
270 static inline bool is_new_section(const struct section
*s
)
275 static struct section
*get_section_by_name(const char *segname
,
276 const char *sectname
)
281 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
283 sp
= hash_find(§ion_by_name
, sect
, NULL
);
284 return sp
? (struct section
*)(*sp
) : NULL
;
287 static struct section
*get_section_by_index(int32_t index
)
289 if (index
< 0 || index
>= SEG_ABS
|| (index
& 1))
292 return raa_read_ptr(section_by_index
, index
>> 1);
296 struct dir_list
*next
;
297 struct dir_list
*last
;
298 const char *dir_name
;
303 struct file_list
*next
;
304 struct file_list
*last
;
305 const char *file_name
;
307 struct dir_list
*dir
;
310 struct dw_sect_list
{
316 struct dw_sect_list
*next
;
317 struct dw_sect_list
*last
;
320 struct section_info
{
325 #define DW_LN_BASE (-5)
326 #define DW_LN_RANGE 14
327 #define DW_OPCODE_BASE 13
328 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
329 #define DW_MAX_SP_OPCODE 256
331 static struct file_list
*dw_head_file
= 0, *dw_cur_file
= 0, **dw_last_file_next
= NULL
;
332 static struct dir_list
*dw_head_dir
= 0, **dw_last_dir_next
= NULL
;
333 static struct dw_sect_list
*dw_head_sect
= 0, *dw_cur_sect
= 0, *dw_last_sect
= 0;
334 static uint32_t cur_line
= 0, dw_num_files
= 0, dw_num_dirs
= 0, dw_num_sects
= 0;
335 static bool dbg_immcall
= false;
336 static const char *module_name
= NULL
;
339 * Special section numbers which are used to define Mach-O special
340 * symbols, which can be used with WRT to provide PIC relocation
343 static int32_t macho_tlvp_sect
;
344 static int32_t macho_gotpcrel_sect
;
346 static void macho_init(void)
348 module_name
= inname
;
352 /* Fake section for absolute symbols */
353 absolute_sect
.index
= NO_SEG
;
362 extsyms
= raa_init();
365 section_by_index
= raa_init();
366 hash_init(§ion_by_name
, HASH_MEDIUM
);
368 /* string table starts with a zero byte so index 0 is an empty string */
369 saa_wbytes(strs
, zero_buffer
, 1);
372 /* add special symbol for TLVP */
373 macho_tlvp_sect
= seg_alloc() + 1;
374 backend_label("..tlvp", macho_tlvp_sect
, 0L);
377 static void sect_write(struct section
*sect
,
378 const uint8_t *data
, uint32_t len
)
380 saa_wbytes(sect
->data
, data
, len
);
385 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
387 static struct symbol
*macho_find_sym(struct section
*s
, uint64_t offset
,
388 bool global
, bool exact
)
392 srb
= rb_search(s
->syms
[global
], offset
);
394 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
395 nasm_error(ERR_NONFATAL
, "unable to find a suitable%s%s symbol"
396 " for this reference",
397 global
? " global" : "",
398 s
== &absolute_sect
? " absolute " : "");
402 return container_of(srb
- global
, struct symbol
, symv
);
405 static int64_t add_reloc(struct section
*sect
, int32_t section
,
407 enum reltype reltype
, int bytes
)
414 /* Double check this is a valid relocation type for this platform */
415 nasm_assert(reltype
<= fmt
.maxreltype
);
417 /* the current end of the section will be the symbol's address for
418 ** now, might have to be fixed by macho_fixup_relocs() later on. make
419 ** sure we don't make the symbol scattered by setting the highest
420 ** bit by accident */
421 r
= nasm_malloc(sizeof(struct reloc
));
422 r
->addr
= sect
->size
& ~R_SCATTERED
;
426 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
427 r
->length
= ilog2_32(bytes
);
429 /* set default relocation values */
430 r
->type
= fmt
.reloc_abs
;
434 s
= get_section_by_index(section
);
435 fi
= s
? s
->fileindex
: NO_SECT
;
437 /* absolute relocation */
440 if (section
== NO_SEG
) {
441 /* absolute (can this even happen?) */
443 } else if (fi
== NO_SECT
) {
445 r
->snum
= raa_read(extsyms
, section
);
455 r
->type
= fmt
.reloc_rel
;
457 if (section
== NO_SEG
) {
458 /* may optionally be converted below by fmt.forcesym */
460 } else if (fi
== NO_SECT
) {
463 r
->snum
= raa_read(extsyms
, section
);
464 if (reltype
== RL_BRANCH
)
465 r
->type
= X86_64_RELOC_BRANCH
;
470 if (reltype
== RL_BRANCH
)
471 r
->type
= X86_64_RELOC_BRANCH
;
475 case RL_SUB
: /* obsolete */
476 nasm_error(ERR_WARNING
, "relcation with subtraction"
477 "becomes to be obsolete");
479 r
->type
= X86_64_RELOC_SUBTRACTOR
;
483 r
->type
= X86_64_RELOC_GOT
;
487 r
->type
= X86_64_RELOC_GOT_LOAD
;
491 r
->type
= fmt
.reloc_tlv
;
495 r
->pcrel
= (fmt
.ptrsize
== 8 ? 1 : 0);
496 if (section
== NO_SEG
) {
497 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
499 } else if (fi
== NO_SECT
) {
501 r
->snum
= raa_read(extsyms
, section
);
503 /* internal - GOTPCREL doesn't need to be in global */
504 struct symbol
*sym
= macho_find_sym(s
, offset
,
505 false, /* reltype != RL_TLV */
508 nasm_error(ERR_NONFATAL
, "Symbol for WRT not found");
512 adjust
-= sym
->symv
[0].key
;
513 r
->snum
= sym
->initial_snum
;
519 * For 64-bit Mach-O, force a symbol reference if at all possible
520 * Allow for r->snum == R_ABS by searching absolute_sect
522 if (!r
->ext
&& fmt
.forcesym
) {
523 struct symbol
*sym
= macho_find_sym(s
? s
: &absolute_sect
,
524 offset
, false, false);
526 adjust
-= sym
->symv
[0].key
;
527 r
->snum
= sym
->initial_snum
;
533 adjust
+= ((r
->ext
&& fmt
.ptrsize
== 8) ? bytes
: -(int64_t)sect
->size
);
535 /* NeXT as puts relocs in reversed order (address-wise) into the
536 ** files, so we do the same, doesn't seem to make much of a
537 ** difference either way */
538 r
->next
= sect
->relocs
;
551 static void macho_output(int32_t secto
, const void *data
,
552 enum out_type type
, uint64_t size
,
553 int32_t section
, int32_t wrt
)
556 int64_t addr
, offset
;
557 uint8_t mydata
[16], *p
;
559 enum reltype reltype
;
561 s
= get_section_by_index(secto
);
563 nasm_error(ERR_WARNING
, "attempt to assemble code in"
564 " section %d: defaulting to `.text'", secto
);
565 s
= get_section_by_name("__TEXT", "__text");
567 /* should never happen */
569 nasm_panic("text section not found");
572 /* debug code generation only for sections tagged with
573 * instruction attribute */
574 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
576 struct section_info sinfo
;
577 sinfo
.size
= s
->size
;
579 dfmt
->debug_output(0, &sinfo
);
582 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
584 if (is_bss
&& type
!= OUT_RESERVE
) {
585 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
586 "BSS section: ignored");
588 nasm_error(ERR_WARNING
, "section size may be negative"
589 "with address symbols");
590 s
->size
+= realsize(type
, size
);
594 memset(mydata
, 0, sizeof(mydata
));
599 nasm_error(ERR_WARNING
, "uninitialized space declared in"
600 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
602 sect_write(s
, NULL
, size
);
609 sect_write(s
, data
, size
);
614 int asize
= abs((int)size
);
616 addr
= *(int64_t *)data
;
617 if (section
!= NO_SEG
) {
619 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
620 " section base references");
621 } else if (wrt
== NO_SEG
) {
622 if (fmt
.ptrsize
== 8 && asize
!= 8) {
623 nasm_error(ERR_NONFATAL
,
624 "Mach-O 64-bit format does not support"
625 " 32-bit absolute addresses");
627 addr
+= add_reloc(s
, section
, addr
, RL_ABS
, asize
);
629 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
!= 8 &&
630 asize
== (int) fmt
.ptrsize
) {
631 addr
+= add_reloc(s
, section
, addr
, RL_TLV
, asize
);
633 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
639 WRITEADDR(p
, addr
, asize
);
640 sect_write(s
, mydata
, asize
);
648 offset
= *(int64_t *)data
;
649 addr
= offset
- size
;
651 if (section
!= NO_SEG
&& section
% 2) {
652 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
653 " section base references");
654 } else if (fmt
.ptrsize
== 8) {
655 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
656 " Macho-O relocation [2]");
657 } else if (wrt
!= NO_SEG
) {
658 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
660 wrt
= NO_SEG
; /* we can at least _try_ to continue */
662 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
,
663 type
== OUT_REL1ADR
? 1 : 2);
667 sect_write(s
, mydata
, type
== OUT_REL1ADR
? 1 : 2);
674 offset
= *(int64_t *)data
;
675 addr
= offset
- size
;
678 if (section
!= NO_SEG
&& section
% 2) {
679 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
680 " section base references");
681 } else if (wrt
== NO_SEG
) {
682 if (fmt
.ptrsize
== 8 &&
683 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
686 opcode
[0] = opcode
[1] = 0;
688 /* HACK: Retrieve instruction opcode */
689 if (likely(s
->data
->datalen
>= 2)) {
690 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
691 } else if (s
->data
->datalen
== 1) {
692 saa_fread(s
->data
, 0, opcode
+1, 1);
695 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
696 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
697 /* Direct call, jmp, or jcc */
701 } else if (wrt
== macho_gotpcrel_sect
) {
704 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
705 s
->data
->datalen
>= 3) {
708 /* HACK: Retrieve instruction opcode */
709 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
710 if ((gotload
[0] & 0xf8) == 0x48 &&
711 gotload
[1] == 0x8b &&
712 (gotload
[2] & 0307) == 0005) {
713 /* movq <reg>,[rel sym wrt ..gotpcrel] */
714 reltype
= RL_GOTLOAD
;
717 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
== 8) {
720 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
722 /* continue with RL_REL */
725 addr
+= add_reloc(s
, section
, offset
, reltype
,
726 type
== OUT_REL4ADR
? 4 : 8);
728 sect_write(s
, mydata
, type
== OUT_REL4ADR
? 4 : 8);
732 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
737 #define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
738 #define NO_TYPE S_NASM_TYPE_MASK
740 /* Translation table from traditional Unix section names to Mach-O */
741 static const struct macho_known_section
{
742 const char *nasmsect
;
744 const char *sectname
;
745 const uint32_t flags
;
746 } known_sections
[] = {
747 { ".text", "__TEXT", "__text", S_CODE
},
748 { ".data", "__DATA", "__data", S_REGULAR
},
749 { ".rodata", "__DATA", "__const", S_REGULAR
},
750 { ".bss", "__DATA", "__bss", S_ZEROFILL
},
751 { ".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
752 { ".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
753 { ".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
754 { ".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
757 /* Section type or attribute directives */
758 static const struct macho_known_section_attr
{
762 { "data", S_REGULAR
},
764 { "mixed", S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
},
765 { "bss", S_ZEROFILL
},
766 { "zerofill", S_ZEROFILL
},
767 { "no_dead_strip", NO_TYPE
| S_ATTR_NO_DEAD_STRIP
},
768 { "live_support", NO_TYPE
| S_ATTR_LIVE_SUPPORT
},
769 { "strip_static_syms", NO_TYPE
| S_ATTR_STRIP_STATIC_SYMS
},
770 { "debug", NO_TYPE
| S_ATTR_DEBUG
},
774 static const struct macho_known_section
*
775 lookup_known_section(const char *name
, bool by_sectname
)
779 if (name
&& name
[0]) {
780 for (i
= 0; i
< ARRAY_SIZE(known_sections
); i
++) {
781 const char *p
= by_sectname
?
782 known_sections
[i
].sectname
:
783 known_sections
[i
].nasmsect
;
784 if (!strcmp(name
, p
))
785 return &known_sections
[i
];
792 static int32_t macho_section(char *name
, int pass
, int *bits
)
794 const struct macho_known_section
*known_section
;
795 const struct macho_known_section_attr
*sa
;
796 char *sectionAttributes
;
798 const char *section
, *segment
;
800 char *currentAttribute
;
807 /* Default to the appropriate number of bits. */
809 *bits
= fmt
.ptrsize
<< 3;
811 sectionAttributes
= NULL
;
813 sectionAttributes
= name
;
814 name
= nasm_strsep(§ionAttributes
, " \t");
817 section
= segment
= NULL
;
820 comma
= strchr(name
, ',');
828 len
= strlen(segment
);
830 nasm_error(ERR_NONFATAL
, "empty segment name\n");
831 } else if (len
> 16) {
832 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
835 len
= strlen(section
);
837 nasm_error(ERR_NONFATAL
, "empty section name\n");
838 } else if (len
> 16) {
839 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
842 known_section
= lookup_known_section(section
, true);
844 flags
= known_section
->flags
;
848 known_section
= lookup_known_section(name
, false);
849 if (!known_section
) {
850 nasm_error(ERR_NONFATAL
, "unknown section name %s\n", name
);
854 segment
= known_section
->segname
;
855 section
= known_section
->sectname
;
856 flags
= known_section
->flags
;
859 /* try to find section with that name, or create it */
860 s
= find_or_add_section(segment
, section
);
861 new_seg
= is_new_section(s
);
863 /* initialize it if it is a brand new section */
866 sectstail
= &s
->next
;
868 s
->data
= saa_init(1L);
869 s
->fileindex
= ++seg_nsects
;
881 *comma
= ','; /* Restore comma */
883 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
887 while (sectionAttributes
&&
888 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
889 if (!*currentAttribute
)
892 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
894 int newAlignment
, value
;
896 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
897 newAlignment
= alignlog2_32(value
);
900 nasm_error(ERR_NONFATAL
,
901 "unknown or missing alignment value \"%s\" "
902 "specified for section \"%s\"",
903 currentAttribute
+ 6,
905 } else if (0 > newAlignment
) {
906 nasm_error(ERR_NONFATAL
,
907 "alignment of %d (for section \"%s\") is not "
913 if (s
->align
< newAlignment
)
914 s
->align
= newAlignment
;
916 for (sa
= sect_attribs
; sa
->name
; sa
++) {
917 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
918 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
919 flags
= (flags
& ~S_NASM_TYPE_MASK
)
920 | (sa
->flags
& S_NASM_TYPE_MASK
);
922 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
928 nasm_error(ERR_NONFATAL
,
929 "unknown section attribute %s for section %s",
930 currentAttribute
, name
);
935 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
936 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
937 nasm_error(ERR_NONFATAL
,
938 "inconsistent section attributes for section %s\n",
941 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
944 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
947 return s
->subsection
;
950 static int32_t macho_herelabel(const char *name
, enum label_type type
,
951 int32_t section
, int32_t *subsection
,
958 if (!(head_flags
& MH_SUBSECTIONS_VIA_SYMBOLS
))
961 /* No subsection only for local labels */
962 if (type
== LBL_LOCAL
)
965 s
= get_section_by_index(section
);
969 subsec
= *subsection
;
970 if (subsec
== NO_SEG
) {
971 /* Allocate a new subsection index */
972 subsec
= *subsection
= seg_alloc();
973 section_by_index
= raa_write_ptr(section_by_index
, subsec
>> 1, s
);
976 s
->subsection
= subsec
;
977 *copyoffset
= true; /* Maintain previous offset */
981 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
982 int is_global
, char *special
)
986 bool special_used
= false;
988 #if defined(DEBUG) && DEBUG>2
989 nasm_error(ERR_DEBUG
,
990 " macho_symdef: %s, pass0=%d, passn=%"PRId64
", sec=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
991 name
, pass0
, passn
, section
, offset
, is_global
, special
);
994 if (is_global
== 3) {
996 int n
= strcspn(special
, " \t");
998 if (!nasm_strnicmp(special
, "private_extern", n
)) {
999 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1000 if (!strcmp(name
, sym
->name
)) {
1001 if (sym
->type
& N_PEXT
)
1002 return; /* nothing to be done */
1009 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
1010 "(yet) support forward reference fixups.");
1014 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1016 * This is a NASM special symbol. We never allow it into
1017 * the Macho-O symbol table, even if it's a valid one. If it
1018 * _isn't_ a valid one, we should barf immediately.
1020 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1021 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1025 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1027 symstail
= &sym
->next
;
1030 sym
->strx
= strslen
;
1033 sym
->symv
[0].key
= offset
;
1034 sym
->symv
[1].key
= offset
;
1035 sym
->initial_snum
= -1;
1037 /* external and common symbols get N_EXT */
1038 if (is_global
!= 0) {
1041 if (is_global
== 1) {
1042 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1044 int n
= strcspn(special
, " \t");
1046 if (!nasm_strnicmp(special
, "private_extern", n
))
1047 sym
->type
|= N_PEXT
;
1049 nasm_error(ERR_NONFATAL
, "unrecognised symbol type `%.*s'", n
, special
);
1051 special_used
= true;
1054 /* track the initially allocated symbol number for use in future fix-ups */
1055 sym
->initial_snum
= nsyms
;
1057 if (section
== NO_SEG
) {
1058 /* symbols in no section get absolute */
1060 sym
->sect
= NO_SECT
;
1064 s
= get_section_by_index(section
);
1066 sym
->type
|= N_SECT
;
1068 /* get the in-file index of the section the symbol was defined in */
1069 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1072 /* remember symbol number of references to external
1073 ** symbols, this works because every external symbol gets
1074 ** its own section number allocated internally by nasm and
1075 ** can so be used as a key */
1076 extsyms
= raa_write(extsyms
, section
, nsyms
);
1078 switch (is_global
) {
1081 /* there isn't actually a difference between global
1082 ** and common symbols, both even have their size in
1083 ** sym->symv[0].key */
1088 /* give an error on unfound section if it's not an
1089 ** external or common symbol (assemble_file() does a
1090 ** seg_alloc() on every call for them) */
1091 nasm_panic("in-file index for section %d not found, is_global = %d", section
, is_global
);
1098 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1100 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1105 if (special
&& !special_used
)
1106 nasm_error(ERR_NONFATAL
, "no special symbol features supported here");
1109 static void macho_sectalign(int32_t seg
, unsigned int value
)
1114 nasm_assert(!(seg
& 1));
1116 s
= get_section_by_index(seg
);
1118 if (!s
|| !is_power2(value
))
1121 align
= alignlog2_32(value
);
1122 if (s
->align
< align
)
1126 extern macros_t macho_stdmac
[];
1128 /* Comparison function for qsort symbol layout. */
1129 static int layout_compare (const struct symbol
**s1
,
1130 const struct symbol
**s2
)
1132 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1135 /* The native assembler does a few things in a similar function
1137 * Remove temporary labels
1138 * Sort symbols according to local, external, undefined (by name)
1139 * Order the string table
1141 We do not remove temporary labels right now.
1143 numsyms is the total number of symbols we have. strtabsize is the
1144 number entries in the string table. */
1146 static void macho_layout_symbols (uint32_t *numsyms
,
1147 uint32_t *strtabsize
)
1149 struct symbol
*sym
, **symp
;
1153 *strtabsize
= sizeof (char);
1157 while ((sym
= *symp
)) {
1158 /* Undefined symbols are now external. */
1159 if (sym
->type
== N_UNDF
)
1162 if ((sym
->type
& N_EXT
) == 0) {
1163 sym
->snum
= *numsyms
;
1164 *numsyms
= *numsyms
+ 1;
1168 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1174 /* If we handle debug info we'll want
1175 to check for it here instead of just
1176 adding the symbol to the string table. */
1177 sym
->strx
= *strtabsize
;
1178 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1179 *strtabsize
+= strlen(sym
->name
) + 1;
1181 symp
= &(sym
->next
);
1184 /* Next, sort the symbols. Most of this code is a direct translation from
1185 the Apple cctools symbol layout. We need to keep compatibility with that. */
1186 /* Set the indexes for symbol groups into the symbol table */
1188 iextdefsym
= nlocalsym
;
1189 iundefsym
= nlocalsym
+ nextdefsym
;
1191 /* allocate arrays for sorting externals by name */
1192 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1193 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1200 while ((sym
= *symp
)) {
1202 if((sym
->type
& N_EXT
) == 0) {
1203 sym
->strx
= *strtabsize
;
1204 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1205 *strtabsize
+= strlen(sym
->name
) + 1;
1208 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1209 extdefsyms
[i
++] = sym
;
1211 undefsyms
[j
++] = sym
;
1214 symp
= &(sym
->next
);
1217 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1218 (int (*)(const void *, const void *))layout_compare
);
1219 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1220 (int (*)(const void *, const void *))layout_compare
);
1222 for(i
= 0; i
< nextdefsym
; i
++) {
1223 extdefsyms
[i
]->snum
= *numsyms
;
1226 for(j
= 0; j
< nundefsym
; j
++) {
1227 undefsyms
[j
]->snum
= *numsyms
;
1232 /* Calculate some values we'll need for writing later. */
1234 static void macho_calculate_sizes (void)
1239 /* count sections and calculate in-memory and in-file offsets */
1240 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1243 /* recalculate segment address based on alignment and vm size */
1244 s
->addr
= seg_vmsize
;
1246 /* we need section alignment to calculate final section address */
1248 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1250 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1253 seg_vmsize
= newaddr
+ s
->size
;
1255 /* zerofill sections aren't actually written to the file */
1256 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1258 * LLVM/Xcode as always aligns the section data to 4
1259 * bytes; there is a comment in the LLVM source code that
1260 * perhaps aligning to pointer size would be better.
1262 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1263 s
->offset
= seg_filesize
+ s
->pad
;
1264 seg_filesize
+= s
->size
+ s
->pad
;
1266 /* filesize and vmsize needs to be aligned */
1267 seg_vmsize
+= s
->pad
;
1271 /* calculate size of all headers, load commands and sections to
1272 ** get a pointer to the start of all the raw data */
1273 if (seg_nsects
> 0) {
1275 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1280 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1283 if (seg_nsects
> MAX_SECT
) {
1284 nasm_fatal("MachO output is limited to %d sections\n",
1288 /* Create a table of sections by file index to avoid linear search */
1289 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1290 sectstab
[NO_SECT
] = &absolute_sect
;
1291 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1295 /* Write out the header information for the file. */
1297 static void macho_write_header (void)
1299 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1300 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1301 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1302 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1303 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1304 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1305 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1306 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1309 /* Write out the segment load command at offset. */
1311 static uint32_t macho_write_segment (uint64_t offset
)
1313 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1314 uint32_t s_reloff
= 0;
1317 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1319 /* size of load command including section load commands */
1320 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1323 /* in an MH_OBJECT file all sections are in one unnamed (name
1324 ** all zeros) segment */
1325 fwritezero(16, ofile
);
1326 fwriteptr(0, ofile
); /* in-memory offset */
1327 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1328 fwriteptr(offset
, ofile
); /* in-file offset to data */
1329 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1330 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1331 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1332 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1333 fwriteint32_t(0, ofile
); /* no flags */
1335 /* emit section headers */
1336 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1338 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1339 s
->flags
|= S_ATTR_LOC_RELOC
;
1341 s
->flags
|= S_ATTR_EXT_RELOC
;
1342 } else if (!xstrncmp(s
->segname
, "__DATA") &&
1343 !xstrncmp(s
->sectname
, "__const") &&
1345 !get_section_by_name("__TEXT", "__const")) {
1347 * The MachO equivalent to .rodata can be either
1348 * __DATA,__const or __TEXT,__const; the latter only if
1349 * there are no relocations. However, when mixed it is
1350 * better to specify the segments explicitly.
1352 xstrncpy(s
->segname
, "__TEXT");
1355 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1356 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1357 fwriteptr(s
->addr
, ofile
);
1358 fwriteptr(s
->size
, ofile
);
1360 /* dummy data for zerofill sections or proper values */
1361 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1362 nasm_assert(s
->pad
!= (uint32_t)-1);
1364 fwriteint32_t(offset
, ofile
);
1366 /* Write out section alignment, as a power of two.
1367 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1368 fwriteint32_t(s
->align
, ofile
);
1369 /* To be compatible with cctools as we emit
1370 a zero reloff if we have no relocations. */
1371 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1372 fwriteint32_t(s
->nreloc
, ofile
);
1374 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1376 fwriteint32_t(0, ofile
);
1377 fwriteint32_t(s
->align
, ofile
);
1378 fwriteint32_t(0, ofile
);
1379 fwriteint32_t(0, ofile
);
1382 fwriteint32_t(s
->flags
, ofile
); /* flags */
1383 fwriteint32_t(0, ofile
); /* reserved */
1384 fwriteptr(0, ofile
); /* reserved */
1387 rel_padcnt
= rel_base
- offset
;
1388 offset
= rel_base
+ s_reloff
;
1393 /* For a given chain of relocs r, write out the entire relocation
1394 chain to the object file. */
1396 static void macho_write_relocs (struct reloc
*r
)
1401 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1404 word2
|= r
->pcrel
<< 24;
1405 word2
|= r
->length
<< 25;
1406 word2
|= r
->ext
<< 27;
1407 word2
|= r
->type
<< 28;
1408 fwriteint32_t(word2
, ofile
); /* reloc data */
1413 /* Write out the section data. */
1414 static void macho_write_section (void)
1426 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1427 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1430 /* Like a.out Mach-O references things in the data or bss
1431 * sections by addresses which are actually relative to the
1432 * start of the _text_ section, in the _file_. See outaout.c
1433 * for more information. */
1434 saa_rewind(s
->data
);
1435 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1436 len
= (uint32_t)1 << r
->length
;
1437 if (len
> 4) /* Can this ever be an issue?! */
1440 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1442 /* get offset based on relocation type */
1443 #ifdef WORDS_LITTLEENDIAN
1447 l
+= ((int64_t)blk
.buf
[1]) << 8;
1448 l
+= ((int64_t)blk
.buf
[2]) << 16;
1449 l
+= ((int64_t)blk
.buf
[3]) << 24;
1450 l
+= ((int64_t)blk
.buf
[4]) << 32;
1451 l
+= ((int64_t)blk
.buf
[5]) << 40;
1452 l
+= ((int64_t)blk
.buf
[6]) << 48;
1453 l
+= ((int64_t)blk
.buf
[7]) << 56;
1456 /* If the relocation is internal add to the current section
1457 offset. Otherwise the only value we need is the symbol
1458 offset which we already have. The linker takes care
1459 of the rest of the address. */
1461 /* generate final address by section address and offset */
1462 nasm_assert(r
->snum
<= seg_nsects
);
1463 l
+= sectstab
[r
->snum
]->addr
;
1466 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1470 /* write new offset back */
1473 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1476 /* dump the section data to file */
1477 fwritezero(s
->pad
, ofile
);
1478 saa_fpwrite(s
->data
, ofile
);
1481 /* pad last section up to reloc entries on pointer boundary */
1482 fwritezero(rel_padcnt
, ofile
);
1484 /* emit relocation entries */
1485 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1486 macho_write_relocs (s
->relocs
);
1489 /* Write out the symbol table. We should already have sorted this
1491 static void macho_write_symtab (void)
1496 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1498 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1499 if ((sym
->type
& N_EXT
) == 0) {
1500 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1501 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1502 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1503 fwriteint16_t(sym
->desc
, ofile
); /* description */
1505 /* Fix up the symbol value now that we know the final section
1507 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1508 nasm_assert(sym
->sect
<= seg_nsects
);
1509 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1512 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1516 for (i
= 0; i
< nextdefsym
; i
++) {
1517 sym
= extdefsyms
[i
];
1518 fwriteint32_t(sym
->strx
, ofile
);
1519 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1520 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1521 fwriteint16_t(sym
->desc
, ofile
); /* description */
1523 /* Fix up the symbol value now that we know the final section
1525 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1526 nasm_assert(sym
->sect
<= seg_nsects
);
1527 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1530 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1533 for (i
= 0; i
< nundefsym
; i
++) {
1535 fwriteint32_t(sym
->strx
, ofile
);
1536 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1537 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1538 fwriteint16_t(sym
->desc
, ofile
); /* description */
1540 /* Fix up the symbol value now that we know the final section
1542 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1543 nasm_assert(sym
->sect
<= seg_nsects
);
1544 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1547 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1552 /* Fixup the snum in the relocation entries, we should be
1553 doing this only for externally referenced symbols. */
1554 static void macho_fixup_relocs (struct reloc
*r
)
1560 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1561 if (sym
->initial_snum
== r
->snum
) {
1562 r
->snum
= sym
->snum
;
1571 /* Write out the object file. */
1573 static void macho_write (void)
1575 uint64_t offset
= 0;
1577 /* mach-o object file structure:
1583 ** uint32_t mach file type
1584 ** uint32_t number of load commands
1585 ** uint32_t size of all load commands
1586 ** (includes section struct size of segment command)
1590 ** uint32_t command type == LC_SEGMENT[_64]
1591 ** uint32_t size of load command
1592 ** (including section load commands)
1593 ** char[16] segment name
1594 ** pointer in-memory offset
1595 ** pointer in-memory size
1596 ** pointer in-file offset to data area
1597 ** pointer in-file size
1598 ** (in-memory size excluding zerofill sections)
1599 ** int maximum vm protection
1600 ** int initial vm protection
1601 ** uint32_t number of sections
1605 ** char[16] section name
1606 ** char[16] segment name
1607 ** pointer in-memory offset
1608 ** pointer in-memory size
1609 ** uint32_t in-file offset
1610 ** uint32_t alignment
1611 ** (irrelevant in MH_OBJECT)
1612 ** uint32_t in-file offset of relocation entires
1613 ** uint32_t number of relocations
1615 ** uint32_t reserved
1616 ** uint32_t reserved
1618 ** symbol table command
1619 ** uint32_t command type == LC_SYMTAB
1620 ** uint32_t size of load command
1621 ** uint32_t symbol table offset
1622 ** uint32_t number of symbol table entries
1623 ** uint32_t string table offset
1624 ** uint32_t string table size
1628 ** padding to pointer boundary
1630 ** relocation data (struct reloc)
1632 ** uint data (symbolnum, pcrel, length, extern, type)
1634 ** symbol table data (struct nlist)
1635 ** int32_t string table entry number
1637 ** (extern, absolute, defined in section)
1639 ** (0 for global symbols, section number of definition (>= 1, <=
1640 ** 254) for local symbols, size of variable for common symbols
1641 ** [type == extern])
1642 ** int16_t description
1643 ** (for stab debugging format)
1644 ** pointer value (i.e. file offset) of symbol or stab offset
1646 ** string table data
1647 ** list of null-terminated strings
1650 /* Emit the Mach-O header. */
1651 macho_write_header();
1653 offset
= fmt
.header_size
+ head_sizeofcmds
;
1655 /* emit the segment load command */
1657 offset
= macho_write_segment (offset
);
1659 nasm_error(ERR_WARNING
, "no sections?");
1662 /* write out symbol command */
1663 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1664 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1665 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1666 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1668 offset
+= nsyms
* fmt
.nlist_size
;
1669 fwriteint32_t(offset
, ofile
); /* string table offset */
1670 fwriteint32_t(strslen
, ofile
); /* string table size */
1673 /* emit section data */
1675 macho_write_section ();
1677 /* emit symbol table if we have symbols */
1679 macho_write_symtab ();
1681 /* we don't need to pad here, we are already aligned */
1683 /* emit string table */
1684 saa_fpwrite(strs
, ofile
);
1686 /* We do quite a bit here, starting with finalizing all of the data
1687 for the object file, writing, and then freeing all of the data from
1690 static void macho_cleanup(void)
1698 /* Sort all symbols. */
1699 macho_layout_symbols (&nsyms
, &strslen
);
1701 /* Fixup relocation entries */
1702 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1703 macho_fixup_relocs (s
->relocs
);
1706 /* First calculate and finalize needed values. */
1707 macho_calculate_sizes();
1710 /* free up everything */
1711 while (sects
->next
) {
1713 sects
= sects
->next
;
1716 while (s
->relocs
!= NULL
) {
1718 s
->relocs
= s
->relocs
->next
;
1735 nasm_free(extdefsyms
);
1736 nasm_free(undefsyms
);
1737 nasm_free(sectstab
);
1738 raa_free(section_by_index
);
1739 hash_free(§ion_by_name
);
1742 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1748 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1749 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1753 s
= get_section_by_index(nasm_seg
);
1755 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1764 * Mark a symbol for no dead stripping
1766 static enum directive_result
macho_no_dead_strip(const char *labels
)
1770 enum directive_result rv
= DIRR_ERROR
;
1771 bool real
= passn
> 1;
1773 p
= s
= nasm_strdup(labels
);
1775 ep
= nasm_skip_identifier(p
);
1777 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1781 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1782 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1787 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1791 p
= nasm_skip_spaces(ep
);
1793 p
= nasm_skip_spaces(++p
);
1806 static enum directive_result
1807 macho_pragma(const struct pragma
*pragma
)
1809 bool real
= passn
> 1;
1811 switch (pragma
->opcode
) {
1812 case D_SUBSECTIONS_VIA_SYMBOLS
:
1814 return DIRR_BADPARAM
;
1817 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1819 /* Jmp-match optimization conflicts */
1820 optimizing
.flag
|= OPTIM_DISABLE_JMP_MATCH
;
1824 case D_NO_DEAD_STRIP
:
1825 return macho_no_dead_strip(pragma
->tail
);
1828 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1832 static const struct pragma_facility macho_pragma_list
[] = {
1833 { "macho", macho_pragma
},
1834 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1837 static void macho_dbg_generate(void)
1839 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1840 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1841 struct section
*p_section
= NULL
;
1842 /* calculated at debug_str and referenced at debug_info */
1843 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1845 /* debug section defines */
1848 macho_section(".debug_abbrev", 0, &bits
);
1849 macho_section(".debug_info", 0, &bits
);
1850 macho_section(".debug_line", 0, &bits
);
1851 macho_section(".debug_str", 0, &bits
);
1854 /* dw section walk to find high_addr and total_len */
1856 struct dw_sect_list
*p_sect
;
1858 list_for_each(p_sect
, dw_head_sect
) {
1859 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1860 struct SAA
*p_linep
= p_sect
->psaa
;
1862 saa_write8(p_linep
, 2); /* std op 2 */
1863 saa_write8(p_linep
, offset
- p_sect
->offset
);
1864 saa_write8(p_linep
, DW_LNS_extended_op
);
1865 saa_write8(p_linep
, 1); /* operand length */
1866 saa_write8(p_linep
, DW_LNE_end_sequence
);
1868 total_len
+= p_linep
->datalen
;
1869 high_addr
+= offset
;
1875 struct dw_sect_list
*p_sect
;
1876 size_t linep_off
, buf_size
;
1877 struct SAA
*p_lines
= saa_init(1L);
1878 struct dir_list
*p_dir
;
1879 struct file_list
*p_file
;
1881 p_section
= get_section_by_name("__DWARF", "__debug_line");
1882 nasm_assert(p_section
!= NULL
);
1884 saa_write8(p_lines
, 1); /* minimum instruction length */
1885 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1886 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1887 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1888 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1889 saa_write8(p_lines
, 0); /* std opcode 1 length */
1890 saa_write8(p_lines
, 1); /* std opcode 2 length */
1891 saa_write8(p_lines
, 1); /* std opcode 3 length */
1892 saa_write8(p_lines
, 1); /* std opcode 4 length */
1893 saa_write8(p_lines
, 1); /* std opcode 5 length */
1894 saa_write8(p_lines
, 0); /* std opcode 6 length */
1895 saa_write8(p_lines
, 0); /* std opcode 7 length */
1896 saa_write8(p_lines
, 0); /* std opcode 8 length */
1897 saa_write8(p_lines
, 1); /* std opcode 9 length */
1898 saa_write8(p_lines
, 0); /* std opcode 10 length */
1899 saa_write8(p_lines
, 0); /* std opcode 11 length */
1900 saa_write8(p_lines
, 1); /* std opcode 12 length */
1901 list_for_each(p_dir
, dw_head_dir
) {
1902 saa_wcstring(p_lines
, p_dir
->dir_name
);
1904 saa_write8(p_lines
, 0); /* end of table */
1906 list_for_each(p_file
, dw_head_file
) {
1907 saa_wcstring(p_lines
, p_file
->file_name
);
1908 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1909 saa_write8(p_lines
, 0); /* time */
1910 saa_write8(p_lines
, 0); /* size */
1912 saa_write8(p_lines
, 0); /* end of table */
1914 linep_off
= p_lines
->datalen
;
1915 /* 10 bytes for initial & prolong length, and dwarf version info */
1916 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1917 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1919 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1920 WRITESHORT(p_buf
, 2); /* dwarf version */
1921 WRITELONG(p_buf
, linep_off
); /* prolong length */
1923 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1927 list_for_each(p_sect
, dw_head_sect
) {
1928 struct SAA
*p_linep
= p_sect
->psaa
;
1930 saa_len
= p_linep
->datalen
;
1931 saa_rnbytes(p_linep
, p_buf
, saa_len
);
1937 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
1939 nasm_free(p_buf_base
);
1942 /* string section */
1944 struct SAA
*p_str
= saa_init(1L);
1945 char *cur_path
= nasm_realpath(module_name
);
1946 char *cur_file
= nasm_basename(cur_path
);
1947 char *cur_dir
= nasm_dirname(cur_path
);
1949 p_section
= get_section_by_name("__DWARF", "__debug_str");
1950 nasm_assert(p_section
!= NULL
);
1952 producer_str_offset
= 0;
1953 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
1954 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
1955 saa_wcstring(p_str
, cur_dir
);
1957 saa_len
= p_str
->datalen
;
1958 p_buf
= nasm_malloc(saa_len
);
1959 saa_rnbytes(p_str
, p_buf
, saa_len
);
1960 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
1962 nasm_free(cur_path
);
1963 nasm_free(cur_file
);
1971 struct SAA
*p_info
= saa_init(1L);
1973 p_section
= get_section_by_name("__DWARF", "__debug_info");
1974 nasm_assert(p_section
!= NULL
);
1976 /* size will be overwritten once determined, so skip in p_info layout */
1977 saa_write16(p_info
, 2); /* dwarf version */
1978 saa_write32(p_info
, 0); /* offset info abbrev */
1979 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
1981 saa_write8(p_info
, 1); /* abbrev entry number */
1983 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
1984 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
1985 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
1986 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
1987 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
1989 if (ofmt
== &of_macho64
) {
1990 saa_write64(p_info
, 0); /* DW_AT_low_pc */
1991 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
1993 saa_write32(p_info
, 0); /* DW_AT_low_pc */
1994 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
1997 saa_write8(p_info
, 2); /* abbrev entry number */
1999 if (ofmt
== &of_macho64
) {
2000 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2001 saa_write64(p_info
, 0); /* DW_AT_frame_base */
2003 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2004 saa_write32(p_info
, 0); /* DW_AT_frame_base */
2006 saa_write8(p_info
, DW_END_default
);
2008 saa_len
= p_info
->datalen
;
2009 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
2011 WRITELONG(p_buf
, saa_len
);
2012 saa_rnbytes(p_info
, p_buf
, saa_len
);
2013 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
2016 nasm_free(p_buf_base
);
2019 /* abbrev section */
2021 struct SAA
*p_abbrev
= saa_init(1L);
2023 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
2024 nasm_assert(p_section
!= NULL
);
2026 saa_write8(p_abbrev
, 1); /* entry number */
2028 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2029 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2031 saa_write8(p_abbrev
, DW_AT_producer
);
2032 saa_write8(p_abbrev
, DW_FORM_strp
);
2034 saa_write8(p_abbrev
, DW_AT_language
);
2035 saa_write8(p_abbrev
, DW_FORM_data2
);
2037 saa_write8(p_abbrev
, DW_AT_name
);
2038 saa_write8(p_abbrev
, DW_FORM_strp
);
2040 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2041 saa_write8(p_abbrev
, DW_FORM_strp
);
2043 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2044 saa_write8(p_abbrev
, DW_FORM_data4
);
2046 saa_write8(p_abbrev
, DW_AT_low_pc
);
2047 saa_write8(p_abbrev
, DW_FORM_addr
);
2049 saa_write8(p_abbrev
, DW_AT_high_pc
);
2050 saa_write8(p_abbrev
, DW_FORM_addr
);
2052 saa_write16(p_abbrev
, DW_END_default
);
2054 saa_write8(p_abbrev
, 2); /* entry number */
2056 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2057 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2059 saa_write8(p_abbrev
, DW_AT_low_pc
);
2060 saa_write8(p_abbrev
, DW_FORM_addr
);
2062 saa_write8(p_abbrev
, DW_AT_frame_base
);
2063 saa_write8(p_abbrev
, DW_FORM_addr
);
2065 saa_write16(p_abbrev
, DW_END_default
);
2067 saa_write8(p_abbrev
, 0); /* Terminal zero entry */
2069 saa_len
= p_abbrev
->datalen
;
2071 p_buf
= nasm_malloc(saa_len
);
2073 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2074 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2081 static void new_file_list (const char *file_name
, const char *dir_name
)
2083 struct dir_list
*dir_list
;
2084 bool need_new_dir_list
= true;
2086 nasm_new(dw_cur_file
);
2087 dw_cur_file
->file
= ++dw_num_files
;
2088 dw_cur_file
->file_name
= file_name
;
2090 dw_head_file
= dw_cur_file
;
2092 *dw_last_file_next
= dw_cur_file
;
2094 dw_last_file_next
= &(dw_cur_file
->next
);
2097 list_for_each(dir_list
, dw_head_dir
) {
2098 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2099 dw_cur_file
->dir
= dir_list
;
2100 need_new_dir_list
= false;
2106 if(need_new_dir_list
)
2109 dir_list
->dir
= dw_num_dirs
++;
2110 dir_list
->dir_name
= dir_name
;
2112 dw_head_dir
= dir_list
;
2114 *dw_last_dir_next
= dir_list
;
2116 dw_last_dir_next
= &(dir_list
->next
);
2117 dw_cur_file
->dir
= dir_list
;
2121 static void macho_dbg_init(void)
2125 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2127 bool need_new_list
= true;
2128 const char *cur_file
= nasm_basename(file_name
);
2129 const char *cur_dir
= nasm_dirname(file_name
);
2132 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2133 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2135 struct file_list
*match
;
2137 list_for_each(match
, dw_head_file
) {
2138 if(!(strcmp(cur_file
, match
->file_name
)) &&
2139 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2140 dw_cur_file
= match
;
2141 dw_cur_file
->dir
= match
->dir
;
2142 need_new_list
= false;
2149 new_file_list(cur_file
, cur_dir
);
2154 cur_line
= line_num
;
2157 static void macho_dbg_output(int type
, void *param
)
2159 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2160 int32_t secto
= sinfo_param
->secto
;
2161 bool need_new_sect
= false;
2162 struct SAA
*p_linep
= NULL
;
2165 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2166 need_new_sect
= true;
2168 struct dw_sect_list
*match
= dw_head_sect
;
2171 for(; idx
< dw_num_sects
; idx
++) {
2172 if(match
->section
== secto
) {
2173 dw_cur_sect
= match
;
2174 need_new_sect
= false;
2177 match
= match
->next
;
2183 nasm_new(dw_cur_sect
);
2185 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2186 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2187 dw_cur_sect
->offset
= 0;
2188 dw_cur_sect
->next
= NULL
;
2189 dw_cur_sect
->section
= secto
;
2191 saa_write8(p_linep
, DW_LNS_extended_op
);
2192 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2193 saa_write8(p_linep
, DW_LNE_set_address
);
2194 if (ofmt
== &of_macho64
) {
2195 saa_write64(p_linep
, 0);
2197 saa_write32(p_linep
, 0);
2201 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2203 dw_last_sect
->next
= dw_cur_sect
;
2204 dw_last_sect
= dw_cur_sect
;
2208 if(dbg_immcall
== true) {
2209 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2210 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2211 uint32_t cur_file
= dw_cur_file
->file
;
2212 p_linep
= dw_cur_sect
->psaa
;
2214 if(cur_file
!= dw_cur_sect
->file
) {
2215 saa_write8(p_linep
, DW_LNS_set_file
);
2216 saa_write8(p_linep
, cur_file
);
2217 dw_cur_sect
->file
= cur_file
;
2221 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2224 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2225 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2226 saa_write8(p_linep
, special_opcode
);
2228 saa_write8(p_linep
, DW_LNS_advance_line
);
2229 saa_wleb128s(p_linep
, line_delta
);
2231 saa_write8(p_linep
, DW_LNS_advance_pc
);
2232 saa_wleb128u(p_linep
, offset_delta
);
2234 saa_write8(p_linep
, DW_LNS_copy
);
2237 dw_cur_sect
->line
= cur_line
;
2238 dw_cur_sect
->offset
= sinfo_param
->size
;
2241 dbg_immcall
= false;
2245 static void macho_dbg_cleanup(void)
2247 /* dwarf sectors generation */
2248 macho_dbg_generate();
2251 struct dw_sect_list
*p_sect
= dw_head_sect
;
2252 struct file_list
*p_file
= dw_head_file
;
2255 for(; idx
< dw_num_sects
; idx
++) {
2256 struct dw_sect_list
*next
= p_sect
->next
;
2261 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2262 struct file_list
*next
= p_file
->next
;
2270 static const struct macho_fmt macho32_fmt
= {
2280 GENERIC_RELOC_VANILLA
,
2281 GENERIC_RELOC_VANILLA
,
2283 false /* Allow segment-relative relocations */
2286 static void macho32_init(void)
2291 macho_gotpcrel_sect
= NO_SEG
;
2294 static const struct dfmt macho32_df_dwarf
= {
2295 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2299 null_debug_deflabel
,
2300 null_debug_directive
,
2301 null_debug_typevalue
,
2304 NULL
/*pragma list*/
2307 static const struct dfmt
* const macho32_df_arr
[2] =
2308 { &macho32_df_dwarf
, NULL
};
2310 const struct ofmt of_macho32
= {
2311 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2321 nasm_do_legacy_output
,
2335 static const struct macho_fmt macho64_fmt
= {
2340 MACHO_HEADER64_SIZE
,
2341 MACHO_SEGCMD64_SIZE
,
2342 MACHO_SECTCMD64_SIZE
,
2345 X86_64_RELOC_UNSIGNED
,
2346 X86_64_RELOC_SIGNED
,
2348 true /* Force symbol-relative relocations */
2351 static void macho64_init(void)
2356 /* add special symbol for ..gotpcrel */
2357 macho_gotpcrel_sect
= seg_alloc() + 1;
2358 backend_label("..gotpcrel", macho_gotpcrel_sect
, 0L);
2361 static const struct dfmt macho64_df_dwarf
= {
2362 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2366 null_debug_deflabel
,
2367 null_debug_directive
,
2368 null_debug_typevalue
,
2371 NULL
/*pragma list*/
2374 static const struct dfmt
* const macho64_df_arr
[2] =
2375 { &macho64_df_dwarf
, NULL
};
2377 const struct ofmt of_macho64
= {
2378 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2388 nasm_do_legacy_output
,