aboutsummaryrefslogtreecommitdiff
path: root/elf/rtld.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c181
1 files changed, 96 insertions, 85 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index a65e9c4..e015477 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1138,103 +1138,114 @@ of this helper program; chances are you did not intend to run this program.\n\
HP_TIMING_ACCUM_NT (load_time, diff);
}
- /* Read the contents of the file. */
- const char preload_file[] = "/etc/ld.so.preload";
- file = _dl_sysdep_read_whole_file (preload_file, &file_size,
- PROT_READ | PROT_WRITE);
- if (__builtin_expect (file != MAP_FAILED, 0))
+ /* There usually is no ld.so.preload file, it should only be used
+ for emergencies and testing. So the open call etc should usually
+ fail. Using access() on a non-existing file is faster than using
+ open(). So we do this first. If it succeeds we do almost twice
+ the work but this does not matter, since it is not for production
+ use. */
+ static const char preload_file[] = "/etc/ld.so.preload";
+ if (__builtin_expect (__access (preload_file, R_OK) == 0, 0))
{
- /* Parse the file. It contains names of libraries to be loaded,
- separated by white spaces or `:'. It may also contain
- comments introduced by `#'. */
- char *problem;
- char *runp;
- size_t rest;
-
- /* Eliminate comments. */
- runp = file;
- rest = file_size;
- while (rest > 0)
+ /* Read the contents of the file. */
+ file = _dl_sysdep_read_whole_file (preload_file, &file_size,
+ PROT_READ | PROT_WRITE);
+ if (__builtin_expect (file != MAP_FAILED, 0))
{
- char *comment = memchr (runp, '#', rest);
- if (comment == NULL)
- break;
-
- rest -= comment - runp;
- do
- *comment = ' ';
- while (--rest > 0 && *++comment != '\n');
- }
-
- /* We have one problematic case: if we have a name at the end of
- the file without a trailing terminating characters, we cannot
- place the \0. Handle the case separately. */
- if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
- && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
- {
- problem = &file[file_size];
- while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
- && problem[-1] != '\n' && problem[-1] != ':')
- --problem;
-
- if (problem > file)
- problem[-1] = '\0';
- }
- else
- {
- problem = NULL;
- file[file_size - 1] = '\0';
- }
+ /* Parse the file. It contains names of libraries to be loaded,
+ separated by white spaces or `:'. It may also contain
+ comments introduced by `#'. */
+ char *problem;
+ char *runp;
+ size_t rest;
+
+ /* Eliminate comments. */
+ runp = file;
+ rest = file_size;
+ while (rest > 0)
+ {
+ char *comment = memchr (runp, '#', rest);
+ if (comment == NULL)
+ break;
- HP_TIMING_NOW (start);
+ rest -= comment - runp;
+ do
+ *comment = ' ';
+ while (--rest > 0 && *++comment != '\n');
+ }
- if (file != problem)
- {
- char *p;
- runp = file;
- while ((p = strsep (&runp, ": \t\n")) != NULL)
- if (p[0] != '\0')
- {
- const char *objname;
- const char *err_str = NULL;
- struct map_args args;
+ /* We have one problematic case: if we have a name at the end of
+ the file without a trailing terminating characters, we cannot
+ place the \0. Handle the case separately. */
+ if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
+ && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
+ {
+ problem = &file[file_size];
+ while (problem > file && problem[-1] != ' '
+ && problem[-1] != '\t'
+ && problem[-1] != '\n' && problem[-1] != ':')
+ --problem;
+
+ if (problem > file)
+ problem[-1] = '\0';
+ }
+ else
+ {
+ problem = NULL;
+ file[file_size - 1] = '\0';
+ }
- args.str = p;
- args.loader = GL(dl_loaded);
- args.is_preloaded = 1;
- args.mode = 0;
+ HP_TIMING_NOW (start);
- (void) _dl_catch_error (&objname, &err_str, map_doit, &args);
- if (__builtin_expect (err_str != NULL, 0))
+ if (file != problem)
+ {
+ char *p;
+ runp = file;
+ while ((p = strsep (&runp, ": \t\n")) != NULL)
+ if (p[0] != '\0')
{
- _dl_error_printf ("\
+ const char *objname;
+ const char *err_str = NULL;
+ struct map_args args;
+
+ args.str = p;
+ args.loader = GL(dl_loaded);
+ args.is_preloaded = 1;
+ args.mode = 0;
+
+ (void) _dl_catch_error (&objname, &err_str, map_doit,
+ &args);
+ if (__builtin_expect (err_str != NULL, 0))
+ {
+ _dl_error_printf ("\
ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
- p, preload_file);
- /* No need to call free, this is still before the libc's
- malloc is used. */
+ p, preload_file);
+ /* No need to call free, this is still before
+ the libc's malloc is used. */
+ }
+ else if (++args.map->l_opencount == 1)
+ /* It is no duplicate. */
+ ++npreloads;
}
- else if (++args.map->l_opencount == 1)
- /* It is no duplicate. */
- ++npreloads;
- }
- }
+ }
- if (problem != NULL)
- {
- char *p = strndupa (problem, file_size - (problem - file));
- struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
- lt_library, 0, 0);
- if (++new_map->l_opencount == 1)
- /* It is no duplicate. */
- ++npreloads;
- }
+ if (problem != NULL)
+ {
+ char *p = strndupa (problem, file_size - (problem - file));
+ struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
+ lt_library, 0, 0);
+ if (++new_map->l_opencount == 1)
+ /* It is no duplicate. */
+ ++npreloads;
+ }
- HP_TIMING_NOW (stop);
- HP_TIMING_DIFF (diff, start, stop);
- HP_TIMING_ACCUM_NT (load_time, diff);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_DIFF (diff, start, stop);
+ HP_TIMING_ACCUM_NT (load_time, diff);
- /* We don't need the file anymore. */
- __munmap (file, file_size);
+ /* We don't need the file anymore. */
+ __munmap (file, file_size);
+ }
}
if (__builtin_expect (npreloads, 0) != 0)