From patchwork Wed Aug 16 18:03:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Cbg7Zz8W; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwyY3DK0z1yNm for ; Thu, 17 Aug 2023 04:04:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKrx-00024b-MK; Wed, 16 Aug 2023 14:03:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKrw-00022g-1l for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:44 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKrt-0001Ic-In for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:43 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1bdb801c667so44707695ad.1 for ; Wed, 16 Aug 2023 11:03:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209020; x=1692813820; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=KVQEaJs3GbLkjPKeCbXH/uHTPUARwUrZn+9U7CYMhDA=; b=Cbg7Zz8WrgfVFUz1spaNhc2DU3Q4gNkC/eZXP9LXywJdO5dxyj75NeY/7HfGWmauXj GnSLFX2cQWIPoe5IZJZLaSZWgPL7OLm6sCoaa7kQ+dYak60Skw6bp9urCVSVmDoLnXTG 0w1UEO4qnTjRcFJEMZErGLnC4BPUYrdMA2UDri65rVJAqLfbw1i2bgRL+AdrskSoekfT ZjOf1ST1UHMm3jm6HFskGcQ6ZxSTAkPDpm1vmeVjRxcgP2Rrk4si4XdbMKPbI22zDdPC TeJiHS4Y7A/hfvvYt4DD3sCIm9WZeBxXC3fDiiVj/rC41jx+xE2U7+Fg/25+uzSqmU+X UsoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209020; x=1692813820; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KVQEaJs3GbLkjPKeCbXH/uHTPUARwUrZn+9U7CYMhDA=; b=NZOVO0iBEQX3lClz9FvmFtPgg0OlgSrFqbr3fciETymRoxMqrFuzWpCW7GawB0aB/A PZwiNTPtfGw+y2a1EMDSAsu/6UQmguxqtD2l1vKSgRhhj9fwH+zmLzpUk8VxSJRYKx/Y lHzR2DfLy2vz23q2y6lNccIApwe2VGz26ChaGLHK7+DE/QxWw3eCi+kzHz3o/CjX7vEH KlSeq2mfK5V4Sw6JR5+xImnVtv4zKuY7iDqCTcOgH7UP2oMpF9L9okKzm4VdMvRN3o8n EIJrWmPNG2f0PAPsQrLXQxuK2TP3o0lGa5GzUb+EV8q90+E0HsPG55e31uow6pQeqYt8 RoVg== X-Gm-Message-State: AOJu0YxuiUDqpt9PPbrfeBc3jzkq9ZF/qVirVchormUW6IJDu2sH2U1c 6tzhxYIvX0pDeFft2M+SX/jaWdJWVZYz4m5JpWU= X-Google-Smtp-Source: AGHT+IGfOx/craWJn0/SQ1//cI3X0i5o7AuaDkQr5YZmQGZ/ySBz5knLPp3fnEb7HdVoTNdYdaYkXQ== X-Received: by 2002:a17:902:dad1:b0:1b3:e90b:93e1 with SMTP id q17-20020a170902dad100b001b3e90b93e1mr3349934plx.36.1692209020225; Wed, 16 Aug 2023 11:03:40 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:39 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 01/18] linux-user: Introduce imgsrc_read, imgsrc_read_alloc Date: Wed, 16 Aug 2023 11:03:21 -0700 Message-Id: <20230816180338.572576-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Introduced and initialized, but not yet really used. These will tidy the current tests vs BPRM_BUF_SIZE. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- linux-user/loader.h | 61 +++++++++++++++++++++++----- linux-user/linuxload.c | 90 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 9 deletions(-) diff --git a/linux-user/loader.h b/linux-user/loader.h index 59cbeacf24..311d20f5d1 100644 --- a/linux-user/loader.h +++ b/linux-user/loader.h @@ -18,6 +18,48 @@ #ifndef LINUX_USER_LOADER_H #define LINUX_USER_LOADER_H +typedef struct { + const void *cache; + unsigned int cache_size; + int fd; +} ImageSource; + +/** + * imgsrc_read: Read from ImageSource + * @dst: destination for read + * @offset: offset within file for read + * @len: size of the read + * @img: ImageSource to read from + * @errp: Error details. + * + * Read into @dst, using the cache when possible. + */ +bool imgsrc_read(void *dst, off_t offset, size_t len, + const ImageSource *img, Error **errp); + +/** + * imgsrc_read_alloc: Read from ImageSource + * @offset: offset within file for read + * @size: size of the read + * @img: ImageSource to read from + * @errp: Error details. + * + * Read into newly allocated memory, using the cache when possible. + */ +void *imgsrc_read_alloc(off_t offset, size_t len, + const ImageSource *img, Error **errp); + +/** + * imgsrc_mmap: Map from ImageSource + * + * If @src has a file descriptor, pass on to target_mmap. Otherwise, + * this is "mapping" from a host buffer, which resolves to memcpy. + * Therefore, flags must be MAP_PRIVATE | MAP_FIXED; the argument is + * retained for clarity. + */ +abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot, + int flags, const ImageSource *src, abi_ulong offset); + /* * Read a good amount of data initially, to hopefully get all the * program headers loaded. @@ -29,15 +71,16 @@ * used when loading binaries. */ struct linux_binprm { - char buf[BPRM_BUF_SIZE] __attribute__((aligned)); - abi_ulong p; - int fd; - int e_uid, e_gid; - int argc, envc; - char **argv; - char **envp; - char *filename; /* Name of binary */ - int (*core_dump)(int, const CPUArchState *); /* coredump routine */ + char buf[BPRM_BUF_SIZE] __attribute__((aligned)); + ImageSource src; + abi_ulong p; + int fd; + int e_uid, e_gid; + int argc, envc; + char **argv; + char **envp; + char *filename; /* Name of binary */ + int (*core_dump)(int, const CPUArchState *); /* coredump routine */ }; void do_init_thread(struct target_pt_regs *regs, struct image_info *infop); diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 745cce70ab..3536dd8104 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -3,7 +3,9 @@ #include "qemu/osdep.h" #include "qemu.h" #include "user-internals.h" +#include "user-mmap.h" #include "loader.h" +#include "qapi/error.h" #define NGROUPS 32 @@ -76,6 +78,10 @@ static int prepare_binprm(struct linux_binprm *bprm) /* Make sure the rest of the loader won't read garbage. */ memset(bprm->buf + retval, 0, BPRM_BUF_SIZE - retval); } + + bprm->src.cache = bprm->buf; + bprm->src.cache_size = retval; + return retval; } @@ -139,6 +145,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, int retval; bprm->fd = fdexec; + bprm->src.fd = fdexec; bprm->filename = (char *)filename; bprm->argc = count(argv); bprm->argv = argv; @@ -173,3 +180,86 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, return retval; } + +bool imgsrc_read(void *dst, off_t offset, size_t len, + const ImageSource *img, Error **errp) +{ + ssize_t ret; + + if (offset + len <= img->cache_size) { + memcpy(dst, img->cache + offset, len); + return true; + } + + if (img->fd < 0) { + error_setg(errp, "read past end of buffer"); + return false; + } + + ret = pread(img->fd, dst, len, offset); + if (ret == len) { + return true; + } + if (ret < 0) { + error_setg_errno(errp, errno, "Error reading file header"); + } else { + error_setg(errp, "Incomplete read of file header"); + } + return false; +} + +void *imgsrc_read_alloc(off_t offset, size_t len, + const ImageSource *img, Error **errp) +{ + void *alloc = g_malloc(len); + bool ok = imgsrc_read(alloc, offset, len, img, errp); + + if (!ok) { + g_free(alloc); + alloc = NULL; + } + return alloc; +} + +abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot, + int flags, const ImageSource *src, abi_ulong offset) +{ + const int prot_write = PROT_READ | PROT_WRITE; + abi_long ret; + void *haddr; + + assert(flags == (MAP_PRIVATE | MAP_FIXED)); + + if (src->fd >= 0) { + return target_mmap(start, len, prot, flags, src->fd, offset); + } + + /* + * This case is for the vdso; we don't expect bad images. + * The mmap may extend beyond the end of the image, especially + * to the end of the page. Zero fill. + */ + assert(offset < src->cache_size); + + ret = target_mmap(start, len, prot_write, flags | MAP_ANON, -1, 0); + if (ret == -1) { + return ret; + } + + haddr = lock_user(VERIFY_WRITE, start, len, 0); + assert(haddr != NULL); + if (offset + len <= src->cache_size) { + memcpy(haddr, src->cache + offset, len); + } else { + size_t rest = src->cache_size - offset; + memcpy(haddr, src->cache + offset, rest); + memset(haddr + rest, 0, len - rest); + } + unlock_user(haddr, start, len); + + if (prot != prot_write) { + target_mprotect(start, len, prot); + } + + return ret; +} From patchwork Wed Aug 16 18:03:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821982 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=zw+dwHlC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwyY3Pcrz1yXY for ; Thu, 17 Aug 2023 04:04:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKrz-00026A-86; Wed, 16 Aug 2023 14:03:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKrx-00024h-JZ for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:45 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKru-0001J6-FA for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:45 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1bb84194bf3so43519525ad.3 for ; Wed, 16 Aug 2023 11:03:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209021; x=1692813821; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BbPoiA4hDTDe4hGu5oLPJ3b2yV0sQkSxEUBuznSGCYM=; b=zw+dwHlCnf29iPqZKw64+5+ren92LHt0qfYE+wBM/DINK76rLtniDSfwqVvyk6vhmC 3Rzqz68IsZH3u/Br1aZEAN+69Xy3Cz2ZKAK9q5939gV6rCsc9OlqZvMN3VBXgJ6xcsaD 7335nYyn5eTs3y3NoLbI153fvXQxULbGRzS7o+TVJqPEnvirxFQI15jJP9KEGij+1/4x AjlSdaAuju8Y3Ys8dcf2TF1V/aeRm4oN0OxrFSCBwFzH+/eSR4zFoWVlV/W7Jif/6fRn Vjvppfuqx5kwp4rSoVStxq+0OZYWnRaKJ0yhrcunlbrQRpPkSarymd5zbQMa2vFYKCTN I9eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209021; x=1692813821; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BbPoiA4hDTDe4hGu5oLPJ3b2yV0sQkSxEUBuznSGCYM=; b=dpVsrZiOYr3dY57GmTFPZoLJNeSjX2JrJ6TZ1gO7nNlDzFQ8xHyg5h3XHB5X2XHZwx p3gBCBNdDDEywrZB5+IUI25L4kaPRL7gE596MYLkK0WNZiFIvQTO6dcRphIJq9X9qRmH 4cbJuyvyrCQl6JkXVZl1Q/uxZfxLV/tQrjEpO97nW9mMNbNGomyvJ4QhP1aXS2HGXgjS s4qgi9fombWHGHDLcXM40meaRp4GzUaizAnLdtV8wDnw8r4WK3gfDkvjx23OA+nR164R oNxKdpljrA6G9rfudW5xLbUHu//uF2w/g2VcdFNctmxCCiJuOvh9nTcjUNhkf0pVfm9z NmkA== X-Gm-Message-State: AOJu0YwKrHEl8fupHiFCTQNnqK+Nma/Aht62fPYxIX6N1jtLx343t3mU AOiwGi+97vLRaeZkFtYUPlieBsI/8A5YUTGsUAQ= X-Google-Smtp-Source: AGHT+IHFhHT2okcUG9IOc6mJ4WsIImH34gHAdUmPYYtuHL7HPv7Zcz8ReYzvR9B6EfbNb00k2em7zg== X-Received: by 2002:a17:903:48c:b0:1be:1a2:8a85 with SMTP id jj12-20020a170903048c00b001be01a28a85mr2002807plb.0.1692209021128; Wed, 16 Aug 2023 11:03:41 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:40 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [PATCH v4 02/18] linux-user: Tidy loader_exec Date: Wed, 16 Aug 2023 11:03:22 -0700 Message-Id: <20230816180338.572576-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x635.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Reorg the if cases to reduce indentation. Test for 4 bytes in the file before checking the signatures. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/linuxload.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 3536dd8104..5b7e9ab983 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -154,31 +154,31 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, retval = prepare_binprm(bprm); - if (retval >= 0) { - if (bprm->buf[0] == 0x7f - && bprm->buf[1] == 'E' - && bprm->buf[2] == 'L' - && bprm->buf[3] == 'F') { - retval = load_elf_binary(bprm, infop); -#if defined(TARGET_HAS_BFLT) - } else if (bprm->buf[0] == 'b' - && bprm->buf[1] == 'F' - && bprm->buf[2] == 'L' - && bprm->buf[3] == 'T') { - retval = load_flt_binary(bprm, infop); -#endif - } else { - return -ENOEXEC; - } + if (retval < 4) { + return -ENOEXEC; } - - if (retval >= 0) { - /* success. Initialize important registers */ - do_init_thread(regs, infop); + if (bprm->buf[0] == 0x7f + && bprm->buf[1] == 'E' + && bprm->buf[2] == 'L' + && bprm->buf[3] == 'F') { + retval = load_elf_binary(bprm, infop); +#if defined(TARGET_HAS_BFLT) + } else if (bprm->buf[0] == 'b' + && bprm->buf[1] == 'F' + && bprm->buf[2] == 'L' + && bprm->buf[3] == 'T') { + retval = load_flt_binary(bprm, infop); +#endif + } else { + return -ENOEXEC; + } + if (retval < 0) { return retval; } - return retval; + /* Success. Initialize important registers. */ + do_init_thread(regs, infop); + return 0; } bool imgsrc_read(void *dst, off_t offset, size_t len, From patchwork Wed Aug 16 18:03:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821996 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=afiy5sIn; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQx080GWBz1xrk for ; Thu, 17 Aug 2023 04:06:16 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs0-00026w-6x; Wed, 16 Aug 2023 14:03:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKrx-000253-TY for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:45 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKrv-0001JB-EV for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:45 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1bc8045e09dso44592305ad.0 for ; Wed, 16 Aug 2023 11:03:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209022; x=1692813822; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hnWfSxPGmBDugDNsx/9arIWCUJcfcyXd41yVekLb5Tk=; b=afiy5sInHu265F+vBkOieYxZaCEiQ5T8C4CMDdi5wJgiaQYYs3vJFkWcKnKcFNUXFr n7ld/k8JdcKSx/Uf9jMY0qvbc4t0c7A0yCQPWPVqMNUPODkCEPzZf+6lO13OQJqY25eg EAscvJaXLkLzfCFbcttBE599yrODbGTrg/5QeZ7pLwXk5mKnROVXv+kD9Ofw/4reD3Hn DdQ+PXfbUY9lb39DzdA9HD12bO0WaOo7oAp9oMn0MsMwoQ6tb17jgccOPCowX4WTHuA0 hM3FEE6cVW0By8X06GeS/OIULAX7YWuW4WmLHduEFxw5QUEclxt8xKPP8MsHjx9d/mm0 n2Yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209022; x=1692813822; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hnWfSxPGmBDugDNsx/9arIWCUJcfcyXd41yVekLb5Tk=; b=UggmMQGWlDusSOWuTtkvd/zU/g0VdopXK1jtbrgZVPs/W/swPQ056nyJJb/jXUY7pM 9Or8TdQ9Su7eBm8qV4nasSL9W2uEN+jn7eDns1jpMC9hSvnbbdOARBOkpRzRTdDElYCj ieiVvNwqLZJEjQfpV/T7VEIcYtQEXjA31HrIaBVJipRQrs+USeIyPtSvB9gqmMMT2BF6 unBdCUAnMepmDr/I5oEfods4/4lymWQabn0qFkm6eZmJj7+18HiOvpDkkKTNyS8ux3e1 37NPauqj5BXhFRtK71V5vQ02ITDyh6gCfZAS1DsxBHX3WaHCok0a9TUjxXuFrbV1T6yr rR9A== X-Gm-Message-State: AOJu0YyMdTOO4wSs0or5aU/Z2hABCHH73pAGRycnEZsb1eoxZy2zCihR SYTSknJWD8SiWfTtLlYFhkLM4ztvL4HGkptARZM= X-Google-Smtp-Source: AGHT+IEqNnIPgi/VYHZicgLkc001IjDihJ8GYsp26CzDk2SDeUjmQzcvyeacP5KA/Hxo4gGmZEjn9Q== X-Received: by 2002:a17:902:a3c9:b0:1bc:9c49:f8ce with SMTP id q9-20020a170902a3c900b001bc9c49f8cemr2236035plb.4.1692209022119; Wed, 16 Aug 2023 11:03:42 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:41 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [PATCH v4 03/18] linux-user: Do not clobber bprm_buf swapping ehdr Date: Wed, 16 Aug 2023 11:03:23 -0700 Message-Id: <20230816180338.572576-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::631; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x631.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Rearrange the allocation of storage for ehdr between load_elf_image and load_elf_binary. The same set of copies are done, but we don't modify bprm_buf, which will be important later. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/elfload.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index ac03beb01b..11bbf4e99b 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -3019,16 +3019,17 @@ static bool parse_elf_properties(int image_fd, On return: INFO values will be filled in, as necessary or available. */ static void load_elf_image(const char *image_name, int image_fd, - struct image_info *info, char **pinterp_name, + struct image_info *info, struct elfhdr *ehdr, + char **pinterp_name, char bprm_buf[BPRM_BUF_SIZE]) { - struct elfhdr *ehdr = (struct elfhdr *)bprm_buf; struct elf_phdr *phdr; abi_ulong load_addr, load_bias, loaddr, hiaddr, error; int i, retval, prot_exec; Error *err = NULL; /* First of all, some simple consistency checks */ + memcpy(ehdr, bprm_buf, sizeof(*ehdr)); if (!elf_check_ident(ehdr)) { error_setg(&err, "Invalid ELF image for this architecture"); goto exit_errmsg; @@ -3343,6 +3344,7 @@ static void load_elf_image(const char *image_name, int image_fd, static void load_elf_interp(const char *filename, struct image_info *info, char bprm_buf[BPRM_BUF_SIZE]) { + struct elfhdr ehdr; int fd, retval; Error *err = NULL; @@ -3364,7 +3366,7 @@ static void load_elf_interp(const char *filename, struct image_info *info, memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval); } - load_elf_image(filename, fd, info, NULL, bprm_buf); + load_elf_image(filename, fd, info, &ehdr, NULL, bprm_buf); } static int symfind(const void *s0, const void *s1) @@ -3557,8 +3559,14 @@ uint32_t get_elf_eflags(int fd) int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) { + /* + * We need a copy of the elf header for passing to create_elf_tables. + * We will have overwritten the original when we re-use bprm->buf + * while loading the interpreter. Allocate the storage for this now + * and let elf_load_image do any swapping that may be required. + */ + struct elfhdr ehdr; struct image_info interp_info; - struct elfhdr elf_ex; char *elf_interpreter = NULL; char *scratch; @@ -3570,12 +3578,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) info->start_mmap = (abi_ulong)ELF_START_MMAP; load_elf_image(bprm->filename, bprm->fd, info, - &elf_interpreter, bprm->buf); - - /* ??? We need a copy of the elf header for passing to create_elf_tables. - If we do nothing, we'll have overwritten this when we re-use bprm->buf - when we load the interpreter. */ - elf_ex = *(struct elfhdr *)bprm->buf; + &ehdr, &elf_interpreter, bprm->buf); /* Do this so that we can load the interpreter, if need be. We will change some of these later */ @@ -3662,7 +3665,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC); } - bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex, + bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr, info, (elf_interpreter ? &interp_info : NULL)); info->start_stack = bprm->p; From patchwork Wed Aug 16 18:03:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821992 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=kUZ+X368; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwzy1fdSz1xrk for ; Thu, 17 Aug 2023 04:06:06 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs1-00027k-0b; Wed, 16 Aug 2023 14:03:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKry-00025l-Nv for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:46 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKrw-0001JR-6e for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:46 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1bc6535027aso57837335ad.2 for ; Wed, 16 Aug 2023 11:03:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209023; x=1692813823; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=dcDp54///Kf+CDj6N0TXUWsVxMt18CBlFITqwULqOtE=; b=kUZ+X368TYenYVrvLowpRrM1wGLbhZe0hLsrM2fs9dgENT1Gn6wrfTKWj4qo3PWxc5 5pLC3z3TbEpQy8p8egIAXwwKB8AOlApXJXgVS8mULh4pS8rWlyQOjbNt/EwnNw9V0NLL uQ4+pd5yMVrNWH3f0OO/dhBmMeD91Wa6sQYj0qdEIA4TPK3TWiK+VP+o5JD+CwWhhmS0 m/DnBckjC3vL8rpwAHvai5uX81VQ7wnB4xqU0v9bO+CywUYb8ijeguqOJn5t10qB1Emh SkXE29bzHS6Shx8ip1UfF1xYdB0Aeub8sQoX4o3xt+fsqnufGA615+cCbIReZDocLIqf 32eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209023; x=1692813823; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dcDp54///Kf+CDj6N0TXUWsVxMt18CBlFITqwULqOtE=; b=jFK5WrAXN/60psrpdm8b3xRbSQKWlGSgmOdlQZ3Zjv98Mfz+Ida8T05LHdz9bRzy5D DCuTOgcneL7sUGFbuK2C09coesW4OFgAUQhuk6grAfscyQcWACkncikRe2yfKT3b6BJO epvY5D+cL0CYIb6GGzqSOaPrsSLDMGqSlslvU2pC0lVb+lpAue1+TBE5oL/FCz/PE0b2 xY8QffR1tGxEMbKuBNCyo9fgb0FoiIME1/7ZShUuvQUJ+ngxHvwT86oCuS8FIb2WaBo8 YeHxjoM21F9RuzajCdZme9lUGH0AEykOirqYljmHzry9kbWDa/0Q5+Lk9vmPv4fM6Zv6 NnZA== X-Gm-Message-State: AOJu0Yz6WxKJLvXC1l17FP8pIwZKlZkBwkUZV7L3IPLvVeJLBu3YNkUW Utqn5n7qjTqp+wjIgdqzDvOW3mZ+OGHI8zZwLgk= X-Google-Smtp-Source: AGHT+IHVWZYo4RAA93SxQoyJAQOFKDzmM1lcVt7g4DyfrLJOZtN8/hlgmMd9JcQWO8s/qI9NHR+x6A== X-Received: by 2002:a17:902:efd6:b0:1b9:de67:286f with SMTP id ja22-20020a170902efd600b001b9de67286fmr2470149plb.49.1692209022887; Wed, 16 Aug 2023 11:03:42 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:42 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 04/18] linux-user: Use ImageSource in load_elf_image Date: Wed, 16 Aug 2023 11:03:24 -0700 Message-Id: <20230816180338.572576-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Change parse_elf_properties as well, as the bprm_buf argument ties the two functions closely. Signed-off-by: Richard Henderson --- linux-user/elfload.c | 128 +++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 79 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 11bbf4e99b..f3511ae766 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2922,10 +2922,9 @@ static bool parse_elf_property(const uint32_t *data, int *off, int datasz, } /* Process NT_GNU_PROPERTY_TYPE_0. */ -static bool parse_elf_properties(int image_fd, +static bool parse_elf_properties(const ImageSource *src, struct image_info *info, const struct elf_phdr *phdr, - char bprm_buf[BPRM_BUF_SIZE], Error **errp) { union { @@ -2953,14 +2952,8 @@ static bool parse_elf_properties(int image_fd, return false; } - if (phdr->p_offset + n <= BPRM_BUF_SIZE) { - memcpy(¬e, bprm_buf + phdr->p_offset, n); - } else { - ssize_t len = pread(image_fd, ¬e, n, phdr->p_offset); - if (len != n) { - error_setg_errno(errp, errno, "Error reading file header"); - return false; - } + if (!imgsrc_read(¬e, phdr->p_offset, n, src, errp)) { + return false; } /* @@ -3006,30 +2999,34 @@ static bool parse_elf_properties(int image_fd, } } -/* Load an ELF image into the address space. +/** + * load_elf_image: Load an ELF image into the address space. + * @image_name: the filename of the image, to use in error messages. + * @src: the ImageSource from which to read. + * @info: info collected from the loaded image. + * @ehdr: the ELF header, not yet bswapped. + * @pinterp_name: record any PT_INTERP string found. + * + * On return: @info values will be filled in, as necessary or available. + */ - IMAGE_NAME is the filename of the image, to use in error messages. - IMAGE_FD is the open file descriptor for the image. - - BPRM_BUF is a copy of the beginning of the file; this of course - contains the elf file header at offset 0. It is assumed that this - buffer is sufficiently aligned to present no problems to the host - in accessing data at aligned offsets within the buffer. - - On return: INFO values will be filled in, as necessary or available. */ - -static void load_elf_image(const char *image_name, int image_fd, +static void load_elf_image(const char *image_name, const ImageSource *src, struct image_info *info, struct elfhdr *ehdr, - char **pinterp_name, - char bprm_buf[BPRM_BUF_SIZE]) + char **pinterp_name) { - struct elf_phdr *phdr; + g_autofree struct elf_phdr *phdr = NULL; abi_ulong load_addr, load_bias, loaddr, hiaddr, error; - int i, retval, prot_exec; + int i, prot_exec; Error *err = NULL; - /* First of all, some simple consistency checks */ - memcpy(ehdr, bprm_buf, sizeof(*ehdr)); + /* + * First of all, some simple consistency checks. + * Note that we rely on the bswapped ehdr staying in bprm_buf, + * for later use by load_elf_binary and create_elf_tables. + */ + if (!imgsrc_read(ehdr, 0, sizeof(*ehdr), src, &err)) { + goto exit_errmsg; + } if (!elf_check_ident(ehdr)) { error_setg(&err, "Invalid ELF image for this architecture"); goto exit_errmsg; @@ -3040,15 +3037,11 @@ static void load_elf_image(const char *image_name, int image_fd, goto exit_errmsg; } - i = ehdr->e_phnum * sizeof(struct elf_phdr); - if (ehdr->e_phoff + i <= BPRM_BUF_SIZE) { - phdr = (struct elf_phdr *)(bprm_buf + ehdr->e_phoff); - } else { - phdr = (struct elf_phdr *) alloca(i); - retval = pread(image_fd, phdr, i, ehdr->e_phoff); - if (retval != i) { - goto exit_read; - } + phdr = imgsrc_read_alloc(ehdr->e_phoff, + ehdr->e_phnum * sizeof(struct elf_phdr), + src, &err); + if (phdr == NULL) { + goto exit_errmsg; } bswap_phdr(phdr, ehdr->e_phnum); @@ -3085,17 +3078,10 @@ static void load_elf_image(const char *image_name, int image_fd, goto exit_errmsg; } - interp_name = g_malloc(eppnt->p_filesz); - - if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) { - memcpy(interp_name, bprm_buf + eppnt->p_offset, - eppnt->p_filesz); - } else { - retval = pread(image_fd, interp_name, eppnt->p_filesz, - eppnt->p_offset); - if (retval != eppnt->p_filesz) { - goto exit_read; - } + interp_name = imgsrc_read_alloc(eppnt->p_offset, eppnt->p_filesz, + src, &err); + if (interp_name == NULL) { + goto exit_errmsg; } if (interp_name[eppnt->p_filesz - 1] != 0) { error_setg(&err, "Invalid PT_INTERP entry"); @@ -3103,7 +3089,7 @@ static void load_elf_image(const char *image_name, int image_fd, } *pinterp_name = g_steal_pointer(&interp_name); } else if (eppnt->p_type == PT_GNU_PROPERTY) { - if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) { + if (!parse_elf_properties(src, info, eppnt, &err)) { goto exit_errmsg; } } else if (eppnt->p_type == PT_GNU_STACK) { @@ -3256,9 +3242,9 @@ static void load_elf_image(const char *image_name, int image_fd, * but no backing file segment. */ if (eppnt->p_filesz != 0) { - error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, + error = imgsrc_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, elf_prot, MAP_PRIVATE | MAP_FIXED, - image_fd, eppnt->p_offset - vaddr_po); + src, eppnt->p_offset - vaddr_po); if (error == -1) { goto exit_mmap; } @@ -3290,20 +3276,11 @@ static void load_elf_image(const char *image_name, int image_fd, #ifdef TARGET_MIPS } else if (eppnt->p_type == PT_MIPS_ABIFLAGS) { Mips_elf_abiflags_v0 abiflags; - if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) { - error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry"); + + if (!imgsrc_read(&abiflags, eppnt->p_offset, sizeof(abiflags), + src, &err)) { goto exit_errmsg; } - if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) { - memcpy(&abiflags, bprm_buf + eppnt->p_offset, - sizeof(Mips_elf_abiflags_v0)); - } else { - retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0), - eppnt->p_offset); - if (retval != sizeof(Mips_elf_abiflags_v0)) { - goto exit_read; - } - } bswap_mips_abiflags(&abiflags); info->fp_abi = abiflags.fp_abi; #endif @@ -3316,23 +3293,16 @@ static void load_elf_image(const char *image_name, int image_fd, } if (qemu_log_enabled()) { - load_symbols(ehdr, image_fd, load_bias); + load_symbols(ehdr, src->fd, load_bias); } - debuginfo_report_elf(image_name, image_fd, load_bias); + debuginfo_report_elf(image_name, src->fd, load_bias); mmap_unlock(); - close(image_fd); + close(src->fd); return; - exit_read: - if (retval >= 0) { - error_setg(&err, "Incomplete read of file header"); - } else { - error_setg_errno(&err, errno, "Error reading file header"); - } - goto exit_errmsg; exit_mmap: error_setg_errno(&err, errno, "Error mapping file"); goto exit_errmsg; @@ -3345,6 +3315,7 @@ static void load_elf_interp(const char *filename, struct image_info *info, char bprm_buf[BPRM_BUF_SIZE]) { struct elfhdr ehdr; + ImageSource src; int fd, retval; Error *err = NULL; @@ -3362,11 +3333,11 @@ static void load_elf_interp(const char *filename, struct image_info *info, exit(-1); } - if (retval < BPRM_BUF_SIZE) { - memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval); - } + src.fd = fd; + src.cache = bprm_buf; + src.cache_size = retval; - load_elf_image(filename, fd, info, &ehdr, NULL, bprm_buf); + load_elf_image(filename, &src, info, &ehdr, NULL); } static int symfind(const void *s0, const void *s1) @@ -3577,8 +3548,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) info->start_mmap = (abi_ulong)ELF_START_MMAP; - load_elf_image(bprm->filename, bprm->fd, info, - &ehdr, &elf_interpreter, bprm->buf); + load_elf_image(bprm->filename, &bprm->src, info, &ehdr, &elf_interpreter); /* Do this so that we can load the interpreter, if need be. We will change some of these later */ From patchwork Wed Aug 16 18:03:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821995 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=R3DR6/FI; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQx031Mvhz1xrk for ; Thu, 17 Aug 2023 04:06:11 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs2-00029o-1L; Wed, 16 Aug 2023 14:03:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKrz-00026p-VM for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:47 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKrx-0001Jm-IZ for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:47 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1bdc243d62bso32116955ad.3 for ; Wed, 16 Aug 2023 11:03:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209024; x=1692813824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ePVxotW82jMDrWJ+ESk2twixLo2Priek8MjmEOc4z70=; b=R3DR6/FIzsudhGKUIUXzmKb3um1eoD20giGTiQklQv/UmY7m0lWyovyqdCiWsIvDoi eTVxVIVu27gXW1ey80qxv+3Z8oPUkCZYtfBiIBM3E9V2kgPMSbW9Nkbt413fE6rbqq7F zZoDS57wT7XEoBNaT8ZcT3ao0/fhlJA3AVsg67qVtal8xBqh8+DzXop48h+a8LGxONUT ypf0MWPF25b3uvgRyNkUTrTio0s1+uFNvb8F3Eg1ckWaW35IqVbHrcML37p6nsXmKcfM u7u9mpQc69Pxt0ZBYA7g+wngVX7kG+sr5KuHV7W7oMw0ntbtMJ5E+Ys+KWIupNXWnyES bK4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209024; x=1692813824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ePVxotW82jMDrWJ+ESk2twixLo2Priek8MjmEOc4z70=; b=hax5cHGqrA4a4bLdGuoPmeW2O6ohES+s65Vh9EN6hkS37/kdWceXyRWizlpGIMBxfP RnScclF5WcSSCnhTiCZSVp+yERn3v+DR0EsS57g13LF3R++jySebUn+ewlewZndcqq4T 7YOdcAwBLGSWevpUnqpyP/zAbgh+ddCr55KISreUz3a2zCLlID1nXddsnl0jxfBj0R4X B3DWhdYzp7QPHuZtQQqnpVQDtFHzTZ9anNI3I1zn1ZDsiUIUqBbsywBs+0Ymp0IMz9I/ 0MwTSIYpGdB4VP2KZ1uu6C5ZJJEN6bzFHoVpqhEPqneTsYPEz7P7i3ncx3KHupuLfoNY KamA== X-Gm-Message-State: AOJu0Yym5Cmfp7qsnSYE39+zD3NOujO2u1dsIpF2ynLuVE0EiVLv9lGQ +ofdHyqTXMDXJkysgYALW9m0JpXnEL3dt82DUzQ= X-Google-Smtp-Source: AGHT+IE7+owtNyLY8577OMbCuCZEA3uVa3xJKG52EjiynZm2TucjPYTk+7FSODrr4yQWWgF7fQ9f3A== X-Received: by 2002:a17:903:1246:b0:1b9:cb27:7f43 with SMTP id u6-20020a170903124600b001b9cb277f43mr3044388plh.43.1692209023673; Wed, 16 Aug 2023 11:03:43 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:43 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 05/18] linux-user: Use ImageSource in load_symbols Date: Wed, 16 Aug 2023 11:03:25 -0700 Message-Id: <20230816180338.572576-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::631; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x631.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Aside from the section headers, we're unlikely to hit the ImageSource cache on guest executables. But the interface for imgsrc_read_* is better. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- linux-user/elfload.c | 87 ++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index f3511ae766..19d3cac039 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2048,7 +2048,8 @@ static inline void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags) { } #ifdef USE_ELF_CORE_DUMP static int elf_core_dump(int, const CPUArchState *); #endif /* USE_ELF_CORE_DUMP */ -static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias); +static void load_symbols(struct elfhdr *hdr, const ImageSource *src, + abi_ulong load_bias); /* Verify the portions of EHDR within E_IDENT for the target. This can be performed before bswapping the entire header. */ @@ -3293,7 +3294,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src, } if (qemu_log_enabled()) { - load_symbols(ehdr, src->fd, load_bias); + load_symbols(ehdr, src, load_bias); } debuginfo_report_elf(image_name, src->fd, load_bias); @@ -3384,19 +3385,20 @@ static int symcmp(const void *s0, const void *s1) } /* Best attempt to load symbols from this ELF object. */ -static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) +static void load_symbols(struct elfhdr *hdr, const ImageSource *src, + abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; - uint64_t segsz; - struct elf_shdr *shdr; + g_autofree struct elf_shdr *shdr = NULL; char *strings = NULL; - struct syminfo *s = NULL; - struct elf_sym *new_syms, *syms = NULL; + struct elf_sym *syms = NULL; + struct elf_sym *new_syms; + uint64_t segsz; shnum = hdr->e_shnum; - i = shnum * sizeof(struct elf_shdr); - shdr = (struct elf_shdr *)alloca(i); - if (pread(fd, shdr, i, hdr->e_shoff) != i) { + shdr = imgsrc_read_alloc(hdr->e_shoff, shnum * sizeof(struct elf_shdr), + src, NULL); + if (shdr == NULL) { return; } @@ -3414,31 +3416,33 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) found: /* Now know where the strtab and symtab are. Snarf them. */ - s = g_try_new(struct syminfo, 1); - if (!s) { - goto give_up; - } segsz = shdr[str_idx].sh_size; - s->disas_strtab = strings = g_try_malloc(segsz); - if (!strings || - pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) { + strings = g_try_malloc(segsz); + if (!strings) { + goto give_up; + } + if (!imgsrc_read(strings, shdr[str_idx].sh_offset, segsz, src, NULL)) { goto give_up; } segsz = shdr[sym_idx].sh_size; - syms = g_try_malloc(segsz); - if (!syms || pread(fd, syms, segsz, shdr[sym_idx].sh_offset) != segsz) { - goto give_up; - } - if (segsz / sizeof(struct elf_sym) > INT_MAX) { - /* Implausibly large symbol table: give up rather than ploughing - * on with the number of symbols calculation overflowing + /* + * Implausibly large symbol table: give up rather than ploughing + * on with the number of symbols calculation overflowing. */ goto give_up; } nsyms = segsz / sizeof(struct elf_sym); + syms = g_try_malloc(segsz); + if (!syms) { + goto give_up; + } + if (!imgsrc_read(syms, shdr[sym_idx].sh_offset, segsz, src, NULL)) { + goto give_up; + } + for (i = 0; i < nsyms; ) { bswap_sym(syms + i); /* Throw away entries which we do not need. */ @@ -3463,10 +3467,12 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) goto give_up; } - /* Attempt to free the storage associated with the local symbols - that we threw away. Whether or not this has any effect on the - memory allocation depends on the malloc implementation and how - many symbols we managed to discard. */ + /* + * Attempt to free the storage associated with the local symbols + * that we threw away. Whether or not this has any effect on the + * memory allocation depends on the malloc implementation and how + * many symbols we managed to discard. + */ new_syms = g_try_renew(struct elf_sym, syms, nsyms); if (new_syms == NULL) { goto give_up; @@ -3475,20 +3481,23 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) qsort(syms, nsyms, sizeof(*syms), symcmp); - s->disas_num_syms = nsyms; -#if ELF_CLASS == ELFCLASS32 - s->disas_symtab.elf32 = syms; -#else - s->disas_symtab.elf64 = syms; -#endif - s->lookup_symbol = lookup_symbolxx; - s->next = syminfos; - syminfos = s; + { + struct syminfo *s = g_new(struct syminfo, 1); + s->disas_strtab = strings; + s->disas_num_syms = nsyms; +#if ELF_CLASS == ELFCLASS32 + s->disas_symtab.elf32 = syms; +#else + s->disas_symtab.elf64 = syms; +#endif + s->lookup_symbol = lookup_symbolxx; + s->next = syminfos; + syminfos = s; + } return; -give_up: - g_free(s); + give_up: g_free(strings); g_free(syms); } From patchwork Wed Aug 16 18:03:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=OYZ6xemA; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQx0032Sgz1xrk for ; Thu, 17 Aug 2023 04:06:08 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs2-0002Bx-Vb; Wed, 16 Aug 2023 14:03:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs0-00026u-4V for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:48 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKrx-0001K4-TW for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:47 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1bdca7cc28dso38507695ad.1 for ; Wed, 16 Aug 2023 11:03:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209024; x=1692813824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RtG96b3jmli1q7lVtewuvoGgDoJMS7AqHQZel0hsDHw=; b=OYZ6xemAXvjp939jMTyaTd9OpdU7rtzYEsDef4uXacOVOm5rk3gn+vph1H5b5iu48q hTdFi5MkMx/pqiGHRW6R3rvzx9wFL0oPM+kvSpyXszxgbYFRqNoG8Lyq8o3hMRPM8DI4 XoNvd+CMJ5ZcZDPs24DTP6HF9EQ56Hd9/6ErIcGQ6j1fmzy+3BDpWo2olfMtCiAT/E8w wXxzJiGd/TiGv0LceuyhhBQJ3VET8ExthQd/V0Gj2BKp8LbJfZELuqSiNTtYVENU4EOz 6t+d09iMrw9wlbEJVyD5xoaZUaSFPn8TPTDPrbGy20ioO46ntTQOFCp6H2OE8iI1SrAC 031A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209024; x=1692813824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RtG96b3jmli1q7lVtewuvoGgDoJMS7AqHQZel0hsDHw=; b=EeJDpqCkfaIu3meEYcXtWl2+Vl2nhvYjmblvcBBU0/XaQxBjD1Dd9EzzxfIt86lLvJ qlm6IMdRxCMZR4xPMRiV4LlrFaVVjzHjjPg4iTT6gd7DhEjuOFl3rKQEL81yQbdXF7bR KFMlUCnAaqHcJtMKtVCf+HVIhQ8nFwEKxbvd3MTot/Majj/OufYZIIQyVgqbdm/oByug sx/5oq9h+Q8TSO8kIv8k6EkGZcjee59iGNQckkvmaSriq70ky13C6ee1aBB2TYIFhGPg 7kpKCIU3Sp/dF3diAoJtlGcPU/3C+vi9O60pg3XZno/ahrwdxgKk4p072LjTFCcOwqjp 6V+A== X-Gm-Message-State: AOJu0YzBgsZR5owSFKIn97BJF5sYlCG7Vl+XZghBMg0mbP/twlxIUWB2 vzs2vHcJ4wXJypkuzvKcB+5HBVS7LrJjbIaqbn4= X-Google-Smtp-Source: AGHT+IElbCT/zV9myCRNSP2t0yHxVrBE2mMI/P1J2Mj+Q4/FddFJOc92GMr+NsJs6BT1XdKPK+UDww== X-Received: by 2002:a17:902:c943:b0:1bc:6c8:cded with SMTP id i3-20020a170902c94300b001bc06c8cdedmr2831020pla.67.1692209024447; Wed, 16 Aug 2023 11:03:44 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:44 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [PATCH v4 06/18] linux-user: Replace bprm->fd with bprm->src.fd Date: Wed, 16 Aug 2023 11:03:26 -0700 Message-Id: <20230816180338.572576-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There are only a couple of uses of bprm->fd remaining. Migrate to the other field. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/loader.h | 1 - linux-user/flatload.c | 8 ++++---- linux-user/linuxload.c | 5 ++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/linux-user/loader.h b/linux-user/loader.h index 311d20f5d1..5b4cdddd50 100644 --- a/linux-user/loader.h +++ b/linux-user/loader.h @@ -74,7 +74,6 @@ struct linux_binprm { char buf[BPRM_BUF_SIZE] __attribute__((aligned)); ImageSource src; abi_ulong p; - int fd; int e_uid, e_gid; int argc, envc; char **argv; diff --git a/linux-user/flatload.c b/linux-user/flatload.c index 8f5e9f489b..15e3ec5f6b 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -463,7 +463,7 @@ static int load_flat_file(struct linux_binprm * bprm, DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); textpos = target_mmap(0, text_len, PROT_READ|PROT_EXEC, - MAP_PRIVATE, bprm->fd, 0); + MAP_PRIVATE, bprm->src.fd, 0); if (textpos == -1) { fprintf(stderr, "Unable to mmap process text\n"); return -1; @@ -490,7 +490,7 @@ static int load_flat_file(struct linux_binprm * bprm, } else #endif { - result = target_pread(bprm->fd, datapos, + result = target_pread(bprm->src.fd, datapos, data_len + (relocs * sizeof(abi_ulong)), fpos); } @@ -540,10 +540,10 @@ static int load_flat_file(struct linux_binprm * bprm, else #endif { - result = target_pread(bprm->fd, textpos, + result = target_pread(bprm->src.fd, textpos, text_len, 0); if (result >= 0) { - result = target_pread(bprm->fd, datapos, + result = target_pread(bprm->src.fd, datapos, data_len + (relocs * sizeof(abi_ulong)), ntohl(hdr->data_start)); } diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 5b7e9ab983..4a794f8cea 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -39,7 +39,7 @@ static int prepare_binprm(struct linux_binprm *bprm) int mode; int retval; - if (fstat(bprm->fd, &st) < 0) { + if (fstat(bprm->src.fd, &st) < 0) { return -errno; } @@ -69,7 +69,7 @@ static int prepare_binprm(struct linux_binprm *bprm) bprm->e_gid = st.st_gid; } - retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE); + retval = read(bprm->src.fd, bprm->buf, BPRM_BUF_SIZE); if (retval < 0) { perror("prepare_binprm"); exit(-1); @@ -144,7 +144,6 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, { int retval; - bprm->fd = fdexec; bprm->src.fd = fdexec; bprm->filename = (char *)filename; bprm->argc = count(argv); From patchwork Wed Aug 16 18:03:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821990 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=GJCrOIzT; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwzm3p5sz1xrk for ; Thu, 17 Aug 2023 04:05:56 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs3-0002By-0A; Wed, 16 Aug 2023 14:03:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs1-00028C-9s for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:49 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKry-0001Ka-Pc for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:49 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1bda9207132so54670885ad.0 for ; Wed, 16 Aug 2023 11:03:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209025; x=1692813825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qAG6PGIV1uQFBhWqnMGM8QSbNiLc7gv0kNNHJcbKMjM=; b=GJCrOIzTumK6O7vr8Yvz86qW1wbfEA442N0ulAD1yCvu4XBn8uBytVjco6riWz2rOa qweKXi8SAVk1MojcaNgMmUFVbfm6FHtk73bIr9nWEfPoPniZyUT5wligm9d2uNzXM0jf NBieQrseUPdYwUeo/3WjqriugytA3510kYJs9ZrxVU5bVHl0jlODniAAZJzh5gipmLlx T/7eFa3AzbFFgPgRNC6tfmNoCYgGLqaWJJlrRTEWKb0rrM7jXE9cGbvDGeFyQxfDxTCp nF78uQ/RXZ1sA4ptoMnEC37oEkt/qsEBJ57Y0pgXo6xpt1p7IxF3hJVyJXxvVWMyDk22 Ulrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209025; x=1692813825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qAG6PGIV1uQFBhWqnMGM8QSbNiLc7gv0kNNHJcbKMjM=; b=NUJtnwkf8E5Nok8WGB5NIo54WHiB2SC+x+IHq97fdmE8K8uztE+iuZfGDv9jMMo//R /J8lyiQMGe2yi7B+dnNbpPFYc1GP3aG7eAywLaSQHOrnLly4sFkXtVzpm4T4e6nlH137 7QD+Hc1tDQIri+Zz3PJMenPK3DQmrFnAFCcc9aCCsuFVTDZI0bWtfrUWmf4HzHNVYwKE HzGYkE+P5VzJrTUQ9/kkGAGb5kB+KcEkTOF/MQqZN5iop57RPHreZXnpXsicbIG4sJAR OfUnwlI/FjYaSIzhTVtHgXqZ/vj85v9xJEsZ0GwoGJdRZeek3ujp5TcdhMimvypI89KQ QmOA== X-Gm-Message-State: AOJu0YwgOIB8yVrpVC5jdFbcIEeErAk6tj7mDkMlo+TfklVxkUt0u0PS kloUvZLh1bnIRCq9TQv5ziqxJy7K6m9IhOiDqAc= X-Google-Smtp-Source: AGHT+IHFWXC+cZSx0xRreOfLCy8cTIWbx3rU5khhsZYIGqVutf6busikg0I+RHeKugD2XWUByyvqAg== X-Received: by 2002:a17:902:be08:b0:1bb:a4e4:54b6 with SMTP id r8-20020a170902be0800b001bba4e454b6mr2588554pls.62.1692209025476; Wed, 16 Aug 2023 11:03:45 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:45 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 07/18] linux-user: Load vdso image if available Date: Wed, 16 Aug 2023 11:03:27 -0700 Message-Id: <20230816180338.572576-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x629.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The vdso image will be pre-processed into a C data array, with a simple list of relocations to perform, and identifying the location of signal trampolines. Signed-off-by: Richard Henderson --- linux-user/elfload.c | 87 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 19d3cac039..f94963638a 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -33,6 +33,19 @@ #undef ELF_ARCH #endif +#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0 +#endif + +typedef struct { + const uint8_t *image; + const uint32_t *relocs; + unsigned image_size; + unsigned reloc_count; + unsigned sigreturn_ofs; + unsigned rt_sigreturn_ofs; +} VdsoImageInfo; + #define ELF_OSABI ELFOSABI_SYSV /* from personality.h */ @@ -2291,7 +2304,8 @@ static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong s static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, struct elfhdr *exec, struct image_info *info, - struct image_info *interp_info) + struct image_info *interp_info, + struct image_info *vdso_info) { abi_ulong sp; abi_ulong u_argc, u_argv, u_envp, u_auxv; @@ -2379,10 +2393,15 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, } size = (DLINFO_ITEMS + 1) * 2; - if (k_base_platform) + if (k_base_platform) { size += 2; - if (k_platform) + } + if (k_platform) { size += 2; + } + if (vdso_info) { + size += 2; + } #ifdef DLINFO_ARCH_ITEMS size += DLINFO_ARCH_ITEMS * 2; #endif @@ -2464,6 +2483,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, if (u_platform) { NEW_AUX_ENT(AT_PLATFORM, u_platform); } + if (vdso_info) { + NEW_AUX_ENT(AT_SYSINFO_EHDR, vdso_info->load_addr); + } NEW_AUX_ENT (AT_NULL, 0); #undef NEW_AUX_ENT @@ -3341,6 +3363,49 @@ static void load_elf_interp(const char *filename, struct image_info *info, load_elf_image(filename, &src, info, &ehdr, NULL); } +#ifndef vdso_image_info +#define vdso_image_info() NULL +#endif + +static void load_elf_vdso(struct image_info *info, const VdsoImageInfo *vdso) +{ + ImageSource src; + struct elfhdr ehdr; + abi_ulong load_bias, load_addr; + + src.fd = -1; + src.cache = vdso->image; + src.cache_size = vdso->image_size; + + load_elf_image("", &src, info, &ehdr, NULL); + load_addr = info->load_addr; + load_bias = info->load_bias; + + /* + * We need to relocate the VDSO image. The one built into the kernel + * is built for a fixed address. The one built for QEMU is not, since + * that requires close control of the guest address space. + * We pre-processed the image to locate all of the addresses that need + * to be updated. + */ + for (unsigned i = 0, n = vdso->reloc_count; i < n; i++) { + abi_ulong *addr = g2h_untagged(load_addr + vdso->relocs[i]); + *addr = tswapal(tswapal(*addr) + load_bias); + } + + /* Install signal trampolines, if present. */ + if (vdso->sigreturn_ofs) { + default_sigreturn = load_addr + vdso->sigreturn_ofs; + } + if (vdso->rt_sigreturn_ofs) { + default_rt_sigreturn = load_addr + vdso->rt_sigreturn_ofs; + } + + /* Remove write from VDSO segment. */ + target_mprotect(info->start_data, info->end_data - info->start_data, + PROT_READ | PROT_EXEC); +} + static int symfind(const void *s0, const void *s1) { struct elf_sym *sym = (struct elf_sym *)s1; @@ -3546,7 +3611,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) * and let elf_load_image do any swapping that may be required. */ struct elfhdr ehdr; - struct image_info interp_info; + struct image_info interp_info, vdso_info; char *elf_interpreter = NULL; char *scratch; @@ -3629,10 +3694,13 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) } /* - * TODO: load a vdso, which would also contain the signal trampolines. - * Otherwise, allocate a private page to hold them. + * Load a vdso if available, which will amongst other things contain the + * signal trampolines. Otherwise, allocate a separate page for them. */ - if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) { + const VdsoImageInfo *vdso = vdso_image_info(); + if (vdso) { + load_elf_vdso(&vdso_info, vdso); + } else if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) { abi_long tramp_page = target_mmap(0, TARGET_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); @@ -3644,8 +3712,9 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC); } - bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr, - info, (elf_interpreter ? &interp_info : NULL)); + bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr, info, + elf_interpreter ? &interp_info : NULL, + vdso ? &vdso_info : NULL); info->start_stack = bprm->p; /* If we have an interpreter, set that as the program's entry point. From patchwork Wed Aug 16 18:03:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821989 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=tDh7hyBy; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwzj6fsYz1xrk for ; Thu, 17 Aug 2023 04:05:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs4-0002HM-4z; Wed, 16 Aug 2023 14:03:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs3-0002D8-7u for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:51 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs0-0001Ku-0y for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:50 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-1bd9b4f8e0eso42889205ad.1 for ; Wed, 16 Aug 2023 11:03:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209026; x=1692813826; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=8DdcwZ9eARbtAsO2bsYseMjavqpyn3Vml59R5brpVvQ=; b=tDh7hyByUweBfSXlXsTc8xhRfbC/3oZzw4mtx4Q2N7BZv6WwAqn6lF4OdQP2h4FN6L pud9JiLMEWrBQyrToyU9AMnelcF6mGv8O+xGS0tOwHfhqTVtgd4aVF9eQbysf/fbH/JP RGXt9TLXOz3Du6Vl6APGQ9QSG2RwSvS8eai2Kr5aAWyyckD8vm7HlnyvngVTAl7pyGam J7JCTIrIe6bm0h3c+ZT0oBo1GFcJhEOCDPYz4jg5cCyKYvhzoOa2pQjnxHr8nyfgVN7w reZGwcSRx9b7XAe7QSQtG5XiRfbZtktTpd/eu1OuiP/5Y1udt5+XwflMSf8zs5Ds/7fs IMtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209026; x=1692813826; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8DdcwZ9eARbtAsO2bsYseMjavqpyn3Vml59R5brpVvQ=; b=ah0js17hZ3Br4TwPHfd8ffAWGcYvyBI9miW2k3jXdWm2+xKZXn/jyxBb3cOkVqHVNl Po124BCWBNbG9EIKWx0X21YYiO5oW9owuOh4AeE8GjWBKG978klmCGB4Jbx/TsFBzaHB 3DE6BYwdJLXqZTTSZ2hb0Kdn1yi/ihqA0DcI1UGurOaisi/Y4V3fNx4zm2hXiLIkN8RL 1NPsjP2NGSzIpkEz84nY+Nn1/UddeOLRiX1s1/evzUHurVwuayZyUPCbk1aqd0c34kcO eFznqKcz4qy+qHncuQ6r15jl9NXSMbGWbbZmJ+EwzgX+mMmQSgngU4u6PCJYaMJLyJXZ Y1Og== X-Gm-Message-State: AOJu0Ywcnl+b/2tQPjWqFH+Slo7rWIK2bvqXnNY9YcrTLh65H5qMUPnq WKvI1fTF/LSV8FYQmvGDlyvI2EYxSfKKZE62Nzw= X-Google-Smtp-Source: AGHT+IHZDHDyYI/2B3RDTSUCeTn6UH5YEDwauYrlRwgU4ChtKl1m6GBr48ASqMnPDS46VLUL7HiZoQ== X-Received: by 2002:a17:903:1105:b0:1b8:9b17:f63d with SMTP id n5-20020a170903110500b001b89b17f63dmr3335621plh.23.1692209026320; Wed, 16 Aug 2023 11:03:46 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:45 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 08/18] linux-user: Add gen-vdso tool Date: Wed, 16 Aug 2023 11:03:28 -0700 Message-Id: <20230816180338.572576-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This tool will be used for post-processing the linked vdso image, turning it into something that is easy to include into elfload.c. Signed-off-by: Richard Henderson --- linux-user/gen-vdso.c | 223 ++++++++++++++++++++++++ linux-user/gen-vdso-elfn.c.inc | 307 +++++++++++++++++++++++++++++++++ linux-user/meson.build | 6 +- 3 files changed, 535 insertions(+), 1 deletion(-) create mode 100644 linux-user/gen-vdso.c create mode 100644 linux-user/gen-vdso-elfn.c.inc diff --git a/linux-user/gen-vdso.c b/linux-user/gen-vdso.c new file mode 100644 index 0000000000..a6c61d2f6e --- /dev/null +++ b/linux-user/gen-vdso.c @@ -0,0 +1,223 @@ +/* + * Post-process a vdso elf image for inclusion into qemu. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "elf.h" + + +#define bswap_(p) _Generic(*(p), \ + uint16_t: __builtin_bswap16, \ + uint32_t: __builtin_bswap32, \ + uint64_t: __builtin_bswap64, \ + int16_t: __builtin_bswap16, \ + int32_t: __builtin_bswap32, \ + int64_t: __builtin_bswap64) +#define bswaps(p) (*(p) = bswap_(p)(*(p))) + +static void output_reloc(FILE *outf, void *buf, void *loc) +{ + fprintf(outf, " 0x%08lx,\n", (unsigned long)(loc - buf)); +} + +static const char *sigreturn_sym; +static const char *rt_sigreturn_sym; + +static unsigned sigreturn_addr; +static unsigned rt_sigreturn_addr; + +#define N 32 +#define elfN(x) elf32_##x +#define ElfN(x) Elf32_##x +#include "gen-vdso-elfn.c.inc" +#undef N +#undef elfN +#undef ElfN + +#define N 64 +#define elfN(x) elf64_##x +#define ElfN(x) Elf64_##x +#include "gen-vdso-elfn.c.inc" +#undef N +#undef elfN +#undef ElfN + + +int main(int argc, char **argv) +{ + FILE *inf, *outf; + long total_len; + const char *prefix = "vdso"; + const char *inf_name; + const char *outf_name = NULL; + unsigned char *buf; + bool need_bswap; + + while (1) { + int opt = getopt(argc, argv, "o:p:r:s:"); + if (opt < 0) { + break; + } + switch (opt) { + case 'o': + outf_name = optarg; + break; + case 'p': + prefix = optarg; + break; + case 'r': + rt_sigreturn_sym = optarg; + break; + case 's': + sigreturn_sym = optarg; + break; + default: + usage: + fprintf(stderr, "usage: [-p prefix] [-r rt-sigreturn-name] " + "[-s sigreturn-name] -o output-file input-file\n"); + return EXIT_FAILURE; + } + } + + if (optind >= argc || outf_name == NULL) { + goto usage; + } + inf_name = argv[optind]; + + /* + * Open the input and output files. + */ + inf = fopen(inf_name, "rb"); + if (inf == NULL) { + goto perror_inf; + } + outf = fopen(outf_name, "w"); + if (outf == NULL) { + goto perror_outf; + } + + /* + * Read the input file into a buffer. + * We expect the vdso to be small, on the order of one page, + * therefore we do not expect a partial read. + */ + fseek(inf, 0, SEEK_END); + total_len = ftell(inf); + fseek(inf, 0, SEEK_SET); + + buf = malloc(total_len); + if (buf == NULL) { + goto perror_inf; + } + + errno = 0; + if (fread(buf, 1, total_len, inf) != total_len) { + if (errno) { + goto perror_inf; + } + fprintf(stderr, "%s: incomplete read\n", inf_name); + return EXIT_FAILURE; + } + fclose(inf); + + /* + * Write out the vdso image now, before we make local changes. + */ + + fprintf(outf, + "/* Automatically generated from linux-user/gen-vdso.c. */\n" + "\n" + "static const uint8_t %s_image[] = {", + prefix); + for (long i = 0; i < total_len; ++i) { + if (i % 12 == 0) { + fputs("\n ", outf); + } + fprintf(outf, " 0x%02x,", buf[i]); + } + fprintf(outf, "\n};\n\n"); + + /* + * Identify which elf flavor we're processing. + * The first 16 bytes of the file are e_ident. + */ + + if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1 || + buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3) { + fprintf(stderr, "%s: not an elf file\n", inf_name); + return EXIT_FAILURE; + } + switch (buf[EI_DATA]) { + case ELFDATA2LSB: + need_bswap = BYTE_ORDER != LITTLE_ENDIAN; + break; + case ELFDATA2MSB: + need_bswap = BYTE_ORDER != BIG_ENDIAN; + break; + default: + fprintf(stderr, "%s: invalid elf EI_DATA (%u)\n", + inf_name, buf[EI_DATA]); + return EXIT_FAILURE; + } + + /* + * We need to relocate the VDSO image. The one built into the kernel + * is built for a fixed address. The one we built for QEMU is not, + * since that requires close control of the guest address space. + * + * Output relocation addresses as we go. + */ + + fprintf(outf, "static const unsigned %s_relocs[] = {\n", prefix); + + switch (buf[EI_CLASS]) { + case ELFCLASS32: + elf32_process(outf, buf, need_bswap); + break; + case ELFCLASS64: + elf64_process(outf, buf, need_bswap); + break; + default: + fprintf(stderr, "%s: invalid elf EI_CLASS (%u)\n", + inf_name, buf[EI_CLASS]); + return EXIT_FAILURE; + } + + fprintf(outf, "};\n\n"); /* end vdso_relocs. */ + + fprintf(outf, "static const VdsoImageInfo %s_image_info = {\n", prefix); + fprintf(outf, " .image = %s_image,\n", prefix); + fprintf(outf, " .relocs = %s_relocs,\n", prefix); + fprintf(outf, " .image_size = sizeof(%s_image),\n", prefix); + fprintf(outf, " .reloc_count = ARRAY_SIZE(%s_relocs),\n", prefix); + fprintf(outf, " .sigreturn_ofs = 0x%x,\n", sigreturn_addr); + fprintf(outf, " .rt_sigreturn_ofs = 0x%x,\n", rt_sigreturn_addr); + fprintf(outf, "};\n"); + + /* + * Everything should have gone well. + */ + if (fclose(outf)) { + goto perror_outf; + } + return EXIT_SUCCESS; + + perror_inf: + perror(inf_name); + return EXIT_FAILURE; + + perror_outf: + perror(outf_name); + return EXIT_FAILURE; +} diff --git a/linux-user/gen-vdso-elfn.c.inc b/linux-user/gen-vdso-elfn.c.inc new file mode 100644 index 0000000000..7034c36d5e --- /dev/null +++ b/linux-user/gen-vdso-elfn.c.inc @@ -0,0 +1,307 @@ +/* + * Post-process a vdso elf image for inclusion into qemu. + * Elf size specialization. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +static void elfN(bswap_ehdr)(ElfN(Ehdr) *ehdr) +{ + bswaps(&ehdr->e_type); /* Object file type */ + bswaps(&ehdr->e_machine); /* Architecture */ + bswaps(&ehdr->e_version); /* Object file version */ + bswaps(&ehdr->e_entry); /* Entry point virtual address */ + bswaps(&ehdr->e_phoff); /* Program header table file offset */ + bswaps(&ehdr->e_shoff); /* Section header table file offset */ + bswaps(&ehdr->e_flags); /* Processor-specific flags */ + bswaps(&ehdr->e_ehsize); /* ELF header size in bytes */ + bswaps(&ehdr->e_phentsize); /* Program header table entry size */ + bswaps(&ehdr->e_phnum); /* Program header table entry count */ + bswaps(&ehdr->e_shentsize); /* Section header table entry size */ + bswaps(&ehdr->e_shnum); /* Section header table entry count */ + bswaps(&ehdr->e_shstrndx); /* Section header string table index */ +} + +static void elfN(bswap_phdr)(ElfN(Phdr) *phdr) +{ + bswaps(&phdr->p_type); /* Segment type */ + bswaps(&phdr->p_flags); /* Segment flags */ + bswaps(&phdr->p_offset); /* Segment file offset */ + bswaps(&phdr->p_vaddr); /* Segment virtual address */ + bswaps(&phdr->p_paddr); /* Segment physical address */ + bswaps(&phdr->p_filesz); /* Segment size in file */ + bswaps(&phdr->p_memsz); /* Segment size in memory */ + bswaps(&phdr->p_align); /* Segment alignment */ +} + +static void elfN(bswap_shdr)(ElfN(Shdr) *shdr) +{ + bswaps(&shdr->sh_name); + bswaps(&shdr->sh_type); + bswaps(&shdr->sh_flags); + bswaps(&shdr->sh_addr); + bswaps(&shdr->sh_offset); + bswaps(&shdr->sh_size); + bswaps(&shdr->sh_link); + bswaps(&shdr->sh_info); + bswaps(&shdr->sh_addralign); + bswaps(&shdr->sh_entsize); +} + +static void elfN(bswap_sym)(ElfN(Sym) *sym) +{ + bswaps(&sym->st_name); + bswaps(&sym->st_value); + bswaps(&sym->st_size); + bswaps(&sym->st_shndx); +} + +static void elfN(bswap_dyn)(ElfN(Dyn) *dyn) +{ + bswaps(&dyn->d_tag); /* Dynamic type tag */ + bswaps(&dyn->d_un.d_ptr); /* Dynamic ptr or val, in union */ +} + +static void elfN(search_symtab)(ElfN(Shdr) *shdr, unsigned sym_idx, + void *buf, bool need_bswap) +{ + unsigned str_idx = shdr[sym_idx].sh_link; + ElfN(Sym) *sym = buf + shdr[sym_idx].sh_offset; + unsigned sym_n = shdr[sym_idx].sh_size / sizeof(*sym); + const char *str = buf + shdr[str_idx].sh_offset; + + for (unsigned i = 0; i < sym_n; ++i) { + const char *name; + + if (need_bswap) { + elfN(bswap_sym)(sym + i); + } + name = str + sym[i].st_name; + + if (sigreturn_sym && strcmp(sigreturn_sym, name) == 0) { + sigreturn_addr = sym[i].st_value; + } + if (rt_sigreturn_sym && strcmp(rt_sigreturn_sym, name) == 0) { + rt_sigreturn_addr = sym[i].st_value; + } + } +} + +static void elfN(process)(FILE *outf, void *buf, bool need_bswap) +{ + ElfN(Ehdr) *ehdr = buf; + ElfN(Phdr) *phdr; + ElfN(Shdr) *shdr; + unsigned phnum, shnum; + unsigned dynamic_ofs = 0; + unsigned dynamic_addr = 0; + unsigned symtab_idx = 0; + unsigned dynsym_idx = 0; + unsigned first_segsz = 0; + int errors = 0; + + if (need_bswap) { + elfN(bswap_ehdr)(ehdr); + } + + phnum = ehdr->e_phnum; + phdr = buf + ehdr->e_phoff; + if (need_bswap) { + for (unsigned i = 0; i < phnum; ++i) { + elfN(bswap_phdr)(phdr + i); + } + } + + shnum = ehdr->e_shnum; + shdr = buf + ehdr->e_shoff; + if (need_bswap) { + for (unsigned i = 0; i < shnum; ++i) { + elfN(bswap_shdr)(shdr + i); + } + } + for (unsigned i = 0; i < shnum; ++i) { + switch (shdr[i].sh_type) { + case SHT_SYMTAB: + symtab_idx = i; + break; + case SHT_DYNSYM: + dynsym_idx = i; + break; + } + } + + /* + * Validate the VDSO is created as we expect: that PT_PHDR, + * PT_DYNAMIC, and PT_NOTE located in a writable data segment. + * PHDR and DYNAMIC require relocation, and NOTE will get the + * linux version number. + */ + for (unsigned i = 0; i < phnum; ++i) { + if (phdr[i].p_type != PT_LOAD) { + continue; + } + if (first_segsz != 0) { + fprintf(stderr, "Multiple LOAD segments\n"); + errors++; + } + if (phdr[i].p_offset != 0) { + fprintf(stderr, "LOAD segment does not cover EHDR\n"); + errors++; + } + if (phdr[i].p_vaddr != 0) { + fprintf(stderr, "LOAD segment not loaded at address 0\n"); + errors++; + } + first_segsz = phdr[i].p_filesz; + if (first_segsz < ehdr->e_phoff + phnum * sizeof(*phdr)) { + fprintf(stderr, "LOAD segment does not cover PHDRs\n"); + errors++; + } + if ((phdr[i].p_flags & (PF_R | PF_W)) != (PF_R | PF_W)) { + fprintf(stderr, "LOAD segment is not read-write\n"); + errors++; + } + } + for (unsigned i = 0; i < phnum; ++i) { + const char *which; + + switch (phdr[i].p_type) { + case PT_PHDR: + which = "PT_PHDR"; + break; + case PT_NOTE: + which = "PT_NOTE"; + break; + case PT_DYNAMIC: + dynamic_ofs = phdr[i].p_offset; + dynamic_addr = phdr[i].p_vaddr; + which = "PT_DYNAMIC"; + break; + default: + continue; + } + if (first_segsz < phdr[i].p_vaddr + phdr[i].p_filesz) { + fprintf(stderr, "LOAD segment does not cover %s\n", which); + errors++; + } + } + if (errors) { + exit(EXIT_FAILURE); + } + + /* Relocate the program headers. */ + for (unsigned i = 0; i < phnum; ++i) { + output_reloc(outf, buf, &phdr[i].p_vaddr); + output_reloc(outf, buf, &phdr[i].p_paddr); + } + + /* Relocate the DYNAMIC entries. */ + if (dynamic_addr) { + ElfN(Dyn) *dyn = buf + dynamic_ofs; + __typeof(dyn->d_tag) tag; + + do { + + if (need_bswap) { + elfN(bswap_dyn)(dyn); + } + tag = dyn->d_tag; + + switch (tag) { + case DT_HASH: + case DT_SYMTAB: + case DT_STRTAB: + case DT_VERDEF: + case DT_VERSYM: + case DT_PLTGOT: + case DT_ADDRRNGLO ... DT_ADDRRNGHI: + /* These entries store an address in the entry. */ + output_reloc(outf, buf, &dyn->d_un.d_val); + break; + + case DT_NULL: + case DT_STRSZ: + case DT_SONAME: + case DT_DEBUG: + case DT_FLAGS: + case DT_FLAGS_1: + case DT_SYMBOLIC: + case DT_BIND_NOW: + case DT_VERDEFNUM: + case DT_VALRNGLO ... DT_VALRNGHI: + /* These entries store an integer in the entry. */ + break; + + case DT_SYMENT: + if (dyn->d_un.d_val != sizeof(ElfN(Sym))) { + fprintf(stderr, "VDSO has incorrect dynamic symbol size\n"); + errors++; + } + break; + + case DT_REL: + case DT_RELSZ: + case DT_RELA: + case DT_RELASZ: + /* + * These entries indicate that the VDSO was built incorrectly. + * It should not have any real relocations. + * ??? The RISC-V toolchain will emit these even when there + * are no relocations. Validate zeros. + */ + if (dyn->d_un.d_val != 0) { + fprintf(stderr, "VDSO has dynamic relocations\n"); + errors++; + } + break; + case DT_RELENT: + case DT_RELAENT: + case DT_TEXTREL: + /* These entries store an integer in the entry. */ + /* Should not be required; see above. */ + break; + + case DT_NEEDED: + case DT_VERNEED: + case DT_PLTREL: + case DT_JMPREL: + case DT_RPATH: + case DT_RUNPATH: + fprintf(stderr, "VDSO has external dependencies\n"); + errors++; + break; + + default: + /* This is probably something target specific. */ + fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n", + (unsigned long)tag); + errors++; + break; + } + dyn++; + } while (tag != DT_NULL); + if (errors) { + exit(EXIT_FAILURE); + } + } + + /* Relocate the dynamic symbol table. */ + if (dynsym_idx) { + ElfN(Sym) *sym = buf + shdr[dynsym_idx].sh_offset; + unsigned sym_n = shdr[dynsym_idx].sh_size / sizeof(*sym); + + for (unsigned i = 0; i < sym_n; ++i) { + output_reloc(outf, buf, &sym[i].st_value); + } + } + + /* Search both dynsym and symtab for the signal return symbols. */ + if (dynsym_idx) { + elfN(search_symtab)(shdr, dynsym_idx, buf, need_bswap); + } + if (symtab_idx) { + elfN(search_symtab)(shdr, symtab_idx, buf, need_bswap); + } +} diff --git a/linux-user/meson.build b/linux-user/meson.build index 7171dc60be..e4cb70ed2d 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -28,9 +28,13 @@ linux_user_ss.add(when: 'TARGET_HAS_BFLT', if_true: files('flatload.c')) linux_user_ss.add(when: 'TARGET_I386', if_true: files('vm86.c')) linux_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', if_true: files('semihost.c')) - syscall_nr_generators = {} +gen_vdso_exe = executable('gen-vdso', 'gen-vdso.c', + native: true, build_by_default: false) +gen_vdso = generator(gen_vdso_exe, output: '@BASENAME@.c.inc', + arguments: ['-o', '@OUTPUT@', '@EXTRA_ARGS@', '@INPUT@']) + subdir('alpha') subdir('arm') subdir('hppa') From patchwork Wed Aug 16 18:03:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821993 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=nQ38ypAS; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwzz21CDz1yXY for ; Thu, 17 Aug 2023 04:06:07 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs5-0002OU-L3; Wed, 16 Aug 2023 14:03:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs3-0002Ed-JZ for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:51 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs0-0001L1-EH for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:51 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-1bda9207132so54671185ad.0 for ; Wed, 16 Aug 2023 11:03:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209027; x=1692813827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=u9xrzd9cWzcmW3Vzjy3QBbkkODEi+xGilFYizFblloc=; b=nQ38ypASOQviJs+XYMhpVVve00fiIyVol9BIosin5Ux9cWP5zA05UNlBUd2kHVh+gk gMrz04gFNGmVVEaEjhWnOHKg666bJC5LWTpN+1CGeZFn9xCuS552JlVvDR3OmHLapOUx 5bb4t9cd/SA5LR2ciwvr7ymy7vWr7JyQ2tTaI+oWLmUxJYQKemBtvkoCHT+YTDo/D2R9 UfHfRr9uBjtdHJeXfv6DxfhSbJNEfsrf817G3cKaW7RuquaN0QK6VsfxrR8xIHFSKX10 aZH28Fi07yb1qa8+JcgGEQFgzjqvcptcwkM5Kk+iqchMHYH7hei04SqKi/8it4LZrki3 t45g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209027; x=1692813827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=u9xrzd9cWzcmW3Vzjy3QBbkkODEi+xGilFYizFblloc=; b=A0tsAOjVLKFur4S20/tVlFZvpF4k8xrwVnE+34sZMwmGAWwzt2Rm8i20oqnByzLv1a GA11QPmN1URbrM8TkywEs7OqGF8tDRGYmhd/Q6Si0UNyC4tauyKZrGaSPiahiPjUc8Ua 8wIYcv5pS0pG1srZTKM+bmXLwDxRkqPq8mEv4mqa275psnj3A6kK6hT4qJ9kSKhPlCk8 Y4Yf31MKCH/it/25g/pH/RnOLMle7POLT6eu19TV+Vrm5mwbQtANKy+Dxex96y0yoZJW wozcU7wwJY9rvT7hJH6r70tLY3bW/8zD06xa2VSxtKH/0tX7iqb228DejMNvfcd3TjcK fnVA== X-Gm-Message-State: AOJu0YzLiHUdzlYTT85DkNU/XUvq495XhOu9UHou2N2CYH0Q7eimhst3 MqQVrWdY4nfDbeQd9Riohoj/cYlV1j0h7qNWvKY= X-Google-Smtp-Source: AGHT+IHhKZFIRMC4DU6yVzTr1f7/r7G+kU4KuGPrU733CwlgJeUZYxomQCsQJ3jN81ZNysJ1+WXsmQ== X-Received: by 2002:a17:902:d349:b0:1bd:bbc3:c87b with SMTP id l9-20020a170902d34900b001bdbbc3c87bmr2623228plk.41.1692209027094; Wed, 16 Aug 2023 11:03:47 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:46 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 09/18] linux-user/i386: Add vdso Date: Wed, 16 Aug 2023 11:03:29 -0700 Message-Id: <20230816180338.572576-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1267 Signed-off-by: Richard Henderson --- linux-user/i386/vdso-asmoffset.h | 6 ++ linux-user/elfload.c | 16 +++- linux-user/i386/signal.c | 11 +++ linux-user/i386/Makefile.vdso | 5 ++ linux-user/i386/meson.build | 7 ++ linux-user/i386/vdso.S | 143 +++++++++++++++++++++++++++++++ linux-user/i386/vdso.ld | 76 ++++++++++++++++ linux-user/i386/vdso.so | Bin 0 -> 2672 bytes 8 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 linux-user/i386/vdso-asmoffset.h create mode 100644 linux-user/i386/Makefile.vdso create mode 100644 linux-user/i386/vdso.S create mode 100644 linux-user/i386/vdso.ld create mode 100755 linux-user/i386/vdso.so GIT binary patch literal 2672 zcmbtWU1%It6u#5lG_z^4ZB?X_C>9o5sxCF8QBlyONt?nZ)?|y73e)ZGba%;SR(597 zjTXE8QIiHtY6YPbDhO>6s(mPS(FX(Z2Q`g?1xp_^KInr_=|f8&)b;yj=5}w=eGok1 z%XiMX=brmB_ny0ldSlx(O%qZAA|PnR8-(ZpuhYGj4)L&P5F5p65f&@qVw=PV(21ar zS~fT!zaSUUNMnrKqu7p`(Ouv?E|~S#J4vR z?eBj&+ji~rg~eZ!zf~VSJr_pXM}D8DFrl0ORPzVHn5LKmbB!e|qzOC^tO77~@mIB) zzl6kpgPDI3e2U8d6uIY2bq_`x0-wZWxDMLSfe$J6M%crOeHivUY<@1rr@`l7bI!EC z1WQ>fZdBic@iW@_P1t@f_$4LZXEGSfcpH2f?e~Kj&v`Zj+$T!NBlkb|jQhnHeiL+a z&lJblO18$ z-OkRAyW9oSmOj5{et#-4CVgruv?pIJqQxKI&ZY~dQ!H3DSHUrA-dxrymL5+h95ZU? zqfdy~j)7gfjrM5g9c>HN9>C7?j(;zF-_-GQuCsOgock95 z$CvrnLFHO513c5BE36+~5f2BEAVM30`47nj^o(oe;NgZND~~oF)87oe)%5l%caD!C zZUR`#4&CABw}%(BE9KdV>yxiUf|Id`UI}64SIQGVslJnSd`)$H14yd$t+Ysc2OQ(J+srhD+k<&>BHxRjq5)uze70i3T0nE36-;4MD zX|P(C`eCbeVGnF6>~F$Q>&)x0)jBo>TdiYfVXJlMbJ%KKV=Y$enlO4^9_Z@du@yHB zwchCMGqw$O_4gWmJ%e{HQ)lfOF0TyrZnl4$<)z$G>%HU>FE1lXy;xFj>Xa70cGRgB zZe?YqcLID@7{~XU=z-4s6vh$lz%9JdjN|)G?1a8N?pfc* zIKKY`&zcmDP2m_-KOf(Hg0)2EV}IgBfWHx_^Y;P~hc5SkbEE79n459x?;V(~$T$m@ zjElobxDGGOT`N`AK*n(#-do~0bSZKjGMDr(AZ`H$D-74d^xS8@>$IiJAn|o+fMq_` OKQ-regs[R_ESP]); (*regs)[16] = tswapreg(env->segs[R_SS].selector & 0xffff); } -#endif + +/* + * i386 is the only target which supplies AT_SYSINFO for the vdso. + * All others only supply AT_SYSINFO_EHDR. + */ +#define DLINFO_ARCH_ITEMS 1 +#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO, vdso_info->entry); + +#include "vdso.c.inc" + +#define vdso_image_info() &vdso_image_info + +#endif /* TARGET_X86_64 */ #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 -#endif +#endif /* TARGET_I386 */ #ifdef TARGET_ARM diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c index 60fa07d6f9..bc5d45302e 100644 --- a/linux-user/i386/signal.c +++ b/linux-user/i386/signal.c @@ -214,6 +214,17 @@ struct rt_sigframe { }; #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \ offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET) + +/* + * Verify that vdso-asmoffset.h constants match. + */ +#include "i386/vdso-asmoffset.h" + +QEMU_BUILD_BUG_ON(offsetof(struct sigframe, sc.eip) + != SIGFRAME_SIGCONTEXT_eip); +QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, uc.tuc_mcontext.eip) + != RT_SIGFRAME_SIGCONTEXT_eip); + #else struct rt_sigframe { diff --git a/linux-user/i386/Makefile.vdso b/linux-user/i386/Makefile.vdso new file mode 100644 index 0000000000..26bc993cda --- /dev/null +++ b/linux-user/i386/Makefile.vdso @@ -0,0 +1,5 @@ +CROSS_CC ?= i686-linux-gnu-gcc + +vdso.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) -m32 -nostdlib -shared -Wl,-T,vdso.ld -Wl,--build-id=sha1 \ + -Wl,-h,linux-gate.so.1 -Wl,--hash-style=both vdso.S -o $@ diff --git a/linux-user/i386/meson.build b/linux-user/i386/meson.build index ee523019a5..b729d73686 100644 --- a/linux-user/i386/meson.build +++ b/linux-user/i386/meson.build @@ -3,3 +3,10 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +gen = [ + gen_vdso.process('vdso.so', extra_args: ['-s', '__kernel_sigreturn', + '-r', '__kernel_rt_sigreturn']) +] + +linux_user_ss.add(when: 'TARGET_I386', if_true: gen) diff --git a/linux-user/i386/vdso.S b/linux-user/i386/vdso.S new file mode 100644 index 0000000000..e7a1f333a1 --- /dev/null +++ b/linux-user/i386/vdso.S @@ -0,0 +1,143 @@ +/* + * i386 linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include "vdso-asmoffset.h" + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro vdso_syscall1 name, nr +\name: + .cfi_startproc + mov %ebx, %edx + .cfi_register %ebx, %edx + mov 4(%esp), %ebx + mov $\nr, %eax + int $0x80 + mov %edx, %ebx + ret + .cfi_endproc +endf \name +.endm + +.macro vdso_syscall2 name, nr +\name: + .cfi_startproc + mov %ebx, %edx + .cfi_register %ebx, %edx + mov 4(%esp), %ebx + mov 8(%esp), %ecx + mov $\nr, %eax + int $0x80 + mov %edx, %ebx + ret + .cfi_endproc +endf \name +.endm + +.macro vdso_syscall3 name, nr +\name: + .cfi_startproc + push %ebx + .cfi_adjust_cfa_offset 4 + .cfi_rel_offset %ebx, 0 + mov 8(%esp), %ebx + mov 12(%esp), %ecx + mov 16(%esp), %edx + mov $\nr, %eax + int $0x80 + pop %ebx + .cfi_adjust_cfa_offset -4 + .cfi_restore %ebx + ret + .cfi_endproc +endf \name +.endm + +__kernel_vsyscall: + .cfi_startproc + int $0x80 + ret + .cfi_endproc +endf __kernel_vsyscall + +vdso_syscall2 __vdso_clock_gettime, __NR_clock_gettime +vdso_syscall2 __vdso_clock_gettime64, __NR_clock_gettime64 +vdso_syscall2 __vdso_clock_getres, __NR_clock_getres +vdso_syscall2 __vdso_gettimeofday, __NR_gettimeofday +vdso_syscall1 __vdso_time, __NR_time +vdso_syscall3 __vdso_getcpu, __NR_gettimeofday + +/* + * Signal return handlers. + */ + + .cfi_startproc simple + .cfi_signal_frame + +/* + * For convenience, put the cfa just above eip in sigcontext, and count + * offsets backward from there. Re-compute the cfa in the two contexts + * we have for signal unwinding. This is far simpler than the + * DW_CFA_expression form that the kernel uses, and is equally correct. + */ + + .cfi_def_cfa %esp, SIGFRAME_SIGCONTEXT_eip + 4 + + .cfi_offset %eip, -4 + /* err, -8 */ + /* trapno, -12 */ + .cfi_offset %eax, -16 + .cfi_offset %ecx, -20 + .cfi_offset %edx, -24 + .cfi_offset %ebx, -28 + .cfi_offset %esp, -32 + .cfi_offset %ebp, -36 + .cfi_offset %esi, -40 + .cfi_offset %edi, -44 + +/* + * While this frame is marked as a signal frame, that only applies to how + * the return address is handled for the outer frame. The return address + * that arrived here, from the inner frame, is not marked as a signal frame + * and so the unwinder still tries to subtract 1 to examine the presumed + * call insn. Thus we must extend the unwind info to a nop before the start. + */ + nop + +__kernel_sigreturn: + popl %eax /* pop sig */ + .cfi_adjust_cfa_offset -4 + movl $__NR_sigreturn, %eax + int $0x80 +endf __kernel_sigreturn + + .cfi_def_cfa_offset RT_SIGFRAME_SIGCONTEXT_eip + 4 + nop + +__kernel_rt_sigreturn: + movl $__NR_rt_sigreturn, %eax + int $0x80 +endf __kernel_rt_sigreturn + + .cfi_endproc + +/* + * TODO: Add elf notes. E.g. + * + * #include + * ELFNOTE_START(Linux, 0, "a") + * .long LINUX_VERSION_CODE + * ELFNOTE_END + * + * but what version number would we set for QEMU? + */ diff --git a/linux-user/i386/vdso.ld b/linux-user/i386/vdso.ld new file mode 100644 index 0000000000..326b7a8f98 --- /dev/null +++ b/linux-user/i386/vdso.ld @@ -0,0 +1,76 @@ +/* + * Linker script for linux i386 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +ENTRY(__kernel_vsyscall) + +VERSION { + LINUX_2.6 { + global: + __vdso_clock_gettime; + __vdso_gettimeofday; + __vdso_time; + __vdso_clock_getres; + __vdso_clock_gettime64; + __vdso_getcpu; + }; + + LINUX_2.5 { + global: + __kernel_vsyscall; + __kernel_sigreturn; + __kernel_rt_sigreturn; + local: *; + }; +} + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + . = SIZEOF_HEADERS; + + /* + * The following, including the FILEHDRS and PHDRS, are modified + * when we relocate the binary. We want them to be initially + * writable for the relocation; we'll force them read-only after. + */ + .note : { *(.note*) } :load :note + .dynamic : { *(.dynamic) } :load :dynamic + .dynsym : { *(.dynsym) } :load + .data : { + /* + * There ought not be any real read-write data. + * But since we manipulated the segment layout, + * we have to put these sections somewhere. + */ + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .rodata : { *(.rodata*) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr + .eh_frame : { *(.eh_frame) } :load + + .text : { *(.text*) } :load =0x90909090 +} diff --git a/linux-user/i386/vdso.so b/linux-user/i386/vdso.so new file mode 100755 index 0000000000000000000000000000000000000000..bdece5dfcf8da036d013262d4e37208350283cfa From patchwork Wed Aug 16 18:03:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821997 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=L8jL9BG5; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQx0F2G9Nz1xrk for ; Thu, 17 Aug 2023 04:06:21 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs5-0002Ob-MR; Wed, 16 Aug 2023 14:03:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs4-0002Hr-6o for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:52 -0400 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs1-0001LI-GR for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:51 -0400 Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1bf078d5f33so3235335ad.3 for ; Wed, 16 Aug 2023 11:03:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209028; x=1692813828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=hJw7fFJBNL9nbUJT0kEhhC1qZ9auicHCmAeSkdC8GLw=; b=L8jL9BG5EutRPh5QLjnXb43dpQ3GpkB6bz29gbH7WVB8sccvyV16pa4LxIO5jYxVjy YeiNz4eJVPtmnz7R5GgrEUwacCauck+bNKFoygeL0tNSFZvvnFJdgMdhVrHzBQ1v+5X+ zurypjXYYSAF+oSaZDK7cKZTzyLoY/S9ewQISNO7iOM/xlPtaC3k9G5QyT3GtdawE7o3 nHFk1W749i5uVsWM79W1nhcUc0OGoyOuk08/rlxa8cyNY4HZ0yaV5ifB0QS51kTdeqES fEpQa+3eQeTdTC1fp/5ifDbzqpOt/yeVj7j9/cNahsEZJ+cv9bybAs+dQOvBltk/llH/ SS8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209028; x=1692813828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hJw7fFJBNL9nbUJT0kEhhC1qZ9auicHCmAeSkdC8GLw=; b=WmGDSUYtd9RzZZKfTUhCvW8wf6TFtWADGmRzxzieqa0+TNdY98GZ++yWi7FLdJTTQm UMDYgDPpOEklFlLKIFMJDEnq2yHG9V8krxRj2Jf1NhNgRlbuwekQF2GUrX3+lJqSneRz ZMKsA5gPpI7tSzC6JpyKsG6IKIGz1hcPcPHQ8mv9XAx/fS+bVD9WDwGbqoz5UoNqTPAT K1LRWYtSXXVul5xjwrDNEnk4nsTSV5TskbmZS2jOIJI5RvnBHY72b01Xv6q7ScbfRR7x 7uxfPWu5iDgQSLjRW9gr82tVecAmcuLLHC1xfmMQQj0KursEeq3v5csvAX+SNJBjI9RT BJ5g== X-Gm-Message-State: AOJu0Yz2cEa8Ruzms5UnfyvVr6SH7V87jhqPAvI/5rodf/YM2G590Fs8 PK4ompHXWdyFFlbhZK184MhtBJ66MugG7UhB9ms= X-Google-Smtp-Source: AGHT+IEdmAp6/ZQLSWZs2shi4j7WlDcbKh3JhjPPOYnBOJNhapK4KI9P8KjQAoAC/Je+CeWinEz7RQ== X-Received: by 2002:a17:902:7c91:b0:1be:fe18:3a44 with SMTP id y17-20020a1709027c9100b001befe183a44mr1364065pll.22.1692209028072; Wed, 16 Aug 2023 11:03:48 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:47 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 10/18] linux-user/x86_64: Add vdso Date: Wed, 16 Aug 2023 11:03:30 -0700 Message-Id: <20230816180338.572576-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62f; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Richard Henderson --- linux-user/elfload.c | 4 +- linux-user/x86_64/Makefile.vdso | 5 ++ linux-user/x86_64/meson.build | 6 +++ linux-user/x86_64/vdso.S | 78 ++++++++++++++++++++++++++++++++ linux-user/x86_64/vdso.ld | 73 ++++++++++++++++++++++++++++++ linux-user/x86_64/vdso.so | Bin 0 -> 2968 bytes 6 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 linux-user/x86_64/Makefile.vdso create mode 100644 linux-user/x86_64/vdso.S create mode 100644 linux-user/x86_64/vdso.ld create mode 100755 linux-user/x86_64/vdso.so GIT binary patch literal 2968 zcmcgtO=w(I6uvKUOl$t7l}J=nY6?Lgol-PVEvcEL6HP)om@-1c>vZO|6VjQnGcRQ# zQlk(xE{v3}x(Eh$E+iYFJ0pdXxDr=E=&lLvMs(4vwBz~aoiCl-j=CuHBzL}hzkANP z=iPhmJs%H_3^h28p){If=E2CAex2B8q6WA=6OrF`(`KF&`Uz?MI&EW@IwS5;Jq_-2rSodh0=h5M8yR&|8~q9xUzjR(|@2weye zz8a;S7@IIXlUIKD#o1b1+rN5odUE>L=z;rh$dv40C`m=ye*;62d-p2^;2j+^>^@b* z{zK-lF(OZeV2X;(id~9-RYHGjYX7&6)!h7{=_DaLK@yv17h==zIwme4kF^2|U3rG4QL%vz2K73uCxOLI|+`aN! z$F-%z;-Tzk@6K$E*Jv}RD{ao_%it)TlnNq<^Unr!fz4Lw$ zOy&HC$f92&rz(YWnba(~S{s>9e=uV%Oyy_Fufeq||4}nCJT{T^4!f^Qd<}K~WJ1Kz zzvUl)Z^gZPP8#nNzOg~(w`aa@FjYY9u^!IW^5APGzK1@7^HK>gD4>;p^R}arI;0o1?04=jpKWw!W)=?0Yt= zynUbER^IkMss3a7y}So_=McZ`$9S>#$BvH<4@j=b`|AzHy`jYM(LpaBOVlKlW^ujb z)P%J2ye6gV=6*G&ja!<{1*x-wK{3QEd-+1(8#gnXPvxf4)sE;I_k4cF&8AA(kO_(* zbIC83rV9C8121D-KkJ<idjF0yGj>9sy zEwzyLtiMFu4~T6avc|lrbF^o@CbB+LUq6S#>RVK)S)cWo$nWI(T!)Byg4)h8>pihg zSHk{7hu^QXIU^m!MEjk0M(-crN9uFmIL=%4U1~>sm5Pe?`en6ee(>HC`S#L{y??u6 vr;^|o8ppUAvD!gdKbRPND1BpVH#|fA;?X5$6$T literal 0 HcmV?d00001 diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 7e02765954..e8a2375ba8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -317,12 +317,12 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en #define DLINFO_ARCH_ITEMS 1 #define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO, vdso_info->entry); +#endif /* TARGET_X86_64 */ + #include "vdso.c.inc" #define vdso_image_info() &vdso_image_info -#endif /* TARGET_X86_64 */ - #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 diff --git a/linux-user/x86_64/Makefile.vdso b/linux-user/x86_64/Makefile.vdso new file mode 100644 index 0000000000..6de038dcfb --- /dev/null +++ b/linux-user/x86_64/Makefile.vdso @@ -0,0 +1,5 @@ +CROSS_CC ?= x86_64-linux-gnu-gcc + +vdso.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) -nostdlib -shared -Wl,-T,vdso.ld -Wl,--build-id=sha1 \ + -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both vdso.S -o $@ diff --git a/linux-user/x86_64/meson.build b/linux-user/x86_64/meson.build index 203af9a60c..f6a0015953 100644 --- a/linux-user/x86_64/meson.build +++ b/linux-user/x86_64/meson.build @@ -3,3 +3,9 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +gen = [ + gen_vdso.process('vdso.so') +] + +linux_user_ss.add(when: 'TARGET_X86_64', if_true: gen) diff --git a/linux-user/x86_64/vdso.S b/linux-user/x86_64/vdso.S new file mode 100644 index 0000000000..47d16c00ab --- /dev/null +++ b/linux-user/x86_64/vdso.S @@ -0,0 +1,78 @@ +/* + * x86-64 linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro weakalias name +\name = __vdso_\name + .weak \name +.endm + +.macro vdso_syscall name, nr +__vdso_\name: + mov $\nr, %eax + syscall + ret +endf __vdso_\name +weakalias \name +.endm + + .cfi_startproc + +vdso_syscall clock_gettime, __NR_clock_gettime +vdso_syscall clock_getres, __NR_clock_getres +vdso_syscall gettimeofday, __NR_gettimeofday +vdso_syscall time, __NR_time + +__vdso_getcpu: + /* + * There is no syscall number for this allocated on x64. + * We can handle this several ways: + * + * (1) Invent a syscall number for use within qemu. + * It should be easy enough to pick a number that + * is well out of the way of the kernel numbers. + * + * (2) Force the emulated cpu to support the rdtscp insn, + * and initialize the TSC_AUX value the appropriate value. + * + * (3) Pretend that we're always running on cpu 0. + * + * This last is the one that's implemented here, with the + * tiny bit of extra code to support rdtscp in place. + */ + xor %ecx, %ecx /* rdtscp w/ tsc_aux = 0 */ + + /* if (cpu != NULL) *cpu = (ecx & 0xfff); */ + test %rdi, %rdi + jz 1f + mov %ecx, %eax + and $0xfff, %eax + mov %eax, (%rdi) + + /* if (node != NULL) *node = (ecx >> 12); */ +1: test %rsi, %rsi + jz 2f + shr $12, %ecx + mov %ecx, (%rsi) + +2: xor %eax, %eax + ret +endf __vdso_getcpu + +weakalias getcpu + + .cfi_endproc + +/* TODO: Add elf note for LINUX_VERSION_CODE */ diff --git a/linux-user/x86_64/vdso.ld b/linux-user/x86_64/vdso.ld new file mode 100644 index 0000000000..ca6001cc3c --- /dev/null +++ b/linux-user/x86_64/vdso.ld @@ -0,0 +1,73 @@ +/* + * Linker script for linux x86-64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6 { + global: + clock_gettime; + __vdso_clock_gettime; + gettimeofday; + __vdso_gettimeofday; + getcpu; + __vdso_getcpu; + time; + __vdso_time; + clock_getres; + __vdso_clock_getres; + + local: *; + }; +} + + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + . = SIZEOF_HEADERS; + + /* + * The following, including the FILEHDRS and PHDRS, are modified + * when we relocate the binary. We want them to be initially + * writable for the relocation; we'll force them read-only after. + */ + .note : { *(.note*) } :load :note + .dynamic : { *(.dynamic) } :load :dynamic + .dynsym : { *(.dynsym) } :load + .data : { + /* + * There ought not be any real read-write data. + * But since we manipulated the segment layout, + * we have to put these sections somewhere. + */ + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .rodata : { *(.rodata*) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr + .eh_frame : { *(.eh_frame) } :load + + .text : { *(.text*) } :load =0x90909090 +} diff --git a/linux-user/x86_64/vdso.so b/linux-user/x86_64/vdso.so new file mode 100755 index 0000000000000000000000000000000000000000..c873d6ea580b393825506d2ffbddcf9827d89e14 From patchwork Wed Aug 16 18:03:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821979 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=caI9R65H; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwyT5DpDz1yXZ for ; Thu, 17 Aug 2023 04:04:49 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKs7-0002Qe-DS; Wed, 16 Aug 2023 14:03:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs5-0002Oz-Qj for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:53 -0400 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs2-0001LT-If for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:53 -0400 Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1bbff6b2679so44768385ad.1 for ; Wed, 16 Aug 2023 11:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209029; x=1692813829; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=M478cD9e19CcONyDKO+nZ894P/ANoM0KduR/gS2DCkU=; b=caI9R65HoEX81wObwUFzgmuxDK8MftLo5Hf74fWrmn1VSsr2qk3To45/CzPE2ElKZY 46HOBRVCl53vOdGbBlcb3CUxVio2//y+RSO5mTeJ11wneKiYVTafQN4Jiua0bnP8O+lT 9R4PEq5jBhrpIAuNtz6mbc/Nk5sNu3XFFRSQV6R/OC60oU0fHvlQGsWx3LLKTGZXy8fe q6rdVCsvXIv6bswjhrjQEFdNRi8ohlRAJeVbHm7wEFw8yQuJDdWGGEP9h7pzsSUXy4t0 knW8bFeExjyE6+w9o8rUSxSVrHMvsUrTM96sA5whMRhP4J8o/icCDMcszZQF9FD6lrVi gxeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209029; x=1692813829; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M478cD9e19CcONyDKO+nZ894P/ANoM0KduR/gS2DCkU=; b=hTbrhxQ2y/PMKS1lnAxrozNRsXKcsSF+cquZI6GzNuHEMnSEJAUoiopT+TivIQXy51 IBCmSAc5fnIsedO+5yoXn8pNitJ//YW+VK6ad330FJPezrLYdKepJuVA6/zepUs82cRX L/NCld36q2ocXh6YDlJ8rCBNIQMTrg0bGpBTMW8rOB4YXSw2D87jenZsPK9C6cLS9mph 5R166Hj79brLZ8gPpnHOVpICEFdO+OGD8LF6I3rjejQLZ64p3xoBzh864YXpa7GrV8Gl YC5IqPyv9iGxg6aiWBW+kVnSc96rxUZpVbF0KdkyK9UvnUnnZVXOOu1NaKfX/YwTVLI+ zNzg== X-Gm-Message-State: AOJu0YyMrZGt2gfjoaGJLfeMddPeWcT8qaFumMffF5PePbA6A2MG4/5K V+HcyGW6EihsQiZq5nyEGZjxYoHHwEu4MlcgW58= X-Google-Smtp-Source: AGHT+IFM72BOXV/WfkzC6/GV4PXPrcrEqz5xXMc3CdDtMgVvQzhfLOMGL6GqezZfcznLi+serB9sSA== X-Received: by 2002:a17:903:2584:b0:1bd:d162:5dc6 with SMTP id jb4-20020a170903258400b001bdd1625dc6mr2072140plb.14.1692209028995; Wed, 16 Aug 2023 11:03:48 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:48 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 11/18] linux-user/aarch64: Add vdso Date: Wed, 16 Aug 2023 11:03:31 -0700 Message-Id: <20230816180338.572576-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62f; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Richard Henderson --- linux-user/elfload.c | 4 ++ linux-user/aarch64/Makefile.vdso | 12 +++++ linux-user/aarch64/meson.build | 12 +++++ linux-user/aarch64/vdso-be.so | Bin 0 -> 3216 bytes linux-user/aarch64/vdso-le.so | Bin 0 -> 3216 bytes linux-user/aarch64/vdso.S | 73 +++++++++++++++++++++++++++++++ linux-user/aarch64/vdso.ld | 72 ++++++++++++++++++++++++++++++ linux-user/meson.build | 1 + 8 files changed, 174 insertions(+) create mode 100644 linux-user/aarch64/Makefile.vdso create mode 100644 linux-user/aarch64/meson.build create mode 100755 linux-user/aarch64/vdso-be.so create mode 100755 linux-user/aarch64/vdso-le.so create mode 100644 linux-user/aarch64/vdso.S create mode 100644 linux-user/aarch64/vdso.ld diff --git a/linux-user/elfload.c b/linux-user/elfload.c index e8a2375ba8..98cb1ff053 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -588,10 +588,14 @@ static const char *get_elf_platform(void) #define ELF_CLASS ELFCLASS64 #if TARGET_BIG_ENDIAN # define ELF_PLATFORM "aarch64_be" +# include "vdso-be.c.inc" #else # define ELF_PLATFORM "aarch64" +# include "vdso-le.c.inc" #endif +#define vdso_image_info() &vdso_image_info + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { diff --git a/linux-user/aarch64/Makefile.vdso b/linux-user/aarch64/Makefile.vdso new file mode 100644 index 0000000000..53c19e1ce9 --- /dev/null +++ b/linux-user/aarch64/Makefile.vdso @@ -0,0 +1,12 @@ +CROSS_CC ?= aarch64-linux-gnu-gcc +LDFLAGS := -nostdlib -shared -Wl,-T,vdso.ld \ + -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 \ + -Wl,-z,max-page-size=4096 + +all: vdso-le.so vdso-be.so + +vdso-le.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mlittle-endian vdso.S -o $@ + +vdso-be.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mbig-endian vdso.S -o $@ diff --git a/linux-user/aarch64/meson.build b/linux-user/aarch64/meson.build new file mode 100644 index 0000000000..35e50c9b2c --- /dev/null +++ b/linux-user/aarch64/meson.build @@ -0,0 +1,12 @@ +# ??? There does not seem to be a way to do +# when: ['TARGET_AARCH64', !'TARGET_WORDS_BIGENDIAN'] +# so we'd need to add TARGET_WORDS_LITTLEENDIAN. +# In the meantime, build both files for aarch64 and aarch64_be, +# only one of which will be included. + +gen = [ + gen_vdso.process('vdso-be.so', extra_args: ['-r', '__kernel_rt_sigreturn']), + gen_vdso.process('vdso-le.so', extra_args: ['-r', '__kernel_rt_sigreturn']) +] + +linux_user_ss.add(when: 'TARGET_AARCH64', if_true: gen) diff --git a/linux-user/aarch64/vdso-be.so b/linux-user/aarch64/vdso-be.so new file mode 100755 index 0000000000000000000000000000000000000000..311f192d88149f744ee05c2492e8e8de6c5b5ec4 GIT binary patch literal 3216 zcmc&$L2nyH6rS~N;}lA9Dk>rcL6IUEgoN5dk&tN3_h#N3uPqxPao{Dh-+bS^ zH#0jkZ@h2k3rne#r=0of3)B;WY0295@hi;c)jpL~8TBCe7)oH(wY8;%# zNLzi>Gq`121T#caC_J9mApu==4D`^_-fN7P<6l=Ha$L~14uhy3;y^+2mx8LdZrcY@ zbb^uJ_Idjv~$3@CLUuRf3-)YZWF1H#X z{-08XQ!D4z^<4N&`1Es_4dtKw5%cWd1HXU$2^gK{M^NlJr8i0`FRj0Sm)ihplOEob ze;h#m?p&=(Oh7X-_`q4Rlh`D>b? zr>&pMW6|k6!}{|N{`*;(y3udLuzpCB zaX&@f*@*rRd2Zak^`AoEu=fgk{{FJ-9QVSA{C_c#=gE7dlF)B*KeX;|CUjY!4D=5Y z`Ze~?s8T6cd3k=d8aC8)SxvW<&b_j-aQf8qNIzWsI=`%!))r3Z^>S`a>63*siwgyP zW@+iA{8@c=VX=_c{Tb-;-evgcRCd1q=8jNdYj-;?z6y++7OPULH{wWz<=uL5yH+w4 z_yUV@QH7QIPFO9rs#cGiR=FHCTeU{LkLa=rqpIF$7Pli^EyGio3gf69^P>GnpmV`_ zzZJW%$Q^@v1Bds$%~hE%`bfY((WH;K6-HF?wRYK{qh=%Xq!Bk79tkf z$@I87`um?&P1YB5E%Ah|>RRqcs3`}>G!QZRK>48ZQRNR?k-xNTkm-@G)tokTJ)!bQ z>;Hec9C8N@(QVy_rUzve|3h)y$NP+r(7l$uQ@K|0bJg;*OYxsA+_uLWc__z@GnYB; zL-aI-2std6=m;)D?0%qhiu$AU7Cn)FIbG?S@OML)vwZWrMlYKcfM4wx%|JM@<(S+ z&YJ`7>+Zofcr(0v{K+b%f0uvy>siU?-8_)1@=iT0zjVX&p|0c}gi>S9VZlTv&Er)b zLb%7&hjY~1cs?~Y^g@V9eh%@N5G5uv?)i-?allsV#;&vbTSaG{we5v@Reo-u*I#;RBF1s}vFVT2| zO!mFm%*@fZxcs>Bo7}XSn#;`O%yf2+%#r-D$xPlHo0@tzcfy>=Oy+Z@y8_#F->&e- zmvUS8zw`)l>uW1P;SBS@k9ZlgYAx`{Ev;1xE0tn6VO{2hpg`_Yb=55w>g5Oz{0KSk z`SnVz+O;qxa=o%y^b0GVDVJCiD{=#`5%3v4ElFO;cLmB4c?m9g5GVXT0DF-q(ua{g z$UAUOu8{EU0(9~)TYiR=mXkNZx9KF$qm$>F#?`YZTeC@Qz(f1>vI zhCrVI$Nu5QjvtQ=9pM|QcurqTzAJa~K>SfrV%o|BcN+rwIIRi)T^!`OeSag2CD{*X Jpo>qi{}(kpCh`CP literal 0 HcmV?d00001 diff --git a/linux-user/aarch64/vdso.S b/linux-user/aarch64/vdso.S new file mode 100644 index 0000000000..e436e60fd9 --- /dev/null +++ b/linux-user/aarch64/vdso.S @@ -0,0 +1,73 @@ +/* + * aarch64 linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + +/* ??? These are in include/elf.h, which is not ready for inclusion in asm. */ +#define NT_GNU_PROPERTY_TYPE_0 5 +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) + +#define GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT \ + (GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC) + + .section .note.gnu.property + .align 3 + .long 2f - 1f + .long 6f - 3f + .long NT_GNU_PROPERTY_TYPE_0 +1: .string "GNU" +2: .align 3 +3: .long GNU_PROPERTY_AARCH64_FEATURE_1_AND + .long 5f - 4f +4: .long GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT +5: .align 3 +6: + + .text + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro vdso_syscall name, nr +\name: + bti c + mov x8, #\nr + svc #0 + ret +endf \name +.endm + + .cfi_startproc + +vdso_syscall __kernel_gettimeofday, __NR_gettimeofday +vdso_syscall __kernel_clock_gettime, __NR_clock_gettime +vdso_syscall __kernel_clock_getres, __NR_clock_getres + + .cfi_endproc + + +/* + * TODO: The kernel makes a big deal of turning off the .cfi directives, + * because they cause libgcc to crash, but that's because they're wrong. + * + * For now, elide the unwind info for __kernel_rt_sigreturn and rely on + * the libgcc fallback routine as we have always done. This requires + * that the code sequence used be exact. + */ +__kernel_rt_sigreturn: + /* No BTI C insn here -- we arrive via RET. */ + mov x8, #__NR_rt_sigreturn + svc #0 +endf __kernel_rt_sigreturn + +/* TODO: Add elf note for LINUX_VERSION_CODE */ diff --git a/linux-user/aarch64/vdso.ld b/linux-user/aarch64/vdso.ld new file mode 100644 index 0000000000..4c12f33352 --- /dev/null +++ b/linux-user/aarch64/vdso.ld @@ -0,0 +1,72 @@ +/* + * Linker script for linux aarch64 replacement vdso. + * + * Copyright 2021 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.39 { + global: + __kernel_rt_sigreturn; + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + + local: *; + }; +} + + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + /* + * We can't prelink to any address without knowing something about + * the virtual memory space of the host, since that leaks over into + * the available memory space of the guest. + */ + . = SIZEOF_HEADERS; + + /* + * The following, including the FILEHDRS and PHDRS, are modified + * when we relocate the binary. We want them to be initially + * writable for the relocation; we'll force them read-only after. + */ + .note : { *(.note*) } :load :note + .dynamic : { *(.dynamic) } :load :dynamic + .dynsym : { *(.dynsym) } :load + /* + * There ought not be any real read-write data. + * But since we manipulated the segment layout, + * we have to put these sections somewhere. + */ + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .rodata : { *(.rodata*) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr + .eh_frame : { *(.eh_frame) } :load + + .text : { *(.text*) } :load =0xd503201f +} diff --git a/linux-user/meson.build b/linux-user/meson.build index e4cb70ed2d..dd24389052 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -35,6 +35,7 @@ gen_vdso_exe = executable('gen-vdso', 'gen-vdso.c', gen_vdso = generator(gen_vdso_exe, output: '@BASENAME@.c.inc', arguments: ['-o', '@OUTPUT@', '@EXTRA_ARGS@', '@INPUT@']) +subdir('aarch64') subdir('alpha') subdir('arm') subdir('hppa') From patchwork Wed Aug 16 18:03:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=FCDcUp7V; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwyT5C3Rz1yXY for ; Thu, 17 Aug 2023 04:04:49 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKsB-0002Rt-Bi; Wed, 16 Aug 2023 14:03:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs6-0002QU-TX for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:54 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs3-0001LY-8k for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:54 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1bb84194bf3so43520505ad.3 for ; Wed, 16 Aug 2023 11:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209030; x=1692813830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=wyk/wqqae3PWGVb2dUGppyGhAFdYitmYsOT76yz/I4g=; b=FCDcUp7VdmCXdiqx4cxoY+n5SETVjkI/wfgSi8mbYbvNdHtvQw3+edtBi/heS3HHT+ xMNb3rEixgCNkVFrnBp4oS48czL8I6bz6bfLyQwNBcZssuQJwBg/c/SN9b42leN1jPhY eSJCSLffLEbSI+mLw0JQqvsIOBVo6oAc2DjKh7zPHRpQtjUqLi5k3VMWIE9T8KvbvP65 dZVmTpBXq6eF7LNLXXq7coh93R0yPseuHmC2rdw34dWxMcp01CgfsiR56oxWhnAWtcJK jvmHQimvFC6JRgh0xXSSmKWeRNtlemKUwO3zxZ1z5TAvlzXkudhz1+bbxhmghnFpQcCS A+uA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209030; x=1692813830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wyk/wqqae3PWGVb2dUGppyGhAFdYitmYsOT76yz/I4g=; b=Zkryp4IdO7LvNENITCYPMXfk+kVFwnzVdsAd5o3bMmA5KqVjyIEwPDy2lpQqJCj8kk snP9wDgUGljdTuH+dxKW0Od4tZlbcCbOrtFaQVqzB4pQ/DVVwL8VfkOzBJihXEw2Qnsa P6HPKfJwnZcwdAk+SNmnky7fgbB0Pe3Uai0dRVMjzexmevGnoQE2yGNhLGc4tYcFrp4Q UbiWKSXgl7zEaAriVo8ZVg4ZZ0+p74jbvXwBVMUbj8NUjXpVJ0O4gNjByx16m/Kt3A8A 2nXlmkw7nnUmYGK55a1NSfYR3BoxCLXV6PIsCvqXPTTVYh0CXSGmqF9Biko5k9MrXrOB St5g== X-Gm-Message-State: AOJu0YzsbNVjusNGpGMp/qZ45N9yWM74bZwqWA8fj0MYbApDFU6Lfztx Dt9zUoUcllf0lPuD8zEOvf4ru9G4NY0XtL4OkIc= X-Google-Smtp-Source: AGHT+IEsvfKTabl3DdayW1ny7eS9J0b8Rk0zdiv6q3+i33r7pgEPWSqwG+7COstqMsK108bypX0c/A== X-Received: by 2002:a17:903:32cd:b0:1b5:1467:c4e8 with SMTP id i13-20020a17090332cd00b001b51467c4e8mr2928672plr.15.1692209029812; Wed, 16 Aug 2023 11:03:49 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:49 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 12/18] linux-user/arm: Add vdso Date: Wed, 16 Aug 2023 11:03:32 -0700 Message-Id: <20230816180338.572576-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x629.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The thumb vdso will only be used for m-profile, as all of our a-profile cpus support arm mode. Signed-off-by: Richard Henderson --- linux-user/arm/signal.c | 30 +++--- linux-user/elfload.c | 24 +++++ linux-user/arm/Makefile.vdso | 17 +++ linux-user/arm/meson.build | 18 ++++ linux-user/arm/vdso-arm-be.so | Bin 0 -> 2712 bytes linux-user/arm/vdso-arm-le.so | Bin 0 -> 2712 bytes linux-user/arm/vdso-thm-be.so | Bin 0 -> 2684 bytes linux-user/arm/vdso-thm-le.so | Bin 0 -> 2684 bytes linux-user/arm/vdso.S | 193 ++++++++++++++++++++++++++++++++++ linux-user/arm/vdso.ld | 67 ++++++++++++ 10 files changed, 332 insertions(+), 17 deletions(-) create mode 100644 linux-user/arm/Makefile.vdso create mode 100755 linux-user/arm/vdso-arm-be.so create mode 100755 linux-user/arm/vdso-arm-le.so create mode 100755 linux-user/arm/vdso-thm-be.so create mode 100755 linux-user/arm/vdso-thm-le.so create mode 100644 linux-user/arm/vdso.S create mode 100644 linux-user/arm/vdso.ld diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c index cf99fd7b8a..bd160b113b 100644 --- a/linux-user/arm/signal.c +++ b/linux-user/arm/signal.c @@ -167,9 +167,8 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig, abi_ulong handler = 0; abi_ulong handler_fdpic_GOT = 0; abi_ulong retcode; - int thumb, retcode_idx; - int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info); - bool copy_retcode; + bool thumb; + bool is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info); if (is_fdpic) { /* In FDPIC mode, ka->_sa_handler points to a function @@ -184,9 +183,7 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig, } else { handler = ka->_sa_handler; } - thumb = handler & 1; - retcode_idx = thumb + (ka->sa_flags & TARGET_SA_SIGINFO ? 2 : 0); uint32_t cpsr = cpsr_read(env); @@ -202,24 +199,23 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig, cpsr &= ~CPSR_E; } + /* Our vdso default_sigreturn label is a table of entry points. */ + int idx = is_fdpic * 2 + ((ka->sa_flags & TARGET_SA_SIGINFO) != 0); + retcode = default_sigreturn + idx * 16; + + /* + * Put the sigreturn code on the stack no matter which return + * mechanism we use in order to remain ABI compliant. + */ + memcpy(frame->retcode, g2h_untagged(retcode & ~1), 16); + if (ka->sa_flags & TARGET_SA_RESTORER) { if (is_fdpic) { + /* Place the function descriptor in slot 3. */ __put_user((abi_ulong)ka->sa_restorer, &frame->retcode[3]); - retcode = (sigreturn_fdpic_tramp + - retcode_idx * RETCODE_BYTES + thumb); - copy_retcode = true; } else { retcode = ka->sa_restorer; - copy_retcode = false; } - } else { - retcode = default_sigreturn + retcode_idx * RETCODE_BYTES + thumb; - copy_retcode = true; - } - - /* Copy the code to the stack slot for ABI compatibility. */ - if (copy_retcode) { - memcpy(frame->retcode, g2h_untagged(retcode & ~1), RETCODE_BYTES); } env->regs[0] = usig; diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 98cb1ff053..8c2ca3520f 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -580,6 +580,30 @@ static const char *get_elf_platform(void) #undef END } +#if TARGET_BIG_ENDIAN +# include "vdso-arm-be.c.inc" +# include "vdso-thm-be.c.inc" +#else +# include "vdso-arm-le.c.inc" +# include "vdso-thm-le.c.inc" +#endif + +static const VdsoImageInfo *vdso_image_info(void) +{ + ARMCPU *cpu = ARM_CPU(thread_cpu); + + /* + * The only cpus we support that do *not* have arm mode are m-profile. + * It's not really possible to run Linux on these, but this config is + * useful for testing gcc. In any case, choose the vdso image that + * will work for the target cpu. + */ + return (arm_feature(&cpu->env, ARM_FEATURE_M) + ? &vdso_thm_image_info + : &vdso_arm_image_info); +} +#define vdso_image_info vdso_image_info + #else /* 64 bit ARM definitions */ #define ELF_START_MMAP 0x80000000 diff --git a/linux-user/arm/Makefile.vdso b/linux-user/arm/Makefile.vdso new file mode 100644 index 0000000000..e031a3d549 --- /dev/null +++ b/linux-user/arm/Makefile.vdso @@ -0,0 +1,17 @@ +CROSS_CC ?= arm-linux-gnueabihf-gcc +LDFLAGS := -nostdlib -shared -Wl,-T,vdso.ld \ + -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 + +all: vdso-arm-le.so vdso-arm-be.so vdso-thm-le.so vdso-thm-be.so + +vdso-arm-le.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mlittle-endian -marm vdso.S -o $@ + +vdso-arm-be.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mbig-endian -marm vdso.S -o $@ + +vdso-thm-le.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mlittle-endian -mthumb vdso.S -o $@ + +vdso-thm-be.so: vdso.S vdso.ld Makefile.vdso + $(CROSS_CC) $(LDFLAGS) -mbig-endian -mthumb vdso.S -o $@ diff --git a/linux-user/arm/meson.build b/linux-user/arm/meson.build index 5a93c925cf..66072411d6 100644 --- a/linux-user/arm/meson.build +++ b/linux-user/arm/meson.build @@ -5,3 +5,21 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +# ??? There does not seem to be a way to do +# when: ['TARGET_ARM', !'TARGET_WORDS_BIGENDIAN'] +# so we'd need to add TARGET_WORDS_LITTLEENDIAN. +# In the meantime, build both files for arm and armeb. + +gen = [ + gen_vdso.process('vdso-arm-be.so', + extra_args: ['-s', 'sigreturn_codes', '-p', 'vdso_arm']), + gen_vdso.process('vdso-arm-le.so', + extra_args: ['-s', 'sigreturn_codes', '-p', 'vdso_arm']), + gen_vdso.process('vdso-thm-be.so', + extra_args: ['-s', 'sigreturn_codes', '-p', 'vdso_thm']), + gen_vdso.process('vdso-thm-le.so', + extra_args: ['-s', 'sigreturn_codes', '-p', 'vdso_thm']), +] + +linux_user_ss.add(when: 'TARGET_ARM', if_true: gen) diff --git a/linux-user/arm/vdso-arm-be.so b/linux-user/arm/vdso-arm-be.so new file mode 100755 index 0000000000000000000000000000000000000000..b642b8e5e9322513c289a75ed431645e5f139475 GIT binary patch literal 2712 zcmbtWO-x)>6h3eMX<-;D!8UY(kr-3USSe|mXbb}brDm8m6k@H3kH^fwObRn(=Fx(w zGHNZ=V%vmnn_${S7uFE%!i~zRF|J&&FmZz^O)xQ96Et0@LTo1M76&W+vp>KW28NtI##*8B_wSgG@8*Y&L*pHdY3Ln50oVyd3YE&A@GnFE1@3`< z0CflL|0^*pe;$KGc8SzNw}Es1Mwd5%r>i*j*oS@E^k>jk(jb-J(BS@R@uI;qqo#15 zD0o+OB0LW*jN$nae*Yeyj$t4FQuDWxJ#b~9?u+lb^W8W0Jac#7B{9u2=~BT=jTcg< z&9RJa=O!}S8V_|mW-ew*+UE8wjHay_8PDaXrrS7f6yFylaWpw}(rk|&!YZ)gn;!$~ z#Ha3;uRn&JXTBHUx#~AFyq`|}0Y)E1?UT{$eG%m;yD*KnrrJwInQo@``;*C;n1AtGWU}91Hi^M_CDA!{$ugO zu>A}~s>bO6=bR@nX+0+$E=S&}e>ePI-TB)0cV5^rS93A+LGZ)CCI7tdBkyI;6;2M} z{4W8Y0DGl3yz1Ipz`p^OfJTXg{cmmf1A$0QkosvKuZ^?-T*o31abf~)OhCuLB~tEe z`zbiNc+WUDcQ0sM{k2^Fa-FsX*S1h)3%RyXl`RQdQk;I6?#Hv>XTjMfZiC;h;v4PP z?}t1K>rYgkSAP58RvyEep0qO7NDj9|q|V+*GPjFsD{SH{1st1U1;^AX_Jw`h2^w8ru%#BCcacYR+^lwK0Mc6vA8SMX@ULV?A z-^+SG-1tG*l(_Zi4fLOfLD#n;_%yh#Zx_JRRs1?Q*XQ_CsaPU*YUp&dAgz|Prp1iE zmW=fu?Uqt*teCN__RmS`qxjux$njG0X%QZtF#nQ2?1v4Q@mW!uHv z$drw(`A>rLR`-;5pLs#F0$O}-<0)wU+rs-wlmYjStK8uI-UsmBVm#)N%B5j&#__Il zJmyQg%W;jFU&NOC%{YR&z&zu4YYt>TIQl8kafk66&H9fx=A+8V4)90gx?CIM;ttgB zz8VY6h3brGYn-IhHA78E~*mK)G}5ijY)}N_$yVQ4L=dP@G;Chn29jc%sg5! zRmWOOwLdhWOPgSH;ldhXT(~i^GRB2*fr*VSFttfdjAB9?Ow{rF?t2#>l!b{0zIX0- z&bjCQynD}^*E)N;48ssDrtB5Xnqge6#3LZVX4xY_`06AkA(-gXSU{Vo@SyvHDp`Sp zU@AfO0G{hUl+Y%0|6{kD^g4nxI^ZL;pL*Gc2DAyk|9)^2INUcRH@-de_4j*kyfg5} zBh{Bie`q;#=lEO{z9FyAPnhtXzsva;#tg#N0nIf|!@dJL4^#s&;Lmb7zXbnZ&``1p z{RtcYQxfQZ5ewiLJ0&8G(9_^t2l)fgX&>hvAMnz4qLNeP28#mUS{+%v-66eCj1@+;*Jo zq`j^2VDmlZf?d=$uV;QNot%-0Y;J10k$L0ze^Ppm^bHMLP4R=AL}263z)bn~?&rVO zaIYQ$_+BaQ+6=in^^r**MembQZyss|=b0Qv;4t(A^a2&ov(V*yZeQ86JeCZuBEQc`Md{JHYP!cF7! z?9EE!%5SC8XSZpa_iXb%TiCOOeYQT>`o!&r5q~@dehQpz;yUT%Ihqxt2F+mepo9W^i}%X1XEMcg>pNt6H-zWPne`zDWN^#adim9rQNQ-xYO;wHD`|tWADo#I4sqt3e zS}ITv7{PksNtpM(?Z|A`M_3awCzrIN-^_*Rp>`le<(vXyfv{)T4^d)+av`aBNUa+01Le5I% z)2f=F=v$rLR#$(bx6|tG=ojm7&(XF-k9D-GYoK$`8cekHbXvZW;uWw>1!!wg^A)O1 zg>IXgrs|)>i!+l>aunJrxH_X-xx8abJUx?3PG(c8fmrCIla%;)ZYrKh7BjBhDY%xC zcA=Qf=Qa^5Epam#k>o`&tN_pRoABv?bY#0DDd$HS1DKor{J(cVmFPGJOvkYf5D`5o_;lQ>UL4;E?+;KzB+J!+;MEk KRUHJanfzeXTGMyNMk*LAZOhV=ojiFEqGZbbAacbg6X+LNqv`hQJz%cC; zx9R3~p;=<4$<%8%VrJsaVy}$Zh4F$5FJ|-t6Jw0=XPRBO;q$!T_u>a~V?5>Qd7ty1 z_y3$zULF`u89qZc#4it_tqnaQ;niTxC(0;KJ;ry5`Bc~cl9c?MhDu2w|^(Ne{f`6mR341J$vie&4_XN z1M7C~hhX>l^XQ8L(IBrebB!^ zT|xW*N&?&GIt_P-G(&fRThL7|-v$1hhvSX|PkA_fm9)zGuW0aowfNECn^9AEPZXS0 zy$Ih!3w`*0L@>BJpnW(dxYBk_3VY9GBA+dK_{PV;KJkhC z{Mq}k^Ud!8_^$e7hX2yspJ42xsCzQn{EwmC3xwf#7#c7pp^re%K%au1hrS5?5;We~ zco%2@R)9UQ#Q-s0%!qF(YP2;+NV(2k0Pnv^648c}zO%eb+V=uKZet&U?fN$M3D~{_ z8a(s#fOE}5ShR(UPSj$@TV9F28d+|BZO4hGlZ~euUJt(!IvqR{c+-E@caDogxc=k7 z3E*BCjDF|Z+rhs8&Hy_l77ZS|5e$W5jbZBh0}LB!2Yv#UfSBVGa(zPD2VEkyPkMg~ z-zneLuCn!(+Zw&GeAKaxJV;$nUH)Ba#8GhFrv7LPzj~qh+B>P(p!WG@3r}FpyR%ky zvWO_a-hz*Ir6m*zryIQ?&7Ez?Dq9G0_xMhpfV%@!&a$b25`iU;&pz5H&UaYaYD{I!xrC&ob?70ILL4CW@;_q3^siRY)<7o zd>nuD(Z2;F)p)es`Ot#6{wOWZ`3+}$8+wkz){D#F_=olW(B}T0(D&i`kHMzItvSzQ zytjr`z?pBlh9UMg)v))#|EXcQTxKvm(qD*|rNfqvyqL*nMiS`*{ZcJXS1fz3QZjSp zys8)|?B>9bnaU*61LjaNBj(`nXkTL398IMT4UCy%iN4_h(^EFwBDJZ=Y%N@#VzjB4 zZBw^YjgxqFan{aGLfaKb7j&yswk?V07fadMVoo*S3!SyI5}z*3#S7VL!Li#F$1-nK zs>O0?6EX7=w+iM|B|B@Gg*-epleldy*b+}<(($ZqSBjH!Hm>GB3Eo@9DPx~`L399G z+?bd9U|@VB>{PrkW@~^O;|M1wzB{2AXPA$9q;hEjoPLZ|`mttqyBzZ|zf_KS#nKIf$Nxl1q}5=b^+WU=VZZ94BT_Y})Mlt5M8Q(B`PrnBpPD8Z5u9vxC)vehr|eGB zL~7k?Y-<~vhx#H`sE99uT13H@(tQ%?gZL1&4;6jT7ZIsiOA&4SzB_Z{B<4ZzB;TC- zoqO(?JNMpm?!M5|pEe9bw1nkB(X0)|l^7l&iL}X1iJ-4hk`jf9eH!P{CTe`>@t{ho z=pYzM5IuzF%>XKB6MFoCAKctcIB9gFkI?O*C{`FTKU$&O-O`vboAM-sX{QIp{Cy94PVC#nFH_pSp1=<0&0!iS{)m5j8{=cB1 zIa(%UM9r!)e6bw_s zZ)Kd|^yxzz!Tw0ijtJWvLoSz_E(|a4$#;G6NqooKUB%P8KD}QoYc5xItn9Rteb$0O&d#?mu8IGLrGNk6=$O@NwsR7pwLb$h<=0LYuw8k)(Wp*WrMJ0 zc$^vL)eet))lS!ju(yj+UGuL~{;YAHzd9AN*H6;0syHGC{A3NI1_UK6asLZEYYlRq z9@<~v-$1UD-jAna(0?0M`#Xw=V zdit#NaB85(>gygBtG9osGu3YmrPBv{My!!kXMc|sC>wr}T32K?7Op@sT35_AsavYX ziCJElaWfOpZpqVm-6}e+EoN?^n3*YLRRg}z88;*5RB_hKXUcic?v^~uoLwpxoZ>oS z<;1k})?_I&V_W$gJT(*3wdY+iQ^Nyh#&t`DiCGs*^WTO0?OpHx+^5Zf;r`K+dtlS| z2hR&p0lX9L-3_c!y8zykJTlB9VjOMyF>M%+Ioj%T9!;JnB6zy#N3dQo%NUP&N9;yh zA8GCPC~P-24m$2*?j-L3`Ul{}8;svnQ}OK^TV9;lkrlhFEiKov%U zbJ1(c`B5eT#^$)-ZyHb~+Rp{keyjsTy`B{MwBJ$Rk9)#=Ck~;lMb&7KMF1hzx~lNw zo@>#e^*gowD*SlIv3~G(2dLUNRxG^+Xvz{M@F5$%=y;9bLBD-ikk_;mwD$WOF-L=H literal 0 HcmV?d00001 diff --git a/linux-user/arm/vdso.S b/linux-user/arm/vdso.S new file mode 100644 index 0000000000..57e405d453 --- /dev/null +++ b/linux-user/arm/vdso.S @@ -0,0 +1,193 @@ +/* + * arm linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + + .text + .eabi_attribute Tag_FP_arch, 0 + +#ifdef __thumb__ + .thumb + .arch armv7-m + .eabi_attribute Tag_ARM_ISA_use, 0 + .eabi_attribute Tag_CPU_arch, 13 /* TAG_CPU_ARCH_V7_M */ + +.macro raw_syscall n + .ifne \n < 0x100 + mov r7, #\n + .else + ldr r7, =\n + .endif + swi #0 +.endm + +.macro fdpic_thunk ofs + ldr r3, [sp, #\ofs] + ldmia r2, {r2, r3} + mov r9, r3 + bx r2 +.endm + +#else + .arm + .arch armv4t + .eabi_attribute Tag_THUMB_ISA_use, 0 + +.macro raw_syscall n + .ifne \n < 0x100 + mov r7, #\n + .else + mov r7, #(\n & 0xff) + orr r7, r7, #(\n & 0xff00) + .endif + svc #(\n | __NR_OABI_SYSCALL_BASE) +.endm + +.macro fdpic_thunk ofs + ldr r3, [sp, #\ofs] + ldmia r3, {r3, r9} + bx r3 +.endm + +#endif + +.macro endf name + .globl \name + .type \name, %function + .size \name, . - \name +.endm + +/* + * We must save/restore r7 for the EABI syscall number. + * While we're doing that, we might as well save LR to get a free return, + * and a branch that is interworking back to ARMv5. + */ + +.macro SYSCALL name, nr +\name: + .cfi_startproc + push {r7, lr} + .cfi_adjust_cfa_offset 8 + .cfi_offset r7, -8 + .cfi_offset lr, -4 + raw_syscall \nr + pop {r7, pc} + .cfi_endproc +endf \name +.endm + +SYSCALL __vdso_clock_gettime, __NR_clock_gettime +SYSCALL __vdso_clock_gettime64, __NR_clock_gettime64 +SYSCALL __vdso_clock_getres, __NR_clock_getres +SYSCALL __vdso_gettimeofday, __NR_gettimeofday + + +/* + * We, like the real kernel, use a table of sigreturn trampolines. + * Unlike the real kernel, we do not attempt to pack this into as + * few bytes as possible -- simply use 16 bytes per slot. + * + * Within each slot, use the exact same code sequence as the kernel, + * lest we trip up someone doing code inspection. + */ + +/* offsetof(struct sigframe, retcode[3]) */ +#define SIGFRAME_RC3_OFFSET 756 +#define RT_SIGFRAME_RC3_OFFSET 884 + +.macro slot n + .balign 16 + .org sigreturn_codes + 16 * \n +.endm + +/* + * Start the unwind info at least one instruction before the signal + * trampoline, because the unwinder will assume we are returning + * after a call site. + */ + .cfi_startproc simple + .cfi_signal_frame + .cfi_return_column 15 + + .cfi_def_cfa sp, 32 + 64 + .cfi_offset r0, -16 * 4 + .cfi_offset r1, -15 * 4 + .cfi_offset r2, -14 * 4 + .cfi_offset r3, -13 * 4 + .cfi_offset r4, -12 * 4 + .cfi_offset r5, -11 * 4 + .cfi_offset r6, -10 * 4 + .cfi_offset r7, -9 * 4 + .cfi_offset r8, -8 * 4 + .cfi_offset r9, -7 * 4 + .cfi_offset r10, -6 * 4 + .cfi_offset r11, -5 * 4 + .cfi_offset r12, -4 * 4 + .cfi_offset r13, -3 * 4 + .cfi_offset r14, -2 * 4 + .cfi_offset r15, -1 * 4 + + nop + + .balign 16 +sigreturn_codes: + /* [EO]ABI sigreturn */ + slot 0 + raw_syscall __NR_sigreturn + + .cfi_def_cfa_offset 160 + 64 + + /* [EO]ABI rt_sigreturn */ + slot 1 + raw_syscall __NR_rt_sigreturn + + .cfi_endproc + + .macro cfi_fdpic_pc ofs + /* + * fd = *(r13 + ofs) + * pc = *fd + * + * DW_CFA_expression lr (14), length (5), + * DW_OP_breg13, ofs, DW_OP_deref, DW_OP_deref + */ + .cfi_escape 0x10, 14, 5, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x06 + .endm + + .macro cfi_fdpic_r9 ofs + /* + * fd = *(r13 + ofs) + * r9 = *(fd + 4) + * + * DW_CFA_expression r9, length (7), + * DW_OP_breg13, ofs, DW_OP_deref, + * DW_OP_plus_uconst, 4, DW_OP_deref + */ + .cfi_escape 0x10, 9, 7, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x23, 4, 0x06 + .endm + + /* FDPIC sigreturn */ + .cfi_startproc + cfi_fdpic_pc SIGFRAME_RC3_OFFSET + cfi_fdpic_r9 SIGFRAME_RC3_OFFSET + + slot 2 + fdpic_thunk SIGFRAME_RC3_OFFSET + .cfi_endproc + + /* FDPIC rt_sigreturn */ + .cfi_startproc + cfi_fdpic_pc RT_SIGFRAME_RC3_OFFSET + cfi_fdpic_r9 RT_SIGFRAME_RC3_OFFSET + + slot 3 + fdpic_thunk RT_SIGFRAME_RC3_OFFSET + .cfi_endproc + + .balign 16 +endf sigreturn_codes diff --git a/linux-user/arm/vdso.ld b/linux-user/arm/vdso.ld new file mode 100644 index 0000000000..3b00adf27a --- /dev/null +++ b/linux-user/arm/vdso.ld @@ -0,0 +1,67 @@ +/* + * Linker script for linux arm replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6 { + global: + __vdso_clock_gettime; + __vdso_gettimeofday; + __vdso_clock_getres; + __vdso_clock_gettime64; + + local: *; + }; +} + + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + . = SIZEOF_HEADERS; + + /* + * The following, including the FILEHDRS and PHDRS, are modified + * when we relocate the binary. We want them to be initially + * writable for the relocation; we'll force them read-only after. + */ + .note : { *(.note*) } :load :note + .dynamic : { *(.dynamic) } :load :dynamic + .dynsym : { *(.dynsym) } :load + /* + * There ought not be any real read-write data. + * But since we manipulated the segment layout, + * we have to put these sections somewhere. + */ + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .rodata : { *(.rodata*) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr + .eh_frame : { *(.eh_frame) } :load + + .text : { *(.text*) } :load +} From patchwork Wed Aug 16 18:03:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1821987 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=QS6hoP6J; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQwyt5jtcz1xrk for ; Thu, 17 Aug 2023 04:05:10 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qWKsD-0002ST-FC; Wed, 16 Aug 2023 14:04:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qWKs7-0002RD-Vj for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:57 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qWKs4-0001Lo-CQ for qemu-devel@nongnu.org; Wed, 16 Aug 2023 14:03:55 -0400 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-68872ca740bso1559290b3a.2 for ; Wed, 16 Aug 2023 11:03:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1692209030; x=1692813830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=aVsqnKwMmDO/vVnxHUpbU9gJRW2DfdsfW1emGjWwUQA=; b=QS6hoP6JTC1frtmLUmMTKecuKCtYyuW2meQjHiXNFIspzOJTQdOHWVztCGlW18iBvw 0eLVH4xSW3xxHloNZuevqbKmcEU+om2p+wqZK2uVKNBvTjDlHYPSpg0CypMDGMt+nBTY 8hzbA2py063JsnYdmCK+JyQtOysyRdwDTygsiWcliwVlmXz08SpxPt2oZp2VQcBtW42E HU5T2DruRltNAn4cw7eAUmqRaUWP7wdtR7LcEwG0T95I6tmpVdGMOCKLQyruzyqJWq8B W4Y0qF9cd99A1w2R+enO6+WKxdHoQaGO5LfguKVmUOrdcORZ10A2jJtTsC7NlSXc/kWD jQ7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692209030; x=1692813830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aVsqnKwMmDO/vVnxHUpbU9gJRW2DfdsfW1emGjWwUQA=; b=iTYA+t6SqzKqp+lVrHzNz+V0UjyYUienAx4Kxa+6ri1y2ER+e8hG7YN9PN8lShlyUd GYVe6g+Vh3MOS2cqTM9goAW9qFccy5O6+cBh2MNxo3MQ/gFwYfMTLS+H/SaO+jS4vtxQ UZ/4Zrg+Qab1NoPupWObK+VKALJL+52kieTfOqMF2Fuql1ge//18n03BMVKSStkrOz10 6qG1D8qeV/tLPg8Pzweo7gIFbnCd5bfuXLXPGt/M8dYdYrPbG2NEjRmCKfdQ/OK9UK+w fejmO9ktmV5uAI9oLh7YrUhePmkRZSh4M5KQbJTxanDi/0eLjvtlYjYFwJNEk05HA0J4 IJgA== X-Gm-Message-State: AOJu0YziwDSQywCK5e5wakIFEofSz+N9XB3vdAjKygLvrfAzugMIfQ8y EnSS8bq136KTLB4UPVmhQanDLpq36d4ocEM0DpQ= X-Google-Smtp-Source: AGHT+IF4MfQGo8xQnxezaePusFhhlV/UtcgyatCLTFQRGAWrInLd46IBagR7oEPJlZGkaHJOZTDfvg== X-Received: by 2002:a17:902:ecc2:b0:1b8:1335:b775 with SMTP id a2-20020a170902ecc200b001b81335b775mr3329420plh.0.1692209030535; Wed, 16 Aug 2023 11:03:50 -0700 (PDT) Received: from stoup.. ([2602:47:d483:7301:a064:e3f9:a812:973b]) by smtp.gmail.com with ESMTPSA id g14-20020a170902868e00b001bc2831e1a9sm13446584plo.90.2023.08.16.11.03.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 11:03:50 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 13/18] linux-user/hppa: Add vdso Date: Wed, 16 Aug 2023 11:03:33 -0700 Message-Id: <20230816180338.572576-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230816180338.572576-1-richard.henderson@linaro.org> References: <20230816180338.572576-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Richard Henderson --- linux-user/hppa/vdso-asmoffset.h | 12 +++ linux-user/elfload.c | 4 + linux-user/hppa/signal.c | 24 +++-- linux-user/hppa/Makefile.vdso | 6 ++ linux-user/hppa/meson.build | 6 ++ linux-user/hppa/vdso.S | 165 +++++++++++++++++++++++++++++++ linux-user/hppa/vdso.ld | 77 +++++++++++++++ linux-user/hppa/vdso.so | Bin 0 -> 2104 bytes 8 files changed, 284 insertions(+), 10 deletions(-) create mode 100644 linux-user/hppa/vdso-asmoffset.h create mode 100644 linux-user/hppa/Makefile.vdso create mode 100644 linux-user/hppa/vdso.S create mode 100644 linux-user/hppa/vdso.ld create mode 100755 linux-user/hppa/vdso.so GIT binary patch literal 2104 zcmbtVTXR!Y6kaFkhEgcBP%l`hafWdil!Lv1RY03GNz;<1rD7>6(0JUG~~*U)EYXMdFQ(BmGb?r%x-$mIFC+3xTU<+0?(1N%-~JGte| zwo#0&1h`Mkv8G3g7ybaBfv&)R1jiYzaqu#r23QVo^SCSe7yscgz|X_x1OE;7zacM{ z)|dd5Qv4kHJ82ot+=CYbD;A=;?E| z+O@bm6U{_s6$j@&=K!(p?Mg~X zNxxOSx@O|YQQtBD{UyiM14~XUeXw+5*+XR~mp{DXk@8b3A6<32;<3udS3j}l$*QL= zd;0Qcu9&>?*|pDI^?daU>t0;{Qq9X(zY>_*^y+o5UH|&#H|#gJymiCdwbOO))W6&C z-q!cGeQ@K4jUV0g@y(xX|8&P^J3qhW%&lKEeHlC(`l|Ws@Hdf}=(jE3#lCMHW; zONHX9xm|@5D$=2%ovLNGigl^hq-yI{yLwc7k81B#i9XfQuR8at-M6W(+g0)o)qSVx zanzoDsyC(j22_8Vr_*Qt6`W`0eJzTL#S4K_@ijH9MKe`ddw-H+LR}U|=Qy2(>V?rY z1fBH)(sj*o{IovBFBJ9<$eQLCI%^7~`+_?Ao;v%3I{KO9);;u6S9h0zzRc5gxj|&Sy_i8rNTu72w>n-mm4>KjyI4HF5rW`17r(z$)~w!;~p-Ow|1nqfFBMc>aU8q_P9)|;yMpZzCl>C4=|Coz%^Y;{L;DN4)bKq{t{_fJydxBhI~~zzGScmI z2Sf3Qv!HS8{Ndq3>MpVKg`CR=jg%cJWW-J%&ZdTk?$!c)!Bd5l*!#1i_FyVM=-LZ8 z*K#P6%MXoY7bs3z?98AufIVfL!8AOLCUzk+R&dYvKfl%RW1g54)&;QvFy!T2u7QF1 zMOrSt&AewX$GSF{-%SAXhIp(aT}uJz^keQAkM9EVqIJY$eh5<^kS@K|J0P>p7;oBz z?knzt#CSv_-q=6E={Ms-0?_~K7xHZML!Ihc<@;@jdnC0XUJ;yrc(-*8a~%^8c8*D} zdE;G`CSg6AJLMeG0KnLAF#k;p-Us8y>={4wf$jxe@351M-+hqjhn)DwT}TsjLrtFG t#WH69ET#p-{eR>C0pl?r>_u}nn&