]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 13503
authorNick Clifton <nickc@redhat.com>
Fri, 11 May 2012 12:59:23 +0000 (12:59 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 11 May 2012 12:59:23 +0000 (12:59 +0000)
* 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.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-avr.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-avr.c
include/elf/ChangeLog
include/elf/avr.h

index e776f41dda6ba3123ec9d20b2d023a0f871b3db0..e958f63e021bc81666bd2c10ebe658a93ae6dfea 100644 (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
index a66c74f335577044a7e6a9e9ce68ab08c8aec917..a087115c699890f72655cf8df711f6cc4e9a97d0 100644 (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,
index 9fb72f583f5be7503da68762cd6bad85b433014c..582cdaee9fab170f1a9a147a1899d1b3b65f543a 100644 (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
index e4acdb0cfa9a4f296384bea734f55fc2ce56ab54..026b0778c85e156e27549561b702910d7e5ff7bb 100644 (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",
index 29c54c8767a1f110bc987b393b3c7cfbb5056537..e5dd8bc7cb4b9d85f02750c71425cc06d31ea666 100644 (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
index c9048e3c56866052fe01f273e8b8bcf91b2c5d43..82ef7b7dee00f97644073208ee1e3ec1ce68d89c 100644 (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
index 42eda2fd1bc1fc1d983c7c462d779fe7dbf3993b..b2f2de2b8f79ca0a6ede4c5af8adbe4109a3aa5b 100644 (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;
+
+  /* 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
index ab9b2deae3a15c9fb9f816e8eb2051962d0784be..a405d8b980ff1c1bb6a822bc82a1bc4770d03af1 100644 (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.
index 11d43f96684fae03d07e2f0644789b5a36bae51a..6e3b308990fbc18d508a9331e30c418d6352147e 100644 (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.
    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     
 #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 */