X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/b21525c7b2b9f64150f97e79f1f0788edbc7b3bf..5a2ae41928193b489e490abb580abc2fa53181ea:/sig/parse.cpp diff --git a/sig/parse.cpp b/sig/parse.cpp index a786039..05b3213 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -1,21 +1,54 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include "minimal/stdlib.h" - -#include - -#include - +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * 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. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. +*/ +/* }}} */ + +#include #include "sig/parse.hpp" +#include "Error.hpp" -namespace sig { +#include +#include +#include -void (*sig_aggregate)(apr_pool_t *pool, enum Primitive primitive, const char *name, struct Signature *signature, const char *types) = NULL; +namespace sig { -void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos); -struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named); +void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback); +struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback); /* XXX: I really screwed up this time */ @@ -25,10 +58,11 @@ void *prealloc_(apr_pool_t *pool, void *odata, size_t osize, size_t nsize) { return ndata; } -void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos) { +void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback) { _assert(*name != NULL); - bool named = **name == '"'; + // XXX: this is just a stupid check :( + bool named(**name == '"'); signature->elements = NULL; signature->count = 0; @@ -52,7 +86,7 @@ void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, ch *name = quote + 1; } - element->type = Parse_(pool, name, eos, named); + element->type = Parse_(pool, name, eos, named, callback); if (**name < '0' || **name > '9') element->offset = _not(size_t); @@ -66,7 +100,7 @@ void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, ch } } -struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { +struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback) { char next = *(*name)++; if (next == '?') return NULL; @@ -80,7 +114,10 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { case '#': type->primitive = typename_P; break; case '(': - type->primitive = union_P; + if (type->data.signature.count < 2) + type->primitive = struct_P; + else + type->primitive = union_P; next = ')'; goto aggregate; @@ -109,7 +146,7 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { case '[': type->primitive = array_P; type->data.data.size = strtoul(*name, (char **) name, 10); - type->data.data.type = Parse_(pool, name, eos, false); + type->data.data.type = Parse_(pool, name, eos, false, callback); if (**name != ']') { printf("']' != \"%s\"\n", *name); _assert(false); @@ -119,13 +156,13 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { case '^': type->primitive = pointer_P; - if (**name == 'v') { - type->data.data.type = NULL; - ++*name; - } else if (**name == '"') { + if (**name == '"') { type->data.data.type = NULL; } else { - type->data.data.type = Parse_(pool, name, eos, named); + type->data.data.type = Parse_(pool, name, eos, named, callback); + sig::Type *&target(type->data.data.type); + if (target != NULL && target->primitive == void_P) + target = NULL; } break; @@ -162,24 +199,19 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { else type->name = NULL; + // XXX: this types thing is a throwback to JocStrap + char *types; - if (next != '=') + if (next != '=') { types = NULL; - else { - const char *temp = *name; - Parse_(pool, &type->data.signature, name, end); + } else { + const char *temp(*name); + Parse_(pool, &type->data.signature, name, end, callback); types = (char *) apr_pstrmemdup(pool, temp, *name - temp - 1); } - if (type->name != NULL && sig_aggregate != NULL) { - char *angle = strchr(type->name, '<'); - if (angle == NULL) - (*sig_aggregate)(pool, type->primitive, type->name, &type->data.signature, types); - else { - angle = (char *) apr_pstrmemdup(pool, type->name, angle - type->name); - (*sig_aggregate)(pool, type->primitive, angle, &type->data.signature, types); - } - } + if (callback != NULL) + (*callback)(pool, type->name, types, type); } break; case 'N': type->flags |= JOC_TYPE_INOUT; goto next; @@ -203,9 +235,9 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) { return type; } -void Parse(apr_pool_t *pool, struct Signature *signature, const char *name) { +void Parse(apr_pool_t *pool, struct Signature *signature, const char *name, Callback callback) { const char *temp = name; - Parse_(pool, signature, &temp, '\0'); + Parse_(pool, signature, &temp, '\0', callback); _assert(temp[-1] == '\0'); } @@ -242,7 +274,7 @@ const char *Unparse(apr_pool_t *pool, struct Type *type) { return apr_psprintf(pool, "[%lu%s]", type->data.data.size, value); } break; - case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "" : Unparse(pool, type->data.data.type)); + case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "v" : Unparse(pool, type->data.data.type)); case bit_P: return apr_psprintf(pool, "b%zu", type->data.data.size); case char_P: return "c"; case double_P: return "d";