merge upstream/noglib and update some glib related types

This commit is contained in:
Chris Eagle 2016-12-19 12:32:06 -08:00
commit f8f9e993a8
11 changed files with 227 additions and 114 deletions

View file

@ -58,6 +58,9 @@ UNICORN_CFLAGS += -fPIC
# Verbose output? # Verbose output?
V ?= 0 V ?= 0
# on MacOS, compile in Universal format by default
MACOS_UNIVERSAL ?= yes
ifeq ($(UNICORN_DEBUG),yes) ifeq ($(UNICORN_DEBUG),yes)
CFLAGS += -g CFLAGS += -g
else else
@ -177,9 +180,9 @@ LIBDATADIR ?= $(LIBDIR)
ifndef USE_GENERIC_LIBDATADIR ifndef USE_GENERIC_LIBDATADIR
ifeq ($(UNAME_S), FreeBSD) ifeq ($(UNAME_S), FreeBSD)
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata LIBDATADIR = $(PREFIX)/libdata
else ifeq ($(UNAME_S), DragonFly) else ifeq ($(UNAME_S), DragonFly)
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata LIBDATADIR = $(PREFIX)/libdata
endif endif
endif endif

View file

@ -8,24 +8,10 @@ To compile for Microsoft Windows, see [COMPILE-WINDOWS.md](COMPILE-WINDOWS.md)
[0] Dependencies [0] Dependencies
Unicorn requires few dependent packages as follows. For MacOS, Unicorn requires "pkg-config" package.
Brew users can install this with:
- For Mac OS X, "pkg-config" and "glib" are needed.
Brew users can install "pkg-config" and "glib" with:
$ brew install pkg-config glib
NOTE: to build Unicorn universal binaries (which support both 32-bit &
64-bit), you need to have glib in universal format. To do that, build &
install glib with:
$ brew install glib --universal
- For Linux, "glib2-dev" is needed.
Ubuntu/Debian users can install this with:
$ sudo apt-get install libglib2.0-dev
$ brew install pkg-config
[1] Tailor Unicorn to your need. [1] Tailor Unicorn to your need.
@ -75,12 +61,8 @@ To build Unicorn on *nix (such as MacOSX, Linux, *BSD, Solaris):
$ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh $ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh
- To cross-compile Unicorn on 64-bit Linux to target 32-bit binary, install - To cross-compile Unicorn on 64-bit Linux to target 32-bit binary,
libglib2.0-dev for i386. On Ubuntu, this can be done with: cross-compile to 32-bit with:
$ sudo apt-get install libglib2.0-dev:i386
Then cross-compile to 32-bit with:
$ ./make.sh linux32 $ ./make.sh linux32

View file

@ -7,9 +7,8 @@ To compile for Linux, Mac OS X and Unix-based OS, see [COMPILE-NIX.md](COMPILE-N
[0] Dependencies [0] Dependencies
For Windows, cross-compile requires Mingw. Mingw-glib2 is needed. For Windows, cross-compile requires Mingw. At the moment, it is confirmed that
At the moment, it is confirmed that Unicorn can be compiled either on Ubuntu Unicorn can be compiled either on Ubuntu or Windows.
or Windows.
- On Ubuntu 14.04 64-bit, do: - On Ubuntu 14.04 64-bit, do:
@ -17,14 +16,6 @@ or Windows.
https://launchpad.net/~greg-hellings/+archive/ubuntu/mingw-libs/+build/2924251 https://launchpad.net/~greg-hellings/+archive/ubuntu/mingw-libs/+build/2924251
- To cross-compile for Windows 32-bit, install Mingw with (ignore all the warnings):
$ sudo dpkg -i --force-depends mingw64-x86-glib2_2.31.0_all.deb
To cross-compile for Windows 64-bit, install Mingw with:
$ sudo dpkg -i --force-depends mingw64-x64-glib2_2.31.0_all.deb
- On Windows, install MinGW via package MSYS2 at https://msys2.github.io/ - On Windows, install MinGW via package MSYS2 at https://msys2.github.io/
@ -43,7 +34,6 @@ or Windows.
$ pacman -S python2 $ pacman -S python2
$ pacman -S make $ pacman -S make
$ pacman -S pkg-config $ pacman -S pkg-config
$ pacman -S mingw-w64-i686-glib2
$ pacman -S mingw-w64-i686-toolchain $ pacman -S mingw-w64-i686-toolchain
- To compile for Windows 64-bit, run: - To compile for Windows 64-bit, run:
@ -51,15 +41,14 @@ or Windows.
$ pacman -S python2 $ pacman -S python2
$ pacman -S make $ pacman -S make
$ pacman -S pkg-config $ pacman -S pkg-config
$ pacman -S mingw-w64-x86_64-glib2
$ pacman -S mingw-w64-x86_64-toolchain $ pacman -S mingw-w64-x86_64-toolchain
- For Cygwin, "make", "gcc-core", "pkg-config", "libpcre-devel", "zlib-devel" - For Cygwin, "make", "gcc-core", "pkg-config", "libpcre-devel", "zlib-devel"
and "libglib2.0-devel" are needed. are needed.
If apt-cyg is available, you can install these with: If apt-cyg is available, you can install these with:
$ apt-cyg install make gcc-core pkg-config libpcre-devel zlib-devel libglib2.0-devel $ apt-cyg install make gcc-core pkg-config libpcre-devel zlib-devel
@ -111,7 +100,6 @@ To run sample_x86.exe on Windows 32-bit, you need the following files:
unicorn.dll unicorn.dll
%MSYS2%\mingw32\bin\libgcc_s_dw2-1.dll %MSYS2%\mingw32\bin\libgcc_s_dw2-1.dll
%MSYS2%\mingw32\bin\libglib-2.0-0.dll
%MSYS2%\mingw32\bin\libiconv-2.dll %MSYS2%\mingw32\bin\libiconv-2.dll
%MSYS2%\mingw32\bin\libintl-8.dll %MSYS2%\mingw32\bin\libintl-8.dll
%MSYS2%\mingw32\bin\libpcre-1.dll %MSYS2%\mingw32\bin\libpcre-1.dll
@ -121,7 +109,6 @@ To run sample_x86.exe on Windows 64-bit, you need the following files:
unicorn.dll unicorn.dll
%MSYS2%\mingw64\bin\libgcc_s_seh-1.dll %MSYS2%\mingw64\bin\libgcc_s_seh-1.dll
%MSYS2%\mingw64\bin\libglib-2.0-0.dll
%MSYS2%\mingw64\bin\libiconv-2.dll %MSYS2%\mingw64\bin\libiconv-2.dll
%MSYS2%\mingw64\bin\libintl-8.dll %MSYS2%\mingw64\bin\libintl-8.dll
%MSYS2%\mingw64\bin\libpcre-1.dll %MSYS2%\mingw64\bin\libpcre-1.dll
@ -171,14 +158,12 @@ be used on Windows machine.
To run sample_x86.exe on Windows 32-bit, you need the following files: To run sample_x86.exe on Windows 32-bit, you need the following files:
unicorn.dll unicorn.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll
/usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
/usr/i686-w64-mingw32/lib/libwinpthread-1.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
To run sample_x86.exe on Windows 64-bit, you need the following files: To run sample_x86.exe on Windows 64-bit, you need the following files:
unicorn.dll unicorn.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll
/usr/lib/gcc/x86_64-w64-mingw32/4.8/libgcc_s_sjlj-1.dll /usr/lib/gcc/x86_64-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
/usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll

View file

@ -102,6 +102,7 @@ case "$1" in
"install" ) install;; "install" ) install;;
"uninstall" ) uninstall;; "uninstall" ) uninstall;;
"macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE};; "macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE};;
"macos-universal-no" ) MACOS_UNIVERSAL=no ${MAKE};;
"cross-win32" ) build_cross i686-w64-mingw32;; "cross-win32" ) build_cross i686-w64-mingw32;;
"cross-win64" ) build_cross x86_64-w64-mingw32;; "cross-win64" ) build_cross x86_64-w64-mingw32;;
"cross-android" ) CROSS=arm-linux-androideabi ${MAKE};; "cross-android" ) CROSS=arm-linux-androideabi ${MAKE};;

View file

@ -65,7 +65,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
This may be marginally better than what glib does in their direct_hash This may be marginally better than what glib does in their direct_hash
but someone with some chops in this space should fix if it needs improving but someone with some chops in this space should fix if it needs improving
*/ */
guint g_direct_hash(const void *v) { guint g_direct_hash(const void *v)
{
#ifdef __HAVE_64_BIT_PTRS #ifdef __HAVE_64_BIT_PTRS
uint64_t hash = (uint64_t)v; uint64_t hash = (uint64_t)v;
hash = (hash >> 4) | (hash << 60); hash = (hash >> 4) | (hash << 60);
@ -78,7 +79,8 @@ guint g_direct_hash(const void *v) {
#endif #endif
} }
int g_direct_equal(const void *v1, const void *v2) { int g_direct_equal(const void *v1, const void *v2)
{
return v1 == v2; return v1 == v2;
} }
@ -86,7 +88,8 @@ int g_direct_equal(const void *v1, const void *v2) {
djb2+ string hashing djb2+ string hashing
see: http://www.cse.yorku.ca/~oz/hash.html see: http://www.cse.yorku.ca/~oz/hash.html
*/ */
guint g_str_hash(const void *v) { guint g_str_hash(const void *v)
{
const char *s = (const char*)v; const char *s = (const char*)v;
guint hash = 5381; guint hash = 5381;
while (*s) { while (*s) {
@ -96,7 +99,8 @@ guint g_str_hash(const void *v) {
return hash; return hash;
} }
int g_str_equal(const void *v1, const void *v2) { int g_str_equal(const void *v1, const void *v2)
{
return strcmp((const char*)v1, (const char*)v2) == 0; return strcmp((const char*)v1, (const char*)v2) == 0;
} }
@ -104,7 +108,8 @@ int g_str_equal(const void *v1, const void *v2) {
Bob Jenkins integer hash algorithm Bob Jenkins integer hash algorithm
see: http://burtleburtle.net/bob/hash/integer.html see: http://burtleburtle.net/bob/hash/integer.html
*/ */
guint g_int_hash(const void *v) { guint g_int_hash(const void *v)
{
guint hash = *(const guint*)v; guint hash = *(const guint*)v;
hash = (hash + 0x7ed55d16) + (hash << 12); hash = (hash + 0x7ed55d16) + (hash << 12);
hash = (hash ^ 0xc761c23c) ^ (hash >> 19); hash = (hash ^ 0xc761c23c) ^ (hash >> 19);
@ -115,26 +120,30 @@ guint g_int_hash(const void *v) {
return hash; return hash;
} }
int g_int_equal(const void *v1, const void *v2) { int g_int_equal(const void *v1, const void *v2)
{
return *(const int*)v1 == *(const int*)v2; return *(const int*)v1 == *(const int*)v2;
} }
/* Doubly-linked list */ /* Doubly-linked list */
GList *g_list_first(GList *list) { GList *g_list_first(GList *list)
{
if (list == NULL) return NULL; if (list == NULL) return NULL;
while (list->prev) list = list->prev; while (list->prev) list = list->prev;
return list; return list;
} }
void g_list_foreach(GList *list, list_func func, void* user_data) { void g_list_foreach(GList *list, GFunc func, void* user_data)
{
GList *lp; GList *lp;
for (lp = list; lp; lp = lp->next) { for (lp = list; lp; lp = lp->next) {
(*func)(lp->data, user_data); (*func)(lp->data, user_data);
} }
} }
void g_list_free(GList *list) { void g_list_free(GList *list)
{
GList *lp, *next, *prev = NULL; GList *lp, *next, *prev = NULL;
if (list) prev = list->prev; if (list) prev = list->prev;
for (lp = list; lp; lp = next) { for (lp = list; lp; lp = next) {
@ -147,7 +156,8 @@ void g_list_free(GList *list) {
} }
} }
GList *g_list_insert_sorted(GList *list, void* data, compare_func compare) { GList *g_list_insert_sorted(GList *list, void* data, GCompareFunc compare)
{
GList *i; GList *i;
GList *n = (GList*)g_malloc(sizeof(GList)); GList *n = (GList*)g_malloc(sizeof(GList));
n->data = data; n->data = data;
@ -170,7 +180,8 @@ GList *g_list_insert_sorted(GList *list, void* data, compare_func compare) {
return list; return list;
} }
GList *g_list_prepend(GList *list, void* data) { GList *g_list_prepend(GList *list, void* data)
{
GList *n = (GList*)g_malloc(sizeof(GList)); GList *n = (GList*)g_malloc(sizeof(GList));
n->next = list; n->next = list;
n->prev = NULL; n->prev = NULL;
@ -178,14 +189,16 @@ GList *g_list_prepend(GList *list, void* data) {
return n; return n;
} }
GList *g_list_remove_link(GList *list, GList *llink) { GList *g_list_remove_link(GList *list, GList *llink)
{
if (llink == list) list = list->next; if (llink == list) list = list->next;
if (llink->prev) llink->prev->next = llink->next; if (llink->prev) llink->prev->next = llink->next;
if (llink->next) llink->next->prev = llink->prev; if (llink->next) llink->next->prev = llink->prev;
return list; return list;
} }
GList *g_list_sort(GList *list, compare_func compare) { GList *g_list_sort(GList *list, GCompareFunc compare)
{
GList *i, *it, *j; GList *i, *it, *j;
/* base case for singletons or empty lists */ /* base case for singletons or empty lists */
if (list == NULL || list->next == NULL) return list; if (list == NULL || list->next == NULL) return list;
@ -235,7 +248,8 @@ GList *g_list_sort(GList *list, compare_func compare) {
/* Singly-linked list */ /* Singly-linked list */
GSList *g_slist_append(GSList *list, void* data) { GSList *g_slist_append(GSList *list, void* data)
{
GSList *head = list; GSList *head = list;
if (list) { if (list) {
while (list->next) list = list->next; while (list->next) list = list->next;
@ -250,14 +264,16 @@ GSList *g_slist_append(GSList *list, void* data) {
return head; return head;
} }
void g_slist_foreach(GSList *list, list_func func, void* user_data) { void g_slist_foreach(GSList *list, GFunc func, void* user_data)
{
GSList *lp; GSList *lp;
for (lp = list; lp; lp = lp->next) { for (lp = list; lp; lp = lp->next) {
(*func)(lp->data, user_data); (*func)(lp->data, user_data);
} }
} }
void g_slist_free(GSList *list) { void g_slist_free(GSList *list)
{
GSList *lp, *next; GSList *lp, *next;
for (lp = list; lp; lp = next) { for (lp = list; lp; lp = next) {
next = lp->next; next = lp->next;
@ -265,7 +281,8 @@ void g_slist_free(GSList *list) {
} }
} }
void g_slist_free_full(GSList *list, GDestroyNotify free_func) { void g_slist_free_full(GSList *list, GDestroyNotify free_func)
{
GSList *lp, *next; GSList *lp, *next;
for (lp = list; lp; lp = next) { for (lp = list; lp; lp = next) {
next = lp->next; next = lp->next;
@ -274,14 +291,16 @@ void g_slist_free_full(GSList *list, GDestroyNotify free_func) {
} }
} }
GSList *g_slist_prepend(GSList *list, void* data) { GSList *g_slist_prepend(GSList *list, void* data)
{
GSList *head = (GSList*)g_malloc(sizeof(GSList)); GSList *head = (GSList*)g_malloc(sizeof(GSList));
head->next = list; head->next = list;
head->data = data; head->data = data;
return head; return head;
} }
GSList *g_slist_sort(GSList *list, compare_func compare) { GSList *g_slist_sort(GSList *list, GCompareFunc compare)
{
GSList *i, *it, *j; GSList *i, *it, *j;
/* base case for singletons or empty lists */ /* base case for singletons or empty lists */
if (list == NULL || list->next == NULL) return list; if (list == NULL || list->next == NULL) return list;
@ -326,7 +345,8 @@ GSList *g_slist_sort(GSList *list, compare_func compare) {
return list; return list;
} }
GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func) { GSList *g_slist_find_custom(GSList *list, const void *data, GCompareFunc func)
{
GSList *lp; GSList *lp;
for (lp = list; lp; lp = lp->next) { for (lp = list; lp; lp = lp->next) {
if ((*func)(lp->data, data) == 0) return lp; if ((*func)(lp->data, data) == 0) return lp;
@ -334,7 +354,8 @@ GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func) {
return NULL; return NULL;
} }
GSList *g_slist_remove(GSList *list, const void *data) { GSList *g_slist_remove(GSList *list, const void *data)
{
GSList *lp, *prev = NULL; GSList *lp, *prev = NULL;
for (lp = list; lp; lp = lp->next) { for (lp = list; lp; lp = lp->next) {
if (lp->data == data) { if (lp->data == data) {
@ -362,7 +383,7 @@ typedef struct _KeyValue {
void *value; void *value;
} KeyValue; } KeyValue;
typedef struct _GHashTable { struct _GHashTable {
GHashFunc hash_func; GHashFunc hash_func;
GEqualFunc key_equal_func; GEqualFunc key_equal_func;
GDestroyNotify key_destroy_func; GDestroyNotify key_destroy_func;
@ -371,15 +392,17 @@ typedef struct _GHashTable {
uint32_t size; uint32_t size;
uint32_t num_entries; uint32_t num_entries;
GSList **buckets; GSList **buckets;
} GHashTable; };
void g_hash_table_destroy(GHashTable *hash_table) { void g_hash_table_destroy(GHashTable *hash_table)
{
if (hash_table == NULL) return; if (hash_table == NULL) return;
g_hash_table_remove_all(hash_table); g_hash_table_remove_all(hash_table);
g_hash_table_unref(hash_table); g_hash_table_unref(hash_table);
} }
void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_data) { void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_data)
{
if (hash_table == NULL) return NULL; if (hash_table == NULL) return NULL;
int i; int i;
for (i = 0; i < hash_table->size; i++) { for (i = 0; i < hash_table->size; i++) {
@ -392,7 +415,8 @@ void* g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, void* user_da
return NULL; return NULL;
} }
void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data) { void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data)
{
if (hash_table == NULL) return; if (hash_table == NULL) return;
int i; int i;
for (i = 0; i < hash_table->size; i++) { for (i = 0; i < hash_table->size; i++) {
@ -404,7 +428,8 @@ void g_hash_table_foreach(GHashTable *hash_table, GHFunc func, void* user_data)
} }
} }
int g_hash_table_insert(GHashTable *hash_table, void* key, void* value) { int g_hash_table_insert(GHashTable *hash_table, void* key, void* value)
{
if (hash_table == NULL) return 1; if (hash_table == NULL) return 1;
GSList *lp; GSList *lp;
guint hash = (*hash_table->hash_func)(key); guint hash = (*hash_table->hash_func)(key);
@ -428,7 +453,8 @@ int g_hash_table_insert(GHashTable *hash_table, void* key, void* value) {
return 1; return 1;
} }
void* g_hash_table_lookup(GHashTable *hash_table, const void* key) { void* g_hash_table_lookup(GHashTable *hash_table, const void* key)
{
if (hash_table == NULL) return NULL; if (hash_table == NULL) return NULL;
GSList *lp; GSList *lp;
guint hash = (*hash_table->hash_func)(key); guint hash = (*hash_table->hash_func)(key);
@ -443,12 +469,14 @@ void* g_hash_table_lookup(GHashTable *hash_table, const void* key) {
return NULL; return NULL;
} }
GHashTable *g_hash_table_new(GHashFunc hash_func, GEqualFunc key_equal_func) { GHashTable *g_hash_table_new(GHashFunc hash_func, GEqualFunc key_equal_func)
{
return g_hash_table_new_full(hash_func, key_equal_func, NULL, NULL); return g_hash_table_new_full(hash_func, key_equal_func, NULL, NULL);
} }
GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func, GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func) { GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
{
GHashTable *ht = (GHashTable*)g_malloc(sizeof(GHashTable)); GHashTable *ht = (GHashTable*)g_malloc(sizeof(GHashTable));
ht->hash_func = hash_func ? hash_func : g_direct_hash; ht->hash_func = hash_func ? hash_func : g_direct_hash;
ht->key_equal_func = key_equal_func; ht->key_equal_func = key_equal_func;
@ -461,7 +489,8 @@ GHashTable *g_hash_table_new_full(GHashFunc hash_func, GEqualFunc key_equal_func
return ht; return ht;
} }
void g_hash_table_remove_all(GHashTable *hash_table) { void g_hash_table_remove_all(GHashTable *hash_table)
{
if (hash_table == NULL) return; if (hash_table == NULL) return;
int i; int i;
for (i = 0; i < hash_table->size; i++) { for (i = 0; i < hash_table->size; i++) {
@ -478,7 +507,8 @@ void g_hash_table_remove_all(GHashTable *hash_table) {
hash_table->num_entries = 0; hash_table->num_entries = 0;
} }
int g_hash_table_remove(GHashTable *hash_table, const void* key) { int g_hash_table_remove(GHashTable *hash_table, const void* key)
{
GSList *lp, *prev = NULL; GSList *lp, *prev = NULL;
if (hash_table == NULL) return 0; if (hash_table == NULL) return 0;
guint hash = (*hash_table->hash_func)(key); guint hash = (*hash_table->hash_func)(key);
@ -504,7 +534,8 @@ int g_hash_table_remove(GHashTable *hash_table, const void* key) {
return 0; return 0;
} }
void g_hash_table_unref(GHashTable *hash_table) { void g_hash_table_unref(GHashTable *hash_table)
{
if (hash_table == NULL) return; if (hash_table == NULL) return;
hash_table->refcount--; hash_table->refcount--;
if (hash_table->refcount == 0) { if (hash_table->refcount == 0) {
@ -513,13 +544,15 @@ void g_hash_table_unref(GHashTable *hash_table) {
} }
} }
GHashTable *g_hash_table_ref(GHashTable *hash_table) { GHashTable *g_hash_table_ref(GHashTable *hash_table)
{
if (hash_table == NULL) return NULL; if (hash_table == NULL) return NULL;
hash_table->refcount++; hash_table->refcount++;
return hash_table; return hash_table;
} }
guint g_hash_table_size(GHashTable *hash_table) { guint g_hash_table_size(GHashTable *hash_table)
{
return hash_table ? hash_table->num_entries : 0; return hash_table ? hash_table->num_entries : 0;
} }
@ -528,27 +561,31 @@ guint g_hash_table_size(GHashTable *hash_table) {
/* general g_XXX substitutes */ /* general g_XXX substitutes */
void *g_malloc(size_t size) { void *g_malloc(size_t size)
{
if (size == 0) return NULL; if (size == 0) return NULL;
void *res = malloc(size); void *res = malloc(size);
if (res == NULL) exit(1); if (res == NULL) exit(1);
return res; return res;
} }
void *g_malloc0(size_t size) { void *g_malloc0(size_t size)
{
if (size == 0) return NULL; if (size == 0) return NULL;
void *res = calloc(size, 1); void *res = calloc(size, 1);
if (res == NULL) exit(1); if (res == NULL) exit(1);
return res; return res;
} }
void *g_try_malloc0(size_t size) { void *g_try_malloc0(size_t size)
{
if (size == 0) return NULL; if (size == 0) return NULL;
void *res = calloc(size, 1); void *res = calloc(size, 1);
return res; return res;
} }
void *g_realloc(void *ptr, size_t size) { void *g_realloc(void *ptr, size_t size)
{
if (size == 0) { if (size == 0) {
free(ptr); free(ptr);
return NULL; return NULL;
@ -558,11 +595,13 @@ void *g_realloc(void *ptr, size_t size) {
return res; return res;
} }
char *g_strdup(const char *str) { char *g_strdup(const char *str)
{
return str ? strdup(str) : NULL; return str ? strdup(str) : NULL;
} }
char *g_strdup_printf(const char *format, ...) { char *g_strdup_printf(const char *format, ...)
{
va_list ap; va_list ap;
char *res; char *res;
va_start(ap, format); va_start(ap, format);
@ -571,20 +610,23 @@ char *g_strdup_printf(const char *format, ...) {
return res; return res;
} }
char *g_strdup_vprintf(const char *format, va_list ap) { char *g_strdup_vprintf(const char *format, va_list ap)
{
char *str_res = NULL; char *str_res = NULL;
vasprintf(&str_res, format, ap); vasprintf(&str_res, format, ap);
return str_res; return str_res;
} }
char *g_strndup(const char *str, size_t n) { char *g_strndup(const char *str, size_t n)
{
/* try to mimic glib's g_strndup */ /* try to mimic glib's g_strndup */
char *res = calloc(n + 1, 1); char *res = calloc(n + 1, 1);
strncpy(res, str, n); strncpy(res, str, n);
return res; return res;
} }
void g_strfreev(char **str_array) { void g_strfreev(char **str_array)
{
char **p = str_array; char **p = str_array;
if (p) { if (p) {
while (*p) { while (*p) {
@ -594,7 +636,8 @@ void g_strfreev(char **str_array) {
free(str_array); free(str_array);
} }
void *g_memdup(const void *mem, size_t byte_size) { void *g_memdup(const void *mem, size_t byte_size)
{
if (mem) { if (mem) {
void *res = g_malloc(byte_size); void *res = g_malloc(byte_size);
memcpy(res, mem, byte_size); memcpy(res, mem, byte_size);
@ -603,25 +646,29 @@ void *g_memdup(const void *mem, size_t byte_size) {
return NULL; return NULL;
} }
void *g_new_(size_t sz, size_t n_structs) { void *g_new_(size_t sz, size_t n_structs)
{
size_t need = sz * n_structs; size_t need = sz * n_structs;
if ((need / sz) != n_structs) return NULL; if ((need / sz) != n_structs) return NULL;
return g_malloc(need); return g_malloc(need);
} }
void *g_new0_(size_t sz, size_t n_structs) { void *g_new0_(size_t sz, size_t n_structs)
{
size_t need = sz * n_structs; size_t need = sz * n_structs;
if ((need / sz) != n_structs) return NULL; if ((need / sz) != n_structs) return NULL;
return g_malloc0(need); return g_malloc0(need);
} }
void *g_renew_(size_t sz, void *mem, size_t n_structs) { void *g_renew_(size_t sz, void *mem, size_t n_structs)
{
size_t need = sz * n_structs; size_t need = sz * n_structs;
if ((need / sz) != n_structs) return NULL; if ((need / sz) != n_structs) return NULL;
return g_realloc(mem, need); return g_realloc(mem, need);
} }
char *g_strconcat (const char *string1, ...) { char *g_strconcat (const char *string1, ...)
{
va_list ap; va_list ap;
char *res; char *res;
size_t sz = strlen(string1); size_t sz = strlen(string1);
@ -644,7 +691,8 @@ char *g_strconcat (const char *string1, ...) {
return res; return res;
} }
char **g_strsplit(const char *string, const char *delimiter, int max_tokens) { char **g_strsplit(const char *string, const char *delimiter, int max_tokens)
{
char **res; char **res;
if (string == NULL || *string == 0) { if (string == NULL || *string == 0) {
res = (char**)g_malloc(sizeof(char*)); res = (char**)g_malloc(sizeof(char*));
@ -686,7 +734,8 @@ char **g_strsplit(const char *string, const char *delimiter, int max_tokens) {
#include <windows.h> #include <windows.h>
char *g_win32_error_message(int error) { char *g_win32_error_message(int error)
{
char *msg; char *msg;
char *winMsg = NULL; char *winMsg = NULL;
if (error == 0) { if (error == 0) {

View file

@ -39,18 +39,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
/* typedefs for glib related types that may still be referenced */ /* typedefs for glib related types that may still be referenced */
typedef void* gpointer; typedef void* gpointer;
typedef const void *gconstpointer; typedef const void *gconstpointer;
typedef uint32_t guint; typedef int gint;
typedef unsigned int guint;
typedef char gchar; typedef char gchar;
typedef int gboolean; typedef int gboolean;
typedef int (*GCompareFunc)(const void *v1, const void *v2); typedef void (*GFunc)(void* data, void* user_data);
typedef gint (*GCompareFunc)(const void *v1, const void *v2);
typedef void (*GDestroyNotify)(void *data); typedef void (*GDestroyNotify)(void *data);
uint32_t g_direct_hash(const void *v); guint g_direct_hash(const void *v);
int g_direct_equal(const void *v1, const void *v2); int g_direct_equal(const void *v1, const void *v2);
uint32_t g_str_hash(const void *v); guint g_str_hash(const void *v);
int g_str_equal(const void *v1, const void *v2); int g_str_equal(const void *v1, const void *v2);
uint32_t g_int_hash(const void *v); guint g_int_hash(const void *v);
int g_int_equal(const void *v1, const void *v2); int g_int_equal(const void *v1, const void *v2);
typedef struct _GList { typedef struct _GList {
@ -59,17 +61,14 @@ typedef struct _GList {
struct _GList *prev; struct _GList *prev;
} GList; } GList;
typedef void (*list_func)(void* data, void* user_data);
typedef int (*compare_func)(const void *d1, const void *d2);
GList *g_list_first(GList *list); GList *g_list_first(GList *list);
void g_list_foreach(GList *list, list_func func, void* user_data); void g_list_foreach(GList *list, GFunc func, void* user_data);
void g_list_free(GList *list); void g_list_free(GList *list);
GList *g_list_insert_sorted(GList *list, void* data, compare_func compare); GList *g_list_insert_sorted(GList *list, void* data, GCompareFunc compare);
#define g_list_next(list) (list->next) #define g_list_next(list) (list->next)
GList *g_list_prepend(GList *list, void* data); GList *g_list_prepend(GList *list, void* data);
GList *g_list_remove_link(GList *list, GList *llink); GList *g_list_remove_link(GList *list, GList *llink);
GList *g_list_sort(GList *list, compare_func compare); GList *g_list_sort(GList *list, GCompareFunc compare);
typedef struct _GSList { typedef struct _GSList {
void *data; void *data;
@ -77,15 +76,15 @@ typedef struct _GSList {
} GSList; } GSList;
GSList *g_slist_append(GSList *list, void* data); GSList *g_slist_append(GSList *list, void* data);
void g_slist_foreach(GSList *list, list_func func, void* user_data); void g_slist_foreach(GSList *list, GFunc func, void* user_data);
void g_slist_free(GSList *list); void g_slist_free(GSList *list);
void g_slist_free_full(GSList *list, GDestroyNotify free_func); void g_slist_free_full(GSList *list, GDestroyNotify free_func);
GSList *g_slist_prepend(GSList *list, void* data); GSList *g_slist_prepend(GSList *list, void* data);
GSList *g_slist_sort(GSList *list, compare_func compare); GSList *g_slist_sort(GSList *list, GCompareFunc compare);
GSList *g_slist_find_custom(GSList *list, const void *data, compare_func func); GSList *g_slist_find_custom(GSList *list, const void *data, GCompareFunc func);
GSList *g_slist_remove(GSList *list, const void *data); GSList *g_slist_remove(GSList *list, const void *data);
typedef uint32_t (*GHashFunc)(const void *key); typedef guint (*GHashFunc)(const void *key);
typedef int (*GEqualFunc)(const void *a, const void *b); typedef int (*GEqualFunc)(const void *a, const void *b);
typedef void (*GHFunc)(void* key, void* value, void* user_data); typedef void (*GHFunc)(void* key, void* value, void* user_data);
typedef int (*GHRFunc)(void* key, void* value, void* user_data); typedef int (*GHRFunc)(void* key, void* value, void* user_data);
@ -104,7 +103,7 @@ void g_hash_table_remove_all(GHashTable *hash_table);
int g_hash_table_remove(GHashTable *hash_table, const void* key); int g_hash_table_remove(GHashTable *hash_table, const void* key);
void g_hash_table_unref(GHashTable *hash_table); void g_hash_table_unref(GHashTable *hash_table);
GHashTable *g_hash_table_ref(GHashTable *hash_table); GHashTable *g_hash_table_ref(GHashTable *hash_table);
uint32_t g_hash_table_size(GHashTable *hash_table); guint g_hash_table_size(GHashTable *hash_table);
/* replacement for g_malloc dependency */ /* replacement for g_malloc dependency */
void *g_malloc(size_t size); void *g_malloc(size_t size);

View file

@ -119,7 +119,7 @@ static inline GList *g_list_insert_sorted_merged(GList *list,
return list; return list;
} }
static inline int32_t range_compare(gconstpointer a, gconstpointer b) static inline gint range_compare(gconstpointer a, gconstpointer b)
{ {
Range *ra = (Range *)a, *rb = (Range *)b; Range *ra = (Range *)a, *rb = (Range *)b;
if (ra->begin == rb->begin && ra->end == rb->end) { if (ra->begin == rb->begin && ra->end == rb->end) {

View file

@ -1285,6 +1285,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
return !(env->daif & PSTATE_I); return !(env->daif & PSTATE_I);
default: default:
g_assert_not_reached(); g_assert_not_reached();
return false;
} }
} }

View file

@ -155,7 +155,7 @@ static void count_cpreg(gpointer key, gpointer opaque)
} }
} }
static int32_t cpreg_key_compare(gconstpointer a, gconstpointer b) static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
{ {
uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a); uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b); uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);

View file

@ -14,7 +14,7 @@ V ?= 0
CFLAGS += -Wall -Werror -I../include CFLAGS += -Wall -Werror -I../include
LDFLAGS += -L$(LIBDIR) -lunicorn -lpthread -lm LDFLAGS += -L$(LIBDIR) -lunicorn -lpthread -lm
LDLIBS += -lpthread -lunicorn -lm LDLIBS += -lpthread -lunicorn -lm -lrt
ifneq ($(CROSS),) ifneq ($(CROSS),)
CC = $(CROSS)gcc CC = $(CROSS)gcc

View file

@ -0,0 +1,93 @@
from __future__ import print_function
from unicorn import *
from unicorn.arm_const import *
import regress
# code to be emulated
'''
ins = {
0x00008cd4: """
push {r11}
add r11, sp, #0
mov r3, pc
mov r0, r3
sub sp, r11, #0
pop {r11}
bx lr
""",
0x00008cf0: """
push {r11}
add r11, sp, #0
push {r6}
add r6, pc, $1
bx r6
.code 16
mov r3, pc
add r3, $0x4
push {r3}
pop {pc}
.code 32
pop {r6}
mov r0, r3
sub sp, r11, #0
pop {r11}
bx lr
""",
0x00008d20: """
push {r11}
add r11, sp, #0
mov r3, lr
mov r0, r3
sub sp, r11, #0
pop {r11}
bx lr
""",
0x00008d68: "bl 0x8cd4\n"
"mov r4, r0\n"
"bl 0x8cf0\n"
"mov r3, r0\n"
"add r4, r4, r3\n"
"bl 0x8d20\n"
"mov r3, r0\n"
"add r2, r4, r3",
}
'''
class BxTwiceTest(regress.RegressTest):
def runTest(self):
ADDRESS = 0x8000
MAIN_ADDRESS = 0x8d68
STACK_ADDR = ADDRESS + 0x1000
code = {
0x8cf0: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x04`-\xe5\x01`\x8f\xe2\x16\xff/\xe1{F\x03\xf1\x04\x03\x08\xb4\x00\xbd\x00\x00\x04`\x9d\xe4\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
0x8d20: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x0e0\xa0\xe1\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
0x8cd4: '\x04\xb0-\xe5\x00\xb0\x8d\xe2\x0f0\xa0\xe1\x03\x00\xa0\xe1\x00\xd0K\xe2\x04\xb0\x9d\xe4\x1e\xff/\xe1',
0x8d68: '\xd9\xff\xff\xeb\x00@\xa0\xe1\xde\xff\xff\xeb\x000\xa0\xe1\x03@\x84\xe0\xe7\xff\xff\xeb\x000\xa0\xe1\x03 \x84\xe0'
}
try:
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
# map 2MB memory for this emulation
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
# write machine code to be emulated to memory
for addr, c in code.items():
print("Writing chunk to 0x{:x}".format(addr))
mu.mem_write(addr, c)
# initialize machine registers
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR)
print("Starting emulation")
# emulate code in infinite time & unlimited instructions
mu.emu_start(MAIN_ADDRESS, MAIN_ADDRESS + len(code[MAIN_ADDRESS]))
print("Emulation done")
r2 = mu.reg_read(UC_ARM_REG_R2)
print(">>> r2: 0x{:08x}".format(r2))
except UcError as e:
self.fail("ERROR: %s" % e)