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
60 #if defined(OF_MACHO) || defined(OF_MACHO64)
62 /* Mach-O in-file header structure sizes */
63 #define MACHO_HEADER_SIZE 28
64 #define MACHO_SEGCMD_SIZE 56
65 #define MACHO_SECTCMD_SIZE 68
66 #define MACHO_SYMCMD_SIZE 24
67 #define MACHO_NLIST_SIZE 12
68 #define MACHO_RELINFO_SIZE 8
70 #define MACHO_HEADER64_SIZE 32
71 #define MACHO_SEGCMD64_SIZE 72
72 #define MACHO_SECTCMD64_SIZE 80
73 #define MACHO_NLIST64_SIZE 16
75 /* Mach-O file header values */
76 #define MH_MAGIC 0xfeedface
77 #define MH_MAGIC_64 0xfeedfacf
78 #define CPU_TYPE_I386 7 /* x86 platform */
79 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
80 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
81 #define MH_OBJECT 0x1 /* object file */
83 /* Mach-O header flags */
84 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
86 /* Mach-O load commands */
87 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
88 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
89 #define LC_SYMTAB 0x2 /* symbol table load command */
91 /* Mach-O relocations numbers */
93 /* Generic relocs, used by i386 Mach-O */
94 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
95 #define GENERIC_RELOC_TLV 5 /* Thread local */
97 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
98 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
99 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
100 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
101 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
102 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
103 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
104 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
105 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
106 #define X86_64_RELOC_TLV 9 /* Thread local */
108 /* Mach-O VM permission constants */
109 #define VM_PROT_NONE (0x00)
110 #define VM_PROT_READ (0x01)
111 #define VM_PROT_WRITE (0x02)
112 #define VM_PROT_EXECUTE (0x04)
114 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
115 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
117 /* Our internal relocation types */
119 RL_ABS
, /* Absolute relocation */
120 RL_REL
, /* Relative relocation */
121 RL_TLV
, /* Thread local */
122 RL_BRANCH
, /* Relative direct branch */
123 RL_SUB
, /* X86_64_RELOC_SUBTRACT */
124 RL_GOT
, /* X86_64_RELOC_GOT */
125 RL_GOTLOAD
/* X86_64_RELOC_GOT_LOAD */
127 #define RL_MAX_32 RL_TLV
128 #define RL_MAX_64 RL_GOTLOAD
131 uint32_t ptrsize
; /* Pointer size in bytes */
132 uint32_t mh_magic
; /* Which magic number to use */
133 uint32_t cpu_type
; /* Which CPU type */
134 uint32_t lc_segment
; /* Which segment load command */
135 uint32_t header_size
; /* Header size */
136 uint32_t segcmd_size
; /* Segment command size */
137 uint32_t sectcmd_size
; /* Section command size */
138 uint32_t nlist_size
; /* Nlist (symbol) size */
139 enum reltype maxreltype
; /* Maximum entry in enum reltype permitted */
140 uint32_t reloc_abs
; /* Absolute relocation type */
141 uint32_t reloc_rel
; /* Relative relocation type */
142 uint32_t reloc_tlv
; /* Thread local relocation type */
143 bool forcesym
; /* Always use "external" (symbol-relative) relocations */
146 static struct macho_fmt fmt
;
148 static void fwriteptr(uint64_t data
, FILE * fp
)
150 fwriteaddr(data
, fmt
.ptrsize
, fp
);
154 /* nasm internal data */
155 struct section
*next
;
157 int32_t index
; /* Main section index */
158 int32_t subsection
; /* Current subsection index */
160 struct reloc
*relocs
;
161 struct rbtree
*syms
[2]; /* All/global symbols symbols in section */
163 bool by_name
; /* This section was specified by full MachO name */
164 char namestr
[34]; /* segment,section as a C string */
166 /* data that goes into the file */
167 char sectname
[16]; /* what this section is called */
168 char segname
[16]; /* segment this section will be in */
169 uint64_t addr
; /* in-memory address (subject to alignment) */
170 uint64_t size
; /* in-memory and -file size */
171 uint64_t offset
; /* in-file offset */
172 uint32_t pad
; /* padding bytes before section */
173 uint32_t nreloc
; /* relocation entry count */
174 uint32_t flags
; /* type and attributes (masked) */
175 uint32_t extreloc
; /* external relocations */
178 #define SECTION_TYPE 0x000000ff /* section type mask */
180 #define S_REGULAR (0x0) /* standard section */
181 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
183 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
184 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
185 machine instructions */
186 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
187 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
188 #define S_ATTR_DEBUG 0x02000000
189 #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
190 #define S_ATTR_LIVE_SUPPORT 0x08000000
191 #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
192 #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
193 #define S_ATTR_NO_TOC 0x40000000
194 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
195 #define S_ATTR_DEBUG 0x02000000 /* debug section */
197 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
199 /* fake section for absolute symbols, *not* part of the section linked list */
200 static struct section absolute_sect
;
203 /* nasm internal data */
206 /* data that goes into the file */
207 int32_t addr
; /* op's offset in section */
208 uint32_t snum
:24, /* contains symbol index if
209 ** ext otherwise in-file
211 pcrel
:1, /* relative relocation */
212 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
213 ext
:1, /* external symbol referenced */
214 type
:4; /* reloc type */
217 #define R_ABS 0 /* absolute relocation */
218 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
219 ** highest bit == 1 */
222 /* nasm internal data */
223 struct rbtree symv
[2]; /* All/global symbol rbtrees; "key" contains the
225 struct symbol
*next
; /* next symbol in the list */
226 char *name
; /* name of this symbol */
227 int32_t initial_snum
; /* symbol number used above in reloc */
228 int32_t snum
; /* true snum for reloc */
230 /* data that goes into the file */
231 uint32_t strx
; /* string table index */
232 uint8_t type
; /* symbol type */
233 uint8_t sect
; /* NO_SECT or section number */
234 uint16_t desc
; /* for stab debugging, 0 for us */
237 /* symbol type bits */
238 #define N_EXT 0x01 /* global or external symbol */
239 #define N_PEXT 0x10 /* private external symbol */
241 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
242 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
243 #define N_SECT 0xe /* defined symbol, n_sect holds
246 #define N_TYPE 0x0e /* type bit mask */
248 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
250 /* special section number values */
251 #define NO_SECT 0 /* no section, invalid */
252 #define MAX_SECT 255 /* maximum number of sections */
254 static struct section
*sects
, **sectstail
, **sectstab
;
255 static struct symbol
*syms
, **symstail
;
256 static uint32_t nsyms
;
258 /* These variables are set by macho_layout_symbols() to organize
259 the symbol table and string table in order the dynamic linker
260 expects. They are then used in macho_write() to put out the
261 symbols and strings in that order.
263 The order of the symbol table is:
265 defined external symbols (sorted by name)
266 undefined external symbols (sorted by name)
268 The order of the string table is:
269 strings for external symbols
270 strings for local symbols
272 static uint32_t ilocalsym
= 0;
273 static uint32_t iextdefsym
= 0;
274 static uint32_t iundefsym
= 0;
275 static uint32_t nlocalsym
;
276 static uint32_t nextdefsym
;
277 static uint32_t nundefsym
;
278 static struct symbol
**extdefsyms
= NULL
;
279 static struct symbol
**undefsyms
= NULL
;
281 static struct RAA
*extsyms
;
282 static struct SAA
*strs
;
283 static uint32_t strslen
;
285 /* Global file information. This should be cleaned up into either
286 a structure or as function arguments. */
287 static uint32_t head_ncmds
= 0;
288 static uint32_t head_sizeofcmds
= 0;
289 static uint32_t head_flags
= 0;
290 static uint64_t seg_filesize
= 0;
291 static uint64_t seg_vmsize
= 0;
292 static uint32_t seg_nsects
= 0;
293 static uint64_t rel_padcnt
= 0;
296 * Functions for handling fixed-length zero-padded string
297 * fields, that may or may not be null-terminated.
300 /* Copy a string into a zero-padded fixed-length field */
301 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
303 /* Compare a fixed-length field with a string */
304 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
306 #define alignint32_t(x) \
307 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
309 #define alignint64_t(x) \
310 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
312 #define alignptr(x) \
313 ALIGN(x, fmt.ptrsize) /* align x to output format width */
315 static struct hash_table section_by_name
;
316 static struct RAA
*section_by_index
;
318 static struct section
* never_null
319 find_or_add_section(const char *segname
, const char *sectname
)
321 struct hash_insert hi
;
326 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
328 sp
= hash_find(§ion_by_name
, sect
, &hi
);
330 return (struct section
*)(*sp
);
332 s
= nasm_zalloc(sizeof *s
);
333 xstrncpy(s
->segname
, segname
);
334 xstrncpy(s
->sectname
, sectname
);
335 xstrncpy(s
->namestr
, sect
);
336 hash_add(&hi
, s
->namestr
, s
);
338 s
->index
= s
->subsection
= seg_alloc();
339 section_by_index
= raa_write_ptr(section_by_index
, s
->index
>> 1, s
);
344 static inline bool is_new_section(const struct section
*s
)
349 static struct section
*get_section_by_name(const char *segname
,
350 const char *sectname
)
355 snprintf(sect
, sizeof sect
, "%-16s,%-16s", segname
, sectname
);
357 sp
= hash_find(§ion_by_name
, sect
, NULL
);
358 return sp
? (struct section
*)(*sp
) : NULL
;
361 static struct section
*get_section_by_index(int32_t index
)
363 if (index
< 0 || index
>= SEG_ABS
|| (index
& 1))
366 return (struct section
*)raa_read(section_by_index
, index
>> 1);
370 struct dir_list
*next
;
371 struct dir_list
*last
;
372 const char *dir_name
;
377 struct file_list
*next
;
378 struct file_list
*last
;
379 const char *file_name
;
381 struct dir_list
*dir
;
384 struct dw_sect_list
{
390 struct dw_sect_list
*next
;
391 struct dw_sect_list
*last
;
394 struct section_info
{
399 #define DW_LN_BASE (-5)
400 #define DW_LN_RANGE 14
401 #define DW_OPCODE_BASE 13
402 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
403 #define DW_MAX_SP_OPCODE 256
405 static struct file_list
*dw_head_file
= 0, *dw_cur_file
= 0, **dw_last_file_next
= NULL
;
406 static struct dir_list
*dw_head_dir
= 0, **dw_last_dir_next
= NULL
;
407 static struct dw_sect_list
*dw_head_sect
= 0, *dw_cur_sect
= 0, *dw_last_sect
= 0;
408 static uint32_t cur_line
= 0, dw_num_files
= 0, dw_num_dirs
= 0, dw_num_sects
= 0;
409 static bool dbg_immcall
= false;
410 static const char *module_name
= NULL
;
413 * Special section numbers which are used to define Mach-O special
414 * symbols, which can be used with WRT to provide PIC relocation
417 static int32_t macho_tlvp_sect
;
418 static int32_t macho_gotpcrel_sect
;
420 static void macho_init(void)
422 module_name
= inname
;
426 /* Fake section for absolute symbols */
427 absolute_sect
.index
= NO_SEG
;
436 extsyms
= raa_init();
439 section_by_index
= raa_init();
440 hash_init(§ion_by_name
, HASH_MEDIUM
);
442 /* string table starts with a zero byte so index 0 is an empty string */
443 saa_wbytes(strs
, zero_buffer
, 1);
446 /* add special symbol for TLVP */
447 macho_tlvp_sect
= seg_alloc() + 1;
448 backend_label("..tlvp", macho_tlvp_sect
, 0L);
451 static void sect_write(struct section
*sect
,
452 const uint8_t *data
, uint32_t len
)
454 saa_wbytes(sect
->data
, data
, len
);
459 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
461 static struct symbol
*macho_find_sym(struct section
*s
, uint64_t offset
,
462 bool global
, bool exact
)
466 srb
= rb_search(s
->syms
[global
], offset
);
468 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
469 nasm_error(ERR_NONFATAL
, "unable to find a suitable%s%s symbol"
470 " for this reference",
471 global
? " global" : "",
472 s
== &absolute_sect
? " absolute " : "");
476 return container_of(srb
- global
, struct symbol
, symv
);
479 static int64_t add_reloc(struct section
*sect
, int32_t section
,
481 enum reltype reltype
, int bytes
)
488 /* Double check this is a valid relocation type for this platform */
489 nasm_assert(reltype
<= fmt
.maxreltype
);
491 /* the current end of the section will be the symbol's address for
492 ** now, might have to be fixed by macho_fixup_relocs() later on. make
493 ** sure we don't make the symbol scattered by setting the highest
494 ** bit by accident */
495 r
= nasm_malloc(sizeof(struct reloc
));
496 r
->addr
= sect
->size
& ~R_SCATTERED
;
500 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
501 r
->length
= ilog2_32(bytes
);
503 /* set default relocation values */
504 r
->type
= fmt
.reloc_abs
;
508 s
= get_section_by_index(section
);
509 fi
= s
? s
->fileindex
: NO_SECT
;
511 /* absolute relocation */
514 if (section
== NO_SEG
) {
515 /* absolute (can this even happen?) */
518 } else if (fi
== NO_SECT
) {
520 r
->snum
= raa_read(extsyms
, section
);
525 adjust
= -sect
->size
;
531 r
->type
= fmt
.reloc_rel
;
533 if (section
== NO_SEG
) {
534 /* absolute - seems to produce garbage no matter what */
535 nasm_error(ERR_NONFATAL
, "Mach-O does not support relative "
536 "references to absolute addresses");
539 /* This "seems" to be how it ought to work... */
541 struct symbol
*sym
= macho_find_sym(&absolute_sect
, offset
,
548 adjust
= -sect
->size
;
550 } else if (fi
== NO_SECT
) {
553 r
->snum
= raa_read(extsyms
, section
);
554 if (reltype
== RL_BRANCH
)
555 r
->type
= X86_64_RELOC_BRANCH
;
556 else if (r
->type
== GENERIC_RELOC_VANILLA
)
557 adjust
= -sect
->size
;
562 adjust
= -sect
->size
;
568 r
->type
= X86_64_RELOC_SUBTRACTOR
;
572 r
->type
= X86_64_RELOC_GOT
;
576 r
->type
= X86_64_RELOC_GOT_LOAD
;
580 r
->type
= fmt
.reloc_tlv
;
585 if (section
== NO_SEG
) {
586 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
587 } else if (fi
== NO_SECT
) {
589 r
->snum
= raa_read(extsyms
, section
);
591 /* internal - does it really need to be global? */
592 struct symbol
*sym
= macho_find_sym(s
, offset
, true,
597 r
->snum
= sym
->initial_snum
;
602 /* For 64-bit Mach-O, force a symbol reference if at all possible */
603 if (!r
->ext
&& r
->snum
!= NO_SECT
&& fmt
.forcesym
) {
604 struct symbol
*sym
= macho_find_sym(s
, offset
, false, false);
606 adjust
= bytes
- sym
->symv
[0].key
;
607 r
->snum
= sym
->initial_snum
;
612 /* NeXT as puts relocs in reversed order (address-wise) into the
613 ** files, so we do the same, doesn't seem to make much of a
614 ** difference either way */
615 r
->next
= sect
->relocs
;
628 static void macho_output(int32_t secto
, const void *data
,
629 enum out_type type
, uint64_t size
,
630 int32_t section
, int32_t wrt
)
633 int64_t addr
, offset
;
634 uint8_t mydata
[16], *p
;
636 enum reltype reltype
;
638 s
= get_section_by_index(secto
);
640 nasm_error(ERR_WARNING
, "attempt to assemble code in"
641 " section %d: defaulting to `.text'", secto
);
642 s
= get_section_by_name("__TEXT", "__text");
644 /* should never happen */
646 nasm_panic(0, "text section not found");
649 /* debug code generation only for sections tagged with
650 * instruction attribute */
651 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
653 struct section_info sinfo
;
654 sinfo
.size
= s
->size
;
656 dfmt
->debug_output(0, &sinfo
);
659 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
661 if (is_bss
&& type
!= OUT_RESERVE
) {
662 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
663 "BSS section: ignored");
664 s
->size
+= realsize(type
, size
);
668 memset(mydata
, 0, sizeof(mydata
));
673 nasm_error(ERR_WARNING
, "uninitialized space declared in"
674 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
676 sect_write(s
, NULL
, size
);
683 sect_write(s
, data
, size
);
688 int asize
= abs((int)size
);
690 addr
= *(int64_t *)data
;
691 if (section
!= NO_SEG
) {
693 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
694 " section base references");
695 } else if (wrt
== NO_SEG
) {
696 if (fmt
.ptrsize
== 8 && asize
!= 8) {
697 nasm_error(ERR_NONFATAL
,
698 "Mach-O 64-bit format does not support"
699 " 32-bit absolute addresses");
701 add_reloc(s
, section
, addr
, RL_ABS
, asize
);
704 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
710 WRITEADDR(p
, addr
, asize
);
711 sect_write(s
, mydata
, asize
);
719 offset
= *(int64_t *)data
;
720 addr
= offset
- size
;
722 if (section
!= NO_SEG
&& section
% 2) {
723 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
724 " section base references");
725 } else if (fmt
.ptrsize
== 8) {
726 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
727 " Macho-O relocation [2]");
728 } else if (wrt
!= NO_SEG
) {
729 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
731 wrt
= NO_SEG
; /* we can at least _try_ to continue */
733 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
,
734 type
== OUT_REL1ADR
? 1 : 2);
738 sect_write(s
, mydata
, type
== OUT_REL1ADR
? 1 : 2);
745 offset
= *(int64_t *)data
;
746 addr
= offset
- size
;
749 if (section
!= NO_SEG
&& section
% 2) {
750 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
751 " section base references");
752 } else if (wrt
== NO_SEG
) {
753 if (fmt
.ptrsize
== 8 &&
754 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
757 opcode
[0] = opcode
[1] = 0;
759 /* HACK: Retrieve instruction opcode */
760 if (likely(s
->data
->datalen
>= 2)) {
761 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
762 } else if (s
->data
->datalen
== 1) {
763 saa_fread(s
->data
, 0, opcode
+1, 1);
766 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
767 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
768 /* Direct call, jmp, or jcc */
772 } else if (wrt
== macho_gotpcrel_sect
) {
775 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
776 s
->data
->datalen
>= 3) {
779 /* HACK: Retrieve instruction opcode */
780 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
781 if ((gotload
[0] & 0xf8) == 0x48 &&
782 gotload
[1] == 0x8b &&
783 (gotload
[2] & 0307) == 0005) {
784 /* movq <reg>,[rel sym wrt ..gotpcrel] */
785 reltype
= RL_GOTLOAD
;
788 } else if (wrt
== macho_tlvp_sect
) {
791 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
793 /* continue with RL_REL */
796 addr
+= add_reloc(s
, section
, offset
, reltype
,
797 type
== OUT_REL4ADR
? 4 : 8);
799 sect_write(s
, mydata
, type
== OUT_REL4ADR
? 4 : 8);
803 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
808 /* Translation table from traditional Unix section names to Mach-O */
809 static const struct sectmap
{
810 const char *nasmsect
;
812 const char *sectname
;
813 const uint32_t flags
;
815 {".text", "__TEXT", "__text",
816 S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
817 {".data", "__DATA", "__data", S_REGULAR
},
818 {".rodata", "__DATA", "__const", S_REGULAR
},
819 {".bss", "__DATA", "__bss", S_ZEROFILL
},
820 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
821 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
822 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
823 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
824 {NULL
, NULL
, NULL
, 0}
827 #define NO_TYPE S_NASM_TYPE_MASK
829 /* Section type or attribute directives */
830 static const struct sect_attribs
{
834 { "data", S_REGULAR
},
835 { "code", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
836 { "mixed", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
837 { "bss", S_ZEROFILL
},
838 { "zerofill", S_ZEROFILL
},
839 { "no_dead_strip", NO_TYPE
|S_ATTR_NO_DEAD_STRIP
},
840 { "live_support", NO_TYPE
|S_ATTR_LIVE_SUPPORT
},
841 { "strip_static_syms", NO_TYPE
|S_ATTR_STRIP_STATIC_SYMS
},
842 { "debug", NO_TYPE
|S_ATTR_DEBUG
},
846 static int32_t macho_section(char *name
, int pass
, int *bits
)
848 char *sectionAttributes
;
849 const struct sectmap
*sm
;
851 const char *section
, *segment
;
853 const struct sect_attribs
*sa
;
854 char *currentAttribute
;
861 /* Default to the appropriate number of bits. */
863 *bits
= fmt
.ptrsize
<< 3;
865 sectionAttributes
= NULL
;
867 sectionAttributes
= name
;
868 name
= nasm_strsep(§ionAttributes
, " \t");
871 section
= segment
= NULL
;
874 comma
= strchr(name
, ',');
882 len
= strlen(segment
);
884 nasm_error(ERR_NONFATAL
, "empty segment name\n");
885 } else if (len
> 16) {
886 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
889 len
= strlen(section
);
891 nasm_error(ERR_NONFATAL
, "empty section name\n");
892 } else if (len
> 16) {
893 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
896 if (!strcmp(section
, "__text")) {
897 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
898 S_ATTR_PURE_INSTRUCTIONS
;
899 } else if (!strcmp(section
, "__bss")) {
905 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
906 /* make lookup into section name translation table */
907 if (!strcmp(name
, sm
->nasmsect
)) {
908 segment
= sm
->segname
;
909 section
= sm
->sectname
;
914 nasm_error(ERR_NONFATAL
, "unknown section name\n");
919 /* try to find section with that name, or create it */
920 s
= find_or_add_section(segment
, section
);
921 new_seg
= is_new_section(s
);
923 /* initialize it if it is a brand new section */
926 sectstail
= &s
->next
;
928 s
->data
= saa_init(1L);
929 s
->fileindex
= ++seg_nsects
;
941 *comma
= ','; /* Restore comma */
943 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
947 while (sectionAttributes
&&
948 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
949 if (!*currentAttribute
)
952 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
954 int newAlignment
, value
;
956 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
957 newAlignment
= alignlog2_32(value
);
960 nasm_error(ERR_NONFATAL
,
961 "unknown or missing alignment value \"%s\" "
962 "specified for section \"%s\"",
963 currentAttribute
+ 6,
965 } else if (0 > newAlignment
) {
966 nasm_error(ERR_NONFATAL
,
967 "alignment of %d (for section \"%s\") is not "
973 if (s
->align
< newAlignment
)
974 s
->align
= newAlignment
;
976 for (sa
= sect_attribs
; sa
->name
; sa
++) {
977 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
978 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
979 flags
= (flags
& ~S_NASM_TYPE_MASK
)
980 | (sa
->flags
& S_NASM_TYPE_MASK
);
982 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
988 nasm_error(ERR_NONFATAL
,
989 "unknown section attribute %s for section %s",
990 currentAttribute
, name
);
995 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
996 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
997 nasm_error(ERR_NONFATAL
,
998 "inconsistent section attributes for section %s\n",
1001 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
1004 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
1007 return s
->subsection
;
1010 static int32_t macho_herelabel(const char *name
, enum label_type type
,
1011 int32_t section
, int32_t *subsection
)
1017 if (!(head_flags
& MH_SUBSECTIONS_VIA_SYMBOLS
))
1020 /* No subsection only for local labels */
1021 if (type
== LBL_LOCAL
)
1024 s
= get_section_by_index(section
);
1028 subsec
= *subsection
;
1029 if (subsec
== NO_SEG
) {
1030 /* Allocate a new subsection index */
1031 subsec
= *subsection
= seg_alloc();
1032 section_by_index
= raa_write_ptr(section_by_index
, subsec
>> 1, s
);
1035 s
->subsection
= subsec
;
1039 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
1040 int is_global
, char *special
)
1044 bool special_used
= false;
1046 #if defined(DEBUG) && DEBUG>2
1047 nasm_error(ERR_DEBUG
,
1048 " macho_symdef: %s, sec=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
1049 name
, section
, offset
, is_global
, special
);
1052 if (is_global
== 3) {
1054 int n
= strcspn(special
, " \t");
1056 if (!nasm_strnicmp(special
, "private_extern", n
)) {
1057 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1058 if (!strcmp(name
, sym
->name
)) {
1059 if (sym
->type
& N_PEXT
)
1060 return; /* nothing to be done */
1067 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
1068 "(yet) support forward reference fixups.");
1072 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1074 * This is a NASM special symbol. We never allow it into
1075 * the Macho-O symbol table, even if it's a valid one. If it
1076 * _isn't_ a valid one, we should barf immediately.
1078 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1079 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1083 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1085 symstail
= &sym
->next
;
1088 sym
->strx
= strslen
;
1091 sym
->symv
[0].key
= offset
;
1092 sym
->symv
[1].key
= offset
;
1093 sym
->initial_snum
= -1;
1095 /* external and common symbols get N_EXT */
1096 if (is_global
!= 0) {
1099 if (is_global
== 1) {
1100 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1102 int n
= strcspn(special
, " \t");
1104 if (!nasm_strnicmp(special
, "private_extern", n
))
1105 sym
->type
|= N_PEXT
;
1107 nasm_error(ERR_NONFATAL
, "unrecognised symbol type `%.*s'", n
, special
);
1109 special_used
= true;
1112 if (section
== NO_SEG
) {
1113 /* symbols in no section get absolute */
1115 sym
->sect
= NO_SECT
;
1119 s
= get_section_by_index(section
);
1121 sym
->type
|= N_SECT
;
1123 /* get the in-file index of the section the symbol was defined in */
1124 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1126 /* track the initially allocated symbol number for use in future fix-ups */
1127 sym
->initial_snum
= nsyms
;
1130 /* remember symbol number of references to external
1131 ** symbols, this works because every external symbol gets
1132 ** its own section number allocated internally by nasm and
1133 ** can so be used as a key */
1134 extsyms
= raa_write(extsyms
, section
, nsyms
);
1136 switch (is_global
) {
1139 /* there isn't actually a difference between global
1140 ** and common symbols, both even have their size in
1141 ** sym->symv[0].key */
1146 /* give an error on unfound section if it's not an
1147 ** external or common symbol (assemble_file() does a
1148 ** seg_alloc() on every call for them) */
1149 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section
, is_global
);
1156 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1158 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1163 if (special
&& !special_used
)
1164 nasm_error(ERR_NONFATAL
, "no special symbol features supported here");
1167 static void macho_sectalign(int32_t seg
, unsigned int value
)
1172 nasm_assert(!(seg
& 1));
1174 s
= get_section_by_index(seg
);
1176 if (!s
|| !is_power2(value
))
1179 align
= alignlog2_32(value
);
1180 if (s
->align
< align
)
1184 extern macros_t macho_stdmac
[];
1186 /* Comparison function for qsort symbol layout. */
1187 static int layout_compare (const struct symbol
**s1
,
1188 const struct symbol
**s2
)
1190 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1193 /* The native assembler does a few things in a similar function
1195 * Remove temporary labels
1196 * Sort symbols according to local, external, undefined (by name)
1197 * Order the string table
1199 We do not remove temporary labels right now.
1201 numsyms is the total number of symbols we have. strtabsize is the
1202 number entries in the string table. */
1204 static void macho_layout_symbols (uint32_t *numsyms
,
1205 uint32_t *strtabsize
)
1207 struct symbol
*sym
, **symp
;
1211 *strtabsize
= sizeof (char);
1215 while ((sym
= *symp
)) {
1216 /* Undefined symbols are now external. */
1217 if (sym
->type
== N_UNDF
)
1220 if ((sym
->type
& N_EXT
) == 0) {
1221 sym
->snum
= *numsyms
;
1222 *numsyms
= *numsyms
+ 1;
1226 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1232 /* If we handle debug info we'll want
1233 to check for it here instead of just
1234 adding the symbol to the string table. */
1235 sym
->strx
= *strtabsize
;
1236 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1237 *strtabsize
+= strlen(sym
->name
) + 1;
1239 symp
= &(sym
->next
);
1242 /* Next, sort the symbols. Most of this code is a direct translation from
1243 the Apple cctools symbol layout. We need to keep compatibility with that. */
1244 /* Set the indexes for symbol groups into the symbol table */
1246 iextdefsym
= nlocalsym
;
1247 iundefsym
= nlocalsym
+ nextdefsym
;
1249 /* allocate arrays for sorting externals by name */
1250 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1251 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1258 while ((sym
= *symp
)) {
1260 if((sym
->type
& N_EXT
) == 0) {
1261 sym
->strx
= *strtabsize
;
1262 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1263 *strtabsize
+= strlen(sym
->name
) + 1;
1266 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1267 extdefsyms
[i
++] = sym
;
1269 undefsyms
[j
++] = sym
;
1272 symp
= &(sym
->next
);
1275 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1276 (int (*)(const void *, const void *))layout_compare
);
1277 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1278 (int (*)(const void *, const void *))layout_compare
);
1280 for(i
= 0; i
< nextdefsym
; i
++) {
1281 extdefsyms
[i
]->snum
= *numsyms
;
1284 for(j
= 0; j
< nundefsym
; j
++) {
1285 undefsyms
[j
]->snum
= *numsyms
;
1290 /* Calculate some values we'll need for writing later. */
1292 static void macho_calculate_sizes (void)
1297 /* count sections and calculate in-memory and in-file offsets */
1298 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1301 /* recalculate segment address based on alignment and vm size */
1302 s
->addr
= seg_vmsize
;
1304 /* we need section alignment to calculate final section address */
1306 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1308 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1311 seg_vmsize
= newaddr
+ s
->size
;
1313 /* zerofill sections aren't actually written to the file */
1314 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1316 * LLVM/Xcode as always aligns the section data to 4
1317 * bytes; there is a comment in the LLVM source code that
1318 * perhaps aligning to pointer size would be better.
1320 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1321 s
->offset
= seg_filesize
+ s
->pad
;
1322 seg_filesize
+= s
->size
+ s
->pad
;
1324 /* filesize and vmsize needs to be aligned */
1325 seg_vmsize
+= s
->pad
;
1329 /* calculate size of all headers, load commands and sections to
1330 ** get a pointer to the start of all the raw data */
1331 if (seg_nsects
> 0) {
1333 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1338 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1341 if (seg_nsects
> MAX_SECT
) {
1342 nasm_fatal(0, "MachO output is limited to %d sections\n",
1346 /* Create a table of sections by file index to avoid linear search */
1347 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1348 sectstab
[NO_SECT
] = &absolute_sect
;
1349 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1353 /* Write out the header information for the file. */
1355 static void macho_write_header (void)
1357 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1358 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1359 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1360 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1361 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1362 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1363 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1364 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1367 /* Write out the segment load command at offset. */
1369 static uint32_t macho_write_segment (uint64_t offset
)
1371 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1372 uint32_t s_reloff
= 0;
1375 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1377 /* size of load command including section load commands */
1378 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1381 /* in an MH_OBJECT file all sections are in one unnamed (name
1382 ** all zeros) segment */
1383 fwritezero(16, ofile
);
1384 fwriteptr(0, ofile
); /* in-memory offset */
1385 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1386 fwriteptr(offset
, ofile
); /* in-file offset to data */
1387 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1388 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1389 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1390 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1391 fwriteint32_t(0, ofile
); /* no flags */
1393 /* emit section headers */
1394 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1396 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1397 s
->flags
|= S_ATTR_LOC_RELOC
;
1399 s
->flags
|= S_ATTR_EXT_RELOC
;
1400 } else if (!xstrncmp(s
->segname
, "__DATA") &&
1401 !xstrncmp(s
->sectname
, "__const") &&
1403 !get_section_by_name("__TEXT", "__const")) {
1405 * The MachO equivalent to .rodata can be either
1406 * __DATA,__const or __TEXT,__const; the latter only if
1407 * there are no relocations. However, when mixed it is
1408 * better to specify the segments explicitly.
1410 xstrncpy(s
->segname
, "__TEXT");
1413 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1414 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1415 fwriteptr(s
->addr
, ofile
);
1416 fwriteptr(s
->size
, ofile
);
1418 /* dummy data for zerofill sections or proper values */
1419 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1420 nasm_assert(s
->pad
!= (uint32_t)-1);
1422 fwriteint32_t(offset
, ofile
);
1424 /* Write out section alignment, as a power of two.
1425 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1426 fwriteint32_t(s
->align
, ofile
);
1427 /* To be compatible with cctools as we emit
1428 a zero reloff if we have no relocations. */
1429 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1430 fwriteint32_t(s
->nreloc
, ofile
);
1432 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1434 fwriteint32_t(0, ofile
);
1435 fwriteint32_t(s
->align
, ofile
);
1436 fwriteint32_t(0, ofile
);
1437 fwriteint32_t(0, ofile
);
1440 fwriteint32_t(s
->flags
, ofile
); /* flags */
1441 fwriteint32_t(0, ofile
); /* reserved */
1442 fwriteptr(0, ofile
); /* reserved */
1445 rel_padcnt
= rel_base
- offset
;
1446 offset
= rel_base
+ s_reloff
;
1451 /* For a given chain of relocs r, write out the entire relocation
1452 chain to the object file. */
1454 static void macho_write_relocs (struct reloc
*r
)
1459 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1462 word2
|= r
->pcrel
<< 24;
1463 word2
|= r
->length
<< 25;
1464 word2
|= r
->ext
<< 27;
1465 word2
|= r
->type
<< 28;
1466 fwriteint32_t(word2
, ofile
); /* reloc data */
1471 /* Write out the section data. */
1472 static void macho_write_section (void)
1484 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1485 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1488 /* Like a.out Mach-O references things in the data or bss
1489 * sections by addresses which are actually relative to the
1490 * start of the _text_ section, in the _file_. See outaout.c
1491 * for more information. */
1492 saa_rewind(s
->data
);
1493 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1494 len
= (uint32_t)1 << r
->length
;
1495 if (len
> 4) /* Can this ever be an issue?! */
1498 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1500 /* get offset based on relocation type */
1501 #ifdef WORDS_LITTLEENDIAN
1505 l
+= ((int64_t)blk
.buf
[1]) << 8;
1506 l
+= ((int64_t)blk
.buf
[2]) << 16;
1507 l
+= ((int64_t)blk
.buf
[3]) << 24;
1508 l
+= ((int64_t)blk
.buf
[4]) << 32;
1509 l
+= ((int64_t)blk
.buf
[5]) << 40;
1510 l
+= ((int64_t)blk
.buf
[6]) << 48;
1511 l
+= ((int64_t)blk
.buf
[7]) << 56;
1514 /* If the relocation is internal add to the current section
1515 offset. Otherwise the only value we need is the symbol
1516 offset which we already have. The linker takes care
1517 of the rest of the address. */
1519 /* generate final address by section address and offset */
1520 nasm_assert(r
->snum
<= seg_nsects
);
1521 l
+= sectstab
[r
->snum
]->addr
;
1524 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1528 /* write new offset back */
1531 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1534 /* dump the section data to file */
1535 fwritezero(s
->pad
, ofile
);
1536 saa_fpwrite(s
->data
, ofile
);
1539 /* pad last section up to reloc entries on pointer boundary */
1540 fwritezero(rel_padcnt
, ofile
);
1542 /* emit relocation entries */
1543 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1544 macho_write_relocs (s
->relocs
);
1547 /* Write out the symbol table. We should already have sorted this
1549 static void macho_write_symtab (void)
1554 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1556 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1557 if ((sym
->type
& N_EXT
) == 0) {
1558 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1559 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1560 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1561 fwriteint16_t(sym
->desc
, ofile
); /* description */
1563 /* Fix up the symbol value now that we know the final section
1565 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1566 nasm_assert(sym
->sect
<= seg_nsects
);
1567 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1570 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1574 for (i
= 0; i
< nextdefsym
; i
++) {
1575 sym
= extdefsyms
[i
];
1576 fwriteint32_t(sym
->strx
, ofile
);
1577 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1578 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1579 fwriteint16_t(sym
->desc
, ofile
); /* description */
1581 /* Fix up the symbol value now that we know the final section
1583 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1584 nasm_assert(sym
->sect
<= seg_nsects
);
1585 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1588 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1591 for (i
= 0; i
< nundefsym
; i
++) {
1593 fwriteint32_t(sym
->strx
, ofile
);
1594 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1595 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1596 fwriteint16_t(sym
->desc
, ofile
); /* description */
1598 /* Fix up the symbol value now that we know the final section
1600 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1601 nasm_assert(sym
->sect
<= seg_nsects
);
1602 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1605 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1610 /* Fixup the snum in the relocation entries, we should be
1611 doing this only for externally referenced symbols. */
1612 static void macho_fixup_relocs (struct reloc
*r
)
1618 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1619 if (sym
->initial_snum
== r
->snum
) {
1620 r
->snum
= sym
->snum
;
1629 /* Write out the object file. */
1631 static void macho_write (void)
1633 uint64_t offset
= 0;
1635 /* mach-o object file structure:
1641 ** uint32_t mach file type
1642 ** uint32_t number of load commands
1643 ** uint32_t size of all load commands
1644 ** (includes section struct size of segment command)
1648 ** uint32_t command type == LC_SEGMENT[_64]
1649 ** uint32_t size of load command
1650 ** (including section load commands)
1651 ** char[16] segment name
1652 ** pointer in-memory offset
1653 ** pointer in-memory size
1654 ** pointer in-file offset to data area
1655 ** pointer in-file size
1656 ** (in-memory size excluding zerofill sections)
1657 ** int maximum vm protection
1658 ** int initial vm protection
1659 ** uint32_t number of sections
1663 ** char[16] section name
1664 ** char[16] segment name
1665 ** pointer in-memory offset
1666 ** pointer in-memory size
1667 ** uint32_t in-file offset
1668 ** uint32_t alignment
1669 ** (irrelevant in MH_OBJECT)
1670 ** uint32_t in-file offset of relocation entires
1671 ** uint32_t number of relocations
1673 ** uint32_t reserved
1674 ** uint32_t reserved
1676 ** symbol table command
1677 ** uint32_t command type == LC_SYMTAB
1678 ** uint32_t size of load command
1679 ** uint32_t symbol table offset
1680 ** uint32_t number of symbol table entries
1681 ** uint32_t string table offset
1682 ** uint32_t string table size
1686 ** padding to pointer boundary
1688 ** relocation data (struct reloc)
1690 ** uint data (symbolnum, pcrel, length, extern, type)
1692 ** symbol table data (struct nlist)
1693 ** int32_t string table entry number
1695 ** (extern, absolute, defined in section)
1697 ** (0 for global symbols, section number of definition (>= 1, <=
1698 ** 254) for local symbols, size of variable for common symbols
1699 ** [type == extern])
1700 ** int16_t description
1701 ** (for stab debugging format)
1702 ** pointer value (i.e. file offset) of symbol or stab offset
1704 ** string table data
1705 ** list of null-terminated strings
1708 /* Emit the Mach-O header. */
1709 macho_write_header();
1711 offset
= fmt
.header_size
+ head_sizeofcmds
;
1713 /* emit the segment load command */
1715 offset
= macho_write_segment (offset
);
1717 nasm_error(ERR_WARNING
, "no sections?");
1720 /* write out symbol command */
1721 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1722 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1723 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1724 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1726 offset
+= nsyms
* fmt
.nlist_size
;
1727 fwriteint32_t(offset
, ofile
); /* string table offset */
1728 fwriteint32_t(strslen
, ofile
); /* string table size */
1731 /* emit section data */
1733 macho_write_section ();
1735 /* emit symbol table if we have symbols */
1737 macho_write_symtab ();
1739 /* we don't need to pad here, we are already aligned */
1741 /* emit string table */
1742 saa_fpwrite(strs
, ofile
);
1744 /* We do quite a bit here, starting with finalizing all of the data
1745 for the object file, writing, and then freeing all of the data from
1748 static void macho_cleanup(void)
1756 /* Sort all symbols. */
1757 macho_layout_symbols (&nsyms
, &strslen
);
1759 /* Fixup relocation entries */
1760 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1761 macho_fixup_relocs (s
->relocs
);
1764 /* First calculate and finalize needed values. */
1765 macho_calculate_sizes();
1768 /* free up everything */
1769 while (sects
->next
) {
1771 sects
= sects
->next
;
1774 while (s
->relocs
!= NULL
) {
1776 s
->relocs
= s
->relocs
->next
;
1793 nasm_free(extdefsyms
);
1794 nasm_free(undefsyms
);
1795 nasm_free(sectstab
);
1796 raa_free(section_by_index
);
1797 hash_free(§ion_by_name
);
1800 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1806 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1807 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1811 s
= get_section_by_index(nasm_seg
);
1813 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1822 * Mark a symbol for no dead stripping
1824 static enum directive_result
macho_no_dead_strip(const char *labels
)
1828 enum directive_result rv
= DIRR_ERROR
;
1829 bool real
= passn
> 1;
1831 p
= s
= nasm_strdup(labels
);
1833 ep
= nasm_skip_identifier(p
);
1835 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1839 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1840 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1845 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1849 p
= nasm_skip_spaces(ep
);
1851 p
= nasm_skip_spaces(++p
);
1864 static enum directive_result
1865 macho_pragma(const struct pragma
*pragma
)
1867 bool real
= passn
> 1;
1869 switch (pragma
->opcode
) {
1870 case D_SUBSECTIONS_VIA_SYMBOLS
:
1872 return DIRR_BADPARAM
;
1875 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1879 case D_NO_DEAD_STRIP
:
1880 return macho_no_dead_strip(pragma
->tail
);
1883 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1887 static const struct pragma_facility macho_pragma_list
[] = {
1888 { "macho", macho_pragma
},
1889 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1892 static void macho_dbg_generate(void)
1894 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1895 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1896 struct section
*p_section
= NULL
;
1897 /* calculated at debug_str and referenced at debug_info */
1898 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1900 /* debug section defines */
1903 macho_section(".debug_abbrev", 0, &bits
);
1904 macho_section(".debug_info", 0, &bits
);
1905 macho_section(".debug_line", 0, &bits
);
1906 macho_section(".debug_str", 0, &bits
);
1909 /* dw section walk to find high_addr and total_len */
1911 struct dw_sect_list
*p_sect
;
1913 list_for_each(p_sect
, dw_head_sect
) {
1914 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1915 struct SAA
*p_linep
= p_sect
->psaa
;
1917 saa_write8(p_linep
, 2); /* std op 2 */
1918 saa_write8(p_linep
, offset
- p_sect
->offset
);
1919 saa_write8(p_linep
, DW_LNS_extended_op
);
1920 saa_write8(p_linep
, 1); /* operand length */
1921 saa_write8(p_linep
, DW_LNE_end_sequence
);
1923 total_len
+= p_linep
->datalen
;
1924 high_addr
+= offset
;
1930 struct dw_sect_list
*p_sect
;
1931 size_t linep_off
, buf_size
;
1932 struct SAA
*p_lines
= saa_init(1L);
1933 struct dir_list
*p_dir
;
1934 struct file_list
*p_file
;
1936 p_section
= get_section_by_name("__DWARF", "__debug_line");
1937 nasm_assert(p_section
!= NULL
);
1939 saa_write8(p_lines
, 1); /* minimum instruction length */
1940 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1941 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1942 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1943 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1944 saa_write8(p_lines
, 0); /* std opcode 1 length */
1945 saa_write8(p_lines
, 1); /* std opcode 2 length */
1946 saa_write8(p_lines
, 1); /* std opcode 3 length */
1947 saa_write8(p_lines
, 1); /* std opcode 4 length */
1948 saa_write8(p_lines
, 1); /* std opcode 5 length */
1949 saa_write8(p_lines
, 0); /* std opcode 6 length */
1950 saa_write8(p_lines
, 0); /* std opcode 7 length */
1951 saa_write8(p_lines
, 0); /* std opcode 8 length */
1952 saa_write8(p_lines
, 1); /* std opcode 9 length */
1953 saa_write8(p_lines
, 0); /* std opcode 10 length */
1954 saa_write8(p_lines
, 0); /* std opcode 11 length */
1955 saa_write8(p_lines
, 1); /* std opcode 12 length */
1956 list_for_each(p_dir
, dw_head_dir
) {
1957 saa_wcstring(p_lines
, p_dir
->dir_name
);
1959 saa_write8(p_lines
, 0); /* end of table */
1961 list_for_each(p_file
, dw_head_file
) {
1962 saa_wcstring(p_lines
, p_file
->file_name
);
1963 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1964 saa_write8(p_lines
, 0); /* time */
1965 saa_write8(p_lines
, 0); /* size */
1967 saa_write8(p_lines
, 0); /* end of table */
1969 linep_off
= p_lines
->datalen
;
1970 /* 10 bytes for initial & prolong length, and dwarf version info */
1971 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1972 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1974 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1975 WRITESHORT(p_buf
, 2); /* dwarf version */
1976 WRITELONG(p_buf
, linep_off
); /* prolong length */
1978 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1982 list_for_each(p_sect
, dw_head_sect
) {
1983 struct SAA
*p_linep
= p_sect
->psaa
;
1985 saa_len
= p_linep
->datalen
;
1986 saa_rnbytes(p_linep
, p_buf
, saa_len
);
1992 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
1994 nasm_free(p_buf_base
);
1997 /* string section */
1999 struct SAA
*p_str
= saa_init(1L);
2000 char *cur_path
= nasm_realpath(module_name
);
2001 char *cur_file
= nasm_basename(cur_path
);
2002 char *cur_dir
= nasm_dirname(cur_path
);
2004 p_section
= get_section_by_name("__DWARF", "__debug_str");
2005 nasm_assert(p_section
!= NULL
);
2007 producer_str_offset
= 0;
2008 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
2009 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
2010 saa_wcstring(p_str
, cur_dir
);
2012 saa_len
= p_str
->datalen
;
2013 p_buf
= nasm_malloc(saa_len
);
2014 saa_rnbytes(p_str
, p_buf
, saa_len
);
2015 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2017 nasm_free(cur_path
);
2018 nasm_free(cur_file
);
2026 struct SAA
*p_info
= saa_init(1L);
2028 p_section
= get_section_by_name("__DWARF", "__debug_info");
2029 nasm_assert(p_section
!= NULL
);
2031 /* size will be overwritten once determined, so skip in p_info layout */
2032 saa_write16(p_info
, 2); /* dwarf version */
2033 saa_write32(p_info
, 0); /* offset info abbrev */
2034 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
2036 saa_write8(p_info
, 1); /* abbrev entry number */
2038 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
2039 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
2040 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
2041 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
2042 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
2044 if (ofmt
== &of_macho64
) {
2045 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2046 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
2048 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2049 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
2052 saa_write8(p_info
, 2); /* abbrev entry number */
2054 if (ofmt
== &of_macho64
) {
2055 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2056 saa_write64(p_info
, 0); /* DW_AT_frame_base */
2058 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2059 saa_write32(p_info
, 0); /* DW_AT_frame_base */
2061 saa_write8(p_info
, DW_END_default
);
2063 saa_len
= p_info
->datalen
;
2064 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
2066 WRITELONG(p_buf
, saa_len
);
2067 saa_rnbytes(p_info
, p_buf
, saa_len
);
2068 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
2071 nasm_free(p_buf_base
);
2074 /* abbrev section */
2076 struct SAA
*p_abbrev
= saa_init(1L);
2078 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
2079 nasm_assert(p_section
!= NULL
);
2081 saa_write8(p_abbrev
, 1); /* entry number */
2083 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2084 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2086 saa_write8(p_abbrev
, DW_AT_producer
);
2087 saa_write8(p_abbrev
, DW_FORM_strp
);
2089 saa_write8(p_abbrev
, DW_AT_language
);
2090 saa_write8(p_abbrev
, DW_FORM_data2
);
2092 saa_write8(p_abbrev
, DW_AT_name
);
2093 saa_write8(p_abbrev
, DW_FORM_strp
);
2095 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2096 saa_write8(p_abbrev
, DW_FORM_strp
);
2098 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2099 saa_write8(p_abbrev
, DW_FORM_data4
);
2101 saa_write8(p_abbrev
, DW_AT_low_pc
);
2102 saa_write8(p_abbrev
, DW_FORM_addr
);
2104 saa_write8(p_abbrev
, DW_AT_high_pc
);
2105 saa_write8(p_abbrev
, DW_FORM_addr
);
2107 saa_write16(p_abbrev
, DW_END_default
);
2109 saa_write8(p_abbrev
, 2); /* entry number */
2111 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2112 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2114 saa_write8(p_abbrev
, DW_AT_low_pc
);
2115 saa_write8(p_abbrev
, DW_FORM_addr
);
2117 saa_write8(p_abbrev
, DW_AT_frame_base
);
2118 saa_write8(p_abbrev
, DW_FORM_addr
);
2120 saa_write16(p_abbrev
, DW_END_default
);
2122 saa_write8(p_abbrev
, 0); /* Terminal zero entry */
2124 saa_len
= p_abbrev
->datalen
;
2126 p_buf
= nasm_malloc(saa_len
);
2128 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2129 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2136 static void new_file_list (const char *file_name
, const char *dir_name
)
2138 struct dir_list
*dir_list
;
2139 bool need_new_dir_list
= true;
2141 nasm_new(dw_cur_file
);
2142 dw_cur_file
->file
= ++dw_num_files
;
2143 dw_cur_file
->file_name
= file_name
;
2145 dw_head_file
= dw_cur_file
;
2147 *dw_last_file_next
= dw_cur_file
;
2149 dw_last_file_next
= &(dw_cur_file
->next
);
2152 list_for_each(dir_list
, dw_head_dir
) {
2153 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2154 dw_cur_file
->dir
= dir_list
;
2155 need_new_dir_list
= false;
2161 if(need_new_dir_list
)
2164 dir_list
->dir
= dw_num_dirs
++;
2165 dir_list
->dir_name
= dir_name
;
2167 dw_head_dir
= dir_list
;
2169 *dw_last_dir_next
= dir_list
;
2171 dw_last_dir_next
= &(dir_list
->next
);
2172 dw_cur_file
->dir
= dir_list
;
2176 static void macho_dbg_init(void)
2180 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2182 bool need_new_list
= true;
2183 const char *cur_file
= nasm_basename(file_name
);
2184 const char *cur_dir
= nasm_dirname(file_name
);
2187 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2188 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2190 struct file_list
*match
;
2192 list_for_each(match
, dw_head_file
) {
2193 if(!(strcmp(cur_file
, match
->file_name
)) &&
2194 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2195 dw_cur_file
= match
;
2196 dw_cur_file
->dir
= match
->dir
;
2197 need_new_list
= false;
2204 new_file_list(cur_file
, cur_dir
);
2209 cur_line
= line_num
;
2212 static void macho_dbg_output(int type
, void *param
)
2214 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2215 int32_t secto
= sinfo_param
->secto
;
2216 bool need_new_sect
= false;
2217 struct SAA
*p_linep
= NULL
;
2220 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2221 need_new_sect
= true;
2223 struct dw_sect_list
*match
= dw_head_sect
;
2226 for(; idx
< dw_num_sects
; idx
++) {
2227 if(match
->section
== secto
) {
2228 dw_cur_sect
= match
;
2229 need_new_sect
= false;
2232 match
= match
->next
;
2238 nasm_new(dw_cur_sect
);
2240 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2241 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2242 dw_cur_sect
->offset
= 0;
2243 dw_cur_sect
->next
= NULL
;
2244 dw_cur_sect
->section
= secto
;
2246 saa_write8(p_linep
, DW_LNS_extended_op
);
2247 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2248 saa_write8(p_linep
, DW_LNE_set_address
);
2249 if (ofmt
== &of_macho64
) {
2250 saa_write64(p_linep
, 0);
2252 saa_write32(p_linep
, 0);
2256 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2258 dw_last_sect
->next
= dw_cur_sect
;
2259 dw_last_sect
= dw_cur_sect
;
2263 if(dbg_immcall
== true) {
2264 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2265 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2266 uint32_t cur_file
= dw_cur_file
->file
;
2267 p_linep
= dw_cur_sect
->psaa
;
2269 if(cur_file
!= dw_cur_sect
->file
) {
2270 saa_write8(p_linep
, DW_LNS_set_file
);
2271 saa_write8(p_linep
, cur_file
);
2272 dw_cur_sect
->file
= cur_file
;
2276 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2279 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2280 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2281 saa_write8(p_linep
, special_opcode
);
2283 saa_write8(p_linep
, DW_LNS_advance_line
);
2284 saa_wleb128s(p_linep
, line_delta
);
2286 saa_write8(p_linep
, DW_LNS_advance_pc
);
2287 saa_wleb128u(p_linep
, offset_delta
);
2289 saa_write8(p_linep
, DW_LNS_copy
);
2292 dw_cur_sect
->line
= cur_line
;
2293 dw_cur_sect
->offset
= sinfo_param
->size
;
2296 dbg_immcall
= false;
2300 static void macho_dbg_cleanup(void)
2302 /* dwarf sectors generation */
2303 macho_dbg_generate();
2306 struct dw_sect_list
*p_sect
= dw_head_sect
;
2307 struct file_list
*p_file
= dw_head_file
;
2310 for(; idx
< dw_num_sects
; idx
++) {
2311 struct dw_sect_list
*next
= p_sect
->next
;
2316 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2317 struct file_list
*next
= p_file
->next
;
2325 static const struct macho_fmt macho32_fmt
= {
2335 GENERIC_RELOC_VANILLA
,
2336 GENERIC_RELOC_VANILLA
,
2338 false /* Allow segment-relative relocations */
2341 static void macho32_init(void)
2346 macho_gotpcrel_sect
= NO_SEG
;
2349 static const struct dfmt macho32_df_dwarf
= {
2350 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2354 null_debug_deflabel
,
2355 null_debug_directive
,
2356 null_debug_typevalue
,
2359 NULL
/*pragma list*/
2362 static const struct dfmt
* const macho32_df_arr
[2] =
2363 { &macho32_df_dwarf
, NULL
};
2365 const struct ofmt of_macho32
= {
2366 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2376 nasm_do_legacy_output
,
2390 static const struct macho_fmt macho64_fmt
= {
2395 MACHO_HEADER64_SIZE
,
2396 MACHO_SEGCMD64_SIZE
,
2397 MACHO_SECTCMD64_SIZE
,
2400 X86_64_RELOC_UNSIGNED
,
2401 X86_64_RELOC_SIGNED
,
2403 true /* Force symbol-relative relocations */
2406 static void macho64_init(void)
2411 /* add special symbol for ..gotpcrel */
2412 macho_gotpcrel_sect
= seg_alloc() + 1;
2413 backend_label("..gotpcrel", macho_gotpcrel_sect
, 0L);
2416 static const struct dfmt macho64_df_dwarf
= {
2417 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2421 null_debug_deflabel
,
2422 null_debug_directive
,
2423 null_debug_typevalue
,
2426 NULL
/*pragma list*/
2429 static const struct dfmt
* const macho64_df_arr
[2] =
2430 { &macho64_df_dwarf
, NULL
};
2432 const struct ofmt of_macho64
= {
2433 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2443 nasm_do_legacy_output
,