#include <string.h>
#include <stdint.h>
#include <_simple.h>
#include "Logging.h"
namespace dyld3 {
static bool sVerboseLoading = false;
static bool sVerboseInitializers = false;
static bool sVerboseSegments = false;
static bool sVerboseAPIs = false;
static bool sVerboseNotifications = false;
static bool sVerboseFixups = false;
static bool sVerboseDOFs = false;
static void vlog_default(const char* format, va_list list)
{
_simple_vdprintf(2, format, list);
}
static void (*sLogFunction)(const char* format, va_list list) = &vlog_default;
static void (*sHaltFunction)(const char* message) __attribute__((noreturn)) = nullptr;
void halt(const char* message)
{
(*sHaltFunction)(message);
}
static void vlog(const char* format, va_list list)
{
(*sLogFunction)(format, list);
}
bool log_loads(const char* format, ...)
{
if ( !sVerboseLoading )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_segments(const char* format, ...)
{
if ( !sVerboseSegments )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_fixups(const char* format, ...)
{
if ( !sVerboseFixups )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_initializers(const char* format, ...)
{
if ( !sVerboseInitializers )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_apis(const char* format, ...)
{
if ( !sVerboseAPIs )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_notifications(const char* format, ...)
{
if ( !sVerboseNotifications )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
bool log_dofs(const char* format, ...)
{
if ( !sVerboseDOFs )
return false;
va_list list;
va_start(list, format);
vlog(format, list);
va_end(list);
return true;
}
void setLoggingFromEnvs(const char* envp[])
{
for(const char** p = envp; *p != NULL; p++) {
const char* keyEqualsValue = *p;
const char* equals = strchr(keyEqualsValue, '=');
if ( equals != NULL ) {
const size_t keyLen = equals-keyEqualsValue;
char key[keyLen+1];
strncpy(key, keyEqualsValue, keyLen);
key[keyLen] = '\0';
if ( strcmp(key, "DYLD_PRINT_LIBRARIES") == 0 ) {
sVerboseLoading = true;
}
else if ( strcmp(key, "DYLD_PRINT_SEGMENTS") == 0 ) {
sVerboseSegments = true;
}
else if ( strcmp(key, "DYLD_PRINT_INITIALIZERS") == 0 ) {
sVerboseInitializers = true;
}
else if ( strcmp(key, "DYLD_PRINT_APIS") == 0 ) {
sVerboseAPIs = true;
}
else if ( strcmp(key, "DYLD_PRINT_NOTIFICATIONS") == 0 ) {
sVerboseNotifications = true;
}
else if ( strcmp(key, "DYLD_PRINT_BINDINGS") == 0 ) {
sVerboseFixups = true;
}
else if ( strcmp(key, "DYLD_PRINT_DOFS") == 0 ) {
sVerboseDOFs = true;
}
}
}
}
void setLoggingFunction(void (*func)(const char* format, va_list list))
{
sLogFunction = func;
}
void setHaltFunction(void (*func)(const char* message) __attribute__((noreturn)))
{
sHaltFunction = func;
}
}