1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CRAZY_LINKER_LIBRARY_VIEW_H
6#define CRAZY_LINKER_LIBRARY_VIEW_H
7
8#include "crazy_linker_error.h"
9#include "crazy_linker_util.h"
10
11namespace crazy {
12
13class SharedLibrary;
14
15// A LibraryView is a reference-counted handle to either a
16// crazy::SharedLibrary object or a library handle returned by the system's
17// dlopen() function.
18//
19// It has a name, which is always a base name, because only one
20// library with a given base name can be loaded in the system.
21class LibraryView {
22 public:
23  enum {
24    TYPE_NONE = 0xbaadbaad,
25    TYPE_SYSTEM = 0x2387cef,
26    TYPE_CRAZY = 0xcdef2387,
27  };
28
29  LibraryView()
30      : type_(TYPE_NONE), crazy_(NULL), system_(NULL), name_(), ref_count_(1) {}
31
32  ~LibraryView();
33
34  bool IsSystem() const { return type_ == TYPE_SYSTEM; }
35
36  bool IsCrazy() const { return type_ == TYPE_CRAZY; }
37
38  void SetSystem(void* system_lib, const char* name) {
39    type_ = TYPE_SYSTEM;
40    system_ = system_lib;
41    name_ = name;
42  }
43
44  void SetCrazy(SharedLibrary* crazy_lib, const char* name) {
45    type_ = TYPE_CRAZY;
46    crazy_ = crazy_lib;
47    name_ = name;
48  }
49
50  const char* GetName() { return name_.c_str(); }
51
52  SharedLibrary* GetCrazy() { return IsCrazy() ? crazy_ : NULL; }
53
54  void* GetSystem() { return IsSystem() ? system_ : NULL; }
55
56  void AddRef() { ref_count_++; }
57
58  // Decrement reference count. Returns true iff it reaches 0.
59  // This never destroys the object.
60  bool SafeDecrementRef() { return (--ref_count_ == 0); }
61
62  // Lookup a symbol from this library.
63  // If this is a crazy library, perform a breadth-first search,
64  // for system libraries, use dlsym() instead.
65  void* LookupSymbol(const char* symbol_name);
66
67  // Retrieve library information.
68  bool GetInfo(size_t* load_address,
69               size_t* load_size,
70               size_t* relro_start,
71               size_t* relro_size,
72               Error* error);
73
74  // Only used for debugging.
75  int ref_count() const { return ref_count_; }
76
77 private:
78  uint32_t type_;
79  SharedLibrary* crazy_;
80  void* system_;
81  String name_;
82  int ref_count_;
83};
84
85}  // namespace crazy
86
87#endif  // CRAZY_LINKER_LIBRARY_VIEW_H