From: Sergey Bugaev <bugaevc@gmail.com>
To: libc-alpha@sourceware.org
Cc: bug-hurd@gnu.org, Samuel Thibault <samuel.thibault@gnu.org>
Subject: [RFC PATCH v3 5/6] hurd: Make it possible to call memcpy very early
Date: Sat, 29 Apr 2023 23:18:21 +0300 [thread overview]
Message-ID: <20230429201822.2605207-6-bugaevc@gmail.com> (raw)
In-Reply-To: <20230429201822.2605207-1-bugaevc@gmail.com>
Normally, in static builds, the first code that runs is _start, in e.g.
sysdeps/x86_64/start.S, which quickly calls __libc_start_main, passing
it the argv etc. Among the first things __libc_start_main does is
initializing the tunables (based on env), then CPU features, and then
calls _dl_relocate_static_pie (). Specifically, this runs ifunc
resolvers to pick, based on the CPU features discovered earlier, the
most suitable implementation of "string" functions such as memcpy.
Before that point, calling memcpy (or other ifunc-resolved functions)
will not work.
In the Hurd port, things are more complex. In order to get argv/env for
our process, glibc normally needs to do an RPC to the exec server,
unless our args/env are already located on the stack (which is what
happens to bootstrap processes spawned by GNU Mach). Fetching our
argv/env from the exec server has to be done before the call to
__libc_start_main, since we need to know what our argv/env are to pass
them to __libc_start_main.
On the other hand, the implementation of the RPC (and other initial
setup needed on the Hurd before __libc_start_main can be run) is not
very trivial. In particular, it may (and on x86_64, will) use memcpy.
But as described above, calling memcpy before __libc_start_main can not
work, since the GOT entry for it is not yet initialized at that point.
Work around this by pre-filling the GOT entry with the baseline version
of memcpy, __memcpy_sse2_unaligned. This makes it possible for early
calls to memcpy to just work. The initial value of the GOT entry is
unused on x86_64, and changing it won't interfere with the relocation
being performed later: once _dl_relocate_static_pie () is called, the
baseline version will get replaced with the most suitable one, and that
is what subsequent calls of memcpy are going to call.
Checked on x86_64-gnu.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
---
Changes since v1:
- drop the stpncpy, since it's apparently not required during early
startup;
- as a result of the above, there are no longer any changes to the
i386 version;
- drop the PIC/non-PIC split, we can always use %rip-relative addressing
on x86_64;
- as mentioned somewhere in the v1 thread, I have, since posting the v1,
actually gone and checked that the relocations do work and the proper,
more effecient memcpy version does get installed into the GOT slot and
invoked whenever anything calls memcpy;
- convinced myself that this is not a terrible hack but rather an OK
solution;
- worked out how this would be done on an architecture that (like i386,
unlike x86_64) does need the original value in the GOT to perform the
relocation, but (unlike i386, like x86_64) still uses an ifunc-selected
memcpy in static builds: namely, we'd simply put the original ifunc
address back into the GOT slot a few lines below, after the call to
_hurd_stack_setup.
sysdeps/mach/hurd/x86_64/static-start.S | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sysdeps/mach/hurd/x86_64/static-start.S b/sysdeps/mach/hurd/x86_64/static-start.S
index 982d3d52..cc8e2410 100644
--- a/sysdeps/mach/hurd/x86_64/static-start.S
+++ b/sysdeps/mach/hurd/x86_64/static-start.S
@@ -19,6 +19,9 @@
.text
.globl _start
_start:
+
+ leaq __memcpy_sse2_unaligned(%rip), %rax
+ movq %rax, memcpy@GOTPCREL(%rip)
call _hurd_stack_setup
xorq %rdx, %rdx
jmp _start1
--
2.40.1
next prev parent reply other threads:[~2023-04-29 20:18 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-29 20:18 [PATCH v3 0/6] The remaining x86_64-gnu patches Sergey Bugaev
2023-04-29 20:18 ` [PATCH v3 1/6] hurd: Implement sigreturn for x86_64 Sergey Bugaev
2023-04-30 23:06 ` Samuel Thibault
2023-04-29 20:18 ` [PATCH v3 2/6] hurd: Implement longjmp " Sergey Bugaev
2023-04-30 23:16 ` Samuel Thibault
2023-04-29 20:18 ` [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption Sergey Bugaev
2023-05-01 1:20 ` Samuel Thibault
2023-04-29 20:18 ` [PATCH v3 4/6] hurd: Add expected abilist files for x86_64 Sergey Bugaev
2023-04-30 23:18 ` Samuel Thibault
2023-05-01 10:20 ` Samuel Thibault
2023-05-01 17:33 ` Sergey Bugaev
2023-05-01 17:43 ` Samuel Thibault
2023-04-29 20:18 ` Sergey Bugaev [this message]
2023-04-30 23:21 ` [RFC PATCH v3 5/6] hurd: Make it possible to call memcpy very early Samuel Thibault
2023-04-29 20:18 ` [DO NOT PUSH PATCH v3 6/6] TMP hurd: Lower BRK_START Sergey Bugaev
2023-05-02 14:03 ` [PATCH v3 0/6] The remaining x86_64-gnu patches Joseph Myers
2023-05-02 14:16 ` Sergey Bugaev
2023-05-02 18:27 ` Joseph Myers
2023-05-02 15:17 ` Samuel Thibault
2023-05-02 18:24 ` Joseph Myers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230429201822.2605207-6-bugaevc@gmail.com \
--to=bugaevc@gmail.com \
--cc=bug-hurd@gnu.org \
--cc=libc-alpha@sourceware.org \
--cc=samuel.thibault@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).