summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-03-03 13:24:23 -0500
committerRich Felker <dalias@aerifal.cx>2019-03-03 13:24:23 -0500
commit43e7efb46555f13a556d92944ac05c19b8929b60 (patch)
treea6def1b293af724d0745d47c9f04e36770da02b2
parentf034f145bdf7541995eaf08451275329e09694d8 (diff)
avoid malloc of ctor queue for programs with no external deps
together with the previous two commits, this completes restoration of the property that dynamic-linked apps with no external deps and no tls have no failure paths before entry.
-rw-r--r--ldso/dynlink.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 4f090ada..35cacd76 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -30,6 +30,7 @@ static void error(const char *, ...);
#define ALIGN(x,y) ((x)+(y)-1 & -(y))
#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))
+#define countof(a) ((sizeof (a))/(sizeof (a)[0]))
struct debug {
int ver;
@@ -135,6 +136,7 @@ static pthread_mutex_t init_fini_lock;
static pthread_cond_t ctor_cond;
static struct dso *builtin_deps[2];
static struct dso *const no_deps[1];
+static struct dso *builtin_ctor_queue[4];
static struct dso **main_ctor_queue;
static struct fdpic_loadmap *app_loadmap;
static struct fdpic_dummy_loadmap app_dummy_loadmap;
@@ -1405,7 +1407,10 @@ static struct dso **queue_ctors(struct dso *dso)
p->mark = 0;
}
cnt++; /* termination slot */
- stack = queue = calloc(cnt, sizeof *queue);
+ if (dso==head && cnt <= countof(builtin_ctor_queue))
+ queue = builtin_ctor_queue;
+ else
+ queue = calloc(cnt, sizeof *queue);
if (!queue) {
error("Error allocating constructor queue: %m\n");
@@ -1416,6 +1421,7 @@ static struct dso **queue_ctors(struct dso *dso)
/* Opposite ends of the allocated buffer serve as an output queue
* and a working stack. Setup initial stack with just the argument
* dso and initial queue empty... */
+ stack = queue;
qpos = 0;
spos = cnt;
stack[--spos] = dso;
@@ -1487,7 +1493,8 @@ static void do_init_fini(struct dso **queue)
void __libc_start_init(void)
{
do_init_fini(main_ctor_queue);
- if (!__malloc_replaced) free(main_ctor_queue);
+ if (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)
+ free(main_ctor_queue);
main_ctor_queue = 0;
}