/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.format;
import static jpcsp.util.Utilities.readUByte;
import static jpcsp.util.Utilities.readUHalf;
import static jpcsp.util.Utilities.readUWord;
import java.io.IOException;
import java.nio.ByteBuffer;
import jpcsp.MemoryMap;
import jpcsp.util.Utilities;
public class Elf32Header {
public static final int E_MACHINE_SPARC = 0x0002;
public static final int E_MACHINE_x86 = 0x0003;
public static final int E_MACHINE_MIPS = 0x0008;
public static final int E_MACHINE_PowerPC = 0x0014;
public static final int E_MACHINE_ARM = 0x0028;
public static final int E_MACHINE_SuperH = 0x002A;
public static final int E_MACHINE_IA_64 = 0x0032;
public static final int E_MACHINE_x86_64 = 0x003E;
public static final int E_MACHINE_AArch64 = 0x00B7;
private int e_magic;
private int e_class;
private int e_data;
private int e_idver;
private byte[] e_pad = new byte[9];
private int e_type;
private int e_machine;
private int e_version;
private int e_entry;
private int e_phoff;
private int e_shoff;
private int e_flags;
private int e_ehsize;
private int e_phentsize;
private int e_phnum;
private int e_shentsize;
private int e_shnum;
private int e_shstrndx;
private void read(ByteBuffer f) throws IOException {
if (f.capacity() == 0) {
return;
}
e_magic = readUWord(f);
e_class = readUByte(f);
e_data = readUByte(f);
e_idver = readUByte(f);
f.get(getE_pad()); // can raise EOF exception
e_type = readUHalf(f);
e_machine = readUHalf(f);
e_version = readUWord(f);
e_entry = readUWord(f);
e_phoff = readUWord(f);
e_shoff = readUWord(f);
e_flags = readUWord(f);
e_ehsize = readUHalf(f);
e_phentsize = readUHalf(f);
e_phnum = readUHalf(f);
e_shentsize = readUHalf(f);
e_shnum = readUHalf(f);
e_shstrndx = readUHalf(f);
}
public Elf32Header(ByteBuffer f) throws IOException {
read(f);
}
public boolean isValid(){
return getE_magic() == 0x464C457F;
}
public boolean isMIPSExecutable(){
return getE_machine() == E_MACHINE_MIPS;
}
public boolean isPRXDetected(){
return getE_type() == 0xFFA0;
}
public boolean requiresRelocation(){
return isPRXDetected() || getE_entry() < MemoryMap.START_RAM;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("-----ELF HEADER---------" + "\n");
str.append("e_magic " + "\t " + Utilities.formatString("long", Long.toHexString(getE_magic() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_class " + "\t " + Utilities.integerToHex(getE_class() & 0xFF) + "\n");
// str.append("e_class " + "\t " + Utilities.formatString("byte", Integer.toHexString(e_class & 0xFF ).toUpperCase())+ "\n");
str.append("e_data " + "\t\t " + Utilities.formatString("byte", Integer.toHexString(getE_data() & 0xFF).toUpperCase()) + "\n");
str.append("e_idver " + "\t " + Utilities.formatString("byte", Integer.toHexString(getE_idver() & 0xFF).toUpperCase()) + "\n");
str.append("e_type " + "\t\t " + Utilities.formatString("short", Integer.toHexString(getE_type() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_machine " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_machine() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_version " + "\t " + Utilities.formatString("long", Long.toHexString(getE_version() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_entry " + "\t " + Utilities.formatString("long", Long.toHexString(getE_entry() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_phoff " + "\t " + Utilities.formatString("long", Long.toHexString(getE_phoff() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_shoff " + "\t " + Utilities.formatString("long", Long.toHexString(getE_shoff() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_flags " + "\t " + Utilities.formatString("long", Long.toHexString(getE_flags() & 0xFFFFFFFFL).toUpperCase()) + "\n");
str.append("e_ehsize " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_ehsize() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_phentsize " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_phentsize() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_phnum " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_phnum() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_shentsize " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_shentsize() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_shnum " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_shnum() & 0xFFFF).toUpperCase()) + "\n");
str.append("e_shstrndx " + "\t " + Utilities.formatString("short", Integer.toHexString(getE_shstrndx() & 0xFFFF).toUpperCase()) + "\n");
return str.toString();
}
public int getE_magic() {
return e_magic;
}
public int getE_class() {
return e_class;
}
public int getE_data() {
return e_data;
}
public int getE_idver() {
return e_idver;
}
public byte[] getE_pad() {
return e_pad;
}
public int getE_type() {
return e_type;
}
public int getE_machine() {
return e_machine;
}
public int getE_version() {
return e_version;
}
public int getE_entry() {
return e_entry;
}
public int getE_phoff() {
return e_phoff;
}
public int getE_shoff() {
return e_shoff;
}
public int getE_flags() {
return e_flags;
}
public int getE_ehsize() {
return e_ehsize;
}
public int getE_phentsize() {
return e_phentsize;
}
public int getE_phnum() {
return e_phnum;
}
public int getE_shentsize() {
return e_shentsize;
}
public int getE_shnum() {
return e_shnum;
}
public int getE_shstrndx() {
return e_shstrndx;
}
}