summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2013-09-01 19:29:18 +0200
committerThomas Schwinge <thomas@codesourcery.com>2013-09-01 19:29:18 +0200
commitcbb58c37bb81d176f106a4de3c7f3b02dee2ff66 (patch)
treec746d229279f84aac0fe3afe537813fb281f7f78 /elf
parentffeaf5a2df0d177a7780fd7c6f5e7595caba766a (diff)
parentd5860b5273bc00632c65b43cb931d3238db0ab57 (diff)
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Conflicts: sysdeps/mach/hurd/i386/init-first.c sysdeps/unix/sysv/linux/ldsodefs.h
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile13
-rw-r--r--elf/dl-conflict.c3
-rw-r--r--elf/dl-deps.c6
-rw-r--r--elf/dl-dst.h13
-rw-r--r--elf/dl-error.c2
-rw-r--r--elf/dl-fini.c2
-rw-r--r--elf/dl-init.c5
-rw-r--r--elf/dl-load.c21
-rw-r--r--elf/dl-lookup.c22
-rw-r--r--elf/dl-open.c34
-rw-r--r--elf/dl-profile.c13
-rw-r--r--elf/dl-reloc.c5
-rw-r--r--elf/dl-support.c55
-rw-r--r--elf/dl-sysdep.c10
-rw-r--r--elf/dl-version.c9
-rw-r--r--elf/elf.h7
-rw-r--r--elf/ifuncdep2.c8
-rw-r--r--elf/ifuncmain1.c2
-rw-r--r--elf/ifuncmain1vis.c2
-rw-r--r--elf/reldep.c2
-rw-r--r--elf/reldep3.c2
-rw-r--r--elf/rtld-Rules34
-rw-r--r--elf/rtld.c13
-rw-r--r--elf/setup-vdso.h2
-rw-r--r--elf/sln.c8
-rw-r--r--elf/sprof.c2
-rw-r--r--elf/testobj.h10
-rw-r--r--elf/tst-null-argv-lib.c24
-rw-r--r--elf/tst-null-argv.c35
-rw-r--r--elf/tst-stackguard1.c2
30 files changed, 225 insertions, 141 deletions
diff --git a/elf/Makefile b/elf/Makefile
index c01ca9ef68..3b58649de5 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -145,7 +145,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-audit1 tst-audit2 tst-audit8 \
tst-stackguard1 tst-addr1 tst-thrlock \
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
- tst-initorder tst-initorder2 tst-relsort1
+ tst-initorder tst-initorder2 tst-relsort1 tst-null-argv
# reldep9
test-srcs = tst-pathopt
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
@@ -208,7 +208,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-initorder2a tst-initorder2b tst-initorder2c \
tst-initorder2d \
tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
- tst-array5dep
+ tst-array5dep tst-null-argv-lib
ifeq (yesyes,$(have-fpie)$(build-shared))
modules-names += tst-piemod1
tests += tst-pie1
@@ -318,13 +318,16 @@ generated += librtld.map librtld.mk rtld-libc.a librtld.os.map
z-now-yes = -Wl,-z,now
$(objpfx)ld.so: $(objpfx)librtld.os $(ld-map)
- $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
+# Link into a temporary file so that we don't touch $@ at all
+# if the sanity check below fails.
+ $(LINK.o) -nostdlib -nostartfiles -shared -o $@.new \
$(LDFLAGS-rtld) -Wl,-z,defs $(z-now-$(bind-now)) \
$(filter-out $(map-file),$^) $(load-map-file) \
-Wl,-soname=$(rtld-installed-name) \
-Wl,-defsym=_begin=0
- $(READELF) -s $@ \
+ $(READELF) -s $@.new \
| $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }'
+ mv -f $@.new $@
# interp.c exists just to get this string into the libraries.
CFLAGS-interp.c = -D'RUNTIME_LINKER="$(rtlddir)/$(rtld-installed-name)"' \
@@ -494,7 +497,9 @@ $(objpfx)tst-initorderb2.so: $(objpfx)tst-initorderb1.so $(objpfx)tst-initordera
$(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb1.so
$(objpfx)tst-initordera4.so: $(objpfx)tst-initordera3.so
$(objpfx)tst-initorder: $(objpfx)tst-initordera4.so $(objpfx)tst-initordera1.so $(objpfx)tst-initorderb2.so
+$(objpfx)tst-null-argv: $(objpfx)tst-null-argv-lib.so
+tst-null-argv-ENV = LD_DEBUG=all LD_DEBUG_OUTPUT=$(objpfx)tst-null-argv.debug.out
LDFLAGS-nodel2mod3.so = $(no-as-needed)
LDFLAGS-reldepmod5.so = $(no-as-needed)
LDFLAGS-reldep6mod1.so = $(no-as-needed)
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
index d63086d99c..11e3cd8773 100644
--- a/elf/dl-conflict.c
+++ b/elf/dl-conflict.c
@@ -33,8 +33,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
{
#if ! ELF_MACHINE_NO_RELA
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
- _dl_debug_printf ("\nconflict processing: %s\n",
- l->l_name[0] ? l->l_name : rtld_progname);
+ _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
{
/* Do the conflict relocation of the object and library GOT and other
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index cd1c236b2e..1c36f501bc 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -310,8 +310,7 @@ _dl_map_object_deps (struct link_map *map,
_dl_debug_printf ("load auxiliary object=%s"
" requested by file=%s\n",
name,
- l->l_name[0]
- ? l->l_name : rtld_progname);
+ DSO_FILENAME (l->l_name));
/* We must be prepared that the addressed shared
object is not available. */
@@ -337,8 +336,7 @@ _dl_map_object_deps (struct link_map *map,
_dl_debug_printf ("load filtered object=%s"
" requested by file=%s\n",
name,
- l->l_name[0]
- ? l->l_name : rtld_progname);
+ DSO_FILENAME (l->l_name));
/* For filter objects the dependency must be available. */
bool malloced;
diff --git a/elf/dl-dst.h b/elf/dl-dst.h
index 20b68d90b6..3ed95d02d5 100644
--- a/elf/dl-dst.h
+++ b/elf/dl-dst.h
@@ -55,7 +55,6 @@
First get the origin string if it is not available yet. \
This can only happen for the map of the executable or, when \
auditing, in ld.so. */ \
- DL_DST_REQ_STATIC (l) \
if ((l)->l_origin == NULL) \
{ \
assert ((l)->l_name[0] == '\0' || IS_RTLD (l)); \
@@ -73,15 +72,3 @@
} \
\
__len; })
-
-#ifdef SHARED
-# define DL_DST_REQ_STATIC(l) /* nothing */
-#else
-# define DL_DST_REQ_STATIC(l) \
- if ((l) == NULL) \
- { \
- const char *origin = _dl_get_origin (); \
- dst_len = (origin && origin != (char *) -1 ? strlen (origin) : 0); \
- } \
- else
-#endif
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 798784543b..8257c17030 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -119,7 +119,7 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
/* Lossage while resolving the program's own symbols is always fatal. */
char buffer[1024];
_dl_fatal_printf ("%s: %s: %s%s%s%s%s\n",
- rtld_progname ?: "<program name unknown>",
+ RTLD_PROGNAME,
occation ?: N_("error while loading shared libraries"),
objname, *objname ? ": " : "",
errstring, errcode ? ": " : "",
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index c5d1674aa4..6b245f0022 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -237,7 +237,7 @@ _dl_fini (void)
if (__builtin_expect (GLRO(dl_debug_mask)
& DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
- l->l_name[0] ? l->l_name : rtld_progname,
+ DSO_FILENAME (l->l_name),
ns);
/* First see whether an array is given. */
diff --git a/elf/dl-init.c b/elf/dl-init.c
index fe4d2a07da..a657eb6c40 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -54,7 +54,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
/* Print a debug message if wanted. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ncalling init: %s\n\n",
- l->l_name[0] ? l->l_name : rtld_progname);
+ DSO_FILENAME (l->l_name));
/* Now run the local constructors. There are two forms of them:
- the one named by DT_INIT
@@ -110,8 +110,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ncalling preinit: %s\n\n",
- main_map->l_name[0]
- ? main_map->l_name : rtld_progname);
+ DSO_FILENAME (main_map->l_name));
addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
for (cnt = 0; cnt < i; ++cnt)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index dd182c9155..6a73f27345 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -324,7 +324,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
const char *const start = name;
/* Now fill the result path. While copying over the string we keep
- track of the start of the last path element. When we come accross
+ track of the start of the last path element. When we come across
a DST we copy over the value or (if the value is not available)
leave the entire path element out. */
char *wp = result;
@@ -342,13 +342,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
if ((len = is_dst (start, name, "ORIGIN", is_path,
INTUSE(__libc_enable_secure))) != 0)
{
-#ifndef SHARED
- if (l == NULL)
- repl = _dl_get_origin ();
- else
-#endif
- repl = l->l_origin;
-
+ repl = l->l_origin;
check_for_trusted = (INTUSE(__libc_enable_secure)
&& l->l_type == lt_executable);
}
@@ -1493,7 +1487,11 @@ cannot allocate TLS data structures for initial thread");
if (__builtin_expect (p + s <= relro_end, 1))
{
/* The variable lies in the region protected by RELRO. */
- __mprotect ((void *) p, s, PROT_READ|PROT_WRITE);
+ if (__mprotect ((void *) p, s, PROT_READ|PROT_WRITE) < 0)
+ {
+ errstring = N_("cannot change memory protections");
+ goto call_lose_errno;
+ }
__stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
__mprotect ((void *) p, s, PROT_READ);
}
@@ -1651,7 +1649,7 @@ print_search_path (struct r_search_path_elem **list,
if (name != NULL)
_dl_debug_printf_c ("\t\t(%s from file %s)\n", what,
- name[0] ? name : rtld_progname);
+ DSO_FILENAME (name));
else
_dl_debug_printf_c ("\t\t(%s)\n", what);
}
@@ -2124,8 +2122,7 @@ _dl_map_object (struct link_map *loader, const char *name,
_dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
? "\nfile=%s [%lu]; needed by %s [%lu]\n"
: "\nfile=%s [%lu]; dynamically loaded by %s [%lu]\n",
- name, nsid, loader->l_name[0]
- ? loader->l_name : rtld_progname, loader->l_ns);
+ name, nsid, DSO_FILENAME (loader->l_name), loader->l_ns);
#ifdef SHARED
/* Give the auditing libraries a chance to change the name before we
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 68f8daccb9..39f463eae1 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -112,8 +112,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
/* Print some debugging info if wanted. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))
_dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
- undef_name,
- map->l_name[0] ? map->l_name : rtld_progname,
+ undef_name, DSO_FILENAME (map->l_name),
map->l_ns);
/* If the hash table is empty there is nothing to do here. */
@@ -667,10 +666,9 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
_dl_debug_printf ("\
\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
- map->l_name[0] ? map->l_name : rtld_progname,
+ DSO_FILENAME (map->l_name),
map->l_ns,
- undef_map->l_name[0]
- ? undef_map->l_name : rtld_progname,
+ DSO_FILENAME (undef_map->l_name),
undef_map->l_ns);
}
else
@@ -751,9 +749,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
const char *reference_name = undef_map ? undef_map->l_name : NULL;
/* XXX We cannot translate the message. */
- _dl_signal_cerror (0, (reference_name[0]
- ? reference_name
- : (rtld_progname ?: "<main program>")),
+ _dl_signal_cerror (0, DSO_FILENAME (reference_name),
N_("relocation error"),
make_string ("symbol ", undef_name, ", version ",
version->name,
@@ -780,9 +776,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
? version->name : "");
/* XXX We cannot translate the message. */
- _dl_signal_cerror (0, (reference_name[0]
- ? reference_name
- : (rtld_progname ?: "<main program>")),
+ _dl_signal_cerror (0, DSO_FILENAME (reference_name),
N_("symbol lookup error"),
make_string (undefined_msg, undef_name,
versionstr, versionname));
@@ -912,11 +906,9 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
{
_dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
- (reference_name[0]
- ? reference_name
- : (rtld_progname ?: "<main program>")),
+ DSO_FILENAME (reference_name),
undef_map->l_ns,
- value->m->l_name[0] ? value->m->l_name : rtld_progname,
+ DSO_FILENAME (value->m->l_name),
value->m->l_ns,
protected ? "protected" : "normal", undef_name);
if (version)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 92fae7f59b..1403c8c091 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -158,7 +158,7 @@ add_to_global (struct link_map *new)
return 0;
}
-/* Search link maps in all namespaces for the DSO that containes the object at
+/* Search link maps in all namespaces for the DSO that contains the object at
address ADDR. Returns the pointer to the link map of the matching DSO, or
NULL if a match is not found. */
struct link_map *
@@ -204,11 +204,9 @@ dl_open_worker (void *a)
{
const void *caller_dlopen = args->caller_dlopen;
-#ifdef SHARED
/* We have to find out from which object the caller is calling.
By default we assume this is the main application. */
call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-#endif
struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen);
@@ -216,15 +214,7 @@ dl_open_worker (void *a)
call_map = l;
if (args->nsid == __LM_ID_CALLER)
- {
-#ifndef SHARED
- /* In statically linked apps there might be no loaded object. */
- if (call_map == NULL)
- args->nsid = LM_ID_BASE;
- else
-#endif
- args->nsid = call_map->l_ns;
- }
+ args->nsid = call_map->l_ns;
}
assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
@@ -406,7 +396,7 @@ dl_open_worker (void *a)
/* If this here is the shared object which we want to profile
make sure the profile is started. We can find out whether
this is necessary or not by observing the `_dl_profile_map'
- variable. If it was NULL but is not NULL afterwars we must
+ variable. If it was NULL but is not NULL afterwards we must
start the profiling. */
struct link_map *old_profile_map = GL(dl_profile_map);
@@ -568,6 +558,10 @@ cannot load any more object with static TLS"));
if (relocation_in_progress)
LIBC_PROBE (reloc_complete, 3, args->nsid, r, new);
+#ifndef SHARED
+ DL_STATIC_INIT (new);
+#endif
+
/* Run the initializer functions of new objects. */
_dl_init (new, args->argc, args->argv, args->env);
@@ -638,12 +632,6 @@ no more namespaces available for dlmopen()"));
|| GL(dl_ns)[nsid]._ns_loaded->l_auditing))
_dl_signal_error (EINVAL, file, NULL,
N_("invalid target namespace in dlmopen()"));
-#ifndef SHARED
- else if ((nsid == LM_ID_BASE || nsid == __LM_ID_CALLER)
- && GL(dl_ns)[LM_ID_BASE]._ns_loaded == NULL
- && GL(dl_nns) == 0)
- GL(dl_nns) = 1;
-#endif
struct dl_open_args args;
args.file = file;
@@ -721,10 +709,6 @@ no more namespaces available for dlmopen()"));
/* Release the lock. */
__rtld_lock_unlock_recursive (GL(dl_load_lock));
-#ifndef SHARED
- DL_STATIC_INIT (args.map);
-#endif
-
return args.map;
}
@@ -733,7 +717,7 @@ void
_dl_show_scope (struct link_map *l, int from)
{
_dl_debug_printf ("object=%s [%lu]\n",
- *l->l_name ? l->l_name : rtld_progname, l->l_ns);
+ DSO_FILENAME (l->l_name), l->l_ns);
if (l->l_scope != NULL)
for (int scope_cnt = from; l->l_scope[scope_cnt] != NULL; ++scope_cnt)
{
@@ -744,7 +728,7 @@ _dl_show_scope (struct link_map *l, int from)
_dl_debug_printf_c (" %s",
l->l_scope[scope_cnt]->r_list[cnt]->l_name);
else
- _dl_debug_printf_c (" %s", rtld_progname);
+ _dl_debug_printf_c (" %s", RTLD_PROGNAME);
_dl_debug_printf_c ("\n");
}
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 9034be229a..8fa6efca42 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -131,7 +131,18 @@ struct here_cg_arc_record
{
uintptr_t from_pc;
uintptr_t self_pc;
- uint32_t count;
+ /* The count field is atomically incremented in _dl_mcount, which
+ requires it to be properly aligned for its type, and for this
+ alignment to be visible to the compiler. The amount of data
+ before an array of this structure is calculated as
+ expected_size in _dl_start_profile. Everything in that
+ calculation is a multiple of 4 bytes (in the case of
+ kcountsize, because it is derived from a subtraction of
+ page-aligned values, and the corresponding calculation in
+ __monstartup also ensures it is at least a multiple of the size
+ of u_long), so all copies of this field do in fact have the
+ appropriate alignment. */
+ uint32_t count __attribute__ ((aligned (__alignof__ (uint32_t))));
} __attribute__ ((packed));
static struct here_cg_arc_record *data;
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 73d98f8c2e..5c5431098c 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -185,8 +185,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
_dl_debug_printf ("\nrelocation processing: %s%s\n",
- l->l_name[0] ? l->l_name : rtld_progname,
- lazy ? " (lazy)" : "");
+ DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
/* DT_TEXTREL is now in level 2 and might phase out at some time.
But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make
@@ -276,7 +275,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
errstring = N_("%s: no PLTREL found in object %s\n");
fatal:
_dl_fatal_printf (errstring,
- rtld_progname ?: "<program name unknown>",
+ RTLD_PROGNAME,
l->l_name);
}
diff --git a/elf/dl-support.c b/elf/dl-support.c
index a793fe6868..e551078df1 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -70,17 +70,52 @@ const char *_dl_origin_path;
/* Nonzero if runtime lookup should not update the .got/.plt. */
int _dl_bind_not;
+/* A dummy link map for the executable, used by dlopen to access the global
+ scope. We don't export any symbols ourselves, so this can be minimal. */
+static struct link_map _dl_main_map =
+ {
+ .l_name = (char *) "",
+ .l_real = &_dl_main_map,
+ .l_ns = LM_ID_BASE,
+ .l_libname = &(struct libname_list) { .name = "", .dont_free = 1 },
+ .l_searchlist =
+ {
+ .r_list = &(struct link_map *) { &_dl_main_map },
+ .r_nlist = 1,
+ },
+ .l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } },
+ .l_type = lt_executable,
+ .l_scope_mem = { &_dl_main_map.l_searchlist },
+ .l_scope_max = (sizeof (_dl_main_map.l_scope_mem)
+ / sizeof (_dl_main_map.l_scope_mem[0])),
+ .l_scope = _dl_main_map.l_scope_mem,
+ .l_local_scope = { &_dl_main_map.l_searchlist },
+ .l_used = 1,
+ .l_tls_offset = NO_TLS_OFFSET,
+ .l_serial = 1,
+ };
+
/* Namespace information. */
-struct link_namespaces _dl_ns[DL_NNS];
-size_t _dl_nns;
+struct link_namespaces _dl_ns[DL_NNS] =
+ {
+ [LM_ID_BASE] =
+ {
+ ._ns_loaded = &_dl_main_map,
+ ._ns_nloaded = 1,
+ ._ns_main_searchlist = &_dl_main_map.l_searchlist,
+ }
+ };
+size_t _dl_nns = 1;
/* Incremented whenever something may have been added to dl_loaded. */
-unsigned long long _dl_load_adds;
+unsigned long long _dl_load_adds = 1;
-/* Fake scope. In dynamically linked binaries this is the scope of the
- main application but here we don't have something like this. So
- create a fake scope containing nothing. */
-struct r_scope_elem _dl_initial_searchlist;
+/* Fake scope of the main application. */
+struct r_scope_elem _dl_initial_searchlist =
+ {
+ .r_list = &(struct link_map *) { &_dl_main_map },
+ .r_nlist = 1,
+ };
#ifndef HAVE_INLINED_SYSCALLS
/* Nonzero during startup. */
@@ -130,6 +165,7 @@ ElfW(auxv_t) *_dl_auxv;
const ElfW(Phdr) *_dl_phdr;
size_t _dl_phnum;
uint64_t _dl_hwcap __attribute__ ((nocommon));
+uint64_t _dl_hwcap2 __attribute__ ((nocommon));
/* This is not initialized to HWCAP_IMPORTANT, matching the definition
of _dl_important_hwcaps, below, where no hwcap strings are ever
@@ -215,6 +251,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
case AT_HWCAP:
GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
break;
+ case AT_HWCAP2:
+ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
+ break;
#ifdef NEED_DL_SYSINFO
case AT_SYSINFO:
GL(dl_sysinfo) = av->a_un.a_val;
@@ -266,6 +305,8 @@ void
internal_function
_dl_non_dynamic_init (void)
{
+ _dl_main_map.l_origin = _dl_get_origin ();
+
if (HP_TIMING_AVAIL)
HP_TIMING_NOW (_dl_cpuclock_offset);
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 52de23f44b..08c74ef83b 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -156,6 +156,9 @@ _dl_sysdep_start (void **start_argptr,
case AT_HWCAP:
GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
break;
+ case AT_HWCAP2:
+ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
+ break;
case AT_CLKTCK:
GLRO(dl_clktck) = av->a_un.a_val;
break;
@@ -303,6 +306,7 @@ _dl_show_auxv (void)
[AT_SYSINFO - 2] = { "SYSINFO: 0x", hex },
[AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
[AT_RANDOM - 2] = { "RANDOM: 0x", hex },
+ [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex },
};
unsigned int idx = (unsigned int) (av->a_type - 2);
@@ -314,10 +318,10 @@ _dl_show_auxv (void)
assert (AT_NULL == 0);
assert (AT_IGNORE == 1);
- if (av->a_type == AT_HWCAP)
+ if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2)
{
- /* This is handled special. */
- if (_dl_procinfo (av->a_un.a_val) == 0)
+ /* These are handled in a special way per platform. */
+ if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
continue;
}
diff --git a/elf/dl-version.c b/elf/dl-version.c
index c02baa0600..62be4aef75 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -85,7 +85,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS, 0))
_dl_debug_printf ("\
checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
- string, map->l_name[0] ? map->l_name : rtld_progname,
+ string, DSO_FILENAME (map->l_name),
map->l_ns, name, ns);
if (__builtin_expect (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL, 0))
@@ -162,7 +162,7 @@ no version information available (required by ", name, ")");
name, ")");
result = 1;
call_cerror:
- _dl_signal_cerror (0, map->l_name[0] ? map->l_name : rtld_progname,
+ _dl_signal_cerror (0, DSO_FILENAME (map->l_name),
N_("version lookup error"), errstring);
return result;
}
@@ -210,7 +210,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
&buf[sizeof (buf) - 1], 10, 0),
" of Verneed record\n");
call_error:
- _dl_signal_error (errval, *map->l_name ? map->l_name : rtld_progname,
+ _dl_signal_error (errval, DSO_FILENAME (map->l_name),
NULL, errstring);
}
@@ -234,8 +234,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
while (1)
{
/* Match the symbol. */
- result |= match_symbol ((*map->l_name
- ? map->l_name : rtld_progname),
+ result |= match_symbol (DSO_FILENAME (map->l_name),
map->l_ns, aux->vna_hash,
strtab + aux->vna_name,
needed->l_real, verbose,
diff --git a/elf/elf.h b/elf/elf.h
index 4ad4f39999..fe55c928cd 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -811,7 +811,7 @@ typedef struct
#define DF_1_EDITED 0x00200000 /* Object is modified after built. */
#define DF_1_NORELOC 0x00400000
#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
-#define DF_1_GLOBAUDIT 0x01000000 /* Global auditin required. */
+#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
/* Flags for the feature selection in DT_FEATURE_1. */
@@ -993,7 +993,7 @@ typedef struct
/* Some more special a_type values describing the hardware. */
#define AT_PLATFORM 15 /* String identifying platform. */
-#define AT_HWCAP 16 /* Machine dependent hints about
+#define AT_HWCAP 16 /* Machine-dependent hints about
processor capabilities. */
/* This entry gives some information about the FPU initialization
@@ -1015,6 +1015,9 @@ typedef struct
#define AT_RANDOM 25 /* Address of 16 random bytes. */
+#define AT_HWCAP2 26 /* More machine-dependent hints about
+ processor capabilities. */
+
#define AT_EXECFN 31 /* Filename of executable. */
/* Pointer to the global system page used for system calls and other
diff --git a/elf/ifuncdep2.c b/elf/ifuncdep2.c
index 758bae1932..99d19263ae 100644
--- a/elf/ifuncdep2.c
+++ b/elf/ifuncdep2.c
@@ -17,7 +17,7 @@ minus_one (void)
}
static int
-zero (void)
+zero (void)
{
return 0;
}
@@ -25,7 +25,7 @@ zero (void)
void * foo1_ifunc (void) __asm__ ("foo1");
__asm__(".type foo1, %gnu_indirect_function");
-void *
+void *
foo1_ifunc (void)
{
return ifunc_sel (one, minus_one, zero);
@@ -34,7 +34,7 @@ foo1_ifunc (void)
void * foo2_ifunc (void) __asm__ ("foo2");
__asm__(".type foo2, %gnu_indirect_function");
-void *
+void *
foo2_ifunc (void)
{
return ifunc_sel (minus_one, one, zero);
@@ -43,7 +43,7 @@ foo2_ifunc (void)
void * foo3_ifunc (void) __asm__ ("foo3");
__asm__(".type foo3, %gnu_indirect_function");
-void *
+void *
foo3_ifunc (void)
{
return ifunc_sel (one, zero, minus_one);
diff --git a/elf/ifuncmain1.c b/elf/ifuncmain1.c
index cc1e5ec5ba..747fc02648 100644
--- a/elf/ifuncmain1.c
+++ b/elf/ifuncmain1.c
@@ -29,7 +29,7 @@ int
main (void)
{
foo_p p;
-
+
if (foo_ptr != foo)
abort ();
if (foo () != -1)
diff --git a/elf/ifuncmain1vis.c b/elf/ifuncmain1vis.c
index 81cd12288e..d35e2f81fc 100644
--- a/elf/ifuncmain1vis.c
+++ b/elf/ifuncmain1vis.c
@@ -50,7 +50,7 @@ int
main (void)
{
foo_p p;
-
+
if (foo_ptr != foo)
abort ();
if ((*foo_ptr) () != -30)
diff --git a/elf/reldep.c b/elf/reldep.c
index 44b239b6c7..adabc0d5d5 100644
--- a/elf/reldep.c
+++ b/elf/reldep.c
@@ -54,7 +54,7 @@ main (void)
}
/* Now close the first object. If must still be around since we have
- a implicit dependency. */
+ an implicit dependency. */
if (dlclose (h1) != 0)
{
printf ("closing h1 failed: %s\n", dlerror ());
diff --git a/elf/reldep3.c b/elf/reldep3.c
index b051c41dbc..05013d3509 100644
--- a/elf/reldep3.c
+++ b/elf/reldep3.c
@@ -54,7 +54,7 @@ main (void)
}
/* Now close the first object. If must still be around since we have
- a implicit dependency. */
+ an implicit dependency. */
if (dlclose (h1) != 0)
{
printf ("closing h1 failed: %s\n", dlerror ());
diff --git a/elf/rtld-Rules b/elf/rtld-Rules
index f11dbe079a..1aa00060b8 100644
--- a/elf/rtld-Rules
+++ b/elf/rtld-Rules
@@ -88,29 +88,39 @@ else
# Some other subdir's Makefile has provided all its normal rules,
# and we just provide some additional definitions.
+rtld-compile-command.S = $(compile-command.S) $(rtld-CPPFLAGS)
+rtld-compile-command.s = $(compile-command.s) $(rtld-CPPFLAGS)
+rtld-compile-command.c = $(compile-command.c) $(rtld-CPPFLAGS)
+
# These are the basic compilation rules corresponding to the Makerules ones.
# The sysd-rules generated makefile already defines pattern rules for rtld-%
# targets built from sysdeps source files.
$(objpfx)rtld-%.os: rtld-%.S $(before-compile)
- $(compile-command.S) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.S)
$(objpfx)rtld-%.os: rtld-%.s $(before-compile)
- $(compile-command.s) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.s)
$(objpfx)rtld-%.os: rtld-%.c $(before-compile)
- $(compile-command.c) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.c)
$(objpfx)rtld-%.os: %.S $(before-compile)
- $(compile-command.S) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.S)
$(objpfx)rtld-%.os: %.s $(before-compile)
- $(compile-command.s) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.s)
$(objpfx)rtld-%.os: %.c $(before-compile)
- $(compile-command.c) $(rtld-CPPFLAGS)
+ $(rtld-compile-command.c)
# The rules for generated source files.
-$(objpfx)rtld-%.os: $(objpfx)rtld-%.S $(before-compile); $(compile-command.S)
-$(objpfx)rtld-%.os: $(objpfx)rtld-%.s $(before-compile); $(compile-command.s)
-$(objpfx)rtld-%.os: $(objpfx)rtld-%.c $(before-compile); $(compile-command.c)
-$(objpfx)rtld-%.os: $(objpfx)%.S $(before-compile); $(compile-command.S)
-$(objpfx)rtld-%.os: $(objpfx)%.s $(before-compile); $(compile-command.s)
-$(objpfx)rtld-%.os: $(objpfx)%.c $(before-compile); $(compile-command.c)
+$(objpfx)rtld-%.os: $(objpfx)rtld-%.S $(before-compile)
+ $(rtld-compile-command.S)
+$(objpfx)rtld-%.os: $(objpfx)rtld-%.s $(before-compile)
+ $(rtld-compile-command.s)
+$(objpfx)rtld-%.os: $(objpfx)rtld-%.c $(before-compile)
+ $(rtld-compile-command.c)
+$(objpfx)rtld-%.os: $(objpfx)%.S $(before-compile)
+ $(rtld-compile-command.S)
+$(objpfx)rtld-%.os: $(objpfx)%.s $(before-compile)
+ $(rtld-compile-command.s)
+$(objpfx)rtld-%.os: $(objpfx)%.c $(before-compile)
+ $(rtld-compile-command.c)
# The command line setting of rtld-modules (see above) tells us
# what we need to build, and that tells us what dependency files we need.
diff --git a/elf/rtld.c b/elf/rtld.c
index bf2e3351d3..a0bda1d165 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1840,10 +1840,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (_dl_name_match_p (GLRO(dl_trace_prelink), l))
GLRO(dl_trace_prelink_map) = l;
_dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)",
- l->l_libname->name[0] ? l->l_libname->name
- : rtld_progname ?: "<main program>",
- l->l_name[0] ? l->l_name
- : rtld_progname ?: "<main program>",
+ DSO_FILENAME (l->l_libname->name),
+ DSO_FILENAME (l->l_name),
(int) sizeof l->l_map_start * 2,
(size_t) l->l_map_start,
(int) sizeof l->l_addr * 2,
@@ -2000,8 +1998,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
first = 0;
}
- _dl_printf ("\t%s:\n",
- map->l_name[0] ? map->l_name : rtld_progname);
+ _dl_printf ("\t%s:\n", DSO_FILENAME (map->l_name));
while (1)
{
@@ -2324,7 +2321,7 @@ print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
const char *errstring)
{
if (objname[0] == '\0')
- objname = rtld_progname ?: "<main program>";
+ objname = RTLD_PROGNAME;
_dl_error_printf ("%s (%s)\n", errstring, objname);
}
@@ -2334,7 +2331,7 @@ static void
print_missing_version (int errcode __attribute__ ((unused)),
const char *objname, const char *errstring)
{
- _dl_error_printf ("%s: %s: %s\n", rtld_progname ?: "<program name unknown>",
+ _dl_error_printf ("%s: %s: %s\n", RTLD_PROGNAME,
objname, errstring);
}
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
index a98dfeca33..056d885bd6 100644
--- a/elf/setup-vdso.h
+++ b/elf/setup-vdso.h
@@ -89,7 +89,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
addresses in the vsyscall DSO pages in writev() calls. */
const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
- size_t len = strlen (dsoname);
+ size_t len = strlen (dsoname) + 1;
char *copy = malloc (len);
if (copy == NULL)
_dl_fatal_printf ("out of memory\n");
diff --git a/elf/sln.c b/elf/sln.c
index a585c77817..be39fe41d5 100644
--- a/elf/sln.c
+++ b/elf/sln.c
@@ -176,13 +176,13 @@ makesymlink (src, dest)
if (S_ISDIR (stats.st_mode))
{
fprintf (stderr, _("%s: destination must not be a directory\n"),
- dest);
+ dest);
return 1;
}
else if (unlink (dest) && errno != ENOENT)
{
fprintf (stderr, _("%s: failed to remove the old destination\n"),
- dest);
+ dest);
return 1;
}
}
@@ -205,7 +205,7 @@ makesymlink (src, dest)
error = strerror (errno);
unlink (dest);
fprintf (stderr, _("Invalid link from \"%s\" to \"%s\": %s\n"),
- src, dest, error);
+ src, dest, error);
return 1;
}
return 0;
@@ -214,7 +214,7 @@ makesymlink (src, dest)
{
error = strerror (errno);
fprintf (stderr, _("Invalid link from \"%s\" to \"%s\": %s\n"),
- src, dest, error);
+ src, dest, error);
return 1;
}
}
diff --git a/elf/sprof.c b/elf/sprof.c
index 60f310f47a..ecb7bdb2dc 100644
--- a/elf/sprof.c
+++ b/elf/sprof.c
@@ -1364,7 +1364,7 @@ generate_call_graph (struct profdata *profdata)
runp = runp->next;
}
- /* Info abount the function itself. */
+ /* Info about the function itself. */
n = printf ("[%Zu]", cnt);
printf ("%*s%5.1f%8.2f%8.2f%9" PRIdMAX " %s [%Zd]\n",
(int) (7 - n), " ",
diff --git a/elf/testobj.h b/elf/testobj.h
index 12f18effcc..1707ae340e 100644
--- a/elf/testobj.h
+++ b/elf/testobj.h
@@ -15,14 +15,14 @@ extern int obj3func1 (int);
extern int obj3func2 (int);
extern int obj4func1 (int);
-
+
extern int obj4func2 (int);
-
+
extern int obj5func1 (int);
-
+
extern int obj5func2 (int);
-
+
extern int obj6func1 (int);
-
+
extern int obj6func2 (int);
diff --git a/elf/tst-null-argv-lib.c b/elf/tst-null-argv-lib.c
new file mode 100644
index 0000000000..e754299dc0
--- /dev/null
+++ b/elf/tst-null-argv-lib.c
@@ -0,0 +1,24 @@
+/* Verify that program does not crash when LD_DEBUG is set and the program name
+ is not available. This is the library.
+ Copyright (C) 2013 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/>. */
+
+void
+foo (void)
+{
+ return;
+}
diff --git a/elf/tst-null-argv.c b/elf/tst-null-argv.c
new file mode 100644
index 0000000000..dc242e495d
--- /dev/null
+++ b/elf/tst-null-argv.c
@@ -0,0 +1,35 @@
+/* Verify that program does not crash when LD_DEBUG is set and the program name
+ is not available.
+ Copyright (C) 2013 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/>. */
+
+extern void foo (void);
+
+int
+do_test (int argc, char **argv)
+{
+ argv[0] = argv[1];
+ argc--;
+
+ /* This should result in a symbol lookup, causing a volley of debug output
+ when LD_DEBUG=symbols. */
+ foo ();
+
+ return 0;
+}
+
+#include <test-skeleton.c>
diff --git a/elf/tst-stackguard1.c b/elf/tst-stackguard1.c
index fba60bdc90..2caa4a7807 100644
--- a/elf/tst-stackguard1.c
+++ b/elf/tst-stackguard1.c
@@ -160,7 +160,7 @@ do_test (void)
the 16 runs, something is very wrong. */
int ndifferences = 0;
int ndefaults = 0;
- for (i = 0; i < N; ++i)
+ for (i = 0; i < N; ++i)
{
if (child_stack_chk_guards[i] != child_stack_chk_guards[i+1])
ndifferences++;