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 Content-Language: en-US From: "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" To: djgpp AT delorie DOT com References: In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 > 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"