1 /*
2  * Copyright (C) 2017 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_LOADED_ELF_FILE_H_
18 #define BERBERIS_TINY_LOADER_LOADED_ELF_FILE_H_
19 
20 #include "berberis/base/macros.h"
21 #include "berberis/tiny_loader/elf_types.h"
22 #include "berberis/tiny_loader/tiny_symbol_table.h"
23 
24 #include <elf.h>
25 
26 #include <string>
27 
28 class LoadedElfFile {
29  public:
LoadedElfFile()30   LoadedElfFile()
31       : e_type_(ET_NONE),
32         base_addr_(nullptr),
33         load_bias_(0),
34         entry_point_(nullptr),
35         phdr_table_(nullptr),
36         phdr_count_(0),
37         dynamic_(nullptr) {}
38 
LoadedElfFile(ElfHalf e_type,void * base_addr,ElfAddr load_bias,void * entry_point,const ElfPhdr * phdr_table,size_t phdr_count,const ElfDyn * dynamic,size_t gnu_nbucket,uint32_t * gnu_bucket,uint32_t * gnu_chain,uint32_t gnu_maskwords,uint32_t gnu_shift2,ElfAddr * gnu_bloom_filter,ElfSym * symtab,const char * strtab,size_t strtab_size)39   LoadedElfFile(ElfHalf e_type, void* base_addr, ElfAddr load_bias, void* entry_point,
40                 const ElfPhdr* phdr_table, size_t phdr_count, const ElfDyn* dynamic,
41                 size_t gnu_nbucket, uint32_t* gnu_bucket, uint32_t* gnu_chain,
42                 uint32_t gnu_maskwords, uint32_t gnu_shift2, ElfAddr* gnu_bloom_filter,
43                 ElfSym* symtab, const char* strtab, size_t strtab_size)
44       : e_type_(e_type),
45         base_addr_(base_addr),
46         load_bias_(load_bias),
47         entry_point_(entry_point),
48         phdr_table_(phdr_table),
49         phdr_count_(phdr_count),
50         dynamic_(dynamic),
51         symbol_table_(load_bias, symtab, strtab, strtab_size, gnu_nbucket, gnu_bucket, gnu_chain,
52                       gnu_maskwords, gnu_shift2, gnu_bloom_filter) {}
53 
LoadedElfFile(ElfHalf e_type,void * base_addr,ElfAddr load_bias,void * entry_point,const ElfPhdr * phdr_table,size_t phdr_count,const ElfDyn * dynamic,size_t sysv_nbucket,size_t sysv_nchain,uint32_t * sysv_bucket,uint32_t * sysv_chain,ElfSym * symtab,const char * strtab,size_t strtab_size)54   LoadedElfFile(ElfHalf e_type, void* base_addr, ElfAddr load_bias, void* entry_point,
55                 const ElfPhdr* phdr_table, size_t phdr_count, const ElfDyn* dynamic,
56                 size_t sysv_nbucket, size_t sysv_nchain, uint32_t* sysv_bucket,
57                 uint32_t* sysv_chain, ElfSym* symtab, const char* strtab, size_t strtab_size)
58       : e_type_(e_type),
59         base_addr_(base_addr),
60         load_bias_(load_bias),
61         entry_point_(entry_point),
62         phdr_table_(phdr_table),
63         phdr_count_(phdr_count),
64         dynamic_(dynamic),
65         symbol_table_(load_bias, symtab, strtab, strtab_size, sysv_nbucket, sysv_nchain,
66                       sysv_bucket, sysv_chain) {}
67 
68   LoadedElfFile(LoadedElfFile&& that) = default;
69 
70   LoadedElfFile& operator=(LoadedElfFile&& that) = default;
71 
is_loaded()72   bool is_loaded() const { return e_type_ != ET_NONE; }
73 
e_type()74   ElfHalf e_type() const { return e_type_; }
75 
base_addr()76   void* base_addr() const { return base_addr_; }
77 
load_bias()78   ElfAddr load_bias() const { return load_bias_; }
79 
entry_point()80   void* entry_point() const { return entry_point_; }
81 
phdr_table()82   const ElfPhdr* phdr_table() const { return phdr_table_; }
83 
phdr_count()84   size_t phdr_count() const { return phdr_count_; }
85 
dynamic()86   const ElfDyn* dynamic() const { return dynamic_; }
87 
FindSymbol(const char * name)88   void* FindSymbol(const char* name) const { return symbol_table_.FindSymbol(name); }
89 
ForEachSymbol(std::function<void (const char *,void *,const ElfSym *)> symbol_handler)90   void ForEachSymbol(std::function<void(const char*, void*, const ElfSym*)> symbol_handler) const {
91     symbol_table_.ForEachSymbol(symbol_handler);
92   }
93 
94  private:
95   ElfHalf e_type_;
96   void* base_addr_;
97   ElfAddr load_bias_;
98   void* entry_point_;
99   const ElfPhdr* phdr_table_;
100   size_t phdr_count_;
101   const ElfDyn* dynamic_;
102 
103   TinySymbolTable symbol_table_;
104 };
105 
106 #endif  // BERBERIS_TINY_LOADER_LOADED_ELF_FILE_H_
107