4198875361a6b900c9ff76add03af1e81f69ac37
[gem5.git] / src / base / loader / elf_object.cc
1 /*
2 * Copyright (c) 2011-2013, 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 #include "base/loader/elf_object.hh"
42
43 #include <fcntl.h>
44 #include <sys/mman.h>
45 #include <sys/stat.h>
46 #include <sys/types.h>
47 #include <unistd.h>
48
49 #include <cassert>
50 #include <string>
51
52 #include "base/bitfield.hh"
53 #include "base/loader/symtab.hh"
54 #include "base/logging.hh"
55 #include "base/trace.hh"
56 #include "debug/Loader.hh"
57 #include "gelf.h"
58 #include "sim/byteswap.hh"
59
60 namespace Loader
61 {
62
63 ObjectFile *
64 ElfObjectFormat::load(ImageFileDataPtr ifd)
65 {
66 // check that header matches library version
67 if (elf_version(EV_CURRENT) == EV_NONE)
68 panic("wrong elf version number!");
69
70 ObjectFile *object = nullptr;
71
72 // get a pointer to elf structure
73 // Check that we actually have a elf file
74 Elf *elf =
75 elf_memory((char *)const_cast<uint8_t *>(ifd->data()), ifd->len());
76 assert(elf);
77
78 GElf_Ehdr ehdr;
79 if (gelf_getehdr(elf, &ehdr) == 0)
80 DPRINTFR(Loader, "Not ELF\n");
81 else
82 object = new ElfObject(ifd);
83
84 elf_end(elf);
85
86 return object;
87 }
88
89 namespace
90 {
91
92 ElfObjectFormat elfObjectFormat;
93 std::string interpDir;
94
95 } // anonymous namespace
96
97 void
98 setInterpDir(const std::string &dirname)
99 {
100 fatal_if(!interpDir.empty(),
101 "Error: setInterpDir has already been called once\n");
102 interpDir = dirname;
103 }
104
105 ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
106 {
107 // get a pointer to elf structure
108 elf = elf_memory((char *)const_cast<uint8_t *>(imageData->data()),
109 imageData->len());
110 assert(elf);
111 gelf_getehdr(elf, &ehdr);
112
113 determineArch();
114 determineOpSys();
115 determineByteOrder();
116
117 entry = ehdr.e_entry;
118 _programHeaderCount = ehdr.e_phnum;
119 _programHeaderSize = ehdr.e_phentsize;
120
121 // Go through all the segments in the program and record them.
122 for (int i = 0; i < ehdr.e_phnum; ++i) {
123 GElf_Phdr phdr;
124 if (gelf_getphdr(elf, i, &phdr) == 0) {
125 panic("gelf_getphdr failed for segment %d.", i);
126 }
127
128 if (phdr.p_type == PT_LOAD)
129 handleLoadableSegment(phdr, i);
130 if (phdr.p_type == PT_INTERP) {
131 // Make sure the interpreter is an valid ELF file.
132 auto interp_path = getInterpPath(phdr);
133 ObjectFile *obj = createObjectFile(interp_path);
134 interpreter = dynamic_cast<ElfObject *>(obj);
135 assert(interpreter != nullptr);
136 _symtab.insert(obj->symtab());
137 }
138 }
139
140 // should have found at least one loadable segment
141 warn_if(image.segments().empty(),
142 "No loadable segments in '%s'. ELF file corrupted?\n",
143 imageData->filename());
144
145 for (M5_VAR_USED auto &seg: image.segments())
146 DPRINTFR(Loader, "%s\n", seg);
147
148 // We will actually read the sections when we need to load them
149
150 // check that header matches library version
151 if (elf_version(EV_CURRENT) == EV_NONE)
152 panic("wrong elf version number!");
153
154 // Get the first section
155 int sec_idx = 1; // there is a 0 but it is nothing, go figure
156 Elf_Scn *section = elf_getscn(elf, sec_idx);
157
158 // While there are no more sections
159 while (section) {
160 GElf_Shdr shdr;
161 gelf_getshdr(section, &shdr);
162
163 if (shdr.sh_type == SHT_SYMTAB) {
164 Elf_Data *data = elf_getdata(section, nullptr);
165 int count = shdr.sh_size / shdr.sh_entsize;
166 DPRINTF(Loader, "Found Symbol Table, %d symbols present.", count);
167
168 // Loop through all the symbols.
169 for (int i = 0; i < count; ++i) {
170 GElf_Sym sym;
171 gelf_getsym(data, i, &sym);
172
173 char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name);
174 if (!sym_name || sym_name[0] == '$')
175 continue;
176
177 Loader::Symbol symbol;
178 symbol.address = sym.st_value;
179 symbol.name = sym_name;
180
181 switch (GELF_ST_BIND(sym.st_info)) {
182 case STB_GLOBAL:
183 symbol.binding = Loader::Symbol::Binding::Global;
184 break;
185 case STB_LOCAL:
186 symbol.binding = Loader::Symbol::Binding::Local;
187 break;
188 case STB_WEAK:
189 symbol.binding = Loader::Symbol::Binding::Weak;
190 break;
191 default:
192 continue;
193 }
194
195 if (_symtab.insert(symbol)) {
196 DPRINTF(Loader, "Symbol: %-40s value %#x.\n",
197 symbol.name, symbol.address);
198 }
199 }
200 }
201 ++sec_idx;
202 section = elf_getscn(elf, sec_idx);
203 }
204 }
205
206 std::string
207 ElfObject::getInterpPath(const GElf_Phdr &phdr) const
208 {
209 // This is the interpreter path as specified in the elf file
210 const std::string elf_path = (char *)imageData->data() + phdr.p_offset;
211 if (!interpDir.empty())
212 return interpDir + elf_path;
213 else
214 return elf_path;
215 }
216
217 void
218 ElfObject::determineArch()
219 {
220 auto &emach = ehdr.e_machine;
221 auto &eclass = ehdr.e_ident[EI_CLASS];
222 auto &edata = ehdr.e_ident[EI_DATA];
223
224 // Detect the architecture
225 if (emach == EM_SPARC64 || (emach == EM_SPARC && eclass == ELFCLASS64) ||
226 emach == EM_SPARCV9) {
227 arch = SPARC64;
228 } else if (emach == EM_SPARC32PLUS ||
229 (emach == EM_SPARC && eclass == ELFCLASS32)) {
230 arch = SPARC32;
231 } else if (emach == EM_MIPS && eclass == ELFCLASS32) {
232 arch = Mips;
233 if (edata != ELFDATA2LSB) {
234 fatal("The binary you're trying to load is compiled for big "
235 "endian MIPS. gem5\nonly supports little endian MIPS. "
236 "Please recompile your binary.\n");
237 }
238 } else if (emach == EM_X86_64 && eclass == ELFCLASS64) {
239 arch = X86_64;
240 } else if (emach == EM_386 && eclass == ELFCLASS32) {
241 arch = I386;
242 } else if (emach == EM_ARM && eclass == ELFCLASS32) {
243 arch = bits(ehdr.e_entry, 0) ? Thumb : Arm;
244 } else if (emach == EM_AARCH64 && eclass == ELFCLASS64) {
245 arch = Arm64;
246 } else if (emach == EM_RISCV) {
247 arch = (eclass == ELFCLASS64) ? Riscv64 : Riscv32;
248 } else if (emach == EM_PPC && eclass == ELFCLASS32) {
249 arch = Power;
250 if (edata != ELFDATA2MSB) {
251 fatal("The binary you're trying to load is compiled for "
252 "little endian Power.\ngem5 only supports big "
253 "endian Power. Please recompile your binary.\n");
254 }
255 } else if (emach == EM_PPC64) {
256 fatal("The binary you're trying to load is compiled for 64-bit "
257 "Power. M5\n only supports 32-bit Power. Please "
258 "recompile your binary.\n");
259 } else {
260 warn("Unknown architecture: %d\n", emach);
261 }
262 }
263
264 void
265 ElfObject::determineOpSys()
266 {
267 // Detect the operating system
268 switch (ehdr.e_ident[EI_OSABI]) {
269 case ELFOSABI_LINUX:
270 opSys = Linux;
271 return;
272 case ELFOSABI_SOLARIS:
273 opSys = Solaris;
274 return;
275 case ELFOSABI_TRU64:
276 opSys = Tru64;
277 return;
278 case ELFOSABI_ARM:
279 opSys = LinuxArmOABI;
280 return;
281 case ELFOSABI_FREEBSD:
282 opSys = FreeBSD;
283 return;
284 default:
285 opSys = UnknownOpSys;
286 }
287
288 Elf_Scn *section = elf_getscn(elf, 1);
289 for (int sec_idx = 1; section; section = elf_getscn(elf, ++sec_idx)) {
290 GElf_Shdr shdr;
291 gelf_getshdr(section, &shdr);
292
293 char *e_str = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
294 if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag", e_str)) {
295 // we have found a ABI note section
296 // Check the 5th 32bit word for OS 0 == linux, 1 == hurd,
297 // 2 == solaris, 3 == freebsd
298 Elf_Data *raw_data = elf_rawdata(section, nullptr);
299 assert(raw_data && raw_data->d_buf);
300
301 uint32_t raw_abi = ((uint32_t *)raw_data->d_buf)[4];
302 bool is_le = ehdr.e_ident[EI_DATA] == ELFDATA2LSB;
303 uint32_t os_abi = is_le ? htole(raw_abi) : htobe(raw_abi);
304
305 switch (os_abi) {
306 case 0:
307 opSys = Linux;
308 return;
309 case 1:
310 fatal("gem5 does not support the HURD ABI.\n");
311 case 2:
312 opSys = Solaris;
313 return;
314 case 3:
315 opSys = FreeBSD;
316 return;
317 }
318 }
319
320 if (!strcmp(".SUNW_version", e_str) || !strcmp(".stab.index", e_str)) {
321 opSys = Solaris;
322 return;
323 }
324 }
325 }
326
327 void
328 ElfObject::determineByteOrder()
329 {
330 auto edata = ehdr.e_ident[EI_DATA];
331 if (edata == ELFDATANONE)
332 panic("invalid ELF data encoding");
333 byteOrder = (edata == ELFDATA2MSB) ? ByteOrder::big : ByteOrder::little;
334 }
335
336 void
337 ElfObject::handleLoadableSegment(GElf_Phdr phdr, int seg_num)
338 {
339 auto name = std::to_string(seg_num);
340
341 if (phdr.p_memsz == 0) {
342 warn("Ignoring empty loadable segment %s", name);
343 return;
344 }
345
346 image.addSegment({ name, phdr.p_paddr, imageData,
347 phdr.p_offset, phdr.p_filesz });
348 Addr uninitialized = phdr.p_memsz - phdr.p_filesz;
349 if (uninitialized) {
350 // There may be parts of a segment which aren't included in the
351 // file. In those cases, we need to create a new segment with no
352 // data to take up the extra space. This should be zeroed when
353 // loaded into memory.
354 image.addSegment({ name + "(uninitialized)",
355 phdr.p_paddr + phdr.p_filesz, uninitialized });
356 }
357
358 const Addr file_start = phdr.p_offset;
359 const Addr file_end = file_start + phdr.p_filesz;
360
361 // If there is a program header table, figure out the virtual
362 // address of the header table in the final memory image. We use
363 // the program headers themselves to translate from a file offset
364 // to the address in the image.
365 if (file_start <= ehdr.e_phoff && file_end > ehdr.e_phoff)
366 _programHeaderTable = phdr.p_vaddr + (ehdr.e_phoff - file_start);
367 }
368
369 ElfObject::~ElfObject()
370 {
371 elf_end(elf);
372 }
373
374 void
375 ElfObject::getSections()
376 {
377 assert(!sectionNames.size());
378
379 // check that header matches library version
380 if (elf_version(EV_CURRENT) == EV_NONE)
381 panic("wrong elf version number!");
382
383 // get a pointer to elf structure
384 Elf *elf =
385 elf_memory((char *)const_cast<uint8_t *>(imageData->data()),
386 imageData->len());
387 assert(elf != NULL);
388
389 // Check that we actually have a elf file
390 GElf_Ehdr ehdr;
391 if (gelf_getehdr(elf, &ehdr) ==0) {
392 panic("Not ELF, shouldn't be here");
393 }
394
395 // Get the first section
396 int sec_idx = 1; // there is a 0 but it is nothing, go figure
397 Elf_Scn *section = elf_getscn(elf, sec_idx);
398
399 // While there are no more sections
400 while (section) {
401 GElf_Shdr shdr;
402 gelf_getshdr(section, &shdr);
403 sectionNames.insert(elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
404 section = elf_getscn(elf, ++sec_idx);
405 } // while sections
406
407 elf_end(elf);
408 }
409
410 bool
411 ElfObject::sectionExists(std::string sec)
412 {
413 if (!sectionNames.size())
414 getSections();
415
416 return sectionNames.find(sec) != sectionNames.end();
417 }
418
419
420 void
421 ElfObject::updateBias(Addr bias_addr)
422 {
423 // Record the bias.
424 ldBias = bias_addr;
425
426 // Patch the entry point with bias_addr.
427 entry += bias_addr;
428
429 // Patch segments with the bias_addr.
430 image.offset(bias_addr);
431 }
432
433 } // namespace Loader