Browse Source

avoid malloc of deps array for programs with no external deps

traditionally, we've provided a guarantee that dynamic-linked
applications with no external dependencies (nothing but libc) and no
thread-local storage have no failure paths before the entry point.
normally, thanks to reclaim_gaps, such a malloc will not require a
syscall anyway, but if segment alignment is unlucky, it might. use a
builtin array for this common special case.
master
Rich Felker 7 years ago
parent
commit
e612d094b1
  1. 13
      ldso/dynlink.c

13
ldso/dynlink.c

@ -133,6 +133,7 @@ static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
static size_t static_tls_cnt; static size_t static_tls_cnt;
static pthread_mutex_t init_fini_lock; static pthread_mutex_t init_fini_lock;
static pthread_cond_t ctor_cond; static pthread_cond_t ctor_cond;
static struct dso *builtin_deps[2];
static struct dso **main_ctor_queue; static struct dso **main_ctor_queue;
static struct fdpic_loadmap *app_loadmap; static struct fdpic_loadmap *app_loadmap;
static struct fdpic_dummy_loadmap app_dummy_loadmap; static struct fdpic_dummy_loadmap app_dummy_loadmap;
@ -1152,6 +1153,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
static void load_direct_deps(struct dso *p) static void load_direct_deps(struct dso *p)
{ {
size_t i, cnt=0; size_t i, cnt=0;
if (p->deps) return; if (p->deps) return;
/* For head, all preloads are direct pseudo-dependencies. /* For head, all preloads are direct pseudo-dependencies.
* Count and include them now to avoid realloc later. */ * Count and include them now to avoid realloc later. */
@ -1159,7 +1161,10 @@ static void load_direct_deps(struct dso *p)
cnt++; cnt++;
for (i=0; p->dynv[i]; i+=2) for (i=0; p->dynv[i]; i+=2)
if (p->dynv[i] == DT_NEEDED) cnt++; if (p->dynv[i] == DT_NEEDED) cnt++;
p->deps = calloc(cnt+1, sizeof *p->deps); /* Use builtin buffer for apps with no external deps, to
* preserve property of no runtime failure paths. */
p->deps = (p==head && cnt<2) ? builtin_deps :
calloc(cnt+1, sizeof *p->deps);
if (!p->deps) { if (!p->deps) {
error("Error loading dependencies for %s", p->name); error("Error loading dependencies for %s", p->name);
if (runtime) longjmp(*rtld_fail, 1); if (runtime) longjmp(*rtld_fail, 1);
@ -1195,8 +1200,10 @@ static void extend_bfs_deps(struct dso *p)
struct dso **tmp; struct dso **tmp;
/* Can't use realloc if the original p->deps was allocated at /* Can't use realloc if the original p->deps was allocated at
* program entry and malloc has been replaced. */ * program entry and malloc has been replaced, or if it's
int no_realloc = __malloc_replaced && !p->runtime_loaded; * the builtin non-allocated trivial main program deps array. */
int no_realloc = (__malloc_replaced && !p->runtime_loaded)
|| p->deps == builtin_deps;
if (p->bfs_built) return; if (p->bfs_built) return;
ndeps_all = p->ndeps_direct; ndeps_all = p->ndeps_direct;

Loading…
Cancel
Save