X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-aarch64.c;h=2cc7b4bd26284726259f66e9df8f18f1a4c4efc5;hb=a75cf613fd7d0a48d526a996ff5c250c599d3ab7;hp=50311342ab24bf68fdf225c650a1bc60db0bbd74;hpb=4bf8c6e8986890caa482c845d2c4a0ff238c1e28;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 50311342ab..2cc7b4bd26 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -171,24 +171,12 @@ get_error_message (void) return inst.parsing_error.error; } -static inline void -set_error_message (const char *error) -{ - inst.parsing_error.error = error; -} - static inline enum aarch64_operand_error_kind get_error_kind (void) { return inst.parsing_error.kind; } -static inline void -set_error_kind (enum aarch64_operand_error_kind kind) -{ - inst.parsing_error.kind = kind; -} - static inline void set_error (enum aarch64_operand_error_kind kind, const char *error) { @@ -1472,28 +1460,28 @@ mapping_state (enum mstate state) { enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; -#define TRANSITION(from, to) (mapstate == (from) && state == (to)) - - if (mapstate == state) - /* The mapping symbol has already been emitted. - There is nothing else to do. */ - return; - if (state == MAP_INSN) /* AArch64 instructions require 4-byte alignment. When emitting instructions into any section, record the appropriate section alignment. */ record_alignment (now_seg, 2); - if (TRANSITION (MAP_UNDEFINED, MAP_DATA)) - /* This case will be evaluated later in the next else. */ + if (mapstate == state) + /* The mapping symbol has already been emitted. + There is nothing else to do. */ + return; + +#define TRANSITION(from, to) (mapstate == (from) && state == (to)) + if (TRANSITION (MAP_UNDEFINED, MAP_DATA) && !subseg_text_p (now_seg)) + /* Emit MAP_DATA within executable section in order. Otherwise, it will be + evaluated later in the next else. */ return; else if (TRANSITION (MAP_UNDEFINED, MAP_INSN)) { /* Only add the symbol if the offset is > 0: - if we're at the first frag, check it's size > 0; - if we're not at the first frag, then for sure - the offset is > 0. */ + if we're at the first frag, check it's size > 0; + if we're not at the first frag, then for sure + the offset is > 0. */ struct frag *const frag_first = seg_info (now_seg)->frchainP->frch_root; const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0); @@ -1501,9 +1489,9 @@ mapping_state (enum mstate state) if (add_symbol) make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first); } +#undef TRANSITION mapping_state_2 (state, 0); -#undef TRANSITION } /* Same as mapping_state, but MAX_CHARS bytes have already been @@ -1867,8 +1855,14 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED) return; } - if (!need_pass_2) + /* Sections are assumed to start aligned. In executable section, there is no + MAP_DATA symbol pending. So we only align the address during + MAP_DATA --> MAP_INSN transition. + For other sections, this is not guaranteed. */ + enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; + if (!need_pass_2 && subseg_text_p (now_seg) && mapstate == MAP_DATA) frag_align_code (2, 0); + #ifdef OBJ_ELF mapping_state (MAP_INSN); #endif @@ -1898,6 +1892,21 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED) } #ifdef OBJ_ELF +/* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction. */ + +static void +s_tlsdescadd (int ignored ATTRIBUTE_UNUSED) +{ + expressionS exp; + + expression (&exp); + frag_grow (4); + fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 4, &exp, 0, + BFD_RELOC_AARCH64_TLSDESC_ADD); + + demand_empty_rest_of_line (); +} + /* Emit BFD_RELOC_AARCH64_TLSDESC_CALL on the next BLR instruction. */ static void @@ -1917,6 +1926,21 @@ s_tlsdesccall (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } + +/* Emit BFD_RELOC_AARCH64_TLSDESC_LDR on the next LDR instruction. */ + +static void +s_tlsdescldr (int ignored ATTRIBUTE_UNUSED) +{ + expressionS exp; + + expression (&exp); + frag_grow (4); + fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 4, &exp, 0, + BFD_RELOC_AARCH64_TLSDESC_LDR); + + demand_empty_rest_of_line (); +} #endif /* OBJ_ELF */ static void s_aarch64_arch (int); @@ -1942,7 +1966,9 @@ const pseudo_typeS md_pseudo_table[] = { {"arch_extension", s_aarch64_arch_extension, 0}, {"inst", s_aarch64_inst, 0}, #ifdef OBJ_ELF + {"tlsdescadd", s_tlsdescadd, 0}, {"tlsdesccall", s_tlsdesccall, 0}, + {"tlsdescldr", s_tlsdescldr, 0}, {"word", s_aarch64_elf_cons, 4}, {"long", s_aarch64_elf_cons, 4}, {"xword", s_aarch64_elf_cons, 8}, @@ -2461,6 +2487,51 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_LD_GOT_LO12_NC, 0}, + /* 0-15 bits of address/value: MOVk, no check. */ + {"gotoff_g0_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC, + 0, + 0, + 0}, + + /* Most significant bits 16-31 of address/value: MOVZ. */ + {"gotoff_g1", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_MOVW_GOTOFF_G1, + 0, + 0, + 0}, + + /* 15 bit offset into the page containing GOT entry for that symbol. */ + {"gotoff_lo15", 0, + 0, /* adr_type */ + 0, + 0, + 0, + BFD_RELOC_AARCH64_LD64_GOTOFF_LO15, + 0}, + + /* Get to the page containing GOT TLS entry for a symbol */ + {"gottprel_g0_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, + 0, + 0, + 0}, + + /* Get to the page containing GOT TLS entry for a symbol */ + {"gottprel_g1", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1, + 0, + 0, + 0}, + /* Get to the page containing GOT TLS entry for a symbol */ {"tlsgd", 0, BFD_RELOC_AARCH64_TLSGD_ADR_PREL21, /* adr_type */ @@ -2479,6 +2550,24 @@ static struct reloc_table_entry reloc_table[] = { 0, 0}, + /* Lower 16 bits address/value: MOVk. */ + {"tlsgd_g0_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC, + 0, + 0, + 0}, + + /* Most significant bits 16-31 of address/value: MOVZ. */ + {"tlsgd_g1", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSGD_MOVW_G1, + 0, + 0, + 0}, + /* Get to the page containing GOT TLS entry for a symbol */ {"tlsdesc", 0, BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21, /* adr_type */ @@ -2497,6 +2586,118 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC, 0}, + /* Get to the page containing GOT TLS entry for a symbol. + The same as GD, we allocate two consecutive GOT slots + for module index and module offset, the only difference + with GD is the module offset should be intialized to + zero without any outstanding runtime relocation. */ + {"tlsldm", 0, + BFD_RELOC_AARCH64_TLSLD_ADR_PREL21, /* adr_type */ + BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21, + 0, + 0, + 0, + 0}, + + /* 12 bit offset into the page containing GOT TLS entry for a symbol */ + {"tlsldm_lo12_nc", 0, + 0, /* adr_type */ + 0, + 0, + BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC, + 0, + 0}, + + /* 12 bit offset into the module TLS base address. */ + {"dtprel_lo12", 0, + 0, /* adr_type */ + 0, + 0, + BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12, + BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12, + 0}, + + /* Same as dtprel_lo12, no overflow check. */ + {"dtprel_lo12_nc", 0, + 0, /* adr_type */ + 0, + 0, + BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, + BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC, + 0}, + + /* bits[23:12] of offset to the module TLS base address. */ + {"dtprel_hi12", 0, + 0, /* adr_type */ + 0, + 0, + BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12, + 0, + 0}, + + /* bits[15:0] of offset to the module TLS base address. */ + {"dtprel_g0", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0, + 0, + 0, + 0}, + + /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */ + {"dtprel_g0_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, + 0, + 0, + 0}, + + /* bits[31:16] of offset to the module TLS base address. */ + {"dtprel_g1", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1, + 0, + 0, + 0}, + + /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */ + {"dtprel_g1_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, + 0, + 0, + 0}, + + /* bits[47:32] of offset to the module TLS base address. */ + {"dtprel_g2", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2, + 0, + 0, + 0}, + + /* Lower 16 bit offset into GOT entry for a symbol */ + {"tlsdesc_off_g0_nc", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC, + 0, + 0, + 0}, + + /* Higher 16 bit offset into GOT entry for a symbol */ + {"tlsdesc_off_g1", 0, + 0, /* adr_type */ + 0, + BFD_RELOC_AARCH64_TLSDESC_OFF_G1, + 0, + 0, + 0}, + /* Get to the page containing GOT TLS entry for a symbol */ {"gottprel", 0, 0, /* adr_type */ @@ -2595,6 +2796,24 @@ static struct reloc_table_entry reloc_table[] = { 0, 0, 0}, + + /* 15bit offset from got entry to base address of GOT table. */ + {"gotpage_lo15", 0, + 0, + 0, + 0, + 0, + BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15, + 0}, + + /* 14bit offset from got entry to base address of GOT table. */ + {"gotpage_lo14", 0, + 0, + 0, + 0, + 0, + BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14, + 0}, }; /* Given the address of a pointer pointing to the textual name of a @@ -3389,10 +3608,15 @@ parse_barrier (char **str) Returns the encoding for the option, or PARSE_FAIL. If IMPLE_DEFINED_P is non-zero, the function will also try to parse the - implementation defined system register name S____. */ + implementation defined system register name S____. + + If PSTATEFIELD_P is non-zero, the function will parse the name as a PSTATE + field, otherwise as a system register. +*/ static int -parse_sys_reg (char **str, struct hash_control *sys_regs, int imple_defined_p) +parse_sys_reg (char **str, struct hash_control *sys_regs, + int imple_defined_p, int pstatefield_p) { char *p, *q; char buf[32]; @@ -3427,9 +3651,15 @@ parse_sys_reg (char **str, struct hash_control *sys_regs, int imple_defined_p) } else { + if (pstatefield_p && !aarch64_pstatefield_supported_p (cpu_variant, o)) + as_bad (_("selected processor does not support PSTATE field " + "name '%s'"), buf); + if (!pstatefield_p && !aarch64_sys_reg_supported_p (cpu_variant, o)) + as_bad (_("selected processor does not support system register " + "name '%s'"), buf); if (aarch64_sys_reg_deprecated_p (o)) as_warn (_("system register name '%s' is deprecated and may be " -"removed in a future release"), buf); + "removed in a future release"), buf); value = o->value; } @@ -4526,6 +4756,7 @@ process_movw_reloc_info (void) case BFD_RELOC_AARCH64_MOVW_G0_S: case BFD_RELOC_AARCH64_MOVW_G1_S: case BFD_RELOC_AARCH64_MOVW_G2_S: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: @@ -4539,22 +4770,35 @@ process_movw_reloc_info (void) switch (inst.reloc.type) { case BFD_RELOC_AARCH64_MOVW_G0: - case BFD_RELOC_AARCH64_MOVW_G0_S: case BFD_RELOC_AARCH64_MOVW_G0_NC: + case BFD_RELOC_AARCH64_MOVW_G0_S: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: shift = 0; break; case BFD_RELOC_AARCH64_MOVW_G1: - case BFD_RELOC_AARCH64_MOVW_G1_S: case BFD_RELOC_AARCH64_MOVW_G1_NC: + case BFD_RELOC_AARCH64_MOVW_G1_S: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: shift = 16; break; case BFD_RELOC_AARCH64_MOVW_G2: - case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G2_NC: + case BFD_RELOC_AARCH64_MOVW_G2_S: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: if (is32) { @@ -4608,17 +4852,38 @@ get_logsz (unsigned int size) static inline bfd_reloc_code_real_type ldst_lo12_determine_real_reloc_type (void) { - int logsz; + unsigned logsz; enum aarch64_opnd_qualifier opd0_qlf = inst.base.operands[0].qualifier; enum aarch64_opnd_qualifier opd1_qlf = inst.base.operands[1].qualifier; - const bfd_reloc_code_real_type reloc_ldst_lo12[5] = { - BFD_RELOC_AARCH64_LDST8_LO12, BFD_RELOC_AARCH64_LDST16_LO12, - BFD_RELOC_AARCH64_LDST32_LO12, BFD_RELOC_AARCH64_LDST64_LO12, + const bfd_reloc_code_real_type reloc_ldst_lo12[3][5] = { + { + BFD_RELOC_AARCH64_LDST8_LO12, + BFD_RELOC_AARCH64_LDST16_LO12, + BFD_RELOC_AARCH64_LDST32_LO12, + BFD_RELOC_AARCH64_LDST64_LO12, BFD_RELOC_AARCH64_LDST128_LO12 + }, + { + BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, + BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, + BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, + BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, + BFD_RELOC_AARCH64_NONE + }, + { + BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, + BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, + BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, + BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, + BFD_RELOC_AARCH64_NONE + } }; - gas_assert (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12); + gas_assert (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12 + || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12 + || (inst.reloc.type + == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)); gas_assert (inst.base.opcode->operands[1] == AARCH64_OPND_ADDR_UIMM12); if (opd1_qlf == AARCH64_OPND_QLF_NIL) @@ -4628,9 +4893,16 @@ ldst_lo12_determine_real_reloc_type (void) gas_assert (opd1_qlf != AARCH64_OPND_QLF_NIL); logsz = get_logsz (aarch64_get_qualifier_esize (opd1_qlf)); - gas_assert (logsz >= 0 && logsz <= 4); + if (inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12 + || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC) + gas_assert (logsz <= 3); + else + gas_assert (logsz <= 4); - return reloc_ldst_lo12[logsz]; + /* In reloc.c, these pseudo relocation types should be defined in similar + order as above reloc_ldst_lo12 array. Because the array index calcuation + below relies on this. */ + return reloc_ldst_lo12[inst.reloc.type - BFD_RELOC_AARCH64_LDST_LO12][logsz]; } /* Check whether a register list REGINFO is valid. The registers must be @@ -5266,7 +5538,11 @@ parse_operands (char *str, const aarch64_opcode *opcode) } if (inst.reloc.type == BFD_RELOC_UNUSED) aarch64_set_gas_internal_fixup (&inst.reloc, info, 1); - else if (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12) + else if (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12 + || (inst.reloc.type + == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12) + || (inst.reloc.type + == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)) inst.reloc.type = ldst_lo12_determine_real_reloc_type (); /* Leave qualifier to be determined by libopcodes. */ break; @@ -5294,7 +5570,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) break; case AARCH64_OPND_SYSREG: - if ((val = parse_sys_reg (&str, aarch64_sys_regs_hsh, 1)) + if ((val = parse_sys_reg (&str, aarch64_sys_regs_hsh, 1, 0)) == PARSE_FAIL) { set_syntax_error (_("unknown or missing system register name")); @@ -5304,7 +5580,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) break; case AARCH64_OPND_PSTATEFIELD: - if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0)) + if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0, 1)) == PARSE_FAIL) { set_syntax_error (_("unknown or missing PSTATE field name")); @@ -5695,6 +5971,14 @@ md_assemble (char *str) init_operand_error_report (); + /* Sections are assumed to start aligned. In executable section, there is no + MAP_DATA symbol pending. So we only align the address during + MAP_DATA --> MAP_INSN transition. + For other sections, this is not guaranteed. */ + enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; + if (!need_pass_2 && subseg_text_p (now_seg) && mapstate == MAP_DATA) + frag_align_code (2, 0); + saved_cond = inst.cond; reset_aarch64_instruction (&inst); inst.cond = saved_cond; @@ -6026,21 +6310,20 @@ aarch64_init_frag (fragS * fragP, int max_chars) /* Record a mapping symbol for alignment frags. We will delete this later if the alignment ends up empty. */ if (!fragP->tc_frag_data.recorded) + fragP->tc_frag_data.recorded = 1; + + switch (fragP->fr_type) { - fragP->tc_frag_data.recorded = 1; - switch (fragP->fr_type) - { - case rs_align: - case rs_align_test: - case rs_fill: - mapping_state_2 (MAP_DATA, max_chars); - break; - case rs_align_code: - mapping_state_2 (MAP_INSN, max_chars); - break; - default: - break; - } + case rs_align: + case rs_align_test: + case rs_fill: + mapping_state_2 (MAP_DATA, max_chars); + break; + case rs_align_code: + mapping_state_2 (MAP_INSN, max_chars); + break; + default: + break; } } @@ -6600,8 +6883,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) } break; - case BFD_RELOC_AARCH64_JUMP26: case BFD_RELOC_AARCH64_CALL26: + case BFD_RELOC_AARCH64_JUMP26: if (fixP->fx_done || !seg->use_rela_p) { if (value & 3) @@ -6617,18 +6900,36 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) break; case BFD_RELOC_AARCH64_MOVW_G0: - case BFD_RELOC_AARCH64_MOVW_G0_S: case BFD_RELOC_AARCH64_MOVW_G0_NC: + case BFD_RELOC_AARCH64_MOVW_G0_S: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: scale = 0; goto movw_common; case BFD_RELOC_AARCH64_MOVW_G1: - case BFD_RELOC_AARCH64_MOVW_G1_S: case BFD_RELOC_AARCH64_MOVW_G1_NC: + case BFD_RELOC_AARCH64_MOVW_G1_S: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: scale = 16; goto movw_common; + case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: + scale = 0; + S_SET_THREAD_LOCAL (fixP->fx_addsy); + /* Should always be exported to object file, see + aarch64_force_relocation(). */ + gas_assert (!fixP->fx_done); + gas_assert (seg->use_rela_p); + goto movw_common; + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: + scale = 16; + S_SET_THREAD_LOCAL (fixP->fx_addsy); + /* Should always be exported to object file, see + aarch64_force_relocation(). */ + gas_assert (!fixP->fx_done); + gas_assert (seg->use_rela_p); + goto movw_common; case BFD_RELOC_AARCH64_MOVW_G2: - case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G2_NC: + case BFD_RELOC_AARCH64_MOVW_G2_S: scale = 32; goto movw_common; case BFD_RELOC_AARCH64_MOVW_G3: @@ -6654,6 +6955,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) case BFD_RELOC_AARCH64_MOVW_G1: case BFD_RELOC_AARCH64_MOVW_G2: case BFD_RELOC_AARCH64_MOVW_G3: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: if (unsigned_overflow (value, scale + 16)) as_bad_where (fixP->fx_file, fixP->fx_line, _("unsigned value out of range")); @@ -6722,10 +7025,33 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: + case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: + case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: @@ -6751,18 +7077,21 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) gas_assert (seg->use_rela_p); break; - case BFD_RELOC_AARCH64_ADR_HI21_PCREL: - case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: case BFD_RELOC_AARCH64_ADD_LO12: - case BFD_RELOC_AARCH64_LDST8_LO12: + case BFD_RELOC_AARCH64_ADR_GOT_PAGE: + case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: + case BFD_RELOC_AARCH64_ADR_HI21_PCREL: + case BFD_RELOC_AARCH64_GOT_LD_PREL19: + case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: + case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: + case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: + case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LDST128_LO12: case BFD_RELOC_AARCH64_LDST16_LO12: case BFD_RELOC_AARCH64_LDST32_LO12: case BFD_RELOC_AARCH64_LDST64_LO12: - case BFD_RELOC_AARCH64_LDST128_LO12: - case BFD_RELOC_AARCH64_GOT_LD_PREL19: - case BFD_RELOC_AARCH64_ADR_GOT_PAGE: - case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: - case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LDST8_LO12: /* Should always be exported to object file, see aarch64_force_relocation(). */ gas_assert (!fixP->fx_done); @@ -6770,8 +7099,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) break; case BFD_RELOC_AARCH64_TLSDESC_ADD: - case BFD_RELOC_AARCH64_TLSDESC_LDR: case BFD_RELOC_AARCH64_TLSDESC_CALL: + case BFD_RELOC_AARCH64_TLSDESC_LDR: break; case BFD_RELOC_UNUSED: @@ -6897,9 +7226,9 @@ aarch64_force_relocation (struct fix *fixp) even if the symbol is extern or weak. */ return 0; - case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: - case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: case BFD_RELOC_AARCH64_LD_GOT_LO12_NC: + case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: + case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: /* Pseudo relocs that need to be fixed up according to ilp32_p. */ return 0; @@ -6910,6 +7239,9 @@ aarch64_force_relocation (struct fix *fixp) case BFD_RELOC_AARCH64_ADR_HI21_PCREL: case BFD_RELOC_AARCH64_GOT_LD_PREL19: case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: + case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: + case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: case BFD_RELOC_AARCH64_LDST128_LO12: case BFD_RELOC_AARCH64_LDST16_LO12: @@ -6922,13 +7254,38 @@ aarch64_force_relocation (struct fix *fixp) case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: + case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: + case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: + case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: + case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: @@ -6952,6 +7309,11 @@ aarch64_force_relocation (struct fix *fixp) const char * elf64_aarch64_target_format (void) { + if (strcmp (TARGET_OS, "cloudabi") == 0) + { + /* FIXME: What to do for ilp32_p ? */ + return target_big_endian ? "elf64-bigaarch64-cloudabi" : "elf64-littleaarch64-cloudabi"; + } if (target_big_endian) return ilp32_p ? "elf32-bigaarch64" : "elf64-bigaarch64"; else @@ -7154,24 +7516,24 @@ md_begin (void) aarch64_pstatefields[i].name, (void *) (aarch64_pstatefields + i)); - for (i = 0; aarch64_sys_regs_ic[i].template != NULL; i++) + for (i = 0; aarch64_sys_regs_ic[i].name != NULL; i++) checked_hash_insert (aarch64_sys_regs_ic_hsh, - aarch64_sys_regs_ic[i].template, + aarch64_sys_regs_ic[i].name, (void *) (aarch64_sys_regs_ic + i)); - for (i = 0; aarch64_sys_regs_dc[i].template != NULL; i++) + for (i = 0; aarch64_sys_regs_dc[i].name != NULL; i++) checked_hash_insert (aarch64_sys_regs_dc_hsh, - aarch64_sys_regs_dc[i].template, + aarch64_sys_regs_dc[i].name, (void *) (aarch64_sys_regs_dc + i)); - for (i = 0; aarch64_sys_regs_at[i].template != NULL; i++) + for (i = 0; aarch64_sys_regs_at[i].name != NULL; i++) checked_hash_insert (aarch64_sys_regs_at_hsh, - aarch64_sys_regs_at[i].template, + aarch64_sys_regs_at[i].name, (void *) (aarch64_sys_regs_at + i)); - for (i = 0; aarch64_sys_regs_tlbi[i].template != NULL; i++) + for (i = 0; aarch64_sys_regs_tlbi[i].name != NULL; i++) checked_hash_insert (aarch64_sys_regs_tlbi_hsh, - aarch64_sys_regs_tlbi[i].template, + aarch64_sys_regs_tlbi[i].name, (void *) (aarch64_sys_regs_tlbi + i)); for (i = 0; i < ARRAY_SIZE (reg_names); i++) @@ -7320,7 +7682,12 @@ static const struct aarch64_cpu_option_table aarch64_cpus[] = { AARCH64_FEATURE_CRC), "Cortex-A57"}, {"cortex-a72", AARCH64_FEATURE (AARCH64_ARCH_V8, AARCH64_FEATURE_CRC), "Cortex-A72"}, - {"thunderx", AARCH64_ARCH_V8, "Cavium ThunderX"}, + {"exynos-m1", AARCH64_FEATURE (AARCH64_ARCH_V8, + AARCH64_FEATURE_CRC | AARCH64_FEATURE_CRYPTO), + "Samsung Exynos M1"}, + {"thunderx", AARCH64_FEATURE (AARCH64_ARCH_V8, + AARCH64_FEATURE_CRC | AARCH64_FEATURE_CRYPTO), + "Cavium ThunderX"}, /* The 'xgene-1' name is an older name for 'xgene1', which was used in earlier releases and is superseded by 'xgene1' in all tools. */ @@ -7344,6 +7711,7 @@ struct aarch64_arch_option_table static const struct aarch64_arch_option_table aarch64_archs[] = { {"all", AARCH64_ANY}, {"armv8-a", AARCH64_ARCH_V8}, + {"armv8.1-a", AARCH64_ARCH_V8_1}, {NULL, AARCH64_ARCH_NONE} }; @@ -7360,6 +7728,10 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { {"fp", AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)}, {"lse", AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0)}, {"simd", AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)}, + {"pan", AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0)}, + {"lor", AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0)}, + {"rdma", AARCH64_FEATURE (AARCH64_FEATURE_SIMD + | AARCH64_FEATURE_RDMA, 0)}, {NULL, AARCH64_ARCH_NONE} };