ATMEL AVR microcontroller support.

This commit is contained in:
Alan Modra 2000-03-27 08:39:14 +00:00
parent e7d0728ac1
commit adde6300e0
46 changed files with 5599 additions and 1529 deletions

View File

@ -1,3 +1,29 @@
2000-03-27 Alan Modra <alan@linuxcare.com>
* elf32-avr.c (elf32_avr_gc_mark_hook, elf32_avr_gc_sweep_hook,
elf32_avr_check_relocs, avr_final_link_relocate,
elf32_avr_relocate_section, bfd_elf_avr_final_write_processing,
elf32_avr_object_p): Add prototypes.
(elf32_avr_gc_mark_hook): Add default for h->root.type.
(bfd_elf_avr_final_write_processing): Make static.
2000-03-27 Denis Chertykov <denisc@overta.ru>
* cpu-avr.c: New file. BFD support routines for AVR architecture.
* archures.c (bfd_architecture): Add AVR architecture.
(bfd_archures_list): Add reference to AVR architecture info.
* elf.c (prep_headers): Handle bfd_arch_avr.
* reloc.c: Add various AVR relocation enums.
* targets.c (bfd_elf32_avr_vec): Declare and add to target vector
list.
* Makefile.am: Add support for AVR elf.
* configure.in: Likewise.
* config.bfd: Likewise.
* Makefile.in: Regenerate.
* configure: This too.
* bfd-in2.h: And this.
* libbfd.h: And this.
2000-03-24 H.J. Lu <hjl@gnu.org>
* elf64-alpha.c (elf64_alpha_merge_ind_symbols): Add prototype.

View File

@ -41,6 +41,7 @@ ALL_MACHINES = \
cpu-alpha.lo \
cpu-arc.lo \
cpu-arm.lo \
cpu-avr.lo \
cpu-d10v.lo \
cpu-d30v.lo \
cpu-fr30.lo \
@ -77,6 +78,7 @@ ALL_MACHINES_CFILES = \
cpu-alpha.c \
cpu-arc.c \
cpu-arm.c \
cpu-avr.c \
cpu-d10v.c \
cpu-d30v.c \
cpu-fr30.c \
@ -157,6 +159,7 @@ BFD32_BACKENDS = \
elf32-arc.lo \
elfarm-oabi.lo \
elfarm-nabi.lo \
elf32-avr.lo \
elf32-d10v.lo \
elf32-d30v.lo \
elf32-fr30.lo \
@ -286,6 +289,7 @@ BFD32_BACKENDS_CFILES = \
elf32-arc.c \
elfarm-oabi.c \
elfarm-nabi.c \
elf32-avr.c \
elf32-d10v.c \
elf32-d30v.c \
elf32-fr30.c \
@ -693,6 +697,7 @@ cpu-a29k.lo: cpu-a29k.c
cpu-alpha.lo: cpu-alpha.c
cpu-arc.lo: cpu-arc.c
cpu-arm.lo: cpu-arm.c
cpu-avr.lo: cpu-avr.c
cpu-d10v.lo: cpu-d10v.c
cpu-d30v.lo: cpu-d30v.c
cpu-fr30.lo: cpu-fr30.c
@ -851,6 +856,9 @@ elfarm-nabi.lo: elfarm-nabi.c $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h \
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf32-arm.h \
elf32-target.h
elf32-avr.lo: elf32-avr.c elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
$(INCDIR)/elf/avr.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
elf32-d10v.lo: elf32-d10v.c elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
elf32-target.h

View File

@ -156,6 +156,7 @@ ALL_MACHINES = \
cpu-alpha.lo \
cpu-arc.lo \
cpu-arm.lo \
cpu-avr.lo \
cpu-d10v.lo \
cpu-d30v.lo \
cpu-fr30.lo \
@ -193,6 +194,7 @@ ALL_MACHINES_CFILES = \
cpu-alpha.c \
cpu-arc.c \
cpu-arm.c \
cpu-avr.c \
cpu-d10v.c \
cpu-d30v.c \
cpu-fr30.c \
@ -274,6 +276,7 @@ BFD32_BACKENDS = \
elf32-arc.lo \
elfarm-oabi.lo \
elfarm-nabi.lo \
elf32-avr.lo \
elf32-d10v.lo \
elf32-d30v.lo \
elf32-fr30.lo \
@ -404,6 +407,7 @@ BFD32_BACKENDS_CFILES = \
elf32-arc.c \
elfarm-oabi.c \
elfarm-nabi.c \
elf32-avr.c \
elf32-d10v.c \
elf32-d30v.c \
elf32-fr30.c \
@ -1221,6 +1225,7 @@ cpu-a29k.lo: cpu-a29k.c
cpu-alpha.lo: cpu-alpha.c
cpu-arc.lo: cpu-arc.c
cpu-arm.lo: cpu-arm.c
cpu-avr.lo: cpu-avr.c
cpu-d10v.lo: cpu-d10v.c
cpu-d30v.lo: cpu-d30v.c
cpu-fr30.lo: cpu-fr30.c
@ -1379,6 +1384,9 @@ elfarm-nabi.lo: elfarm-nabi.c $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h \
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf32-arm.h \
elf32-target.h
elf32-avr.lo: elf32-avr.c elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
$(INCDIR)/elf/avr.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
elf32-d10v.lo: elf32-d10v.c elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
elf32-target.h

View File

@ -199,6 +199,11 @@ DESCRIPTION
.#define bfd_mach_fr30 0x46523330
. bfd_arch_mcore,
. bfd_arch_pj,
. bfd_arch_avr, {* Atmel AVR microcontrollers *}
.#define bfd_mach_avr1 1
.#define bfd_mach_avr2 2
.#define bfd_mach_avr3 3
.#define bfd_mach_avr4 4
. bfd_arch_last
. };
@ -271,6 +276,7 @@ extern const bfd_arch_info_type bfd_w65_arch;
extern const bfd_arch_info_type bfd_v850_arch;
extern const bfd_arch_info_type bfd_fr30_arch;
extern const bfd_arch_info_type bfd_mcore_arch;
extern const bfd_arch_info_type bfd_avr_arch;
static const bfd_arch_info_type * const bfd_archures_list[] =
{
@ -309,7 +315,8 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
&bfd_w65_arch,
&bfd_v850_arch,
&bfd_fr30_arch,
& bfd_mcore_arch,
&bfd_mcore_arch,
&bfd_avr_arch,
#endif
0
};

View File

@ -1415,6 +1415,11 @@ enum bfd_architecture
#define bfd_mach_fr30 0x46523330
bfd_arch_mcore,
bfd_arch_pj,
bfd_arch_avr, /* Atmel AVR microcontrollers */
#define bfd_mach_avr1 1
#define bfd_mach_avr2 2
#define bfd_mach_avr3 3
#define bfd_mach_avr4 4
bfd_arch_last
};
@ -1624,7 +1629,7 @@ struct reloc_howto_struct
/* The src_mask selects which parts of the read in data
are to be used in the relocation sum. E.g., if this was an 8 bit
bit of data which we read and relocated, this would be
byte of data which we read and relocated, this would be
0x000000ff. When we have relocs which have an addend, such as
sun4 extended relocs, the value in the offset part of a
relocating field is garbage so we never use it. In this case
@ -2123,39 +2128,39 @@ assumed to be 0. */
This is a 6-bit absolute reloc. */
BFD_RELOC_D30V_6,
/* This is a 6-bit pc-relative reloc with
/* This is a 6-bit pc-relative reloc with
the right 3 bits assumed to be 0. */
BFD_RELOC_D30V_9_PCREL,
/* This is a 6-bit pc-relative reloc with
/* This is a 6-bit pc-relative reloc with
the right 3 bits assumed to be 0. Same
as the previous reloc but on the right side
of the container. */
BFD_RELOC_D30V_9_PCREL_R,
/* This is a 12-bit absolute reloc with the
/* This is a 12-bit absolute reloc with the
right 3 bitsassumed to be 0. */
BFD_RELOC_D30V_15,
/* This is a 12-bit pc-relative reloc with
/* This is a 12-bit pc-relative reloc with
the right 3 bits assumed to be 0. */
BFD_RELOC_D30V_15_PCREL,
/* This is a 12-bit pc-relative reloc with
/* This is a 12-bit pc-relative reloc with
the right 3 bits assumed to be 0. Same
as the previous reloc but on the right side
of the container. */
BFD_RELOC_D30V_15_PCREL_R,
/* This is an 18-bit absolute reloc with
/* This is an 18-bit absolute reloc with
the right 3 bits assumed to be 0. */
BFD_RELOC_D30V_21,
/* This is an 18-bit pc-relative reloc with
/* This is an 18-bit pc-relative reloc with
the right 3 bits assumed to be 0. */
BFD_RELOC_D30V_21_PCREL,
/* This is an 18-bit pc-relative reloc with
/* This is an 18-bit pc-relative reloc with
the right 3 bits assumed to be 0. Same
as the previous reloc but on the right side
of the container. */
@ -2303,7 +2308,75 @@ short offset into 11 bits. */
BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2,
BFD_RELOC_MCORE_RVA,
/* These two relocations are used by the linker to determine which of
/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative
short offset into 7 bits. */
BFD_RELOC_AVR_7_PCREL,
/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative
short offset into 12 bits. */
BFD_RELOC_AVR_13_PCREL,
/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually
program memory address) into 16 bits. */
BFD_RELOC_AVR_16_PM,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
data memory address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_LO8_LDI,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
of data memory address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_HI8_LDI,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of program memory address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_HH8_LDI,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(usually data memory address) into 8 bit immediate value of SUBI insn. */
BFD_RELOC_AVR_LO8_LDI_NEG,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 8 bit of data memory address) into 8 bit immediate value of
SUBI insn. */
BFD_RELOC_AVR_HI8_LDI_NEG,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(most high 8 bit of program memory address) into 8 bit immediate value
of LDI or SUBI insn. */
BFD_RELOC_AVR_HH8_LDI_NEG,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
command address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_LO8_LDI_PM,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
of command address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_HI8_LDI_PM,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of command address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_HH8_LDI_PM,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(usually command address) into 8 bit immediate value of SUBI insn. */
BFD_RELOC_AVR_LO8_LDI_PM_NEG,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 8 bit of 16 bit command address) into 8 bit immediate value
of SUBI insn. */
BFD_RELOC_AVR_HI8_LDI_PM_NEG,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 6 bit of 22 bit command address) into 8 bit immediate
value of SUBI insn. */
BFD_RELOC_AVR_HH8_LDI_PM_NEG,
/* This is a 32 bit reloc for the AVR that stores 23 bit value
into 22 bits. */
BFD_RELOC_AVR_CALL,
/* These two relocations are used by the linker to determine which of
the entries in a C++ virtual function table are actually used. When
the --gc-sections option is given, the linker will zero out the entries
that are not used, so that the code for those functions need not be
@ -2317,7 +2390,7 @@ relocation should be located at the child vtable.
VTABLE_ENTRY is a zero-space relocation that describes the use of a
virtual function table entry. The reloc's symbol should refer to the
table of the class mentioned in the code. Off of that base, an offset
describes the entry that is being used. For Rela hosts, this offset
describes the entry that is being used. For Rela hosts, this offset
is stored in the reloc's addend. For Rel hosts, we are forced to put
this offset in the reloc's section offset. */
BFD_RELOC_VTABLE_INHERIT,

View File

@ -175,6 +175,10 @@ case "${targ}" in
targ_underscore=yes
;;
avr-*-*)
targ_defvec=bfd_elf32_avr_vec
;;
c30-*-*aout* | tic30-*-*aout*)
targ_defvec=tic30_aout_vec
;;

953
bfd/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -439,6 +439,7 @@ do
b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"
target64=true ;;
bfd_elf32_avr_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;;
bfd_elf32_littlearc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
bfd_elf32_littlearm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;;
bfd_elf32_littlearm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;

89
bfd/cpu-avr.c Normal file
View File

@ -0,0 +1,89 @@
/* BFD library support routines for the AVR architecture.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
static const bfd_arch_info_type *compatible
PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
#define N(addr_bits, machine, print, default, next) \
{ \
8, /* 8 bits in a word */ \
addr_bits, /* bits in an address */ \
8, /* 8 bits in a byte */ \
bfd_arch_avr, \
machine, /* machine */ \
"avr", /* arch_name */ \
print, /* printable name */ \
1, /* section align power */ \
default, /* the default machine */ \
compatible, \
bfd_default_scan, \
next \
}
static const bfd_arch_info_type arch_info_struct[] =
{
/* AT90S1200 */
N (16, bfd_mach_avr1, "avr:1", false, & arch_info_struct[1]),
/* AT90S2xxx, AT90S4xxx, AT90S81xx, ATtiny22 */
N (16, bfd_mach_avr2, "avr:2", false, & arch_info_struct[2]),
/* ATmega103, ATmega603 */
N (22, bfd_mach_avr3, "avr:3", false, & arch_info_struct[3]),
/* ATmega161 */
N (16, bfd_mach_avr4, "avr:4", false, NULL)
};
const bfd_arch_info_type bfd_avr_arch =
N (16, bfd_mach_avr2, "avr", true, & arch_info_struct[0]);
/* This routine is provided two arch_infos and works out which AVR
machine which would be compatible with both and returns a pointer
to its info structure. */
static const bfd_arch_info_type *
compatible (a,b)
const bfd_arch_info_type * a;
const bfd_arch_info_type * b;
{
/* If a & b are for different architectures we can do nothing. */
if (a->arch != b->arch)
return NULL;
/* Special case for ATmega[16]03 (avr:3) and ATmega161 (avr:4). */
if ((a->mach == 3 && b->mach == 4)
|| (a->mach == 4 && b->mach == 3))
return NULL;
/* So far all newer AVR architecture cores are supersets of previous
cores. */
if (a->mach <= b->mach)
return b;
/* Never reached! */
return NULL;
}

View File

@ -3276,6 +3276,9 @@ prep_headers (abfd)
case bfd_arch_mcore:
i_ehdrp->e_machine = EM_MCORE;
break;
case bfd_arch_avr:
i_ehdrp->e_machine = EM_AVR;
break;
case bfd_arch_v850:
switch (bfd_get_mach (abfd))
{

963
bfd/elf32-avr.c Normal file
View File

@ -0,0 +1,963 @@
/* AVR-specific support for 32-bit ELF
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/avr.h"
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
static void avr_info_to_howto_rela
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
static asection *elf32_avr_gc_mark_hook
PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *));
static boolean elf32_avr_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
static boolean elf32_avr_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
static bfd_reloc_status_type avr_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, bfd_vma));
static boolean elf32_avr_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static void bfd_elf_avr_final_write_processing PARAMS ((bfd *, boolean));
static boolean elf32_avr_object_p PARAMS ((bfd *));
/* Use RELA instead of REL */
#undef USE_REL
static reloc_howto_type elf_avr_howto_table[] =
{
HOWTO (R_AVR_NONE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_NONE", /* name */
false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
false), /* pcrel_offset */
HOWTO (R_AVR_32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_32", /* name */
false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
/* A 7 bit PC relative relocation. */
HOWTO (R_AVR_7_PCREL, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
7, /* bitsize */
true, /* pc_relative */
3, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_7_PCREL", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
true), /* pcrel_offset */
/* A 13 bit PC relative relocation. */
HOWTO (R_AVR_13_PCREL, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
13, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_13_PCREL", /* name */
false, /* partial_inplace */
0xfff, /* src_mask */
0xfff, /* dst_mask */
true), /* pcrel_offset */
/* A 16 bit absolute relocation. */
HOWTO (R_AVR_16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_16", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A 16 bit absolute relocation for command address. */
HOWTO (R_AVR_16_PM, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_16_PM", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A low 8 bit absolute relocation of 16 bit address.
For LDI command. */
HOWTO (R_AVR_LO8_LDI, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_LO8_LDI", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 8 bit absolute relocation of 16 bit address.
For LDI command. */
HOWTO (R_AVR_HI8_LDI, /* type */
8, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HI8_LDI", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 6 bit absolute relocation of 22 bit address.
For LDI command. */
HOWTO (R_AVR_HH8_LDI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HH8_LDI", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A negative low 8 bit absolute relocation of 16 bit address.
For LDI command. */
HOWTO (R_AVR_LO8_LDI_NEG, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_LO8_LDI_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A hegative high 8 bit absolute relocation of 16 bit address.
For LDI command. */
HOWTO (R_AVR_HI8_LDI_NEG, /* type */
8, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HI8_LDI_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A hegative high 6 bit absolute relocation of 22 bit address.
For LDI command. */
HOWTO (R_AVR_HH8_LDI_NEG, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HH8_LDI_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A low 8 bit absolute relocation of 24 bit program memory address.
For LDI command. */
HOWTO (R_AVR_LO8_LDI_PM, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_LO8_LDI_PM", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 8 bit absolute relocation of 16 bit program memory address.
For LDI command. */
HOWTO (R_AVR_HI8_LDI_PM, /* type */
9, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HI8_LDI_PM", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 8 bit absolute relocation of 24 bit program memory address.
For LDI command. */
HOWTO (R_AVR_HH8_LDI_PM, /* type */
17, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HH8_LDI_PM", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A low 8 bit absolute relocation of a negative 24 bit
program memory address. For LDI command. */
HOWTO (R_AVR_LO8_LDI_PM_NEG, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_LO8_LDI_PM_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 8 bit absolute relocation of a negative 16 bit
program memory address. For LDI command. */
HOWTO (R_AVR_HI8_LDI_PM_NEG, /* type */
9, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HI8_LDI_PM_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A high 8 bit absolute relocation of a negative 24 bit
program memory address. For LDI command. */
HOWTO (R_AVR_HH8_LDI_PM_NEG, /* type */
17, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_HH8_LDI_PM_NEG", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* Relocation for CALL command in ATmega. */
HOWTO (R_AVR_CALL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
23, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_AVR_CALL", /* name */
false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false) /* pcrel_offset */
};
/* Map BFD reloc types to AVR ELF reloc types. */
struct avr_reloc_map
{
bfd_reloc_code_real_type bfd_reloc_val;
unsigned int elf_reloc_val;
};
static const struct avr_reloc_map avr_reloc_map[] =
{
{ BFD_RELOC_NONE, R_AVR_NONE },
{ BFD_RELOC_32, R_AVR_32 },
{ BFD_RELOC_AVR_7_PCREL, R_AVR_7_PCREL },
{ BFD_RELOC_AVR_13_PCREL, R_AVR_13_PCREL },
{ BFD_RELOC_16, R_AVR_16 },
{ BFD_RELOC_AVR_16_PM, R_AVR_16_PM },
{ BFD_RELOC_AVR_LO8_LDI, R_AVR_LO8_LDI},
{ BFD_RELOC_AVR_HI8_LDI, R_AVR_HI8_LDI },
{ BFD_RELOC_AVR_HH8_LDI, R_AVR_HH8_LDI },
{ BFD_RELOC_AVR_LO8_LDI_NEG, R_AVR_LO8_LDI_NEG },
{ BFD_RELOC_AVR_HI8_LDI_NEG, R_AVR_HI8_LDI_NEG },
{ BFD_RELOC_AVR_HH8_LDI_NEG, R_AVR_HH8_LDI_NEG },
{ BFD_RELOC_AVR_LO8_LDI_PM, R_AVR_LO8_LDI_PM },
{ BFD_RELOC_AVR_HI8_LDI_PM, R_AVR_HI8_LDI_PM },
{ BFD_RELOC_AVR_HH8_LDI_PM, R_AVR_HH8_LDI_PM },
{ BFD_RELOC_AVR_LO8_LDI_PM_NEG, R_AVR_LO8_LDI_PM_NEG },
{ BFD_RELOC_AVR_HI8_LDI_PM_NEG, R_AVR_HI8_LDI_PM_NEG },
{ BFD_RELOC_AVR_HH8_LDI_PM_NEG, R_AVR_HH8_LDI_PM_NEG },
{ BFD_RELOC_AVR_CALL, R_AVR_CALL }
};
static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
bfd *abfd;
bfd_reloc_code_real_type code;
{
unsigned int i;
for (i = 0;
i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
i++)
{
if (avr_reloc_map[i].bfd_reloc_val == code)
return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
}
return NULL;
}
/* Set the howto pointer for an AVR ELF reloc. */
static void
avr_info_to_howto_rela (abfd, cache_ptr, dst)
bfd *abfd;
arelent *cache_ptr;
Elf32_Internal_Rela *dst;
{
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
BFD_ASSERT (r_type < (unsigned int) R_AVR_max);
cache_ptr->howto = &elf_avr_howto_table[r_type];
}
static asection *
elf32_avr_gc_mark_hook (abfd, info, rel, h, sym)
bfd *abfd;
struct bfd_link_info *info;
Elf_Internal_Rela *rel;
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
{
if (h != NULL)
{
switch (ELF32_R_TYPE (rel->r_info))
{
default:
switch (h->root.type)
{
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
return h->root.u.def.section;
case bfd_link_hash_common:
return h->root.u.c.p->section;
default:
break;
}
}
}
else
{
if (!(elf_bad_symtab (abfd)
&& ELF_ST_BIND (sym->st_info) != STB_LOCAL)
&& !((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
&& sym->st_shndx != SHN_COMMON))
{
return bfd_section_from_elf_index (abfd, sym->st_shndx);
}
}
return NULL;
}
static boolean
elf32_avr_gc_sweep_hook (abfd, info, sec, relocs)
bfd *abfd;
struct bfd_link_info *info;
asection *sec;
const Elf_Internal_Rela *relocs;
{
/* We don't use got and plt entries for avr. */
return true;
}
/* Look through the relocs for a section during the first phase.
Since we don't do .gots or .plts, we just need to consider the
virtual table relocs for gc. */
static boolean
elf32_avr_check_relocs (abfd, info, sec, relocs)
bfd *abfd;
struct bfd_link_info *info;
asection *sec;
const Elf_Internal_Rela *relocs;
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
if (info->relocateable)
return true;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
if (!elf_bad_symtab (abfd))
sym_hashes_end -= symtab_hdr->sh_info;
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
struct elf_link_hash_entry *h;
unsigned long r_symndx;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
}
return true;
}
/* Perform a single relocation. By default we use the standard BFD
routines, but a few relocs, we have to do them ourselves. */
static bfd_reloc_status_type
avr_final_link_relocate (howto, input_bfd, input_section,
contents, rel, relocation)
reloc_howto_type * howto;
bfd * input_bfd;
asection * input_section;
bfd_byte * contents;
Elf_Internal_Rela * rel;
bfd_vma relocation;
{
bfd_reloc_status_type r = bfd_reloc_ok;
bfd_vma x;
bfd_signed_vma srel;
switch (howto->type)
{
case R_AVR_7_PCREL:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation;
srel += rel->r_addend;
srel -= rel->r_offset;
srel -= 2; /* Branch instructions add 2 to the PC... */
srel -= (input_section->output_section->vma +
input_section->output_offset);
if (srel & 1)
return bfd_reloc_outofrange;
if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))
return bfd_reloc_overflow;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_13_PCREL:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation;
srel += rel->r_addend;
srel -= rel->r_offset;
srel -= 2; /* Branch instructions add 2 to the PC... */
srel -= (input_section->output_section->vma +
input_section->output_offset);
if (srel & 1)
return bfd_reloc_outofrange;
/* AVR addresses commands as words. */
srel >>= 1;
/* Check for overflow. */
if (srel < -2048 || srel > 2047)
{
/* Apply WRAPAROUND if possible. */
if (bfd_get_mach (input_bfd) == bfd_mach_avr2)
{
if (srel > 2047)
srel -= 4096;
else
srel += 4096;
}
else
return bfd_reloc_overflow;
}
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf000) | (srel & 0xfff);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_LO8_LDI:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HI8_LDI:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = (srel >> 8) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HH8_LDI:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = (srel >> 16) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_LO8_LDI_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HI8_LDI_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
srel = (srel >> 8) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HH8_LDI_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
srel = (srel >> 16) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_LO8_LDI_PM:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HI8_LDI_PM:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
srel = (srel >> 8) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HH8_LDI_PM:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
srel = (srel >> 16) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_LO8_LDI_PM_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HI8_LDI_PM_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
srel = (srel >> 8) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_HH8_LDI_PM_NEG:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
srel = -srel;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
srel = (srel >> 16) & 0xff;
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
bfd_put_16 (input_bfd, x, contents);
break;
case R_AVR_CALL:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation + rel->r_addend;
if (srel & 1)
return bfd_reloc_outofrange;
srel = srel >> 1;
x = bfd_get_16 (input_bfd, contents);
x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;
bfd_put_16 (input_bfd, x, contents);
bfd_put_16 (input_bfd, srel & 0xffff, contents+2);
break;
default:
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset,
relocation, rel->r_addend);
}
return r;
}
/* Relocate an AVR ELF section. */
static boolean
elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
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;
Elf_Internal_Rela * relend;
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
relend = relocs + input_section->reloc_count;
for (rel = relocs; rel < relend; rel ++)
{
reloc_howto_type * howto;
unsigned long r_symndx;
Elf_Internal_Sym * sym;
asection * sec;
struct elf_link_hash_entry * h;
bfd_vma relocation;
bfd_reloc_status_type r;
const char * name = NULL;
int r_type;
r_type = ELF32_R_TYPE (rel->r_info);
r_symndx = ELF32_R_SYM (rel->r_info);
if (info->relocateable)
{
/* This is a relocateable link. We don't have to change
anything, unless the reloc is against a section symbol,
in which case we have to adjust according to where the
section symbol winds up in the output section. */
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
sec = local_sections [r_symndx];
rel->r_addend += sec->output_offset + sym->st_value;
}
}
continue;
}
/* This is a final link. */
howto = elf_avr_howto_table + 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 = (sec->output_section->vma
+ sec->output_offset
+ sym->st_value);
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
}
else
{
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
name = h->root.root.string;
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
sec = h->root.u.def.section;
relocation = (h->root.u.def.value
+ sec->output_section->vma
+ sec->output_offset);
}
else if (h->root.type == bfd_link_hash_undefweak)
{
relocation = 0;
}
else
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
input_section, rel->r_offset, true)))
return false;
relocation = 0;
}
}
r = avr_final_link_relocate (howto, input_bfd, input_section,
contents, rel, relocation);
if (r != bfd_reloc_ok)
{
const char * msg = (const char *) NULL;
switch (r)
{
case bfd_reloc_overflow:
r = info->callbacks->reloc_overflow
(info, name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
r = info->callbacks->undefined_symbol
(info, name, input_bfd, input_section, rel->r_offset, true);
break;
case bfd_reloc_outofrange:
msg = _("internal error: out of range error");
break;
case bfd_reloc_notsupported:
msg = _("internal error: unsupported relocation error");
break;
case bfd_reloc_dangerous:
msg = _("internal error: dangerous relocation");
break;
default:
msg = _("internal error: unknown error");
break;
}
if (msg)
r = info->callbacks->warning
(info, msg, name, input_bfd, input_section, rel->r_offset);
if (! r)
return false;
}
}
return true;
}
/* The final processing done just before writing out a AVR ELF object
file. This gets the AVR architecture right based on the machine
number. */
static void
bfd_elf_avr_final_write_processing (abfd, linker)
bfd *abfd;
boolean linker ATTRIBUTE_UNUSED;
{
unsigned long val;
switch (bfd_get_mach (abfd))
{
default:
case bfd_mach_avr2:
val = E_AVR_MACH_AVR2;
break;
case bfd_mach_avr1:
val = E_AVR_MACH_AVR1;
break;
case bfd_mach_avr3:
val = E_AVR_MACH_AVR3;
break;
case bfd_mach_avr4:
val = E_AVR_MACH_AVR4;
break;
}
elf_elfheader (abfd)->e_machine = EM_AVR;
elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
elf_elfheader (abfd)->e_flags |= val;
}
/* Set the right machine number. */
static boolean
elf32_avr_object_p (abfd)
bfd *abfd;
{
int e_set = bfd_mach_avr2;
if (elf_elfheader (abfd)->e_machine == EM_AVR)
{
int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;
switch (e_mach)
{
default:
case E_AVR_MACH_AVR2:
e_set = bfd_mach_avr2;
break;
case E_AVR_MACH_AVR1:
e_set = bfd_mach_avr1;
break;
case E_AVR_MACH_AVR3:
e_set = bfd_mach_avr3;
break;
case E_AVR_MACH_AVR4:
e_set = bfd_mach_avr4;
break;
}
}
return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
e_set);
}
#define ELF_ARCH bfd_arch_avr
#define ELF_MACHINE_CODE EM_AVR
#define ELF_MAXPAGESIZE 1
#define TARGET_LITTLE_SYM bfd_elf32_avr_vec
#define TARGET_LITTLE_NAME "elf32-avr"
#define elf_info_to_howto avr_info_to_howto_rela
#define elf_info_to_howto_rel NULL
#define elf_backend_relocate_section elf32_avr_relocate_section
#define elf_backend_gc_mark_hook elf32_avr_gc_mark_hook
#define elf_backend_gc_sweep_hook elf32_avr_gc_sweep_hook
#define elf_backend_check_relocs elf32_avr_check_relocs
#define elf_backend_can_gc_sections 1
#define elf_backend_final_write_processing \
bfd_elf_avr_final_write_processing
#define elf_backend_object_p elf32_avr_object_p
#include "elf32-target.h"

View File

@ -871,6 +871,22 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MCORE_PCREL_32",
"BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2",
"BFD_RELOC_MCORE_RVA",
"BFD_RELOC_AVR_7_PCREL",
"BFD_RELOC_AVR_13_PCREL",
"BFD_RELOC_AVR_16_PM",
"BFD_RELOC_AVR_LO8_LDI",
"BFD_RELOC_AVR_HI8_LDI",
"BFD_RELOC_AVR_HH8_LDI",
"BFD_RELOC_AVR_LO8_LDI_NEG",
"BFD_RELOC_AVR_HI8_LDI_NEG",
"BFD_RELOC_AVR_HH8_LDI_NEG",
"BFD_RELOC_AVR_LO8_LDI_PM",
"BFD_RELOC_AVR_HI8_LDI_PM",
"BFD_RELOC_AVR_HH8_LDI_PM",
"BFD_RELOC_AVR_LO8_LDI_PM_NEG",
"BFD_RELOC_AVR_HI8_LDI_PM_NEG",
"BFD_RELOC_AVR_HH8_LDI_PM_NEG",
"BFD_RELOC_AVR_CALL",
"BFD_RELOC_VTABLE_INHERIT",
"BFD_RELOC_VTABLE_ENTRY",
"@@overflow: BFD_RELOC_UNUSED@@",

View File

@ -2590,6 +2590,91 @@ ENUMX
ENUMDOC
Motorola Mcore relocations.
ENUM
BFD_RELOC_AVR_7_PCREL
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit pc relative
short offset into 7 bits.
ENUM
BFD_RELOC_AVR_13_PCREL
ENUMDOC
This is a 16 bit reloc for the AVR that stores 13 bit pc relative
short offset into 12 bits.
ENUM
BFD_RELOC_AVR_16_PM
ENUMDOC
This is a 16 bit reloc for the AVR that stores 17 bit value (usually
program memory address) into 16 bits.
ENUM
BFD_RELOC_AVR_LO8_LDI
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (usually
data memory address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_HI8_LDI
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
of data memory address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_HH8_LDI
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of program memory address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_LO8_LDI_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(usually data memory address) into 8 bit immediate value of SUBI insn.
ENUM
BFD_RELOC_AVR_HI8_LDI_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 8 bit of data memory address) into 8 bit immediate value of
SUBI insn.
ENUM
BFD_RELOC_AVR_HH8_LDI_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(most high 8 bit of program memory address) into 8 bit immediate value
of LDI or SUBI insn.
ENUM
BFD_RELOC_AVR_LO8_LDI_PM
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (usually
command address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_HI8_LDI_PM
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
of command address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_HH8_LDI_PM
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of command address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_LO8_LDI_PM_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(usually command address) into 8 bit immediate value of SUBI insn.
ENUM
BFD_RELOC_AVR_HI8_LDI_PM_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 8 bit of 16 bit command address) into 8 bit immediate value
of SUBI insn.
ENUM
BFD_RELOC_AVR_HH8_LDI_PM_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(high 6 bit of 22 bit command address) into 8 bit immediate
value of SUBI insn.
ENUM
BFD_RELOC_AVR_CALL
ENUMDOC
This is a 32 bit reloc for the AVR that stores 23 bit value
into 22 bits.
ENUM
BFD_RELOC_VTABLE_INHERIT
ENUMX

View File

@ -506,6 +506,7 @@ extern const bfd_target arm_epoc_pei_big_vec;
extern const bfd_target b_out_vec_big_host;
extern const bfd_target b_out_vec_little_host;
extern const bfd_target bfd_elf64_alpha_vec;
extern const bfd_target bfd_elf32_avr_vec;
extern const bfd_target bfd_elf32_bigarc_vec;
extern const bfd_target bfd_elf32_bigarm_vec;
extern const bfd_target bfd_elf32_bigarm_oabi_vec;
@ -690,6 +691,7 @@ const bfd_target * const bfd_target_vector[] = {
#ifdef BFD64
&bfd_elf64_alpha_vec,
#endif
&bfd_elf32_avr_vec,
&bfd_elf32_bigarc_vec,
&bfd_elf32_bigarm_vec,
&bfd_elf32_bigarm_oabi_vec,

View File

@ -1,3 +1,8 @@
2000-03-27 Alan Modra <alan@linuxcare.com>
* readelf.c: Include elf/avr.h
(dump_relocations): Add EM_AVR case.
2000-03-09 Tim Waugh <twaugh@redhat.com>
* strings.1: Correct '-bytes' to '--bytes'.

View File

@ -68,6 +68,7 @@
#include "elf/mcore.h"
#include "elf/i960.h"
#include "elf/pj.h"
#include "elf/avr.h"
#include "bucomm.h"
#include "getopt.h"
@ -805,6 +806,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
rtype = elf_i960_reloc_type (type);
break;
case EM_AVR:
rtype = elf_avr_reloc_type (type);
break;
case EM_OLD_SPARCV9:
case EM_SPARC32PLUS:
case EM_SPARCV9:

View File

@ -1,3 +1,19 @@
2000-03-27 Alan Modra <alan@linuxcare.com>
* config/tc-avr.h (TC_HANDLES_FX_DONE): Define.
* config/tc-avr.c (mcu_types): Add missing initialiser.
(md_pcrel_from_section): Add prototype.
(avr_operand): Remove redundant test of unsigned < 0.
(avr_cons_fix_new): Ensure exp_mod_pm zero on function exit.
2000-03-27 Denis Chertykov <denisc@overta.ru>
* config/tc-avr.c: New file for AVR support.
* config/tc-avr.h: Likewise.
* configure.in: Add AVR support.
* configure: Regenerate.
2000-03-26 Timothy Wall <twall@cygnus.com>
* gasp.c (macro_op): Add new argument to check_macro call.

View File

@ -2,6 +2,8 @@
Changes in 2.10:
Support for ATMEL AVR.
Support for IBM 370 ELF. Somewhat experimental.
Support for numbers with suffixes.

1252
gas/config/tc-avr.c Normal file

File diff suppressed because it is too large Load Diff

118
gas/config/tc-avr.h Normal file
View File

@ -0,0 +1,118 @@
/* This file is tc-avr.h
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef BFD_ASSEMBLER
#error AVR support requires BFD_ASSEMBLER
#endif
#define TC_AVR
/* By convention, you should define this macro in the `.h' file. For
example, `tc-m68k.h' defines `TC_M68K'. You might have to use this
if it is necessary to add CPU specific code to the object format
file. */
#define TARGET_FORMAT "elf32-avr"
/* This macro is the BFD target name to use when creating the output
file. This will normally depend upon the `OBJ_FMT' macro. */
#define TARGET_ARCH bfd_arch_avr
/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'. */
#define TARGET_MACH 0
/* This macro is the BFD machine number to pass to
`bfd_set_arch_mach'. If it is not defined, GAS will use 0. */
#define TARGET_BYTES_BIG_ENDIAN 0
/* You should define this macro to be non-zero if the target is big
endian, and zero if the target is little endian. */
#define ONLY_STANDARD_ESCAPES
/* If you define this macro, GAS will warn about the use of
nonstandard escape sequences in a string. */
#define md_operand(x)
/* GAS will call this function for any expression that can not be
recognized. When the function is called, `input_line_pointer'
will point to the start of the expression. */
void avr_parse_cons_expression (expressionS *exp, int nbytes);
#define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR,N)
/*
You may define this macro to parse an expression used in a data
allocation pseudo-op such as `.word'. You can use this to
recognize relocation directives that may appear in such directives.*/
void avr_cons_fix_new(fragS *frag,int where, int nbytes, expressionS *exp);
#define TC_CONS_FIX_NEW(FRAG,WHERE,N,EXP) avr_cons_fix_new(FRAG,WHERE,N,EXP)
/* You may define this macro to generate a fixup for a data
allocation pseudo-op. */
#define md_number_to_chars number_to_chars_littleendian
/* This should just call either `number_to_chars_bigendian' or
`number_to_chars_littleendian', whichever is appropriate. On
targets like the MIPS which support options to change the
endianness, which function to call is a runtime decision. On
other targets, `md_number_to_chars' can be a simple macro. */
#define WORKING_DOT_WORD
/*
`md_short_jump_size'
`md_long_jump_size'
`md_create_short_jump'
`md_create_long_jump'
If `WORKING_DOT_WORD' is defined, GAS will not do broken word
processing (*note Broken words::.). Otherwise, you should set
`md_short_jump_size' to the size of a short jump (a jump that is
just long enough to jump around a long jmp) and
`md_long_jump_size' to the size of a long jump (a jump that can go
anywhere in the function), You should define
`md_create_short_jump' to create a short jump around a long jump,
and define `md_create_long_jump' to create a long jump. */
#define MD_APPLY_FIX3
#define TC_HANDLES_FX_DONE
#undef RELOC_EXPANSION_POSSIBLE
/* If you define this macro, it means that `tc_gen_reloc' may return
multiple relocation entries for a single fixup. In this case, the
return value of `tc_gen_reloc' is a pointer to a null terminated
array. */
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
/* If you define this macro, it should return the offset between the
address of a PC relative fixup and the position from which the PC
relative adjustment should be made. On many processors, the base
of a PC relative instruction is the next instruction, so this
macro would return the length of an instruction. */
#define LISTING_WORD_SIZE 2
/* The number of bytes to put into a word in a listing. This affects
the way the bytes are clumped together in the listing. For
example, a value of 2 might print `1234 5678' where a value of 1
would print `12 34 56 78'. The default value is 4. */
#define LEX_DOLLAR 0
/* AVR port uses `$' as a logical line separator */

876
gas/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -164,6 +164,8 @@ changequote([,])dnl
arm-*-pe | thumb-*-pe) fmt=coff em=pe ;;
arm-*-riscix*) fmt=aout em=riscix ;;
avr-*-*) fmt=elf bfd_gas=yes ;;
d10v-*-*) fmt=elf bfd_gas=yes ;;
d30v-*-*) fmt=elf bfd_gas=yes ;;

View File

@ -1,3 +1,7 @@
2000-03-27 Denis Chertykov <denisc@overta.ru>
* dis-asm.h (print_insn_avr): Declare.
2000-03-14 Bernd Schmidt <bernds@cygnus.co.uk>
* hashtab.h (htab_trav): Modify type so that first arg is of type

View File

@ -194,6 +194,7 @@ extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic80 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_pj PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_avr PARAMS ((bfd_vma, disassemble_info*));
extern void print_arm_disassembler_options PARAMS ((FILE *));
extern void parse_arm_disassembler_option PARAMS ((char *));

View File

@ -1,3 +1,8 @@
2000-03-27 Denis Chertykov <denisc@overta.ru>
* avr.h: New file. AVR ELF support for BFD.
* common.h: Add AVR magic number.
2000-03-10 Geoffrey Keating <geoffk@cygnus.com>
* mips.h: Add R_MIPS_GNU_REL_HI16, R_MIPS_GNU_REL_LO16,

58
include/elf/avr.h Normal file
View File

@ -0,0 +1,58 @@
/* AVR ELF support for BFD.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _ELF_AVR_H
#define _ELF_AVR_H
#include "elf/reloc-macros.h"
/* Processor specific flags for the ELF header e_flags field. */
#define EF_AVR_MACH 0xf
#define E_AVR_MACH_AVR1 1
#define E_AVR_MACH_AVR2 2
#define E_AVR_MACH_AVR3 3
#define E_AVR_MACH_AVR4 4
/* Relocations. */
START_RELOC_NUMBERS (elf_avr_reloc_type)
RELOC_NUMBER (R_AVR_NONE, 0)
RELOC_NUMBER (R_AVR_32, 1)
RELOC_NUMBER (R_AVR_7_PCREL, 2)
RELOC_NUMBER (R_AVR_13_PCREL, 3)
RELOC_NUMBER (R_AVR_16, 4)
RELOC_NUMBER (R_AVR_16_PM, 5)
RELOC_NUMBER (R_AVR_LO8_LDI, 6)
RELOC_NUMBER (R_AVR_HI8_LDI, 7)
RELOC_NUMBER (R_AVR_HH8_LDI, 8)
RELOC_NUMBER (R_AVR_LO8_LDI_NEG, 9)
RELOC_NUMBER (R_AVR_HI8_LDI_NEG, 10)
RELOC_NUMBER (R_AVR_HH8_LDI_NEG, 11)
RELOC_NUMBER (R_AVR_LO8_LDI_PM, 12)
RELOC_NUMBER (R_AVR_HI8_LDI_PM, 13)
RELOC_NUMBER (R_AVR_HH8_LDI_PM, 14)
RELOC_NUMBER (R_AVR_LO8_LDI_PM_NEG, 15)
RELOC_NUMBER (R_AVR_HI8_LDI_PM_NEG, 16)
RELOC_NUMBER (R_AVR_HH8_LDI_PM_NEG, 17)
RELOC_NUMBER (R_AVR_CALL, 18)
EMPTY_RELOC (R_AVR_max)
END_RELOC_NUMBERS
#endif /* _ELF_AVR_H */

View File

@ -189,6 +189,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* FR30 magic number - no EABI available. */
#define EM_CYGNUS_FR30 0x3330
/* AVR magic number
Written in the absense of an ABI. */
#define EM_AVR 0x1057
/* See the above comment before you add a new EM_* value here. */
/* Values for e_version */

View File

@ -1,3 +1,18 @@
2000-03-27 Denis Chertykov <denisc@overta.ru>
* configure.tgt (avr-*-*): New target support.
* Makefile.am: Likewise.
* scripttempl/elf32avr.sc: New script file.
* emulparams/avr1200.sh: New file.
* emulparams/avr23xx.sh: New file.
* emulparams/avr4433.sh New file.
* emulparams/avr44x4.sh New file.
* emulparams/avr85xx.sh New file.
* emulparams/avrmega103.sh New file.
* emulparams/avrmega161.sh New file.
* emulparams/avrmega603.sh New file.
* Makefile.in: Regenerate.
2000-03-09 Andreas Jaeger <aj@suse.de>
* Makefile.am (check-DEJAGNU): Also unset LANG.

View File

@ -111,6 +111,14 @@ ALL_EMULATIONS = \
earmnbsd.o \
earmpe.o \
earm_epoc_pe.o \
eavr1200.o \
eavr23xx.o \
eavr44x4.o \
eavr4433.o \
eavr85xx.o \
eavrmega603.o \
eavrmega103.o \
eavrmega161.o \
ecoff_sparc.o \
ed10velf.o \
ed30velf.o \
@ -320,6 +328,38 @@ earm_epoc_pe.c: $(srcdir)/emulparams/arm_epoc_pe.sh \
earmpe.c: $(srcdir)/emulparams/armpe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} armpe "$(tdir_armpe)"
eavr85xx.c: $(srcdir)/emulparams/avr85xx.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr85xx "$(tdir_avr85xx)"
eavr1200.c: $(srcdir)/emulparams/avr1200.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr1200 "$(tdir_avr85xx)"
eavr23xx.c: $(srcdir)/emulparams/avr23xx.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr23xx "$(tdir_avr85xx)"
eavr44x4.c: $(srcdir)/emulparams/avr44x4.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr44x4 "$(tdir_avr85xx)"
eavr4433.c: $(srcdir)/emulparams/avr4433.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr4433 "$(tdir_avr85xx)"
eavrmega603.c: $(srcdir)/emulparams/avrmega603.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega603 "$(tdir_avr85xx)"
eavrmega103.c: $(srcdir)/emulparams/avrmega103.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega103 "$(tdir_avr85xx)"
eavrmega161.c: $(srcdir)/emulparams/avrmega161.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega161 "$(tdir_avr85xx)"
ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS}
${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)"

View File

@ -214,6 +214,14 @@ ALL_EMULATIONS = \
earmnbsd.o \
earmpe.o \
earm_epoc_pe.o \
eavr1200.o \
eavr23xx.o \
eavr44x4.o \
eavr4433.o \
eavr85xx.o \
eavrmega603.o \
eavrmega103.o \
eavrmega161.o \
ecoff_sparc.o \
ed10velf.o \
ed30velf.o \
@ -1019,6 +1027,38 @@ earm_epoc_pe.c: $(srcdir)/emulparams/arm_epoc_pe.sh \
earmpe.c: $(srcdir)/emulparams/armpe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} armpe "$(tdir_armpe)"
eavr85xx.c: $(srcdir)/emulparams/avr85xx.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr85xx "$(tdir_avr85xx)"
eavr1200.c: $(srcdir)/emulparams/avr1200.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr1200 "$(tdir_avr85xx)"
eavr23xx.c: $(srcdir)/emulparams/avr23xx.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr23xx "$(tdir_avr85xx)"
eavr44x4.c: $(srcdir)/emulparams/avr44x4.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr44x4 "$(tdir_avr85xx)"
eavr4433.c: $(srcdir)/emulparams/avr4433.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avr4433 "$(tdir_avr85xx)"
eavrmega603.c: $(srcdir)/emulparams/avrmega603.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega603 "$(tdir_avr85xx)"
eavrmega103.c: $(srcdir)/emulparams/avrmega103.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega103 "$(tdir_avr85xx)"
eavrmega161.c: $(srcdir)/emulparams/avrmega161.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf32avr.sc \
${GEN_DEPENDS}
${GENSCRIPTS} avrmega161 "$(tdir_avr85xx)"
ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS}
${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)"

840
ld/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ arm-*-wince) targ_emul=armpe ;
arm-*-pe) targ_emul=armpe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
arc-*-elf*) targ_emul=arcelf ;;
avr-*-*) targ_emul=avr85xx
targ_extra_emuls="avr1200 avr23xx avr44x4 avr4433 avrmega603 avrmega103 avrmega161" ;;
d10v-*-*) targ_emul=d10velf ;;
d30v-*-*ext*) targ_emul=d30v_e; targ_extra_emuls="d30velf d30v_o" ;;
d30v-*-*onchip*) targ_emul=d30v_o; targ_extra_emuls="d30velf d30v_e" ;;

11
ld/emulparams/avr1200.sh Normal file
View File

@ -0,0 +1,11 @@
ARCH=avr:1
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=1K
DATA_LENGTH=0
EEPROM_LENGTH=64

12
ld/emulparams/avr23xx.sh Normal file
View File

@ -0,0 +1,12 @@
ARCH=avr:2
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=2K
DATA_LENGTH=128
EEPROM_LENGTH=128

12
ld/emulparams/avr4433.sh Normal file
View File

@ -0,0 +1,12 @@
ARCH=avr:2
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=4K
DATA_LENGTH=128
EEPROM_LENGTH=256

12
ld/emulparams/avr44x4.sh Normal file
View File

@ -0,0 +1,12 @@
ARCH=avr:2
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=4K
DATA_LENGTH=256
EEPROM_LENGTH=256

12
ld/emulparams/avr85xx.sh Normal file
View File

@ -0,0 +1,12 @@
ARCH=avr:2
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=8K
DATA_LENGTH=512
EEPROM_LENGTH=512

View File

@ -0,0 +1,12 @@
ARCH=avr:3
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=128K
DATA_LENGTH=4K
EEPROM_LENGTH=4K

View File

@ -0,0 +1,12 @@
ARCH=avr:4
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=16K
DATA_LENGTH=1K
EEPROM_LENGTH=512

View File

@ -0,0 +1,12 @@
ARCH=avr:3
MACHINE=
SCRIPT_NAME=elf32avr
OUTPUT_FORMAT="elf32-avr"
MAXPAGESIZE=1
EMBEDDED=yes
TEMPLATE_NAME=generic
TEXT_LENGTH=64K
DATA_LENGTH=4K
EEPROM_LENGTH=2K

149
ld/scripttempl/elf32avr.sc Normal file
View File

@ -0,0 +1,149 @@
cat <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}")
OUTPUT_ARCH(${ARCH})
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = $TEXT_LENGTH
data (rw!x) : ORIGIN = 0x800060, LENGTH = $DATA_LENGTH
eeprom (rw!x) : ORIGIN = 0, LENGTH = $EEPROM_LENGTH
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
${TEXT_DYNAMIC+${DYNAMIC}}
.hash ${RELOCATING-0} : { *(.hash) }
.dynsym ${RELOCATING-0} : { *(.dynsym) }
.dynstr ${RELOCATING-0} : { *(.dynstr) }
.gnu.version ${RELOCATING-0} : { *(.gnu.version) }
.gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
.gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
.rel.init ${RELOCATING-0} : { *(.rel.init) }
.rela.init ${RELOCATING-0} : { *(.rela.init) }
.rel.text ${RELOCATING-0} :
{
*(.rel.text)
${RELOCATING+*(.rel.text.*)}
${RELOCATING+*(.rel.gnu.linkonce.t*)}
}
.rela.text ${RELOCATING-0} :
{
*(.rela.text)
${RELOCATING+*(.rela.text.*)}
${RELOCATING+*(.rela.gnu.linkonce.t*)}
}
.rel.fini ${RELOCATING-0} : { *(.rel.fini) }
.rela.fini ${RELOCATING-0} : { *(.rela.fini) }
.rel.rodata ${RELOCATING-0} :
{
*(.rel.rodata)
${RELOCATING+*(.rel.rodata.*)}
${RELOCATING+*(.rel.gnu.linkonce.r*)}
}
.rela.rodata ${RELOCATING-0} :
{
*(.rela.rodata)
${RELOCATING+*(.rela.rodata.*)}
${RELOCATING+*(.rela.gnu.linkonce.r*)}
}
.rel.data ${RELOCATING-0} :
{
*(.rel.data)
${RELOCATING+*(.rel.data.*)}
${RELOCATING+*(.rel.gnu.linkonce.d*)}
}
.rela.data ${RELOCATING-0} :
{
*(.rela.data)
${RELOCATING+*(.rela.data.*)}
${RELOCATING+*(.rela.gnu.linkonce.d*)}
}
.rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
.rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
.rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
.rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
.rel.got ${RELOCATING-0} : { *(.rel.got) }
.rela.got ${RELOCATING-0} : { *(.rela.got) }
.rel.bss ${RELOCATING-0} : { *(.rel.bss) }
.rela.bss ${RELOCATING-0} : { *(.rela.bss) }
.rel.plt ${RELOCATING-0} : { *(.rel.plt) }
.rela.plt ${RELOCATING-0} : { *(.rela.plt) }
/* Internal text space or external memory */
.text :
{
*(.init)
*(.progmem.gcc*)
*(.progmem*)
${RELOCATING+. = ALIGN(2);}
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
${RELOCATING+. = ALIGN(2);}
*(.fini)
${RELOCATING+ _etext = . ; }
} ${RELOCATING+ > text}
.data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
{
*(.data)
*(.gnu.linkonce.d*)
${RELOCATING+. = ALIGN(2);}
${RELOCATING+ _edata = . ; }
} ${RELOCATING+ > data}
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
${RELOCATING+AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.data))}
{
${RELOCATING+ PROVIDE (__bss_start = .) ; }
*(.bss)
*(COMMON)
${RELOCATING+ PROVIDE (__bss_end = .) ; }
${RELOCATING+ _end = . ; }
} ${RELOCATING+ > data}
.eeprom ${RELOCATING-0}:
{
*(.eeprom*)
${RELOCATING+ __eeprom_end = . ; }
} ${RELOCATING+ > eeprom}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}
EOF

View File

@ -1,3 +1,20 @@
2000-03-27 Alan Modra <alan@linuxcare.com>
* avr-dis.c (add0fff, add03f8): Don't use structure bitfields to
truncate integers.
(print_insn_avr): Call function via pointer in K&R compatible way.
(dispLDD, regPP, reg50, reg104, reg40, reg20w, lit404, lit204,
add0fff, add03f8): Convert to old style function declaration and
add prototype.
(avrdis_opcode): Add prototype.
2000-03-27 Denis Chertykov <denisc@overta.ru>
* avr-dis.c: New file. AVR disassembler.
* configure.in (bfd_avr_arch): New architecture support.
* disassemble.c: Likewise.
* configure: Regenerate.
Mon Mar 6 19:52:05 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
* sh-opc.h (sh_table): ldre and ldrs have a *signed* displacement.

577
opcodes/avr-dis.c Normal file
View File

@ -0,0 +1,577 @@
/* Disassemble AVR instructions.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "dis-asm.h"
#include "opintl.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#define IFMASK(a,b) ((opcode & (a)) == (b))
#define CODE_MAX 65537
static char* SREG_flags = "CZNVSHTI";
static char* sect94[] = {"COM","NEG","SWAP","INC","NULL","ASR","LSR","ROR",
0,0,"DEC",0,0,0,0,0};
static char* sect98[] = {"CBI","SBIC","SBI","SBIS"};
static char* branchs[] = {
"BRCS","BREQ","BRMI","BRVS",
"BRLT","BRHS","BRTS","BRIE",
"BRCC","BRNE","BRPL","BRVC",
"BRGE","BRHC","BRTC","BRID"
};
static char* last4[] = {"BLD","BST","SBRC","SBRS"};
static void dispLDD PARAMS ((u16, char *));
static void
dispLDD (opcode, dest)
u16 opcode;
char *dest;
{
opcode = (((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7)
| (opcode & 7));
sprintf(dest, "%d", opcode);
}
static void regPP PARAMS ((u16, char *));
static void
regPP (opcode, dest)
u16 opcode;
char *dest;
{
opcode = ((opcode & 0x0600) >> 5) | (opcode & 0xf);
sprintf(dest, "0x%02X", opcode);
}
static void reg50 PARAMS ((u16, char *));
static void
reg50 (opcode, dest)
u16 opcode;
char *dest;
{
opcode = (opcode & 0x01f0) >> 4;
sprintf(dest, "R%d", opcode);
}
static void reg104 PARAMS ((u16, char *));
static void
reg104 (opcode, dest)
u16 opcode;
char *dest;
{
opcode = (opcode & 0xf) | ((opcode & 0x0200) >> 5);
sprintf(dest, "R%d", opcode);
}
static void reg40 PARAMS ((u16, char *));
static void
reg40 (opcode, dest)
u16 opcode;
char *dest;
{
opcode = (opcode & 0xf0) >> 4;
sprintf(dest, "R%d", opcode + 16);
}
static void reg20w PARAMS ((u16, char *));
static void
reg20w (opcode, dest)
u16 opcode;
char *dest;
{
opcode = (opcode & 0x30) >> 4;
sprintf(dest, "R%d", 24 + opcode * 2);
}
static void lit404 PARAMS ((u16, char *));
static void
lit404 (opcode, dest)
u16 opcode;
char *dest;
{
opcode = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
sprintf(dest, "0x%02X", opcode);
}
static void lit204 PARAMS ((u16, char *));
static void
lit204 (opcode, dest)
u16 opcode;
char *dest;
{
opcode = ((opcode & 0xc0) >> 2) | (opcode & 0xf);
sprintf(dest, "0x%02X", opcode);
}
static void add0fff PARAMS ((u16, char *, int));
static void
add0fff (op, dest, pc)
u16 op;
char *dest;
int pc;
{
int opcode = op & 0x0fff;
sprintf(dest, ".%+-8d ; 0x%06X", opcode * 2, pc + 2 + opcode * 2);
}
static void add03f8 PARAMS ((u16, char *, int));
static void
add03f8 (op, dest, pc)
u16 op;
char *dest;
int pc;
{
int opcode = (op >> 3) & 0x7f;
sprintf(dest, ".%+-8d ; 0x%06X", opcode * 2, pc + 2 + opcode * 2);
}
static u16 avrdis_opcode PARAMS ((bfd_vma, disassemble_info *));
static u16
avrdis_opcode (addr, info)
bfd_vma addr;
disassemble_info *info;
{
bfd_byte buffer[2];
int status;
status = info->read_memory_func(addr, buffer, 2, info);
if (status != 0)
{
info->memory_error_func(status, addr, info);
return -1;
}
return bfd_getl16 (buffer);
}
int
print_insn_avr(addr, info)
bfd_vma addr;
disassemble_info *info;
{
char rr[200];
char rd[200];
u16 opcode;
void *stream = info->stream;
fprintf_ftype prin = info->fprintf_func;
int cmd_len = 2;
opcode = avrdis_opcode (addr, info);
if (IFMASK(0xd000, 0x8000))
{
char letter;
reg50(opcode, rd);
dispLDD(opcode, rr);
if (opcode & 8)
letter = 'Y';
else
letter = 'Z';
if (opcode & 0x0200)
(*prin) (stream, " STD %c+%s,%s", letter, rr, rd);
else
(*prin) (stream, " LDD %s,%c+%s", rd, letter, rr);
}
else
{
switch (opcode & 0xf000)
{
case 0x0000:
{
reg50(opcode, rd);
reg104(opcode, rr);
switch (opcode & 0x0c00)
{
case 0x0000:
(*prin) (stream, " NOP");
break;
case 0x0400:
(*prin) (stream, " CPC %s,%s", rd, rr);
break;
case 0x0800:
(*prin) (stream, " SBC %s,%s", rd, rr);
break;
case 0x0c00:
(*prin) (stream, " ADD %s,%s", rd, rr);
break;
}
}
break;
case 0x1000:
{
reg50(opcode, rd);
reg104(opcode, rr);
switch (opcode & 0x0c00)
{
case 0x0000:
(*prin) (stream, " CPSE %s,%s", rd, rr);
break;
case 0x0400:
(*prin) (stream, " CP %s,%s", rd, rr);
break;
case 0x0800:
(*prin) (stream, " SUB %s,%s", rd, rr);
break;
case 0x0c00:
(*prin) (stream, " ADC %s,%s", rd, rr);
break;
}
}
break;
case 0x2000:
{
reg50(opcode, rd);
reg104(opcode, rr);
switch (opcode & 0x0c00)
{
case 0x0000:
(*prin) (stream, " AND %s,%s", rd, rr);
break;
case 0x0400:
(*prin) (stream, " EOR %s,%s", rd, rr);
break;
case 0x0800:
(*prin) (stream, " OR %s,%s", rd, rr);
break;
case 0x0c00:
(*prin) (stream, " MOV %s,%s", rd, rr);
break;
}
}
break;
case 0x3000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " CPI %s,%s", rd, rr);
}
break;
case 0x4000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " SBCI %s,%s", rd, rr);
}
break;
case 0x5000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " SUBI %s,%s", rd, rr);
}
break;
case 0x6000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " ORI %s,%s", rd, rr);
}
break;
case 0x7000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " ANDI %s,%s", rd, rr);
}
break;
case 0x9000:
{
switch (opcode & 0x0e00)
{
case 0x0000:
{
reg50(opcode, rd);
switch (opcode & 0xf)
{
case 0x0:
{
(*prin) (stream, " LDS %s,0x%04X", rd,
avrdis_opcode(addr + 2, info));
cmd_len = 4;
}
break;
case 0x1:
{
(*prin) (stream, " LD %s,Z+", rd);
}
break;
case 0x2:
{
(*prin) (stream, " LD %s,-Z", rd);
}
break;
case 0x9:
{
(*prin) (stream, " LD %s,Y+", rd);
}
break;
case 0xa:
{
(*prin) (stream, " LD %s,-Y", rd);
}
break;
case 0xc:
{
(*prin) (stream, " LD %s,X", rd);
}
break;
case 0xd:
{
(*prin) (stream, " LD %s,X+", rd);
}
break;
case 0xe:
{
(*prin) (stream, " LD %s,-X", rd);
}
break;
case 0xf:
{
(*prin) (stream, " POP %s", rd);
}
break;
default:
{
(*prin) (stream, " ????");
}
break;
}
}
break;
case 0x0200:
{
reg50(opcode, rd);
switch (opcode & 0xf)
{
case 0x0:
{
(*prin) (stream, " STS 0x%04X,%s",
avrdis_opcode(addr + 2, info), rd);
cmd_len = 4;
}
break;
case 0x1:
{
(*prin) (stream, " ST Z+,%s", rd);
}
break;
case 0x2:
{
(*prin) (stream, " ST -Z,%s", rd);
}
break;
case 0x9:
{
(*prin) (stream, " ST Y+,%s", rd);
}
break;
case 0xa:
{
(*prin) (stream, " ST -Y,%s", rd);
}
break;
case 0xc:
{
(*prin) (stream, " ST X,%s", rd);
}
break;
case 0xd:
{
(*prin) (stream, " ST X+,%s", rd);
}
break;
case 0xe:
{
(*prin) (stream, " ST -X,%s", rd);
}
break;
case 0xf:
{
(*prin) (stream, " PUSH %s", rd);
}
break;
default:
{
(*prin) (stream, " ????");
}
break;
}
}
break;
case 0x0400:
{
if (IFMASK(0x020c, 0x000c))
{
u32 k = ((opcode & 0x01f0) >> 3) | (opcode & 1);
k = (k << 16) | avrdis_opcode(addr + 2, info);
if (opcode & 0x0002)
(*prin) (stream, " CALL 0x%06X", k*2);
else
(*prin) (stream, " JMP 0x%06X", k*2);
cmd_len = 4;
}
else if (IFMASK(0x010f, 0x0008))
{
int sf = (opcode & 0x70) >> 4;
if (opcode & 0x0080)
(*prin) (stream, " CL%c", SREG_flags[sf]);
else
(*prin) (stream, " SE%c", SREG_flags[sf]);
}
else if (IFMASK(0x000f, 0x0009))
{
if (opcode & 0x0100)
(*prin) (stream, " ICALL");
else
(*prin) (stream, " IJMP");
}
else if (IFMASK(0x010f, 0x0108))
{
if (IFMASK(0x0090, 0x0000))
(*prin) (stream, " RET");
else if (IFMASK(0x0090, 0x0010))
(*prin) (stream, " RETI");
else if (IFMASK(0x00e0, 0x0080))
(*prin) (stream, " SLEEP");
else if (IFMASK(0x00e0, 0x00a0))
(*prin) (stream, " WDR");
else if (IFMASK(0x00f0, 0x00c0))
(*prin) (stream, " LPM");
else if (IFMASK(0x00f0, 0x00d0))
(*prin) (stream, " ELPM");
else
(*prin) (stream, " ????");
}
else
{
const char* p;
reg50(opcode, rd);
p = sect94[opcode & 0xf];
if (!p)
p = "????";
(*prin) (stream, " %-8s%s", p, rd);
}
}
break;
case 0x0600:
{
if (opcode & 0x0200)
{
lit204(opcode, rd);
reg20w(opcode, rr);
if (opcode & 0x0100)
(*prin) (stream, " SBIW %s,%s", rr, rd);
else
(*prin) (stream, " ADIW %s,%s", rr, rd);
}
}
break;
case 0x0800:
case 0x0a00:
{
(*prin) (stream, " %-8s0x%02X,%d",
sect98[(opcode & 0x0300) >> 8],
(opcode & 0xf8) >> 3,
opcode & 7);
}
break;
default:
{
reg50(opcode, rd);
reg104(opcode, rr);
(*prin) (stream, " MUL %s,%s", rd, rr);
}
}
}
break;
case 0xb000:
{
reg50(opcode, rd);
regPP(opcode, rr);
if (opcode & 0x0800)
(*prin) (stream, " OUT %s,%s", rr, rd);
else
(*prin) (stream, " IN %s,%s", rd, rr);
}
break;
case 0xc000:
{
add0fff(opcode, rd, addr);
(*prin) (stream, " RJMP %s", rd);
}
break;
case 0xd000:
{
add0fff(opcode, rd, addr);
(*prin) (stream, " RCALL %s", rd);
}
break;
case 0xe000:
{
reg40(opcode, rd);
lit404(opcode, rr);
(*prin) (stream, " LDI %s,%s", rd, rr);
}
break;
case 0xf000:
{
if (opcode & 0x0800)
{
reg50(opcode, rd);
(*prin) (stream, " %-8s%s,%d",
last4[(opcode & 0x0600) >> 9],
rd, opcode & 7);
}
else
{
char* p;
add03f8(opcode, rd, addr);
p = branchs[((opcode & 0x0400) >> 7) | (opcode & 7)];
(*prin) (stream, " %-8s%s", p, rd);
}
}
break;
}
}
return cmd_len;
}

736
opcodes/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,7 @@ if test x${all_targets} = xfalse ; then
bfd_alpha_arch) ta="$ta alpha-dis.lo alpha-opc.lo" ;;
bfd_arc_arch) ta="$ta arc-dis.lo arc-opc.lo" ;;
bfd_arm_arch) ta="$ta arm-dis.lo" ;;
bfd_avr_arch) ta="$ta avr-dis.lo" ;;
bfd_convex_arch) ;;
bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;;
bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;;

View File

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define ARCH_alpha
#define ARCH_arc
#define ARCH_arm
#define ARCH_avr
#define ARCH_d10v
#define ARCH_d30v
#define ARCH_h8300
@ -93,6 +94,11 @@ disassembler (abfd)
disassemble = print_insn_little_arm;
break;
#endif
#ifdef ARCH_avr
case bfd_arch_avr:
disassemble = print_insn_avr;
break;
#endif
#ifdef ARCH_d10v
case bfd_arch_d10v:
disassemble = print_insn_d10v;