[RFC,2/5] ELF: Add machine-dependent main link map setup hook
Commit Message
Add a hook allowing machine-dependent code to initialize its parts of
the main link map at run time, in a way which can fail, presumably due
to an incompatibility between the binary loaded and hardware which can
only be detected at run time in a machine-dependent way, and only in our
startup such as in the case of a binary loaded through an explicit
invocation of the run-time loader.
Handle any failure appropriately, observing however that the failure
path is called too early for `__r_strerror' to be able to retrieve an
error message corresponding to the code passed in all cases, so a
numerical value might only be reported instead. This is supposed to
never happen for static startup as in this case the operating system's
kernel is expected to have rejected any incompatible binary, however
handle a failure anyway, for consistency.
Assume the compiler will optimize the failure path in the default case
of empty `elf_machine_main_map_setup' always succeeding.
* elf/dl-machine-main-map-setup.h: New file.
* elf/dl-support.c (_dl_non_dynamic_init): Call
`elf_machine_main_map_setup'.
* elf/rtld.c (dl_main): Likewise.
---
glibc-main-map-setup.diff
===================================================================
@@ -0,0 +1,33 @@
+/* Machine-dependent main link map setup for the ELF loader.
+ Copyright (C) 2015 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/>. */
+
+#ifndef _DL_MACHINE_MAIN_MAP_SETUP
+#define _DL_MACHINE_MAIN_MAP_SETUP 1
+
+#include <stdbool.h>
+
+/* Set up machine-dependent parts of the main link map. Return 0
+ if successful. */
+
+static inline int
+elf_machine_main_map_setup (struct link_map *map, bool rtld_is_main)
+{
+ return 0;
+}
+
+#endif /* dl-machine-main-map-setup.h */
===================================================================
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <ldsodefs.h>
#include <dl-machine.h>
+#include <dl-machine-main-map-setup.h>
#include <libc-lock.h>
#include <dl-cache.h>
#include <dl-librecon.h>
@@ -311,6 +312,12 @@ _dl_non_dynamic_init (void)
_dl_main_map.l_phdr = GL(dl_phdr);
_dl_main_map.l_phnum = GL(dl_phnum);
+ int err = elf_machine_main_map_setup (&_dl_main_map, false);
+ if (__glibc_unlikely (err))
+ _dl_signal_error (err, NULL,
+ N_ ("error while initializing executable"),
+ N_ ("platform setup error"));
+
if (HP_SMALL_TIMING_AVAIL)
HP_TIMING_NOW (_dl_cpuclock_offset);
===================================================================
@@ -19,6 +19,7 @@
#include <errno.h>
#include <dlfcn.h>
#include <fcntl.h>
+#include <libintl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@@ -36,6 +37,7 @@
#include <dl-librecon.h>
#include <unsecvars.h>
#include <dl-cache.h>
+#include <dl-machine-main-map-setup.h>
#include <dl-osinfo.h>
#include <dl-procinfo.h>
#include <tls.h>
@@ -1453,6 +1455,13 @@ ERROR: ld.so: object '%s' cannot be load
GL(dl_rtld_map).l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
#endif
+ /* Let any machine setup process the main map before objects are added. */
+ int err = elf_machine_main_map_setup (main_map, rtld_is_main);
+ if (__glibc_unlikely (err))
+ _dl_signal_error (err, NULL,
+ N_ ("error while initializing executable"),
+ N_ ("platform setup error"));
+
/* We start adding objects. */
r->r_state = RT_ADD;
_dl_debug_state ();