|
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 |
a4d34d |
+++ nasm-2.14.02/output/outcoff.c 2019-01-18 21:52:03.156000000 +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 |
a4d34d |
@@ -765,6 +766,101 @@
|
|
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 |
a4d34d |
+ uint64_t global_sym_addr;
|
|
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 |
a4d34d |
+ global_sym_addr = (uint64_t)global_sym->sym->value;
|
|
Lucio Andrés Illanes Albornoz |
a4d34d |
+ coff_sect_write(coff_sects[sym->section - 1], &global_sym_addr, sizeof(global_sym_addr));
|
|
Lucio Andrés Illanes Albornoz |
74192c |
+ reloc_type = IMAGE_REL_AMD64_ADDR64;
|
|
Lucio Andrés Illanes Albornoz |
c4980e |
+ } else {
|
|
Lucio Andrés Illanes Albornoz |
a4d34d |
+ coff_sect_write(coff_sects[sym->section - 1], &global_sym->sym->value, sizeof(global_sym->sym->value));
|
|
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 |
a4d34d |
@@ -793,7 +889,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 |
a4d34d |
@@ -888,8 +986,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 |
a4d34d |
@@ -1086,7 +1188,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);
|