diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2016-02-16 12:56:27 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2016-02-16 12:56:27 -0800 |
commit | 6fc2b123afaaf57577581a7680aa41fe101fd86b (patch) | |
tree | bfce6df922d9a71bcecbe707c5c2eccb7a99c476 | |
parent | d1da074b837cd8f56f2eca3e622cdfe2de20dbec (diff) | |
download | nasm-6fc2b123afaaf57577581a7680aa41fe101fd86b.tar.gz |
outmacho: if .rodata contains no relocations, change it to __TEXT,__const
If we specify .rodata as opposed to the explicit __DATA,__const, and
we end up with no relocations, change it to __TEXT,__const per the
Mach-O ABI. However, it is generally better for the programmer to
explicitly specify the items that should go into __TEXT,__const as
otherwise a single relocatable item will force the whole thing into
__DATA.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | output/outmacho.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/output/outmacho.c b/output/outmacho.c index e39d655f..6872a7bf 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -114,6 +114,7 @@ struct section { int32_t index; struct reloc *relocs; int align; + bool by_name; /* This section was specified by full MachO name */ /* data that goes into the file */ char sectname[16]; /* what this section is called */ @@ -248,7 +249,6 @@ static uint64_t seg_vmsize = 0; static uint32_t seg_nsects = 0; static uint64_t rel_padcnt = 0; - #define xstrncpy(xdst, xsrc) \ memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \ strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \ @@ -632,14 +632,14 @@ static int32_t macho_section(char *name, int pass, int *bits) len = strlen(segment); if (len == 0) { nasm_error(ERR_NONFATAL, "empty segment name\n"); - } else if (len > 16) { + } else if (len >= 16) { nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment); } len = strlen(section); if (len == 0) { nasm_error(ERR_NONFATAL, "empty section name\n"); - } else if (len > 16) { + } else if (len >= 16) { nasm_error(ERR_NONFATAL, "section name %s too long\n", section); } @@ -682,6 +682,7 @@ static int32_t macho_section(char *name, int pass, int *bits) s->align = -1; s->pad = -1; s->offset = -1; + s->by_name = false; xstrncpy(s->segname, segment); xstrncpy(s->sectname, section); @@ -697,6 +698,8 @@ static int32_t macho_section(char *name, int pass, int *bits) if (comma) *comma = ','; /* Restore comma */ + s->by_name = s->by_name || comma; /* Was specified by name */ + flags = (uint32_t)-1; while ((NULL != sectionAttributes) @@ -1114,6 +1117,17 @@ static uint32_t macho_write_segment (uint64_t offset) s->flags |= S_ATTR_LOC_RELOC; if (s->extreloc) s->flags |= S_ATTR_EXT_RELOC; + } else if (!strcmp(s->segname, "__DATA") && + !strcmp(s->sectname, "__const") && + !s->by_name && + !get_section_by_name("__TEXT", "__const")) { + /* + * The MachO equivalent to .rodata can be either + * __DATA,__const or __TEXT,__const; the latter only if + * there are no relocations. However, when mixed it is + * better to specify the segments explicitly. + */ + xstrncpy(s->segname, "__TEXT"); } fwriteint32_t(s->flags, ofile); /* flags */ |