1 /* Common target-dependent code for NetBSD systems. 2 3 Copyright (C) 2002-2023 Free Software Foundation, Inc. 4 5 Contributed by Wasabi Systems, Inc. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #include "defs.h" 23 #include "auxv.h" 24 #include "solib-svr4.h" 25 #include "netbsd-tdep.h" 26 #include "gdbarch.h" 27 #include "objfiles.h" 28 #include "xml-syscall.h" 29 30 #include "elf/common.h" 31 32 /* Flags in the 'kve_protection' field in struct kinfo_vmentry. These 33 match the KVME_PROT_* constants in <sys/sysctl.h>. */ 34 35 #define KINFO_VME_PROT_READ 0x00000001 36 #define KINFO_VME_PROT_WRITE 0x00000002 37 #define KINFO_VME_PROT_EXEC 0x00000004 38 39 /* Flags in the 'kve_flags' field in struct kinfo_vmentry. These 40 match the KVME_FLAG_* constants in <sys/sysctl.h>. */ 41 42 #define KINFO_VME_FLAG_COW 0x00000001 43 #define KINFO_VME_FLAG_NEEDS_COPY 0x00000002 44 #define KINFO_VME_FLAG_NOCOREDUMP 0x00000004 45 #define KINFO_VME_FLAG_PAGEABLE 0x00000008 46 #define KINFO_VME_FLAG_GROWS_UP 0x00000010 47 #define KINFO_VME_FLAG_GROWS_DOWN 0x00000020 48 49 int 50 nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *func_name) 51 { 52 /* Check for libc-provided signal trampoline. All such trampolines 53 have function names which begin with "__sigtramp". */ 54 55 return (func_name != NULL 56 && startswith (func_name, "__sigtramp")); 57 } 58 59 /* This enum is derived from NETBSD's <sys/signal.h>. */ 60 61 enum 62 { 63 NBSD_SIGHUP = 1, 64 NBSD_SIGINT = 2, 65 NBSD_SIGQUIT = 3, 66 NBSD_SIGILL = 4, 67 NBSD_SIGTRAP = 5, 68 NBSD_SIGABRT = 6, 69 NBSD_SIGEMT = 7, 70 NBSD_SIGFPE = 8, 71 NBSD_SIGKILL = 9, 72 NBSD_SIGBUS = 10, 73 NBSD_SIGSEGV = 11, 74 NBSD_SIGSYS = 12, 75 NBSD_SIGPIPE = 13, 76 NBSD_SIGALRM = 14, 77 NBSD_SIGTERM = 15, 78 NBSD_SIGURG = 16, 79 NBSD_SIGSTOP = 17, 80 NBSD_SIGTSTP = 18, 81 NBSD_SIGCONT = 19, 82 NBSD_SIGCHLD = 20, 83 NBSD_SIGTTIN = 21, 84 NBSD_SIGTTOU = 22, 85 NBSD_SIGIO = 23, 86 NBSD_SIGXCPU = 24, 87 NBSD_SIGXFSZ = 25, 88 NBSD_SIGVTALRM = 26, 89 NBSD_SIGPROF = 27, 90 NBSD_SIGWINCH = 28, 91 NBSD_SIGINFO = 29, 92 NBSD_SIGUSR1 = 30, 93 NBSD_SIGUSR2 = 31, 94 NBSD_SIGPWR = 32, 95 NBSD_SIGRTMIN = 33, 96 NBSD_SIGRTMAX = 63, 97 }; 98 99 /* Implement the "gdb_signal_from_target" gdbarch method. */ 100 101 static enum gdb_signal 102 nbsd_gdb_signal_from_target (struct gdbarch *gdbarch, int signal) 103 { 104 switch (signal) 105 { 106 case 0: 107 return GDB_SIGNAL_0; 108 109 case NBSD_SIGHUP: 110 return GDB_SIGNAL_HUP; 111 112 case NBSD_SIGINT: 113 return GDB_SIGNAL_INT; 114 115 case NBSD_SIGQUIT: 116 return GDB_SIGNAL_QUIT; 117 118 case NBSD_SIGILL: 119 return GDB_SIGNAL_ILL; 120 121 case NBSD_SIGTRAP: 122 return GDB_SIGNAL_TRAP; 123 124 case NBSD_SIGABRT: 125 return GDB_SIGNAL_ABRT; 126 127 case NBSD_SIGEMT: 128 return GDB_SIGNAL_EMT; 129 130 case NBSD_SIGFPE: 131 return GDB_SIGNAL_FPE; 132 133 case NBSD_SIGKILL: 134 return GDB_SIGNAL_KILL; 135 136 case NBSD_SIGBUS: 137 return GDB_SIGNAL_BUS; 138 139 case NBSD_SIGSEGV: 140 return GDB_SIGNAL_SEGV; 141 142 case NBSD_SIGSYS: 143 return GDB_SIGNAL_SYS; 144 145 case NBSD_SIGPIPE: 146 return GDB_SIGNAL_PIPE; 147 148 case NBSD_SIGALRM: 149 return GDB_SIGNAL_ALRM; 150 151 case NBSD_SIGTERM: 152 return GDB_SIGNAL_TERM; 153 154 case NBSD_SIGURG: 155 return GDB_SIGNAL_URG; 156 157 case NBSD_SIGSTOP: 158 return GDB_SIGNAL_STOP; 159 160 case NBSD_SIGTSTP: 161 return GDB_SIGNAL_TSTP; 162 163 case NBSD_SIGCONT: 164 return GDB_SIGNAL_CONT; 165 166 case NBSD_SIGCHLD: 167 return GDB_SIGNAL_CHLD; 168 169 case NBSD_SIGTTIN: 170 return GDB_SIGNAL_TTIN; 171 172 case NBSD_SIGTTOU: 173 return GDB_SIGNAL_TTOU; 174 175 case NBSD_SIGIO: 176 return GDB_SIGNAL_IO; 177 178 case NBSD_SIGXCPU: 179 return GDB_SIGNAL_XCPU; 180 181 case NBSD_SIGXFSZ: 182 return GDB_SIGNAL_XFSZ; 183 184 case NBSD_SIGVTALRM: 185 return GDB_SIGNAL_VTALRM; 186 187 case NBSD_SIGPROF: 188 return GDB_SIGNAL_PROF; 189 190 case NBSD_SIGWINCH: 191 return GDB_SIGNAL_WINCH; 192 193 case NBSD_SIGINFO: 194 return GDB_SIGNAL_INFO; 195 196 case NBSD_SIGUSR1: 197 return GDB_SIGNAL_USR1; 198 199 case NBSD_SIGUSR2: 200 return GDB_SIGNAL_USR2; 201 202 case NBSD_SIGPWR: 203 return GDB_SIGNAL_PWR; 204 205 /* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>, 206 therefore we have to handle them here. */ 207 case NBSD_SIGRTMIN: 208 return GDB_SIGNAL_REALTIME_33; 209 210 case NBSD_SIGRTMAX: 211 return GDB_SIGNAL_REALTIME_63; 212 } 213 214 if (signal >= NBSD_SIGRTMIN + 1 && signal <= NBSD_SIGRTMAX - 1) 215 { 216 int offset = signal - NBSD_SIGRTMIN + 1; 217 218 return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_34 + offset); 219 } 220 221 return GDB_SIGNAL_UNKNOWN; 222 } 223 224 /* Implement the "gdb_signal_to_target" gdbarch method. */ 225 226 static int 227 nbsd_gdb_signal_to_target (struct gdbarch *gdbarch, 228 enum gdb_signal signal) 229 { 230 switch (signal) 231 { 232 case GDB_SIGNAL_0: 233 return 0; 234 235 case GDB_SIGNAL_HUP: 236 return NBSD_SIGHUP; 237 238 case GDB_SIGNAL_INT: 239 return NBSD_SIGINT; 240 241 case GDB_SIGNAL_QUIT: 242 return NBSD_SIGQUIT; 243 244 case GDB_SIGNAL_ILL: 245 return NBSD_SIGILL; 246 247 case GDB_SIGNAL_TRAP: 248 return NBSD_SIGTRAP; 249 250 case GDB_SIGNAL_ABRT: 251 return NBSD_SIGABRT; 252 253 case GDB_SIGNAL_EMT: 254 return NBSD_SIGEMT; 255 256 case GDB_SIGNAL_FPE: 257 return NBSD_SIGFPE; 258 259 case GDB_SIGNAL_KILL: 260 return NBSD_SIGKILL; 261 262 case GDB_SIGNAL_BUS: 263 return NBSD_SIGBUS; 264 265 case GDB_SIGNAL_SEGV: 266 return NBSD_SIGSEGV; 267 268 case GDB_SIGNAL_SYS: 269 return NBSD_SIGSYS; 270 271 case GDB_SIGNAL_PIPE: 272 return NBSD_SIGPIPE; 273 274 case GDB_SIGNAL_ALRM: 275 return NBSD_SIGALRM; 276 277 case GDB_SIGNAL_TERM: 278 return NBSD_SIGTERM; 279 280 case GDB_SIGNAL_URG: 281 return NBSD_SIGSTOP; 282 283 case GDB_SIGNAL_TSTP: 284 return NBSD_SIGTSTP; 285 286 case GDB_SIGNAL_CONT: 287 return NBSD_SIGCONT; 288 289 case GDB_SIGNAL_CHLD: 290 return NBSD_SIGCHLD; 291 292 case GDB_SIGNAL_TTIN: 293 return NBSD_SIGTTIN; 294 295 case GDB_SIGNAL_TTOU: 296 return NBSD_SIGTTOU; 297 298 case GDB_SIGNAL_IO: 299 return NBSD_SIGIO; 300 301 case GDB_SIGNAL_XCPU: 302 return NBSD_SIGXCPU; 303 304 case GDB_SIGNAL_XFSZ: 305 return NBSD_SIGXFSZ; 306 307 case GDB_SIGNAL_VTALRM: 308 return NBSD_SIGVTALRM; 309 310 case GDB_SIGNAL_PROF: 311 return NBSD_SIGPROF; 312 313 case GDB_SIGNAL_WINCH: 314 return NBSD_SIGWINCH; 315 316 case GDB_SIGNAL_INFO: 317 return NBSD_SIGINFO; 318 319 case GDB_SIGNAL_USR1: 320 return NBSD_SIGUSR1; 321 322 case GDB_SIGNAL_USR2: 323 return NBSD_SIGUSR2; 324 325 case GDB_SIGNAL_PWR: 326 return NBSD_SIGPWR; 327 328 /* GDB_SIGNAL_REALTIME_33 is not continuous in <gdb/signals.def>, 329 therefore we have to handle it here. */ 330 case GDB_SIGNAL_REALTIME_33: 331 return NBSD_SIGRTMIN; 332 333 /* Same comment applies to _64. */ 334 case GDB_SIGNAL_REALTIME_63: 335 return NBSD_SIGRTMAX; 336 } 337 338 if (signal >= GDB_SIGNAL_REALTIME_34 339 && signal <= GDB_SIGNAL_REALTIME_62) 340 { 341 int offset = signal - GDB_SIGNAL_REALTIME_32; 342 343 return NBSD_SIGRTMIN + 1 + offset; 344 } 345 346 return -1; 347 } 348 349 /* Shared library resolver handling. */ 350 351 static CORE_ADDR 352 nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) 353 { 354 struct bound_minimal_symbol msym; 355 356 msym = lookup_minimal_symbol ("_rtld_bind_start", NULL, NULL); 357 if (msym.minsym && msym.value_address () == pc) 358 return frame_unwind_caller_pc (get_current_frame ()); 359 else 360 return find_solib_trampoline_target (get_current_frame (), pc); 361 } 362 363 struct nbsd_gdbarch_data 364 { 365 struct type *siginfo_type = nullptr; 366 }; 367 368 static const registry<gdbarch>::key<nbsd_gdbarch_data> 369 nbsd_gdbarch_data_handle; 370 371 static struct nbsd_gdbarch_data * 372 get_nbsd_gdbarch_data (struct gdbarch *gdbarch) 373 { 374 struct nbsd_gdbarch_data *result = nbsd_gdbarch_data_handle.get (gdbarch); 375 if (result == nullptr) 376 result = nbsd_gdbarch_data_handle.emplace (gdbarch); 377 return result; 378 } 379 380 /* Print descriptions of NetBSD-specific AUXV entries to FILE. */ 381 382 static void 383 nbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, 384 CORE_ADDR type, CORE_ADDR val) 385 { 386 const char *name = "???"; 387 const char *description = ""; 388 enum auxv_format format = AUXV_FORMAT_HEX; 389 390 switch (type) 391 { 392 default: 393 default_print_auxv_entry (gdbarch, file, type, val); 394 return; 395 #define _TAGNAME(tag) #tag 396 #define TAGNAME(tag) _TAGNAME(AT_##tag) 397 #define TAG(tag, text, kind) \ 398 case AT_NETBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break 399 TAG (STACKBASE, _("Base address of main thread"), AUXV_FORMAT_HEX); 400 } 401 402 fprint_auxv_entry (file, name, description, format, type, val); 403 } 404 405 /* Implement the "get_siginfo_type" gdbarch method. */ 406 407 static struct type * 408 nbsd_get_siginfo_type (struct gdbarch *gdbarch) 409 { 410 nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch); 411 if (nbsd_gdbarch_data->siginfo_type != NULL) 412 return nbsd_gdbarch_data->siginfo_type; 413 414 type *char_type = builtin_type (gdbarch)->builtin_char; 415 type *int_type = builtin_type (gdbarch)->builtin_int; 416 type *long_type = builtin_type (gdbarch)->builtin_long; 417 418 type *void_ptr_type 419 = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); 420 421 type *int32_type = builtin_type (gdbarch)->builtin_int32; 422 type *uint32_type = builtin_type (gdbarch)->builtin_uint32; 423 type *uint64_type = builtin_type (gdbarch)->builtin_uint64; 424 425 bool lp64 = void_ptr_type->length () == 8; 426 size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8; 427 428 /* pid_t */ 429 type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, 430 int32_type->length () * char_bits, "pid_t"); 431 pid_type->set_target_type (int32_type); 432 433 /* uid_t */ 434 type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, 435 uint32_type->length () * char_bits, "uid_t"); 436 uid_type->set_target_type (uint32_type); 437 438 /* clock_t */ 439 type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, 440 int_type->length () * char_bits, "clock_t"); 441 clock_type->set_target_type (int_type); 442 443 /* lwpid_t */ 444 type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, 445 int32_type->length () * char_bits, 446 "lwpid_t"); 447 lwpid_type->set_target_type (int32_type); 448 449 /* union sigval */ 450 type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); 451 sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval")); 452 append_composite_type_field (sigval_type, "sival_int", int_type); 453 append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type); 454 455 /* union _option */ 456 type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); 457 option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option")); 458 append_composite_type_field (option_type, "_pe_other_pid", pid_type); 459 append_composite_type_field (option_type, "_pe_lwp", lwpid_type); 460 461 /* union _reason */ 462 type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); 463 464 /* _rt */ 465 type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 466 append_composite_type_field (t, "_pid", pid_type); 467 append_composite_type_field (t, "_uid", uid_type); 468 append_composite_type_field (t, "_value", sigval_type); 469 append_composite_type_field (reason_type, "_rt", t); 470 471 /* _child */ 472 t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 473 append_composite_type_field (t, "_pid", pid_type); 474 append_composite_type_field (t, "_uid", uid_type); 475 append_composite_type_field (t, "_status", int_type); 476 append_composite_type_field (t, "_utime", clock_type); 477 append_composite_type_field (t, "_stime", clock_type); 478 append_composite_type_field (reason_type, "_child", t); 479 480 /* _fault */ 481 t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 482 append_composite_type_field (t, "_addr", void_ptr_type); 483 append_composite_type_field (t, "_trap", int_type); 484 append_composite_type_field (t, "_trap2", int_type); 485 append_composite_type_field (t, "_trap3", int_type); 486 append_composite_type_field (reason_type, "_fault", t); 487 488 /* _poll */ 489 t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 490 append_composite_type_field (t, "_band", long_type); 491 append_composite_type_field (t, "_fd", int_type); 492 append_composite_type_field (reason_type, "_poll", t); 493 494 /* _syscall */ 495 t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 496 append_composite_type_field (t, "_sysnum", int_type); 497 append_composite_type_field (t, "_retval", 498 init_vector_type (int_type, 2)); 499 append_composite_type_field (t, "_error", int_type); 500 append_composite_type_field (t, "_args", 501 init_vector_type (uint64_type, 8)); 502 append_composite_type_field (reason_type, "_syscall", t); 503 504 /* _ptrace_state */ 505 t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 506 append_composite_type_field (t, "_pe_report_event", int_type); 507 append_composite_type_field (t, "_option", option_type); 508 append_composite_type_field (reason_type, "_ptrace_state", t); 509 510 /* struct _ksiginfo */ 511 type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); 512 ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo")); 513 append_composite_type_field (ksiginfo_type, "_signo", int_type); 514 append_composite_type_field (ksiginfo_type, "_code", int_type); 515 append_composite_type_field (ksiginfo_type, "_errno", int_type); 516 if (lp64) 517 append_composite_type_field (ksiginfo_type, "_pad", int_type); 518 append_composite_type_field (ksiginfo_type, "_reason", reason_type); 519 520 /* union siginfo */ 521 type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); 522 siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo")); 523 append_composite_type_field (siginfo_type, "si_pad", 524 init_vector_type (char_type, 128)); 525 append_composite_type_field (siginfo_type, "_info", ksiginfo_type); 526 527 nbsd_gdbarch_data->siginfo_type = siginfo_type; 528 529 return siginfo_type; 530 } 531 532 /* See netbsd-tdep.h. */ 533 534 void 535 nbsd_info_proc_mappings_header (int addr_bit) 536 { 537 gdb_printf (_("Mapped address spaces:\n\n")); 538 if (addr_bit == 64) 539 { 540 gdb_printf (" %18s %18s %10s %10s %9s %s\n", 541 "Start Addr", 542 " End Addr", 543 " Size", " Offset", "Flags ", "File"); 544 } 545 else 546 { 547 gdb_printf ("\t%10s %10s %10s %10s %9s %s\n", 548 "Start Addr", 549 " End Addr", 550 " Size", " Offset", "Flags ", "File"); 551 } 552 } 553 554 /* Helper function to generate mappings flags for a single VM map 555 entry in 'info proc mappings'. */ 556 557 static const char * 558 nbsd_vm_map_entry_flags (int kve_flags, int kve_protection) 559 { 560 static char vm_flags[9]; 561 562 vm_flags[0] = (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-'; 563 vm_flags[1] = (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-'; 564 vm_flags[2] = (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-'; 565 vm_flags[3] = ' '; 566 vm_flags[4] = (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-'; 567 vm_flags[5] = (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-'; 568 vm_flags[6] = (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-'; 569 vm_flags[7] = (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U' 570 : (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-'; 571 vm_flags[8] = '\0'; 572 573 return vm_flags; 574 } 575 576 void 577 nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start, 578 ULONGEST kve_end, ULONGEST kve_offset, 579 int kve_flags, int kve_protection, 580 const char *kve_path) 581 { 582 if (addr_bit == 64) 583 { 584 gdb_printf (" %18s %18s %10s %10s %9s %s\n", 585 hex_string (kve_start), 586 hex_string (kve_end), 587 hex_string (kve_end - kve_start), 588 hex_string (kve_offset), 589 nbsd_vm_map_entry_flags (kve_flags, kve_protection), 590 kve_path); 591 } 592 else 593 { 594 gdb_printf ("\t%10s %10s %10s %10s %9s %s\n", 595 hex_string (kve_start), 596 hex_string (kve_end), 597 hex_string (kve_end - kve_start), 598 hex_string (kve_offset), 599 nbsd_vm_map_entry_flags (kve_flags, kve_protection), 600 kve_path); 601 } 602 } 603 604 /* Implement the "get_syscall_number" gdbarch method. */ 605 606 static LONGEST 607 nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) 608 { 609 610 /* NetBSD doesn't use gdbarch_get_syscall_number since NetBSD 611 native targets fetch the system call number from the 612 'si_sysnum' member of siginfo_t in nbsd_nat_target::wait. 613 However, system call catching requires this function to be 614 set. */ 615 616 internal_error (_("nbsd_get_sycall_number called")); 617 } 618 619 /* See netbsd-tdep.h. */ 620 621 void 622 nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 623 { 624 set_gdbarch_gdb_signal_from_target (gdbarch, nbsd_gdb_signal_from_target); 625 set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target); 626 set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver); 627 set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse); 628 set_gdbarch_print_auxv_entry (gdbarch, nbsd_print_auxv_entry); 629 set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type); 630 631 /* `catch syscall' */ 632 set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml"); 633 set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number); 634 } 635