001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2005, 2008, Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package lib.dwfl;
041    
042    import inua.eio.ByteOrder;
043    
044    /**
045     * An ElfEHeader is a header for and Elf file. This appears at the
046     * start of every Elf file.
047     */
048    public final class ElfEHeader {
049    
050        public ElfEHeader(){
051        }
052    
053            // Version
054            //public static final int PHEADER_EV_VERSION = parent.getElfVersion();
055    
056        // ident[CLASS} contains the word-size
057        public static final int CLASSNONE = 0;
058        public static final int CLASS32 = 1;
059        public static final int CLASS64 = 2;
060        public final static int CLASS = 4;
061    
062        // Data class
063        public static final int DATANONE = 0;
064        public static final int DATA2LSB = 1;
065        public static final int DATA2MSB = 2;
066        public static final int DATA = 5;
067        
068            // Type
069            public static final int PHEADER_ET_NONE = 0;
070            public static final int PHEADER_ET_REL = 1;
071            public static final int PHEADER_ET_EXEC = 2;
072            public static final int PHEADER_ET_DYN = 3;
073            public static final int PHEADER_ET_CORE = 4;
074            public static final int PHEADER_ET_NUM = 5;
075            public static final int PHEADER_ET_LOOS = 0xfe00;
076            public static final int PHEADER_ET_HIOS = 0xfeff;
077            public static final int PHEADER_ET_LOPROC =  0xff00;
078            public static final int PHEADER_ET_HIPROC = 0xffff;
079    
080        public static final int NIDENT = 16;
081        public byte[] ident = new byte[NIDENT];
082    
083            public int type;
084            public int machine;
085            public long version;
086            public long entry;
087            public long phoff;
088            public long shoff;
089            public int flags;
090            public int ehsize;
091            public int phentsize;
092            public int phnum;
093            public int shentsize;
094            public int shnum;
095            public int shstrndx;
096            
097        /**
098         * Interpret the IDENT field; extracting the word-size.
099         */
100        public int getWordSize() {
101            switch (ident[CLASS]) {
102            case CLASSNONE:
103                return 0;
104            case CLASS32:
105                return 4;
106            case CLASS64:
107                return 8;
108            default:
109                // This is a programmer error; not a an Elf file or format error.
110                throw new RuntimeException("Unknown ELF class " + ident[CLASS]);
111            }
112        }
113    
114        /**
115         * Encode SIZE into the IDENT field.
116         */
117        public ElfEHeader setWordSize(int size) {
118            switch (size) {
119            case 0:
120                ident[CLASS] = CLASSNONE;
121                return this;
122            case 4:
123                ident[CLASS] = CLASS32;
124                return this;
125            case 8:
126                ident[CLASS] = CLASS64;
127                return this;
128            default:
129                // This is a programmer error; not an Elf file format error.
130                throw new RuntimeException("No class for word-size " + size);
131            }
132        }
133            
134        /**
135         * Interpret the IDENT field; extracting the byte order.
136         */
137        public ByteOrder getByteOrder() {
138            switch (ident[DATA]) {
139            case DATANONE:
140                return null;
141            case DATA2LSB:
142                return ByteOrder.LITTLE_ENDIAN;
143            case DATA2MSB:
144                return ByteOrder.BIG_ENDIAN;
145            default:
146                // This is a programmer error; not a an Elf file or format error.
147                throw new RuntimeException("Unknown ELF class " + ident[DATA]);
148            }
149        }
150    
151        /**
152         * Encode SIZE into the IDENT field.
153         */
154        public ElfEHeader setByteOrder(ByteOrder order) {
155            if (order == null)
156                ident[DATA] = DATANONE;
157            else if (order == ByteOrder.LITTLE_ENDIAN)
158                ident[DATA] = DATA2LSB;
159            else if (order == ByteOrder.BIG_ENDIAN)
160                ident[DATA] = DATA2MSB;
161            else
162                // This is a programmer error; not an Elf file format error.
163                throw new RuntimeException("No data for byte-order " + order);
164            return this;
165        }
166    }