/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/latebindingsymboltable.h"

#if defined(WEBRTC_POSIX)
#include <dlfcn.h>
#endif

#include "webrtc/base/logging.h"

namespace rtc {

#if defined(WEBRTC_POSIX)
static const DllHandle kInvalidDllHandle = NULL;
#else
#error Not implemented
#endif

static const char *GetDllError() {
#if defined(WEBRTC_POSIX)
  const char *err = dlerror();
  if (err) {
    return err;
  } else {
    return "No error";
  }
#else
#error Not implemented
#endif
}

static bool LoadSymbol(DllHandle handle,
                       const char *symbol_name,
                       void **symbol) {
#if defined(WEBRTC_POSIX)
  *symbol = dlsym(handle, symbol_name);
  const char *err = dlerror();
  if (err) {
    LOG(LS_ERROR) << "Error loading symbol " << symbol_name << ": " << err;
    return false;
  } else if (!*symbol) {
    // ELF allows for symbols to be NULL, but that should never happen for our
    // usage.
    LOG(LS_ERROR) << "Symbol " << symbol_name << " is NULL";
    return false;
  }
  return true;
#else
#error Not implemented
#endif
}

LateBindingSymbolTable::LateBindingSymbolTable(const TableInfo *info,
    void **table)
    : info_(info),
      table_(table),
      handle_(kInvalidDllHandle),
      undefined_symbols_(false) {
  ClearSymbols();
}

LateBindingSymbolTable::~LateBindingSymbolTable() {
  Unload();
}

bool LateBindingSymbolTable::IsLoaded() const {
  return handle_ != kInvalidDllHandle;
}

bool LateBindingSymbolTable::Load() {
  ASSERT(info_->dll_name != NULL);
  return LoadFromPath(info_->dll_name);
}

bool LateBindingSymbolTable::LoadFromPath(const char *dll_path) {
  if (IsLoaded()) {
    return true;
  }
  if (undefined_symbols_) {
    // We do not attempt to load again because repeated attempts are not
    // likely to succeed and DLL loading is costly.
    LOG(LS_ERROR) << "We know there are undefined symbols";
    return false;
  }

#if defined(WEBRTC_POSIX)
  handle_ = dlopen(dll_path,
                   // RTLD_NOW front-loads symbol resolution so that errors are
                   // caught early instead of causing a process abort later.
                   // RTLD_LOCAL prevents other modules from automatically
                   // seeing symbol definitions in the newly-loaded tree. This
                   // is necessary for same-named symbols in different ABI
                   // versions of the same library to not explode.
                   RTLD_NOW|RTLD_LOCAL
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
                   // RTLD_DEEPBIND makes symbol dependencies in the
                   // newly-loaded tree prefer to resolve to definitions within
                   // that tree (the default on OS X). This is necessary for
                   // same-named symbols in different ABI versions of the same
                   // library to not explode.
                   |RTLD_DEEPBIND
#endif
                   );  // NOLINT
#else
#error Not implemented
#endif

  if (handle_ == kInvalidDllHandle) {
    LOG(LS_WARNING) << "Can't load " << dll_path << ": "
                    << GetDllError();
    return false;
  }
#if defined(WEBRTC_POSIX)
  // Clear any old errors.
  dlerror();
#endif
  for (int i = 0; i < info_->num_symbols; ++i) {
    if (!LoadSymbol(handle_, info_->symbol_names[i], &table_[i])) {
      undefined_symbols_ = true;
      Unload();
      return false;
    }
  }
  return true;
}

void LateBindingSymbolTable::Unload() {
  if (!IsLoaded()) {
    return;
  }

#if defined(WEBRTC_POSIX)
  if (dlclose(handle_) != 0) {
    LOG(LS_ERROR) << GetDllError();
  }
#else
#error Not implemented
#endif

  handle_ = kInvalidDllHandle;
  ClearSymbols();
}

void LateBindingSymbolTable::ClearSymbols() {
  memset(table_, 0, sizeof(void *) * info_->num_symbols);
}

}  // namespace rtc
