--- a/mozglue/linker/CustomElf.cpp
+++ b/mozglue/linker/CustomElf.cpp
@@ -57,24 +57,24 @@ const Ehdr *Ehdr::validate(const void *b
return ehdr;
}
namespace {
void debug_phdr(const char *type, const Phdr *phdr)
{
- debug("%s @0x%08" PRIxAddr " ("
- "filesz: 0x%08" PRIxAddr ", "
- "memsz: 0x%08" PRIxAddr ", "
- "offset: 0x%08" PRIxAddr ", "
- "flags: %c%c%c)",
- type, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz,
- phdr->p_offset, phdr->p_flags & PF_R ? 'r' : '-',
- phdr->p_flags & PF_W ? 'w' : '-', phdr->p_flags & PF_X ? 'x' : '-');
+ DEBUG_LOG("%s @0x%08" PRIxAddr " ("
+ "filesz: 0x%08" PRIxAddr ", "
+ "memsz: 0x%08" PRIxAddr ", "
+ "offset: 0x%08" PRIxAddr ", "
+ "flags: %c%c%c)",
+ type, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz,
+ phdr->p_offset, phdr->p_flags & PF_R ? 'r' : '-',
+ phdr->p_flags & PF_W ? 'w' : '-', phdr->p_flags & PF_X ? 'x' : '-');
}
} /* anonymous namespace */
/**
* RAII wrapper for a mapping of the first page off a Mappable object.
* This calls Mappable::munmap instead of system munmap.
*/
@@ -97,17 +97,17 @@ private:
mozilla::RefPtr<Mappable> mappable;
};
TemporaryRef<LibHandle>
CustomElf::Load(Mappable *mappable, const char *path, int flags)
{
- debug("CustomElf::Load(\"%s\", 0x%x) = ...", path, flags);
+ DEBUG_LOG("CustomElf::Load(\"%s\", 0x%x) = ...", path, flags);
if (!mappable)
return NULL;
/* Keeping a RefPtr of the CustomElf is going to free the appropriate
* resources when returning NULL */
RefPtr<CustomElf> elf = new CustomElf(mappable, path);
/* Map the first page of the Elf object to access Elf and program headers */
Mappable1stPagePtr ehdr_raw(mappable);
if (ehdr_raw == MAP_FAILED)
@@ -137,50 +137,50 @@ 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());
+ LOG("%s: Multiple PT_DYNAMIC segments detected", elf->GetPath());
return NULL;
}
break;
case PT_TLS:
debug_phdr("PT_TLS", phdr);
if (phdr->p_memsz) {
- log("%s: TLS is not supported", elf->GetPath());
+ LOG("%s: TLS is not supported", elf->GetPath());
return NULL;
}
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());
+ LOG("%s: Executable stack is not supported", elf->GetPath());
return NULL;
}
#endif
break;
default:
- debug("%s: Warning: program header type #%d not handled",
- elf->GetPath(), phdr->p_type);
+ DEBUG_LOG("%s: Warning: program header type #%d not handled",
+ elf->GetPath(), phdr->p_type);
}
}
if (min_vaddr != 0) {
- log("%s: Unsupported minimal virtual address: 0x%08" PRIxAddr,
+ LOG("%s: Unsupported minimal virtual address: 0x%08" PRIxAddr,
elf->GetPath(), min_vaddr);
return NULL;
}
if (!dyn) {
- log("%s: No PT_DYNAMIC segment found", elf->GetPath());
+ LOG("%s: No PT_DYNAMIC segment found", elf->GetPath());
return NULL;
}
/* 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
@@ -189,17 +189,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(mmap(NULL, max_vaddr, PROT_NONE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0), max_vaddr);
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());
+ LOG("%s: Failed to mmap", elf->GetPath());
return NULL;
}
/* Load and initialize library */
for (std::vector<const Phdr *>::iterator it = pt_loads.begin();
it < pt_loads.end(); ++it)
if (!elf->LoadSegment(*it))
return NULL;
@@ -214,25 +214,25 @@ CustomElf::Load(Mappable *mappable, cons
elf->l_name = elf->GetPath();
elf->l_ld = elf->GetPtr<Dyn>(dyn->p_vaddr);
ElfLoader::Singleton.Register(elf);
if (!elf->InitDyn(dyn))
return NULL;
elf->stats("oneLibLoaded");
- debug("CustomElf::Load(\"%s\", 0x%x) = %p", path, flags,
- static_cast<void *>(elf));
+ DEBUG_LOG("CustomElf::Load(\"%s\", 0x%x) = %p", path, flags,
+ static_cast<void *>(elf));
return elf;
}
CustomElf::~CustomElf()
{
- debug("CustomElf::~CustomElf(%p [\"%s\"])",
- reinterpret_cast<void *>(this), GetPath());
+ DEBUG_LOG("CustomElf::~CustomElf(%p [\"%s\"])",
+ reinterpret_cast<void *>(this), GetPath());
CallFini();
/* Normally, __cxa_finalize is called by the .fini function. However,
* Android NDK before r6b doesn't do that. Our wrapped cxa_finalize only
* calls destructors once, so call it in all cases. */
ElfLoader::__wrap_cxa_finalize(this);
ElfLoader::Singleton.Forget(this);
}
@@ -265,18 +265,18 @@ CustomElf::GetSymbolPtr(const char *symb
void *
CustomElf::GetSymbolPtr(const char *symbol, unsigned long hash) const
{
const Sym *sym = GetSymbol(symbol, hash);
void *ptr = NULL;
if (sym && sym->st_shndx != SHN_UNDEF)
ptr = GetPtr(sym->st_value);
- debug("CustomElf::GetSymbolPtr(%p [\"%s\"], \"%s\") = %p",
- reinterpret_cast<const void *>(this), GetPath(), symbol, ptr);
+ DEBUG_LOG("CustomElf::GetSymbolPtr(%p [\"%s\"], \"%s\") = %p",
+ reinterpret_cast<const void *>(this), GetPath(), symbol, ptr);
return ptr;
}
void *
CustomElf::GetSymbolPtrInDeps(const char *symbol) const
{
/* Resolve dlopen and related functions to point to ours */
if (symbol[0] == 'd' && symbol[1] == 'l') {
@@ -311,17 +311,17 @@ CustomElf::GetSymbolPtrInDeps(const char
void *sym;
/* Search the symbol in the main program. Note this also tries all libraries
* the system linker will have loaded RTLD_GLOBAL. Unfortunately, that doesn't
* work with bionic, but its linker doesn't normally search the main binary
* anyways. Moreover, on android, the main binary is dalvik. */
#ifdef __GLIBC__
sym = dlsym(RTLD_DEFAULT, symbol);
- debug("dlsym(RTLD_DEFAULT, \"%s\") = %p", symbol, sym);
+ DEBUG_LOG("dlsym(RTLD_DEFAULT, \"%s\") = %p", symbol, sym);
if (sym)
return sym;
#endif
/* Then search the symbol in our dependencies. Since we already searched in
* libraries the system linker loaded, skip those (on glibc systems). We
* also assume the symbol is to be found in one of the dependent libraries
* directly, not in their own dependent libraries. Building libraries with
@@ -374,54 +374,54 @@ CustomElf::stats(const char *when) const
{
mappable->stats(when, GetPath());
}
bool
CustomElf::LoadSegment(const Phdr *pt_load) const
{
if (pt_load->p_type != PT_LOAD) {
- debug("%s: Elf::LoadSegment only takes PT_LOAD program headers", GetPath());
+ DEBUG_LOG("%s: Elf::LoadSegment only takes PT_LOAD program headers", GetPath());
return false;;
}
int prot = ((pt_load->p_flags & PF_X) ? PROT_EXEC : 0) |
((pt_load->p_flags & PF_W) ? PROT_WRITE : 0) |
((pt_load->p_flags & PF_R) ? PROT_READ : 0);
/* Mmap at page boundary */
Addr align = PAGE_SIZE;
void *mapped, *where;
do {
Addr align_offset = pt_load->p_vaddr & (align - 1);
where = GetPtr(pt_load->p_vaddr - align_offset);
- debug("%s: Loading segment @%p %c%c%c", GetPath(), where,
- prot & PROT_READ ? 'r' : '-',
- prot & PROT_WRITE ? 'w' : '-',
- prot & PROT_EXEC ? 'x' : '-');
+ DEBUG_LOG("%s: Loading segment @%p %c%c%c", GetPath(), where,
+ prot & PROT_READ ? 'r' : '-',
+ prot & PROT_WRITE ? 'w' : '-',
+ prot & PROT_EXEC ? 'x' : '-');
mapped = mappable->mmap(where, pt_load->p_filesz + align_offset,
prot, MAP_PRIVATE | MAP_FIXED,
pt_load->p_offset - align_offset);
if ((mapped != MAP_FAILED) || (pt_load->p_vaddr == 0) ||
(pt_load->p_align == align))
break;
/* The virtual address space for the library is properly aligned at
* 16k on ARMv6 (see CustomElf::Load), and so is the first segment
* (p_vaddr == 0). But subsequent segments may not be 16k aligned
* and fail to mmap. In such case, try to mmap again at the p_align
* boundary instead of page boundary. */
- debug("%s: Failed to mmap, retrying", GetPath());
+ 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());
+ LOG("%s: Failed to mmap", GetPath());
} else {
- log("%s: Didn't map at the expected location (wanted: %p, got: %p)",
+ LOG("%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). */
@@ -441,29 +441,29 @@ CustomElf::LoadSegment(const Phdr *pt_lo
* address space. We just need to adjust this anonymous memory protection
* flags. */
if (pt_load->p_memsz > pt_load->p_filesz) {
Addr file_end = pt_load->p_vaddr + pt_load->p_filesz;
Addr mem_end = pt_load->p_vaddr + pt_load->p_memsz;
Addr next_page = (file_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
if (mem_end > next_page) {
if (mprotect(GetPtr(next_page), mem_end - next_page, prot) < 0) {
- log("%s: Failed to mprotect", GetPath());
+ LOG("%s: Failed to mprotect", GetPath());
return false;
}
}
}
return true;
}
namespace {
void debug_dyn(const char *type, const Dyn *dyn)
{
- debug("%s 0x%08" PRIxAddr, type, dyn->d_un.d_val);
+ DEBUG_LOG("%s 0x%08" PRIxAddr, type, dyn->d_un.d_val);
}
} /* anonymous namespace */
bool
CustomElf::InitDyn(const Phdr *pt_dyn)
{
/* Scan PT_DYNAMIC segment and gather some information */
@@ -492,43 +492,43 @@ 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());
+ LOG("%s: Unsupported DT_SYMENT", GetPath());
return false;
}
break;
case DT_TEXTREL:
- log("%s: Text relocations are not supported", GetPath());
+ LOG("%s: Text relocations are not supported", GetPath());
return false;
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());
+ LOG("%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());
+ LOG("%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:
@@ -559,32 +559,32 @@ 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());
+ LOG("%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) {
- log("%s: Text relocations are not supported", GetPath());
+ LOG("%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",
+ LOG("%s: Warning: 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
@@ -597,31 +597,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",
+ LOG("%s: Warning: dynamic header type #%" PRIxAddr" not handled",
GetPath(), dyn->d_tag);
}
}
if (!buckets || !symnum) {
- log("%s: Missing or broken DT_HASH", GetPath());
+ LOG("%s: Missing or broken DT_HASH", GetPath());
return false;
}
if (!strtab) {
- log("%s: Missing DT_STRTAB", GetPath());
+ LOG("%s: Missing DT_STRTAB", GetPath());
return false;
}
if (!symtab) {
- log("%s: Missing DT_SYMTAB", GetPath());
+ LOG("%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);
@@ -632,17 +632,17 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
/* Finish initialization */
return Relocate() && RelocateJumps() && CallInit();
}
bool
CustomElf::Relocate()
{
- debug("Relocate %s @%p", GetPath(), static_cast<void *>(base));
+ DEBUG_LOG("Relocate %s @%p", GetPath(), static_cast<void *>(base));
for (Array<Reloc>::iterator rel = relocations.begin();
rel < relocations.end(); ++rel) {
/* Location of the relocation */
void *ptr = GetPtr(rel->r_offset);
/* R_*_RELATIVE relocations apply directly at the given location */
if (ELF_R_TYPE(rel->r_info) == R_RELATIVE) {
*(void **) ptr = GetPtr(rel->GetAddend(base));
@@ -656,31 +656,31 @@ CustomElf::Relocate()
} else {
/* TODO: avoid symbol resolution when it's the same symbol as last
* iteration */
/* TODO: handle symbol resolving to NULL vs. being undefined. */
symptr = GetSymbolPtrInDeps(strtab.GetStringAt(sym.st_name));
}
if (symptr == NULL)
- log("%s: Warning: relocation to NULL @0x%08" PRIxAddr,
+ LOG("%s: Warning: 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,
+ LOG("%s: Unsupported relocation type: 0x%" PRIxAddr,
GetPath(), ELF_R_TYPE(rel->r_info));
return false;
}
}
return true;
}
bool
@@ -689,30 +689,30 @@ 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());
+ LOG("%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 == NULL) {
- log("%s: %s: relocation to NULL @0x%08" PRIxAddr " for symbol \"%s\"",
+ 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)
return false;
}
/* Apply relocation */
*(void **) ptr = symptr;
--- a/mozglue/linker/CustomElf.h
+++ b/mozglue/linker/CustomElf.h
@@ -137,17 +137,17 @@ private:
{
/* C++ doesn't allow direct conversion between pointer-to-object
* and pointer-to-function. */
union {
void *ptr;
void (*func)(void);
} f;
f.ptr = ptr;
- debug("%s: Calling function @%p", GetPath(), ptr);
+ DEBUG_LOG("%s: Calling function @%p", GetPath(), ptr);
f.func();
}
/**
* Call a function given a an address relative to the library base
*/
void CallFunction(Elf::Addr addr) const
{
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -228,46 +228,46 @@ LibHandle::MappableMUnmap(void *addr, si
* SystemElf
*/
TemporaryRef<LibHandle>
SystemElf::Load(const char *path, int flags)
{
/* The Android linker returns a handle when the file name matches an
* already loaded library, even when the full path doesn't exist */
if (path && path[0] == '/' && (access(path, F_OK) == -1)){
- debug("dlopen(\"%s\", 0x%x) = %p", path, flags, (void *)NULL);
+ DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, (void *)NULL);
return NULL;
}
void *handle = dlopen(path, flags);
- debug("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
+ DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
ElfLoader::Singleton.lastError = dlerror();
if (handle) {
SystemElf *elf = new SystemElf(path, handle);
ElfLoader::Singleton.Register(elf);
return elf;
}
return NULL;
}
SystemElf::~SystemElf()
{
if (!dlhandle)
return;
- debug("dlclose(%p [\"%s\"])", dlhandle, GetPath());
+ DEBUG_LOG("dlclose(%p [\"%s\"])", dlhandle, GetPath());
dlclose(dlhandle);
ElfLoader::Singleton.lastError = dlerror();
ElfLoader::Singleton.Forget(this);
}
void *
SystemElf::GetSymbolPtr(const char *symbol) const
{
void *sym = dlsym(dlhandle, symbol);
- debug("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol, sym);
+ DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol, sym);
ElfLoader::Singleton.lastError = dlerror();
return sym;
}
Mappable *
SystemElf::GetMappable() const
{
const char *path = GetPath();
@@ -348,19 +348,19 @@ ElfLoader::Load(const char *path, int fl
handle = SystemElf::Load(path, flags);
/* If we didn't have an absolute path and haven't been able to load
* a library yet, try in the system search path */
if (!handle && abs_path)
handle = SystemElf::Load(name, flags);
delete [] abs_path;
- debug("ElfLoader::Load(\"%s\", 0x%x, %p [\"%s\"]) = %p", requested_path, flags,
- reinterpret_cast<void *>(parent), parent ? parent->GetPath() : "",
- static_cast<void *>(handle));
+ DEBUG_LOG("ElfLoader::Load(\"%s\", 0x%x, %p [\"%s\"]) = %p", requested_path, flags,
+ reinterpret_cast<void *>(parent), parent ? parent->GetPath() : "",
+ static_cast<void *>(handle));
return handle;
}
mozilla::TemporaryRef<LibHandle>
ElfLoader::GetHandleByPtr(void *addr)
{
/* Scan the list of handles we already have for a match */
@@ -415,24 +415,24 @@ ElfLoader::Register(LibHandle *handle)
dbg.Add(static_cast<CustomElf *>(handle));
}
void
ElfLoader::Forget(LibHandle *handle)
{
LibHandleList::iterator it = std::find(handles.begin(), handles.end(), handle);
if (it != handles.end()) {
- debug("ElfLoader::Forget(%p [\"%s\"])", reinterpret_cast<void *>(handle),
- handle->GetPath());
+ DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"])", reinterpret_cast<void *>(handle),
+ handle->GetPath());
if (dbg && !handle->IsSystemElf())
dbg.Remove(static_cast<CustomElf *>(handle));
handles.erase(it);
} else {
- debug("ElfLoader::Forget(%p [\"%s\"]): Handle not found",
- reinterpret_cast<void *>(handle), handle->GetPath());
+ DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"]): Handle not found",
+ reinterpret_cast<void *>(handle), handle->GetPath());
}
}
ElfLoader::~ElfLoader()
{
LibHandleList list;
/* Build up a list of all library handles with direct (external) references.
* We actually skip system library handles because we want to keep at least
@@ -454,23 +454,23 @@ ElfLoader::~ElfLoader()
while ((*it)->ReleaseDirectRef()) { }
}
/* Remove the remaining system handles. */
if (handles.size()) {
list = handles;
for (LibHandleList::reverse_iterator it = list.rbegin();
it < list.rend(); ++it) {
if ((*it)->IsSystemElf()) {
- debug("ElfLoader::~ElfLoader(): Remaining handle for \"%s\" "
- "[%d direct refs, %d refs total]", (*it)->GetPath(),
- (*it)->DirectRefCount(), (*it)->refCount());
+ DEBUG_LOG("ElfLoader::~ElfLoader(): Remaining handle for \"%s\" "
+ "[%d direct refs, %d refs total]", (*it)->GetPath(),
+ (*it)->DirectRefCount(), (*it)->refCount());
} else {
- debug("ElfLoader::~ElfLoader(): Unexpected remaining handle for \"%s\" "
- "[%d direct refs, %d refs total]", (*it)->GetPath(),
- (*it)->DirectRefCount(), (*it)->refCount());
+ DEBUG_LOG("ElfLoader::~ElfLoader(): Unexpected remaining handle for \"%s\" "
+ "[%d direct refs, %d refs total]", (*it)->GetPath(),
+ (*it)->DirectRefCount(), (*it)->refCount());
/* Not removing, since it could have references to other libraries,
* destroying them as a side effect, and possibly leaving dangling
* pointers in the handle list we're scanning */
}
}
}
}
@@ -516,18 +516,18 @@ ElfLoader::__wrap_cxa_finalize(void *dso
}
}
}
void
ElfLoader::DestructorCaller::Call()
{
if (destructor) {
- debug("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
- FunctionPtr(destructor), object, dso_handle);
+ DEBUG_LOG("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
+ FunctionPtr(destructor), object, dso_handle);
destructor(object);
destructor = NULL;
}
}
ElfLoader::DebuggerHelper::DebuggerHelper(): dbg(NULL)
{
/* Find ELF auxiliary vectors.
@@ -605,45 +605,45 @@ ElfLoader::DebuggerHelper::DebuggerHelpe
base = reinterpret_cast<char *>(auxv->value & PAGE_MASK);
}
if (auxv->type == AT_PHNUM)
phdrs.Init(auxv->value);
auxv++;
}
if (!phdrs) {
- debug("Couldn't find program headers");
+ DEBUG_LOG("Couldn't find program headers");
return;
}
/* In some cases, the address for the program headers we get from the
* auxiliary vectors is not mapped, because of the PT_LOAD segments
* definitions in the program executable. Trying to map anonymous memory
* with a hint giving the base address will return a different address
* if something is mapped there, and the base address otherwise. */
MappedPtr mem(mmap(base, PAGE_SIZE, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0), PAGE_SIZE);
if (mem == base) {
/* If program headers aren't mapped, try to map them */
int fd = open("/proc/self/exe", O_RDONLY);
if (fd == -1) {
- debug("Failed to open /proc/self/exe");
+ DEBUG_LOG("Failed to open /proc/self/exe");
return;
}
mem.Assign(mmap(base, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0), PAGE_SIZE);
/* If we don't manage to map at the right address, just give up. */
if (mem != base) {
- debug("Couldn't read program headers");
+ DEBUG_LOG("Couldn't read program headers");
return;
}
}
/* Sanity check: the first bytes at the base address should be an ELF
* header. */
if (!Elf::Ehdr::validate(base)) {
- debug("Couldn't find program base");
+ DEBUG_LOG("Couldn't find program base");
return;
}
/* Search for the program PT_DYNAMIC segment */
Array<Elf::Dyn> dyns;
for (Array<Elf::Phdr>::iterator phdr = phdrs.begin(); phdr < phdrs.end();
++phdr) {
/* While the program headers are expected within the first mapped page of
@@ -652,28 +652,28 @@ ElfLoader::DebuggerHelper::DebuggerHelpe
* library. We thus need to adjust the base address, compensating for the
* virtual address of the PT_LOAD segment corresponding to offset 0. */
if (phdr->p_type == PT_LOAD && phdr->p_offset == 0)
base -= phdr->p_vaddr;
if (phdr->p_type == PT_DYNAMIC)
dyns.Init(base + phdr->p_vaddr, phdr->p_filesz);
}
if (!dyns) {
- debug("Failed to find PT_DYNAMIC section in program");
+ DEBUG_LOG("Failed to find PT_DYNAMIC section in program");
return;
}
/* Search for the DT_DEBUG information */
for (Array<Elf::Dyn>::iterator dyn = dyns.begin(); dyn < dyns.end(); ++dyn) {
if (dyn->d_tag == DT_DEBUG) {
dbg = reinterpret_cast<r_debug *>(dyn->d_un.d_ptr);
break;
}
}
- debug("DT_DEBUG points at %p", static_cast<void *>(dbg));
+ DEBUG_LOG("DT_DEBUG points at %p", static_cast<void *>(dbg));
}
/**
* Helper class to ensure the given pointer is writable within the scope of
* an instance. Permissions to the memory page where the pointer lies are
* restored to their original value when the instance is destroyed.
*/
class EnsureWritable
@@ -933,48 +933,48 @@ SEGVHandler::~SEGVHandler()
/* Restore original signal handler */
sys_sigaction(SIGSEGV, &this->action, NULL);
}
/* TODO: "properly" handle signal masks and flags */
void SEGVHandler::handler(int signum, siginfo_t *info, void *context)
{
//ASSERT(signum == SIGSEGV);
- debug("Caught segmentation fault @%p", info->si_addr);
+ DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
/* Check whether we segfaulted in the address space of a CustomElf. We're
* only expecting that to happen as an access error. */
if (info->si_code == SEGV_ACCERR) {
mozilla::RefPtr<LibHandle> handle =
ElfLoader::Singleton.GetHandleByPtr(info->si_addr);
if (handle && !handle->IsSystemElf()) {
- debug("Within the address space of a CustomElf");
+ DEBUG_LOG("Within the address space of a CustomElf");
CustomElf *elf = static_cast<CustomElf *>(static_cast<LibHandle *>(handle));
if (elf->mappable->ensure(info->si_addr))
return;
}
}
/* Redispatch to the registered handler */
SEGVHandler &that = ElfLoader::Singleton;
if (that.action.sa_flags & SA_SIGINFO) {
- debug("Redispatching to registered handler @%p",
- FunctionPtr(that.action.sa_sigaction));
+ DEBUG_LOG("Redispatching to registered handler @%p",
+ FunctionPtr(that.action.sa_sigaction));
that.action.sa_sigaction(signum, info, context);
} else if (that.action.sa_handler == SIG_DFL) {
- debug("Redispatching to default handler");
+ DEBUG_LOG("Redispatching to default handler");
/* Reset the handler to the default one, and trigger it. */
sys_sigaction(signum, &that.action, NULL);
raise(signum);
} else if (that.action.sa_handler != SIG_IGN) {
- debug("Redispatching to registered handler @%p",
- FunctionPtr(that.action.sa_handler));
+ DEBUG_LOG("Redispatching to registered handler @%p",
+ FunctionPtr(that.action.sa_handler));
that.action.sa_handler(signum);
} else {
- debug("Ignoring");
+ DEBUG_LOG("Ignoring");
}
}
int
SEGVHandler::__wrap_sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact)
{
/* Use system sigaction() function for all but SIGSEGV signals. */
--- a/mozglue/linker/Logging.h
+++ b/mozglue/linker/Logging.h
@@ -2,49 +2,49 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef Logging_h
#define Logging_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_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
#define MOZ_ONE_OR_MORE_ARGS(...) \
MOZ_ONE_OR_MORE_ARGS_IMPL((__VA_ARGS__, m, m, m, m, m, m, m, m, 1, 0))
#define MOZ_MACRO_GLUE(a, b) a b
#define MOZ_CONCAT2(a, b) a ## b
#define MOZ_CONCAT1(a, b) MOZ_CONCAT2(a, b)
#define MOZ_CONCAT(a, b) MOZ_CONCAT1(a, b)
-/* Some magic to choose between log1 and logm depending on the number of
+/* Some magic to choose between LOG1 and LOGm depending on the number of
* arguments */
#define MOZ_CHOOSE_LOG(...) \
- MOZ_MACRO_GLUE(MOZ_CONCAT(log, MOZ_ONE_OR_MORE_ARGS(__VA_ARGS__)), \
+ 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 LOG1(format) fprintf(stderr, format "\n")
+#define LOGm(format, ...) fprintf(stderr, format "\n", __VA_ARGS__)
+#define LOG(...) MOZ_CHOOSE_LOG(__VA_ARGS__)
#endif
#ifdef MOZ_DEBUG_LINKER
-#define debug log
+#define DEBUG_LOG LOG
#else
-#define debug(...)
+#define DEBUG_LOG(...)
#endif
/* HAVE_64BIT_OS is not defined when building host tools, so use
* __SIZEOF_POINTER__ */
#if defined(HAVE_64BIT_OS) || __SIZEOF_POINTER__ == 8
# define PRIxAddr "lx"
# define PRIxSize "lx"
# define PRIdSize "ld"
--- a/mozglue/linker/Mappable.cpp
+++ b/mozglue/linker/Mappable.cpp
@@ -72,94 +72,94 @@ 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; "
+ LOG("Warning: MOZ_LINKER_EXTRACT is set, but not MOZ_LINKER_CACHE; "
"not extracting");
return NULL;
}
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) {
struct stat zipStat;
stat(zip->GetName(), &zipStat);
if (cacheStat.st_mtime > zipStat.st_mtime) {
- debug("Reusing %s", static_cast<char *>(path));
+ DEBUG_LOG("Reusing %s", static_cast<char *>(path));
return MappableFile::Create(path);
}
}
- debug("Extracting to %s", static_cast<char *>(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());
+ LOG("Couldn't open %s to decompress library", path.get());
return NULL;
}
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());
+ LOG("Couldn't ftruncate %s to decompress library", file.get());
return NULL;
}
/* Map the temporary file for use as inflate buffer */
MappedPtr buffer(::mmap(NULL, stream->GetUncompressedSize(), PROT_WRITE,
MAP_SHARED, fd, 0), stream->GetUncompressedSize());
if (buffer == MAP_FAILED) {
- log("Couldn't map %s to decompress library", file.get());
+ LOG("Couldn't map %s to decompress library", file.get());
return NULL;
}
z_stream zStream = stream->GetZStream(buffer);
/* Decompress */
if (inflateInit2(&zStream, -MAX_WBITS) != Z_OK) {
- log("inflateInit failed: %s", zStream.msg);
+ LOG("inflateInit failed: %s", zStream.msg);
return NULL;
}
if (inflate(&zStream, Z_FINISH) != Z_STREAM_END) {
- log("inflate failed: %s", zStream.msg);
+ LOG("inflate failed: %s", zStream.msg);
return NULL;
}
if (inflateEnd(&zStream) != Z_OK) {
- log("inflateEnd failed: %s", zStream.msg);
+ LOG("inflateEnd failed: %s", zStream.msg);
return NULL;
}
if (zStream.total_out != stream->GetUncompressedSize()) {
- log("File not fully uncompressed! %ld / %d", zStream.total_out,
+ LOG("File not fully uncompressed! %ld / %d", zStream.total_out,
static_cast<unsigned int>(stream->GetUncompressedSize()));
return NULL;
}
} else if (stream->GetType() == Zip::Stream::STORE) {
SeekableZStream zStream;
if (!zStream.Init(stream->GetBuffer(), stream->GetSize())) {
- log("Couldn't initialize SeekableZStream for %s", name);
+ LOG("Couldn't initialize SeekableZStream for %s", name);
return NULL;
}
if (ftruncate(fd, zStream.GetUncompressedSize()) == -1) {
- log("Couldn't ftruncate %s to decompress library", file.get());
+ LOG("Couldn't ftruncate %s to decompress library", file.get());
return NULL;
}
MappedPtr buffer(::mmap(NULL, zStream.GetUncompressedSize(), PROT_WRITE,
MAP_SHARED, fd, 0), zStream.GetUncompressedSize());
if (buffer == MAP_FAILED) {
- log("Couldn't map %s to decompress library", file.get());
+ LOG("Couldn't map %s to decompress library", file.get());
return NULL;
}
if (!zStream.Decompress(buffer, 0, zStream.GetUncompressedSize())) {
- log("%s: failed to decompress", name);
+ LOG("%s: failed to decompress", name);
return NULL;
}
} else {
return NULL;
}
return new MappableExtractFile(fd.forget(), file.forget());
}
@@ -208,36 +208,36 @@ public:
* create an empty anonymous page after the ashmem mapping. To do so,
* allocate one page more than requested, then replace the last page with
* an anonymous mapping. */
void *buf = ::mmap(NULL, length + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf != MAP_FAILED) {
::mmap(reinterpret_cast<char *>(buf) + ((length + PAGE_SIZE - 1) & PAGE_MASK),
PAGE_SIZE, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
- debug("Decompression buffer of size %d in ashmem \"%s\", mapped @%p",
- length, str, buf);
+ DEBUG_LOG("Decompression buffer of size %d in ashmem \"%s\", mapped @%p",
+ length, str, buf);
return new _MappableBuffer(fd.forget(), buf, length);
}
#else
/* On Linux, use /dev/shm as base directory for temporary files, assuming
* it's on tmpfs */
/* TODO: check that /dev/shm is tmpfs */
char path[256];
sprintf(path, "/dev/shm/%s.XXXXXX", name);
fd = mkstemp(path);
if (fd == -1)
return NULL;
unlink(path);
ftruncate(fd, length);
void *buf = ::mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf != MAP_FAILED) {
- debug("Decompression buffer of size %ld in \"%s\", mapped @%p",
- length, path, buf);
+ DEBUG_LOG("Decompression buffer of size %ld in \"%s\", mapped @%p",
+ length, path, buf);
return new _MappableBuffer(fd.forget(), buf, length);
}
#endif
return NULL;
}
void *mmap(const void *addr, size_t length, int prot, int flags, off_t offset)
{
@@ -295,46 +295,46 @@ 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);
+ LOG("inflateInit failed: %s", zStream.msg);
return MAP_FAILED;
}
int ret = inflate(&zStream, Z_SYNC_FLUSH);
if (ret < 0) {
- log("inflate failed: %s", zStream.msg);
+ LOG("inflate failed: %s", zStream.msg);
return MAP_FAILED;
}
if (ret == Z_NEED_DICT) {
- log("zstream requires a dictionary. %s", zStream.msg);
+ LOG("zstream requires a dictionary. %s", zStream.msg);
return MAP_FAILED;
}
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);
+ LOG("inflateEnd failed: %s", zStream.msg);
return MAP_FAILED;
}
if (zStream.total_out != buffer->GetLength()) {
- log("File not fully uncompressed! %ld / %d", zStream.total_out,
+ LOG("File not fully uncompressed! %ld / %d", zStream.total_out,
static_cast<unsigned int>(buffer->GetLength()));
return MAP_FAILED;
}
}
}
#if defined(ANDROID) && defined(__arm__)
if (prot & PROT_EXEC) {
/* We just extracted data that may be executed in the future.
* We thus need to ensure Instruction and Data cache coherency. */
- debug("cacheflush(%p, %p)", *buffer + offset, *buffer + (offset + length));
+ DEBUG_LOG("cacheflush(%p, %p)", *buffer + offset, *buffer + (offset + length));
cacheflush(reinterpret_cast<uintptr_t>(*buffer + offset),
reinterpret_cast<uintptr_t>(*buffer + (offset + length)), 0);
}
#endif
return buffer->mmap(addr, length, prot, flags, offset);
}
@@ -440,17 +440,17 @@ public:
}
private:
pthread_mutex_t *mutex;
};
bool
MappableSeekableZStream::ensure(const void *addr)
{
- debug("ensure @%p", addr);
+ DEBUG_LOG("ensure @%p", addr);
void *addrPage = reinterpret_cast<void *>
(reinterpret_cast<uintptr_t>(addr) & PAGE_MASK);
/* Find the mapping corresponding to the given page */
std::vector<LazyMap>::iterator map;
for (map = lazyMaps.begin(); map < lazyMaps.end(); ++map) {
if (map->Contains(addrPage))
break;
}
@@ -494,17 +494,17 @@ MappableSeekableZStream::ensure(const vo
if (chunkAvail[chunk] < (length + PAGE_SIZE - 1) / PAGE_SIZE) {
if (!zStream.DecompressChunk(*buffer + chunkStart, chunk, length))
return false;
#if defined(ANDROID) && defined(__arm__)
if (map->prot & PROT_EXEC) {
/* We just extracted data that may be executed in the future.
* We thus need to ensure Instruction and Data cache coherency. */
- debug("cacheflush(%p, %p)", *buffer + chunkStart, *buffer + (chunkStart + length));
+ DEBUG_LOG("cacheflush(%p, %p)", *buffer + chunkStart, *buffer + (chunkStart + length));
cacheflush(reinterpret_cast<uintptr_t>(*buffer + chunkStart),
reinterpret_cast<uintptr_t>(*buffer + (chunkStart + length)), 0);
}
#endif
/* Only count if we haven't already decompressed parts of the chunk */
if (chunkAvail[chunk] == 0)
chunkAvailNum++;
@@ -521,42 +521,42 @@ MappableSeekableZStream::ensure(const vo
const void *chunkEndAddr = reinterpret_cast<const void *>
(reinterpret_cast<uintptr_t>(chunkAddr) + length);
const void *start = std::max(map->addr, chunkAddr);
const void *end = std::min(map->end(), chunkEndAddr);
length = reinterpret_cast<uintptr_t>(end)
- reinterpret_cast<uintptr_t>(start);
- debug("mprotect @%p, 0x%" PRIxSize ", 0x%x", start, length, map->prot);
+ DEBUG_LOG("mprotect @%p, 0x%" PRIxSize ", 0x%x", start, length, map->prot);
if (mprotect(const_cast<void *>(start), length, map->prot) == 0)
return true;
- log("mprotect failed");
+ LOG("mprotect failed");
return false;
}
void
MappableSeekableZStream::stats(const char *when, const char *name) const
{
size_t nEntries = zStream.GetChunksNum();
- debug("%s: %s; %" PRIdSize "/%" PRIdSize " chunks decompressed",
- name, when, chunkAvailNum, nEntries);
+ DEBUG_LOG("%s: %s; %" PRIdSize "/%" PRIdSize " chunks decompressed",
+ name, when, chunkAvailNum, nEntries);
size_t len = 64;
mozilla::ScopedDeleteArray<char> map;
map = new char[len + 3];
map[0] = '[';
for (size_t i = 0, j = 1; i < nEntries; i++, j++) {
map[j] = chunkAvail[i] ? '*' : '_';
if ((j == len) || (i == nEntries - 1)) {
map[j + 1] = ']';
map[j + 2] = '\0';
- debug("%s", static_cast<char *>(map));
+ DEBUG_LOG("%s", static_cast<char *>(map));
j = 0;
}
}
}
size_t
MappableSeekableZStream::GetLength() const
{
--- a/mozglue/linker/SeekableZStream.cpp
+++ b/mozglue/linker/SeekableZStream.cpp
@@ -14,17 +14,17 @@
#define PAGE_MASK (~ (PAGE_SIZE - 1))
#endif
bool
SeekableZStream::Init(const void *buf, size_t length)
{
const SeekableZStreamHeader *header = SeekableZStreamHeader::validate(buf);
if (!header) {
- log("Not a seekable zstream");
+ LOG("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;
@@ -36,17 +36,17 @@ SeekableZStream::Init(const void *buf, s
/* Sanity check */
if ((chunkSize == 0) ||
(chunkSize % PAGE_SIZE) ||
(chunkSize > 8 * PAGE_SIZE) ||
(offsetTable.numElements() < 1) ||
(lastChunkSize == 0) ||
(lastChunkSize > chunkSize) ||
(length < totalSize)) {
- log("Malformed or broken seekable zstream");
+ LOG("Malformed or broken seekable zstream");
return false;
}
return true;
}
bool
SeekableZStream::Decompress(void *where, size_t chunk, size_t length)
@@ -61,55 +61,55 @@ 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 ")",
+ LOG("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;
if (length == 0 || length > chunkLen)
length = chunkLen;
- debug("DecompressChunk #%" PRIdSize " @%p (%" PRIdSize "/% " PRIdSize ")",
+ DEBUG_LOG("DecompressChunk #%" PRIdSize " @%p (%" PRIdSize "/% " PRIdSize ")",
chunk, where, length, chunkLen);
z_stream zStream;
memset(&zStream, 0, sizeof(zStream));
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);
+ LOG("inflateInit failed: %s", zStream.msg);
return false;
}
if (dictionary && inflateSetDictionary(&zStream, dictionary,
dictionary.numElements()) != Z_OK) {
- log("inflateSetDictionary failed: %s", zStream.msg);
+ LOG("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);
+ LOG("inflate failed: %s", zStream.msg);
return false;
}
if (inflateEnd(&zStream) != Z_OK) {
- log("inflateEnd failed: %s", zStream.msg);
+ LOG("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));
+ LOG("Error opening %s: %s", filename, strerror(errno));
return NULL;
}
struct stat st;
if (fstat(fd, &st) == -1) {
- log("Error stating %s: %s", filename, strerror(errno));
+ LOG("Error stating %s: %s", filename, strerror(errno));
return NULL;
}
size_t size = st.st_size;
if (size <= sizeof(CentralDirectoryEnd)) {
- log("Error reading %s: too short", filename);
+ LOG("Error reading %s: too short", filename);
return NULL;
}
void *mapped = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (mapped == MAP_FAILED) {
- log("Error mmapping %s: %s", filename, strerror(errno));
+ LOG("Error mmapping %s: %s", filename, strerror(errno));
return NULL;
}
- debug("Mapped %s @%p", filename, mapped);
+ 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);
+ LOG("%s - Invalid zip", filename);
return NULL;
}
ZipCollection::Singleton.Register(zip);
return zip;
}
Zip::Zip(const char *filename, void *mapped, size_t size)
@@ -71,38 +71,38 @@ Zip::Zip(const char *filename, void *map
GetFirstEntry();
}
Zip::~Zip()
{
ZipCollection::Forget(this);
if (name) {
munmap(mapped, size);
- debug("Unmapped %s @%p", name, mapped);
+ DEBUG_LOG("Unmapped %s @%p", name, mapped);
free(name);
}
}
bool
Zip::GetStream(const char *path, Zip::Stream *out) const
{
- debug("%s - GetFile %s", name, path);
+ DEBUG_LOG("%s - GetFile %s", name, path);
/* Fast path: if the Local File header on store matches, we can return the
* corresponding stream right away.
* However, the Local File header may not contain enough information, in
* which case the 3rd bit on the generalFlag is set. Unfortunately, this
* bit is also set in some archives even when we do have the data (most
* notably the android packages as built by the Mozilla build system).
* So instead of testing the generalFlag bit, only use the fast path when
* we haven't read the central directory entries yet, and when the
* compressed size as defined in the header is not filled (which is a
* normal condition for the bit to be set). */
if (nextFile && nextFile->GetName().Equals(path) &&
!entries && (nextFile->compressedSize != 0)) {
- debug("%s - %s was next file: fast path", name, path);
+ DEBUG_LOG("%s - %s was next file: fast path", name, path);
/* Fill Stream info from Local File header content */
const char *data = reinterpret_cast<const char *>(nextFile->GetData());
out->compressedBuf = data;
out->compressedSize = nextFile->compressedSize;
out->uncompressedSize = nextFile->uncompressedSize;
out->type = static_cast<Stream::Type>(uint16_t(nextFile->compression));
/* Find the next Local File header. It is usually simply following the
@@ -115,33 +115,33 @@ Zip::GetStream(const char *path, Zip::St
nextFile = LocalFile::validate(data);
return true;
}
/* If the directory entry we have in store doesn't match, scan the Central
* Directory for the entry corresponding to the given path */
if (!nextDir || !nextDir->GetName().Equals(path)) {
const DirectoryEntry *entry = GetFirstEntry();
- debug("%s - Scan directory entries in search for %s", name, path);
+ DEBUG_LOG("%s - Scan directory entries in search for %s", name, path);
while (entry && !entry->GetName().Equals(path)) {
entry = entry->GetNext();
}
nextDir = entry;
}
if (!nextDir) {
- debug("%s - Couldn't find %s", name, path);
+ DEBUG_LOG("%s - Couldn't find %s", name, path);
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);
+ LOG("%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 = NULL;
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);
+ LOG("%s - Couldn't find end of central directory record", name);
return NULL;
}
entries = DirectoryEntry::validate(static_cast<const char *>(mapped)
+ end->offset);
if (!entries) {
- log("%s - Couldn't find central directory record", name);
+ LOG("%s - Couldn't find central directory record", name);
}
return entries;
}
ZipCollection ZipCollection::Singleton;
mozilla::TemporaryRef<Zip>
ZipCollection::GetZip(const char *path)
@@ -197,17 +197,17 @@ void
ZipCollection::Register(Zip *zip)
{
Singleton.zips.push_back(zip);
}
void
ZipCollection::Forget(Zip *zip)
{
- debug("ZipCollection::Forget(\"%s\")", zip->GetName());
+ DEBUG_LOG("ZipCollection::Forget(\"%s\")", zip->GetName());
std::vector<Zip *>::iterator it = std::find(Singleton.zips.begin(),
Singleton.zips.end(), zip);
if (*it == zip) {
Singleton.zips.erase(it);
} else {
- debug("ZipCollection::Forget: didn't find \"%s\" in bookkeeping", zip->GetName());
+ DEBUG_LOG("ZipCollection::Forget: didn't find \"%s\" in bookkeeping", zip->GetName());
}
}
--- a/mozglue/linker/szip.cpp
+++ b/mozglue/linker/szip.cpp
@@ -123,17 +123,17 @@ class Dictionary: public Buffer
return a.second < b.second;
}
public:
Dictionary(Buffer &inBuf, size_t size)
{
if (!size || !Resize(size))
return;
- debug("Creating dictionary");
+ DEBUG_LOG("Creating dictionary");
piece *origBufPieces = reinterpret_cast<piece *>(
static_cast<void *>(inBuf));
std::map<piece, int> stats;
for (int i = 0; i < inBuf.GetLength() / sizeof(piece); i++) {
stats[origBufPieces[i]]++;
}
std::vector<stat_pair> statsVec(stats.begin(), stats.end());
std::sort(statsVec.begin(), statsVec.end(), stat_cmp);
@@ -203,58 +203,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);
+ LOG("%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));
+ LOG("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);
+ LOG("Won't compress %s: it's empty", name);
return 1;
}
if (SeekableZStreamHeader::validate(origBuf)) {
- log("Skipping %s: it's already a szip", name);
+ LOG("Skipping %s: it's already a szip", name);
return 0;
}
bool compressed = false;
- log("Size = %" PRIuSize, origSize);
+ 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));
+ LOG("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;
@@ -267,28 +267,28 @@ int SzipCompress::run(const char *name,
}
mozilla::ScopedDeletePtr<Buffer> filteredBuf;
Buffer *origData;
for (SeekableZStream::FilterId f = firstFilter; f < lastFilter; ++f) {
FilteredBuffer *filteredTmp = NULL;
Buffer tmpBuf;
if (f != SeekableZStream::NONE) {
- debug("Applying filter \"%s\"", filterName[f]);
+ DEBUG_LOG("Applying filter \"%s\"", filterName[f]);
filteredTmp = new FilteredBuffer();
filteredTmp->Filter(origBuf, f, chunkSize);
origData = filteredTmp;
} else {
origData = &origBuf;
}
if (dictSize && !scanFilters) {
filteredBuf = filteredTmp;
break;
}
- debug("Compressing with no dictionary");
+ DEBUG_LOG("Compressing with no dictionary");
if (do_compress(*origData, tmpBuf, NULL, 0, f) == 0) {
if (tmpBuf.GetLength() < outBuf.GetLength()) {
outBuf.Fill(tmpBuf);
compressed = true;
filter = f;
filteredBuf = filteredTmp;
continue;
}
@@ -308,54 +308,54 @@ int SzipCompress::run(const char *name,
firstDictSize = scanFilters ? 4096 : 0;
lastDictSize = SzipCompress::winSize;
} else {
firstDictSize = lastDictSize = dictSize;
}
Buffer tmpBuf;
for (size_t d = firstDictSize; d <= lastDictSize; d += 4096) {
- debug("Compressing with dictionary of size %" PRIuSize, d);
+ DEBUG_LOG("Compressing with dictionary of size %" PRIuSize, d);
if (do_compress(*origData, tmpBuf, static_cast<unsigned char *>(dict)
+ SzipCompress::winSize - d, d, filter))
continue;
if (!compressed || tmpBuf.GetLength() < outBuf.GetLength()) {
outBuf.Fill(tmpBuf);
compressed = true;
dictSize = d;
}
}
}
if (!compressed) {
outBuf.Fill(origBuf);
- log("Not compressed");
+ LOG("Not compressed");
return 0;
}
if (dictSize == (size_t) -1)
dictSize = 0;
- debug("Used filter \"%s\" and dictionary size of %" PRIuSize,
- filterName[filter], dictSize);
- log("Compressed size is %" PRIuSize, outBuf.GetLength());
+ DEBUG_LOG("Used filter \"%s\" and dictionary size of %" PRIuSize,
+ filterName[filter], dictSize);
+ LOG("Compressed size is %" PRIuSize, outBuf.GetLength());
/* 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);
+ LOG("Compression error: %" PRIuSize " != %" PRIuSize, size, origSize);
return 1;
}
if (memcmp(static_cast<void *>(origBuf), static_cast<void *>(tmpBuf), size)) {
- log("Compression error: content mismatch");
+ LOG("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)
@@ -372,17 +372,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));
+ LOG("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);
@@ -436,17 +436,17 @@ int SzipCompress::do_compress(Buffer &or
size -= avail;
data += avail;
offset += len;
}
header->lastChunkSize = avail;
MOZ_ASSERT(header->totalSize == offset);
if (!outBuf.Resize(offset)) {
- log("Error truncating output: %s", strerror(errno));
+ LOG("Error truncating output: %s", strerror(errno));
return 1;
}
MOZ_ASSERT(header->nChunks == nChunks);
return 0;
}
@@ -475,100 +475,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");
+ LOG("Invalid chunk size");
return 1;
}
} else if (strcmp(firstArg[0], "-f") == 0) {
firstArg++;
argc--;
if (!firstArg[0])
break;
bool matched = false;
for (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");
+ LOG("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");
+ LOG("Invalid dictionary size");
return 1;
}
}
}
if (argc != 2 || !firstArg[0]) {
- log("usage: %s [-d] [-c CHUNKSIZE] [-f FILTER] [-D DICTSIZE] file",
+ 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");
+ LOG("-c is incompatible with -d");
return 1;
}
if (dictSize) {
- log("-D is incompatible with -d");
+ LOG("-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));
+ LOG("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));
+ LOG("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));
+ LOG("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));
+ LOG("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;
}
}