diff options
Diffstat (limited to 'src/java/jogamp/common/os/elf/SectionHeader.java')
-rw-r--r-- | src/java/jogamp/common/os/elf/SectionHeader.java | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/java/jogamp/common/os/elf/SectionHeader.java b/src/java/jogamp/common/os/elf/SectionHeader.java new file mode 100644 index 0000000..18a3293 --- /dev/null +++ b/src/java/jogamp/common/os/elf/SectionHeader.java @@ -0,0 +1,274 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.os.elf; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import static jogamp.common.os.elf.IOUtils.long2Int; +import static jogamp.common.os.elf.IOUtils.readBytes; +import static jogamp.common.os.elf.IOUtils.seek; +import static jogamp.common.os.elf.IOUtils.getString; +import static jogamp.common.os.elf.IOUtils.toHexString; + +/** + * ELF ABI Section Header + * <p> + * References: + * <ul> + * <li>http://linux.die.net/man/5/elf</li> + * <li>http://www.sco.com/developers/gabi/latest/contents.html</li> + * <li>http://infocenter.arm.com/ + * <ul> + * <li>ARM IHI 0044E, current through ABI release 2.09</li> + * </ul></li> + * </ul> + * </p> + */ +public class SectionHeader { + /** + * {@value} + */ + public static final int SHT_NULL = 0; + /** + * {@value} + */ + public static final int SHT_PROGBITS = 1; + /** + * {@value} + */ + public static final int SHT_SYMTAB = 2; + /** + * {@value} + */ + public static final int SHT_STRTAB = 3; + /** + * {@value} + */ + public static final int SHT_RELA = 4; + /** + * {@value} + */ + public static final int SHT_HASH = 5; + /** + * {@value} + */ + public static final int SHT_DYNAMIC = 6; + /** + * {@value} + */ + public static final int SHT_NOTE = 7; + /** + * {@value} + */ + public static final int SHT_NOBITS = 8; + /** + * {@value} + */ + public static final int SHT_REL = 9; + /** + * {@value} + */ + public static final int SHT_SHLIB = 10; + /** + * {@value} + */ + public static final int SHT_DYNSYM = 11; + /** + * {@value} + */ + public static final int SHT_NUM = 12; + /** + * {@value} + */ + public static final int SHT_LOPROC = 0x70000000; + /** + * {@value} + */ + public static final int SHT_HIPROC = 0x7fffffff; + /** + * {@value} + */ + public static final int SHT_LOUSER = 0x80000000; + /** + * {@value} + */ + public static final int SHT_HIUSER = 0xffffffff; + + /** + * {@value} + */ + public static final int SHT_ARM_EXIDX = 0x70000001; + /** + * {@value} + */ + public static final int SHT_ARM_PREEMPTMAP = 0x70000002; + /** + * {@value} + */ + public static final int SHT_ARM_ATTRIBUTES = 0x70000003; + /** + * {@value} + */ + public static final int SHT_ARM_DEBUGOVERLAY = 0x70000004; + /** + * {@value} + */ + public static final int SHT_ARM_OVERLAYSECTION = 0x70000005; + + /** + * {@value} + */ + public static final short SHN_UNDEF = (short)0; + /** + * {@value} + */ + public static final short SHN_LORESERVE = (short)0xff00; + /** + * {@value} + */ + public static final short SHN_LOPROC = (short)0xff00; + /** + * {@value} + */ + public static final short SHN_HIPROC = (short)0xff1f; + /** + * {@value} + */ + public static final short SHN_ABS = (short)0xfff1; + /** + * {@value} + */ + public static final short SHN_COMMON = (short)0xfff2; + /** + * {@value} + */ + public static final short SHN_HIRESERVE = (short)0xffff; + + /** Public access to the raw elf section header */ + public final Shdr d; + + private int idx; + private String name; + + SectionHeader(byte[] buf, int offset, int length, int sectionIdx) { + this( ByteBuffer.wrap(buf, 0, buf.length), sectionIdx ); + } + SectionHeader(java.nio.ByteBuffer buf, int idx) { + d = Shdr.create(buf); + this.idx = idx; + name = null; + } + + public String toString() { + return "SectionHeader[idx "+idx+", name "+name+", type "+toHexString(getType())+", link "+d.getSh_link()+", info "+toHexString(d.getSh_info())+", flags "+toHexString(getFlags())+"]"; + } + + /** + * @param strS the {@link SectionHeader#SHT_STRTAB} section containing all strings + * @param nameOffset name offset within strS + */ + void initName(final Section strS, final int nameOffset) throws IndexOutOfBoundsException { + name = getString(strS.data, strS.offset + nameOffset, strS.length - nameOffset, null); + } + + /** Returns the index of this section within the Elf section header table. */ + public int getIndex() { + return idx; + } + + /** Returns the type of this section. */ + public int getType() { + return d.getSh_type(); + } + + /** Returns the flags of this section. */ + public long getFlags() { + return d.getSh_flags(); + } + + /** Returns the size of this section. */ + public long getSize() { + return d.getSh_size(); + } + + /** Returns this section name, maybe <code>null</code> if not read. */ + public String getName() { + return name; + } + + /** + * Returns the Section referenced w/ this section header + * + * @param in file owning the section + * @throws IOException if read error occurs + * @throws IllegalArgumentException if section offset or size mismatch including size > {@link Integer#MAX_VALUE} + */ + public Section readSection(RandomAccessFile in) throws IOException, IllegalArgumentException { + final int s_size = long2Int(d.getSh_size()); + if( 0 == s_size || 0 > s_size ) { + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + } + final byte[] s_buf = new byte[s_size]; + return readSectionImpl(in, s_buf, 0, s_size); + } + + /** + * Returns the Section referenced w/ this section header using given byte array. + * + * @param in file owning the section + * @param b destination buffer + * @param b_off offset in destination buffer + * @param r_len requested read length in bytes, which shall be ≤ than this section size + * @throws IOException if read error occurs + * @throws IllegalArgumentException if section offset or size mismatch including size > {@link Integer#MAX_VALUE} + * @throws IllegalArgumentException if requested read length is > section size + */ + public Section readSection(RandomAccessFile in, byte[] b, int b_off, int r_len) throws IOException, IllegalArgumentException { + final int s_size = long2Int(d.getSh_size()); + if( 0 == s_size || 0 > s_size ) { + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + } + if( r_len > s_size ) { + throw new IllegalArgumentException("Shdr["+idx+"] has only "+s_size+" bytes, while read request is of "+r_len+" bytes"); + } + return readSectionImpl(in, b, b_off, r_len); + } + + Section readSectionImpl(RandomAccessFile in, byte[] b, int b_off, int r_len) throws IOException, IllegalArgumentException { + final long s_off = d.getSh_offset(); + seek(in, s_off); + readBytes(in, b, b_off, r_len); + if( SectionHeader.SHT_ARM_ATTRIBUTES == getType() ) { + return new SectionArmAttributes(this, b, b_off, r_len); + } else { + return new Section(this, b, b_off, r_len); + } + } +} |