From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13024 invoked by alias); 18 Mar 2009 13:14:49 -0000 Received: (qmail 13008 invoked by uid 22791); 18 Mar 2009 13:14:43 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL,BAYES_50,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from ti-out-0910.google.com (HELO ti-out-0910.google.com) (209.85.142.184) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 18 Mar 2009 13:14:35 +0000 Received: by ti-out-0910.google.com with SMTP id a1so29686tib.12 for ; Wed, 18 Mar 2009 06:14:31 -0700 (PDT) MIME-Version: 1.0 Received: by 10.110.92.8 with SMTP id p8mr1913682tib.56.1237382071554; Wed, 18 Mar 2009 06:14:31 -0700 (PDT) In-Reply-To: References: <200903092034.57367.pedro@codesourcery.com> Date: Wed, 18 Mar 2009 13:54:00 -0000 Message-ID: Subject: Re: [RFA] Submit process record and replay third time, 3/9 From: teawater To: Pedro Alves Cc: gdb-patches@sourceware.org, Marc Khouzam , Michael Snyder Content-Type: multipart/mixed; boundary=0016e652fa26d398870465647661 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00376.txt.bz2 --0016e652fa26d398870465647661 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-length: 67776 This is the patches updated follow cvs head. Thanks, Hui On Wed, Mar 18, 2009 at 21:11, teawater wrote: > Hi Pedro, > > I make a new patch according to your mail. > Please help me review it. > > Thanks, > Hui > > On Tue, Mar 10, 2009 at 04:34, Pedro Alves wrote: >> On Monday 23 February 2009 09:20:13, teawater wrote: >>> This is the new version patches that follow cvs-head. >> >> Thanks. >> >>> >>> =A0gdb/Makefile.in | =A0 =A04 >>> =A0gdb/record.c =A0 =A0| 1283 +++++++++++++++++++++++++++++++++++++++++= +++++++++++++++ >>> =A0gdb/record.h =A0 =A0| =A0 87 +++ >>> =A03 files changed, 1372 insertions(+), 2 deletions(-) >>> >>> Index: src/gdb/Makefile.in >>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>> --- src.orig/gdb/Makefile.in =A02009-02-21 15:53:27.000000000 +0000 >>> +++ src/gdb/Makefile.in =A0 =A0 =A0 2009-02-28 20:23:20.000000000 +0000 >>> @@ -662,7 +662,7 @@ SFILES =3D ada-exp.y ada-lang.c ada-typepr >>> =A0 =A0 =A0 valarith.c valops.c valprint.c value.c varobj.c vec.c \ >>> =A0 =A0 =A0 wrapper.c \ >>> =A0 =A0 =A0 xml-tdesc.c xml-support.c \ >>> - =A0 =A0 inferior.c >>> + =A0 =A0 inferior.c record.c >>> >>> =A0LINTFILES =3D $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c >>> >>> @@ -813,7 +813,7 @@ COMMON_OBS =3D $(DEPFILES) $(CONFIG_OBS) $ >>> =A0 =A0 =A0 solib.o solib-null.o \ >>> =A0 =A0 =A0 prologue-value.o memory-map.o xml-support.o \ >>> =A0 =A0 =A0 target-descriptions.o target-memory.o xml-tdesc.o xml-built= in.o \ >>> - =A0 =A0 inferior.o osdata.o >>> + =A0 =A0 inferior.o osdata.o record.o >>> >>> =A0TSOBS =3D inflow.o >>> >>> Index: src/gdb/record.c >>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>> --- /dev/null 1970-01-01 00:00:00.000000000 +0000 >>> +++ src/gdb/record.c =A02009-02-28 20:23:20.000000000 +0000 >>> @@ -0,0 +1,1283 @@ >>> +/* Process record and replay target for GDB, the GNU debugger. >>> + >>> + =A0 Copyright (C) 2008 Free Software Foundation, Inc. >> >> Oops, you'll have to update this. >> >>> + >>> + =A0 This file is part of GDB. >>> + >>> + =A0 This program is free software; you can redistribute it and/or mod= ify >>> + =A0 it under the terms of the GNU General Public License as published= by >>> + =A0 the Free Software Foundation; either version 3 of the License, or >>> + =A0 (at your option) any later version. >>> + >>> + =A0 This program is distributed in the hope that it will be useful, >>> + =A0 but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + =A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =A0See the >>> + =A0 GNU General Public License for more details. >>> + >>> + =A0 You should have received a copy of the GNU General Public License >>> + =A0 along with this program. =A0If not, see . =A0*/ >>> + >>> +#include "defs.h" >>> +#include "target.h" >>> +#include "gdbcmd.h" >>> +#include "regcache.h" >>> +#include "inferior.h" >>> +#include "gdbthread.h" >>> +#include "event-top.h" >>> +#include "annotate.h" >>> +#include "observer.h" >>> +#include "record.h" >> >> Why did you need annotate.h? =A0Can you check which headers are >> really needed here? >> >>> + >>> +#include >>> + >>> +#define DEFAULT_RECORD_INSN_MAX_NUM =A0200000 >>> + >>> +int record_debug =3D 0; >>> + >>> +record_t record_first; >>> +record_t *record_list =3D &record_first; >>> +record_t *record_arch_list_head =3D NULL; >>> +record_t *record_arch_list_tail =3D NULL; >>> +struct regcache *record_regcache =3D NULL; >>> + >>> +/* 1 ask user. 0 auto delete the last record_t. =A0*/ >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ^ double-space please. >> >>> +static int record_stop_at_limit =3D 1; >>> +static int record_insn_max_num =3D DEFAULT_RECORD_INSN_MAX_NUM; >>> +static int record_insn_num =3D 0; >>> + >>> +struct target_ops record_ops; >>> +static int record_resume_step =3D 0; >>> +static enum target_signal record_resume_siggnal; >>> +static int record_get_sig =3D 0; >>> +static sigset_t record_maskall; >>> +static int record_gdb_operation_disable =3D 0; >>> +int record_will_store_registers =3D 0; >> >> You've got a bunch of magic variables here. =A0Could you >> add some comments explaining what they're for? >> >>> + >>> +extern struct bp_location *bp_location_chain; >> >> This is not right. =A0You're accessing a breakpoints.c >> internal implementation detail. =A0We need to come up with interfaces >> to replace this hack. >> >>> + >>> +/* The beneath function pointers. =A0*/ >>> +static struct target_ops *record_beneath_to_resume_ops =3D NULL; >>> +static void (*record_beneath_to_resume) (struct target_ops *, ptid_t, = int, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 enum target_signal) =3D NULL; >>> +static struct target_ops *record_beneath_to_wait_ops =3D NULL; >>> +static ptid_t (*record_beneath_to_wait) (struct target_ops *, ptid_t, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0struct target_waitstatus *) =3D NULL; >>> +static struct target_ops *record_beneath_to_store_registers_ops =3D NU= LL; >>> +static void (*record_beneath_to_store_registers) (struct target_ops *, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct regcache *, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 int regno) =3D NULL; >>> +static struct target_ops *record_beneath_to_xfer_partial_ops =3D NULL; >>> +static LONGEST (*record_beneath_to_xfer_partial) (struct target_ops * = ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 enum target_object object, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 const char *annex, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 gdb_byte * readbuf, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 const gdb_byte * writebuf, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 ULONGEST offset, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 LONGEST len) =3D NULL; >>> +static int (*record_beneath_to_insert_breakpoint) (struct bp_target_in= fo *) =3D >>> + =A0NULL; >>> +static int (*record_beneath_to_remove_breakpoint) (struct bp_target_in= fo *) =3D >>> + =A0NULL; >> >> I can't say I'm happy with this mechanism yet, but it is much >> better than the previous version of making target.c aware of record.c's = callbacks. >> >> >>> + >>> +static void >>> +record_list_release (record_t * rec) >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0^ no = space after *, please. >> >>> +{ >>> + =A0record_t *tmp; >>> + >>> + =A0if (!rec) >>> + =A0 =A0return; >>> + >>> + =A0while (rec->next) >>> + =A0 =A0{ >>> + =A0 =A0 =A0rec =3D rec->next; >>> + =A0 =A0} >>> + >>> + =A0while (rec->prev) >>> + =A0 =A0{ >>> + =A0 =A0 =A0tmp =3D rec; >>> + =A0 =A0 =A0rec =3D rec->prev; >>> + =A0 =A0 =A0if (tmp->type =3D=3D record_reg) >>> + =A0 =A0 xfree (tmp->u.reg.val); >>> + =A0 =A0 =A0else if (tmp->type =3D=3D record_mem) >>> + =A0 =A0 xfree (tmp->u.mem.val); >>> + =A0 =A0 =A0xfree (tmp); >>> + =A0 =A0} >>> + >>> + =A0if (rec !=3D &record_first) >>> + =A0 =A0xfree (rec); >>> +} >>> + >>> +static void >>> +record_list_release_next (void) >>> +{ >>> + =A0record_t *rec =3D record_list; >>> + =A0record_t *tmp =3D rec->next; >>> + =A0rec->next =3D NULL; >>> + =A0while (tmp) >>> + =A0 =A0{ >>> + =A0 =A0 =A0rec =3D tmp->next; >>> + =A0 =A0 =A0if (tmp->type =3D=3D record_reg) >>> + =A0 =A0 record_insn_num--; >>> + =A0 =A0 =A0else if (tmp->type =3D=3D record_reg) >>> + =A0 =A0 xfree (tmp->u.reg.val); >>> + =A0 =A0 =A0else if (tmp->type =3D=3D record_mem) >>> + =A0 =A0 xfree (tmp->u.mem.val); >>> + =A0 =A0 =A0xfree (tmp); >>> + =A0 =A0 =A0tmp =3D rec; >>> + =A0 =A0} >>> +} >>> + >>> +static void >>> +record_list_release_first (void) >>> +{ >>> + =A0record_t *tmp =3D NULL; >>> + =A0enum record_type type; >>> + >>> + =A0if (!record_first.next) >>> + =A0 =A0return; >>> + >>> + =A0while (1) >>> + =A0 =A0{ >>> + =A0 =A0 =A0type =3D record_first.next->type; >>> + >>> + =A0 =A0 =A0if (type =3D=3D record_reg) >>> + =A0 =A0 xfree (record_first.next->u.reg.val); >>> + =A0 =A0 =A0else if (type =3D=3D record_mem) >>> + =A0 =A0 xfree (record_first.next->u.mem.val); >>> + =A0 =A0 =A0tmp =3D record_first.next; >>> + =A0 =A0 =A0record_first.next =3D tmp->next; >>> + =A0 =A0 =A0xfree (tmp); >>> + >>> + =A0 =A0 =A0if (!record_first.next) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 gdb_assert (record_insn_num =3D=3D 1); >>> + =A0 =A0 =A0 break; >>> + =A0 =A0 } >>> + >>> + =A0 =A0 =A0record_first.next->prev =3D &record_first; >>> + >>> + =A0 =A0 =A0if (type =3D=3D record_end) >>> + =A0 =A0 break; >>> + =A0 =A0} >>> + >>> + =A0record_insn_num--; >>> +} >>> + >>> +/* Add a record_t to record_arch_list. =A0*/ >>> +static void >>> +record_arch_list_add (record_t * rec) >>> +{ >>> + =A0if (record_debug > 1) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: record_arch_= list_add %s.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 host_address_to_string (rec)); >>> + >>> + =A0if (record_arch_list_tail) >>> + =A0 =A0{ >>> + =A0 =A0 =A0record_arch_list_tail->next =3D rec; >>> + =A0 =A0 =A0rec->prev =3D record_arch_list_tail; >>> + =A0 =A0 =A0record_arch_list_tail =3D rec; >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0{ >>> + =A0 =A0 =A0record_arch_list_head =3D rec; >>> + =A0 =A0 =A0record_arch_list_tail =3D rec; >>> + =A0 =A0} >>> +} >>> + >>> +/* Record the value of a register ("num") to record_arch_list. =A0*/ >> >> When we want to mention the value of a parameter, we mentions it in >> uppercase, like so: >> >> /* Record the value of register NUM to record_arch_list. =A0*/ >> >> Also, there should be an empty line between the comment and >> the function itself. =A0Here and elsewhere. >> >>> +int >>> +record_arch_list_add_reg (int num) >>> +{ >>> + =A0record_t *rec; >>> + >>> + =A0if (record_debug > 1) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: add register= num =3D %d to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record list.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 num); >>> + >>> + =A0rec =3D (record_t *) xmalloc (sizeof (record_t)); >>> + =A0rec->u.reg.val =3D (gdb_byte *) xmalloc (MAX_REGISTER_SIZE); >>> + =A0rec->prev =3D NULL; >>> + =A0rec->next =3D NULL; >>> + =A0rec->type =3D record_reg; >>> + =A0rec->u.reg.num =3D num; >>> + >>> + =A0regcache_raw_read (record_regcache, num, rec->u.reg.val); >>> + >>> + =A0record_arch_list_add (rec); >>> + >>> + =A0return 0; >>> +} >>> + >>> +/* Record the value of a region of memory whose address is "addr" and >>> + =A0 length is "len" to record_arch_list. =A0*/ >> >> /* Record the value of a region of memory whose address is ADDR and >> =A0 length is LEN to record_arch_list. =A0*/ >> >>> + >>> +int >>> +record_arch_list_add_mem (CORE_ADDR addr, int len) >>> +{ >>> + =A0record_t *rec; >>> + >>> + =A0if (record_debug > 1) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: add mem addr= =3D 0x%s len =3D %d to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record list.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddr_nz (addr), len); >>> + >> >>> + =A0if (!addr) >>> + =A0 =A0return 0; >> >> Why is this check for addr =3D=3D 0 necessary here? >> >>> + >>> + =A0rec =3D (record_t *) xmalloc (sizeof (record_t)); >>> + =A0rec->u.mem.val =3D (gdb_byte *) xmalloc (len); >>> + =A0rec->prev =3D NULL; >>> + =A0rec->next =3D NULL; >>> + =A0rec->type =3D record_mem; >>> + =A0rec->u.mem.addr =3D addr; >>> + =A0rec->u.mem.len =3D len; >>> + >>> + =A0if (target_read_memory (addr, rec->u.mem.val, len)) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (record_debug) >>> + =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: erro= r reading memory at " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "addr =3D 0x%s len = =3D %d.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddr_nz (addr), len); >>> + =A0 =A0 =A0xfree (rec->u.mem.val); >>> + =A0 =A0 =A0xfree (rec); >>> + =A0 =A0 =A0return -1; >>> + =A0 =A0} >>> + >>> + =A0record_arch_list_add (rec); >>> + >>> + =A0return 0; >>> +} >>> + >>> +/* Add a record_end type record_t to record_arch_list. =A0*/ >>> +int >>> +record_arch_list_add_end (int need_dasm) >>> +{ >>> + =A0record_t *rec; >>> + >>> + =A0if (record_debug > 1) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: add end need= _dasm =3D %d to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "arch list.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 need_dasm); >>> + >>> + =A0rec =3D (record_t *) xmalloc (sizeof (record_t)); >>> + =A0rec->prev =3D NULL; >>> + =A0rec->next =3D NULL; >>> + =A0rec->type =3D record_end; >>> + >>> + =A0rec->u.need_dasm =3D need_dasm; >>> + >>> + =A0record_arch_list_add (rec); >>> + >>> + =A0return 0; >>> +} >>> + >>> +static void >>> +record_check_insn_num (int set_terminal) >>> +{ >>> + =A0if (record_insn_max_num) >>> + =A0 =A0{ >>> + =A0 =A0 =A0gdb_assert (record_insn_num <=3D record_insn_max_num); >>> + =A0 =A0 =A0if (record_insn_num =3D=3D record_insn_max_num) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 /* Ask user what to do. =A0*/ >>> + =A0 =A0 =A0 if (record_stop_at_limit) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 int q; >>> + =A0 =A0 =A0 =A0 =A0 if (set_terminal) >>> + =A0 =A0 =A0 =A0 =A0 =A0 target_terminal_ours (); >>> + =A0 =A0 =A0 =A0 =A0 q =3D yquery (_("Do you want to auto delete previ= ous execution " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "log entries when rec= ord/replay buffer becomes " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "full (record-stop-at= -limit)?")); >>> + =A0 =A0 =A0 =A0 =A0 if (set_terminal) >>> + =A0 =A0 =A0 =A0 =A0 =A0 target_terminal_inferior (); >>> + =A0 =A0 =A0 =A0 =A0 if (q) >>> + =A0 =A0 =A0 =A0 =A0 =A0 record_stop_at_limit =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 =A0 =A0 error (_("Process record: inferior program st= opped.")); >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 } >>> + =A0 =A0} >>> +} >>> + >>> +static void >>> +record_normal_stop (void) >>> +{ >>> + =A0finish_thread_state (minus_one_ptid); >>> + >>> + =A0if (!breakpoints_always_inserted_mode () && target_has_execution) >>> + =A0 =A0remove_breakpoints (); >>> + >>> + =A0target_terminal_ours (); >>> + >>> + =A0if (target_has_stack && !stop_stack_dummy) >>> + =A0 =A0set_current_sal_from_frame (get_current_frame (), 1); >>> + >>> + =A0select_frame (get_current_frame ()); >>> + >>> + =A0annotate_stopped (); >>> + =A0if (!suppress_stop_observer) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (!ptid_equal (inferior_ptid, null_ptid)) >>> + =A0 =A0 observer_notify_normal_stop (inferior_thread ()->stop_bpstat,= 0); >>> + =A0 =A0 =A0else >>> + =A0 =A0 observer_notify_normal_stop (NULL, 0); >>> + =A0 =A0} >>> +} >> >> Nope sorry, this is worse than before. =A0When I asked to not call >> normal_stop, I didn't mean that you should inline chunks of >> it here. =A0This is papering over a different problem. =A0Why >> is it that record.c needs to do this, while other targets do not? >> If we need to do something like this, it should be needed by all >> targets that can throw from target_wait (which, is documented >> as something you shouldn't do anyway). =A0Actually, do you still need >> any of this in current head? >> >>> + >>> +/* Before inferior step (when GDB record the running message, inferior >>> + =A0 only can step), GDB will call this function to record the values = to >>> + =A0 record_list. =A0This function will call gdbarch_process_record to >>> + =A0 record the running message of inferior and set them to >>> + =A0 record_arch_list, and add it to record_list. =A0*/ >>> + >>> +static void >>> +record_message_cleanups (void *ignore) >>> +{ >>> + =A0record_list_release (record_arch_list_tail); >>> + =A0set_executing (inferior_ptid, 0); >>> + =A0record_normal_stop (); >>> +} >> >> Same as above. =A0This isn't a record.c problem. >> >>> + >>> +void >>> +record_message (struct gdbarch *gdbarch) >>> +{ >>> + =A0int ret; >>> + =A0struct cleanup *old_cleanups =3D make_cleanup (record_message_clea= nups, 0); >>> + >>> + =A0record_arch_list_head =3D NULL; >>> + =A0record_arch_list_tail =3D NULL; >>> + >>> + =A0/* Check record_insn_num. =A0*/ >>> + =A0record_check_insn_num (1); >>> + >>> + =A0record_regcache =3D get_current_regcache (); >>> + >>> + =A0ret =3D gdbarch_process_record (gdbarch, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_read= _pc (record_regcache)); >>> + =A0if (ret > 0) >>> + =A0 =A0error (_("Process record: inferior program stopped.")); >>> + =A0if (ret < 0) >>> + =A0 =A0error (_("Process record: failed to record execution log.")); >>> + >>> + =A0discard_cleanups (old_cleanups); >>> + >>> + =A0record_list->next =3D record_arch_list_head; >>> + =A0record_arch_list_head->prev =3D record_list; >>> + =A0record_list =3D record_arch_list_tail; >>> + >>> + =A0if (record_insn_num =3D=3D record_insn_max_num && record_insn_max_= num) >>> + =A0 =A0record_list_release_first (); >>> + =A0else >>> + =A0 =A0record_insn_num++; >>> +} >>> + >> >> >>> +/* Things to clean up if we error or QUIT out of function that set >>> + =A0 record_gdb_operation_disable (ie. command that caused target_wait= to >>> + =A0 be called). =A0*/ >>> +static void >>> +record_gdb_operation_disable_cleanups (void *ignore) >>> +{ >>> + =A0record_gdb_operation_disable =3D 0; >>> +} >>> + >>> +struct cleanup * >>> +record_gdb_operation_disable_set (void) >>> +{ >>> + =A0struct cleanup *old_cleanups =3D >>> + =A0 =A0make_cleanup (record_gdb_operation_disable_cleanups, 0); >>> + =A0record_gdb_operation_disable =3D 1; >>> + >>> + =A0return old_cleanups; >>> +} >> >> This is make_cleanup_restore_integer. >> >>> + >>> +static void >>> +record_open (char *name, int from_tty) >>> +{ >>> + =A0struct target_ops *t; >>> + >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: record_open\n= "); >>> + >>> + =A0/* check exec */ >> >> and core. >> >>> + =A0if (!target_has_execution) >>> + =A0 =A0error (_("Process record: the program is not being run.")); >>> + =A0if (non_stop) >>> + =A0 =A0error (_("Process record target can't debug inferior in non-st= op mode " >>> + =A0 =A0 =A0 =A0 =A0"(non-stop).")); >>> + =A0if (target_async_permitted) >>> + =A0 =A0error (_("Process record target can't debug inferior in asynch= ronous " >>> + =A0 =A0 =A0 =A0 =A0"mode (target-async).")); >>> + >>> + =A0if (!gdbarch_process_record_p (current_gdbarch)) >>> + =A0 =A0error (_("Process record: the current architecture doesn't sup= port " >>> + =A0 =A0 =A0 =A0 =A0"record function.")); >>> + >>> + =A0/* Check if record target is already running. =A0*/ >>> + =A0if (TARGET_IS_PROCESS_RECORD) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (!nquery >>> + =A0 =A0 =A0 (_("Process record target already running, do you want to= delete " >>> + =A0 =A0 =A0 =A0 =A0"the old record log?"))) >>> + =A0 =A0 return; >>> + =A0 =A0} >>> + >>> + =A0/* Set the beneath function pointers. =A0*/ >>> + =A0for (t =3D current_target.beneath; t !=3D NULL; t =3D t->beneath) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (!record_beneath_to_resume) >>> + =A0 =A0 =A0 =A0{ >>> + =A0 =A0 =A0 record_beneath_to_resume =3D t->to_resume; >>> + =A0 =A0 =A0 record_beneath_to_resume_ops =3D t; >>> + =A0 =A0 =A0 =A0} >>> + =A0 =A0 =A0if (!record_beneath_to_wait) >>> + =A0 =A0 =A0 =A0{ >>> + =A0 =A0 =A0 record_beneath_to_wait =3D t->to_wait; >>> + =A0 =A0 =A0 record_beneath_to_wait_ops =3D t; >>> + =A0 =A0 =A0 =A0} >>> + =A0 =A0 =A0if (!record_beneath_to_store_registers) >>> + =A0 =A0 =A0 =A0{ >>> + =A0 =A0 =A0 record_beneath_to_store_registers =3D t->to_store_registe= rs; >>> + =A0 =A0 =A0 record_beneath_to_store_registers_ops =3D t; >>> + =A0 =A0 =A0 =A0} >>> + =A0 =A0 =A0if (!record_beneath_to_xfer_partial) >>> + =A0 =A0 =A0 =A0{ >>> + =A0 =A0 =A0 record_beneath_to_xfer_partial =3D t->to_xfer_partial; >>> + =A0 =A0 =A0 record_beneath_to_xfer_partial_ops =3D t; >>> + =A0 =A0 =A0 =A0} >>> + =A0 =A0 =A0if (!record_beneath_to_insert_breakpoint) >>> + =A0 =A0 record_beneath_to_insert_breakpoint =3D t->to_insert_breakpoi= nt; >>> + =A0 =A0 =A0if (!record_beneath_to_remove_breakpoint) >>> + =A0 =A0 record_beneath_to_remove_breakpoint =3D t->to_remove_breakpoi= nt; >>> + =A0 =A0} >>> + =A0if (!record_beneath_to_resume) >>> + =A0 =A0error (_("Process record can't get to_resume.")); >>> + =A0if (!record_beneath_to_wait) >>> + =A0 =A0error (_("Process record can't get to_wait.")); >>> + =A0if (!record_beneath_to_store_registers) >>> + =A0 =A0error (_("Process record can't get to_store_registers.")); >>> + =A0if (!record_beneath_to_xfer_partial) >>> + =A0 =A0error (_("Process record can't get to_xfer_partial.")); >>> + =A0if (!record_beneath_to_insert_breakpoint) >>> + =A0 =A0error (_("Process record can't get to_insert_breakpoint.")); >>> + =A0if (!record_beneath_to_remove_breakpoint) >>> + =A0 =A0error (_("Process record can't get to_remove_breakpoint.")); >> >> As I said above, this is better than making target.c aware of >> these pointers, but, it still isn't ideal. =A0For one thing, if >> some other layer/target is pushed after the record target is opened, >> these will be wrong. =A0I would prefer that this beneath lookup >> would be done at each callback implementation (record_resume, etc.), >> but, I'm happy enough with this for now. =A0It is now contained, so we c= an >> clean this up afterwards... >> >>> + >>> + =A0push_target (&record_ops); >>> + >>> + =A0/* Reset */ >>> + =A0record_insn_num =3D 0; >>> + =A0record_list =3D &record_first; >>> + =A0record_list->next =3D NULL; >>> +} >>> + >>> +static void >>> +record_close (int quitting) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: record_close\= n"); >>> + >>> + =A0record_list_release (record_list); >>> +} >> >> Shouldn't this clear the record_beneath_* pointers as well? >> >>> + >>> +static void >>> +record_resume (struct target_ops *ops, ptid_t ptid, int step, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 enum target_signal siggnal) >>> +{ >>> + =A0record_resume_step =3D step; >>> + =A0record_resume_siggnal =3D siggnal; >>> + >>> + =A0if (!RECORD_IS_REPLAY) >>> + =A0 =A0{ >>> + =A0 =A0 =A0record_message (current_gdbarch); >>> + =A0 =A0 =A0record_beneath_to_resume (record_beneath_to_resume_ops, pt= id, 1, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0siggna= l); >>> + =A0 =A0} >>> +} >>> + >>> +static void >>> +record_sig_handler (int signo) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: get a signal\= n"); >>> + >>> + =A0record_resume_step =3D 1; >>> + =A0record_get_sig =3D 1; >>> +} >> >> This handler is magical. =A0Why is it setting resume_step, for instance? >> It would definitelly benefic from some comments. =A0In fact, most of the >> file is undercommented. >> >>> + >>> +static void >>> +record_wait_cleanups (void *ignore) >>> +{ >>> + =A0if (execution_direction =3D=3D EXEC_REVERSE) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (record_list->next) >>> + =A0 =A0 record_list =3D record_list->next; >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0record_list =3D record_list->prev; >>> + >>> + =A0set_executing (inferior_ptid, 0); >>> + =A0record_normal_stop (); >>> +} >> >> See comments about record_normal_stop above. >> >>> + >>> +/* record_wait >> >> Please remove the function name from the comment. =A0It's redundant. >> >>> + =A0 In replay mode, this function examines the recorded log and >>> + =A0 determines where to stop. =A0*/ >>> + >>> +static ptid_t >>> +record_wait (struct target_ops *ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0ptid_t ptid, struct target_waitstatus *sta= tus) >>> +{ >>> + =A0struct cleanup *set_cleanups =3D record_gdb_operation_disable_set = (); >>> + >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Process record: record_wait " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record_resume_step =3D %d\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_resume_step); >>> + >>> + =A0if (!RECORD_IS_REPLAY) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (record_resume_step) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 /* This is a single step. =A0*/ >>> + =A0 =A0 =A0 return record_beneath_to_wait (record_beneath_to_wait_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ptid, status); >>> + =A0 =A0 } >>> + =A0 =A0 =A0else >>> + =A0 =A0 { >>> + =A0 =A0 =A0 if (record_resume_step) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* This is a single step. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 return record_beneath_to_wait (record_beneath_to_= wait_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ptid, status); >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* This is not a single step. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 ptid_t ret; >>> + =A0 =A0 =A0 =A0 =A0 int is_breakpoint =3D 1; >>> + =A0 =A0 =A0 =A0 =A0 CORE_ADDR pc =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 int pc_is_read =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 struct bp_location *bl; >>> + =A0 =A0 =A0 =A0 =A0 struct breakpoint *b; >>> + >>> + =A0 =A0 =A0 =A0 =A0 do >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D record_beneath_to_wait (record_be= neath_to_wait_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ptid, status); >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (status->kind =3D=3D TARGET_WAITKIND_S= TOPPED >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && status->value.sig =3D=3D TARGE= T_SIGNAL_TRAP) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Check if there is a breakpoint= . =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pc_is_read =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 registers_changed (); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (bl =3D bp_location_chain; bl= ; bl =3D bl->global_next) >> >> This will need to be fixed. =A0Can you use the breakpoint_here-like func= tions >> exported by breakpoint.h instead of referencing bp_location_chain direct= ly? >> >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 b =3D bl->owner; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdb_assert (b); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (b->enable_state !=3D = bp_enabled >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && b->enable_stat= e !=3D bp_permanent) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!pc_is_read) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pc =3D >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_read= _pc (get_thread_regcache (ret)); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pc_is_read =3D 1; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 switch (b->type) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 default: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (bl->address = =3D=3D pc) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto breakpoi= nt; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case bp_watchpoint: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* XXX teawater: = I still not very clear how to >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0deal with = it. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto breakpoint; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case bp_catchpoint: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdb_assert (b->op= s !=3D NULL >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 && b->ops->breakpoint_hit !=3D NULL); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (b->ops->break= point_hit (b)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto breakpoi= nt; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case bp_hardware_watc= hpoint: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case bp_read_watchpoi= nt: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case bp_access_watchp= oint: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (STOPPED_BY_WA= TCHPOINT (0)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto breakpoi= nt; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* There is not a breakpoint. =A0= */ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_message (current_gdbarch); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_beneath_to_resume (record_= beneath_to_resume_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0ptid, 1, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 record_resume_siggnal); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 is_breakpoint =3D 0; >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 breakpoint: >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Add gdbarch_decr_pc_after_break to pc = because gdb will >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0expect the pc to be at address plu= s decr_pc_after_break >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0when the inferior stops at a break= point. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (is_breakpoint) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CORE_ADDR decr_pc_after_break =3D >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdbarch_decr_pc_after_break (= current_gdbarch); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (decr_pc_after_break) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!pc_is_read) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pc =3D >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_read_pc = (get_thread_regcache (ret)); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_write_pc (get_th= read_regcache (ret), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0pc + decr_pc_after_break); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 while (1); >>> + >>> + =A0 =A0 =A0 =A0 =A0 return ret; >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 } >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0{ >>> + =A0 =A0 =A0int need_dasm =3D 0; >>> + =A0 =A0 =A0struct regcache *regcache =3D get_current_regcache (); >>> + =A0 =A0 =A0int continue_flag =3D 1; >>> + =A0 =A0 =A0int first_record_end =3D 1; >>> + =A0 =A0 =A0struct cleanup *old_cleanups =3D make_cleanup (record_wait= _cleanups, 0); >>> + =A0 =A0 =A0CORE_ADDR tmp_pc; >>> + >>> + =A0 =A0 =A0status->kind =3D TARGET_WAITKIND_STOPPED; >>> + >>> + =A0 =A0 =A0/* Check breakpoint when forward execute. =A0*/ >>> + =A0 =A0 =A0if (execution_direction =3D=3D EXEC_FORWARD) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 tmp_pc =3D regcache_read_pc (regcache); >>> + =A0 =A0 =A0 if (breakpoint_inserted_here_p (tmp_pc)) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 if (record_debug) >>> + =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Proc= ess record: break at 0x%s.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddr= _nz (tmp_pc)); >>> + =A0 =A0 =A0 =A0 =A0 if (gdbarch_decr_pc_after_break (get_regcache_arc= h (regcache)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !record_resume_step) >>> + =A0 =A0 =A0 =A0 =A0 =A0 regcache_write_pc (regcache, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tmp_pc= + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gdbarc= h_decr_pc_after_break >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(get_r= egcache_arch (regcache))); >>> + =A0 =A0 =A0 =A0 =A0 goto replay_out; >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 } >>> + >>> + =A0 =A0 =A0record_get_sig =3D 0; >>> + =A0 =A0 =A0signal (SIGINT, record_sig_handler); >>> + =A0 =A0 =A0/* If GDB is in terminal_inferior mode, it will not get th= e signal. >>> + =A0 =A0 =A0 =A0 And in GDB replay mode, GDB doesn't need to be in ter= minal_inferior >>> + =A0 =A0 =A0 =A0 mode, because inferior will not executed. >>> + =A0 =A0 =A0 =A0 Then set it to terminal_ours to make GDB get the sign= al. =A0*/ >>> + =A0 =A0 =A0target_terminal_ours (); >>> + >>> + =A0 =A0 =A0/* In EXEC_FORWARD mode, record_list points to the tail of= prev >>> + =A0 =A0 =A0 =A0 instruction. =A0*/ >>> + =A0 =A0 =A0if (execution_direction =3D=3D EXEC_FORWARD && record_list= ->next) >>> + =A0 =A0 record_list =3D record_list->next; >>> + >>> + =A0 =A0 =A0/* Loop over the record_list, looking for the next place to >>> + =A0 =A0 =A0stop. =A0*/ >>> + =A0 =A0 =A0do >>> + =A0 =A0 { >>> + =A0 =A0 =A0 /* Check for beginning and end of log. =A0*/ >>> + =A0 =A0 =A0 if (execution_direction =3D=3D EXEC_REVERSE >>> + =A0 =A0 =A0 =A0 =A0 && record_list =3D=3D &record_first) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* Hit beginning of record log in reverse. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 status->kind =3D TARGET_WAITKIND_NO_HISTORY; >>> + =A0 =A0 =A0 =A0 =A0 break; >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 if (execution_direction !=3D EXEC_REVERSE && !record_list= ->next) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* Hit end of record log going forward. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 status->kind =3D TARGET_WAITKIND_NO_HISTORY; >>> + =A0 =A0 =A0 =A0 =A0 break; >>> + =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 /* Set ptid, register and memory according to record_list= . =A0*/ >>> + =A0 =A0 =A0 if (record_list->type =3D=3D record_reg) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* reg */ >>> + =A0 =A0 =A0 =A0 =A0 gdb_byte reg[MAX_REGISTER_SIZE]; >>> + =A0 =A0 =A0 =A0 =A0 if (record_debug > 1) >>> + =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Proc= ess record: record_reg %s to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "infe= rior num =3D %d.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 host_= address_to_string (record_list), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 recor= d_list->u.reg.num); >>> + =A0 =A0 =A0 =A0 =A0 regcache_cooked_read (regcache, record_list->u.re= g.num, reg); >>> + =A0 =A0 =A0 =A0 =A0 regcache_cooked_write (regcache, record_list->u.r= eg.num, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0re= cord_list->u.reg.val); >>> + =A0 =A0 =A0 =A0 =A0 memcpy (record_list->u.reg.val, reg, MAX_REGISTER= _SIZE); >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 else if (record_list->type =3D=3D record_mem) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* mem */ >>> + =A0 =A0 =A0 =A0 =A0 gdb_byte *mem =3D alloca (record_list->u.mem.len); >>> + =A0 =A0 =A0 =A0 =A0 if (record_debug > 1) >>> + =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Proc= ess record: record_mem %s to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "infe= rior addr =3D 0x%s len =3D %d.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 host_= address_to_string (record_list), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddr= _nz (record_list->u.mem.addr), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 recor= d_list->u.mem.len); >>> + >>> + =A0 =A0 =A0 =A0 =A0 if (target_read_memory >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (record_list->u.mem.addr, mem, record_lis= t->u.mem.len)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 error (_("Process record: error reading memor= y at " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"addr =3D 0x%s len =3D %d.= "), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0paddr_nz (record_list->u.mem.a= ddr), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_list->u.mem.len); >>> + >>> + =A0 =A0 =A0 =A0 =A0 if (target_write_memory >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (record_list->u.mem.addr, record_list->u.= mem.val, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_list->u.mem.len)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 error (_ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0("Process record: error writin= g memory at " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "addr =3D 0x%s len =3D %d."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0paddr_nz (record_list->u.mem.a= ddr), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_list->u.mem.len); >>> + >>> + =A0 =A0 =A0 =A0 =A0 memcpy (record_list->u.mem.val, mem, record_list-= >u.mem.len); >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 if (record_debug > 1) >>> + =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Proc= ess record: record_end %s to " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "infe= rior need_dasm =3D %d.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 host_= address_to_string (record_list), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 recor= d_list->u.need_dasm); >>> + >>> + =A0 =A0 =A0 =A0 =A0 if (execution_direction =3D=3D EXEC_FORWARD) >>> + =A0 =A0 =A0 =A0 =A0 =A0 need_dasm =3D record_list->u.need_dasm; >>> + =A0 =A0 =A0 =A0 =A0 if (need_dasm) >>> + =A0 =A0 =A0 =A0 =A0 =A0 gdbarch_process_record_dasm (current_gdbarch); >>> + >>> + =A0 =A0 =A0 =A0 =A0 if (first_record_end && execution_direction =3D= =3D EXEC_REVERSE) >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* When reverse excute, the first record_= end is the part of >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0current instruction. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 first_record_end =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* In EXEC_REVERSE mode, this is the reco= rd_end of prev >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0instruction. >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0In EXEC_FORWARD mode, this is the = record_end of current >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0instruction. =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* step */ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_resume_step) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_debug > 1) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlo= g, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 "Process record: step.\n"); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue_flag =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* check breakpoint */ >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 tmp_pc =3D regcache_read_pc (regcache); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (breakpoint_inserted_here_p (tmp_pc)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_debug) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlo= g, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 "Process record: break " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 "at 0x%s.\n", >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 paddr_nz (tmp_pc)); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (gdbarch_decr_pc_after_break (= get_regcache_arch (regcache)) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && execution_direction = =3D=3D EXEC_FORWARD >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !record_resume_step) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_write_pc (regcache, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0tmp_pc + >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0gdbarch_decr_pc_after_break >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0(get_regcache_arch (regcache))); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue_flag =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 if (execution_direction =3D=3D EXEC_REVERSE) >>> + =A0 =A0 =A0 =A0 =A0 =A0 need_dasm =3D record_list->u.need_dasm; >>> + =A0 =A0 =A0 =A0 } >>> + >>> +next: >>> + =A0 =A0 =A0 if (continue_flag) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 if (execution_direction =3D=3D EXEC_REVERSE) >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_list->prev) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_list =3D record_list->prev; >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_list->next) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_list =3D record_list->next; >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 } >>> + =A0 =A0 =A0while (continue_flag); >>> + >>> + =A0 =A0 =A0signal (SIGINT, handle_sigint); >>> + >>> +replay_out: >>> + =A0 =A0 =A0if (record_get_sig) >>> + =A0 =A0 status->value.sig =3D TARGET_SIGNAL_INT; >>> + =A0 =A0 =A0else >>> + =A0 =A0 status->value.sig =3D TARGET_SIGNAL_TRAP; >>> + >>> + =A0 =A0 =A0discard_cleanups (old_cleanups); >>> + =A0 =A0} >>> + >>> + =A0do_cleanups (set_cleanups); >>> + =A0return inferior_ptid; >>> +} >> >> I have to say that I find that function confusing, due to >> the use of gotos, and excessive nesting. =A0Personally, I much prefer >> code that does: >> >> =A0if (foo) >> =A0 =A0{ >> =A0 =A0 =A0/* something */ >> =A0 =A0 =A0return; >> =A0 =A0} >> >> =A0if (bar) >> =A0 =A0{ >> =A0 =A0 =A0/* something */ >> =A0 =A0 =A0return; >> =A0 =A0} >> >> =A0if (lala) >> =A0 =A0{ >> =A0 =A0 =A0/* something */ >> =A0 =A0 =A0return; >> =A0 =A0} >> >> Over: >> >> =A0if (foo) >> =A0 =A0{ >> =A0 =A0 =A0/* something */ >> =A0 =A0 =A0return; >> =A0 =A0} >> =A0else >> =A0 { >> =A0 =A0 if (bar) >> =A0 =A0 =A0 { >> =A0 =A0 =A0 =A0 /* something */ >> =A0 =A0 =A0 =A0 return; >> =A0 =A0 =A0 } >> =A0 =A0 else >> =A0 =A0 =A0{ >> =A0 =A0 =A0 =A0 if (lala) >> =A0 =A0 =A0 =A0 =A0 { >> =A0 =A0 =A0 =A0 =A0 =A0 /* something */ >> =A0 =A0 =A0 =A0 =A0 =A0 return; >> =A0 =A0 =A0 =A0 =A0 } >> =A0 =A0 =A0} >> =A0 } >> >> >>> + >>> +static void >>> +record_disconnect (struct target_ops *target, char *args, int from_tty) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: record_discon= nect\n"); >>> + >>> + =A0unpush_target (&record_ops); >>> + =A0target_disconnect (args, from_tty); >>> +} >>> + >>> +static void >>> +record_detach (struct target_ops *ops, char *args, int from_tty) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: record_detach= \n"); >>> + >>> + =A0unpush_target (&record_ops); >>> + =A0target_detach (args, from_tty); >>> +} >> >> This trick you're using happens to work, but, could you try >> this instead? =A0Here and elsewhere similarly. >> >> =A0struct target_ops *beneath =3D find_target_beaneath (ops); >> =A0unpush_target (ops); >> =A0beneath->to_detach (args, from_tty); >> >>> + >>> +static void >>> +record_mourn_inferior (struct target_ops *ops) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "reco= rd_mourn_inferior\n"); >>> + >>> + =A0unpush_target (&record_ops); >>> + =A0target_mourn_inferior (); >>> +} >>> + >>> +/* Close process record target before killing the inferior process. = =A0*/ >>> +static void >>> +record_kill (void) >>> +{ >>> + =A0if (record_debug) >>> + =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: record_kill\n= "); >>> + >>> + =A0unpush_target (&record_ops); >>> + =A0target_kill (); >>> +} >>> + >>> +/* Record registers change (by user or by GDB) to list as an instructi= on. =A0*/ >>> +static void >>> +record_registers_change (struct regcache *regcache, int regnum) >>> +{ >>> + =A0/* Check record_insn_num. =A0*/ >>> + =A0record_check_insn_num (0); >>> + >>> + =A0record_arch_list_head =3D NULL; >>> + =A0record_arch_list_tail =3D NULL; >>> + >>> + =A0record_regcache =3D get_current_regcache (); >>> + >>> + =A0if (regnum < 0) >>> + =A0 =A0{ >>> + =A0 =A0 =A0int i; >>> + =A0 =A0 =A0for (i =3D 0; i < gdbarch_num_regs (get_regcache_arch (reg= cache)); i++) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 if (record_arch_list_add_reg (i)) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 record_list_release (record_arch_list_tail); >>> + =A0 =A0 =A0 =A0 =A0 error (_("Process record: failed to record execut= ion log.")); >>> + =A0 =A0 =A0 =A0 } >>> + =A0 =A0 } >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (record_arch_list_add_reg (regnum)) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 record_list_release (record_arch_list_tail); >>> + =A0 =A0 =A0 error (_("Process record: failed to record execution log.= ")); >>> + =A0 =A0 } >>> + =A0 =A0} >>> + =A0if (record_arch_list_add_end (0)) >>> + =A0 =A0{ >>> + =A0 =A0 =A0record_list_release (record_arch_list_tail); >>> + =A0 =A0 =A0error (_("Process record: failed to record execution log."= )); >>> + =A0 =A0} >>> + =A0record_list->next =3D record_arch_list_head; >>> + =A0record_arch_list_head->prev =3D record_list; >>> + =A0record_list =3D record_arch_list_tail; >>> + >>> + =A0if (record_insn_num =3D=3D record_insn_max_num && record_insn_max_= num) >>> + =A0 =A0record_list_release_first (); >>> + =A0else >>> + =A0 =A0record_insn_num++; >>> +} >>> + >>> +static void >>> +record_store_registers (struct target_ops *ops, struct regcache *regca= che, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int regno) >>> +{ >>> + =A0if (!record_gdb_operation_disable) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (RECORD_IS_REPLAY) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 int n; >>> + =A0 =A0 =A0 struct cleanup *old_cleanups; >>> + >>> + =A0 =A0 =A0 /* Let user choose if he wants to write register or not. = =A0*/ >>> + =A0 =A0 =A0 if (regno < 0) >>> + =A0 =A0 =A0 =A0 n =3D >>> + =A0 =A0 =A0 =A0 =A0 nquery (_("Because GDB is in replay mode, changin= g the " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "value of a register will mak= e the execution " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "log unusable from this point= onward. =A0" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Change all registers?")); >>> + =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 n =3D >>> + =A0 =A0 =A0 =A0 =A0 nquery (_("Because GDB is in replay mode, changin= g the value " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "of a register will make the = execution log unusable " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "from this point onward. =A0C= hange register %s?"), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdbarch_register_name (get_regcac= he_arch (regcache), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0regno)); >>> + >>> + =A0 =A0 =A0 if (!n) >>> + =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 /* Invalidate the value of regcache that was set = in function >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0"regcache_raw_write". =A0*/ >>> + =A0 =A0 =A0 =A0 =A0 if (regno < 0) >>> + =A0 =A0 =A0 =A0 =A0 =A0 { >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 int i; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D 0; >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < gdbarch_num_regs (get_regc= ache_arch (regcache)); >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_invalidate (regcache, i); >>> + =A0 =A0 =A0 =A0 =A0 =A0 } >>> + =A0 =A0 =A0 =A0 =A0 else >>> + =A0 =A0 =A0 =A0 =A0 =A0 regcache_invalidate (regcache, regno); >>> + >>> + =A0 =A0 =A0 =A0 =A0 error (_("Process record canceled the operation."= )); >>> + =A0 =A0 =A0 =A0 } >>> + >>> + =A0 =A0 =A0 /* Destroy the record from here forward. =A0*/ >>> + =A0 =A0 =A0 record_list_release_next (); >>> + =A0 =A0 } >>> + >>> + =A0 =A0 =A0record_registers_change (regcache, regno); >>> + =A0 =A0} >>> + =A0record_beneath_to_store_registers (record_beneath_to_store_registe= rs_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 regcache, regno); >>> +} >>> + >>> +/* record_xfer_partial -- behavior is conditional on RECORD_IS_REPLAY. >>> + =A0 In replay mode, we cannot write memory unles we are willing to >>> + =A0 invalidate the record/replay log from this point forward. =A0*/ >>> + >>> +static LONGEST >>> +record_xfer_partial (struct target_ops *ops, enum target_object object, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *annex, gdb_byte * read= buf, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const gdb_byte * writebuf, ULONGES= T offset, LONGEST len) >>> +{ >>> + =A0if (!record_gdb_operation_disable >>> + =A0 =A0 =A0&& (object =3D=3D TARGET_OBJECT_MEMORY >>> + =A0 =A0 =A0 || object =3D=3D TARGET_OBJECT_RAW_MEMORY) && writebuf) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (RECORD_IS_REPLAY) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 /* Let user choose if he wants to write memory or not. = =A0*/ >>> + =A0 =A0 =A0 if (!nquery (_("Because GDB is in replay mode, writing to= memory " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"will make the execution l= og unusable from this " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"point onward. =A0Write me= mory at address 0x%s?"), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0paddr_nz (offset))) >>> + =A0 =A0 =A0 =A0 return -1; >>> + >>> + =A0 =A0 =A0 /* Destroy the record from here forward. =A0*/ >>> + =A0 =A0 =A0 record_list_release_next (); >>> + =A0 =A0 } >>> + >>> + =A0 =A0 =A0/* Check record_insn_num */ >>> + =A0 =A0 =A0record_check_insn_num (0); >>> + >>> + =A0 =A0 =A0/* Record registers change to list as an instruction. =A0*/ >>> + =A0 =A0 =A0record_arch_list_head =3D NULL; >>> + =A0 =A0 =A0record_arch_list_tail =3D NULL; >>> + =A0 =A0 =A0if (record_arch_list_add_mem (offset, len)) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 record_list_release (record_arch_list_tail); >>> + =A0 =A0 =A0 if (record_debug) >>> + =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Process re= cord: failed to record " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "executio= n log.")); >>> + =A0 =A0 =A0 return -1; >>> + =A0 =A0 } >>> + =A0 =A0 =A0if (record_arch_list_add_end (0)) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 record_list_release (record_arch_list_tail); >>> + =A0 =A0 =A0 if (record_debug) >>> + =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Process re= cord: failed to record " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "executio= n log.")); >>> + =A0 =A0 =A0 return -1; >>> + =A0 =A0 } >>> + =A0 =A0 =A0record_list->next =3D record_arch_list_head; >>> + =A0 =A0 =A0record_arch_list_head->prev =3D record_list; >>> + =A0 =A0 =A0record_list =3D record_arch_list_tail; >>> + >>> + =A0 =A0 =A0if (record_insn_num =3D=3D record_insn_max_num && record_i= nsn_max_num) >>> + =A0 =A0 record_list_release_first (); >>> + =A0 =A0 =A0else >>> + =A0 =A0 record_insn_num++; >>> + =A0 =A0} >>> + >>> + =A0return record_beneath_to_xfer_partial (record_beneath_to_xfer_part= ial_ops, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 object, annex, readbuf, writebuf, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 offset, len); >>> +} >>> + >>> +/* record_insert_breakpoint >>> + =A0 record_remove_breakpoint >>> + =A0 Behavior is conditional on RECORD_IS_REPLAY. >>> + =A0 We will not actually insert or remove breakpoints when replaying, >>> + =A0 nor when recording. =A0*/ >>> + >>> +static int >>> +record_insert_breakpoint (struct bp_target_info *bp_tgt) >>> +{ >>> + =A0if (!RECORD_IS_REPLAY) >>> + =A0 =A0{ >>> + =A0 =A0 =A0struct cleanup *old_cleanups =3D record_gdb_operation_disa= ble_set (); >>> + =A0 =A0 =A0int ret =3D record_beneath_to_insert_breakpoint (bp_tgt); >>> + >>> + =A0 =A0 =A0do_cleanups (old_cleanups); >>> + >>> + =A0 =A0 =A0return ret; >>> + =A0 =A0} >>> + >>> + =A0return 0; >>> +} >>> + >>> +static int >>> +record_remove_breakpoint (struct bp_target_info *bp_tgt) >>> +{ >>> + =A0if (!RECORD_IS_REPLAY) >>> + =A0 =A0{ >>> + =A0 =A0 =A0struct cleanup *old_cleanups =3D record_gdb_operation_disa= ble_set (); >>> + =A0 =A0 =A0int ret =3D record_beneath_to_remove_breakpoint (bp_tgt); >>> + >>> + =A0 =A0 =A0do_cleanups (old_cleanups); >>> + >>> + =A0 =A0 =A0return ret; >>> + =A0 =A0} >>> + >>> + =A0return 0; >>> +} >>> + >>> +static int >>> +record_can_execute_reverse (void) >>> +{ >>> + =A0return 1; >>> +} >>> + >>> +static void >>> +init_record_ops (void) >>> +{ >>> + =A0record_ops.to_shortname =3D "record"; >>> + =A0record_ops.to_longname =3D "Process record and replay target"; >>> + =A0record_ops.to_doc =3D >>> + =A0 =A0"Log program while executing and replay execution from log."; >>> + =A0record_ops.to_open =3D record_open; >>> + =A0record_ops.to_close =3D record_close; >>> + =A0record_ops.to_resume =3D record_resume; >>> + =A0record_ops.to_wait =3D record_wait; >>> + =A0record_ops.to_disconnect =3D record_disconnect; >>> + =A0record_ops.to_detach =3D record_detach; >>> + =A0record_ops.to_mourn_inferior =3D record_mourn_inferior; >>> + =A0record_ops.to_kill =3D record_kill; >>> + =A0record_ops.to_create_inferior =3D find_default_create_inferior; >>> + =A0record_ops.to_store_registers =3D record_store_registers; >>> + =A0record_ops.to_xfer_partial =3D record_xfer_partial; >>> + =A0record_ops.to_insert_breakpoint =3D record_insert_breakpoint; >>> + =A0record_ops.to_remove_breakpoint =3D record_remove_breakpoint; >>> + =A0record_ops.to_can_execute_reverse =3D record_can_execute_reverse; >>> + =A0record_ops.to_stratum =3D record_stratum; >>> + =A0record_ops.to_magic =3D OPS_MAGIC; >>> +} >>> + >>> +static void >>> +show_record_debug (struct ui_file *file, int from_tty, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct cmd_list_element *c, const char= *value) >>> +{ >>> + =A0fprintf_filtered (file, _("Debugging of process record target is %= s.\n"), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 value); >>> +} >>> + >>> +/* cmd_record_start -- alias for "target record". =A0*/ >>> + >>> +static void >>> +cmd_record_start (char *args, int from_tty) >>> +{ >>> + =A0execute_command ("target record", from_tty); >>> +} >>> + >>> +/* cmd_record_delete -- truncate the record log from the present point >>> + =A0 of replay until the end. =A0*/ >>> + >>> +static void >>> +cmd_record_delete (char *args, int from_tty) >>> +{ >>> + =A0if (TARGET_IS_PROCESS_RECORD) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (RECORD_IS_REPLAY) >>> + =A0 =A0 { >>> + =A0 =A0 =A0 if (!from_tty || query (_("Delete the log from this point= forward " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "and = begin to record the running message " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "at c= urrent PC?"))) >>> + =A0 =A0 =A0 =A0 record_list_release_next (); >>> + =A0 =A0 } >>> + =A0 =A0 =A0else >>> + =A0 =A0 =A0 printf_unfiltered (_("Already at end of record list.\n")); >>> + >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0printf_unfiltered (_("Process record is not started.\n")); >>> +} >>> + >>> +/* cmd_record_stop -- implement the "stoprecord" command. =A0*/ >>> + >>> +static void >>> +cmd_record_stop (char *args, int from_tty) >>> +{ >>> + =A0if (TARGET_IS_PROCESS_RECORD) >>> + =A0 =A0{ >>> + =A0 =A0 =A0if (!record_list || !from_tty || query (_("Delete recorded= log and " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 "stop recording?"))) >>> + =A0 =A0 unpush_target (&record_ops); >>> + =A0 =A0} >>> + =A0else >>> + =A0 =A0printf_unfiltered (_("Process record is not started.\n")); >>> +} >>> + >>> +/* set_record_insn_max_num -- set upper limit of record log size. =A0*/ >>> + >>> +static void >>> +set_record_insn_max_num (char *args, int from_tty, struct cmd_list_ele= ment *c) >>> +{ >>> + =A0if (record_insn_num > record_insn_max_num && record_insn_max_num) >>> + =A0 =A0{ >>> + =A0 =A0 =A0printf_unfiltered (_("Record instructions number is bigger= than " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"record instructions m= ax number. =A0Auto delete " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"the first ones?\n")); >>> + >>> + =A0 =A0 =A0while (record_insn_num > record_insn_max_num) >>> + =A0 =A0 record_list_release_first (); >>> + =A0 =A0} >>> +} >>> + >>> +/* show_record_insn_number -- print the current index >>> + =A0 into the record log (number of insns recorded so far). =A0*/ >>> + >>> +static void >>> +show_record_insn_number (char *ignore, int from_tty) >>> +{ >>> + =A0printf_unfiltered (_("Record instruction number is %d.\n"), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_insn_num); >>> +} >>> + >>> +void >>> +_initialize_record (void) >>> +{ >>> + =A0/* Init record_maskall. =A0*/ >>> + =A0if (sigfillset (&record_maskall) =3D=3D -1) >>> + =A0 =A0perror_with_name (_("Process record: sigfillset failed")); >> >> This will not build on all hosts. =A0Is it still needed? =A0I can't >> find any other reference to this variable in this patch. >> >>> + >>> + =A0/* Init record_first. =A0*/ >>> + =A0record_first.prev =3D NULL; >>> + =A0record_first.next =3D NULL; >>> + =A0record_first.type =3D record_end; >>> + =A0record_first.u.need_dasm =3D 0; >>> + >>> + =A0init_record_ops (); >>> + =A0add_target (&record_ops); >>> + >>> + =A0add_setshow_zinteger_cmd ("record", no_class, &record_debug, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Set debugging of r= ecord/replay feature."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Show debugging of = record/replay feature."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("When enabled, debu= gging output for " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record/replay fe= ature is displayed."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL, show_record_deb= ug, &setdebuglist, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &showdebuglist); >>> + >>> + =A0add_com ("record", class_obscure, cmd_record_start, >>> + =A0 =A0 =A0 =A0_("Abbreviated form of \"target record\" command.")); >>> + >>> + =A0add_com_alias ("rec", "record", class_obscure, 1); >>> + >>> + =A0/* XXX: I try to use some simple commands such as "disconnect" and >>> + =A0 =A0 "detach" to support this functions. =A0But these commands all= have >>> + =A0 =A0 other affect to GDB such as call function "no_shared_librarie= s". >>> + =A0 =A0 So I add special commands to GDB. =A0*/ >>> + =A0add_com ("delrecord", class_obscure, cmd_record_delete, >>> + =A0 =A0 =A0 =A0_("Delete the rest of execution log and start recordin= g it anew.")); >>> + =A0add_com_alias ("dr", "delrecord", class_obscure, 1); >>> + =A0add_com ("stoprecord", class_obscure, cmd_record_stop, >>> + =A0 =A0 =A0 =A0_("Stop the record/replay target.")); >>> + =A0add_com_alias ("sr", "stoprecord", class_obscure, 1); >>> + >>> + =A0/* Record instructions number limit command. =A0*/ >>> + =A0add_setshow_boolean_cmd ("record-stop-at-limit", no_class, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &record_stop_at_limit, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Set whether record= /replay stop when " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record/replay bu= ffer becomes full."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Show whether recor= d/replay stop when " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "record/replay bu= ffer becomes full."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Enable is default = value.\n" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "When enabled, if= the record/replay buffer " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "becomes full,\n" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"ask user = what to do.\n" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"When disa= bled, if the record/replay buffer " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "becomes full,\n" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"delete it= and start new recording."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL, NULL, &setlist,= &showlist); >>> + =A0add_setshow_zinteger_cmd ("record-insn-number-max", no_class, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &record_insn_max_num, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Set record/replay = buffer limit."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Show record/replay= buffer limit."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 _("Set the maximum nu= mber of instructions to be " >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"stored in= the\n" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"record/re= play buffer. =A0" >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"Zero mean= s unlimited (default 200000)."), >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 set_record_insn_max_n= um, >>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL, &setlist, &show= list); >>> + =A0add_info ("record-insn-number", show_record_insn_number, >>> + =A0 =A0 =A0 =A0 _("Show the current number of instructions in the " >>> + =A0 =A0 =A0 =A0 =A0 "record/replay buffer.")); >>> +} >>> Index: src/gdb/record.h >>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>> --- /dev/null 1970-01-01 00:00:00.000000000 +0000 >>> +++ src/gdb/record.h =A02009-02-28 20:23:20.000000000 +0000 >>> @@ -0,0 +1,87 @@ >>> +/* Process record and replay target for GDB, the GNU debugger. >>> + >>> + =A0 Copyright (C) 2008 Free Software Foundation, Inc. >>> + >>> + =A0 This file is part of GDB. >>> + >>> + =A0 This program is free software; you can redistribute it and/or mod= ify >>> + =A0 it under the terms of the GNU General Public License as published= by >>> + =A0 the Free Software Foundation; either version 3 of the License, or >>> + =A0 (at your option) any later version. >>> + >>> + =A0 This program is distributed in the hope that it will be useful, >>> + =A0 but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + =A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =A0See the >>> + =A0 GNU General Public License for more details. >>> + >>> + =A0 You should have received a copy of the GNU General Public License >>> + =A0 along with this program. =A0If not, see . =A0*/ >>> + >>> +#ifndef _RECORD_H_ >>> +#define _RECORD_H_ >>> + >>> +#define TARGET_IS_PROCESS_RECORD =A0 \ >>> + =A0 =A0 (current_target.beneath =3D=3D &record_ops) >> >> Sorry, but I repeat the request I've made several times already. =A0This= is >> not the right way to do this. =A0You need to add a new target_ops method= or >> property that the core of GDB checks on. =A0It is not correct that make >> the core of GDB reference record_ops directly. =A0To come up with >> the target callback's name, at each call site of TARGET_IS_PROCESS_RECOR= D, >> consider what is the property of the current target that GDB needs to >> know about the current target. =A0Is it something like: >> >> =A0target_is_recording () ? >> =A0target_is_replaying () ? >> =A0target_is_read_only () ? >> >> etc. >> >>> +#define RECORD_IS_REPLAY \ >>> + =A0 =A0 (record_list->next || execution_direction =3D=3D EXEC_REVERSE) >> >> AFAICS, this macro is not used outside of record.c. =A0It should move >> there, along with anything that isn't used outside of record.c. >> >>> + >>> +typedef struct record_reg_s >>> +{ >>> + =A0int num; >>> + =A0gdb_byte *val; >>> +} record_reg_t; >>> + >>> +typedef struct record_mem_s >>> +{ >>> + =A0CORE_ADDR addr; >>> + =A0int len; >>> + =A0gdb_byte *val; >>> +} record_mem_t; >>> + >>> +enum record_type >>> +{ >>> + =A0record_end =3D 0, >>> + =A0record_reg, >>> + =A0record_mem >>> +}; >>> + >>> +/* This is the core struct of record function. >>> + >>> + =A0 An entity of record_t is a record of the value change of a regist= er >>> + =A0 ("record_reg") or a part of memory ("record_mem"). =A0And each >>> + =A0 instruction must has a record_t ("record_end") that points out th= is >>> + =A0 is the last record_t of this instruction. >>> + >>> + =A0 Each record_t is linked to "record_list" by "prev" and "next". >>> + */ >>> +typedef struct record_s >>> +{ >>> + =A0struct record_s *prev; >>> + =A0struct record_s *next; >>> + =A0enum record_type type; >>> + =A0union >>> + =A0{ >>> + =A0 =A0/* reg */ >>> + =A0 =A0record_reg_t reg; >>> + =A0 =A0/* mem */ >>> + =A0 =A0record_mem_t mem; >>> + =A0 =A0/* end */ >>> + =A0 =A0int need_dasm; >>> + =A0} u; >>> +} record_t; >>> + >>> +extern int record_debug; >>> +extern record_t *record_list; >>> +extern record_t *record_arch_list_head; >>> +extern record_t *record_arch_list_tail; >>> +extern struct regcache *record_regcache; >> >> Most of these things don't appear to be used anywhere else other >> than in record.c. =A0Can you remove these declarations from the >> public header, and make them static in record.c? >> >>> + >>> +extern struct target_ops record_ops; >> >> Once you get rid of TARGET_IS_PROCESS_RECORD this doesn't >> need to be public anymore. >> >>> + >>> +extern int record_arch_list_add_reg (int num); >>> +extern int record_arch_list_add_mem (CORE_ADDR addr, int len); >>> +extern int record_arch_list_add_end (int need_dasm); >>> +extern void record_message (struct gdbarch *gdbarch); >>> +extern struct cleanup * record_gdb_operation_disable_set (void); >>> + >>> +#endif /* _RECORD_H_ */ >>> >> >> -- >> Pedro Alves >> > --0016e652fa26d398870465647661 Content-Type: application/x-bzip2; name="prec3.tar.bz2" Content-Disposition: attachment; filename="prec3.tar.bz2" Content-Transfer-Encoding: base64 X-Attachment-Id: f_fsg1bwk61 Content-length: 33095 QlpoNjFBWSZTWXtR17oAhWJ/nf/8fRR///////////////4AQAQQEBhAAAAI YIWb74PniDQuWnEcPam1GW7cHnu7iQDDSO93K3yXudPiPsam9huynu++AoCp xC969CocHtVtd8Dvp3tCqH1K1t6662RMa5d2tpPXCuzY517ywB716DTV7ds3 bXgbetli72xc4GPPn3e+h3NdtOW2OuL6d7Ab21bHpyJRABdre3WnNjAdwBwh AfI1NjbA0H00PTR92HSS9b6cu4ZoSKqdYJ613dxV9ZFKPRocmns5Dkor20xX ZyqgHifL728L6Op9gMUew8759q9WxgF1WRS201mtVzl21uD6yrgt7O+w91gC QzZQKsWNGS92ubbUSlZAtlAlV3cc0VLZ93To0i9t2PIqcwFwbW2iL3d5Jbar Xud3OJdakj1dwdNmUUBVATdwaaQAFNNACNBomJoJiaamDINTJo2gmCaNJpky YQBoAGmgEQIjQQ0GiNQ9JtQajQeo0xGgMgyAaHqAANBoGgSNKSQjJNqAieky Mm00CaaDQANGhpoGgAABoAAAEnqpJUJsozSaaB6gBpoGgDQAAAAAAAAAAAEK SIIJpiDQI0aKn6epNTMDTTQp6TJ6ah6npB5R6geibRqB6jQ0BkESQgIE0BNA E0NRgTICnk1NT2ijyT9QjTTGppmpiBoGgHqab7QHp/+/uA+EDGnAFssCF6CQ h918oBA6CL+X7H7Ps+2YD3CsISPEAwBmYmRWctLlvnLjqaJD+R0amYOZiGAS AoOSiESqoYCu2hF0qBiQBknTiOAoAaJUEHJUpFEMIBsxB1GKCjgAHCUXUqKd n9P7f2aDuv1l/Lv+v9exwum6E6YU+1Up1rMpCUgURjbRtmrZU2WqKjRZjaSa KJakFWU1YtRghKBCEQfuIT1wP4j1aU+wff+b4wqu+T1fQP1fYPt/P+A++0l+ 8fV+DqB36avFbhYif3MEQ8fcv6dDfwfvCnaD/OP8Mv8xw5Ii381mDKqqkqdD SWPwp3OovAbix7ZHusUNJyKGXlVq3X0zydo0wxbKbTEsU2ltlMWplqbXlLca iJrbCKa0tKmpmlsTJlG02pbWixWbKrNNWjZQlaoWpMSzbM2myKkotSoJWmgW IpJCRYZWGVjWahZlUyuLh5XObM2oxYK0FjaYs2rRtSNC2xtJRaNY1lltorFp lIaxsW0aja1LZayJWBSFlDRIBgsoS4ZiuHy9+gf0k+B7MfC6CZxD4GlvmLj8 2dGJIW+qjtn9kH1wyhIPwIGkcRDhMRzi/DSm/roZBMsqHiQO7DDBGIBDMMRl LDEwqiCrZUKWTFm8cbdS6uU5FUqSwhyGZKRjMMRCQEZyDAwzAoXM1rUNpQwQ WRIQXzfnfK4eHygDv/u5mfwPUxRMeoP5fIoAd86jrI/r1nrouX4uxrM4IzZ8 EYrowOiP8jhGvsPb/gv7Ncf0N/owTF1OT2n/3Ykk7uz9Wvn0zEkO/nHk+Jrv RKYY2AIJKf2aNuja5/wyWJ1ctGQfLdPHna9B/aTwCAkmoJgO3q0OjlBien/v h/Vc43hgJI5ctAaWAkkmU67GF6uOcbZgFk6DWOhZSA+jZN7ffdaSA2DcyyOW Vg+goLroGhRRS6OR/ruEIbhGyOSlIQc4/GFjEdDHGH9H/v7bbHbohst7WOA4 MG8RuFb/PY0Swwx15uj2zPeO5N5C1aS8MZRqEtKTErXK8SxEwVbF0bA5wveM 4euwejpY0apWyDoezTqyE1ha1mSisd5GuXDjcl2iokaRoAsU6L2KHcva3wad JaOO1MS9dqURJ0bETq17CVMgAN8Nlq0aIaAmKJkIg+p5/f0cEKeMg5NHjT97 wO2Dbgkk407znrJgDnKxVLlVyBYxlCYu0liip06dc2UspZSycTrVrXzKd3D2 GbWVaGJMjO7YZL4iSLSaSMT7v2/o7/z/jV/z/v9HeWePp9ontsA9Z7ZS20fZ BrGxLKsUVWxsDztKW3MgyklsGNsWqjZGwGwsJbkkw4qFJay89rmOnrnDlhW+ 7mYmaoqJdpEM1JuZTmmqIKiNnWoonSwvLO/ZSsN7eqqcMTFpaYpEpBLRsBBa Rh1ClCXzsWtC0xgSr2KiN+4MsyBnGLP5uvd/N/N/PZfR+Pw7vf95/wihj8Hv v5MkFWj2u5dmshCiEg+zn2jaShJToClGpQoWN97AigixLLbXZuE5MFSRZ6cX VvcTPRZreIgMh+XnyH6xxE5ARwCMhOToTkaVfmiqBpIkFDfbjAQ1a5S0G0Pv kcCaaiWmhIhTokHcTlDTSNIVQjxg6oXRNKUU/U937Dr9/DgxBSwxo3da8010 2KrbGoSIylMjy9WVXFGwVo0WyISATP+OAuQNawpIhH/Zl+z+954OmcrjwF6w mDxOwitaKlhYNGiUbX6Vu+He0+HA8EiG7ySsGElaVpXfA1rGKNYmslksWLFk 2NjY2UoDbGAFlmoBgDY2FJUpps045SmNtAmGwjv3phsyHHMNQlCUFGkd45FR REH0ej8nX9rmces5r19GdUyaMghozm4kW5y5YspRmDS6VyV1y4cbblnFznNc oySRMsiIYyZKIhsspSyIpUUKEMRZFCMZhQYwYMTUWbs5oSEKFSlJYzEkUCGA owUokaKdrwGKc4Rrk3G5KCo0c5zccBbOc5TcXKystapVbKsEqtVGjVqNLbbb apaVLUsaSlYjFqxGtGFso1FbK1BWiNLJuqbSFJLLIWc6Qhhqs484UBmmHqOD jQtk0RVOZSUFvrWiHNYgpkVDkDLaUM7CtBqaLLdWsJbSWWGreuFm5zC2zZI0 IYp1xnCcpDGrbMC31rctbazS7ou8mRSxKRZJkEENFJrDAjMMImg2a3yc3jRG 9g6tqnbbE3FtElNdSccHmfa9HM2+5r0DS+rmmScR2Db+Cff+bqGTh1oGoGYf yfv4AS02PpWav9cBwhuwgjYl4DFyVsMSfaUAKQhoSJafF3uFoqFPiCWFOuVO cpizGscc1jrVejM3zcg3iGorYLLTpGgF0E5KDqEoGlFyAArfbYNKyROdMTi3 lRQvOPbhJqDh64RtwWjwk0awuNoiNbaDJ1NUYG85zvJx/n6fLxZvB9fynhX9 /nZ6Ov1S+Ls73d9VI/i/jD2GV97kbgKRZkhg2mFM+eMp04xx02nljOjY2xxr gdFA0ZdCcuocOVZvoqjtAVYdUchnVnZ+4tcsYlVECCxbPk79XeC7Fq56xM1A saxVpFrrvdR9XxlTwhQneCXJJKKU3a946ujs3gnqAWQAHxAFAKEBOuJ4dg77 nKWTbYkEAm8l7CiYIPHuxnTIn41tDhCk6D1CNOb/QDoRXjaCGW5JNy9nlt9Z fMIH9FVIyBIyfq7q04bXu2vCG4QMKYmyMDCaMDIKGlws348P3u/x8XjaflOs 4GKGQc5HIOhOyWigKGKBHZB4g4pNX6T84cQGEa9pI27s09Xkr4pQVfEW6car eJX5wJVVVOwT05gr+5Fe/MF0RIAIHoAgQFUPxQJ+VfX9HQanMsyYr0rtf3s5 rGAAAQAatRbUAAABEAAIAEgACAAJlBCJVGZViUAmZgZkY2ZUclzeMdEkRYRk wCshCX5LFKRGVezs7tlB2BpQh4JZCSWllPK2jtnvTH18HG8MGoVDqgVlpIzG VtRraNja1aG2m1tspSpq0mbFloTRRG1hMo2JrY2ymjQspUqJQhQi0hARAwsK TVRKMZbquu3VrtobRsREgjSO+AODRthiFDSmrBISRIWRIXbKooHUYy72pDYJ xjJT8OpRttiQbDy5oFOxTlMw4EShve+TwqZKmcVM2I5Z52VslyiSyRmGRDrb Dbbj8ym65wJHFld1pYGdkRJA4awyiMjAjLAoJopBiQrOVVGwbbDmgpJKJOcO OylhQyMEQFqyJdKbNg4IpYcLpcQGBaZbKWHddjhiANlIJtMUyNY1G0ssVWLF CEMsDDBZmRLlmEuEIBRqBAxNUuAIFRViBQ4txW1dBtXUrckiJquXNyS1XLAC lUjMFMBhnMwqasNRo1RkE5hMOCYjYY0JQymZidWIQBeJWlEAAYtd2HrawvSE HZSkHr0ZR+9K9XKhCPJHe+IY8Sh9f4Q7Qm7LN8ZfUnfwxdPi5ktPTYY6BldA OV5qNSHpQ1L7PnsiFE8g7q76lVE4VHSBDOMhaNjFIUa7c7nDXhmnIxKNbFGK /LE0L5ZeoTxyhqSJxghb8sPLv6ZThSaOMVwCxBabSgnovWGKHsigD+jY/b+F HCH8fx2D+5fW3KMYHKk5+c8XtSKfmAD8dO0nPyhr58sssbpkvp2zGPGA8fCq NUB1fmm28Cig3CToQkKhf1UGCfVodU+SQhJ6jZvkEOYqm0fxOPzp0eRl3c4M Clih20UjEIWeGSP/1wCh1DBkZVQgoiCGA26VkBwHBTzB+52a9e6n7jJ9tx5/ +IBQd0G08TlH4xQpIfOMQV3MgQ3HnWs1dzU9Jx8cePYGvwuiPiCeK7R28szU 38N+wK3JxpB8i51z+WPvy34dN+SXcyExDI91CuRAMdzumt+kBASwG3eXuKNy FiJWbKTJ7Tj2mvTrwFQdAmvVs4hv0piFAxcwzmZUMOIlVWChCjmGtGbDoczv M9dv8GJDMNMaB39uXGscL75X1VYkSBye0vdFNUsgY5onJECIkc6NZR0ZyFvO o5YK7KXL7hX31Ba/Pj+v5Dj74anDgWNoWegXUBbRj7S9peHj8QrsV+kdyGIG Tmz9hPkfruGCJ3aMlIFth3kLTDLfiZlo9qzn7hQIKzumWXrHd90YE0Rvoli1 VMU0kfqDLLc5ol4YzA5STOWXM4RtMT9GSaViZDN6vDizEAiqCs8r6sGO5rYo Vy5mbeUYH88Es+HjI6BMc3v5ZbNWIomPcdlNKaeGQeCQE/YNJtFVFF34cHe2 IRdJa7hRYq0KMwqG7HeOobIqFCwvr153PWLaBXKQzH8mkGaiFQcw6oCQGsGR YcbgOQAz536h6hyXXF1azoFiQwGpRYkNLsuuBWzc7jdxTA6AdBoqCsaMibVD AgT+JnDOvQrrqeGmNMhS5wGAsvxMDqnBiBNh+jRBwDXBrydsWWMxIRjIVtTG zEmNp0smcpl0o1iy5M1BwjaHxSc7eLWPwhAfTtndCEcOjB6jHf8QLy9DzJ3e 1JQNwiFYbTTHPE9ZJ8EUAZy9Hh5r4P4NvrXnwODtIRVFdIc6T4bBdQOX8oep fwoKREGCGMgA5+C/bCQGimqH3Egn0B9wDPX5+r7Hzkjf37NEfBuriHjiilIS C7T4+3ZPYkriObFrgK/ckBfuSKzAmhCBXAgDN8BDKlGNGAmVCJXUZkHS/ejv Tr4CddAcL8wk0iRcUar1qgl6UtOEAvEYSm0p0wu8ImjxkpBLEb9V0aLjpZsH TBy5+8MzcE4wEqBVUCkIplEGAPGW4cQtxipw5PXUA11oecHnAdA1hL72dSa6 CbFg0EIF4YvcAxcuWVrSRaDaCUZoFyGQXVP49Ts+fy+wPV+IB3mqB/tGIG+7 FwA/0HeprH9QOZnE+A8olFASiJ3umI8nIOcDR37pVJH3GuGpYCdoF4U0XxvC uy0ZNNDwEFm4IkoMpaCgWMAlKw0EjTbw+DwueQSSPzeP2D+LV+j5a8X0/O35 vO95YWVg789JfE1ffc78v1fXlpKafXJ7Kt8E/rdVSLzMZwfaOcZOUc21UPeU c6qOnudnwNf60h3Odw6iFB6ypa17A82Jc3kWte2b3rKv8JNMQ0rt7vopKMHU TMMINkADCMB4I/Hxdc1C0dnMrPruaGSBqcZxKNNYPGGRwqnGoGohJS510WDW jXQhcOjSrqAwh7968/pgJKDLPJXr2YmWMo8gJmaI5QLMKtvRpmEQiZIAAJYO EDghXPU7hVX7X33ntT7TFiXhwY+m0/Thg9ug15NFvfemkexiUgunR0AdVHfA OgD2fOnuAkFCW1YOKJeRCBO3KrQx7zlg5EZAyw8e3s1DbhYPgEmo4gDTxAqB MgabDg3+n46h4DhAAYAEZJfPAWA/7A3V4J5pyPJ5vDfgdvZ07+QOihqgmCgL U8XgAAkACSSQAAAAAAAAAAAAAAAAJAkAAAAAAAAAIAAJJCQAABXhdO9Sg5S8 FdLq8Pyu3PQ3GQ5eq5lfMsDsHxS/9VpxtlnQVoWscSiAvade319TB1pSkoAf 5J+bpQPZsn4oePq/M7Kqv1kqp8wbp5Tlil+0H1+kvgi6SSQUe3PpBh20UsPm 8LBwuEozAtCBop08Mi65DCRYZOWIZdH3g4hp2aQg9hz9KWOEVwhSDy5Q+RFm yVV7nyt32Ecw4NafniEqdCtYTVA14a2aF/vH+kTczHkHorjrXdbr2+3lD9fe pvHUX5telkHG/kTENahCXUqg1CIXaMs3VcrTkzUmsAICAykfRruwSm1325Oq t/yQCm+FUJ2g1RxQIGIcjsHNixBPIAsJrzB9PmKYEI5pQV8WdtnAFRq+Y+Nw LUDsM/lzppBKD2lVEQoRIajHRy4EU4n9oRM+tjsZRCEtswUboI8sbGsb4euu jarSBg2/X35d999A95vzQU7vORtrwXJQAZUAbnqqrMDizAceOVi/JKR5glcb lWKQK2PYHOl4D9fUrrv0zatVUMkI8TQh8a5Hy6mBsGhBFVIIYigcrEpnUzGO hdJuO3PU8c6WMgJfE54ERAHWgaili9/j7rpJqVVBDF0a5zGOu2rQKivkGZWb MWUHXwZsNUfFUZ3B8nT5OfseBv1AAGajP4NukF73YIM2XKj+WAC/dqQC5RuW PJycIQ5IsHRj9IFgETMIwEFOVvK8e88ePXY90FAiaDnztgNBXuXvbjMw/eSh mY+Fx7Cg0uAg8dI1cg1h3RmCcd04IHAWz8Pd6Gu4KElpy7w3MyDkUOO+OqQ4 Hl9Hxzb+aJD5RFsDtv3lEaxckG0TzoRnpQFZV0IucKYfHGo0sKCEX0aOPMIQ fdHTTV28DFga7dZuk9JQCKZKscMougAxzb8xdC+fBAyXKNYzP4XqA49iblMz 3QCD7FJ6DBl77d0ADkDxj7+Yo5EceGqipUUIyKSOXr9/T9FDtgMTuSd9yeRg DQZigvco7wQ+xqeyQ9B0ZQsEUAxW254vobCTtcASxA8PVxRqG1hp6tkBp8d9 mHT6PJ6Ord1dXXrGrcQeuWPKN/b68B1vRVq9BlhYT8omRDtxVknsQppABLEu BC2OoQC9U60O/5HXPf7/Hds6J5cDWIAfObn2Fgz2yttt9FFrTwwlz2BeB9IC 7l6jkPCIAMfKuoDAXSiY9iKEJCuRABA5Ftdtfm6DnrRDIJQzcF/u42TtZIVa qD4zjobSgucROiqQeA6AGxACACQoNut4fTWRUCpzMSMx1ot+NUPqhiD4X7+W rpB5dmoPI7R7jr3bG5YUzM4pcjWQ3ciWTPKqcTKIqCC47CoaoStauerNRVAz /Gp9KpAvq8DL30AD7NAxgxAA1Bi1UZk1L1tjFQ/zbXQz7A2GpEcKhgsmCIiX DXDTBdIvFVAKdwG6RCWNF+kWaAQG6LgeO2gD+B2n19zhwhnvAKgU4Hc7tsUI Vy2VbPbTuGWVGFsz1yiQAwHwAWFAabZLZQQBChGpT6hGNOiNGoP1DMqnx9aA BqImUaHSrRWc2DcgGkDSfbA9TIuXQr29HEME3IG34tHYcY82OPRWhCeIfSqA gjAgD2slQOheUyDQNmjKjRcJlK2S3aQpeFOfzadMYdN6NdJxp7LmAJYtYLBR 4aGjyK4w9Jc0DmBiGt09RD0X6SZ+uxtyBc/d28HI40GhGQdIQ9M6XHmHfruf P6TpOiq5ASmAKdrBIVQWBS3HbAEGH53fHuyzoQfWCQhpfU8fyGfA4a66l/A1 qKLfhoH4U2O6UHawsLaB6bLY0vXBbTbvPPqbiUSiHvbYP1tfiay/L50Ik3gv J16fRpuQeQ8RwUDupM/LztaXwoc6slpfKxbsl7eNUR2mMAdMB3pRvY9uR7J9 iVZPWbsFBJNBO5reRuxWhgGvENXHejR5ga0KJrpQAAGwPUJNcBgw68W4EAse y2sEl/SZJ0PXFoQ1j6I25G7pMdnDclU5jCwKcCgFPgtxAn1fItgeYZC9MR4x iR54VgO0KgfwjqPLlt4iQzRdH21GJ5gJSJyBurThc7SclhHKrg4OUlHJh8ck QLCHzROzY28eJfPh+jgHml67149E06Y6+7f8bbPqa6iKv1ss3owIDtGA1Zg0 0nQc+q6PbeOmW3KAwH2YbNw2HJ12DJLTEDMeAKjTxWKND3PAYetjEv0XCH74 6w6wyH0+u4cxEkUEDt2ZnKlufOp69xzMWP2HpU9Jc76kjCASQ3rfwvZ4x9nY GDggc7AjsPIoKbnUgBFgGiVKoSMGolftoQDsN9Uweov3cujwmYfZYq3RomdA ZWOHw78AdABuCBcrVTlrAXHpZ/oCEUN6lOAoVeCBtOiAOWGsLUk2oKhVVKhu UPcnUzi/WbGzATfIcpoGYGpzH1iBO3xFGRIT7UDd9MgbMHNjqFLgBQFHWq17 cT0gYYhCT110l4YQBYErqeRwT5j6HyvNyAeu31CLhUE+iJe6OQVoIKUhgeXU 2ja979So44ysAPDWXdSysLKuXwrOURIBHND9JcXECPhWJPGQoTfXo0RDhJQN fR2uxRB+RDhYK42oK5t/Z2/k4aEH35GlOX0bmRlB3iYtf3XQLW9Ur58ASrz7 MAv1DmdwYz5fNB2PpMZ2cmi/w+D8BO71dMb94ygbv1Vginp7pChgIBHAdmUk hh44oOcB/ddxE4bNWowVbZKBJ7e5xwA6EFuIjkygZls0JbEDHpKQIQAXHUIs WklX0kfIgVABkzWQRsQT7Xt8Y9dnun12eeA8x8R+M+78HzsQNt8oZ9DVT0EA D4COICRaSqAf6VqlSC9Z6x0gphInstGZNgvd83h+K+v/q+vxvxfDv+V6v0OE ZjmEMhCQkFgEUookysIG/zzJfs4Vb9XxuWnyx+Yy5Wxt0+VPxSfwdsZORgea RbZ0fp2gjZbrDWNgYpxmttboB/ff7Ho7u57u5/lv3n2nvi0YhbqVDtCScurs qDFqBgqhQJaAhXX+ohwCALIDkK6vT/2SIcEoUEDJCoxP9phheihz+dHv4YDX 49PR6et4eCfYphAkg0tClKWkl9KQLChBMR+FxZgRklKaaYYaQFKDxS9kmQD1 BAWpbGgP4/t/5X1PosOJ63+7b+1QOYAfyiL3SJkEI8TtMPFBTqQKVU9onEwF 8CNgMxAHhA5FAiZCxJSiakKQXynOxoYYswrAnFsBpRkVcgVDtihCkXYg/HI5 MDFDEiPC2zFRB4SCKeWVA3gB6ZCIRoUaRDIG2w4Qh+IB9ggAR0c/uDpeV7Ox qECJ+qLQn5S1NXeg0IPq84WJggIBlEoih/pCFGzE/r0zwI0/afnr7/n0PjmY 8focPSxFDnIUQBAQHM9vMOE6O7GKUGiSiaJ78lzNot7FIAEKF4XNBO+pQdAM itsRf4B5m8Od9F6tgA4qCQ0NQQRAgCNLFIIPZ9urY7JnVJ8XnzOf+Ncj6Zhk cHEBQNSgFRoeUHusTOWM+G+P0afTf35fHvg9qAZiBuG7YGtCUzx+/aNnjXor x7hr4YgYISgyhqDkmOU2e9Oc8ZbvkpzspZ874RgO5GeMYQ089M/5JRGj4Whu irdDgyzpaWq6KvIlRYnSYxXNOPzP7dI7OUBgYzT2DejgiBAm3Smadd3Q1r2n +kOHpwDW6HXqHZbh+T8/fOZ8AIH6804oTOEhgOQbWMZ9mDRx+u/eKDn8MTgL gXs5IVejwAoYKCoKAgW/BrBLkGR/PESfNyUaOHi2SeFf9zEm5UwZcvVQ+xfT ny+Zw2u3Nw42pRqPYRsIK9VJnhbNbm7YrCeOmPIlcv4NStQvCTGCZl37AaJF UgABiQjQUJUpQKJ6yXYcA8HYoT1RHNu/p117jH2FvKh8Ow6yE4uz34ddn1Hq L65bAtpJ6tWatASURoEyES5DRnGXMBnGnI/Vv0MtQvi17aADDed4WX2Bv81u tHnwkfCeJEsW102Ko2GbzSG02kb1UHyUspQ8fcZrLZClgd15MzbzuCXcx6Ci IHAiIA8oHT72DwZSUJkCGmy4HbG0ae32jRMb9zMYkDgUA0ml1G3MoU8DxcFv ozEJla/gqWIm0KxmXTtgeybK/Dttr0wdxVaQ+NcS86ZZXCI0QczKsA2ASi7g PZCiNVAWCkpIcasuDyx54ikUT4yNlYDLAasWlWQLTCaiYL82Woi2cMLI0CmS 3U+Tjhfbj15WsF0PjqAp0gDh54tIm+Z2Q7MHM0aAHkP0qNBwQNriuIrjEtpI +RfDC65TVzSR7SftIIJUoUqnulMIJlEpRiEpRCICgGSUESEkiTs952/Y3VRf v7yYAIv4IVQ4n4cFpiBO2aFZqqkDofzAAqhRhKCIjCBgsYKg6DQwZgh7n1Xu 08NxYDEpO8O4mzYRNgMkppCKElHBVQsHx+CfB74Rva1gPT9dP1YM4ZXoKCsr LZEYmvQ1rW+YnXs5F54qH3iGqrCBI34CJA0oGL4AEtKl1jao/gpaNOx1zPRH k3Y5MYl9CCKBRK6onLyr1F2buZStmNMsVmBXgiez1sP206lw/ZGADq93u43w dC49oH3mdq8X2Wq8kheWfV09F8okPSX4mucYY3LUR1bWo2tLPf5w1stvGc5x 4cuqrYUSnK2Y5Ry2WTvLly5npeR8B9ft5PtMtqaM6pPvNCxYvVBeGCWgNcNu 6fm1I6ihUARjwPbXZldtkeZnPxDQIjvscmYYhQ9+8IxNjnkW0ZlEhEjfL0HL ZRJH6GBUBQ0Ct6MjBpORGdGCLxAtSTlwSmeLeszQOs6ZYlhjW1pIoYox8wvj cw5d3GuIeXZcP0j0E7p4zhLcPX6DutzUFNgPMyvgEjQNKsSuSP3jbu6TA9V8 Ae31+PzBVyo9pYLDD8hWlaqXb2qQz0VowIkfOhb7R8Q/0/b+IFvuAoJBPvDX pCFhT/eBkL8TMEUd53IQPBQU93rPDUVIAYntDbsgMitjMg9jmVZoEAwdNhTZ JS1YZlTVhhuEYhv79HD0/H9TXv9Uef2du4G3HmhR9PpyKj4z42TimfH931Af N77qe/j9upmHRDvNg4SyE30MRgGc6ywLsbnaFcrSizGYae/gN7Vy9c1ExkC9 2m94DQOsDKBA06zUMHiEOIe1sD3m92+hiE+46jhsp+BiyNgOUYag5xcvra9Z zAPi9AfMBN0SaXBeekasdtuu2y+GXJw3aI+roijBxLMuhjXlLkYAK3O2Gf5Q IG6DeJaXixrQGhZlQquuF/AtkXi7vGGqjay4aPUI6rsU3wMHHlgLXqVV8QGC jzsCW4E9uHYOQSgQsOwJCBXMMObhVK7/XYNtLUeSt6dGx/zemMnr7AFtwqqV UqYOHRVwwVVhlRRRcNYQA/OHMD94puBmhzDU4fNqabb6XTjnWR3FDaxMuw1+ hMzB05a+3kUdA586U7XkGBAPs4tncAzkSGnTO+3C23ZjrnEizH5BUUP3/j/I WeuxjLY/npQuDUbVUolClLHFk0uWUKZcxqMiULf0NJrSh1YbhNYNduXCxRQY ERNg65w1TJN02uSt0txJEQAJUQx/KHaHyfr/WnqPOfze78vH4efl5cuoMzwc ykkkneEPL9XvD0hciBlX9AagfqAPo/eKeB+z6zx2L8UN8+T+ZOc/zgMMnECT 0LEIikAhwxb65JA9wCEKFZhEFCEQSHp5Ph/X6vzezzRzp3AAlAAGVaE8oP6H Z3rEHrwE6ipOQAIGLxjEIrxGZT/YY+zDtWBaxiYOQomZgVAaIhgrCIDM9Soe zLSzQbAhRUy+EqhYW7m77gLd3cJBAitO3z+XOc1y2x6MY9PyZi+rOuu+90Hm X3C8FaE4wytw5BbGPSMgAQUA7DwXuRV0IP7sUFAUgAUILAgJBFggxIgIezlv ptyqZlpX+D3AGrD6M7IbDlQY3tZLEAC8ahkyIt/teHDq45iOKwiXrXHsSAkl L3UDBFg6y+MCA/c7R9nwALcIZkgSMDYlbZznvtEy0z59x92DEXJI7lFjSbxl z5cYyLyGtcz1lXBVECKgrWtaBocGVaGYkUDg7lSSmQcZloziBbwIICmQClg3 TzaPpD88JAPsK0/S5tDvA3km++Mk+1N+GujxjQADuQNNFXOluEDgv4xM8h06 WBAITFnDPhU0d3dEfPb6Kqo17Krx83d450q9cZ807XtV14ms1VYG27Y059Oc ejq6duzXV3oI6hoBoBpQIgpUWGUGkWioqJvgwMnQ/1L3+SCSQSSCcYjYe3+b 5l9Pkd46Huz4aEuSqr2K0uogr0/UZ2zU7eRvw5YFQzzK1fTpVhZVAVEIBwhx BU5gFJQKQoBw88f2fTwfq+TxmhEnrUDsHar9Kr2+Se8hVWgQnicjKvnjTSAg oQtVMvqQgoUtVE0RGCiCxa1PJgggQsRbImuq5IsWt2oSCBAiGhRBRgBRAkMs mWUIHDsxNism1EqRvIfHj45Sk6+yEN9NvKteWggGLOtFbZp0HbiuM1xejTms yMtougAwACiAgAoPL4ec+j0KxZsvcAQADbxJCcgoqJtduXnGE5+i3Z07C9pW vy+b2dtzaB/PEXm+msILrx5H9u/TNyjJPlTsdKv7MqsXgmCYvftrqH0oKZQA FKzLXyzyQGQAAPzk3sVV6exwvci+tqEvWvsYQHiHG9LImWcbbu799TqgH4kh IEoEIdxud3hw5zieW3m4GpSNfV67u48/mn4B8E+V1K2JbGJw2lltLaG8Dl/h +HGmDNYzxfNQQCCiFCE9C94DAJpkAVnioQd78GsHM0BbzKsaYHlipVHc3GqI mOh+LQGNbhhQ5iE/YTeoOUzHMQ5ct63TcPpDR2eTvyxjO/E7vLFzUhKI95T0 FyBd3cQE1IQTMxMAakMpMy0TAA0fHdd1F0uEHUCNEKXd3UBNitVVPUKYhoh3 Z300JmZmcqtumpJPm8GDVt5O3t000nl0u7180+HD41i99eG3ndVluFOMVjni OQzF5dn0A7tQAvgEXTrJJJJJnOY6NxG438O5/A8QvHwHvIhE0/HwABd+Xhee F4np1XZN1d3QeZWZl3d7iEAQd4ChQgERLu7u5KOru8uBELEOzu7u76ssumDZ 76x3d+WlKP04QjPa7Xer7xtVQtcl3Npdsi2+2D4rHCbVcZt0QfM7RzNc+HHf kWHhl6LecDlB9kQt71b27age1k25kQB/6QAGzxKcvN5urWOuqEvERnKtEc9t MVE11Y/CeuWCM18aKju+wKPvaIliqpYjxhmGsAd+/mGXHGlTsVK79OtM4vHZ LdOyxb3aMzN3Ie0Qrx9B2Z8qvR0Vc7G218S1s1vLy82bnZkoReNQuRlXNyQF riC5ITfDctKDTG18J78KAIUnUarbFZervx71JyDWEkI7t+PRFz3+S72jj8PO YmdyHd2z0iHgcZhojmQAHd2PJYAh2iHdnZlZizYK4eyK46Z27rxXbi2cVriH tgXlc66wzd6967d+vkuxuHxkaxwGTmE7RjnPPoxPc1H0Vo1z2v0AD3JMPpkC 0OxWQx7du5/+3wRRQdhXfLInfyloiXd3dyrvQhoeHdWfwyPvpKgATTLNMkAA AIBRSZmJsQzRDuzvsrQa3Njk1xjF+fPolp168J0jahyOtWpsyUpZGGL3zU5N mEaVrQNq2utByIBhm6lUkkkmc0gcKaNwaMTcuU/xzyYaqvZs5d3d1d3d2ch3 d3d3Z70mYiXVXfMQ0RGRLxMquMNXPHY9VO/HX3Z7uO7TbJWdXOuuvJ54xjfB Dd3IzodDjD65nfmSSSSDbjtC3uFDMSpZ7lKdK3nOc5znjTJXGta1rWta1rWu S1rWta1rWta4ta+TEYYK8YVde+TB6kOVnn93z/c6UrokjO9GLA58sJQkx4kO QfFLZqby6tGJq6ldvvDdf3xWk4IYWPw8j8v8Oft4EJzDh98VC6MY4ylK+jdu 17mMYzdtrWta12Xve973ve973ve973ve973ve973ve973vObbiUpSdKRhe96 1rWta0pSlKUpSlKUpSlKUpSlKTnOc53pSlKVta1rWta1rWtbbfzXcxxxxxxx xrppxxtxvvvvtrpmI3nerh2e70zecZzjOdtNtdttpvZjtmM5znOumsbw5eOC YnjGa0xQgXtWVNb8RpOjxnTZLWDXG8YeVzroS7axrmKOt4w0UJd2pcLULb0y zazh1g4u8XVrbhnZbCqrRVNNy9y8rSpUSTGGoW7hlpmZrsFbqVJxNvDyFl1x dUwMXgxi5d6FVYwS9YuVnfcQc1i6dcMxcUyrjTSS1tK4qYLRi8CFtot8XZq7 ousCKB4WhqXGr8GmqcK0cLe3mN8r2p9OXLao2pZZ34IfDzs6uN9qSt1+oRkH R9+fNd+NMavjaad24HKdIdVh3hVV65Wtiaay8NRXTC4C2rw9hcM9nGMSGN4F uMXK1VwLRWda5PlS9WPfx8P6320TD/rn2MiBAwoifj9ID0ozsGrybvVWEYfR T0emj8suj5Vkfm5/pT7QQTtj8xbyh6SD3pSUhR25y43SBVXsGf9HPBf2egMj IEakhkaIYRRUNa+o83Uer5aAHxRoCB7jSQf0h50fLsv6snp0K686TWEg8o5W LWJCqPd8edg4D7YKpnEzCjANCjQAbn9feVtVS5CduxnGRsY7M/qTXbmK8/vH err5um42uL8YRfik+f/abdPtLeqpCw/jLTnrz9OfFyO2FGndp7meaGUCvOyU okhEVF7VYnIQEtpnRwKEQhHTpWDAiD618f5HpE/V8+efDTOs47lUeYg9bX0o SprEo1lemBaB6yj3Z3dHHpfjzW5hnXmtO9OsMQqmkpI0UqWki2JUJr24znOT Hx4lx07qy6HLhYy7+NxzhnGt6qAovbT4zAaLpM+mHe5XZP1y2Kyl+/vMDygf JUzswc2idC0iFy6O7azhEhxGcjIcMVFwfGqjYruNoFwRHLOrD3RjnIZDQ5dD Q7FtC031vBwVdu+uzhmnVW9rZfZORTQRKsSK0lOvgBj9MP3w+rJyhGcboaWO 6HqDaBiwnZEocQQSkS8T3yEhJb5rOnuug2h29T17e22hmi5hyppNIWYXhLgS 0DwtcfGqNcY9l0QLwQDjkyeMaezucP1+LUT2+k1+YsKyFP5QqD4oQg71P+tz fE6/vbcpeWrjH3o0vJx9E42s7j5t/Ue8R6D1Hu8a+KXcYFf4We+7tg51D1kU 3xYlIaFZCyjuvZNWqGqKuazxAc4382zVy9PIT09J5dLCpkKdMKg874Qdwfzu bzuv09GUvLVxj0xpeTjxzjazunV0nYR0kdPDjZ0cOhgV/BnS7hBzqHpIpvix KQ0KyFl6Sr50VrA5RV7Wdvd7NiN7qKnbdkzqDkAWMAMllH3rJZ61ddxGHjb3 6jyOb4WgYeYbPM841zZZJnlGsXDRAj6nZNZNJVwDZ+SAFPJVIKOqkqttyIrv n4no/Y2H49ev1hwb07evxb7957w84fP/eP2gH8IVAkyVKqf7//uP/S83pwA3 R3MUH+gQzRE2tOsW330f12DBkn825huG5VAHE2kgoiAwYy2DZ20O9sQbyYBz gBDCUdUYDQ4Ac0xMoKQmUQpCDbFMCZIJNsXiQOkAJMFvUSiJ5TyBgPNaI/UE p0gArer4zw5+1iv+q7SKcF/nEYE62AqFKmgPpQ+L1/Fo2Cvu4p+g+gftjgG8 NI7J86fF7gAw/fE/aJlmfnAr+6G4XCB4jqEDRNwYGNg3un70qpP5E/mKTbm4 SKG4nAS/6t2Q/8Id3f38QTv4J/AO470snU/7f9egnVNTxJIkhImQVZNUA6PM PROHojOnTsuX/1BVQkno8hOKfDmnlJOrYxNDuJiQkinnCT0UREJCfxD5YOra qKpB72V6MTiniMOlPIiom+x/jz9UNaA7U5ic/FlVVSSCSskKwCdCeHRJQfk9 RW6gB6Uk23OYTUid3DdLInnZXvuZ952uumMsHl6LejP22z20KwS1GxA2jIja 5jKWsVadv9JDuFbou3Iy790PPi1uei6juHjkZJzUUKIACRggbdsjD1Un/I5n o7vDwtjnGqSEFqiMDlPxmhhxIRCBwHg80WkVE5H+8obIewH2tIaxKA4GFSwA REQnUdeDmTv4xkKHQ0QO4i5BcEND/pWhNHQf1CbgXEjreLXo7c06bvuHHCAF ZkCyWSQ5NXAkkA2kCTegYuYnBOQOx1wKQLjklCAGPGJ/b/7V/bE39h5+fptf nBylpO86p2r18sp31hV0DNUe1MzQuGE8CyUHwEhdE92pMSUUQsCf1CbD6fCH pE5D6BI9bVoSDQPanRslRN3m0lBwULCCFhMHYNwgWEtE49pVVHJU5yE89Jum PIV4poOrKKq4GD2h70w0PB2QuyPiCpgCImqbJllG2xpTalSYxre+gCJIIHvi raKEjgeAnyTcbBsm6QDFHxEg5BiHvSjknIyE1a9AmaaJmKBEiKBdQAiUieAn f2mSctDV/KdAnBOkJOgOAdCYqdgih7oqqqa7l5LSX6nFG16wpeJK8bx8GJ3f IXCzI9Sg7Ug2TzS5YSGOI6AXOho1UJJgzKrTacspbLCZkQxnJJJShzAD5BkJ knfwJJJJ5iZ95yjYdxOd6S43DQNjhEAhdMgscEwlAxHGtCi04EPlA9FVUGnt r26Iq91d9gHgeghlr/Z0Ex2Q4h2aGgZZZUHiJE4YiejJuB5e+TUe8x3CZj3B sltvVZ85Z3kaPLm++V4B7O0u0fbRFUnq8vGvNBSe42DJbHalAeuHili6WUgP YwIahUDkodTskkgLnLACFQwhomQarkdORvYPYJp4cu+2c5XxZeQYlCgexsJQ igQTc5DZPekSlwBChieR58ndniEEyTgHkiaKCpxN7psamYnUO8PBNwF2T3ws PUcPjnmev2T3TYzbp7zcIItvFtfZTmcE5Nhseg9GkIyTknVuJ5Rdw4u6B7El N4TVNU3HAXXC4fOAyB300BZwh8PdhjFSLSiyPZ3lXk9WtVxSHqE8pltwsVJM ggXALEQ1cVe8JMx6BA0rkhjmZJsIKm45qIG/R/WFCBYUAggQe9UiKJUXIU2E 0BiJXUEhxEseXoOItBml0CBhTJCz2myP+aAf+f9tUOzqwh+9/iT+Uic9rE1Z eCe0CREPCefyyAl1QYM1id+QJ6FuGxcS4j32JJJJQmwnrSgTBmlAlEE2E6ee QnwTCZAapg+mwZ/4/hozMycwzKlQDqA9I8059pv1wQ67KokmYmQkUfTyZDOw e8wJYLDwO1Lpdo0UrYTqmE4pcQOInzj7EgHtg6jnEZAOnvy5XTBVTF8GLXvi rYvc4iZi9oe6E+FFVBAVCukhEYz/ZiUHRHJtaMbquHSzEMKsZFmLDJjnMDyA SAzSB58a6KcLM0cwHDu7hwR56JUlJRKDAROR4RCJwLJ4CWAEoTkd6AYTgaYO AX9ISEISHkHTBsKIcIgBmnNOiYQpQAglJYO02S4ckg4Hy0eQmSmBXaAG3Ukh JIlegeAQOgRL4UC3bxmIaROIecJT54T0SlUJzUN+1TYLKBc7RPAsiIeBunpD n3B1Lh6yJmhuHYsDlvPbVSJpVSdyd6didgaHhlJIqIqqtB1HBE5afK+TCKvP 4n1cKIMNYZnm0aNRXbVVUDzDrSw3E5L8seNDY1CPnA1SPbarUU1Es1RVWtgX wO2BxC9BFtCFAUJ6aTuVDVAPdjgFzy1ppLBzA6EFDyfyKn6WR+/+b5T8/Sg/ mv2H8x+XO+/2sCfv0lofZ/Ve36Pl19TqSHq8vwp+N+0fZpCqLP3Nvyta8++9 +l/TwNuPv853nxfXCjWBRXzyqfOQkBamtNn3nwPr3FkAn4WuexAKbJYyTDET 27a1uteZ38mTJkJM8vXavXXua91ZlEC4foPvA0iKB+dL9zkcXoVu1+/Qev0M ozMGU7LduWbFzAMsbSSUboIBuN2QiWd4sPuxEoWkyMloNI0rgsGGo3bBqS1x HFtl2xMYAzLakEXqt9AuPUhQw0Db80PwITAoBzyDnxDZ6IQO7l42zysTEU1E xMTExKRhIwkYTJkyZMmTJkyZMmTJkyZMmTJkyZMmTJkyZMmTJkyZMmTJkyZM mTJIQOAj3hnjJnyPoIJIiAn+r++ny95cMf9Qkw6LkKKnH95n+YP9Cfj/WG2g I/y/mE31ZJFVURVVtm/Qoi9Tt/srt4N4uKZps3CBhuxsTS1kqLKlN0kvRqdK HLmnItCzYz2z01tHS6ZUov4pC0zpM8r1DZDfZkZJQOL4hoZJb+xOKYE2MyhC jXMJRQaUnDWSSQkmzZAyyUlGafm49vHNMCETnnytGTVmXQa02lNwesPSTh1+ PfRQVAak1rE/VJleXDbbA5b8yKKorOR0lmzKUvI9Tgl8MoewtKlTrlroFk8P 0l/5Y9M4BMwgByCImZw3FJMdgbNjUxQSmUyl5poMKLXCECXS0zqVW1F8Mua3 QfI0Kttcgw6ENNo69CzBQoVMkqgkIpECCF3u12WMSb3WZ78wC7qKqcOLYjko cCA24WxDq6L6QNEJAkiEHLF6vrCxphlLLWaIywdvLtjVuzGTNBgSp5O4OxpK WAgiDtO3DmoniDiPPm3SGs0t++ljEESRMTaNvF1a7ND8UInhAPdvh0nJNucN wIbbmk9sx15DPKZA4bamDwcVCfNnM02GQULkCYTJLEbPTPnoymUEpyDsPCEl tCHGAZgCPmKg720RbtWgf3s6b0WJrctaiGZkZpRkg9jFWxlSAmAt3gCFAKHE I2YCIxZwxuDYj4szyQNNcoBKTnYtGRIkCA5POBLHXLNypcZJM9e/J2cxNC1H HkxNrB6MB2ClKUguzz47RcODZxDi6zfW5Fba05MTWbLEVttbVFYznfcPIBgO XLOhkHv64KwVV3UBS7sqq7hcxyvMCGIcDtk382RJ1U0lMSw7l6bBpy6SiEks AGB5elErl4RhXKbtV1eD6jv6enYu7H6J8xmNCauJbxwzjrgL+qWgwod9nvcE Jy0pfarrD1lBMJph9HD01GSq6aMxcoASklMnTRbM2tjDskFYWBDsGCHjUSlr QPEtdLgCHOwvTsJGSWzC456iHY3AiSJibLG4gBoIE9GHYLze/jx0YRUWVgW7 1KIXONvAM6k4bMaxzDj6amiisS7S8Mcg1YwYdhrr48mWxplgOOMTSQCRmR9Z +MP/9PzgbeU7TwO/rzdQQ/HcbpBh63Rgnj81URRQVev7/i+nWvu/B/s63zzy /b+7Tu9vSdu/w58uvah2kEkYRJIZoNhJTzOAiq9Q0wHEgII5SEBBWEHwYV6e YkIKwQ8qvYIotqU6+8HX4g3Kwqg9J8Ijx5Uom7B4k1oHEoUBILXyfo+P+LdO Afm0L+jQfjYdLBkRCXL+Hhr825/JwJ4PsNiQJhjVSkLk9Sib06EWh5IsppO/ sKDsqXO4h2cuLJqJ6BR8/Soch42uevFbqHEYGUGfUq8wFUoH+UZewifee77o wqoFFTgDe3SUbxoi3TIpaCd9YVoMzCaSLGLErnxzCntumWRgQ8CKmIBGLulF Vt/Za6aEdPdYBbW93EBt6Lq8ol4j6Ew/dOB0dUNC0hiHXLzg+zI0o8ZyXzjQ dbPzXAv43HOIkjt7jG/EuZPihAoBMJq3gZLRplancCbRWTy1o8zyXkvCCHSK FgRUivO48XzgHE1KQuSSCWHcY+P/AAHSwAFYEipAVkeewSR/SRQTb2EHAPDr 1tJ2BXotyD9A7dsgwSKzBj2Pb6e27eJrDuvyOIFgBQaCItVUCkMvFMvCbc0O 4hz5/5y+RYIhik9HbpXq9vKN9cDbl1aDtNWgyqGISsMjIapvPGKUFw4obUIc Q4bh+yDfuO6xxKL9vZbBcKMGmW19ADQMxc0FgiHb8tgttlYKFvbh7QcqDCJo 2V9ipu+EAy7R6kO3SA6qoNAHJAODyKpC8RT4WKySB03/N2/Z/m/hLLgQgqlw iY5wQSSCQSSCnl8tPKxnlt46thB/l8vC/QNmS1fLC7B+3pmiIiADGWarUQIm fjDfXKnkAjH1QDGY0tbK76op+2IYxYsh8iC/b92gI/BBvnpzLEv77P0gXB5R H8AD9qTPb0mgeIQPvO82yLwYj+vzjoZWUEgFX6J2HUMSwQDJqEPVauXMDgcv Iwlxn+K1VJgsQllaBQ3Pv5GZhKAiHDdRFoM/VPEknz01BPx4JIQoV9/0l0t2 9PeWqgJlkAJAAFqikNbDTFZ4cYwXoUgWtoyDJDEgWTfTPhYxxhyYpApuZOSS tJtiCaQWgOUkAGYG4DiPfKkDAAgKCT2s7q9vb2dfJndGMO3u9sc3LmXC97uG kFCQmcgkKEGhWKQNekS0ewEUXW24exK+BvZr2SJrMMNRiWpM3wX3w8H245EB u/Qe4pCFFoqlVoWlaVoUIIFSqUSYBSlAihhBYSQCWUllJJSCKRikgMRbnJN+ akefOh4/7i9/FPC1rdH8KIO2MWuJsmDIExt3xRWQGStM8b1FeaxkOESZ8xrW mVMrDFyEQHrDtI7yMhf1GeT8GxjFWWaTp5iKLp0Fd4M14hBvkZHhVqlHYV1O B2bMZLCQagYEYkpbPICISBYgKLgC7Gae/D6aqTmHP0CmpFIgweA9A7ZIe+NJ Gk+qZ4xv7kV9Zu8jglPtwMOSiCD5xey7p6qDWa5UkgSJ6U86+shcDXdOPgjj c9bB4rCYAIhEpoggnY46dRmGmAYGsbAZSULixtsKhWQ1S2X7PPX8PNMoCA51 B10HdDrB6Bq0Un7sx9kqHVI9t3F6bO0yK3+rAbBWpAp8Ylmz4zvYGdzIpFCj D1FQZarODU7jPO+Xs4TBvUx+FwDKxKkal/GgtaO2AoNyrqpp4wfTaaJCZKeh jDAJYSnGTAUNeQsHBEthZR5dgpYbAlgUvLy3nDAB38eUZTgDWtIIv+YmsxBo g1UE0rQvmJgheqPAjdC8KmKcg7dWAdBe5YaUbS0aYUSBgnKexQA4AoAMsAiF Ec4KB4PB4D4O3tzPdqf4O/16KUvmOq8L/b2gr3d1UaaELXnfVAipYgI4gHkr HkN+FlFxAMhIYSKeSQVzMighUiEG2kU0mYC6kAPOSBpWJUEkOSLAbwIGBICb 63HfaFQJTEUEZFTEcbI2cNy6kLLEMRZDQaJWSYqJWYiE3wEQ3QIawUzD4+yt 69vmUcSycOAZAUfa6wVRNWssX7hJqUUA6H3CkKkEcwIVzHCRAvDfNSDABgHs 9tFknwnQTkdAvd+4+kkQhn9n/4gKfcZFyqGiLRrz4IigfXZLdnTRyIZeVBpD UfrDYE0Hto6AGBCTnRXsuUZJ3q2O4aFg8n8x+71+uuaG0VkJBh9tPZCxFnoC BwJ4cQsw4AhxNcg9FFfX1/Nw8vEyBOc8k4cnMTu7ZMooBUc4NREZJLEUTrFD vQEyLnUo2MtWx7Q7bFFg0x3Bn7SVNDBgtt0rQ3DGdBHXxf18dMe9BaiD3qvM AgEcxah36/K/1ZmU1RfTNvhW87IEogBiAgUoqUiiZZRcxyEAsEcKGYSk0RNC aRHqhBQIAiVrZ3UYBO99liEJHtuJbTVRPFrRlhx7OGZfkMOGoAoOaBuEDYtp ZjKqks7ct77YjSBmbpepgulriUGls4HEDQOyzVrttVTTXgrpGgA0GAAAAAHd q7du13OvA73PN+J3O729W3bwg52C2VsddQ0SaVnohplRlYaCGRlZDsql8jgd HJzxobhAQe5I03gvhw7qUOc6hTbTwjVtgOJkFUtbDw6og7cUjY4wbVWcDSGl UtcQoekXsmWdVvKW0QqAVtbJzAyofcSJiApYgYAJFAXEhRlFXYwXBSIVUHC5 1eMpkNoEYAAT9wOHvDbg8AeTkuCvOAt6DmicOD1lXCWRCkDGHFk8soadAEaV YkMmGgFWxLwJVQHl3ACIgpUFUiWFXMDA2BvbSxVNb6GtTY2Ghu/AdG+xYPt+ /66n3/f9v287ff93rcu3Rv2zbXJaw1cerOzYSliGaXhp2O2w3EMYrCIgv3Az vmDS+pS9h9joevJuuaQNQilJxSh4xXIgprmUgFupKBzCAugZJnjeJhbaCCNY ALtK3GDkwaipSF7WVeMhvIcA23PZiD7jQAjtSUzMiKvSX1n7qKQT5ZtAYiF6 Tqgvk34AG+D0Gg6UQPww+U7TgZo47bOxJk4BZVBJQjQGrJDQa7n9DBbJsdou w96bNrXzUJtktGYW1W2g1d3dwD6+vYX6FfrDrVNqLaIbMyHmIuduvlwllQyi Ia36hfXs7AqxkNOhYNNAxe1jXB5tcp5wKH5BjhNQLtbWrhLbFZH6qOm2aWDj wsHFaK0C4eWcuSwOfMKB/pCbQ4mv9RSZHl9XU7B1h6YCdAIgKboHp0qxnqFh VDaNEEUA5BJMkg+mKJdIgaF/bOp6U707zepvE2WQieW6BZx9Z4nQesCSRcGQ 0G/2QJA+2/b1EA6QqV5K9ciiQJ2YCGMByY8jCiYrGx6HYQLG82BQd0B7Asnc Ad4ug5GeNbssTan4vpM00XwfpKPFBYf1A+/fxBOHMnYkhKI150PjHQ9VhNu0 wxR6XBcNjshNcNZbGo4EZHa7D/X9/6dPvVeRyT0HgSZBREQiqRUIiTD0or5h LSHkzt7MDZA8pr5grdhXsUahQ2jp5CDQFhekqUGsCQGCSvpkKuhpqGAwGRCp nNqHMtrbKrDtqUJkb5JIkLGSsWongjmAbJ8wxbgoTLMSIDgLosgP/MB60/s7 +KPh7vePvhVWtVqfIuiyEMbABFd+weRaANXiU25nsUrx+R45/QANTLBdrlBd QvFqYsRloAVmsogARntegOx1JM9myBlZZYStelbgUErQwQGQAqiJEdQIGKYI EGZBxU9m9LBEqLEEyEGKYdp2G3R3Gwb4DaSB5+shSMUtS2WgwnzbAqbWwpkG C+3QTU+XiYyS/pFTtOELdxNotOaknE0yo21kqIhIWUop5rmYGeHsc2KLmIYb zqiQ89d7bngU7IEUwAQoiaWqiork+RZFUfi07Pi7d6aB2CJqvAO0D9pA/nPM 0xQeehyi0LrtM6KgC1kYcfQ9OHdP1COthTLYnU/u01WbPZV2qo/m/krgimq7 PBOonIfofYM9YI0CymkqtJtVJtarMtkpEKJ1+j2xvsb/xSe8gNFqFghyCnMx pzF0GlDKgJgCkNZs819f2wPTA0lCUMwlAFL9z8P4fvZn09e/3un8PyeT7/T+ D9zXKs+We38m/anvoWKIZAdYe+QntXsVKUvFJBuJ3haFC+R7RuZuoNKyyAxu WSC9p5JwgTDhuYQ0HGYHfbVOED4fw9qXHKZH8Mx0VC0BCi6ApxLpZYIa0XQM wAu8KkZGqGVeuTKiml+BSoXT8Z+M/G1B88B3fybfTf6IBqk1KKDVZVkcrZd4 NJX03sDvE/JY/mLA8g9NE4w8ydCIZpknghVjub/qulyZeAlHf6Vbhy4hYiuD /lKL5IdBXHjjhKwqMTkmBIBdOOEfuR8+zrg+kALKdu4YU4WcM45A5Dm7Wo7c HGIomaMrMsMVcmmqyRwLIdGkJwoIjKFj2sBA3NbbythTvbYqbybbYBrWiiNM EyQ1Yp9iADnZzL52Cs87XvXYmRBbBaaQujBFF/g+fFPWoC1ROgNgQ9JcfcWl 2kkc1nAz0zw2MHgQUeHLRoNu/ReLw8fjaiqoikhIXj4vsBGwbRsdoHl6NOhY hCBkGZcqAYhXpXExAsxxXokHb0dp3oQcDA795v5cjIqWjRY2QOLToJ2D2Vo1 CDw0G50mwdNwTjMwxBwjTSQnkP3g08jvo8uJ8BIaEouKeMBnxHIOmp+3M527 TuUtLOoBovStzCFrPdj8h39Rl2kA0pOU1LorZa2iw4NkhprAKCjaizQYKgOw yaBHI6jsNh/wwJED4XoUmTMZIHtIhZfRDm4T5aHoHiDisi/4ZBKXJAwIpQKQ aCgyQcW4mlQXIQF7+KmddNMHiFhOp4z6zYy2XwxtBkPA43m74bh2KrLuceZu GtSnHdThQRVSxQQEEmBsYSkoKxx0PPzf+LXMIH6qCDBNlspHmH+wOH3npy/3 XeQWlFo/YT5yPwoqE+MlqP2P0p86zws2TSA0LSSX2/g5VGD7g4jQ1gqqtYMA kb3KsjMoTNmtsoP+T5fFE6D3w/KkyR3pfH4aiRragPA3dA3yQjqCpY0/aAUH 1exKPkC8dN6qSSH5aKkmxLbXDgIbrw4RERVY+r8pUVbbcczcnNWmrBYhCELE KLUUVmHIHr0mHfH2wP7sNtNy8LXf8/3+sQQCYEuuuquNyubrqUmaIN042Wji 5VTTIyQS5aULJSba4Eog7IykSJpbZbtSlylKoUtroWNDWA1OcLczKbY0G2Zp NpNsFUkylMGsNQ6GQbWOEiUtLApQKQpaFg4NpoGNJg0YhBEYFldS5DrXW6ur c5cOuqbFLQtlCYmxAt1fpmCHswT3vrHuYOlrw7GkmV+Mh8QQh8kr7HqTE8JQ 4vyXWA38jghgkSRUuMHf6fAYiGkQokmAtgFDPZdLqrt3oBLj+E+0keNK7RPR PjBfwhYmW3HQQv3iPz1adeqdc8sN2eNEi1gwgKch0PLDEPjQ1VIE8ws2efu7 r9xAr7qL4vZyMsXxclrSUPyL/Lz7z2K/Np7QrW4oPtKrPRez4YHpzicnKfAh RE0ZFhSILsOs4Ln1KswW2rShrXK9pRM62tYoPEO96xnurzOAnnyLvw8XFYDy J5gNKJoA9UTLB0Zkfaq/1yO/nweDFDixw20Oh+WsMEyKRA9wSwRt7QvZziGP 9VGRkUZH/HSgHqzGoaiER49Gh2878ByLfrwQyCgIlKT6koXNjQ2IpP5zOzbY FCyWZZfUB9QB5BJSwkgcOFPgqB3W2RPm+naU+j9tqqtVWqrVraitVVWqtqKV FtRVVVVWqqrVVqq1atWrVq1VVVVVaqtVWrVq1VVaqtWrVVVVVV9AfcWQ+QFg R7oIFBEEMw2BPrIJIqe4SixuTWsIyOgiIwD5WPj5eCfKQpw5nuQD5XRo0VKa U0jUNpVMaMGUwrwgGXzEO8P57iYbIiL1QGwFNs2M+d7iH5JepVpRIxuP+aHu L/G9D6c88wC4yg075krxMVKYUKeqQnsBD1k7fewDA1EIzIFAeIX2DSAkBlD3 3F7lgtzUgJChDkmcciB4+KB6VLwBUkBAOXEiwtCZ1H67R5Acc9rtTha9F2nG MqoSXCWtWKGlEUtUgpgOBdSvc0BJ2JhgfkvR09FBy9qeAOXJwnA3ES+9PFJO cWmMkj3E0rutI+Ko3jCHhZNDqwnlbGwfdCjWKywtgWgRRLepXkK8oIcaM1gc LlMlJXEI4W3A36EzZgiNssnia4ZmsqjAxEl1AG+LAXAZZKStFO8BefZNdMzi hc8OVBJqKu2WVzmVpw5jQBuQEcjbXS54OW1UBoQtaRod5UjA7SgpaKpbxofC t9UH9O3JBOSBiBkOjyL3OFL6giyC+6G/TKrnbgtH23vLF40w98bXxnnjEL1T ROnaTkWI+crNA4xNRs6w6dr/fmXaJjvM/l3g7n2hmappcPYnmx1JdLNrFVLN jp/ZedCx6+3S0tbTM5TjVqnoLN2QsRhM0/xWVQKA6BBaYh2e8qvaUilwgIA8 vPy7vxIZGyYPpDfKMzAfPJlRk5DIlLFFBAUMFRFGiScNCW+AYc911ZAvX+TX Zb+ix3+FIekLWxohD2xPCKSHkCH0UL6OZt2akk6JKZJDKRtcPfC3LmnT25nt hcNczLfuTLJQS+Rk+ij5+SSCGgKEmOOsBYAvGdu3ceimGpjiryksVJ7QoIBZ iBGaQClCACXxDqzJdzwoazLLZCnaGhOhiwE5yzkOFbScArubNQmyEhCQKcJ4 RsGlDID4OuO442ihgxJRkETRsBCrtmwtsA9C97CfZL/FMvMSOddD3VbtN+w4 ZO03lAFKQwgz8M+RB4iA6sefbnJnBgMdVmMlNDImrV2GoCpY+qUkPoF4JALW gH3EBoGCEB9qsH2RDK58wb8yqGdpaxxROUInIoHXQJJG62EOxPbx9SZYnUQm tQIJqWLp8Ig3jYPFNijcSEn0ibGtIEqJvD80EMYKpQaL/RcQuvnQ9gokt2ES g9EAuDaNJ/hPSkyhSL0/p50GZpnrmCKvDDYHR5O8LH1dVEftsKargPwycfmr 4/mvlzO+WbPbzbwhCBHsI85vaXlvneuCxdBEaAg9xpAMIgOPkdcm2M1GJEOi 3tgrPg4DbzlMVOxmFJqEKUd2unVF6KdFbgQ6LNwlbby46OHHmvSDD955deOx a9sDv+JJA8w7ySwDo+rexUlIkSXQEidQXHOt0bp2TSdAWgkCMMGtIkbpoolm wf5cj4jchtnVMFgtq+Wj27fPNZ6c5kOebQ5UcY1y+jgfMPaEOCcuwsYFbq2Q 0JEqWhiNJdLETvhLslkpIFLLbM8zOqHMbnED5xxhwIUODAWIlNICkCyC9g9l xljkB1RzbI4M8Jfmho2oPzPsgyw180CxIH5KSp3zA7IDsByUQoFPzptctIAy MIqBJLBU1RBdU4E4qwZ162FOs3gLUYHHHvhrjA6XCIyHd1qShrops8pzqhXg fL8CFj3MkcwJoRHjF5cHiWo4p6vrJc2iGSnphsRXSdQCgGBbV0mECOySo7Uy sm2CWZjYZhgLIa7c5GqWVqksqWK1aAQsKJFhLlajEQjaWyxLAEklMGMaZlkJ Ge7AdJpAgj0A/AF5C4lkTsVhQEPURA+gHxsHMTE4EfKLdTwpOcMspl9l7wLQ pqgojoVUXKJa0StwE5PAAR5w5cSqb4TRRPs69b7Trcww+bF0QkNEecxx/BuD lAUKQ92icoPDGDB8ivyWSRKQ4KBUiwJIBH9GsC9g1KYmVGeTnguNc7Nw0amA hcZU0aLAHMVdk0I+94eXydCH8KAobmE2SBshZBApA5jCNFkEH6onVIlHroUk zBUiSxWzIYUThHp5InMfOqwnqgJlUMLzceuppqOy2M7NHlA8aHAA+7KL2gMf WFTluAvm4jAz/q4n0vthzSFuSsYodZJJJKpddBNhdiD5UfjDwYmUBpgBr6NL yDLI+hOmE6JXCAXhIdMj6AkD0SAUw0y0X9nfC0JYCyvBYmlyxcYZotAlmBg5 Yrwh+csXOZw5k6W2uFBaNQVneieTdA+WMwxHVRLdAdwZMwMdnG11UowOIod5 FqVG9FEOVANw6D+gNNOBfdp5uuJpAQbPRjHIcCypRotI35YIYw2HAkwlw+dD lClthbDwAEQfbA7w3zLTNrYAhIlJ7gyvoGSY16KL2QuuYomRgGAZ8DoGnMp2 M9v8eX9yLvO7PV7/xOHiBZqSxZbMjkgZAcYmSQM4V7fnW3Pz/6J+/MP8eQfM oGff+K/1hAPWdwbn7gPWeLFTUcw+K/ThPgvL2SdnAJc/GvfHMyikFIjBpDzD rd44KTbZTzGASIfSZP5fVyLYg++aZL4HA2+ije2EDe7TtC29gaRAbyGqC1mV mEWRt19X2Pg3FFeJAgEQzQ01uWICSEiqFoKBlV9E0vrrroW1DvSxrtkj0bXT MDCZz2h7vf3n87B99GG05vvhGqHV3j3GLitCdcgmQ2UKuyoHptBCgiHRQ+cK CrAQ5+8xfFFIGaWa9HTcMpklKQ8cuG4m6CyB3NEC+uPzowPur8LUsgJEmRtv sJQ6ZIXUkRS8a1C/jOOQXjIZ4UWqLJt6wNFuTEP0B7YHKB9kLnX6qDx8iIUV R500SkqirWuCHI6HEwB8IMiFD/LPXb0kAdjxrXvAkiFgINQYxFQkSjBJZx8z v1z/ktif6J5B5vg0eFXA+bpBFXQZIfIkdsvghg1U5hx1TNMlPnT2pE48PfHI oLB26610AcO67Ph4aOzhJmdNqjiBYVFsNg0UJAkCtwvbQ99szO9U9SFkabi6 Al5Q4yJa306LbKAqgjbMSZ3wwmaZpaSRbyKbm1SSZGnSQYUtt67l0LGk7dyR fAuOFAiUDFd5dJC0kygZkSxI4+IZ1oUN4Gd6KqrF8jvvJewDwgWUTDSuAMFI 5HmUjodgpaFuzpk7h+T5+y+mitImiqDOoG6qo9+uvUJQoUtI0qpJMQIgESIg vUUZj7bEOEYGUcjRrDVkRxqBqOKWSmYaG0LAE67wCE+Z5ziLqc/ZGaaQfdOG i+MOwQEdu8dsPVPrOy5/RsbgSUm2YtBF7sMo4MPok6Y8RZPQpInuhA6ZaCJD UrF0borm3k2NQthe9/MofffC2K9QsbLEiYQDi2Mhz4tmK5mIglKA5jAh5J4o yLNJcT5XsHWNjcOGM9CzC5eqcM8FmFz23aiU770SE/L2pxLXKIOc7EcORZxJ 2babMDjG9vrE4w6hWKtCL9HZvJdyIOcKQap31oyyIUbb7BjtROLZaWSy9fPN snpzJ2stPR4HYcKnhSa+mc7sukkd1WmPGRCCQIXlAk6kUiIgCLiw5I/GIUOa KbOToyUcgMr6Qw6YeEbpAEx4tACGBvFtmRSB44+ASvSCh6fSYD3g/cBF8UDL fckOfJiWFQOSd2+MUZrJIQ1kH1lLKUlny4bJqHWAOUWWB34oKeQgOJw588XJ VhiUMMJGTEwNppCCkhhjboFgJCNYG+adn2mPCQ3CwpIKZiaKeRnhBladpQ12 pe/WQPq7cPL8kSsBC91wfWhTUJEr4ThBkhwuXw4JPAsHsUMGXdLhEA0ucuPZ nftI2mKCgfcb+WTgJguOyYkY6UhgDE0gUhopkBxlptCYGjFBaUE0FpJaKNUU 0W9m5xUOBkz32OgeoUFO4SswO4G9T8gUF5/nzVQzQGB82f0H8YIUw0HeWDhs xO3xevVgUoPHPt654NpQJNYSV2IdtXFyEDqPBBUcSQiEgDw+13teNIJGkZWi omVtlCc+Y0eagar5H0HnrXiAvgjpv6Brdrjy1oOxV0iBDHjgchDUkkJ5TvMX sQDsQ6wxsFkVbSylsAGQ7pNizBACAU6qoHHPsCx/GFgOz47Xg6qarCAyAwSC DIBaBseza3gZBxM/q1D9yYx2b02Ap6D29pVJCSBsYzs/VbKHhlzLlcTkaBoB wDckAl5D4m2Eud4RCQNCMImyxeBnjlPBCEEDGDN4w7u7xBTcj1OFDDElCZw3 GoTh2Jq6zUzaA5f/DuWDbOsoESBL2qpZ4zsge7FIbgtyp6q3g2DbWc65BADF 4BIDwCbCi5Z2OOJR0iZc4a5XCpVJUhDi5aHC70TWMNjkEKmQYIQhBQ2HPMPv qmT1bY1FwMBweMOJAkcQnAyg4zwHcaIeo7g6bbHSi2+zqRqXWA3NBrjiiWRA JAwo5IIYhHycaBYFJycVbMGarlB1htRnTT46xp0mr7EAyhRAGQQoQAdkCHjJ EYZN2B7EgNASiFAkEKeTvmJS0kUzEeh552Z4+GGQfmPJzDVVyKsJkWHLHaBu nU5KAdgcukOlYgFbXvcQUG9USqbMEbYDbBQZgFzK8cIy0sGV5nLwzC2IWMrT CWQ6ck5SXSg2KCl9pIELnd0x3XOR2KdmEC4m50AZcnGwXXaaTs4IWhZCw98o ny54b+r2VmjgxZ7K+uykOVA2iZdSSUvbw7Tr2V5qGudD2GZD8p3oSLpnn5Be 1hgHTtqSjsdXssXydgkDL+zMBvkLAn+PMi6y+1aEJmO0ejxXB8YDznfrhJ5D kwZGY8vt8qqqqrWlSorAVtRWtiqqoQVFVRUVVgrFVVVVVVYKqisVVVaLUViq qqqqqqoqraItqKraikViqqqsZUqqqqqqoE4w8mAeof4Q5PlqY9h06Z37kTJQ fEra5rUPTnd9fZPekh3S80yKGKSSrzc9CmnmN4en7KNLkE6k6w0gqvYwKSwJ 4J723XR5Q4MtkM4MecPJ5x23eJmtk24bGgBycgJTCxqJVBMCRxgtC7dQNjrq lYAqnOFUU2s/HhwtL2s5UGaxNTTm6ZklD7HUrQBEtCN38zPivsegy8/n1T7H oBD0K6MD0QZWQYMx3IDhnZ5DDTuXhLo0UhhgQ6Z3WVtYKRJ46AWC2Gk4B1vy kYNmMGBPhzoLWgeu2VspbKKUkiTMdhRtrs30uXO8igUpaPAhIcTJVo95YPSf H15GXMklMLdBdkGx1cvZqKdhE7pFeskoU0Rq1Fq3a2lRcc2SpWbzAPBO3mJ5 51hfmbFecV80EndQO3w9Hh7vh22hR7iVanatDCy5e2DXJdmHzEIXC/1hxsUb ChQoJa6sRZKAGfnCCmpZpTT1lIyJgOoqwodyqgJYWYmHDqx0eKpRlEBCyFzA xAoyzzMrWsQb5U3kvuzFOwB5wQ0CwatGudWSs+dFZXzQMzPV8eOWs9QZGknE dKipSxEgvoEl3KCgkPVDm9voBAdA4FI4QWQ4Vy0AYFibnLAXIKjIEzgFnCog jIgBMCKVAyxNprDJ8N6MXqFmcQklEQAuF5M5U3vfTsh9XuOwW+KzVvnYD4nd g0nY0PR6EztASWGadHdaI1MyrzqUYJjDiJCoBCBcUwGYyMIy5iGVGMLhagS0 LZXbBBAMaVYV7yiIwlxgBAygmEdWZCwUJR3YnAAnN8GlzQyMrBDA4aCngXxv M7YKHIOJIEhUmSBptlYIY0QpLMLDIQzM5boIRchFAxfCk8Djb4TpDTpbe2u0 LQtuRsvQtQqFVRAOHQhXJQB7DsUNSJuHXaXEF1kjXDkHboHpnBjIGhrcrpQu Z18jVyjZrKQvHWXktMNsqKb1vpldI4QvLLOy6oGXDOxAkCSCaA7x5zbY2Mir ZTKFomuCjDEGweu3PufEE4ddiFTteHqB7HXE8dHUk5dUYECIUOqK5Jh1RgRN pMSrUN1CxA0oImujhUNO2i68Tc3DHYtKawILLoDHDaFKJ2DR1myrjGxbMukC NYOkGLFLCF10sLRF0HJInA/htpkv7KkkTMschzgNB0G2EJdYie2PofsKDt8j 12DP8Cs7Lix+ewUEIoWRfhQW+WgnwucOtHySpSiPl7cVu3LA8AHcmw2npTxc zIRVIetWQAgCEAiGN1Qx3xz0nzqgsLWos3okvSXZRe3fYcEmObdUt5Ro5YaX 5IH2AEO07mTu9/v7wd6vyYxioPHscycQdUIgGQBGx91SVNYFwjVzzE9wkYD8 IKHQ90lDHTgmB7VxkIRik0uZHCW+TgFDcW4GsC7QdM5W78ehyJEeYnhJ7YAT wgQyyFTJVyKEOPCOgwM1+TMA2yHFC2DoPTF56Cjp18Fczs5iISd9vBDaLXEM te4yrMKO2jMskBxUih/VEOHDTGUZnw2A8lxCQAmWmkJQgDtM8QaMtwqQzMsw MDFIHiawhOYHAx4Fhx6dLkMygDo6M1o+I9j5w7iQ1h9adJAkVTVRMSVSBBsW NZq0qtyCq4AgSBE0BFB93PsjJ0p09fj26hVFburopteRVTbJsbsp37d5aG+n oYtDZmobIalobM0lktC1qG0C1qctV+mLIIfAgFEHviht1y8AlDiNWx4+myvi lSiG/EyAdEYBziU0NCCF/dJfHXI22ysejiVI5R0jbbOzx+oyMoDZXazrda+s LCHEX04CyJKCpm0UWVAWle/nzVvRwAoeTgDdLhOwWG+Zjv8I9FQUbO7lh8Qe Gee5vn0odRyFIJTQIq44foBsHIPJVA8BXSIHtIBQ9f4g2UIkE8xAd9d8jYqB CjsFydczqz3k+YtSvuONtbMVhaWGsDHDhi08vpTwDyD7A6A0l1D6VTh2GxQh SSRkDhLMFAQSlFO0g+NAO9DltHkHUt+F7pdXc6wDkmaiEY8AyH/KRnXAYOuY LYNM+xeYcumfK4FV++2vYIe+IhIWAyIAiYHiB8LTHNkEF0mlWAwhEbu4HcDq 8wiEiwTyPRBbabnd9H+jtKP8AGw1YM5A1/hVQOgXCAQJaej36FWRTn+uJoGF cPVRB9p/X/H9VJ85brao5TUyo9Wl4hKRXTlU7PEtaTYPNYasYC8K+YsYSkaq T7D38E0X7opf6KO8+QUofqEkNtDiePdRzgUULx+eiQ1qFw5ot9S9I2WgNYaN 3xMVZowdzliSWya/LBHZkF2+B7w0ScJvYhEkSfIKH+9euQqDAwlUcA+bnXt9 lASI9OgGz9PJ6wIdBNomSaHEA+e3fzoyg9IHdFfywkVecH1Rag8fE14pzOxR yUubxeBZzzKCdsWgkUwZHgH6gr7B7Wv4SpLQYGQmBRn5wB1oggX8++yiA8Ys WJtIxByMGSZgEVEPOYAMoZfIHJDHSIV4ty1oVq3kZgWgcfYgajSvNWAeHvnU jAxmDshaWbO4EBH0d6PrD5Bker11hS8FOwgGr5amuxoYNDP4x3ipvkJayQqQ JVekIpmnALumZM8jOImA4EKxWiNiVlLbmpMFisU7z/aRO2B6hDooaAhE1C90 EB3VReIKX/V4P74CAmkNjgl+/HfSeBZGBYQsra0EIKllAP+cIKlxZe4j+uJg v70BwchPKQ4cIKf+bZLgSBKASH3p1IGSBDFAUIcPy9HSnQb8XWIYYGkDBoWl haWSGgJEh2uOM4gDIctOuauTaurbsQtJsaihorvEYEVkHAYB74OR5+rbPGMr 2s3zuuO7Qu5OYK/8BdyRThQkHtR17oA= --0016e652fa26d398870465647661--