diff options
author | Sergey Belyashov <sergey.belyashov@gmail.com> | 2020-02-07 14:53:46 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-02-07 14:53:46 +0000 |
commit | 9fc0b501af78bc4a92f53ec712e1aaa123e0224c (patch) | |
tree | f3ef7a39227828252a1878f1a526b3df19ec7c65 /bfd | |
parent | adb8754e48d53b219ddaa9e8368e4b1acb9db53a (diff) | |
download | gdb-9fc0b501af78bc4a92f53ec712e1aaa123e0224c.zip gdb-9fc0b501af78bc4a92f53ec712e1aaa123e0224c.tar.gz gdb-9fc0b501af78bc4a92f53ec712e1aaa123e0224c.tar.bz2 |
Add support for the GBZ80 and Z80N variants of the Z80 architecture, and add DWARF debug info support to the Z80 assembler.
PR 25469
bfd * archures.c: Add GBZ80 and Z80N machine values.
* reloc.c: Add BFD_RELOC_Z80_16_BE.
* coff-z80.c: Add support for new reloc.
* coffcode.h: Add support for new machine values.
* cpu-z80.c: Add support for new machine names.
* elf32-z80.c: Add support for new reloc.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
binutils* readelf.c (get_machine_flags): Add support for Z80N machine
number.
gas * config/tc-z80.c: Add -gbz80 command line option to generate code
for the GameBoy Z80. Add support for generating DWARF.
* config/tc-z80.h: Add support for DWARF debug information
generation.
* doc/c-z80.texi: Document new command line option.
* testsuite/gas/z80/gbz80_all.d: New file.
* testsuite/gas/z80/gbz80_all.s: New file.
* testsuite/gas/z80/z80.exp: Run the new tests.
* testsuite/gas/z80/z80n_all.d: New file.
* testsuite/gas/z80/z80n_all.s: New file.
* testsuite/gas/z80/z80n_reloc.d: New file.
include * coff/internal.h (R_IMM16BE): Define.
* elf/z80.h (EF_Z80_MACH_Z80N): Define.
(R_Z80_16_BE): New reloc.
ld * emulparams/elf32z80.sh: Use z80 emulation.
* emultempl/z80.em: Make generic to both COFF and ELF Z80 emulations.
* emultempl/z80elf.em: Delete.
* testsuite/ld-elf/pr22450.d: Expect to fail for the Z80.
* testsuite/ld-elf/sec64k.exp: Fix Z80 assembly.
* testsuite/ld-unique/pr21529.s: Avoid register name conflict.
* testsuite/ld-unique/unique.s: Likewise.
* testsuite/ld-unique/unique_empty.s: Likewise.
* testsuite/ld-unique/unique_shared.s: Likewise.
* testsuite/ld-unique/unique.d: Updated expected output.
* testsuite/ld-z80/arch_z80n.d: New file.
* testsuite/ld-z80/comb_arch_z80_z80n.d: New file.
* testsuite/ld-z80/labels.s: Add more labels.
* testsuite/ld-z80/relocs.s: Add more reloc tests.
* testsuite/ld-z80/relocs_f_z80n.d: New file
opcodes * z80-dis.c: Add support for GBZ80 opcodes.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/archures.c | 17 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 20 | ||||
-rw-r--r-- | bfd/coff-z80.c | 26 | ||||
-rw-r--r-- | bfd/coffcode.h | 2 | ||||
-rw-r--r-- | bfd/cpu-z80.c | 3 | ||||
-rw-r--r-- | bfd/elf32-z80.c | 350 | ||||
-rw-r--r-- | bfd/libbfd.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 4 |
9 files changed, 369 insertions, 66 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 584dd7f..96d8fe1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com> + + PR 25469 + * archures.c: Add GBZ80 and Z80N machine values. + * reloc.c: Add BFD_RELOC_Z80_16_BE. + * coff-z80.c: Add support for new reloc. + * coffcode.h: Add support for new machine values. + * cpu-z80.c: Add support for new machine names. + * elf32-z80.c: Add support for new reloc. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + 2020-02-07 Nick Clifton <nickc@redhat.com> PR 23932 diff --git a/bfd/archures.c b/bfd/archures.c index 89c7990..5789ea2 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -504,14 +504,15 @@ DESCRIPTION . bfd_arch_xtensa, {* Tensilica's Xtensa cores. *} .#define bfd_mach_xtensa 1 . bfd_arch_z80, -.#define bfd_mach_gbz80 0 {* GameBoy Z80 (reduced instruction set) *} -.#define bfd_mach_z80strict 1 {* Z80 without undocumented opcodes. *} -.#define bfd_mach_z180 2 {* Z180: successor with additional instructions, but without halves of ix and iy *} -.#define bfd_mach_z80 3 {* Z80 with ixl, ixh, iyl, and iyh. *} -.#define bfd_mach_ez80_z80 4 {* eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode *} -.#define bfd_mach_ez80_adl 5 {* eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode *} -.#define bfd_mach_z80full 7 {* Z80 with all undocumented instructions. *} -.#define bfd_mach_r800 11 {* R800: successor with multiplication. *} +.#define bfd_mach_z80strict 1 {* Zilog Z80 without undocumented opcodes. *} +.#define bfd_mach_z180 2 {* Zilog Z180: successor with additional instructions, but without halves of ix and iy *} +.#define bfd_mach_z80 3 {* Zilog Z80 with ixl, ixh, iyl, and iyh. *} +.#define bfd_mach_ez80_z80 4 {* Zilog eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode *} +.#define bfd_mach_ez80_adl 5 {* Zilog eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode *} +.#define bfd_mach_z80n 6 {* Z80N *} +.#define bfd_mach_z80full 7 {* Zilog Z80 with all undocumented instructions. *} +.#define bfd_mach_gbz80 8 {* GameBoy Z80 (reduced instruction set) *} +.#define bfd_mach_r800 11 {* Ascii R800: successor with multiplication. *} . bfd_arch_lm32, {* Lattice Mico32. *} .#define bfd_mach_lm32 1 . bfd_arch_microblaze,{* Xilinx MicroBlaze. *} diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 2d26b81..180383b 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1897,14 +1897,15 @@ enum bfd_architecture bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ #define bfd_mach_xtensa 1 bfd_arch_z80, -#define bfd_mach_gbz80 0 /* GameBoy Z80 (reduced instruction set) */ -#define bfd_mach_z80strict 1 /* Z80 without undocumented opcodes. */ -#define bfd_mach_z180 2 /* Z180: successor with additional instructions, but without halves of ix and iy */ -#define bfd_mach_z80 3 /* Z80 with ixl, ixh, iyl, and iyh. */ -#define bfd_mach_ez80_z80 4 /* eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode */ -#define bfd_mach_ez80_adl 5 /* eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode */ -#define bfd_mach_z80full 7 /* Z80 with all undocumented instructions. */ -#define bfd_mach_r800 11 /* R800: successor with multiplication. */ +#define bfd_mach_z80strict 1 /* Zilog Z80 without undocumented opcodes. */ +#define bfd_mach_z180 2 /* Zilog Z180: successor with additional instructions, but without halves of ix and iy */ +#define bfd_mach_z80 3 /* Zilog Z80 with ixl, ixh, iyl, and iyh. */ +#define bfd_mach_ez80_z80 4 /* Zilog eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode */ +#define bfd_mach_ez80_adl 5 /* Zilog eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode */ +#define bfd_mach_z80n 6 /* Z80N */ +#define bfd_mach_z80full 7 /* Zilog Z80 with all undocumented instructions. */ +#define bfd_mach_gbz80 8 /* GameBoy Z80 (reduced instruction set) */ +#define bfd_mach_r800 11 /*Ascii R800: Z80 successor with multiplication. */ bfd_arch_lm32, /* Lattice Mico32. */ #define bfd_mach_lm32 1 bfd_arch_microblaze,/* Xilinx MicroBlaze. */ @@ -5301,6 +5302,9 @@ BFD_RELOC_XTENSA_ASM_EXPAND. */ /* Highest 16 bits of multibyte (32 or 24 bit) value. */ BFD_RELOC_Z80_WORD1, +/* 16 bit word big endian */ + BFD_RELOC_Z80_16_BE, + /* DJNZ offset. */ BFD_RELOC_Z8K_DISP7, diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c index bb519fd..8913fb5 100644 --- a/bfd/coff-z80.c +++ b/bfd/coff-z80.c @@ -221,6 +221,21 @@ static bfd_howto_type howto_table[] = 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + BFD_HOWTO (BFD_RELOC_Z80_16_BE, + R_IMM16BE, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "r_imm16be", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; #define NUM_HOWTOS ARRAY_SIZE (howto_table) @@ -421,6 +436,17 @@ extra_case (bfd *in_abfd, break; } + case R_IMM16BE: + if (reloc->howto->partial_inplace) + val += (bfd_get_8 ( in_abfd, data+*src_ptr+0) * 0x100 + + bfd_get_8 ( in_abfd, data+*src_ptr+1)) & reloc->howto->src_mask; + + bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr+0); + bfd_put_8 (in_abfd, val, data + *dst_ptr+1); + (*dst_ptr) += 2; + (*src_ptr) += 2; + break; + default: abort (); } diff --git a/bfd/coffcode.h b/bfd/coffcode.h index dec2e9c..96a7f20 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2163,6 +2163,7 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) { case bfd_mach_z80strict << 12: case bfd_mach_z80 << 12: + case bfd_mach_z80n << 12: case bfd_mach_z80full << 12: case bfd_mach_r800 << 12: case bfd_mach_gbz80 << 12: @@ -2655,6 +2656,7 @@ coff_set_flags (bfd * abfd, { case bfd_mach_z80strict: case bfd_mach_z80: + case bfd_mach_z80n: case bfd_mach_z80full: case bfd_mach_r800: case bfd_mach_gbz80: diff --git a/bfd/cpu-z80.c b/bfd/cpu-z80.c index 96fcfa3..76f2ff6 100644 --- a/bfd/cpu-z80.c +++ b/bfd/cpu-z80.c @@ -54,7 +54,8 @@ static const bfd_arch_info_type arch_info_struct[] = N (bfd_mach_r800, "r800", 16, FALSE, M(4)), N (bfd_mach_gbz80, "gbz80", 16, FALSE, M(5)), N (bfd_mach_z180, "z180", 16, FALSE, M(6)), - N (bfd_mach_ez80_z80, "ez80-z80", 16, FALSE, M(7)), + N (bfd_mach_z80n, "z80n", 16, FALSE, M(7)), + N (bfd_mach_ez80_z80, "ez80-z80", 16, FALSE, M(8)), N (bfd_mach_ez80_adl, "ez80-adl", 24, FALSE, NULL) }; diff --git a/bfd/elf32-z80.c b/bfd/elf32-z80.c index 888606e..89089f5 100644 --- a/bfd/elf32-z80.c +++ b/bfd/elf32-z80.c @@ -30,12 +30,6 @@ /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ #define OCTETS_PER_BYTE(ABFD, SEC) 1 -/* Relocation functions. */ -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - (bfd *, bfd_reloc_code_real_type); -static bfd_boolean z80_info_to_howto_rel - (bfd *, arelent *, Elf_Internal_Rela *); - typedef struct { bfd_reloc_code_real_type r_type; reloc_howto_type howto; @@ -44,6 +38,11 @@ typedef struct { #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)} #define BFD_HOWTO(rt,a,b,c,d,e,f,g,h,i,j,k,l,m) {rt, HOWTO(a,b,c,d,e,f,g,h,i,j,k,l,m)} +static bfd_reloc_status_type +z80_elf_16_be_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message); + static const bfd_howto_type elf_z80_howto_table[] = { @@ -253,11 +252,27 @@ bfd_howto_type elf_z80_howto_table[] = 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* An 16 bit big endian absolute relocation */ + BFD_HOWTO (BFD_RELOC_Z80_16_BE, + R_Z80_16_BE, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + z80_elf_16_be_reloc, /* special_function */ + "r_imm16be", /* name */ + FALSE, /* partial_inplace */ + 0x00000000, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, - bfd_reloc_code_real_type code) +z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { enum { @@ -268,16 +283,16 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, for (i = 0; i < table_size; i++) { if (elf_z80_howto_table[i].r_type == code) - return &elf_z80_howto_table[i].howto; + return &elf_z80_howto_table[i].howto; } - printf ("%s:%d Not found type %d\n", __FILE__, __LINE__, code); + printf ("%s:%d Not found BFD reloc type %d\n", __FILE__, __LINE__, code); return NULL; } static reloc_howto_type * -bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) +z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) { enum { @@ -288,82 +303,308 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) for (i = 0; i < table_size; i++) { if (elf_z80_howto_table[i].howto.name != NULL - && strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0) - return &elf_z80_howto_table[i].howto; + && strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0) + return &elf_z80_howto_table[i].howto; } + printf ("%s:%d Not found ELF reloc name `%s'\n", __FILE__, __LINE__, r_name); + return NULL; } -/* Set the howto pointer for an z80 ELF reloc. */ - -static bfd_boolean -z80_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) +static reloc_howto_type * +z80_rtype_to_howto (bfd *abfd, unsigned r_type) { enum { table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0]) }; - unsigned int i; - unsigned int r_type = ELF32_R_TYPE (dst->r_info); + unsigned int i; for (i = 0; i < table_size; i++) { if (elf_z80_howto_table[i].howto.type == r_type) - { - cache_ptr->howto = &elf_z80_howto_table[i].howto; - return TRUE; - } + return &elf_z80_howto_table[i].howto; } /* xgettext:c-format */ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), - abfd, r_type); + abfd, r_type); + return NULL; +} + +/* Set the howto pointer for an z80 ELF reloc. */ + +static bfd_boolean +z80_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) +{ + unsigned int r_type = ELF32_R_TYPE (dst->r_info); + reloc_howto_type *howto = z80_rtype_to_howto (abfd, r_type); + if (howto != NULL) + { + cache_ptr->howto = howto; + return TRUE; + } bfd_set_error (bfd_error_bad_value); return FALSE; } +static bfd_reloc_status_type +z80_elf_final_link_relocate (unsigned long r_type, + bfd *input_bfd, + bfd *output_bfd ATTRIBUTE_UNUSED, + asection *input_section ATTRIBUTE_UNUSED, + bfd_byte *contents, + bfd_vma offset, + bfd_vma value, + bfd_vma addend, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sym_sec ATTRIBUTE_UNUSED, + int is_local ATTRIBUTE_UNUSED) +{ + bfd_boolean r; + reloc_howto_type *howto; + + switch (r_type) + { + case R_Z80_16_BE: + value += addend; + bfd_put_8 (input_bfd, value >> 8, contents + offset + 0); + bfd_put_8 (input_bfd, value >> 0, contents + offset + 1); + return bfd_reloc_ok; + } + + howto = z80_rtype_to_howto (input_bfd, r_type); + if (howto == NULL) + return bfd_reloc_notsupported; + + r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, + offset, value, addend); + return r ? bfd_reloc_ok : bfd_reloc_notsupported; +} + +static bfd_boolean +z80_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + Elf_Internal_Rela *rel, *relend; + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + + rel = relocs; + relend = relocs + input_section->reloc_count; + for (; rel < relend; rel++) + { + unsigned int r_type; + unsigned long r_symndx; + Elf_Internal_Sym *sym; + asection *sec; + struct elf_link_hash_entry *h; + bfd_vma relocation; + + /* This is a final link. */ + r_symndx = ELF32_R_SYM (rel->r_info); + r_type = ELF32_R_TYPE (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + } + else + { + bfd_boolean unresolved_reloc, warned, ignored; + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, warned, ignored); + } + + if (sec != NULL && discarded_section (sec)) + { + /* For relocs against symbols from removed linkonce sections, + or sections discarded by a linker script, we just want the + section contents cleared. Avoid any special processing. */ + reloc_howto_type *howto; + howto = z80_rtype_to_howto (input_bfd, r_type); + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, 1, relend, howto, 0, contents); + } + + if (bfd_link_relocatable (info)) + continue; + + + z80_elf_final_link_relocate (r_type, input_bfd, output_bfd, + input_section, + contents, rel->r_offset, + relocation, rel->r_addend, + info, sec, h == NULL); + } + + return TRUE; +} + +/* The final processing done just before writing out a Z80 ELF object + file. This gets the Z80 architecture right based on the machine + number. */ + static bfd_boolean -z80_elf_set_mach_from_flags (bfd *abfd) +z80_elf_final_write_processing (bfd *abfd) { - int mach; - switch (elf_elfheader (abfd)->e_flags) + unsigned long val = bfd_get_mach (abfd); + + switch (val) { - case EF_Z80_MACH_GBZ80: - mach = bfd_mach_gbz80; + default: + _bfd_error_handler (_("%pB: unsupported bfd mach %#lx"), + abfd, val); + /* fall through */ + case bfd_mach_z80: + case bfd_mach_z80full: + case bfd_mach_z80strict: + val = EF_Z80_MACH_Z80; break; - case EF_Z80_MACH_Z80: - mach = bfd_mach_z80; + case bfd_mach_gbz80: + val = EF_Z80_MACH_GBZ80; break; - case EF_Z80_MACH_Z180: - mach = bfd_mach_z180; + case bfd_mach_z80n: + val = EF_Z80_MACH_Z80N; break; - case EF_Z80_MACH_EZ80_Z80: - mach = bfd_mach_ez80_z80; + case bfd_mach_z180: + val = EF_Z80_MACH_Z180; break; - case EF_Z80_MACH_EZ80_ADL: - mach = bfd_mach_ez80_adl; + case bfd_mach_ez80_z80: + val = EF_Z80_MACH_EZ80_Z80; break; - case EF_Z80_MACH_R800: - mach = bfd_mach_r800; + case bfd_mach_ez80_adl: + val = EF_Z80_MACH_EZ80_ADL; break; - default: - mach = bfd_mach_z80; + case bfd_mach_r800: + val = EF_Z80_MACH_R800; break; } + elf_elfheader (abfd)->e_machine = EM_Z80; + elf_elfheader (abfd)->e_flags &= ~EF_Z80_MACH_MSK; + elf_elfheader (abfd)->e_flags |= val; + return _bfd_elf_final_write_processing (abfd); +} - bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach); - return TRUE; +/* Set the right machine number. */ +static bfd_boolean +z80_elf_object_p (bfd *abfd) +{ + unsigned int mach; + + if (elf_elfheader (abfd)->e_machine == EM_Z80) + { + int e_mach = elf_elfheader (abfd)->e_flags & EF_Z80_MACH_MSK; + switch (e_mach) + { + default: + _bfd_error_handler (_("%pB: unsupported mach %#x"), + abfd, e_mach); + /* fall through */ + case EF_Z80_MACH_Z80: + mach = bfd_mach_z80; + break; + case EF_Z80_MACH_GBZ80: + mach = bfd_mach_gbz80; + break; + case EF_Z80_MACH_Z180: + mach = bfd_mach_z180; + break; + case EF_Z80_MACH_EZ80_Z80: + mach = bfd_mach_ez80_z80; + break; + case EF_Z80_MACH_EZ80_ADL: + mach = bfd_mach_ez80_adl; + break; + case EF_Z80_MACH_R800: + mach = bfd_mach_r800; + break; + case EF_Z80_MACH_Z80N: + mach = bfd_mach_z80n; + break; + } + } + else + { + _bfd_error_handler (_("%pB: unsupported arch %#x"), + abfd, elf_elfheader (abfd)->e_machine); + mach = bfd_mach_z80; + } + return bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach); } static int -z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, - const char * name) +z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, + const char * name) { return (name[0] == '.' && name[1] == 'L') || - _bfd_elf_is_local_label_name (abfd, name); + _bfd_elf_is_local_label_name (abfd, name); } +static bfd_reloc_status_type +z80_elf_16_be_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void *data, + asection *input_section, + bfd *output_bfd, + char **error_message) +{ + bfd_vma val; + long x; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* Get symbol value. */ + val = 0; + if (!bfd_is_com_section (symbol->section)) + val = symbol->value; + val += symbol->section->output_offset + input_section->output_offset; + if (symbol->section->output_section) + val += symbol->section->output_section->vma; + + val += reloc_entry->addend; + if (reloc_entry->howto->partial_inplace) + { + x = bfd_get_8 (abfd, (bfd_byte *) data + octets + 0) * 0x100; + x += bfd_get_8 (abfd, (bfd_byte *) data + octets + 1); + x &= ~reloc_entry->howto->src_mask; + } + else + x = 0; + + x |= val & reloc_entry->howto->dst_mask; + if (x < -0x8000 || x >= 0x10000) + return bfd_reloc_outofrange; + + bfd_put_8 (abfd, x >> 8, (bfd_byte *) data + octets + 0); + bfd_put_8 (abfd, x >> 0, (bfd_byte *) data + octets + 1); + return bfd_reloc_ok; +} #define ELF_ARCH bfd_arch_z80 #define ELF_MACHINE_CODE EM_Z80 @@ -372,9 +613,20 @@ z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, #define TARGET_LITTLE_SYM z80_elf32_vec #define TARGET_LITTLE_NAME "elf32-z80" -#define elf_info_to_howto NULL -#define elf_info_to_howto_rel z80_info_to_howto_rel -#define elf_backend_object_p z80_elf_set_mach_from_flags +#define elf_backend_can_refcount 1 +#define elf_backend_can_gc_sections 1 +#define elf_backend_stack_align 1 +#define elf_backend_rela_normal 1 + +#define elf_info_to_howto z80_info_to_howto_rela +#define elf_info_to_howto_rel z80_info_to_howto_rela + +#define elf_backend_final_write_processing z80_elf_final_write_processing +#define elf_backend_object_p z80_elf_object_p +#define elf_backend_relocate_section z80_elf_relocate_section + +#define bfd_elf32_bfd_reloc_type_lookup z80_reloc_type_lookup +#define bfd_elf32_bfd_reloc_name_lookup z80_reloc_name_lookup #define bfd_elf32_bfd_is_local_label_name z80_is_local_label_name #include "elf32-target.h" diff --git a/bfd/libbfd.h b/bfd/libbfd.h index d97d4e5..a3684a9 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2875,6 +2875,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_Z80_BYTE3", "BFD_RELOC_Z80_WORD0", "BFD_RELOC_Z80_WORD1", + "BFD_RELOC_Z80_16_BE", "BFD_RELOC_Z8K_DISP7", "BFD_RELOC_Z8K_CALLR", "BFD_RELOC_Z8K_IMM4L", diff --git a/bfd/reloc.c b/bfd/reloc.c index 33cd671..dab7d17 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -6697,6 +6697,10 @@ ENUM BFD_RELOC_Z80_WORD1 ENUMDOC Highest 16 bits of multibyte (32 or 24 bit) value. +ENUM + BFD_RELOC_Z80_16_BE +ENUMDOC + Like BFD_RELOC_16 but big-endian. ENUM BFD_RELOC_Z8K_DISP7 |