* reloc.c: Add new ENUM for BFD_RELOC_AVR_8_LO,
	BFD_RELOC_AVR_8_HI, BFD_RELOC_AVR_8_HHI.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenrate.
	* elf32-avr.c (elf_avr_howto_table): Add entries for
	R_AVR_8_LO8, R_AVR_8_HI8, R_AVR_8_HHI8.
	(avr_reloc_map): Add RELOC mappings for R_AVR_8_LO8, R_AVR_8_HI8,
	R_AVR_8_HHI8.

	* config/tc-avr.c (exp_mod_pm): Remove variable.
	(exp_mod_data_t): New typedef.
	(pexp_mod_data, exp_mod_data): New variables.
	(avr_parse_cons_expression): Scan through exp_mod_data[] to find
	data expression modifiers "pm", "gs", "lo8", hi8", "hhi8", "hh8"
	and set pexp_mod_data accordingly to be used in avr_cons_fix_new.
	(avr_cons_fix_new): Handle new data expression modifiers shipped
	in pexp_mod_data.
	(md_apply_fix): Handle BFD_RELOC_AVR_8_LO, BFD_RELOC_AVR_8_HI,
	BFD_RELOC_AVR_8_HHI.

	* elf/avr.h (RELOC_NUMBERS): Add values for R_AVR_8_LO8,
	R_AVR_8_HI8, R_AVR_8_HHI8.
This commit is contained in:
Nick Clifton 2012-05-11 12:59:23 +00:00
parent fd885f3a4d
commit 99700d6feb
9 changed files with 219 additions and 48 deletions

View File

@ -1,3 +1,15 @@
2012-05-11 Georg-Johann Lay <avr@gjlay.de
PR target/13503
* reloc.c: Add new ENUM for BFD_RELOC_AVR_8_LO,
BFD_RELOC_AVR_8_HI, BFD_RELOC_AVR_8_HHI.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenrate.
* elf32-avr.c (elf_avr_howto_table): Add entries for
R_AVR_8_LO8, R_AVR_8_HI8, R_AVR_8_HHI8.
(avr_reloc_map): Add RELOC mappings for R_AVR_8_LO8, R_AVR_8_HI8,
R_AVR_8_HHI8.
2012-05-10 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (elf_x86_64_relocate_section): Use int in x32

View File

@ -4088,6 +4088,18 @@ instructions */
instructions */
BFD_RELOC_AVR_6_ADIW,
/* This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
in .byte lo8(symbol) */
BFD_RELOC_AVR_8_LO,
/* This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol
in .byte hi8(symbol) */
BFD_RELOC_AVR_8_HI,
/* This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol
in .byte hhi8(symbol) */
BFD_RELOC_AVR_8_HHI,
/* Renesas RL78 Relocations. */
BFD_RELOC_RL78_NEG8,
BFD_RELOC_RL78_NEG16,

View File

@ -517,6 +517,48 @@ static reloc_howto_type elf_avr_howto_table[] =
0x000000ff, /* src_mask */
0x000000ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* lo8-part to use in .byte lo8(sym). */
HOWTO (R_AVR_8_LO8, /* type */
0, /* rightshift */
0, /* 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_8_LO8", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* hi8-part to use in .byte hi8(sym). */
HOWTO (R_AVR_8_HI8, /* type */
8, /* rightshift */
0, /* 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_8_HI8", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* hhi8-part to use in .byte hhi8(sym). */
HOWTO (R_AVR_8_HHI8, /* type */
16, /* rightshift */
0, /* 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_8_HHI8", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
};
/* Map BFD reloc types to AVR ELF reloc types. */
@ -555,7 +597,10 @@ static const struct avr_reloc_map avr_reloc_map[] =
{ BFD_RELOC_AVR_LDI, R_AVR_LDI },
{ BFD_RELOC_AVR_6, R_AVR_6 },
{ BFD_RELOC_AVR_6_ADIW, R_AVR_6_ADIW },
{ BFD_RELOC_8, R_AVR_8 }
{ BFD_RELOC_8, R_AVR_8 },
{ BFD_RELOC_AVR_8_LO, R_AVR_8_LO8 },
{ BFD_RELOC_AVR_8_HI, R_AVR_8_HI8 },
{ BFD_RELOC_AVR_8_HHI, R_AVR_8_HHI8 }
};
/* Meant to be filled one day with the wrap around address for the

View File

@ -1867,6 +1867,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_AVR_LDI",
"BFD_RELOC_AVR_6",
"BFD_RELOC_AVR_6_ADIW",
"BFD_RELOC_AVR_8_LO",
"BFD_RELOC_AVR_8_HI",
"BFD_RELOC_AVR_8_HHI",
"BFD_RELOC_RL78_NEG8",
"BFD_RELOC_RL78_NEG16",
"BFD_RELOC_RL78_NEG24",

View File

@ -4360,6 +4360,21 @@ ENUM
ENUMDOC
This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
instructions
ENUM
BFD_RELOC_AVR_8_LO
ENUMDOC
This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
in .byte lo8(symbol)
ENUM
BFD_RELOC_AVR_8_HI
ENUMDOC
This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol
in .byte hi8(symbol)
ENUM
BFD_RELOC_AVR_8_HHI
ENUMDOC
This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol
in .byte hhi8(symbol)
ENUM
BFD_RELOC_RL78_NEG8

View File

@ -1,3 +1,17 @@
2012-05-11 Georg-Johann Lay <avr@gjlay.de
PR target/13503
* config/tc-avr.c (exp_mod_pm): Remove variable.
(exp_mod_data_t): New typedef.
(pexp_mod_data, exp_mod_data): New variables.
(avr_parse_cons_expression): Scan through exp_mod_data[] to find
data expression modifiers "pm", "gs", "lo8", hi8", "hhi8", "hh8"
and set pexp_mod_data accordingly to be used in avr_cons_fix_new.
(avr_cons_fix_new): Handle new data expression modifiers shipped
in pexp_mod_data.
(md_apply_fix): Handle BFD_RELOC_AVR_8_LO, BFD_RELOC_AVR_8_HI,
BFD_RELOC_AVR_8_HHI.
2012-05-10 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (tc_gen_reloc): Use bfd_signed_vma in x32

View File

@ -1,7 +1,7 @@
/* tc-avr.c -- Assembler code for the ATMEL AVR
Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009,
2010 Free Software Foundation, Inc.
2010, 2012 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of GAS, the GNU Assembler.
@ -65,19 +65,19 @@ static struct mcu_type_s mcu_types[] =
{
{"avr1", AVR_ISA_AVR1, bfd_mach_avr1},
/* TODO: insruction set for avr2 architecture should be AVR_ISA_AVR2,
but set to AVR_ISA_AVR25 for some following version
of GCC (from 4.3) for backward compatibility. */
but set to AVR_ISA_AVR25 for some following version
of GCC (from 4.3) for backward compatibility. */
{"avr2", AVR_ISA_AVR25, bfd_mach_avr2},
{"avr25", AVR_ISA_AVR25, bfd_mach_avr25},
/* TODO: insruction set for avr3 architecture should be AVR_ISA_AVR3,
but set to AVR_ISA_AVR3_ALL for some following version
/* TODO: insruction set for avr3 architecture should be AVR_ISA_AVR3,
but set to AVR_ISA_AVR3_ALL for some following version
of GCC (from 4.3) for backward compatibility. */
{"avr3", AVR_ISA_AVR3_ALL, bfd_mach_avr3},
{"avr31", AVR_ISA_AVR31, bfd_mach_avr31},
{"avr35", AVR_ISA_AVR35, bfd_mach_avr35},
{"avr4", AVR_ISA_AVR4, bfd_mach_avr4},
/* TODO: insruction set for avr5 architecture should be AVR_ISA_AVR5,
but set to AVR_ISA_AVR51 for some following version
/* TODO: insruction set for avr5 architecture should be AVR_ISA_AVR5,
but set to AVR_ISA_AVR51 for some following version
of GCC (from 4.3) for backward compatibility. */
{"avr5", AVR_ISA_AVR51, bfd_mach_avr5},
{"avr51", AVR_ISA_AVR51, bfd_mach_avr51},
@ -1013,7 +1013,7 @@ avr_operand (struct avr_opcodes_s *opcode,
op_mask |= (x << 4);
}
break;
case '?':
break;
@ -1334,7 +1334,19 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
}
break;
default:
case BFD_RELOC_AVR_8_LO:
*where = 0xff & value;
break;
case BFD_RELOC_AVR_8_HI:
*where = 0xff & (value >> 8);
break;
case BFD_RELOC_AVR_8_HHI:
*where = 0xff & (value >> 16);
break;
default:
as_fatal (_("line %d: unknown relocation type: 0x%x"),
fixP->fx_line, fixP->fx_r_type);
break;
@ -1465,40 +1477,75 @@ md_assemble (char *str)
}
}
/* Flag to pass `pm' mode between `avr_parse_cons_expression' and
`avr_cons_fix_new'. */
static int exp_mod_pm = 0;
typedef struct
{
/* Name of the expression modifier allowed with .byte, .word, etc. */
const char *name;
/* Parse special CONS expression: pm (expression)
or alternatively: gs (expression).
These are used for addressing program memory.
Relocation: BFD_RELOC_AVR_16_PM. */
/* Only allowed with n bytes of data. */
int nbytes;
/* Associated RELOC. */
bfd_reloc_code_real_type reloc;
/* Part of the error message. */
const char *error;
} exp_mod_data_t;
static const exp_mod_data_t exp_mod_data[] =
{
/* Default, must be first. */
{ "", 0, BFD_RELOC_16, "" },
/* Divides by 2 to get word address. Generate Stub. */
{ "gs", 2, BFD_RELOC_AVR_16_PM, "`gs' " },
{ "pm", 2, BFD_RELOC_AVR_16_PM, "`pm' " },
/* The following are used together with avr-gcc's __memx address space
in order to initialize a 24-bit pointer variable with a 24-bit address.
For address in flash, hhi8 will contain the flash segment if the
symbol is located in flash. If the symbol is located in RAM; hhi8
will contain 0x80 which matches avr-gcc's notion of how 24-bit RAM/flash
addresses linearize address space. */
{ "lo8", 1, BFD_RELOC_AVR_8_LO, "`lo8' " },
{ "hi8", 1, BFD_RELOC_AVR_8_HI, "`hi8' " },
{ "hhi8", 1, BFD_RELOC_AVR_8_HHI, "`hhi8' " },
{ "hh8", 1, BFD_RELOC_AVR_8_HHI, "`hh8' " },
/* End of list. */
{ NULL, 0, 0, NULL }
};
/* Data to pass between `avr_parse_cons_expression' and `avr_cons_fix_new'. */
static const exp_mod_data_t *pexp_mod_data = &exp_mod_data[0];
/* Parse special CONS expression: pm (expression) or alternatively
gs (expression). These are used for addressing program memory. Moreover,
define lo8 (expression), hi8 (expression) and hhi8 (expression). */
void
avr_parse_cons_expression (expressionS *exp, int nbytes)
{
const exp_mod_data_t *pexp = &exp_mod_data[0];
char *tmp;
exp_mod_pm = 0;
pexp_mod_data = pexp;
tmp = input_line_pointer = skip_space (input_line_pointer);
if (nbytes == 2)
{
char *pm_name1 = "pm";
char *pm_name2 = "gs";
int len = strlen (pm_name1);
/* len must be the same for both pm identifiers. */
/* The first entry of exp_mod_data[] contains an entry if no
expression modifier is present. Skip it. */
if (strncasecmp (input_line_pointer, pm_name1, len) == 0
|| strncasecmp (input_line_pointer, pm_name2, len) == 0)
for (pexp++; pexp->name; pexp++)
{
int len = strlen (pexp->name);
if (nbytes == pexp->nbytes
&& strncasecmp (input_line_pointer, pexp->name, len) == 0)
{
input_line_pointer = skip_space (input_line_pointer + len);
if (*input_line_pointer == '(')
{
input_line_pointer = skip_space (input_line_pointer + 1);
exp_mod_pm = 1;
pexp_mod_data = pexp;
expression (exp);
if (*input_line_pointer == ')')
@ -1506,13 +1553,15 @@ avr_parse_cons_expression (expressionS *exp, int nbytes)
else
{
as_bad (_("`)' required"));
exp_mod_pm = 0;
pexp_mod_data = &exp_mod_data[0];
}
return;
}
input_line_pointer = tmp;
break;
}
}
@ -1525,8 +1574,11 @@ avr_cons_fix_new (fragS *frag,
int nbytes,
expressionS *exp)
{
if (exp_mod_pm == 0)
int bad = 0;
switch (pexp_mod_data->reloc)
{
default:
if (nbytes == 1)
fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_8);
else if (nbytes == 2)
@ -1534,16 +1586,24 @@ avr_cons_fix_new (fragS *frag,
else if (nbytes == 4)
fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_32);
else
as_bad (_("illegal %srelocation size: %d"), "", nbytes);
}
else
{
if (nbytes == 2)
fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_AVR_16_PM);
bad = 1;
break;
case BFD_RELOC_AVR_16_PM:
case BFD_RELOC_AVR_8_LO:
case BFD_RELOC_AVR_8_HI:
case BFD_RELOC_AVR_8_HHI:
if (nbytes == pexp_mod_data->nbytes)
fix_new_exp (frag, where, nbytes, exp, FALSE, pexp_mod_data->reloc);
else
as_bad (_("illegal %srelocation size: %d"), "`pm' ", nbytes);
exp_mod_pm = 0;
bad = 1;
break;
}
if (bad)
as_bad (_("illegal %srelocation size: %d"), pexp_mod_data->error, nbytes);
pexp_mod_data = &exp_mod_data[0];
}
void

View File

@ -1,3 +1,9 @@
2012-05-11 Georg-Johann Lay <avr@gjlay.de
PR target/13503
* elf/avr.h (RELOC_NUMBERS): Add values for R_AVR_8_LO8,
R_AVR_8_HI8, R_AVR_8_HHI8.
2012-05-03 Sean Keys <skeys@ipdatasys.com>
* xgate.h: Mininal file to support XGATE relocations.

View File

@ -1,5 +1,6 @@
/* AVR ELF support for BFD.
Copyright 1999, 2000, 2004, 2006, 2010 Free Software Foundation, Inc.
Copyright 1999, 2000, 2004, 2006, 2010, 2012
Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
@ -30,16 +31,16 @@
as reference for the relocations so that linker relaxation is possible. */
#define EF_AVR_LINKRELAX_PREPARED 0x80
#define E_AVR_MACH_AVR1 1
#define E_AVR_MACH_AVR2 2
#define E_AVR_MACH_AVR25 25
#define E_AVR_MACH_AVR3 3
#define E_AVR_MACH_AVR31 31
#define E_AVR_MACH_AVR35 35
#define E_AVR_MACH_AVR4 4
#define E_AVR_MACH_AVR5 5
#define E_AVR_MACH_AVR51 51
#define E_AVR_MACH_AVR6 6
#define E_AVR_MACH_AVR1 1
#define E_AVR_MACH_AVR2 2
#define E_AVR_MACH_AVR25 25
#define E_AVR_MACH_AVR3 3
#define E_AVR_MACH_AVR31 31
#define E_AVR_MACH_AVR35 35
#define E_AVR_MACH_AVR4 4
#define E_AVR_MACH_AVR5 5
#define E_AVR_MACH_AVR51 51
#define E_AVR_MACH_AVR6 6
#define E_AVR_MACH_XMEGA1 101
#define E_AVR_MACH_XMEGA2 102
#define E_AVR_MACH_XMEGA3 103
@ -77,6 +78,9 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
RELOC_NUMBER (R_AVR_LO8_LDI_GS, 24)
RELOC_NUMBER (R_AVR_HI8_LDI_GS, 25)
RELOC_NUMBER (R_AVR_8, 26)
RELOC_NUMBER (R_AVR_8_LO8, 27)
RELOC_NUMBER (R_AVR_8_HI8, 28)
RELOC_NUMBER (R_AVR_8_HHI8, 29)
END_RELOC_NUMBERS (R_AVR_max)
#endif /* _ELF_AVR_H */