Movatterモバイル変換


[0]ホーム

URL:


This is the mail archive of thelibc-alpha@sourceware.orgmailing list for theglibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav:[Date Prev] [Date Next][Thread Prev] [Thread Next]
Other format:[Raw text]

[PATCH] i386: Add _startup_sbrk and _startup_fatal [BZ #21913]


On Linux/x86, there are 3 ways to make a system call:1. call *%gs:SYSINFO_OFFSET.  This requires TLS initialization.2. call *_dl_sysinfo.  This requires relocation of _dl_sysinfo.3. int $0x80.  This works everywhere.When an object file is compiled with PIC, #1 is prefered since it isfaster than #3 and doesn't require relocation of _dl_sysinfo.  Fordynamic executables, ld.so initializes TLS.  However, for staticexecutables, before TLS is initialized by __libc_setup_tls, #3 shouldbe used for syscalls.  This patch adds _startup_sbrk and _startup_fatalto be used in static executables before __libc_setup_tls is called.  Bydefault, they are defined to __sbrk and __libc_fatal, respectively.  Onx86, a special _startup_sbrk is provided and _startup_fatal is turnedinto ABORT_INSTRUCTION.Any comments?H.J.---[BZ #21913]* csu/libc-tls.c: Include <startup.h>.(__libc_setup_tls): Call _startup_sbrk instead of __sbrk.  Call_startup_fatal instead of __libc_fatal.* elf/dl-tunables.c: Include <startup.h>.(tunables_strdup): Call _startup_sbrk instead of __sbrk.* sysdeps/generic/startup.h: New file.* sysdeps/unix/sysv/linux/i386/startup.h: Likewise.* sysdeps/unix/sysv/linux/i386/startup_sbrk.c: Likewise.* sysdeps/unix/sysv/linux/i386/Makefile (sysdep_routine): Addstartup_sbrk if default to PIC.(static-only-routines): Likewise.--- csu/libc-tls.c                              | 13 +++--- elf/dl-tunables.c                           |  8 +++- sysdeps/generic/startup.h                   | 30 +++++++++++++ sysdeps/unix/sysv/linux/i386/Makefile       |  4 ++ sysdeps/unix/sysv/linux/i386/startup.h      | 38 ++++++++++++++++ sysdeps/unix/sysv/linux/i386/startup_sbrk.c | 67 +++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 sysdeps/generic/startup.h create mode 100644 sysdeps/unix/sysv/linux/i386/startup.h create mode 100644 sysdeps/unix/sysv/linux/i386/startup_sbrk.cdiff --git a/csu/libc-tls.c b/csu/libc-tls.cindex 3c897bf28b..6f0e698220 100644--- a/csu/libc-tls.c+++ b/csu/libc-tls.c@@ -16,11 +16,12 @@    License along with the GNU C Library; if not, see    <http://www.gnu.org/licenses/>.  */ +#include <unistd.h>+#include <stdio.h>+#include <startup.h> #include <errno.h> #include <ldsodefs.h> #include <tls.h>-#include <unistd.h>-#include <stdio.h> #include <sys/param.h>  @@ -142,11 +143,11 @@ __libc_setup_tls (void)      _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign      and dl_tls_static_align.  */   tcb_offset = roundup (memsz + GL(dl_tls_static_size), max_align);-  tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align);+  tlsblock = _startup_sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align); #elif TLS_DTV_AT_TP   tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1);-  tlsblock = __sbrk (tcb_offset + memsz + max_align-     + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));+  tlsblock = _startup_sbrk (tcb_offset + memsz + max_align+    + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));   tlsblock += TLS_PRE_TCB_SIZE; #else   /* In case a model with a different layout for the TCB and DTV@@ -193,7 +194,7 @@ __libc_setup_tls (void) # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" #endif   if (__builtin_expect (lossage != NULL, 0))-    __libc_fatal (lossage);+    _startup_fatal (lossage);    /* Update the executable's link map with enough information to make      the TLS routines happy.  */diff --git a/elf/dl-tunables.c b/elf/dl-tunables.cindex 231fb8ca93..23c89b2c03 100644--- a/elf/dl-tunables.c+++ b/elf/dl-tunables.c@@ -18,9 +18,11 @@    License along with the GNU C Library; if not, see    <http://www.gnu.org/licenses/>.  */ +#include <unistd.h>+#include <stdio.h>+#include <startup.h> #include <stdint.h> #include <stdbool.h>-#include <unistd.h> #include <stdlib.h> #include <sysdep.h> #include <fcntl.h>@@ -42,7 +44,9 @@ tunables_strdup (const char *in)   size_t i = 0;    while (in[i++] != '\0');-  char *out = __sbrk (i);++  /* Can't use __sbrk before __libc_setup_tls is called.  */+  char *out = _startup_sbrk (i);    /* FIXME: In reality if the allocation fails, __sbrk will crash attempting to      set the thread-local errno since the TCB has not yet been set up.  Thisdiff --git a/sysdeps/generic/startup.h b/sysdeps/generic/startup.hnew file mode 100644index 0000000000..aa63b31181--- /dev/null+++ b/sysdeps/generic/startup.h@@ -0,0 +1,30 @@+/* Generic definitions of functions used by static libc main startup.+   Copyright (C) 2017 Free Software Foundation, Inc.+   This file is part of the GNU C Library.++   The GNU C Library is free software; you can redistribute it and/or+   modify it under the terms of the GNU Lesser General Public+   License as published by the Free Software Foundation; either+   version 2.1 of the License, or (at your option) any later version.++   The GNU C Library is distributed in the hope that it will be useful,+   but WITHOUT ANY WARRANTY; without even the implied warranty of+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+   Lesser General Public License for more details.++   You should have received a copy of the GNU Lesser General Public+   License along with the GNU C Library; if not, see+   <http://www.gnu.org/licenses/>.  */++static inline void *+_startup_sbrk (intptr_t __delta)+{+  return __sbrk (__delta);+}++__attribute__ ((__noreturn__))+static inline void+_startup_fatal (const char *__message)+{+  __libc_fatal (__message);+}diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefileindex 4080b8c966..cefa1511f6 100644--- a/sysdeps/unix/sysv/linux/i386/Makefile+++ b/sysdeps/unix/sysv/linux/i386/Makefile@@ -31,6 +31,10 @@ sysdep_routines += divdi3 shared-only-routines += divdi3 CPPFLAGS-divdi3.c = -Din_divdi3_c endif+ifneq (,$(pic-default))+sysdep_routines += startup_sbrk+static-only-routines += startup_sbrk+endif endif  ifeq ($(subdir),nptl)diff --git a/sysdeps/unix/sysv/linux/i386/startup.h b/sysdeps/unix/sysv/linux/i386/startup.hnew file mode 100644index 0000000000..ccfba45153--- /dev/null+++ b/sysdeps/unix/sysv/linux/i386/startup.h@@ -0,0 +1,38 @@+/* Linux/i386 definitions of functions used by static libc main startup.+   Copyright (C) 2017 Free Software Foundation, Inc.+   This file is part of the GNU C Library.++   The GNU C Library is free software; you can redistribute it and/or+   modify it under the terms of the GNU Lesser General Public+   License as published by the Free Software Foundation; either+   version 2.1 of the License, or (at your option) any later version.++   The GNU C Library is distributed in the hope that it will be useful,+   but WITHOUT ANY WARRANTY; without even the implied warranty of+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+   Lesser General Public License for more details.++   You should have received a copy of the GNU Lesser General Public+   License along with the GNU C Library; if not, see+   <http://www.gnu.org/licenses/>.  */++#if defined PIC && !defined SHARED+# include <abort-instr.h>++/* Can't use "call *%gs:SYSINFO_OFFSET" during statup in static PIE.  */+# define I386_USE_SYSENTER 0++extern void * _startup_sbrk (intptr_t) attribute_hidden;++__attribute__ ((__noreturn__))+static inline void+_startup_fatal (const char *__message __attribute__ ((unused)))+{+  /* This is only called very early during startup in static PIE.+     FIXME: How can it be improved?  */+  ABORT_INSTRUCTION;+  __builtin_unreachable ();+}+#else+# include_next <startup.h>+#endifdiff --git a/sysdeps/unix/sysv/linux/i386/startup_sbrk.c b/sysdeps/unix/sysv/linux/i386/startup_sbrk.cnew file mode 100644index 0000000000..8239938ddf--- /dev/null+++ b/sysdeps/unix/sysv/linux/i386/startup_sbrk.c@@ -0,0 +1,67 @@+/* Linux/i386 definitions of _startup_sbrk.+   Copyright (C) 2017 Free Software Foundation, Inc.+   This file is part of the GNU C Library.++   The GNU C Library is free software; you can redistribute it and/or+   modify it under the terms of the GNU Lesser General Public+   License as published by the Free Software Foundation; either+   version 2.1 of the License, or (at your option) any later version.++   The GNU C Library is distributed in the hope that it will be useful,+   but WITHOUT ANY WARRANTY; without even the implied warranty of+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+   Lesser General Public License for more details.++   You should have received a copy of the GNU Lesser General Public+   License along with the GNU C Library; if not, see+   <http://www.gnu.org/licenses/>.  */++#include <unistd.h>+#include <startup.h>+#include <errno.h>+#include <sysdep.h>++/* Defined in brk.c.  */+extern void *__curbrk attribute_hidden;++static int+startup_brk (void *addr)+{+  INTERNAL_SYSCALL_DECL (err);+  void *newbrk = (void *) INTERNAL_SYSCALL_CALL (brk, err, addr);+  __curbrk = newbrk;+  if (newbrk < addr)+    _startup_fatal (NULL);+  return 0;+}++/* Extend the process's data space by INCREMENT.  If INCREMENT is negative,+   shrink data space by - INCREMENT.  Return start of new space allocated,+   or call _startup_fatal for errors.  */++void *+_startup_sbrk (intptr_t increment)+{+  void *oldbrk;++  /* Update __curbrk from the kernel's brk value.  That way two separate+     instances of __brk and __sbrk can share the heap, returning+     interleaved pieces of it.  */+  if (__curbrk == NULL)+    if (startup_brk (0) < 0)/* Initialize the break.  */+      _startup_fatal (NULL);++  if (increment == 0)+    return __curbrk;++  oldbrk = __curbrk;+  if (increment > 0+      ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk)+      : ((uintptr_t) oldbrk < (uintptr_t) -increment))+    _startup_fatal (NULL);++  if (startup_brk (oldbrk + increment) < 0)+    _startup_fatal (NULL);++  return oldbrk;+}-- 2.13.3

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav:[Date Prev] [Date Next][Thread Prev] [Thread Next]

[8]ページ先頭

©2009-2026 Movatter.jp