From patchwork Fri Mar 5 09:03:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Chen X-Patchwork-Id: 1447699 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=JxmTJKrB; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=SyJ5nXAm; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DsMJW6s9xz9sVt for ; Fri, 5 Mar 2021 20:05:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1RVtZr6FHhY8vTcqeZzJUCLbIWkC5zNyj8WJLBxj+2s=; b=JxmTJKrBh9oLkloiV/Pv9AIDcY UebqN4nTnGgli5H/DSC2sw5aMPzlaCbOuGc7mRIxm1vs7JPve16rb/2Mx+EGq08MFf0WRMb/u3d4p F0QjIdwj/C0eeYrnGzp96sflJRUnROh+Y9MZa6jNf9Kae+HV/EgBR0Iy5780lB2ACCpIKuQyDwhVm JpgvCU+0luE0y3vJfAsoEwWSk2kOGNbrQNfthyXhLWmpcDUr9xH23Med5rSfBxlMR14WOroVBHwmJ kSq+cGkUuuuB31/JR6RtvKDRwFsAUKhB3qxJbnZMotwdVP/pXnK8cPytB81HR4vVMRGIycKGbgJ7R qFUB8ZmA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lI6OW-00E9Ij-5t; Fri, 05 Mar 2021 09:05:12 +0000 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lI6N6-00E8XG-Ho for opensbi@lists.infradead.org; Fri, 05 Mar 2021 09:03:46 +0000 Received: by mail-pj1-x102b.google.com with SMTP id i4-20020a17090a7184b02900bfb60fbc6bso5836536pjk.0 for ; Fri, 05 Mar 2021 01:03:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=stElRirRmvFb7d3IP4KhboS7Urguugy+JX+zXvZHYw4=; b=SyJ5nXAmHTkSYDVngBfZfg+yqIVld3MDQboV34oFQvFDRLc+0EqzJ4rguqDrsZyUno 3gOpIA35nY5Rz7pAvqEYjgwlzWEiF/iZCFx66ODEHIah7r2tC0lqvMBzVDgOypsxBHcc 6/qEbHPkg2+WQJmGXsx6BwZgykPd3JS5sJq89WsMbWYosy8wgE0az7Uq8TFXsBb4ST9r eaMbnskz3UsIFotf3vUxWsfolcax9PRT61vJO1nZnPXrSSc4G4Diju3WJm2LNi/NPIJj 55G0BZwdOJEHSPh4Yau1E3TWt50j+pPv5v03RIqNKv5gEgJk8E//fVZBQ4rj2KAzCa/J gqtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=stElRirRmvFb7d3IP4KhboS7Urguugy+JX+zXvZHYw4=; b=U8RJyDw4FpVGr66p0eQH5yjqAXOvL3mxl6VpQuUyzH4cEAWmO5YwB/daLyVKgz2VXF kQrupYvuSphio/ivdpqc8HSigkHRCKtuMTDW9PEZ0c+DGPm2Gn6jBJBtDpB2yce7bC/U DJTNy25OpXWL63LuK3PyTVbeNfMFBYJxHDUthlsEMwOkSvqJiqD5G0fs3PFGnwF9twu7 1XktWr8/WRhp741sPD/mCn09BlO6xFGMj5vVF/XtEWSMMkXj802u7IzFcWlIRqtUutAJ XXfqhWZlns85hB/6sUMzplMB/mS+4p/E39Yhbjwg1iqJpcBXxYZJOjisD884aVGCRNZc ml2Q== X-Gm-Message-State: AOAM530/TV2T8CZsYYzRuBm46+0oTA/2zyzE6eWAUF1eQD+M7ZOOBy/1 WTVDsOd/v8DBczcLh+vt1KJRK862Mpa+vnIc X-Google-Smtp-Source: ABdhPJyy/DDWOM1ddXL8zwDZhOOIWybKqLt9rbeGaTnUYcymFsCwjYPJlKt9vaqcorZxxngky281/w== X-Received: by 2002:a17:90b:1b46:: with SMTP id nv6mr9286916pjb.45.1614935022761; Fri, 05 Mar 2021 01:03:42 -0800 (PST) Received: from VincentChen-ThinkPad-T480s.internal.sifive.com (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221]) by smtp.gmail.com with ESMTPSA id a24sm1859524pfo.9.2021.03.05.01.03.41 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Mar 2021 01:03:42 -0800 (PST) From: Vincent Chen To: opensbi@lists.infradead.org Cc: Vincent Chen Subject: [PATCH v2 2/2] firmware: Support position independent execution Date: Fri, 5 Mar 2021 17:03:34 +0800 Message-Id: <1614935014-18600-3-git-send-email-vincent.chen@sifive.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1614935014-18600-1-git-send-email-vincent.chen@sifive.com> References: <1614935014-18600-1-git-send-email-vincent.chen@sifive.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210305_090344_791301_9A60929C X-CRM114-Status: GOOD ( 19.27 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Enable OpenSBI to support position independent execution. Because the position independent code will cause an additional GOT reference when accessing the global variables, it will reduce performance a [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:102b listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Enable OpenSBI to support position independent execution. Because the position independent code will cause an additional GOT reference when accessing the global variables, it will reduce performance a bit. Therefore, the position independent execution is disabled by default. Users can through specifying "FW_PIC=y" on the make command to enable this feature. In theory, after enabling position-independent execution, the OpenSBI can run at arbitrary address with appropriate alignment. Therefore, the original relocation mechanism will be skipped. In other words, OpenSBI will directly run at the load address without any code movement. Signed-off-by: Vincent Chen --- Makefile | 2 +- firmware/fw_base.S | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- firmware/fw_base.ldS | 13 +++++++++++ firmware/fw_jump.S | 10 +++++++++ firmware/fw_payload.S | 6 +++++ firmware/objects.mk | 7 ++++++ include/sbi/riscv_elf.h | 9 ++++++++ 7 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 include/sbi/riscv_elf.h diff --git a/Makefile b/Makefile index d6f097d..038cc99 100644 --- a/Makefile +++ b/Makefile @@ -210,8 +210,8 @@ CFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA) CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL) CFLAGS += $(GENFLAGS) CFLAGS += $(platform-cflags-y) -CFLAGS += $(firmware-cflags-y) CFLAGS += -fno-pie -no-pie +CFLAGS += $(firmware-cflags-y) CPPFLAGS += $(GENFLAGS) CPPFLAGS += $(platform-cppflags-y) diff --git a/firmware/fw_base.S b/firmware/fw_base.S index 6cc5f88..5f49c88 100644 --- a/firmware/fw_base.S +++ b/firmware/fw_base.S @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -67,6 +68,57 @@ _try_lottery: lla t1, _start REG_S t1, 0(t0) +#ifdef FW_PIC + /* relocate the global table content */ + lla t0, _link_start + REG_L t0, 0(t0) + sub t2, t1, t0 + lla t3, _runtime_offset + REG_S t2, (t3) + lla t0, __rel_dyn_start + lla t1, __rel_dyn_end + beq t0, t1, _relocate_done + j 5f +2: + REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */ + li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ + bne t5, t3, 3f + REG_L t3, -(REGBYTES*3)(t0) + REG_L t5, -(REGBYTES)(t0) /* t5 <-- addend */ + add t5, t5, t2 + add t3, t3, t2 + REG_S t5, 0(t3) /* store runtime address to the GOT entry */ + j 5f + +3: + lla t4, __dyn_sym_start + +4: + REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */ + srli t6, t5, SYM_INDEX /* t6 <--- sym table index */ + andi t5, t5, 0xFF /* t5 <--- relocation type */ + li t3, RELOC_TYPE + bne t5, t3, 5f + + /* address R_RISCV_64 or R_RISCV_32 cases*/ + REG_L t3, -(REGBYTES*3)(t0) + li t5, SYM_SIZE + mul t6, t6, t5 + add s5, t4, t6 + REG_L t6, -(REGBYTES)(t0) /* t0 <-- addend */ + REG_L t5, REGBYTES(s5) + add t5, t5, t6 + add t5, t5, t2 /* t5 <-- location to fix up in RAM */ + add t3, t3, t2 /* t3 <-- location to fix up in RAM */ + REG_S t5, 0(t3) /* store runtime address to the variable */ + +5: + addi t0, t0, (REGBYTES*3) + ble t0, t1, 2b + j _relocate_done +_wait_relocate_copy_done: + j _wait_for_boot_hart +#else /* Relocate if load address != link address */ _relocate: lla t0, _link_start @@ -137,6 +189,7 @@ _wait_relocate_copy_done: nop bgt t4, t5, 1b jr t3 +#endif _relocate_done: /* @@ -144,12 +197,14 @@ _relocate_done: * Use _boot_status copy relative to the load address */ lla t0, _boot_status +#ifndef FW_PIC lla t1, _link_start REG_L t1, 0(t1) lla t2, _load_start REG_L t2, 0(t2) sub t0, t0, t1 add t0, t0, t2 +#endif li t1, BOOT_STATUS_RELOCATE_DONE REG_S t1, 0(t0) fence rw, rw @@ -446,6 +501,8 @@ _skip_trap_exit_rv32_hyp: j _start_hang .align 3 +_runtime_offset: + RISCV_PTR 0 _relocate_lottery: RISCV_PTR 0 _boot_status: @@ -453,7 +510,7 @@ _boot_status: _load_start: RISCV_PTR _fw_start _link_start: - RISCV_PTR _fw_start + RISCV_PTR FW_TEXT_START _link_end: RISCV_PTR _fw_reloc_end diff --git a/firmware/fw_base.ldS b/firmware/fw_base.ldS index 0ac75f2..3904959 100644 --- a/firmware/fw_base.ldS +++ b/firmware/fw_base.ldS @@ -61,6 +61,19 @@ PROVIDE(_data_end = .); } + .dynsym : { + PROVIDE(__dyn_sym_start = .); + *(.dynsym) + PROVIDE(__dyn_sym_end = .); + } + + .rela.dyn : { + PROVIDE(__rel_dyn_start = .); + *(.rela*) + . = ALIGN(8); + PROVIDE(__rel_dyn_end = .); + } + . = ALIGN(0x1000); /* Ensure next section is page aligned */ .bss : diff --git a/firmware/fw_jump.S b/firmware/fw_jump.S index 5b24f8b..4fb3e0c 100644 --- a/firmware/fw_jump.S +++ b/firmware/fw_jump.S @@ -46,6 +46,11 @@ fw_save_info: fw_next_arg1: #ifdef FW_JUMP_FDT_ADDR li a0, FW_JUMP_FDT_ADDR +#ifdef FW_PIC + lla a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif #else add a0, a1, zero #endif @@ -61,6 +66,11 @@ fw_next_arg1: fw_next_addr: lla a0, _jump_addr REG_L a0, (a0) +#ifdef FW_PIC + lla a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif ret .section .entry, "ax", %progbits diff --git a/firmware/fw_payload.S b/firmware/fw_payload.S index c53a3bb..00c7cb7 100644 --- a/firmware/fw_payload.S +++ b/firmware/fw_payload.S @@ -46,6 +46,12 @@ fw_save_info: fw_next_arg1: #ifdef FW_PAYLOAD_FDT_ADDR li a0, FW_PAYLOAD_FDT_ADDR +#ifdef FW_PIC + lla a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif + #else add a0, a1, zero #endif diff --git a/firmware/objects.mk b/firmware/objects.mk index b2ace75..c1f632e 100644 --- a/firmware/objects.mk +++ b/firmware/objects.mk @@ -13,6 +13,13 @@ firmware-cflags-y += firmware-asflags-y += firmware-ldflags-y += +ifeq ($(FW_PIC),y) +firmware-genflags-y += -DFW_PIC +firmware-asflags-y += -fpic +firmware-cflags-y += -fPIE -pie +firmware-ldflags-y += -Wl,--no-dynamic-linker +endif + ifdef FW_TEXT_START firmware-genflags-y += -DFW_TEXT_START=$(FW_TEXT_START) endif diff --git a/include/sbi/riscv_elf.h b/include/sbi/riscv_elf.h new file mode 100644 index 0000000..cf211ac --- /dev/null +++ b/include/sbi/riscv_elf.h @@ -0,0 +1,9 @@ +#include + +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 + +#define RELOC_TYPE __REG_SEL(R_RISCV_64, R_RISCV_32) +#define SYM_INDEX __REG_SEL(0x20, 0x8) +#define SYM_SIZE __REG_SEL(0x18,0x10)