The Pedigree Project  0.1
Elf.h
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 #ifndef KERNEL_LINKER_ELF_H
21 #define KERNEL_LINKER_ELF_H
22 
23 #ifdef IN_PEDIGREE_KERNEL
24 #include "pedigree/kernel/compiler.h"
25 #include "pedigree/kernel/processor/types.h"
26 #include "pedigree/kernel/utilities/String.h"
27 #include "pedigree/kernel/utilities/new"
28 #endif
29 
30 #include "pedigree/kernel/linker/SymbolTable.h"
31 #include "pedigree/kernel/utilities/List.h"
32 
36 #ifdef VERBOSE_LINKER
37 #define DEBUG NOTICE
38 #else
39 #define DEBUG(...)
40 #endif
41 
42 // Object file types
43 #define ET_NONE 0x0
44 #define ET_REL 0x1
45 #define ET_EXEC 0x2
46 #define ET_DYN 0x3
47 #define ET_CORE 0x4
48 
49 // Section header types - common to Elf32 and Elf64.
50 #define SHT_PROGBITS 0x1 // The data is contained in the program file.
51 #define SHT_SYMTAB 0x2 // Symbol table
52 #define SHT_STRTAB 0x3 // String table
53 #define SHT_RELA 0x4
54 #define SHT_HASH 0x5 // Symbol hash table
55 #define SHT_DYNAMIC 0x6 // Dynamic linking information
56 #define SHT_NOTE 0x7
57 #define SHT_NOBITS 0x8 // The data is not contained in the program file.
58 #define SHT_REL 0x9
59 #define SHT_DYNSYM 0xb
60 #define SHT_INIT_ARRAY 0xe
61 #define SHT_FINI_ARRAY 0xf
62 #define SHT_PREINIT_ARRAY 0x10
63 
64 // Section header flags - common to Elf32 and Elf64.
65 #define SHF_WRITE 0x1
66 #define SHF_ALLOC 0x2
67 #define SHF_EXECINSTR 0x4
68 #define SHF_MASKPROC 0xf0000000
69 
70 // Program header flags - common to Elf32 and Elf64.
71 #define PF_X 0x1
72 #define PF_W 0x2
73 #define PF_R 0x4
74 
75 // Process header flags - common to Elf32 and Elf64.
76 #define PT_NULL 0 /* Program header table entry unused */
77 #define PT_LOAD 1 /* Loadable program segment */
78 #define PT_DYNAMIC 2 /* Dynamic linking information */
79 #define PT_INTERP 3 /* Program interpreter */
80 #define PT_NOTE 4 /* Auxiliary information */
81 #define PT_SHLIB 5 /* Reserved */
82 #define PT_PHDR 6 /* Entry for header table itself */
83 #define PT_TLS 7 /* Thread-local storage segment */
84 #define PT_NUM 8 /* Number of defined types */
85 
86 // Dynamic table flags - common to Elf32 and Elf64.
87 #define DT_NULL 0 /* Marks end of dynamic section */
88 #define DT_NEEDED 1 /* Name of needed library */
89 #define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
90 #define DT_PLTGOT 3 /* Processor defined value */
91 #define DT_HASH 4 /* Address of symbol hash table */
92 #define DT_STRTAB 5 /* Address of string table */
93 #define DT_SYMTAB 6 /* Address of symbol table */
94 #define DT_RELA 7 /* Address of Rela relocs */
95 #define DT_RELASZ 8 /* Total size of Rela relocs */
96 #define DT_RELAENT 9 /* Size of one Rela reloc */
97 #define DT_STRSZ 10 /* Size of string table */
98 #define DT_SYMENT 11 /* Size of one symbol table entry */
99 #define DT_INIT 12 /* Address of init function */
100 #define DT_FINI 13 /* Address of termination function */
101 #define DT_SONAME 14 /* Name of shared object */
102 #define DT_RPATH 15 /* Library search path (deprecated) */
103 #define DT_SYMBOLIC 16 /* Start symbol search here */
104 #define DT_REL 17 /* Address of Rel relocs */
105 #define DT_RELSZ 18 /* Total size of Rel relocs */
106 #define DT_RELENT 19 /* Size of one Rel reloc */
107 #define DT_PLTREL 20 /* Type of reloc in PLT */
108 #define DT_DEBUG 21 /* For debugging; unspecified */
109 #define DT_TEXTREL 22 /* Reloc might modify .text */
110 #define DT_JMPREL 23 /* Address of PLT relocs */
111 #define DT_BIND_NOW 24 /* Process relocations of object */
112 #define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
113 #define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
114 #define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
115 #define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
116 #define DT_RUNPATH 29 /* Library search path */
117 #define DT_FLAGS 30 /* Flags for the object being loaded */
118 #define DT_ENCODING 32 /* Start of encoded range */
119 #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
120 #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
121 
122 // Symbol types
123 #define STT_NOTYPE 0
124 #define STT_OBJECT 1
125 #define STT_FUNC 2
126 #define STT_SECTION 3
127 #define STT_FILE 4
128 #define STT_COMMON 5
129 #define STT_TLS 6
130 
131 // Symbol bindings
132 #define STB_LOCAL 0
133 #define STB_GLOBAL 1
134 #define STB_WEAK 2
135 
136 // Symbol visibilities
137 #define STV_DEFAULT 0
138 #define STV_INTERNAL 1
139 #define STV_HIDDEN 2
140 #define STV_PROTECTED 3
141 
142 #ifdef BITS_32
143 
144 #define R_SYM(val) ((val) >> 8)
145 #define R_TYPE(val) ((val) &0xff)
146 
147 #define ST_BIND(i) ((i) >> 4)
148 #define ST_TYPE(i) ((i) &0xf)
149 #define ST_INFO(b, t) (((b) << 4) + ((t) &0xf))
150 
151 typedef uint32_t Elf_Addr;
152 typedef uint32_t Elf_Off;
153 typedef uint16_t Elf_Half;
154 typedef uint32_t Elf_Word;
155 typedef int32_t Elf_Sword;
156 
157 // We define the Xword and Sxword types for ELF32 even though they don't exist
158 // in the spec for forwards compatibility with ELF64.
159 typedef uint32_t Elf_Xword;
160 typedef int32_t Elf_Sxword;
161 
162 #endif
163 #ifdef BITS_64
164 
165 #define R_SYM(val) ((val) >> 32)
166 #define R_TYPE(val) ((val) &0xffffffffUL)
167 
168 #define ST_BIND(i) ((i) >> 4)
169 #define ST_TYPE(i) ((i) &0xf)
170 #define ST_INFO(b, t) (((b) << 4) + ((t) &0xf))
171 
172 typedef uint64_t Elf_Addr;
173 typedef uint64_t Elf_Off;
174 typedef uint16_t Elf_Half;
175 typedef uint32_t Elf_Word;
176 typedef int32_t Elf_Sword;
177 typedef uint64_t Elf_Xword;
178 typedef int64_t Elf_Sxword;
179 
180 // Compatibility types for 64-bit kernel, which is actually a 32-bit ELF.
181 typedef uint32_t Elf32_Addr;
182 typedef uint32_t Elf32_Off;
183 typedef uint16_t Elf32_Half;
184 typedef uint32_t Elf32_Word;
185 typedef int32_t Elf32_Sword;
186 typedef uint32_t Elf32_Xword;
187 typedef int32_t Elf32_Sxword;
188 
189 #endif
190 
191 // Is the symbol type OK to add to the symbol table?
192 #define ST_TYPEOK(x) (ST_TYPE((x)) <= STT_FUNC)
193 
194 #ifndef _NO_ELF_CLASS
195 
202 {
203  // PosixSubsystem can use memory mapped files to do its own (very basic)
204  // ELF loading, which is an improvement on load()'s copies.
205  friend class PosixSubsystem;
206 
207  protected:
208  // Forward declaration of ELF symbol type for lookupSymbol template.
209  struct ElfSymbol_t;
210 
211  public:
213  Elf();
214 
216  virtual ~Elf();
217 
219  Elf(const Elf &);
220 
222  bool validate(uint8_t *pBuffer, size_t length);
223 
226  bool create(uint8_t *pBuffer, size_t length);
227 
230  bool createNeededOnly(uint8_t *pBuffer, size_t length);
231 
235  bool loadModule(
236  uint8_t *pBuffer, size_t length, uintptr_t &loadBase, size_t &loadSize,
237  SymbolTable *pSymbolTableCopy = 0);
238 
244  bool finaliseModule(uint8_t *pBuffer, uintptr_t length);
245 
250  bool allocate(
251  uint8_t *pBuffer, size_t length, uintptr_t &loadBase,
252  SymbolTable *pSymtab = 0, bool bAllocate = true, size_t *pSize = 0);
253 
261  bool load(
262  uint8_t *pBuffer, size_t length, uintptr_t loadBase,
263  SymbolTable *pSymtab = 0, uintptr_t nStart = 0, uintptr_t nEnd = ~0,
264  bool relocate = true);
265 
267  static bool
268  extractEntryPoint(uint8_t *pBuffer, size_t length, uintptr_t &entry);
269 
271  static bool extractInformation(
272  uint8_t *pBuffer, size_t length, size_t &phdrCount,
273  size_t &phdrEntrySize, uintptr_t &phdrAddress);
274 
276  List<char *> &neededLibraries();
277 
280  String &getInterpreter();
281 
284  uintptr_t getLastAddress();
285 
286  uintptr_t getInitFunc()
287  {
288  return m_InitFunc;
289  }
290  uintptr_t getFiniFunc()
291  {
292  return m_FiniFunc;
293  }
294 
300  template <class T = ElfSymbol_t>
301  const char *
302  lookupSymbol(uintptr_t addr, uintptr_t *startAddr, T *symbolTable);
303 
306  const char *lookupSymbol(uintptr_t addr, uintptr_t *startAddr);
307 
309  uintptr_t lookupSymbol(const char *pName);
310 
313  uintptr_t lookupDynamicSymbolAddress(const char *str, uintptr_t loadBase);
314 
317  uintptr_t applySpecificRelocation(
318  uintptr_t off, SymbolTable *pSymtab, uintptr_t loadBase,
320 
323  uintptr_t getGlobalOffsetTable();
324 
326  size_t getPltSize();
327 
333  void populateSymbolTable(SymbolTable *pSymtab, uintptr_t loadBase);
334 
336  void preallocateSymbols(
337  SymbolTable *pSymtabOverride = nullptr,
338  SymbolTable *pAdditionalSymtab = nullptr);
339 
340  SymbolTable *getSymbolTable()
341  {
342  return &m_SymbolTable;
343  }
344 
346  uintptr_t getEntryPoint();
347 
348  uintptr_t debugFrameTable();
349  uintptr_t debugFrameTableLength();
350 
352  void setName(const String &s)
353  {
354  m_Name = s;
355  }
356 
358  const String &getName() const
359  {
360  return m_Name;
361  }
362 
363  protected:
364 #endif
365  struct ElfHeader_t
366  {
367  uint8_t ident[16];
368  Elf_Half type;
369  Elf_Half machine;
370  Elf_Word version;
371  Elf_Addr entry;
372  Elf_Off phoff;
373  Elf_Off shoff;
374  Elf_Word flags;
375  Elf_Half ehsize;
376  Elf_Half phentsize;
377  Elf_Half phnum;
378  Elf_Half shentsize;
379  Elf_Half shnum;
380  Elf_Half shstrndx;
381  } PACKED;
382 
384  {
385  Elf_Word type;
386 #ifdef BITS_64
387  Elf_Word flags;
388 #endif
389  Elf_Off offset;
390  Elf_Addr vaddr;
391  Elf_Addr paddr;
392  Elf_Xword filesz;
393  Elf_Xword memsz;
394 #ifndef BITS_64
395  Elf_Word flags;
396 #endif
397  Elf_Xword align;
398  } PACKED;
399 
401  {
402  Elf_Word name;
403  Elf_Word type;
404  Elf_Xword flags;
405  Elf_Addr addr;
406  Elf_Off offset;
407  Elf_Xword size;
408  Elf_Word link;
409  Elf_Word info;
410  Elf_Xword addralign;
411  Elf_Xword entsize;
412  } PACKED;
413 
414 #ifdef BITS_64
416  {
417  Elf32_Word name;
418  Elf32_Word type;
419  Elf32_Xword flags;
420  Elf32_Addr addr;
421  Elf32_Off offset;
422  Elf32_Xword size;
423  Elf32_Word link;
424  Elf32_Word info;
425  Elf32_Xword addralign;
426  Elf32_Xword entsize;
427  } PACKED;
428 #else
430 #endif
431 
432  struct ElfSymbol_t
433  {
434  Elf_Word name;
435 #ifdef BITS_64
436  uint8_t info;
437  uint8_t other;
438  Elf_Half shndx;
439 #endif
440  Elf_Addr value;
441  Elf_Xword size;
442 #ifndef BITS_64
443  uint8_t info;
444  uint8_t other;
445  Elf_Half shndx;
446 #endif
447  } PACKED;
448 
449 #ifdef BITS_64
451  {
452  Elf32_Word name;
453  Elf32_Addr value;
454  Elf32_Xword size;
455  uint8_t info;
456  uint8_t other;
457  Elf32_Half shndx;
458  } PACKED;
459 #else
460 typedef ElfSymbol_t Elf32Symbol_t;
461 #endif
462 
463  struct ElfHash_t
464  {
465  Elf_Word nbucket;
466  Elf_Word nchain;
467  // buckets follow
468  // chains follow
469  };
470 
471  struct ElfDyn_t
472  {
473  Elf_Sxword tag;
474  union
475  {
476  Elf_Xword val;
477  Elf_Addr ptr;
478  } un;
479  } PACKED;
480 
481  struct ElfRel_t
482  {
483  Elf_Addr offset;
484  Elf_Xword info;
485  } PACKED;
486 
487  struct ElfRela_t
488  {
489  Elf_Addr offset;
490  Elf_Xword info;
491  Elf_Sxword addend;
492  } PACKED;
493 
494 #ifndef _NO_ELF_CLASS
495  private:
496  template <typename T>
497  static T *elfCopy(uint8_t *, ElfProgramHeader_t *, size_t, T *, size_t);
498 
499  bool relocate(uint8_t *pBuffer, uintptr_t length);
500  bool relocateModinfo(uint8_t *pBuffer, uintptr_t length);
501 
510  bool applyRelocation(
511  ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab = 0,
512  uintptr_t loadBase = 0,
514 
523  bool applyRelocation(
524  ElfRela_t rela, ElfSectionHeader_t *pSh, SymbolTable *pSymtab = 0,
525  uintptr_t loadBase = 0,
527 
529  void rebaseDynamic();
530 
531  protected:
532  ElfSymbol_t *m_pSymbolTable;
533  size_t m_nSymbolTableSize;
534  char *m_pStringTable;
535  size_t m_nStringTableSize;
536  char *m_pShstrtab;
537  size_t m_nShstrtabSize;
538  uintptr_t *m_pGotTable; // Global offset table.
539  ElfRel_t *m_pRelTable; // Dynamic REL relocations.
540  ElfRela_t *m_pRelaTable; // Dynamic RELA relocations.
541  size_t m_nRelTableSize;
542  size_t m_nRelaTableSize;
543  ElfRel_t *m_pPltRelTable;
544  ElfRela_t *m_pPltRelaTable;
545  bool m_bUsesRela; // If PltRelaTable is valid, else PltRelTable is.
546  uint32_t *m_pDebugTable;
547  size_t m_nDebugTableSize;
548  ElfSymbol_t *m_pDynamicSymbolTable;
549  size_t m_nDynamicSymbolTableSize;
550  char *m_pDynamicStringTable;
551  size_t m_nDynamicStringTableSize;
552  ElfSectionHeader_t *m_pSectionHeaders;
553  size_t m_nSectionHeaders;
554  ElfProgramHeader_t *m_pProgramHeaders;
555  size_t m_nProgramHeaders;
556  size_t m_nPltSize;
557  uintptr_t m_nEntry;
558  List<char *> m_NeededLibraries;
559  SymbolTable m_SymbolTable;
560  uintptr_t m_InitFunc;
561  uintptr_t m_FiniFunc;
562  String m_sInterpreter;
563 
564  String m_Name;
565  uintptr_t m_LoadBase;
566 
567  private:
570  Elf &operator=(const Elf &);
571 };
572 
574 extern template const char *Elf::lookupSymbol<Elf::ElfSymbol_t>(
575  uintptr_t addr, uintptr_t *startAddr = 0, ElfSymbol_t *symbolTable = 0);
576 #ifdef BITS_64
577 extern template const char *Elf::lookupSymbol<Elf::Elf32Symbol_t>(
578  uintptr_t addr, uintptr_t *startAddr = 0, Elf32Symbol_t *symbolTable = 0);
579 #endif
580 
581 #endif
582 
585 #endif
Definition: String.h:49
Definition: Elf.h:201
const String & getName() const
Definition: Elf.h:358
void setName(const String &s)
Definition: Elf.h:352