reloc->offset = r_offset;
reloc->addend = array_to_integer (input_reloc->r_addend, 8, endianess);
- if ((state->format & LD_TARGET_MACHINE_AMD64)) {
+ if ((state->format & LD_TARGET_MACHINE_AARCH64)) {
+
+ switch (rel_type) {
+
+ case R_AARCH64_NONE:
+
+ goto bad;
+
+ case R_AARCH64_PREL32:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_PC32];
+ reloc->addend += 4;
+
+ break;
+
+ case R_AARCH64_ABS64:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_64];
+
+ integer_to_array (0, part->content + reloc->offset, 8, endianess);
+ break;
+
+ case R_AARCH64_ABS32:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_32];
+
+ integer_to_array (0, part->content + reloc->offset, 4, endianess);
+ break;
+
+ case R_AARCH64_ADR_PREL_PG_HI21:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_ADR_PREL_PG_HI21];
+ break;
+
+ case R_AARCH64_ADD_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_ADD_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_LDST8_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_LDST8_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_LDST16_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_LDST32_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_LDST64_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_LDST64_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_LDST128_ABS_LO12_NC:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_LDST128_ABS_LO12_NC];
+ break;
+
+ case R_AARCH64_JUMP26:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_JUMP26];
+ break;
+
+ case R_AARCH64_CALL26:
+
+ reloc->howto = &reloc_howtos[RELOC_TYPE_AARCH64_CALL26];
+ break;
+
+ case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_LD64_GOT_LO12_NC:
+
+ report_at (__FILE__, __LINE__, REPORT_WARNING, "Position Independent Executables are not supported, ignoring relocation type %u", rel_type);
+ goto bad;
+
+ default:
+
+ report_at (__FILE__, __LINE__, REPORT_INTERNAL_ERROR, "+++relocation type 0x%02x not supported yet", rel_type);
+ exit (EXIT_FAILURE);
+
+ }
+
+ } else if ((state->format & LD_TARGET_MACHINE_AMD64)) {
switch (rel_type) {
#define PT_LOAD 1
#define EM_I386 3
+
#define EM_AMD64 62
+#define EM_AARCH64 183
static uint32_t translate_section_flags_to_sh_flags (uint32_t flags) {
header.e_ident[EI_VERSION] = EV_CURRENT;
integer_to_array (ET_EXEC, header.e_type, 2, 0);
- integer_to_array (EM_AMD64, header.e_machine, 2, 0);
+
+ if ((state->format & LD_TARGET_MACHINE_AARCH64)) {
+ integer_to_array (EM_AARCH64, header.e_machine, 2, 0);
+ } else if ((state->format & LD_TARGET_MACHINE_AMD64)) {
+ integer_to_array (EM_AMD64, header.e_machine, 2, 0);
+ }
+
integer_to_array (EV_CURRENT, header.e_version, 4, 0);
integer_to_array (state->entry_point + state->base_address, header.e_entry, 8, 0);
#define R_AMD64_32 10
#define R_AMD64_32S 11
+#define R_AARCH64_NONE 0
+#define R_AARCH64_ABS64 257
+#define R_AARCH64_ABS32 258
+#define R_AARCH64_PREL32 261
+#define R_AARCH64_ADR_PREL_PG_HI21 275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
+#define R_AARCH64_LDST64_ABS_LO12_NC 286
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+#define R_AARCH64_JUMP26 282
+#define R_AARCH64_CALL26 283
+#define R_AARCH64_ADR_GOT_PAGE 311
+#define R_AARCH64_LD64_GOT_LO12_NC 312
+
struct elf32_phdr {
unsigned char p_type[4];
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;
}
}
elks_before_link ();
} else if (state->format == LD_FORMAT_I386_PE) {
pe_before_link ();
- } else if (state->format == LD_FORMAT_AMD64_MACHO || state->format == LD_FORMAT_AARCH64_MACHO) {
+ } else if (state->format == LD_FORMAT_AARCH64_MACHO || state->format == LD_FORMAT_AMD64_MACHO) {
macho_before_link ();
- } else if (state->format == LD_FORMAT_AMD64_ELF || state->format == LD_FORMAT_I386_ELF) {
+ } else if (state->format == LD_FORMAT_AARCH64_ELF || state->format == LD_FORMAT_AMD64_ELF || state->format == LD_FORMAT_I386_ELF) {
elf_before_link ();
}
elks_write (state->output_filename);
} else if (state->format == LD_FORMAT_I386_ELF) {
elf32_write (state->output_filename);
- } else if (state->format == LD_FORMAT_AMD64_ELF) {
+ } 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) {
#define LD_FORMAT_AMD64_ELF (LD_TARGET_MACHINE_AMD64 | 0x10)
#define LD_FORMAT_AARCH64_MACHO (LD_TARGET_MACHINE_AARCH64 | 0x11)
+#define LD_FORMAT_AARCH64_ELF (LD_TARGET_MACHINE_AARCH64 | 0x12)
extern struct ld_state *state;
fprintf (stderr, " --help Print option help.\n");
fprintf (stderr, " --oformat FORMAT Specify the format of output file (default msdos).\n");
fprintf (stderr, " Supported formats are:\n");
- fprintf (stderr, " a.out-i386, elf-amd64, elf-i386\n");
+ fprintf (stderr, " a.out-i386, elf-aarch64\n");
+ fprintf (stderr, " elf-amd64, elf-i386\n");
fprintf (stderr, " elks-ia16, elks-i386\n");
fprintf (stderr, " macho-aarch64, macho-amd64\n");
fprintf (stderr, " pe-i386, binary, msdos\n");
}
+ if (xstrcasecmp (optarg, "elf-aarch64") == 0) {
+
+ state->format = LD_FORMAT_AARCH64_ELF;
+
+ /*if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_I386_COFF;
+ }*/
+
+ break;
+
+ }
+
report_at (program_name, 0, REPORT_ERROR, "unrecognised output format '%s'", optarg);
exit (EXIT_FAILURE);