mailing list of musl libc
 help / color / mirror / code / Atom feed
6af5037032c8a8607b48c50cf507a666ebe6eb66 blob 3264 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
 
#include <stddef.h>
#include "dynlink.h"

#ifdef SHARED

#ifndef START
#define START "_dlstart"
#endif

#include "crt_arch.h"

__attribute__((__visibility__("hidden")))
void _dlstart_c(size_t *sp, size_t *dynv)
{
	size_t i, aux[AUX_CNT], dyn[DYN_CNT];

	int argc = *sp;
	char **argv = (void *)(sp+1);

	for (i=argc+1; argv[i]; i++);
	size_t *auxv = (void *)(argv+i+1);

	for (i=0; i<AUX_CNT; i++) aux[i] = 0;
	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT)
		aux[auxv[i]] = auxv[i+1];

	for (i=0; i<DYN_CNT; i++) dyn[i] = 0;
	for (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT)
		dyn[dynv[i]] = dynv[i+1];

	/* If the dynamic linker is invoked as a command, its load
	 * address is not available in the aux vector. Instead, compute
	 * the load address as the difference between &_DYNAMIC and the
	 * virtual address in the PT_DYNAMIC program header. */
	unsigned char *base = (void *)aux[AT_BASE];
	if (!base) {
		size_t phnum = aux[AT_PHNUM];
		size_t phentsize = aux[AT_PHENT];
		Phdr *ph = (void *)aux[AT_PHDR];
		for (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) {
			if (ph->p_type == PT_DYNAMIC) {
				base = (void *)((size_t)dynv - ph->p_vaddr);
				break;
			}
		}
	}

	/* MIPS uses an ugly packed form for GOT relocations. Since we
	 * can't make function calls yet and the code is tiny anyway,
	 * it's simply inlined here. */
	if (NEED_MIPS_GOT_RELOCS) {
		size_t local_cnt = 0;
		size_t *got = (void *)(base + dyn[DT_PLTGOT]);
		for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO)
			local_cnt = dynv[i+1];
		for (i=0; i<local_cnt; i++) got[i] += (size_t)base;
	}

	size_t *rel, rel_size, symbolic_rel_cnt=0;

	rel = (void *)(base+dyn[DT_REL]);
	rel_size = dyn[DT_RELSZ];
	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
		if (!IS_RELATIVE(rel[1])) {
			symbolic_rel_cnt++;
			continue;
		}
		size_t *rel_addr = (void *)(base + rel[0]);
		*rel_addr += (size_t)base;
	}

	rel = (void *)(base+dyn[DT_RELA]);
	rel_size = dyn[DT_RELASZ];
	for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
		if (!IS_RELATIVE(rel[1])) continue;
		size_t *rel_addr = (void *)(base + rel[0]);
		*rel_addr = (size_t)base + rel[2];
	}

	/* Prepare storage for stages 2 to save clobbered REL
	 * addends so they can be reused in stage 3. There should
	 * be very few. If something goes wrong and there are a
	 * huge number, pass a null pointer to trigger stage 2
	 * to abort instead of risking stack overflow. */
	int too_many_addends = symbolic_rel_cnt > 4096;
	size_t naddends = too_many_addends ? 1 : symbolic_rel_cnt;
	size_t addends[naddends];
	size_t *paddends = too_many_addends ? 0 : addends;

	const char *strings = (void *)(base + dyn[DT_STRTAB]);
	const Sym *syms = (void *)(base + dyn[DT_SYMTAB]);

	/* Call dynamic linker stage-2, __dls2 */
	for (i=0; ;i++) {
		const char *s = strings + syms[i].st_name;
		if (s[0]=='_' && s[1]=='_' && s[2]=='d'
		 && s[3]=='l' && s[4]=='s' && s[5]=='2' && !s[6])
			break;
	}
	((stage2_func)(base + syms[i].st_value))(base, paddends);

	/* Call dynamic linker stage-3, __dls3 */
	for (i=0; ;i++) {
		const char *s = strings + syms[i].st_name;
		if (s[0]=='_' && s[1]=='_' && s[2]=='d'
		 && s[3]=='l' && s[4]=='s' && s[5]=='3' && !s[6])
			break;
	}
	((stage3_func)(base + syms[i].st_value))(sp);
}

#endif
debug log:

solving 6af5037 ...
found 6af5037 in https://inbox.vuxu.org/musl/20150525214512.GU17573@brightrain.aerifal.cx/
found 5f84465 in https://git.vuxu.org/mirror/musl/
preparing index
index prepared:
100644 5f84465c6182d549fec5350aba79d2edef72a91b	src/ldso/dlstart.c

applying [1/1] https://inbox.vuxu.org/musl/20150525214512.GU17573@brightrain.aerifal.cx/
diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c
index 5f84465..6af5037 100644

Checking patch src/ldso/dlstart.c...
Applied patch src/ldso/dlstart.c cleanly.

index at:
100644 6af5037032c8a8607b48c50cf507a666ebe6eb66	src/ldso/dlstart.c

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).