diff options
Diffstat (limited to '')
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/vtable_layout_x86.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/xpcom/reflect/xptcall/md/unix/vtable_layout_x86.cpp b/xpcom/reflect/xptcall/md/unix/vtable_layout_x86.cpp new file mode 100644 index 0000000000..9139d4b2aa --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/vtable_layout_x86.cpp @@ -0,0 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* this code contributed by Bert Driehuis <bert_driehuis@nl.compuware.com> */ + +#include <stdio.h> + +// Try to determine the vtable layout generated by G++ +// Produces the offset at which the first vtable entry can be +// found, and the factor to apply for subsequent entries on stdout. +// Example output: +// #define GCC_VTABLE_START 0xc +// #define GCC_VTABLE_FACTOR 0x8 + +class test { +public: + virtual int t1(void); + virtual int t2(void); + int x; +}; + +test::test() { this->x = 0x12121212; }; + +int test::t1(void) { return 1; } +int test::t2(void) { return 2; } + +void die(char *x) { + fprintf(stderr, "%s\n", x); + exit(1); +} + +int +main() +{ + int i; + test *t = new test(); + int *tp = (int *) t; + int off1 = -1; + int off2 = -1; + int factor; + int factorshift; + + if (*tp++ != 0x12121212) + die("Integer element test::x not found!"); + tp = (int *) *tp; + for (i = 0; i < 10; i++) { + if (tp[i] == (int) t->t1) + off1 = i; + if (tp[i] == (int) t->t2) + off2 = i; + } + if (off1 == -1 || off2 == -1) + die("Could not determine offset into vtable!"); + factor = (off2 - off1) * 4; + factorshift = -1; + while (factor) { + factorshift++; + factor >>= 1; + } + printf("/* Automatically generated by vtable_layout_x86.cpp */\n"); + printf("#define GCC_VTABLE_START\t0x%x\n", off1 * 4); + printf("#define GCC_VTABLE_FACTOR\t0x%x\n", (off2 - off1) * 4); + printf("#define GCC_VTABLE_SHIFT\t0x%x\n", factorshift); + exit(0); +} |