CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
elf_reader.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Read ELF
4
5Author:
6
7\*******************************************************************/
8
11
12#include "elf_reader.h"
13
15
16#include <cstdint>
17#include <istream>
18
20{
21 const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
22 input = (((uint16_t)input_as_bytes[0]) << (le_input ? 0 : 8)) |
23 (((uint16_t)input_as_bytes[1]) << (le_input ? 8 : 0));
24}
25
27{
28 const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
29 input = (((uint32_t)input_as_bytes[0]) << (le_input ? 0 : 24)) |
30 (((uint32_t)input_as_bytes[1]) << (le_input ? 8 : 16)) |
31 (((uint32_t)input_as_bytes[2]) << (le_input ? 16 : 8)) |
32 (((uint32_t)input_as_bytes[3]) << (le_input ? 24 : 0));
33}
34
35static void
36u64_to_native_endian_inplace(bool le_input, unsigned long long &input)
37{
38 static_assert(
39 sizeof(unsigned long long) == 8,
40 "unsigned long long expected to be 8 bytes");
41 const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
42 input = (((unsigned long long)input_as_bytes[0]) << (le_input ? 0 : 56)) |
43 (((unsigned long long)input_as_bytes[1]) << (le_input ? 8 : 48)) |
44 (((unsigned long long)input_as_bytes[2]) << (le_input ? 16 : 40)) |
45 (((unsigned long long)input_as_bytes[3]) << (le_input ? 24 : 32)) |
46 (((unsigned long long)input_as_bytes[4]) << (le_input ? 32 : 24)) |
47 (((unsigned long long)input_as_bytes[5]) << (le_input ? 40 : 16)) |
48 (((unsigned long long)input_as_bytes[6]) << (le_input ? 48 : 8)) |
49 (((unsigned long long)input_as_bytes[7]) << (le_input ? 56 : 0));
50}
51
53{
54 // read 32-bit header
55 in.read(
56 reinterpret_cast<char*>(&elf32_header),
57 sizeof(elf32_header));
58
59 if(!in)
60 throw deserialization_exceptiont("failed to read ELF header");
61
62 if(elf32_header.e_ident[0]!=0x7f ||
63 elf32_header.e_ident[1]!='E' ||
64 elf32_header.e_ident[2]!='L' ||
65 elf32_header.e_ident[3]!='F')
66 throw deserialization_exceptiont("ELF header malformed (magic)");
67
69
70 if(elf_class==ELF32)
71 {
72 const auto ei_data = elf32_header.e_ident[5];
73
74 if(ei_data==1)
75 little_endian=true;
76 else if(ei_data==2)
77 little_endian=false;
78 else
79 throw deserialization_exceptiont("ELF32 header malformed (EI_DATA)");
80
94
96 throw deserialization_exceptiont("unknown ELF32 version");
97
98 // get offset for section header
99 if(elf32_header.e_shoff==0 ||
101 throw deserialization_exceptiont("ELF32 without section header");
102
105
106 // iterate over these
107 for(std::size_t i=0; i<elf32_section_header_table.size(); i++)
108 {
109 // go to right place
111
112 // read section header
113 in.read(
114 reinterpret_cast<char*>(&elf32_section_header_table[i]),
115 sizeof(Elf32_Shdr));
136 }
137
138 // string table
141 throw deserialization_exceptiont("ELF32 without string table");
142
144 }
145 else if(elf_class==ELF64)
146 {
147 // read 64-bit header
148 in.seekg(0);
149 in.read(
150 reinterpret_cast<char*>(&elf64_header),
151 sizeof(elf64_header));
152
153 const auto ei_data = elf64_header.e_ident[5];
154
155 if(ei_data==1)
156 little_endian=true;
157 else if(ei_data==2)
158 little_endian=false;
159 else
160 throw deserialization_exceptiont("ELF64 header malformed (EI_DATA)");
174
176 throw deserialization_exceptiont("unknown ELF64 version");
177
178 // get offset for section header
179 if(elf64_header.e_shoff==0 ||
181 throw deserialization_exceptiont("ELF64 without section header");
182
185
186 // iterate over these
187 for(std::size_t i=0; i<elf64_section_header_table.size(); i++)
188 {
189 // go to right place
191
192 // read section header
193 in.read(
194 reinterpret_cast<char*>(&elf64_section_header_table[i]),
195 sizeof(Elf64_Shdr));
216 }
217
218 // string table
221 throw deserialization_exceptiont("ELF64 without string table");
222
224 }
225}
226
227std::string elf_readert::get_string(std::streampos index) const
228{
229 in.seekg(string_table_offset+index);
230
231 std::string result;
232
233 while(in)
234 {
235 char ch;
236 in.read(&ch, 1);
237 if(ch==0)
238 break;
239 result+=ch;
240 }
241
242 return result;
243}
244
245bool elf_readert::has_section(const std::string &name) const
246{
247 for(std::size_t i=0; i<number_of_sections; i++)
248 if(section_name(i)==name)
249 return true;
250
251 return false;
252}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Thrown when failing to deserialize a value from some low level format, like JSON or raw bytes.
std::size_t number_of_sections
Definition elf_reader.h:135
Elf64_Ehdr elf64_header
Definition elf_reader.h:110
Elf32_Ehdr elf32_header
Definition elf_reader.h:109
elf_readert(std::istream &_in)
std::string get_string(std::streampos index) const
elf64_section_header_tablet elf64_section_header_table
Definition elf_reader.h:119
std::istream & in
Definition elf_reader.h:154
bool has_section(const std::string &name) const
elf32_section_header_tablet elf32_section_header_table
Definition elf_reader.h:116
std::string section_name(std::size_t index) const
Definition elf_reader.h:137
std::streampos string_table_offset
Definition elf_reader.h:122
bool little_endian
Definition elf_reader.h:112
elf_classt elf_class
Definition elf_reader.h:106
std::streampos section_offset(std::size_t index) const
Definition elf_reader.h:144
static void u32_to_native_endian_inplace(bool le_input, uint32_t &input)
static void u16_to_native_endian_inplace(bool le_input, uint16_t &input)
static void u64_to_native_endian_inplace(bool le_input, unsigned long long &input)
Read ELF.
Elf32_Off e_shoff
Definition elf_reader.h:44
Elf32_Half e_ehsize
Definition elf_reader.h:46
Elf32_Half e_shnum
Definition elf_reader.h:50
Elf32_Half e_machine
Definition elf_reader.h:40
Elf32_Off e_phoff
Definition elf_reader.h:43
Elf32_Half e_phnum
Definition elf_reader.h:48
Elf32_Half e_shstrndx
Definition elf_reader.h:51
Elf32_Half e_type
Definition elf_reader.h:39
unsigned char e_ident[16]
Definition elf_reader.h:38
Elf32_Word e_flags
Definition elf_reader.h:45
Elf32_Word e_version
Definition elf_reader.h:41
Elf32_Half e_shentsize
Definition elf_reader.h:49
Elf32_Addr e_entry
Definition elf_reader.h:42
Elf32_Half e_phentsize
Definition elf_reader.h:47
Elf64_Half e_type
Definition elf_reader.h:57
Elf64_Half e_shentsize
Definition elf_reader.h:67
unsigned char e_ident[16]
Definition elf_reader.h:56
Elf64_Half e_shnum
Definition elf_reader.h:68
Elf64_Word e_version
Definition elf_reader.h:59
Elf64_Half e_ehsize
Definition elf_reader.h:64
Elf64_Off e_shoff
Definition elf_reader.h:62
Elf64_Addr e_entry
Definition elf_reader.h:60
Elf64_Half e_phentsize
Definition elf_reader.h:65
Elf64_Off e_phoff
Definition elf_reader.h:61
Elf64_Half e_machine
Definition elf_reader.h:58
Elf64_Word e_flags
Definition elf_reader.h:63
Elf64_Half e_shstrndx
Definition elf_reader.h:69
Elf64_Half e_phnum
Definition elf_reader.h:66