Bug fixes and don't extend ELKS format master
authorRobert Pengelly <robertapengelly@hotmail.com>
Mon, 26 Jan 2026 23:55:30 +0000 (23:55 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Mon, 26 Jan 2026 23:55:30 +0000 (23:55 +0000)
16 files changed:
Makefile.unix
Makefile.w32
Makefile.wat
dx.c [new file with mode: 0644]
dx.h [new file with mode: 0644]
elf.c
elf.h
elks.c
elks.h
inttypes.h
ld.c
ld.h
lib.c
link.c
macho.c
stdint.h

index 88ebe511b737dc335c2d7dc89fb4387504dfcaa9..7778788ae3b08f8c1aa73e174133640e40765b35 100644 (file)
@@ -7,7 +7,7 @@ VPATH               :=  $(SRCDIR)
 CC                  :=  gcc
 CFLAGS              :=  -D_FILE_OFFSET_BITS=64 -O2 -Wall -Werror -Wextra -ansi -pedantic -std=c90
 
-CSRC                :=  aout.c coff.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
+CSRC                :=  aout.c coff.c dx.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
 
 ifeq ($(OS), Windows_NT)
 all: slink.exe
index 00e19dad9603d433ca04601ffca07232dd46eaa9..5cccc57f41f23f90a26569b658a1f99db5a466b8 100644 (file)
@@ -7,7 +7,7 @@ VPATH               :=  $(SRCDIR)
 CC                  :=  gcc
 CFLAGS              :=  -D_FILE_OFFSET_BITS=64 -O2 -Wall -Werror -Wextra
 
-CSRC                :=  aout.c coff.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
+CSRC                :=  aout.c coff.c dx.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
 
 all: slink.exe
 
index daa5883303a08be97903800ee100160f13b22c5f..026fb801fadf6389dce34b1c48ddcf2f0e2ff134 100644 (file)
@@ -4,7 +4,7 @@
 SRCDIR              ?=  $(CURDIR)
 VPATH               :=  $(SRCDIR)
 
-SRC                 :=  aout.c coff.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
+SRC                 :=  aout.c coff.c dx.c elf.c elks.c hashtab.c ld.c lib.c link.c macho.c map.c mz.c omf.c pe.c report.c section.c symbol.c vector.c write7x.c
 
 all: slink.exe
 
diff --git a/dx.c b/dx.c
new file mode 100644 (file)
index 0000000..589f74e
--- /dev/null
+++ b/dx.c
@@ -0,0 +1,239 @@
+/******************************************************************************
+ * @file            dx.c
+ *****************************************************************************/
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <string.h>
+
+#include    "dx.h"
+#include    "ld.h"
+#include    "lib.h"
+#include    "reloc.h"
+#include    "report.h"
+#include    "section.h"
+#include    "symbol.h"
+
+static unsigned long section_alignment = DEFAULT_SECTION_ALIGNMENT;
+
+static unsigned long section_get_num_relocs (struct section *section) {
+
+    unsigned long num_relocs = 0, i;
+    
+    struct section_part *part;
+    struct reloc_howto *howto;
+    
+    for (part = section->first_part; part; part = part->next) {
+    
+        for (i = 0; i < part->reloc_cnt; i++) {
+        
+            howto = part->reloc_arr[i].howto;
+            
+            if (howto == &reloc_howtos[RELOC_TYPE_64] || howto == &reloc_howtos[RELOC_TYPE_32] || howto == &reloc_howtos[RELOC_TYPE_16] || howto == &reloc_howtos[RELOC_TYPE_8]) {
+                num_relocs++;
+            }
+        
+        }
+    
+    }
+    
+    return num_relocs;
+
+}
+
+static unsigned char *write_relocs_for_section (unsigned char *pos, struct section *section) {
+
+    struct section_part *part;
+    struct dx_relocation_info rel;
+    
+    struct symbol *symbol;
+    unsigned long size_log2, i, r_symbolnum;
+    
+    for (part = section->first_part; part; part = part->next) {
+    
+        for (i = 0; i < part->reloc_cnt; i++) {
+        
+            memset (&rel, 0, sizeof (rel));
+            
+            if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_64]) {
+                size_log2 = 3;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_32]) {
+                size_log2 = 2;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_16]) {
+                size_log2 = 1;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_8]) {
+                size_log2 = 0;
+            } else {
+                continue;
+            }
+            
+            symbol = part->reloc_arr[i].symbol;
+            
+            if (symbol_is_undefined (symbol)) {
+                symbol = symbol_find (symbol->name);
+            }
+            
+            integer_to_array (part->rva - part->section->rva + part->reloc_arr[i].offset, rel.r_address, 4, 0);
+            
+            if (!symbol->part || strcmp (symbol->part->section->name, ".text") == 0) {
+                r_symbolnum = N_TEXT;
+            } else if (strcmp (symbol->part->section->name, ".data") == 0) {
+                r_symbolnum = N_DATA;
+            } else if (strcmp (symbol->part->section->name, ".bss") == 0) {
+                r_symbolnum = N_BSS;
+            } else {
+                r_symbolnum = N_TEXT;
+            }
+            
+            if ((part->reloc_arr[i].r_symbolnum >> 27) & 1) {
+                r_symbolnum |= (1LU << 27);
+            }
+            
+            integer_to_array (r_symbolnum | (size_log2 << 25), rel.r_symbolnum, 4, 0);
+            
+            memcpy (pos, &rel, sizeof (rel));
+            pos += sizeof (rel);
+        
+        }
+    
+    }
+    
+    return pos;
+
+}
+
+void dx_write (const char *filename) {
+
+    FILE *fp;
+    
+    unsigned char *data, *pos;
+    unsigned long image_size;
+    
+    struct section *text_section, *data_section, *bss_section;
+    unsigned long text_size = 0, data_size = 0, bss_size = 0;
+    
+    struct dx_exec exec;
+    memset (&exec, 0, sizeof (exec));
+    
+    if (!(fp = fopen (filename, "wb"))) {
+    
+        report_at (program_name, 0, REPORT_ERROR, "failed to open '%s' for writing", filename);
+        return;
+    
+    }
+    
+    text_section = section_find (".text");
+    data_section = section_find (".data");
+    bss_section  = section_find (".bss");
+    
+    integer_to_array (DX_MAGIC, exec.a_magic, 4, 0);
+    
+    exec.a_cpu = (state->format == LD_FORMAT_I386_DX) ? 0x10 : 0x04;
+    exec.a_hdrlen = sizeof (exec);
+    
+    if (text_section) {
+    
+        if (state->impure) {
+            text_size = text_section->total_size;
+        } else {
+            text_size = ALIGN (text_section->total_size, section_alignment);
+        }
+    
+    }
+    
+    if (data_section) {
+    
+        if (state->impure) {
+            data_size = data_section->total_size;
+        } else {
+            data_size = ALIGN (data_section->total_size, section_alignment);
+        }
+    
+    }
+    
+    if (bss_section) {
+    
+        if (state->impure) {
+            bss_size = bss_section->total_size;
+        } else {
+            bss_size = ALIGN (bss_section->total_size, section_alignment);
+        }
+    
+    }
+    
+    integer_to_array (text_size, exec.a_text, 4, 0);
+    integer_to_array (data_size, exec.a_data, 4, 0);
+    
+    integer_to_array (bss_size, exec.a_bss, 4, 0);
+    integer_to_array (state->entry_point, exec.a_entry, 4, 0);
+    
+    integer_to_array (array_to_integer (exec.a_text, 4, 0) + array_to_integer (exec.a_data, 4, 0), exec.a_total, 4, 0);
+    
+    if (text_section) {
+        integer_to_array (section_get_num_relocs (text_section) * sizeof (struct dx_relocation_info), exec.a_trsize, 4, 0);
+    }
+    
+    if (data_section) {
+        integer_to_array (section_get_num_relocs (data_section) * sizeof (struct dx_relocation_info), exec.a_drsize, 4, 0);
+    }
+    
+    image_size = sizeof (exec);
+    
+    image_size += (array_to_integer (exec.a_text, 4, 0) + array_to_integer (exec.a_data, 4, 0));
+    image_size += (array_to_integer (exec.a_trsize, 4, 0) + array_to_integer (exec.a_drsize, 4, 0));
+    
+    image_size += 4;
+    
+    data = xmalloc (image_size);
+    memcpy (data, &exec, sizeof (exec));
+    
+    pos = data + sizeof (exec);
+    
+    if (text_section) {
+        section_write (text_section, pos);
+    }
+    
+    pos += array_to_integer (exec.a_text, 4, 0);
+    
+    if (data_section) {
+        section_write (data_section, pos);
+    }
+    
+    pos += array_to_integer (exec.a_data, 4, 0);
+    
+    if (text_section) {
+        pos = write_relocs_for_section (pos, text_section);
+    }
+    
+    if (data_section) {
+        pos = write_relocs_for_section (pos, data_section);
+    }
+    
+    integer_to_array (4, pos, 4, 0);
+    
+    if (fwrite (data, image_size, 1, fp) != 1) {
+        report_at (program_name, 0, REPORT_ERROR, "failed to write data to '%s'", filename);
+    }
+    
+    free (data);
+    fclose (fp);
+
+}
+
+
+void dx_before_link (void) {
+
+    if (!state->impure) {
+    
+        struct section *section;
+        
+        for (section = all_sections; section; section = section->next) {
+        
+            if (section->section_alignment < section_alignment) {
+                section->section_alignment = section_alignment;
+            }
+        
+        }
+    
+    }
+
+}
diff --git a/dx.h b/dx.h
new file mode 100644 (file)
index 0000000..727d6f9
--- /dev/null
+++ b/dx.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * @file            dx.h
+ *****************************************************************************/
+#ifndef     _DX_H
+#define     _DX_H
+
+struct dx_exec {
+
+    /* offset 0 */
+    unsigned char a_magic[2];
+    unsigned char a_flags;
+    unsigned char a_cpu;
+    unsigned char a_hdrlen;
+    unsigned char a_unused;
+    unsigned char a_version[2];
+    
+    /* offset 8 */
+    unsigned char a_text[4];
+    unsigned char a_data[4];
+    unsigned char a_bss[4];
+    unsigned char a_entry[4];
+    unsigned char a_total[4];
+    unsigned char a_syms[4];
+    
+    /* offset 32 */
+    unsigned char a_trsize[4];
+    unsigned char a_drsize[4];
+    unsigned char a_trbase[4];
+    unsigned char a_drbase[4];
+
+};
+
+#define     N_UNDF                      0x00
+#define     N_ABS                       0x02
+#define     N_TEXT                      0x04
+#define     N_DATA                      0x06
+#define     N_BSS                       0x08
+#define     N_COMM                      0x12
+
+struct dx_relocation_info {
+
+    unsigned char r_address[4];
+    unsigned char r_symbolnum[4];
+
+};
+
+#define     N_EXT                       0x01
+
+struct dx_nlist {
+
+    unsigned char n_strx[4];
+    unsigned char n_type;
+    
+    unsigned char n_other;
+    unsigned char n_desc[2];
+    
+    unsigned char n_value[4];
+
+};
+
+#define     DX_MAGIC                    0x5844
+#define     N_TYPE                      0x1e
+
+void dx_before_link (void);
+void dx_write (const char *filename);
+
+#endif      /* _DX_H */
diff --git a/elf.c b/elf.c
index 121c552858fd974b777b39e5c9da483d271f8b73..16e215bb1ad2f2c156f5797830dd0a1e5c7984fa 100644 (file)
--- a/elf.c
+++ b/elf.c
@@ -84,15 +84,29 @@ static void translate_relocation (const char *filename, struct reloc_entry *relo
 
 }
 
-#define     ELF64_R_SYM(i)              ((i) >> 32)
-#define     ELF64_R_TYPE(i)             ((i) & 0xffffffff)
+#ifndef     NO_LONG_LONG
+# define        ELF64_R_SYM(i)          ((i) >> 32)
+# define        ELF64_R_TYPE(i)         ((i) & 0xffffffff)
+#endif
 
 static void translate_relocation64_addend (const char *filename, struct reloc_entry *reloc, struct elf64_rela *input_reloc, struct section_part *part, int endianess) {
 
-    uint64_t r_info = array_to_integer (input_reloc->r_info, 8, endianess);
-    uint64_t r_offset = array_to_integer (input_reloc->r_offset, 8, endianess);
-    
-    uint32_t symbol_index = ELF64_R_SYM (r_info), rel_type = ELF64_R_TYPE (r_info);
+    uint64_t r_info, r_offset;
+    uint32_t symbol_index, rel_type;
+    
+#if     defined (NO_LONG_LONG)
+    r_info = array_to_integer (input_reloc->r_info + 4, 4, endianess);
+    r_offset = array_to_integer (input_reloc->r_offset, 4, endianess);
+    
+    rel_type = array_to_integer (input_reloc->r_info, 4, endianess);
+    symbol_index = r_info;
+#else
+    r_info = array_to_integer (input_reloc->r_info, 8, endianess);
+    r_offset = array_to_integer (input_reloc->r_offset, 8, endianess);
+    
+    symbol_index = ELF64_R_SYM (r_info);
+    rel_type = ELF64_R_TYPE (r_info);
+#endif
     
     if (symbol_index >= part->of->symbol_cnt) {
     
diff --git a/elf.h b/elf.h
index eb4a337a2cf7697090142ace8739914b90be1278..e8220198843c962a9cc5b9b054c53a2556a06d1e 100644 (file)
--- a/elf.h
+++ b/elf.h
@@ -212,9 +212,9 @@ struct elf64_phdr {
 void elf_before_link (void);
 
 void read_elf32_object (const char *filename, unsigned char *data, unsigned long data_size, int endianess);
-void read_elf64_object (const char *filename, unsigned char *data, unsigned long data_size, int endianess);
-
 void elf32_write (const char *filename);
+
+void read_elf64_object (const char *filename, unsigned char *data, unsigned long data_size, int endianess);
 void elf64_write (const char *filename);
 
 #include    "stdint.h"
diff --git a/elks.c b/elks.c
index 0dbfe7faec7d33ffa157827c17438fa5f010b999..1757499d5e4ca084d64d33fe543cabe72b12ea0d 100644 (file)
--- a/elks.c
+++ b/elks.c
@@ -542,7 +542,6 @@ void elks_write (const char *filename) {
     image_size += 4;
     
     data = xmalloc (image_size);
-    data = xmalloc (data_size);
     memcpy (data, &exec, sizeof (exec));
     
     pos = data + sizeof (exec);
diff --git a/elks.h b/elks.h
index babd6fae9cf1fe9ec52353fb904aa08fc43634fb..ce20b9e5b20bf918feaf5195887b4efe872ec6a7 100644 (file)
--- a/elks.h
+++ b/elks.h
@@ -58,8 +58,8 @@ struct elks_nlist {
 
 };
 
-#define     N_TYPE                      0x1e
 #define     ELKS_MAGIC                  0403
+#define     N_TYPE                      0x1e
 
 void read_elks_object (const char *filename, unsigned char *data, unsigned long data_size);
 
index 34d387c40df81b681f7b4ed56171046cb5394258..2ff8fed02ec67a4c7589250ca4730db52f5bdb6a 100644 (file)
@@ -9,7 +9,7 @@
 # define    I64_FMT                     "I64"
 #elif   defined (__PRI_64_LENGTH_MODIFIER__)                                                        /* Mac */
 # define    I64_FMT                     __PRI_64_LENGTH_MODIFIER__
-#elif   (defined (SIZEOF_LONG) && SIZEOF_LONG >= 8) || ULONG_MAX > 4294967295UL
+#elif   (defined (SIZEOF_LONG) && SIZEOF_LONG >= 8) || ((ULONG_MAX >> 16) >> 16) == 0xffffffff
 # define    I64_FMT                     "l"
 #else
 # define    I64_FMT                     "ll"
diff --git a/ld.c b/ld.c
index 98fefa242fc6b847f2fb6f7b52285ff347d70fa9..796e72166fc2401cc2ebfedfb455f22c4f0ac1f3 100644 (file)
--- a/ld.c
+++ b/ld.c
@@ -8,6 +8,7 @@
 #include    "aout.h"
 #include    "ar.h"
 #include    "coff.h"
+#include    "dx.h"
 #include    "elf.h"
 #include    "elks.h"
 #include    "ld.h"
@@ -501,11 +502,15 @@ int main (int argc, char **argv) {
     
     }
     
-    if (state->format == LD_FORMAT_I386_AOUT || state->format == LD_FORMAT_I386_ELKS || state->format == LD_FORMAT_IA16_ELKS || state->format == LD_FORMAT_MZ) {
+    if (state->format == LD_FORMAT_I386_AOUT || state->format == LD_FORMAT_I386_DX || state->format == LD_FORMAT_IA16_DX || state->format == LD_FORMAT_I386_ELKS || state->format == LD_FORMAT_IA16_ELKS || state->format == LD_FORMAT_MZ) {
     
         section_find_or_make (".text");
         section_find_or_make (".data");
         section_find_or_make (".bss");
+        
+        if (state->format == LD_FORMAT_IA16_DX) {
+            state->impure = 1;
+        }
     
     }
     
@@ -532,20 +537,29 @@ int main (int argc, char **argv) {
                 state->base_address = 0x00400000;
             }
         
+        } else if (state->format == LD_FORMAT_AMD64_ELF || state->format == LD_FORMAT_I386_ELF) {
+            state->base_address = 0x0040000;
+#if     defined(NO_LONG_LONG)
+        } else if (state->format == LD_FORMAT_AMD64_MACHO || state->format == LD_FORMAT_AARCH64_MACHO) {
+            state->base_address = 0x10000000;
+        } else if (state->format == LD_FORMAT_AARCH64_ELF) {
+            state->base_address = 0x14000000;
+        }
+#else
         } else if (state->format == LD_FORMAT_AMD64_MACHO || state->format == LD_FORMAT_AARCH64_MACHO) {
             state->base_address = 0x100000000;
-        } else if (state->format == LD_FORMAT_AMD64_ELF || state->format == LD_FORMAT_I386_ELF) {
-            state->base_address = 0x00400000;
         } else if (state->format == LD_FORMAT_AARCH64_ELF) {
             state->base_address = 0x140000000;
         }
-    
+#endif
     }
     
     if (state->format == LD_FORMAT_I386_AOUT) {
         aout_before_link ();
     } else if (state->format == LD_FORMAT_I386_COFF) {
         coff_before_link ();
+    } else if (state->format == LD_FORMAT_I386_DX) {
+        dx_before_link ();
     } else if (state->format == LD_FORMAT_I386_ELKS) {
         elks_before_link ();
     } else if (state->format == LD_FORMAT_I386_PE) {
@@ -609,12 +623,12 @@ int main (int argc, char **argv) {
         mz_write (state->output_filename);
     } else if (state->format == LD_FORMAT_I386_AOUT) {
         aout_write (state->output_filename);
+    } else if (state->format == LD_FORMAT_I386_DX || state->format == LD_FORMAT_IA16_DX) {
+        dx_write (state->output_filename);
     } else if (state->format == LD_FORMAT_I386_ELKS || state->format == LD_FORMAT_IA16_ELKS) {
         elks_write (state->output_filename);
     } else if (state->format == LD_FORMAT_I386_ELF) {
         elf32_write (state->output_filename);
-    } else if (state->format == LD_FORMAT_AARCH64_ELF || state->format == LD_FORMAT_AMD64_ELF) {
-        elf64_write (state->output_filename);
     } else if (state->format == LD_FORMAT_I386_PE) {
     
         pe_after_link ();
@@ -625,6 +639,8 @@ int main (int argc, char **argv) {
         coff_after_link ();
         coff_write (state->output_filename);
     
+    } else if (state->format == LD_FORMAT_AARCH64_ELF || state->format == LD_FORMAT_AMD64_ELF) {
+        elf64_write (state->output_filename);
     } else if (state->format == LD_FORMAT_AMD64_MACHO || state->format == LD_FORMAT_AARCH64_MACHO) {
         macho_write (state->output_filename);
     }
diff --git a/ld.h b/ld.h
index 5901f9659b5449e21e78b9f77399a78224878fce..68db48e350ad7f580dc4eaa03a9fc90d19d4efc1 100644 (file)
--- a/ld.h
+++ b/ld.h
@@ -36,12 +36,12 @@ struct ld_state {
 
 #define     LD_EMULATION_NONE           0x00
 
-#define     LD_EMULATION_IA16_ELKS      0x01
+#define     LD_EMULATION_IA16_DX        0x01
 #define     LD_EMULATION_IA16_MZ        0x02
 
 #define     LD_EMULATION_I386_AOUT      0x03
 #define     LD_EMULATION_I386_COFF      0x04
-#define     LD_EMULATION_I386_ELKS      0x05
+#define     LD_EMULATION_I386_DX        0x05
 #define     LD_EMULATION_I386_PE        0x06
 
 #define     LD_EMULATION_MACHO          0x07
@@ -50,19 +50,22 @@ struct ld_state {
 #define     LD_FORMAT_COM               0x00
 #define     LD_FORMAT_MZ                0x01
 #define     LD_FORMAT_BIN               0x02
+
 #define     LD_FORMAT_IA16_ELKS         0x03
+#define     LD_FORMAT_IA16_DX           0x04
 
-#define     LD_FORMAT_I386_ELKS         (LD_TARGET_MACHINE_I386     | 0x04)
-#define     LD_FORMAT_I386_AOUT         (LD_TARGET_MACHINE_I386     | 0x05)
-#define     LD_FORMAT_I386_COFF         (LD_TARGET_MACHINE_I386     | 0x06)
-#define     LD_FORMAT_I386_PE           (LD_TARGET_MACHINE_I386     | 0x07)
-#define     LD_FORMAT_I386_ELF          (LD_TARGET_MACHINE_I386     | 0x08)
+#define     LD_FORMAT_I386_ELKS         (LD_TARGET_MACHINE_I386     | 0x05)
+#define     LD_FORMAT_I386_DX           (LD_TARGET_MACHINE_I386     | 0x06)
+#define     LD_FORMAT_I386_AOUT         (LD_TARGET_MACHINE_I386     | 0x07)
+#define     LD_FORMAT_I386_COFF         (LD_TARGET_MACHINE_I386     | 0x08)
+#define     LD_FORMAT_I386_PE           (LD_TARGET_MACHINE_I386     | 0x09)
+#define     LD_FORMAT_I386_ELF          (LD_TARGET_MACHINE_I386     | 0x10)
 
-#define     LD_FORMAT_AMD64_MACHO       (LD_TARGET_MACHINE_AMD64    | 0x09)
-#define     LD_FORMAT_AMD64_ELF         (LD_TARGET_MACHINE_AMD64    | 0x10)
+#define     LD_FORMAT_AMD64_MACHO       (LD_TARGET_MACHINE_AMD64    | 0x11)
+#define     LD_FORMAT_AMD64_ELF         (LD_TARGET_MACHINE_AMD64    | 0x12)
 
-#define     LD_FORMAT_AARCH64_MACHO     (LD_TARGET_MACHINE_AARCH64  | 0x11)
-#define     LD_FORMAT_AARCH64_ELF       (LD_TARGET_MACHINE_AARCH64  | 0x12)
+#define     LD_FORMAT_AARCH64_MACHO     (LD_TARGET_MACHINE_AARCH64  | 0x13)
+#define     LD_FORMAT_AARCH64_ELF       (LD_TARGET_MACHINE_AARCH64  | 0x14)
 
 
 extern struct ld_state *state;
diff --git a/lib.c b/lib.c
index de203f17d91ce1b25c1108235429406d8de2160d..9e670ff0c883b0aff5bc42b64e0f092e9dfff823 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -154,9 +154,9 @@ static void use_option (const char *cmd_arg, int idx, const char *optarg) {
         
         case LD_OPTION_EMULATION: {
         
-            if (xstrcasecmp (optarg, "ia16_elks") == 0) {
+            if (xstrcasecmp (optarg, "ia16_dx") == 0) {
             
-                state->emulation = LD_EMULATION_IA16_ELKS;
+                state->emulation = LD_EMULATION_IA16_DX;
                 break;
             
             }
@@ -182,9 +182,9 @@ static void use_option (const char *cmd_arg, int idx, const char *optarg) {
             
             }
             
-            if (xstrcasecmp (optarg, "i386elks") == 0) {
+            if (xstrcasecmp (optarg, "i386dx") == 0) {
             
-                state->emulation = LD_EMULATION_I386_ELKS;
+                state->emulation = LD_EMULATION_I386_DX;
                 break;
             
             }
@@ -254,13 +254,37 @@ static void use_option (const char *cmd_arg, int idx, const char *optarg) {
             
             }
             
+            if (xstrcasecmp (optarg, "dx-ia16") == 0) {
+            
+                state->format = LD_FORMAT_IA16_DX;
+                
+                if (state->emulation == LD_EMULATION_NONE) {
+                    state->emulation = LD_EMULATION_IA16_DX;
+                }
+                
+                break;
+            
+            }
+            
+            if (xstrcasecmp (optarg, "dx-i386") == 0) {
+            
+                state->format = LD_FORMAT_I386_DX;
+                
+                if (state->emulation == LD_EMULATION_NONE) {
+                    state->emulation = LD_EMULATION_I386_DX;
+                }
+                
+                break;
+            
+            }
+            
             if (xstrcasecmp (optarg, "elks-ia16") == 0) {
             
                 state->format = LD_FORMAT_IA16_ELKS;
                 
-                if (state->emulation == LD_EMULATION_NONE) {
+                /*if (state->emulation == LD_EMULATION_NONE) {
                     state->emulation = LD_EMULATION_IA16_ELKS;
-                }
+                }*/
                 
                 break;
             
@@ -270,9 +294,9 @@ static void use_option (const char *cmd_arg, int idx, const char *optarg) {
             
                 state->format = LD_FORMAT_I386_ELKS;
                 
-                if (state->emulation == LD_EMULATION_NONE) {
+                /*if (state->emulation == LD_EMULATION_NONE) {
                     state->emulation = LD_EMULATION_I386_ELKS;
-                }
+                }*/
                 
                 break;
             
@@ -466,7 +490,7 @@ uint64_t array_to_integer (unsigned char *arr, int size, int big_endian) {
     uint64_t value = 0;
     int i;
     
-#if     defined (NO_LONG_LONG) && ULONG_MAX <= 4294967295UL
+#if     defined (NO_LONG_LONG) && ((ULONG_MAX >> 16) >> 16) < 0xffffffff
     if (size == 8) { size = 4; }
 #endif
     
@@ -492,7 +516,7 @@ uint64_t array_to_integer (unsigned char *arr, int size, int big_endian) {
 
 void integer_to_array (uint64_t value, unsigned char *dest, int size, int big_endian) {
 
-#if     defined (NO_LONG_LONG) && ULONG_MAX <= 4294967295UL
+#if     defined (NO_LONG_LONG) && ((ULONG_MAX >> 16) >> 16) < 0xffffffff
     if (size == 8) { size = 4; }
 #endif
     
diff --git a/link.c b/link.c
index a3ff6ca7da7fae04709048a3908bcfdeacbcb9fb..49a0eb55e99ad7d29aa21e6c9d9d75dce9edb6fa 100644 (file)
--- a/link.c
+++ b/link.c
@@ -716,7 +716,7 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s
     
     }
     
-    if (state->emulation == LD_EMULATION_IA16_ELKS || state->emulation == LD_EMULATION_IA16_MZ) {
+    if (state->emulation == LD_EMULATION_IA16_DX || state->emulation == LD_EMULATION_IA16_MZ) {
     
         if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) {
         
@@ -1066,7 +1066,7 @@ void link (void) {
     
     }
     
-    if (state->emulation == LD_EMULATION_IA16_ELKS || state->emulation == LD_EMULATION_IA16_MZ) {
+    if (state->emulation == LD_EMULATION_IA16_DX || state->emulation == LD_EMULATION_IA16_MZ) {
     
         value = 0;
         
diff --git a/macho.c b/macho.c
index 350717db7e8eeb76f6f350ec1c137adecb176b4f..b020ad2caba0c39753724ade1778eb89b578f878 100644 (file)
--- a/macho.c
+++ b/macho.c
@@ -1044,7 +1044,30 @@ static void calculate_chained_fixups (struct chained_fixup_starts *cfs, int doin
             uint64_t result = array_to_integer (p->part->content + p->reloc_entry->offset, 8, 0);
             result -= state->base_address;
             
-#if     !defined (NO_LONG_LONG) || ULONG_MAX > 4294967295UL
+#if     defined (NO_LONG_LONG) && ((ULONG_MAX >> 16) >> 16) < 0xffffffff
+
+            integer_to_array (result, p->part->content + p->reloc_entry->offset, 4, 0);
+            
+            if (p + 1 != part_rels + num_relocs) {
+            
+                uint64_t rva1, rva2;
+                
+                rva1 = p->part->rva + p->reloc_entry->offset;
+                rva2 = p[1].part->rva + p[1].reloc_entry->offset;
+                
+                if (FLOOR_TO (rva1, PAGE_SIZE) != FLOOR_TO (rva2, PAGE_SIZE)) {
+                
+                    p++;
+                    break;
+                
+                }
+                
+                result = (((rva2 - rva1) / 4) & 0xfff) << 19;
+                integer_to_array (result, p->part->content + p->reloc_entry->offset + 4, 4, 0);
+            
+            }
+
+#else
 
             result &= 0xfffffffff;
             
@@ -1067,10 +1090,10 @@ static void calculate_chained_fixups (struct chained_fixup_starts *cfs, int doin
                 result |= (((rva2 - rva1) / 4) & 0xfff) << 51;
             
             }
-
-#endif
             
             integer_to_array (result, p->part->content + p->reloc_entry->offset, 8, 0);
+
+#endif
         
         }
     
index fc8eb0a75c73e5d6b2836582ff59e78c3ea324f3..164c7336cf2fb86b1db62de5d75d77ede2fcec72 100644 (file)
--- a/stdint.h
+++ b/stdint.h
@@ -28,7 +28,7 @@ typedef     unsigned long               uint32_t;
 
 #ifndef     _INT64_T
 #define     _INT64_T
-#if     defined (NO_LONG_LONG) || ULONG_MAX > 4294967295UL
+#if     defined (NO_LONG_LONG) || ((ULONG_MAX >> 16) >> 16) == 0xffffffff
 typedef     signed long                 int64_t;
 #else
 typedef     signed long long            int64_t;
@@ -37,7 +37,7 @@ typedef     signed long long            int64_t;
 
 #ifndef     _UINT64_T
 #define     _UINT64_T
-#if     defined (NO_LONG_LONG) || ULONG_MAX > 4294967295UL
+#if     defined (NO_LONG_LONG) || ((ULONG_MAX >> 16) >> 16) == 0xffffffff
 typedef     unsigned long               uint64_t;
 #else
 typedef     unsigned long long          uint64_t;