From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 777DC3850874 for ; Thu, 21 Jul 2022 01:38:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 777DC3850874 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from 5.5.5 (unknown [10.2.5.5]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9DxL9IJrthi4bErAA--.40628S5; Thu, 21 Jul 2022 09:38:28 +0800 (CST) From: liuzhensong To: binutils@sourceware.org Cc: xry111@xry111.site, i.swmail@xen0n.name, maskray@google.com, xuchenghua@loongson.cn, mengqinggang@loongson.cn, huangpei@loongson.cn, chenglulu@loongson.cn, caiyinyu@loongson.cn, liuzhensong Subject: [PATCH v2 3/6] LoongArch: gas: Add new reloc types. Date: Thu, 21 Jul 2022 09:37:49 +0800 Message-Id: <20220721013751.466014-4-liuzhensong@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220721013751.466014-1-liuzhensong@loongson.cn> References: <20220721013751.466014-1-liuzhensong@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: AQAAf9DxL9IJrthi4bErAA--.40628S5 X-Coremail-Antispam: 1UD129KBjvJXoW3Cw18CF1DWry7tw4DGFyrXrb_yoWkKry8pF sxZw4ftr48JF1IgF98tFyku3WUZ3s7K342vFyaqw109r4xJryrAa1vqFy3XF909ws0gw47 Xr9Yg3WUX3W5Aa7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPC14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWx Jr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2I x0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8 JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2 ka0xkIwI1lc2xSY4AK6svPMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4U MI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67 AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0 cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z2 80aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI 43ZEXa7VUbJ73DUUUUU== X-CM-SenderInfo: holx6xphqv003j6o00pqjv00gofq/ X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jul 2022 01:38:34 -0000 Generate new relocate types while use new macro insns. gas/config/ loongarch-lex.h loongarch-parse.y tc-loongarch.c tc-loongarch.h --- gas/config/loongarch-lex.h | 3 + gas/config/loongarch-parse.y | 72 +++++------------- gas/config/tc-loongarch.c | 140 ++++++++++++++++++++++++----------- gas/config/tc-loongarch.h | 7 +- 4 files changed, 120 insertions(+), 102 deletions(-) diff --git a/gas/config/loongarch-lex.h b/gas/config/loongarch-lex.h index 59212442242..35d22dbdbc9 100644 --- a/gas/config/loongarch-lex.h +++ b/gas/config/loongarch-lex.h @@ -32,3 +32,6 @@ loongarch_parse_expr (const char *expr, size_t max_reloc_num, size_t *reloc_num, offsetT *imm); +bfd_reloc_code_real_type +loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *l_r_name); diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y index 710f854c74f..902d7204e8e 100644 --- a/gas/config/loongarch-parse.y +++ b/gas/config/loongarch-parse.y @@ -83,11 +83,11 @@ static const char * my_getExpression (expressionS *ep, const char *str) { char *save_in, *ret; + if (*str == ':') { unsigned long j; char *str_1 = (char *) str; - str_1++; j = strtol (str_1, &str_1, 10); get_internal_label (ep, j, *str_1 == 'f'); return NULL; @@ -104,65 +104,31 @@ static void reloc (const char *op_c_str, const char *id_c_str, offsetT addend) { expressionS id_sym_expr; + bfd_reloc_code_real_type btype; if (end <= top) as_fatal (_("expr too huge")); - if (id_c_str) - { - my_getExpression (&id_sym_expr, id_c_str); - id_sym_expr.X_add_number += addend; - } + /* For compatible old asm code. */ + if (0 == strcmp (op_c_str, "plt")) + btype = BFD_RELOC_LARCH_B26; else - { - id_sym_expr.X_op = O_constant; - id_sym_expr.X_add_number = addend; - } + btype = loongarch_larch_reloc_name_lookup (NULL, op_c_str); - if (strcmp (op_c_str, "abs") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_ABSOLUTE; - top++; - } - else if (strcmp (op_c_str, "pcrel") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_PCREL; - top++; - } - else if (strcmp (op_c_str, "gprel") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_GPREL; - top++; - } - else if (strcmp (op_c_str, "tprel") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL; - top++; - } - else if (strcmp (op_c_str, "tlsgot") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT; - top++; - } - else if (strcmp (op_c_str, "tlsgd") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GD; - top++; - } - else if (strcmp (op_c_str, "plt") == 0) - { - top->value = id_sym_expr; - top->type = BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL; - top++; - } + if (id_c_str) + { + my_getExpression (&id_sym_expr, id_c_str); + id_sym_expr.X_add_number += addend; + } else - as_fatal (_("unknown reloc hint: %s"), op_c_str); + { + id_sym_expr.X_op = O_constant; + id_sym_expr.X_add_number = addend; + } + + top->value = id_sym_expr; + top->type = btype; + top++; } static void diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 08203d291bd..fbbaca55085 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -362,18 +362,6 @@ loongarch_mach (void) static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 }; -static const char * -my_getExpression (expressionS *ep, const char *str) -{ - char *save_in, *ret; - save_in = input_line_pointer; - input_line_pointer = (char *) str; - expression (ep); - ret = input_line_pointer; - input_line_pointer = save_in; - return ret; -} - static void s_loongarch_align (int arg) { @@ -480,11 +468,6 @@ get_internal_label (expressionS *label_expr, unsigned long label, label_expr->X_add_number = 0; } -extern int loongarch_parse_expr (const char *expr, - struct reloc_info *reloc_stack_top, - size_t max_reloc_num, size_t *reloc_num, - offsetT *imm_if_no_reloc); - static int is_internal_label (const char *c_str) { @@ -652,6 +635,15 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, as_fatal ( _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"), esc_ch1, esc_ch2, bit_field, arg); + if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16 + && ip->reloc_info[0].type < BFD_RELOC_LARCH_RELAX) + { + /* As we compact stack-relocs, it is no need for pop operation. + But break out until here in order to check the imm field. + May be reloc_num > 1 if implement relax? */ + ip->reloc_num += reloc_num; + break; + } reloc_num++; ip->reloc_num += reloc_num; ip->reloc_info[ip->reloc_num - 1].type = reloc_type; @@ -767,7 +759,12 @@ get_loongarch_opcode (struct loongarch_cl_insn *insn) { ase->name_hash_entry = str_htab_create (); for (it = ase->opcodes; it->name; it++) - str_hash_insert (ase->name_hash_entry, it->name, (void *) it, 0); + { + if ((!it->include || (it->include && *it->include)) + && (!it->exclude || (it->exclude && !(*it->exclude)))) + str_hash_insert (ase->name_hash_entry, it->name, + (void *) it, 0); + } } if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL) @@ -800,10 +797,11 @@ static int check_this_insn_before_appending (struct loongarch_cl_insn *ip) { int ret = 0; - if (strcmp (ip->name, "la.abs") == 0) + + if (strncmp (ip->name, "la.abs", 6) == 0) { ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA; - my_getExpression (&ip->reloc_info[ip->reloc_num].value, ip->arg_strs[1]); + ip->reloc_info[ip->reloc_num].value = const_0; ip->reloc_num++; } else if (ip->insn->mask == 0xffff8000 @@ -980,6 +978,7 @@ assember_macro_helper (const char *const args[], void *context_ptr) ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL, sizeof (args_buf)); } + return ret; } @@ -1096,6 +1095,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) static int64_t stack_top; static int last_reloc_is_sop_push_pcrel_1 = 0; int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1; + segT sub_segment; last_reloc_is_sop_push_pcrel_1 = 0; char *buf = fixP->fx_frag->fr_literal + fixP->fx_where; @@ -1104,26 +1104,40 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL: case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD: case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT: - case BFD_RELOC_LARCH_SOP_PUSH_PCREL: - case BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL: + case BFD_RELOC_LARCH_TLS_LE_HI20: + case BFD_RELOC_LARCH_TLS_LE_LO12: + case BFD_RELOC_LARCH_TLS_LE64_LO20: + case BFD_RELOC_LARCH_TLS_LE64_HI12: + case BFD_RELOC_LARCH_TLS_IE_PC_HI20: + case BFD_RELOC_LARCH_TLS_IE_PC_LO12: + case BFD_RELOC_LARCH_TLS_IE64_PC_LO20: + case BFD_RELOC_LARCH_TLS_IE64_PC_HI12: + case BFD_RELOC_LARCH_TLS_IE_HI20: + case BFD_RELOC_LARCH_TLS_IE_LO12: + case BFD_RELOC_LARCH_TLS_IE64_LO20: + case BFD_RELOC_LARCH_TLS_IE64_HI12: + case BFD_RELOC_LARCH_TLS_LD_PC_HI20: + case BFD_RELOC_LARCH_TLS_LD_HI20: + case BFD_RELOC_LARCH_TLS_GD_PC_HI20: + case BFD_RELOC_LARCH_TLS_GD_HI20: + /* Add tls lo (got_lo reloc type). */ if (fixP->fx_addsy == NULL) as_bad_where (fixP->fx_file, fixP->fx_line, _("Relocation against a constant")); + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; - if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL - || fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GD - || fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT) - S_SET_THREAD_LOCAL (fixP->fx_addsy); + case BFD_RELOC_LARCH_SOP_PUSH_PCREL: + if (fixP->fx_addsy == NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Relocation against a constant")); - if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_PCREL) - { - last_reloc_is_sop_push_pcrel_1 = 1; - if (S_GET_SEGMENT (fixP->fx_addsy) == seg) - stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset - - (fixP->fx_where + fixP->fx_frag->fr_address)); - else - stack_top = 0; - } + last_reloc_is_sop_push_pcrel_1 = 1; + if (S_GET_SEGMENT (fixP->fx_addsy) == seg) + stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset + - (fixP->fx_where + fixP->fx_frag->fr_address)); + else + stack_top = 0; break; case BFD_RELOC_LARCH_SOP_POP_32_S_10_5: @@ -1143,11 +1157,24 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_64: case BFD_RELOC_32: + case BFD_RELOC_24: + case BFD_RELOC_16: + case BFD_RELOC_8: + + if (fixP->fx_r_type == BFD_RELOC_32 + && fixP->fx_addsy && fixP->fx_subsy + && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy)) + && strcmp (sub_segment->name, ".eh_frame") == 0 + && S_GET_VALUE (fixP->fx_subsy) + == fixP->fx_frag->fr_address + fixP->fx_where) + { + fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL; + fixP->fx_subsy = NULL; + break; + } + if (fixP->fx_subsy) { - case BFD_RELOC_24: - case BFD_RELOC_16: - case BFD_RELOC_8: fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); fixP->fx_next->fx_addsy = fixP->fx_subsy; fixP->fx_next->fx_subsy = NULL; @@ -1190,6 +1217,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) } break; + case BFD_RELOC_LARCH_B16: + case BFD_RELOC_LARCH_B21: + case BFD_RELOC_LARCH_B26: + if (fixP->fx_addsy == NULL) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _ ("Relocation against a constant.")); + } + if (S_GET_SEGMENT (fixP->fx_addsy) == seg + && !S_FORCE_RELOC (fixP->fx_addsy, 1)) + { + int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset; + int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address; + fix_reloc_insn (fixP, sym_addend - pc, buf); + fixP->fx_done = 1; + } + + break; + default: break; } @@ -1210,6 +1256,18 @@ md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED, return 0; } +int +loongarch_fix_adjustable (fixS *fix) +{ + /* Prevent all adjustments to global symbols. */ + if (S_IS_EXTERNAL (fix->fx_addsy) + || S_IS_WEAK (fix->fx_addsy) + || S_FORCE_RELOC (fix->fx_addsy, true)) + return 0; + + return 1; +} + /* Translate internal representation of relocation info to BFD target format. */ arelent * @@ -1249,12 +1307,6 @@ loongarch_cfi_frame_initial_instructions (void) cfi_add_CFA_def_cfa_register (3 /* $sp */); } -int -loongarch_dwarf2_addr_size (void) -{ - return LARCH_opts.ase_lp64 ? 8 : 4; -} - void tc_loongarch_parse_to_dw2regnum (expressionS *exp) { diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h index 2664da59f51..f05926d7d67 100644 --- a/gas/config/tc-loongarch.h +++ b/gas/config/tc-loongarch.h @@ -49,7 +49,8 @@ extern int loongarch_relax_frag (asection *, struct frag *, long); /* This is called to see whether a reloc against a defined symbol should be converted into a reloc against a section. */ -#define tc_fix_adjustable(fixp) 0 +extern int loongarch_fix_adjustable (struct fix *fix); +#define tc_fix_adjustable(fixp) loongarch_fix_adjustable(fixp) /* Values passed to md_apply_fix don't include symbol values. */ #define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 @@ -59,10 +60,6 @@ extern int loongarch_relax_frag (asection *, struct frag *, long); #define TARGET_USE_CFIPOP 1 #define DWARF2_DEFAULT_RETURN_COLUMN 1 /* $ra. */ #define DWARF2_CIE_DATA_ALIGNMENT -4 -extern int loongarch_dwarf2_addr_size (void); -#define DWARF2_FDE_RELOC_SIZE loongarch_dwarf2_addr_size () -#define DWARF2_ADDR_SIZE(bfd) loongarch_dwarf2_addr_size () -#define CFI_DIFF_EXPR_OK 0 #define tc_cfi_frame_initial_instructions \ loongarch_cfi_frame_initial_instructions -- 2.31.1