1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/*
2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project
3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License.
6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at
7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software
11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and
14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License.
15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */
16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef ELF_HEADER_H
18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_HEADER_H
19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFTypes.h"
21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELF.h"
22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/ADT/OwningPtr.h>
24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <string.h>
26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFHeaderHelperMixin {
28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getClassStr(int clazz);
30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getEndiannessStr(int endianness);
31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getOSABIStr(int abi);
32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getObjectTypeStr(uint16_t type);
33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getMachineStr(uint16_t machine);
34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getVersionStr(uint32_t version);
35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFHeader : private ELFHeaderHelperMixin {
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t   e_ident[EI_NIDENT];
44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_type;
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_machine;
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t   e_version;
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t   e_entry;
48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  offset_t e_phoff;
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  offset_t e_shoff;
50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t   e_flags;
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_ehsize;
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_phentsize;
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_phnum;
54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_shentsize;
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_shnum;
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t   e_shstrndx;
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFHeader() { }
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getClass() const {
63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_CLASS];
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getEndianness() const {
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_DATA];
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getVersionFromIdent() const {
71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_VERSION];
72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getOSABI() const {
75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_OSABI];
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getABIVersion() const {
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_ABIVERSION];
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool is32bit() const {
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_CLASS] == ELFCLASS32;
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool is64bit() const {
87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_CLASS] == ELFCLASS64;
88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isBigEndian() const {
91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_DATA] == ELFDATA2MSB;
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isLittleEndian() const {
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ident[EI_DATA] == ELFDATA2LSB;
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getObjectType() const {
99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_type;
100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getMachine() const {
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_machine;
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t getVersion() const {
107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_version;
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t getEntryAddress() const {
111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_entry;
112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  offset_t getProgramHeaderTableOffset() const {
115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_phoff;
116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  offset_t getSectionHeaderTableOffset() const {
119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_shoff;
120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t getFlags() const {
123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_flags;
124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getELFHeaderSize() const {
127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_ehsize;
128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getProgramHeaderEntrySize() const {
131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_phentsize;
132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getProgramHeaderNum() const {
135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_phnum;
136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getSectionHeaderEntrySize() const {
139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_shentsize;
140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getSectionHeaderNum() const {
143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_shnum;
144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getStringSectionIndex() const {
147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return e_shstrndx;
148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static ELFHeader *read(Archiver &AR) {
152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    if (!AR) {
153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      // Archiver is in bad state before calling read function.
154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      // Return NULL and do nothing.
155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      return 0;
156b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    llvm::OwningPtr<ELFHeader> header(new ELFHeader());
159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    if (!header->serialize(AR)) {
160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      // Unable to read the structure.  Return NULL.
161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      return 0;
162b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
163b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
164b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    if (!header->isValid()) {
165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      // Header read from archiver is not valid.  Return NULL.
166b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      return 0;
167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
168b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
169b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return header.take();
170b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
171b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
172b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  void print();
173b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
174b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValid() const {
175b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (isValidELFIdent() && isCompatibleHeaderSize());
176b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
177b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
178b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
179b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
180b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool serialize(Archiver &AR) {
181b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.prologue(TypeTraits<ELFHeaderTy>::size);
182b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
183b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_ident;
184b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_type;
185b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_machine;
186b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_version;
187b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_entry;
188b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_phoff;
189b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_shoff;
190b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_flags;
191b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_ehsize;
192b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_phentsize;
193b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_phnum;
194b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_shentsize;
195b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_shnum;
196b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & e_shstrndx;
197b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
198b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.epilogue(TypeTraits<ELFHeaderTy>::size);
199b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return AR;
200b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
201b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
202b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValidMagicWord() const {
203b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (memcmp(e_ident, "\x7f" "ELF", 4) == 0);
204b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
205b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
206b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValidClass() const {
207b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ((Bitwidth == 32 && is32bit()) ||
208b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            (Bitwidth == 64 && is64bit()));
209b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
210b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
211b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValidEndianness() const {
212b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (isBigEndian() || isLittleEndian());
213b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
214b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
215b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValidHeaderVersion() const {
216b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (getVersion() == EV_CURRENT);
217b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
218b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
219b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isUnusedZeroedPadding() const {
220b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    for (size_t i = EI_PAD; i < EI_NIDENT; ++i) {
221b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      if (e_ident[i] != 0) {
222b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        return false;
223b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
224b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
225b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return true;
226b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
227b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
228b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValidELFIdent() const {
229b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (isValidMagicWord() &&
230b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            isValidClass() &&
231b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            isValidEndianness() &&
232b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            isValidHeaderVersion() &&
233b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            isUnusedZeroedPadding());
234b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
235b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
236b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isCompatibleHeaderSize() const {
237b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return (
238b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      (e_ehsize == TypeTraits<ELFHeaderTy>::size) &&
239b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      (e_phnum == 0 || e_phentsize == TypeTraits<ELFProgramHeaderTy>::size) &&
240b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      (e_shnum == 0 || e_shentsize == TypeTraits<ELFSectionHeaderTy>::size));
241b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
242b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
243b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
244b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "impl/ELFHeader.hxx"
245b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
246b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_HEADER_H
247