1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef BERBERIS_TINY_LOADER_TINY_SYMBOL_TABLE_H_
18 #define BERBERIS_TINY_LOADER_TINY_SYMBOL_TABLE_H_
19 
20 #include "berberis/base/macros.h"
21 #include "berberis/tiny_loader/elf_types.h"
22 
23 #include <elf.h>
24 
25 #include <functional>
26 
27 class TinySymbolTable {
28  public:
29   TinySymbolTable();
30 
31   TinySymbolTable(ElfAddr load_bias, ElfSym* symtab, const char* strtab, size_t strtab_size,
32                   size_t gnu_nbucket, uint32_t* gnu_bucket, uint32_t* gnu_chain,
33                   uint32_t gnu_maskwords, uint32_t gnu_shift2, ElfAddr* gnu_bloom_filter);
34 
35   TinySymbolTable(ElfAddr load_bias, ElfSym* symtab, const char* strtab, size_t strtab_size,
36                   size_t sysv_nbucket, size_t sysv_nchain, uint32_t* sysv_bucket,
37                   uint32_t* sysv_chain);
38 
39   TinySymbolTable(TinySymbolTable&& that) = default;
40   TinySymbolTable& operator=(TinySymbolTable&& that) = default;
41 
42   void* FindSymbol(const char* name) const;
43 
44   // Iterate over all defined symbols in the elf-file
45   void ForEachSymbol(std::function<void(const char*, void*, const ElfSym*)> symbol_handler) const;
46 
47  private:
48   uint32_t GnuHash(const char* name) const;
49   uint32_t SysvHash(const char* name) const;
50   void* FindGnuSymbol(const char* name) const;
51   void* FindSysvSymbol(const char* name) const;
52   void ForEachGnuSymbol(std::function<void(const ElfSym*)> symbol_handler) const;
53   void ForEachSysvSymbol(std::function<void(const ElfSym*)> symbol_handler) const;
54 
55   const char* GetString(ElfWord index) const;
56 
57   ElfAddr load_bias_;
58 
59   // Symbol table
60   ElfSym* symtab_;
61 
62   // String table
63   const char* strtab_;
64   size_t strtab_size_;
65 
66   bool is_gnu_hash_;
67 
68   // Gnu hash
69   size_t gnu_nbucket_;
70   uint32_t* gnu_bucket_;
71   uint32_t* gnu_chain_;
72   uint32_t gnu_maskwords_;
73   uint32_t gnu_shift2_;
74   ElfAddr* gnu_bloom_filter_;
75 
76   // Sysv hash
77   size_t sysv_nbucket_;
78   size_t sysv_nchain_;
79   uint32_t* sysv_bucket_;
80   uint32_t* sysv_chain_;
81 };
82 
83 #endif  // BERBERIS_TINY_LOADER_TINY_SYMBOL_TABLE_H_
84