Skip to content

Commit bdd42d3

Browse files
committed
Make ELF reader big-endian compatible
Converting from integers to char arrays reveals endianness.
1 parent f88d3c1 commit bdd42d3

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

src/goto-programs/elf_reader.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,39 @@ Module: Read ELF
1414

1515
#include <istream>
1616

17+
static void u16_to_native_endian_inplace(bool le_input, uint16_t &input)
18+
{
19+
const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
20+
input = (((uint16_t)input_as_bytes[0]) << (le_input ? 0 : 8)) |
21+
(((uint16_t)input_as_bytes[1]) << (le_input ? 8 : 0));
22+
}
23+
24+
static void u32_to_native_endian_inplace(bool le_input, uint32_t &input)
25+
{
26+
const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
27+
input = (((uint32_t)input_as_bytes[0]) << (le_input ? 0 : 24)) |
28+
(((uint32_t)input_as_bytes[1]) << (le_input ? 8 : 16)) |
29+
(((uint32_t)input_as_bytes[2]) << (le_input ? 16 : 8)) |
30+
(((uint32_t)input_as_bytes[3]) << (le_input ? 24 : 0));
31+
}
32+
33+
static void
34+
u64_to_native_endian_inplace(bool le_input, unsigned long long &input)
35+
{
36+
static_assert(
37+
sizeof(unsigned long long) == 8,
38+
"unsigned long long expected to be 8 bytes");
39+
const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
40+
input = (((unsigned long long)input_as_bytes[0]) << (le_input ? 0 : 56)) |
41+
(((unsigned long long)input_as_bytes[1]) << (le_input ? 8 : 48)) |
42+
(((unsigned long long)input_as_bytes[2]) << (le_input ? 16 : 40)) |
43+
(((unsigned long long)input_as_bytes[3]) << (le_input ? 24 : 32)) |
44+
(((unsigned long long)input_as_bytes[4]) << (le_input ? 32 : 24)) |
45+
(((unsigned long long)input_as_bytes[5]) << (le_input ? 40 : 16)) |
46+
(((unsigned long long)input_as_bytes[6]) << (le_input ? 48 : 8)) |
47+
(((unsigned long long)input_as_bytes[7]) << (le_input ? 56 : 0));
48+
}
49+
1750
elf_readert::elf_readert(std::istream &_in):in(_in)
1851
{
1952
// read 32-bit header
@@ -43,6 +76,20 @@ elf_readert::elf_readert(std::istream &_in):in(_in)
4376
else
4477
throw deserialization_exceptiont("ELF32 header malformed (EI_DATA)");
4578

79+
u16_to_native_endian_inplace(little_endian, elf32_header.e_type);
80+
u16_to_native_endian_inplace(little_endian, elf32_header.e_machine);
81+
u32_to_native_endian_inplace(little_endian, elf32_header.e_version);
82+
u32_to_native_endian_inplace(little_endian, elf32_header.e_entry);
83+
u32_to_native_endian_inplace(little_endian, elf32_header.e_phoff);
84+
u32_to_native_endian_inplace(little_endian, elf32_header.e_shoff);
85+
u32_to_native_endian_inplace(little_endian, elf32_header.e_flags);
86+
u16_to_native_endian_inplace(little_endian, elf32_header.e_ehsize);
87+
u16_to_native_endian_inplace(little_endian, elf32_header.e_phentsize);
88+
u16_to_native_endian_inplace(little_endian, elf32_header.e_phnum);
89+
u16_to_native_endian_inplace(little_endian, elf32_header.e_shentsize);
90+
u16_to_native_endian_inplace(little_endian, elf32_header.e_shnum);
91+
u16_to_native_endian_inplace(little_endian, elf32_header.e_shstrndx);
92+
4693
if(elf32_header.e_version!=1)
4794
throw deserialization_exceptiont("unknown ELF32 version");
4895

@@ -64,6 +111,26 @@ elf_readert::elf_readert(std::istream &_in):in(_in)
64111
in.read(
65112
reinterpret_cast<char*>(&elf32_section_header_table[i]),
66113
sizeof(Elf32_Shdr));
114+
u32_to_native_endian_inplace(
115+
little_endian, elf32_section_header_table[i].sh_name);
116+
u32_to_native_endian_inplace(
117+
little_endian, elf32_section_header_table[i].sh_type);
118+
u32_to_native_endian_inplace(
119+
little_endian, elf32_section_header_table[i].sh_flags);
120+
u32_to_native_endian_inplace(
121+
little_endian, elf32_section_header_table[i].sh_addr);
122+
u32_to_native_endian_inplace(
123+
little_endian, elf32_section_header_table[i].sh_offset);
124+
u32_to_native_endian_inplace(
125+
little_endian, elf32_section_header_table[i].sh_size);
126+
u32_to_native_endian_inplace(
127+
little_endian, elf32_section_header_table[i].sh_link);
128+
u32_to_native_endian_inplace(
129+
little_endian, elf32_section_header_table[i].sh_info);
130+
u32_to_native_endian_inplace(
131+
little_endian, elf32_section_header_table[i].sh_addralign);
132+
u32_to_native_endian_inplace(
133+
little_endian, elf32_section_header_table[i].sh_entsize);
67134
}
68135

69136
// string table
@@ -89,6 +156,19 @@ elf_readert::elf_readert(std::istream &_in):in(_in)
89156
little_endian=false;
90157
else
91158
throw deserialization_exceptiont("ELF64 header malformed (EI_DATA)");
159+
u16_to_native_endian_inplace(little_endian, elf64_header.e_type);
160+
u16_to_native_endian_inplace(little_endian, elf64_header.e_machine);
161+
u32_to_native_endian_inplace(little_endian, elf64_header.e_version);
162+
u64_to_native_endian_inplace(little_endian, elf64_header.e_entry);
163+
u64_to_native_endian_inplace(little_endian, elf64_header.e_phoff);
164+
u64_to_native_endian_inplace(little_endian, elf64_header.e_shoff);
165+
u32_to_native_endian_inplace(little_endian, elf64_header.e_flags);
166+
u16_to_native_endian_inplace(little_endian, elf64_header.e_ehsize);
167+
u16_to_native_endian_inplace(little_endian, elf64_header.e_phentsize);
168+
u16_to_native_endian_inplace(little_endian, elf64_header.e_phnum);
169+
u16_to_native_endian_inplace(little_endian, elf64_header.e_shentsize);
170+
u16_to_native_endian_inplace(little_endian, elf64_header.e_shnum);
171+
u16_to_native_endian_inplace(little_endian, elf64_header.e_shstrndx);
92172

93173
if(elf64_header.e_version!=1)
94174
throw deserialization_exceptiont("unknown ELF64 version");
@@ -111,6 +191,26 @@ elf_readert::elf_readert(std::istream &_in):in(_in)
111191
in.read(
112192
reinterpret_cast<char*>(&elf64_section_header_table[i]),
113193
sizeof(Elf64_Shdr));
194+
u32_to_native_endian_inplace(
195+
little_endian, elf64_section_header_table[i].sh_name);
196+
u32_to_native_endian_inplace(
197+
little_endian, elf64_section_header_table[i].sh_type);
198+
u64_to_native_endian_inplace(
199+
little_endian, elf64_section_header_table[i].sh_flags);
200+
u64_to_native_endian_inplace(
201+
little_endian, elf64_section_header_table[i].sh_addr);
202+
u64_to_native_endian_inplace(
203+
little_endian, elf64_section_header_table[i].sh_offset);
204+
u64_to_native_endian_inplace(
205+
little_endian, elf64_section_header_table[i].sh_size);
206+
u32_to_native_endian_inplace(
207+
little_endian, elf64_section_header_table[i].sh_link);
208+
u32_to_native_endian_inplace(
209+
little_endian, elf64_section_header_table[i].sh_info);
210+
u64_to_native_endian_inplace(
211+
little_endian, elf64_section_header_table[i].sh_addralign);
212+
u64_to_native_endian_inplace(
213+
little_endian, elf64_section_header_table[i].sh_entsize);
114214
}
115215

116216
// string table

0 commit comments

Comments
 (0)