From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id APdhJGoKq1+VGAAAWB0awg (envelope-from ) for ; Tue, 10 Nov 2020 16:47:22 -0500 Received: by simark.ca (Postfix, from userid 112) id 936DF1F08B; Tue, 10 Nov 2020 16:47:22 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A70B11E58E for ; Tue, 10 Nov 2020 16:47:21 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 467C83987447; Tue, 10 Nov 2020 21:47:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 467C83987447 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1605044841; bh=UG5mfXdfyz4cS13Uv2sUV7ycAB4MykE9/TDcu4vikNI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=uB61lmhHUo2UXudsyQ/ZOHsk8nH9R2YuZe8vjuwa3ZTy7TE2AwiHiMqxu69vxAVjI QNHvsFZq9o+8WjQkb7Hm+WEi1l+bFlm/HAX3b/jjn+HHORk+A9Swbq3NuKuVOE/77x 4gRlUqzgMpmQJUgh2Y29X9xUzIneBJzTVh842Ty4= Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 43E833987428 for ; Tue, 10 Nov 2020 21:47:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 43E833987428 X-ASG-Debug-ID: 1605044838-0c856e6cd5714d0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id 1oWmkCpjTSe3rS4w (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 10 Nov 2020 16:47:18 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-181-218.qc.cable.ebox.net [192.222.181.218]) by smtp.ebox.ca (Postfix) with ESMTP id 4DB6B441B21; Tue, 10 Nov 2020 16:47:18 -0500 (EST) X-Barracuda-RBL-IP: 192.222.181.218 X-Barracuda-Effective-Source-IP: 192-222-181-218.qc.cable.ebox.net[192.222.181.218] X-Barracuda-Apparent-Source-IP: 192.222.181.218 To: gdb-patches@sourceware.org Subject: [PATCH 12/12] gdb: use two displaced step buffers on amd64/Linux Date: Tue, 10 Nov 2020 16:46:14 -0500 X-ASG-Orig-Subj: [PATCH 12/12] gdb: use two displaced step buffers on amd64/Linux Message-Id: <20201110214614.2842615-13-simon.marchi@efficios.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201110214614.2842615-1-simon.marchi@efficios.com> References: <20201110214614.2842615-1-simon.marchi@efficios.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1605044838 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 4536 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.85785 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Simon Marchi via Gdb-patches Reply-To: Simon Marchi Cc: Simon Marchi Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" As observed on a binary compiled on AMD64 Ubuntu 20.04, against glibc 2.31 (I think it's the libc that provides this startup code, right?), there are enough bytes at the executable's entry point to hold more than one displaced step buffer. gdbarch_max_insn_length is 16, and the code at _start looks like: 0000000000001040 <_start>: 1040: f3 0f 1e fa endbr64 1044: 31 ed xor %ebp,%ebp 1046: 49 89 d1 mov %rdx,%r9 1049: 5e pop %rsi 104a: 48 89 e2 mov %rsp,%rdx 104d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 1051: 50 push %rax 1052: 54 push %rsp 1053: 4c 8d 05 56 01 00 00 lea 0x156(%rip),%r8 # 11b0 <__libc_csu_fini> 105a: 48 8d 0d df 00 00 00 lea 0xdf(%rip),%rcx # 1140 <__libc_csu_init> 1061: 48 8d 3d c1 00 00 00 lea 0xc1(%rip),%rdi # 1129
1068: ff 15 72 2f 00 00 callq *0x2f72(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5> 106e: f4 hlt 106f: 90 nop The two buffers would occupy [0x1040, 0x1060). I checked on Alpine, which uses the musl C library, the startup code looks like: 0000000000001048 <_start>: 1048: 48 31 ed xor %rbp,%rbp 104b: 48 89 e7 mov %rsp,%rdi 104e: 48 8d 35 e3 2d 00 00 lea 0x2de3(%rip),%rsi # 3e38 <_DYNAMIC> 1055: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 1059: e8 00 00 00 00 callq 105e <_start_c> 000000000000105e <_start_c>: 105e: 48 8b 37 mov (%rdi),%rsi 1061: 48 8d 57 08 lea 0x8(%rdi),%rdx 1065: 45 31 c9 xor %r9d,%r9d 1068: 4c 8d 05 47 01 00 00 lea 0x147(%rip),%r8 # 11b6 <_fini> 106f: 48 8d 0d 8a ff ff ff lea -0x76(%rip),%rcx # 1000 <_init> 1076: 48 8d 3d 0c 01 00 00 lea 0x10c(%rip),%rdi # 1189
107d: e9 9e ff ff ff jmpq 1020 <__libc_start_main@plt> Even though there's a _start_c symbol, it all appears to be code that runs once at the very beginning of the program, so it looks fine if the two buffers occupy [0x1048, 0x1068). One important thing I discovered while doing this is that when debugging a dynamically-linked executable, breakpoints in the shared library loader are hit before executing the _start code, and these breakpoints may be displaced-stepped. So it's very important that the buffer bytes are restored properly after doing the displaced steps, otherwise the _start code will be corrupted once we try to execute it. Another thing that made me think about is that library constructors (as in `__attribute__((constructor))`) run before _start. And they are free to spawn threads. What if one of these threads executes a displaced step, therefore changing the bytes at _start, while the main thread executes _start? That doesn't sound good and I don't know how we could prevent it. But this is a problem that predates the current patch. Even when stress-testing the implementation, by making many threads do displaced steps over and over, I didn't see a significant performance (I confirmed that the two buffers were used by checking the "set debug displaced" logs though). However, this patch mostly helps make the feature testable by anybody with an AMD64/Linux machine, so I think it's useful. gdb/ChangeLog: * amd64-linux-tdep.c (amd64_linux_init_abi): Pass 2 as the number of displaced step buffers. Change-Id: Ia0c96ea0fcda893f4726df6fdac7be5214620112 --- gdb/amd64-linux-tdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 60707ed7aaf..4f2d83f0286 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1880,7 +1880,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) if (!valid_p) return; - amd64_linux_init_abi_common (info, gdbarch, 1); + amd64_linux_init_abi_common (info, gdbarch, 2); /* Initialize the amd64_linux_record_tdep. */ /* These values are the size of the type that will be used in a system -- 2.28.0