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_LIST_H
6#define CRAZY_LINKER_LIBRARY_LIST_H
7
8#include <link.h>
9
10#include "crazy_linker_error.h"
11#include "crazy_linker_search_path_list.h"
12#include "elf_traits.h"
13
14// This header contains definitions related to the global list of
15// library views maintained by the crazy linker. Each library view
16// points to either a crazy library, or a system one.
17
18namespace crazy {
19
20class SharedLibrary;
21class LibraryView;
22
23// The list of all shared libraries loaded by the crazy linker.
24// IMPORTANT: This class is not thread-safe!
25class LibraryList {
26 public:
27  LibraryList();
28  ~LibraryList();
29
30  // Find a library in the list by its base name.
31  // |base_name| must not contain a directory separator.
32  LibraryView* FindLibraryByName(const char* base_name);
33
34  // Lookup for a given |symbol_name|, starting from |from_lib|
35  // then through its dependencies in breadth-first search order.
36  // On failure, returns NULL.
37  void* FindSymbolFrom(const char* symbol_name, LibraryView* from_lib);
38
39  // Return the address of a visible given symbol. Used to implement
40  // the dlsym() wrapper. Returns NULL on failure.
41  void* FindAddressForSymbol(const char* symbol_name);
42
43  // Find a SharedLibrary that contains a given address, or NULL if none
44  // could be found. This simply scans all libraries.
45  LibraryView* FindLibraryForAddress(void* address);
46
47#ifdef __arm__
48  // Find the base address of the .ARM.exidx section corresponding
49  // to the address |pc|, as well as the number of 8-byte entries in
50  // the table into |*count|. Used to implement the wrapper for
51  // dl_unwind_find_exidx().
52  _Unwind_Ptr FindArmExIdx(void* pc, int* count);
53#else
54  typedef int (*PhdrIterationCallback)(dl_phdr_info* info,
55                                       size_t info_size,
56                                       void* data);
57
58  // Loop over all loaded libraries and call the |cb| callback
59  // on each iteration. If the function returns 0, stop immediately
60  // and return its value. Used to implement the wrapper for
61  // dl_iterate_phdr().
62  int IteratePhdr(PhdrIterationCallback callback, void* data);
63#endif
64
65  // Try to load a library, possibly at a fixed address.
66  // On failure, returns NULL and sets the |error| message.
67  LibraryView* LoadLibrary(const char* path,
68                           int dlopen_flags,
69                           uintptr_t load_address,
70                           off_t file_offset,
71                           SearchPathList* search_path_list,
72                           Error* error);
73
74  // Try to load a library from its location in the zip file.
75  // On failure, returns NULL and sets the |error| message.
76  LibraryView* LoadLibraryInZipFile(const char* zip_file_path,
77                                    const char* lib_name,
78                                    int dlopen_flags,
79                                    uintptr_t load_address,
80                                    SearchPathList* search_path_list,
81                                    Error* error);
82
83  // Unload a given shared library. This really decrements the library's
84  // internal reference count. When it reaches zero, the library's
85  // destructors are run, its dependencies are unloaded, then the
86  // library is removed from memory.
87  void UnloadLibrary(LibraryView* lib);
88
89  // Used internally by the wrappers only.
90  void AddLibrary(LibraryView* lib);
91
92 private:
93  LibraryList(const LibraryList&);
94  LibraryList& operator=(const LibraryList&);
95
96  void ClearError();
97
98  // The list of all known libraries.
99  Vector<LibraryView*> known_libraries_;
100
101  LibraryView* FindKnownLibrary(const char* name);
102
103  // The list of all libraries loaded by the crazy linker.
104  // This does _not_ include system libraries present in known_libraries_.
105  SharedLibrary* head_;
106
107  size_t count_;
108  bool has_error_;
109  char error_buffer_[512];
110};
111
112}  // namespace crazy
113
114#endif  // CRAZY_LINKER_LIBRARY_LIST_H
115