1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2016 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
51 #include "output/outform.h"
52 #include "output/outlib.h"
54 #if defined(OF_MACHO) || defined(OF_MACHO64)
56 /* Mach-O in-file header structure sizes */
57 #define MACHO_HEADER_SIZE 28
58 #define MACHO_SEGCMD_SIZE 56
59 #define MACHO_SECTCMD_SIZE 68
60 #define MACHO_SYMCMD_SIZE 24
61 #define MACHO_NLIST_SIZE 12
62 #define MACHO_RELINFO_SIZE 8
64 #define MACHO_HEADER64_SIZE 32
65 #define MACHO_SEGCMD64_SIZE 72
66 #define MACHO_SECTCMD64_SIZE 80
67 #define MACHO_NLIST64_SIZE 16
69 /* Mach-O file header values */
70 #define MH_MAGIC 0xfeedface
71 #define MH_MAGIC_64 0xfeedfacf
72 #define CPU_TYPE_I386 7 /* x86 platform */
73 #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
74 #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
75 #define MH_OBJECT 0x1 /* object file */
77 /* Mach-O load commands */
78 #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
79 #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
80 #define LC_SYMTAB 0x2 /* symbol table load command */
82 /* Mach-O relocations numbers */
84 /* Generic relocs, used by i386 Mach-O */
85 #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
86 #define GENERIC_RELOC_TLV 5 /* Thread local */
88 #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
89 #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
90 #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
91 #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
92 #define X86_64_RELOC_GOT 4 /* Different GOT entry */
93 #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
94 #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
95 #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
96 #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
97 #define X86_64_RELOC_TLV 9 /* Thread local */
99 /* Mach-O VM permission constants */
100 #define VM_PROT_NONE (0x00)
101 #define VM_PROT_READ (0x01)
102 #define VM_PROT_WRITE (0x02)
103 #define VM_PROT_EXECUTE (0x04)
105 #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
106 #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
108 /* Our internal relocation types */
110 RL_ABS
, /* Absolute relocation */
111 RL_REL
, /* Relative relocation */
112 RL_TLV
, /* Thread local */
113 RL_BRANCH
, /* Relative direct branch */
114 RL_SUB
, /* X86_64_RELOC_SUBTRACT */
115 RL_GOT
, /* X86_64_RELOC_GOT */
116 RL_GOTLOAD
/* X86_64_RELOC_GOT_LOAD */
118 #define RL_MAX_32 RL_TLV
119 #define RL_MAX_64 RL_GOTLOAD
122 uint32_t ptrsize
; /* Pointer size in bytes */
123 uint32_t mh_magic
; /* Which magic number to use */
124 uint32_t cpu_type
; /* Which CPU type */
125 uint32_t lc_segment
; /* Which segment load command */
126 uint32_t header_size
; /* Header size */
127 uint32_t segcmd_size
; /* Segment command size */
128 uint32_t sectcmd_size
; /* Section command size */
129 uint32_t nlist_size
; /* Nlist (symbol) size */
130 enum reltype maxreltype
; /* Maximum entry in enum reltype permitted */
131 uint32_t reloc_abs
; /* Absolute relocation type */
132 uint32_t reloc_rel
; /* Relative relocation type */
133 uint32_t reloc_tlv
; /* Thread local relocation type */
136 static struct macho_fmt fmt
;
138 static void fwriteptr(uint64_t data
, FILE * fp
)
140 fwriteaddr(data
, fmt
.ptrsize
, fp
);
144 /* nasm internal data */
145 struct section
*next
;
149 struct reloc
*relocs
;
150 struct rbtree
*gsyms
; /* Global symbols in section */
152 bool by_name
; /* This section was specified by full MachO name */
154 /* data that goes into the file */
155 char sectname
[16]; /* what this section is called */
156 char segname
[16]; /* segment this section will be in */
157 uint64_t addr
; /* in-memory address (subject to alignment) */
158 uint64_t size
; /* in-memory and -file size */
159 uint64_t offset
; /* in-file offset */
160 uint32_t pad
; /* padding bytes before section */
161 uint32_t nreloc
; /* relocation entry count */
162 uint32_t flags
; /* type and attributes (masked) */
163 uint32_t extreloc
; /* external relocations */
166 #define SECTION_TYPE 0x000000ff /* section type mask */
168 #define S_REGULAR (0x0) /* standard section */
169 #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
171 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
172 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
173 machine instructions */
174 #define S_ATTR_EXT_RELOC 0x00000200 /* section has external
175 relocation entries */
176 #define S_ATTR_LOC_RELOC 0x00000100 /* section has local
177 relocation entries */
178 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure
179 machine instructions */
181 /* Fake section for absolute symbols, *not* part of the section linked list */
182 static struct section absolute_sect
;
184 static const struct sectmap
{
185 const char *nasmsect
;
187 const char *sectname
;
190 {".text", "__TEXT", "__text", S_REGULAR
|S_ATTR_SOME_INSTRUCTIONS
|S_ATTR_PURE_INSTRUCTIONS
},
191 {".data", "__DATA", "__data", S_REGULAR
},
192 {".rodata", "__DATA", "__const", S_REGULAR
},
193 {".bss", "__DATA", "__bss", S_ZEROFILL
},
194 {NULL
, NULL
, NULL
, 0}
198 /* nasm internal data */
201 /* data that goes into the file */
202 int32_t addr
; /* op's offset in section */
203 uint32_t snum
:24, /* contains symbol index if
204 ** ext otherwise in-file
206 pcrel
:1, /* relative relocation */
207 length
:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
208 ext
:1, /* external symbol referenced */
209 type
:4; /* reloc type */
212 #define R_ABS 0 /* absolute relocation */
213 #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
214 ** highest bit == 1 */
217 /* nasm internal data */
218 struct rbtree symv
; /* Global symbol rbtree; "key" contains the
220 struct symbol
*next
; /* next symbol in the list */
221 char *name
; /* name of this symbol */
222 int32_t initial_snum
; /* symbol number used above in reloc */
223 int32_t snum
; /* true snum for reloc */
225 /* data that goes into the file */
226 uint32_t strx
; /* string table index */
227 uint8_t type
; /* symbol type */
228 uint8_t sect
; /* NO_SECT or section number */
229 uint16_t desc
; /* for stab debugging, 0 for us */
232 /* symbol type bits */
233 #define N_EXT 0x01 /* global or external symbol */
235 #define N_UNDF 0x0 /* undefined symbol | n_sect == */
236 #define N_ABS 0x2 /* absolute symbol | NO_SECT */
237 #define N_SECT 0xe /* defined symbol, n_sect holds
240 #define N_TYPE 0x0e /* type bit mask */
242 #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
244 /* special section number values */
245 #define NO_SECT 0 /* no section, invalid */
246 #define MAX_SECT 255 /* maximum number of sections */
248 static struct section
*sects
, **sectstail
, **sectstab
;
249 static struct symbol
*syms
, **symstail
;
250 static uint32_t nsyms
;
252 /* These variables are set by macho_layout_symbols() to organize
253 the symbol table and string table in order the dynamic linker
254 expects. They are then used in macho_write() to put out the
255 symbols and strings in that order.
257 The order of the symbol table is:
259 defined external symbols (sorted by name)
260 undefined external symbols (sorted by name)
262 The order of the string table is:
263 strings for external symbols
264 strings for local symbols
266 static uint32_t ilocalsym
= 0;
267 static uint32_t iextdefsym
= 0;
268 static uint32_t iundefsym
= 0;
269 static uint32_t nlocalsym
;
270 static uint32_t nextdefsym
;
271 static uint32_t nundefsym
;
272 static struct symbol
**extdefsyms
= NULL
;
273 static struct symbol
**undefsyms
= NULL
;
275 static struct RAA
*extsyms
;
276 static struct SAA
*strs
;
277 static uint32_t strslen
;
279 /* Global file information. This should be cleaned up into either
280 a structure or as function arguments. */
281 static uint32_t head_ncmds
= 0;
282 static uint32_t head_sizeofcmds
= 0;
283 static uint64_t seg_filesize
= 0;
284 static uint64_t seg_vmsize
= 0;
285 static uint32_t seg_nsects
= 0;
286 static uint64_t rel_padcnt
= 0;
288 #define xstrncpy(xdst, xsrc) \
289 memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
290 strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
291 xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
293 #define alignint32_t(x) \
294 ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
296 #define alignint64_t(x) \
297 ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
299 #define alignptr(x) \
300 ALIGN(x, fmt.ptrsize) /* align x to output format width */
302 static struct section
*get_section_by_name(const char *segname
,
303 const char *sectname
)
307 for (s
= sects
; s
!= NULL
; s
= s
->next
)
308 if (!strcmp(s
->segname
, segname
) && !strcmp(s
->sectname
, sectname
))
314 static struct section
*get_section_by_index(const int32_t index
)
318 for (s
= sects
; s
!= NULL
; s
= s
->next
)
319 if (index
== s
->index
)
326 * Special section numbers which are used to define Mach-O special
327 * symbols, which can be used with WRT to provide PIC relocation
330 static int32_t macho_tlvp_sect
;
331 static int32_t macho_gotpcrel_sect
;
333 static void macho_init(void)
338 /* Fake section for absolute symbols */
339 absolute_sect
.index
= NO_SEG
;
348 extsyms
= raa_init();
351 /* string table starts with a zero byte so index 0 is an empty string */
352 saa_wbytes(strs
, zero_buffer
, 1);
355 /* add special symbol for TLVP */
356 macho_tlvp_sect
= seg_alloc() + 1;
357 define_label("..tlvp", macho_tlvp_sect
, 0L, NULL
, false, false);
361 static void sect_write(struct section
*sect
,
362 const uint8_t *data
, uint32_t len
)
364 saa_wbytes(sect
->data
, data
, len
);
369 * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
371 static struct symbol
*macho_find_gsym(struct section
*s
,
372 uint64_t offset
, bool exact
)
376 srb
= rb_search(s
->gsyms
, offset
);
378 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
379 nasm_error(ERR_NONFATAL
, "unable to find a suitable %s symbol"
380 " for this reference",
381 s
== &absolute_sect
? "absolute" : "global");
385 return container_of(srb
, struct symbol
, symv
);
388 static int64_t add_reloc(struct section
*sect
, int32_t section
,
390 enum reltype reltype
, int bytes
)
397 /* Double check this is a valid relocation type for this platform */
398 nasm_assert(reltype
<= fmt
.maxreltype
);
400 /* the current end of the section will be the symbol's address for
401 ** now, might have to be fixed by macho_fixup_relocs() later on. make
402 ** sure we don't make the symbol scattered by setting the highest
403 ** bit by accident */
404 r
= nasm_malloc(sizeof(struct reloc
));
405 r
->addr
= sect
->size
& ~R_SCATTERED
;
409 /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
410 r
->length
= ilog2_32(bytes
);
412 /* set default relocation values */
413 r
->type
= fmt
.reloc_abs
;
418 if (section
!= NO_SEG
)
419 s
= get_section_by_index(section
);
420 fi
= s
? s
->fileindex
: NO_SECT
;
422 /* absolute relocation */
425 if (section
== NO_SEG
) {
426 /* absolute (can this even happen?) */
429 } else if (fi
== NO_SECT
) {
431 r
->snum
= raa_read(extsyms
, section
);
436 adjust
= -sect
->size
;
442 r
->type
= fmt
.reloc_rel
;
444 if (section
== NO_SEG
) {
445 /* absolute - seems to produce garbage no matter what */
446 nasm_error(ERR_NONFATAL
, "Mach-O does not support relative "
447 "references to absolute addresses");
450 /* This "seems" to be how it ought to work... */
452 struct symbol
*sym
= macho_find_gsym(&absolute_sect
,
459 adjust
= -sect
->size
;
461 } else if (fi
== NO_SECT
) {
464 r
->snum
= raa_read(extsyms
, section
);
465 if (reltype
== RL_BRANCH
)
466 r
->type
= X86_64_RELOC_BRANCH
;
471 adjust
= -sect
->size
;
477 r
->type
= X86_64_RELOC_SUBTRACTOR
;
481 r
->type
= X86_64_RELOC_GOT
;
485 r
->type
= X86_64_RELOC_GOT_LOAD
;
489 r
->type
= fmt
.reloc_tlv
;
494 if (section
== NO_SEG
) {
495 nasm_error(ERR_NONFATAL
, "Unsupported use of use of WRT");
496 } else if (fi
== NO_SECT
) {
498 r
->snum
= raa_read(extsyms
, section
);
501 struct symbol
*sym
= macho_find_gsym(s
, offset
, reltype
!= RL_TLV
);
504 r
->snum
= sym
->initial_snum
;
509 /* NeXT as puts relocs in reversed order (address-wise) into the
510 ** files, so we do the same, doesn't seem to make much of a
511 ** difference either way */
512 r
->next
= sect
->relocs
;
525 static void macho_output(int32_t secto
, const void *data
,
526 enum out_type type
, uint64_t size
,
527 int32_t section
, int32_t wrt
)
530 int64_t addr
, offset
;
531 uint8_t mydata
[16], *p
;
533 enum reltype reltype
;
535 if (secto
== NO_SEG
) {
536 if (type
!= OUT_RESERVE
)
537 nasm_error(ERR_NONFATAL
, "attempt to assemble code in "
542 s
= get_section_by_index(secto
);
545 nasm_error(ERR_WARNING
, "attempt to assemble code in"
546 " section %d: defaulting to `.text'", secto
);
547 s
= get_section_by_name("__TEXT", "__text");
549 /* should never happen */
551 nasm_panic(0, "text section not found");
554 is_bss
= (s
->flags
& SECTION_TYPE
) == S_ZEROFILL
;
556 if (is_bss
&& type
!= OUT_RESERVE
) {
557 nasm_error(ERR_WARNING
, "attempt to initialize memory in "
558 "BSS section: ignored");
559 s
->size
+= realsize(type
, size
);
563 memset(mydata
, 0, sizeof(mydata
));
568 nasm_error(ERR_WARNING
, "uninitialized space declared in"
569 " %s,%s section: zeroing", s
->segname
, s
->sectname
);
571 sect_write(s
, NULL
, size
);
578 if (section
!= NO_SEG
)
579 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
581 sect_write(s
, data
, size
);
586 int asize
= abs((int)size
);
588 addr
= *(int64_t *)data
;
589 if (section
!= NO_SEG
) {
591 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
592 " section base references");
593 } else if (wrt
== NO_SEG
) {
594 if (fmt
.ptrsize
== 8 && asize
!= 8) {
595 nasm_error(ERR_NONFATAL
,
596 "Mach-O 64-bit format does not support"
597 " 32-bit absolute addresses");
599 add_reloc(s
, section
, addr
, RL_ABS
, asize
);
602 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
608 WRITEADDR(p
, addr
, asize
);
609 sect_write(s
, mydata
, asize
);
614 nasm_assert(section
!= secto
);
617 offset
= *(int64_t *)data
;
618 addr
= offset
- size
;
620 if (section
!= NO_SEG
&& section
% 2) {
621 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
622 " section base references");
623 } else if (fmt
.ptrsize
== 8) {
624 nasm_error(ERR_NONFATAL
, "Unsupported non-32-bit"
625 " Macho-O relocation [2]");
626 } else if (wrt
!= NO_SEG
) {
627 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
629 wrt
= NO_SEG
; /* we can at least _try_ to continue */
631 addr
+= add_reloc(s
, section
, addr
+size
, RL_REL
, 2);
635 sect_write(s
, mydata
, 2);
639 nasm_assert(section
!= secto
);
642 offset
= *(int64_t *)data
;
643 addr
= offset
- size
;
646 if (section
!= NO_SEG
&& section
% 2) {
647 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
648 " section base references");
649 } else if (wrt
== NO_SEG
) {
650 if (fmt
.ptrsize
== 8 &&
651 (s
->flags
& S_ATTR_SOME_INSTRUCTIONS
)) {
654 opcode
[0] = opcode
[1] = 0;
656 /* HACK: Retrieve instruction opcode */
657 if (likely(s
->data
->datalen
>= 2)) {
658 saa_fread(s
->data
, s
->data
->datalen
-2, opcode
, 2);
659 } else if (s
->data
->datalen
== 1) {
660 saa_fread(s
->data
, 0, opcode
+1, 1);
663 if ((opcode
[0] != 0x0f && (opcode
[1] & 0xfe) == 0xe8) ||
664 (opcode
[0] == 0x0f && (opcode
[1] & 0xf0) == 0x80)) {
665 /* Direct call, jmp, or jcc */
669 } else if (wrt
== macho_gotpcrel_sect
) {
672 if ((s
->flags
& S_ATTR_SOME_INSTRUCTIONS
) &&
673 s
->data
->datalen
>= 3) {
676 /* HACK: Retrieve instruction opcode */
677 saa_fread(s
->data
, s
->data
->datalen
-3, gotload
, 3);
678 if ((gotload
[0] & 0xf8) == 0x48 &&
679 gotload
[1] == 0x8b &&
680 (gotload
[2] & 0307) == 0005) {
681 /* movq <reg>,[rel sym wrt ..gotpcrel] */
682 reltype
= RL_GOTLOAD
;
685 } else if (wrt
== macho_tlvp_sect
) {
688 nasm_error(ERR_NONFATAL
, "Mach-O format does not support"
690 /* continue with RL_REL */
693 addr
+= add_reloc(s
, section
, offset
, reltype
, 4);
695 sect_write(s
, mydata
, 4);
699 nasm_error(ERR_NONFATAL
, "Unrepresentable relocation in Mach-O");
704 static int32_t macho_section(char *name
, int pass
, int *bits
)
706 char *sectionAttributes
;
707 const struct sectmap
*sm
;
709 const char *section
, *segment
;
711 char *currentAttribute
;
717 /* Default to the appropriate number of bits. */
719 *bits
= fmt
.ptrsize
<< 3;
721 sectionAttributes
= NULL
;
723 sectionAttributes
= name
;
724 name
= nasm_strsep(§ionAttributes
, " \t");
727 section
= segment
= NULL
;
730 comma
= strchr(name
, ',');
738 len
= strlen(segment
);
740 nasm_error(ERR_NONFATAL
, "empty segment name\n");
741 } else if (len
>= 16) {
742 nasm_error(ERR_NONFATAL
, "segment name %s too long\n", segment
);
745 len
= strlen(section
);
747 nasm_error(ERR_NONFATAL
, "empty section name\n");
748 } else if (len
>= 16) {
749 nasm_error(ERR_NONFATAL
, "section name %s too long\n", section
);
752 if (!strcmp(section
, "__text")) {
753 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
754 S_ATTR_PURE_INSTRUCTIONS
;
755 } else if (!strcmp(section
, "__bss")) {
761 for (sm
= sectmap
; sm
->nasmsect
!= NULL
; ++sm
) {
762 /* make lookup into section name translation table */
763 if (!strcmp(name
, sm
->nasmsect
)) {
764 segment
= sm
->segname
;
765 section
= sm
->sectname
;
770 nasm_error(ERR_NONFATAL
, "unknown section name\n");
775 /* try to find section with that name */
776 s
= get_section_by_name(segment
, section
);
778 /* create it if it doesn't exist yet */
782 s
= *sectstail
= nasm_zalloc(sizeof(struct section
));
783 sectstail
= &s
->next
;
785 s
->data
= saa_init(1L);
786 s
->index
= seg_alloc();
787 s
->fileindex
= ++seg_nsects
;
793 xstrncpy(s
->segname
, segment
);
794 xstrncpy(s
->sectname
, section
);
803 *comma
= ','; /* Restore comma */
805 s
->by_name
= s
->by_name
|| comma
; /* Was specified by name */
807 flags
= (uint32_t)-1;
809 while ((NULL
!= sectionAttributes
)
810 && (currentAttribute
= nasm_strsep(§ionAttributes
, " \t"))) {
811 if (0 != *currentAttribute
) {
812 if (!nasm_strnicmp("align=", currentAttribute
, 6)) {
814 int newAlignment
, value
;
816 value
= strtoul(currentAttribute
+ 6, (char**)&end
, 0);
817 newAlignment
= alignlog2_32(value
);
820 nasm_error(ERR_NONFATAL
,
821 "unknown or missing alignment value \"%s\" "
822 "specified for section \"%s\"",
823 currentAttribute
+ 6,
825 } else if (0 > newAlignment
) {
826 nasm_error(ERR_NONFATAL
,
827 "alignment of %d (for section \"%s\") is not "
833 if (s
->align
< newAlignment
)
834 s
->align
= newAlignment
;
835 } else if (!nasm_stricmp("data", currentAttribute
)) {
837 } else if (!nasm_stricmp("code", currentAttribute
) ||
838 !nasm_stricmp("text", currentAttribute
)) {
839 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
|
840 S_ATTR_PURE_INSTRUCTIONS
;
841 } else if (!nasm_stricmp("mixed", currentAttribute
)) {
842 flags
= S_REGULAR
| S_ATTR_SOME_INSTRUCTIONS
;
843 } else if (!nasm_stricmp("bss", currentAttribute
)) {
846 nasm_error(ERR_NONFATAL
,
847 "unknown section attribute %s for section %s",
853 if (flags
!= (uint32_t)-1) {
854 if (!new_seg
&& s
->flags
!= flags
) {
855 nasm_error(ERR_NONFATAL
,
856 "inconsistent section attributes for section %s\n",
867 static void macho_symdef(char *name
, int32_t section
, int64_t offset
,
868 int is_global
, char *special
)
873 nasm_error(ERR_NONFATAL
, "The Mach-O output format does "
874 "not support any special symbol types");
878 if (is_global
== 3) {
879 nasm_error(ERR_NONFATAL
, "The Mach-O format does not "
880 "(yet) support forward reference fixups.");
884 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
886 * This is a NASM special symbol. We never allow it into
887 * the Macho-O symbol table, even if it's a valid one. If it
888 * _isn't_ a valid one, we should barf immediately.
890 if (strcmp(name
, "..gotpcrel") && strcmp(name
, "..tlvp"))
891 nasm_error(ERR_NONFATAL
, "unrecognized special symbol `%s'", name
);
895 sym
= *symstail
= nasm_zalloc(sizeof(struct symbol
));
897 symstail
= &sym
->next
;
903 sym
->symv
.key
= offset
;
904 sym
->initial_snum
= -1;
906 /* external and common symbols get N_EXT */
907 if (is_global
!= 0) {
911 if (section
== NO_SEG
) {
912 /* symbols in no section get absolute */
916 /* all absolute symbols are available to use as references */
917 absolute_sect
.gsyms
= rb_insert(absolute_sect
.gsyms
, &sym
->symv
);
919 struct section
*s
= get_section_by_index(section
);
923 /* get the in-file index of the section the symbol was defined in */
924 sym
->sect
= s
? s
->fileindex
: NO_SECT
;
926 /* track the initially allocated symbol number for use in future fix-ups */
927 sym
->initial_snum
= nsyms
;
930 /* remember symbol number of references to external
931 ** symbols, this works because every external symbol gets
932 ** its own section number allocated internally by nasm and
933 ** can so be used as a key */
934 extsyms
= raa_write(extsyms
, section
, nsyms
);
939 /* there isn't actually a difference between global
940 ** and common symbols, both even have their size in
946 /* give an error on unfound section if it's not an
947 ** external or common symbol (assemble_file() does a
948 ** seg_alloc() on every call for them) */
949 nasm_panic(0, "in-file index for section %d not found, is_global = %d", section
, is_global
);
952 } else if (is_global
) {
953 s
->gsyms
= rb_insert(s
->gsyms
, &sym
->symv
);
959 static void macho_sectalign(int32_t seg
, unsigned int value
)
964 nasm_assert(!(seg
& 1));
966 s
= get_section_by_index(seg
);
968 if (!s
|| !is_power2(value
))
971 align
= alignlog2_32(value
);
972 if (s
->align
< align
)
976 static int32_t macho_segbase(int32_t section
)
981 static void macho_filename(char *inname
, char *outname
)
983 standard_extension(inname
, outname
, ".o");
986 extern macros_t macho_stdmac
[];
988 /* Comparison function for qsort symbol layout. */
989 static int layout_compare (const struct symbol
**s1
,
990 const struct symbol
**s2
)
992 return (strcmp ((*s1
)->name
, (*s2
)->name
));
995 /* The native assembler does a few things in a similar function
997 * Remove temporary labels
998 * Sort symbols according to local, external, undefined (by name)
999 * Order the string table
1001 We do not remove temporary labels right now.
1003 numsyms is the total number of symbols we have. strtabsize is the
1004 number entries in the string table. */
1006 static void macho_layout_symbols (uint32_t *numsyms
,
1007 uint32_t *strtabsize
)
1009 struct symbol
*sym
, **symp
;
1013 *strtabsize
= sizeof (char);
1017 while ((sym
= *symp
)) {
1018 /* Undefined symbols are now external. */
1019 if (sym
->type
== N_UNDF
)
1022 if ((sym
->type
& N_EXT
) == 0) {
1023 sym
->snum
= *numsyms
;
1024 *numsyms
= *numsyms
+ 1;
1028 if ((sym
->type
& N_TYPE
) != N_UNDF
) {
1034 /* If we handle debug info we'll want
1035 to check for it here instead of just
1036 adding the symbol to the string table. */
1037 sym
->strx
= *strtabsize
;
1038 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen(sym
->name
) + 1));
1039 *strtabsize
+= strlen(sym
->name
) + 1;
1041 symp
= &(sym
->next
);
1044 /* Next, sort the symbols. Most of this code is a direct translation from
1045 the Apple cctools symbol layout. We need to keep compatibility with that. */
1046 /* Set the indexes for symbol groups into the symbol table */
1048 iextdefsym
= nlocalsym
;
1049 iundefsym
= nlocalsym
+ nextdefsym
;
1051 /* allocate arrays for sorting externals by name */
1052 extdefsyms
= nasm_malloc(nextdefsym
* sizeof(struct symbol
*));
1053 undefsyms
= nasm_malloc(nundefsym
* sizeof(struct symbol
*));
1060 while ((sym
= *symp
)) {
1062 if((sym
->type
& N_EXT
) == 0) {
1063 sym
->strx
= *strtabsize
;
1064 saa_wbytes (strs
, sym
->name
, (int32_t)(strlen (sym
->name
) + 1));
1065 *strtabsize
+= strlen(sym
->name
) + 1;
1068 if((sym
->type
& N_TYPE
) != N_UNDF
) {
1069 extdefsyms
[i
++] = sym
;
1071 undefsyms
[j
++] = sym
;
1074 symp
= &(sym
->next
);
1077 qsort(extdefsyms
, nextdefsym
, sizeof(struct symbol
*),
1078 (int (*)(const void *, const void *))layout_compare
);
1079 qsort(undefsyms
, nundefsym
, sizeof(struct symbol
*),
1080 (int (*)(const void *, const void *))layout_compare
);
1082 for(i
= 0; i
< nextdefsym
; i
++) {
1083 extdefsyms
[i
]->snum
= *numsyms
;
1086 for(j
= 0; j
< nundefsym
; j
++) {
1087 undefsyms
[j
]->snum
= *numsyms
;
1092 /* Calculate some values we'll need for writing later. */
1094 static void macho_calculate_sizes (void)
1099 /* count sections and calculate in-memory and in-file offsets */
1100 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1103 /* recalculate segment address based on alignment and vm size */
1104 s
->addr
= seg_vmsize
;
1106 /* we need section alignment to calculate final section address */
1108 s
->align
= DEFAULT_SECTION_ALIGNMENT
;
1110 newaddr
= ALIGN(s
->addr
, 1 << s
->align
);
1113 seg_vmsize
= newaddr
+ s
->size
;
1115 /* zerofill sections aren't actually written to the file */
1116 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1118 * LLVM/Xcode as always aligns the section data to 4
1119 * bytes; there is a comment in the LLVM source code that
1120 * perhaps aligning to pointer size would be better.
1122 s
->pad
= ALIGN(seg_filesize
, 4) - seg_filesize
;
1123 s
->offset
= seg_filesize
+ s
->pad
;
1124 seg_filesize
+= s
->size
+ s
->pad
;
1128 /* calculate size of all headers, load commands and sections to
1129 ** get a pointer to the start of all the raw data */
1130 if (seg_nsects
> 0) {
1132 head_sizeofcmds
+= fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
;
1137 head_sizeofcmds
+= MACHO_SYMCMD_SIZE
;
1140 if (seg_nsects
> MAX_SECT
) {
1141 nasm_fatal(0, "MachO output is limited to %d sections\n",
1145 /* Create a table of sections by file index to avoid linear search */
1146 sectstab
= nasm_malloc((seg_nsects
+ 1) * sizeof(*sectstab
));
1147 sectstab
[NO_SECT
] = &absolute_sect
;
1148 for (s
= sects
, fi
= 1; s
!= NULL
; s
= s
->next
, fi
++)
1152 /* Write out the header information for the file. */
1154 static void macho_write_header (void)
1156 fwriteint32_t(fmt
.mh_magic
, ofile
); /* magic */
1157 fwriteint32_t(fmt
.cpu_type
, ofile
); /* CPU type */
1158 fwriteint32_t(CPU_SUBTYPE_I386_ALL
, ofile
); /* CPU subtype */
1159 fwriteint32_t(MH_OBJECT
, ofile
); /* Mach-O file type */
1160 fwriteint32_t(head_ncmds
, ofile
); /* number of load commands */
1161 fwriteint32_t(head_sizeofcmds
, ofile
); /* size of load commands */
1162 fwriteint32_t(0, ofile
); /* no flags */
1163 fwritezero(fmt
.header_size
- 7*4, ofile
); /* reserved fields */
1166 /* Write out the segment load command at offset. */
1168 static uint32_t macho_write_segment (uint64_t offset
)
1170 uint64_t rel_base
= alignptr(offset
+ seg_filesize
);
1171 uint32_t s_reloff
= 0;
1174 fwriteint32_t(fmt
.lc_segment
, ofile
); /* cmd == LC_SEGMENT_64 */
1176 /* size of load command including section load commands */
1177 fwriteint32_t(fmt
.segcmd_size
+ seg_nsects
* fmt
.sectcmd_size
,
1180 /* in an MH_OBJECT file all sections are in one unnamed (name
1181 ** all zeros) segment */
1182 fwritezero(16, ofile
);
1183 fwriteptr(0, ofile
); /* in-memory offset */
1184 fwriteptr(seg_vmsize
, ofile
); /* in-memory size */
1185 fwriteptr(offset
, ofile
); /* in-file offset to data */
1186 fwriteptr(seg_filesize
, ofile
); /* in-file size */
1187 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* maximum vm protection */
1188 fwriteint32_t(VM_PROT_DEFAULT
, ofile
); /* initial vm protection */
1189 fwriteint32_t(seg_nsects
, ofile
); /* number of sections */
1190 fwriteint32_t(0, ofile
); /* no flags */
1192 /* emit section headers */
1193 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1195 nasm_assert((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
);
1196 s
->flags
|= S_ATTR_LOC_RELOC
;
1198 s
->flags
|= S_ATTR_EXT_RELOC
;
1199 } else if (!strcmp(s
->segname
, "__DATA") &&
1200 !strcmp(s
->sectname
, "__const") &&
1202 !get_section_by_name("__TEXT", "__const")) {
1204 * The MachO equivalent to .rodata can be either
1205 * __DATA,__const or __TEXT,__const; the latter only if
1206 * there are no relocations. However, when mixed it is
1207 * better to specify the segments explicitly.
1209 xstrncpy(s
->segname
, "__TEXT");
1212 nasm_write(s
->sectname
, sizeof(s
->sectname
), ofile
);
1213 nasm_write(s
->segname
, sizeof(s
->segname
), ofile
);
1214 fwriteptr(s
->addr
, ofile
);
1215 fwriteptr(s
->size
, ofile
);
1217 /* dummy data for zerofill sections or proper values */
1218 if ((s
->flags
& SECTION_TYPE
) != S_ZEROFILL
) {
1219 nasm_assert(s
->pad
!= (uint32_t)-1);
1221 fwriteint32_t(offset
, ofile
);
1223 /* Write out section alignment, as a power of two.
1224 e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1225 fwriteint32_t(s
->align
, ofile
);
1226 /* To be compatible with cctools as we emit
1227 a zero reloff if we have no relocations. */
1228 fwriteint32_t(s
->nreloc
? rel_base
+ s_reloff
: 0, ofile
);
1229 fwriteint32_t(s
->nreloc
, ofile
);
1231 s_reloff
+= s
->nreloc
* MACHO_RELINFO_SIZE
;
1233 fwriteint32_t(0, ofile
);
1234 fwriteint32_t(s
->align
, ofile
);
1235 fwriteint32_t(0, ofile
);
1236 fwriteint32_t(0, ofile
);
1239 fwriteint32_t(s
->flags
, ofile
); /* flags */
1240 fwriteint32_t(0, ofile
); /* reserved */
1241 fwriteptr(0, ofile
); /* reserved */
1244 rel_padcnt
= rel_base
- offset
;
1245 offset
= rel_base
+ s_reloff
;
1250 /* For a given chain of relocs r, write out the entire relocation
1251 chain to the object file. */
1253 static void macho_write_relocs (struct reloc
*r
)
1258 fwriteint32_t(r
->addr
, ofile
); /* reloc offset */
1261 word2
|= r
->pcrel
<< 24;
1262 word2
|= r
->length
<< 25;
1263 word2
|= r
->ext
<< 27;
1264 word2
|= r
->type
<< 28;
1265 fwriteint32_t(word2
, ofile
); /* reloc data */
1270 /* Write out the section data. */
1271 static void macho_write_section (void)
1283 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1284 if ((s
->flags
& SECTION_TYPE
) == S_ZEROFILL
)
1287 /* Like a.out Mach-O references things in the data or bss
1288 * sections by addresses which are actually relative to the
1289 * start of the _text_ section, in the _file_. See outaout.c
1290 * for more information. */
1291 saa_rewind(s
->data
);
1292 for (r
= s
->relocs
; r
!= NULL
; r
= r
->next
) {
1293 len
= (uint32_t)1 << r
->length
;
1294 if (len
> 4) /* Can this ever be an issue?! */
1297 saa_fread(s
->data
, r
->addr
, blk
.buf
, len
);
1299 /* get offset based on relocation type */
1300 #ifdef WORDS_LITTLEENDIAN
1304 l
+= ((int64_t)blk
.buf
[1]) << 8;
1305 l
+= ((int64_t)blk
.buf
[2]) << 16;
1306 l
+= ((int64_t)blk
.buf
[3]) << 24;
1307 l
+= ((int64_t)blk
.buf
[4]) << 32;
1308 l
+= ((int64_t)blk
.buf
[5]) << 40;
1309 l
+= ((int64_t)blk
.buf
[6]) << 48;
1310 l
+= ((int64_t)blk
.buf
[7]) << 56;
1313 /* If the relocation is internal add to the current section
1314 offset. Otherwise the only value we need is the symbol
1315 offset which we already have. The linker takes care
1316 of the rest of the address. */
1318 /* generate final address by section address and offset */
1319 nasm_assert(r
->snum
<= seg_nsects
);
1320 l
+= sectstab
[r
->snum
]->addr
;
1325 /* write new offset back */
1328 saa_fwrite(s
->data
, r
->addr
, blk
.buf
, len
);
1331 /* dump the section data to file */
1332 fwritezero(s
->pad
, ofile
);
1333 saa_fpwrite(s
->data
, ofile
);
1336 /* pad last section up to reloc entries on pointer boundary */
1337 fwritezero(rel_padcnt
, ofile
);
1339 /* emit relocation entries */
1340 for (s
= sects
; s
!= NULL
; s
= s
->next
)
1341 macho_write_relocs (s
->relocs
);
1344 /* Write out the symbol table. We should already have sorted this
1346 static void macho_write_symtab (void)
1351 /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1353 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1354 if ((sym
->type
& N_EXT
) == 0) {
1355 fwriteint32_t(sym
->strx
, ofile
); /* string table entry number */
1356 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1357 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1358 fwriteint16_t(sym
->desc
, ofile
); /* description */
1360 /* Fix up the symbol value now that we know the final section
1362 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1363 nasm_assert(sym
->sect
<= seg_nsects
);
1364 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1367 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1371 for (i
= 0; i
< nextdefsym
; i
++) {
1372 sym
= extdefsyms
[i
];
1373 fwriteint32_t(sym
->strx
, ofile
);
1374 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1375 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1376 fwriteint16_t(sym
->desc
, ofile
); /* description */
1378 /* Fix up the symbol value now that we know the final section
1380 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1381 nasm_assert(sym
->sect
<= seg_nsects
);
1382 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1385 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1388 for (i
= 0; i
< nundefsym
; i
++) {
1390 fwriteint32_t(sym
->strx
, ofile
);
1391 nasm_write(&sym
->type
, 1, ofile
); /* symbol type */
1392 nasm_write(&sym
->sect
, 1, ofile
); /* section */
1393 fwriteint16_t(sym
->desc
, ofile
); /* description */
1395 /* Fix up the symbol value now that we know the final section
1397 if (((sym
->type
& N_TYPE
) == N_SECT
) && (sym
->sect
!= NO_SECT
)) {
1398 nasm_assert(sym
->sect
<= seg_nsects
);
1399 sym
->symv
.key
+= sectstab
[sym
->sect
]->addr
;
1402 fwriteptr(sym
->symv
.key
, ofile
); /* value (i.e. offset) */
1407 /* Fixup the snum in the relocation entries, we should be
1408 doing this only for externally referenced symbols. */
1409 static void macho_fixup_relocs (struct reloc
*r
)
1415 for (sym
= syms
; sym
!= NULL
; sym
= sym
->next
) {
1416 if (sym
->initial_snum
== r
->snum
) {
1417 r
->snum
= sym
->snum
;
1426 /* Write out the object file. */
1428 static void macho_write (void)
1430 uint64_t offset
= 0;
1432 /* mach-o object file structure:
1438 ** uint32_t mach file type
1439 ** uint32_t number of load commands
1440 ** uint32_t size of all load commands
1441 ** (includes section struct size of segment command)
1445 ** uint32_t command type == LC_SEGMENT[_64]
1446 ** uint32_t size of load command
1447 ** (including section load commands)
1448 ** char[16] segment name
1449 ** pointer in-memory offset
1450 ** pointer in-memory size
1451 ** pointer in-file offset to data area
1452 ** pointer in-file size
1453 ** (in-memory size excluding zerofill sections)
1454 ** int maximum vm protection
1455 ** int initial vm protection
1456 ** uint32_t number of sections
1460 ** char[16] section name
1461 ** char[16] segment name
1462 ** pointer in-memory offset
1463 ** pointer in-memory size
1464 ** uint32_t in-file offset
1465 ** uint32_t alignment
1466 ** (irrelevant in MH_OBJECT)
1467 ** uint32_t in-file offset of relocation entires
1468 ** uint32_t number of relocations
1470 ** uint32_t reserved
1471 ** uint32_t reserved
1473 ** symbol table command
1474 ** uint32_t command type == LC_SYMTAB
1475 ** uint32_t size of load command
1476 ** uint32_t symbol table offset
1477 ** uint32_t number of symbol table entries
1478 ** uint32_t string table offset
1479 ** uint32_t string table size
1483 ** padding to pointer boundary
1485 ** relocation data (struct reloc)
1487 ** uint data (symbolnum, pcrel, length, extern, type)
1489 ** symbol table data (struct nlist)
1490 ** int32_t string table entry number
1492 ** (extern, absolute, defined in section)
1494 ** (0 for global symbols, section number of definition (>= 1, <=
1495 ** 254) for local symbols, size of variable for common symbols
1496 ** [type == extern])
1497 ** int16_t description
1498 ** (for stab debugging format)
1499 ** pointer value (i.e. file offset) of symbol or stab offset
1501 ** string table data
1502 ** list of null-terminated strings
1505 /* Emit the Mach-O header. */
1506 macho_write_header();
1508 offset
= fmt
.header_size
+ head_sizeofcmds
;
1510 /* emit the segment load command */
1512 offset
= macho_write_segment (offset
);
1514 nasm_error(ERR_WARNING
, "no sections?");
1517 /* write out symbol command */
1518 fwriteint32_t(LC_SYMTAB
, ofile
); /* cmd == LC_SYMTAB */
1519 fwriteint32_t(MACHO_SYMCMD_SIZE
, ofile
); /* size of load command */
1520 fwriteint32_t(offset
, ofile
); /* symbol table offset */
1521 fwriteint32_t(nsyms
, ofile
); /* number of symbol
1523 offset
+= nsyms
* fmt
.nlist_size
;
1524 fwriteint32_t(offset
, ofile
); /* string table offset */
1525 fwriteint32_t(strslen
, ofile
); /* string table size */
1528 /* emit section data */
1530 macho_write_section ();
1532 /* emit symbol table if we have symbols */
1534 macho_write_symtab ();
1536 /* we don't need to pad here, we are already aligned */
1538 /* emit string table */
1539 saa_fpwrite(strs
, ofile
);
1541 /* We do quite a bit here, starting with finalizing all of the data
1542 for the object file, writing, and then freeing all of the data from
1545 static void macho_cleanup(void)
1551 /* Sort all symbols. */
1552 macho_layout_symbols (&nsyms
, &strslen
);
1554 /* Fixup relocation entries */
1555 for (s
= sects
; s
!= NULL
; s
= s
->next
) {
1556 macho_fixup_relocs (s
->relocs
);
1559 /* First calculate and finalize needed values. */
1560 macho_calculate_sizes();
1563 /* free up everything */
1564 while (sects
->next
) {
1566 sects
= sects
->next
;
1569 while (s
->relocs
!= NULL
) {
1571 s
->relocs
= s
->relocs
->next
;
1587 nasm_free(extdefsyms
);
1588 nasm_free(undefsyms
);
1589 nasm_free(sectstab
);
1593 static const struct macho_fmt macho32_fmt
= {
1603 GENERIC_RELOC_VANILLA
,
1604 GENERIC_RELOC_VANILLA
,
1608 static void macho32_init(void)
1613 macho_gotpcrel_sect
= NO_SEG
;
1616 const struct ofmt of_macho32
= {
1617 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
1638 static const struct macho_fmt macho64_fmt
= {
1643 MACHO_HEADER64_SIZE
,
1644 MACHO_SEGCMD64_SIZE
,
1645 MACHO_SECTCMD64_SIZE
,
1648 X86_64_RELOC_UNSIGNED
,
1649 X86_64_RELOC_SIGNED
,
1653 static void macho64_init(void)
1658 /* add special symbol for ..gotpcrel */
1659 macho_gotpcrel_sect
= seg_alloc() + 1;
1660 define_label("..gotpcrel", macho_gotpcrel_sect
, 0L, NULL
, false, false);
1663 const struct ofmt of_macho64
= {
1664 "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",