Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
target_php.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <glib.h>
22 
23 #include "object.h"
24 #include "binfile.h"
25 #include "dwdebug.h"
26 #include "dwdebug_priv.h"
27 #include "target.h"
28 #include "target_api.h"
29 #include "probe_api.h"
30 
31 #include "target_php.h"
32 
33 /*
34  * INITIALIZATION:
35  *
36  * To implement php, we do things a lot like the xdebug extension. We
37  * basically breakpoint at strategic places in the php compiler (i.e.,
38  * to harvest globals and classes) and executor (i.e. to "implement"
39  * function breakpoints). The two main structures we need are the
40  * compiler_globals and executor_globals structs.
41  *
42  * If php is not compiled with multithread support (! #define ZTS), we
43  * can just read them directly.
44  *
45  * BUT, if php is compiled with thread support, we have to access the
46  * compiler_globals and executor_globals through thread-local storage.
47  * We only support one kind of TSRM: Linux/pthreads. Of course,
48  * pthreads are 1-to-1 mapped to real kernel threads on any current
49  * version of glibc. This allows us to load the compiler_globals and
50  * executor_globals addresses one time per thread, and cache it. It
51  * won't change.
52  *
53  * It would be nice if we could just load the compiler_globals and
54  * executor_globals TLS structs whenever we attach to an executing php
55  * process, but that isn't quite possible on Linux/pthreads. Why? Zend
56  * uses pthread_(set|get)specific to implement TLS. But the problem is
57  * -- zend uses pthread_getspecific() to get key-specific TLS entries.
58  * We don't want to depend on that; plus, it's probably different on
59  * x86_64 (%fs-based TLS?) and i386. Thus, unless we emulate those
60  * calls specifically for the target, we can't quite get at the TLS
61  * structs directly; we have to snoop on their values as local vars in
62  * functions. Emulating those calls is a bad idea, so we have to snoop.
63  *
64  * (Here are the relevant src bits from php5.5-ish that led me to all
65  * these conclusions:
66  *
67  * #ifndef TSRM_DEBUG
68  * #define TSRM_ERROR(args)
69  * #define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
70  * if (offset==0) { \
71  * return &array; \
72  * } else { \
73  * return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \
74  * }
75  * #endif
76  *
77  * #if defined(PTHREADS)
78  * static pthread_key_t tls_key;
79  * # define tsrm_tls_set(what)
80  * pthread_setspecific(tls_key, (void*)(what))
81  * # define tsrm_tls_get()
82  * pthread_getspecific(tls_key)
83  * #endif
84  *
85  * void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) {
86  * THREAD_T thread_id;
87  * int hash_value;
88  * tsrm_tls_entry *thread_resources;
89  *
90  * thread_resources = tsrm_tls_get();
91  *
92  * if (thread_resources) {
93  * TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
94  * // Read a specific resource from the thread's resources.
95  * // This is called outside of a mutex, so have to be aware about external
96  * // changes to the structure as we read it.
97  * TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
98  * }
99  * thread_id = tsrm_thread_id();
100  *
101  *
102  *
103  * #define TSRMLS_FETCH()
104  * void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
105  * #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)
106  * ((rsrc_id)-1)
107  * #define TSRMG(id, type, element)
108  * (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
109  *
110  * #ifdef ZTS
111  * # define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
112  * #else
113  * # define CG(v) (compiler_globals.v)
114  * extern ZEND_API struct _zend_compiler_globals compiler_globals;
115  * #endif
116  *
117  * #ifdef ZTS
118  * # define EG(v) TSRMG(executor_globals_id, zend_executor_globals *, v)
119  * #else
120  * # define EG(v) (executor_globals.v)
121  * extern ZEND_API zend_executor_globals executor_globals;
122  * #endif
123  * ).
124  *
125  * So how can we best snoop on the execution? If we can catch the php
126  * process directly at startup once it's been loaded, but before it
127  * runs, we can place breakpoints on compiler_globals_ctor and
128  * executor_globals_ctor, which will be called by Zend's TSRM lib when
129  * new threads are created -- to initialize those copies of TLS for the
130  * new thread. Only one problem: Zend startup is a bit funny because it
131  * creates "global" read-only version of the global structs, and they
132  * are cloned to create read-write per-thread versions, I think. So, we
133  * need to breakpoint zend_post_startup(), then we can breakpoint the
134  * ctors to obtain their per-thread struct addresses and remove the
135  * zend_post_startup breakpoint. Each time on of those ctors is called,
136  * we have a new thread entering. So, that's how we get access to these
137  * critical structs if ZTS is enabled -- we hook onto a function that
138  * has the TLS global pointer as an arg to it.
139  *
140  * But what if we're already executing? We can either place probes on
141  * key execution functions (but we won't catch them all; we can't probe
142  * on all the opcode handlers). We *can* look through the current stack
143  * unwind of the the thread and find a function in the execution stack
144  * that has the TLS global pointer as an arg. Then we're good.
145  *
146  * Obviously, we are making the optimizing assumption that we only have
147  * check tsrm_ls once per thread to get the "symbol" we're interested
148  * in.
149  *
150  * SO -- what we're going to do instead is, on attach, unwind the stack
151  * and look for functions with tsrm_ls (if php was compiled with ZTS).
152  * If we find none, we place probes on the primary execution functions
153  * (zend_execute, execute_ex, and execute_internal), and try to snoop
154  * tsrm_ls at those points. Then as soon as one or the other of those
155  * is hit, load the current thread's compiler_globals and/or
156  * executor_globals stuff from CG(tsrm_ls), and remove the corresponding
157  * initial probes to find tsrm_ls.
158  *
159  *
160  * BREAKPOINTS:
161  *
162  * I had hoped that it would be sufficient to breakpoint on execute_ex
163  * and execute_internal, but it is not; we cannot implement lineno
164  * breakpoints without being able to trap on all statement executions.
165  * zend_extension provides a way to hook the statement execution, but we
166  * cannot just "add" a zend_extension with such a hook in from the
167  * outside; requires dynamic memory allocation. So, then we're left
168  * with probing the individual opcode handlers (ugh -- there are a
169  * *ton*). Plus it is slow! But it is the only way to do line-based
170  * breakpoints from outside, and the only way to single step -- a step
171  * is an opcode execution in PHP.
172  *
173  * Ok, we have a lot of opcode handlers we might need to breakpoint if
174  * we wanted to catch all statements. So we're going to give up on this
175  * and only allow breakpoints on function/method calls. Let's
176  * breakpoint each FCALL opcode handler and hope for the best? Do we
177  * have to handle JMP handlers too?
178  *
179  *
180  * SYMBOLS:
181  *
182  * We want to *wait* until we hit an execution of a script before we
183  * read the currently compiled global functions, vars, and types. We do
184  * *not* want to try to read them as they are parsed/compiled. On the
185  * other hand, this may lead us into problems later on where we have
186  * dynamic compilation as a result of execution of a compiled scope.
187  * XXX: what do we do at runtime as far as eval() and dynamic
188  * types/functions go? Vars we can handle by just doing a scope lookup
189  * as necessary. But wouldn't we have to catch the parsing functions
190  * for types/functions?
191  *
192  * But once we have an execution about to start, we scan the
193  * compiler_globals struct and grab all the global vars, functions, and
194  * types, and build symbols for them. Then we need to check the
195  * executor_globals struct for
196  *
197  *
198  * UNWINDING:
199  *
200  * How do we walk the stack? EG(argument_stack) ??
201  * EG(current_execute_data) ?? xdebug builds a stack of function
202  * invocations; can I get away without this?
203  *
204  *
205  */
206 
207 /*
208  * Load it via tsrm_ls:
209  * *((zend_executor_globals *) (*((void ***) tsrm_ls))[6 - 1])
210  *
211  * Except we already did the first tsrm_ls deref when we loaded it.
212  */
213 static struct value *php_TSRMG(struct target *target,ADDR tsrm_ls,int rsrc_id,
214  struct symbol *type) {
215  ADDR ptr = tsrm_ls;
216 
217  if (!tsrm_ls) {
218  errno = EINVAL;
219  return NULL;
220  }
221 
222  /* Deref the first pointer to the array. */
223  /*
224  ptr = 0;
225  if (!target_read_addr(target->base,tsrm_ls,target->base->ptrsize,
226  (unsigned char *)&ptr)) {
227  verror("could not read tsrm_ls 0x%"PRIxADDR"!\n",tsrm_ls);
228  return NULL;
229  }
230  */
231 
232  /* Apply the unshuffled (rsrc_id - 1) rsrc_id index into the array. */
233  ptr += (target->base->arch->ptrsize * (rsrc_id - 1));
234 
235  /* Read it to get the pointer at that array index. */
236  if (!target_read_addr(target->base,ptr,target->base->arch->ptrsize,
237  (unsigned char *)&ptr)) {
238  verror("could not read tsrm_ls idx %d (%d) 0x%"PRIxADDR
239  " (0x%"PRIxADDR")!\n",
240  rsrc_id - 1,rsrc_id,ptr,tsrm_ls);
241  return NULL;
242  }
243 
244  vdebug(5,LA_TARGET,LF_PHP,"TSRMG(0x%"PRIxADDR",%d,%s) about to load type\n",
245  ptr,rsrc_id,symbol_get_name(type));
246 
247  return target_load_type(target->base,type,ptr,LOAD_FLAG_AUTO_DEREF);
248 }
249 
250 /*
251  * Loads a member from the executor_globals struct.
252  */
253 static struct value *php_EG(struct target *target,tid_t tid,char *name) {
254  struct php_state *pstate = (struct php_state *)target->state;
255  struct target_thread *tthread;
256  struct php_thread_state *ptstate;
257  struct value *retval = NULL;
258 
259  tthread = target_lookup_thread(target,tid);
260  if (!tthread) {
261  verror("tid %"PRIiTID" does not exist!\n",tid);
262  errno = ESRCH;
263  return NULL;
264  }
265  ptstate = (struct php_thread_state *)tthread->state;
266 
267  /*
268  * The only reason it would be unloaded would be if this was a
269  * ZTS-enabled php; so handle that.
270  */
271  if (!ptstate->EG) {
272  if (pstate->zts) {
273  if (!ptstate->ztsinfo.tsrm_ls) {
274  verror("EG struct not yet loaded and no ZTS tsrm_ls yet!\n");
275  return NULL;
276  }
277  else {
278  ptstate->EG = php_TSRMG(target,ptstate->ztsinfo.tsrm_ls,
279  pstate->ztsinfo.EG_id,
281  if (!ptstate->EG) {
282  verror("could not load executor_globals struct"
283  " for thread %"PRIiTID"!\n",tid);
284  return NULL;
285  }
286  }
287  }
288  else {
289  verror("EG not loaded for non-ZTS php -- BUG?!\n");
290  errno = EINVAL;
291  return NULL;
292  }
293  }
294  else {
295  vdebug(5,LA_TARGET,LF_PHP,"refreshing EG at 0x%"PRIxADDR"\n",
296  value_addr(ptstate->EG));
297  /* Refresh the value. */
298  value_refresh(ptstate->EG,0);
299  }
300 
301  vdebug(5,LA_TARGET,LF_PHP,"about to load EG(%s) member\n",name);
302 
303  VLVAL(target->base,ptstate->base_tlctxt,ptstate->EG,name,
305 
306  return retval;
307 
308  errout:
309  verror("failed to load EG(%s) in thread %"PRIiTID"!\n",name,tid);
310  return NULL;
311 }
312 
313 #define PHP_UTIL_ZEND_HASH_APPLY_FREE 0
314 #define PHP_UTIL_ZEND_HASH_APPLY_SAVE 1 << 0
315 #define PHP_UTIL_ZEND_HASH_APPLY_STOP 1 << 1
316 typedef int (*php_util_zend_hash_apply_func_t)(struct target *target,
317  struct target_location_ctxt *tlctxt,
318  struct value *k,struct value *v,
319  void *priv);
320 
321 static int php_util_zend_hash_apply(struct target *target,
322  struct target_location_ctxt *tlctxt,
323  struct value *zht,struct symbol *vtype,
325  int f_wants_key,void *fpriv) {
326  ADDR pData,pListNext;
327  struct value *next_k,*next_v;
328  struct value *bucket_v = NULL;
329  struct value *next_bucket_v = NULL;
330  int rc;
331 
332  /* Check if it's completely empty. */
333  VLV(target,tlctxt,zht,"pListHead",LOAD_FLAG_NONE,&pListNext,NULL,errout);
334  if (pListNext == 0) {
335  vdebug(9,LA_TARGET,LF_PHP,"zend_hash 0x%"PRIxADDR" empty\n",
336  value_addr(zht));
337  return 0;
338  }
339  pListNext = 0;
340 
341  VLVAL(target,tlctxt,zht,"pListHead",LOAD_FLAG_AUTO_DEREF,&bucket_v,errout);
342  while (bucket_v) {
343  VLVAR(target,tlctxt,bucket_v,"pData",LOAD_FLAG_NONE,&pData,
344  errout);
345  VLVAR(target,tlctxt,bucket_v,"pListNext",LOAD_FLAG_NONE,&pListNext,
346  errout);
347 
348  if (!pData) {
349  verror("NULL data in zend_hash; skipping!\n");
350  goto next;
351  }
352  next_v = target_load_type(target,vtype,pData,LOAD_FLAG_AUTO_DEREF);
353  if (!next_v) {
354  verror("could not load value of type '%s' at 0x%"PRIxADDR";"
355  " skipping!\n",
356  symbol_get_name(vtype),pData);
357  goto next;
358  }
359  if (f_wants_key) {
360  VLVAL(target,tlctxt,bucket_v,"arKey",LOAD_FLAG_AUTO_STRING,
361  &next_k,errout_key);
362 
363  if (!next_k) {
364  errout_key:
365  value_free(next_v);
366  goto errout;
367  }
368  }
369  else
370  next_k = NULL;
371 
372  rc = f(target,tlctxt,next_k,next_v,fpriv);
373  if (rc < 0) {
374  value_free(next_k);
375  value_free(next_v);
376  value_free(bucket_v);
377  return -1;
378  }
379  if (!(rc & PHP_UTIL_ZEND_HASH_APPLY_SAVE)) {
380  if (next_k)
381  value_free(next_k);
382  value_free(next_v);
383  }
385  value_free(bucket_v);
386  return 0;
387  }
388 
389  if (!pListNext) {
390  value_free(bucket_v);
391  return 0;
392  }
393 
394  next:
395  VLVAL(target,tlctxt,bucket_v,"pListNext",LOAD_FLAG_AUTO_DEREF,
396  &next_bucket_v,errout);
397  value_free(bucket_v);
398  bucket_v = next_bucket_v;
399  }
400 
401  errout:
402  verror("error loading member from zend_hash Bucket!\n");
403  if (bucket_v)
404  value_free(bucket_v);
405  return -1;
406 }
407 
408 /*
409  * (Re-)Populate a PHP debugfile.
410  *
411  * NB: debugfiles are per-region, not per-thread! This is technically
412  * incorrect -- each PHP thread could have a different compiler/executor
413  * state. But we don't worry about that for now.
414  *
415  * Once we have addresses for the compiler_globals and executor_globals
416  * structs, and have reached the first call to zend_execute, we can scan
417  * the CG and EG values and dynamically generate symbols.
418  *
419  *
420  */
421 
423  struct target *target;
426 };
427 
428 static struct symbol *php_debugfile_add_root(struct target *target,
429  struct debugfile *debugfile,
430  char *filename) {
431  struct php_state *pstate = (struct php_state *)target->state;
432  struct symbol *root;
433 
434  root = debugfile_lookup_root_name(debugfile,filename);
435  if (root)
436  return root;
437 
438  if (0 && strcmp(filename,"Reflection") == 0)
439  asm("int $0x3");
440 
442  pstate->debugfile_symbol_counter++,
443  LOADTYPE_FULL,NULL);
444  debugfile_insert_root(debugfile,root);
445 
446  return root;
447 }
448 
449 /*
450  * These came from ~5.5 php-src.
451  */
452 #define PHP_ZEND_INTERNAL_FUNCTION 1U
453 #define PHP_ZEND_USER_FUNCTION 2U
454 #define PHP_ZEND_OVERLOADED_FUNCTION 3U
455 #define PHP_ZEND_EVAL_CODE 4U
456 #define PHP_ZEND_OVERLOADED_FUNCTION_TEMPORARY 5U
457 
458 static int php_debugfile_add_function(struct target *base,
459  struct target_location_ctxt *tlctxt,
460  struct value *zend_hash_key_v,
461  struct value *zend_function_v,
462  void *priv) {
463  struct php_state *pstate;
464  struct debugfile *debugfile;
465  struct lsymbol *ls;
466  struct symbol *symbol;
467  struct value *v = NULL;
468  unsigned int ftype = 0;
469  struct symbol *root = NULL;
470  struct target *target;
471  struct php_debugfile_info *pdi;
472  unsigned int num_args;
473  ADDR arg_info_addr;
474  struct symbol *arg_symbol;
475  struct value *v2;
476  unsigned int i;
477  struct location *loc;
478  int *argslot;
479  unsigned int srcline = 0;
480 
481  pdi = (struct php_debugfile_info *)priv;
482  target = pdi->target;
483  debugfile = pdi->debugfile;
484  pstate = (struct php_state *)target->state;
485 
486  /*
487  * If this function is already in the debugfile via its address,
488  * skip it!
489  */
490  ls = debugfile_lookup_addr(debugfile,value_addr(zend_function_v));
491  if (ls) {
492  lsymbol_release(ls);
494  }
495 
496  VLV(tlctxt->thread->target,tlctxt,zend_function_v,"type",LOAD_FLAG_NONE,
497  &ftype,NULL,errout);
498 
499  vdebug(5,LA_TARGET,LF_PHP,"zend_function 0x%"PRIxADDR" is type %d\n",
500  value_addr(zend_function_v),ftype);
501 
502  /*
503  * If we are not adding this function to another symbol, then get or
504  * create the root symbol.
505  */
506  if (!pdi->current_symbol) {
507  if (ftype == PHP_ZEND_USER_FUNCTION) {
508  VLVAL(tlctxt->thread->target,tlctxt,zend_function_v,
509  "op_array.filename",LOAD_FLAG_AUTO_STRING,&v,errout);
510  VLVAR(tlctxt->thread->target,tlctxt,zend_function_v,
511  "op_array.line_start",LOAD_FLAG_NONE,&srcline,errout);
512 
513  root = php_debugfile_add_root(base,debugfile,v_string(v));
514  if (v)
515  value_free(v);
516  }
517  else if (ftype == PHP_ZEND_INTERNAL_FUNCTION) {
518  v = target_load_value_member(tlctxt->thread->target,tlctxt,
519  zend_function_v,
520  "internal_function.module.name",NULL,
522 
523  root = php_debugfile_add_root(base,debugfile,
524  v ? v_string(v) : "__BUILTIN__");
525  if (v)
526  value_free(v);
527  }
528  else
529  goto out;
530  }
531 
532  /* Now that we have the root symbol, create the function symbol. */
533  v = target_load_value_member(tlctxt->thread->target,tlctxt,zend_function_v,
534  "common.function_name",NULL,
536  if (!v) {
537  verror("could not read function name for zend_function 0x%"PRIxADDR";"
538  " skipping!\n",value_addr(zend_function_v));
539  goto errout;
540  }
541 
542  if (pdi->current_symbol)
546  else
550  value_free(v);
552  symbol);
553  symbol_set_addr(symbol,value_addr(zend_function_v));
554  symbol_set_srcline(symbol,(int)srcline);
555  g_hash_table_insert(pstate->debugfile->addresses,
556  (gpointer)(uintptr_t)symbol_get_addr(symbol),symbol);
557  if (!pdi->current_symbol)
558  debugfile_add_global(debugfile,symbol);
559 
560  /*
561  * Ok, load the arguments.
562  */
563  VLVAR(tlctxt->thread->target,tlctxt,zend_function_v,"common.num_args",
564  LOAD_FLAG_NONE,&num_args,errout);
565  VLVAR(tlctxt->thread->target,tlctxt,zend_function_v,"common.arg_info",
566  LOAD_FLAG_NONE,&arg_info_addr,errout);
567 
568  for (i = 0; i < num_args; ++i) {
569  v = target_load_type(tlctxt->thread->target,pstate->zend_arg_info_type,
570  arg_info_addr,LOAD_FLAG_AUTO_DEREF);
571  if (!v) {
572  vwarn("could not load arg %d for function %s",
573  i,symbol_get_name(symbol));
574  if (pdi->current_symbol)
575  vwarnc(" in class %s\n",symbol_get_name(pdi->current_symbol));
576  else
577  vwarnc("\n");
578  break;
579  }
580 
581  VLVAL(tlctxt->thread->target,tlctxt,v,"name",LOAD_FLAG_AUTO_STRING,
582  &v2,errout);
583 
585  v_string(v2),1,
586  pstate->debugfile_symbol_counter++,
588  symbol_set_parameter(arg_symbol);
589  symbol_insert_symbol(symbol,arg_symbol);
590 
591  loc = location_create();
592  argslot = malloc(sizeof(*argslot));
593  *argslot = i;
594  location_set_runtime(loc,(char *)argslot,sizeof(*argslot),0);
595  symbol_set_location(arg_symbol,loc);
596 
597  value_free(v2);
598 
599  arg_info_addr += symbol_get_bytesize(pstate->zend_arg_info_type);
600  }
601 
602  out:
604 
605  errout:
606  verror("error parsing zend_function value at 0x%"PRIxADDR"!\n",
607  value_addr(zend_function_v));
609 }
610 
611 static struct symbol *php_target_get_base_type_symbol(struct target *target,
612  php_base_symbol_t stype) {
613  if (!PHP_ZEND_TYPE_IS_BASE(stype))
614  return NULL;
615 
616  return ((struct php_state *)(target->state))->base_symbols[stype];
617 }
618 
619 static int php_debugfile_add_constant(struct target *base,
620  struct target_location_ctxt *tlctxt,
621  struct value *zend_hash_key_v,
622  struct value *zend_zval_v,
623  void *priv) {
624  struct php_state *pstate;
625  struct symbol *symbol;
626  unsigned char zvtype = 0;
627  struct target *target;
628  struct php_debugfile_info *pdi;
629  char *buf;
630  struct symbol *symbol_base_type;
631  int symbol_base_type_size;
632 
633  pdi = (struct php_debugfile_info *)priv;
634  target = pdi->target;
635  pstate = (struct php_state *)target->state;
636 
637  if (!pdi->current_symbol) {
638  errno = EINVAL;
639  return -1;
640  }
641  if (!zend_hash_key_v || !v_string(zend_hash_key_v)) {
642  errno = EINVAL;
643  return -1;
644  }
645 
646  VLVAR(tlctxt->thread->target,tlctxt,zend_zval_v,"type",LOAD_FLAG_NONE,
647  &zvtype,errout);
648 
649  if (PHP_ZEND_TYPE_IS_BASE(zvtype)) {
651  "class '%s' constant '%s' zval 0x%"PRIxADDR" is type %d\n",
652  symbol_get_name(pdi->current_symbol),v_string(zend_hash_key_v),
653  value_addr(zend_zval_v),(int)zvtype);
654  }
655  else {
656  verror("class '%s' constant '%s' is non-base type %d; ignoring!\n",
657  symbol_get_name(pdi->current_symbol),v_string(zend_hash_key_v),
658  (int)zvtype);
659  goto errout;
660  }
661 
662  /* Create the constant symbol. */
664  v_string(zend_hash_key_v),1,
667  symbol_base_type = php_target_get_base_type_symbol(target,zvtype);
668  symbol->datatype = symbol_base_type;
669  symbol_base_type_size = symbol_get_bytesize(symbol_base_type);
670  if (zvtype == PHP_ZEND_NULL) {
671  symbol_set_constval(symbol,NULL,0,0);
672  goto out;
673  }
674  else if (zvtype == PHP_ZEND_LONG || zvtype == PHP_ZEND_BOOL) {
675  buf = malloc(symbol_base_type_size);
676  VLVAR(tlctxt->thread->target,tlctxt,zend_zval_v,"value.lval",
677  LOAD_FLAG_NONE,buf,errout);
678  symbol_set_constval(symbol,buf,symbol_base_type_size,1);
679  }
680  else if (zvtype == PHP_ZEND_DOUBLE) {
681  buf = malloc(symbol_base_type_size);
682  VLVAR(tlctxt->thread->target,tlctxt,zend_zval_v,"value.dval",
683  LOAD_FLAG_NONE,buf,errout);
684  symbol_set_constval(symbol,buf,symbol_base_type_size,1);
685  }
686  else if (zvtype == PHP_ZEND_STRING) {
687  int slen;
688  VLVAR(tlctxt->thread->target,tlctxt,zend_zval_v,"value.str.len",
689  LOAD_FLAG_NONE,&slen,errout);
690  if (slen > 4096) {
691  verror("constant string length %d too big; skipping!\n",slen);
692  goto errout;
693  }
694  else if (slen < 1) {
695  verror("constant string length %d too small; skipping!\n",slen);
696  goto errout;
697  }
698  ADDR saddr;
699  VLVAR(tlctxt->thread->target,tlctxt,zend_zval_v,"value.str.val",
700  LOAD_FLAG_NONE,&saddr,errout);
701  buf = malloc(slen + 1);
702  target_read_addr(tlctxt->thread->target,saddr,
703  (unsigned long)slen,(unsigned char *)buf);
704  buf[slen] = '\0';
705  symbol_set_constval(symbol,buf,slen,1);
706  }
708  symbol_set_addr(symbol,value_addr(zend_zval_v));
709  g_hash_table_insert(pstate->debugfile->addresses,
710  (gpointer)(uintptr_t)symbol_get_addr(symbol),symbol);
711 
712  out:
714 
715  errout:
716  verror("error parsing zval value at 0x%"PRIxADDR"!\n",
717  value_addr(zend_zval_v));
719 }
720 
721 /*
722  * These came from ~5.5 php-src.
723  */
724 #define PHP_ZEND_INTERNAL_CLASS 1
725 #define PHP_ZEND_USER_CLASS 2
726 
727 static int php_debugfile_add_class(struct target *base,
728  struct target_location_ctxt *tlctxt,
729  struct value *zend_hash_key_v,
730  struct value *zend_class_entry_v,
731  void *priv) {
732  struct php_state *pstate;
733  struct debugfile *debugfile;
734  struct lsymbol *ls;
735  struct symbol *symbol;
736  struct symbol *old_current_symbol;
737  struct value *v = NULL;
738  char ctype = 0;
739  struct symbol *root = NULL;
740  struct php_debugfile_info *pdi;
741  struct target *target;
742 
743  pdi = (struct php_debugfile_info *)priv;
744  target = pdi->target;
745  debugfile = pdi->debugfile;
746  pstate = (struct php_state *)target->state;
747 
748  /*
749  * If this class is already in the debugfile via its "address",
750  * skip it! Yes, this is a bad abuse of the symbol address field,
751  * but we do it anyway!
752  */
753  ls = debugfile_lookup_addr(debugfile,value_addr(zend_class_entry_v));
754  if (ls) {
755  lsymbol_release(ls);
757  }
758 
759  VLVAR(tlctxt->thread->target,tlctxt,zend_class_entry_v,"type",
760  LOAD_FLAG_NONE,&ctype,errout);
761 
762  vdebug(5,LA_TARGET,LF_PHP,"zend_class_entry 0x%"PRIxADDR" is type %d\n",
763  value_addr(zend_class_entry_v),(int)ctype);
764 
765  /* Get or create the root symbol if we don't have a current symbol. */
766  if (!pdi->current_symbol) {
767  if (ctype == PHP_ZEND_USER_CLASS) {
768  VLVAL(tlctxt->thread->target,tlctxt,zend_class_entry_v,
769  "info.user.filename",LOAD_FLAG_AUTO_STRING,&v,errout);
770 
771  root = php_debugfile_add_root(base,debugfile,v_string(v));
772  value_free(v);
773  }
774  else if (ctype == PHP_ZEND_INTERNAL_CLASS) {
775  v = target_load_value_member(tlctxt->thread->target,tlctxt,
776  zend_class_entry_v,
777  "info.internal.module.name",NULL,
779 
780  root = php_debugfile_add_root(base,debugfile,
781  v ? v_string(v) : "__BUILTIN__");
782  if (v)
783  value_free(v);
784  }
785  else
786  goto out;
787  }
788 
789  /* Now that we have the root symbol, create the class symbol. */
790  v = target_load_value_member(tlctxt->thread->target,tlctxt,
791  zend_class_entry_v,"name",NULL,
793  if (!v) {
794  verror("could not read class name for zend_class_entry 0x%"PRIxADDR";"
795  " skipping!\n",value_addr(zend_class_entry_v));
796  goto errout;
797  }
798 
799  if (pdi->current_symbol)
803  else
807  value_free(v);
809  symbol);
810  symbol->datatype_code = DATATYPE_CLASS;
811  symbol_set_addr(symbol,value_addr(zend_class_entry_v));
812  g_hash_table_insert(pstate->debugfile->addresses,
813  (gpointer)(uintptr_t)symbol_get_addr(symbol),symbol);
814  if (!pdi->current_symbol)
815  debugfile_add_type(debugfile,symbol);
816 
817  /*
818  * Read member functions, properties, constants.
819  *
820  * NB: someday support traits!
821  */
822  v = target_load_value_member(tlctxt->thread->target,tlctxt,
823  zend_class_entry_v,"function_table",NULL,
825  if (!v) {
826  verror("could not load function_table for class '%s'; skipping it!\n",
827  symbol_get_name(symbol));
828  }
829  else {
830  old_current_symbol = pdi->current_symbol;
831  pdi->current_symbol = symbol;
832  php_util_zend_hash_apply(tlctxt->thread->target,tlctxt,v,
833  pstate->zend_function_type,
834  php_debugfile_add_function,0,pdi);
835  pdi->current_symbol = old_current_symbol;
836  value_free(v);
837  }
838 
839  /* Constants. */
840  v = target_load_value_member(tlctxt->thread->target,tlctxt,
841  zend_class_entry_v,"constants_table",NULL,
843  if (!v) {
844  verror("could not load constants_table for class '%s'; skipping it!\n",
845  symbol_get_name(symbol));
846  }
847  else {
848  old_current_symbol = pdi->current_symbol;
849  pdi->current_symbol = symbol;
850  php_util_zend_hash_apply(tlctxt->thread->target,tlctxt,v,
851  pstate->zend_zval_ptr_type,
852  php_debugfile_add_constant,1,pdi);
853  pdi->current_symbol = old_current_symbol;
854  value_free(v);
855  }
856 
857  out:
859 
860  errout:
861  verror("error parsing zend_class_entry value at 0x%"PRIxADDR"!\n",
862  value_addr(zend_class_entry_v));
864 }
865 
866 static int php_populate_debugfile(struct target *target,
867  struct debugfile *debugfile) {
868  struct php_state *pstate;
869  struct target *base;
870  struct php_thread_state *gptstate;
871  struct target_location_ctxt *base_tlctxt;
872  struct value *v;
873  struct php_debugfile_info pdi;
874 
875  pdi.target = target;
876  pdi.debugfile = debugfile;
877  pdi.current_symbol = NULL;
878 
879  pstate = (struct php_state *)target->state;
880  base = target->base;
881  gptstate = (struct php_thread_state *)target->global_thread->state;
882  base_tlctxt = gptstate->base_tlctxt;
883 
884  v = php_EG(target,base_tlctxt->thread->tid,"function_table");
885  if (!v) {
886  verror("could not load EG(function_table)!\n");
887  return -1;
888  }
889 
890  php_util_zend_hash_apply(base,base_tlctxt,v,pstate->zend_function_type,
891  php_debugfile_add_function,0,&pdi);
892  value_free(v);
893 
894  v = php_EG(target,base_tlctxt->thread->tid,"class_table");
895  if (!v) {
896  verror("could not load EG(class_table)!\n");
897  return -1;
898  }
899 
900  php_util_zend_hash_apply(base,base_tlctxt,v,
902  php_debugfile_add_class,0,&pdi);
903  value_free(v);
904 
905  struct dump_info ud = {
906  .stream = stderr,
907  .prefix = " ",
908  .meta = 1,
909  .detail = 1,
910  };
911 
912  debugfile_dump(debugfile,&ud,1,1,1,1,1);
913 
914  return 0;
915 }
916 
917 /*
918  * Convert a zhash to a ghashtable. The string keys we strdup and set a
919  * key destructor; the values are target(void *) unsigned long ints (so
920  * there is no dtor for them). So the caller just has to
921  * g_hash_table_destroy() when finished.
922  *
923  * NB: the caller has to cast the values and load them by type to do
924  * much useful stuff.
925  */
926 GHashTable *php_zhash_to_ghash(struct target *target,struct value *zhash);
927 
928 #define php_zhash_foreach_loadtype(target,zhash_val,lpc,value,value_type)
929 
930 /*
931  * Loads the value as type @type, if it exists.
932  */
933 struct value *php_zhash_find(struct target *target,struct value *zhash,char *key,
934  struct symbol *type);
935 
936 
937 
938 struct php_spec *php_build_spec(void) {
939  struct php_spec *pspec;
940 
941  pspec = calloc(1,sizeof(*pspec));
942 
943  return pspec;
944 }
945 
946 void php_free_spec(struct php_spec *spec) {
947  free(spec);
948 }
949 
950 /*
951  * Prototypes.
952  */
953 static int php_snprintf(struct target *target,char *buf,int bufsiz);
954 static int php_init(struct target *target);
955 static int php_postloadinit(struct target *target);
956 static int php_attach(struct target *target);
957 static int php_detach(struct target *target,int stay_paused);
958 static int php_fini(struct target *target);
959 static int php_loadspaces(struct target *target);
960 static int php_loadregions(struct target *target,struct addrspace *space);
961 static int php_loaddebugfiles(struct target *target,
962  struct addrspace *space,struct memregion *region);
963 
964 static target_status_t php_status(struct target *target);
965 static int php_pause(struct target *target,int nowait);
966 static int php_resume(struct target *target);
967 static unsigned char *php_read(struct target *target,ADDR addr,
968  unsigned long length,unsigned char *buf);
969 static unsigned long php_write(struct target *target,ADDR addr,
970  unsigned long length,unsigned char *buf);
971 static struct value *php_read_symbol(struct target *target,
972  struct target_location_ctxt *tlctxt,
973  struct bsymbol *bsymbol,
974  load_flags_t flags);
975 
976 static tid_t php_gettid(struct target *target);
977 static void php_free_thread_state(struct target *target,void *state);
978 static struct array_list *php_list_available_tids(struct target *target);
979 static struct target_thread *php_load_thread(struct target *target,
980  tid_t tid,int force);
981 static struct target_thread *php_load_current_thread(struct target *target,
982  int force);
983 static int php_load_all_threads(struct target *target,int force);
984 static int php_load_available_threads(struct target *target,int force);
985 static int php_flush_thread(struct target *target,tid_t tid);
986 static int php_flush_current_thread(struct target *target);
987 static int php_flush_all_threads(struct target *target);
988 static int php_invalidate_thread(struct target *target,
989  struct target_thread *tthread);
990 static int php_thread_snprintf(struct target *target,
991  struct target_thread *tthread,
992  char *buf,int bufsiz,
993  int detail,char *sep,char *kvsep);
994 static REGVAL php_read_reg(struct target *target,tid_t tid,REG reg);
995 static int php_write_reg(struct target *target,tid_t tid,REG reg,REGVAL value);
996 
997 static struct target_location_ctxt *php_unwind(struct target *target,tid_t tid);
998 static int php_unwind_read_reg(struct target_location_ctxt *tlctxt,
999  REG reg,REGVAL *o_regval);
1000 static struct target_location_ctxt_frame *
1001 php_unwind_prev(struct target_location_ctxt *tlctxt);
1002 
1003 static int php_probe_register_symbol(struct target *target,tid_t tid,
1004  struct probe *probe,struct bsymbol *bsymbol,
1005  probepoint_style_t style,
1006  probepoint_whence_t whence,
1007  probepoint_watchsize_t watchsize);
1008 
1009 int php_singlestep(struct target *target,tid_t tid,int isbp,
1010  struct target *overlay);
1011 int php_singlestep_end(struct target *target,tid_t tid,
1012  struct target *overlay);
1013 
1014 
1016  .snprintf = php_snprintf,
1017 
1018  .init = php_init,
1019  .fini = php_fini,
1020  .attach = php_attach,
1021  .detach = php_detach,
1022  .kill = NULL,
1023  .loadspaces = php_loadspaces,
1024  .loadregions = php_loadregions,
1025  .loaddebugfiles = php_loaddebugfiles,
1026  .postloadinit = php_postloadinit,
1027 
1028  /* Don't support overlays at all. */
1029  .instantiate_overlay = NULL,
1030 
1031  .status = php_status,
1032  .pause = php_pause,
1033  .resume = php_resume,
1034  .monitor = NULL,
1035  .poll = NULL,
1036  .read = php_read,
1037  .write = php_write,
1038 
1039  .read_symbol = php_read_symbol,
1040 
1041  .gettid = php_gettid,
1042  .free_thread_state = php_free_thread_state,
1043 
1044  /* There are never any untracked threads in this target. */
1045  .list_available_tids = target_list_tids,
1046  /* There are never any untracked threads in this target. */
1047  .load_available_threads = php_load_all_threads,
1048  .load_thread = php_load_thread,
1049  .load_current_thread = php_load_current_thread,
1050  .load_all_threads = php_load_all_threads,
1051  .pause_thread = NULL,
1052  .flush_thread = php_flush_thread,
1053  .flush_current_thread = php_flush_current_thread,
1054  .flush_all_threads = php_flush_all_threads,
1055  .invalidate_thread = php_invalidate_thread,
1056  .thread_snprintf = php_thread_snprintf,
1057 
1058  .attach_evloop = NULL,
1059  .detach_evloop = NULL,
1060 
1061  .readreg = php_read_reg,
1062  .writereg = php_write_reg,
1063 
1064  .unwind = php_unwind,
1065  .unwind_read_reg = php_unwind_read_reg,
1066  .unwind_prev = php_unwind_prev,
1067 
1068  .probe_register_symbol = php_probe_register_symbol,
1069 
1070  .singlestep = php_singlestep,
1071  .singlestep_end = php_singlestep_end,
1072 };
1073 
1074 static int php_snprintf(struct target *target,char *buf,int bufsiz) {
1075  return snprintf(buf,bufsiz,"php(%d)",target->base_tid);
1076 }
1077 
1078 static int php_init(struct target *target) {
1079  struct php_state *pstate;
1080  struct target_thread *base_thread = target->base_thread;
1081  struct php_thread_state *ptstate;
1082  struct target *base = target->base;
1083  tid_t base_tid = target->base_tid;
1084 
1085  if (target->spec->stay_paused) {
1086  verror("PHP driver cannot leave target process closed on exit!\n");
1087  errno = EINVAL;
1088  return -1;
1089  }
1090 
1091  /*
1092  * Setup target mode stuff.
1093  */
1094  target->threadctl = 0;
1095  target->live = base->live;
1096  target->writeable = base->writeable;
1097  target->mmapable = 0;
1098  /* NB: only native arch supported! i.e., no 32-bit emu on 64-bit host. */
1099  target->arch = base->arch;
1100 
1101  /* Which register is the fbreg is dependent on host cpu type, not
1102  * target cpu type.
1103  */
1104 #if __WORDSIZE == 64
1105  target->fbregno = 6;
1106  target->spregno = 7;
1107  target->ipregno = 16;
1108 #else
1109  target->fbregno = 5;
1110  target->spregno = 4;
1111  target->ipregno = 8;
1112 #endif
1113 
1114  /*
1115  * Make sure the base thread is loaded.
1116  */
1117  if (!(base_thread = target_load_thread(base,base_tid,0))) {
1118  verror("could not load base tid %d!\n",base_tid);
1119  return -1;
1120  }
1121  else if (base_thread != target->base_thread) {
1122  /*
1123  * Catch stale threads; if there is a huge delay between
1124  * target_instantiate and target_open, this could potentially
1125  * happen -- but PID wraparound in the kernel would have to
1126  * happen mighty fast! Unlikely.
1127  */
1128  vwarn("target->base_thread does not match with just-loaded thread"
1129  " for %d; pid wraparound caused stale thread??\n",base_tid);
1130  target->base_thread = base_thread;
1131  }
1132 
1133  /*
1134  * Just adjust for the user, don't error :)
1135  */
1136  if (target->spec->bpmode == THREAD_BPMODE_STRICT) {
1137  vwarn("auto-enabling SEMI_STRICT bpmode on PHP target.\n");
1139  }
1140 
1141  /*
1142  * Initialize our state.
1143  */
1144  target->state = pstate = calloc(1,sizeof(struct php_state));
1145 
1146  target->location_ops = &php_location_ops;
1147 
1148  /*
1149  * XXX: for now, just create a thread for the primary thread.
1150  */
1151  ptstate = calloc(1,sizeof(*ptstate));
1152  ptstate->base_tlctxt =
1153  target_location_ctxt_create(base,target->base_tid,NULL);
1154  target->current_thread = target_create_thread(target,base_tid,ptstate,NULL);
1157 
1158  /*
1159  * Don't do anything else here; do it in attach().
1160  */
1161  return 0;
1162 }
1163 
1164 static int php_fini(struct target *target) {
1165  return 0;
1166 }
1167 
1168 /*
1169  * As described in the notes, first check if ZTS (thread safety) was
1170  * compiled in. If not, everything is very easy. If so, try to find
1171  * the thread-local storage pointer by unwinding the stack and finding
1172  * zend_execute_scripts. If the stack doesn't include this
1173  *
1174  * XXX: eventually, we'll have to check the zend_execute and
1175  * zend_execute_internal pointers and break on those functions instead
1176  * of execute and execute_internal (and in later versions,
1177  * zend_execute_ex and execute_ex) to make sure we catch phps running
1178  * with dtrace or xdebug.
1179  */
1180 static int php_attach(struct target *target) {
1181  struct php_state *pstate = (struct php_state *)target->state;
1182  struct php_thread_state *ptstate;
1183  struct target *base = target->base;
1184  struct bsymbol *bsymbol;
1185  struct symbol *arg;
1186  struct value *v;
1187  struct target_location_ctxt *tlctxt = NULL;
1188  struct target_location_ctxt_frame *tlctxtf = NULL;
1189  struct addrspace *space;
1190  struct memregion *region = NULL;
1191  ADDR derefed_tsrm_ls = 0;
1192 
1193  ptstate = (struct php_thread_state *)target->global_thread->state;
1194 
1195  if (target_pause(base)) {
1196  verror("could not pause base target %s!\n",base->name);
1197  return -1;
1198  }
1199 
1201 
1202  /* Create a default lookup/load context. */
1203  /* Cheat: grab the first region :). */
1204  space = (struct addrspace *)g_list_nth_data(target->spaces,0);
1205  region = (struct memregion *)g_list_nth_data(space->regions,0);
1206 
1207  pstate->default_tlctxt =
1208  target_location_ctxt_create(target,target->base_tid,region);
1209 
1210  /*
1211  * Figure out if this php has ZTS (thread safety) or not.
1212  */
1213  bsymbol = target_lookup_sym(base,"compiler_globals",NULL,NULL,
1215  if (!bsymbol) {
1217  "could not find compiler_globals; checking for ZTS\n");
1218 
1219  bsymbol = target_lookup_sym(base,"compiler_globals_id",NULL,NULL,
1221  if (!bsymbol) {
1222  verror("could not find compiler_globals nor compiler_globals_id;"
1223  " cannot attach to this PHP!\n");
1224  errno = ENOTSUP;
1225  return -1;
1226  }
1227  ptstate->base_tlctxt->region = bsymbol->region;
1229 
1230  tlctxt = target_location_ctxt_create_from_bsymbol(base,target->base_tid,
1231  bsymbol);
1232 
1233  /* We have a threaded php. */
1234  pstate->zts = 1;
1235 
1236  /* Grab the TLS resource ids we need. */
1237  VLS(base,ptstate->base_tlctxt,"compiler_globals_id",LOAD_FLAG_NONE,
1238  &pstate->ztsinfo.CG_id,NULL,errout);
1239  VLS(base,ptstate->base_tlctxt,"executor_globals_id",LOAD_FLAG_NONE,
1240  &pstate->ztsinfo.EG_id,NULL,errout);
1241  }
1242  else {
1243  tlctxt = target_location_ctxt_create_from_bsymbol(base,target->base_tid,
1244  bsymbol);
1245  ptstate->base_tlctxt->region = bsymbol->region;
1246 
1247  pstate->zts = 0;
1248 
1249  /* We will reload these later. */
1250  VLS(base,ptstate->base_tlctxt,"compiler_globals",LOAD_FLAG_NONE,
1251  NULL,&ptstate->CG,errout);
1252  VLS(base,ptstate->base_tlctxt,"executor_globals",LOAD_FLAG_NONE,
1253  NULL,&ptstate->EG,errout);
1254 
1256  }
1257 
1258  /*
1259  * Grab some types.
1260  */
1261  bsymbol = target_lookup_sym(base,"struct _zend_compiler_globals",NULL,NULL,
1263  if (!bsymbol) {
1264  verror("could not lookup struct _zend_compiler_globals; fatal!\n");
1265  return -1;
1266  }
1268  RHOLD(pstate->_zend_compiler_globals_type,pstate);
1270 
1271  bsymbol = target_lookup_sym(base,"struct _zend_executor_globals",NULL,NULL,
1273  if (!bsymbol) {
1274  verror("could not lookup struct _zend_executor_globals; fatal!\n");
1275  return -1;
1276  }
1278  RHOLD(pstate->_zend_executor_globals_type,pstate);
1280 
1281  bsymbol = target_lookup_sym(base,"union _zend_function",NULL,NULL,
1283  if (!bsymbol) {
1284  verror("could not lookup union _zend_function; fatal!\n");
1285  return -1;
1286  }
1288  RHOLD(pstate->zend_function_type,pstate);
1290 
1291  bsymbol = target_lookup_sym(base,"struct _zend_class_entry",NULL,NULL,
1293  if (!bsymbol) {
1294  verror("could not lookup struct _zend_class_entry; fatal!\n");
1295  return -1;
1296  }
1297  /* NB: the things in the class table are pointers to class_entry structs. */
1298  pstate->zend_class_entry_ptr_type =
1300  RHOLD(pstate->zend_class_entry_ptr_type,pstate);
1302 
1303  bsymbol = target_lookup_sym(base,"struct _zval_struct",NULL,NULL,
1305  if (!bsymbol) {
1306  verror("could not lookup struct _zval_struct; fatal!\n");
1307  return -1;
1308  }
1309  /* NB: we need both the struct AND pointers to zval structs. */
1311  RHOLD(pstate->zend_zval_type,pstate);
1312  pstate->zend_zval_ptr_type =
1314  RHOLD(pstate->zend_zval_ptr_type,pstate);
1316 
1317  bsymbol = target_lookup_sym(base,"struct _zend_arg_info",NULL,NULL,
1319  if (!bsymbol) {
1320  verror("could not lookup struct _zend_arg_info; fatal!\n");
1321  return -1;
1322  }
1324  RHOLD(pstate->zend_arg_info_type,pstate);
1326 
1327 
1328 
1329 
1330  bsymbol = target_lookup_sym(base,"zend_do_fcall_common_helper_SPEC",
1331  NULL,NULL,SYMBOL_TYPE_FLAG_FUNC);
1332  if (!bsymbol) {
1333  verror("could not lookup zend_do_fcall_common_helper_SPEC;"
1334  " cannot probe; fatal\n");
1335  return -1;
1336  }
1337  pstate->fprobe_func = bsymbol;
1338  RHOLD(pstate->fprobe_func,pstate);
1340 
1342  "execute_data",NULL);
1343  if (!bsymbol) {
1344  verror("could not lookup zend_do_fcall_common_helper_SPEC.execute_data arg"
1345  "; cannot probe; fatal!\n");
1346  return -1;
1347  }
1349  RHOLD(pstate->fprobe_func_execute_data_arg,pstate);
1351 
1352  bsymbol = target_lookup_sym(base,"zend_leave_helper_SPEC",
1353  NULL,NULL,SYMBOL_TYPE_FLAG_FUNC);
1354  if (!bsymbol) {
1355  verror("could not lookup zend_leave_helper_SPEC;"
1356  " cannot probe; fatal\n");
1357  return -1;
1358  }
1359  pstate->fprobe_func_return = bsymbol;
1360  RHOLD(pstate->fprobe_func_return,pstate);
1362 
1363  /*
1364  * See if we attached to a running PHP (if zend_execute_scripts is
1365  * part of our unwind stack). If so, and if ZTS was compiled in,
1366  * grab our TLS base pointer. Otherwise, insert a probe on
1367  * zend_execute_scripts to know when execution is going to begin.
1368  */
1369  if (target_location_ctxt_unwind(tlctxt)) {
1370  verror("failed to unwind stack to see if php is executing scripts;"
1371  " will probe for execution!\n");
1372  }
1373  else {
1374  tlctxtf = target_location_ctxt_current_frame(tlctxt);
1375  while (tlctxtf) {
1376  if (!bsymbol_get_name(tlctxtf->bsymbol)
1377  || strcmp("zend_execute_scripts",
1378  bsymbol_get_name(tlctxtf->bsymbol))) {
1379  tlctxtf = target_location_ctxt_prev(tlctxt);
1380  continue;
1381  }
1382 
1383  ptstate->is_executing = 1;
1384 
1385  /* If we have ZTS compiled in, grab the TLS base pointer. */
1386  if (pstate->zts) {
1387  arg = symbol_get_member(bsymbol_get_symbol(tlctxtf->bsymbol),
1388  "tsrm_ls",NULL);
1389  if (!arg) {
1390  verror("could not find 'tsrm_ls' arg to '%s'; cannot"
1391  " infer TLS base pointer for PHP thread %d!\n",
1392  bsymbol_get_name(tlctxtf->bsymbol),target->base_tid);
1393  goto errout;
1394  }
1395  v = target_load_symbol_member(base,tlctxt,tlctxtf->bsymbol,
1396  "tsrm_ls",NULL,LOAD_FLAG_NONE);
1397  if (!v) {
1398  verror("could not load 'tsrm_ls' arg to '%s'; cannot"
1399  " infer TLS base pointer for PHP thread %d!\n",
1400  bsymbol_get_name(tlctxtf->bsymbol),target->base_tid);
1401  goto errout;
1402  }
1403 
1404  ptstate->ztsinfo.tsrm_ls = v_addr(v);
1405  value_free(v);
1406 
1407  /* Deref the first pointer to the array. */
1408  if (!target_read_addr(target->base,ptstate->ztsinfo.tsrm_ls,
1409  target->base->arch->ptrsize,
1410  (unsigned char *)&derefed_tsrm_ls)) {
1411  verror("could not read tsrm_ls 0x%"PRIxADDR"!\n",
1412  ptstate->ztsinfo.tsrm_ls);
1413  goto errout;
1414  }
1415 
1417  "tsrm_ls=0x%"PRIxADDR", *tsrm_ls=0x%"PRIxADDR"\n",
1418  ptstate->ztsinfo.tsrm_ls,derefed_tsrm_ls);
1419 
1420  ptstate->ztsinfo.tsrm_ls = derefed_tsrm_ls;
1421  }
1422 
1423  break;
1424  }
1425  }
1426 
1427  if (tlctxt)
1428  target_location_ctxt_free(tlctxt);
1429 
1430  if (ptstate->is_executing && pstate->zts && !ptstate->ztsinfo.tsrm_ls) {
1431  vwarn("PHP thread %d is executing scripts, but could not find"
1432  " tsrm_ls; will look later!\n",target->base_tid);
1433  }
1434  else if (ptstate->is_executing)
1435  php_populate_debugfile(target,pstate->debugfile);
1436 
1437  return 0;
1438 
1439  errout:
1440  if (tlctxt)
1441  target_location_ctxt_free(tlctxt);
1442  return -1;
1443 }
1444 
1445 static int php_detach(struct target *target,int stay_paused) {
1446  /*
1447  * Just detach all our threads.
1448  */
1449  return 0;
1450 }
1451 
1452 static int php_loadspaces(struct target *target) {
1453  addrspace_create(target,"php",target->base_tid);
1454  return 0;
1455 }
1456 
1457 /*
1458  * PHP just has a single region and range. Hm, or should they also have
1459  * ranges for each extension??? Shoot, probably yes. Plus we have to
1460  * technically suck in the heap/stack from the underlying process. Hm,
1461  * maybe we should just sort of clone the underlying one.
1462  *
1463  * No, the right choice is to just have a single region/range that is
1464  * updated to cover the sum of the underlying regions/ranges. Then
1465  * region/range protection is free due to the underlying target.
1466  *
1467  * It's either that or create a single debugfile that is linked to each
1468  * region. Either way, I think the right thing here is to rely on
1469  * the base target's active probing to generate events for us, and
1470  * either grow our mirrored regions/ranges, or expand/reduce the big
1471  * main one.
1472  */
1473 static int php_loadregions(struct target *target,struct addrspace *space) {
1474  struct memregion *region;
1475  struct memrange *range;
1476 
1477  region = memregion_create(space,REGION_TYPE_MAIN,"PHP");
1478  if (!region)
1479  return -1;
1480  /* XXX: use underlying target bounds! */
1481  range = memrange_create(region,0,ADDRMAX,0,
1483  if (!range)
1484  return -1;
1485 
1486  return 0;
1487 }
1488 
1489 /*
1490  * PHP regions have a single debugfile that is dynamically built.
1491  */
1492 static int php_loaddebugfiles(struct target *target,
1493  struct addrspace *space,
1494  struct memregion *region) {
1495  struct php_state *pstate = (struct php_state *)target->state;
1496  struct php_thread_state *gptstate;
1497  struct symbol *builtin_root;
1498  struct symbol *base;
1499  char buf[64];
1500 
1501  vdebug(5,LA_TARGET,LF_PHP,"tid %d\n",target->base_tid);
1502 
1503  pstate->debugfile_symbol_counter = 0;
1504 
1505  php_snprintf(target,buf,sizeof(buf));
1509  if (!pstate->debugfile)
1510  return -1;
1511 
1512  if (target_associate_debugfile(target,region,pstate->debugfile)) {
1513  debugfile_free(pstate->debugfile,1);
1514  return -1;
1515  }
1516 
1517  pstate->base_symbols = calloc(PHP_BASE_SYMBOL_COUNT,sizeof(struct symbol *));
1518 
1519  /*
1520  * Add in the base types into the special __BUILTIN__ file.
1521  */
1522  builtin_root = php_debugfile_add_root(target,pstate->debugfile,"__BUILTIN__");
1523  pstate->builtin_root = builtin_root;
1524 
1526  pstate->debugfile_symbol_counter++,
1528  base->datatype_code = DATATYPE_VOID;
1530  pstate->base_symbols[PHP_BASE_NULL] = base;
1531 
1532  /*
1533  * NB: all values are encoded in PHP's _zval_value union as either
1534  * long, double, str { char *val;int len; }, HashTable *,
1535  * zend_object_value obj. Thus, it is best to make the basic
1536  * numeric types be of size target->wordsize.
1537  */
1538 
1540  pstate->debugfile_symbol_counter++,
1542  base->datatype_code = DATATYPE_BASE;
1544  symbol_set_bytesize(base,target->arch->wordsize);
1546  pstate->base_symbols[PHP_BASE_BOOL] = base;
1547 
1549  pstate->debugfile_symbol_counter++,
1551  base->datatype_code = DATATYPE_BASE;
1553  symbol_set_bytesize(base,target->arch->wordsize);
1555  pstate->base_symbols[PHP_BASE_LONG] = base;
1556 
1558  pstate->debugfile_symbol_counter++,
1560  base->datatype_code = DATATYPE_BASE;
1562  symbol_set_bytesize(base,target->arch->wordsize);
1564  pstate->base_symbols[PHP_BASE_DOUBLE] = base;
1565 
1567  pstate->debugfile_symbol_counter++,
1569  base->datatype_code = DATATYPE_BASE;
1572  pstate->base_symbols[PHP_BASE_STRING] = base;
1573 
1575  pstate->debugfile_symbol_counter++,
1577  base->datatype_code = DATATYPE_BASE;
1580  pstate->base_symbols[PHP_BASE_HASH] = base;
1581 
1582  /*
1583  * If we're already executing, try to populate the debugfile!
1584  */
1585  gptstate = (struct php_thread_state *)target->global_thread->state;
1586  if (gptstate->is_executing)
1587  php_populate_debugfile(target,pstate->debugfile);
1588 
1589  return 0;
1590 }
1591 
1592 static int php_postloadinit(struct target *target) {
1593 
1594  return 0;
1595 }
1596 
1597 static int php_set_active_probing(struct target *target,
1598  active_probe_flags_t flags) {
1599  verror("active probing not supported\n");
1600  errno = ENOTSUP;
1601  return -1;
1602 }
1603 
1604 static target_status_t php_status(struct target *target) {
1605  return target_status(target->base);
1606 }
1607 
1608 static int php_pause(struct target *target,int nowait) {
1609  int rc;
1610 
1611  rc = target_pause(target->base);
1612  if (rc)
1613  return rc;
1614  target_set_status(target,target->base->status);
1615 
1616  return 0;
1617 }
1618 
1619 static int php_resume(struct target *target) {
1620  int rc;
1621 
1622  rc = target_resume(target->base);
1623  if (rc)
1624  return rc;
1625  target_set_status(target,target->base->status);
1626 
1627  return 0;
1628 }
1629 
1630 static unsigned char *php_read(struct target *target,ADDR addr,
1631  unsigned long length,unsigned char *buf) {
1632  return target->base->ops->read(target->base,addr,length,buf);
1633 }
1634 
1635 static unsigned long php_write(struct target *target,ADDR addr,
1636  unsigned long length,unsigned char *buf) {
1637  return target->base->ops->write(target->base,addr,length,buf);
1638 }
1639 
1640 static struct value *php_zval_to_value(struct target *target,
1641  struct target_location_ctxt *tlctxt,
1642  struct value *zval_v,
1643  struct bsymbol *bsymbol) {
1644  struct php_state *pstate;
1645  struct php_thread_state *ptstate;
1646  unsigned char zvtype = 0;
1647  struct value *v = NULL;
1648  struct lsymbol *lsymbol;
1649  //struct symbol *symbol;
1650  //struct symbol *datatype;
1651 
1652  pstate = (struct php_state *)target->state;
1653  ptstate = (struct php_thread_state *)tlctxt->thread->state;
1654 
1655  if (bsymbol) {
1656  lsymbol = bsymbol_get_lsymbol(bsymbol);
1657  //symbol = bsymbol_get_symbol(bsymbol);
1658  //datatype = symbol_get_datatype(symbol);
1659  }
1660  else {
1661  lsymbol = NULL;
1662  //symbol = NULL;
1663  //datatype = NULL;
1664  }
1665 
1666  VLVAR(target->base,ptstate->base_tlctxt,zval_v,"type",
1667  LOAD_FLAG_NONE,&zvtype,errout);
1668 
1669  /*
1670  * Remember, use the zval's datatype, not the symbol's (if any),
1671  * because the zval has dynamic type.
1672  */
1673  if (zvtype == PHP_ZEND_NULL) {
1674  v = value_create_noalloc(tlctxt->thread,NULL,lsymbol,
1675  pstate->base_symbols[zvtype]);
1676  }
1677  else if (zvtype == PHP_ZEND_LONG || zvtype == PHP_ZEND_BOOL) {
1678  v = value_create(tlctxt->thread,NULL,lsymbol,
1679  pstate->base_symbols[zvtype]);
1680  VLVAR(target->base,ptstate->base_tlctxt,zval_v,"value.lval",
1681  LOAD_FLAG_NONE,(unsigned long *)v->buf,errout);
1682  }
1683  else if (zvtype == PHP_ZEND_DOUBLE) {
1684  v = value_create(tlctxt->thread,NULL,lsymbol,
1685  pstate->base_symbols[zvtype]);
1686  VLVAR(target->base,ptstate->base_tlctxt,zval_v,"value.dval",
1687  LOAD_FLAG_NONE,(double *)v->buf,errout);
1688  }
1689  else if (zvtype == PHP_ZEND_STRING) {
1690  int slen;
1691  VLVAR(target->base,ptstate->base_tlctxt,zval_v,"value.str.len",
1692  LOAD_FLAG_NONE,&slen,errout);
1693  if (slen > 4096) {
1694  verror("constant string length %d too big; skipping!\n",slen);
1695  goto errout;
1696  }
1697  else if (slen < 1) {
1698  verror("constant string length %d too small; skipping!\n",slen);
1699  goto errout;
1700  }
1701  ADDR saddr;
1702  VLVAR(target->base,ptstate->base_tlctxt,zval_v,"value.str.val",
1703  LOAD_FLAG_NONE,&saddr,errout);
1704 
1705  v = value_create_noalloc(tlctxt->thread,NULL,lsymbol,
1706  pstate->base_symbols[zvtype]);
1707  v->buf = malloc(slen + 1);
1708  v->bufsiz = slen;
1709  target_read_addr(tlctxt->thread->target,saddr,
1710  (unsigned long)slen,(unsigned char *)v->buf);
1711  v->buf[slen] = '\0';
1712  v->isstring = 1;
1713  }
1714  else {
1715  vwarn("unsupported zval type %d!\n",zvtype);
1716  errno = ENOTSUP;
1717  goto errout;
1718  }
1719 
1720  return v;
1721 
1722  errout:
1723  if (v)
1724  value_free(v);
1725  return NULL;
1726 }
1727 
1728 static struct value *php_read_symbol(struct target *target,
1729  struct target_location_ctxt *tlctxt,
1730  struct bsymbol *bsymbol,
1731  load_flags_t flags) {
1732  struct php_state *pstate;
1733  struct value *zval_v;
1734  struct value *value;
1735  struct symbol *symbol;
1736  char *argslotdata;
1737  int argslot = 0;
1738  int len;
1739  struct value *EG_argument_stack_v = NULL;
1740  ADDR stack_top_addr;
1741  struct php_thread_state *ptstate;
1742  long unsigned int arg_count;
1743  struct symbol *parent;
1744  ADDR final;
1745  struct target *base;
1746  struct target_location_ctxt *base_tlctxt;
1747  struct target_location_ctxt_frame *tlctxtf = NULL;
1748  struct php_target_location_ctxt_frame_state *pfstate = NULL;
1749  struct value *EX_v;
1750 
1751  pstate = (struct php_state *)target->state;
1752  ptstate = (struct php_thread_state *)tlctxt->thread->state;
1753  base = target->base;
1754  base_tlctxt = ptstate->base_tlctxt;
1755 
1756  if (tlctxt->frames) {
1757  tlctxtf = (struct target_location_ctxt_frame *) \
1758  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame);
1759  pfstate = (struct php_target_location_ctxt_frame_state *)tlctxtf->priv;
1760  }
1761 
1762  symbol = bsymbol_get_symbol(bsymbol);
1763  if (!SYMBOL_IS_VAR(symbol) || !symbol_is_parameter(symbol)) {
1764  errno = EINVAL;
1765  goto errout;
1766  }
1767 
1768  /*
1769  * XXX: handle loading in an unwind context!
1770  */
1771 
1772  if (symbol_is_parameter(symbol)) {
1773  parent = symbol_find_parent(symbol);
1774  if (!SYMBOL_IS_FUNC(parent)) {
1775  errno = EINVAL;
1776  goto errout;
1777  }
1778 
1779  /*
1780  * If we're not in a function, we can't load an argument.
1781  *
1782  * XXX: we should also really check to make sure that the called
1783  * function matches the parent :) -- but for now just trust the
1784  * user to do the right thing.
1785  */
1786  if (tlctxtf && tlctxtf->frame > 0) {
1787  if (!pfstate->execute_data_v) {
1788  errno = EINVAL;
1789  goto errout;
1790  }
1791  else
1792  EX_v = pfstate->execute_data_v;
1793  }
1794  else if (!ptstate->current_execute_data_v) {
1795  errno = EINVAL;
1796  goto errout;
1797  }
1798  else
1799  EX_v = ptstate->current_execute_data_v;
1800 
1801  /*
1802  * Grab the number of passed args and see if we can load our
1803  * argslot from them.
1804  */
1805  VLVAR(base,base_tlctxt,EX_v,"opline.extended_value",
1806  LOAD_FLAG_NONE,&arg_count,errout);
1807 
1808  LOCATION_GET_DATA(SYMBOLX_VAR_LOC(symbol),argslotdata,len);
1809  /*
1810  * NB: this is safe because we malloc an int when we store
1811  * argslotdata.
1812  */
1813  memcpy(&argslot,argslotdata,len);
1814  if (argslot < 0) {
1815  verror("BUG: bad argslot %d for function %s!\n",
1816  argslot,symbol_get_name(parent));
1817  errno = EINVAL;
1818  goto errout;
1819  }
1820  else if (argslot >= (int)arg_count) {
1821  if (!SYMBOLX_VAR(symbol) || !SYMBOLX_VAR(symbol)->constval) {
1823  "argslot %d exceeds arg_count %lu for function %s"
1824  " and no default value; exception will be thrown!\n",
1825  argslot,arg_count,symbol_get_name(parent));
1826  errno = EINVAL;
1827  goto errout;
1828  }
1829  else {
1830  /*
1831  * Load constval as the default value.
1832  */
1833  value = value_create_type(tlctxt->thread,NULL,
1834  symbol_get_datatype(symbol));
1835  memcpy(value->buf,SYMBOLX_VAR(symbol)->constval,value->bufsiz);
1836 
1838  "symbol %s: loaded default param value len %d\n",
1839  symbol_get_name(symbol),value->bufsiz);
1840  }
1841  }
1842  else {
1844  "trying to load arg %s in slot %d for function %s\n",
1845  symbol_get_name(symbol),argslot,symbol_get_name(parent));
1846  }
1847 
1848  if (tlctxtf && tlctxtf->frame > 0) {
1849  VLVAR(base,base_tlctxt,EX_v,"function_state.arguments",
1850  LOAD_FLAG_NONE,&stack_top_addr,errout);
1851  }
1852  else {
1853  EG_argument_stack_v =
1854  php_EG(target,tlctxt->thread->tid,"argument_stack");
1855  if (!EG_argument_stack_v) {
1856  verror("could not load argstack!\n");
1857  goto errout;
1858  }
1859 
1860  VLVAR(base,base_tlctxt,EG_argument_stack_v,"top",LOAD_FLAG_NONE,
1861  &stack_top_addr,errout);
1862  }
1863 
1864  /*
1865  * So, we have the argument_stack pointer; we have the number of
1866  * arguments on the stack. Now, for this symbol, get its arg
1867  * index, read the pointer at the index, and load the zval at
1868  * its address, and return!
1869  */
1870  final = 0; // - 8
1871  if (tlctxtf && tlctxtf->frame == 0)
1872  stack_top_addr -= 8;
1873  target_read_addr(base,stack_top_addr - (arg_count - argslot) * base->arch->ptrsize,
1874  base->arch->ptrsize,(unsigned char *)&final);
1875 
1876  zval_v = target_load_type(base,pstate->zend_zval_type,final,
1877  LOAD_FLAG_NONE);
1878  if (!zval_v) {
1879  if (!errno)
1880  errno = EFAULT;
1881  goto errout;
1882  }
1883 
1884  value = php_zval_to_value(target,tlctxt,zval_v,bsymbol);
1885  value_free(zval_v);
1886  }
1887  else if (SYMBOLX_VAR(symbol) && SYMBOLX_VAR(symbol)->constval) {
1888  /*
1889  * Load constval.
1890  */
1891  value = value_create_type(tlctxt->thread,NULL,
1892  symbol_get_datatype(symbol));
1893  memcpy(value->buf,SYMBOLX_VAR(symbol)->constval,value->bufsiz);
1894 
1896  "symbol %s: loaded default const value len %d\n",
1897  symbol_get_name(symbol),value->bufsiz);
1898  }
1899  else {
1900  verror("cannot load var symbol %s; unsupported!\n",
1901  symbol_get_name(symbol));
1902  errno = ENOTSUP;
1903  goto errout;
1904  }
1905 
1906  return value;
1907 
1908  errout:
1909  if (EG_argument_stack_v)
1910  value_free(EG_argument_stack_v);
1911  return NULL;
1912 }
1913 
1914 static tid_t php_gettid(struct target *target) {
1915  struct target_thread *tthread;
1916 
1917  // XXX: fix!
1918  return target->base_tid;
1919 
1920  if (target->current_thread && OBJVALID(target->current_thread))
1921  return target->current_thread->tid;
1922 
1923  tthread = php_load_current_thread(target,0);
1924  if (!tthread) {
1925  verror("could not load current thread to get TID!\n");
1926  return 0;
1927  }
1928 
1929  return tthread->tid;
1930 }
1931 
1932 static void php_free_thread_state(struct target *target,void *state) {
1933  if (state)
1934  free(state);
1935 }
1936 
1937 /*
1938  * XXX:
1939  *
1940  * Need to load/unload any new/stale threads in this function;
1941  * everything calls it, basically. We need to keep a state bit in the
1942  * php_state struct saying if we scanned the list this pass
1943  * yet or not (and we can replace this with active probing, of course).
1944  */
1945 static int __is_our_tid(struct target *target,tid_t tid) {
1946  if (g_hash_table_lookup(target->threads,(gpointer)(uintptr_t)tid))
1947  return 1;
1948  return 0;
1949 }
1950 
1951 /* XXX: obviously, need to reload the tgid list. */
1952 static struct array_list *php_list_available_tids(struct target *target) {
1953  struct array_list *retval;
1954 
1955  retval = array_list_create(1);
1956  array_list_append(retval,(void *)(uintptr_t)target->base_tid);
1957 
1958  return retval;
1959 }
1960 
1961 static struct target_thread *php_load_thread(struct target *target,
1962  tid_t tid,int force) {
1963  if (!target_load_thread(target->base,tid,force))
1964  return NULL;
1965 
1966  return target_lookup_thread(target,tid);
1967 }
1968 
1969 static struct target_thread *
1970 php_load_current_thread(struct target *target,int force) {
1971  struct target_thread *uthread;
1972 
1973  uthread = target_load_current_thread(target->base,force);
1974  if (!uthread) {
1975  verror("could not load base target current thread: %s\n",
1976  strerror(errno));
1977  target->current_thread = NULL;
1978  return NULL;
1979  }
1980 
1981  /* XXX: should we return the primary thread, or NULL? */
1982  if (!__is_our_tid(target,uthread->tid)) {
1984  "base target current tid %d is not in tgid %d!\n",
1985  uthread->tid,target->base_tid);
1986  errno = ESRCH;
1987  target->current_thread = NULL;
1988  return NULL;
1989  }
1990 
1991  target->current_thread = target_lookup_thread(target,uthread->tid);
1992 
1993  return target->current_thread;
1994 }
1995 
1996 /* XXX: need to actually do them all! */
1997 static int php_load_all_threads(struct target *target,int force) {
1998  if (php_load_thread(target,target->base_tid,force))
1999  return 0;
2000  return 1;
2001 }
2002 
2003 static int php_load_available_threads(struct target *target,
2004  int force) {
2005  if (php_load_thread(target,target->base_tid,force))
2006  return 0;
2007  return -1;
2008 }
2009 
2010 static int php_flush_thread(struct target *target,tid_t tid) {
2011  struct target_thread *tthread;
2012 
2013  tthread = target_lookup_thread(target,tid);
2014  if (!OBJDIRTY(tthread))
2015  return 0;
2016 
2017  if (!__is_our_tid(target,tid)) {
2018  verror("tid %d is not in tgid %d!\n",tid,target->base_tid);
2019  errno = ESRCH;
2020  return -1;
2021  }
2022 
2023  /*
2024  rc = target->base->ops->flush_thread(target->base,tid);
2025  if (rc) {
2026  verror("could not flush base target tid %d: %s\n",tid,strerror(errno));
2027  return rc;
2028  }
2029  */
2030 
2031  OBJSCLEAN(tthread);
2032 
2033  return 0;
2034 }
2035 
2036 static int php_flush_current_thread(struct target *target) {
2037  //if (target->current_thread)
2038  // return php_flush_thread(target,target->current_thread->tid);
2039  return 0;
2040 }
2041 
2042 static int php_flush_all_threads(struct target *target) {
2043  return 0; //php_flush_thread(target,target->base_tid);
2044 }
2045 
2046 static int php_invalidate_thread(struct target *target,
2047  struct target_thread *tthread) {
2048  struct php_thread_state *ptstate;
2049 
2050  ptstate = (struct php_thread_state *)tthread->state;
2051 
2052  OBJSINVALID(tthread);
2053 
2054  if (ptstate->current_execute_data_v) {
2056  ptstate->current_execute_data_v = NULL;
2057  }
2058 
2059  return 0;
2060 }
2061 
2062 static int php_thread_snprintf(struct target *target,
2063  struct target_thread *tthread,
2064  char *buf,int bufsiz,
2065  int detail,char *sep,char *kvsep) {
2066  if (!__is_our_tid(target,tthread->tid)) {
2067  verror("tid %d is not in tgid %d!\n",
2068  tthread->tid,tthread->target->base_tid);
2069  errno = ESRCH;
2070  return -1;
2071  }
2072 
2073  return target->base->ops->thread_snprintf(target->base,target->base_thread,
2074  buf,bufsiz,detail,sep,kvsep);
2075 }
2076 
2077 /*
2078  * Meaningless to user, but may as well leave these.
2079  */
2080 static REGVAL php_read_reg(struct target *target,tid_t tid,REG reg) {
2081  return target->base->ops->readreg(target->base,tid,reg);
2082 }
2083 
2084 static int php_write_reg(struct target *target,tid_t tid,REG reg,
2085  REGVAL value) {
2086  return target->base->ops->writereg(target->base,tid,reg,value);
2087 }
2088 
2089 static struct target_location_ctxt *php_unwind(struct target *target,tid_t tid) {
2090  struct target_location_ctxt *tlctxt;
2091  struct target_location_ctxt_frame *tlctxtf;
2092  struct target_thread *tthread;
2093  struct bsymbol *bsymbol;
2094  struct php_state *pstate;
2095  struct php_thread_state *ptstate;
2096  struct php_target_location_ctxt_frame_state *pfstate;
2097  struct value *zend_function_v;
2098  struct target *base;
2099  ADDR zend_function_addr;
2100 
2101  pstate = (struct php_state *)target->state;
2102  base = target->base;
2103  tthread = target_lookup_thread(target,tid);
2104  if (!tthread) {
2105  verror("tid %"PRIiTID" does not exist!\n",tid);
2106  errno = ESRCH;
2107  return NULL;
2108  }
2109  ptstate = (struct php_thread_state *)tthread->state;
2110 
2111  /*
2112  * Load EG(current_execute_data) if not already loaded for this
2113  * thread. Find the symbol. Fix php_read_symbol to read from an
2114  * unwind context.
2115  */
2116  if (!ptstate->current_execute_data_v) {
2117  ptstate->current_execute_data_v =
2118  php_EG(target,tid,"current_execute_data");
2119  if (!ptstate->current_execute_data_v) {
2120  verror("could not load execute_data arg; cannot determine which"
2121  " function is going to execute; skipping!\n");
2122  return RESULT_SUCCESS;
2123  }
2124  }
2125 
2126  zend_function_v = target_load_value_member(base,ptstate->base_tlctxt,
2127  ptstate->current_execute_data_v,
2128  "function_state.function",NULL,
2130  if (!zend_function_v) {
2131  verror("could not load execute_data->function_state.function; cannot"
2132  " determine which function is executing; skipping!\n");
2133  return RESULT_SUCCESS;
2134  }
2135 
2136  zend_function_addr = value_addr(zend_function_v);
2137  value_free(zend_function_v);
2138  zend_function_v = NULL;
2139 
2140  bsymbol = target_lookup_sym_addr(target,zend_function_addr);
2141  if (!bsymbol) {
2142  verror("did not find PHP function symbol for zend_function"
2143  " 0x%"PRIxADDR"; skipping!\n",
2144  zend_function_addr);
2145  return RESULT_SUCCESS;
2146  }
2147 
2149  "unwind starting at '%s'\n",bsymbol_get_name(bsymbol));
2150 
2151  /* Ok, we have enough info to start unwinding. */
2152 
2153  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,bsymbol);
2154  tlctxt->frames = array_list_create(8);
2155 
2156  /*
2157  * Create the 0-th frame (current) (with a per-frame lops_priv).
2158  *
2159  * For each frame we create, its private target_location_ctxt->lctxt
2160  * is just a *ref* to unw->tlctxt->lctxt; this will get fixed
2161  * eventually; for now, see target_unwind_free() for our care in
2162  * handling this.
2163  */
2164  tlctxtf = calloc(1,sizeof(*tlctxtf));
2165  tlctxtf->tlctxt = tlctxt;
2166  tlctxtf->frame = 0;
2167  tlctxtf->bsymbol = bsymbol;
2168  tlctxtf->registers = NULL;
2169 
2170  pfstate = calloc(1,sizeof(*pfstate));
2171  pfstate->execute_data_v = value_clone(ptstate->current_execute_data_v);
2172 
2173  tlctxtf->priv = pfstate;
2174 
2175  array_list_append(tlctxt->frames,tlctxtf);
2176 
2177  return tlctxt;
2178 }
2179 
2180 static int php_unwind_read_reg(struct target_location_ctxt *tlctxt,
2181  REG reg,REGVAL *o_regval) {
2182  errno = ENOTSUP;
2183  return 0;
2184 }
2185 
2186 static struct target_location_ctxt_frame *
2187 php_unwind_prev(struct target_location_ctxt *tlctxt) {
2188  struct target_location_ctxt_frame *tlctxtf;
2189  struct php_target_location_ctxt_frame_state *pfstate;
2190  struct target_location_ctxt_frame *new;
2191  ADDR prev_execute_data_addr;
2192  struct value *prev_execute_data_v = NULL;
2193  struct value *zend_function_v = NULL;
2194  ADDR zend_function_addr;
2195  struct bsymbol *bsymbol = NULL;
2196  struct target *target;
2197  struct target *base;
2198  struct php_thread_state *ptstate;
2199 
2200  target = tlctxt->thread->target;
2201  base = target->base;
2202  ptstate = (struct php_thread_state *)tlctxt->thread->state;
2203 
2204  /* Just return it if it already exists. */
2205  new = (struct target_location_ctxt_frame *) \
2206  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame + 1);
2207  if (new)
2208  return new;
2209 
2210  tlctxtf = (struct target_location_ctxt_frame *) \
2211  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame);
2212  pfstate = (struct php_target_location_ctxt_frame_state *)tlctxtf->priv;
2213 
2214  /*
2215  * Try to load the pointer value of tlctxtf->priv->execute_data_v's
2216  * prev_execute_data member; if it is non-zero, build a new frame!
2217  * Otherwise we're done.
2218  */
2219  VLVAR(base,ptstate->base_tlctxt,pfstate->execute_data_v,"prev_execute_data",
2220  LOAD_FLAG_NONE,&prev_execute_data_addr,errout);
2221 
2222  if (!prev_execute_data_addr) {
2224  "stopping unwind at current frame %d; no prior frames",
2225  tlctxtf->frame);
2226  return NULL;
2227  }
2228 
2229  /*
2230  * Now grab the prev_execute_data value!
2231  */
2232  VLVAL(base,ptstate->base_tlctxt,pfstate->execute_data_v,"prev_execute_data",
2233  LOAD_FLAG_AUTO_DEREF,&prev_execute_data_v,errout);
2234 
2235 
2236  /*
2237  * Now grab the symbol for this execute_data!
2238  */
2239  zend_function_v = target_load_value_member(base,ptstate->base_tlctxt,
2240  prev_execute_data_v,
2241  "function_state.function",NULL,
2243  if (!zend_function_v) {
2244  verror("could not load prev_execute_data->function_state.function; cannot"
2245  " determine which function is executing; stopping unwind!\n");
2246  goto errout;
2247  }
2248 
2249  zend_function_addr = value_addr(zend_function_v);
2250  value_free(zend_function_v);
2251  zend_function_v = NULL;
2252 
2253  bsymbol = target_lookup_sym_addr(target,zend_function_addr);
2254  if (!bsymbol) {
2255  verror("did not find PHP function symbol for zend_function"
2256  " 0x%"PRIxADDR"; stopping unwind!\n",
2257  zend_function_addr);
2258  goto errout;
2259  }
2260 
2261  /*
2262  * Create the i-th frame (current) (with a per-frame lops_priv).
2263  *
2264  * For each frame we create, its private target_location_ctxt->lctxt
2265  * is just a *ref* to tlctxt->tlctxt->lctxt; this will get fixed
2266  * eventually; for now, see target_unwind_free() for our care in
2267  * handling this.
2268  */
2269  new = calloc(1,sizeof(*new));
2270  new->tlctxt = tlctxt;
2271  new->frame = array_list_len(tlctxt->frames);
2272  new->bsymbol = bsymbol;
2273  new->registers = NULL;
2274 
2275  pfstate = calloc(1,sizeof(*pfstate));
2276  pfstate->execute_data_v = prev_execute_data_v;
2277 
2278  new->priv = pfstate;
2279 
2280  array_list_append(tlctxt->frames,new);
2281 
2282  tlctxt->region = bsymbol->region;
2283  ++tlctxt->lctxt->current_frame;
2284 
2286  "unwind created new previous frame %d for function '%s'\n",
2287  tlctxt->lctxt->current_frame,bsymbol_get_name(bsymbol));
2288 
2289  return new;
2290 
2291  errout:
2292  if (bsymbol)
2293  bsymbol_release(bsymbol);
2294  if (zend_function_v)
2295  value_free(zend_function_v);
2296  if (prev_execute_data_v)
2297  value_free(prev_execute_data_v);
2298  //if (new)
2299  // target_location_ctxt_frame_free(new);
2300 
2301  return NULL;
2302 }
2303 
2304 static int php_probe_fini(struct probe *probe) {
2305  struct php_thread_state *ptstate;
2306 
2307  ptstate = (struct php_thread_state *)probe->thread->state;
2308 
2309  if (!ptstate)
2310  return 0;
2311 
2312  if (ptstate->fprobe == probe)
2313  ptstate->fprobe = NULL;
2314  else if (ptstate->fprobe_return == probe)
2315  ptstate->fprobe_return = NULL;
2316  else if (ptstate->vprobe == probe)
2317  ptstate->fprobe = NULL;
2318 
2319  return 0;
2320 }
2321 
2322 static struct probe_ops php_probe_ops = {
2323  .fini = php_probe_fini,
2324 };
2325 
2326 static result_t __php_function_probe_handler(int type,
2327  struct probe *probe,
2328  tid_t tid,void *handler_data,
2329  struct probe *trigger,
2330  struct probe *basep) {
2331  struct probe *ptmp;
2332  GList *list;
2333  int retval = 0;
2334  int rc;
2335  ADDR zend_function_addr;
2336  struct bsymbol *bsymbol;
2337  struct target *target;
2338  struct php_state *pstate;
2339  struct target_thread *tthread;
2340  struct target *base;
2341  struct php_thread_state *ptstate;
2342  struct value *zend_function_v;
2343  struct php_thread_stack_frame *stack_frame;
2344 
2345  target = (struct target *)handler_data;
2346  pstate = (struct php_state *)target->state;
2347  base = probe->target;
2348  tthread = target_lookup_thread(target,probe->thread->tid);
2349  ptstate = (struct php_thread_state *)tthread->state;
2350 
2351  /*
2352  * Check which function is executing (meaning check the addr of the
2353  * zval representing it); if that zval's addr matches one of the
2354  * probes subscribed to us, fire that probe's handlers!
2355  *
2356  * This basically emulates probe_do_sink_(pre|post)_handlers.
2357  */
2358  if (!ptstate->current_execute_data_v) {
2359  ptstate->current_execute_data_v =
2360  target_load_symbol(base,ptstate->base_tlctxt,
2363  if (!ptstate->current_execute_data_v) {
2364  verror("could not load execute_data arg; cannot determine which"
2365  " function is going to execute; skipping!\n");
2366  return RESULT_SUCCESS;
2367  }
2368  }
2369 
2370  zend_function_v = target_load_value_member(base,ptstate->base_tlctxt,
2371  ptstate->current_execute_data_v,
2372  "function_state.function",NULL,
2374  if (!zend_function_v) {
2375  verror("could not load execute_data->function_state.function; cannot"
2376  " determine which function is executing; skipping!\n");
2377  return RESULT_SUCCESS;
2378  }
2379 
2380  zend_function_addr = value_addr(zend_function_v);
2381  value_free(zend_function_v);
2382  zend_function_v = NULL;
2383 
2384  bsymbol = target_lookup_sym_addr(target,zend_function_addr);
2385  if (!bsymbol) {
2386  verror("did not find PHP function symbol for zend_function"
2387  " 0x%"PRIxADDR"; skipping!\n",
2388  zend_function_addr);
2389  return RESULT_SUCCESS;
2390  }
2391 
2393  "bphandler checking '%s'\n",bsymbol_get_name(bsymbol));
2394 
2395  if (probe->sinks) {
2396  vdebug(5,LA_PROBE,LF_PROBE,"");
2398 
2399  list = probe->sinks;
2400  while (list) {
2401  ptmp = (struct probe *)list->data;
2402 
2403  /* Check if this probe matches. */
2404  if (!ptmp->bsymbol || !bsymbol
2405  || bsymbol_get_symbol(ptmp->bsymbol)
2406  != bsymbol_get_symbol(bsymbol))
2407  goto next;
2408 
2409  /*
2410  * Do this stuff regardless of if there's a prehandler or
2411  * not! Why? Because if we do it for the prehandler, we
2412  * have to do it for the posthandler too. Since we can't
2413  * tell if we did it or didn't do it for the prehandler once
2414  * we get to the posthandler, we ALWAYS have to do it!
2415  */
2416  PROBE_SAFE_OP_ARGS(ptmp,values_notify_phase,tid,PHASE_PRE_START);
2417 
2418  /*
2419  * Signal each of the sinks, IF their threads match (thus a
2420  * sink can act as a filter on a thread id.
2421  */
2422  if (ptmp->pre_handler
2423  && (ptmp->thread->tid == TID_GLOBAL
2424  || ptmp->thread->tid == tid)
2425  && probe_filter_check(ptmp,tid,probe,0) == 0) {
2426 
2427  rc = ptmp->pre_handler(ptmp,tid,ptmp->handler_data,probe,basep);
2428  if (rc == RESULT_ERROR) {
2429  probe_disable(ptmp);
2430  retval |= rc;
2431  }
2432  }
2433 
2434  PROBE_SAFE_OP_ARGS(ptmp,values_notify_phase,tid,PHASE_PRE_END);
2435 
2436  next:
2437  list = g_list_next(list);
2438  }
2439  }
2440 
2441  /* Save it on the stack. */
2442  stack_frame = calloc(1,sizeof(*stack_frame));
2443  stack_frame->bsymbol = bsymbol;
2444  stack_frame->current_execute_data_v =
2446  ptstate->stack_frames = g_slist_prepend(ptstate->stack_frames,stack_frame);
2447 
2448  //if (bsymbol)
2449  // bsymbol_release(bsymbol);
2450 
2451  return retval;
2452 }
2453 
2454 static result_t php_function_return_probe_pre_handler(struct probe *probe,
2455  tid_t tid,void *handler_data,
2456  struct probe *trigger,
2457  struct probe *basep) {
2458  struct target *target;
2459  //struct php_state *pstate;
2460  struct target_thread *tthread;
2461  //struct target *base;
2462  struct php_thread_state *ptstate;
2463  struct php_thread_stack_frame *stack_frame;
2464  struct probe *ptmp;
2465  GList *list;
2466  int retval = 0;
2467  int rc;
2468  struct bsymbol *bsymbol;
2469 
2470  target = (struct target *)handler_data;
2471  //pstate = (struct php_state *)target->state;
2472  //base = probe->target;
2473  tthread = target_lookup_thread(target,probe->thread->tid);
2474  ptstate = (struct php_thread_state *)tthread->state;
2475 
2476  if (!ptstate->stack_frames) {
2477  vwarnopt(12,LA_TARGET,LF_PHP,"stack underflow!\n");
2478  return RESULT_SUCCESS;
2479  }
2480 
2481  stack_frame = (struct php_thread_stack_frame *) \
2482  g_slist_nth_data(ptstate->stack_frames,0);
2483  bsymbol = stack_frame->bsymbol;
2484 
2486  "bphandler checking '%s'\n",bsymbol_get_name(bsymbol));
2487 
2488  if (probe->sinks) {
2489  vdebug(5,LA_PROBE,LF_PROBE,"");
2491 
2492  list = probe->sinks;
2493  while (list) {
2494  ptmp = (struct probe *)list->data;
2495 
2496  /* Check if this probe matches. */
2497  if (!ptmp->bsymbol || !bsymbol
2498  || bsymbol_get_symbol(ptmp->bsymbol)
2499  != bsymbol_get_symbol(bsymbol))
2500  goto next;
2501 
2502  PROBE_SAFE_OP_ARGS(ptmp,values_notify_phase,tid,PHASE_POST_START);
2503 
2504  /*
2505  * Signal each of the sinks, IF their threads match (thus a
2506  * sink can act as a filter on a thread id.
2507  */
2508  if (ptmp->post_handler
2509  && (ptmp->thread->tid == TID_GLOBAL
2510  || ptmp->thread->tid == tid)
2511  && probe_filter_check(ptmp,tid,probe,0) == 0) {
2512 
2513  rc = ptmp->post_handler(ptmp,tid,ptmp->handler_data,probe,basep);
2514  if (rc == RESULT_ERROR) {
2515  probe_disable(ptmp);
2516  retval |= rc;
2517  }
2518  }
2519 
2520  PROBE_SAFE_OP_ARGS(ptmp,values_notify_phase,tid,PHASE_POST_END);
2521 
2522  next:
2523  list = g_list_next(list);
2524  }
2525  }
2526 
2527  /*
2528  * Pop it off the stack.
2529  *
2530  * XXX: maybe make sure we're really returning from the top-most
2531  * function on our shadow stack??
2532  *
2533  * XXX: what about exceptions?
2534  */
2535  ptstate->stack_frames = g_slist_remove(ptstate->stack_frames,stack_frame);
2536 
2537  bsymbol_release(stack_frame->bsymbol);
2538  value_free(stack_frame->current_execute_data_v);
2539  free(stack_frame);
2540 
2541  return RESULT_SUCCESS;
2542 }
2543 
2544 static result_t php_function_probe_pre_handler (struct probe *probe,
2545  tid_t tid,void *handler_data,
2546  struct probe *trigger,
2547  struct probe *base) {
2548  volatile result_t ret = __php_function_probe_handler(1,probe,tid,handler_data,trigger,base);
2549  return ret + 0;
2550 }
2551 
2552 static result_t php_function_probe_post_handler(struct probe *probe,
2553  tid_t tid,void *handler_data,
2554  struct probe *trigger,
2555  struct probe *base) {
2556  volatile result_t ret = __php_function_probe_handler(2,probe,tid,handler_data,trigger,base);
2557  return ret + 0;
2558 }
2559 
2560 static int php_insert_function_probes(struct target *target,tid_t tid) {
2561  struct php_state *pstate;
2562  struct php_thread_state *ptstate;
2563  struct target_thread *tthread;
2564  char buf[128];
2565 
2566  pstate = (struct php_state *)target->state;
2567  tthread = target_lookup_thread(target,tid);
2568  if (!tthread) {
2569  verror("tid %"PRIiTID" does not exist!\n",tid);
2570  errno = ESRCH;
2571  return -1;
2572  }
2573  ptstate = (struct php_thread_state *)tthread->state;
2574 
2575  if (ptstate->fprobe)
2576  return 0;
2577 
2578  if (!pstate->fprobe_func) {
2579  verror("no fcall helper symbol; cannot probe!\n");
2580  return -1;
2581  }
2582 
2583  /*
2584  * Insert probes on the underlying target, on the function call
2585  * opcode handler functions. Then subscribe a metaprobe to them,
2586  * save it off in ptstate->fprobe, and be done.
2587  *
2588  * Hm, upon further code analysis, we can more easily probe the
2589  * single 'zend_do_fcall_common_helper_SPEC' helper function, called
2590  * by all those opcodes. That way, more of the function state is
2591  * already setup for us -- it's "closer" to the call site.
2592  */
2593  snprintf(buf,sizeof(buf),"php__%s__%d",
2594  bsymbol_get_name(pstate->fprobe_func),tid);
2595  ptstate->fprobe = probe_create(target->base,tid,&php_probe_ops,buf,
2596  php_function_probe_pre_handler,
2597  php_function_return_probe_pre_handler, //php_function_probe_post_handler,
2598  target,1,1);
2599  if (!ptstate->fprobe)
2600  return -1;
2601  if (!probe_register_symbol(ptstate->fprobe,pstate->fprobe_func,
2602  PROBEPOINT_SW,0,0)) {
2603  probe_free(ptstate->fprobe,0);
2604  ptstate->fprobe = NULL;
2605  return -1;
2606  }
2607 
2608  /*
2609  snprintf(buf,sizeof(buf),"php__%s__%d",
2610  bsymbol_get_name(pstate->fprobe_func),tid);
2611  ptstate->fprobe_return = probe_create(target->base,tid,&php_probe_ops,buf,
2612  php_function_return_probe_pre_handler,
2613  NULL,target,1,1);
2614  if (!ptstate->fprobe_return)
2615  return -1;
2616  if (!probe_register_symbol(ptstate->fprobe_return,
2617  pstate->fprobe_func_return,PROBEPOINT_SW,0,0)) {
2618  probe_free(ptstate->fprobe_return,0);
2619  ptstate->fprobe_return = NULL;
2620  return -1;
2621  }
2622  */
2623 
2624  return 0;
2625 }
2626 
2627 static int php_probe_register_symbol(struct target *target,tid_t tid,
2628  struct probe *probe,struct bsymbol *bsymbol,
2629  probepoint_style_t style,
2630  probepoint_whence_t whence,
2631  probepoint_watchsize_t watchsize) {
2632  struct target_thread *tthread;
2633  struct php_thread_state *ptstate;
2634  struct symbol *symbol;
2635 
2636  tthread = target_lookup_thread(target,tid);
2637  if (!tthread) {
2638  verror("tid %"PRIiTID" does not exist!\n",tid);
2639  errno = ESRCH;
2640  return -1;
2641  }
2642  ptstate = (struct php_thread_state *)tthread->state;
2643 
2644  /*
2645  * Just insert the primary probe(s) if they don't already exist for
2646  * this thread (probe the function call opcode handlers for
2647  * functions; probe the assignment and inc/dec opcode
2648  * handlers/helpers for watchpoints -- and NB we only support
2649  * write watchpoints).
2650  */
2651  symbol = bsymbol_get_symbol(bsymbol);
2652  if (SYMBOL_IS_FUNC(symbol)) {
2653  php_insert_function_probes(target,tid);
2654  }
2655  else if (SYMBOL_IS_VAR(symbol)) {
2656  verror("watchpoints not yet supported!\n");
2657  errno = ENOTSUP;
2658  return -1;
2659  }
2660  else {
2661  verror("cannot probe symbol type '%s'!\n",SYMBOL_TYPE(symbol->type));
2662  errno = ENOTSUP;
2663  return -1;
2664  }
2665 
2666  if (!probe_register_source(probe,ptstate->fprobe))
2667  return -1;
2668 
2669  probe->bsymbol = bsymbol;
2670  RHOLD(bsymbol,probe);
2671 
2672  return 0;
2673 }
2674 
2675 /*
2676  * Single step in php is different; we need to single step the opcode
2677  * execution. What this means is catching the return from that
2678  * function, once we hit a breakpoint. So it doesn't involve the base
2679  * target, *as long as* we can catch the opcode executor assuredly --
2680  * i.e., no long jmps etc.
2681  */
2682 int php_singlestep(struct target *target,tid_t tid,int isbp,
2683  struct target *overlay) {
2684  // XXX
2685 }
2686 
2687 int php_singlestep_end(struct target *target,tid_t tid,
2688  struct target *overlay) {
2689  // XXX
2690 }
2691 
2698  struct target_location_ctxt *tlctxt =
2699  (struct target_location_ctxt *)lctxt->priv;
2700  struct target_location_ctxt_frame *tlctxtf =
2701  target_location_ctxt_get_frame(tlctxt,frame);
2702 
2703  if (!tlctxtf) {
2704  errno = EBADSLT;
2705  return -1;
2706  }
2707 
2708  tlctxt->region = tlctxtf->bsymbol->region;
2709  lctxt->current_frame = frame;
2710  return 0;
2711 }
2712 
2713 struct symbol *__php_location_ops_getsymbol(struct location_ctxt *lctxt) {
2714  struct target_location_ctxt *tlctxt =
2715  (struct target_location_ctxt *)lctxt->priv;
2716  struct target_location_ctxt_frame *tlctxtf =
2718 
2719  return bsymbol_get_symbol(tlctxtf->bsymbol);
2720 }
2721 
2723  struct target_location_ctxt *tlctxt;
2724 
2725  tlctxt = (struct target_location_ctxt *)lctxt->priv;
2726  return tlctxt->thread->target->arch->wordsize;
2727 }
2728 
2730  common_reg_t creg,REG *o_reg) {
2731  errno = ENOTSUP;
2732  return -1;
2733 }
2734 
2736  REG regno,REGVAL *regval) {
2737  errno = ENOTSUP;
2738  return -1;
2739 }
2740 
2742  REG regno,REGVAL regval) {
2743  errno = ENOTSUP;
2744  return -1;
2745 }
2746 
2748  REG regno,REGVAL regval) {
2749  errno = ENOTSUP;
2750  return -1;
2751 }
2752 
2754  errno = ENOTSUP;
2755  return -1;
2756 }
2757 
2759  ADDR real_addr,ADDR *pval) {
2760  struct target_location_ctxt *tlctxt;
2761  unsigned char *rc;
2762 
2763  tlctxt = (struct target_location_ctxt *)lctxt->priv;
2764 
2765  rc = target_read_addr(tlctxt->thread->target,real_addr,
2766  tlctxt->thread->target->arch->ptrsize,(unsigned char *)pval);
2767  if (rc != (unsigned char *)pval) {
2768  verror("could not read 0x%"PRIxADDR": %s!\n",
2769  real_addr,strerror(errno));
2770  return -1;
2771  }
2772 
2773  return 0;
2774 }
2775 
2777  ADDR real_addr,ADDR pval) {
2778  struct target_location_ctxt *tlctxt;
2779  unsigned long rc;
2780 
2781  tlctxt = (struct target_location_ctxt *)lctxt->priv;
2782 
2783  rc = target_write_addr(tlctxt->thread->target,real_addr,
2784  tlctxt->thread->target->arch->ptrsize,
2785  (unsigned char *)&pval);
2786  if (rc != tlctxt->thread->target->arch->ptrsize) {
2787  verror("could not write 0x%"PRIxADDR" to 0x%"PRIxADDR": %s!\n",
2788  pval,real_addr,strerror(errno));
2789  return -1;
2790  }
2791 
2792  return 0;
2793 }
2794 
2796  ADDR obj_addr,ADDR *real_addr) {
2797  *real_addr = obj_addr;
2798  return 0;
2799 }
2800 
2802  ADDR real_addr,ADDR *obj_addr) {
2803  *obj_addr = real_addr;
2804  return 0;
2805 }
2806 
2809  .getsymbol = __php_location_ops_getsymbol,
2810  .readreg = __php_location_ops_readreg,
2811  .writereg = __php_location_ops_writereg,
2812  .cachereg = __php_location_ops_cachereg,
2813  .readipreg = __php_location_ops_readipreg,
2814 
2815  .readword = __php_location_ops_readword,
2816  .writeword = __php_location_ops_writeword,
2817  .relocate = __php_location_ops_relocate,
2818  .unrelocate = __php_location_ops_unrelocate,
2819 
2820  .getregno = __php_location_ops_getregno,
2821  .getaddrsize = __php_location_ops_getaddrsize,
2822 };
struct php_state::@29 ztsinfo
int debugfile_add_type(struct debugfile *debugfile, struct symbol *symbol)
Definition: debug.c:2300
#define OBJSCLEAN(obj)
Definition: object.h:116
int debugfile_insert_root(struct debugfile *debugfile, struct symbol *symbol)
Definition: debug.c:1891
#define PHP_UTIL_ZEND_HASH_APPLY_STOP
Definition: target_php.c:315
int symbol_insert_symbol(struct symbol *parent, struct symbol *child)
Definition: debug.c:2758
struct value * target_load_symbol(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, load_flags_t flags)
Definition: target.c:3270
struct value * target_load_type(struct target *target, struct symbol *type, ADDR addr, load_flags_t flags)
Definition: target.c:2653
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
#define PHP_UTIL_ZEND_HASH_APPLY_SAVE
Definition: target_php.c:314
struct value * value_create_noalloc(struct target_thread *thread, struct memrange *range, struct lsymbol *lsymbol, struct symbol *type)
Definition: value.c:153
struct symbol * symbol_find_parent(struct symbol *symbol)
Definition: debug.c:3106
int __php_location_ops_getregno(struct location_ctxt *lctxt, common_reg_t creg, REG *o_reg)
Definition: target_php.c:2729
struct probe * vprobe
Definition: target_php.h:65
struct target * base
Definition: target_api.h:2654
struct symbol * zend_arg_info_type
Definition: target_php.h:127
void * state
Definition: target_api.h:2526
struct symbol * current_symbol
Definition: target_php.c:425
int debugfile_symbol_counter
Definition: target_php.h:119
struct bsymbol * fprobe_func
Definition: target_php.h:129
thread_bpmode_t bpmode
Definition: target_api.h:2211
struct value * EG
Definition: target_php.h:61
struct value * current_execute_data_v
Definition: target_php.h:36
probe_handler_t pre_handler
Definition: probe.h:350
unsigned char *(* read)(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2953
int32_t tid_t
Definition: common.h:36
unsigned int ptrsize
Definition: arch.h:122
void symbol_set_bytesize(struct symbol *s, uint32_t b)
Definition: debug.c:3219
struct array_list * frames
Definition: target_api.h:2396
REFCNT lsymbol_release(struct lsymbol *lsymbol)
Definition: debug.c:4805
struct debugfile * debugfile
Definition: target_php.h:108
target_status_t
Definition: target_api.h:197
#define VLS(target, tlctxt, varstr, loadflags, outvarptr, outvalueptr, errlabel)
Definition: target_api.h:1677
common_reg_t
Definition: arch.h:73
int symbol_set_constval(struct symbol *symbol, void *value, int len, int copy)
Definition: debug.c:3429
struct memregion * region
Definition: target_api.h:2391
int(* php_util_zend_hash_apply_func_t)(struct target *target, struct target_location_ctxt *tlctxt, struct value *k, struct value *v, void *priv)
Definition: target_php.c:316
struct symbol * symbol_create(symbol_type_t symtype, symbol_source_t source, char *name, int name_copy, SMOFFSET offset, load_type_t loadtype, struct scope *scope)
Definition: debug.c:2550
int __php_location_ops_readword(struct location_ctxt *lctxt, ADDR real_addr, ADDR *pval)
Definition: target_php.c:2758
struct scope * symbol_read_owned_scope(struct symbol *symbol)
Definition: debug.c:2674
int __php_location_ops_readipreg(struct location_ctxt *lctxt, REGVAL *regval)
Definition: target_php.c:2753
Definition: log.h:190
GList * sinks
Definition: probe.h:387
struct symbol ** base_symbols
Definition: target_php.h:121
#define PHP_UTIL_ZEND_HASH_APPLY_FREE
Definition: target_php.c:313
static uint64_t unsigned int i
struct bsymbol * target_lookup_sym(struct target *target, const char *name, const char *delim, char *srcfile, symbol_type_flag_t ftype)
Definition: target.c:2199
int __php_location_ops_getaddrsize(struct location_ctxt *lctxt)
Definition: target_php.c:2722
struct symbol * _zend_executor_globals_type
Definition: target_php.h:134
#define VLV(target, tlctxt, invalue, varstr, loadflags, outvarptr, outvalueptr, errlabel)
Definition: target_api.h:1739
int target_resume(struct target *target)
Definition: target_api.c:1012
struct target_location_ctxt * target_location_ctxt_create_from_bsymbol(struct target *target, tid_t tid, struct bsymbol *bsymbol)
Definition: target.c:5325
struct bsymbol * bsymbol
Definition: target_php.h:35
probepoint_whence_t
Definition: probe_api.h:234
struct symbol * __php_location_ops_getsymbol(struct location_ctxt *lctxt)
Definition: target_php.c:2713
#define PHP_ZEND_STRING
Definition: target_php.h:78
struct target_thread * base_thread
Definition: target_api.h:2655
struct target_location_ctxt * tlctxt
Definition: target_api.h:2403
struct php_spec * php_build_spec(void)
Definition: target_php.c:938
void php_free_spec(struct php_spec *spec)
Definition: target_php.c:946
int target_pause(struct target *target)
Definition: target_api.c:1027
struct target * target
Definition: target_php.c:423
ADDR symbol_get_addr(struct symbol *symbol)
Definition: debug.c:3096
struct target_thread * global_thread
Definition: target_api.h:2685
int __php_location_ops_writereg(struct location_ctxt *lctxt, REG regno, REGVAL regval)
Definition: target_php.c:2741
#define PHP_ZEND_DOUBLE
Definition: target_php.h:74
uint32_t symbol_get_bytesize(struct symbol *symbol)
Definition: debug.c:3065
struct probe * fprobe
Definition: target_php.h:63
#define PHP_ZEND_INTERNAL_CLASS
Definition: target_php.c:724
void symbol_set_srcline(struct symbol *s, int sl)
Definition: debug.c:3194
char * bsymbol_get_name(struct bsymbol *bsymbol)
Definition: symbol.c:62
int php_singlestep_end(struct target *target, tid_t tid, struct target *overlay)
Definition: target_php.c:2687
#define PHP_ZEND_INTERNAL_FUNCTION
Definition: target_php.c:452
int target_associate_debugfile(struct target *target, struct memregion *region, struct debugfile *debugfile)
Definition: target.c:1993
uint8_t stay_paused
Definition: target_api.h:2213
int(* writereg)(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.h:3064
#define verror(format,...)
Definition: log.h:30
int symbol_is_parameter(struct symbol *symbol)
Definition: debug.c:3035
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1053
int bufsiz
Definition: target_api.h:3297
int __php_location_ops_cachereg(struct location_ctxt *lctxt, REG regno, REGVAL regval)
Definition: target_php.c:2747
struct symbol * _zend_compiler_globals_type
Definition: target_php.h:133
struct symbol * symbol_get_datatype(struct symbol *symbol)
Definition: debug.c:2989
struct symbol * builtin_root
Definition: target_php.h:120
#define SYMBOLX_VAR_LOC(sym)
int __php_location_ops_setcurrentframe(struct location_ctxt *lctxt, int frame)
Definition: target_php.c:2697
symbol_type_t type
Definition: dwdebug_priv.h:833
struct lsymbol * debugfile_lookup_addr(struct debugfile *debugfile, ADDR addr)
Definition: debug.c:667
#define OBJSINVALID(obj)
Definition: object.h:106
uint32_t mmapable
Definition: target_api.h:2465
struct memregion * memregion_create(struct addrspace *space, region_type_t type, char *name)
Definition: memory.c:242
#define vwarn(format,...)
Definition: log.h:33
uint32_t threadctl
Definition: target_api.h:2465
#define ADDRMAX
Definition: common.h:74
void free(void *ptr)
Definition: debugserver.c:207
struct target_location_ctxt_frame * target_location_ctxt_get_frame(struct target_location_ctxt *tlctxt, int frame)
Definition: target.c:5742
int(* thread_snprintf)(struct target *target, struct target_thread *tthread, char *buf, int bufsiz, int detail, char *sep, char *key_val_sep)
Definition: target_api.h:3007
#define LOCATION_GET_DATA(loc, buf, buflen)
Definition: dwdebug_priv.h:633
enum php_base_symbol php_base_symbol_t
struct target_thread * target_load_thread(struct target *target, tid_t tid, int force)
Definition: target_api.c:1311
struct probe * probe_register_source(struct probe *sink, struct probe *src)
Definition: probe.c:1593
int symbol_set_encoding(struct symbol *symbol, encoding_t num)
Definition: debug.c:3332
struct memrange * memrange_create(struct memregion *region, ADDR start, ADDR end, OFFSET offset, unsigned int prot_flags)
Definition: memory.c:538
int __php_location_ops_unrelocate(struct location_ctxt *lctxt, ADDR real_addr, ADDR *obj_addr)
Definition: target_php.c:2801
int __php_location_ops_writeword(struct location_ctxt *lctxt, ADDR real_addr, ADDR pval)
Definition: target_php.c:2776
#define PHP_ZEND_USER_FUNCTION
Definition: target_php.c:453
struct target_thread * target_load_current_thread(struct target *target, int force)
Definition: target_api.c:1305
uint8_t isstring
Definition: target_api.h:3300
int symbol_set_location(struct symbol *symbol, struct location *loc)
Definition: debug.c:3365
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
struct target_thread * current_thread
Definition: target_api.h:2680
datatype_code_t datatype_code
Definition: dwdebug_priv.h:827
REFCNT debugfile_free(struct debugfile *debugfile, int force)
Definition: debug.c:2384
#define OBJDIRTY(obj)
Definition: object.h:80
struct symbol * zend_function_type
Definition: target_php.h:123
struct array_list * target_list_tids(struct target *target)
Definition: target_api.c:1210
probepoint_watchsize_t
Definition: probe_api.h:241
tid_t base_tid
Definition: target_api.h:2657
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
struct addrspace * space
Definition: target.h:937
struct target_location_ctxt_frame * target_location_ctxt_prev(struct target_location_ctxt *tlctxt)
Definition: target.c:5812
char * buf
Definition: target_api.h:3298
int value_refresh(struct value *value, int recursive)
Definition: value.c:329
uint32_t live
Definition: target_api.h:2465
GHashTable * threads
Definition: target_api.h:2672
int(* fini)(struct probe *probe)
Definition: probe_api.h:187
#define LOGDUMPPROBE_NL(dl, la, lt, p)
Definition: probe.h:73
#define VLVAR(target, tlctxt, invalue, varstr, loadflags, outvarptr, errlabel)
Definition: target_api.h:1782
struct value * value_create_type(struct target_thread *thread, struct memrange *range, struct symbol *type)
Definition: value.c:102
void value_free(struct value *value)
Definition: value.c:282
int location_set_runtime(struct location *l, char *data, int len, int nocopy)
Definition: location.c:164
struct value * target_load_value_member(struct target *target, struct target_location_ctxt *tlctxt, struct value *old_value, const char *member, const char *delim, load_flags_t flags)
Definition: target.c:2942
#define PHP_ZEND_TYPE_IS_BASE(type)
Definition: target_php.h:94
#define SYMBOLX_VAR(sym)
struct bsymbol * target_lookup_sym_addr(struct target *target, ADDR addr)
Definition: target.c:2093
int target_location_ctxt_unwind(struct target_location_ctxt *tlctxt)
Definition: target.c:5417
#define PROT_EXEC
Definition: common.h:108
int debugfile_add_global(struct debugfile *debugfile, struct symbol *symbol)
Definition: debug.c:2262
struct debugfile * debugfile_create_basic(debugfile_type_t dtype, debugfile_type_flags_t dtflags, char *filename, struct debugfile_load_opts *opts)
Definition: debug.c:1298
int len
Definition: dumptarget.c:52
struct value * value_clone(struct value *in)
Definition: value.c:195
#define RHOLD(x, hx)
Definition: common.h:622
#define PROBE_SAFE_OP_ARGS(probe, op,...)
Definition: probe.h:31
#define PROT_WRITE
Definition: common.h:107
void symbol_set_addr(struct symbol *s, ADDR a)
Definition: debug.c:3276
Definition: probe.h:308
GList * spaces
Definition: target_api.h:2643
#define PHP_ZEND_NULL
Definition: target_php.h:72
struct probe * probe_create(struct target *target, tid_t tid, struct probe_ops *pops, const char *name, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data, int autofree, int tracked)
Definition: probe.c:729
struct target_thread * thread
Definition: probe.h:343
Definition: log.h:170
struct target_ops php_ops
Definition: target_php.c:1015
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
ADDR v_addr(struct value *v)
Definition: value.c:429
FILE * stream
Definition: output.h:26
struct symbol * zend_zval_type
Definition: target_php.h:125
int(* setcurrentframe)(struct location_ctxt *lctxt, int frame)
Definition: dwdebug_priv.h:673
#define OBJVALID(obj)
Definition: object.h:76
struct target_location_ctxt_frame * target_location_ctxt_current_frame(struct target_location_ctxt *tlctxt)
Definition: target.c:5748
struct arch * arch
Definition: target_api.h:2603
struct location * location_create(void)
Definition: location.c:39
unsigned int wordsize
Definition: arch.h:121
GHashTable * php_zhash_to_ghash(struct target *target, struct value *zhash)
struct value * value_create(struct target_thread *thread, struct memrange *range, struct lsymbol *lsymbol, struct symbol *type)
Definition: value.c:138
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
#define VLVAL(target, tlctxt, invalue, varstr, loadflags, outvalueptr, errlabel)
Definition: target_api.h:1814
GSList * stack_frames
Definition: target_php.h:43
void target_thread_set_status(struct target_thread *tthread, thread_status_t status)
Definition: target.c:4041
struct target * target
Definition: target_api.h:2078
int __php_location_ops_relocate(struct location_ctxt *lctxt, ADDR obj_addr, ADDR *real_addr)
Definition: target_php.c:2795
Definition: log.h:70
int probe_disable(struct probe *probe)
Definition: probe.c:1811
struct bsymbol * fprobe_func_execute_data_arg
Definition: target_php.h:130
struct debugfile * debugfile
Definition: target_php.c:424
result_t
Definition: common.h:25
struct symbol * debugfile_lookup_root_name(struct debugfile *debugfile, char *name)
Definition: debug.c:1978
uint32_t REGVAL
Definition: common.h:66
int php_singlestep(struct target *target, tid_t tid, int isbp, struct target *overlay)
Definition: target_php.c:2682
Definition: log.h:71
int __php_location_ops_readreg(struct location_ctxt *lctxt, REG regno, REGVAL *regval)
Definition: target_php.c:2735
target_status_t target_status(struct target *target)
Definition: target_api.c:1046
#define PRIiTID
Definition: common.h:37
char * v_string(struct value *v)
Definition: value.c:430
void target_reuse_thread_as_global(struct target *target, struct target_thread *thread)
Definition: target.c:4105
int8_t REG
Definition: common.h:93
#define symbol_set_parameter(s)
struct lsymbol * bsymbol_get_lsymbol(struct bsymbol *bsymbol)
Definition: symbol.c:70
probepoint_style_t
Definition: probe_api.h:228
struct target_location_ctxt * target_location_ctxt_create(struct target *target, tid_t tid, struct memregion *region)
Definition: target.c:5304
struct location_ops php_location_ops
Definition: target_php.c:2807
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
struct target * target
Definition: probe.h:342
#define vwarnc(format,...)
Definition: log.h:35
Definition: log.h:174
uint32_t ADDR
Definition: common.h:64
struct php_thread_state::@28 ztsinfo
char * name
Definition: target_api.h:2521
struct target_ops * ops
Definition: target_api.h:2548
struct symbol * type
Definition: target_api.h:3287
struct value * php_zhash_find(struct target *target, struct value *zhash, char *key, struct symbol *type)
REG spregno
Definition: target_api.h:2507
#define PHP_ZEND_LONG
Definition: target_php.h:73
target_status_t status
Definition: target_api.h:2503
#define PROT_READ
Definition: common.h:106
unsigned int is_executing
Definition: target_php.h:40
struct symbol * symbol_get_member(struct symbol *symbol, char *memberlist, const char *delim)
Definition: debug.c:4136
struct target_location_ctxt * base_tlctxt
Definition: target_php.h:54
struct value * target_load_symbol_member(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, const char *member, const char *delim, load_flags_t flags)
Definition: target.c:2920
REG fbregno
Definition: target_api.h:2506
#define PRIxADDR
Definition: common.h:67
void target_location_ctxt_free(struct target_location_ctxt *tlctxt)
Definition: target.c:5348
char * SYMBOL_TYPE(int n)
Definition: debug.c:5662
#define PHP_ZEND_USER_CLASS
Definition: target_php.c:725
GHashTable * addresses
Definition: dwdebug.h:965
int(* snprintf)(struct target *target, char *buf, int bufsiz)
Definition: target_api.h:2798
struct value * current_execute_data_v
Definition: target_php.h:42
struct symbol * target_create_synthetic_type_pointer(struct target *target, struct symbol *type)
Definition: symbol.c:27
struct target_spec * spec
Definition: target_api.h:2605
int probe_filter_check(struct probe *probe, tid_t tid, struct probe *trigger, int whence)
Definition: probe_filter.c:35
struct bsymbol * bsymbol
Definition: probe.h:389
struct bsymbol * fprobe_func_return
Definition: target_php.h:131
load_flags_t
Definition: target_api.h:406
struct bsymbol * bsymbol
Definition: target_api.h:2415
char * symbol_get_name(struct symbol *symbol)
Definition: debug.c:2587
REGVAL(* readreg)(struct target *target, tid_t tid, REG reg)
Definition: target_api.h:3063
active_probe_flags_t
Definition: target_api.h:432
struct location_ops * location_ops
Definition: target_api.h:2549
struct symbol_root * root
Definition: dwdebug_priv.h:973
void * malloc(size_t size)
Definition: debugserver.c:214
#define PHP_BASE_SYMBOL_COUNT
Definition: target_php.h:92
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:4023
void target_set_status(struct target *target, target_status_t status)
Definition: target.c:4035
struct target_thread * thread
Definition: target_api.h:2383
unsigned long(* write)(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2956
unsigned long target_write_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1060
void debugfile_dump(struct debugfile *debugfile, struct dump_info *ud, int types, int globals, int symtabs, int elfsymtab, int doranges)
Definition: debug.c:4907
void * handler_data
Definition: probe.h:359
struct probe * fprobe_return
Definition: target_php.h:64
struct bsymbol * target_lookup_sym_member(struct target *target, struct bsymbol *bsymbol, const char *name, const char *delim)
Definition: target.c:2248
#define PHP_ZEND_BOOL
Definition: target_php.h:75
struct target_location_ctxt * default_tlctxt
Definition: target_php.h:102
struct probe * probe_register_symbol(struct probe *probe, struct bsymbol *bsymbol, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe.c:1470
#define SYMBOL_IS_FUNC(sym)
struct value * CG
Definition: target_php.h:60
struct target_thread * target_create_thread(struct target *target, tid_t tid, void *tstate, void *tpstate)
Definition: target.c:4063
struct symbol * zend_class_entry_ptr_type
Definition: target_php.h:124
ADDR value_addr(struct value *value)
Definition: value.c:302
REG ipregno
Definition: target_api.h:2508
struct location_ctxt * lctxt
Definition: target_api.h:2377
struct symbol * zend_zval_ptr_type
Definition: target_php.h:126
unsigned int zts
Definition: target_php.h:100
probe_handler_t post_handler
Definition: probe.h:354
struct symbol * datatype
Definition: dwdebug_priv.h:925
#define TID_GLOBAL
Definition: target_api.h:145
struct memregion * region
Definition: target.h:1020
#define SYMBOL_IS_VAR(sym)
GList * regions
Definition: target.h:909
struct addrspace * addrspace_create(struct target *target, char *name, ADDR tag)
Definition: memory.c:41
uint32_t writeable
Definition: target_api.h:2465