aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2012-05-11 12:59:23 +0000
committerNick Clifton <nickc@redhat.com>2012-05-11 12:59:23 +0000
commit99700d6febe92cfcd0ce5b62cad8472020e6c248 (patch)
tree46b61fbed4f38c2cb1cbee18275c3c40b2966c24
parentfd885f3a4d85dc33d794ca359ea91f31e3082717 (diff)
downloadgdb-99700d6febe92cfcd0ce5b62cad8472020e6c248.zip
gdb-99700d6febe92cfcd0ce5b62cad8472020e6c248.tar.gz
gdb-99700d6febe92cfcd0ce5b62cad8472020e6c248.tar.bz2
PR 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. * 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.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/bfd-in2.h12
-rw-r--r--bfd/elf32-avr.c47
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/reloc.c15
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/config/tc-avr.c130
-rw-r--r--include/elf/ChangeLog6
-rw-r--r--include/elf/avr.h26
9 files changed, 218 insertions, 47 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e776f41..e958f63 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index a66c74f..a087115 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index 9fb72f5..582cdae 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -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
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index e4acdb0..026b077 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 29c54c8..e5dd8bc 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -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
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c9048e3..82ef7b7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index 42eda2f..b2f2de2 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -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;
+
+ /* 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.
- Relocation: BFD_RELOC_AVR_16_PM. */
+/* 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)
+ /* The first entry of exp_mod_data[] contains an entry if no
+ expression modifier is present. Skip it. */
+
+ for (pexp++; pexp->name; pexp++)
{
- char *pm_name1 = "pm";
- char *pm_name2 = "gs";
- int len = strlen (pm_name1);
- /* len must be the same for both pm identifiers. */
+ int len = strlen (pexp->name);
- if (strncasecmp (input_line_pointer, pm_name1, len) == 0
- || strncasecmp (input_line_pointer, pm_name2, len) == 0)
+ 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
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index ab9b2de..a405d8b 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -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.
diff --git a/include/elf/avr.h b/include/elf/avr.h
index 11d43f9..6e3b308 100644
--- a/include/elf/avr.h
+++ b/include/elf/avr.h
@@ -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 */