#include <elf.h>
#include <sys/mman.h>
#include <limits.h>
-#include <stdint.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
-#include <limits.h>
-#include <elf.h>
#include <link.h>
#include <setjmp.h>
#include <pthread.h>
void *__install_initial_tls(void *);
void __init_libc(char **, char *);
+const char *__libc_get_version(void);
+
static struct dso *head, *tail, *ldso, *fini_head;
static char *env_path, *sys_path;
static unsigned long long gencnt;
name = strings + sym->st_name;
ctx = IS_COPY(type) ? head->next : head;
def = find_sym(ctx, name, IS_PLT(type));
- if (!def.sym && sym->st_info>>4 != STB_WEAK) {
+ if (!def.sym && (sym->st_shndx != SHN_UNDEF
+ || sym->st_info>>4 != STB_WEAK)) {
snprintf(errbuf, sizeof errbuf,
"Error relocating %s: %s: symbol not found",
dso->name, name);
}
n = 0;
s = p->rpath_orig;
- while ((t=strstr(s, "$ORIGIN")) || (t=strstr(s, "${ORIGIN}"))) {
+ while ((t=strchr(s, '$'))) {
+ if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
+ return -1;
s = t+1;
n++;
}
* (either system paths or a call to dlopen). */
if (libc.secure)
return -1;
- if (readlink("/proc/self/exe", buf, buf_size) >= buf_size)
+ l = readlink("/proc/self/exe", buf, buf_size);
+ if (l >= buf_size)
return -1;
+ buf[l] = 0;
origin = buf;
} else {
origin = p->name;
d = p->rpath;
s = p->rpath_orig;
- while ((t=strstr(s, "$ORIGIN")) || (t=strstr(s, "${ORIGIN}"))) {
+ while ((t=strchr(s, '$'))) {
memcpy(d, s, t-s);
d += t-s;
memcpy(d, origin, l);
d += l;
+ /* It was determined previously that the '$' is followed
+ * either by "ORIGIN" or "{ORIGIN}". */
s = t + 7 + 2*(t[1]=='{');
}
strcpy(d, s);
sys_path = "";
}
fclose(f);
+ } else if (errno != ENOENT) {
+ sys_path = "";
}
}
if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
env_preload = 0;
libc.secure = 1;
}
+ libc.page_size = aux[AT_PAGESZ];
/* If the dynamic linker was invoked as a program itself, AT_BASE
* will not be set. In that case, we assume the base address is
}
if (app->tls_size) app->tls_image = (char *)app->base + tls_image;
if (interp_off) lib->name = (char *)app->base + interp_off;
- app->name = argv[0];
+ if ((aux[0] & (1UL<<AT_EXECFN))
+ && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
+ app->name = (char *)aux[AT_EXECFN];
+ else
+ app->name = argv[0];
app->kernel_mapped = 1;
app->dynv = (void *)(app->base + find_dyn(
(void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT]));
*argv++ = (void *)-1;
if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1;
if (!argv[0]) {
- dprintf(2, "musl libc/dynamic program loader\n");
- dprintf(2, "usage: %s pathname%s\n", ldname,
+ dprintf(2, "musl libc\n"
+ "Version %s\n"
+ "Dynamic Program Loader\n"
+ "Usage: %s [--] pathname%s\n",
+ __libc_get_version(), ldname,
ldd_mode ? "" : " [args]");
_exit(1);
}
p = 0;
errflag = 1;
goto end;
- } else p = load_library(file, 0);
+ } else p = load_library(file, head);
if (!p) {
snprintf(errbuf, sizeof errbuf, noload ?
return 0;
}
-int __dladdr(void *addr, Dl_info *info)
+int __dladdr(const void *addr, Dl_info *info)
{
struct dso *p;
Sym *sym;
uint32_t *hashval;
buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
sym += p->ghashtab[1];
- for (i = 0; i < p->ghashtab[0]; i++) {
+ for (i = nsym = 0; i < p->ghashtab[0]; i++) {
if (buckets[i] > nsym)
nsym = buckets[i];
}
{
return 0;
}
-int __dladdr (void *addr, Dl_info *info)
+int __dladdr (const void *addr, Dl_info *info)
{
return 0;
}