[git commit] xtensa: ldso: coalesce dl_mprotect address ranges
Bernhard Reutner-Fischer
rep.dot.nop at gmail.com
Fri Jan 23 20:16:12 UTC 2015
commit: http://git.uclibc.org/uClibc/commit/?id=59f06d06f05abf20092617fcfa34438c77d92bdd
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/master
This noticeably lowers the number of mprotect calls at program startup,
e.g. for busybox: 7 calls vs 1835 calls.
Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
ldso/ldso/xtensa/dl-startup.h | 20 +++++++++++++++++++-
ldso/ldso/xtensa/dl-sysdep.h | 24 +++++++++++++++++++++++-
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h
index b135a4c..0c28d5e 100644
--- a/ldso/ldso/xtensa/dl-startup.h
+++ b/ldso/ldso/xtensa/dl-startup.h
@@ -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); \
} \
\
diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h
index a0ed4e5..5f8bcb0 100644
--- a/ldso/ldso/xtensa/dl-sysdep.h
+++ b/ldso/ldso/xtensa/dl-sysdep.h
@@ -36,6 +36,7 @@ typedef struct xtensa_got_location_struct {
do { \
xtensa_got_location *got_loc; \
Elf32_Addr l_addr = MODULE->loadaddr; \
+ Elf32_Addr prev_got_start = 0, prev_got_end = 0; \
int x; \
\
got_loc = (xtensa_got_location *) \
@@ -47,7 +48,28 @@ typedef struct xtensa_got_location_struct {
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); \
} \
\
More information about the uClibc-cvs
mailing list