1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 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
39 /* Most of this file is, like Mach-O itself, based on a.out. For more
40 * guidelines see outaout.c. */
54 #include "output/outform.h"
55 #include "output/outlib.h"
57 #if defined(OF_MACHO32)
59 /* Mach-O in-file header structure sizes */
60 #define MACHO_HEADER_SIZE (28)
61 #define MACHO_SEGCMD_SIZE (56)
62 #define MACHO_SECTCMD_SIZE (68)
63 #define MACHO_SYMCMD_SIZE (24)
64 #define MACHO_NLIST_SIZE (12)
65 #define MACHO_RELINFO_SIZE (8)
67 /* Mach-O file header values */
68 #define MH_MAGIC (0xfeedface)
69 #define CPU_TYPE_I386 (7) /* x86 platform */
70 #define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */
71 #define MH_OBJECT (0x1) /* object file */
73 #define LC_SEGMENT (0x1) /* segment load command */
74 #define LC_SYMTAB (0x2) /* symbol table load command */
76 #define VM_PROT_NONE (0x00)
77 #define VM_PROT_READ (0x01)
78 #define VM_PROT_WRITE (0x02)
79 #define VM_PROT_EXECUTE (0x04)
81 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
82 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
85 /* nasm internal data */
92 /* data that goes into the file */
93 char sectname
[16]; /* what this section is called */
94 char segname
[16]; /* segment this section will be in */
95 uint32_t addr
; /* in-memory address (subject to alignment) */
96 uint32_t size
; /* in-memory and -file size */
97 uint32_t nreloc
; /* relocation entry count */
98 uint32_t flags
; /* type and attributes (masked) */
101 #define SECTION_TYPE 0x000000ff /* section type mask */
103 #define S_REGULAR (0x0) /* standard section */
104 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
106 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
107 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
108 machine instructions */
109 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external
110 relocation entries */
111 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local
112 relocation entries */
115 static struct sectmap
{
116 const char *nasmsect
;
118 const char *sectname
;
121 {".text", "__TEXT", "__text", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
},
122 {".data", "__DATA", "__data", S_REGULAR
},
123 {".rodata", "__DATA", "__const", S_REGULAR
},
124 {".bss", "__DATA", "__bss", S_ZEROFILL
},
125 {NULL
, NULL
, NULL
, 0}
129 /* nasm internal data */
132 /* data that goes into the file */
133 int32_t addr
; /* op's offset in section */
134 unsigned int snum
:24, /* contains symbol index if
135 ** ext otherwise in-file
137 pcrel
:1, /* relative relocation */
138 length
:2, /* 0=byte, 1=word, 2=int32_t */
139 ext
:1, /* external symbol referenced */
140 type
:4; /* reloc type, 0 for us */
143 #define R_ABS 0 /* absolute relocation */
144 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
145 ** highest bit == 1 */
148 /* nasm internal data */
149 struct symbol
*next
; /* next symbol in the list */
150 char *name
; /* name of this symbol */
151 int32_t initial_snum
; /* symbol number used above in
153 int32_t snum
; /* true snum for reloc */
155 /* data that goes into the file */
156 int32_t strx
; /* string table index */
157 uint8_t type
; /* symbol type */
158 uint8_t sect
; /* NO_SECT or section number */
159 int16_t desc
; /* for stab debugging, 0 for us */
160 uint32_t value
; /* offset of symbol in section */
163 /* symbol type bits */
164 #define N_EXT 0x01 /* global or external symbol */
166 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
167 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
168 #define N_SECT 0xe /* defined symbol, n_sect holds
171 #define N_TYPE 0x0e /* type bit mask */
173 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
175 /* special section number values */
176 #define NO_SECT 0 /* no section, invalid */
177 #define MAX_SECT 255 /* maximum number of sections */
179 static struct section
*sects
, **sectstail
;
180 static struct symbol
*syms
, **symstail
;
181 static uint32_t nsyms
;
183 /* These variables are set by macho_layout_symbols() to organize
184 the symbol table and string table in order the dynamic linker
185 expects. They are then used in macho_write() to put out the
186 symbols and strings in that order.
188 The order of the symbol table is:
190 defined external symbols (sorted by name)
191 undefined external symbols (sorted by name)
193 The order of the string table is:
194 strings for external symbols
195 strings for local symbols
197 static uint32_t ilocalsym
= 0;
198 static uint32_t iextdefsym
= 0;
199 static uint32_t iundefsym
= 0;
200 static uint32_t nlocalsym
;
201 static uint32_t nextdefsym
;
202 static uint32_t nundefsym
;
203 static struct symbol
**extdefsyms
= NULL
;
204 static struct symbol
**undefsyms
= NULL
;
206 static struct RAA
*extsyms
;
207 static struct SAA
*strs
;
208 static uint32_t strslen
;
210 static FILE *machofp
;
212 static evalfunc evaluate
;
214 extern struct ofmt of_macho
;
216 /* Global file information. This should be cleaned up into either
217 a structure or as function arguments. */
218 uint32_t head_ncmds
= 0;
219 uint32_t head_sizeofcmds
= 0;
220 uint32_t seg_filesize
= 0;
221 uint32_t seg_vmsize
= 0;
222 uint32_t seg_nsects
= 0;
223 uint32_t rel_padcnt
= 0;
226 #define xstrncpy(xdst, xsrc) \
227 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
228 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
229 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
231 #define align(x, y) \
232 (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */
234 #define alignint32_t(x) \
235 align(x, sizeof(int32_t)) /* align x to int32_t boundary */
237 static void debug_reloc (struct reloc
*);
238 static void debug_section_relocs (struct section
*) _unused
;
240 static int exact_log2 (uint32_t align
)
244 } else if (align
& (align
-1)) {
245 return -1; /* Not a power of 2 */
248 return __builtin_ctzl (align
);
252 /* We know exactly one bit is set at this point. */
253 if (align
& 0xffff0000)
255 if (align
& 0xff00ff00)
257 if (align
& 0xf0f0f0f0)
259 if (align
& 0xcccccccc)
261 if (align
& 0xaaaaaaaa)
269 static struct section
*get_section_by_name(const char *segname
,
270 const char *sectname
)
274 for (s
= sects
; s
!= NULL
; s
= s
->next
)
275 if (!strcmp(s
->segname
, segname
) && !strcmp(s
->sectname
, sectname
))
281 static struct section
*get_section_by_index(const int32_t index
)
285 for (s
= sects
; s
!= NULL
; s
= s
->next
)
286 if (index
== s
->index
)
292 static int32_t get_section_index_by_name(const char *segname
,
293 const char *sectname
)
297 for (s
= sects
; s
!= NULL
; s
= s
->next
)
298 if (!strcmp(s
->segname
, segname
) && !strcmp(s
->sectname
, sectname
))
304 static char *get_section_name_by_index(const int32_t index
)
308 for (s
= sects
; s
!= NULL
; s
= s
->next
)
309 if (index
== s
->index
)
315 static uint8_t get_section_fileindex_by_index(const int32_t index
)
320 for (s
= sects
; s
!= NULL
&& i
< MAX_SECT
; s
= s
->next
, ++i
)
321 if (index
== s
->index
)
326 "too many sections (>255) - clipped by fileindex");
331 static void macho_init(FILE * fp
, efunc errfunc
, ldfunc ldef
,
340 (void)ldef
; /* placate optimisers */
352 extsyms
= raa_init();
355 /* string table starts with a zero byte - don't ask why */
356 saa_wbytes(strs
, &zero
, sizeof(char));
360 static int macho_setinfo(enum geninfo type
, char **val
)
367 static void sect_write(struct section
*sect
,
368 const uint8_t *data
, uint32_t len
)
370 saa_wbytes(sect
->data
, data
, len
);
374 static void add_reloc(struct section
*sect
, int32_t section
,
375 int pcrel
, int bytes
)
380 /* NeXT as puts relocs in reversed order (address-wise) into the
381 ** files, so we do the same, doesn't seem to make much of a
382 ** difference either way */
383 r
= nasm_malloc(sizeof(struct reloc
));
384 r
->next
= sect
->relocs
;
387 /* the current end of the section will be the symbol's address for
388 ** now, might have to be fixed by macho_fixup_relocs() later on. make
389 ** sure we don't make the symbol scattered by setting the highest
390 ** bit by accident */
391 r
->addr
= sect
->size
& ~R_SCATTERED
;
395 /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */
396 r
->length
= bytes
>> 1;
398 /* vanilla relocation (GENERIC_RELOC_VANILLA) */
401 if (section
== NO_SEG
) {
402 /* absolute local symbol if no section index given */
405 fi
= get_section_fileindex_by_index(section
);
408 /* external symbol if no section with that index known,
409 ** symbol number was saved in macho_symdef() */
410 r
->snum
= raa_read(extsyms
, section
);
413 /* local symbol in section fi */
421 static void macho_output(int32_t secto
, const void *data
,
422 enum out_type type
, uint64_t size
,
423 int32_t section
, int32_t wrt
)
425 struct section
*s
, *sbss
;
427 uint8_t mydata
[4], *p
;
431 error(ERR_NONFATAL
, "WRT not supported by Mach-O output format");
432 /* continue to do _something_ */
435 if (secto
== NO_SEG
) {
436 if (type
!= OUT_RESERVE
)
437 error(ERR_NONFATAL
, "attempt to assemble code in "
443 s
= get_section_by_index(secto
);
446 error(ERR_WARNING
, "attempt to assemble code in"
447 " section %d: defaulting to `.text'", secto
);
448 s
= get_section_by_name("__TEXT", "__text");
450 /* should never happen */
452 error(ERR_PANIC
, "text section not found");
455 sbss
= get_section_by_name("__DATA", "__bss");
457 if (s
== sbss
&& type
!= OUT_RESERVE
) {
458 error(ERR_WARNING
, "attempt to initialize memory in the"
459 " BSS section: ignored");
460 s
->size
+= realsize(type
, size
);
467 error(ERR_WARNING
, "uninitialized space declared in"
468 " %s section: zeroing",
469 get_section_name_by_index(secto
));
471 sect_write(s
, NULL
, size
);
478 if (section
!= NO_SEG
)
479 error(ERR_PANIC
, "OUT_RAWDATA with other than NO_SEG");
481 sect_write(s
, data
, size
);
485 addr
= *(int64_t *)data
;
487 if (section
!= NO_SEG
) {
489 error(ERR_NONFATAL
, "Mach-O format does not support"
490 " section base references");
492 add_reloc(s
, section
, 0, size
);
496 WRITEADDR(p
, addr
, size
);
497 sect_write(s
, mydata
, size
);
501 if (section
== secto
)
502 error(ERR_PANIC
, "intra-section OUT_REL2ADR");
504 if (section
!= NO_SEG
&& section
% 2) {
505 error(ERR_NONFATAL
, "Mach-O format does not support"
506 " section base references");
508 add_reloc(s
, section
, 1, 2);
511 WRITESHORT(p
, *(int32_t *)data
- (size
+ s
->size
));
512 sect_write(s
, mydata
, 2L);
516 if (section
== secto
)
517 error(ERR_PANIC
, "intra-section OUT_REL4ADR");
519 if (section
!= NO_SEG
&& section
% 2) {
520 error(ERR_NONFATAL
, "Mach-O format does not support"
521 " section base references");
523 add_reloc(s
, section
, 1, 4);
526 WRITELONG(p
, *(int32_t *)data
- (size
+ s
->size
));
527 sect_write(s
, mydata
, 4L);
531 error(ERR_PANIC
, "unknown output type?");
536 static int32_t macho_section(char *name
, int pass
, int *bits
)
538 int32_t index
, originalIndex
;
539 char *sectionAttributes
;
545 /* Default to 32 bits. */
549 sectionAttributes
= NULL
;
551 sectionAttributes
= name
;
552 name
= nasm_strsep(§ionAttributes
, " \t");
555 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
556 /* make lookup into section name translation table */
557 if (!strcmp(name
, sm
->nasmsect
)) {
558 char *currentAttribute
;
560 /* try to find section with that name */
561 originalIndex
= index
= get_section_index_by_name(sm
->segname
,
564 /* create it if it doesn't exist yet */
566 s
= *sectstail
= nasm_malloc(sizeof(struct section
));
568 sectstail
= &s
->next
;
570 s
->data
= saa_init(1L);
571 s
->index
= seg_alloc();
575 xstrncpy(s
->segname
, sm
->segname
);
576 xstrncpy(s
->sectname
, sm
->sectname
);
579 s
->flags
= sm
->flags
;
583 s
= get_section_by_index(index
);
586 while ((NULL
!= sectionAttributes
)
587 && (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
588 if (0 != *currentAttribute
) {
589 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
591 int newAlignment
, value
;
593 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
594 newAlignment
= exact_log2(value
);
598 "unknown or missing alignment value \"%s\" "
599 "specified for section \"%s\"",
600 currentAttribute
+ 6,
603 } else if (0 > newAlignment
) {
605 "alignment of %d (for section \"%s\") is not "
612 if ((-1 != originalIndex
)
613 && (s
->align
!= newAlignment
)
614 && (s
->align
!= -1)) {
616 "section \"%s\" has already been specified "
617 "with alignment %d, conflicts with new "
625 s
->align
= newAlignment
;
626 } else if (!nasm_stricmp("data", currentAttribute
)) {
627 /* Do nothing; 'data' is implicit */
630 "unknown section attribute %s for section %s",
642 error(ERR_PANIC
, "invalid section name %s", name
);
646 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
647 int is_global
, char *special
)
652 error(ERR_NONFATAL
, "The Mach-O output format does "
653 "not support any special symbol types");
657 if (is_global
== 3) {
658 error(ERR_NONFATAL
, "The Mach-O format does not "
659 "(yet) support forward reference fixups.");
663 sym
= *symstail
= nasm_malloc(sizeof(struct symbol
));
665 symstail
= &sym
->next
;
672 sym
->initial_snum
= -1;
674 /* external and common symbols get N_EXT */
678 if (section
== NO_SEG
) {
679 /* symbols in no section get absolute */
685 /* get the in-file index of the section the symbol was defined in */
686 sym
->sect
= get_section_fileindex_by_index(section
);
688 if (sym
->sect
== NO_SECT
) {
689 /* remember symbol number of references to external
690 ** symbols, this works because every external symbol gets
691 ** its own section number allocated internally by nasm and
692 ** can so be used as a key */
693 extsyms
= raa_write(extsyms
, section
, nsyms
);
694 sym
->initial_snum
= nsyms
;
699 /* there isn't actually a difference between global
700 ** and common symbols, both even have their size in
706 /* give an error on unfound section if it's not an
707 ** external or common symbol (assemble_file() does a
708 ** seg_alloc() on every call for them) */
709 error(ERR_PANIC
, "in-file index for section %d not found",
718 static int32_t macho_segbase(int32_t section
)
723 static int macho_directive(char *directive
, char *value
, int pass
)
731 static void macho_filename(char *inname
, char *outname
, efunc error
)
733 standard_extension(inname
, outname
, ".o", error
);
736 extern macros_t macho_stdmac
[];
738 /* Comparison function for qsort symbol layout. */
739 static int layout_compare (const struct symbol
**s1
,
740 const struct symbol
**s2
)
742 return (strcmp ((*s1
)->name
, (*s2
)->name
));
745 /* The native assembler does a few things in a similar function
747 * Remove temporary labels
748 * Sort symbols according to local, external, undefined (by name)
749 * Order the string table
751 We do not remove temporary labels right now.
753 numsyms is the total number of symbols we have. strtabsize is the
754 number entries in the string table. */
756 static void macho_layout_symbols (uint32_t *numsyms
,
757 uint32_t *strtabsize
)
759 struct symbol
*sym
, **symp
;
763 *strtabsize
= sizeof (char);
767 while ((sym
= *symp
)) {
768 /* Undefined symbols are now external. */
769 if (sym
->type
== N_UNDF
)
772 if ((sym
->type
& N_EXT
) == 0) {
773 sym
->snum
= *numsyms
;
774 *numsyms
= *numsyms
+ 1;
778 if ((sym
->type
& N_TYPE
) != N_UNDF
)
783 /* If we handle debug info we'll want
784 to check for it here instead of just
785 adding the symbol to the string table. */
786 sym
->strx
= *strtabsize
;
787 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
788 *strtabsize
+= strlen(sym
->name
) + 1;
793 /* Next, sort the symbols. Most of this code is a direct translation from
794 the Apple cctools symbol layout. We need to keep compatibility with that. */
795 /* Set the indexes for symbol groups into the symbol table */
797 iextdefsym
= nlocalsym
;
798 iundefsym
= nlocalsym
+ nextdefsym
;
800 /* allocate arrays for sorting externals by name */
801 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
802 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
809 while ((sym
= *symp
)) {
811 if((sym
->type
& N_EXT
) == 0) {
812 sym
->strx
= *strtabsize
;
813 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
814 *strtabsize
+= strlen(sym
->name
) + 1;
817 if((sym
->type
& N_TYPE
) != N_UNDF
)
818 extdefsyms
[i
++] = sym
;
820 undefsyms
[j
++] = sym
;
825 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
826 (int (*)(const void *, const void *))layout_compare
);
827 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
828 (int (*)(const void *, const void *))layout_compare
);
830 for(i
= 0; i
< nextdefsym
; i
++) {
831 extdefsyms
[i
]->snum
= *numsyms
;
834 for(j
= 0; j
< nundefsym
; j
++) {
835 undefsyms
[j
]->snum
= *numsyms
;
840 /* Calculate some values we'll need for writing later. */
842 static void macho_calculate_sizes (void)
846 /* count sections and calculate in-memory and in-file offsets */
847 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
850 /* zerofill sections aren't actually written to the file */
851 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
)
852 seg_filesize
+= s
->size
;
854 /* recalculate segment address based on alignment and vm size */
855 s
->addr
= seg_vmsize
;
856 /* we need section alignment to calculate final section address */
858 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
860 uint32_t newaddr
= align(s
->addr
, 1 << s
->align
);
861 pad
= newaddr
- s
->addr
;
865 seg_vmsize
+= s
->size
+ pad
;
869 /* calculate size of all headers, load commands and sections to
870 ** get a pointer to the start of all the raw data */
871 if (seg_nsects
> 0) {
874 MACHO_SEGCMD_SIZE
+ seg_nsects
* MACHO_SECTCMD_SIZE
;
879 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
883 /* Write out the header information for the file. */
885 static void macho_write_header (void)
887 fwriteint32_t(MH_MAGIC
, machofp
); /* magic */
888 fwriteint32_t(CPU_TYPE_I386
, machofp
); /* CPU type */
889 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, machofp
); /* CPU subtype */
890 fwriteint32_t(MH_OBJECT
, machofp
); /* Mach-O file type */
891 fwriteint32_t(head_ncmds
, machofp
); /* number of load commands */
892 fwriteint32_t(head_sizeofcmds
, machofp
); /* size of load commands */
893 fwriteint32_t(0, machofp
); /* no flags */
896 /* Write out the segment load command at offset. */
898 static uint32_t macho_write_segment (uint32_t offset
)
900 uint32_t rel_base
= alignint32_t (offset
+ seg_filesize
);
901 uint32_t s_reloff
= 0;
904 fwriteint32_t(LC_SEGMENT
, machofp
); /* cmd == LC_SEGMENT */
906 /* size of load command including section load commands */
907 fwriteint32_t(MACHO_SEGCMD_SIZE
+ seg_nsects
*
908 MACHO_SECTCMD_SIZE
, machofp
);
910 /* in an MH_OBJECT file all sections are in one unnamed (name
911 ** all zeros) segment */
912 fwritezero(16, machofp
);
913 fwriteint32_t(0, machofp
); /* in-memory offset */
914 fwriteint32_t(seg_vmsize
, machofp
); /* in-memory size */
915 fwriteint32_t(offset
, machofp
); /* in-file offset to data */
916 fwriteint32_t(seg_filesize
, machofp
); /* in-file size */
917 fwriteint32_t(VM_PROT_DEFAULT
, machofp
); /* maximum vm protection */
918 fwriteint32_t(VM_PROT_DEFAULT
, machofp
); /* initial vm protection */
919 fwriteint32_t(seg_nsects
, machofp
); /* number of sections */
920 fwriteint32_t(0, machofp
); /* no flags */
922 /* emit section headers */
923 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
924 fwrite(s
->sectname
, sizeof(s
->sectname
), 1, machofp
);
925 fwrite(s
->segname
, sizeof(s
->segname
), 1, machofp
);
926 fwriteint32_t(s
->addr
, machofp
);
927 fwriteint32_t(s
->size
, machofp
);
929 /* dummy data for zerofill sections or proper values */
930 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
931 fwriteint32_t(offset
, machofp
);
932 /* Write out section alignment, as a power of two.
933 e.g. 32-bit word alignment would be 2 (2^^2 = 4). */
935 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
936 fwriteint32_t(s
->align
, machofp
);
937 /* To be compatible with cctools as we emit
938 a zero reloff if we have no relocations. */
939 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, machofp
);
940 fwriteint32_t(s
->nreloc
, machofp
);
943 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
945 fwriteint32_t(0, machofp
);
946 fwriteint32_t(0, machofp
);
947 fwriteint32_t(0, machofp
);
948 fwriteint32_t(0, machofp
);
951 fwriteint32_t(s
->flags
, machofp
); /* flags */
952 fwriteint32_t(0, machofp
); /* reserved */
953 fwriteint32_t(0, machofp
); /* reserved */
956 rel_padcnt
= rel_base
- offset
;
957 offset
= rel_base
+ s_reloff
;
962 /* For a given chain of relocs r, write out the entire relocation
963 chain to the object file. */
965 static void macho_write_relocs (struct reloc
*r
)
970 fwriteint32_t(r
->addr
, machofp
); /* reloc offset */
973 word2
|= r
->pcrel
<< 24;
974 word2
|= r
->length
<< 25;
975 word2
|= r
->ext
<< 27;
976 word2
|= r
->type
<< 28;
977 fwriteint32_t(word2
, machofp
); /* reloc data */
983 /* Write out the section data. */
984 static void macho_write_section (void)
986 struct section
*s
, *s2
;
988 uint8_t fi
, *p
, *q
, blk
[4];
991 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
992 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
995 /* no padding needs to be done to the sections */
997 /* Like a.out Mach-O references things in the data or bss
998 * sections by addresses which are actually relative to the
999 * start of the _text_ section, in the _file_. See outaout.c
1000 * for more information. */
1001 saa_rewind(s
->data
);
1002 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1003 saa_fread(s
->data
, r
->addr
, blk
, (int32_t)r
->length
<< 1);
1007 /* get offset based on relocation type */
1008 if (r
->length
> 0) {
1009 l
+= ((int32_t)*p
++) << 8;
1011 if (r
->length
== 2) {
1012 l
+= ((int32_t)*p
++) << 16;
1013 l
+= ((int32_t)*p
++) << 24;
1017 /* If the relocation is internal add to the current section
1018 offset. Otherwise the only value we need is the symbol
1019 offset which we already have. The linker takes care
1020 of the rest of the address. */
1022 /* generate final address by section address and offset */
1023 for (s2
= sects
, fi
= 1;
1024 s2
!= NULL
; s2
= s2
->next
, fi
++) {
1025 if (fi
== r
->snum
) {
1032 /* write new offset back */
1035 else if (r
->length
== 1)
1040 saa_fwrite(s
->data
, r
->addr
, blk
, (int32_t)r
->length
<< 1);
1043 /* dump the section data to file */
1044 saa_fpwrite(s
->data
, machofp
);
1047 /* pad last section up to reloc entries on int32_t boundary */
1048 fwritezero(rel_padcnt
, machofp
);
1050 /* emit relocation entries */
1051 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1052 macho_write_relocs (s
->relocs
);
1055 /* Write out the symbol table. We should already have sorted this
1057 static void macho_write_symtab (void)
1064 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1066 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1067 if ((sym
->type
& N_EXT
) == 0) {
1068 fwriteint32_t(sym
->strx
, machofp
); /* string table entry number */
1069 fwrite(&sym
->type
, 1, 1, machofp
); /* symbol type */
1070 fwrite(&sym
->sect
, 1, 1, machofp
); /* section */
1071 fwriteint16_t(sym
->desc
, machofp
); /* description */
1073 /* Fix up the symbol value now that we know the final section
1075 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1076 for (s
= sects
, fi
= 1;
1077 s
!= NULL
&& fi
< sym
->sect
; s
= s
->next
, ++fi
)
1078 sym
->value
+= s
->size
;
1081 fwriteint32_t(sym
->value
, machofp
); /* value (i.e. offset) */
1085 for (i
= 0; i
< nextdefsym
; i
++) {
1086 sym
= extdefsyms
[i
];
1087 fwriteint32_t(sym
->strx
, machofp
);
1088 fwrite(&sym
->type
, 1, 1, machofp
); /* symbol type */
1089 fwrite(&sym
->sect
, 1, 1, machofp
); /* section */
1090 fwriteint16_t(sym
->desc
, machofp
); /* description */
1092 /* Fix up the symbol value now that we know the final section
1094 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1095 for (s
= sects
, fi
= 1;
1096 s
!= NULL
&& fi
< sym
->sect
; s
= s
->next
, ++fi
)
1097 sym
->value
+= s
->size
;
1100 fwriteint32_t(sym
->value
, machofp
); /* value (i.e. offset) */
1103 for (i
= 0; i
< nundefsym
; i
++) {
1105 fwriteint32_t(sym
->strx
, machofp
);
1106 fwrite(&sym
->type
, 1, 1, machofp
); /* symbol type */
1107 fwrite(&sym
->sect
, 1, 1, machofp
); /* section */
1108 fwriteint16_t(sym
->desc
, machofp
); /* description */
1110 /* Fix up the symbol value now that we know the final section
1112 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1113 for (s
= sects
, fi
= 1;
1114 s
!= NULL
&& fi
< sym
->sect
; s
= s
->next
, ++fi
)
1115 sym
->value
+= s
->size
;
1118 fwriteint32_t(sym
->value
, machofp
); /* value (i.e. offset) */
1122 /* Fixup the snum in the relocation entries, we should be
1123 doing this only for externally undefined symbols. */
1124 static void macho_fixup_relocs (struct reloc
*r
)
1131 for (i
= 0; i
< nundefsym
; i
++) {
1133 if (sym
->initial_snum
== r
->snum
) {
1134 r
->snum
= sym
->snum
;
1143 /* Write out the object file. */
1145 static void macho_write (void)
1147 uint32_t offset
= 0;
1149 /* mach-o object file structure:
1155 ** uint32_t mach file type
1156 ** uint32_t number of load commands
1157 ** uint32_t size of all load commands
1158 ** (includes section struct size of segment command)
1162 ** uint32_t command type == LC_SEGMENT
1163 ** uint32_t size of load command
1164 ** (including section load commands)
1165 ** char[16] segment name
1166 ** uint32_t in-memory offset
1167 ** uint32_t in-memory size
1168 ** uint32_t in-file offset to data area
1169 ** uint32_t in-file size
1170 ** (in-memory size excluding zerofill sections)
1171 ** int maximum vm protection
1172 ** int initial vm protection
1173 ** uint32_t number of sections
1177 ** char[16] section name
1178 ** char[16] segment name
1179 ** uint32_t in-memory offset
1180 ** uint32_t in-memory size
1181 ** uint32_t in-file offset
1182 ** uint32_t alignment
1183 ** (irrelevant in MH_OBJECT)
1184 ** uint32_t in-file offset of relocation entires
1185 ** uint32_t number of relocations
1187 ** uint32_t reserved
1188 ** uint32_t reserved
1190 ** symbol table command
1191 ** uint32_t command type == LC_SYMTAB
1192 ** uint32_t size of load command
1193 ** uint32_t symbol table offset
1194 ** uint32_t number of symbol table entries
1195 ** uint32_t string table offset
1196 ** uint32_t string table size
1200 ** padding to int32_t boundary
1202 ** relocation data (struct reloc)
1204 ** uint data (symbolnum, pcrel, length, extern, type)
1206 ** symbol table data (struct nlist)
1207 ** int32_t string table entry number
1209 ** (extern, absolute, defined in section)
1211 ** (0 for global symbols, section number of definition (>= 1, <=
1212 ** 254) for local symbols, size of variable for common symbols
1213 ** [type == extern])
1214 ** int16_t description
1215 ** (for stab debugging format)
1216 ** uint32_t value (i.e. file offset) of symbol or stab offset
1218 ** string table data
1219 ** list of null-terminated strings
1222 /* Emit the Mach-O header. */
1223 macho_write_header();
1225 offset
= MACHO_HEADER_SIZE
+ head_sizeofcmds
;
1227 /* emit the segment load command */
1229 offset
= macho_write_segment (offset
);
1231 error(ERR_WARNING
, "no sections?");
1234 /* write out symbol command */
1235 fwriteint32_t(LC_SYMTAB
, machofp
); /* cmd == LC_SYMTAB */
1236 fwriteint32_t(MACHO_SYMCMD_SIZE
, machofp
); /* size of load command */
1237 fwriteint32_t(offset
, machofp
); /* symbol table offset */
1238 fwriteint32_t(nsyms
, machofp
); /* number of symbol
1241 offset
+= nsyms
* MACHO_NLIST_SIZE
;
1242 fwriteint32_t(offset
, machofp
); /* string table offset */
1243 fwriteint32_t(strslen
, machofp
); /* string table size */
1246 /* emit section data */
1248 macho_write_section ();
1250 /* emit symbol table if we have symbols */
1252 macho_write_symtab ();
1254 /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */
1256 /* emit string table */
1257 saa_fpwrite(strs
, machofp
);
1259 /* We do quite a bit here, starting with finalizing all of the data
1260 for the object file, writing, and then freeing all of the data from
1263 static void macho_cleanup(int debuginfo
)
1271 /* Sort all symbols. */
1272 macho_layout_symbols (&nsyms
, &strslen
);
1274 /* Fixup relocation entries */
1275 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1276 macho_fixup_relocs (s
->relocs
);
1279 /* First calculate and finalize needed values. */
1280 macho_calculate_sizes();
1286 /* free up everything */
1287 while (sects
->next
) {
1289 sects
= sects
->next
;
1292 while (s
->relocs
!= NULL
) {
1294 s
->relocs
= s
->relocs
->next
;
1305 while (syms
->next
) {
1314 /* Debugging routines. */
1315 static void debug_reloc (struct reloc
*r
)
1317 fprintf (stdout
, "reloc:\n");
1318 fprintf (stdout
, "\taddr: %"PRId32
"\n", r
->addr
);
1319 fprintf (stdout
, "\tsnum: %d\n", r
->snum
);
1320 fprintf (stdout
, "\tpcrel: %d\n", r
->pcrel
);
1321 fprintf (stdout
, "\tlength: %d\n", r
->length
);
1322 fprintf (stdout
, "\text: %d\n", r
->ext
);
1323 fprintf (stdout
, "\ttype: %d\n", r
->type
);
1326 static void debug_section_relocs (struct section
*s
)
1328 struct reloc
*r
= s
->relocs
;
1330 fprintf (stdout
, "relocs for section %s:\n\n", s
->sectname
);
1338 struct ofmt of_macho32
= {
1339 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
1356 struct ofmt of_macho
= {
1357 "MACHO (short name for MACHO32)",