From: Robert Pengelly Date: Mon, 26 Jan 2026 23:55:30 +0000 (+0000) Subject: Bug fixes and don't extend ELKS format X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=ddd99c511231325df563e5f17aec93e6244723ab;p=slink.git Bug fixes and don't extend ELKS format --- diff --git a/Makefile.unix b/Makefile.unix index 88ebe51..7778788 100644 --- a/Makefile.unix +++ b/Makefile.unix @@ -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 diff --git a/Makefile.w32 b/Makefile.w32 index 00e19da..5cccc57 100644 --- a/Makefile.w32 +++ b/Makefile.w32 @@ -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 diff --git a/Makefile.wat b/Makefile.wat index daa5883..026fb80 100644 --- a/Makefile.wat +++ b/Makefile.wat @@ -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 index 0000000..589f74e --- /dev/null +++ b/dx.c @@ -0,0 +1,239 @@ +/****************************************************************************** + * @file dx.c + *****************************************************************************/ +#include +#include +#include + +#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 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 121c552..16e215b 100644 --- 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 eb4a337..e822019 100644 --- 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 0dbfe7f..1757499 100644 --- 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 babd6fa..ce20b9e 100644 --- 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); diff --git a/inttypes.h b/inttypes.h index 34d387c..2ff8fed 100644 --- a/inttypes.h +++ b/inttypes.h @@ -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 98fefa2..796e721 100644 --- 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 5901f96..68db48e 100644 --- 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 de203f1..9e670ff 100644 --- 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 a3ff6ca..49a0eb5 100644 --- 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 350717d..b020ad2 100644 --- 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 } diff --git a/stdint.h b/stdint.h index fc8eb0a..164c733 100644 --- 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;