blob: 33b5fc3f9bf1e35b59ef02ab74d74bd4f69d02ed [file] [log] [blame]
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_ELF_FILE_H_
18#define ART_RUNTIME_ELF_FILE_H_
Brian Carlstrom700c8d32012-11-05 10:42:02 -080019
Brian Carlstrom265091e2013-01-30 14:08:26 -080020#include <map>
Brian Carlstrom700c8d32012-11-05 10:42:02 -080021#include <vector>
22
23#include <llvm/Support/ELF.h>
24
25#include "base/unix_file/fd_file.h"
26#include "globals.h"
27#include "mem_map.h"
28#include "os.h"
29#include "UniquePtr.h"
30
31namespace art {
32
33// Used for compile time and runtime for ElfFile access. Because of
34// the need for use at runtime, cannot directly use LLVM classes such as
35// ELFObjectFile.
36class ElfFile {
37 public:
38 static ElfFile* Open(File* file, bool writable, bool program_header_only);
39 ~ElfFile();
40
41 // Load segments into memory based on PT_LOAD program headers
42
43 File& GetFile() const {
44 return *file_;
45 }
46
47 byte* Begin() {
48 return map_->Begin();
49 }
50
51 byte* End() {
52 return map_->End();
53 }
54
55 size_t Size() const {
56 return map_->Size();
57 }
58
Ian Rogers4c1c2832013-03-04 18:30:13 -080059 ::llvm::ELF::Elf32_Ehdr& GetHeader();
Brian Carlstrom700c8d32012-11-05 10:42:02 -080060
Ian Rogers4c1c2832013-03-04 18:30:13 -080061 ::llvm::ELF::Elf32_Word GetProgramHeaderNum();
62 ::llvm::ELF::Elf32_Phdr& GetProgramHeader(::llvm::ELF::Elf32_Word);
63 ::llvm::ELF::Elf32_Phdr* FindProgamHeaderByType(::llvm::ELF::Elf32_Word type);
Brian Carlstrom700c8d32012-11-05 10:42:02 -080064
Ian Rogers4c1c2832013-03-04 18:30:13 -080065 ::llvm::ELF::Elf32_Word GetSectionHeaderNum();
66 ::llvm::ELF::Elf32_Shdr& GetSectionHeader(::llvm::ELF::Elf32_Word);
67 ::llvm::ELF::Elf32_Shdr* FindSectionByType(::llvm::ELF::Elf32_Word type);
Brian Carlstrom700c8d32012-11-05 10:42:02 -080068
Brian Carlstrom265091e2013-01-30 14:08:26 -080069 ::llvm::ELF::Elf32_Shdr& GetSectionNameStringSection();
70
71 // Find .dynsym using .hash for more efficient lookup than FindSymbolAddress.
Brian Carlstrom700c8d32012-11-05 10:42:02 -080072 byte* FindDynamicSymbolAddress(const std::string& symbol_name);
73
Ian Rogers4c1c2832013-03-04 18:30:13 -080074 static bool IsSymbolSectionType(::llvm::ELF::Elf32_Word section_type);
75 ::llvm::ELF::Elf32_Word GetSymbolNum(::llvm::ELF::Elf32_Shdr&);
76 ::llvm::ELF::Elf32_Sym& GetSymbol(::llvm::ELF::Elf32_Word section_type, ::llvm::ELF::Elf32_Word i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -080077
Brian Carlstrom265091e2013-01-30 14:08:26 -080078 // Find symbol in specified table, returning NULL if it is not found.
79 //
80 // If build_map is true, builds a map to speed repeated access. The
81 // map does not included untyped symbol values (aka STT_NOTYPE)
82 // since they can contain duplicates. If build_map is false, the map
83 // will be used if it was already created. Typically build_map
84 // should be set unless only a small number of symbols will be
85 // looked up.
86 ::llvm::ELF::Elf32_Sym* FindSymbolByName(::llvm::ELF::Elf32_Word section_type,
87 const std::string& symbol_name,
88 bool build_map);
89
90 // Find address of symbol in specified table, returning 0 if it is
91 // not found. See FindSymbolByName for an explanation of build_map.
92 ::llvm::ELF::Elf32_Addr FindSymbolAddress(::llvm::ELF::Elf32_Word section_type,
93 const std::string& symbol_name,
94 bool build_map);
95
96 // Lookup a string given string section and offset. Returns NULL for
97 // special 0 offset.
98 const char* GetString(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word);
99
100 // Lookup a string by section type. Returns NULL for special 0 offset.
101 const char* GetString(::llvm::ELF::Elf32_Word section_type, ::llvm::ELF::Elf32_Word);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800102
Ian Rogers4c1c2832013-03-04 18:30:13 -0800103 ::llvm::ELF::Elf32_Word GetDynamicNum();
104 ::llvm::ELF::Elf32_Dyn& GetDynamic(::llvm::ELF::Elf32_Word);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800105 ::llvm::ELF::Elf32_Word FindDynamicValueByType(::llvm::ELF::Elf32_Sword type);
106
107 ::llvm::ELF::Elf32_Word GetRelNum(::llvm::ELF::Elf32_Shdr&);
108 ::llvm::ELF::Elf32_Rel& GetRel(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word);
109
110 ::llvm::ELF::Elf32_Word GetRelaNum(::llvm::ELF::Elf32_Shdr&);
111 ::llvm::ELF::Elf32_Rela& GetRela(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800112
113 // Returns the expected size when the file is loaded at runtime
114 size_t GetLoadedSize();
115
Brian Carlstromf1d34552013-07-12 20:22:23 -0700116 // Load segments into memory based on PT_LOAD program headers.
117 // executable is true at run time, false at compile time.
118 bool Load(bool executable);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800119
120 private:
121 ElfFile();
122
123 bool Setup(File* file, bool writable, bool program_header_only);
124
125 bool SetMap(MemMap* map);
126
127 byte* GetProgramHeadersStart();
128 byte* GetSectionHeadersStart();
Ian Rogers4c1c2832013-03-04 18:30:13 -0800129 ::llvm::ELF::Elf32_Phdr& GetDynamicProgramHeader();
130 ::llvm::ELF::Elf32_Dyn* GetDynamicSectionStart();
131 ::llvm::ELF::Elf32_Sym* GetSymbolSectionStart(::llvm::ELF::Elf32_Word section_type);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800132 const char* GetStringSectionStart(::llvm::ELF::Elf32_Word section_type);
133 ::llvm::ELF::Elf32_Rel* GetRelSectionStart(::llvm::ELF::Elf32_Shdr&);
134 ::llvm::ELF::Elf32_Rela* GetRelaSectionStart(::llvm::ELF::Elf32_Shdr&);
Ian Rogers4c1c2832013-03-04 18:30:13 -0800135 ::llvm::ELF::Elf32_Word* GetHashSectionStart();
136 ::llvm::ELF::Elf32_Word GetHashBucketNum();
137 ::llvm::ELF::Elf32_Word GetHashChainNum();
138 ::llvm::ELF::Elf32_Word GetHashBucket(size_t i);
139 ::llvm::ELF::Elf32_Word GetHashChain(size_t i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800140
Brian Carlstrom265091e2013-01-30 14:08:26 -0800141 typedef std::map<std::string, ::llvm::ELF::Elf32_Sym*> SymbolTable;
142 SymbolTable** GetSymbolTable(::llvm::ELF::Elf32_Word section_type);
143
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800144 File* file_;
145 bool writable_;
146 bool program_header_only_;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800147
148 // ELF header mapping. If program_header_only_ is false, will actually point to the entire elf file.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800149 UniquePtr<MemMap> map_;
Ian Rogers4c1c2832013-03-04 18:30:13 -0800150 ::llvm::ELF::Elf32_Ehdr* header_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800151 std::vector<MemMap*> segments_;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800152
153 // Pointer to start of first PT_LOAD program segment after Load() when program_header_only_ is true.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800154 byte* base_address_;
155
156 // The program header should always available but use GetProgramHeadersStart() to be sure.
157 byte* program_headers_start_;
158
159 // Conditionally available values. Use accessors to ensure they exist if they are required.
160 byte* section_headers_start_;
Ian Rogers4c1c2832013-03-04 18:30:13 -0800161 ::llvm::ELF::Elf32_Phdr* dynamic_program_header_;
162 ::llvm::ELF::Elf32_Dyn* dynamic_section_start_;
163 ::llvm::ELF::Elf32_Sym* symtab_section_start_;
164 ::llvm::ELF::Elf32_Sym* dynsym_section_start_;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800165 const char* strtab_section_start_;
166 const char* dynstr_section_start_;
Ian Rogers4c1c2832013-03-04 18:30:13 -0800167 ::llvm::ELF::Elf32_Word* hash_section_start_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800168
Brian Carlstrom265091e2013-01-30 14:08:26 -0800169 SymbolTable* symtab_symbol_table_;
170 SymbolTable* dynsym_symbol_table_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800171};
172
173} // namespace art
174
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700175#endif // ART_RUNTIME_ELF_FILE_H_