1 /* ----------------------------------------------------------------------- *
2 *
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.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
10 *
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.
17 *
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.
31 *
32 * ----------------------------------------------------------------------- */
33
34 /*
35 * outmacho.c output routines for the Netwide Assembler to produce
36 * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
37 */
38
39 #include "compiler.h"
40
41 #include "nctype.h"
42
43 #include "nasm.h"
44 #include "nasmlib.h"
45 #include "ilog2.h"
46 #include "labels.h"
47 #include "error.h"
48 #include "saa.h"
49 #include "raa.h"
50 #include "rbtree.h"
51 #include "hashtbl.h"
52 #include "outform.h"
53 #include "outlib.h"
54 #include "ver.h"
55 #include "dwarf.h"
56 #include "macho.h"
57
58 #if defined(OF_MACHO) || defined(OF_MACHO64)
59
60 /* Mach-O in-file header structure sizes */
61 #define MACHO_HEADER_SIZE 28
62 #define MACHO_SEGCMD_SIZE 56
63 #define MACHO_SECTCMD_SIZE 68
64 #define MACHO_SYMCMD_SIZE 24
65 #define MACHO_NLIST_SIZE 12
66 #define MACHO_RELINFO_SIZE 8
67
68 #define MACHO_HEADER64_SIZE 32
69 #define MACHO_SEGCMD64_SIZE 72
70 #define MACHO_SECTCMD64_SIZE 80
71 #define MACHO_NLIST64_SIZE 16
72
73 /* Mach-O relocations numbers */
74
75 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
76 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
77
78 /* Our internal relocation types */
79 enum reltype {
80 RL_ABS, /* Absolute relocation */
81 RL_REL, /* Relative relocation */
82 RL_TLV, /* Thread local */
83 RL_BRANCH, /* Relative direct branch */
84 RL_SUB, /* X86_64_RELOC_SUBTRACT */
85 RL_GOT, /* X86_64_RELOC_GOT */
86 RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
87 };
88 #define RL_MAX_32 RL_TLV
89 #define RL_MAX_64 RL_GOTLOAD
90
91 struct macho_fmt {
92 uint32_t ptrsize; /* Pointer size in bytes */
93 uint32_t mh_magic; /* Which magic number to use */
94 uint32_t cpu_type; /* Which CPU type */
95 uint32_t lc_segment; /* Which segment load command */
96 uint32_t header_size; /* Header size */
97 uint32_t segcmd_size; /* Segment command size */
98 uint32_t sectcmd_size; /* Section command size */
99 uint32_t nlist_size; /* Nlist (symbol) size */
100 enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
101 uint32_t reloc_abs; /* Absolute relocation type */
102 uint32_t reloc_rel; /* Relative relocation type */
103 uint32_t reloc_tlv; /* Thread local relocation type */
104 bool forcesym; /* Always use "external" (symbol-relative) relocations */
105 };
106
107 static struct macho_fmt fmt;
108
fwriteptr(uint64_t data,FILE * fp)109 static void fwriteptr(uint64_t data, FILE * fp)
110 {
111 fwriteaddr(data, fmt.ptrsize, fp);
112 }
113
114 struct section {
115 /* nasm internal data */
116 struct section *next;
117 struct SAA *data;
118 int32_t index; /* Main section index */
119 int32_t subsection; /* Current subsection index */
120 int32_t fileindex;
121 struct reloc *relocs;
122 struct rbtree *syms[2]; /* All/global symbols symbols in section */
123 int align;
124 bool by_name; /* This section was specified by full MachO name */
125 char namestr[34]; /* segment,section as a C string */
126
127 /* data that goes into the file */
128 char sectname[16]; /* what this section is called */
129 char segname[16]; /* segment this section will be in */
130 uint64_t addr; /* in-memory address (subject to alignment) */
131 uint64_t size; /* in-memory and -file size */
132 uint64_t offset; /* in-file offset */
133 uint32_t pad; /* padding bytes before section */
134 uint32_t nreloc; /* relocation entry count */
135 uint32_t flags; /* type and attributes (masked) */
136 uint32_t extreloc; /* external relocations */
137 };
138
139 #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
140
141 /* fake section for absolute symbols, *not* part of the section linked list */
142 static struct section absolute_sect;
143
144 struct reloc {
145 /* nasm internal data */
146 struct reloc *next;
147
148 /* data that goes into the file */
149 int32_t addr; /* op's offset in section */
150 uint32_t snum:24, /* contains symbol index if
151 ** ext otherwise in-file
152 ** section number */
153 pcrel:1, /* relative relocation */
154 length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
155 ext:1, /* external symbol referenced */
156 type:4; /* reloc type */
157 };
158
159 struct symbol {
160 /* nasm internal data */
161 struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
162 symbol offset. */
163 struct symbol *next; /* next symbol in the list */
164 char *name; /* name of this symbol */
165 int32_t initial_snum; /* symbol number used above in reloc */
166 int32_t snum; /* true snum for reloc */
167
168 /* data that goes into the file */
169 uint32_t strx; /* string table index */
170 uint8_t type; /* symbol type */
171 uint8_t sect; /* NO_SECT or section number */
172 uint16_t desc; /* for stab debugging, 0 for us */
173 };
174
175 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
176
177 static struct section *sects, **sectstail, **sectstab;
178 static struct symbol *syms, **symstail;
179 static uint32_t nsyms;
180
181 /* These variables are set by macho_layout_symbols() to organize
182 the symbol table and string table in order the dynamic linker
183 expects. They are then used in macho_write() to put out the
184 symbols and strings in that order.
185
186 The order of the symbol table is:
187 local symbols
188 defined external symbols (sorted by name)
189 undefined external symbols (sorted by name)
190
191 The order of the string table is:
192 strings for external symbols
193 strings for local symbols
194 */
195 static uint32_t ilocalsym = 0;
196 static uint32_t iextdefsym = 0;
197 static uint32_t iundefsym = 0;
198 static uint32_t nlocalsym;
199 static uint32_t nextdefsym;
200 static uint32_t nundefsym;
201 static struct symbol **extdefsyms = NULL;
202 static struct symbol **undefsyms = NULL;
203
204 static struct RAA *extsyms;
205 static struct SAA *strs;
206 static uint32_t strslen;
207
208 /* Global file information. This should be cleaned up into either
209 a structure or as function arguments. */
210 static uint32_t head_ncmds = 0;
211 static uint32_t head_sizeofcmds = 0;
212 static uint32_t head_flags = 0;
213 static uint64_t seg_filesize = 0;
214 static uint64_t seg_vmsize = 0;
215 static uint32_t seg_nsects = 0;
216 static uint64_t rel_padcnt = 0;
217
218 /*
219 * Functions for handling fixed-length zero-padded string
220 * fields, that may or may not be null-terminated.
221 */
222
223 /* Copy a string into a zero-padded fixed-length field */
224 #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
225
226 /* Compare a fixed-length field with a string */
227 #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
228
229 #define alignint32_t(x) \
230 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
231
232 #define alignint64_t(x) \
233 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
234
235 #define alignptr(x) \
236 ALIGN(x, fmt.ptrsize) /* align x to output format width */
237
238 static struct hash_table section_by_name;
239 static struct RAA *section_by_index;
240
241 static struct section * never_null
find_or_add_section(const char * segname,const char * sectname)242 find_or_add_section(const char *segname, const char *sectname)
243 {
244 struct hash_insert hi;
245 void **sp;
246 struct section *s;
247 char sect[34];
248
249 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
250
251 sp = hash_find(§ion_by_name, sect, &hi);
252 if (sp)
253 return (struct section *)(*sp);
254
255 s = nasm_zalloc(sizeof *s);
256 xstrncpy(s->segname, segname);
257 xstrncpy(s->sectname, sectname);
258 xstrncpy(s->namestr, sect);
259 hash_add(&hi, s->namestr, s);
260
261 s->index = s->subsection = seg_alloc();
262 section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
263
264 return s;
265 }
266
is_new_section(const struct section * s)267 static inline bool is_new_section(const struct section *s)
268 {
269 return !s->data;
270 }
271
get_section_by_name(const char * segname,const char * sectname)272 static struct section *get_section_by_name(const char *segname,
273 const char *sectname)
274 {
275 char sect[34];
276 void **sp;
277
278 snprintf(sect, sizeof sect, "%-16s,%-16s", segname, sectname);
279
280 sp = hash_find(§ion_by_name, sect, NULL);
281 return sp ? (struct section *)(*sp) : NULL;
282 }
283
get_section_by_index(int32_t index)284 static struct section *get_section_by_index(int32_t index)
285 {
286 if (index < 0 || index >= SEG_ABS || (index & 1))
287 return NULL;
288
289 return raa_read_ptr(section_by_index, index >> 1);
290 }
291
292 struct dir_list {
293 struct dir_list *next;
294 struct dir_list *last;
295 const char *dir_name;
296 uint32_t dir;
297 };
298
299 struct file_list {
300 struct file_list *next;
301 struct file_list *last;
302 const char *file_name;
303 uint32_t file;
304 struct dir_list *dir;
305 };
306
307 struct dw_sect_list {
308 struct SAA *psaa;
309 int32_t section;
310 uint32_t line;
311 uint64_t offset;
312 uint32_t file;
313 struct dw_sect_list *next;
314 struct dw_sect_list *last;
315 };
316
317 struct section_info {
318 uint64_t size;
319 int32_t secto;
320 };
321
322 #define DW_LN_BASE (-5)
323 #define DW_LN_RANGE 14
324 #define DW_OPCODE_BASE 13
325 #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
326 #define DW_MAX_SP_OPCODE 256
327
328 static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
329 static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
330 static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
331 static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
332 static bool dbg_immcall = false;
333 static const char *module_name = NULL;
334
335 /*
336 * Special section numbers which are used to define Mach-O special
337 * symbols, which can be used with WRT to provide PIC relocation
338 * types.
339 */
340 static int32_t macho_tlvp_sect;
341 static int32_t macho_gotpcrel_sect;
342
macho_init(void)343 static void macho_init(void)
344 {
345 module_name = inname;
346 sects = NULL;
347 sectstail = §s;
348
349 /* Fake section for absolute symbols */
350 absolute_sect.index = NO_SEG;
351
352 syms = NULL;
353 symstail = &syms;
354 nsyms = 0;
355 nlocalsym = 0;
356 nextdefsym = 0;
357 nundefsym = 0;
358
359 extsyms = raa_init();
360 strs = saa_init(1L);
361
362 section_by_index = raa_init();
363
364 /* string table starts with a zero byte so index 0 is an empty string */
365 saa_wbytes(strs, zero_buffer, 1);
366 strslen = 1;
367
368 /* add special symbol for TLVP */
369 macho_tlvp_sect = seg_alloc() + 1;
370 backend_label("..tlvp", macho_tlvp_sect, 0L);
371 }
372
sect_write(struct section * sect,const uint8_t * data,uint32_t len)373 static void sect_write(struct section *sect,
374 const uint8_t *data, uint32_t len)
375 {
376 saa_wbytes(sect->data, data, len);
377 sect->size += len;
378 }
379
380 /*
381 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
382 */
macho_find_sym(struct section * s,uint64_t offset,bool global,bool exact)383 static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
384 bool global, bool exact)
385 {
386 struct rbtree *srb;
387
388 srb = rb_search(s->syms[global], offset);
389
390 if (!srb || (exact && srb->key != offset)) {
391 nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
392 " for this reference",
393 global ? " global" : "",
394 s == &absolute_sect ? " absolute " : "");
395 return NULL;
396 }
397
398 return container_of(srb - global, struct symbol, symv);
399 }
400
add_reloc(struct section * sect,int32_t section,int64_t offset,enum reltype reltype,int bytes)401 static int64_t add_reloc(struct section *sect, int32_t section,
402 int64_t offset,
403 enum reltype reltype, int bytes)
404 {
405 struct reloc *r;
406 struct section *s;
407 int32_t fi;
408 int64_t adjust;
409
410 /* Double check this is a valid relocation type for this platform */
411 nasm_assert(reltype <= fmt.maxreltype);
412
413 /* the current end of the section will be the symbol's address for
414 ** now, might have to be fixed by macho_fixup_relocs() later on. make
415 ** sure we don't make the symbol scattered by setting the highest
416 ** bit by accident */
417 r = nasm_malloc(sizeof(struct reloc));
418 r->addr = sect->size & ~R_SCATTERED;
419 r->ext = 1;
420 adjust = 0;
421
422 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
423 r->length = ilog2_32(bytes);
424
425 /* set default relocation values */
426 r->type = fmt.reloc_abs;
427 r->pcrel = 0;
428 r->snum = R_ABS;
429
430 s = get_section_by_index(section);
431 fi = s ? s->fileindex : NO_SECT;
432
433 /* absolute relocation */
434 switch (reltype) {
435 case RL_ABS:
436 if (section == NO_SEG) {
437 /* absolute (can this even happen?) */
438 r->ext = 0;
439 } else if (fi == NO_SECT) {
440 /* external */
441 r->snum = raa_read(extsyms, section);
442 } else {
443 /* local */
444 r->ext = 0;
445 r->snum = fi;
446 }
447 break;
448
449 case RL_REL:
450 case RL_BRANCH:
451 r->type = fmt.reloc_rel;
452 r->pcrel = 1;
453 if (section == NO_SEG) {
454 /* may optionally be converted below by fmt.forcesym */
455 r->ext = 0;
456 } else if (fi == NO_SECT) {
457 /* external */
458 sect->extreloc = 1;
459 r->snum = raa_read(extsyms, section);
460 if (reltype == RL_BRANCH)
461 r->type = X86_64_RELOC_BRANCH;
462 } else {
463 /* local */
464 r->ext = 0;
465 r->snum = fi;
466 if (reltype == RL_BRANCH)
467 r->type = X86_64_RELOC_BRANCH;
468 }
469 break;
470
471 case RL_SUB: /* obsolete */
472 nasm_warn(WARN_OTHER, "relcation with subtraction"
473 "becomes to be obsolete");
474 r->ext = 0;
475 r->type = X86_64_RELOC_SUBTRACTOR;
476 break;
477
478 case RL_GOT:
479 r->type = X86_64_RELOC_GOT;
480 goto needsym;
481
482 case RL_GOTLOAD:
483 r->type = X86_64_RELOC_GOT_LOAD;
484 goto needsym;
485
486 case RL_TLV:
487 r->type = fmt.reloc_tlv;
488 goto needsym;
489
490 needsym:
491 r->pcrel = (fmt.ptrsize == 8 ? 1 : 0);
492 if (section == NO_SEG) {
493 nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
494 goto bail;
495 } else if (fi == NO_SECT) {
496 /* external */
497 r->snum = raa_read(extsyms, section);
498 } else {
499 /* internal - GOTPCREL doesn't need to be in global */
500 struct symbol *sym = macho_find_sym(s, offset,
501 false, /* reltype != RL_TLV */
502 true);
503 if (!sym) {
504 nasm_error(ERR_NONFATAL, "Symbol for WRT not found");
505 goto bail;
506 }
507
508 adjust -= sym->symv[0].key;
509 r->snum = sym->initial_snum;
510 }
511 break;
512 }
513
514 /*
515 * For 64-bit Mach-O, force a symbol reference if at all possible
516 * Allow for r->snum == R_ABS by searching absolute_sect
517 */
518 if (!r->ext && fmt.forcesym) {
519 struct symbol *sym = macho_find_sym(s ? s : &absolute_sect,
520 offset, false, false);
521 if (sym) {
522 adjust -= sym->symv[0].key;
523 r->snum = sym->initial_snum;
524 r->ext = 1;
525 }
526 }
527
528 if (r->pcrel)
529 adjust += ((r->ext && fmt.ptrsize == 8) ? bytes : -(int64_t)sect->size);
530
531 /* NeXT as puts relocs in reversed order (address-wise) into the
532 ** files, so we do the same, doesn't seem to make much of a
533 ** difference either way */
534 r->next = sect->relocs;
535 sect->relocs = r;
536 if (r->ext)
537 sect->extreloc = 1;
538 ++sect->nreloc;
539
540 return adjust;
541
542 bail:
543 nasm_free(r);
544 return 0;
545 }
546
macho_output(int32_t secto,const void * data,enum out_type type,uint64_t size,int32_t section,int32_t wrt)547 static void macho_output(int32_t secto, const void *data,
548 enum out_type type, uint64_t size,
549 int32_t section, int32_t wrt)
550 {
551 struct section *s;
552 int64_t addr, offset;
553 uint8_t mydata[16], *p;
554 bool is_bss;
555 enum reltype reltype;
556
557 s = get_section_by_index(secto);
558 if (!s) {
559 nasm_warn(WARN_OTHER, "attempt to assemble code in"
560 " section %d: defaulting to `.text'", secto);
561 s = get_section_by_name("__TEXT", "__text");
562
563 /* should never happen */
564 if (!s)
565 nasm_panic("text section not found");
566 }
567
568 /* debug code generation only for sections tagged with
569 * instruction attribute */
570 if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
571 {
572 struct section_info sinfo;
573 sinfo.size = s->size;
574 sinfo.secto = secto;
575 dfmt->debug_output(0, &sinfo);
576 }
577
578 is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
579
580 if (is_bss && type != OUT_RESERVE) {
581 nasm_warn(WARN_OTHER, "attempt to initialize memory in "
582 "BSS section: ignored");
583 /* FIXME */
584 nasm_warn(WARN_OTHER, "section size may be negative"
585 "with address symbols");
586 s->size += realsize(type, size);
587 return;
588 }
589
590 memset(mydata, 0, sizeof(mydata));
591
592 switch (type) {
593 case OUT_RESERVE:
594 if (!is_bss) {
595 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
596 " %s,%s section: zeroing", s->segname, s->sectname);
597
598 sect_write(s, NULL, size);
599 } else
600 s->size += size;
601
602 break;
603
604 case OUT_RAWDATA:
605 sect_write(s, data, size);
606 break;
607
608 case OUT_ADDRESS:
609 {
610 int asize = abs((int)size);
611
612 addr = *(int64_t *)data;
613 if (section != NO_SEG) {
614 if (section % 2) {
615 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
616 " section base references");
617 } else if (wrt == NO_SEG) {
618 if (fmt.ptrsize == 8 && asize != 8) {
619 nasm_error(ERR_NONFATAL,
620 "Mach-O 64-bit format does not support"
621 " 32-bit absolute addresses");
622 } else {
623 addr += add_reloc(s, section, addr, RL_ABS, asize);
624 }
625 } else if (wrt == macho_tlvp_sect && fmt.ptrsize != 8 &&
626 asize == (int) fmt.ptrsize) {
627 addr += add_reloc(s, section, addr, RL_TLV, asize);
628 } else {
629 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
630 " this use of WRT");
631 }
632 }
633
634 p = mydata;
635 WRITEADDR(p, addr, asize);
636 sect_write(s, mydata, asize);
637 break;
638 }
639
640 case OUT_REL1ADR:
641 case OUT_REL2ADR:
642
643 p = mydata;
644 offset = *(int64_t *)data;
645 addr = offset - size;
646
647 if (section != NO_SEG && section % 2) {
648 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
649 " section base references");
650 } else if (fmt.ptrsize == 8) {
651 nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
652 " Macho-O relocation [2]");
653 } else if (wrt != NO_SEG) {
654 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
655 " this use of WRT");
656 wrt = NO_SEG; /* we can at least _try_ to continue */
657 } else {
658 addr += add_reloc(s, section, addr+size, RL_REL,
659 type == OUT_REL1ADR ? 1 : 2);
660 }
661
662 WRITESHORT(p, addr);
663 sect_write(s, mydata, type == OUT_REL1ADR ? 1 : 2);
664 break;
665
666 case OUT_REL4ADR:
667 case OUT_REL8ADR:
668
669 p = mydata;
670 offset = *(int64_t *)data;
671 addr = offset - size;
672 reltype = RL_REL;
673
674 if (section != NO_SEG && section % 2) {
675 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
676 " section base references");
677 } else if (wrt == NO_SEG) {
678 if (fmt.ptrsize == 8 &&
679 (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
680 uint8_t opcode[2];
681
682 opcode[0] = opcode[1] = 0;
683
684 /* HACK: Retrieve instruction opcode */
685 if (likely(s->data->datalen >= 2)) {
686 saa_fread(s->data, s->data->datalen-2, opcode, 2);
687 } else if (s->data->datalen == 1) {
688 saa_fread(s->data, 0, opcode+1, 1);
689 }
690
691 if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
692 (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
693 /* Direct call, jmp, or jcc */
694 reltype = RL_BRANCH;
695 }
696 }
697 } else if (wrt == macho_gotpcrel_sect) {
698 reltype = RL_GOT;
699
700 if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
701 s->data->datalen >= 3) {
702 uint8_t gotload[3];
703
704 /* HACK: Retrieve instruction opcode */
705 saa_fread(s->data, s->data->datalen-3, gotload, 3);
706 if ((gotload[0] & 0xf8) == 0x48 &&
707 gotload[1] == 0x8b &&
708 (gotload[2] & 0307) == 0005) {
709 /* movq <reg>,[rel sym wrt ..gotpcrel] */
710 reltype = RL_GOTLOAD;
711 }
712 }
713 } else if (wrt == macho_tlvp_sect && fmt.ptrsize == 8) {
714 reltype = RL_TLV;
715 } else {
716 nasm_error(ERR_NONFATAL, "Mach-O format does not support"
717 " this use of WRT");
718 /* continue with RL_REL */
719 }
720
721 addr += add_reloc(s, section, offset, reltype,
722 type == OUT_REL4ADR ? 4 : 8);
723 WRITELONG(p, addr);
724 sect_write(s, mydata, type == OUT_REL4ADR ? 4 : 8);
725 break;
726
727 default:
728 nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
729 break;
730 }
731 }
732
733 #define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
734 #define NO_TYPE S_NASM_TYPE_MASK
735
736 /* Translation table from traditional Unix section names to Mach-O */
737 static const struct macho_known_section {
738 const char *nasmsect;
739 const char *segname;
740 const char *sectname;
741 const uint32_t flags;
742 } known_sections[] = {
743 { ".text", "__TEXT", "__text", S_CODE },
744 { ".data", "__DATA", "__data", S_REGULAR },
745 { ".rodata", "__DATA", "__const", S_REGULAR },
746 { ".bss", "__DATA", "__bss", S_ZEROFILL },
747 { ".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG },
748 { ".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG },
749 { ".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG },
750 { ".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG },
751 };
752
753 /* Section type or attribute directives */
754 static const struct macho_known_section_attr {
755 const char *name;
756 uint32_t flags;
757 } sect_attribs[] = {
758 { "data", S_REGULAR },
759 { "code", S_CODE },
760 { "mixed", S_REGULAR | S_ATTR_SOME_INSTRUCTIONS },
761 { "bss", S_ZEROFILL },
762 { "zerofill", S_ZEROFILL },
763 { "no_dead_strip", NO_TYPE | S_ATTR_NO_DEAD_STRIP },
764 { "live_support", NO_TYPE | S_ATTR_LIVE_SUPPORT },
765 { "strip_static_syms", NO_TYPE | S_ATTR_STRIP_STATIC_SYMS },
766 { "debug", NO_TYPE | S_ATTR_DEBUG },
767 { NULL, 0 }
768 };
769
770 static const struct macho_known_section *
lookup_known_section(const char * name,bool by_sectname)771 lookup_known_section(const char *name, bool by_sectname)
772 {
773 size_t i;
774
775 if (name && name[0]) {
776 for (i = 0; i < ARRAY_SIZE(known_sections); i++) {
777 const char *p = by_sectname ?
778 known_sections[i].sectname :
779 known_sections[i].nasmsect;
780 if (!strcmp(name, p))
781 return &known_sections[i];
782 }
783 }
784
785 return NULL;
786 }
787
macho_section(char * name,int * bits)788 static int32_t macho_section(char *name, int *bits)
789 {
790 const struct macho_known_section *known_section;
791 const struct macho_known_section_attr *sa;
792 char *sectionAttributes;
793 struct section *s;
794 const char *section, *segment;
795 uint32_t flags;
796 char *currentAttribute;
797 char *comma;
798
799 bool new_seg;
800
801 /* Default to the appropriate number of bits. */
802 if (!name) {
803 *bits = fmt.ptrsize << 3;
804 name = ".text";
805 sectionAttributes = NULL;
806 } else {
807 sectionAttributes = name;
808 name = nasm_strsep(§ionAttributes, " \t");
809 }
810
811 section = segment = NULL;
812 flags = 0;
813
814 comma = strchr(name, ',');
815 if (comma) {
816 int len;
817
818 *comma = '\0';
819 segment = name;
820 section = comma+1;
821
822 len = strlen(segment);
823 if (len == 0) {
824 nasm_error(ERR_NONFATAL, "empty segment name\n");
825 } else if (len > 16) {
826 nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
827 }
828
829 len = strlen(section);
830 if (len == 0) {
831 nasm_error(ERR_NONFATAL, "empty section name\n");
832 } else if (len > 16) {
833 nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
834 }
835
836 known_section = lookup_known_section(section, true);
837 if (known_section)
838 flags = known_section->flags;
839 else
840 flags = S_REGULAR;
841 } else {
842 known_section = lookup_known_section(name, false);
843 if (!known_section) {
844 nasm_error(ERR_NONFATAL, "unknown section name %s\n", name);
845 return NO_SEG;
846 }
847
848 segment = known_section->segname;
849 section = known_section->sectname;
850 flags = known_section->flags;
851 }
852
853 /* try to find section with that name, or create it */
854 s = find_or_add_section(segment, section);
855 new_seg = is_new_section(s);
856
857 /* initialize it if it is a brand new section */
858 if (new_seg) {
859 *sectstail = s;
860 sectstail = &s->next;
861
862 s->data = saa_init(1L);
863 s->fileindex = ++seg_nsects;
864 s->align = -1;
865 s->pad = -1;
866 s->offset = -1;
867 s->by_name = false;
868
869 s->size = 0;
870 s->nreloc = 0;
871 s->flags = flags;
872 }
873
874 if (comma)
875 *comma = ','; /* Restore comma */
876
877 s->by_name = s->by_name || comma; /* Was specified by name */
878
879 flags = NO_TYPE;
880
881 while (sectionAttributes &&
882 (currentAttribute = nasm_strsep(§ionAttributes, " \t"))) {
883 if (!*currentAttribute)
884 continue;
885
886 if (!nasm_strnicmp("align=", currentAttribute, 6)) {
887 char *end;
888 int newAlignment, value;
889
890 value = strtoul(currentAttribute + 6, (char**)&end, 0);
891 newAlignment = alignlog2_32(value);
892
893 if (0 != *end) {
894 nasm_error(ERR_NONFATAL,
895 "unknown or missing alignment value \"%s\" "
896 "specified for section \"%s\"",
897 currentAttribute + 6,
898 name);
899 } else if (0 > newAlignment) {
900 nasm_error(ERR_NONFATAL,
901 "alignment of %d (for section \"%s\") is not "
902 "a power of two",
903 value,
904 name);
905 }
906
907 if (s->align < newAlignment)
908 s->align = newAlignment;
909 } else {
910 for (sa = sect_attribs; sa->name; sa++) {
911 if (!nasm_stricmp(sa->name, currentAttribute)) {
912 if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
913 flags = (flags & ~S_NASM_TYPE_MASK)
914 | (sa->flags & S_NASM_TYPE_MASK);
915 }
916 flags |= sa->flags & ~S_NASM_TYPE_MASK;
917 break;
918 }
919 }
920
921 if (!sa->name) {
922 nasm_error(ERR_NONFATAL,
923 "unknown section attribute %s for section %s",
924 currentAttribute, name);
925 }
926 }
927 }
928
929 if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
930 if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
931 nasm_error(ERR_NONFATAL,
932 "inconsistent section attributes for section %s\n",
933 name);
934 } else {
935 s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
936 }
937 } else {
938 s->flags |= flags & ~S_NASM_TYPE_MASK;
939 }
940
941 return s->subsection;
942 }
943
macho_herelabel(const char * name,enum label_type type,int32_t section,int32_t * subsection,bool * copyoffset)944 static int32_t macho_herelabel(const char *name, enum label_type type,
945 int32_t section, int32_t *subsection,
946 bool *copyoffset)
947 {
948 struct section *s;
949 int32_t subsec;
950 (void)name;
951
952 if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
953 return section;
954
955 /* No subsection only for local labels */
956 if (type == LBL_LOCAL)
957 return section;
958
959 s = get_section_by_index(section);
960 if (!s)
961 return section;
962
963 subsec = *subsection;
964 if (subsec == NO_SEG) {
965 /* Allocate a new subsection index */
966 subsec = *subsection = seg_alloc();
967 section_by_index = raa_write_ptr(section_by_index, subsec >> 1, s);
968 }
969
970 s->subsection = subsec;
971 *copyoffset = true; /* Maintain previous offset */
972 return subsec;
973 }
974
macho_symdef(char * name,int32_t section,int64_t offset,int is_global,char * special)975 static void macho_symdef(char *name, int32_t section, int64_t offset,
976 int is_global, char *special)
977 {
978 struct symbol *sym;
979 struct section *s;
980 bool special_used = false;
981
982 #if defined(DEBUG) && DEBUG>2
983 nasm_error(ERR_DEBUG,
984 " macho_symdef: %s, pass=%"PRId64" type %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
985 name, pass_count(), pass_types[pass_type()],
986 section, offset, is_global, special);
987 #endif
988
989 if (is_global == 3) {
990 if (special) {
991 int n = strcspn(special, " \t");
992
993 if (!nasm_strnicmp(special, "private_extern", n)) {
994 for (sym = syms; sym != NULL; sym = sym->next) {
995 if (!strcmp(name, sym->name)) {
996 if (sym->type & N_PEXT)
997 return; /* nothing to be done */
998 else
999 break;
1000 }
1001 }
1002 }
1003 }
1004 nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1005 "(yet) support forward reference fixups.");
1006 return;
1007 }
1008
1009 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1010 /*
1011 * This is a NASM special symbol. We never allow it into
1012 * the Macho-O symbol table, even if it's a valid one. If it
1013 * _isn't_ a valid one, we should barf immediately.
1014 */
1015 if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1016 nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1017 return;
1018 }
1019
1020 sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1021 sym->next = NULL;
1022 symstail = &sym->next;
1023
1024 sym->name = name;
1025 sym->strx = strslen;
1026 sym->type = 0;
1027 sym->desc = 0;
1028 sym->symv[0].key = offset;
1029 sym->symv[1].key = offset;
1030 sym->initial_snum = -1;
1031
1032 /* external and common symbols get N_EXT */
1033 if (is_global != 0) {
1034 sym->type |= N_EXT;
1035 }
1036 if (is_global == 1) {
1037 /* check special to see if the global symbol shall be marked as private external: N_PEXT */
1038 if (special) {
1039 int n = strcspn(special, " \t");
1040
1041 if (!nasm_strnicmp(special, "private_extern", n))
1042 sym->type |= N_PEXT;
1043 else
1044 nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'", n, special);
1045 }
1046 special_used = true;
1047 }
1048
1049 /* track the initially allocated symbol number for use in future fix-ups */
1050 sym->initial_snum = nsyms;
1051
1052 if (section == NO_SEG) {
1053 /* symbols in no section get absolute */
1054 sym->type |= N_ABS;
1055 sym->sect = NO_SECT;
1056
1057 s = &absolute_sect;
1058 } else {
1059 s = get_section_by_index(section);
1060
1061 sym->type |= N_SECT;
1062
1063 /* get the in-file index of the section the symbol was defined in */
1064 sym->sect = s ? s->fileindex : NO_SECT;
1065
1066 if (!s) {
1067 /* remember symbol number of references to external
1068 ** symbols, this works because every external symbol gets
1069 ** its own section number allocated internally by nasm and
1070 ** can so be used as a key */
1071 extsyms = raa_write(extsyms, section, nsyms);
1072
1073 switch (is_global) {
1074 case 1:
1075 case 2:
1076 /* there isn't actually a difference between global
1077 ** and common symbols, both even have their size in
1078 ** sym->symv[0].key */
1079 sym->type = N_EXT;
1080 break;
1081
1082 default:
1083 /* give an error on unfound section if it's not an
1084 ** external or common symbol (assemble_file() does a
1085 ** seg_alloc() on every call for them) */
1086 nasm_panic("in-file index for section %d not found, is_global = %d", section, is_global);
1087 break;
1088 }
1089 }
1090 }
1091
1092 if (s) {
1093 s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1094 if (is_global)
1095 s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1096 }
1097
1098 ++nsyms;
1099
1100 if (special && !special_used)
1101 nasm_error(ERR_NONFATAL, "no special symbol features supported here");
1102 }
1103
macho_sectalign(int32_t seg,unsigned int value)1104 static void macho_sectalign(int32_t seg, unsigned int value)
1105 {
1106 struct section *s;
1107 int align;
1108
1109 nasm_assert(!(seg & 1));
1110
1111 s = get_section_by_index(seg);
1112
1113 if (!s || !is_power2(value))
1114 return;
1115
1116 align = alignlog2_32(value);
1117 if (s->align < align)
1118 s->align = align;
1119 }
1120
1121 extern macros_t macho_stdmac[];
1122
1123 /* Comparison function for qsort symbol layout. */
layout_compare(const struct symbol ** s1,const struct symbol ** s2)1124 static int layout_compare (const struct symbol **s1,
1125 const struct symbol **s2)
1126 {
1127 return (strcmp ((*s1)->name, (*s2)->name));
1128 }
1129
1130 /* The native assembler does a few things in a similar function
1131
1132 * Remove temporary labels
1133 * Sort symbols according to local, external, undefined (by name)
1134 * Order the string table
1135
1136 We do not remove temporary labels right now.
1137
1138 numsyms is the total number of symbols we have. strtabsize is the
1139 number entries in the string table. */
1140
macho_layout_symbols(uint32_t * numsyms,uint32_t * strtabsize)1141 static void macho_layout_symbols (uint32_t *numsyms,
1142 uint32_t *strtabsize)
1143 {
1144 struct symbol *sym, **symp;
1145 uint32_t i,j;
1146
1147 *numsyms = 0;
1148 *strtabsize = sizeof (char);
1149
1150 symp = &syms;
1151
1152 while ((sym = *symp)) {
1153 /* Undefined symbols are now external. */
1154 if (sym->type == N_UNDF)
1155 sym->type |= N_EXT;
1156
1157 if ((sym->type & N_EXT) == 0) {
1158 sym->snum = *numsyms;
1159 *numsyms = *numsyms + 1;
1160 nlocalsym++;
1161 }
1162 else {
1163 if ((sym->type & N_TYPE) != N_UNDF) {
1164 nextdefsym++;
1165 } else {
1166 nundefsym++;
1167 }
1168
1169 /* If we handle debug info we'll want
1170 to check for it here instead of just
1171 adding the symbol to the string table. */
1172 sym->strx = *strtabsize;
1173 saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1174 *strtabsize += strlen(sym->name) + 1;
1175 }
1176 symp = &(sym->next);
1177 }
1178
1179 /* Next, sort the symbols. Most of this code is a direct translation from
1180 the Apple cctools symbol layout. We need to keep compatibility with that. */
1181 /* Set the indexes for symbol groups into the symbol table */
1182 ilocalsym = 0;
1183 iextdefsym = nlocalsym;
1184 iundefsym = nlocalsym + nextdefsym;
1185
1186 /* allocate arrays for sorting externals by name */
1187 extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1188 undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1189
1190 i = 0;
1191 j = 0;
1192
1193 symp = &syms;
1194
1195 while ((sym = *symp)) {
1196
1197 if((sym->type & N_EXT) == 0) {
1198 sym->strx = *strtabsize;
1199 saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1200 *strtabsize += strlen(sym->name) + 1;
1201 }
1202 else {
1203 if ((sym->type & N_TYPE) != N_UNDF) {
1204 extdefsyms[i++] = sym;
1205 } else {
1206 undefsyms[j++] = sym;
1207 }
1208 }
1209 symp = &(sym->next);
1210 }
1211
1212 qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1213 (int (*)(const void *, const void *))layout_compare);
1214 qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1215 (int (*)(const void *, const void *))layout_compare);
1216
1217 for(i = 0; i < nextdefsym; i++) {
1218 extdefsyms[i]->snum = *numsyms;
1219 *numsyms += 1;
1220 }
1221 for(j = 0; j < nundefsym; j++) {
1222 undefsyms[j]->snum = *numsyms;
1223 *numsyms += 1;
1224 }
1225 }
1226
1227 /* Calculate some values we'll need for writing later. */
1228
macho_calculate_sizes(void)1229 static void macho_calculate_sizes (void)
1230 {
1231 struct section *s;
1232 int fi;
1233
1234 /* count sections and calculate in-memory and in-file offsets */
1235 for (s = sects; s != NULL; s = s->next) {
1236 uint64_t newaddr;
1237
1238 /* recalculate segment address based on alignment and vm size */
1239 s->addr = seg_vmsize;
1240
1241 /* we need section alignment to calculate final section address */
1242 if (s->align == -1)
1243 s->align = DEFAULT_SECTION_ALIGNMENT;
1244
1245 newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1246 s->addr = newaddr;
1247
1248 seg_vmsize = newaddr + s->size;
1249
1250 /* zerofill sections aren't actually written to the file */
1251 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1252 /*
1253 * LLVM/Xcode as always aligns the section data to 4
1254 * bytes; there is a comment in the LLVM source code that
1255 * perhaps aligning to pointer size would be better.
1256 */
1257 s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1258 s->offset = seg_filesize + s->pad;
1259 seg_filesize += s->size + s->pad;
1260
1261 /* filesize and vmsize needs to be aligned */
1262 seg_vmsize += s->pad;
1263 }
1264 }
1265
1266 /* calculate size of all headers, load commands and sections to
1267 ** get a pointer to the start of all the raw data */
1268 if (seg_nsects > 0) {
1269 ++head_ncmds;
1270 head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1271 }
1272
1273 if (nsyms > 0) {
1274 ++head_ncmds;
1275 head_sizeofcmds += MACHO_SYMCMD_SIZE;
1276 }
1277
1278 if (seg_nsects > MAX_SECT) {
1279 nasm_fatal("MachO output is limited to %d sections\n",
1280 MAX_SECT);
1281 }
1282
1283 /* Create a table of sections by file index to avoid linear search */
1284 sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1285 sectstab[NO_SECT] = &absolute_sect;
1286 for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1287 sectstab[fi] = s;
1288 }
1289
1290 /* Write out the header information for the file. */
1291
macho_write_header(void)1292 static void macho_write_header (void)
1293 {
1294 fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1295 fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1296 fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1297 fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1298 fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1299 fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1300 fwriteint32_t(head_flags, ofile); /* flags, if any */
1301 fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1302 }
1303
1304 /* Write out the segment load command at offset. */
1305
macho_write_segment(uint64_t offset)1306 static uint32_t macho_write_segment (uint64_t offset)
1307 {
1308 uint64_t rel_base = alignptr(offset + seg_filesize);
1309 uint32_t s_reloff = 0;
1310 struct section *s;
1311
1312 fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1313
1314 /* size of load command including section load commands */
1315 fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1316 ofile);
1317
1318 /* in an MH_OBJECT file all sections are in one unnamed (name
1319 ** all zeros) segment */
1320 fwritezero(16, ofile);
1321 fwriteptr(0, ofile); /* in-memory offset */
1322 fwriteptr(seg_vmsize, ofile); /* in-memory size */
1323 fwriteptr(offset, ofile); /* in-file offset to data */
1324 fwriteptr(seg_filesize, ofile); /* in-file size */
1325 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1326 fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1327 fwriteint32_t(seg_nsects, ofile); /* number of sections */
1328 fwriteint32_t(0, ofile); /* no flags */
1329
1330 /* emit section headers */
1331 for (s = sects; s != NULL; s = s->next) {
1332 if (s->nreloc) {
1333 nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1334 s->flags |= S_ATTR_LOC_RELOC;
1335 if (s->extreloc)
1336 s->flags |= S_ATTR_EXT_RELOC;
1337 } else if (!xstrncmp(s->segname, "__DATA") &&
1338 !xstrncmp(s->sectname, "__const") &&
1339 !s->by_name &&
1340 !get_section_by_name("__TEXT", "__const")) {
1341 /*
1342 * The MachO equivalent to .rodata can be either
1343 * __DATA,__const or __TEXT,__const; the latter only if
1344 * there are no relocations. However, when mixed it is
1345 * better to specify the segments explicitly.
1346 */
1347 xstrncpy(s->segname, "__TEXT");
1348 }
1349
1350 nasm_write(s->sectname, sizeof(s->sectname), ofile);
1351 nasm_write(s->segname, sizeof(s->segname), ofile);
1352 fwriteptr(s->addr, ofile);
1353 fwriteptr(s->size, ofile);
1354
1355 /* dummy data for zerofill sections or proper values */
1356 if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1357 nasm_assert(s->pad != (uint32_t)-1);
1358 offset += s->pad;
1359 fwriteint32_t(offset, ofile);
1360 offset += s->size;
1361 /* Write out section alignment, as a power of two.
1362 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1363 fwriteint32_t(s->align, ofile);
1364 /* To be compatible with cctools as we emit
1365 a zero reloff if we have no relocations. */
1366 fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1367 fwriteint32_t(s->nreloc, ofile);
1368
1369 s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1370 } else {
1371 fwriteint32_t(0, ofile);
1372 fwriteint32_t(s->align, ofile);
1373 fwriteint32_t(0, ofile);
1374 fwriteint32_t(0, ofile);
1375 }
1376
1377 fwriteint32_t(s->flags, ofile); /* flags */
1378 fwriteint32_t(0, ofile); /* reserved */
1379 fwriteptr(0, ofile); /* reserved */
1380 }
1381
1382 rel_padcnt = rel_base - offset;
1383 offset = rel_base + s_reloff;
1384
1385 return offset;
1386 }
1387
1388 /* For a given chain of relocs r, write out the entire relocation
1389 chain to the object file. */
1390
macho_write_relocs(struct reloc * r)1391 static void macho_write_relocs (struct reloc *r)
1392 {
1393 while (r) {
1394 uint32_t word2;
1395
1396 fwriteint32_t(r->addr, ofile); /* reloc offset */
1397
1398 word2 = r->snum;
1399 word2 |= r->pcrel << 24;
1400 word2 |= r->length << 25;
1401 word2 |= r->ext << 27;
1402 word2 |= r->type << 28;
1403 fwriteint32_t(word2, ofile); /* reloc data */
1404 r = r->next;
1405 }
1406 }
1407
1408 /* Write out the section data. */
macho_write_section(void)1409 static void macho_write_section (void)
1410 {
1411 struct section *s;
1412 struct reloc *r;
1413 uint8_t *p;
1414 int32_t len;
1415 int64_t l;
1416 union offset {
1417 uint64_t val;
1418 uint8_t buf[8];
1419 } blk;
1420
1421 for (s = sects; s != NULL; s = s->next) {
1422 if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1423 continue;
1424
1425 /* Like a.out Mach-O references things in the data or bss
1426 * sections by addresses which are actually relative to the
1427 * start of the _text_ section, in the _file_. See outaout.c
1428 * for more information. */
1429 saa_rewind(s->data);
1430 for (r = s->relocs; r != NULL; r = r->next) {
1431 len = (uint32_t)1 << r->length;
1432 if (len > 4) /* Can this ever be an issue?! */
1433 len = 8;
1434 blk.val = 0;
1435 saa_fread(s->data, r->addr, blk.buf, len);
1436
1437 /* get offset based on relocation type */
1438 #ifdef WORDS_LITTLEENDIAN
1439 l = blk.val;
1440 #else
1441 l = blk.buf[0];
1442 l += ((int64_t)blk.buf[1]) << 8;
1443 l += ((int64_t)blk.buf[2]) << 16;
1444 l += ((int64_t)blk.buf[3]) << 24;
1445 l += ((int64_t)blk.buf[4]) << 32;
1446 l += ((int64_t)blk.buf[5]) << 40;
1447 l += ((int64_t)blk.buf[6]) << 48;
1448 l += ((int64_t)blk.buf[7]) << 56;
1449 #endif
1450
1451 /* If the relocation is internal add to the current section
1452 offset. Otherwise the only value we need is the symbol
1453 offset which we already have. The linker takes care
1454 of the rest of the address. */
1455 if (!r->ext) {
1456 /* generate final address by section address and offset */
1457 nasm_assert(r->snum <= seg_nsects);
1458 l += sectstab[r->snum]->addr;
1459 if (r->pcrel)
1460 l -= s->addr;
1461 } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1462 l -= s->addr;
1463 }
1464
1465 /* write new offset back */
1466 p = blk.buf;
1467 WRITEDLONG(p, l);
1468 saa_fwrite(s->data, r->addr, blk.buf, len);
1469 }
1470
1471 /* dump the section data to file */
1472 fwritezero(s->pad, ofile);
1473 saa_fpwrite(s->data, ofile);
1474 }
1475
1476 /* pad last section up to reloc entries on pointer boundary */
1477 fwritezero(rel_padcnt, ofile);
1478
1479 /* emit relocation entries */
1480 for (s = sects; s != NULL; s = s->next)
1481 macho_write_relocs (s->relocs);
1482 }
1483
1484 /* Write out the symbol table. We should already have sorted this
1485 before now. */
macho_write_symtab(void)1486 static void macho_write_symtab (void)
1487 {
1488 struct symbol *sym;
1489 uint64_t i;
1490
1491 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1492
1493 for (sym = syms; sym != NULL; sym = sym->next) {
1494 if ((sym->type & N_EXT) == 0) {
1495 fwriteint32_t(sym->strx, ofile); /* string table entry number */
1496 nasm_write(&sym->type, 1, ofile); /* symbol type */
1497 nasm_write(&sym->sect, 1, ofile); /* section */
1498 fwriteint16_t(sym->desc, ofile); /* description */
1499
1500 /* Fix up the symbol value now that we know the final section
1501 sizes. */
1502 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1503 nasm_assert(sym->sect <= seg_nsects);
1504 sym->symv[0].key += sectstab[sym->sect]->addr;
1505 }
1506
1507 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1508 }
1509 }
1510
1511 for (i = 0; i < nextdefsym; i++) {
1512 sym = extdefsyms[i];
1513 fwriteint32_t(sym->strx, ofile);
1514 nasm_write(&sym->type, 1, ofile); /* symbol type */
1515 nasm_write(&sym->sect, 1, ofile); /* section */
1516 fwriteint16_t(sym->desc, ofile); /* description */
1517
1518 /* Fix up the symbol value now that we know the final section
1519 sizes. */
1520 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1521 nasm_assert(sym->sect <= seg_nsects);
1522 sym->symv[0].key += sectstab[sym->sect]->addr;
1523 }
1524
1525 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1526 }
1527
1528 for (i = 0; i < nundefsym; i++) {
1529 sym = undefsyms[i];
1530 fwriteint32_t(sym->strx, ofile);
1531 nasm_write(&sym->type, 1, ofile); /* symbol type */
1532 nasm_write(&sym->sect, 1, ofile); /* section */
1533 fwriteint16_t(sym->desc, ofile); /* description */
1534
1535 /* Fix up the symbol value now that we know the final section
1536 sizes. */
1537 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1538 nasm_assert(sym->sect <= seg_nsects);
1539 sym->symv[0].key += sectstab[sym->sect]->addr;
1540 }
1541
1542 fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1543 }
1544
1545 }
1546
1547 /* Fixup the snum in the relocation entries, we should be
1548 doing this only for externally referenced symbols. */
macho_fixup_relocs(struct reloc * r)1549 static void macho_fixup_relocs (struct reloc *r)
1550 {
1551 struct symbol *sym;
1552
1553 while (r != NULL) {
1554 if (r->ext) {
1555 for (sym = syms; sym != NULL; sym = sym->next) {
1556 if (sym->initial_snum == r->snum) {
1557 r->snum = sym->snum;
1558 break;
1559 }
1560 }
1561 }
1562 r = r->next;
1563 }
1564 }
1565
1566 /* Write out the object file. */
1567
macho_write(void)1568 static void macho_write (void)
1569 {
1570 uint64_t offset = 0;
1571
1572 /* mach-o object file structure:
1573 **
1574 ** mach header
1575 ** uint32_t magic
1576 ** int cpu type
1577 ** int cpu subtype
1578 ** uint32_t mach file type
1579 ** uint32_t number of load commands
1580 ** uint32_t size of all load commands
1581 ** (includes section struct size of segment command)
1582 ** uint32_t flags
1583 **
1584 ** segment command
1585 ** uint32_t command type == LC_SEGMENT[_64]
1586 ** uint32_t size of load command
1587 ** (including section load commands)
1588 ** char[16] segment name
1589 ** pointer in-memory offset
1590 ** pointer in-memory size
1591 ** pointer in-file offset to data area
1592 ** pointer in-file size
1593 ** (in-memory size excluding zerofill sections)
1594 ** int maximum vm protection
1595 ** int initial vm protection
1596 ** uint32_t number of sections
1597 ** uint32_t flags
1598 **
1599 ** section commands
1600 ** char[16] section name
1601 ** char[16] segment name
1602 ** pointer in-memory offset
1603 ** pointer in-memory size
1604 ** uint32_t in-file offset
1605 ** uint32_t alignment
1606 ** (irrelevant in MH_OBJECT)
1607 ** uint32_t in-file offset of relocation entires
1608 ** uint32_t number of relocations
1609 ** uint32_t flags
1610 ** uint32_t reserved
1611 ** uint32_t reserved
1612 **
1613 ** symbol table command
1614 ** uint32_t command type == LC_SYMTAB
1615 ** uint32_t size of load command
1616 ** uint32_t symbol table offset
1617 ** uint32_t number of symbol table entries
1618 ** uint32_t string table offset
1619 ** uint32_t string table size
1620 **
1621 ** raw section data
1622 **
1623 ** padding to pointer boundary
1624 **
1625 ** relocation data (struct reloc)
1626 ** int32_t offset
1627 ** uint data (symbolnum, pcrel, length, extern, type)
1628 **
1629 ** symbol table data (struct nlist)
1630 ** int32_t string table entry number
1631 ** uint8_t type
1632 ** (extern, absolute, defined in section)
1633 ** uint8_t section
1634 ** (0 for global symbols, section number of definition (>= 1, <=
1635 ** 254) for local symbols, size of variable for common symbols
1636 ** [type == extern])
1637 ** int16_t description
1638 ** (for stab debugging format)
1639 ** pointer value (i.e. file offset) of symbol or stab offset
1640 **
1641 ** string table data
1642 ** list of null-terminated strings
1643 */
1644
1645 /* Emit the Mach-O header. */
1646 macho_write_header();
1647
1648 offset = fmt.header_size + head_sizeofcmds;
1649
1650 /* emit the segment load command */
1651 if (seg_nsects > 0)
1652 offset = macho_write_segment (offset);
1653 else
1654 nasm_warn(WARN_OTHER, "no sections?");
1655
1656 if (nsyms > 0) {
1657 /* write out symbol command */
1658 fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1659 fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1660 fwriteint32_t(offset, ofile); /* symbol table offset */
1661 fwriteint32_t(nsyms, ofile); /* number of symbol
1662 ** table entries */
1663 offset += nsyms * fmt.nlist_size;
1664 fwriteint32_t(offset, ofile); /* string table offset */
1665 fwriteint32_t(strslen, ofile); /* string table size */
1666 }
1667
1668 /* emit section data */
1669 if (seg_nsects > 0)
1670 macho_write_section ();
1671
1672 /* emit symbol table if we have symbols */
1673 if (nsyms > 0)
1674 macho_write_symtab ();
1675
1676 /* we don't need to pad here, we are already aligned */
1677
1678 /* emit string table */
1679 saa_fpwrite(strs, ofile);
1680 }
1681 /* We do quite a bit here, starting with finalizing all of the data
1682 for the object file, writing, and then freeing all of the data from
1683 the file. */
1684
macho_cleanup(void)1685 static void macho_cleanup(void)
1686 {
1687 struct section *s;
1688 struct reloc *r;
1689 struct symbol *sym;
1690
1691 dfmt->cleanup();
1692
1693 /* Sort all symbols. */
1694 macho_layout_symbols (&nsyms, &strslen);
1695
1696 /* Fixup relocation entries */
1697 for (s = sects; s != NULL; s = s->next) {
1698 macho_fixup_relocs (s->relocs);
1699 }
1700
1701 /* First calculate and finalize needed values. */
1702 macho_calculate_sizes();
1703 macho_write();
1704
1705 /* free up everything */
1706 while (sects->next) {
1707 s = sects;
1708 sects = sects->next;
1709
1710 saa_free(s->data);
1711 while (s->relocs != NULL) {
1712 r = s->relocs;
1713 s->relocs = s->relocs->next;
1714 nasm_free(r);
1715 }
1716
1717 nasm_free(s);
1718 }
1719
1720 saa_free(strs);
1721
1722 raa_free(extsyms);
1723
1724 while (syms) {
1725 sym = syms;
1726 syms = syms->next;
1727 nasm_free (sym);
1728 }
1729
1730 nasm_free(extdefsyms);
1731 nasm_free(undefsyms);
1732 nasm_free(sectstab);
1733 raa_free(section_by_index);
1734 hash_free(§ion_by_name);
1735 }
1736
macho_set_section_attribute_by_symbol(const char * label,uint32_t flags)1737 static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1738 {
1739 struct section *s;
1740 int32_t nasm_seg;
1741 int64_t offset;
1742
1743 if (lookup_label(label, &nasm_seg, &offset) == LBL_none) {
1744 nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1745 return false;
1746 }
1747
1748 s = get_section_by_index(nasm_seg);
1749 if (!s) {
1750 nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1751 return false;
1752 }
1753
1754 s->flags |= flags;
1755 return true;
1756 }
1757
1758 /*
1759 * Mark a symbol for no dead stripping
1760 */
macho_no_dead_strip(const char * labels)1761 static enum directive_result macho_no_dead_strip(const char *labels)
1762 {
1763 char *s, *p, *ep;
1764 char ec;
1765 enum directive_result rv = DIRR_ERROR;
1766
1767 p = s = nasm_strdup(labels);
1768 while (*p) {
1769 ep = nasm_skip_identifier(p);
1770 if (!ep) {
1771 nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1772 goto err;
1773 }
1774 ec = *ep;
1775 if (ec && ec != ',' && !nasm_isspace(ec)) {
1776 nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1777 goto err;
1778 }
1779 *ep = '\0';
1780 if (!pass_first()) {
1781 if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1782 rv = DIRR_ERROR;
1783 }
1784 *ep = ec;
1785 p = nasm_skip_spaces(ep);
1786 if (*p == ',')
1787 p = nasm_skip_spaces(++p);
1788 }
1789
1790 rv = DIRR_OK;
1791
1792 err:
1793 nasm_free(s);
1794 return rv;
1795 }
1796
1797 /*
1798 * Mach-O pragmas
1799 */
1800 static enum directive_result
macho_pragma(const struct pragma * pragma)1801 macho_pragma(const struct pragma *pragma)
1802 {
1803 switch (pragma->opcode) {
1804 case D_SUBSECTIONS_VIA_SYMBOLS:
1805 if (*pragma->tail)
1806 return DIRR_BADPARAM;
1807
1808 if (!pass_first())
1809 head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1810
1811 /* Jmp-match optimization conflicts */
1812 optimizing.flag |= OPTIM_DISABLE_JMP_MATCH;
1813
1814 return DIRR_OK;
1815
1816 case D_NO_DEAD_STRIP:
1817 return macho_no_dead_strip(pragma->tail);
1818
1819 default:
1820 return DIRR_UNKNOWN; /* Not a Mach-O directive */
1821 }
1822 }
1823
1824 static const struct pragma_facility macho_pragma_list[] = {
1825 { "macho", macho_pragma },
1826 { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1827 };
1828
macho_dbg_generate(void)1829 static void macho_dbg_generate(void)
1830 {
1831 uint8_t *p_buf = NULL, *p_buf_base = NULL;
1832 size_t saa_len = 0, high_addr = 0, total_len = 0;
1833 struct section *p_section = NULL;
1834 /* calculated at debug_str and referenced at debug_info */
1835 uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1836
1837 /* debug section defines */
1838 {
1839 int bits = 0;
1840 macho_section(".debug_abbrev", &bits);
1841 macho_section(".debug_info", &bits);
1842 macho_section(".debug_line", &bits);
1843 macho_section(".debug_str", &bits);
1844 }
1845
1846 /* dw section walk to find high_addr and total_len */
1847 {
1848 struct dw_sect_list *p_sect;
1849
1850 list_for_each(p_sect, dw_head_sect) {
1851 uint64_t offset = get_section_by_index(p_sect->section)->size;
1852 struct SAA *p_linep = p_sect->psaa;
1853
1854 saa_write8(p_linep, 2); /* std op 2 */
1855 saa_write8(p_linep, offset - p_sect->offset);
1856 saa_write8(p_linep, DW_LNS_extended_op);
1857 saa_write8(p_linep, 1); /* operand length */
1858 saa_write8(p_linep, DW_LNE_end_sequence);
1859
1860 total_len += p_linep->datalen;
1861 high_addr += offset;
1862 }
1863 }
1864
1865 /* debug line */
1866 {
1867 struct dw_sect_list *p_sect;
1868 size_t linep_off, buf_size;
1869 struct SAA *p_lines = saa_init(1L);
1870 struct dir_list *p_dir;
1871 struct file_list *p_file;
1872
1873 p_section = get_section_by_name("__DWARF", "__debug_line");
1874 nasm_assert(p_section != NULL);
1875
1876 saa_write8(p_lines, 1); /* minimum instruction length */
1877 saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1878 saa_write8(p_lines, DW_LN_BASE); /* line base */
1879 saa_write8(p_lines, DW_LN_RANGE); /* line range */
1880 saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1881 saa_write8(p_lines, 0); /* std opcode 1 length */
1882 saa_write8(p_lines, 1); /* std opcode 2 length */
1883 saa_write8(p_lines, 1); /* std opcode 3 length */
1884 saa_write8(p_lines, 1); /* std opcode 4 length */
1885 saa_write8(p_lines, 1); /* std opcode 5 length */
1886 saa_write8(p_lines, 0); /* std opcode 6 length */
1887 saa_write8(p_lines, 0); /* std opcode 7 length */
1888 saa_write8(p_lines, 0); /* std opcode 8 length */
1889 saa_write8(p_lines, 1); /* std opcode 9 length */
1890 saa_write8(p_lines, 0); /* std opcode 10 length */
1891 saa_write8(p_lines, 0); /* std opcode 11 length */
1892 saa_write8(p_lines, 1); /* std opcode 12 length */
1893 list_for_each(p_dir, dw_head_dir) {
1894 saa_wcstring(p_lines, p_dir->dir_name);
1895 }
1896 saa_write8(p_lines, 0); /* end of table */
1897
1898 list_for_each(p_file, dw_head_file) {
1899 saa_wcstring(p_lines, p_file->file_name);
1900 saa_write8(p_lines, p_file->dir->dir); /* directory id */
1901 saa_write8(p_lines, 0); /* time */
1902 saa_write8(p_lines, 0); /* size */
1903 }
1904 saa_write8(p_lines, 0); /* end of table */
1905
1906 linep_off = p_lines->datalen;
1907 /* 10 bytes for initial & prolong length, and dwarf version info */
1908 buf_size = saa_len = linep_off + total_len + 10;
1909 p_buf_base = p_buf = nasm_malloc(buf_size);
1910
1911 WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1912 WRITESHORT(p_buf, 2); /* dwarf version */
1913 WRITELONG(p_buf, linep_off); /* prolong length */
1914
1915 saa_rnbytes(p_lines, p_buf, linep_off);
1916 p_buf += linep_off;
1917 saa_free(p_lines);
1918
1919 list_for_each(p_sect, dw_head_sect) {
1920 struct SAA *p_linep = p_sect->psaa;
1921
1922 saa_len = p_linep->datalen;
1923 saa_rnbytes(p_linep, p_buf, saa_len);
1924 p_buf += saa_len;
1925
1926 saa_free(p_linep);
1927 }
1928
1929 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1930
1931 nasm_free(p_buf_base);
1932 }
1933
1934 /* string section */
1935 {
1936 struct SAA *p_str = saa_init(1L);
1937 char *cur_path = nasm_realpath(module_name);
1938 char *cur_file = nasm_basename(cur_path);
1939 char *cur_dir = nasm_dirname(cur_path);
1940
1941 p_section = get_section_by_name("__DWARF", "__debug_str");
1942 nasm_assert(p_section != NULL);
1943
1944 producer_str_offset = 0;
1945 module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature());
1946 dir_str_offset += saa_wcstring(p_str, cur_file);
1947 saa_wcstring(p_str, cur_dir);
1948
1949 saa_len = p_str->datalen;
1950 p_buf = nasm_malloc(saa_len);
1951 saa_rnbytes(p_str, p_buf, saa_len);
1952 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1953
1954 nasm_free(cur_path);
1955 nasm_free(cur_file);
1956 nasm_free(cur_dir);
1957 saa_free(p_str);
1958 nasm_free(p_buf);
1959 }
1960
1961 /* debug info */
1962 {
1963 struct SAA *p_info = saa_init(1L);
1964
1965 p_section = get_section_by_name("__DWARF", "__debug_info");
1966 nasm_assert(p_section != NULL);
1967
1968 /* size will be overwritten once determined, so skip in p_info layout */
1969 saa_write16(p_info, 2); /* dwarf version */
1970 saa_write32(p_info, 0); /* offset info abbrev */
1971 saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1972
1973 saa_write8(p_info, 1); /* abbrev entry number */
1974
1975 saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1976 saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1977 saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1978 saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1979 saa_write32(p_info, 0); /* DW_AT_stmt_list */
1980
1981 if (ofmt == &of_macho64) {
1982 saa_write64(p_info, 0); /* DW_AT_low_pc */
1983 saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1984 } else {
1985 saa_write32(p_info, 0); /* DW_AT_low_pc */
1986 saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1987 }
1988
1989 saa_write8(p_info, 2); /* abbrev entry number */
1990
1991 if (ofmt == &of_macho64) {
1992 saa_write64(p_info, 0); /* DW_AT_low_pc */
1993 saa_write64(p_info, 0); /* DW_AT_frame_base */
1994 } else {
1995 saa_write32(p_info, 0); /* DW_AT_low_pc */
1996 saa_write32(p_info, 0); /* DW_AT_frame_base */
1997 }
1998 saa_write8(p_info, DW_END_default);
1999
2000 saa_len = p_info->datalen;
2001 p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
2002
2003 WRITELONG(p_buf, saa_len);
2004 saa_rnbytes(p_info, p_buf, saa_len);
2005 macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
2006
2007 saa_free(p_info);
2008 nasm_free(p_buf_base);
2009 }
2010
2011 /* abbrev section */
2012 {
2013 struct SAA *p_abbrev = saa_init(1L);
2014
2015 p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2016 nasm_assert(p_section != NULL);
2017
2018 saa_write8(p_abbrev, 1); /* entry number */
2019
2020 saa_write8(p_abbrev, DW_TAG_compile_unit);
2021 saa_write8(p_abbrev, DW_CHILDREN_yes);
2022
2023 saa_write8(p_abbrev, DW_AT_producer);
2024 saa_write8(p_abbrev, DW_FORM_strp);
2025
2026 saa_write8(p_abbrev, DW_AT_language);
2027 saa_write8(p_abbrev, DW_FORM_data2);
2028
2029 saa_write8(p_abbrev, DW_AT_name);
2030 saa_write8(p_abbrev, DW_FORM_strp);
2031
2032 saa_write8(p_abbrev, DW_AT_comp_dir);
2033 saa_write8(p_abbrev, DW_FORM_strp);
2034
2035 saa_write8(p_abbrev, DW_AT_stmt_list);
2036 saa_write8(p_abbrev, DW_FORM_data4);
2037
2038 saa_write8(p_abbrev, DW_AT_low_pc);
2039 saa_write8(p_abbrev, DW_FORM_addr);
2040
2041 saa_write8(p_abbrev, DW_AT_high_pc);
2042 saa_write8(p_abbrev, DW_FORM_addr);
2043
2044 saa_write16(p_abbrev, DW_END_default);
2045
2046 saa_write8(p_abbrev, 2); /* entry number */
2047
2048 saa_write8(p_abbrev, DW_TAG_subprogram);
2049 saa_write8(p_abbrev, DW_CHILDREN_no);
2050
2051 saa_write8(p_abbrev, DW_AT_low_pc);
2052 saa_write8(p_abbrev, DW_FORM_addr);
2053
2054 saa_write8(p_abbrev, DW_AT_frame_base);
2055 saa_write8(p_abbrev, DW_FORM_addr);
2056
2057 saa_write16(p_abbrev, DW_END_default);
2058
2059 saa_write8(p_abbrev, 0); /* Terminal zero entry */
2060
2061 saa_len = p_abbrev->datalen;
2062
2063 p_buf = nasm_malloc(saa_len);
2064
2065 saa_rnbytes(p_abbrev, p_buf, saa_len);
2066 macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2067
2068 saa_free(p_abbrev);
2069 nasm_free(p_buf);
2070 }
2071 }
2072
new_file_list(const char * file_name,const char * dir_name)2073 static void new_file_list (const char *file_name, const char *dir_name)
2074 {
2075 struct dir_list *dir_list;
2076 bool need_new_dir_list = true;
2077
2078 nasm_new(dw_cur_file);
2079 dw_cur_file->file = ++dw_num_files;
2080 dw_cur_file->file_name = file_name;
2081 if(!dw_head_file) {
2082 dw_head_file = dw_cur_file;
2083 } else {
2084 *dw_last_file_next = dw_cur_file;
2085 }
2086 dw_last_file_next = &(dw_cur_file->next);
2087
2088 if(dw_head_dir) {
2089 list_for_each(dir_list, dw_head_dir) {
2090 if(!(strcmp(dir_name, dir_list->dir_name))) {
2091 dw_cur_file->dir = dir_list;
2092 need_new_dir_list = false;
2093 break;
2094 }
2095 }
2096 }
2097
2098 if(need_new_dir_list)
2099 {
2100 nasm_new(dir_list);
2101 dir_list->dir = dw_num_dirs++;
2102 dir_list->dir_name = dir_name;
2103 if(!dw_head_dir) {
2104 dw_head_dir = dir_list;
2105 } else {
2106 *dw_last_dir_next = dir_list;
2107 }
2108 dw_last_dir_next = &(dir_list->next);
2109 dw_cur_file->dir = dir_list;
2110 }
2111 }
2112
macho_dbg_init(void)2113 static void macho_dbg_init(void)
2114 {
2115 }
2116
macho_dbg_linenum(const char * file_name,int32_t line_num,int32_t segto)2117 static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2118 {
2119 bool need_new_list = true;
2120 const char *cur_file = nasm_basename(file_name);
2121 const char *cur_dir = nasm_dirname(file_name);
2122 (void)segto;
2123
2124 if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2125 strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2126 if(dw_head_file) {
2127 struct file_list *match;
2128
2129 list_for_each(match, dw_head_file) {
2130 if(!(strcmp(cur_file, match->file_name)) &&
2131 !(strcmp(cur_dir, match->dir->dir_name))) {
2132 dw_cur_file = match;
2133 dw_cur_file->dir = match->dir;
2134 need_new_list = false;
2135 break;
2136 }
2137 }
2138 }
2139
2140 if(need_new_list) {
2141 new_file_list(cur_file, cur_dir);
2142 }
2143 }
2144
2145 dbg_immcall = true;
2146 cur_line = line_num;
2147 }
2148
macho_dbg_output(int type,void * param)2149 static void macho_dbg_output(int type, void *param)
2150 {
2151 struct section_info *sinfo_param = (struct section_info *)param;
2152 int32_t secto = sinfo_param->secto;
2153 bool need_new_sect = false;
2154 struct SAA *p_linep = NULL;
2155 (void)type;
2156
2157 if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2158 need_new_sect = true;
2159 if(dw_head_sect) {
2160 struct dw_sect_list *match = dw_head_sect;
2161 uint32_t idx = 0;
2162
2163 for(; idx < dw_num_sects; idx++) {
2164 if(match->section == secto) {
2165 dw_cur_sect = match;
2166 need_new_sect = false;
2167 break;
2168 }
2169 match = match->next;
2170 }
2171 }
2172 }
2173
2174 if(need_new_sect) {
2175 nasm_new(dw_cur_sect);
2176 dw_num_sects ++;
2177 p_linep = dw_cur_sect->psaa = saa_init(1L);
2178 dw_cur_sect->line = dw_cur_sect->file = 1;
2179 dw_cur_sect->offset = 0;
2180 dw_cur_sect->next = NULL;
2181 dw_cur_sect->section = secto;
2182
2183 saa_write8(p_linep, DW_LNS_extended_op);
2184 saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2185 saa_write8(p_linep, DW_LNE_set_address);
2186 if (ofmt == &of_macho64) {
2187 saa_write64(p_linep, 0);
2188 } else {
2189 saa_write32(p_linep, 0);
2190 }
2191
2192 if(!dw_head_sect) {
2193 dw_head_sect = dw_last_sect = dw_cur_sect;
2194 } else {
2195 dw_last_sect->next = dw_cur_sect;
2196 dw_last_sect = dw_cur_sect;
2197 }
2198 }
2199
2200 if(dbg_immcall == true) {
2201 int32_t line_delta = cur_line - dw_cur_sect->line;
2202 int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2203 uint32_t cur_file = dw_cur_file->file;
2204 p_linep = dw_cur_sect->psaa;
2205
2206 if(cur_file != dw_cur_sect->file) {
2207 saa_write8(p_linep, DW_LNS_set_file);
2208 saa_write8(p_linep, cur_file);
2209 dw_cur_sect->file = cur_file;
2210 }
2211
2212 if(line_delta) {
2213 int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2214 DW_OPCODE_BASE;
2215
2216 if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2217 (special_opcode < DW_MAX_SP_OPCODE)) {
2218 saa_write8(p_linep, special_opcode);
2219 } else {
2220 saa_write8(p_linep, DW_LNS_advance_line);
2221 saa_wleb128s(p_linep, line_delta);
2222 if(offset_delta) {
2223 saa_write8(p_linep, DW_LNS_advance_pc);
2224 saa_wleb128u(p_linep, offset_delta);
2225 }
2226 saa_write8(p_linep, DW_LNS_copy);
2227 }
2228
2229 dw_cur_sect->line = cur_line;
2230 dw_cur_sect->offset = sinfo_param->size;
2231 }
2232
2233 dbg_immcall = false;
2234 }
2235 }
2236
macho_dbg_cleanup(void)2237 static void macho_dbg_cleanup(void)
2238 {
2239 /* dwarf sectors generation */
2240 macho_dbg_generate();
2241
2242 {
2243 struct dw_sect_list *p_sect = dw_head_sect;
2244 struct file_list *p_file = dw_head_file;
2245 uint32_t idx = 0;
2246
2247 for(; idx < dw_num_sects; idx++) {
2248 struct dw_sect_list *next = p_sect->next;
2249 nasm_free(p_sect);
2250 p_sect = next;
2251 }
2252
2253 for(idx = 0; idx < dw_num_files; idx++) {
2254 struct file_list *next = p_file->next;
2255 nasm_free(p_file);
2256 p_file = next;
2257 }
2258 }
2259 }
2260
2261 #ifdef OF_MACHO32
2262 static const struct macho_fmt macho32_fmt = {
2263 4,
2264 MH_MAGIC,
2265 CPU_TYPE_I386,
2266 LC_SEGMENT,
2267 MACHO_HEADER_SIZE,
2268 MACHO_SEGCMD_SIZE,
2269 MACHO_SECTCMD_SIZE,
2270 MACHO_NLIST_SIZE,
2271 RL_MAX_32,
2272 GENERIC_RELOC_VANILLA,
2273 GENERIC_RELOC_VANILLA,
2274 GENERIC_RELOC_TLV,
2275 false /* Allow segment-relative relocations */
2276 };
2277
macho32_init(void)2278 static void macho32_init(void)
2279 {
2280 fmt = macho32_fmt;
2281 macho_init();
2282
2283 macho_gotpcrel_sect = NO_SEG;
2284 }
2285
2286 static const struct dfmt macho32_df_dwarf = {
2287 "Mach-O i386 dwarf for Darwin/MacOS",
2288 "dwarf",
2289 macho_dbg_init,
2290 macho_dbg_linenum,
2291 null_debug_deflabel,
2292 null_debug_directive,
2293 null_debug_typevalue,
2294 macho_dbg_output,
2295 macho_dbg_cleanup,
2296 NULL /*pragma list*/
2297 };
2298
2299 static const struct dfmt * const macho32_df_arr[2] =
2300 { &macho32_df_dwarf, NULL };
2301
2302 const struct ofmt of_macho32 = {
2303 "Mach-O i386 (Mach, including MacOS X and variants)",
2304 "macho32",
2305 ".o",
2306 0,
2307 32,
2308 macho32_df_arr,
2309 &macho32_df_dwarf,
2310 macho_stdmac,
2311 macho32_init,
2312 null_reset,
2313 nasm_do_legacy_output,
2314 macho_output,
2315 macho_symdef,
2316 macho_section,
2317 macho_herelabel,
2318 macho_sectalign,
2319 null_segbase,
2320 null_directive,
2321 macho_cleanup,
2322 macho_pragma_list
2323 };
2324 #endif
2325
2326 #ifdef OF_MACHO64
2327 static const struct macho_fmt macho64_fmt = {
2328 8,
2329 MH_MAGIC_64,
2330 CPU_TYPE_X86_64,
2331 LC_SEGMENT_64,
2332 MACHO_HEADER64_SIZE,
2333 MACHO_SEGCMD64_SIZE,
2334 MACHO_SECTCMD64_SIZE,
2335 MACHO_NLIST64_SIZE,
2336 RL_MAX_64,
2337 X86_64_RELOC_UNSIGNED,
2338 X86_64_RELOC_SIGNED,
2339 X86_64_RELOC_TLV,
2340 true /* Force symbol-relative relocations */
2341 };
2342
macho64_init(void)2343 static void macho64_init(void)
2344 {
2345 fmt = macho64_fmt;
2346 macho_init();
2347
2348 /* add special symbol for ..gotpcrel */
2349 macho_gotpcrel_sect = seg_alloc() + 1;
2350 backend_label("..gotpcrel", macho_gotpcrel_sect, 0L);
2351 }
2352
2353 static const struct dfmt macho64_df_dwarf = {
2354 "Mach-O x86-64 dwarf for Darwin/MacOS",
2355 "dwarf",
2356 macho_dbg_init,
2357 macho_dbg_linenum,
2358 null_debug_deflabel,
2359 null_debug_directive,
2360 null_debug_typevalue,
2361 macho_dbg_output,
2362 macho_dbg_cleanup,
2363 NULL /*pragma list*/
2364 };
2365
2366 static const struct dfmt * const macho64_df_arr[2] =
2367 { &macho64_df_dwarf, NULL };
2368
2369 const struct ofmt of_macho64 = {
2370 "Mach-O x86-64 (Mach, including MacOS X and variants)",
2371 "macho64",
2372 ".o",
2373 0,
2374 64,
2375 macho64_df_arr,
2376 &macho64_df_dwarf,
2377 macho_stdmac,
2378 macho64_init,
2379 null_reset,
2380 nasm_do_legacy_output,
2381 macho_output,
2382 macho_symdef,
2383 macho_section,
2384 macho_herelabel,
2385 macho_sectalign,
2386 null_segbase,
2387 null_directive,
2388 macho_cleanup,
2389 macho_pragma_list,
2390 };
2391 #endif
2392
2393 #endif
2394
2395 /*
2396 * Local Variables:
2397 * mode:c
2398 * c-basic-offset:4
2399 * End:
2400 *
2401 * end of file */
2402