Adding adr_type and prevent adr :got:
authorMarcus Shawcroft <marcus.shawcroft@arm.com>
Thu, 5 Feb 2015 16:57:09 +0000 (16:57 +0000)
committerMarcus Shawcroft <marcus.shawcroft@arm.com>
Thu, 26 Feb 2015 22:23:09 +0000 (22:23 +0000)
The current implementation of the :got: assembler modifier does not
distinguish the ADR and ADRP instruction.  The :got: modifier does not
make sense on and ADR instruction and should be error'd rather than
the current behavior of applying an inappropriate relocation to the
output and scrambling the underlying instruction silently.

gas/ChangeLog
gas/config/tc-aarch64.c

index e4b3077e6401cca6747a0519e5ca3ebf013c5966..36234628d475f253d3c0ccc914d26384be86879d 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-26  Marcus Shawcroft  <marcus.shawcroft@arm.com>
+
+       * config/tc-aarch64.c (reloc_table_entry): Add adr_type.
+       (reloc_table): Likewise.
+       (parse_address_main): Use adr_type.
+
 2015-02-26  Marcus Shawcroft  <marcus.shawcroft@arm.com>
 
        * config/tc-aarch64.c (aarch64_arch_any, aarch64_arch_node): Remove.
index 01f39f61af4c6ff357fe2edb72cd991f8940caf2..b5f9ec3e089d012b88a37eeae596263c48dfe3fd 100644 (file)
@@ -2310,6 +2310,7 @@ struct reloc_table_entry
 {
   const char *name;
   int pc_rel;
+  bfd_reloc_code_real_type adr_type;
   bfd_reloc_code_real_type adrp_type;
   bfd_reloc_code_real_type movw_type;
   bfd_reloc_code_real_type add_type;
@@ -2319,6 +2320,7 @@ struct reloc_table_entry
 static struct reloc_table_entry reloc_table[] = {
   /* Low 12 bits of absolute address: ADD/i and LDR/STR */
   {"lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_ADD_LO12,
@@ -2326,6 +2328,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Higher 21 bits of pc-relative page offset: ADRP */
   {"pg_hi21", 1,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_HI21_PCREL,
    0,
    0,
@@ -2333,6 +2336,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Higher 21 bits of pc-relative page offset: ADRP, no check */
   {"pg_hi21_nc", 1,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL,
    0,
    0,
@@ -2340,6 +2344,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 0-15 of unsigned address/value: MOVZ */
   {"abs_g0", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G0,
    0,
@@ -2347,6 +2352,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 0-15 of signed address/value: MOVN/Z */
   {"abs_g0_s", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G0_S,
    0,
@@ -2354,6 +2360,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Less significant bits 0-15 of address/value: MOVK, no check */
   {"abs_g0_nc", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G0_NC,
    0,
@@ -2361,6 +2368,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 16-31 of unsigned address/value: MOVZ */
   {"abs_g1", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G1,
    0,
@@ -2368,6 +2376,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 16-31 of signed address/value: MOVN/Z */
   {"abs_g1_s", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G1_S,
    0,
@@ -2375,6 +2384,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Less significant bits 16-31 of address/value: MOVK, no check */
   {"abs_g1_nc", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G1_NC,
    0,
@@ -2382,6 +2392,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 32-47 of unsigned address/value: MOVZ */
   {"abs_g2", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G2,
    0,
@@ -2389,6 +2400,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 32-47 of signed address/value: MOVN/Z */
   {"abs_g2_s", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G2_S,
    0,
@@ -2396,6 +2408,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Less significant bits 32-47 of address/value: MOVK, no check */
   {"abs_g2_nc", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G2_NC,
    0,
@@ -2403,6 +2416,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 48-63 of signed/unsigned address/value: MOVZ */
   {"abs_g3", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_MOVW_G3,
    0,
@@ -2410,6 +2424,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get to the page containing GOT entry for a symbol.  */
   {"got", 1,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_GOT_PAGE,
    0,
    0,
@@ -2417,6 +2432,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* 12 bit offset into the page containing GOT entry for that symbol.  */
   {"got_lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    0,
@@ -2424,6 +2440,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get to the page containing GOT TLS entry for a symbol */
   {"tlsgd", 0,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21,
    0,
    0,
@@ -2431,6 +2448,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
   {"tlsgd_lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC,
@@ -2438,6 +2456,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get to the page containing GOT TLS entry for a symbol */
   {"tlsdesc", 0,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21,
    0,
    0,
@@ -2445,6 +2464,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
   {"tlsdesc_lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC,
@@ -2452,6 +2472,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get to the page containing GOT TLS entry for a symbol */
   {"gottprel", 0,
+   0,                          /* adr_type */
    BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21,
    0,
    0,
@@ -2459,6 +2480,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
   {"gottprel_lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    0,
@@ -2466,6 +2488,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get tp offset for a symbol.  */
   {"tprel", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
@@ -2473,6 +2496,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get tp offset for a symbol.  */
   {"tprel_lo12", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
@@ -2480,6 +2504,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get tp offset for a symbol.  */
   {"tprel_hi12", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12,
@@ -2487,6 +2512,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Get tp offset for a symbol.  */
   {"tprel_lo12_nc", 0,
+   0,                          /* adr_type */
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC,
@@ -2494,6 +2520,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 32-47 of address/value: MOVZ.  */
   {"tprel_g2", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2,
    0,
@@ -2501,6 +2528,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 16-31 of address/value: MOVZ.  */
   {"tprel_g1", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1,
    0,
@@ -2508,6 +2536,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 16-31 of address/value: MOVZ, no check.  */
   {"tprel_g1_nc", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC,
    0,
@@ -2515,6 +2544,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 0-15 of address/value: MOVZ.  */
   {"tprel_g0", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0,
    0,
@@ -2522,6 +2552,7 @@ static struct reloc_table_entry reloc_table[] = {
 
   /* Most significant bits 0-15 of address/value: MOVZ, no check.  */
   {"tprel_g0_nc", 0,
+   0,                          /* adr_type */
    0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC,
    0,
@@ -2931,6 +2962,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc,
       skip_past_char (&p, '#');
       if (reloc && skip_past_char (&p, ':'))
        {
+         bfd_reloc_code_real_type ty;
          struct reloc_table_entry *entry;
 
          /* Try to parse a relocation modifier.  Anything else is
@@ -2942,7 +2974,19 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc,
              return FALSE;
            }
 
-         if (entry->ldst_type == 0)
+         switch (operand->type)
+           {
+           case AARCH64_OPND_ADDR_PCREL21:
+             /* adr */
+             ty = entry->adr_type;
+             break;
+
+           default:
+             ty = entry->ldst_type;
+             break;
+           }
+
+         if (ty == 0)
            {
              set_syntax_error
                (_("this relocation modifier is not allowed on this "
@@ -2958,8 +3002,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc,
            }
 
          /* #:<reloc_op>:<expr>  */
-         /* Record the load/store relocation type.  */
-         inst.reloc.type = entry->ldst_type;
+         /* Record the relocation type.  */
+         inst.reloc.type = ty;
          inst.reloc.pc_rel = entry->pc_rel;
        }
       else