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 raa_read_ptr(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?) */
517 } else if (fi
== NO_SECT
) {
519 r
->snum
= raa_read(extsyms
, section
);
529 r
->type
= fmt
.reloc_rel
;
531 if (section
== NO_SEG
) {
532 /* may optionally be converted below by fmt.forcesym */
534 } else if (fi
== NO_SECT
) {
537 r
->snum
= raa_read(extsyms
, section
);
538 if (reltype
== RL_BRANCH
)
539 r
->type
= X86_64_RELOC_BRANCH
;
544 if (reltype
== RL_BRANCH
)
545 r
->type
= X86_64_RELOC_BRANCH
;
549 case RL_SUB
: /* obsolete */
550 nasm_error(ERR_WARNING
, "relcation with subtraction"
551 "becomes to be obsolete");
553 r
->type
= X86_64_RELOC_SUBTRACTOR
;
557 r
->type
= X86_64_RELOC_GOT
;
561 r
->type
= X86_64_RELOC_GOT_LOAD
;
565 r
->type
= fmt
.reloc_tlv
;
569 r
->pcrel
= (fmt
.ptrsize
== 8 ? 1 : 0);
570 if (section
== NO_SEG
) {
571 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
573 } else if (fi
== NO_SECT
) {
575 r
->snum
= raa_read(extsyms
, section
);
577 /* internal - GOTPCREL doesn't need to be in global */
578 struct symbol
*sym
= macho_find_sym(s
, offset
,
579 false, /* reltype != RL_TLV */
582 nasm_error(ERR_NONFATAL
, "Symbol for WRT not found");
586 adjust
-= sym
->symv
[0].key
;
587 r
->snum
= sym
->initial_snum
;
593 * For 64-bit Mach-O, force a symbol reference if at all possible
594 * Allow for r->snum == R_ABS by searching absolute_sect
596 if (!r
->ext
&& fmt
.forcesym
) {
597 struct symbol
*sym
= macho_find_sym(s
? s
: &absolute_sect
,
598 offset
, false, false);
600 adjust
-= sym
->symv
[0].key
;
601 r
->snum
= sym
->initial_snum
;
607 adjust
+= ((r
->ext
&& fmt
.ptrsize
== 8) ? bytes
: -(int64_t)sect
->size
);
609 /* NeXT as puts relocs in reversed order (address-wise) into the
610 ** files, so we do the same, doesn't seem to make much of a
611 ** difference either way */
612 r
->next
= sect
->relocs
;
625 static void macho_output(int32_t secto
, const void *data
,
626 enum out_type type
, uint64_t size
,
627 int32_t section
, int32_t wrt
)
630 int64_t addr
, offset
;
631 uint8_t mydata
[16], *p
;
633 enum reltype reltype
;
635 s
= get_section_by_index(secto
);
637 nasm_error(ERR_WARNING
, "attempt to assemble code in"
638 " section %d: defaulting to `.text'", secto
);
639 s
= get_section_by_name("__TEXT", "__text");
641 /* should never happen */
643 nasm_panic("text section not found");
646 /* debug code generation only for sections tagged with
647 * instruction attribute */
648 if (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)
650 struct section_info sinfo
;
651 sinfo
.size
= s
->size
;
653 dfmt
->debug_output(0, &sinfo
);
656 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
658 if (is_bss
&& type
!= OUT_RESERVE
) {
659 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
660 "BSS section: ignored");
662 nasm_error(ERR_WARNING
, "section size may be negative"
663 "with address symbols");
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 addr
+= add_reloc(s
, section
, addr
, RL_ABS
, asize
);
703 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
!= 8 &&
704 asize
== (int) fmt
.ptrsize
) {
705 addr
+= add_reloc(s
, section
, addr
, RL_TLV
, asize
);
707 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
713 WRITEADDR(p
, addr
, asize
);
714 sect_write(s
, mydata
, asize
);
722 offset
= *(int64_t *)data
;
723 addr
= offset
- size
;
725 if (section
!= NO_SEG
&& section
% 2) {
726 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
727 " section base references");
728 } else if (fmt
.ptrsize
== 8) {
729 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
730 " Macho-O relocation [2]");
731 } else if (wrt
!= NO_SEG
) {
732 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
734 wrt
= NO_SEG
; /* we can at least _try_ to continue */
736 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
,
737 type
== OUT_REL1ADR
? 1 : 2);
741 sect_write(s
, mydata
, type
== OUT_REL1ADR
? 1 : 2);
748 offset
= *(int64_t *)data
;
749 addr
= offset
- size
;
752 if (section
!= NO_SEG
&& section
% 2) {
753 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
754 " section base references");
755 } else if (wrt
== NO_SEG
) {
756 if (fmt
.ptrsize
== 8 &&
757 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
760 opcode
[0] = opcode
[1] = 0;
762 /* HACK: Retrieve instruction opcode */
763 if (likely(s
->data
->datalen
>= 2)) {
764 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
765 } else if (s
->data
->datalen
== 1) {
766 saa_fread(s
->data
, 0, opcode
+1, 1);
769 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
770 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
771 /* Direct call, jmp, or jcc */
775 } else if (wrt
== macho_gotpcrel_sect
) {
778 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
779 s
->data
->datalen
>= 3) {
782 /* HACK: Retrieve instruction opcode */
783 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
784 if ((gotload
[0] & 0xf8) == 0x48 &&
785 gotload
[1] == 0x8b &&
786 (gotload
[2] & 0307) == 0005) {
787 /* movq <reg>,[rel sym wrt ..gotpcrel] */
788 reltype
= RL_GOTLOAD
;
791 } else if (wrt
== macho_tlvp_sect
&& fmt
.ptrsize
== 8) {
794 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
796 /* continue with RL_REL */
799 addr
+= add_reloc(s
, section
, offset
, reltype
,
800 type
== OUT_REL4ADR
? 4 : 8);
802 sect_write(s
, mydata
, type
== OUT_REL4ADR
? 4 : 8);
806 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
811 /* Translation table from traditional Unix section names to Mach-O */
812 static const struct sectmap
{
813 const char *nasmsect
;
815 const char *sectname
;
816 const uint32_t flags
;
818 {".text", "__TEXT", "__text",
819 S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
820 {".data", "__DATA", "__data", S_REGULAR
},
821 {".rodata", "__DATA", "__const", S_REGULAR
},
822 {".bss", "__DATA", "__bss", S_ZEROFILL
},
823 {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG
},
824 {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG
},
825 {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG
},
826 {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG
},
827 {NULL
, NULL
, NULL
, 0}
830 #define NO_TYPE S_NASM_TYPE_MASK
832 /* Section type or attribute directives */
833 static const struct sect_attribs
{
837 { "data", S_REGULAR
},
838 { "code", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
839 { "mixed", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
840 { "bss", S_ZEROFILL
},
841 { "zerofill", S_ZEROFILL
},
842 { "no_dead_strip", NO_TYPE
|S_ATTR_NO_DEAD_STRIP
},
843 { "live_support", NO_TYPE
|S_ATTR_LIVE_SUPPORT
},
844 { "strip_static_syms", NO_TYPE
|S_ATTR_STRIP_STATIC_SYMS
},
845 { "debug", NO_TYPE
|S_ATTR_DEBUG
},
849 static int32_t macho_section(char *name
, int pass
, int *bits
)
851 char *sectionAttributes
;
852 const struct sectmap
*sm
;
854 const char *section
, *segment
;
856 const struct sect_attribs
*sa
;
857 char *currentAttribute
;
864 /* Default to the appropriate number of bits. */
866 *bits
= fmt
.ptrsize
<< 3;
868 sectionAttributes
= NULL
;
870 sectionAttributes
= name
;
871 name
= nasm_strsep(§ionAttributes
, " \t");
874 section
= segment
= NULL
;
877 comma
= strchr(name
, ',');
885 len
= strlen(segment
);
887 nasm_error(ERR_NONFATAL
, "empty segment name\n");
888 } else if (len
> 16) {
889 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
892 len
= strlen(section
);
894 nasm_error(ERR_NONFATAL
, "empty section name\n");
895 } else if (len
> 16) {
896 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
899 if (!strcmp(section
, "__text")) {
900 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
901 S_ATTR_PURE_INSTRUCTIONS
;
902 } else if (!strcmp(section
, "__bss")) {
908 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
909 /* make lookup into section name translation table */
910 if (!strcmp(name
, sm
->nasmsect
)) {
911 segment
= sm
->segname
;
912 section
= sm
->sectname
;
917 nasm_error(ERR_NONFATAL
, "unknown section name\n");
922 /* try to find section with that name, or create it */
923 s
= find_or_add_section(segment
, section
);
924 new_seg
= is_new_section(s
);
926 /* initialize it if it is a brand new section */
929 sectstail
= &s
->next
;
931 s
->data
= saa_init(1L);
932 s
->fileindex
= ++seg_nsects
;
944 *comma
= ','; /* Restore comma */
946 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
950 while (sectionAttributes
&&
951 (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
952 if (!*currentAttribute
)
955 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
957 int newAlignment
, value
;
959 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
960 newAlignment
= alignlog2_32(value
);
963 nasm_error(ERR_NONFATAL
,
964 "unknown or missing alignment value \"%s\" "
965 "specified for section \"%s\"",
966 currentAttribute
+ 6,
968 } else if (0 > newAlignment
) {
969 nasm_error(ERR_NONFATAL
,
970 "alignment of %d (for section \"%s\") is not "
976 if (s
->align
< newAlignment
)
977 s
->align
= newAlignment
;
979 for (sa
= sect_attribs
; sa
->name
; sa
++) {
980 if (!nasm_stricmp(sa
->name
, currentAttribute
)) {
981 if ((sa
->flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
982 flags
= (flags
& ~S_NASM_TYPE_MASK
)
983 | (sa
->flags
& S_NASM_TYPE_MASK
);
985 flags
|= sa
->flags
& ~S_NASM_TYPE_MASK
;
991 nasm_error(ERR_NONFATAL
,
992 "unknown section attribute %s for section %s",
993 currentAttribute
, name
);
998 if ((flags
& S_NASM_TYPE_MASK
) != NO_TYPE
) {
999 if (!new_seg
&& ((s
->flags
^ flags
) & S_NASM_TYPE_MASK
)) {
1000 nasm_error(ERR_NONFATAL
,
1001 "inconsistent section attributes for section %s\n",
1004 s
->flags
= (s
->flags
& ~S_NASM_TYPE_MASK
) | flags
;
1007 s
->flags
|= flags
& ~S_NASM_TYPE_MASK
;
1010 return s
->subsection
;
1013 static int32_t macho_herelabel(const char *name
, enum label_type type
,
1014 int32_t section
, int32_t *subsection
,
1021 if (!(head_flags
& MH_SUBSECTIONS_VIA_SYMBOLS
))
1024 /* No subsection only for local labels */
1025 if (type
== LBL_LOCAL
)
1028 s
= get_section_by_index(section
);
1032 subsec
= *subsection
;
1033 if (subsec
== NO_SEG
) {
1034 /* Allocate a new subsection index */
1035 subsec
= *subsection
= seg_alloc();
1036 section_by_index
= raa_write_ptr(section_by_index
, subsec
>> 1, s
);
1039 s
->subsection
= subsec
;
1040 *copyoffset
= true; /* Maintain previous offset */
1044 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
1045 int is_global
, char *special
)
1049 bool special_used
= false;
1051 #if defined(DEBUG) && DEBUG>2
1052 nasm_error(ERR_DEBUG
,
1053 " macho_symdef: %s, pass0=%d, passn=%"PRId64
", sec=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
1054 name
, pass0
, passn
, section
, offset
, is_global
, special
);
1057 if (is_global
== 3) {
1059 int n
= strcspn(special
, " \t");
1061 if (!nasm_strnicmp(special
, "private_extern", n
)) {
1062 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1063 if (!strcmp(name
, sym
->name
)) {
1064 if (sym
->type
& N_PEXT
)
1065 return; /* nothing to be done */
1072 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
1073 "(yet) support forward reference fixups.");
1077 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
1079 * This is a NASM special symbol. We never allow it into
1080 * the Macho-O symbol table, even if it's a valid one. If it
1081 * _isn't_ a valid one, we should barf immediately.
1083 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
1084 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
1088 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
1090 symstail
= &sym
->next
;
1093 sym
->strx
= strslen
;
1096 sym
->symv
[0].key
= offset
;
1097 sym
->symv
[1].key
= offset
;
1098 sym
->initial_snum
= -1;
1100 /* external and common symbols get N_EXT */
1101 if (is_global
!= 0) {
1104 if (is_global
== 1) {
1105 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1107 int n
= strcspn(special
, " \t");
1109 if (!nasm_strnicmp(special
, "private_extern", n
))
1110 sym
->type
|= N_PEXT
;
1112 nasm_error(ERR_NONFATAL
, "unrecognised symbol type `%.*s'", n
, special
);
1114 special_used
= true;
1117 /* track the initially allocated symbol number for use in future fix-ups */
1118 sym
->initial_snum
= nsyms
;
1120 if (section
== NO_SEG
) {
1121 /* symbols in no section get absolute */
1123 sym
->sect
= NO_SECT
;
1127 s
= get_section_by_index(section
);
1129 sym
->type
|= N_SECT
;
1131 /* get the in-file index of the section the symbol was defined in */
1132 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
1135 /* remember symbol number of references to external
1136 ** symbols, this works because every external symbol gets
1137 ** its own section number allocated internally by nasm and
1138 ** can so be used as a key */
1139 extsyms
= raa_write(extsyms
, section
, nsyms
);
1141 switch (is_global
) {
1144 /* there isn't actually a difference between global
1145 ** and common symbols, both even have their size in
1146 ** sym->symv[0].key */
1151 /* give an error on unfound section if it's not an
1152 ** external or common symbol (assemble_file() does a
1153 ** seg_alloc() on every call for them) */
1154 nasm_panic("in-file index for section %d not found, is_global = %d", section
, is_global
);
1161 s
->syms
[0] = rb_insert(s
->syms
[0], &sym
->symv
[0]);
1163 s
->syms
[1] = rb_insert(s
->syms
[1], &sym
->symv
[1]);
1168 if (special
&& !special_used
)
1169 nasm_error(ERR_NONFATAL
, "no special symbol features supported here");
1172 static void macho_sectalign(int32_t seg
, unsigned int value
)
1177 nasm_assert(!(seg
& 1));
1179 s
= get_section_by_index(seg
);
1181 if (!s
|| !is_power2(value
))
1184 align
= alignlog2_32(value
);
1185 if (s
->align
< align
)
1189 extern macros_t macho_stdmac
[];
1191 /* Comparison function for qsort symbol layout. */
1192 static int layout_compare (const struct symbol
**s1
,
1193 const struct symbol
**s2
)
1195 return (strcmp ((*s1
)->name
, (*s2
)->name
));
1198 /* The native assembler does a few things in a similar function
1200 * Remove temporary labels
1201 * Sort symbols according to local, external, undefined (by name)
1202 * Order the string table
1204 We do not remove temporary labels right now.
1206 numsyms is the total number of symbols we have. strtabsize is the
1207 number entries in the string table. */
1209 static void macho_layout_symbols (uint32_t *numsyms
,
1210 uint32_t *strtabsize
)
1212 struct symbol
*sym
, **symp
;
1216 *strtabsize
= sizeof (char);
1220 while ((sym
= *symp
)) {
1221 /* Undefined symbols are now external. */
1222 if (sym
->type
== N_UNDF
)
1225 if ((sym
->type
& N_EXT
) == 0) {
1226 sym
->snum
= *numsyms
;
1227 *numsyms
= *numsyms
+ 1;
1231 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1237 /* If we handle debug info we'll want
1238 to check for it here instead of just
1239 adding the symbol to the string table. */
1240 sym
->strx
= *strtabsize
;
1241 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1242 *strtabsize
+= strlen(sym
->name
) + 1;
1244 symp
= &(sym
->next
);
1247 /* Next, sort the symbols. Most of this code is a direct translation from
1248 the Apple cctools symbol layout. We need to keep compatibility with that. */
1249 /* Set the indexes for symbol groups into the symbol table */
1251 iextdefsym
= nlocalsym
;
1252 iundefsym
= nlocalsym
+ nextdefsym
;
1254 /* allocate arrays for sorting externals by name */
1255 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1256 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1263 while ((sym
= *symp
)) {
1265 if((sym
->type
& N_EXT
) == 0) {
1266 sym
->strx
= *strtabsize
;
1267 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1268 *strtabsize
+= strlen(sym
->name
) + 1;
1271 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1272 extdefsyms
[i
++] = sym
;
1274 undefsyms
[j
++] = sym
;
1277 symp
= &(sym
->next
);
1280 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1281 (int (*)(const void *, const void *))layout_compare
);
1282 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1283 (int (*)(const void *, const void *))layout_compare
);
1285 for(i
= 0; i
< nextdefsym
; i
++) {
1286 extdefsyms
[i
]->snum
= *numsyms
;
1289 for(j
= 0; j
< nundefsym
; j
++) {
1290 undefsyms
[j
]->snum
= *numsyms
;
1295 /* Calculate some values we'll need for writing later. */
1297 static void macho_calculate_sizes (void)
1302 /* count sections and calculate in-memory and in-file offsets */
1303 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1306 /* recalculate segment address based on alignment and vm size */
1307 s
->addr
= seg_vmsize
;
1309 /* we need section alignment to calculate final section address */
1311 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1313 newaddr
= ALIGN(s
->addr
, UINT64_C(1) << s
->align
);
1316 seg_vmsize
= newaddr
+ s
->size
;
1318 /* zerofill sections aren't actually written to the file */
1319 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1321 * LLVM/Xcode as always aligns the section data to 4
1322 * bytes; there is a comment in the LLVM source code that
1323 * perhaps aligning to pointer size would be better.
1325 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1326 s
->offset
= seg_filesize
+ s
->pad
;
1327 seg_filesize
+= s
->size
+ s
->pad
;
1329 /* filesize and vmsize needs to be aligned */
1330 seg_vmsize
+= s
->pad
;
1334 /* calculate size of all headers, load commands and sections to
1335 ** get a pointer to the start of all the raw data */
1336 if (seg_nsects
> 0) {
1338 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1343 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1346 if (seg_nsects
> MAX_SECT
) {
1347 nasm_fatal("MachO output is limited to %d sections\n",
1351 /* Create a table of sections by file index to avoid linear search */
1352 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1353 sectstab
[NO_SECT
] = &absolute_sect
;
1354 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1358 /* Write out the header information for the file. */
1360 static void macho_write_header (void)
1362 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1363 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1364 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1365 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1366 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1367 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1368 fwriteint32_t(head_flags
, ofile
); /* flags, if any */
1369 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1372 /* Write out the segment load command at offset. */
1374 static uint32_t macho_write_segment (uint64_t offset
)
1376 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1377 uint32_t s_reloff
= 0;
1380 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1382 /* size of load command including section load commands */
1383 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1386 /* in an MH_OBJECT file all sections are in one unnamed (name
1387 ** all zeros) segment */
1388 fwritezero(16, ofile
);
1389 fwriteptr(0, ofile
); /* in-memory offset */
1390 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1391 fwriteptr(offset
, ofile
); /* in-file offset to data */
1392 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1393 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1394 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1395 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1396 fwriteint32_t(0, ofile
); /* no flags */
1398 /* emit section headers */
1399 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1401 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1402 s
->flags
|= S_ATTR_LOC_RELOC
;
1404 s
->flags
|= S_ATTR_EXT_RELOC
;
1405 } else if (!xstrncmp(s
->segname
, "__DATA") &&
1406 !xstrncmp(s
->sectname
, "__const") &&
1408 !get_section_by_name("__TEXT", "__const")) {
1410 * The MachO equivalent to .rodata can be either
1411 * __DATA,__const or __TEXT,__const; the latter only if
1412 * there are no relocations. However, when mixed it is
1413 * better to specify the segments explicitly.
1415 xstrncpy(s
->segname
, "__TEXT");
1418 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1419 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1420 fwriteptr(s
->addr
, ofile
);
1421 fwriteptr(s
->size
, ofile
);
1423 /* dummy data for zerofill sections or proper values */
1424 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1425 nasm_assert(s
->pad
!= (uint32_t)-1);
1427 fwriteint32_t(offset
, ofile
);
1429 /* Write out section alignment, as a power of two.
1430 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1431 fwriteint32_t(s
->align
, ofile
);
1432 /* To be compatible with cctools as we emit
1433 a zero reloff if we have no relocations. */
1434 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1435 fwriteint32_t(s
->nreloc
, ofile
);
1437 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1439 fwriteint32_t(0, ofile
);
1440 fwriteint32_t(s
->align
, ofile
);
1441 fwriteint32_t(0, ofile
);
1442 fwriteint32_t(0, ofile
);
1445 fwriteint32_t(s
->flags
, ofile
); /* flags */
1446 fwriteint32_t(0, ofile
); /* reserved */
1447 fwriteptr(0, ofile
); /* reserved */
1450 rel_padcnt
= rel_base
- offset
;
1451 offset
= rel_base
+ s_reloff
;
1456 /* For a given chain of relocs r, write out the entire relocation
1457 chain to the object file. */
1459 static void macho_write_relocs (struct reloc
*r
)
1464 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1467 word2
|= r
->pcrel
<< 24;
1468 word2
|= r
->length
<< 25;
1469 word2
|= r
->ext
<< 27;
1470 word2
|= r
->type
<< 28;
1471 fwriteint32_t(word2
, ofile
); /* reloc data */
1476 /* Write out the section data. */
1477 static void macho_write_section (void)
1489 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1490 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1493 /* Like a.out Mach-O references things in the data or bss
1494 * sections by addresses which are actually relative to the
1495 * start of the _text_ section, in the _file_. See outaout.c
1496 * for more information. */
1497 saa_rewind(s
->data
);
1498 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1499 len
= (uint32_t)1 << r
->length
;
1500 if (len
> 4) /* Can this ever be an issue?! */
1503 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1505 /* get offset based on relocation type */
1506 #ifdef WORDS_LITTLEENDIAN
1510 l
+= ((int64_t)blk
.buf
[1]) << 8;
1511 l
+= ((int64_t)blk
.buf
[2]) << 16;
1512 l
+= ((int64_t)blk
.buf
[3]) << 24;
1513 l
+= ((int64_t)blk
.buf
[4]) << 32;
1514 l
+= ((int64_t)blk
.buf
[5]) << 40;
1515 l
+= ((int64_t)blk
.buf
[6]) << 48;
1516 l
+= ((int64_t)blk
.buf
[7]) << 56;
1519 /* If the relocation is internal add to the current section
1520 offset. Otherwise the only value we need is the symbol
1521 offset which we already have. The linker takes care
1522 of the rest of the address. */
1524 /* generate final address by section address and offset */
1525 nasm_assert(r
->snum
<= seg_nsects
);
1526 l
+= sectstab
[r
->snum
]->addr
;
1529 } else if (r
->pcrel
&& r
->type
== GENERIC_RELOC_VANILLA
) {
1533 /* write new offset back */
1536 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1539 /* dump the section data to file */
1540 fwritezero(s
->pad
, ofile
);
1541 saa_fpwrite(s
->data
, ofile
);
1544 /* pad last section up to reloc entries on pointer boundary */
1545 fwritezero(rel_padcnt
, ofile
);
1547 /* emit relocation entries */
1548 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1549 macho_write_relocs (s
->relocs
);
1552 /* Write out the symbol table. We should already have sorted this
1554 static void macho_write_symtab (void)
1559 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1561 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1562 if ((sym
->type
& N_EXT
) == 0) {
1563 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1564 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1565 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1566 fwriteint16_t(sym
->desc
, ofile
); /* description */
1568 /* Fix up the symbol value now that we know the final section
1570 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1571 nasm_assert(sym
->sect
<= seg_nsects
);
1572 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1575 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1579 for (i
= 0; i
< nextdefsym
; i
++) {
1580 sym
= extdefsyms
[i
];
1581 fwriteint32_t(sym
->strx
, ofile
);
1582 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1583 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1584 fwriteint16_t(sym
->desc
, ofile
); /* description */
1586 /* Fix up the symbol value now that we know the final section
1588 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1589 nasm_assert(sym
->sect
<= seg_nsects
);
1590 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1593 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1596 for (i
= 0; i
< nundefsym
; i
++) {
1598 fwriteint32_t(sym
->strx
, ofile
);
1599 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1600 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1601 fwriteint16_t(sym
->desc
, ofile
); /* description */
1603 /* Fix up the symbol value now that we know the final section
1605 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1606 nasm_assert(sym
->sect
<= seg_nsects
);
1607 sym
->symv
[0].key
+= sectstab
[sym
->sect
]->addr
;
1610 fwriteptr(sym
->symv
[0].key
, ofile
); /* value (i.e. offset) */
1615 /* Fixup the snum in the relocation entries, we should be
1616 doing this only for externally referenced symbols. */
1617 static void macho_fixup_relocs (struct reloc
*r
)
1623 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1624 if (sym
->initial_snum
== r
->snum
) {
1625 r
->snum
= sym
->snum
;
1634 /* Write out the object file. */
1636 static void macho_write (void)
1638 uint64_t offset
= 0;
1640 /* mach-o object file structure:
1646 ** uint32_t mach file type
1647 ** uint32_t number of load commands
1648 ** uint32_t size of all load commands
1649 ** (includes section struct size of segment command)
1653 ** uint32_t command type == LC_SEGMENT[_64]
1654 ** uint32_t size of load command
1655 ** (including section load commands)
1656 ** char[16] segment name
1657 ** pointer in-memory offset
1658 ** pointer in-memory size
1659 ** pointer in-file offset to data area
1660 ** pointer in-file size
1661 ** (in-memory size excluding zerofill sections)
1662 ** int maximum vm protection
1663 ** int initial vm protection
1664 ** uint32_t number of sections
1668 ** char[16] section name
1669 ** char[16] segment name
1670 ** pointer in-memory offset
1671 ** pointer in-memory size
1672 ** uint32_t in-file offset
1673 ** uint32_t alignment
1674 ** (irrelevant in MH_OBJECT)
1675 ** uint32_t in-file offset of relocation entires
1676 ** uint32_t number of relocations
1678 ** uint32_t reserved
1679 ** uint32_t reserved
1681 ** symbol table command
1682 ** uint32_t command type == LC_SYMTAB
1683 ** uint32_t size of load command
1684 ** uint32_t symbol table offset
1685 ** uint32_t number of symbol table entries
1686 ** uint32_t string table offset
1687 ** uint32_t string table size
1691 ** padding to pointer boundary
1693 ** relocation data (struct reloc)
1695 ** uint data (symbolnum, pcrel, length, extern, type)
1697 ** symbol table data (struct nlist)
1698 ** int32_t string table entry number
1700 ** (extern, absolute, defined in section)
1702 ** (0 for global symbols, section number of definition (>= 1, <=
1703 ** 254) for local symbols, size of variable for common symbols
1704 ** [type == extern])
1705 ** int16_t description
1706 ** (for stab debugging format)
1707 ** pointer value (i.e. file offset) of symbol or stab offset
1709 ** string table data
1710 ** list of null-terminated strings
1713 /* Emit the Mach-O header. */
1714 macho_write_header();
1716 offset
= fmt
.header_size
+ head_sizeofcmds
;
1718 /* emit the segment load command */
1720 offset
= macho_write_segment (offset
);
1722 nasm_error(ERR_WARNING
, "no sections?");
1725 /* write out symbol command */
1726 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1727 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1728 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1729 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1731 offset
+= nsyms
* fmt
.nlist_size
;
1732 fwriteint32_t(offset
, ofile
); /* string table offset */
1733 fwriteint32_t(strslen
, ofile
); /* string table size */
1736 /* emit section data */
1738 macho_write_section ();
1740 /* emit symbol table if we have symbols */
1742 macho_write_symtab ();
1744 /* we don't need to pad here, we are already aligned */
1746 /* emit string table */
1747 saa_fpwrite(strs
, ofile
);
1749 /* We do quite a bit here, starting with finalizing all of the data
1750 for the object file, writing, and then freeing all of the data from
1753 static void macho_cleanup(void)
1761 /* Sort all symbols. */
1762 macho_layout_symbols (&nsyms
, &strslen
);
1764 /* Fixup relocation entries */
1765 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1766 macho_fixup_relocs (s
->relocs
);
1769 /* First calculate and finalize needed values. */
1770 macho_calculate_sizes();
1773 /* free up everything */
1774 while (sects
->next
) {
1776 sects
= sects
->next
;
1779 while (s
->relocs
!= NULL
) {
1781 s
->relocs
= s
->relocs
->next
;
1798 nasm_free(extdefsyms
);
1799 nasm_free(undefsyms
);
1800 nasm_free(sectstab
);
1801 raa_free(section_by_index
);
1802 hash_free(§ion_by_name
);
1805 static bool macho_set_section_attribute_by_symbol(const char *label
, uint32_t flags
)
1811 if (!lookup_label(label
, &nasm_seg
, &offset
)) {
1812 nasm_error(ERR_NONFATAL
, "unknown symbol `%s' in no_dead_strip", label
);
1816 s
= get_section_by_index(nasm_seg
);
1818 nasm_error(ERR_NONFATAL
, "symbol `%s' is external or absolute", label
);
1827 * Mark a symbol for no dead stripping
1829 static enum directive_result
macho_no_dead_strip(const char *labels
)
1833 enum directive_result rv
= DIRR_ERROR
;
1834 bool real
= passn
> 1;
1836 p
= s
= nasm_strdup(labels
);
1838 ep
= nasm_skip_identifier(p
);
1840 nasm_error(ERR_NONFATAL
, "invalid symbol in NO_DEAD_STRIP");
1844 if (ec
&& ec
!= ',' && !nasm_isspace(ec
)) {
1845 nasm_error(ERR_NONFATAL
, "cannot parse contents after symbol");
1850 if (!macho_set_section_attribute_by_symbol(p
, S_ATTR_NO_DEAD_STRIP
))
1854 p
= nasm_skip_spaces(ep
);
1856 p
= nasm_skip_spaces(++p
);
1869 static enum directive_result
1870 macho_pragma(const struct pragma
*pragma
)
1872 bool real
= passn
> 1;
1874 switch (pragma
->opcode
) {
1875 case D_SUBSECTIONS_VIA_SYMBOLS
:
1877 return DIRR_BADPARAM
;
1880 head_flags
|= MH_SUBSECTIONS_VIA_SYMBOLS
;
1882 /* Jmp-match optimization conflicts */
1883 optimizing
.flag
|= OPTIM_DISABLE_JMP_MATCH
;
1887 case D_NO_DEAD_STRIP
:
1888 return macho_no_dead_strip(pragma
->tail
);
1891 return DIRR_UNKNOWN
; /* Not a Mach-O directive */
1895 static const struct pragma_facility macho_pragma_list
[] = {
1896 { "macho", macho_pragma
},
1897 { NULL
, macho_pragma
} /* Implements macho32/macho64 namespaces */
1900 static void macho_dbg_generate(void)
1902 uint8_t *p_buf
= NULL
, *p_buf_base
= NULL
;
1903 size_t saa_len
= 0, high_addr
= 0, total_len
= 0;
1904 struct section
*p_section
= NULL
;
1905 /* calculated at debug_str and referenced at debug_info */
1906 uint32_t producer_str_offset
= 0, module_str_offset
= 0, dir_str_offset
= 0;
1908 /* debug section defines */
1911 macho_section(".debug_abbrev", 0, &bits
);
1912 macho_section(".debug_info", 0, &bits
);
1913 macho_section(".debug_line", 0, &bits
);
1914 macho_section(".debug_str", 0, &bits
);
1917 /* dw section walk to find high_addr and total_len */
1919 struct dw_sect_list
*p_sect
;
1921 list_for_each(p_sect
, dw_head_sect
) {
1922 uint64_t offset
= get_section_by_index(p_sect
->section
)->size
;
1923 struct SAA
*p_linep
= p_sect
->psaa
;
1925 saa_write8(p_linep
, 2); /* std op 2 */
1926 saa_write8(p_linep
, offset
- p_sect
->offset
);
1927 saa_write8(p_linep
, DW_LNS_extended_op
);
1928 saa_write8(p_linep
, 1); /* operand length */
1929 saa_write8(p_linep
, DW_LNE_end_sequence
);
1931 total_len
+= p_linep
->datalen
;
1932 high_addr
+= offset
;
1938 struct dw_sect_list
*p_sect
;
1939 size_t linep_off
, buf_size
;
1940 struct SAA
*p_lines
= saa_init(1L);
1941 struct dir_list
*p_dir
;
1942 struct file_list
*p_file
;
1944 p_section
= get_section_by_name("__DWARF", "__debug_line");
1945 nasm_assert(p_section
!= NULL
);
1947 saa_write8(p_lines
, 1); /* minimum instruction length */
1948 saa_write8(p_lines
, 1); /* initial value of "is_stmt" */
1949 saa_write8(p_lines
, DW_LN_BASE
); /* line base */
1950 saa_write8(p_lines
, DW_LN_RANGE
); /* line range */
1951 saa_write8(p_lines
, DW_OPCODE_BASE
); /* opcode base */
1952 saa_write8(p_lines
, 0); /* std opcode 1 length */
1953 saa_write8(p_lines
, 1); /* std opcode 2 length */
1954 saa_write8(p_lines
, 1); /* std opcode 3 length */
1955 saa_write8(p_lines
, 1); /* std opcode 4 length */
1956 saa_write8(p_lines
, 1); /* std opcode 5 length */
1957 saa_write8(p_lines
, 0); /* std opcode 6 length */
1958 saa_write8(p_lines
, 0); /* std opcode 7 length */
1959 saa_write8(p_lines
, 0); /* std opcode 8 length */
1960 saa_write8(p_lines
, 1); /* std opcode 9 length */
1961 saa_write8(p_lines
, 0); /* std opcode 10 length */
1962 saa_write8(p_lines
, 0); /* std opcode 11 length */
1963 saa_write8(p_lines
, 1); /* std opcode 12 length */
1964 list_for_each(p_dir
, dw_head_dir
) {
1965 saa_wcstring(p_lines
, p_dir
->dir_name
);
1967 saa_write8(p_lines
, 0); /* end of table */
1969 list_for_each(p_file
, dw_head_file
) {
1970 saa_wcstring(p_lines
, p_file
->file_name
);
1971 saa_write8(p_lines
, p_file
->dir
->dir
); /* directory id */
1972 saa_write8(p_lines
, 0); /* time */
1973 saa_write8(p_lines
, 0); /* size */
1975 saa_write8(p_lines
, 0); /* end of table */
1977 linep_off
= p_lines
->datalen
;
1978 /* 10 bytes for initial & prolong length, and dwarf version info */
1979 buf_size
= saa_len
= linep_off
+ total_len
+ 10;
1980 p_buf_base
= p_buf
= nasm_malloc(buf_size
);
1982 WRITELONG(p_buf
, saa_len
- 4); /* initial length; size excluding itself */
1983 WRITESHORT(p_buf
, 2); /* dwarf version */
1984 WRITELONG(p_buf
, linep_off
); /* prolong length */
1986 saa_rnbytes(p_lines
, p_buf
, linep_off
);
1990 list_for_each(p_sect
, dw_head_sect
) {
1991 struct SAA
*p_linep
= p_sect
->psaa
;
1993 saa_len
= p_linep
->datalen
;
1994 saa_rnbytes(p_linep
, p_buf
, saa_len
);
2000 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, buf_size
, NO_SEG
, 0);
2002 nasm_free(p_buf_base
);
2005 /* string section */
2007 struct SAA
*p_str
= saa_init(1L);
2008 char *cur_path
= nasm_realpath(module_name
);
2009 char *cur_file
= nasm_basename(cur_path
);
2010 char *cur_dir
= nasm_dirname(cur_path
);
2012 p_section
= get_section_by_name("__DWARF", "__debug_str");
2013 nasm_assert(p_section
!= NULL
);
2015 producer_str_offset
= 0;
2016 module_str_offset
= dir_str_offset
= saa_wcstring(p_str
, nasm_signature
);
2017 dir_str_offset
+= saa_wcstring(p_str
, cur_file
);
2018 saa_wcstring(p_str
, cur_dir
);
2020 saa_len
= p_str
->datalen
;
2021 p_buf
= nasm_malloc(saa_len
);
2022 saa_rnbytes(p_str
, p_buf
, saa_len
);
2023 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2025 nasm_free(cur_path
);
2026 nasm_free(cur_file
);
2034 struct SAA
*p_info
= saa_init(1L);
2036 p_section
= get_section_by_name("__DWARF", "__debug_info");
2037 nasm_assert(p_section
!= NULL
);
2039 /* size will be overwritten once determined, so skip in p_info layout */
2040 saa_write16(p_info
, 2); /* dwarf version */
2041 saa_write32(p_info
, 0); /* offset info abbrev */
2042 saa_write8(p_info
, (ofmt
== &of_macho64
) ? 8 : 4); /* pointer size */
2044 saa_write8(p_info
, 1); /* abbrev entry number */
2046 saa_write32(p_info
, producer_str_offset
); /* offset from string table for DW_AT_producer */
2047 saa_write16(p_info
, DW_LANG_Mips_Assembler
); /* DW_AT_language */
2048 saa_write32(p_info
, module_str_offset
); /* offset from string table for DW_AT_name */
2049 saa_write32(p_info
, dir_str_offset
); /* offset from string table for DW_AT_comp_dir */
2050 saa_write32(p_info
, 0); /* DW_AT_stmt_list */
2052 if (ofmt
== &of_macho64
) {
2053 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2054 saa_write64(p_info
, high_addr
); /* DW_AT_high_pc */
2056 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2057 saa_write32(p_info
, high_addr
); /* DW_AT_high_pc */
2060 saa_write8(p_info
, 2); /* abbrev entry number */
2062 if (ofmt
== &of_macho64
) {
2063 saa_write64(p_info
, 0); /* DW_AT_low_pc */
2064 saa_write64(p_info
, 0); /* DW_AT_frame_base */
2066 saa_write32(p_info
, 0); /* DW_AT_low_pc */
2067 saa_write32(p_info
, 0); /* DW_AT_frame_base */
2069 saa_write8(p_info
, DW_END_default
);
2071 saa_len
= p_info
->datalen
;
2072 p_buf_base
= p_buf
= nasm_malloc(saa_len
+ 4); /* 4B for size info */
2074 WRITELONG(p_buf
, saa_len
);
2075 saa_rnbytes(p_info
, p_buf
, saa_len
);
2076 macho_output(p_section
->index
, p_buf_base
, OUT_RAWDATA
, saa_len
+ 4, NO_SEG
, 0);
2079 nasm_free(p_buf_base
);
2082 /* abbrev section */
2084 struct SAA
*p_abbrev
= saa_init(1L);
2086 p_section
= get_section_by_name("__DWARF", "__debug_abbrev");
2087 nasm_assert(p_section
!= NULL
);
2089 saa_write8(p_abbrev
, 1); /* entry number */
2091 saa_write8(p_abbrev
, DW_TAG_compile_unit
);
2092 saa_write8(p_abbrev
, DW_CHILDREN_yes
);
2094 saa_write8(p_abbrev
, DW_AT_producer
);
2095 saa_write8(p_abbrev
, DW_FORM_strp
);
2097 saa_write8(p_abbrev
, DW_AT_language
);
2098 saa_write8(p_abbrev
, DW_FORM_data2
);
2100 saa_write8(p_abbrev
, DW_AT_name
);
2101 saa_write8(p_abbrev
, DW_FORM_strp
);
2103 saa_write8(p_abbrev
, DW_AT_comp_dir
);
2104 saa_write8(p_abbrev
, DW_FORM_strp
);
2106 saa_write8(p_abbrev
, DW_AT_stmt_list
);
2107 saa_write8(p_abbrev
, DW_FORM_data4
);
2109 saa_write8(p_abbrev
, DW_AT_low_pc
);
2110 saa_write8(p_abbrev
, DW_FORM_addr
);
2112 saa_write8(p_abbrev
, DW_AT_high_pc
);
2113 saa_write8(p_abbrev
, DW_FORM_addr
);
2115 saa_write16(p_abbrev
, DW_END_default
);
2117 saa_write8(p_abbrev
, 2); /* entry number */
2119 saa_write8(p_abbrev
, DW_TAG_subprogram
);
2120 saa_write8(p_abbrev
, DW_CHILDREN_no
);
2122 saa_write8(p_abbrev
, DW_AT_low_pc
);
2123 saa_write8(p_abbrev
, DW_FORM_addr
);
2125 saa_write8(p_abbrev
, DW_AT_frame_base
);
2126 saa_write8(p_abbrev
, DW_FORM_addr
);
2128 saa_write16(p_abbrev
, DW_END_default
);
2130 saa_write8(p_abbrev
, 0); /* Terminal zero entry */
2132 saa_len
= p_abbrev
->datalen
;
2134 p_buf
= nasm_malloc(saa_len
);
2136 saa_rnbytes(p_abbrev
, p_buf
, saa_len
);
2137 macho_output(p_section
->index
, p_buf
, OUT_RAWDATA
, saa_len
, NO_SEG
, 0);
2144 static void new_file_list (const char *file_name
, const char *dir_name
)
2146 struct dir_list
*dir_list
;
2147 bool need_new_dir_list
= true;
2149 nasm_new(dw_cur_file
);
2150 dw_cur_file
->file
= ++dw_num_files
;
2151 dw_cur_file
->file_name
= file_name
;
2153 dw_head_file
= dw_cur_file
;
2155 *dw_last_file_next
= dw_cur_file
;
2157 dw_last_file_next
= &(dw_cur_file
->next
);
2160 list_for_each(dir_list
, dw_head_dir
) {
2161 if(!(strcmp(dir_name
, dir_list
->dir_name
))) {
2162 dw_cur_file
->dir
= dir_list
;
2163 need_new_dir_list
= false;
2169 if(need_new_dir_list
)
2172 dir_list
->dir
= dw_num_dirs
++;
2173 dir_list
->dir_name
= dir_name
;
2175 dw_head_dir
= dir_list
;
2177 *dw_last_dir_next
= dir_list
;
2179 dw_last_dir_next
= &(dir_list
->next
);
2180 dw_cur_file
->dir
= dir_list
;
2184 static void macho_dbg_init(void)
2188 static void macho_dbg_linenum(const char *file_name
, int32_t line_num
, int32_t segto
)
2190 bool need_new_list
= true;
2191 const char *cur_file
= nasm_basename(file_name
);
2192 const char *cur_dir
= nasm_dirname(file_name
);
2195 if(!dw_cur_file
|| strcmp(cur_file
, dw_cur_file
->file_name
) ||
2196 strcmp(cur_dir
, dw_cur_file
->dir
->dir_name
)) {
2198 struct file_list
*match
;
2200 list_for_each(match
, dw_head_file
) {
2201 if(!(strcmp(cur_file
, match
->file_name
)) &&
2202 !(strcmp(cur_dir
, match
->dir
->dir_name
))) {
2203 dw_cur_file
= match
;
2204 dw_cur_file
->dir
= match
->dir
;
2205 need_new_list
= false;
2212 new_file_list(cur_file
, cur_dir
);
2217 cur_line
= line_num
;
2220 static void macho_dbg_output(int type
, void *param
)
2222 struct section_info
*sinfo_param
= (struct section_info
*)param
;
2223 int32_t secto
= sinfo_param
->secto
;
2224 bool need_new_sect
= false;
2225 struct SAA
*p_linep
= NULL
;
2228 if(!(dw_cur_sect
&& (dw_cur_sect
->section
== secto
))) {
2229 need_new_sect
= true;
2231 struct dw_sect_list
*match
= dw_head_sect
;
2234 for(; idx
< dw_num_sects
; idx
++) {
2235 if(match
->section
== secto
) {
2236 dw_cur_sect
= match
;
2237 need_new_sect
= false;
2240 match
= match
->next
;
2246 nasm_new(dw_cur_sect
);
2248 p_linep
= dw_cur_sect
->psaa
= saa_init(1L);
2249 dw_cur_sect
->line
= dw_cur_sect
->file
= 1;
2250 dw_cur_sect
->offset
= 0;
2251 dw_cur_sect
->next
= NULL
;
2252 dw_cur_sect
->section
= secto
;
2254 saa_write8(p_linep
, DW_LNS_extended_op
);
2255 saa_write8(p_linep
, (ofmt
== &of_macho64
) ? 9 : 5);
2256 saa_write8(p_linep
, DW_LNE_set_address
);
2257 if (ofmt
== &of_macho64
) {
2258 saa_write64(p_linep
, 0);
2260 saa_write32(p_linep
, 0);
2264 dw_head_sect
= dw_last_sect
= dw_cur_sect
;
2266 dw_last_sect
->next
= dw_cur_sect
;
2267 dw_last_sect
= dw_cur_sect
;
2271 if(dbg_immcall
== true) {
2272 int32_t line_delta
= cur_line
- dw_cur_sect
->line
;
2273 int32_t offset_delta
= sinfo_param
->size
- dw_cur_sect
->offset
;
2274 uint32_t cur_file
= dw_cur_file
->file
;
2275 p_linep
= dw_cur_sect
->psaa
;
2277 if(cur_file
!= dw_cur_sect
->file
) {
2278 saa_write8(p_linep
, DW_LNS_set_file
);
2279 saa_write8(p_linep
, cur_file
);
2280 dw_cur_sect
->file
= cur_file
;
2284 int special_opcode
= (line_delta
- DW_LN_BASE
) + (DW_LN_RANGE
* offset_delta
) +
2287 if((line_delta
>= DW_LN_BASE
) && (line_delta
< DW_MAX_LN
) &&
2288 (special_opcode
< DW_MAX_SP_OPCODE
)) {
2289 saa_write8(p_linep
, special_opcode
);
2291 saa_write8(p_linep
, DW_LNS_advance_line
);
2292 saa_wleb128s(p_linep
, line_delta
);
2294 saa_write8(p_linep
, DW_LNS_advance_pc
);
2295 saa_wleb128u(p_linep
, offset_delta
);
2297 saa_write8(p_linep
, DW_LNS_copy
);
2300 dw_cur_sect
->line
= cur_line
;
2301 dw_cur_sect
->offset
= sinfo_param
->size
;
2304 dbg_immcall
= false;
2308 static void macho_dbg_cleanup(void)
2310 /* dwarf sectors generation */
2311 macho_dbg_generate();
2314 struct dw_sect_list
*p_sect
= dw_head_sect
;
2315 struct file_list
*p_file
= dw_head_file
;
2318 for(; idx
< dw_num_sects
; idx
++) {
2319 struct dw_sect_list
*next
= p_sect
->next
;
2324 for(idx
= 0; idx
< dw_num_files
; idx
++) {
2325 struct file_list
*next
= p_file
->next
;
2333 static const struct macho_fmt macho32_fmt
= {
2343 GENERIC_RELOC_VANILLA
,
2344 GENERIC_RELOC_VANILLA
,
2346 false /* Allow segment-relative relocations */
2349 static void macho32_init(void)
2354 macho_gotpcrel_sect
= NO_SEG
;
2357 static const struct dfmt macho32_df_dwarf
= {
2358 "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2362 null_debug_deflabel
,
2363 null_debug_directive
,
2364 null_debug_typevalue
,
2367 NULL
/*pragma list*/
2370 static const struct dfmt
* const macho32_df_arr
[2] =
2371 { &macho32_df_dwarf
, NULL
};
2373 const struct ofmt of_macho32
= {
2374 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2384 nasm_do_legacy_output
,
2398 static const struct macho_fmt macho64_fmt
= {
2403 MACHO_HEADER64_SIZE
,
2404 MACHO_SEGCMD64_SIZE
,
2405 MACHO_SECTCMD64_SIZE
,
2408 X86_64_RELOC_UNSIGNED
,
2409 X86_64_RELOC_SIGNED
,
2411 true /* Force symbol-relative relocations */
2414 static void macho64_init(void)
2419 /* add special symbol for ..gotpcrel */
2420 macho_gotpcrel_sect
= seg_alloc() + 1;
2421 backend_label("..gotpcrel", macho_gotpcrel_sect
, 0L);
2424 static const struct dfmt macho64_df_dwarf
= {
2425 "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2429 null_debug_deflabel
,
2430 null_debug_directive
,
2431 null_debug_typevalue
,
2434 NULL
/*pragma list*/
2437 static const struct dfmt
* const macho64_df_arr
[2] =
2438 { &macho64_df_dwarf
, NULL
};
2440 const struct ofmt of_macho64
= {
2441 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2451 nasm_do_legacy_output
,