1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * This file contains the functions responsible for opening the output file 34 * image, associating the appropriate input elf structures with the new image, 35 * and obtaining new elf structures to define the new image. 36 */ 37 #include <stdio.h> 38 #include <sys/stat.h> 39 #include <fcntl.h> 40 #include <link.h> 41 #include <errno.h> 42 #include <string.h> 43 #include <limits.h> 44 #include "msg.h" 45 #include "_libld.h" 46 #include <debug.h> 47 48 /* 49 * Open the output file and insure the correct access modes. 50 */ 51 uintptr_t 52 open_outfile(Ofl_desc * ofl) 53 { 54 mode_t mask, mode; 55 struct stat status; 56 int exists = 0; 57 58 /* 59 * Determine the required file mode from the type of output file we 60 * are creating. 61 */ 62 if (ofl->ofl_flags & (FLG_OF_EXEC | FLG_OF_SHAROBJ)) 63 mode = 0777; 64 else 65 mode = 0666; 66 67 /* 68 * Determine if the output file already exists. 69 */ 70 if (stat(ofl->ofl_name, &status) == 0) 71 exists++; 72 73 /* 74 * Open (or create) the output file name (ofl_fd acts as a global 75 * flag to ldexit() signifying whether the output file should be 76 * removed or not on error). 77 */ 78 if ((ofl->ofl_fd = open(ofl->ofl_name, O_RDWR | O_CREAT | O_TRUNC, 79 mode)) < 0) { 80 int err = errno; 81 82 eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), ofl->ofl_name, 83 strerror(err)); 84 return (S_ERROR); 85 } 86 87 /* 88 * If we've just created this file the modes will be fine, however if 89 * the file had already existed make sure the modes are correct. 90 */ 91 if (exists) { 92 /* 93 * If the output file is not a regular file, don't change the 94 * mode, or allow it to be deleted. This allows root users to 95 * specify /dev/null output file for verification links. 96 */ 97 if ((status.st_mode & S_IFMT) != S_IFREG) { 98 ofl->ofl_flags1 |= FLG_OF1_NONREG; 99 } else { 100 mask = umask(0); 101 (void) umask(mask); 102 (void) chmod(ofl->ofl_name, mode & ~mask); 103 } 104 } 105 106 return (1); 107 } 108 109 110 /* 111 * If we are creating a memory model we need to update the present memory image. 112 * First we need to call elf_update(ELF_C_NULL) which will calculate the offsets 113 * of each section and its associated data buffers. From this information we 114 * can then determine what padding is required. 115 * Two actions are necessary to convert the present disc image into a memory 116 * image: 117 * 118 * o Loadable segments must be padded so that the next segments virtual 119 * address and file offset are the same. 120 * 121 * o NOBITS sections must be converted into allocated, null filled sections. 122 */ 123 uintptr_t 124 pad_outfile(Ofl_desc * ofl) 125 { 126 Listnode * lnp1, * lnp2; 127 off_t offset; 128 Elf_Scn * oscn = 0; 129 Sg_desc * sgp; 130 Os_desc * osp; 131 Ehdr * ehdr; 132 133 /* 134 * Update all the elf structures. This will assign offsets to the 135 * section headers and data buffers as they relate to the new image. 136 */ 137 if (elf_update(ofl->ofl_welf, ELF_C_NULL) == -1) { 138 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_UPDATE), ofl->ofl_name); 139 return (S_ERROR); 140 } 141 if ((ehdr = elf_getehdr(ofl->ofl_welf)) == NULL) { 142 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR), ofl->ofl_name); 143 return (S_ERROR); 144 } 145 146 /* 147 * Initialize the offset by skipping the Elf header and program 148 * headers. 149 */ 150 offset = ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize); 151 152 /* 153 * Traverse the segment list looking for loadable segments. 154 */ 155 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 156 Phdr * phdr = &(sgp->sg_phdr); 157 158 /* 159 * If we've already processed a loadable segment, the `scn' 160 * variable will be initialized to the last section that was 161 * part of that segment. Add sufficient padding to this section 162 * to cause the next segments virtual address and file offset to 163 * be the same. 164 */ 165 if (oscn && (phdr->p_type == PT_LOAD)) { 166 Elf_Data * data; 167 size_t size; 168 169 size = (size_t)(S_ROUND(offset, phdr->p_align) - 170 offset); 171 172 if ((data = elf_newdata(oscn)) == NULL) { 173 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_NEWDATA), 174 ofl->ofl_name); 175 return (S_ERROR); 176 } 177 if ((data->d_buf = libld_calloc(size, 1)) == 0) 178 return (S_ERROR); 179 180 data->d_type = ELF_T_BYTE; 181 data->d_size = size; 182 data->d_align = 1; 183 data->d_version = ofl->ofl_libver; 184 } 185 186 /* 187 * Traverse the output sections for this segment calculating the 188 * offset of each section. Retain the final section descriptor 189 * as this will be where any padding buffer will be added. 190 */ 191 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 192 Shdr * shdr = osp->os_shdr; 193 194 offset = (off_t)S_ROUND(offset, shdr->sh_addralign); 195 offset += shdr->sh_size; 196 197 /* 198 * If this is a NOBITS output section convert all of 199 * its associated input sections into real, null filled, 200 * data buffers, and change the section to PROGBITS. 201 */ 202 if (shdr->sh_type == SHT_NOBITS) 203 shdr->sh_type = SHT_PROGBITS; 204 } 205 206 /* 207 * If this is a loadable segment retain the last output section 208 * descriptor. This acts both as a flag that a loadable 209 * segment has been seen, and as the segment to which a padding 210 * buffer will be added. 211 */ 212 if (phdr->p_type == PT_LOAD) 213 oscn = osp->os_scn; 214 } 215 return (1); 216 } 217 218 /* 219 * Create the elf structures that allow the input data to be associated with the 220 * new image: 221 * 222 * o define the new elf image using elf_begin(), 223 * 224 * o obtain an elf header for the image, 225 * 226 * o traverse the input segments and create a program header array 227 * to define the required segments, 228 * 229 * o traverse the output sections for each segment assigning a new 230 * section descriptor and section header for each, 231 * 232 * o traverse the input sections associated with each output section 233 * and assign a new data descriptor to each (each output section 234 * becomes a linked list of input data buffers). 235 */ 236 uintptr_t 237 create_outfile(Ofl_desc * ofl) 238 { 239 Listnode * lnp1, * lnp2, * lnp3; 240 Sg_desc * sgp; 241 Os_desc * osp; 242 Is_desc * isp; 243 Elf_Scn * scn; 244 Elf_Data * tlsdata = 0; 245 Shdr * shdr; 246 Word flags = ofl->ofl_flags; 247 size_t ndx = 0, fndx = 0; 248 Elf_Cmd cmd; 249 Boolean fixalign = FALSE; 250 int fd, nseg = 0, shidx = 0, dataidx = 0, ptloadidx = 0; 251 252 /* 253 * If FLG_OF1_NOHDR was set in map_parse() or FLG_OF1_VADDR was set, 254 * we need to do alignment adjustment. 255 */ 256 if (ofl->ofl_flags1 & (FLG_OF1_NOHDR | FLG_OF1_VADDR)) { 257 fixalign = TRUE; 258 } 259 260 if (flags & FLG_OF_MEMORY) { 261 cmd = ELF_C_IMAGE; 262 fd = 0; 263 } else { 264 fd = ofl->ofl_fd; 265 cmd = ELF_C_WRITE; 266 } 267 268 /* 269 * If there are any ordered section, handle them here. 270 */ 271 if ((ofl->ofl_ordered.head != NULL) && (sort_ordered(ofl) == S_ERROR)) 272 return (S_ERROR); 273 274 /* 275 * Tell the access library about our new temporary file. 276 */ 277 if ((ofl->ofl_welf = elf_begin(fd, cmd, 0)) == NULL) { 278 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_BEGIN), ofl->ofl_name); 279 return (S_ERROR); 280 } 281 282 /* 283 * Obtain a new Elf header. 284 */ 285 if ((ofl->ofl_ehdr = elf_newehdr(ofl->ofl_welf)) == NULL) { 286 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_NEWEHDR), ofl->ofl_name); 287 return (S_ERROR); 288 } 289 ofl->ofl_ehdr->e_machine = ofl->ofl_e_machine; 290 291 DBG_CALL(Dbg_util_nl()); 292 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 293 int frst = 0; 294 Phdr *phdr = &(sgp->sg_phdr); 295 Word ptype = phdr->p_type; 296 297 /* 298 * Count the number of segments that will go in the program 299 * header table. If a segment is empty, ignore it. 300 */ 301 if (!(flags & FLG_OF_RELOBJ)) { 302 if (ptype == PT_PHDR) { 303 /* 304 * If we are generating an interp section (and 305 * thus an associated PT_INTERP program header 306 * entry) also generate a PT_PHDR program header 307 * entry. This allows the kernel to generate 308 * the appropriate aux vector entries to pass to 309 * the interpreter (refer to exec/elf/elf.c). 310 * Note that if an image was generated with an 311 * interp section, but no associated PT_PHDR 312 * program header entry, the kernel will simply 313 * pass the interpreter an open file descriptor 314 * when the image is executed). 315 */ 316 if (ofl->ofl_osinterp) 317 nseg++; 318 } else if (ptype == PT_INTERP) { 319 if (ofl->ofl_osinterp) 320 nseg++; 321 } else if (ptype == PT_DYNAMIC) { 322 if (flags & FLG_OF_DYNAMIC) 323 nseg++; 324 } else if (ptype == PT_TLS) { 325 if (flags & FLG_OF_TLSPHDR) 326 nseg++; 327 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 328 } else if (ptype == PT_SUNW_UNWIND) { 329 if (ofl->ofl_unwindhdr) 330 nseg++; 331 #endif 332 } else if (ptype == PT_SUNWBSS) { 333 if (ofl->ofl_issunwbss) 334 nseg++; 335 } else if (ptype == PT_SUNWSTACK) { 336 nseg++; 337 } else if (ptype == PT_SUNWDTRACE) { 338 if (ofl->ofl_dtracesym) 339 nseg++; 340 } else if (ptype == PT_SUNWCAP) { 341 if (ofl->ofl_oscap) 342 nseg++; 343 } else if ((sgp->sg_osdescs.head) || 344 (sgp->sg_flags & FLG_SG_EMPTY)) { 345 if (((sgp->sg_flags & FLG_SG_EMPTY) == 0) && 346 ((sgp->sg_flags & FLG_SG_PHREQ) == 0)) { 347 /* 348 * If this is a segment for which 349 * we are not making a program header, 350 * don't increment nseg 351 */ 352 ptype = (sgp->sg_phdr).p_type = PT_NULL; 353 } else if (ptype != PT_NULL) 354 nseg++; 355 } 356 } 357 358 /* 359 * If the first loadable segment has the ?N flag, 360 * then ?N will be on. 361 */ 362 if ((ptype == PT_LOAD) && (ptloadidx == 0)) { 363 ptloadidx++; 364 if (sgp->sg_flags & FLG_SG_NOHDR) { 365 fixalign = TRUE; 366 ofl->ofl_flags1 |= FLG_OF1_NOHDR; 367 } 368 } 369 370 shidx = 0; 371 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 372 shidx++; 373 374 /* 375 * Get a section descriptor for the section. 376 */ 377 if ((scn = elf_newscn(ofl->ofl_welf)) == NULL) { 378 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_NEWSCN), 379 ofl->ofl_name); 380 return (S_ERROR); 381 } 382 osp->os_scn = scn; 383 384 /* 385 * Get a new section header table entry and copy the 386 * pertinent information from the in-core descriptor. 387 * As we had originally allocated the section header 388 * (refer place_section()) we might as well free it up. 389 */ 390 if ((shdr = elf_getshdr(scn)) == NULL) { 391 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR), 392 ofl->ofl_name); 393 return (S_ERROR); 394 } 395 *shdr = *(osp->os_shdr); 396 397 if ((fixalign == TRUE) && (ptype == PT_LOAD) && 398 (shidx == 1)) 399 sgp->sg_fscn = scn; 400 401 osp->os_shdr = shdr; 402 403 /* 404 * Knock off the SHF_ORDERED & SHF_LINK_ORDER flags. 405 */ 406 osp->os_shdr->sh_flags &= ~ALL_SHF_ORDER; 407 408 /* 409 * If we are not building a RELOBJ - we strip 410 * off the SHF_GROUP flag (if present). 411 */ 412 if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) 413 osp->os_shdr->sh_flags &= ~SHF_GROUP; 414 415 /* 416 * If this is a TLS section, save it so that the PT_TLS 417 * program header information can be established after 418 * the output image has been initialy created. At this 419 * point, all TLS input sections are ordered as they 420 * will appear in the output image. 421 */ 422 if ((ofl->ofl_flags & FLG_OF_TLSPHDR) && 423 (osp->os_shdr->sh_flags & SHF_TLS)) { 424 if (list_appendc(&ofl->ofl_ostlsseg, osp) == 0) 425 return (S_ERROR); 426 } 427 428 dataidx = 0; 429 for (LIST_TRAVERSE(&(osp->os_isdescs), lnp3, isp)) { 430 Elf_Data * data; 431 Ifl_desc * ifl = isp->is_file; 432 433 /* 434 * At this point we know whether a section has 435 * been referenced. If it hasn't, and the whole 436 * file hasn't been referenced (which would have 437 * been caught in ignore_section_processing()), 438 * give a diagnostic (-D unused,detail) or 439 * discard the section if -zignore is in effect. 440 */ 441 if (ifl && 442 (((ifl->ifl_flags & FLG_IF_FILEREF) == 0) || 443 ((ptype == PT_LOAD) && 444 ((isp->is_flags & FLG_IS_SECTREF) == 0) && 445 (isp->is_shdr->sh_size > 0)))) { 446 if (ifl->ifl_flags & FLG_IF_IGNORE) { 447 isp->is_flags |= FLG_IS_DISCARD; 448 DBG_CALL(Dbg_unused_sec(isp)); 449 continue; 450 } else 451 DBG_CALL(Dbg_unused_sec(isp)); 452 } 453 454 dataidx++; 455 456 /* 457 * If this section provides no data, and isn't 458 * referenced, then it can be discarded as well. 459 * Note, if this is the first input section 460 * associated to an output section, let it 461 * through, there may be a legitimate reason why 462 * the user wants a null section. Discarding 463 * additional sections is intended to remove the 464 * empty clutter the compilers have a habit of 465 * creating. Don't provide an unused diagnostic 466 * as these sections aren't typically the users 467 * creation. 468 */ 469 if (ifl && dataidx && 470 ((isp->is_flags & FLG_IS_SECTREF) == 0) && 471 (isp->is_shdr->sh_size == 0)) { 472 isp->is_flags |= FLG_IS_DISCARD; 473 continue; 474 } 475 476 /* 477 * Create new output data buffers for each of 478 * the input data buffers, thus linking the new 479 * buffers to the new elf output structures. 480 * Simply make the new data buffers point to 481 * the old data. 482 */ 483 if ((data = elf_newdata(scn)) == NULL) { 484 eprintf(ERR_ELF, 485 MSG_INTL(MSG_ELF_NEWDATA), 486 ofl->ofl_name); 487 return (S_ERROR); 488 } 489 *data = *(isp->is_indata); 490 491 if ((fixalign == TRUE) && (ptype == PT_LOAD) && 492 (shidx == 1) && (dataidx == 1)) { 493 data->d_align = sgp->sg_addralign; 494 } 495 isp->is_indata = data; 496 497 /* 498 * Save the first TLS data buffer, as this is 499 * the start of the TLS segment. Realign this 500 * buffer based on the alignment requirements 501 * of all the TLS input sections. 502 */ 503 if ((ofl->ofl_flags & FLG_OF_TLSPHDR) && 504 (isp->is_shdr->sh_flags & SHF_TLS)) { 505 if (tlsdata == 0) 506 tlsdata = data; 507 tlsdata->d_align = lcm(tlsdata->d_align, 508 isp->is_shdr->sh_addralign); 509 } 510 511 #if defined(_ELF64) && defined(_ILP32) 512 /* 513 * 4106312, the 32-bit ELF64 version of ld 514 * needs to be able to create large .bss 515 * sections. The d_size member of Elf_Data 516 * only allows 32-bits in _ILP32, so we build 517 * multiple data-items that each fit into 32- 518 * bits. libelf (4106398) can summ these up 519 * into a 64-bit quantity. This only works 520 * for NOBITS sections which don't have any 521 * real data to maintain and don't require 522 * large file support. 523 */ 524 if (isp->is_shdr->sh_type == SHT_NOBITS) { 525 Xword sz = isp->is_shdr->sh_size; 526 527 while (sz >> 32) { 528 data->d_size = SIZE_MAX; 529 sz -= (Xword)SIZE_MAX; 530 if ((data = 531 elf_newdata(scn)) == NULL) 532 return (S_ERROR); 533 } 534 data->d_size = (size_t)sz; 535 } 536 #endif 537 538 /* 539 * If this segment requires rounding realign the 540 * first data buffer associated with the first 541 * section. 542 */ 543 if ((frst++ == 0) && 544 (sgp->sg_flags & FLG_SG_ROUND)) { 545 Xword align; 546 547 if (data->d_align) 548 align = (Xword) 549 S_ROUND(data->d_align, 550 sgp->sg_round); 551 else 552 align = sgp->sg_round; 553 554 data->d_align = (size_t)align; 555 } 556 } 557 558 /* 559 * Clear the szoutrels counter so that it can be used 560 * again in the building of relocs. See machrel.c. 561 */ 562 osp->os_szoutrels = 0; 563 } 564 } 565 566 /* 567 * Build an empty PHDR. 568 */ 569 if (nseg) { 570 if ((ofl->ofl_phdr = elf_newphdr(ofl->ofl_welf, 571 nseg)) == NULL) { 572 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_NEWPHDR), 573 ofl->ofl_name); 574 return (S_ERROR); 575 } 576 } 577 578 /* 579 * If we need to generate a memory model, pad the image. 580 */ 581 if (flags & FLG_OF_MEMORY) { 582 if (pad_outfile(ofl) == S_ERROR) 583 return (S_ERROR); 584 } 585 586 /* 587 * After all the basic input file processing, all data pointers are 588 * referencing two types of memory: 589 * 590 * o allocated memory, ie. elf structures, internal link 591 * editor structures, and any new sections that have been 592 * created. 593 * 594 * o original input file mmap'ed memory, ie. the actual data 595 * sections of the input file images. 596 * 597 * Up until now, the only memory modifications have been carried out on 598 * the allocated memory. Before carrying out any relocations, write the 599 * new output file image and reassign any necessary data pointers to the 600 * output files memory image. This insures that any relocation 601 * modifications are made to the output file image and not to the input 602 * file image, thus preventing the creation of dirty pages and reducing 603 * the overall swap space requirement. 604 * 605 * Write out the elf structure so as to create the new file image. 606 */ 607 if ((ofl->ofl_size = (size_t)elf_update(ofl->ofl_welf, 608 ELF_C_WRIMAGE)) == (size_t)-1) { 609 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_UPDATE), ofl->ofl_name); 610 return (S_ERROR); 611 } 612 613 /* 614 * Initialize the true `ofl' information with the memory images address 615 * and size. This will be used to write() out the image once any 616 * relocation processing has been completed. We also use this image 617 * information to setup a new Elf descriptor, which is used to obtain 618 * all the necessary elf pointers within the new output image. 619 */ 620 if ((ofl->ofl_elf = elf_begin(0, ELF_C_IMAGE, 621 ofl->ofl_welf)) == NULL) { 622 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_BEGIN), ofl->ofl_name); 623 return (S_ERROR); 624 } 625 if ((ofl->ofl_ehdr = elf_getehdr(ofl->ofl_elf)) == NULL) { 626 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR), ofl->ofl_name); 627 return (S_ERROR); 628 } 629 if (!(flags & FLG_OF_RELOBJ)) 630 if ((ofl->ofl_phdr = elf_getphdr(ofl->ofl_elf)) == NULL) { 631 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETPHDR), 632 ofl->ofl_name); 633 return (S_ERROR); 634 } 635 636 /* 637 * Reinitialize the section descriptors, section headers and obtain new 638 * output data buffer pointers (these will be used to perform any 639 * relocations). 640 */ 641 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 642 Phdr * _phdr = &(sgp->sg_phdr); 643 Boolean recorded = FALSE; 644 645 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 646 if ((osp->os_scn = elf_getscn(ofl->ofl_elf, ++ndx)) == 647 NULL) { 648 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETSCN), 649 ofl->ofl_name, ndx); 650 return (S_ERROR); 651 } 652 if ((osp->os_shdr = elf_getshdr(osp->os_scn)) == 653 NULL) { 654 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR), 655 ofl->ofl_name); 656 return (S_ERROR); 657 } 658 if ((fixalign == TRUE) && (sgp->sg_fscn != 0) && 659 (recorded == FALSE)) { 660 Elf_Scn *scn; 661 662 scn = sgp->sg_fscn; 663 if ((fndx = elf_ndxscn(scn)) == SHN_UNDEF) { 664 eprintf(ERR_ELF, 665 MSG_INTL(MSG_ELF_NDXSCN), 666 ofl->ofl_name); 667 return (S_ERROR); 668 } 669 if (ndx == fndx) { 670 sgp->sg_fscn = osp->os_scn; 671 recorded = TRUE; 672 } 673 } 674 675 if ((osp->os_outdata = 676 elf_getdata(osp->os_scn, NULL)) == NULL) { 677 eprintf(ERR_ELF, MSG_INTL(MSG_ELF_GETDATA), 678 ofl->ofl_name); 679 return (S_ERROR); 680 } 681 682 /* 683 * If this section is part of a loadable segment insure 684 * that the segments alignment is appropriate. 685 */ 686 if (_phdr->p_type == PT_LOAD) { 687 _phdr->p_align = (Xword)lcm(_phdr->p_align, 688 osp->os_shdr->sh_addralign); 689 } 690 } 691 } 692 return (1); 693 } 694