1e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao/* 2e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Copyright 2011, The Android Open Source Project 3e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * 4e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License"); 5e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * you may not use this file except in compliance with the License. 6e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * You may obtain a copy of the License at 7e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * 8e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * http://www.apache.org/licenses/LICENSE-2.0 9e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * 10e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Unless required by applicable law or agreed to in writing, software 11e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS, 12e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * See the License for the specific language governing permissions and 14e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * limitations under the License. 15e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao */ 16e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao 17fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien#ifndef ELF_HEADER_H 18fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien#define ELF_HEADER_H 19fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 20fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien#include "ELFTypes.h" 21404833ada8caa7027105bd52bd36ab7822030369TDYa#include "ELF.h" 22fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 231f100419d794fa433336190aa47bb0862f93f978TDYa#include <llvm/ADT/OwningPtr.h> 2424d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien 2524d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien#include <string.h> 2624d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien 2724d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chienclass ELFHeaderHelperMixin { 2824d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chienprotected: 2924d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getClassStr(int clazz); 3024d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getEndiannessStr(int endianness); 3124d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getOSABIStr(int abi); 3224d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getObjectTypeStr(uint16_t type); 3324d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getMachineStr(uint16_t machine); 3424d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien static char const *getVersionStr(uint32_t version); 3524d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien}; 36fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 37a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth> 38ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chienclass ELFHeader : private ELFHeaderHelperMixin { 39fce76eee4ad1f6349563423e55271d612525c5e9Logan Chienpublic: 40fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); 41fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 42fce76eee4ad1f6349563423e55271d612525c5e9Logan Chienprotected: 43fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t e_ident[EI_NIDENT]; 44fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_type; 45fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_machine; 46fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien word_t e_version; 47fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien addr_t e_entry; 48fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien offset_t e_phoff; 49fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien offset_t e_shoff; 50fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien word_t e_flags; 51fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_ehsize; 52fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_phentsize; 53fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_phnum; 54fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_shentsize; 55fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_shnum; 56fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t e_shstrndx; 57fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 58fce76eee4ad1f6349563423e55271d612525c5e9Logan Chienprotected: 59ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien ELFHeader() { } 60fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 61fce76eee4ad1f6349563423e55271d612525c5e9Logan Chienpublic: 62fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t getClass() const { 63fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_CLASS]; 64fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 65fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 66fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t getEndianness() const { 67fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_DATA]; 68fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 69fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 70fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t getVersionFromIdent() const { 71fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_VERSION]; 72fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 73fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 74fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t getOSABI() const { 75fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_OSABI]; 76fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 77fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 78fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien byte_t getABIVersion() const { 79fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_ABIVERSION]; 80fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 81fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 82fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien bool is32bit() const { 83fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_CLASS] == ELFCLASS32; 84fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 85fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 86fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien bool is64bit() const { 87fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_CLASS] == ELFCLASS64; 88fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 89fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 90fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien bool isBigEndian() const { 91fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_DATA] == ELFDATA2MSB; 92fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 93fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 94fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien bool isLittleEndian() const { 95fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ident[EI_DATA] == ELFDATA2LSB; 96fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 97fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 98fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getObjectType() const { 99fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_type; 100fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 101fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 102fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getMachine() const { 103fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_machine; 104fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 105fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 106fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien word_t getVersion() const { 107fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_version; 108fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 109fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 110fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien addr_t getEntryAddress() const { 111fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_entry; 112fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 113fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 114fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien offset_t getProgramHeaderTableOffset() const { 115fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_phoff; 116fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 117fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 118fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien offset_t getSectionHeaderTableOffset() const { 119fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_shoff; 120fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 121fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 122fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien word_t getFlags() const { 123fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_flags; 124fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 125fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 126fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getELFHeaderSize() const { 127fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_ehsize; 128fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 129fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 130fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getProgramHeaderEntrySize() const { 131fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_phentsize; 132fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 133fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 134fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getProgramHeaderNum() const { 135fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_phnum; 136fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 137fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 138fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getSectionHeaderEntrySize() const { 139fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_shentsize; 140fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 141fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 142fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getSectionHeaderNum() const { 143fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_shnum; 144fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 145fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 146fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien half_t getStringSectionIndex() const { 147fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien return e_shstrndx; 148fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 149fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 150fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien template <typename Archiver> 151ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien static ELFHeader *read(Archiver &AR) { 152fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien if (!AR) { 153fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien // Archiver is in bad state before calling read function. 154fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien // Return NULL and do nothing. 1551f100419d794fa433336190aa47bb0862f93f978TDYa return 0; 156fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 157fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 158ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien llvm::OwningPtr<ELFHeader> header(new ELFHeader()); 159fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien if (!header->serialize(AR)) { 160fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien // Unable to read the structure. Return NULL. 1611f100419d794fa433336190aa47bb0862f93f978TDYa return 0; 162fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 163fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 164fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien if (!header->isValid()) { 165fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien // Header read from archiver is not valid. Return NULL. 1661f100419d794fa433336190aa47bb0862f93f978TDYa return 0; 167fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 168fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 1691f100419d794fa433336190aa47bb0862f93f978TDYa return header.take(); 170fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien } 17124d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien 17224573a0b89be8332225b40cced0d91e52ea87051Logan Chien void print(); 17324d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien 17424d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien bool isValid() const { 1757a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return (isValidELFIdent() && isCompatibleHeaderSize()); 1767a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 1777a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 1787a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chienprivate: 179ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien template <typename Archiver> 180ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien bool serialize(Archiver &AR) { 18158611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien AR.prologue(TypeTraits<ELFHeaderTy>::size); 182ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien 183ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_ident; 184ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_type; 185ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_machine; 186ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_version; 187ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_entry; 188ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_phoff; 189ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_shoff; 190ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_flags; 191ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_ehsize; 192ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_phentsize; 193ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_phnum; 194ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_shentsize; 195ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_shnum; 196ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien AR & e_shstrndx; 197ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien 19858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien AR.epilogue(TypeTraits<ELFHeaderTy>::size); 199ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien return AR; 200ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien } 201ffe9c44fd21e8076f9c51b38035e5f40168083ceLogan Chien 2027a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isValidMagicWord() const { 2037a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return (memcmp(e_ident, "\x7f" "ELF", 4) == 0); 2047a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2057a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2067a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isValidClass() const { 207567fa8fdb8df8f99a3363a6d64aa16ce487214c8Logan Chien return ((Bitwidth == 32 && is32bit()) || 208567fa8fdb8df8f99a3363a6d64aa16ce487214c8Logan Chien (Bitwidth == 64 && is64bit())); 2097a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2107a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2117a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isValidEndianness() const { 2127a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return (isBigEndian() || isLittleEndian()); 2137a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2147a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2157a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isValidHeaderVersion() const { 2167a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return (getVersion() == EV_CURRENT); 2177a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2187a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2197a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isUnusedZeroedPadding() const { 2207a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien for (size_t i = EI_PAD; i < EI_NIDENT; ++i) { 2217a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien if (e_ident[i] != 0) { 2227a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return false; 2237a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2247a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 22524d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien return true; 22624d999f39adf2a2b6b7c1749179f115df9ff9a77Logan Chien } 2277a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2287a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isValidELFIdent() const { 2297a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien return (isValidMagicWord() && 2307a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien isValidClass() && 2317a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien isValidEndianness() && 2327a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien isValidHeaderVersion() && 2337a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien isUnusedZeroedPadding()); 2347a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 2357a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien 2367a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien bool isCompatibleHeaderSize() const { 2379846416aa118f262356da2e3a391d8334d893e3cLogan Chien return ( 2389846416aa118f262356da2e3a391d8334d893e3cLogan Chien (e_ehsize == TypeTraits<ELFHeaderTy>::size) && 2399846416aa118f262356da2e3a391d8334d893e3cLogan Chien (e_phnum == 0 || e_phentsize == TypeTraits<ELFProgramHeaderTy>::size) && 2409846416aa118f262356da2e3a391d8334d893e3cLogan Chien (e_shnum == 0 || e_shentsize == TypeTraits<ELFSectionHeaderTy>::size)); 2417a2a7ef6138b47665a958cb0e33e7eb0b487c639Logan Chien } 242fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien}; 243fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien 244089c5b3d98c8e4416a36cff12199c9ea659d8976Logan Chien#include "impl/ELFHeader.hxx" 24524573a0b89be8332225b40cced0d91e52ea87051Logan Chien 246fce76eee4ad1f6349563423e55271d612525c5e9Logan Chien#endif // ELF_HEADER_H 247