From 427d8e3e57b68370daa143c3e501df9c23e9869f Mon Sep 17 00:00:00 2001 From: "Chang S. Bae" Date: Wed, 2 May 2018 08:07:52 -0700 Subject: [PATCH] output: macho -- Avoid conversion of addresses to RAWDATA Without relocation, the linker may do erroneous dead strip. For the relocation, the conversion of addresses to RAWDATA should be avoided for Mach-O. https://bugzilla.nasm.us/show_bug.cgi?id=3392469 Reported-by: Andrew Fish Signed-off-by: Chang S. Bae Signed-off-by: Cyrill Gorcunov --- asm/assemble.c | 3 ++- include/nasm.h | 4 +++- output/outmacho.c | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/asm/assemble.c b/asm/assemble.c index 561bba55..a6bb0ee5 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -366,7 +366,8 @@ static void out(struct out_data *data) nasm_assert(data->size <= 8); asize = data->size; amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */ - if (data->tsegment == fixseg && data->twrt == NO_SEG) { + if ((ofmt->flags & OFMT_KEEP_ADDR) == 0 && data->tsegment == fixseg && + data->twrt == NO_SEG) { warn_overflow_out(addrval, asize, data->sign); xdata.q = cpu_to_le64(addrval); data->data = xdata.b; diff --git a/include/nasm.h b/include/nasm.h index 48590f20..a5a7b661 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -786,7 +786,9 @@ struct ofmt { /* * Output format flags. */ -#define OFMT_TEXT 1 /* Text file format */ +#define OFMT_TEXT 1 /* Text file format */ +#define OFMT_KEEP_ADDR 2 /* Keep addr; no conversion to data */ + unsigned int flags; int maxbits; /* Maximum segment bits supported */ diff --git a/output/outmacho.c b/output/outmacho.c index a92b9ecc..3eeb057c 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -690,8 +690,8 @@ static void macho_output(int32_t secto, const void *data, break; } + case OUT_REL1ADR: case OUT_REL2ADR: - nasm_assert(section != secto); p = mydata; offset = *(int64_t *)data; @@ -708,15 +708,16 @@ static void macho_output(int32_t secto, const void *data, " this use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } else { - addr += add_reloc(s, section, addr+size, RL_REL, 2); + addr += add_reloc(s, section, addr+size, RL_REL, + type == OUT_REL1ADR ? 1 : 2); } WRITESHORT(p, addr); - sect_write(s, mydata, 2); + sect_write(s, mydata, type == OUT_REL1ADR ? 1 : 2); break; case OUT_REL4ADR: - nasm_assert(section != secto); + case OUT_REL8ADR: p = mydata; offset = *(int64_t *)data; @@ -770,9 +771,10 @@ static void macho_output(int32_t secto, const void *data, /* continue with RL_REL */ } - addr += add_reloc(s, section, offset, reltype, 4); + addr += add_reloc(s, section, offset, reltype, + type == OUT_REL4ADR ? 4 : 8); WRITELONG(p, addr); - sect_write(s, mydata, 4); + sect_write(s, mydata, type == OUT_REL4ADR ? 4 : 8); break; default: @@ -2321,7 +2323,7 @@ const struct ofmt of_macho32 = { "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files", "macho32", ".o", - 0, + OFMT_KEEP_ADDR, 32, macho32_df_arr, &macho32_df_dwarf, @@ -2386,7 +2388,7 @@ const struct ofmt of_macho64 = { "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files", "macho64", ".o", - 0, + OFMT_KEEP_ADDR, 64, macho64_df_arr, &macho64_df_dwarf,