blob: e0e974b82dd0eab66427936d783684fa6ae8deab [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <dlfcn.h>
#include <stdio.h>
// A version of the zoo test library that loads and unloads LIB_NAME
// in an ELF initializer / finalizer, respectively, while performing
// the dlsym() inside of Zoo().
// The point of this is to check that recursive dlopen(), are supported
// by the crazy linker.
// Name of the library that contains this code.
#error THIS_LIB_NAME should be defined!
// Name of the library to load / unload.
#ifndef LIB_NAME
#define LIB_NAME ""
// Name of the entry point to find and call in the loaded library.
#ifndef LIB_SYMBOL
#define LIB_SYMBOL "Zoo"
static void* sLib = NULL;
static char sError[512] = {};
// Declare initializer and finalize functions.
static void RunOnLoad() __attribute__((constructor));
static void RunOnUnload() __attribute__((destructor));
// Define them.
void RunOnLoad() {
printf("%s:%s: Entering\n", THIS_LIB_NAME, __FUNCTION__);
sLib = dlopen(LIB_NAME, RTLD_NOW);
if (!sLib) {
fprintf(stderr, "%s:%s: Could not open %s: %s", THIS_LIB_NAME, __FUNCTION__,
LIB_NAME, dlerror());
printf("%s:%s: Found '%s' handle %p\n", THIS_LIB_NAME, __FUNCTION__, LIB_NAME,
#if defined(LIB_SYMBOL)
auto* lib_func = reinterpret_cast<void (*)()>(dlsym(sLib, LIB_SYMBOL));
if (!lib_func) {
fprintf(stderr, "%s:%s: Could not find '%s' symbol in %s", THIS_LIB_NAME,
printf("%s:%s: Found '%s' symbol at @%p\n", THIS_LIB_NAME, __FUNCTION__,
LIB_SYMBOL, lib_func);
// Call it.
#endif // LIB_SYMBOL
printf("%s:%s: Exiting\n", THIS_LIB_NAME, __FUNCTION__);
void RunOnUnload() {
printf("%s:%s: Entering\n", THIS_LIB_NAME, __FUNCTION__);
if (sLib) {
int ret = dlclose(sLib);
if (ret != 0) {
fprintf(stderr, "%s:%s: Could not close library: %s", THIS_LIB_NAME,
__FUNCTION__, dlerror());
sLib = NULL;
printf("%s:%s: Exiting\n", THIS_LIB_NAME, __FUNCTION__);
extern "C" bool Zoo() {
printf("%s:%s:sLib=%s @ %p\n", THIS_LIB_NAME, __FUNCTION__, LIB_NAME, sLib);
return sLib != NULL;