From patchwork Thu Oct 19 00:30:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tsukasa OI X-Patchwork-Id: 155239 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2010:b0:403:3b70:6f57 with SMTP id fe16csp80534vqb; Wed, 18 Oct 2023 17:32:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFuw8VWtKwEZKp+Blgz2jLXEkT5DLaNQwZGxgicRx5Ieq1HqivZ8mhVixoVxWdalAY6Rr8v X-Received: by 2002:a05:620a:4550:b0:778:8fb1:93b0 with SMTP id u16-20020a05620a455000b007788fb193b0mr939881qkp.8.1697675529777; Wed, 18 Oct 2023 17:32:09 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1697675529; cv=pass; d=google.com; s=arc-20160816; b=MhRQPfO87voM4xv5yIs6yGlrK/hi3WFNIIxDIdbGNV1sxBX7geHbHHHI8blSRlSuDa NFLYwXb8fXbNqMBh4qGdro2uXCkKXAMdhktnlxD8pI4RWHFTWEhE8VUvyuxBWhQqArx4 k9tr2Mfk82dBJzX3n14mDxW+7ZWj5rFl9HG/o+mAPYAPWf8HwYeWJwYQXsTH9KKdOO8O hwhywJ+dqbhRcqXd7UiqxvJog8sjjb+UnF0VrNcbRZ7Ybl7iaWiyYjvFiZQiJrkD1luB d4MqXbzNC/yXCQMRxSvty4tR0R3qGd/I8fm8FAIfLfHx5p4uafLwWB4fpL77PuqL6vxm bv/w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=M/A+Xgm6noZx59ukUaD11sMiGh2pm7RlleZKk4H3QhM=; fh=Q+ZPQdyJDzJx4BfovHNTR1lP4msTSfN6TDra8V1lyf8=; b=QVIz2795VH7Ec7qDlsGB/rVNnZP3REWJgSYbykSXQbjqnjOIShR6/grgDQd/aUGpBh KMWVVPJZhnFTXwTN2Stybcos6E5W6O09dQTW6d223YAevWutV0ENjSG3+LxYTcdgDzXz 31jzK61MsWilcGwRyNtvAyE2j/8Vq2DZbseEN2+dUArIcO1aZ9aFIPXyWL6FskXxYzDy e1XSXVRzy9zPagbJLYjdBNqEXoWwWYugKn+q7shNsa1GkeyybHmAIlDTFdMSiTdfsCmJ tYnZVsRyn/HDPkedZoJsSi0u5duGqnxn39W9uDvu68a9hupMmhki7tfTmLUoyjhfw0OG CRoQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@irq.a4lg.com header.s=2017s01 header.b=EYVPmFmk; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=irq.a4lg.com Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id x24-20020a05620a14b800b007788b89ec58si719734qkj.593.2023.10.18.17.32.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Oct 2023 17:32:09 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@irq.a4lg.com header.s=2017s01 header.b=EYVPmFmk; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=irq.a4lg.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8487338582B0 for ; Thu, 19 Oct 2023 00:32:09 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-sender-0.a4lg.com (mail-sender-0.a4lg.com [IPv6:2401:2500:203:30b:4000:6bfe:4757:0]) by sourceware.org (Postfix) with ESMTPS id A1C5A385841F for ; Thu, 19 Oct 2023 00:31:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A1C5A385841F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=irq.a4lg.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=irq.a4lg.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A1C5A385841F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2401:2500:203:30b:4000:6bfe:4757:0 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697675499; cv=none; b=iTAThc3qfsTjM1+E3CEIE1+D9Wf8e1Y8nHksI5W+9E7glV2bEEPGfIDZoZL0ODEzjJG72BXdCo2cB25n2IwBPEXErNbw9eGCQBC5BuR2IpN5iSOgQEDzRLOofntYGd1rUDx3tntxMX/NHvIO9eld2nhHUS4Ks0W5OLomZHc0DGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697675499; c=relaxed/simple; bh=trE7T1p0LM7tHF0k+fWcQQPqaqKrthzEKaGKsKkEoRE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=E45dCx1sBRGndawlqCor/+W67vwTCDnNa4a7YvpO7JIz/GFUBqjXDRtHxGhKhhsC1J372HV3BJFtkX3GOcA3LunF8ymZu879jt3U9vD5Tm7bveps1+hRa/U9IcSJCvsfMFveSvsG5h5UP1wQtOvcPuzk9gwYAJPePnYWfBRS1VE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id B1F6E300089; Thu, 19 Oct 2023 00:31:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irq.a4lg.com; s=2017s01; t=1697675494; bh=M/A+Xgm6noZx59ukUaD11sMiGh2pm7RlleZKk4H3QhM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Mime-Version:Content-Transfer-Encoding; b=EYVPmFmkKvwZFPGtvsPhS9MoedJwSCoP8v1YiuB1i0hZkINxyJnZEQRDaawQrhsAw Noj8lVj7ygLSJh6xvh/1aCCMSh3ILpUpYHyBnAcNHltTsBjHsRwpLL66m2lmnJarfJ C0vzOdUVNVMcuB0yentR/j0LR8NqeRm2h6dzeLdk= From: Tsukasa OI To: Tsukasa OI , Palmer Dabbelt , Andrew Waterman , Jim Wilson , Nelson Chu , Kito Cheng Cc: binutils@sourceware.org Subject: [PATCH v2 1/1] RISC-V: Separate invalid/internal only ELF relocs Date: Thu, 19 Oct 2023 00:30:59 +0000 Message-ID: <7081bd11d06993823e90497ead4096bde758fea2.1697675352.git.research_trasio@irq.a4lg.com> In-Reply-To: References: Mime-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, KAM_MANYTO, SPF_HELO_NONE, 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.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780141816778153169 X-GMAIL-MSGID: 1780141816778153169 From: Tsukasa OI After ratification of the RISC-V psABI specification (version 1.0), it is getting enhanced and improved. This commit performs following changes. 1. Reject unknown ELF relocation types when fed into a tool Before this commit, it accepted unknown (but small) relocation types and relocation types only for internal uses (linker relaxation). More worryingly, some internal only relocation types conflict with global relocation types in the latest psABI draft [1]. [1] If (a) psABI changes conflict with internal only relocation types and/or (b) an object (possibly malicious or just from the future) with unknown relocation type is encountered while linking (by ld) or relocating by other tools, it can cause a severe failure (with unpredictable erroneous results). This commit now rejects small unknown relocation types and internal only ones when an ELF file with such relocation types is fed into a tool. 2. Move internal only ELF relocation types after all regular ones Currently, we have six internal only relocation types but only R_RISCV_DELETE is distinguished from the regular one (others were defined in between regular relocation types). This design caused the conflict with regular relocation types *and* made fixing the number of such internal relocation a non-trivial task. This commit moves all internal only relocation types (not only R_RISCV_DELETE) after R_RISCV_max and creates separate howto relocation table for range (R_RISCV_DELETE + 1..R_RISCV_internal_max). All internal only relocations are defined relative to R_RISCV_max and will not conflict with regular ones (if psABI started to use large numbers, internal relocations are automatically adjusted). 3. Prevent internal only ELF relocation types from emitting It prevents emitting internal only relocations when the --emit-relocs option is specified when linking (instead, replaces such internal only relocations to R_RISCV_NONE). bfd/ChangeLog: * elfnn-riscv.c (R_RISCV_DELETE): Move to elf_riscv_reloc_type. (riscv_info_to_howto_rela, bad_static_reloc): Reflect riscv_elf_rtype_to_howto changes. (riscv_elf_check_relocs): Likewise. Also reject unknown relocs are found. Reuse howto variable. (riscv_elf_relocate_section): Reflect riscv_elf_rtype_to_howto changesL but also look up for internal relocs only when necessary. Delete internal only relocation after the relocation. * elfxx-riscv.c (HOWTO_ISEMPTY): New macro to query whether the howto entry is empty. (howto_table): Reserve all howto entries defined by the latest RISC-V psABI specification except no actual EMPTY_HOWTO defs at the end of the list. Move internal only relocs to... (howto_table_internal): ...here. (riscv_elf_rtype_to_howto): Add ability to look up internal only relocation types only when necessary. * elfxx-riscv.h (riscv_elf_rtype_to_howto): Reflect above. include/ChangeLog: * elf/riscv.h (enum elf_riscv_reloc_type): Comment all reserved relocation types as defined by the latest RISC-V psABI spec. Move all internal relocation types after R_RISCV_max, first being R_RISCV_DELETE. Add R_RISCV_internal_max. Add safety guard for all relocation types on C11 and later. --- bfd/elfnn-riscv.c | 40 +++++---- bfd/elfxx-riscv.c | 202 +++++++++++++++++++++++++++----------------- bfd/elfxx-riscv.h | 3 +- include/elf/riscv.h | 37 ++++++-- 4 files changed, 183 insertions(+), 99 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 09aa7be225ef..f9f3aca0af6a 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -130,9 +130,6 @@ } \ while (0) -/* Internal relocations used exclusively by the relaxation pass. */ -#define R_RISCV_DELETE (R_RISCV_max + 1) - #define ARCH_SIZE NN #define MINUS_ONE ((bfd_vma)0 - 1) @@ -267,7 +264,8 @@ riscv_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { - cache_ptr->howto = riscv_elf_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info)); + cache_ptr->howto = + riscv_elf_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info), false); return cache_ptr->howto != NULL; } @@ -714,7 +712,7 @@ riscv_elf_record_got_reference (bfd *abfd, struct bfd_link_info *info, static bool bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h) { - reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type); + reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type, false); /* We propably can improve the information to tell users that they should be recompile the code with -fPIC or -fPIE, just like what @@ -756,11 +754,17 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, { unsigned int r_type; unsigned int r_symndx; + reloc_howto_type *howto; struct elf_link_hash_entry *h; bool is_abs_symbol = false; r_symndx = ELFNN_R_SYM (rel->r_info); r_type = ELFNN_R_TYPE (rel->r_info); + howto = riscv_elf_rtype_to_howto (abfd, r_type, false); + + /* Reject unknown relocs. */ + if (!howto) + return false; if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) { @@ -916,12 +920,10 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL); } - reloc_howto_type *r_t = - riscv_elf_rtype_to_howto (abfd, r_type); _bfd_error_handler (_("%pB: relocation %s against absolute symbol `%s' can " "not be used when making a shared object"), - abfd, r_t ? r_t->name : _(""), name); + abfd, howto ? howto->name : _(""), name); bfd_set_error (bfd_error_bad_value); return false; } @@ -959,11 +961,10 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (is_abs_symbol) break; - reloc_howto_type *r_t = riscv_elf_rtype_to_howto (abfd, r_type); _bfd_error_handler (_("%pB: relocation %s against non-absolute symbol `%s' can " "not be used in RVNN when making a shared object"), - abfd, r_t ? r_t->name : _(""), + abfd, howto ? howto->name : _(""), h != NULL ? h->root.root.string : "a local symbol"); bfd_set_error (bfd_error_bad_value); return false; @@ -996,8 +997,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } } - reloc_howto_type *r = riscv_elf_rtype_to_howto (abfd, r_type); - if (RISCV_NEED_DYNAMIC_RELOC (r->pc_relative, info, h, sec)) + if (RISCV_NEED_DYNAMIC_RELOC (howto->pc_relative, info, h, sec)) { struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; @@ -1058,7 +1058,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } p->count += 1; - p->pc_count += r == NULL ? 0 : r->pc_relative; + p->pc_count += howto == NULL ? 0 : howto->pc_relative; } break; @@ -2182,7 +2182,8 @@ riscv_elf_relocate_section (bfd *output_bfd, bool unresolved_reloc, is_ie = false; bfd_vma pc = sec_addr (input_section) + rel->r_offset; int r_type = ELFNN_R_TYPE (rel->r_info), tls_type; - reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type); + reloc_howto_type *howto = + riscv_elf_rtype_to_howto (input_bfd, r_type, true); const char *msg = NULL; bool resolved_to_zero; @@ -2615,7 +2616,8 @@ riscv_elf_relocate_section (bfd *output_bfd, howto); /* Update howto if relocation is changed. */ howto = riscv_elf_rtype_to_howto (input_bfd, - ELFNN_R_TYPE (rel->r_info)); + ELFNN_R_TYPE (rel->r_info), + false); if (howto == NULL) r = bfd_reloc_notsupported; else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, @@ -2766,7 +2768,8 @@ riscv_elf_relocate_section (bfd *output_bfd, contents, howto); /* Update howto if relocation is changed. */ howto = riscv_elf_rtype_to_howto (input_bfd, - ELFNN_R_TYPE (rel->r_info)); + ELFNN_R_TYPE (rel->r_info), + false); if (howto == NULL) r = bfd_reloc_notsupported; else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, @@ -3008,6 +3011,11 @@ riscv_elf_relocate_section (bfd *output_bfd, r = perform_relocation (howto, rel, relocation, input_section, input_bfd, contents); + /* Delete internal only relocations + (overwrite with R_RISCV_NONE). */ + if (r_type >= R_RISCV_max) + rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE); + /* We should have already detected the error and set message before. If the error message isn't set since the linker runs out of memory or we don't set it before, then we should set the default message diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index c070394a3667..2366eae03abf 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -41,6 +41,10 @@ static bfd_reloc_status_type riscv_elf_add_sub_reloc static bfd_reloc_status_type riscv_elf_ignore_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +/* Check whether the given howto entry is empty (unknown). */ + +#define HOWTO_ISEMPTY(howto) (!((howto).name)) + /* The relocation table used for SHT_RELA sections. */ static reloc_howto_type howto_table[] = @@ -602,8 +606,8 @@ static reloc_howto_type howto_table[] = false), /* pcrel_offset */ /* 41 and 42 are reserved. */ - EMPTY_HOWTO (0), - EMPTY_HOWTO (0), + EMPTY_HOWTO (41), + EMPTY_HOWTO (42), /* Indicates an alignment statement. The addend field encodes how many bytes of NOPs follow the statement. The desired alignment is the @@ -652,80 +656,20 @@ static reloc_howto_type howto_table[] = ENCODE_CJTYPE_IMM (-1U), /* dst_mask */ true), /* pcrel_offset */ - /* High 6 bits of 18-bit absolute address. */ - HOWTO (R_RISCV_RVC_LUI, /* type */ - 0, /* rightshift */ - 2, /* size */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_RISCV_RVC_LUI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - ENCODE_CITYPE_IMM (-1U), /* dst_mask */ - false), /* pcrel_offset */ + /* 46 is reserved. */ + EMPTY_HOWTO (46), - /* GP-relative load. */ - HOWTO (R_RISCV_GPREL_I, /* type */ - 0, /* rightshift */ - 4, /* size */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_RISCV_GPREL_I", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - ENCODE_ITYPE_IMM (-1U), /* dst_mask */ - false), /* pcrel_offset */ + /* Reserved for R_RISCV_GPREL_LO12_I. */ + EMPTY_HOWTO (47), - /* GP-relative store. */ - HOWTO (R_RISCV_GPREL_S, /* type */ - 0, /* rightshift */ - 4, /* size */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_RISCV_GPREL_S", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - ENCODE_STYPE_IMM (-1U), /* dst_mask */ - false), /* pcrel_offset */ + /* Reserved for R_RISCV_GPREL_LO12_S. */ + EMPTY_HOWTO (48), - /* TP-relative TLS LE load. */ - HOWTO (R_RISCV_TPREL_I, /* type */ - 0, /* rightshift */ - 4, /* size */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_RISCV_TPREL_I", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - ENCODE_ITYPE_IMM (-1U), /* dst_mask */ - false), /* pcrel_offset */ + /* Reserved for R_RISCV_GPREL_HI20. */ + EMPTY_HOWTO (49), - /* TP-relative TLS LE store. */ - HOWTO (R_RISCV_TPREL_S, /* type */ - 0, /* rightshift */ - 4, /* size */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_RISCV_TPREL_S", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - ENCODE_STYPE_IMM (-1U), /* dst_mask */ - false), /* pcrel_offset */ + /* 50 is reserved. */ + EMPTY_HOWTO (50), /* The paired relocation may be relaxed. */ HOWTO (R_RISCV_RELAX, /* type */ @@ -879,6 +823,101 @@ static reloc_howto_type howto_table[] = 0, /* src_mask */ 0, /* dst_mask */ false), /* pcrel_offset */ + + /* Reserved for R_RISCV_TLSDESC_HI20. */ + /* EMPTY_HOWTO (62), */ + + /* Reserved for R_RISCV_TLSDESC_LOAD_LO12. */ + /* EMPTY_HOWTO (63), */ + + /* Reserved for R_RISCV_TLSDESC_ADD_LO12. */ + /* EMPTY_HOWTO (64), */ + + /* Reserved for R_RISCV_TLSDESC_CALL. */ + /* EMPTY_HOWTO (65), */ +}; + +/* The relocation table used for SHT_RELA sections for internal use. + Those relocations must be removed before we finish linking. */ + +static reloc_howto_type howto_table_internal[] = +{ + /* R_RISCV_DELETE is omitted since this is special. */ + + /* High 6 bits of 18-bit absolute address. */ + HOWTO (R_RISCV_RVC_LUI, /* type */ + 0, /* rightshift */ + 2, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_RVC_LUI", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_CITYPE_IMM (-1U), /* dst_mask */ + false), /* pcrel_offset */ + + /* GP-relative load. */ + HOWTO (R_RISCV_GPREL_I, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_GPREL_I", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_ITYPE_IMM (-1U), /* dst_mask */ + false), /* pcrel_offset */ + + /* GP-relative store. */ + HOWTO (R_RISCV_GPREL_S, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_GPREL_S", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_STYPE_IMM (-1U), /* dst_mask */ + false), /* pcrel_offset */ + + /* TP-relative TLS LE load. */ + HOWTO (R_RISCV_TPREL_I, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_I", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_ITYPE_IMM (-1U), /* dst_mask */ + false), /* pcrel_offset */ + + /* TP-relative TLS LE store. */ + HOWTO (R_RISCV_TPREL_S, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_S", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_STYPE_IMM (-1U), /* dst_mask */ + false), /* pcrel_offset */ }; /* A mapping from BFD reloc types to RISC-V ELF reloc types. */ @@ -973,16 +1012,27 @@ riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) } reloc_howto_type * -riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) +riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type, + bool lookup_internal) { - if (r_type >= ARRAY_SIZE (howto_table)) + reloc_howto_type *ret = NULL; + if (r_type < ARRAY_SIZE (howto_table)) + { + ret = &howto_table[r_type]; + if (HOWTO_ISEMPTY (*ret)) + ret = NULL; + } + else if (lookup_internal + && r_type > R_RISCV_DELETE + && r_type < R_RISCV_internal_max) + ret = &howto_table_internal[r_type - (R_RISCV_DELETE + 1)]; + if (!ret) { (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"), abfd, r_type); bfd_set_error (bfd_error_bad_value); - return NULL; } - return &howto_table[r_type]; + return ret; } /* Special_function of RISCV_ADD and RISCV_SUB relocations. */ diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index abcb409bd78d..9a6f40787110 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -45,7 +45,8 @@ extern reloc_howto_type * riscv_reloc_type_lookup (bfd *, bfd_reloc_code_real_type); extern reloc_howto_type * -riscv_elf_rtype_to_howto (bfd *, unsigned int r_type); +riscv_elf_rtype_to_howto (bfd *, unsigned int r_type, + bool lookup_internal); /* The information of architecture attribute. */ struct riscv_subset_t diff --git a/include/elf/riscv.h b/include/elf/riscv.h index 0aa8b3359c4c..0060542f7998 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -74,11 +74,9 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type) RELOC_NUMBER (R_RISCV_ALIGN, 43) RELOC_NUMBER (R_RISCV_RVC_BRANCH, 44) RELOC_NUMBER (R_RISCV_RVC_JUMP, 45) - RELOC_NUMBER (R_RISCV_RVC_LUI, 46) - RELOC_NUMBER (R_RISCV_GPREL_I, 47) - RELOC_NUMBER (R_RISCV_GPREL_S, 48) - RELOC_NUMBER (R_RISCV_TPREL_I, 49) - RELOC_NUMBER (R_RISCV_TPREL_S, 50) + /* Reserved 47 for R_RISCV_GPREL_LO12_I. */ + /* Reserved 48 for R_RISCV_GPREL_LO12_S. */ + /* Reserved 49 for R_RISCV_GPREL_HI20. */ RELOC_NUMBER (R_RISCV_RELAX, 51) RELOC_NUMBER (R_RISCV_SUB6, 52) RELOC_NUMBER (R_RISCV_SET6, 53) @@ -90,7 +88,34 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type) /* Reserved 59 for R_RISCV_PLT32. */ RELOC_NUMBER (R_RISCV_SET_ULEB128, 60) RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61) -END_RELOC_NUMBERS (R_RISCV_max) + /* Reserved 62 for R_RISCV_TLSDESC_HI20. */ + /* Reserved 63 for R_RISCV_TLSDESC_LOAD_LO12. */ + /* Reserved 64 for R_RISCV_TLSDESC_ADD_LO12. */ + /* Reserved 65 for R_RISCV_TLSDESC_CALL. */ + EMPTY_RELOC (R_RISCV_max) + + /* Internal relocations used exclusively by the relaxation pass. + R_RISCV_DELETE must be the first entry. */ + EMPTY_RELOC (R_RISCV_DELETE) + EMPTY_RELOC (R_RISCV_RVC_LUI) + EMPTY_RELOC (R_RISCV_GPREL_I) + EMPTY_RELOC (R_RISCV_GPREL_S) + EMPTY_RELOC (R_RISCV_TPREL_I) + EMPTY_RELOC (R_RISCV_TPREL_S) +END_RELOC_NUMBERS (R_RISCV_internal_max) + +/* Safety guard for all relocation types. */ +#ifndef RELOC_MACROS_GEN_FUNC +#if !defined (__STDC_VERSION__) || __STDC_VERSION__ < 201112L +#define _Static_assert(cond, err) +#endif +_Static_assert (R_RISCV_internal_max <= 256, + "All relocation types including internal ones must fit" + "into an 8-bit value."); +#ifdef _Static_assert +#undef _Static_assert +#endif +#endif /* Processor specific flags for the ELF header e_flags field. */