The Pedigree Project 0.1
elf.c
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "elf.h"
21
22#include <stdint.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27Elf_t* elf_create(uint8_t* buffer, size_t len) {
28 Elf_t* elf = (Elf_t*)malloc(sizeof(Elf_t));
29 // The main header will be at buffer[0].
30 elf->header = (ElfHeader_t*)buffer;
31
32 // Check the ident.
33 if ((elf->header->ident[1] != 'E') || (elf->header->ident[2] != 'L') ||
34 (elf->header->ident[3] != 'F') || (elf->header->ident[0] != 127)) {
35 printf("ELF file: ident check failed!");
36 return 0;
37 }
38
39 // Check the bit-length.
40 if (elf->header->ident[4] != 1) {
41 printf("ELF file: wrong bit length!");
42 return 0;
43 }
44
45 // Load in the section headers.
46 elf->section_headers =
47 (ElfSectionHeader_t*)malloc(sizeof(ElfSectionHeader_t) * elf->header->shnum);
48 memcpy((uint8_t*)elf->section_headers, &buffer[elf->header->shoff],
49 elf->header->shnum * sizeof(ElfSectionHeader_t));
50
51 // Find the section header string table.
52 ElfSectionHeader_t* shstrtab_section = &elf->section_headers[elf->header->shstrndx];
53
54 // Load the section header string table.
55 char* shstrtab = (char*)malloc(shstrtab_section->size);
56 memcpy((uint8_t*)shstrtab, &buffer[shstrtab_section->offset], shstrtab_section->size);
57
58 ElfSectionHeader_t *symtab = 0, *strtab = 0;
59 // Go through each section header, trying to find .symtab.
60 for (int i = 0; i < elf->header->shnum; i++) {
61 const char* str = shstrtab + elf->section_headers[i].name;
62 if (!strcmp(str, ".symtab"))
63 symtab = &elf->section_headers[i];
64 if (!strcmp(str, ".strtab"))
65 strtab = &elf->section_headers[i];
66 }
67
68 if (symtab == 0) {
69 printf("ELF: symbol table not found!");
70 return 0;
71 } else {
72 elf->symtabsz = symtab->size / sizeof(ElfSymbol_t);
73 elf->symtab = (ElfSymbol_t*)malloc(symtab->size);
74 memcpy((uint8_t*)elf->symtab, &buffer[symtab->offset], symtab->size);
75 }
76
77 if (strtab == 0) {
78 printf("ELF: string table not found!");
79 return 0;
80 } else {
81 elf->strtabsz = strtab->size;
82 elf->strtab = (char*)malloc(strtab->size);
83 memcpy((uint8_t*)elf->strtab, &buffer[strtab->offset], strtab->size);
84 }
85
86 elf->buffer = buffer;
87
88 return elf;
89}
90
91ElfSymbol_t* elf_get_symbol(Elf_t* elf, const char* name) {
92 for (size_t i = 0; i < elf->symtabsz; i++)
93 if (!strcmp((char*)(elf->strtab + elf->symtab[i].name), name))
94 return &(elf->symtab[i]);
95 return 0;
96}
97
98uint8_t* elf_relptr(Elf_t* elf, ElfSymbol_t* sym, uint32_t ptr) {
99 ElfSectionHeader_t* relsh = 0;
100 for (size_t i = 0; i < elf->header->shnum; i++) {
101 if (elf->section_headers[i].type == SHT_REL && elf->section_headers[i].info == sym->shndx) {
102 relsh = &(elf->section_headers[i]);
103 break;
104 }
105 }
106 if (!relsh)
107 return 0;
108 ElfRel_t* rel = 0;
109 for (size_t i = 0; i < (relsh->size / sizeof(ElfRel_t)); i++) {
110 ElfRel_t* tmp = (ElfRel_t*)&(elf->buffer[relsh->offset + i * sizeof(ElfRel_t)]);
111 if (tmp->offset == sym->value) {
112 rel = tmp;
113 break;
114 }
115 }
116 if (!rel)
117 return 0;
118 ElfSymbol_t* relsym = &(elf->symtab[R_SYM(rel->info)]);
119 if (ST_TYPE(relsym->info) != 3)
120 return 0;
121 return &elf->buffer[elf->section_headers[relsym->shndx].offset + ptr];
122}
Definition elf.h:81
Definition elf.h:86