summaryrefslogtreecommitdiff
path: root/repo/system/musl/handle-aux-at_base.patch
diff options
context:
space:
mode:
Diffstat (limited to 'repo/system/musl/handle-aux-at_base.patch')
-rw-r--r--repo/system/musl/handle-aux-at_base.patch46
1 files changed, 46 insertions, 0 deletions
diff --git a/repo/system/musl/handle-aux-at_base.patch b/repo/system/musl/handle-aux-at_base.patch
new file mode 100644
index 0000000..7c9f2dc
--- /dev/null
+++ b/repo/system/musl/handle-aux-at_base.patch
@@ -0,0 +1,46 @@
+This is required to make the gcompat ELF interpreter stub work with some
+packed binaries.
+
+diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
+index b125eb1..616c6a6 100644
+--- a/src/env/__init_tls.c
++++ b/src/env/__init_tls.c
+@@ -66,8 +66,10 @@ void *__copy_tls(unsigned char *mem)
+ }
+
+ #if ULONG_MAX == 0xffffffff
++typedef Elf32_Ehdr Ehdr;
+ typedef Elf32_Phdr Phdr;
+ #else
++typedef Elf64_Ehdr Ehdr;
+ typedef Elf64_Phdr Phdr;
+ #endif
+
+@@ -77,15 +79,23 @@ extern const size_t _DYNAMIC[];
+ static void static_init_tls(size_t *aux)
+ {
+ unsigned char *p;
+- size_t n;
++ size_t n, e;
+ Phdr *phdr, *tls_phdr=0;
+ size_t base = 0;
+ void *mem;
+
+- for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
++ if (aux[AT_BASE]) {
++ Ehdr *ehdr = (void *)aux[AT_BASE];
++ p = (unsigned char *)aux[AT_BASE] + ehdr->e_phoff;
++ n = ehdr->e_phnum;
++ e = ehdr->e_phentsize;
++ } else {
++ p = (void *)aux[AT_PHDR];
++ n = aux[AT_PHNUM];
++ e = aux[AT_PHENT];
++ }
++ for (; n; n--, p+=e) {
+ phdr = (void *)p;
+- if (phdr->p_type == PT_PHDR)
+- base = aux[AT_PHDR] - phdr->p_vaddr;
+ if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+ base = (size_t)_DYNAMIC - phdr->p_vaddr;
+ if (phdr->p_type == PT_TLS)