ldso: fix invalid early references to extern-linkage libc.page_size
[musl] / ldso / dlstart.c
index 4dbe178..259f5e1 100644 (file)
@@ -1,5 +1,6 @@
 #include <stddef.h>
 #include "dynlink.h"
+#include "libc.h"
 
 #ifndef START
 #define START "_dlstart"
 
 #ifndef GETFUNCSYM
 #define GETFUNCSYM(fp, sym, got) do { \
-       __attribute__((__visibility__("hidden"))) void sym(); \
+       hidden void sym(); \
        static void (*static_func_ptr)() = sym; \
        __asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \
        *(fp) = static_func_ptr; } while(0)
 #endif
 
-__attribute__((__visibility__("hidden")))
-void _dlstart_c(size_t *sp, size_t *dynv)
+hidden void _dlstart_c(size_t *sp, size_t *dynv)
 {
        size_t i, aux[AUX_CNT], dyn[DYN_CNT];
        size_t *rel, rel_size, base;
@@ -140,6 +140,21 @@ void _dlstart_c(size_t *sp, size_t *dynv)
                size_t *rel_addr = (void *)(base + rel[0]);
                *rel_addr = base + rel[2];
        }
+
+       rel = (void *)(base+dyn[DT_RELR]);
+       rel_size = dyn[DT_RELRSZ];
+       size_t *relr_addr = 0;
+       for (; rel_size; rel++, rel_size-=sizeof(size_t)) {
+               if ((rel[0]&1) == 0) {
+                       relr_addr = (void *)(base + rel[0]);
+                       *relr_addr++ += base;
+               } else {
+                       for (size_t i=0, bitmap=rel[0]; bitmap>>=1; i++)
+                               if (bitmap&1)
+                                       relr_addr[i] += base;
+                       relr_addr += 8*sizeof(size_t)-1;
+               }
+       }
 #endif
 
        stage2_func dls2;