Bug 687147 - Ensure Instruction and Data cache coherency after extracting libraries. r=mwu
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 23 Sep 2011 14:31:11 +0200
changeset 78727 e299d7fed89dd5fe24a234c226b4f3353a4eb338
parent 78726 c0b96cb41fc1f4a808afbe5278320f18429e0f7a
child 78728 b412c07605722b8a55d5849d4cd61404cfd2b857
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmwu
bugs687147
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 687147 - Ensure Instruction and Data cache coherency after extracting libraries. r=mwu
other-licenses/android/APKOpen.cpp
other-licenses/android/linker.c
--- a/other-licenses/android/APKOpen.cpp
+++ b/other-licenses/android/APKOpen.cpp
@@ -510,16 +510,21 @@ static void * mozload(const char * path,
       close(fd);
       return NULL;
     }
 
     offset = 0;
 
     if (cache_fd < 0) {
       extractLib(entry, data, buf);
+#ifdef ANDROID_ARM_LINKER
+      /* We just extracted data that is going to be executed in the future.
+       * We thus need to ensure Instruction and Data cache coherency. */
+      cacheflush((unsigned) buf, (unsigned) buf + entry->uncompressed_size, 0);
+#endif
       if (!skipLibCache)
         addLibCacheFd(path, fd, lib_size, buf);
     }
 
     // preload libxul, to avoid slowly demand-paging it
     if (!strcmp(path, "libxul.so"))
       madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
     data = buf;
--- a/other-licenses/android/linker.c
+++ b/other-licenses/android/linker.c
@@ -1411,16 +1411,18 @@ static int reloc_library(soinfo *si, Elf
     Elf32_Rel *start = rel;
     unsigned idx;
 
     /* crappy hack to ensure we don't write into the read-only region */
 
     /* crappy hack part 1: find the read only region */
     int cnt;
     void * ro_region_end = si->base;
+    unsigned lowest_text_rel = 0xffffffff;
+
     Elf32_Ehdr *ehdr = (Elf32_Ehdr *)si->base;
     Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned char *)si->base + ehdr->e_phoff);
     for (cnt = 0; cnt < ehdr->e_phnum; ++cnt, ++phdr) {
         if (phdr->p_type != PT_LOAD ||
             PFLAGS_TO_PROT(phdr->p_flags) & PROT_WRITE)
             continue;
 
         if (si->base + phdr->p_vaddr + phdr->p_filesz > ro_region_end)
@@ -1531,16 +1533,18 @@ static int reloc_library(soinfo *si, Elf
                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
                      -1, 0) == MAP_FAILED)
                 DL_ERR("failed to map page for %s at 0x%08x! errno=%d",
                        si->name, reloc_page, errno);
 
             memcpy(reloc_page, copy_page, PAGE_SIZE);
             remapped_page = reloc_page;
         }
+        if ((reloc < ro_region_end) && (reloc < lowest_text_rel))
+            lowest_text_rel = reloc & ~PAGE_MASK;
 
 /* TODO: This is ugly. Split up the relocations by arch into
  * different files.
  */
         switch(type){
 #if defined(ANDROID_ARM_LINKER)
         case R_ARM_JUMP_SLOT:
             COUNT_RELOC(RELOC_ABSOLUTE);
@@ -1637,18 +1641,25 @@ static int reloc_library(soinfo *si, Elf
 
         default:
             DL_ERR("%5d unknown reloc type %d @ %p (%d)",
                   pid, type, rel, (int) (rel - start));
             return -1;
         }
         rel++;
     }
-    if (copy_page)
+    if (copy_page) {
         munmap(copy_page, PAGE_SIZE);
+#if defined(ANDROID_ARM_LINKER)
+        /* If we have a copy_page, it means we applied text relocations,
+         * which, in turn, means we need to maintain Instruction and Data
+         * caches coherent */
+        cacheflush(lowest_text_rel, (unsigned) ro_region_end, 0);
+#endif
+    }
     return 0;
 }
 
 #if defined(ANDROID_SH_LINKER)
 static int reloc_library_a(soinfo *si, Elf32_Rela *rela, unsigned count)
 {
     Elf32_Sym *symtab = si->symtab;
     const char *strtab = si->strtab;
@@ -1797,17 +1808,17 @@ static void call_constructors(soinfo *si
 
     if (si->init_func) {
         TRACE("[ %5d Calling init_func @ 0x%08x for '%s' ]\n", pid,
               (unsigned)si->init_func, si->name);
         si->init_func();
         TRACE("[ %5d Done calling init_func for '%s' ]\n", pid, si->name);
     }
 
-    if (si->init_array && strncmp(si->name, "libmozalloc.so", 14)) {
+    if (si->init_array) {
         TRACE("[ %5d Calling init_array @ 0x%08x [%d] for '%s' ]\n", pid,
               (unsigned)si->init_array, si->init_array_count, si->name);
         call_array(si->init_array, si->init_array_count, 0);
         TRACE("[ %5d Done calling init_array for '%s' ]\n", pid, si->name);
     }
 }