From: <mic...@us...> - 2007-04-23 14:02:09
|
Revision: 84 http://svn.sourceforge.net/pearcolator/?rev=84&view=rev Author: michael_baer Date: 2007-04-23 07:02:09 -0700 (Mon, 23 Apr 2007) Log Message: ----------- Just to show something to Ian... Added Paths: ----------- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java Added: src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java (rev 0) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java 2007-04-23 14:02:09 UTC (rev 84) @@ -0,0 +1,92 @@ +package org.binarytranslator.generic.os.abi.linux; + +import org.binarytranslator.generic.memory.Memory; + +/** Namespace for all structures. */ +public class LinuxStructureFactory { + + /** Solution 1 - automatically generated class. Fast, but pretty unflexible.*/ + public class stat64_2 { + + private Memory mem; + private int addr; + + void st_dev(int value) { + mem.store32(addr + 3, value); + } + + int st_dev() { + return mem.load32(addr + 3); + } + } + + /** Solution 2 - class members created from factory method. More flexible, but higher overhead. */ + public static class stat64 extends Structure { + public final _Int st_dev = newInt(); + public final _Short st_mode = newShort(); + } + + + + + protected static class Structure { + + protected Memory memory; + private int curOffset = 0; + + public abstract class StructureElement<T> { + + protected int address; + public abstract T get(); + public abstract void set(T value); + } + + protected _Int newInt() { + _Int i = new _Int(curOffset); + curOffset += 4; + + return i; + } + + protected _Short newShort() { + _Short s = new _Short(curOffset); + curOffset += 2; + + return s; + } + + public class _Int extends StructureElement<Integer> { + + private _Int(int offset) { + this.address = offset; + } + + @Override + public Integer get() { + return memory.load32(address); + } + + @Override + public void set(Integer value) { + memory.store32(address, value); + } + } + + public class _Short extends StructureElement<Short> { + + private _Short(int offset) { + this.address = offset; + } + + @Override + public Short get() { + return (short) memory.loadUnsigned16(address); + } + + @Override + public void set(Short value) { + memory.store16(address, value); + } + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mic...@us...> - 2007-04-23 14:09:55
|
Revision: 85 http://svn.sourceforge.net/pearcolator/?rev=85&view=rev Author: michael_baer Date: 2007-04-23 07:09:57 -0700 (Mon, 23 Apr 2007) Log Message: ----------- For Ian, 2nd part Modified Paths: -------------- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java 2007-04-23 14:02:09 UTC (rev 84) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java 2007-04-23 14:09:57 UTC (rev 85) @@ -5,9 +5,18 @@ /** Namespace for all structures. */ public class LinuxStructureFactory { - /** Solution 1 - automatically generated class. Fast, but pretty unflexible.*/ - public class stat64_2 { + public static class stat64_3 { + public int st_dev; + public short st_mode; + /** Implemented with a reflection by a base class*/ + public void store(Memory m) {} + public void read(Memory m) {} + } + + /** Solution 2 - automatically generated class. Fast, but pretty unflexible.*/ + public static class stat64_2 { + private Memory mem; private int addr; @@ -20,7 +29,7 @@ } } - /** Solution 2 - class members created from factory method. More flexible, but higher overhead. */ + /** Solution 3 - class members created from factory method. More flexible, but higher overhead. */ public static class stat64 extends Structure { public final _Int st_dev = newInt(); public final _Short st_mode = newShort(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mic...@us...> - 2007-04-23 16:37:25
|
Revision: 86 http://svn.sourceforge.net/pearcolator/?rev=86&view=rev Author: michael_baer Date: 2007-04-23 09:37:12 -0700 (Mon, 23 Apr 2007) Log Message: ----------- New example of handling structures in java. Modified Paths: -------------- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java 2007-04-23 14:09:57 UTC (rev 85) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxStructureFactory.java 2007-04-23 16:37:12 UTC (rev 86) @@ -1,101 +1,354 @@ package org.binarytranslator.generic.os.abi.linux; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + import org.binarytranslator.generic.memory.Memory; /** Namespace for all structures. */ public class LinuxStructureFactory { - public static class stat64_3 { - public int st_dev; - public short st_mode; + public final stat64 new_stat64() { + return new stat64(); + } + + public class stat64 extends Structure { + @_unsigned short st_dev; + @_unsigned @_padding(10) byte __pad0; + @_unsigned @_long long __st_ino; + @_unsigned int st_mode; + @_unsigned int st_nlink; + @_unsigned long st_uid; + @_unsigned long st_gid; + @_unsigned short st_rdev; + @_unsigned @_padding(10) byte __pad3; + @_long long st_size; + @_unsigned long st_blksize; + @_unsigned long st_blocks; + @_unsigned @_padding(1) long __pad4; + @_unsigned long st_atime; + @_unsigned @_padding(1) long __pad5; + @_unsigned long st_mtime; + @_unsigned @_padding(1) long __pad6; + @_unsigned long st_ctime; + @_unsigned @_padding(1) long __pad7; + @_unsigned @_long long st_ino; - /** Implemented with a reflection by a base class*/ - public void store(Memory m) {} - public void read(Memory m) {} + public stat64() { + super(new String[]{ "st_dev", "__pad0", "__st_ino", "st_mode", "st_nlink", "st_uid", + "st_gid", "st_rdev", "__pad3", "st_size", "st_blksize", "st_blocks", "__pad4", "st_atime", + "__pad5", "st_mtime", "__pad6", "st_ctime", "__pad7", "st_ino"}); + } } - /** Solution 2 - automatically generated class. Fast, but pretty unflexible.*/ - public static class stat64_2 { + private @interface _long {} + private @interface _unsigned {} + private @interface _padding { int value(); } + + private class Structure { - private Memory mem; - private int addr; + /** A list of all structure members in the order that they appear in the source code. */ + protected Field[] members; - void st_dev(int value) { - mem.store32(addr + 3, value); + protected Structure(String[] memberNames) { + + Class myType = getClass(); + members = new Field[memberNames.length]; + + for (int i = 0; i < memberNames.length; i++) { + try { + Field field = myType.getField(memberNames[i]); + members[i] = field; + } + catch (NoSuchFieldException e) { + throw new RuntimeException("Invalid field: " + memberNames[i] + " in struct: " + myType.getSimpleName(), e); + } + } } - int st_dev() { - return mem.load32(addr + 3); + public void read(Memory mem, int addr) { + + // get a structure writer, which will keep track of the object offsets + StructureAdapter reader = createStructureAdapter(mem, addr); + + // traverse all public fields + for (Field f : members) { + if (!Modifier.isPrivate(f.getModifiers())) { + try { + // store each public field one after the other + Class<?> type = f.getClass(); + + if (type == int.class) { + f.setInt(this, reader.loadInt()); + continue; + } + + if (type == long.class) { + + if (f.getAnnotation(_long.class) != null) + f.setLong(this, reader.loadLongLong()); + else + f.setLong(this, reader.loadLong()); + continue; + } + + if (type == short.class) { + f.setShort(this, reader.loadShort()); + continue; + } + + if (type == byte.class) { + f.setByte(this, reader.loadByte()); + continue; + } + + throw new RuntimeException( + "Unknown data type while persisting struct: " + this); + } catch (IllegalAccessException e) { + throw new RuntimeException( + "Unknown data type while persisting struct: " + this, e); + } + } + } } + + public void write(Memory mem, int addr) { + + // get a structure writer, which will keep track of the object offsets + StructureAdapter writer = createStructureAdapter(mem, addr); + + // traverse all public fields + for (Field f : members) { + if (!Modifier.isPrivate(f.getModifiers())) { + try { + // store each public field one after the other + Class<?> type = f.getClass(); + + // check if that data type represents a certain amount of padding + _padding padding = f.getAnnotation(_padding.class); + if (padding != null) { + writer.skipPadding(f, padding.value()); + continue; + } + + if (type == int.class) { + writer.storeInt(f.getInt(this)); + continue; + } + + if (type == long.class) { + if (f.getAnnotation(_long.class) != null) + writer.storeLongLong(f.getLong(this)); + else + writer.storeLong(f.getLong(this)); + + continue; + } + + if (type == short.class) { + writer.storeShort(f.getShort(this)); + continue; + } + + if (type == byte.class) { + writer.storeByte(f.getByte(this)); + continue; + } + + throw new RuntimeException( + "Unknown data type while persisting struct: " + this); + } catch (IllegalAccessException e) { + throw new RuntimeException( + "Unknown data type while persisting struct: " + this, e); + } + } + } + } + + @Override + public String toString() { + + StringBuilder struct = new StringBuilder(); + struct.append("struct "); + struct.append(getClass().getSimpleName()); + struct.append(" {\n"); + + // traverse all struct members + for (Field f : members) { + if (!Modifier.isPrivate(f.getModifiers())) { + try { + struct.append(f.getName()); + struct.append(" = "); + struct.append(f.get(this).toString()); + } + catch (IllegalAccessException e) {} + + struct.append('\n'); + } + } + + struct.append('}'); + + return struct.toString(); + } } - /** Solution 3 - class members created from factory method. More flexible, but higher overhead. */ - public static class stat64 extends Structure { - public final _Int st_dev = newInt(); - public final _Short st_mode = newShort(); + protected final StructureAdapter createStructureAdapter(Memory mem, int addr) { + return new DefaultStructureAdapter(mem, addr); } + protected static abstract class StructureAdapter { + + public abstract byte loadByte(); + public abstract short loadShort(); + public abstract int loadInt(); + public abstract long loadLong(); + public abstract long loadLongLong(); + + public abstract void storeByte(byte value); + public abstract void storeShort(short value); + public abstract void storeInt(int value); + public abstract void storeLong(long value); + public abstract void storeLongLong(long value); + + public abstract void skipPadding(Field field, int count); + } - - - protected static class Structure { + protected static class DefaultStructureAdapter extends StructureAdapter { - protected Memory memory; - private int curOffset = 0; + private final Memory mem; + private int addr; - public abstract class StructureElement<T> { - - protected int address; - public abstract T get(); - public abstract void set(T value); + public DefaultStructureAdapter(Memory mem, int addr) { + this.mem = mem; + this.addr = addr; } - protected _Int newInt() { - _Int i = new _Int(curOffset); - curOffset += 4; - - return i; + private final void shortAlignAddress() { + if ((addr & 0xFFFFFFFE) != addr) + addr = (addr & 0xFFFFFFFE) + 2; } - protected _Short newShort() { - _Short s = new _Short(curOffset); - curOffset += 2; + private final void intAlignAddress() { + if ((addr & 0xFFFFFFFC) != addr) + addr = (addr & 0xFFFFFFFC) + 4; + } + + private final void longAlignAddress() { + if ((addr & 0xFFFFFFFC) != addr) + addr = (addr & 0xFFFFFFFC) + 8; + } + + @Override + public void storeByte(byte value) { + mem.store8(addr, value); + addr++; + } + + @Override + public void storeInt(int value) { + //make sure that address is int aligned + intAlignAddress(); + mem.store32(addr, value); + addr += 4; + } + + @Override + public void storeLong(long value) { + //in a lot of C dialects, longs are treated as ints + storeInt((int)value); + } + + @Override + public void storeLongLong(long value) { + longAlignAddress(); - return s; + mem.store32(addr, (int)(value & 0xFFFFFFFF)); + mem.store32(addr, (int)(value >> 32)); + addr += 8; } - public class _Int extends StructureElement<Integer> { + @Override + public void storeShort(short value) { + shortAlignAddress(); + mem.store16(addr, value); + addr += 2; + } + + @Override + public byte loadByte() { + return (byte)mem.loadUnsigned8(addr++); + } + + @Override + public int loadInt() { + intAlignAddress(); + int value = mem.load32(addr); + addr += 4; - private _Int(int offset) { - this.address = offset; - } + return value; + } - @Override - public Integer get() { - return memory.load32(address); - } + @Override + public long loadLong() { + return loadInt(); + } - @Override - public void set(Integer value) { - memory.store32(address, value); - } + @Override + public long loadLongLong() { + longAlignAddress(); + long value = mem.load32(addr); + addr += 8; + value = value | (mem.load32(addr) << 32); + addr += 8; + + return value; } - public class _Short extends StructureElement<Short> { + @Override + public short loadShort() { + shortAlignAddress(); + short value = (short)mem.loadUnsigned16(addr); + addr += 2; - private _Short(int offset) { - this.address = offset; + return value; + } + + @Override + public void skipPadding(Field field, int count) { + + Class<?> type = field.getType(); + + if (type == byte.class) { + addr += count; + return; } - - @Override - public Short get() { - return (short) memory.loadUnsigned16(address); + + if (type == short.class) { + shortAlignAddress(); + addr += count * 2; + return; } - - @Override - public void set(Short value) { - memory.store16(address, value); + + if (type == int.class) { + intAlignAddress(); + addr += count * 4; + return; } + + if (type == long.class) { + + if (field.getAnnotation(_long.class) != null) { + longAlignAddress(); + addr += count * 8; + } + else { + intAlignAddress(); + addr += count * 4; + } + + return; + } } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |