Bug 1024248 - Properly tag linker error/warnings in logcat. r=nfroyd
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 13 Jun 2014 08:45:58 +0900
changeset 188616 79eab42e54839fef24c3e1604466e64a1c082277
parent 188615 5264e512b53c015f7b5a540731b950f341245c55
child 188617 0857ad15c4d75ffc1750a09fe2bc54004e61f5ed
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersnfroyd
bugs1024248
milestone33.0a1
Bug 1024248 - Properly tag linker error/warnings in logcat. r=nfroyd
mozglue/linker/CustomElf.cpp
mozglue/linker/Logging.h
mozglue/linker/Mappable.cpp
mozglue/linker/SeekableZStream.cpp
mozglue/linker/Zip.cpp
mozglue/linker/szip.cpp
--- a/mozglue/linker/CustomElf.cpp
+++ b/mozglue/linker/CustomElf.cpp
@@ -144,57 +144,57 @@ CustomElf::Load(Mappable *mappable, cons
         if (max_vaddr < phdr->p_vaddr + phdr->p_memsz)
           max_vaddr = phdr->p_vaddr + phdr->p_memsz;
         break;
       case PT_DYNAMIC:
         debug_phdr("PT_DYNAMIC", phdr);
         if (!dyn) {
           dyn = phdr;
         } else {
-          LOG("%s: Multiple PT_DYNAMIC segments detected", elf->GetPath());
+          ERROR("%s: Multiple PT_DYNAMIC segments detected", elf->GetPath());
           return nullptr;
         }
         break;
       case PT_TLS:
         debug_phdr("PT_TLS", phdr);
         if (phdr->p_memsz) {
-          LOG("%s: TLS is not supported", elf->GetPath());
+          ERROR("%s: TLS is not supported", elf->GetPath());
           return nullptr;
         }
         break;
       case PT_GNU_STACK:
         debug_phdr("PT_GNU_STACK", phdr);
 // Skip on Android until bug 706116 is fixed
 #ifndef ANDROID
         if (phdr->p_flags & PF_X) {
-          LOG("%s: Executable stack is not supported", elf->GetPath());
+          ERROR("%s: Executable stack is not supported", elf->GetPath());
           return nullptr;
         }
 #endif
         break;
 #ifdef __ARM_EABI__
       case PT_ARM_EXIDX:
         /* We cannot initialize arm_exidx here
            because we don't have a base yet */
         arm_exidx_phdr = phdr;
         break;
 #endif
       default:
-        DEBUG_LOG("%s: Warning: program header type #%d not handled",
+        DEBUG_LOG("%s: Program header type #%d not handled",
                   elf->GetPath(), phdr->p_type);
     }
   }
 
   if (min_vaddr != 0) {
-    LOG("%s: Unsupported minimal virtual address: 0x%08" PRIxAddr,
+    ERROR("%s: Unsupported minimal virtual address: 0x%08" PRIxAddr,
         elf->GetPath(), min_vaddr);
     return nullptr;
   }
   if (!dyn) {
-    LOG("%s: No PT_DYNAMIC segment found", elf->GetPath());
+    ERROR("%s: No PT_DYNAMIC segment found", elf->GetPath());
     return nullptr;
   }
 
   /* Reserve enough memory to map the complete virtual address space for this
    * library.
    * As we are using the base address from here to mmap something else with
    * MAP_FIXED | MAP_SHARED, we need to make sure these mmaps will work. For
    * instance, on armv6, MAP_SHARED mappings require a 16k alignment, but mmap
@@ -203,17 +203,17 @@ CustomElf::Load(Mappable *mappable, cons
    * that we'll be able to use with MAP_FIXED, and then remap MAP_PRIVATE at
    * the same address, because of some bad side effects of keeping it as
    * MAP_SHARED. */
   elf->base.Assign(MemoryRange::mmap(nullptr, max_vaddr, PROT_NONE,
                                      MAP_SHARED | MAP_ANONYMOUS, -1, 0));
   if ((elf->base == MAP_FAILED) ||
       (mmap(elf->base, max_vaddr, PROT_NONE,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != elf->base)) {
-    LOG("%s: Failed to mmap", elf->GetPath());
+    ERROR("%s: Failed to mmap", elf->GetPath());
     return nullptr;
   }
 
   /* Load and initialize library */
   for (std::vector<const Phdr *>::iterator it = pt_loads.begin();
        it < pt_loads.end(); ++it)
     if (!elf->LoadSegment(*it))
       return nullptr;
@@ -477,19 +477,19 @@ CustomElf::LoadSegment(const Phdr *pt_lo
      * and fail to mmap. In such case, try to mmap again at the p_align
      * boundary instead of page boundary. */
     DEBUG_LOG("%s: Failed to mmap, retrying", GetPath());
     align = pt_load->p_align;
   } while (1);
 
   if (mapped != where) {
     if (mapped == MAP_FAILED) {
-      LOG("%s: Failed to mmap", GetPath());
+      ERROR("%s: Failed to mmap", GetPath());
     } else {
-      LOG("%s: Didn't map at the expected location (wanted: %p, got: %p)",
+      ERROR("%s: Didn't map at the expected location (wanted: %p, got: %p)",
           GetPath(), where, mapped);
     }
     return false;
   }
 
   /* Ensure the availability of all pages within the mapping if on-demand
    * decompression is disabled (MOZ_LINKER_ONDEMAND=0 or signal handler not
    * registered). */
@@ -515,17 +515,17 @@ CustomElf::LoadSegment(const Phdr *pt_lo
       /* The library is not registered at this point, so we can't rely on
        * on-demand decompression to handle missing pages here. */
       void *ptr = GetPtr(file_end);
       mappable->ensure(ptr);
       memset(ptr, 0, next_page - file_end);
     }
     if (mem_end > next_page) {
       if (mprotect(GetPtr(next_page), mem_end - next_page, prot) < 0) {
-        LOG("%s: Failed to mprotect", GetPath());
+        ERROR("%s: Failed to mprotect", GetPath());
         return false;
       }
     }
   }
   return true;
 }
 
 namespace {
@@ -566,48 +566,48 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
         break;
       case DT_SYMTAB:
         debug_dyn("DT_SYMTAB", dyn);
         symtab.Init(GetPtr(dyn->d_un.d_ptr));
         break;
       case DT_SYMENT:
         debug_dyn("DT_SYMENT", dyn);
         if (dyn->d_un.d_val != sizeof(Sym)) {
-          LOG("%s: Unsupported DT_SYMENT", GetPath());
+          ERROR("%s: Unsupported DT_SYMENT", GetPath());
           return false;
         }
         break;
       case DT_TEXTREL:
         if (strcmp("libflashplayer.so", GetName()) == 0) {
           has_text_relocs = true;
         } else {
-          LOG("%s: Text relocations are not supported", GetPath());
+          ERROR("%s: Text relocations are not supported", GetPath());
           return false;
         }
         break;
       case DT_STRSZ: /* Ignored */
         debug_dyn("DT_STRSZ", dyn);
         break;
       case UNSUPPORTED_RELOC():
       case UNSUPPORTED_RELOC(SZ):
       case UNSUPPORTED_RELOC(ENT):
-        LOG("%s: Unsupported relocations", GetPath());
+        ERROR("%s: Unsupported relocations", GetPath());
         return false;
       case RELOC():
         debug_dyn(STR_RELOC(), dyn);
         relocations.Init(GetPtr(dyn->d_un.d_ptr));
         break;
       case RELOC(SZ):
         debug_dyn(STR_RELOC(SZ), dyn);
         relocations.InitSize(dyn->d_un.d_val);
         break;
       case RELOC(ENT):
         debug_dyn(STR_RELOC(ENT), dyn);
         if (dyn->d_un.d_val != sizeof(Reloc)) {
-          LOG("%s: Unsupported DT_RELENT", GetPath());
+          ERROR("%s: Unsupported DT_RELENT", GetPath());
           return false;
         }
         break;
       case DT_JMPREL:
         debug_dyn("DT_JMPREL", dyn);
         jumprels.Init(GetPtr(dyn->d_un.d_ptr));
         break;
       case DT_PLTRELSZ:
@@ -638,36 +638,36 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
         fini_array.Init(GetPtr(dyn->d_un.d_ptr));
         break;
       case DT_FINI_ARRAYSZ:
         debug_dyn("DT_FINI_ARRAYSZ", dyn);
         fini_array.InitSize(dyn->d_un.d_val);
         break;
       case DT_PLTREL:
         if (dyn->d_un.d_val != RELOC()) {
-          LOG("%s: Error: DT_PLTREL is not " STR_RELOC(), GetPath());
+          ERROR("%s: Error: DT_PLTREL is not " STR_RELOC(), GetPath());
           return false;
         }
         break;
       case DT_FLAGS:
         {
            Addr flags = dyn->d_un.d_val;
            /* Treat as a DT_TEXTREL tag */
            if (flags & DF_TEXTREL) {
              if (strcmp("libflashplayer.so", GetName()) == 0) {
                has_text_relocs = true;
              } else {
-               LOG("%s: Text relocations are not supported", GetPath());
+               ERROR("%s: Text relocations are not supported", GetPath());
                return false;
              }
            }
            /* we can treat this like having a DT_SYMBOLIC tag */
            flags &= ~DF_SYMBOLIC;
            if (flags)
-             LOG("%s: Warning: unhandled flags #%" PRIxAddr" not handled",
+             WARN("%s: unhandled flags #%" PRIxAddr" not handled",
                  GetPath(), flags);
         }
         break;
       case DT_SONAME: /* Should match GetName(), but doesn't matter */
       case DT_SYMBOLIC: /* Indicates internal symbols should be looked up in
                          * the library itself first instead of the executable,
                          * which is actually what this linker does by default */
       case RELOC(COUNT): /* Indicates how many relocations are relative, which
@@ -680,31 +680,31 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
       case DT_VERSYM: /* DT_VER* entries are used for symbol versioning, which */
       case DT_VERDEF: /* this linker doesn't support yet. */
       case DT_VERDEFNUM:
       case DT_VERNEED:
       case DT_VERNEEDNUM:
         /* Ignored */
         break;
       default:
-        LOG("%s: Warning: dynamic header type #%" PRIxAddr" not handled",
+        WARN("%s: dynamic header type #%" PRIxAddr" not handled",
             GetPath(), dyn->d_tag);
     }
   }
 
   if (!buckets || !symnum) {
-    LOG("%s: Missing or broken DT_HASH", GetPath());
+    ERROR("%s: Missing or broken DT_HASH", GetPath());
     return false;
   }
   if (!strtab) {
-    LOG("%s: Missing DT_STRTAB", GetPath());
+    ERROR("%s: Missing DT_STRTAB", GetPath());
     return false;
   }
   if (!symtab) {
-    LOG("%s: Missing DT_SYMTAB", GetPath());
+    ERROR("%s: Missing DT_SYMTAB", GetPath());
     return false;
   }
 
   /* Load dependent libraries */
   for (size_t i = 0; i < dt_needed.size(); i++) {
     const char *name = strtab.GetStringAt(dt_needed[i]);
     RefPtr<LibHandle> handle =
       ElfLoader::Singleton.Load(name, RTLD_GLOBAL | RTLD_LAZY, this);
@@ -741,31 +741,31 @@ CustomElf::Relocate()
         symptr = GetPtr(sym.st_value);
       } else {
         /* TODO: handle symbol resolving to nullptr vs. being undefined. */
         symptr = GetSymbolPtrInDeps(strtab.GetStringAt(sym.st_name));
       }
     }
 
     if (symptr == nullptr)
-      LOG("%s: Warning: relocation to NULL @0x%08" PRIxAddr,
+      WARN("%s: Relocation to NULL @0x%08" PRIxAddr,
           GetPath(), rel->r_offset);
 
     /* Apply relocation */
     switch (ELF_R_TYPE(rel->r_info)) {
     case R_GLOB_DAT:
       /* R_*_GLOB_DAT relocations simply use the symbol value */
       *(void **) ptr = symptr;
       break;
     case R_ABS:
       /* R_*_ABS* relocations add the relocation added to the symbol value */
       *(const char **) ptr = (const char *)symptr + rel->GetAddend(base);
       break;
     default:
-      LOG("%s: Unsupported relocation type: 0x%" PRIxAddr,
+      ERROR("%s: Unsupported relocation type: 0x%" PRIxAddr,
           GetPath(), ELF_R_TYPE(rel->r_info));
       return false;
     }
   }
   return true;
 }
 
 bool
@@ -774,35 +774,39 @@ CustomElf::RelocateJumps()
   /* TODO: Dynamic symbol resolution */
   for (Array<Reloc>::iterator rel = jumprels.begin();
        rel < jumprels.end(); ++rel) {
     /* Location of the relocation */
     void *ptr = GetPtr(rel->r_offset);
 
     /* Only R_*_JMP_SLOT relocations are expected */
     if (ELF_R_TYPE(rel->r_info) != R_JMP_SLOT) {
-      LOG("%s: Jump relocation type mismatch", GetPath());
+      ERROR("%s: Jump relocation type mismatch", GetPath());
       return false;
     }
 
     /* TODO: Avoid code duplication with the relocations above */
     const Sym sym = symtab[ELF_R_SYM(rel->r_info)];
     void *symptr;
     if (sym.st_shndx != SHN_UNDEF)
       symptr = GetPtr(sym.st_value);
     else
       symptr = GetSymbolPtrInDeps(strtab.GetStringAt(sym.st_name));
 
     if (symptr == nullptr) {
-      LOG("%s: %s: relocation to NULL @0x%08" PRIxAddr " for symbol \"%s\"",
-          GetPath(),
-          (ELF_ST_BIND(sym.st_info) == STB_WEAK) ? "Warning" : "Error",
-          rel->r_offset, strtab.GetStringAt(sym.st_name));
-      if (ELF_ST_BIND(sym.st_info) != STB_WEAK)
+      if (ELF_ST_BIND(sym.st_info) == STB_WEAK) {
+        WARN("%s: Relocation to NULL @0x%08" PRIxAddr " for symbol \"%s\"",
+            GetPath(),
+            rel->r_offset, strtab.GetStringAt(sym.st_name));
+      } else {
+        ERROR("%s: Relocation to NULL @0x%08" PRIxAddr " for symbol \"%s\"",
+            GetPath(),
+            rel->r_offset, strtab.GetStringAt(sym.st_name));
         return false;
+      }
     }
     /* Apply relocation */
     *(void **) ptr = symptr;
   }
   return true;
 }
 
 bool
--- a/mozglue/linker/Logging.h
+++ b/mozglue/linker/Logging.h
@@ -4,17 +4,19 @@
 
 #ifndef Logging_h
 #define Logging_h
 
 #include "mozilla/Likely.h"
 
 #ifdef ANDROID
 #include <android/log.h>
-#define LOG(...) __android_log_print(ANDROID_LOG_ERROR, "GeckoLinker", __VA_ARGS__)
+#define LOG(...) __android_log_print(ANDROID_LOG_INFO, "GeckoLinker", __VA_ARGS__)
+#define WARN(...) __android_log_print(ANDROID_LOG_WARN, "GeckoLinker", __VA_ARGS__)
+#define ERROR(...) __android_log_print(ANDROID_LOG_ERROR, "GeckoLinker", __VA_ARGS__)
 #else
 #include <cstdio>
 
 /* Expand to 1 or m depending on whether there is one argument or more
  * given. */
 #define MOZ_ONE_OR_MORE_ARGS_IMPL2(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) \
   N
 #define MOZ_ONE_OR_MORE_ARGS_IMPL(args) MOZ_ONE_OR_MORE_ARGS_IMPL2 args
@@ -30,16 +32,18 @@
  * arguments */
 #define MOZ_CHOOSE_LOG(...) \
   MOZ_MACRO_GLUE(MOZ_CONCAT(LOG, MOZ_ONE_OR_MORE_ARGS(__VA_ARGS__)), \
                  (__VA_ARGS__))
 
 #define LOG1(format) fprintf(stderr, format "\n")
 #define LOGm(format, ...) fprintf(stderr, format "\n", __VA_ARGS__)
 #define LOG(...) MOZ_CHOOSE_LOG(__VA_ARGS__)
+#define WARN(...) MOZ_CHOOSE_LOG("Warning: " __VA_ARGS__)
+#define ERROR(...) MOZ_CHOOSE_LOG("Error: " __VA_ARGS__)
 
 #endif
 
 class Logging
 {
 public:
   static bool isVerbose()
   {
--- a/mozglue/linker/Mappable.cpp
+++ b/mozglue/linker/Mappable.cpp
@@ -54,17 +54,17 @@ MappableFile::GetLength() const
   return fstat(fd, &st) ? 0 : st.st_size;
 }
 
 Mappable *
 MappableExtractFile::Create(const char *name, Zip *zip, Zip::Stream *stream)
 {
   const char *cachePath = getenv("MOZ_LINKER_CACHE");
   if (!cachePath || !*cachePath) {
-    LOG("Warning: MOZ_LINKER_EXTRACT is set, but not MOZ_LINKER_CACHE; "
+    WARN("MOZ_LINKER_EXTRACT is set, but not MOZ_LINKER_CACHE; "
         "not extracting");
     return nullptr;
   }
   mozilla::ScopedDeleteArray<char> path;
   path = new char[strlen(cachePath) + strlen(name) + 2];
   sprintf(path, "%s/%s", cachePath, name);
   struct stat cacheStat;
   if (stat(path, &cacheStat) == 0) {
@@ -75,73 +75,73 @@ MappableExtractFile::Create(const char *
       return MappableFile::Create(path);
     }
   }
   DEBUG_LOG("Extracting to %s", static_cast<char *>(path));
   AutoCloseFD fd;
   fd = open(path, O_TRUNC | O_RDWR | O_CREAT | O_NOATIME,
                   S_IRUSR | S_IWUSR);
   if (fd == -1) {
-    LOG("Couldn't open %s to decompress library", path.get());
+    ERROR("Couldn't open %s to decompress library", path.get());
     return nullptr;
   }
   AutoUnlinkFile file;
   file = path.forget();
   if (stream->GetType() == Zip::Stream::DEFLATE) {
     if (ftruncate(fd, stream->GetUncompressedSize()) == -1) {
-      LOG("Couldn't ftruncate %s to decompress library", file.get());
+      ERROR("Couldn't ftruncate %s to decompress library", file.get());
       return nullptr;
     }
     /* Map the temporary file for use as inflate buffer */
     MappedPtr buffer(MemoryRange::mmap(nullptr, stream->GetUncompressedSize(),
                                        PROT_WRITE, MAP_SHARED, fd, 0));
     if (buffer == MAP_FAILED) {
-      LOG("Couldn't map %s to decompress library", file.get());
+      ERROR("Couldn't map %s to decompress library", file.get());
       return nullptr;
     }
 
     z_stream zStream = stream->GetZStream(buffer);
 
     /* Decompress */
     if (inflateInit2(&zStream, -MAX_WBITS) != Z_OK) {
-      LOG("inflateInit failed: %s", zStream.msg);
+      ERROR("inflateInit failed: %s", zStream.msg);
       return nullptr;
     }
     if (inflate(&zStream, Z_FINISH) != Z_STREAM_END) {
-      LOG("inflate failed: %s", zStream.msg);
+      ERROR("inflate failed: %s", zStream.msg);
       return nullptr;
     }
     if (inflateEnd(&zStream) != Z_OK) {
-      LOG("inflateEnd failed: %s", zStream.msg);
+      ERROR("inflateEnd failed: %s", zStream.msg);
       return nullptr;
     }
     if (zStream.total_out != stream->GetUncompressedSize()) {
-      LOG("File not fully uncompressed! %ld / %d", zStream.total_out,
+      ERROR("File not fully uncompressed! %ld / %d", zStream.total_out,
           static_cast<unsigned int>(stream->GetUncompressedSize()));
       return nullptr;
     }
   } else if (stream->GetType() == Zip::Stream::STORE) {
     SeekableZStream zStream;
     if (!zStream.Init(stream->GetBuffer(), stream->GetSize())) {
-      LOG("Couldn't initialize SeekableZStream for %s", name);
+      ERROR("Couldn't initialize SeekableZStream for %s", name);
       return nullptr;
     }
     if (ftruncate(fd, zStream.GetUncompressedSize()) == -1) {
-      LOG("Couldn't ftruncate %s to decompress library", file.get());
+      ERROR("Couldn't ftruncate %s to decompress library", file.get());
       return nullptr;
     }
     MappedPtr buffer(MemoryRange::mmap(nullptr, zStream.GetUncompressedSize(),
                                        PROT_WRITE, MAP_SHARED, fd, 0));
     if (buffer == MAP_FAILED) {
-      LOG("Couldn't map %s to decompress library", file.get());
+      ERROR("Couldn't map %s to decompress library", file.get());
       return nullptr;
     }
 
     if (!zStream.Decompress(buffer, 0, zStream.GetUncompressedSize())) {
-      LOG("%s: failed to decompress", name);
+      ERROR("%s: failed to decompress", name);
       return nullptr;
     }
   } else {
     return nullptr;
   }
 
   return new MappableExtractFile(fd.forget(), file.forget());
 }
@@ -307,36 +307,36 @@ MappableDeflate::mmap(const void *addr, 
   /* The deflate stream is uncompressed up to the required offset + length, if
    * it hasn't previously been uncompressed */
   ssize_t missing = offset + length + zStream.avail_out - buffer->GetLength();
   if (missing > 0) {
     uInt avail_out = zStream.avail_out;
     zStream.avail_out = missing;
     if ((*buffer == zStream.next_out) &&
         (inflateInit2(&zStream, -MAX_WBITS) != Z_OK)) {
-      LOG("inflateInit failed: %s", zStream.msg);
+      ERROR("inflateInit failed: %s", zStream.msg);
       return MemoryRange(MAP_FAILED, 0);
     }
     int ret = inflate(&zStream, Z_SYNC_FLUSH);
     if (ret < 0) {
-      LOG("inflate failed: %s", zStream.msg);
+      ERROR("inflate failed: %s", zStream.msg);
       return MemoryRange(MAP_FAILED, 0);
     }
     if (ret == Z_NEED_DICT) {
-      LOG("zstream requires a dictionary. %s", zStream.msg);
+      ERROR("zstream requires a dictionary. %s", zStream.msg);
       return MemoryRange(MAP_FAILED, 0);
     }
     zStream.avail_out = avail_out - missing + zStream.avail_out;
     if (ret == Z_STREAM_END) {
       if (inflateEnd(&zStream) != Z_OK) {
-        LOG("inflateEnd failed: %s", zStream.msg);
+        ERROR("inflateEnd failed: %s", zStream.msg);
         return MemoryRange(MAP_FAILED, 0);
       }
       if (zStream.total_out != buffer->GetLength()) {
-        LOG("File not fully uncompressed! %ld / %d", zStream.total_out,
+        ERROR("File not fully uncompressed! %ld / %d", zStream.total_out,
             static_cast<unsigned int>(buffer->GetLength()));
         return MemoryRange(MAP_FAILED, 0);
       }
     }
   }
 #if defined(ANDROID) && defined(__arm__)
   if (prot & PROT_EXEC) {
     /* We just extracted data that may be executed in the future.
@@ -557,19 +557,18 @@ MappableSeekableZStream::ensure(const vo
   length = reinterpret_cast<uintptr_t>(end)
            - reinterpret_cast<uintptr_t>(start);
 
   if (mprotect(const_cast<void *>(start), length, map->prot) == 0) {
     DEBUG_LOG("mprotect @%p, 0x%" PRIxSize ", 0x%x", start, length, map->prot);
     return true;
   }
 
-  LOG("mprotect @%p, 0x%" PRIxSize ", 0x%x failed with errno %d",
+  ERROR("mprotect @%p, 0x%" PRIxSize ", 0x%x failed with errno %d",
       start, length, map->prot, errno);
-  LOG("mprotect failed");
   return false;
 }
 
 void
 MappableSeekableZStream::stats(const char *when, const char *name) const
 {
   size_t nEntries = zStream.GetChunksNum();
   DEBUG_LOG("%s: %s; %" PRIdSize "/%" PRIdSize " chunks decompressed",
--- a/mozglue/linker/SeekableZStream.cpp
+++ b/mozglue/linker/SeekableZStream.cpp
@@ -6,17 +6,17 @@
 #include "SeekableZStream.h"
 #include "Logging.h"
 
 bool
 SeekableZStream::Init(const void *buf, size_t length)
 {
   const SeekableZStreamHeader *header = SeekableZStreamHeader::validate(buf);
   if (!header) {
-    LOG("Not a seekable zstream");
+    ERROR("Not a seekable zstream");
     return false;
   }
 
   buffer = reinterpret_cast<const unsigned char *>(buf);
   totalSize = header->totalSize;
   chunkSize = header->chunkSize;
   lastChunkSize = header->lastChunkSize;
   windowBits = header->windowBits;
@@ -28,17 +28,17 @@ SeekableZStream::Init(const void *buf, s
   /* Sanity check */
   if ((chunkSize == 0) ||
       (!IsPageAlignedSize(chunkSize)) ||
       (chunkSize > 8 * PageSize()) ||
       (offsetTable.numElements() < 1) ||
       (lastChunkSize == 0) ||
       (lastChunkSize > chunkSize) ||
       (length < totalSize)) {
-    LOG("Malformed or broken seekable zstream");
+    ERROR("Malformed or broken seekable zstream");
     return false;
   }
 
   return true;
 }
 
 bool
 SeekableZStream::Decompress(void *where, size_t chunk, size_t length)
@@ -53,17 +53,17 @@ SeekableZStream::Decompress(void *where,
   }
   return true;
 }
 
 bool
 SeekableZStream::DecompressChunk(void *where, size_t chunk, size_t length)
 {
   if (chunk >= offsetTable.numElements()) {
-    LOG("DecompressChunk: chunk #%" PRIdSize " out of range [0-%" PRIdSize ")",
+    ERROR("DecompressChunk: chunk #%" PRIdSize " out of range [0-%" PRIdSize ")",
         chunk, offsetTable.numElements());
     return false;
   }
 
   bool isLastChunk = (chunk == offsetTable.numElements() - 1);
 
   size_t chunkLen = isLastChunk ? lastChunkSize : chunkSize;
 
@@ -77,31 +77,31 @@ SeekableZStream::DecompressChunk(void *w
   zStream.avail_in = (isLastChunk ? totalSize : uint32_t(offsetTable[chunk + 1]))
                      - uint32_t(offsetTable[chunk]);
   zStream.next_in = const_cast<Bytef *>(buffer + uint32_t(offsetTable[chunk]));
   zStream.avail_out = length;
   zStream.next_out = reinterpret_cast<Bytef *>(where);
 
   /* Decompress chunk */
   if (inflateInit2(&zStream, windowBits) != Z_OK) {
-    LOG("inflateInit failed: %s", zStream.msg);
+    ERROR("inflateInit failed: %s", zStream.msg);
     return false;
   }
   if (dictionary && inflateSetDictionary(&zStream, dictionary,
                                          dictionary.numElements()) != Z_OK) {
-    LOG("inflateSetDictionary failed: %s", zStream.msg);
+    ERROR("inflateSetDictionary failed: %s", zStream.msg);
     return false;
   }
   if (inflate(&zStream, (length == chunkLen) ? Z_FINISH : Z_SYNC_FLUSH)
       != (length == chunkLen) ? Z_STREAM_END : Z_OK) {
-    LOG("inflate failed: %s", zStream.msg);
+    ERROR("inflate failed: %s", zStream.msg);
     return false;
   }
   if (inflateEnd(&zStream) != Z_OK) {
-    LOG("inflateEnd failed: %s", zStream.msg);
+    ERROR("inflateEnd failed: %s", zStream.msg);
     return false;
   }
   if (filter)
     filter(chunk * chunkSize, UNFILTER, (unsigned char *)where, chunkLen);
 
   return true;
 }
 
--- a/mozglue/linker/Zip.cpp
+++ b/mozglue/linker/Zip.cpp
@@ -13,48 +13,48 @@
 #include "Zip.h"
 
 mozilla::TemporaryRef<Zip>
 Zip::Create(const char *filename)
 {
   /* Open and map the file in memory */
   AutoCloseFD fd(open(filename, O_RDONLY));
   if (fd == -1) {
-    LOG("Error opening %s: %s", filename, strerror(errno));
+    ERROR("Error opening %s: %s", filename, strerror(errno));
     return nullptr;
   }
   struct stat st;
   if (fstat(fd, &st) == -1) {
-    LOG("Error stating %s: %s", filename, strerror(errno));
+    ERROR("Error stating %s: %s", filename, strerror(errno));
     return nullptr;
   }
   size_t size = st.st_size;
   if (size <= sizeof(CentralDirectoryEnd)) {
-    LOG("Error reading %s: too short", filename);
+    ERROR("Error reading %s: too short", filename);
     return nullptr;
   }
   void *mapped = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
   if (mapped == MAP_FAILED) {
-    LOG("Error mmapping %s: %s", filename, strerror(errno));
+    ERROR("Error mmapping %s: %s", filename, strerror(errno));
     return nullptr;
   }
   DEBUG_LOG("Mapped %s @%p", filename, mapped);
 
   return Create(filename, mapped, size);
 }
 
 mozilla::TemporaryRef<Zip>
 Zip::Create(const char *filename, void *mapped, size_t size)
 {
   mozilla::RefPtr<Zip> zip = new Zip(filename, mapped, size);
 
   // If neither the first Local File entry nor central directory entries
   // have been found, the zip was invalid.
   if (!zip->nextFile && !zip->entries) {
-    LOG("%s - Invalid zip", filename);
+    ERROR("%s - Invalid zip", filename);
     return nullptr;
   }
 
   ZipCollection::Singleton.Register(zip);
   return zip;
 }
 
 Zip::Zip(const char *filename, void *mapped, size_t size)
@@ -131,17 +131,17 @@ Zip::GetStream(const char *path, Zip::St
     return false;
   }
 
   /* Find the Local File header corresponding to the Directory entry that
    * was found. */
   nextFile = LocalFile::validate(static_cast<const char *>(mapped)
                              + nextDir->offset);
   if (!nextFile) {
-    LOG("%s - Couldn't find the Local File header for %s", name, path);
+    ERROR("%s - Couldn't find the Local File header for %s", name, path);
     return false;
   }
 
   /* Fill Stream info from Directory entry content */
   const char *data = reinterpret_cast<const char *>(nextFile->GetData());
   out->compressedBuf = data;
   out->compressedSize = nextDir->compressedSize;
   out->uncompressedSize = nextDir->uncompressedSize;
@@ -162,24 +162,24 @@ Zip::GetFirstEntry() const
   const CentralDirectoryEnd *end = nullptr;
   const char *_end = static_cast<const char *>(mapped) + size
                      - sizeof(CentralDirectoryEnd);
 
   /* Scan for the Central Directory End */
   for (; _end > mapped && !end; _end--)
     end = CentralDirectoryEnd::validate(_end);
   if (!end) {
-    LOG("%s - Couldn't find end of central directory record", name);
+    ERROR("%s - Couldn't find end of central directory record", name);
     return nullptr;
   }
 
   entries = DirectoryEntry::validate(static_cast<const char *>(mapped)
                                  + end->offset);
   if (!entries) {
-    LOG("%s - Couldn't find central directory record", name);
+    ERROR("%s - Couldn't find central directory record", name);
   }
   return entries;
 }
 
 ZipCollection ZipCollection::Singleton;
 
 mozilla::TemporaryRef<Zip>
 ZipCollection::GetZip(const char *path)
--- a/mozglue/linker/szip.cpp
+++ b/mozglue/linker/szip.cpp
@@ -208,58 +208,58 @@ private:
 };
 
 /* Decompress a seekable compressed stream */
 int SzipDecompress::run(const char *name, Buffer &origBuf,
                         const char *outName, Buffer &outBuf)
 {
   size_t origSize = origBuf.GetLength();
   if (origSize < sizeof(SeekableZStreamHeader)) {
-    LOG("%s is not compressed", name);
+    ERROR("%s is not compressed", name);
     return 0;
   }
 
   SeekableZStream zstream;
   if (!zstream.Init(origBuf, origSize))
     return 0;
 
   size_t size = zstream.GetUncompressedSize();
 
   /* Give enough room for the uncompressed data */
   if (!outBuf.Resize(size)) {
-    LOG("Error resizing %s: %s", outName, strerror(errno));
+    ERROR("Error resizing %s: %s", outName, strerror(errno));
     return 1;
   }
 
   if (!zstream.Decompress(outBuf, 0, size))
     return 1;
 
   return 0;
 }
 
 /* Generate a seekable compressed stream. */
 int SzipCompress::run(const char *name, Buffer &origBuf,
                       const char *outName, Buffer &outBuf)
 {
   size_t origSize = origBuf.GetLength();
   if (origSize == 0) {
-    LOG("Won't compress %s: it's empty", name);
+    ERROR("Won't compress %s: it's empty", name);
     return 1;
   }
   if (SeekableZStreamHeader::validate(origBuf)) {
-    LOG("Skipping %s: it's already a szip", name);
+    WARN("Skipping %s: it's already a szip", name);
     return 0;
   }
   bool compressed = false;
   LOG("Size = %" PRIuSize, origSize);
 
   /* Allocate a buffer the size of the uncompressed data: we don't want
    * a compressed file larger than that anyways. */
   if (!outBuf.Resize(origSize)) {
-    LOG("Couldn't allocate output buffer: %s", strerror(errno));
+    ERROR("Couldn't allocate output buffer: %s", strerror(errno));
     return 1;
   }
 
   /* Find the most appropriate filter */
   SeekableZStream::FilterId firstFilter, lastFilter;
   bool scanFilters;
   if (filter == SeekableZStream::FILTER_MAX) {
     firstFilter = SeekableZStream::NONE;
@@ -346,21 +346,21 @@ int SzipCompress::run(const char *name, 
   /* Sanity check */
   Buffer tmpBuf;
   SzipDecompress decompress;
   if (decompress.run("buffer", outBuf, "buffer", tmpBuf))
     return 1;
 
   size_t size = tmpBuf.GetLength();
   if (size != origSize) {
-    LOG("Compression error: %" PRIuSize " != %" PRIuSize, size, origSize);
+    ERROR("Compression error: %" PRIuSize " != %" PRIuSize, size, origSize);
     return 1;
   }
   if (memcmp(static_cast<void *>(origBuf), static_cast<void *>(tmpBuf), size)) {
-    LOG("Compression error: content mismatch");
+    ERROR("Compression error: content mismatch");
     return 1;
   }
   return 0;
 }
 
 int SzipCompress::do_compress(Buffer &origBuf, Buffer &outBuf,
                               const unsigned char *aDict, size_t aDictSize,
                               SeekableZStream::FilterId aFilter)
@@ -377,17 +377,17 @@ int SzipCompress::do_compress(Buffer &or
                   + nChunks * sizeof(uint32_t);
 
   if (offset >= origSize)
     return 1;
 
     /* Allocate a buffer the size of the uncompressed data: we don't want
    * a compressed file larger than that anyways. */
   if (!outBuf.Resize(origSize)) {
-    LOG("Couldn't allocate output buffer: %s", strerror(errno));
+    ERROR("Couldn't allocate output buffer: %s", strerror(errno));
     return 1;
   }
 
   SeekableZStreamHeader *header = new (outBuf) SeekableZStreamHeader;
   unsigned char *dictionary = static_cast<unsigned char *>(
                               outBuf + sizeof(SeekableZStreamHeader));
   le_uint32 *entry =
     reinterpret_cast<le_uint32 *>(dictionary + aDictSize);
@@ -442,17 +442,17 @@ int SzipCompress::do_compress(Buffer &or
     data += avail;
     offset += len;
   }
   header->lastChunkSize = avail;
   MOZ_ASSERT(header->totalSize == offset);
   MOZ_ASSERT(header->nChunks == nChunks);
 
   if (!outBuf.Resize(offset)) {
-    LOG("Error truncating output: %s", strerror(errno));
+    ERROR("Error truncating output: %s", strerror(errno));
     return 1;
   }
 
   return 0;
 
 }
 
 bool GetSize(const char *str, size_t *out)
@@ -482,100 +482,100 @@ int main(int argc, char* argv[])
       compress = false;
     } else if (strcmp(firstArg[0], "-c") == 0) {
       firstArg++;
       argc--;
       if (!firstArg[0])
         break;
       if (!GetSize(firstArg[0], &chunkSize) || !chunkSize ||
           (chunkSize % 4096) || (chunkSize > maxChunkSize)) {
-        LOG("Invalid chunk size");
+        ERROR("Invalid chunk size");
         return 1;
       }
     } else if (strcmp(firstArg[0], "-f") == 0) {
       firstArg++;
       argc--;
       if (!firstArg[0])
         break;
       bool matched = false;
       for (unsigned int i = 0; i < sizeof(filterName) / sizeof(char *); ++i) {
         if (strcmp(firstArg[0], filterName[i]) == 0) {
           filter = static_cast<SeekableZStream::FilterId>(i);
           matched = true;
           break;
         }
       }
       if (!matched) {
-        LOG("Invalid filter");
+        ERROR("Invalid filter");
         return 1;
       }
     } else if (strcmp(firstArg[0], "-D") == 0) {
       firstArg++;
       argc--;
       if (!firstArg[0])
         break;
       if (strcmp(firstArg[0], "auto") == 0) {
         dictSize = -1;
       } else if (!GetSize(firstArg[0], &dictSize) || (dictSize >= 1 << 16)) {
-        LOG("Invalid dictionary size");
+        ERROR("Invalid dictionary size");
         return 1;
       }
     }
   }
 
   if (argc != 2 || !firstArg[0]) {
     LOG("usage: %s [-d] [-c CHUNKSIZE] [-f FILTER] [-D DICTSIZE] file",
         argv[0]);
     return 1;
   }
 
   if (compress) {
     action = new SzipCompress(chunkSize, filter, dictSize);
   } else {
     if (chunkSize) {
-      LOG("-c is incompatible with -d");
+      ERROR("-c is incompatible with -d");
       return 1;
     }
     if (dictSize) {
-      LOG("-D is incompatible with -d");
+      ERROR("-D is incompatible with -d");
       return 1;
     }
     action = new SzipDecompress();
   }
 
   std::stringstream tmpOutStream;
   tmpOutStream << firstArg[0] << ".sz." << getpid();
   std::string tmpOut(tmpOutStream.str());
   int ret;
   struct stat st;
   {
     FileBuffer origBuf;
     if (!origBuf.Init(firstArg[0])) {
-      LOG("Couldn't open %s: %s", firstArg[0], strerror(errno));
+      ERROR("Couldn't open %s: %s", firstArg[0], strerror(errno));
       return 1;
     }
 
     ret = fstat(origBuf.getFd(), &st);
     if (ret == -1) {
-      LOG("Couldn't stat %s: %s", firstArg[0], strerror(errno));
+      ERROR("Couldn't stat %s: %s", firstArg[0], strerror(errno));
       return 1;
     }
 
     size_t origSize = st.st_size;
 
     /* Mmap the original file */
     if (!origBuf.Resize(origSize)) {
-      LOG("Couldn't mmap %s: %s", firstArg[0], strerror(errno));
+      ERROR("Couldn't mmap %s: %s", firstArg[0], strerror(errno));
       return 1;
     }
 
     /* Create the compressed file */
     FileBuffer outBuf;
     if (!outBuf.Init(tmpOut.c_str(), true)) {
-      LOG("Couldn't open %s: %s", tmpOut.c_str(), strerror(errno));
+      ERROR("Couldn't open %s: %s", tmpOut.c_str(), strerror(errno));
       return 1;
     }
 
     ret = action->run(firstArg[0], origBuf, tmpOut.c_str(), outBuf);
     if ((ret == 0) && (fstat(outBuf.getFd(), &st) == -1)) {
       st.st_size = 0;
     }
   }