delorie.com/archives/browse.cgi | search |
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-bounces using -f |
DKIM-Filter: | OpenDKIM Filter v2.11.0 delorie.com 48SGKAVq1465789 |
Authentication-Results: | delorie.com; |
dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=f2kqZu3z | |
X-Recipient: | djgpp AT delorie DOT com |
X-Original-DKIM-Signature: | v=1; a=rsa-sha256; c=relaxed/relaxed; |
d=gmail.com; s=20230601; t=1727540408; x=1728145208; darn=delorie.com; | |
h=content-transfer-encoding:in-reply-to:references:to:from | |
:content-language:subject:user-agent:mime-version:date:message-id | |
:from:to:cc:subject:date:message-id:reply-to; | |
bh=0aK+UfEVRVEZN8ZkEUC7aXzO+ftcwlhD6pPuCUGGnBk=; | |
b=f2kqZu3zdvy0fl2Kh75QohbS9gbsq0YyJeOQj3fHdDvRdW+F0d2c9pF0b5BhczQQ6V | |
uegR7wk/RYgpbJeC1vvrRHExuooY6izvhSXVCNh8BGx59xZvBaW70TmoJzaJWvdAReb6 | |
pNKwMZm88Fj00YmTNGp9yEk1QRrsZy6Vq0oXc0dUoO5apjYQNt2quA7Zj157tyMLwJTc | |
7Z85VzGM5R+OdAkPH+dLpK+GIhhYPtqI+gtDQzUXo2ScmCI61b8X+B/GhVqxdRU+QwL9 | |
JslniyQgyz8THB/sgry3OD02AG5/9wplipjBapPZ65VcBJwKobj8nY6VooIFubc5M7DK | |
58eg== | |
X-Google-DKIM-Signature: | v=1; a=rsa-sha256; c=relaxed/relaxed; |
d=1e100.net; s=20230601; t=1727540408; x=1728145208; | |
h=content-transfer-encoding:in-reply-to:references:to:from | |
:content-language:subject:user-agent:mime-version:date:message-id | |
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; | |
bh=0aK+UfEVRVEZN8ZkEUC7aXzO+ftcwlhD6pPuCUGGnBk=; | |
b=E1d5ePsynXhXC0YZmMGCagqB0YOXOeISBlv+bAod6ITR6OdtMXtHgxz2nnhIgSCzcI | |
mVoQi4FCVNSM0xyPHoY5eVq4VYJwxrUSJGCYbtBFM0HVb0wLuMV71zbd+YTxY1bi4GG+ | |
Z1ejf7HoUoTGk9fN3DEtYQcU7ZrK5YuA2GVMvOKwKuVMOqCeldIjvBwfFhT+HJZPXKNL | |
lahG0CqhpXltdtQJzgZazp2xO6bRayi7S/QlznkwqgoZaCUsYKuZ+vWZXlxnxXj8T5x6 | |
vXHtZT4kGJmse/jZRv1LvFzRyT3JmxfIaaA5CF5vjsJRilX1AJeYpBOFic2jGLqxP+FV | |
FNNw== | |
X-Gm-Message-State: | AOJu0YyjEReQuxdEA2C4ZqLNOyku2oSUTqvyToQPNCTTeHkPsNnPX6t5 |
v8nrt72hbmcnBa4xNv4qunNAdXYX4eMDI+rA7T3kHlAXNQrMhE+7AYDWWg== | |
X-Google-Smtp-Source: | AGHT+IHkclKTd3lg5HhZ8ZdhRQ+qXyFtXEin3Huq3rh0Q6UVITrioQbTJ9peG/ty0g5NAwF+ojhsVQ== |
X-Received: | by 2002:a05:6402:27ca:b0:5be:ee30:9948 with SMTP id 4fb4d7f45d1cf-5c8824f413emr4708242a12.8.1727540406787; |
Sat, 28 Sep 2024 09:20:06 -0700 (PDT) | |
Message-ID: | <97181383-17e9-464b-956d-0cd36549545a@gmail.com> |
Date: | Sat, 28 Sep 2024 18:20:05 +0200 |
MIME-Version: | 1.0 |
User-Agent: | Mozilla Thunderbird |
Subject: | Re: mcount clobbers argument pointer |
From: | "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" <djgpp AT delorie DOT com> |
To: | djgpp AT delorie DOT com |
References: | <fcc830d6-84e5-4c9b-9189-6a270234d213 AT gmail DOT com> |
In-Reply-To: | <fcc830d6-84e5-4c9b-9189-6a270234d213@gmail.com> |
Reply-To: | djgpp AT delorie DOT com |
On 2024-09-27 20:30, J.W. Jagersma wrote: > User "pif17" on Github discovered the following problem. Given a simple > test case: > > #include <stdio.h> > int main (int, char **argv) > { > puts (argv[0]); > } > > When compiled with '-pg', the above code segfaults. This happens > because gcc aligns the stack on entering 'main', *before* emitting the > call to 'mcount': > > 00001760 <_main>: > 1760: 8d 4c 24 04 lea ecx,[esp+0x4] > 1764: 83 e4 f0 and esp,0xfffffff0 > 1767: ff 71 fc push DWORD PTR [ecx-0x4] > 176a: 55 push ebp > 176b: 89 e5 mov ebp,esp > 176d: 51 push ecx > 176e: 83 ec 04 sub esp,0x4 > 1771: ba e0 16 01 00 mov edx,0x116e0 > 1776: e8 c5 3b 00 00 call 5340 <_mcount> > 177b: 89 c8 mov eax,ecx > 177d: 8b 40 04 mov eax,DWORD PTR [eax+0x4] > 1780: 8b 00 mov eax,DWORD PTR [eax] > 1782: 83 ec 0c sub esp,0xc > 1785: 50 push eax > 1786: e8 25 29 00 00 call 40b0 <_puts> > 178b: 83 c4 10 add esp,0x10 > 178e: b8 00 00 00 00 mov eax,0x0 > 1793: 8b 4d fc mov ecx,DWORD PTR [ebp-0x4] > 1796: c9 leave > 1797: 8d 61 fc lea esp,[ecx-0x4] > 179a: c3 ret > > Here the argument pointer is saved in ECX, which is then clobbered by > mcount. > > GCC has performed this automatic stack alignment since version 4.1, and > it apparently hasn't caused problems for other targets. So this leads > me to conclude that djgpp's mcount is at fault, and it should have saved > all registers. > > I can think of three possible solutions (in increasing order of > difficulty): > > * Mark 'mcount' with attribute 'no_caller_saved_registers'. This should > do the right thing. But note, this attribute was only introduced in > gcc 7. > * Rename 'mcount' -> 'mcount_internal', then write an asm wrapper around > it that saves all registers. > * Convince the gcc people that their compiler emits code in the wrong > order :) > > The second option is probably best, since it also makes retrieving EDX > less fragile. Also, mcount peeks on the stack by manipulating the address of a non-existent parameter, and gcc generates broken code for this (at -O1 and above). So this will need fixing anyway. There is either __builtin_return_address(), or this could be done from the proposed wrapper routine. $ cat test.c unsigned test (int _to) { return *((&_to)-1) - 12; } $ i386-pc-msdosdjgpp-gcc -S -masm=intel test.c -O0 -o - .file "test.c" .intel_syntax noprefix .section .text .globl _test _test: push ebp mov ebp, esp lea eax, [ebp+4] mov eax, DWORD PTR [eax] sub eax, 12 pop ebp ret .ident "GCC: (GNU) 14.2.0" $ i386-pc-msdosdjgpp-gcc -S -masm=intel test.c -O1 -o - .file "test.c" .intel_syntax noprefix .section .text .globl _test _test: push ebp mov ebp, esp sub esp, 4 mov eax, DWORD PTR [ebp-8] sub eax, 12 leave ret .ident "GCC: (GNU) 14.2.0"
webmaster | delorie software privacy |
Copyright © 2019 by DJ Delorie | Updated Jul 2019 |