From 74ad790c76cf890fc7f42d6dd5a4cebfde5cc0db Mon Sep 17 00:00:00 2001 From: Marcus Shawcroft Date: Wed, 18 Feb 2015 18:10:27 +0000 Subject: [PATCH] Adding ld_literal_type. Extend the address modifier parsing to distinguish between the modifers used in LDR literal and LDR register offset address modes. The current parser incorrectly accepts the :got: modifier on a register offset instruction resulting in silent corruption of the output binary. --- gas/ChangeLog | 6 ++++++ gas/config/tc-aarch64.c | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 3623462..59d1c3d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,11 @@ 2015-02-26 Marcus Shawcroft + * config/tc-aarch64.c (reloc_table_entry): Add ld_literal_type. + (reloc_table): Likewise. + (parse_address_main): Use ld_literal_type. + +2015-02-26 Marcus Shawcroft + * config/tc-aarch64.c (reloc_table_entry): Add adr_type. (reloc_table): Likewise. (parse_address_main): Use adr_type. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index b5f9ec3..6795c06 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2315,6 +2315,7 @@ struct reloc_table_entry bfd_reloc_code_real_type movw_type; bfd_reloc_code_real_type add_type; bfd_reloc_code_real_type ldst_type; + bfd_reloc_code_real_type ld_literal_type; }; static struct reloc_table_entry reloc_table[] = { @@ -2324,7 +2325,8 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_ADD_LO12, - BFD_RELOC_AARCH64_LDST_LO12}, + BFD_RELOC_AARCH64_LDST_LO12, + 0}, /* Higher 21 bits of pc-relative page offset: ADRP */ {"pg_hi21", 1, @@ -2332,6 +2334,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_ADR_HI21_PCREL, 0, 0, + 0, 0}, /* Higher 21 bits of pc-relative page offset: ADRP, no check */ @@ -2340,6 +2343,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL, 0, 0, + 0, 0}, /* Most significant bits 0-15 of unsigned address/value: MOVZ */ @@ -2348,6 +2352,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G0, 0, + 0, 0}, /* Most significant bits 0-15 of signed address/value: MOVN/Z */ @@ -2356,6 +2361,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G0_S, 0, + 0, 0}, /* Less significant bits 0-15 of address/value: MOVK, no check */ @@ -2364,6 +2370,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G0_NC, 0, + 0, 0}, /* Most significant bits 16-31 of unsigned address/value: MOVZ */ @@ -2372,6 +2379,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G1, 0, + 0, 0}, /* Most significant bits 16-31 of signed address/value: MOVN/Z */ @@ -2380,6 +2388,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G1_S, 0, + 0, 0}, /* Less significant bits 16-31 of address/value: MOVK, no check */ @@ -2388,6 +2397,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G1_NC, 0, + 0, 0}, /* Most significant bits 32-47 of unsigned address/value: MOVZ */ @@ -2396,6 +2406,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G2, 0, + 0, 0}, /* Most significant bits 32-47 of signed address/value: MOVN/Z */ @@ -2404,6 +2415,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G2_S, 0, + 0, 0}, /* Less significant bits 32-47 of address/value: MOVK, no check */ @@ -2412,6 +2424,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G2_NC, 0, + 0, 0}, /* Most significant bits 48-63 of signed/unsigned address/value: MOVZ */ @@ -2420,6 +2433,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_MOVW_G3, 0, + 0, 0}, /* Get to the page containing GOT entry for a symbol. */ @@ -2428,6 +2442,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_ADR_GOT_PAGE, 0, 0, + 0, BFD_RELOC_AARCH64_GOT_LD_PREL19}, /* 12 bit offset into the page containing GOT entry for that symbol. */ @@ -2436,7 +2451,8 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, 0, - BFD_RELOC_AARCH64_LD_GOT_LO12_NC}, + BFD_RELOC_AARCH64_LD_GOT_LO12_NC, + 0}, /* Get to the page containing GOT TLS entry for a symbol */ {"tlsgd", 0, @@ -2444,6 +2460,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21, 0, 0, + 0, 0}, /* 12 bit offset into the page containing GOT TLS entry for a symbol */ @@ -2452,6 +2469,7 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC, + 0, 0}, /* Get to the page containing GOT TLS entry for a symbol */ @@ -2460,6 +2478,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21, 0, 0, + 0, 0}, /* 12 bit offset into the page containing GOT TLS entry for a symbol */ @@ -2468,7 +2487,8 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC, - BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC}, + BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC, + 0}, /* Get to the page containing GOT TLS entry for a symbol */ {"gottprel", 0, @@ -2476,6 +2496,7 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 0, 0, + 0, 0}, /* 12 bit offset into the page containing GOT TLS entry for a symbol */ @@ -2484,7 +2505,8 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, 0, - BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC}, + BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC, + 0}, /* Get tp offset for a symbol. */ {"tprel", 0, @@ -2492,6 +2514,7 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12, + 0, 0}, /* Get tp offset for a symbol. */ @@ -2500,6 +2523,7 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12, + 0, 0}, /* Get tp offset for a symbol. */ @@ -2508,6 +2532,7 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12, + 0, 0}, /* Get tp offset for a symbol. */ @@ -2516,6 +2541,7 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC, + 0, 0}, /* Most significant bits 32-47 of address/value: MOVZ. */ @@ -2524,6 +2550,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2, 0, + 0, 0}, /* Most significant bits 16-31 of address/value: MOVZ. */ @@ -2532,6 +2559,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1, 0, + 0, 0}, /* Most significant bits 16-31 of address/value: MOVZ, no check. */ @@ -2540,6 +2568,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 0, + 0, 0}, /* Most significant bits 0-15 of address/value: MOVZ. */ @@ -2548,6 +2577,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0, 0, + 0, 0}, /* Most significant bits 0-15 of address/value: MOVZ, no check. */ @@ -2556,6 +2586,7 @@ static struct reloc_table_entry reloc_table[] = { 0, BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 0, + 0, 0}, }; @@ -2982,7 +3013,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, break; default: - ty = entry->ldst_type; + ty = entry->ld_literal_type; break; } -- 2.7.4