root/arch/powerpc/kernel/kprobes.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arch_within_kprobe_blacklist
  2. kprobe_lookup_name
  3. arch_prepare_kprobe
  4. arch_arm_kprobe
  5. arch_disarm_kprobe
  6. arch_remove_kprobe
  7. prepare_singlestep
  8. save_previous_kprobe
  9. restore_previous_kprobe
  10. set_current_kprobe
  11. arch_kprobe_on_func_entry
  12. arch_prepare_kretprobe
  13. try_to_emulate
  14. kprobe_handler
  15. trampoline_probe_handler
  16. kprobe_post_handler
  17. kprobe_fault_handler
  18. arch_deref_entry_point
  19. arch_init_kprobes
  20. arch_trampoline_kprobe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Kernel Probes (KProbes)
   4  *
   5  * Copyright (C) IBM Corporation, 2002, 2004
   6  *
   7  * 2002-Oct     Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
   8  *              Probes initial implementation ( includes contributions from
   9  *              Rusty Russell).
  10  * 2004-July    Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
  11  *              interface to access function arguments.
  12  * 2004-Nov     Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port
  13  *              for PPC64
  14  */
  15 
  16 #include <linux/kprobes.h>
  17 #include <linux/ptrace.h>
  18 #include <linux/preempt.h>
  19 #include <linux/extable.h>
  20 #include <linux/kdebug.h>
  21 #include <linux/slab.h>
  22 #include <asm/code-patching.h>
  23 #include <asm/cacheflush.h>
  24 #include <asm/sstep.h>
  25 #include <asm/sections.h>
  26 #include <linux/uaccess.h>
  27 
  28 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
  29 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
  30 
  31 struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
  32 
  33 bool arch_within_kprobe_blacklist(unsigned long addr)
  34 {
  35         return  (addr >= (unsigned long)__kprobes_text_start &&
  36                  addr < (unsigned long)__kprobes_text_end) ||
  37                 (addr >= (unsigned long)_stext &&
  38                  addr < (unsigned long)__head_end);
  39 }
  40 
  41 kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
  42 {
  43         kprobe_opcode_t *addr = NULL;
  44 
  45 #ifdef PPC64_ELF_ABI_v2
  46         /* PPC64 ABIv2 needs local entry point */
  47         addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
  48         if (addr && !offset) {
  49 #ifdef CONFIG_KPROBES_ON_FTRACE
  50                 unsigned long faddr;
  51                 /*
  52                  * Per livepatch.h, ftrace location is always within the first
  53                  * 16 bytes of a function on powerpc with -mprofile-kernel.
  54                  */
  55                 faddr = ftrace_location_range((unsigned long)addr,
  56                                               (unsigned long)addr + 16);
  57                 if (faddr)
  58                         addr = (kprobe_opcode_t *)faddr;
  59                 else
  60 #endif
  61                         addr = (kprobe_opcode_t *)ppc_function_entry(addr);
  62         }
  63 #elif defined(PPC64_ELF_ABI_v1)
  64         /*
  65          * 64bit powerpc ABIv1 uses function descriptors:
  66          * - Check for the dot variant of the symbol first.
  67          * - If that fails, try looking up the symbol provided.
  68          *
  69          * This ensures we always get to the actual symbol and not
  70          * the descriptor.
  71          *
  72          * Also handle <module:symbol> format.
  73          */
  74         char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN];
  75         bool dot_appended = false;
  76         const char *c;
  77         ssize_t ret = 0;
  78         int len = 0;
  79 
  80         if ((c = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
  81                 c++;
  82                 len = c - name;
  83                 memcpy(dot_name, name, len);
  84         } else
  85                 c = name;
  86 
  87         if (*c != '\0' && *c != '.') {
  88                 dot_name[len++] = '.';
  89                 dot_appended = true;
  90         }
  91         ret = strscpy(dot_name + len, c, KSYM_NAME_LEN);
  92         if (ret > 0)
  93                 addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);
  94 
  95         /* Fallback to the original non-dot symbol lookup */
  96         if (!addr && dot_appended)
  97                 addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
  98 #else
  99         addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
 100 #endif
 101 
 102         return addr;
 103 }
 104 
 105 int arch_prepare_kprobe(struct kprobe *p)
 106 {
 107         int ret = 0;
 108         kprobe_opcode_t insn = *p->addr;
 109 
 110         if ((unsigned long)p->addr & 0x03) {
 111                 printk("Attempt to register kprobe at an unaligned address\n");
 112                 ret = -EINVAL;
 113         } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) {
 114                 printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n");
 115                 ret = -EINVAL;
 116         }
 117 
 118         /* insn must be on a special executable page on ppc64.  This is
 119          * not explicitly required on ppc32 (right now), but it doesn't hurt */
 120         if (!ret) {
 121                 p->ainsn.insn = get_insn_slot();
 122                 if (!p->ainsn.insn)
 123                         ret = -ENOMEM;
 124         }
 125 
 126         if (!ret) {
 127                 memcpy(p->ainsn.insn, p->addr,
 128                                 MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 129                 p->opcode = *p->addr;
 130                 flush_icache_range((unsigned long)p->ainsn.insn,
 131                         (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
 132         }
 133 
 134         p->ainsn.boostable = 0;
 135         return ret;
 136 }
 137 NOKPROBE_SYMBOL(arch_prepare_kprobe);
 138 
 139 void arch_arm_kprobe(struct kprobe *p)
 140 {
 141         patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
 142 }
 143 NOKPROBE_SYMBOL(arch_arm_kprobe);
 144 
 145 void arch_disarm_kprobe(struct kprobe *p)
 146 {
 147         patch_instruction(p->addr, p->opcode);
 148 }
 149 NOKPROBE_SYMBOL(arch_disarm_kprobe);
 150 
 151 void arch_remove_kprobe(struct kprobe *p)
 152 {
 153         if (p->ainsn.insn) {
 154                 free_insn_slot(p->ainsn.insn, 0);
 155                 p->ainsn.insn = NULL;
 156         }
 157 }
 158 NOKPROBE_SYMBOL(arch_remove_kprobe);
 159 
 160 static nokprobe_inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 161 {
 162         enable_single_step(regs);
 163 
 164         /*
 165          * On powerpc we should single step on the original
 166          * instruction even if the probed insn is a trap
 167          * variant as values in regs could play a part in
 168          * if the trap is taken or not
 169          */
 170         regs->nip = (unsigned long)p->ainsn.insn;
 171 }
 172 
 173 static nokprobe_inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 174 {
 175         kcb->prev_kprobe.kp = kprobe_running();
 176         kcb->prev_kprobe.status = kcb->kprobe_status;
 177         kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
 178 }
 179 
 180 static nokprobe_inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 181 {
 182         __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
 183         kcb->kprobe_status = kcb->prev_kprobe.status;
 184         kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
 185 }
 186 
 187 static nokprobe_inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
 188                                 struct kprobe_ctlblk *kcb)
 189 {
 190         __this_cpu_write(current_kprobe, p);
 191         kcb->kprobe_saved_msr = regs->msr;
 192 }
 193 
 194 bool arch_kprobe_on_func_entry(unsigned long offset)
 195 {
 196 #ifdef PPC64_ELF_ABI_v2
 197 #ifdef CONFIG_KPROBES_ON_FTRACE
 198         return offset <= 16;
 199 #else
 200         return offset <= 8;
 201 #endif
 202 #else
 203         return !offset;
 204 #endif
 205 }
 206 
 207 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
 208 {
 209         ri->ret_addr = (kprobe_opcode_t *)regs->link;
 210 
 211         /* Replace the return addr with trampoline addr */
 212         regs->link = (unsigned long)kretprobe_trampoline;
 213 }
 214 NOKPROBE_SYMBOL(arch_prepare_kretprobe);
 215 
 216 static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
 217 {
 218         int ret;
 219         unsigned int insn = *p->ainsn.insn;
 220 
 221         /* regs->nip is also adjusted if emulate_step returns 1 */
 222         ret = emulate_step(regs, insn);
 223         if (ret > 0) {
 224                 /*
 225                  * Once this instruction has been boosted
 226                  * successfully, set the boostable flag
 227                  */
 228                 if (unlikely(p->ainsn.boostable == 0))
 229                         p->ainsn.boostable = 1;
 230         } else if (ret < 0) {
 231                 /*
 232                  * We don't allow kprobes on mtmsr(d)/rfi(d), etc.
 233                  * So, we should never get here... but, its still
 234                  * good to catch them, just in case...
 235                  */
 236                 printk("Can't step on instruction %x\n", insn);
 237                 BUG();
 238         } else {
 239                 /*
 240                  * If we haven't previously emulated this instruction, then it
 241                  * can't be boosted. Note it down so we don't try to do so again.
 242                  *
 243                  * If, however, we had emulated this instruction in the past,
 244                  * then this is just an error with the current run (for
 245                  * instance, exceptions due to a load/store). We return 0 so
 246                  * that this is now single-stepped, but continue to try
 247                  * emulating it in subsequent probe hits.
 248                  */
 249                 if (unlikely(p->ainsn.boostable != 1))
 250                         p->ainsn.boostable = -1;
 251         }
 252 
 253         return ret;
 254 }
 255 NOKPROBE_SYMBOL(try_to_emulate);
 256 
 257 int kprobe_handler(struct pt_regs *regs)
 258 {
 259         struct kprobe *p;
 260         int ret = 0;
 261         unsigned int *addr = (unsigned int *)regs->nip;
 262         struct kprobe_ctlblk *kcb;
 263 
 264         if (user_mode(regs))
 265                 return 0;
 266 
 267         if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))
 268                 return 0;
 269 
 270         /*
 271          * We don't want to be preempted for the entire
 272          * duration of kprobe processing
 273          */
 274         preempt_disable();
 275         kcb = get_kprobe_ctlblk();
 276 
 277         /* Check we're not actually recursing */
 278         if (kprobe_running()) {
 279                 p = get_kprobe(addr);
 280                 if (p) {
 281                         kprobe_opcode_t insn = *p->ainsn.insn;
 282                         if (kcb->kprobe_status == KPROBE_HIT_SS &&
 283                                         is_trap(insn)) {
 284                                 /* Turn off 'trace' bits */
 285                                 regs->msr &= ~MSR_SINGLESTEP;
 286                                 regs->msr |= kcb->kprobe_saved_msr;
 287                                 goto no_kprobe;
 288                         }
 289                         /* We have reentered the kprobe_handler(), since
 290                          * another probe was hit while within the handler.
 291                          * We here save the original kprobes variables and
 292                          * just single step on the instruction of the new probe
 293                          * without calling any user handlers.
 294                          */
 295                         save_previous_kprobe(kcb);
 296                         set_current_kprobe(p, regs, kcb);
 297                         kprobes_inc_nmissed_count(p);
 298                         kcb->kprobe_status = KPROBE_REENTER;
 299                         if (p->ainsn.boostable >= 0) {
 300                                 ret = try_to_emulate(p, regs);
 301 
 302                                 if (ret > 0) {
 303                                         restore_previous_kprobe(kcb);
 304                                         preempt_enable_no_resched();
 305                                         return 1;
 306                                 }
 307                         }
 308                         prepare_singlestep(p, regs);
 309                         return 1;
 310                 } else if (*addr != BREAKPOINT_INSTRUCTION) {
 311                         /* If trap variant, then it belongs not to us */
 312                         kprobe_opcode_t cur_insn = *addr;
 313 
 314                         if (is_trap(cur_insn))
 315                                 goto no_kprobe;
 316                         /* The breakpoint instruction was removed by
 317                          * another cpu right after we hit, no further
 318                          * handling of this interrupt is appropriate
 319                          */
 320                         ret = 1;
 321                 }
 322                 goto no_kprobe;
 323         }
 324 
 325         p = get_kprobe(addr);
 326         if (!p) {
 327                 if (*addr != BREAKPOINT_INSTRUCTION) {
 328                         /*
 329                          * PowerPC has multiple variants of the "trap"
 330                          * instruction. If the current instruction is a
 331                          * trap variant, it could belong to someone else
 332                          */
 333                         kprobe_opcode_t cur_insn = *addr;
 334                         if (is_trap(cur_insn))
 335                                 goto no_kprobe;
 336                         /*
 337                          * The breakpoint instruction was removed right
 338                          * after we hit it.  Another cpu has removed
 339                          * either a probepoint or a debugger breakpoint
 340                          * at this address.  In either case, no further
 341                          * handling of this interrupt is appropriate.
 342                          */
 343                         ret = 1;
 344                 }
 345                 /* Not one of ours: let kernel handle it */
 346                 goto no_kprobe;
 347         }
 348 
 349         kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 350         set_current_kprobe(p, regs, kcb);
 351         if (p->pre_handler && p->pre_handler(p, regs)) {
 352                 /* handler changed execution path, so skip ss setup */
 353                 reset_current_kprobe();
 354                 preempt_enable_no_resched();
 355                 return 1;
 356         }
 357 
 358         if (p->ainsn.boostable >= 0) {
 359                 ret = try_to_emulate(p, regs);
 360 
 361                 if (ret > 0) {
 362                         if (p->post_handler)
 363                                 p->post_handler(p, regs, 0);
 364 
 365                         kcb->kprobe_status = KPROBE_HIT_SSDONE;
 366                         reset_current_kprobe();
 367                         preempt_enable_no_resched();
 368                         return 1;
 369                 }
 370         }
 371         prepare_singlestep(p, regs);
 372         kcb->kprobe_status = KPROBE_HIT_SS;
 373         return 1;
 374 
 375 no_kprobe:
 376         preempt_enable_no_resched();
 377         return ret;
 378 }
 379 NOKPROBE_SYMBOL(kprobe_handler);
 380 
 381 /*
 382  * Function return probe trampoline:
 383  *      - init_kprobes() establishes a probepoint here
 384  *      - When the probed function returns, this probe
 385  *              causes the handlers to fire
 386  */
 387 asm(".global kretprobe_trampoline\n"
 388         ".type kretprobe_trampoline, @function\n"
 389         "kretprobe_trampoline:\n"
 390         "nop\n"
 391         "blr\n"
 392         ".size kretprobe_trampoline, .-kretprobe_trampoline\n");
 393 
 394 /*
 395  * Called when the probe at kretprobe trampoline is hit
 396  */
 397 static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 398 {
 399         struct kretprobe_instance *ri = NULL;
 400         struct hlist_head *head, empty_rp;
 401         struct hlist_node *tmp;
 402         unsigned long flags, orig_ret_address = 0;
 403         unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 404 
 405         INIT_HLIST_HEAD(&empty_rp);
 406         kretprobe_hash_lock(current, &head, &flags);
 407 
 408         /*
 409          * It is possible to have multiple instances associated with a given
 410          * task either because an multiple functions in the call path
 411          * have a return probe installed on them, and/or more than one return
 412          * return probe was registered for a target function.
 413          *
 414          * We can handle this because:
 415          *     - instances are always inserted at the head of the list
 416          *     - when multiple return probes are registered for the same
 417          *       function, the first instance's ret_addr will point to the
 418          *       real return address, and all the rest will point to
 419          *       kretprobe_trampoline
 420          */
 421         hlist_for_each_entry_safe(ri, tmp, head, hlist) {
 422                 if (ri->task != current)
 423                         /* another task is sharing our hash bucket */
 424                         continue;
 425 
 426                 if (ri->rp && ri->rp->handler)
 427                         ri->rp->handler(ri, regs);
 428 
 429                 orig_ret_address = (unsigned long)ri->ret_addr;
 430                 recycle_rp_inst(ri, &empty_rp);
 431 
 432                 if (orig_ret_address != trampoline_address)
 433                         /*
 434                          * This is the real return address. Any other
 435                          * instances associated with this task are for
 436                          * other calls deeper on the call stack
 437                          */
 438                         break;
 439         }
 440 
 441         kretprobe_assert(ri, orig_ret_address, trampoline_address);
 442 
 443         /*
 444          * We get here through one of two paths:
 445          * 1. by taking a trap -> kprobe_handler() -> here
 446          * 2. by optprobe branch -> optimized_callback() -> opt_pre_handler() -> here
 447          *
 448          * When going back through (1), we need regs->nip to be setup properly
 449          * as it is used to determine the return address from the trap.
 450          * For (2), since nip is not honoured with optprobes, we instead setup
 451          * the link register properly so that the subsequent 'blr' in
 452          * kretprobe_trampoline jumps back to the right instruction.
 453          *
 454          * For nip, we should set the address to the previous instruction since
 455          * we end up emulating it in kprobe_handler(), which increments the nip
 456          * again.
 457          */
 458         regs->nip = orig_ret_address - 4;
 459         regs->link = orig_ret_address;
 460 
 461         kretprobe_hash_unlock(current, &flags);
 462 
 463         hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
 464                 hlist_del(&ri->hlist);
 465                 kfree(ri);
 466         }
 467 
 468         return 0;
 469 }
 470 NOKPROBE_SYMBOL(trampoline_probe_handler);
 471 
 472 /*
 473  * Called after single-stepping.  p->addr is the address of the
 474  * instruction whose first byte has been replaced by the "breakpoint"
 475  * instruction.  To avoid the SMP problems that can occur when we
 476  * temporarily put back the original opcode to single-step, we
 477  * single-stepped a copy of the instruction.  The address of this
 478  * copy is p->ainsn.insn.
 479  */
 480 int kprobe_post_handler(struct pt_regs *regs)
 481 {
 482         struct kprobe *cur = kprobe_running();
 483         struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 484 
 485         if (!cur || user_mode(regs))
 486                 return 0;
 487 
 488         /* make sure we got here for instruction we have a kprobe on */
 489         if (((unsigned long)cur->ainsn.insn + 4) != regs->nip)
 490                 return 0;
 491 
 492         if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
 493                 kcb->kprobe_status = KPROBE_HIT_SSDONE;
 494                 cur->post_handler(cur, regs, 0);
 495         }
 496 
 497         /* Adjust nip to after the single-stepped instruction */
 498         regs->nip = (unsigned long)cur->addr + 4;
 499         regs->msr |= kcb->kprobe_saved_msr;
 500 
 501         /*Restore back the original saved kprobes variables and continue. */
 502         if (kcb->kprobe_status == KPROBE_REENTER) {
 503                 restore_previous_kprobe(kcb);
 504                 goto out;
 505         }
 506         reset_current_kprobe();
 507 out:
 508         preempt_enable_no_resched();
 509 
 510         /*
 511          * if somebody else is singlestepping across a probe point, msr
 512          * will have DE/SE set, in which case, continue the remaining processing
 513          * of do_debug, as if this is not a probe hit.
 514          */
 515         if (regs->msr & MSR_SINGLESTEP)
 516                 return 0;
 517 
 518         return 1;
 519 }
 520 NOKPROBE_SYMBOL(kprobe_post_handler);
 521 
 522 int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 523 {
 524         struct kprobe *cur = kprobe_running();
 525         struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 526         const struct exception_table_entry *entry;
 527 
 528         switch(kcb->kprobe_status) {
 529         case KPROBE_HIT_SS:
 530         case KPROBE_REENTER:
 531                 /*
 532                  * We are here because the instruction being single
 533                  * stepped caused a page fault. We reset the current
 534                  * kprobe and the nip points back to the probe address
 535                  * and allow the page fault handler to continue as a
 536                  * normal page fault.
 537                  */
 538                 regs->nip = (unsigned long)cur->addr;
 539                 regs->msr &= ~MSR_SINGLESTEP; /* Turn off 'trace' bits */
 540                 regs->msr |= kcb->kprobe_saved_msr;
 541                 if (kcb->kprobe_status == KPROBE_REENTER)
 542                         restore_previous_kprobe(kcb);
 543                 else
 544                         reset_current_kprobe();
 545                 preempt_enable_no_resched();
 546                 break;
 547         case KPROBE_HIT_ACTIVE:
 548         case KPROBE_HIT_SSDONE:
 549                 /*
 550                  * We increment the nmissed count for accounting,
 551                  * we can also use npre/npostfault count for accounting
 552                  * these specific fault cases.
 553                  */
 554                 kprobes_inc_nmissed_count(cur);
 555 
 556                 /*
 557                  * We come here because instructions in the pre/post
 558                  * handler caused the page_fault, this could happen
 559                  * if handler tries to access user space by
 560                  * copy_from_user(), get_user() etc. Let the
 561                  * user-specified handler try to fix it first.
 562                  */
 563                 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 564                         return 1;
 565 
 566                 /*
 567                  * In case the user-specified fault handler returned
 568                  * zero, try to fix up.
 569                  */
 570                 if ((entry = search_exception_tables(regs->nip)) != NULL) {
 571                         regs->nip = extable_fixup(entry);
 572                         return 1;
 573                 }
 574 
 575                 /*
 576                  * fixup_exception() could not handle it,
 577                  * Let do_page_fault() fix it.
 578                  */
 579                 break;
 580         default:
 581                 break;
 582         }
 583         return 0;
 584 }
 585 NOKPROBE_SYMBOL(kprobe_fault_handler);
 586 
 587 unsigned long arch_deref_entry_point(void *entry)
 588 {
 589 #ifdef PPC64_ELF_ABI_v1
 590         if (!kernel_text_address((unsigned long)entry))
 591                 return ppc_global_function_entry(entry);
 592         else
 593 #endif
 594                 return (unsigned long)entry;
 595 }
 596 NOKPROBE_SYMBOL(arch_deref_entry_point);
 597 
 598 static struct kprobe trampoline_p = {
 599         .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
 600         .pre_handler = trampoline_probe_handler
 601 };
 602 
 603 int __init arch_init_kprobes(void)
 604 {
 605         return register_kprobe(&trampoline_p);
 606 }
 607 
 608 int arch_trampoline_kprobe(struct kprobe *p)
 609 {
 610         if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
 611                 return 1;
 612 
 613         return 0;
 614 }
 615 NOKPROBE_SYMBOL(arch_trampoline_kprobe);

/* [<][>][^][v][top][bottom][index][help] */