summaryrefslogtreecommitdiffhomepage
path: root/patches/nasm_host-2.16.01.local.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/nasm_host-2.16.01.local.patch')
-rw-r--r--patches/nasm_host-2.16.01.local.patch146
1 files changed, 146 insertions, 0 deletions
diff --git a/patches/nasm_host-2.16.01.local.patch b/patches/nasm_host-2.16.01.local.patch
new file mode 100644
index 00000000..5e61a289
--- /dev/null
+++ b/patches/nasm_host-2.16.01.local.patch
@@ -0,0 +1,146 @@
+diff --git nasm-2.16.01/output/outcoff.c.orig nasm-2.16.01/output/outcoff.c
+index c2b4eb6..fc57c1e 100644
+--- nasm-2.16.01/output/outcoff.c.orig
++++ nasm-2.16.01/output/outcoff.c
+@@ -820,6 +820,7 @@ static void coff_sect_write(struct coff_Section *sect,
+ sect->len += len;
+ }
+
++#ifndef COFF_MIDIPIX
+ typedef struct tagString {
+ struct tagString *next;
+ int len;
+@@ -884,6 +885,98 @@ static void BuildExportTable(STRING **rvp)
+
+ *rvp = NULL;
+ }
++#else
++typedef struct tagGlobalSymbol {
++ struct tagGlobalSymbol *next;
++ struct coff_Symbol *sym;
++} GLOBALSYMBOL;
++typedef struct tagGlobalSymbolList {
++ GLOBALSYMBOL *head, *tail;
++} GLOBALSYMBOLLIST;
++
++#define GOT_SECTION_FLAGS \
++ (IMAGE_SCN_CNT_INITIALIZED_DATA | \
++ IMAGE_SCN_ALIGN_4BYTES | \
++ IMAGE_SCN_LNK_COMDAT | \
++ IMAGE_SCN_MEM_READ)
++#define GOT_SECTION_PREFIX ".got$"
++#define GOT_SECTION_PREFIX_LEN (sizeof(GOT_SECTION_PREFIX) - 1)
++#define GOT_SYMBOL_PREFIX "__imp_"
++#define GOT_SYMBOL_PREFIX_LEN (sizeof(GOT_SYMBOL_PREFIX) - 1)
++
++static void BuildGlobalOffsetTable(void)
++{
++ uint64_t global_sym_addr;
++ GLOBALSYMBOL *global_sym, *global_sym_next;
++ char *global_sym_name;
++ GLOBALSYMBOLLIST global_symbols = {NULL, NULL};
++ char *got_sec_name, *got_sym_name;
++ size_t got_sec_name_len, got_sym_name_len;
++ struct coff_Symbol *sym;
++ unsigned long sym_num;
++
++ saa_rewind(coff_syms);
++ for (sym_num = 0; sym_num < coff_nsyms; sym_num++) {
++ sym = saa_rstruct(coff_syms);
++ if (sym->is_global && sym->section > 0) {
++ global_sym = nasm_malloc(sizeof(*global_sym));
++ global_sym->next = NULL;
++ global_sym->sym = sym;
++ if (!global_symbols.head)
++ global_symbols.head = global_sym;
++ if (global_symbols.tail)
++ global_symbols.tail->next = global_sym;
++ global_symbols.tail = global_sym;
++ }
++ }
++
++ for (global_sym = global_symbols.head, global_sym_next = NULL; global_sym; global_sym = global_sym_next) {
++ global_sym_name = nasm_zalloc(global_sym->sym->namlen + 1);
++ if (global_sym->sym->namlen > 8)
++ saa_fread(coff_strs, global_sym->sym->strpos - 4, global_sym_name, global_sym->sym->namlen);
++ else
++ strcpy(global_sym_name, global_sym->sym->name);
++
++ got_sec_name_len = GOT_SECTION_PREFIX_LEN + global_sym->sym->namlen;
++ got_sym_name_len = GOT_SYMBOL_PREFIX_LEN + global_sym->sym->namlen;
++ got_sec_name = nasm_zalloc(got_sec_name_len + 1);
++ got_sym_name = nasm_zalloc(got_sym_name_len + 1);
++ snprintf(got_sec_name, got_sec_name_len + 1, "%s%s", GOT_SECTION_PREFIX, global_sym_name);
++ snprintf(got_sym_name, got_sym_name_len + 1, "%s%s", GOT_SYMBOL_PREFIX, global_sym_name);
++
++ sym_num = coff_nsyms - 1;
++ sym = saa_wstruct(coff_syms);
++ sym->is_global = 1;
++ sym->namlen = got_sym_name_len;
++ sym->section = coff_make_section(got_sec_name, GOT_SECTION_FLAGS) + 1;
++ sym->type = 0; sym->value = 0;
++ coff_nsyms++;
++
++ if (sym->namlen > 8) {
++ sym->strpos = strslen + 4;
++ memset(sym->name, '\0', sizeof(sym->name));
++ saa_wbytes(coff_strs, got_sym_name, sym->namlen + 1);
++ strslen += sym->namlen + 1;
++ } else {
++ sym->strpos = -1;
++ strncpy(sym->name, got_sym_name, sizeof(sym->name));
++ }
++
++ if (win64) {
++ coff_add_reloc(coff_sects[sym->section - 1], coff_sects[global_sym->sym->section - 1]->index, IMAGE_REL_AMD64_ADDR64);
++ global_sym_addr = (uint64_t)global_sym->sym->value;
++ coff_sect_write(coff_sects[sym->section - 1], (const uint8_t *)&global_sym_addr, sizeof(global_sym_addr));
++ } else {
++ coff_add_reloc(coff_sects[sym->section - 1], coff_sects[global_sym->sym->section - 1]->index, IMAGE_REL_I386_DIR32);
++ coff_sect_write(coff_sects[sym->section - 1], (const uint8_t *)&global_sym->sym->value, sizeof(global_sym->sym->value));
++ }
++
++ global_sym_next = global_sym->next;
++ nasm_free(global_sym); nasm_free(global_sym_name);
++ nasm_free(got_sec_name); nasm_free(got_sym_name);
++ }
++}
++#endif
+
+ static void coff_defcomdatname(char *name, int32_t segment)
+ {
+@@ -924,7 +1017,9 @@ coff_directives(enum directive directive, char *value)
+ nasm_nonfatal("unrecognized export qualifier `%s'", q);
+ return DIRR_ERROR;
+ }
++#ifndef COFF_MIDIPIX
+ AddExport(name);
++#endif
+ return DIRR_OK;
+ }
+ case D_SAFESEH:
+@@ -1039,8 +1134,12 @@ static void coff_write(void)
+ int32_t pos, sympos, vsize;
+ int i;
+
++#ifndef COFF_MIDIPIX
+ /* fill in the .drectve section with -export's */
+ BuildExportTable(&Exports);
++#else
++ BuildGlobalOffsetTable();
++#endif
+
+ if (win32) {
+ /* add default value for @feat.00, this allows to 'link /safeseh' */
+@@ -1278,7 +1377,10 @@ static void coff_write_symbols(void)
+ memset(filename, 0, 18); /* useful zeroed buffer */
+
+ for (i = 0; i < (uint32_t) coff_nsects; i++) {
+- coff_symbol(coff_sects[i]->name, 0L, 0L, i + 1, 0, 3, 1);
++ if (coff_sects[i]->namepos == -1)
++ coff_symbol(coff_sects[i]->name, 0L, 0L, i + 1, 0, 3, 1);
++ else
++ coff_symbol(NULL, coff_sects[i]->namepos, 0L, i + 1, 0, 3, 1);
+ fwriteint32_t(coff_sects[i]->len, ofile);
+ fwriteint16_t(coff_sects[i]->nrelocs,ofile);
+ if (coff_sects[i]->flags & IMAGE_SCN_LNK_COMDAT) {