Lucio Andrés Illanes Albornoz 74192c
--- nasm-2.14.02/output/outcoff.c.orig	2018-12-26 13:44:06.000000000 +0000
Lucio Andrés Illanes Albornoz c4980e
+++ nasm-2.14.02/output/outcoff.c	2019-01-17 23:17:37.132000000 +0000
Lucio Andrés Illanes Albornoz 74192c
@@ -701,6 +701,7 @@
Lucio Andrés Illanes Albornoz 74192c
     sect->len += len;
Lucio Andrés Illanes Albornoz 74192c
 }
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
+#ifndef COFF_MIDIPIX
Lucio Andrés Illanes Albornoz 74192c
 typedef struct tagString {
Lucio Andrés Illanes Albornoz 74192c
     struct tagString *next;
Lucio Andrés Illanes Albornoz 74192c
     int len;
Lucio Andrés Illanes Albornoz c4980e
@@ -765,6 +766,99 @@
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
     *rvp = NULL;
Lucio Andrés Illanes Albornoz 74192c
 }
Lucio Andrés Illanes Albornoz 74192c
+#else
Lucio Andrés Illanes Albornoz 74192c
+typedef struct tagGlobalSymbol {
Lucio Andrés Illanes Albornoz 74192c
+    struct tagGlobalSymbol *next;
Lucio Andrés Illanes Albornoz 74192c
+    struct coff_Symbol *sym;
Lucio Andrés Illanes Albornoz 74192c
+} GLOBALSYMBOL;
Lucio Andrés Illanes Albornoz 74192c
+typedef struct tagGlobalSymbolList {
Lucio Andrés Illanes Albornoz 74192c
+    GLOBALSYMBOL *head, *tail;
Lucio Andrés Illanes Albornoz 74192c
+} GLOBALSYMBOLLIST;
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+#define GOT_SECTION_FLAGS                               \
Lucio Andrés Illanes Albornoz 74192c
+    (IMAGE_SCN_CNT_INITIALIZED_DATA             |       \
Lucio Andrés Illanes Albornoz 74192c
+     IMAGE_SCN_ALIGN_4BYTES                     |       \
Lucio Andrés Illanes Albornoz 74192c
+     IMAGE_SCN_LNK_COMDAT                       |       \
Lucio Andrés Illanes Albornoz 74192c
+     IMAGE_SCN_MEM_READ)
Lucio Andrés Illanes Albornoz 74192c
+#define GOT_SECTION_PREFIX           ".got$"
Lucio Andrés Illanes Albornoz 74192c
+#define GOT_SECTION_PREFIX_LEN       (sizeof(GOT_SECTION_PREFIX) - 1)
Lucio Andrés Illanes Albornoz 74192c
+#define GOT_SYMBOL_PREFIX            "__imp_"
Lucio Andrés Illanes Albornoz 74192c
+#define GOT_SYMBOL_PREFIX_LEN       (sizeof(GOT_SYMBOL_PREFIX) - 1)
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+static void BuildGlobalOffsetTable(void)
Lucio Andrés Illanes Albornoz 74192c
+{
Lucio Andrés Illanes Albornoz 74192c
+    GLOBALSYMBOL *global_sym, *global_sym_next;
Lucio Andrés Illanes Albornoz 74192c
+    char *global_sym_name;
Lucio Andrés Illanes Albornoz 74192c
+    GLOBALSYMBOLLIST global_symbols = {NULL, NULL};
Lucio Andrés Illanes Albornoz 74192c
+    char *got_sec_name, *got_sym_name;
Lucio Andrés Illanes Albornoz 74192c
+    size_t got_sec_name_len, got_sym_name_len;
Lucio Andrés Illanes Albornoz 74192c
+    struct coff_Symbol *sym;
Lucio Andrés Illanes Albornoz 74192c
+    unsigned long sym_num;
Lucio Andrés Illanes Albornoz 74192c
+    struct coff_Reloc *reloc;
Lucio Andrés Illanes Albornoz 74192c
+    int16_t reloc_type;
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+    saa_rewind(coff_syms);
Lucio Andrés Illanes Albornoz 74192c
+    for (sym_num = 0; sym_num < coff_nsyms; sym_num++) {
Lucio Andrés Illanes Albornoz 74192c
+        sym = saa_rstruct(coff_syms);
Lucio Andrés Illanes Albornoz 74192c
+        if (sym->is_global && sym->section > 0) {
Lucio Andrés Illanes Albornoz 74192c
+            global_sym = nasm_malloc(sizeof(*global_sym));
Lucio Andrés Illanes Albornoz 74192c
+            global_sym->next = NULL;
Lucio Andrés Illanes Albornoz 74192c
+            global_sym->sym = sym;
Lucio Andrés Illanes Albornoz 74192c
+            if (!global_symbols.head)
Lucio Andrés Illanes Albornoz 74192c
+                global_symbols.head = global_sym;
Lucio Andrés Illanes Albornoz 74192c
+            if (global_symbols.tail)
Lucio Andrés Illanes Albornoz 74192c
+                global_symbols.tail->next = global_sym;
Lucio Andrés Illanes Albornoz 74192c
+            global_symbols.tail = global_sym;
Lucio Andrés Illanes Albornoz 74192c
+        }
Lucio Andrés Illanes Albornoz 74192c
+    }
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+    for (global_sym = global_symbols.head, global_sym_next = NULL; global_sym; global_sym = global_sym_next) {
Lucio Andrés Illanes Albornoz 74192c
+        global_sym_name = nasm_zalloc(global_sym->sym->namlen + 1);
Lucio Andrés Illanes Albornoz 74192c
+        if (global_sym->sym->namlen > 8)
Lucio Andrés Illanes Albornoz 74192c
+            saa_fread(coff_strs, global_sym->sym->strpos - 4, global_sym_name, global_sym->sym->namlen);
Lucio Andrés Illanes Albornoz 74192c
+        else
Lucio Andrés Illanes Albornoz 74192c
+            strcpy(global_sym_name, global_sym->sym->name);
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+        got_sec_name_len = GOT_SECTION_PREFIX_LEN + global_sym->sym->namlen;
Lucio Andrés Illanes Albornoz 74192c
+        got_sym_name_len = GOT_SYMBOL_PREFIX_LEN + global_sym->sym->namlen;
Lucio Andrés Illanes Albornoz 74192c
+        got_sec_name = nasm_zalloc(got_sec_name_len + 1);
Lucio Andrés Illanes Albornoz 74192c
+        got_sym_name = nasm_zalloc(got_sym_name_len + 1);
Lucio Andrés Illanes Albornoz 74192c
+        snprintf(got_sec_name, got_sec_name_len + 1, "%s%s", GOT_SECTION_PREFIX, global_sym_name);
Lucio Andrés Illanes Albornoz 74192c
+        snprintf(got_sym_name, got_sym_name_len + 1, "%s%s", GOT_SYMBOL_PREFIX, global_sym_name);
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+        sym_num = coff_nsyms - 1;
Lucio Andrés Illanes Albornoz 74192c
+        sym = saa_wstruct(coff_syms);
Lucio Andrés Illanes Albornoz 74192c
+        sym->is_global = 1;
Lucio Andrés Illanes Albornoz 74192c
+        sym->namlen = got_sym_name_len;
Lucio Andrés Illanes Albornoz c4980e
+        sym->section = coff_make_section(got_sec_name, GOT_SECTION_FLAGS) + 1;
Lucio Andrés Illanes Albornoz 74192c
+        sym->type = 0; sym->value = 0;
Lucio Andrés Illanes Albornoz 74192c
+        coff_nsyms++;
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+        if (sym->namlen > 8) {
Lucio Andrés Illanes Albornoz 74192c
+            sym->strpos = strslen + 4;
Lucio Andrés Illanes Albornoz 74192c
+            memset(sym->name, '\0', sizeof(sym->name));
Lucio Andrés Illanes Albornoz 74192c
+            saa_wbytes(coff_strs, got_sym_name, sym->namlen + 1);
Lucio Andrés Illanes Albornoz 74192c
+            strslen += sym->namlen + 1;
Lucio Andrés Illanes Albornoz 74192c
+        } else {
Lucio Andrés Illanes Albornoz 74192c
+            sym->strpos = -1;
Lucio Andrés Illanes Albornoz 74192c
+            strncpy(sym->name, got_sym_name, sizeof(sym->name));
Lucio Andrés Illanes Albornoz 74192c
+        }
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz c4980e
+        if (win64) {
Lucio Andrés Illanes Albornoz c4980e
+            coff_sect_write(coff_sects[sym->section - 1], (const uint8_t *)&((uint64_t[]){0ULL}), 8);
Lucio Andrés Illanes Albornoz 74192c
+            reloc_type = IMAGE_REL_AMD64_ADDR64;
Lucio Andrés Illanes Albornoz c4980e
+        } else {
Lucio Andrés Illanes Albornoz c4980e
+            coff_sect_write(coff_sects[sym->section - 1], (const uint8_t *)&((uint32_t[]){0UL}), 4);
Lucio Andrés Illanes Albornoz 74192c
+            reloc_type = IMAGE_REL_I386_DIR32;
Lucio Andrés Illanes Albornoz c4980e
+        }
Lucio Andrés Illanes Albornoz c4980e
+        coff_add_reloc(coff_sects[sym->section - 1], coff_sects[global_sym->sym->section - 1]->index, reloc_type);
Lucio Andrés Illanes Albornoz 74192c
+
Lucio Andrés Illanes Albornoz 74192c
+        global_sym_next = global_sym->next;
Lucio Andrés Illanes Albornoz 74192c
+        nasm_free(global_sym); nasm_free(global_sym_name);
Lucio Andrés Illanes Albornoz 74192c
+        nasm_free(got_sec_name); nasm_free(got_sym_name);
Lucio Andrés Illanes Albornoz 74192c
+    }
Lucio Andrés Illanes Albornoz 74192c
+}
Lucio Andrés Illanes Albornoz 74192c
+#endif
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
 static enum directive_result
Lucio Andrés Illanes Albornoz 74192c
 coff_directives(enum directive directive, char *value, int pass)
Lucio Andrés Illanes Albornoz c4980e
@@ -793,7 +887,9 @@
Lucio Andrés Illanes Albornoz 74192c
             nasm_error(ERR_NONFATAL, "unrecognized export qualifier `%s'", q);
Lucio Andrés Illanes Albornoz 74192c
             return DIRR_ERROR;
Lucio Andrés Illanes Albornoz 74192c
         }
Lucio Andrés Illanes Albornoz 74192c
+#ifndef COFF_MIDIPIX
Lucio Andrés Illanes Albornoz 74192c
         AddExport(name);
Lucio Andrés Illanes Albornoz 74192c
+#endif
Lucio Andrés Illanes Albornoz 74192c
         return DIRR_OK;
Lucio Andrés Illanes Albornoz 74192c
     }
Lucio Andrés Illanes Albornoz 74192c
     case D_SAFESEH:
Lucio Andrés Illanes Albornoz c4980e
@@ -888,8 +984,12 @@
Lucio Andrés Illanes Albornoz 74192c
     int32_t pos, sympos, vsize;
Lucio Andrés Illanes Albornoz 74192c
     int i;
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
+#ifndef COFF_MIDIPIX
Lucio Andrés Illanes Albornoz 74192c
     /* fill in the .drectve section with -export's */
Lucio Andrés Illanes Albornoz 74192c
     BuildExportTable(&Exports);
Lucio Andrés Illanes Albornoz 74192c
+#else
Lucio Andrés Illanes Albornoz 74192c
+    BuildGlobalOffsetTable();
Lucio Andrés Illanes Albornoz 74192c
+#endif
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
     if (win32) {
Lucio Andrés Illanes Albornoz 74192c
         /* add default value for @feat.00, this allows to 'link /safeseh' */
Lucio Andrés Illanes Albornoz c4980e
@@ -1086,7 +1186,10 @@
Lucio Andrés Illanes Albornoz 74192c
     memset(filename, 0, 18);    /* useful zeroed buffer */
Lucio Andrés Illanes Albornoz 74192c
 
Lucio Andrés Illanes Albornoz 74192c
     for (i = 0; i < (uint32_t) coff_nsects; i++) {
Lucio Andrés Illanes Albornoz 74192c
-        coff_symbol(coff_sects[i]->name, 0L, 0L, i + 1, 0, 3, 1);
Lucio Andrés Illanes Albornoz 74192c
+        if (coff_sects[i]->namepos == -1)
Lucio Andrés Illanes Albornoz 74192c
+            coff_symbol(coff_sects[i]->name, 0L, 0L, i + 1, 0, 3, 1);
Lucio Andrés Illanes Albornoz 74192c
+        else
Lucio Andrés Illanes Albornoz 74192c
+            coff_symbol(NULL, coff_sects[i]->namepos, 0L, i + 1, 0, 3, 1);
Lucio Andrés Illanes Albornoz 74192c
         fwriteint32_t(coff_sects[i]->len,    ofile);
Lucio Andrés Illanes Albornoz 74192c
         fwriteint16_t(coff_sects[i]->nrelocs,ofile);
Lucio Andrés Illanes Albornoz 74192c
         nasm_write(filename, 12, ofile);