summaryrefslogtreecommitdiff
path: root/devel/nasm
diff options
context:
space:
mode:
authorjmmv <jmmv@pkgsrc.org>2007-01-06 15:11:57 +0000
committerjmmv <jmmv@pkgsrc.org>2007-01-06 15:11:57 +0000
commit5080918643400cb79975352a1bd61f0d95db5667 (patch)
tree759f19eae512976cc9f8b6a68280aca2c66f56ad /devel/nasm
parentd0807088b2f6c517a2d79bb3e42aace325e836f5 (diff)
downloadpkgsrc-5080918643400cb79975352a1bd61f0d95db5667.tar.gz
Add support to generate Mach-O objects (for Intel Macs). Code taken from
the CVS repository, so it will be in the next public release of nasm. Bump PKGREVISION to 3.
Diffstat (limited to 'devel/nasm')
-rw-r--r--devel/nasm/Makefile4
-rw-r--r--devel/nasm/distinfo6
-rw-r--r--devel/nasm/patches/patch-aa13
-rw-r--r--devel/nasm/patches/patch-ad1322
-rw-r--r--devel/nasm/patches/patch-ae61
5 files changed, 1400 insertions, 6 deletions
diff --git a/devel/nasm/Makefile b/devel/nasm/Makefile
index bc8b7282510..3e322bcdf15 100644
--- a/devel/nasm/Makefile
+++ b/devel/nasm/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.30 2006/11/02 18:17:22 joerg Exp $
+# $NetBSD: Makefile,v 1.31 2007/01/06 15:11:57 jmmv Exp $
DISTNAME= nasm-0.98.39
-PKGREVISION= 2
+PKGREVISION= 3
CATEGORIES= devel lang
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=nasm/}
EXTRACT_SUFX= .tar.bz2
diff --git a/devel/nasm/distinfo b/devel/nasm/distinfo
index ceccdecd774..1829fa585c3 100644
--- a/devel/nasm/distinfo
+++ b/devel/nasm/distinfo
@@ -1,8 +1,10 @@
-$NetBSD: distinfo,v 1.8 2005/05/05 20:12:46 adrianp Exp $
+$NetBSD: distinfo,v 1.9 2007/01/06 15:11:58 jmmv Exp $
SHA1 (nasm-0.98.39.tar.bz2) = 73d64812bb95774355f737c0fb0271382d23db67
RMD160 (nasm-0.98.39.tar.bz2) = b5587b1b81f58cef3a50e438e8efb365945df587
Size (nasm-0.98.39.tar.bz2) = 543976 bytes
-SHA1 (patch-aa) = b0a4c91d7448ba630bfb482ab8f97e98753169cb
+SHA1 (patch-aa) = 27409c3b71634dc5c3aa02b3cae49ebad2db6579
SHA1 (patch-ab) = bbe1d7219dd2e5ade8f97a4f3070bc87d3a7d4b5
SHA1 (patch-ac) = 7ae622ab78b1cf30ca027d652476d7d48deae182
+SHA1 (patch-ad) = 1f572247b2b6b46b4b8c4c2c055010459def496b
+SHA1 (patch-ae) = f6029c8574c4e11d59d161819a379e9f687bc346
diff --git a/devel/nasm/patches/patch-aa b/devel/nasm/patches/patch-aa
index 60d60833200..7a7e026813d 100644
--- a/devel/nasm/patches/patch-aa
+++ b/devel/nasm/patches/patch-aa
@@ -1,6 +1,6 @@
-$NetBSD: patch-aa,v 1.1 2003/09/17 16:40:14 jmmv Exp $
+$NetBSD: patch-aa,v 1.2 2007/01/06 15:11:58 jmmv Exp $
---- Makefile.in.orig Fri Aug 29 21:56:40 2003
+--- Makefile.in.orig 2005-01-15 00:05:31.000000000 +0100
+++ Makefile.in
@@ -18,7 +18,7 @@ CC = @CC@
CFLAGS = @CFLAGS@ @GCCFLAGS@ @DEFS@ -I$(srcdir) -I.
@@ -11,3 +11,12 @@ $NetBSD: patch-aa,v 1.1 2003/09/17 16:40:14 jmmv Exp $
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
+@@ -51,7 +51,7 @@ NASM = nasm.$(O) nasmlib.$(O) float.$(O)
+ labels.$(O) parser.$(O) outform.$(O) output/outbin.$(O) \
+ output/outaout.$(O) output/outcoff.$(O) output/outelf.$(O) \
+ output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
+- output/outdbg.$(O) output/outieee.$(O) \
++ output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
+ preproc.$(O) listing.$(O) eval.$(O)
+
+ NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) insnsd.$(O)
diff --git a/devel/nasm/patches/patch-ad b/devel/nasm/patches/patch-ad
new file mode 100644
index 00000000000..c1e25e516da
--- /dev/null
+++ b/devel/nasm/patches/patch-ad
@@ -0,0 +1,1322 @@
+--- /dev/null 2007-01-06 13:50:40.000000000 +0100
++++ output/outmacho.c 2006-02-02 22:50:47.000000000 +0100
+@@ -0,0 +1,1319 @@
++/* outmacho.c output routines for the Netwide Assembler to produce
++ * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
++ *
++ * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
++ * Julian Hall. All rights reserved. The software is
++ * redistributable under the licence given in the file "Licence"
++ * distributed in the NASM archive.
++ */
++
++/* Most of this file is, like Mach-O itself, based on a.out. For more
++ * guidelines see outaout.c. */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++
++#include "nasm.h"
++#include "nasmlib.h"
++#include "outform.h"
++
++#if defined(OF_MACHO)
++
++/* Mach-O in-file header structure sizes */
++#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)
++
++/* Mach-O file header values */
++#define MH_MAGIC (0xfeedface)
++#define CPU_TYPE_I386 (7) /* x86 platform */
++#define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */
++#define MH_OBJECT (0x1) /* object file */
++
++#define LC_SEGMENT (0x1) /* segment load command */
++#define LC_SYMTAB (0x2) /* symbol table load command */
++
++#define VM_PROT_NONE (0x00)
++#define VM_PROT_READ (0x01)
++#define VM_PROT_WRITE (0x02)
++#define VM_PROT_EXECUTE (0x04)
++
++#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 section {
++ /* nasm internal data */
++ struct section *next;
++ struct SAA *data;
++ long index;
++ struct reloc *relocs;
++ int align;
++
++ /* data that goes into the file */
++ char sectname[16]; /* what this section is called */
++ char segname[16]; /* segment this section will be in */
++ unsigned long size; /* in-memory and -file size */
++ unsigned long nreloc; /* relocation entry count */
++ unsigned long flags; /* type and attributes (masked) */
++};
++
++#define SECTION_TYPE 0x000000ff /* section type mask */
++
++#define S_REGULAR (0x0) /* standard section */
++#define S_ZEROFILL (0x1) /* zerofill, in-memory only */
++
++#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
++#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
++ machine instructions */
++#define S_ATTR_EXT_RELOC 0x00000200 /* section has external
++ relocation entries */
++#define S_ATTR_LOC_RELOC 0x00000100 /* section has local
++ relocation entries */
++
++
++static struct sectmap {
++ const char *nasmsect;
++ const char *segname;
++ const char *sectname;
++ const long flags;
++} sectmap[] = { {
++".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS}, {
++".data", "__DATA", "__data", S_REGULAR}, {
++".rodata", "__DATA", "__const", S_REGULAR}, {
++".bss", "__DATA", "__bss", S_ZEROFILL}, {
++NULL, NULL, NULL}};
++
++struct reloc {
++ /* nasm internal data */
++ struct reloc *next;
++
++ /* data that goes into the file */
++ long addr; /* op's offset in section */
++ unsigned int snum:24, /* contains symbol index if
++ ** ext otherwise in-file
++ ** section number */
++ pcrel:1, /* relative relocation */
++ length:2, /* 0=byte, 1=word, 2=long */
++ ext:1, /* external symbol referenced */
++ type:4; /* reloc type, 0 for us */
++};
++
++#define R_ABS 0 /* absolute relocation */
++#define R_SCATTERED 0x80000000 /* reloc entry is scattered if
++ ** highest bit == 1 */
++
++struct symbol {
++ /* nasm internal data */
++ struct symbol *next; /* next symbol in the list */
++ char *name; /* name of this symbol */
++ long initial_snum; /* symbol number used above in
++ reloc */
++ long snum; /* true snum for reloc */
++
++ /* data that goes into the file */
++ long strx; /* string table index */
++ unsigned char type; /* symbol type */
++ unsigned char sect; /* NO_SECT or section number */
++ short desc; /* for stab debugging, 0 for us */
++ unsigned long value; /* offset of symbol in section */
++};
++
++/* symbol type bits */
++#define N_EXT 0x01 /* global or external symbol */
++
++#define N_UNDF 0x0 /* undefined symbol | n_sect == */
++#define N_ABS 0x2 /* absolute symbol | NO_SECT */
++#define N_SECT 0xe /* defined symbol, n_sect holds
++ ** section number */
++
++#define N_TYPE 0x0e /* type bit mask */
++
++#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
++
++/* special section number values */
++#define NO_SECT 0 /* no section, invalid */
++#define MAX_SECT 255 /* maximum number of sections */
++
++static struct section *sects, **sectstail;
++static struct symbol *syms, **symstail;
++static unsigned long nsyms;
++
++/* These variables are set by macho_layout_symbols() to organize
++ the symbol table and string table in order the dynamic linker
++ expects. They are then used in macho_write() to put out the
++ symbols and strings in that order.
++
++ The order of the symbol table is:
++ local symbols
++ defined external symbols (sorted by name)
++ undefined external symbols (sorted by name)
++
++ The order of the string table is:
++ strings for external symbols
++ strings for local symbols
++ */
++static unsigned long ilocalsym = 0;
++static unsigned long iextdefsym = 0;
++static unsigned long iundefsym = 0;
++static unsigned long nlocalsym;
++static unsigned long nextdefsym;
++static unsigned long nundefsym;
++static struct symbol **extdefsyms = NULL;
++static struct symbol **undefsyms = NULL;
++
++static struct RAA *extsyms;
++static struct SAA *strs;
++static unsigned long strslen;
++
++static FILE *machofp;
++static efunc error;
++static evalfunc evaluate;
++
++extern struct ofmt of_macho;
++
++/* Global file information. This should be cleaned up into either
++ a structure or as function arguments. */
++unsigned long head_ncmds = 0;
++unsigned long head_sizeofcmds = 0;
++unsigned long seg_filesize = 0;
++unsigned long seg_vmsize = 0;
++unsigned long seg_nsects = 0;
++unsigned long rel_padcnt = 0;
++
++
++#define xstrncpy(xdst, xsrc) \
++ memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
++ strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
++ xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
++
++#define align(x, y) \
++ (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */
++
++#define alignlong(x) \
++ align(x, sizeof(long)) /* align x to long boundary */
++
++static void debug_reloc (struct reloc *);
++static void debug_section_relocs (struct section *) __attribute__ ((unused));
++
++static int exact_log2 (unsigned long align) {
++ if (align != (align & -align)) {
++ return -1;
++ } else {
++#ifdef __GNUC__
++ return (align ? __builtin_ctzl (align) : 0);
++#else
++ unsigned long result = 0;
++
++ while (align >>= 1) {
++ ++result;
++ }
++
++ return result;
++#endif
++ }
++}
++
++static struct section *get_section_by_name(const char *segname,
++ const char *sectname)
++{
++ struct section *s;
++
++ for (s = sects; s != NULL; s = s->next)
++ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
++ break;
++
++ return s;
++}
++
++static struct section *get_section_by_index(const long index)
++{
++ struct section *s;
++
++ for (s = sects; s != NULL; s = s->next)
++ if (index == s->index)
++ break;
++
++ return s;
++}
++
++static long get_section_index_by_name(const char *segname,
++ const char *sectname)
++{
++ struct section *s;
++
++ for (s = sects; s != NULL; s = s->next)
++ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
++ return s->index;
++
++ return -1;
++}
++
++static char *get_section_name_by_index(const long index)
++{
++ struct section *s;
++
++ for (s = sects; s != NULL; s = s->next)
++ if (index == s->index)
++ return s->sectname;
++
++ return NULL;
++}
++
++static unsigned char get_section_fileindex_by_index(const long index)
++{
++ struct section *s;
++ unsigned char i = 1;
++
++ for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
++ if (index == s->index)
++ return i;
++
++ if (i == MAX_SECT)
++ error(ERR_WARNING,
++ "too many sections (>255) - clipped by fileindex");
++
++ return NO_SECT;
++}
++
++static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
++ evalfunc eval)
++{
++ char zero = 0;
++
++ machofp = fp;
++ error = errfunc;
++ evaluate = eval;
++
++ (void)ldef; /* placate optimisers */
++
++ sects = NULL;
++ sectstail = &sects;
++
++ syms = NULL;
++ symstail = &syms;
++ nsyms = 0;
++ nlocalsym = 0;
++ nextdefsym = 0;
++ nundefsym = 0;
++
++ extsyms = raa_init();
++ strs = saa_init(1L);
++
++ /* string table starts with a zero byte - don't ask why */
++ saa_wbytes(strs, &zero, sizeof(char));
++ strslen = 1;
++}
++
++static int macho_setinfo(enum geninfo type, char **val)
++{
++ return 0;
++}
++
++static void sect_write(struct section *sect,
++ const unsigned char *data, unsigned long len)
++{
++ saa_wbytes(sect->data, data, len);
++ sect->size += len;
++}
++
++static void add_reloc(struct section *sect, long section,
++ int pcrel, int bytes)
++{
++ struct reloc *r;
++ long fi;
++
++ /* 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 */
++ r = nasm_malloc(sizeof(struct reloc));
++ r->next = sect->relocs;
++ sect->relocs = r;
++
++ /* the current end of the section will be the symbol's address for
++ ** now, might have to be fixed by macho_fixup_relocs() later on. make
++ ** sure we don't make the symbol scattered by setting the highest
++ ** bit by accident */
++ r->addr = sect->size & ~R_SCATTERED;
++ r->ext = 0;
++ r->pcrel = pcrel;
++
++ /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */
++ r->length = bytes >> 1;
++
++ /* vanilla relocation (GENERIC_RELOC_VANILLA) */
++ r->type = 0;
++
++ if (section == NO_SEG) {
++ /* absolute local symbol if no section index given */
++ r->snum = R_ABS;
++ } else {
++ fi = get_section_fileindex_by_index(section);
++
++ if (fi == NO_SECT) {
++ /* external symbol if no section with that index known,
++ ** symbol number was saved in macho_symdef() */
++ r->snum = raa_read(extsyms, section);
++ r->ext = 1;
++ } else {
++ /* local symbol in section fi */
++ r->snum = fi;
++ }
++ }
++
++ ++sect->nreloc;
++}
++
++static void macho_output(long secto, const void *data, unsigned long type,
++ long section, long wrt)
++{
++ struct section *s, *sbss;
++ long realbytes = type & OUT_SIZMASK;
++ long addr;
++ unsigned char mydata[4], *p;
++
++ type &= OUT_TYPMASK;
++
++ if (wrt != NO_SEG) {
++ wrt = NO_SEG;
++ error(ERR_NONFATAL, "WRT not supported by Mach-O output format");
++ /* continue to do _something_ */
++ }
++
++ if (secto == NO_SEG) {
++ if (type != OUT_RESERVE)
++ error(ERR_NONFATAL, "attempt to assemble code in "
++ "[ABSOLUTE] space");
++
++ return;
++ }
++
++ s = get_section_by_index(secto);
++
++ if (s == NULL) {
++ error(ERR_WARNING, "attempt to assemble code in"
++ " section %d: defaulting to `.text'", secto);
++ s = get_section_by_name("__TEXT", "__text");
++
++ /* should never happen */
++ if (s == NULL)
++ error(ERR_PANIC, "text section not found");
++ }
++
++ sbss = get_section_by_name("__DATA", "__bss");
++
++ if (s == sbss && type != OUT_RESERVE) {
++ error(ERR_WARNING, "attempt to initialise memory in the"
++ " BSS section: ignored");
++
++ switch (type) {
++ case OUT_REL2ADR:
++ realbytes = 2;
++ break;
++
++ case OUT_REL4ADR:
++ realbytes = 4;
++ break;
++
++ default:
++ break;
++ }
++
++ s->size += realbytes;
++ return;
++ }
++
++ switch (type) {
++ case OUT_RESERVE:
++ if (s != sbss) {
++ error(ERR_WARNING, "uninitialised space declared in"
++ " %s section: zeroing",
++ get_section_name_by_index(secto));
++
++ sect_write(s, NULL, realbytes);
++ } else
++ s->size += realbytes;
++
++ break;
++
++ case OUT_RAWDATA:
++ if (section != NO_SEG)
++ error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
++
++ sect_write(s, data, realbytes);
++ break;
++
++ case OUT_ADDRESS:
++ addr = *(long *)data;
++
++ if (section != NO_SEG) {
++ if (section % 2) {
++ error(ERR_NONFATAL, "Mach-O format does not support"
++ " section base references");
++ } else
++ add_reloc(s, section, 0, realbytes);
++ }
++
++ p = mydata;
++
++ if (realbytes == 2)
++ WRITESHORT(p, addr);
++ else
++ WRITELONG(p, addr);
++
++ sect_write(s, mydata, realbytes);
++ break;
++
++ case OUT_REL2ADR:
++ if (section == secto)
++ error(ERR_PANIC, "intra-section OUT_REL2ADR");
++
++ if (section != NO_SEG && section % 2) {
++ error(ERR_NONFATAL, "Mach-O format does not support"
++ " section base references");
++ } else
++ add_reloc(s, section, 1, 2);
++
++ p = mydata;
++ WRITESHORT(p, *(long *)data - (realbytes + s->size));
++ sect_write(s, mydata, 2L);
++ break;
++
++ case OUT_REL4ADR:
++ if (section == secto)
++ error(ERR_PANIC, "intra-section OUT_REL4ADR");
++
++ if (section != NO_SEG && section % 2) {
++ error(ERR_NONFATAL, "Mach-O format does not support"
++ " section base references");
++ } else
++ add_reloc(s, section, 1, 4);
++
++ p = mydata;
++ WRITELONG(p, *(long *)data - (realbytes + s->size));
++ sect_write(s, mydata, 4L);
++ break;
++
++ default:
++ error(ERR_PANIC, "unknown output type?");
++ break;
++ }
++}
++
++static long macho_section(char *name, int pass, int *bits)
++{
++ long index, originalIndex;
++ char *sectionAttributes;
++ struct sectmap *sm;
++ struct section *s;
++
++ /* Default to 32 bits. */
++ if (!name) {
++ *bits = 32;
++ name = ".text";
++ sectionAttributes = NULL;
++ } else {
++ sectionAttributes = name;
++ name = strsep(&sectionAttributes, " \t");
++ }
++
++ for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
++ /* make lookup into section name translation table */
++ if (!strcmp(name, sm->nasmsect)) {
++ char *currentAttribute;
++
++ /* try to find section with that name */
++ originalIndex = index = get_section_index_by_name(sm->segname,
++ sm->sectname);
++
++ /* create it if it doesn't exist yet */
++ if (index == -1) {
++ s = *sectstail = nasm_malloc(sizeof(struct section));
++ s->next = NULL;
++ sectstail = &s->next;
++
++ s->data = saa_init(1L);
++ s->index = seg_alloc();
++ s->relocs = NULL;
++ s->align = DEFAULT_SECTION_ALIGNMENT;
++
++ xstrncpy(s->segname, sm->segname);
++ xstrncpy(s->sectname, sm->sectname);
++ s->size = 0;
++ s->nreloc = 0;
++ s->flags = sm->flags;
++
++ index = s->index;
++ } else {
++ s = get_section_by_index(index);
++ }
++
++ while ((NULL != sectionAttributes)
++ && (currentAttribute = strsep(&sectionAttributes, " \t"))) {
++ if (0 != *currentAttribute) {
++ if (0 == strncasecmp("align=", currentAttribute, 6)) {
++ char *end;
++ int newAlignment, value;
++
++ value = strtoul(currentAttribute + 6, &end, 0);
++ newAlignment = exact_log2(value);
++
++ if (0 != *end) {
++ error(ERR_PANIC,
++ "unknown or missing alignment value \"%s\" "
++ "specified for section \"%s\"",
++ currentAttribute + 6,
++ name);
++ return NO_SEG;
++ } else if (0 > newAlignment) {
++ error(ERR_PANIC,
++ "alignment of %d (for section \"%s\") is not "
++ "a power of two",
++ value,
++ name);
++ return NO_SEG;
++ }
++
++ if ((-1 != originalIndex)
++ && (s->align != newAlignment)) {
++ error(ERR_PANIC,
++ "section \"%s\" has already been specified "
++ "with alignment %d, conflicts with new "
++ "alignment of %d",
++ name,
++ (1 << s->align),
++ value);
++ return NO_SEG;
++ }
++
++ s->align = newAlignment;
++ } else if (0 == strcasecmp("data", currentAttribute)) {
++ /* Do nothing; 'data' is implicit */
++ } else {
++ error(ERR_PANIC,
++ "unknown section attribute %s for section %s",
++ currentAttribute,
++ name);
++ return NO_SEG;
++ }
++ }
++ }
++
++ return index;
++ }
++ }
++
++ error(ERR_PANIC, "invalid section name %s", name);
++ return NO_SEG;
++}
++
++static void macho_symdef(char *name, long section, long offset,
++ int is_global, char *special)
++{
++ struct symbol *sym;
++
++ if (special) {
++ error(ERR_NONFATAL, "The Mach-O output format does "
++ "not support any special symbol types");
++ return;
++ }
++
++ if (is_global == 3) {
++ error(ERR_NONFATAL, "The Mach-O format does not "
++ "(yet) support forward reference fixups.");
++ return;
++ }
++
++ sym = *symstail = nasm_malloc(sizeof(struct symbol));
++ sym->next = NULL;
++ symstail = &sym->next;
++
++ sym->name = name;
++ sym->strx = strslen;
++ sym->type = 0;
++ sym->desc = 0;
++ sym->value = offset;
++ sym->initial_snum = -1;
++
++ /* external and common symbols get N_EXT */
++ if (is_global != 0)
++ sym->type |= N_EXT;
++
++ if (section == NO_SEG) {
++ /* symbols in no section get absolute */
++ sym->type |= N_ABS;
++ sym->sect = NO_SECT;
++ } else {
++ sym->type |= N_SECT;
++
++ /* get the in-file index of the section the symbol was defined in */
++ sym->sect = get_section_fileindex_by_index(section);
++
++ if (sym->sect == NO_SECT) {
++ /* remember symbol number of references to external
++ ** symbols, this works because every external symbol gets
++ ** its own section number allocated internally by nasm and
++ ** can so be used as a key */
++ extsyms = raa_write(extsyms, section, nsyms);
++ sym->initial_snum = nsyms;
++
++ switch (is_global) {
++ case 1:
++ case 2:
++ /* there isn't actually a difference between global
++ ** and common symbols, both even have their size in
++ ** sym->value */
++ sym->type = N_EXT;
++ break;
++
++ default:
++ /* give an error on unfound section if it's not an
++ ** external or common symbol (assemble_file() does a
++ ** seg_alloc() on every call for them) */
++ error(ERR_PANIC, "in-file index for section %d not found",
++ section);
++ }
++ }
++ }
++
++ ++nsyms;
++}
++
++static long macho_segbase(long section)
++{
++ return section;
++}
++
++static int macho_directive(char *directive, char *value, int pass)
++{
++ return 0;
++}
++
++static void macho_filename(char *inname, char *outname, efunc error)
++{
++ standard_extension(inname, outname, ".o", error);
++}
++
++static const char *macho_stdmac[] = {
++ "%define __SECT__ [section .text]",
++ "%macro __NASM_CDecl__ 1",
++ "%endmacro",
++ NULL
++};
++
++/* Comparison function for qsort symbol layout. */
++static int layout_compare (const struct symbol **s1,
++ const struct symbol **s2)
++{
++ return (strcmp ((*s1)->name, (*s2)->name));
++}
++
++/* The native assembler does a few things in a similar function
++
++ * Remove temporary labels
++ * Sort symbols according to local, external, undefined (by name)
++ * Order the string table
++
++ We do not remove temporary labels right now.
++
++ numsyms is the total number of symbols we have. strtabsize is the
++ number entries in the string table. */
++
++static void macho_layout_symbols (unsigned long *numsyms,
++ unsigned long *strtabsize)
++{
++ struct symbol *sym, **symp;
++ unsigned long i,j;
++
++ *numsyms = 0;
++ *strtabsize = sizeof (char);
++
++ symp = &syms;
++
++ while ((sym = *symp)) {
++ /* Undefined symbols are now external. */
++ if (sym->type == N_UNDF)
++ sym->type |= N_EXT;
++
++ if ((sym->type & N_EXT) == 0) {
++ sym->snum = *numsyms;
++ *numsyms = *numsyms + 1;
++ nlocalsym++;
++ }
++ else {
++ if ((sym->type & N_TYPE) != N_UNDF)
++ nextdefsym++;
++ else
++ nundefsym++;
++
++ /* If we handle debug info we'll want
++ to check for it here instead of just
++ adding the symbol to the string table. */
++ sym->strx = *strtabsize;
++ saa_wbytes (strs, sym->name, (long)(strlen(sym->name) + 1));
++ *strtabsize += strlen(sym->name) + 1;
++ }
++ symp = &(sym->next);
++ }
++
++ /* Next, sort the symbols. Most of this code is a direct translation from
++ the Apple cctools symbol layout. We need to keep compatibility with that. */
++ /* Set the indexes for symbol groups into the symbol table */
++ ilocalsym = 0;
++ iextdefsym = nlocalsym;
++ iundefsym = nlocalsym + nextdefsym;
++
++ /* allocate arrays for sorting externals by name */
++ extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
++ undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
++
++ i = 0;
++ j = 0;
++
++ symp = &syms;
++
++ while ((sym = *symp)) {
++
++ if((sym->type & N_EXT) == 0) {
++ sym->strx = *strtabsize;
++ saa_wbytes (strs, sym->name, (long)(strlen (sym->name) + 1));
++ *strtabsize += strlen(sym->name) + 1;
++ }
++ else {
++ if((sym->type & N_TYPE) != N_UNDF)
++ extdefsyms[i++] = sym;
++ else
++ undefsyms[j++] = sym;
++ }
++ symp = &(sym->next);
++ }
++
++ qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
++ (int (*)(const void *, const void *))layout_compare);
++ qsort(undefsyms, nundefsym, sizeof(struct symbol *),
++ (int (*)(const void *, const void *))layout_compare);
++
++ for(i = 0; i < nextdefsym; i++) {
++ extdefsyms[i]->snum = *numsyms;
++ *numsyms += 1;
++ }
++ for(j = 0; j < nundefsym; j++) {
++ undefsyms[j]->snum = *numsyms;
++ *numsyms += 1;
++ }
++}
++
++/* Calculate some values we'll need for writing later. */
++
++static void macho_calculate_sizes (void)
++{
++ struct section *s;
++
++ /* count sections and calculate in-memory and in-file offsets */
++ for (s = sects; s != NULL; s = s->next) {
++ /* zerofill sections aren't actually written to the file */
++ if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
++ seg_filesize += s->size;
++
++ seg_vmsize += s->size;
++ ++seg_nsects;
++ }
++
++ /* calculate size of all headers, load commands and sections to
++ ** get a pointer to the start of all the raw data */
++ if (seg_nsects > 0) {
++ ++head_ncmds;
++ head_sizeofcmds +=
++ MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE;
++ }
++
++ if (nsyms > 0) {
++ ++head_ncmds;
++ head_sizeofcmds += MACHO_SYMCMD_SIZE;
++ }
++}
++
++/* Write out the header information for the file. */
++
++static void macho_write_header (void)
++{
++ fwritelong(MH_MAGIC, machofp); /* magic */
++ fwritelong(CPU_TYPE_I386, machofp); /* CPU type */
++ fwritelong(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */
++ fwritelong(MH_OBJECT, machofp); /* Mach-O file type */
++ fwritelong(head_ncmds, machofp); /* number of load commands */
++ fwritelong(head_sizeofcmds, machofp); /* size of load commands */
++ fwritelong(0, machofp); /* no flags */
++}
++
++/* Write out the segment load command at offset. */
++
++static unsigned long macho_write_segment (unsigned long offset)
++{
++ unsigned long s_addr = 0;
++ unsigned long rel_base = alignlong (offset + seg_filesize);
++ unsigned long s_reloff = 0;
++ struct section *s;
++
++ fwritelong(LC_SEGMENT, machofp); /* cmd == LC_SEGMENT */
++
++ /* size of load command including section load commands */
++ fwritelong(MACHO_SEGCMD_SIZE + seg_nsects *
++ MACHO_SECTCMD_SIZE, machofp);
++
++ /* in an MH_OBJECT file all sections are in one unnamed (name
++ ** all zeros) segment */
++ fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 1, machofp);
++ fwritelong(0, machofp); /* in-memory offset */
++ fwritelong(seg_vmsize, machofp); /* in-memory size */
++ fwritelong(offset, machofp); /* in-file offset to data */
++ fwritelong(seg_filesize, machofp); /* in-file size */
++ fwritelong(VM_PROT_DEFAULT, machofp); /* maximum vm protection */
++ fwritelong(VM_PROT_DEFAULT, machofp); /* initial vm protection */
++ fwritelong(seg_nsects, machofp); /* number of sections */
++ fwritelong(0, machofp); /* no flags */
++
++ /* emit section headers */
++ for (s = sects; s != NULL; s = s->next) {
++ fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
++ fwrite(s->segname, sizeof(s->segname), 1, machofp);
++ fwritelong(s_addr, machofp);
++ fwritelong(s->size, machofp);
++
++ /* dummy data for zerofill sections or proper values */
++ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
++ fwritelong(offset, machofp);
++ /* Write out section alignment, as a power of two.
++ e.g. 32-bit word alignment would be 2 (2^^2 = 4). */
++ fwritelong(s->align, machofp);
++ /* To be compatible with cctools as we emit
++ a zero reloff if we have no relocations. */
++ fwritelong(s->nreloc ? rel_base + s_reloff : 0, machofp);
++ fwritelong(s->nreloc, machofp);
++
++ offset += s->size;
++ s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
++ } else {
++ fwritelong(0, machofp);
++ fwritelong(0, machofp);
++ fwritelong(0, machofp);
++ fwritelong(0, machofp);
++ }
++
++ fwritelong(s->flags, machofp); /* flags */
++ fwritelong(0, machofp); /* reserved */
++ fwritelong(0, machofp); /* reserved */
++
++ s_addr += s->size;
++ }
++
++ rel_padcnt = rel_base - offset;
++ offset = rel_base + s_reloff;
++
++ return offset;
++}
++
++/* For a given chain of relocs r, write out the entire relocation
++ chain to the object file. */
++
++static void macho_write_relocs (struct reloc *r)
++{
++ while (r) {
++ unsigned long word2;
++
++ fwritelong(r->addr, machofp); /* reloc offset */
++
++ word2 = r->snum;
++ word2 |= r->pcrel << 24;
++ word2 |= r->length << 25;
++ word2 |= r->ext << 27;
++ word2 |= r->type << 28;
++ fwritelong(word2, machofp); /* reloc data */
++
++ r = r->next;
++ }
++}
++
++/* Write out the section data. */
++static void macho_write_section (void)
++{
++ struct section *s, *s2;
++ struct reloc *r;
++ char *rel_paddata = "\0\0\0";
++ unsigned char fi, *p, *q, blk[4];
++ long l;
++
++ for (s = sects; s != NULL; s = s->next) {
++ if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
++ continue;
++
++ /* no padding needs to be done to the sections */
++
++ /* Like a.out Mach-O references things in the data or bss
++ * sections by addresses which are actually relative to the
++ * start of the _text_ section, in the _file_. See outaout.c
++ * for more information. */
++ saa_rewind(s->data);
++ for (r = s->relocs; r != NULL; r = r->next) {
++ saa_fread(s->data, r->addr, blk, (long)r->length << 1);
++ p = q = blk;
++ l = *p++;
++
++ /* get offset based on relocation type */
++ if (r->length > 0) {
++ l += ((long)*p++) << 8;
++
++ if (r->length == 2) {
++ l += ((long)*p++) << 16;
++ l += ((long)*p++) << 24;
++ }
++ }
++
++ /* 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
++ of the rest of the address. */
++ if (!r->ext) {
++ /* add sizes of previous sections to current offset */
++ for (s2 = sects, fi = 1;
++ s2 != NULL && fi < r->snum; s2 = s2->next, fi++)
++ if ((s2->flags & SECTION_TYPE) != S_ZEROFILL)
++ l += s2->size;
++ }
++
++ /* write new offset back */
++ 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, (long)r->length << 1);
++ }
++
++ /* dump the section data to file */
++ saa_fpwrite(s->data, machofp);
++ }
++
++ /* pad last section up to reloc entries on long boundary */
++ fwrite(rel_paddata, rel_padcnt, 1, machofp);
++
++ /* emit relocation entries */
++ for (s = sects; s != NULL; s = s->next)
++ macho_write_relocs (s->relocs);
++}
++
++/* Write out the symbol table. We should already have sorted this
++ before now. */
++static void macho_write_symtab (void)
++{
++ struct symbol *sym;
++ struct section *s;
++ long fi;
++ long i;
++
++ /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
++
++ for (sym = syms; sym != NULL; sym = sym->next) {
++ if ((sym->type & N_EXT) == 0) {
++ fwritelong(sym->strx, machofp); /* string table entry number */
++ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
++ fwrite(&sym->sect, 1, 1, machofp); /* section */
++ fwriteshort(sym->desc, machofp); /* description */
++
++ /* Fix up the symbol value now that we know the final section
++ sizes. */
++ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
++ for (s = sects, fi = 1;
++ s != NULL && fi < sym->sect; s = s->next, ++fi)
++ sym->value += s->size;
++ }
++
++ fwritelong(sym->value, machofp); /* value (i.e. offset) */
++ }
++ }
++
++ for (i = 0; i < nextdefsym; i++) {
++ sym = extdefsyms[i];
++ fwritelong(sym->strx, machofp);
++ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
++ fwrite(&sym->sect, 1, 1, machofp); /* section */
++ fwriteshort(sym->desc, machofp); /* description */
++
++ /* Fix up the symbol value now that we know the final section
++ sizes. */
++ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
++ for (s = sects, fi = 1;
++ s != NULL && fi < sym->sect; s = s->next, ++fi)
++ sym->value += s->size;
++ }
++
++ fwritelong(sym->value, machofp); /* value (i.e. offset) */
++ }
++
++ for (i = 0; i < nundefsym; i++) {
++ sym = undefsyms[i];
++ fwritelong(sym->strx, machofp);
++ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
++ fwrite(&sym->sect, 1, 1, machofp); /* section */
++ fwriteshort(sym->desc, machofp); /* description */
++
++ /* Fix up the symbol value now that we know the final section
++ sizes. */
++ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
++ for (s = sects, fi = 1;
++ s != NULL && fi < sym->sect; s = s->next, ++fi)
++ sym->value += s->size;
++ }
++
++ fwritelong(sym->value, machofp); /* value (i.e. offset) */
++ }
++}
++
++/* Fixup the snum in the relocation entries, we should be
++ doing this only for externally undefined symbols. */
++static void macho_fixup_relocs (struct reloc *r)
++{
++ struct symbol *sym;
++ int i;
++
++ while (r != NULL) {
++ if (r->ext) {
++ for (i = 0; i < nundefsym; i++) {
++ sym = undefsyms[i];
++ if (sym->initial_snum == r->snum) {
++ r->snum = sym->snum;
++ }
++ }
++ }
++ r = r->next;
++ }
++}
++
++/* Write out the object file. */
++
++static void macho_write (void)
++{
++ unsigned long offset = 0;
++
++ /* mach-o object file structure:
++ **
++ ** mach header
++ ** ulong magic
++ ** int cpu type
++ ** int cpu subtype
++ ** ulong mach file type
++ ** ulong number of load commands
++ ** ulong size of all load commands
++ ** (includes section struct size of segment command)
++ ** ulong flags
++ **
++ ** segment command
++ ** ulong command type == LC_SEGMENT
++ ** ulong size of load command
++ ** (including section load commands)
++ ** char[16] segment name
++ ** ulong in-memory offset
++ ** ulong in-memory size
++ ** ulong in-file offset to data area
++ ** ulong in-file size
++ ** (in-memory size excluding zerofill sections)
++ ** int maximum vm protection
++ ** int initial vm protection
++ ** ulong number of sections
++ ** ulong flags
++ **
++ ** section commands
++ ** char[16] section name
++ ** char[16] segment name
++ ** ulong in-memory offset
++ ** ulong in-memory size
++ ** ulong in-file offset
++ ** ulong alignment
++ ** (irrelevant in MH_OBJECT)
++ ** ulong in-file offset of relocation entires
++ ** ulong number of relocations
++ ** ulong flags
++ ** ulong reserved
++ ** ulong reserved
++ **
++ ** symbol table command
++ ** ulong command type == LC_SYMTAB
++ ** ulong size of load command
++ ** ulong symbol table offset
++ ** ulong number of symbol table entries
++ ** ulong string table offset
++ ** ulong string table size
++ **
++ ** raw section data
++ **
++ ** padding to long boundary
++ **
++ ** relocation data (struct reloc)
++ ** long offset
++ ** uint data (symbolnum, pcrel, length, extern, type)
++ **
++ ** symbol table data (struct nlist)
++ ** long string table entry number
++ ** uchar type
++ ** (extern, absolute, defined in section)
++ ** uchar section
++ ** (0 for global symbols, section number of definition (>= 1, <=
++ ** 254) for local symbols, size of variable for common symbols
++ ** [type == extern])
++ ** short description
++ ** (for stab debugging format)
++ ** ulong value (i.e. file offset) of symbol or stab offset
++ **
++ ** string table data
++ ** list of null-terminated strings
++ */
++
++ /* Emit the Mach-O header. */
++ macho_write_header();
++
++ offset = MACHO_HEADER_SIZE + head_sizeofcmds;
++
++ /* emit the segment load command */
++ if (seg_nsects > 0)
++ offset = macho_write_segment (offset);
++ else
++ error(ERR_WARNING, "no sections?");
++
++ if (nsyms > 0) {
++ /* write out symbol command */
++ fwritelong(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
++ fwritelong(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
++ fwritelong(offset, machofp); /* symbol table offset */
++ fwritelong(nsyms, machofp); /* number of symbol
++ ** table entries */
++
++ offset += nsyms * MACHO_NLIST_SIZE;
++ fwritelong(offset, machofp); /* string table offset */
++ fwritelong(strslen, machofp); /* string table size */
++ }
++
++ /* emit section data */
++ if (seg_nsects > 0)
++ macho_write_section ();
++
++ /* emit symbol table if we have symbols */
++ if (nsyms > 0)
++ macho_write_symtab ();
++
++ /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */
++
++ /* emit string table */
++ saa_fpwrite(strs, machofp);
++}
++/* We do quite a bit here, starting with finalizing all of the data
++ for the object file, writing, and then freeing all of the data from
++ the file. */
++
++static void macho_cleanup(int debuginfo)
++{
++ struct section *s;
++ struct reloc *r;
++ struct symbol *sym;
++
++ (void)debuginfo;
++
++ /* Sort all symbols. */
++ macho_layout_symbols (&nsyms, &strslen);
++
++ /* Fixup relocation entries */
++ for (s = sects; s != NULL; s = s->next) {
++ macho_fixup_relocs (s->relocs);
++ }
++
++ /* First calculate and finalize needed values. */
++ macho_calculate_sizes();
++ macho_write();
++
++ /* done - yay! */
++ fclose(machofp);
++
++ /* free up everything */
++ while (sects->next) {
++ s = sects;
++ sects = sects->next;
++
++ saa_free(s->data);
++ while (s->relocs != NULL) {
++ r = s->relocs;
++ s->relocs = s->relocs->next;
++ nasm_free(r);
++ }
++
++ nasm_free(s);
++ }
++
++ saa_free(strs);
++ raa_free(extsyms);
++
++ if (syms) {
++ while (syms->next) {
++ sym = syms;
++ syms = syms->next;
++
++ nasm_free (sym);
++ }
++ }
++}
++
++/* Debugging routines. */
++static void debug_reloc (struct reloc *r)
++{
++ fprintf (stdout, "reloc:\n");
++ fprintf (stdout, "\taddr: %ld\n", r->addr);
++ fprintf (stdout, "\tsnum: %d\n", r->snum);
++ fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
++ fprintf (stdout, "\tlength: %d\n", r->length);
++ fprintf (stdout, "\text: %d\n", r->ext);
++ fprintf (stdout, "\ttype: %d\n", r->type);
++}
++
++static void debug_section_relocs (struct section *s)
++{
++ struct reloc *r = s->relocs;
++
++ fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
++
++ while (r != NULL) {
++ debug_reloc (r);
++ r = r->next;
++ }
++}
++
++struct ofmt of_macho = {
++ "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files",
++ "macho",
++ NULL,
++ null_debug_arr,
++ &null_debug_form,
++ macho_stdmac,
++ macho_init,
++ macho_setinfo,
++ macho_output,
++ macho_symdef,
++ macho_section,
++ macho_segbase,
++ macho_directive,
++ macho_filename,
++ macho_cleanup
++};
++
++#endif
++
++/*
++ * Local Variables:
++ * mode:c
++ * c-basic-offset:4
++ * End:
++ *
++ * end of file */
diff --git a/devel/nasm/patches/patch-ae b/devel/nasm/patches/patch-ae
new file mode 100644
index 00000000000..2046e5058ca
--- /dev/null
+++ b/devel/nasm/patches/patch-ae
@@ -0,0 +1,61 @@
+$NetBSD: patch-ae,v 1.3 2007/01/06 15:11:58 jmmv Exp $
+
+--- outform.h.orig 2005-01-15 23:15:51.000000000 +0100
++++ outform.h
+@@ -57,7 +57,7 @@
+
+ /* ====configurable info begins here==== */
+ /* formats configurable:
+- * bin,obj,elf,aout,aoutb,coff,win32,as86,rdf2 */
++ * bin,obj,elf,aout,aoutb,coff,win32,as86,rdf2,macho */
+
+ /* process options... */
+
+@@ -98,6 +98,9 @@
+ #ifndef OF_IEEE
+ #define OF_IEEE
+ #endif
++#ifndef OF_MACHO
++#define OF_MACHO
++#endif
+ #endif /* OF_ALL */
+
+ /* turn on groups of formats specified.... */
+@@ -141,6 +144,9 @@
+ #ifndef OF_IEEE
+ #define OF_IEEE
+ #endif
++#ifndef OF_MACHO
++#define OF_MACHO
++#endif
+ #endif
+
+ /* finally... override any format specifically specified to be off */
+@@ -174,6 +180,9 @@
+ #ifdef OF_NO_IEEE
+ #undef OF_IEEE
+ #endif
++#ifdef OF_NO_MACHO
++#undef OF_MACHO
++#endif
+
+ #ifndef OF_DEFAULT
+ #define OF_DEFAULT of_bin
+@@ -194,6 +203,7 @@ extern struct ofmt of_obj;
+ extern struct ofmt of_win32;
+ extern struct ofmt of_rdf2;
+ extern struct ofmt of_ieee;
++extern struct ofmt of_macho;
+ extern struct ofmt of_dbg;
+
+ struct ofmt *drivers[] = {
+@@ -227,6 +237,9 @@ struct ofmt *drivers[] = {
+ #ifdef OF_IEEE
+ &of_ieee,
+ #endif
++#ifdef OF_MACHO
++ &of_macho,
++#endif
+ #ifdef OF_DBG
+ &of_dbg,
+ #endif