diff --git a/asm/directiv.dat b/asm/directiv.dat
index 09b8d840..e7a1553d 100644
--- a/asm/directiv.dat
+++ b/asm/directiv.dat
@@ -1,6 +1,6 @@
;; --------------------------------------------------------------------------
;;
-;; Copyright 1996-2016 The NASM Authors - All Rights Reserved
+;; Copyright 1996-2017 The NASM Authors - All Rights Reserved
;; See the file AUTHORS included with the NASM distribution for
;; the specific copyright holders.
;;
@@ -62,3 +62,4 @@ org ; outbin
osabi ; outelf
safeseh ; outcoff
uppercase ; outieee, outobj
+subsections_via_symbols ; outmacho
diff --git a/asm/directiv.pl b/asm/directiv.pl
index eef46f69..58a5861b 100755
--- a/asm/directiv.pl
+++ b/asm/directiv.pl
@@ -54,7 +54,7 @@ open(DD, "< ${directives_dat}\0")
or die "$0: cannot open: ${directives_dat}: $!\n";
while (defined($line =
)) {
chomp $line;
- if ($line =~ /^\s*([[:alnum:]]+)\s*(|[\;\#].*)$/) {
+ if ($line =~ /^\s*([[:alnum:]_]+)\s*(|[\;\#].*)$/) {
push(@directives, $1);
}
}
diff --git a/output/outmacho.c b/output/outmacho.c
index 5ce3e45b..716f99fd 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 1996-2016 The NASM Authors - All Rights Reserved
+ * Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@@ -75,6 +75,9 @@
#define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
#define MH_OBJECT 0x1 /* object file */
+/* Mach-O header flags */
+#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
+
/* Mach-O load commands */
#define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
#define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
@@ -281,6 +284,7 @@ static uint32_t strslen;
a structure or as function arguments. */
static uint32_t head_ncmds = 0;
static uint32_t head_sizeofcmds = 0;
+static uint32_t head_flags = 0;
static uint64_t seg_filesize = 0;
static uint64_t seg_vmsize = 0;
static uint32_t seg_nsects = 0;
@@ -1162,7 +1166,7 @@ static void macho_write_header (void)
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(head_flags, ofile); /* flags, if any */
fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
}
@@ -1594,6 +1598,27 @@ static void macho_cleanup(void)
nasm_free(sectstab);
}
+/*
+ * Mach-O-specific directives
+ */
+static enum directive_result
+ macho_directive(enum directives directive, char *value, int pass)
+{
+ switch (directive) {
+ case D_SUBSECTIONS_VIA_SYMBOLS:
+ if (*value)
+ return DIRR_BADPARAM;
+
+ if (pass == 2)
+ head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
+
+ return DIRR_OK;
+
+ default:
+ return DIRR_UNKNOWN; /* Not a Mach-O directive */
+ }
+}
+
#ifdef OF_MACHO32
static const struct macho_fmt macho32_fmt = {
4,
@@ -1634,7 +1659,7 @@ const struct ofmt of_macho32 = {
macho_section,
macho_sectalign,
macho_segbase,
- null_directive,
+ macho_directive,
macho_filename,
macho_cleanup,
NULL /* pragma list */
@@ -1683,7 +1708,7 @@ const struct ofmt of_macho64 = {
macho_section,
macho_sectalign,
macho_segbase,
- null_directive,
+ macho_directive,
macho_filename,
macho_cleanup,
NULL /* pragma list */
diff --git a/output/outmacho.mac b/output/outmacho.mac
index f1cdf180..0f56e819 100644
--- a/output/outmacho.mac
+++ b/output/outmacho.mac
@@ -1,6 +1,6 @@
;; --------------------------------------------------------------------------
;;
-;; Copyright 1996-2009 The NASM Authors - All Rights Reserved
+;; Copyright 1996-2017 The NASM Authors - All Rights Reserved
;; See the file AUTHORS included with the NASM distribution for
;; the specific copyright holders.
;;
@@ -35,3 +35,8 @@ OUT: macho macho32 macho64
%define __SECT__ [section .text]
%macro __NASM_CDecl__ 1
%endmacro
+
+; This directive sets the MH_SUBSECTION_VIA_SYMBOLS header flag
+%macro subsection_via_symbols 0
+[%?]
+%endmacro