• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 ART_RUNTIME_OAT_ELF_FILE_IMPL_H_
18 #define ART_RUNTIME_OAT_ELF_FILE_IMPL_H_
19 
20 #include <type_traits>
21 #include <vector>
22 
23 #include "base/macros.h"
24 #include "base/mem_map.h"
25 #include "base/os.h"
26 #include "elf_file.h"
27 
28 namespace art HIDDEN {
29 
30 template <typename ElfTypes>
31 class ElfFileImpl : public ElfFile {
32  public:
33   using Elf_Addr = typename ElfTypes::Addr;
34   using Elf_Off = typename ElfTypes::Off;
35   using Elf_Half = typename ElfTypes::Half;
36   using Elf_Word = typename ElfTypes::Word;
37   using Elf_Sword = typename ElfTypes::Sword;
38   using Elf_Ehdr = typename ElfTypes::Ehdr;
39   using Elf_Shdr = typename ElfTypes::Shdr;
40   using Elf_Sym = typename ElfTypes::Sym;
41   using Elf_Rel = typename ElfTypes::Rel;
42   using Elf_Rela = typename ElfTypes::Rela;
43   using Elf_Phdr = typename ElfTypes::Phdr;
44   using Elf_Dyn = typename ElfTypes::Dyn;
45 
46   static ElfFileImpl* Open(File* file,
47                            off_t start,
48                            size_t file_length,
49                            const std::string& file_location,
50                            bool low_4gb,
51                            /*out*/ std::string* error_msg);
52 
53   Elf_Ehdr& GetHeader() const;
54 
55   Elf_Word GetProgramHeaderNum() const;
56   Elf_Phdr* GetProgramHeader(Elf_Word) const;
57 
58   Elf_Word GetSectionHeaderNum() const;
59   Elf_Shdr* FindSectionByType(Elf_Word type) const;
60 
61   // Find .dynsym using .hash for more efficient lookup than FindSymbolAddress.
62   const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const override;
63 
64   static bool IsSymbolSectionType(Elf_Word section_type);
65   Elf_Word GetSymbolNum(Elf_Shdr&) const;
66   Elf_Sym* GetSymbol(Elf_Word section_type, Elf_Word i) const;
67 
68   Elf_Word GetDynamicNum() const;
69   Elf_Dyn& GetDynamic(Elf_Word) const;
70 
71   // Retrieves the expected size when the file is loaded at runtime. Returns true if successful.
72   bool GetLoadedSize(size_t* size, std::string* error_msg) const override;
73 
74   // Get the alignment of the first loadable program segment. Return 0 if no loadable segment found.
75   size_t GetElfSegmentAlignmentFromFile() const override;
76 
77   // Load segments into memory based on PT_LOAD program headers.
78   // executable is true at run time, false at compile time.
79   bool Load(bool executable,
80             bool low_4gb,
81             /*inout*/ MemMap* reservation,
82             /*out*/ std::string* error_msg) override;
83 
Is64Bit()84   bool Is64Bit() const override { return std::is_same_v<ElfTypes, ElfTypes64>; }
85 
86  private:
ElfFileImpl(File * file,off_t start,size_t file_length,const std::string & file_location)87   ElfFileImpl(File* file, off_t start, size_t file_length, const std::string& file_location)
88       : ElfFile(file, start, file_length, file_location) {}
89 
90   bool GetLoadedAddressRange(/*out*/uint8_t** vaddr_begin,
91                              /*out*/size_t* vaddr_size,
92                              /*out*/std::string* error_msg) const;
93 
94   bool Setup(bool low_4gb, std::string* error_msg);
95 
96   bool SetMap(MemMap&& map, std::string* error_msg);
97 
98   uint8_t* GetProgramHeadersStart() const;
99   Elf_Phdr& GetDynamicProgramHeader() const;
100   Elf_Dyn* GetDynamicSectionStart() const;
101   Elf_Sym* GetSymbolSectionStart(Elf_Word section_type) const;
102   const char* GetStringSectionStart(Elf_Word section_type) const;
103   Elf_Word* GetHashSectionStart() const;
104   Elf_Word GetHashBucketNum() const;
105   Elf_Word GetHashChainNum() const;
106   Elf_Word GetHashBucket(size_t i, bool* ok) const;
107   Elf_Word GetHashChain(size_t i, bool* ok) const;
108 
109   bool ValidPointer(const uint8_t* start) const;
110 
111   const Elf_Sym* FindDynamicSymbol(const std::string& symbol_name) const;
112 
113   // Check that certain sections and their dependencies exist.
114   bool CheckSectionsExist(std::string* error_msg) const;
115 
116   Elf_Phdr* FindProgamHeaderByType(Elf_Word type) const;
117 
118   // Lookup a string by section type. Returns null for special 0 offset.
119   const char* GetString(Elf_Word section_type, Elf_Word) const;
120 
121   Elf_Ehdr* header_ = nullptr;
122 
123   // Conditionally available values. Use accessors to ensure they exist if they are required.
124   uint8_t* section_headers_start_ = nullptr;
125   Elf_Phdr* dynamic_program_header_ = nullptr;
126   Elf_Dyn* dynamic_section_start_ = nullptr;
127   Elf_Sym* symtab_section_start_ = nullptr;
128   Elf_Sym* dynsym_section_start_ = nullptr;
129   char* strtab_section_start_ = nullptr;
130   char* dynstr_section_start_ = nullptr;
131   Elf_Word* hash_section_start_ = nullptr;
132 
133   DISALLOW_COPY_AND_ASSIGN(ElfFileImpl);
134 };
135 
136 }  // namespace art
137 
138 #endif  // ART_RUNTIME_OAT_ELF_FILE_IMPL_H_
139