OSDN Git Service

xtensa: ldso: coalesce dl_mprotect address ranges
[uclinux-h8/uClibc.git] / ldso / ldso / xtensa / dl-startup.h
index b135a4c..0c28d5e 100644 (file)
@@ -83,6 +83,7 @@ do { \
        unsigned long l_addr = tpnt->loadaddr; \
        Elf32_Word relative_count; \
        unsigned long rel_addr; \
+       Elf32_Addr prev_got_start = 0, prev_got_end = 0; \
        int x; \
 \
        got_loc = (xtensa_got_location *) \
@@ -93,7 +94,24 @@ do { \
                got_start = got_loc[x].offset & ~(PAGE_SIZE - 1); \
                got_end = ((got_loc[x].offset + got_loc[x].length + PAGE_SIZE - 1) \
                                   & ~(PAGE_SIZE - 1)); \
-               _dl_mprotect ((void *)(got_start + l_addr), got_end - got_start, \
+               if (got_end >= prev_got_start && got_start <= prev_got_end) { \
+                       if (got_end > prev_got_end) \
+                               prev_got_end = got_end; \
+                       if (got_start < prev_got_start) \
+                               prev_got_start = got_start; \
+                       continue; \
+               } else if (prev_got_start != prev_got_end) { \
+                       _dl_mprotect ((void *)(prev_got_start + l_addr), \
+                                                 prev_got_end - prev_got_start, \
+                                                 PROT_READ | PROT_WRITE | PROT_EXEC); \
+               } \
+               prev_got_start = got_start; \
+               prev_got_end = got_end; \
+       } \
+\
+       if (prev_got_start != prev_got_end) { \
+               _dl_mprotect ((void *)(prev_got_start + l_addr), \
+                                         prev_got_end - prev_got_start, \
                                          PROT_READ | PROT_WRITE | PROT_EXEC); \
        } \
 \