mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-17 17:19:35 +08:00
Merge the macho32 and macho64 (outmac32/64) backends
Merge the two Mach-O backends for cleanliness and maintainability. This should also make the recent fixes to MachO-64 available in MachO-32. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
d7043da281
commit
c635497870
12
Makefile.in
12
Makefile.in
@ -84,8 +84,7 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \
|
||||
output/outelf.$(O) output/outelf32.$(O) output/outelf64.$(O) \
|
||||
output/outelfx32.$(O) \
|
||||
output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac32.$(O) \
|
||||
output/outmac64.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac.$(O) \
|
||||
md5c.$(O) output/codeview.$(O) \
|
||||
preproc.$(O) quote.$(O) pptok.$(O) \
|
||||
macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) \
|
||||
@ -404,12 +403,9 @@ output/outieee.$(O): output/outieee.c compiler.h config.h directiv.h \
|
||||
output/outlib.$(O): output/outlib.c compiler.h config.h directiv.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outlib.h pptok.h preproc.h regs.h \
|
||||
tables.h
|
||||
output/outmac32.$(O): output/outmac32.c compiler.h config.h directiv.h \
|
||||
eval.h insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac64.$(O): output/outmac64.c compiler.h config.h directiv.h \
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac.$(O): output/outmac.c compiler.h config.h directiv.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h \
|
||||
preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outobj.$(O): output/outobj.c compiler.h config.h directiv.h eval.h \
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \
|
||||
pptok.h preproc.h regs.h stdscan.h tables.h
|
||||
|
@ -55,8 +55,7 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \
|
||||
output/outelf.$(O) output/outelf32.$(O) output/outelf64.$(O) \
|
||||
output/outelfx32.$(O) \
|
||||
output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac32.$(O) \
|
||||
output/outmac64.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac.$(O) \
|
||||
md5c.$(O) output/codeview.$(O) \
|
||||
preproc.$(O) quote.$(O) pptok.$(O) \
|
||||
macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) \
|
||||
@ -320,12 +319,9 @@ output/outieee.$(O): output/outieee.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
regs.h tables.h
|
||||
output/outlib.$(O): output/outlib.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h output/outlib.h pptok.h preproc.h regs.h tables.h
|
||||
output/outmac32.$(O): output/outmac32.c compiler.h directiv.h eval.h \
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac64.$(O): output/outmac64.c compiler.h directiv.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h \
|
||||
preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac.$(O): output/outmac.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h preproc.h \
|
||||
raa.h regs.h saa.h tables.h
|
||||
output/outobj.$(O): output/outobj.c compiler.h directiv.h eval.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h \
|
||||
preproc.h regs.h stdscan.h tables.h
|
||||
|
@ -42,8 +42,7 @@ NASM = nasm.o nasmlib.o ver.o \
|
||||
outelf.o outelf32.o outelf64.o \
|
||||
outelfx32.o \
|
||||
outobj.o outas86.o outrdf2.o \
|
||||
outdbg.o outieee.o outmac32.o \
|
||||
outmac64.o \
|
||||
outdbg.o outieee.o outmac.o \
|
||||
md5c.o codeview.o \
|
||||
preproc.o quote.o pptok.o \
|
||||
macros.o listing.o eval.o exprlib.o stdscan.o \
|
||||
@ -224,12 +223,8 @@ outieee.o: outieee.c compiler.h config.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h outform.h outlib.h pptok.h preproc.h regs.h tables.h
|
||||
outlib.o: outlib.c compiler.h config.h directiv.h insnsi.h nasm.h nasmlib.h \
|
||||
opflags.h outlib.h pptok.h preproc.h regs.h tables.h
|
||||
outmac32.o: outmac32.c compiler.h config.h directiv.h eval.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h outform.h outlib.h pptok.h preproc.h raa.h regs.h saa.h \
|
||||
tables.h
|
||||
outmac64.o: outmac64.c compiler.h config.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h outform.h outlib.h pptok.h preproc.h raa.h regs.h saa.h \
|
||||
tables.h
|
||||
outmac.o: outmac.c compiler.h config.h directiv.h insnsi.h nasm.h nasmlib.h \
|
||||
opflags.h outform.h outlib.h pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
outobj.o: outobj.c compiler.h config.h directiv.h eval.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h outform.h outlib.h pptok.h preproc.h regs.h stdscan.h \
|
||||
tables.h
|
||||
|
@ -58,8 +58,7 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) &
|
||||
output/outelf.$(O) output/outelf32.$(O) output/outelf64.$(O) &
|
||||
output/outelfx32.$(O) &
|
||||
output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) &
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac32.$(O) &
|
||||
output/outmac64.$(O) &
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac.$(O) &
|
||||
md5c.$(O) output/codeview.$(O) &
|
||||
preproc.$(O) quote.$(O) pptok.$(O) &
|
||||
macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) &
|
||||
@ -371,12 +370,9 @@ output/outieee.$(O): output/outieee.c compiler.h config.h directiv.h &
|
||||
output/outlib.$(O): output/outlib.c compiler.h config.h directiv.h insnsi.h &
|
||||
nasm.h nasmlib.h opflags.h output/outlib.h pptok.h preproc.h regs.h &
|
||||
tables.h
|
||||
output/outmac32.$(O): output/outmac32.c compiler.h config.h directiv.h &
|
||||
eval.h insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h &
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac64.$(O): output/outmac64.c compiler.h config.h directiv.h &
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h &
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac.$(O): output/outmac.c compiler.h config.h directiv.h insnsi.h &
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h &
|
||||
preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outobj.$(O): output/outobj.c compiler.h config.h directiv.h eval.h &
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h &
|
||||
pptok.h preproc.h regs.h stdscan.h tables.h
|
||||
|
@ -69,8 +69,7 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \
|
||||
output/outelf.$(O) output/outelf32.$(O) output/outelf64.$(O) \
|
||||
output/outelfx32.$(O) \
|
||||
output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac32.$(O) \
|
||||
output/outmac64.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmac.$(O) \
|
||||
md5c.$(O) output/codeview.$(O) \
|
||||
preproc.$(O) quote.$(O) pptok.$(O) \
|
||||
macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) \
|
||||
@ -334,12 +333,9 @@ output/outieee.$(O): output/outieee.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
regs.h tables.h
|
||||
output/outlib.$(O): output/outlib.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h output/outlib.h pptok.h preproc.h regs.h tables.h
|
||||
output/outmac32.$(O): output/outmac32.c compiler.h directiv.h eval.h \
|
||||
insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \
|
||||
pptok.h preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac64.$(O): output/outmac64.c compiler.h directiv.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h \
|
||||
preproc.h raa.h regs.h saa.h tables.h
|
||||
output/outmac.$(O): output/outmac.c compiler.h directiv.h insnsi.h nasm.h \
|
||||
nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h preproc.h \
|
||||
raa.h regs.h saa.h tables.h
|
||||
output/outobj.$(O): output/outobj.c compiler.h directiv.h eval.h insnsi.h \
|
||||
nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h pptok.h \
|
||||
preproc.h regs.h stdscan.h tables.h
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
*
|
||||
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
@ -14,7 +14,7 @@
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
@ -54,26 +54,32 @@
|
||||
#include "output/outform.h"
|
||||
#include "output/outlib.h"
|
||||
|
||||
#if defined(OF_MACHO64)
|
||||
#if defined(OF_MACHO) || defined(OF_MACHO64)
|
||||
|
||||
/* Mach-O in-file header structure sizes */
|
||||
#define MACHO_HEADER64_SIZE (32)
|
||||
#define MACHO_SEGCMD64_SIZE (72)
|
||||
#define MACHO_SECTCMD64_SIZE (80)
|
||||
#define MACHO_SYMCMD_SIZE (24)
|
||||
#define MACHO_NLIST64_SIZE (16)
|
||||
#define MACHO_RELINFO64_SIZE (8)
|
||||
#define MACHO_DATA_IN_CODE_CMD_SIZE (16)
|
||||
#define MACHO_HEADER_SIZE 28
|
||||
#define MACHO_SEGCMD_SIZE 56
|
||||
#define MACHO_SECTCMD_SIZE 68
|
||||
#define MACHO_SYMCMD_SIZE 24
|
||||
#define MACHO_NLIST_SIZE 12
|
||||
#define MACHO_RELINFO_SIZE 8
|
||||
|
||||
#define MACHO_HEADER64_SIZE 32
|
||||
#define MACHO_SEGCMD64_SIZE 72
|
||||
#define MACHO_SECTCMD64_SIZE 80
|
||||
#define MACHO_NLIST64_SIZE 16
|
||||
|
||||
/* Mach-O file header values */
|
||||
#define MH_MAGIC_64 (0xfeedfacf)
|
||||
#define CPU_TYPE_X86_64 (0x01000007) /* x86-64 platform */
|
||||
#define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */
|
||||
#define MH_OBJECT (0x1) /* object file */
|
||||
#define MH_MAGIC 0xfeedface
|
||||
#define MH_MAGIC_64 0xfeedfacf
|
||||
#define CPU_TYPE_I386 7 /* x86 platform */
|
||||
#define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
|
||||
#define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
|
||||
#define MH_OBJECT 0x1 /* object file */
|
||||
|
||||
#define LC_SEGMENT_64 (0x19) /* segment load command */
|
||||
#define LC_SYMTAB (0x2) /* symbol table load command */
|
||||
#define LC_DATA_IN_CODE (0x29) /* data in code command */
|
||||
#define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
|
||||
#define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
|
||||
#define LC_SYMTAB 0x2 /* symbol table load command */
|
||||
|
||||
#define VM_PROT_NONE (0x00)
|
||||
#define VM_PROT_READ (0x01)
|
||||
@ -83,6 +89,46 @@
|
||||
#define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
|
||||
#define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
|
||||
|
||||
struct macho_fmt {
|
||||
uint32_t ptrsize; /* Pointer size in bytes */
|
||||
uint32_t mh_magic; /* Which magic number to use */
|
||||
uint32_t cpu_type; /* Which CPU type */
|
||||
uint32_t lc_segment; /* Which segment load command */
|
||||
uint32_t header_size; /* Header size */
|
||||
uint32_t segcmd_size; /* Segment command size */
|
||||
uint32_t sectcmd_size; /* Section command size */
|
||||
uint32_t nlist_size; /* Nlist (symbol) size */
|
||||
};
|
||||
|
||||
static const struct macho_fmt macho32_fmt = {
|
||||
4,
|
||||
MH_MAGIC,
|
||||
CPU_TYPE_I386,
|
||||
LC_SEGMENT,
|
||||
MACHO_HEADER_SIZE,
|
||||
MACHO_SEGCMD_SIZE,
|
||||
MACHO_SECTCMD_SIZE,
|
||||
MACHO_NLIST_SIZE
|
||||
};
|
||||
|
||||
static const struct macho_fmt macho64_fmt = {
|
||||
8,
|
||||
MH_MAGIC_64,
|
||||
CPU_TYPE_X86_64,
|
||||
LC_SEGMENT_64,
|
||||
MACHO_HEADER64_SIZE,
|
||||
MACHO_SEGCMD64_SIZE,
|
||||
MACHO_SECTCMD64_SIZE,
|
||||
MACHO_NLIST64_SIZE
|
||||
};
|
||||
|
||||
static const struct macho_fmt *fmt;
|
||||
|
||||
static void fwriteptr(uint64_t data, FILE * fp)
|
||||
{
|
||||
fwriteaddr(data, fmt->ptrsize, fp);
|
||||
}
|
||||
|
||||
struct section {
|
||||
/* nasm internal data */
|
||||
struct section *next;
|
||||
@ -231,10 +277,13 @@ static uint64_t rel_padcnt = 0;
|
||||
xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
|
||||
|
||||
#define alignint32_t(x) \
|
||||
ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
|
||||
ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
|
||||
|
||||
#define alignint64_t(x) \
|
||||
ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
|
||||
ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
|
||||
|
||||
#define alignptr(x) \
|
||||
ALIGN(x, fmt->ptrsize) /* align x to output format width */
|
||||
|
||||
static void debug_reloc (struct reloc *);
|
||||
static void debug_section_relocs (struct section *) _unused;
|
||||
@ -330,8 +379,6 @@ static int32_t macho_gotpcrel_sect;
|
||||
|
||||
static void macho_init(void)
|
||||
{
|
||||
char zero = 0;
|
||||
|
||||
sects = NULL;
|
||||
sectstail = §s;
|
||||
|
||||
@ -345,14 +392,9 @@ static void macho_init(void)
|
||||
extsyms = raa_init();
|
||||
strs = saa_init(1L);
|
||||
|
||||
/* string table starts with a zero byte - don't ask why */
|
||||
saa_wbytes(strs, &zero, sizeof(char));
|
||||
/* string table starts with a zero byte so index 0 is an empty string */
|
||||
saa_wbytes(strs, zero_buffer, 1);
|
||||
strslen = 1;
|
||||
|
||||
/* add special symbol for ..gotpcrel */
|
||||
macho_gotpcrel_sect = seg_alloc();
|
||||
macho_gotpcrel_sect++;
|
||||
define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
|
||||
}
|
||||
|
||||
static void sect_write(struct section *sect,
|
||||
@ -362,14 +404,25 @@ static void sect_write(struct section *sect,
|
||||
sect->size += len;
|
||||
}
|
||||
|
||||
enum reltype {
|
||||
RL_ABS, /* Absolute relocation */
|
||||
RL_REL, /* Relative relocation */
|
||||
RL_SUB, /* X86_64_RELOC_SUBTRACT */
|
||||
RL_GOT, /* X86_64_RELOC_GOT */
|
||||
RL_GOTLOAD, /* X86_64_RELOC_GOT_LOAD */
|
||||
};
|
||||
|
||||
static int32_t add_reloc(struct section *sect, int32_t section,
|
||||
int pcrel, int bytes, int64_t reloff)
|
||||
enum reltype reltype, int bytes, int64_t reloff)
|
||||
{
|
||||
struct reloc *r;
|
||||
struct symbol *sym;
|
||||
int32_t fi;
|
||||
int32_t adjustment = 0;
|
||||
|
||||
if (section == NO_SEG)
|
||||
return 0;
|
||||
|
||||
/* NeXT as puts relocs in reversed order (address-wise) into the
|
||||
** files, so we do the same, doesn't seem to make much of a
|
||||
** difference either way */
|
||||
@ -383,97 +436,81 @@ static int32_t add_reloc(struct section *sect, int32_t section,
|
||||
** bit by accident */
|
||||
r->addr = sect->size & ~R_SCATTERED;
|
||||
r->ext = 1;
|
||||
r->pcrel = (pcrel ? 1 : 0);
|
||||
|
||||
/* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
|
||||
switch(bytes){
|
||||
case 1:
|
||||
r->length = 0;
|
||||
break;
|
||||
case 2:
|
||||
r->length = 1;
|
||||
break;
|
||||
case 4:
|
||||
r->length = 2;
|
||||
break;
|
||||
case 8:
|
||||
r->length = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
r->length = ilog2_32(bytes);
|
||||
|
||||
/* set default relocation values */
|
||||
r->type = 0; // X86_64_RELOC_UNSIGNED
|
||||
r->snum = R_ABS; // Absolute Symbol (indicates no relocation)
|
||||
r->type = 0;
|
||||
r->pcrel = 0;
|
||||
r->snum = R_ABS;
|
||||
|
||||
/* absolute relocation */
|
||||
if (pcrel == 0) {
|
||||
|
||||
/* intra-section */
|
||||
if (section == NO_SEG) {
|
||||
// r->snum = R_ABS; // Set above
|
||||
|
||||
/* inter-section */
|
||||
} else {
|
||||
fi = get_section_fileindex_by_index(section);
|
||||
|
||||
/* external */
|
||||
if (fi == NO_SECT) {
|
||||
r->snum = raa_read(extsyms, section);
|
||||
|
||||
/* local */
|
||||
} else {
|
||||
sym = get_closest_section_symbol_by_offset(fi, reloff);
|
||||
r->snum = sym->initial_snum;
|
||||
adjustment = sym->value;
|
||||
}
|
||||
}
|
||||
/* absolute relocation */
|
||||
switch (reltype) {
|
||||
case RL_ABS:
|
||||
if (section == NO_SEG) {
|
||||
/* intra-section */
|
||||
r->snum = R_ABS;
|
||||
} else {
|
||||
/* inter-section */
|
||||
fi = get_section_fileindex_by_index(section);
|
||||
|
||||
/* relative relocation */
|
||||
} else if (pcrel == 1) {
|
||||
|
||||
/* intra-section */
|
||||
if (section == NO_SEG) {
|
||||
r->type = 1; // X86_64_RELOC_SIGNED
|
||||
|
||||
/* inter-section */
|
||||
} else {
|
||||
r->type = 1; // X86_64_RELOC_SIGNED
|
||||
fi = get_section_fileindex_by_index(section);
|
||||
|
||||
/* external */
|
||||
if (fi == NO_SECT) {
|
||||
sect->extreloc = 1;
|
||||
r->snum = raa_read(extsyms, section);
|
||||
|
||||
/* local */
|
||||
} else {
|
||||
sym = get_closest_section_symbol_by_offset(fi, reloff);
|
||||
r->snum = sym->initial_snum;
|
||||
adjustment = sym->value;
|
||||
}
|
||||
}
|
||||
|
||||
/* subtractor */
|
||||
} else if (pcrel == 2) {
|
||||
r->pcrel = 0;
|
||||
r->type = 5; // X86_64_RELOC_SUBTRACTOR
|
||||
|
||||
/* gotpcrel */
|
||||
} else if (pcrel == 3) {
|
||||
r->type = 4; // X86_64_RELOC_GOT
|
||||
r->snum = macho_gotpcrel_sect;
|
||||
|
||||
/* gotpcrel MOVQ load */
|
||||
} else if (pcrel == 4) {
|
||||
r->type = 3; // X86_64_RELOC_GOT_LOAD
|
||||
r->snum = macho_gotpcrel_sect;
|
||||
if (fi == NO_SECT) {
|
||||
/* external */
|
||||
r->snum = raa_read(extsyms, section);
|
||||
} else {
|
||||
/* local */
|
||||
sym = get_closest_section_symbol_by_offset(fi, reloff);
|
||||
r->snum = sym->initial_snum;
|
||||
adjustment = sym->value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
++sect->nreloc;
|
||||
case RL_REL:
|
||||
r->pcrel = 1;
|
||||
if (section == NO_SEG) {
|
||||
/* intra-section */
|
||||
r->type = 1; // X86_64_RELOC_SIGNED
|
||||
} else {
|
||||
/* inter-section */
|
||||
r->type = 1; // X86_64_RELOC_SIGNED
|
||||
fi = get_section_fileindex_by_index(section);
|
||||
|
||||
return adjustment;
|
||||
if (fi == NO_SECT) {
|
||||
/* external */
|
||||
sect->extreloc = 1;
|
||||
r->snum = raa_read(extsyms, section);
|
||||
} else {
|
||||
/* local */
|
||||
sym = get_closest_section_symbol_by_offset(fi, reloff);
|
||||
r->snum = sym->initial_snum;
|
||||
adjustment = sym->value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RL_SUB:
|
||||
r->pcrel = 0;
|
||||
r->type = 5; // X86_64_RELOC_SUBTRACTOR
|
||||
break;
|
||||
|
||||
case RL_GOT:
|
||||
r->pcrel = 1;
|
||||
r->type = 4; // X86_64_RELOC_GOT
|
||||
r->snum = macho_gotpcrel_sect;
|
||||
break;
|
||||
|
||||
case RL_GOTLOAD:
|
||||
r->pcrel = 1;
|
||||
r->type = 3; // X86_64_RELOC_GOT_LOAD
|
||||
r->snum = macho_gotpcrel_sect;
|
||||
break;
|
||||
}
|
||||
|
||||
++sect->nreloc;
|
||||
|
||||
return adjustment;
|
||||
}
|
||||
|
||||
static void macho_output(int32_t secto, const void *data,
|
||||
@ -544,25 +581,18 @@ static void macho_output(int32_t secto, const void *data,
|
||||
if (section % 2) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
if (asize < 8) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
|
||||
" 32-bit absolute addresses");
|
||||
/*
|
||||
Seemingly, Mach-O's X86_64_RELOC_SUBTRACTOR would require
|
||||
pre-determined knowledge of where the image base would be,
|
||||
making it impractical for use in intermediate object files
|
||||
*/
|
||||
} else {
|
||||
addr -= add_reloc(s, section, 0, asize, addr); // X86_64_RELOC_UNSIGNED
|
||||
}
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" this use of WRT");
|
||||
}
|
||||
}
|
||||
} else if (wrt == NO_SEG) {
|
||||
if (fmt->ptrsize == 8 && asize != 8) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
|
||||
" 32-bit absolute addresses");
|
||||
} else {
|
||||
addr -= add_reloc(s, section, RL_ABS, asize, addr);
|
||||
}
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" this use of WRT");
|
||||
}
|
||||
}
|
||||
|
||||
p = mydata;
|
||||
WRITEADDR(p, addr, asize);
|
||||
@ -571,62 +601,67 @@ static void macho_output(int32_t secto, const void *data,
|
||||
}
|
||||
|
||||
case OUT_REL2ADR:
|
||||
nasm_assert(section != secto);
|
||||
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int64_t *)data);
|
||||
|
||||
if (section == secto)
|
||||
nasm_error(ERR_PANIC, "intra-section OUT_REL2ADR");
|
||||
|
||||
if (section == NO_SEG) {
|
||||
/* Do nothing */
|
||||
} else if (section % 2) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
|
||||
" Macho-O relocation [2]");
|
||||
}
|
||||
|
||||
sect_write(s, mydata, 2L);
|
||||
break;
|
||||
|
||||
case OUT_REL4ADR:
|
||||
p = mydata;
|
||||
addr = *(int64_t *)data + 4 - size;
|
||||
|
||||
if (section == secto)
|
||||
nasm_error(ERR_PANIC, "intra-section OUT_REL4ADR");
|
||||
addr = *(int64_t *)data + 2 - size;
|
||||
|
||||
if (section != NO_SEG && section % 2) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
addr -= add_reloc(s, section, 1, 4, addr); // X86_64_RELOC_SIGNED/BRANCH
|
||||
} else if (wrt == macho_gotpcrel_sect) {
|
||||
if (s->data->datalen > 1) {
|
||||
saa_fread(s->data, s->data->datalen-2, &gotload, 1); // Retrieve Instruction Opcode
|
||||
} else {
|
||||
gotload = 0;
|
||||
}
|
||||
if (gotload == 0x8B) { // Check for MOVQ Opcode
|
||||
addr -= add_reloc(s, section, 4, 4, addr); // X86_64_GOT_LOAD (MOVQ load)
|
||||
} else {
|
||||
addr -= add_reloc(s, section, 3, 4, addr); // X86_64_GOT
|
||||
}
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" this use of WRT");
|
||||
wrt = NO_SEG; /* we can at least _try_ to continue */
|
||||
}
|
||||
}
|
||||
" section base references");
|
||||
} else if (fmt->ptrsize == 8) {
|
||||
nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
|
||||
" Macho-O relocation [2]");
|
||||
} else if (wrt != NO_SEG) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" this use of WRT");
|
||||
wrt = NO_SEG; /* we can at least _try_ to continue */
|
||||
} else {
|
||||
addr -= add_reloc(s, section, RL_REL, 2, addr);
|
||||
}
|
||||
|
||||
WRITESHORT(p, addr);
|
||||
sect_write(s, mydata, 2);
|
||||
break;
|
||||
|
||||
case OUT_REL4ADR:
|
||||
nasm_assert(section != secto);
|
||||
|
||||
p = mydata;
|
||||
addr = *(int64_t *)data + 4 - size;
|
||||
|
||||
if (section != NO_SEG && section % 2) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
} else if (wrt == NO_SEG) {
|
||||
/* Plain relative relocation */
|
||||
addr -= add_reloc(s, section, RL_REL, 4, addr);
|
||||
} else if (wrt == macho_gotpcrel_sect) {
|
||||
if (s->data->datalen > 1) {
|
||||
/* Retrieve instruction opcode */
|
||||
saa_fread(s->data, s->data->datalen-2, &gotload, 1);
|
||||
} else {
|
||||
gotload = 0;
|
||||
}
|
||||
if (gotload == 0x8B) {
|
||||
/* Check for MOVQ Opcode -> X86_64_RELOC_GOT_LOAD */
|
||||
addr -= add_reloc(s, section, RL_GOTLOAD, 4, addr);
|
||||
} else {
|
||||
/* X86_64_RELOC_GOT */
|
||||
addr -= add_reloc(s, section, RL_GOT, 4, addr);
|
||||
}
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" this use of WRT");
|
||||
wrt = NO_SEG; /* we can at least _try_ to continue */
|
||||
}
|
||||
|
||||
WRITELONG(p, addr);
|
||||
sect_write(s, mydata, 4L);
|
||||
sect_write(s, mydata, 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
nasm_error(ERR_PANIC, "unknown output type?");
|
||||
nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -796,7 +831,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
|
||||
/* get the in-file index of the section the symbol was defined in */
|
||||
sym->sect = get_section_fileindex_by_index(section);
|
||||
|
||||
|
||||
/* track the initially allocated symbol number for use in future fix-ups */
|
||||
sym->initial_snum = nsyms;
|
||||
|
||||
@ -1004,8 +1039,7 @@ static void macho_calculate_sizes (void)
|
||||
** get a pointer to the start of all the raw data */
|
||||
if (seg_nsects > 0) {
|
||||
++head_ncmds;
|
||||
head_sizeofcmds +=
|
||||
MACHO_SEGCMD64_SIZE + seg_nsects * MACHO_SECTCMD64_SIZE;
|
||||
head_sizeofcmds += fmt->segcmd_size + seg_nsects * fmt->sectcmd_size;
|
||||
}
|
||||
|
||||
if (nsyms > 0) {
|
||||
@ -1024,49 +1058,48 @@ static void macho_calculate_sizes (void)
|
||||
|
||||
static void macho_write_header (void)
|
||||
{
|
||||
fwriteint32_t(MH_MAGIC_64, ofile); /* magic */
|
||||
fwriteint32_t(CPU_TYPE_X86_64, ofile); /* CPU type */
|
||||
fwriteint32_t(fmt->mh_magic, ofile); /* magic */
|
||||
fwriteint32_t(fmt->cpu_type, ofile); /* CPU type */
|
||||
fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
|
||||
fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
|
||||
fwriteint32_t(head_ncmds, ofile); /* number of load commands */
|
||||
fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
|
||||
fwriteint32_t(0, ofile); /* no flags */
|
||||
fwriteint32_t(0, ofile); /* reserved for future use */
|
||||
fwriteint32_t(0, ofile); /* no flags */
|
||||
fwritezero(fmt->header_size - 7*4, ofile); /* reserved fields */
|
||||
}
|
||||
|
||||
/* Write out the segment load command at offset. */
|
||||
|
||||
static uint32_t macho_write_segment (uint64_t offset)
|
||||
{
|
||||
uint64_t rel_base = alignint64_t (offset + seg_filesize);
|
||||
uint64_t rel_base = alignptr(offset + seg_filesize);
|
||||
uint32_t s_reloff = 0;
|
||||
struct section *s;
|
||||
|
||||
fwriteint32_t(LC_SEGMENT_64, ofile); /* cmd == LC_SEGMENT_64 */
|
||||
fwriteint32_t(fmt->lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
|
||||
|
||||
/* size of load command including section load commands */
|
||||
fwriteint32_t(MACHO_SEGCMD64_SIZE +
|
||||
seg_nsects * MACHO_SECTCMD64_SIZE,
|
||||
fwriteint32_t(fmt->segcmd_size + seg_nsects * fmt->sectcmd_size,
|
||||
ofile);
|
||||
|
||||
/* in an MH_OBJECT file all sections are in one unnamed (name
|
||||
** all zeros) segment */
|
||||
fwritezero(16, ofile);
|
||||
fwriteint64_t(0, ofile); /* in-memory offset */
|
||||
fwriteint64_t(seg_vmsize, ofile); /* in-memory size */
|
||||
fwriteint64_t(offset, ofile); /* in-file offset to data */
|
||||
fwriteint64_t(seg_filesize, ofile); /* in-file size */
|
||||
fwriteptr(0, ofile); /* in-memory offset */
|
||||
fwriteptr(seg_vmsize, ofile); /* in-memory size */
|
||||
fwriteptr(offset, ofile); /* in-file offset to data */
|
||||
fwriteptr(seg_filesize, ofile); /* in-file size */
|
||||
fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
|
||||
fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
|
||||
fwriteint32_t(seg_nsects, ofile); /* number of sections */
|
||||
fwriteint32_t(0, ofile); /* no flags */
|
||||
fwriteint32_t(0, ofile); /* no flags */
|
||||
|
||||
/* emit section headers */
|
||||
for (s = sects; s != NULL; s = s->next) {
|
||||
nasm_write(s->sectname, sizeof(s->sectname), ofile);
|
||||
nasm_write(s->segname, sizeof(s->segname), ofile);
|
||||
fwriteint64_t(s->addr, ofile);
|
||||
fwriteint64_t(s->size, ofile);
|
||||
fwriteptr(s->addr, ofile);
|
||||
fwriteptr(s->size, ofile);
|
||||
|
||||
/* dummy data for zerofill sections or proper values */
|
||||
if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
|
||||
@ -1076,33 +1109,29 @@ static uint32_t macho_write_segment (uint64_t offset)
|
||||
offset += s->size;
|
||||
/* Write out section alignment, as a power of two.
|
||||
e.g. 32-bit word alignment would be 2 (2^2 = 4). */
|
||||
if (s->align == -1)
|
||||
s->align = DEFAULT_SECTION_ALIGNMENT;
|
||||
fwriteint32_t(s->align, ofile);
|
||||
/* To be compatible with cctools as we emit
|
||||
a zero reloff if we have no relocations. */
|
||||
fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
|
||||
fwriteint32_t(s->nreloc, ofile);
|
||||
|
||||
s_reloff += s->nreloc * MACHO_RELINFO64_SIZE;
|
||||
s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
|
||||
} else {
|
||||
fwriteint32_t(0, ofile);
|
||||
fwriteint32_t(0, ofile); /* No alignment?! */
|
||||
fwriteint32_t(s->align, ofile);
|
||||
fwriteint32_t(0, ofile);
|
||||
fwriteint32_t(0, ofile);
|
||||
}
|
||||
|
||||
if (s->nreloc) {
|
||||
s->flags |= S_ATTR_LOC_RELOC;
|
||||
if (s->extreloc)
|
||||
s->flags |= S_ATTR_EXT_RELOC;
|
||||
}
|
||||
|
||||
if (s->nreloc) {
|
||||
s->flags |= S_ATTR_LOC_RELOC;
|
||||
if (s->extreloc)
|
||||
s->flags |= S_ATTR_EXT_RELOC;
|
||||
}
|
||||
|
||||
fwriteint32_t(s->flags, ofile); /* flags */
|
||||
fwriteint32_t(0, ofile); /* reserved */
|
||||
fwriteint32_t(0, ofile); /* reserved */
|
||||
|
||||
fwriteint32_t(0, ofile); /* align */
|
||||
fwriteptr(0, ofile); /* reserved */
|
||||
}
|
||||
|
||||
rel_padcnt = rel_base - offset;
|
||||
@ -1136,9 +1165,13 @@ static void macho_write_section (void)
|
||||
{
|
||||
struct section *s, *s2;
|
||||
struct reloc *r;
|
||||
uint8_t fi, *p, *q, blk[8];
|
||||
int32_t len;
|
||||
uint8_t fi, *p;
|
||||
int32_t len;
|
||||
int64_t l;
|
||||
union offset {
|
||||
uint64_t val;
|
||||
uint8_t buf[8];
|
||||
} blk;
|
||||
|
||||
for (s = sects; s != NULL; s = s->next) {
|
||||
if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
|
||||
@ -1150,31 +1183,26 @@ static void macho_write_section (void)
|
||||
* for more information. */
|
||||
saa_rewind(s->data);
|
||||
for (r = s->relocs; r != NULL; r = r->next) {
|
||||
len = (int32_t)r->length << 1;
|
||||
if(len > 4) len = 8;
|
||||
saa_fread(s->data, r->addr, blk, len);
|
||||
p = q = blk;
|
||||
l = *p++;
|
||||
len = (uint32_t)1 << r->length;
|
||||
if (len > 4) /* Can this ever be an issue?! */
|
||||
len = 8;
|
||||
blk.val = 0;
|
||||
saa_fread(s->data, r->addr, blk.buf, len);
|
||||
|
||||
/* get offset based on relocation type */
|
||||
if (r->length > 0) {
|
||||
l += ((int64_t)*p++) << 8;
|
||||
#ifdef WORDS_LITTLEENDIAN
|
||||
l = blk.val;
|
||||
#else
|
||||
l = blk.buf[0];
|
||||
l += ((int64_t)blk.buf[1]) << 8;
|
||||
l += ((int64_t)blk.buf[2]) << 16;
|
||||
l += ((int64_t)blk.buf[3]) << 24;
|
||||
l += ((int64_t)blk.buf[4]) << 32;
|
||||
l += ((int64_t)blk.buf[5]) << 40;
|
||||
l += ((int64_t)blk.buf[6]) << 48;
|
||||
l += ((int64_t)blk.buf[7]) << 56;
|
||||
#endif
|
||||
|
||||
if (r->length > 1) {
|
||||
l += ((int64_t)*p++) << 16;
|
||||
l += ((int64_t)*p++) << 24;
|
||||
}
|
||||
|
||||
if (r->length > 2) {
|
||||
l += ((int64_t)*p++) << 32;
|
||||
l += ((int64_t)*p++) << 40;
|
||||
l += ((int64_t)*p++) << 48;
|
||||
l += ((int64_t)*p++) << 56;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* If the relocation is internal add to the current section
|
||||
offset. Otherwise the only value we need is the symbol
|
||||
offset which we already have. The linker takes care
|
||||
@ -1191,16 +1219,9 @@ static void macho_write_section (void)
|
||||
}
|
||||
|
||||
/* write new offset back */
|
||||
if (r->length == 3)
|
||||
WRITEDLONG(q, l);
|
||||
else if (r->length == 2)
|
||||
WRITELONG(q, l);
|
||||
else if (r->length == 1)
|
||||
WRITESHORT(q, l);
|
||||
else
|
||||
*q++ = l & 0xFF;
|
||||
|
||||
saa_fwrite(s->data, r->addr, blk, len);
|
||||
p = blk.buf;
|
||||
WRITEDLONG(p, l);
|
||||
saa_fwrite(s->data, r->addr, blk.buf, len);
|
||||
}
|
||||
|
||||
/* dump the section data to file */
|
||||
@ -1208,7 +1229,7 @@ static void macho_write_section (void)
|
||||
saa_fpwrite(s->data, ofile);
|
||||
}
|
||||
|
||||
/* pad last section up to reloc entries on int64_t boundary */
|
||||
/* pad last section up to reloc entries on pointer boundary */
|
||||
fwritezero(rel_padcnt, ofile);
|
||||
|
||||
/* emit relocation entries */
|
||||
@ -1239,7 +1260,7 @@ static void macho_write_symtab (void)
|
||||
sym->value += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteint64_t(sym->value, ofile); /* value (i.e. offset) */
|
||||
fwriteptr(sym->value, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,7 +1278,7 @@ static void macho_write_symtab (void)
|
||||
sym->value += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteint64_t(sym->value, ofile); /* value (i.e. offset) */
|
||||
fwriteptr(sym->value, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
|
||||
for (i = 0; i < nundefsym; i++) {
|
||||
@ -1267,13 +1288,14 @@ static void macho_write_symtab (void)
|
||||
nasm_write(&sym->sect, 1, ofile); /* section */
|
||||
fwriteint16_t(sym->desc, ofile); /* description */
|
||||
|
||||
// Fix up the symbol value now that we know the final section sizes.
|
||||
/* Fix up the symbol value now that we know the final section
|
||||
sizes. */
|
||||
if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
|
||||
nasm_assert(sym->sect <= seg_nsects);
|
||||
sym->value += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteint64_t(sym->value, ofile); // value (i.e. offset)
|
||||
fwriteptr(sym->value, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
|
||||
}
|
||||
@ -1286,12 +1308,12 @@ static void macho_fixup_relocs (struct reloc *r)
|
||||
|
||||
while (r != NULL) {
|
||||
if (r->ext) {
|
||||
for (sym = syms; sym != NULL; sym = sym->next) {
|
||||
for (sym = syms; sym != NULL; sym = sym->next) {
|
||||
if (sym->initial_snum == r->snum) {
|
||||
r->snum = sym->snum;
|
||||
break;
|
||||
r->snum = sym->snum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
@ -1316,14 +1338,14 @@ static void macho_write (void)
|
||||
** uint32_t flags
|
||||
**
|
||||
** segment command
|
||||
** uint32_t command type == LC_SEGMENT_64
|
||||
** uint32_t command type == LC_SEGMENT[_64]
|
||||
** uint32_t size of load command
|
||||
** (including section load commands)
|
||||
** char[16] segment name
|
||||
** uint64_t in-memory offset
|
||||
** uint64_t in-memory size
|
||||
** uint64_t in-file offset to data area
|
||||
** uint64_t in-file size
|
||||
** pointer in-memory offset
|
||||
** pointer in-memory size
|
||||
** pointer in-file offset to data area
|
||||
** pointer in-file size
|
||||
** (in-memory size excluding zerofill sections)
|
||||
** int maximum vm protection
|
||||
** int initial vm protection
|
||||
@ -1333,8 +1355,8 @@ static void macho_write (void)
|
||||
** section commands
|
||||
** char[16] section name
|
||||
** char[16] segment name
|
||||
** uint64_t in-memory offset
|
||||
** uint64_t in-memory size
|
||||
** pointer in-memory offset
|
||||
** pointer in-memory size
|
||||
** uint32_t in-file offset
|
||||
** uint32_t alignment
|
||||
** (irrelevant in MH_OBJECT)
|
||||
@ -1354,7 +1376,7 @@ static void macho_write (void)
|
||||
**
|
||||
** raw section data
|
||||
**
|
||||
** padding to int64_t boundary
|
||||
** padding to pointer boundary
|
||||
**
|
||||
** relocation data (struct reloc)
|
||||
** int32_t offset
|
||||
@ -1370,7 +1392,7 @@ static void macho_write (void)
|
||||
** [type == extern])
|
||||
** int16_t description
|
||||
** (for stab debugging format)
|
||||
** uint64_t value (i.e. file offset) of symbol or stab offset
|
||||
** pointer value (i.e. file offset) of symbol or stab offset
|
||||
**
|
||||
** string table data
|
||||
** list of null-terminated strings
|
||||
@ -1379,7 +1401,7 @@ static void macho_write (void)
|
||||
/* Emit the Mach-O header. */
|
||||
macho_write_header();
|
||||
|
||||
offset = MACHO_HEADER64_SIZE + head_sizeofcmds;
|
||||
offset = fmt->header_size + head_sizeofcmds;
|
||||
|
||||
/* emit the segment load command */
|
||||
if (seg_nsects > 0)
|
||||
@ -1394,7 +1416,7 @@ static void macho_write (void)
|
||||
fwriteint32_t(offset, ofile); /* symbol table offset */
|
||||
fwriteint32_t(nsyms, ofile); /* number of symbol
|
||||
** table entries */
|
||||
offset += nsyms * MACHO_NLIST64_SIZE;
|
||||
offset += nsyms * fmt->nlist_size;
|
||||
fwriteint32_t(offset, ofile); /* string table offset */
|
||||
fwriteint32_t(strslen, ofile); /* string table size */
|
||||
}
|
||||
@ -1407,7 +1429,7 @@ static void macho_write (void)
|
||||
if (nsyms > 0)
|
||||
macho_write_symtab ();
|
||||
|
||||
/* we don't need to pad here since MACHO_NLIST64_SIZE == 16 */
|
||||
/* we don't need to pad here, we are already aligned */
|
||||
|
||||
/* emit string table */
|
||||
saa_fpwrite(strs, ofile);
|
||||
@ -1489,15 +1511,24 @@ static void debug_section_relocs (struct section *s)
|
||||
}
|
||||
}
|
||||
|
||||
struct ofmt of_macho64 = {
|
||||
"NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
|
||||
#ifdef OF_MACHO32
|
||||
static void macho32_init(void)
|
||||
{
|
||||
fmt = &macho32_fmt;
|
||||
macho_init();
|
||||
|
||||
macho_gotpcrel_sect = NO_SEG;
|
||||
}
|
||||
|
||||
struct ofmt of_macho32 = {
|
||||
"NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
|
||||
"macho64",
|
||||
0,
|
||||
64,
|
||||
32,
|
||||
null_debug_arr,
|
||||
&null_debug_form,
|
||||
macho_stdmac,
|
||||
macho_init,
|
||||
macho32_init,
|
||||
null_setinfo,
|
||||
macho_output,
|
||||
macho_symdef,
|
||||
@ -1508,6 +1539,40 @@ struct ofmt of_macho64 = {
|
||||
macho_filename,
|
||||
macho_cleanup
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef OF_MACHO64
|
||||
static void macho64_init(void)
|
||||
{
|
||||
fmt = &macho64_fmt;
|
||||
macho_init();
|
||||
|
||||
/* add special symbol for ..gotpcrel */
|
||||
macho_gotpcrel_sect = seg_alloc();
|
||||
macho_gotpcrel_sect++;
|
||||
define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
|
||||
}
|
||||
|
||||
struct ofmt of_macho64 = {
|
||||
"NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
|
||||
"macho64",
|
||||
0,
|
||||
64,
|
||||
null_debug_arr,
|
||||
&null_debug_form,
|
||||
macho_stdmac,
|
||||
macho64_init,
|
||||
null_setinfo,
|
||||
macho_output,
|
||||
macho_symdef,
|
||||
macho_section,
|
||||
macho_sectalign,
|
||||
macho_segbase,
|
||||
null_directive,
|
||||
macho_filename,
|
||||
macho_cleanup
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
1330
output/outmac32.c
1330
output/outmac32.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user