ATMEL AVR microcontroller support.
This commit is contained in:
parent
e7d0728ac1
commit
adde6300e0
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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
953
bfd/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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
89
bfd/cpu-avr.c
Normal 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;
|
||||
}
|
@ -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
963
bfd/elf32-avr.c
Normal 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"
|
16
bfd/libbfd.h
16
bfd/libbfd.h
@ -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@@",
|
||||
|
85
bfd/reloc.c
85
bfd/reloc.c
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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'.
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
2
gas/NEWS
2
gas/NEWS
@ -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
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
118
gas/config/tc-avr.h
Normal 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
876
gas/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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 ;;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 *));
|
||||
|
@ -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
58
include/elf/avr.h
Normal 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 */
|
@ -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 */
|
||||
|
15
ld/ChangeLog
15
ld/ChangeLog
@ -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.
|
||||
|
@ -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)"
|
||||
|
@ -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
840
ld/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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
11
ld/emulparams/avr1200.sh
Normal 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
12
ld/emulparams/avr23xx.sh
Normal 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
12
ld/emulparams/avr4433.sh
Normal 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
12
ld/emulparams/avr44x4.sh
Normal 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
12
ld/emulparams/avr85xx.sh
Normal 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
|
||||
|
12
ld/emulparams/avrmega103.sh
Normal file
12
ld/emulparams/avrmega103.sh
Normal 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
|
||||
|
12
ld/emulparams/avrmega161.sh
Normal file
12
ld/emulparams/avrmega161.sh
Normal 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
|
||||
|
12
ld/emulparams/avrmega603.sh
Normal file
12
ld/emulparams/avrmega603.sh
Normal 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
149
ld/scripttempl/elf32avr.sc
Normal 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
|
||||
|
@ -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
577
opcodes/avr-dis.c
Normal 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
736
opcodes/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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" ;;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user