Merged branch develop into develop

develop
Japa 2016-10-21 22:55:38 +05:30
commit 25a64a2102
4 changed files with 134 additions and 49 deletions

@ -227,7 +227,7 @@ sub render_global_class {
$seen_class{$name}++;
local $compound_off = 0;
$compound_off = 4 if ($meta eq 'class-type');
$compound_off = $SIZEOF_PTR if ($meta eq 'class-type');
$compound_off = sizeof($global_types{$parent}) if $parent;
local $current_typename = $rbname;
@ -244,7 +244,7 @@ sub render_global_class {
indent_rb {
my $sz = sizeof($type);
# see comment is sub sizeof ; but gcc has sizeof(cls) aligned
$sz = align_field($sz, 4) if $os eq 'linux' and $meta eq 'class-type';
$sz = align_field($sz, $SIZEOF_PTR) if $os eq 'linux' and $meta eq 'class-type';
push @lines_rb, "sizeof $sz\n";
push @lines_rb, "rtti_classname :$rtti_name\n" if $rtti_name;
@ -425,8 +425,8 @@ sub render_class_vmethods_voff {
for my $meth ($vms->findnodes('child::vmethod'))
{
$voff += 4 if $meth->getAttribute('is-destructor') and $os eq 'linux';
$voff += 4;
$voff += $SIZEOF_PTR if $meth->getAttribute('is-destructor') and $os eq 'linux';
$voff += $SIZEOF_PTR;
}
return $voff;
@ -470,8 +470,8 @@ sub render_class_vmethods {
}
# on linux, the destructor uses 2 entries
$voff += 4 if $meth->getAttribute('is-destructor') and $os eq 'linux';
$voff += 4;
$voff += $SIZEOF_PTR if $meth->getAttribute('is-destructor') and $os eq 'linux';
$voff += $SIZEOF_PTR;
}
}
@ -598,14 +598,14 @@ sub align_field {
sub get_field_align {
my ($field) = @_;
my $al = 4;
my $al = $SIZEOF_PTR;
my $meta = $field->getAttribute('ld:meta');
if ($meta eq 'number') {
$al = sizeof($field);
# linux aligns int64_t to 4, windows to 8
# linux aligns int64_t to $SIZEOF_PTR, windows to 8
# floats are 4 bytes so no pb
$al = 4 if ($al > 4 and ($os eq 'linux' or $al != 8));
$al = 4 if ($al > 4 and (($os eq 'linux' and $arch == 32) or $al != 8));
} elsif ($meta eq 'global') {
$al = get_global_align($field);
} elsif ($meta eq 'compound') {
@ -800,11 +800,9 @@ sub sizeof_compound {
$sizeof_cache{$typename} = $SIZEOF_LONG if $typename;
return $SIZEOF_LONG;
}
else {
print "$st type $base\n" if $base !~ /int(\d+)_t/;
$sizeof_cache{$typename} = $1/8 if $typename;
return $1/8;
}
print "$st type $base\n" if $base !~ /int(\d+)_t/;
$sizeof_cache{$typename} = $1/8 if $typename;
return $1/8;
}
if ($field->getAttribute('is-union'))
@ -820,11 +818,11 @@ sub sizeof_compound {
my $parent = $field->getAttribute('inherits-from');
my $off = 0;
$off = 4 if ($meta eq 'class-type');
$off = $SIZEOF_PTR if ($meta eq 'class-type');
$off = sizeof($global_types{$parent}) if ($parent);
my $al = 1;
$al = 4 if ($meta eq 'class-type');
$al = $SIZEOF_PTR if ($meta eq 'class-type');
for my $f ($field->findnodes('child::ld:field'))
{

@ -1,5 +1,32 @@
# definition of classes used by ruby-autogen
$sizeof_ptr = case RUBY_PLATFORM
when /x86_64|x64/i; 64
else 32
end
module DFHack
def self.memory_read_int64(addr)
(memory_read_int32(addr) & 0xffffffff) + (memory_read_int32(addr+4) << 32)
end
def self.memory_write_int64(addr, v)
memory_write_int32(addr, v & 0xffffffff) ; memory_write_int32(addr+4, v>>32)
end
if $sizeof_ptr == 64
def self.memory_read_ptr(addr)
memory_read_int64(addr) & 0xffffffff_ffffffff
end
def self.memory_write_ptr(addr, v)
memory_write_int64(addr, v)
end
else
def self.memory_read_ptr(addr)
memory_read_int32(addr) & 0xffffffff
end
def self.memory_write_ptr(addr, v)
memory_write_int32(addr, v)
end
end
module MemHack
INSPECT_SIZE_LIMIT=16384
class MemStruct
@ -62,6 +89,8 @@ module DFHack
case tglen
when 1; StlVector8.new(tg)
when 2; StlVector16.new(tg)
when 4; StlVector32.new(tg)
when 8; StlVector64.new(tg)
else StlVector32.new(tg)
end
end
@ -207,10 +236,10 @@ module DFHack
def _get
v = case @_bits
when 64; DFHack.memory_read_int64(@_memaddr)
when 32; DFHack.memory_read_int32(@_memaddr)
when 16; DFHack.memory_read_int16(@_memaddr)
when 8; DFHack.memory_read_int8( @_memaddr)
when 64;(DFHack.memory_read_int32(@_memaddr) & 0xffffffff) + (DFHack.memory_read_int32(@_memaddr+4) << 32)
end
v &= (1 << @_bits) - 1 if not @_signed
v = @_enum.sym(v) if @_enum
@ -220,10 +249,10 @@ module DFHack
def _set(v)
v = @_enum.int(v) if @_enum
case @_bits
when 64; DFHack.memory_write_int64(@_memaddr, v)
when 32; DFHack.memory_write_int32(@_memaddr, v)
when 16; DFHack.memory_write_int16(@_memaddr, v)
when 8; DFHack.memory_write_int8( @_memaddr, v)
when 64; DFHack.memory_write_int32(@_memaddr, v & 0xffffffff) ; DFHack.memory_write_int32(@memaddr+4, v>>32)
end
end
@ -299,11 +328,11 @@ module DFHack
end
def _getp
DFHack.memory_read_int32(@_memaddr) & 0xffffffff
DFHack.memory_read_ptr(@_memaddr)
end
def _setp(v)
DFHack.memory_write_int32(@_memaddr, v)
DFHack.memory_write_ptr(@_memaddr, v)
end
def _get
@ -316,8 +345,8 @@ module DFHack
# XXX shaky...
def _set(v)
case v
when Pointer; DFHack.memory_write_int32(@_memaddr, v._getp)
when MemStruct; DFHack.memory_write_int32(@_memaddr, v._memaddr)
when Pointer; DFHack.memory_write_ptr(@_memaddr, v._getp)
when MemStruct; DFHack.memory_write_ptr(@_memaddr, v._memaddr)
when Integer
if @_tg and @_tg.kind_of?(MemHack::Number)
if _getp == 0
@ -325,9 +354,9 @@ module DFHack
end
@_tg._at(_getp)._set(v)
else
DFHack.memory_write_int32(@_memaddr, v)
DFHack.memory_write_ptr(@_memaddr, v)
end
when nil; DFHack.memory_write_int32(@_memaddr, 0)
when nil; DFHack.memory_write_ptr(@_memaddr, 0)
else @_tg._at(_getp)._set(v)
end
end
@ -353,7 +382,7 @@ module DFHack
def _getp(i=0)
delta = (i != 0 ? i*@_tglen : 0)
(DFHack.memory_read_int32(@_memaddr) & 0xffffffff) + delta
DFHack.memory_read_ptr(@_memaddr) + delta
end
def _get
@ -364,10 +393,10 @@ module DFHack
def _set(v)
case v
when Pointer; DFHack.memory_write_int32(@_memaddr, v._getp)
when MemStruct; DFHack.memory_write_int32(@_memaddr, v._memaddr)
when Integer; DFHack.memory_write_int32(@_memaddr, v)
when nil; DFHack.memory_write_int32(@_memaddr, 0)
when Pointer; DFHack.memory_write_ptr(@_memaddr, v._getp)
when MemStruct; DFHack.memory_write_ptr(@_memaddr, v._memaddr)
when Integer; DFHack.memory_write_ptr(@_memaddr, v)
when nil; DFHack.memory_write_ptr(@_memaddr, 0)
else raise "cannot PointerAry._set(#{v.inspect})"
end
end
@ -557,6 +586,20 @@ module DFHack
end
end
end
class StlVector64 < StlVector32
def length
DFHack.memory_vector64_length(@_memaddr)
end
def valueptr_at(idx)
DFHack.memory_vector64_ptrat(@_memaddr, idx)
end
def insert_at(idx, val)
DFHack.memory_vector64_insertat(@_memaddr, idx, val)
end
def delete_at(idx)
DFHack.memory_vector64_deleteat(@_memaddr, idx)
end
end
class StlVector16 < StlVector32
def length
DFHack.memory_vector16_length(@_memaddr)
@ -733,8 +776,8 @@ module DFHack
@_tg = tg
end
field(:_ptr, 0) { number 32, false }
field(:_length, 4) { number 16, false }
field(:_ptr, 0) { number $sizeof_ptr, false }
field(:_length, $sizeof_ptr/8) { number 16, false }
def length ; _length ; end
def size ; _length ; end
@ -769,8 +812,8 @@ module DFHack
end
field(:_ptr, 0) { pointer }
field(:_prev, 4) { pointer }
field(:_next, 8) { pointer }
field(:_prev, $sizeof_ptr/8) { pointer }
field(:_next, 2*$sizeof_ptr/8) { pointer }
def item
# With the current xml structure, currently _tg designate
@ -946,7 +989,7 @@ module DFHack
def self.vmethod_call(obj, voff, a0=0, a1=0, a2=0, a3=0, a4=0, a5=0)
this = obj._memaddr
vt = df.get_vtable_ptr(this)
fptr = df.memory_read_int32(vt + voff) & 0xffffffff
fptr = df.memory_read_ptr(vt + voff)
vmethod_do_call(this, fptr, vmethod_arg(a0), vmethod_arg(a1), vmethod_arg(a2),
vmethod_arg(a3), vmethod_arg(a4), vmethod_arg(a5))
end

@ -284,16 +284,15 @@ static command_result df_rubyeval(color_ostream &out, std::vector <std::string>
// this code should work with ruby1.9, but ruby1.9 doesn't like running
// in a dedicated non-main thread, so use ruby1.8 binaries only for now
// these ruby definitions are invalid for windows 64bit (need long long)
typedef unsigned long VALUE;
typedef unsigned long ID;
typedef uintptr_t VALUE;
typedef uintptr_t ID;
#define Qfalse ((VALUE)0)
#define Qtrue ((VALUE)2)
#define Qnil ((VALUE)4)
#define INT2FIX(i) ((VALUE)((((long)i) << 1) | 1))
#define FIX2INT(i) (((long)i) >> 1)
#define INT2FIX(i) ((VALUE)((((intptr_t)i) << 1) | 1))
#define FIX2INT(i) (((intptr_t)i) >> 1)
#define RUBY_METHOD_FUNC(func) ((VALUE(*)(...))func)
void (*ruby_init_stack)(VALUE*);
@ -313,9 +312,9 @@ VALUE (*rb_eval_string_protect)(const char*, int*);
VALUE (*rb_ary_shift)(VALUE);
VALUE (*rb_float_new)(double);
double (*rb_num2dbl)(VALUE);
VALUE (*rb_int2inum)(long);
VALUE (*rb_uint2inum)(unsigned long);
unsigned long (*rb_num2ulong)(VALUE);
VALUE (*rb_int2inum)(intptr_t); // XXX check on win64 long vs intptr_t
VALUE (*rb_uint2inum)(uintptr_t);
uintptr_t (*rb_num2ulong)(VALUE);
// end of rip(ruby.h)
DFHack::DFLibrary *libruby_handle;
@ -582,14 +581,22 @@ static VALUE rb_dfget_vtable(VALUE self, VALUE name)
static VALUE rb_dfget_rtti_classname(VALUE self, VALUE vptr)
{
char *ptr = (char*)rb_num2ulong(vptr);
#ifdef WIN32
#if defined(_WIN64)
// win64
char *rtti = *(char**)(ptr - 0x8);
char *typeinfo = Core::getInstance().p->getBase() + *(uint32_t*)(rtti + 0xC);
// skip the .?AV, trim @@ from end
return rb_str_new(typeinfo+0x14, strlen(typeinfo+0x14)-2);
#elif defined(WIN32)
// win32
char *rtti = *(char**)(ptr - 0x4);
char *typeinfo = *(char**)(rtti + 0xC);
// skip the .?AV, trim @@ from end
return rb_str_new(typeinfo+0xc, strlen(typeinfo+0xc)-2);
#else
char *typeinfo = *(char**)(ptr - 0x4);
char *typestring = *(char**)(typeinfo + 0x4);
// linux/osx 32/64
char *typeinfo = *(char**)(ptr - sizeof(void*));
char *typestring = *(char**)(typeinfo + sizeof(void*));
while (*typestring >= '0' && *typestring <= '9')
typestring++;
return rb_str_new(typestring, strlen(typestring));
@ -598,8 +605,7 @@ static VALUE rb_dfget_rtti_classname(VALUE self, VALUE vptr)
static VALUE rb_dfget_vtable_ptr(VALUE self, VALUE objptr)
{
// actually, rb_dfmemory_read_int32
return rb_uint2inum(*(uint32_t*)rb_num2ulong(objptr));
return rb_uint2inum(*(uintptr_t*)rb_num2ulong(objptr));
}
// run a dfhack command, as if typed from the dfhack console
@ -909,6 +915,30 @@ static VALUE rb_dfmemory_vec32_deleteat(VALUE self, VALUE addr, VALUE idx)
return Qtrue;
}
// vector<uint64>
static VALUE rb_dfmemory_vec64_length(VALUE self, VALUE addr)
{
std::vector<uint64_t> *v = (std::vector<uint64_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->size());
}
static VALUE rb_dfmemory_vec64_ptrat(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint64_t> *v = (std::vector<uint64_t>*)rb_num2ulong(addr);
return rb_uint2inum((uintptr_t)&v->at(FIX2INT(idx)));
}
static VALUE rb_dfmemory_vec64_insertat(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint64_t> *v = (std::vector<uint64_t>*)rb_num2ulong(addr);
v->insert(v->begin()+FIX2INT(idx), rb_num2ulong(val));
return Qtrue;
}
static VALUE rb_dfmemory_vec64_deleteat(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint64_t> *v = (std::vector<uint64_t>*)rb_num2ulong(addr);
v->erase(v->begin()+FIX2INT(idx));
return Qtrue;
}
// vector<bool>
static VALUE rb_dfmemory_vecbool_new(VALUE self)
{
@ -1136,6 +1166,10 @@ static void ruby_bind_dfhack(void) {
rb_define_singleton_method(rb_cDFHack, "memory_vector32_ptrat", RUBY_METHOD_FUNC(rb_dfmemory_vec32_ptrat), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_insertat", RUBY_METHOD_FUNC(rb_dfmemory_vec32_insertat), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_deleteat", RUBY_METHOD_FUNC(rb_dfmemory_vec32_deleteat), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector64_length", RUBY_METHOD_FUNC(rb_dfmemory_vec64_length), 1);
rb_define_singleton_method(rb_cDFHack, "memory_vector64_ptrat", RUBY_METHOD_FUNC(rb_dfmemory_vec64_ptrat), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector64_insertat", RUBY_METHOD_FUNC(rb_dfmemory_vec64_insertat), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector64_deleteat", RUBY_METHOD_FUNC(rb_dfmemory_vec64_deleteat), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vectorbool_new", RUBY_METHOD_FUNC(rb_dfmemory_vecbool_new), 0);
rb_define_singleton_method(rb_cDFHack, "memory_vectorbool_delete", RUBY_METHOD_FUNC(rb_dfmemory_vecbool_delete), 1);
rb_define_singleton_method(rb_cDFHack, "memory_vectorbool_init", RUBY_METHOD_FUNC(rb_dfmemory_vecbool_init), 1);

@ -2,14 +2,24 @@
module Kernel
def puts(*a)
a.flatten.each { |l|
DFHack.print_str(l.to_s.chomp + "\n")
# XXX looks like print_str crashes with strings longer than 4096... maybe not nullterminated ?
# this workaround fixes it
s = l.to_s.chomp + "\n"
while s.length > 0
DFHack.print_str(s[0, 4000])
s[0, 4000] = ''
end
}
nil
end
def puts_err(*a)
a.flatten.each { |l|
DFHack.print_err(l.to_s.chomp + "\n")
s = l.to_s.chomp + "\n"
while s.length > 0
DFHack.print_err(s[0, 4000])
s[0, 4000] = ''
end
}
nil
end