1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** interpsh.c 79** 80** FACILITY: 81** 82** Interface Definition Language (IDL) Compiler 83** 84** ABSTRACT: 85** 86** Procedures shared between interpreters 87** 88*/ 89#if HAVE_CONFIG_H 90#include <config.h> 91#endif 92 93#include <dce/idlddefs.h> 94#include <lsysdep.h> 95 96/******************************************************************************/ 97/* */ 98/* General comments about interpreter structure, variable name, etc. */ 99/* */ 100/******************************************************************************/ 101 102/* 103 * For a description of the layout of the vectors on which the interpreters 104 * rely, see the MTS*.SDML documents in the RPC$ROOT:[DOC.CMS] CMS library 105 */ 106 107/* 108 A range list is a set of [A, A+B] pairs for a varying array. 109*/ 110 111/* 112 p_... Signifies a pointer to an object 113 114 IDL_msp Pointer to the marshalling state block 115 add_null TRUE => marshalling a string to which a null terminator 116 must be explicitly added 117 arm_type_ptr Pointer to union arm type definition 118 array_addr Address of an array 119 array_defn_index Index into definition vector for array definition 120 array_defn_ptr Pointer to array definition in definition vector 121 array_has_pointers TRUE if the base type of the array includes pointers 122 bounds_list List of lower and upper bounds for an array 123 contiguous TRUE if no gaps in set of array elements 124 cs_type_defn_index Index into definition vector for [cs_char] type defn 125 cs_type_defn_ptr Pointer to [cs_char] type definition in definition vector 126 defn_index Index into definition vector 127 defn_vec_ptr Pointer to current byte in definition vector 128 dimensionality Number of dimensions of an array 129 element_count Number of elements in an array or array portion 130 element_defn_index Index into definition vector for description of array 131 element which has complex type 132 element_defn_ptr Pointer to description in definition vector of array 133 element which has complex type 134 element_offset_vec_ptr Pointer to the start of the offset vector entries 135 for an array element of complex type 136 element_size Size of an array element 137 field_defn_index Index into definition vector for description of field 138 which has complex type 139 field_defn_ptr Pointer to description in definition vector of field 140 which has complex type 141 marshall_by_pointing TRUE if array can be marshalled by pointing 142 normal_... Storage used for array description unless array has more 143 than IDL_NORMAL_DIMS dimensions 144 offset_index Index into offset vector 145 offset_vec_ptr Pointer to current element in offset vector 146 param_addr Address of parameter 147 param_index Index of parameter address in parameter vector 148 range_list List of (A,A+B) pairs determining an array's data limits 149 pointee_defn_index Index into definition vector for pointee definition 150 pointee_defn_ptr Pointer to pointee definition in definition vector 151 struct_addr Address of a structure 152 struct_defn_index Index into definition vector for structure definition 153 struct_defn_ptr Pointer to structure definition in definition vector 154 struct_offset_index Index of start of structure offsets in offset vector 155 struct_offset_vec_ptr Pointer to the start of the offset vector entries 156 for a structure 157 struct_size Size of a structure 158 switch_value Value of union discriminant 159 type_byte Byte describing type of datum currently being handled 160 type_is_modified TRUE if a modifier byte occurred before a type byte 161 type_vec_ptr Pointer to parameter type in type/definition vector 162 unmarshall_by_copying TRUE if array can be unmarshalled by copying 163 Z_values List of dimension sizes for conformant array 164*/ 165 166/******************************************************************************/ 167/* */ 168/* Function returning the local size of an object of a specified type */ 169/* For [transmit_as] returns the size of the presented type */ 170/* For a varying array returns the storage size of the array */ 171/* For a type which does not have a fixed size, returns 0 */ 172/* */ 173/******************************************************************************/ 174idl_ulong_int rpc_ss_type_size 175( 176 /* [in] */ idl_byte *defn_vec_ptr, /* Pointer to start of type 177 specification in definition vector */ 178 IDL_msp_t IDL_msp 179) 180{ 181 idl_byte type; 182 idl_ulong_int complex_defn_index; /* Index to description of complex type */ 183 idl_byte *complex_defn_ptr; /* Pointer to description of complex type */ 184 idl_ulong_int offset_index; 185 idl_ulong_int array_defn_index; 186 idl_byte *array_defn_ptr; 187 idl_ulong_int dimensionality; 188 idl_ulong_int i; 189 idl_ulong_int array_element_count; 190 idl_long_int lower_bound; 191 idl_long_int upper_bound; 192 193 type = *defn_vec_ptr; 194 switch (type) 195 { 196 case IDL_DT_BOOLEAN: 197 return(sizeof(idl_boolean)); 198 case IDL_DT_BYTE: 199 return(sizeof(idl_byte)); 200 case IDL_DT_CHAR: 201 return(sizeof(idl_char)); 202 case IDL_DT_DOUBLE: 203 return(sizeof(idl_long_float)); 204 case IDL_DT_ENUM: 205 case IDL_DT_V1_ENUM: 206 return(sizeof(int)); 207 case IDL_DT_FLOAT: 208 return(sizeof(idl_short_float)); 209 case IDL_DT_SMALL: 210 return(sizeof(idl_small_int)); 211 case IDL_DT_SHORT: 212 return(sizeof(idl_short_int)); 213 case IDL_DT_LONG: 214 return(sizeof(idl_long_int)); 215 case IDL_DT_HYPER: 216 return(sizeof(idl_hyper_int)); 217 case IDL_DT_USMALL: 218 return(sizeof(idl_usmall_int)); 219 case IDL_DT_USHORT: 220 return(sizeof(idl_ushort_int)); 221 case IDL_DT_ULONG: 222 case IDL_DT_ERROR_STATUS: 223 return(sizeof(idl_ulong_int)); 224 case IDL_DT_UHYPER: 225 return(sizeof(idl_uhyper_int)); 226 case IDL_DT_FIXED_STRUCT: 227 case IDL_DT_ENC_UNION: 228 case IDL_DT_TRANSMIT_AS: 229 case IDL_DT_REPRESENT_AS: 230 case IDL_DT_CS_TYPE: 231 defn_vec_ptr += 2; /* After properties byte */ 232 IDL_GET_LONG_FROM_VECTOR(complex_defn_index, defn_vec_ptr); 233 complex_defn_ptr = IDL_msp->IDL_type_vec + complex_defn_index; 234 IDL_GET_LONG_FROM_VECTOR(offset_index, complex_defn_ptr); 235 return(*(IDL_msp->IDL_offset_vec + offset_index)); 236 case IDL_DT_N_E_UNION: 237 defn_vec_ptr += 2; /* After properties byte */ 238 IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Switch index */ 239 IDL_GET_LONG_FROM_VECTOR(complex_defn_index, defn_vec_ptr); 240 complex_defn_ptr = IDL_msp->IDL_type_vec + complex_defn_index; 241 IDL_GET_LONG_FROM_VECTOR(offset_index, complex_defn_ptr); 242 return(*(IDL_msp->IDL_offset_vec + offset_index)); 243 case IDL_DT_STRING: 244 case IDL_DT_V1_STRING: 245 defn_vec_ptr++; 246 /* Next byte is DT_VARYING_ARRAY or DT_OPEN_ARRAY */ 247 type = *defn_vec_ptr; 248 /* If it is not DT_OPEN_ARRAY drop through to process it */ 249 if (type == IDL_DT_OPEN_ARRAY) 250 return 0; 251 case IDL_DT_FIXED_ARRAY: 252 case IDL_DT_VARYING_ARRAY: 253 defn_vec_ptr += 2; /* After properties byte */ 254 IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); 255 /* Ignore the full array definition and look at the flattened one */ 256 IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr); 257 array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; 258 dimensionality = (idl_ulong_int)*array_defn_ptr; 259 array_defn_ptr++; 260 array_element_count = 1; 261 for (i=0; i<dimensionality; i++) 262 { 263 IDL_GET_LONG_FROM_VECTOR(lower_bound, array_defn_ptr); 264 IDL_GET_LONG_FROM_VECTOR(upper_bound, array_defn_ptr); 265 array_element_count *= (upper_bound - lower_bound + 1); 266 } 267 if (type == IDL_DT_VARYING_ARRAY) 268 array_defn_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH; 269 return(array_element_count 270 * rpc_ss_type_size(array_defn_ptr, IDL_msp)); 271 case IDL_DT_FULL_PTR: 272 case IDL_DT_UNIQUE_PTR: 273 case IDL_DT_REF_PTR: 274 return(sizeof(rpc_void_p_t)); 275 case IDL_DT_CS_ARRAY: 276 /* The size of the array this modifier is attached to */ 277 return(rpc_ss_type_size(defn_vec_ptr + 1, IDL_msp)); 278 default: 279 return 0; 280 } 281} 282 283static idl_long_int 284interpsh_apply_func_code(byte func_code, idl_long_int size) 285{ 286 idl_long_int calc_size; 287 288 switch(func_code) { 289 /* only "extended" simple expressions for now */ 290 case IDL_FC_DIV_8: 291 calc_size = size / 8; 292 break; 293 case IDL_FC_MUL_8: 294 calc_size = size * 8; 295 break; 296 case IDL_FC_DIV_4: 297 calc_size = size / 4; 298 break; 299 case IDL_FC_MUL_4: 300 calc_size = size * 4; 301 break; 302 case IDL_FC_DIV_2: 303 calc_size = size / 2; 304 break; 305 case IDL_FC_MUL_2: 306 calc_size = size * 2; 307 break; 308 case IDL_FC_SUB_1: 309 calc_size = size - 1; 310 break; 311 case IDL_FC_ADD_1: 312 calc_size = size + 1; 313 break; 314 case IDL_FC_ALIGN_2: 315 calc_size = (size+1) & ~1; 316 break; 317 case IDL_FC_ALIGN_4: 318 calc_size = (size+3) & ~3; 319 break; 320 case IDL_FC_ALIGN_8: 321 calc_size = (size+7) & ~7; 322 break; 323 case IDL_FC_NONE: 324 default: 325 calc_size = size; 326 break; 327 } 328 return calc_size; 329} 330 331/******************************************************************************/ 332/* */ 333/* Clean up after NDR marshalling */ 334/* */ 335/******************************************************************************/ 336void rpc_ss_ndr_clean_up 337( 338 IDL_ms_t *IDL_msp 339) 340{ 341 unsigned32 i; 342 343 /* Clean up marshalling state */ 344 if (IDL_msp->IDL_buff_addr != NULL 345 && IDL_msp->IDL_stack_packet_status != IDL_stack_packet_in_use_k) 346 { 347 free(IDL_msp->IDL_buff_addr); 348 IDL_msp->IDL_buff_addr = NULL; 349 } 350 for (i=0; i<IDL_msp->IDL_elts_in_use; i++) 351 { 352 if (IDL_msp->IDL_iovec.elt[i].buff_dealloc != NULL) 353 { 354 (*IDL_msp->IDL_iovec.elt[i].buff_dealloc) 355 (IDL_msp->IDL_iovec.elt[i].buff_addr); 356 IDL_msp->IDL_iovec.elt[i].buff_dealloc = NULL; 357 } 358 } 359 360 /* Clean up unmarshalling state */ 361 if (IDL_msp->IDL_elt_p != NULL) 362 { 363 if ((IDL_msp->IDL_elt_p->buff_dealloc != NULL) 364 && (IDL_msp->IDL_elt_p->data_len != 0)) 365 (*IDL_msp->IDL_elt_p->buff_dealloc)(IDL_msp->IDL_elt_p->buff_addr); 366 IDL_msp->IDL_elt_p = NULL; 367 } 368} 369 370/******************************************************************************/ 371/* */ 372/* Create a set of Z values from a list of bounds values */ 373/* */ 374/******************************************************************************/ 375void rpc_ss_Z_values_from_bounds 376( 377 /* [in] */ IDL_bound_pair_t *bounds_list, 378 /* [in] */ idl_ulong_int dimensionality, 379 /* [out] */ idl_ulong_int **p_Z_values, 380 IDL_msp_t IDL_msp 381) 382{ 383 idl_ulong_int *Z_values; 384 unsigned32 i; 385 386 if (*p_Z_values == NULL) 387 { 388 Z_values = (idl_ulong_int *)rpc_ss_mem_alloc 389 (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(idl_ulong_int)); 390 *p_Z_values = Z_values; 391 } 392 else 393 Z_values = *p_Z_values; 394 for (i=0; i<dimensionality; i++) 395 { 396 if (bounds_list[i].upper >= bounds_list[i].lower) 397 Z_values[i] = bounds_list[i].upper - bounds_list[i].lower + 1; 398 else 399 Z_values[i] = 0; 400 } 401} 402 403/******************************************************************************/ 404/* */ 405/* Determine whether the elements of a varying or conformant array to be */ 406/* un/marshalled are contiguous. If they are, also return the total number */ 407/* of elements, and their starting address */ 408/* */ 409/******************************************************************************/ 410void rpc_ss_ndr_contiguous_elt 411( 412 /* [in] */ idl_ulong_int dimensionality, 413 /* [in] */ idl_ulong_int *Z_values, 414 /* [in] */ IDL_bound_pair_t *range_list, 415 /* [in] */ idl_ulong_int element_size, 416 /* [out] */ idl_boolean *p_contiguous, 417 /* [out] */ idl_ulong_int *p_element_count, 418 /* [out] */ rpc_void_p_t *p_array_addr 419) 420{ 421 unsigned i; 422 idl_ulong_int element_count; 423 424 element_count = 1; 425 426 for (i=1; i<dimensionality; i++) 427 { 428 if ( (unsigned32)(range_list[i].upper - range_list[i].lower) != Z_values[i] ) 429 { 430 *p_contiguous = idl_false; 431 return; 432 } 433 element_count *= Z_values[i]; 434 } 435 436 *p_contiguous = idl_true; 437 *p_array_addr = (rpc_void_p_t)((idl_byte *)*p_array_addr 438 + range_list[0].lower * element_count * element_size); 439 *p_element_count = element_count 440 * (range_list[0].upper - range_list[0].lower); 441} 442 443/******************************************************************************/ 444/* */ 445/* Alignment operations and optimizing flag for array un/marshalling */ 446/* */ 447/******************************************************************************/ 448void rpc_ss_ndr_arr_align_and_opt 449( 450 /* [in] */ IDL_mar_or_unmar_k_t marsh_or_unmar, 451 /* [in] */ idl_ulong_int dimensionality ATTRIBUTE_UNUSED, 452 /* [out] */ idl_byte *p_base_type, 453 /* [in] */ idl_byte *defn_vec_ptr, /* Points to array base info */ 454 /* [out] */ idl_boolean *p_optimize, 455 IDL_msp_t IDL_msp 456) 457{ 458 idl_byte base_type; 459 idl_ulong_int defn_index; 460 idl_ulong_int pipe_arr_dims; 461 /* Number of dims of array which is base type of a pipe */ 462 idl_ulong_int struct_defn_index; 463 idl_byte *struct_defn_ptr; 464 465 *p_optimize = idl_false; 466 *p_base_type = *defn_vec_ptr; 467 468 base_type = *p_base_type; 469 if (base_type == IDL_DT_FIXED_ARRAY) 470 { 471 /* Base type of a pipe is an array. Find its base type */ 472 IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Full array defn */ 473 IDL_GET_LONG_FROM_VECTOR( defn_index, defn_vec_ptr ); 474 defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index; 475 pipe_arr_dims = (idl_ulong_int)*defn_vec_ptr; 476 defn_vec_ptr++; /* By design this achieves 4-byte alignment */ 477 defn_vec_ptr += pipe_arr_dims * IDL_FIXED_BOUND_PAIR_WIDTH; 478 base_type = *defn_vec_ptr; 479 } 480 481 switch( base_type ) 482 { 483#ifdef PACKED_BYTE_ARRAYS 484 case IDL_DT_BYTE: 485 *p_optimize = idl_true; 486 break; 487#endif 488#ifdef PACKED_CHAR_ARRAYS 489 case IDL_DT_CHAR: 490 if (marsh_or_unmar == IDL_marshalling_k) 491 *p_optimize = idl_true; 492 else 493 *p_optimize = 494 (IDL_msp->IDL_drep.char_rep == ndr_g_local_drep.char_rep); 495 break; 496#endif 497#ifdef PACKED_SCALAR_ARRAYS 498 case IDL_DT_BOOLEAN: 499 *p_optimize = idl_true; 500 break; 501 case IDL_DT_DOUBLE: 502 if (marsh_or_unmar == IDL_marshalling_k) 503 { 504 IDL_MARSH_ALIGN_MP(IDL_msp, 8); 505 *p_optimize = idl_true; 506 } 507 else 508 { 509 IDL_UNMAR_ALIGN_MP(IDL_msp, 8); 510 *p_optimize = 511 ((IDL_msp->IDL_drep.float_rep == ndr_g_local_drep.float_rep) 512 && (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep)); 513 } 514 break; 515 case IDL_DT_FLOAT: 516 if (marsh_or_unmar == IDL_marshalling_k) 517 { 518 IDL_MARSH_ALIGN_MP(IDL_msp, 4); 519 *p_optimize = idl_true; 520 } 521 else 522 { 523 IDL_UNMAR_ALIGN_MP(IDL_msp, 4); 524 *p_optimize = 525 ((IDL_msp->IDL_drep.float_rep == ndr_g_local_drep.float_rep) 526 && (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep)); 527 } 528 break; 529 case IDL_DT_SMALL: 530 case IDL_DT_USMALL: 531 if (marsh_or_unmar == IDL_marshalling_k) 532 *p_optimize = idl_true; 533 else 534 *p_optimize = 535 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 536 break; 537 case IDL_DT_USHORT: 538 /* If language is C, drop through */ 539 case IDL_DT_SHORT: 540 if (marsh_or_unmar == IDL_marshalling_k) 541 { 542 IDL_MARSH_ALIGN_MP(IDL_msp, 2); 543 *p_optimize = idl_true; 544 } 545 else 546 { 547 IDL_UNMAR_ALIGN_MP(IDL_msp, 2); 548 *p_optimize = 549 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 550 } 551 break; 552 case IDL_DT_ERROR_STATUS: 553 /* If ifdef not active, drop through to next case */ 554#ifdef IDL_ENABLE_STATUS_MAPPING 555 if (marsh_or_unmar == IDL_marshalling_k) 556 { 557 IDL_MARSH_ALIGN_MP(IDL_msp, 4); 558 } 559 else 560 { 561 IDL_UNMAR_ALIGN_MP(IDL_msp, 4); 562 } 563 break; 564#endif 565 case IDL_DT_LONG: 566 case IDL_DT_ULONG: 567 if (marsh_or_unmar == IDL_marshalling_k) 568 { 569 IDL_MARSH_ALIGN_MP(IDL_msp, 4); 570 *p_optimize = idl_true; 571 } 572 else 573 { 574 IDL_UNMAR_ALIGN_MP(IDL_msp, 4); 575 *p_optimize = 576 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 577 } 578 break; 579 case IDL_DT_HYPER: 580 case IDL_DT_UHYPER: 581 if (marsh_or_unmar == IDL_marshalling_k) 582 { 583 IDL_MARSH_ALIGN_MP(IDL_msp, 8); 584 *p_optimize = idl_true; 585 } 586 else 587 { 588 IDL_UNMAR_ALIGN_MP(IDL_msp, 8); 589 *p_optimize = 590 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 591 } 592 break; 593 case IDL_DT_ENUM: 594 if (marsh_or_unmar == IDL_marshalling_k) 595 { 596 IDL_MARSH_ALIGN_MP(IDL_msp, 2); 597 *p_optimize = (sizeof(int) == sizeof(idl_short_int)); 598 } 599 else 600 { 601 IDL_UNMAR_ALIGN_MP(IDL_msp, 2); 602 *p_optimize = (sizeof(int) == sizeof(idl_short_int)) && 603 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 604 } 605 break; 606 case IDL_DT_V1_ENUM: 607 if (marsh_or_unmar == IDL_marshalling_k) 608 { 609 IDL_MARSH_ALIGN_MP(IDL_msp, 4); 610 *p_optimize = (sizeof(int) == sizeof(idl_long_int)); 611 } 612 else 613 { 614 IDL_UNMAR_ALIGN_MP(IDL_msp, 4); 615 *p_optimize = (sizeof(int) == sizeof(idl_long_int)) && 616 (IDL_msp->IDL_drep.int_rep == ndr_g_local_drep.int_rep); 617 } 618 break; 619#endif 620 case IDL_DT_FIXED_STRUCT: 621 defn_vec_ptr++; /* Point at properties byte */ 622 /* Could the structure be relied to be correctly laid out 623 in memory on some architecture? */ 624 if ( ! IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_MAYBE_WIRE_ALIGNED)) 625 break; 626 if (marsh_or_unmar == IDL_unmarshalling_k) 627 { 628 /* Can only unmarshall by copying if the drep's for all the 629 fields match */ 630 if ( IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_DEP_CHAR) 631 && (IDL_msp->IDL_drep.char_rep 632 != ndr_g_local_drep.char_rep) ) 633 break; 634 if ( IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_DEP_INT) 635 && (IDL_msp->IDL_drep.int_rep 636 != ndr_g_local_drep.int_rep) ) 637 break; 638 /* For floating point numbers we need the same encoding 639 and the same endianness */ 640 if ( IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_DEP_FLOAT) 641 && ((IDL_msp->IDL_drep.float_rep 642 != ndr_g_local_drep.float_rep) 643 || (IDL_msp->IDL_drep.int_rep 644 != ndr_g_local_drep.int_rep)) ) 645 break; 646 } 647 defn_vec_ptr++; /* Point after properties byte */ 648 IDL_GET_LONG_FROM_VECTOR(struct_defn_index, defn_vec_ptr); 649 struct_defn_ptr = IDL_msp->IDL_type_vec + struct_defn_index; 650 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 651 /* Discard index into offset vector */ 652 /* Because we can't get here for a [v1_struct], the next byte 653 is an alignment byte unless all the fields are 1-byte */ 654 switch (*struct_defn_ptr) 655 { 656 case IDL_DT_NDR_ALIGN_8: 657#ifdef IDL_NATURAL_ALIGN_8 658 if (marsh_or_unmar == IDL_marshalling_k) 659 { 660 IDL_MARSH_ALIGN_MP(IDL_msp, 8); 661 } 662 else 663 { 664 IDL_UNMAR_ALIGN_MP(IDL_msp, 8); 665 } 666 *p_optimize = idl_true; 667#endif 668 break; 669 case IDL_DT_NDR_ALIGN_4: 670#if defined(IDL_NATURAL_ALIGN_8) || defined(IDL_NATURAL_ALIGN_4) 671 if (marsh_or_unmar == IDL_marshalling_k) 672 { 673 IDL_MARSH_ALIGN_MP(IDL_msp, 4); 674 } 675 else 676 { 677 IDL_UNMAR_ALIGN_MP(IDL_msp, 4); 678 } 679 *p_optimize = idl_true; 680#endif 681 break; 682 case IDL_DT_NDR_ALIGN_2: 683#if defined(IDL_NATURAL_ALIGN_8) || defined(IDL_NATURAL_ALIGN_4) 684 if (marsh_or_unmar == IDL_marshalling_k) 685 { 686 IDL_MARSH_ALIGN_MP(IDL_msp, 2); 687 } 688 else 689 { 690 IDL_UNMAR_ALIGN_MP(IDL_msp, 2); 691 } 692 *p_optimize = idl_true; 693#endif 694 break; 695 default: 696#if defined(IDL_NATURAL_ALIGN_8) || defined(IDL_NATURAL_ALIGN_4) || defined(IDL_NATURAL_ALIGN_1) 697 *p_optimize = idl_true; 698#endif 699 break; 700 } 701 break; 702 default: 703 break; 704 } 705} 706 707/******************************************************************************/ 708/* */ 709/* Function whose result is the integer that is of the given type at the */ 710/* given address. For use in unions, boolean's, char's and enum's are */ 711/* treated as integers. */ 712/* */ 713/******************************************************************************/ 714idl_long_int rpc_ss_get_typed_integer 715( 716 /* [in] */ idl_byte type, 717 /* [in] */ rpc_void_p_t address, 718 IDL_msp_t IDL_msp ATTRIBUTE_UNUSED 719) 720{ 721 switch (type) 722 { 723 case IDL_DT_BOOLEAN: 724 return( (idl_long_int)(*(idl_boolean *)address) ); 725 case IDL_DT_CHAR: 726 return( (idl_long_int)(*(idl_char *)address) ); 727 case IDL_DT_ENUM: 728 case IDL_DT_V1_ENUM: 729 return( (idl_long_int)(*(int *)address) ); 730 case IDL_DT_SMALL: 731 return( (idl_long_int)(*(idl_small_int *)address) ); 732 case IDL_DT_SHORT: 733 return( (idl_long_int)(*(idl_short_int *)address) ); 734 case IDL_DT_LONG: 735 return( (idl_long_int)(*(idl_long_int *)address) ); 736 case IDL_DT_USMALL: 737 return( (idl_long_int)(*(idl_usmall_int *)address) ); 738 case IDL_DT_USHORT: 739 return( (idl_long_int)(*(idl_ushort_int *)address) ); 740 case IDL_DT_ERROR_STATUS: 741 case IDL_DT_ULONG: 742 /* !!! Overflow here if value > 2**31 - 1 !!! */ 743 return( (idl_long_int)(*(idl_ulong_int *)address) ); 744 default: 745 DCETHREAD_RAISE( rpc_x_coding_error ); 746 } 747} 748 749/******************************************************************************/ 750/* */ 751/* Build a bounds list for a conformant or open array */ 752/* */ 753/******************************************************************************/ 754void rpc_ss_build_bounds_list 755( 756 /* [in,out] */ idl_byte **p_defn_vec_ptr, 757 /* On entry defn_vec_ptr points to bounds info */ 758 /* On exit it points at 759 conformant array - base type info 760 open array - data limit info */ 761 /* [in] */ rpc_void_p_t array_addr, /* NULL when building bounds list 762 for a conformant structure */ 763 /* [in] */ rpc_void_p_t struct_addr, /* Address of structure that array 764 is field of. NULL if array is a parameter */ 765 /* [in] */ idl_ulong_int *struct_offset_vec_ptr, 766 /* NULL if array is a parameter */ 767 /* [in] */ idl_ulong_int dimensionality, 768 /* [out] */ IDL_bound_pair_t **p_bounds_list, 769 IDL_msp_t IDL_msp 770) 771{ 772 return rpc_ss_build_bounds_list_2(p_defn_vec_ptr, array_addr, struct_addr, 773 struct_offset_vec_ptr, dimensionality, 774 NULL, p_bounds_list, IDL_msp); 775} 776 777/******************************************************************************/ 778/* */ 779/* Build a bounds list for a conformant or open array, with an optional */ 780/* bitmap indicating whether correlated arguments are yet to be unmarshalled */ 781/* */ 782/******************************************************************************/ 783void rpc_ss_build_bounds_list_2 784( 785 /* [in,out] */ idl_byte **p_defn_vec_ptr, 786 /* On entry defn_vec_ptr points to bounds info */ 787 /* On exit it points at 788 conformant array - base type info 789 open array - data limit info */ 790 /* [in] */ rpc_void_p_t array_addr, /* NULL when building bounds list 791 for a conformant structure */ 792 /* [in] */ rpc_void_p_t struct_addr, /* Address of structure that array 793 is field of. NULL if array is a parameter */ 794 /* [in] */ idl_ulong_int *struct_offset_vec_ptr, 795 /* NULL if array is a parameter */ 796 /* [in] */ idl_ulong_int dimensionality, 797 /* [in] */ idl_boolean *unmarshalled_list, /* NULL if marshalling */ 798 /* [out] */ IDL_bound_pair_t **p_bounds_list, 799 IDL_msp_t IDL_msp 800) 801{ 802 IDL_bound_pair_t *bounds_list; 803 idl_byte *defn_vec_ptr = *p_defn_vec_ptr; 804 idl_byte bound_kind, bound_type; 805 unsigned32 i; 806 idl_long_int size; 807 idl_ulong_int element_size; /* Size of base type of string */ 808 idl_ulong_int attribute_index; 809 rpc_void_p_t bound_addr; 810 idl_ulong_int string_field_offset; /* Offset index for string field */ 811 byte func_code = 0; 812 813 if (*p_bounds_list == NULL) 814 { 815 bounds_list = (IDL_bound_pair_t *)rpc_ss_mem_alloc 816 (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(IDL_bound_pair_t)); 817 *p_bounds_list = bounds_list; 818 } 819 else 820 bounds_list = *p_bounds_list; 821 822 for (i = 0; i < dimensionality; i++) 823 { 824 /* Get lower bound */ 825 bound_kind = (*defn_vec_ptr & IDL_BOUND_TYPE_MASK); 826 defn_vec_ptr++; 827 if (bound_kind == IDL_BOUND_FIXED) 828 { 829 IDL_GET_LONG_FROM_VECTOR(bounds_list[i].lower, defn_vec_ptr); 830 } 831 else 832 { 833 /* Lower bound is [min_is] */ 834 bound_type = *defn_vec_ptr; 835 defn_vec_ptr++; 836 IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); 837 if (unmarshalled_list == NULL || unmarshalled_list[i]) 838 { 839 if (struct_addr == NULL) 840 bound_addr = IDL_msp->IDL_param_vec[attribute_index]; 841 else 842 { 843 bound_addr = (rpc_void_p_t) 844 ((idl_byte *)struct_addr 845 + struct_offset_vec_ptr[attribute_index]); 846 } 847 bounds_list[i].lower = 848 rpc_ss_get_typed_integer( bound_type, bound_addr, 849 IDL_msp ); 850 } 851 else 852 bounds_list[i].lower = -1; 853 } 854 855 /* Get upper bound */ 856 bound_kind = (*defn_vec_ptr & IDL_BOUND_TYPE_MASK); 857 defn_vec_ptr++; 858 if (bound_kind == IDL_BOUND_FIXED) 859 { 860 IDL_GET_LONG_FROM_VECTOR(bounds_list[i].upper, defn_vec_ptr); 861 } 862 else if (bound_kind == IDL_BOUND_STRING) 863 { 864 element_size = (idl_ulong_int)*defn_vec_ptr; 865 defn_vec_ptr++; 866 IDL_GET_LONG_FROM_VECTOR(string_field_offset, defn_vec_ptr); 867 /* Value is only used in conformant struct size case */ 868 if (unmarshalled_list == NULL || unmarshalled_list[i]) 869 { 870 if (array_addr == NULL) 871 { 872 /* Conformant field of conformant structure 873 has size determined by [string] */ 874 array_addr = (rpc_void_p_t)((idl_byte *)struct_addr 875 + *(struct_offset_vec_ptr 876 + string_field_offset)); 877 } 878 if (element_size == 1) 879 bounds_list[i].upper = bounds_list[i].lower 880 + (idl_long_int) strlen(array_addr); 881 else 882 { 883 size = rpc_ss_strsiz( (idl_char *)array_addr, element_size ); 884 bounds_list[i].upper = bounds_list[i].lower + size - 1; 885 } 886 } 887 else 888 bounds_list[i].upper = -1; 889 } 890 else 891 { 892 if (bound_kind == IDL_BOUND_SIZE_IS) 893 { 894 func_code = *defn_vec_ptr; 895 defn_vec_ptr++; 896 } 897 /* Upper bound is [max_is] or [size_is] */ 898 bound_type = *defn_vec_ptr; 899 defn_vec_ptr++; 900 IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); 901 if (unmarshalled_list == NULL || unmarshalled_list[i]) 902 { 903 if (struct_addr == NULL) 904 bound_addr = IDL_msp->IDL_param_vec[attribute_index]; 905 else 906 { 907 bound_addr = (rpc_void_p_t) 908 ((idl_byte *)struct_addr 909 + struct_offset_vec_ptr[attribute_index]); 910 } 911 if (bound_kind == IDL_BOUND_MAX_IS) 912 bounds_list[i].upper = 913 rpc_ss_get_typed_integer( bound_type, bound_addr, 914 IDL_msp ); 915 else /* IDL_BOUND_SIZE_IS */ 916 { 917 size = rpc_ss_get_typed_integer( bound_type, bound_addr, 918 IDL_msp ); 919 920 bounds_list[i].upper = bounds_list[i].lower + 921 interpsh_apply_func_code(func_code, size) - 1; 922 } 923 } 924 else 925 bounds_list[i].upper = -1; 926 } 927 /* Inside out bounds mean "no elements". Store value which will 928 yield 0 in subsequent calculations */ 929 if (bounds_list[i].upper < bounds_list[i].lower) 930 bounds_list[i].upper = bounds_list[i].lower - 1; 931 } 932 933 *p_defn_vec_ptr = defn_vec_ptr; 934} 935 936/******************************************************************************/ 937/* */ 938/* A range list is a set of [A, A+B] pairs for a varying array. Build one. */ 939/* Note that A is the difference between the lower bound and the index of */ 940/* the first element in the dimension to be shipped. B is the number of */ 941/* elements in that dimension to be shipped. */ 942/* */ 943/******************************************************************************/ 944void rpc_ss_build_range_list 945( 946 /* [in,out] */ idl_byte **p_defn_vec_ptr, 947 /* [in] */ rpc_void_p_t array_addr, /* Only used if [string] data limit */ 948 /* [in] */ rpc_void_p_t struct_addr, /* Address of structure array is a 949 field of. NULL if array is a parameter */ 950 /* [in] */ idl_ulong_int *struct_offset_vec_ptr, 951 /* NULL if array is a parameter */ 952 /* [in] */ idl_ulong_int dimensionality, 953 /* [in] */ IDL_bound_pair_t *bounds_list, 954 /* [out] */ IDL_bound_pair_t **p_range_list, 955 /* [out] */ idl_boolean *p_add_null, 956 IDL_msp_t IDL_msp 957) 958{ 959 return rpc_ss_build_range_list_2(p_defn_vec_ptr, array_addr, struct_addr, 960 struct_offset_vec_ptr, dimensionality, 961 bounds_list, NULL, p_range_list, p_add_null, 962 IDL_msp); 963} 964 965/******************************************************************************/ 966/* */ 967/* A range list is a set of [A, A+B] pairs for a varying array. Build one, */ 968/* with an optoinal bitmap indicating whether correlated arguments are yet */ 969/* to be unmarshalled. */ 970/* Note that A is the difference between the lower bound and the index of */ 971/* the first element in the dimension to be shipped. B is the number of */ 972/* elements in that dimension to be shipped. */ 973/* */ 974/******************************************************************************/ 975void rpc_ss_build_range_list_2 976( 977 /* [in,out] */ idl_byte **p_defn_vec_ptr, 978 /* [in] */ rpc_void_p_t array_addr, /* Only used if [string] data limit */ 979 /* [in] */ rpc_void_p_t struct_addr, /* Address of structure array is a 980 field of. NULL if array is a parameter */ 981 /* [in] */ idl_ulong_int *struct_offset_vec_ptr, 982 /* NULL if array is a parameter */ 983 /* [in] */ idl_ulong_int dimensionality, 984 /* [in] */ IDL_bound_pair_t *bounds_list, 985 /* [in] */ idl_boolean *unmarshalled_list, /* NULL if marshalling */ 986 /* [out] */ IDL_bound_pair_t **p_range_list, 987 /* [out] */ idl_boolean *p_add_null, 988 IDL_msp_t IDL_msp 989) 990{ 991 IDL_bound_pair_t *range_list; 992 idl_byte *defn_vec_ptr = *p_defn_vec_ptr; 993 idl_byte limit_kind, limit_type; 994 unsigned32 i; 995 idl_long_int data_limit; 996 idl_ulong_int element_size; /* Size of base type of string */ 997 idl_ulong_int attribute_index; 998 rpc_void_p_t limit_addr; 999 byte func_code = 0; 1000 1001 *p_add_null = idl_false; 1002 if (*p_range_list == NULL) 1003 { 1004 range_list = (IDL_bound_pair_t *)rpc_ss_mem_alloc 1005 (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(IDL_bound_pair_t)); 1006 *p_range_list = range_list; 1007 } 1008 else 1009 range_list = *p_range_list; 1010 1011 for (i=0; i<dimensionality; i++) 1012 { 1013 /* Get lower data limit */ 1014 limit_kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK); 1015 defn_vec_ptr++; 1016 if (limit_kind == IDL_LIMIT_FIXED) 1017 { 1018 IDL_GET_LONG_FROM_VECTOR(data_limit, defn_vec_ptr); 1019 } 1020 else 1021 { 1022 /* Lower data limit is [first_is] */ 1023 limit_type = *defn_vec_ptr; 1024 defn_vec_ptr++; 1025 IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); 1026 if (unmarshalled_list == NULL || unmarshalled_list[i]) 1027 { 1028 if (struct_addr == NULL) 1029 limit_addr = IDL_msp->IDL_param_vec[attribute_index]; 1030 else 1031 { 1032 limit_addr = (rpc_void_p_t) 1033 ((idl_byte *)struct_addr 1034 + struct_offset_vec_ptr[attribute_index]); 1035 } 1036 data_limit = rpc_ss_get_typed_integer( limit_type, limit_addr, 1037 IDL_msp ); 1038 } 1039 } 1040 1041 if (unmarshalled_list == NULL || unmarshalled_list[i]) 1042 { 1043 range_list[i].lower = data_limit - bounds_list[i].lower; 1044 if (range_list[i].lower < 0) 1045 DCETHREAD_RAISE( rpc_x_invalid_bound ); 1046 } 1047 else 1048 range_list[i].lower = -1; 1049 1050 /* Get upper data limit */ 1051 limit_kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK); 1052 defn_vec_ptr++; 1053 if (limit_kind == IDL_LIMIT_FIXED) 1054 { 1055 IDL_GET_LONG_FROM_VECTOR(data_limit, defn_vec_ptr); 1056 range_list[i].upper = data_limit + 1 - bounds_list[i].lower; 1057 } 1058 else if (limit_kind == IDL_LIMIT_STRING) 1059 { 1060 element_size = (idl_ulong_int)*defn_vec_ptr; 1061 /* Element size byte is discarded as we align to discard dummy 1062 longword */ 1063 IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); 1064 if (unmarshalled_list == NULL || unmarshalled_list[i]) 1065 { 1066 if (element_size == 1) 1067 data_limit = (idl_long_int) strlen(array_addr) + 1; 1068 else 1069 data_limit = rpc_ss_strsiz( (idl_char *)array_addr, 1070 element_size ); 1071 range_list[i].upper = range_list[i].lower + data_limit; 1072 if ( ! (*p_add_null) ) 1073 { 1074 if ( range_list[i].upper > (bounds_list[i].upper 1075 - bounds_list[i].lower + 1) ) 1076 DCETHREAD_RAISE( rpc_x_invalid_bound ); 1077 } 1078 } 1079 else 1080 range_list[i].upper = -1; 1081 } 1082 else if (limit_kind == IDL_LIMIT_UPPER_CONF) 1083 { 1084 /* Dummy type byte is discarded as we align to discard dummy 1085 longword */ 1086 IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); 1087 range_list[i].upper = 1088 bounds_list[i].upper - bounds_list[i].lower + 1; 1089 } 1090 else 1091 { 1092 /* Upper data limit is [last_is] or [length_is] */ 1093 if (limit_kind == IDL_LIMIT_LENGTH_IS) 1094 { 1095 func_code = *defn_vec_ptr; 1096 defn_vec_ptr++; 1097 } 1098 1099 limit_type = *defn_vec_ptr; 1100 defn_vec_ptr++; 1101 IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); 1102 if (unmarshalled_list == NULL || unmarshalled_list[i]) 1103 { 1104 if (struct_addr == NULL) 1105 limit_addr = IDL_msp->IDL_param_vec[attribute_index]; 1106 else 1107 { 1108 limit_addr = (rpc_void_p_t) 1109 ((idl_byte *)struct_addr 1110 + struct_offset_vec_ptr[attribute_index]); 1111 } 1112 data_limit = rpc_ss_get_typed_integer( limit_type, limit_addr, 1113 IDL_msp ); 1114 if (limit_kind == IDL_LIMIT_LENGTH_IS) 1115 { 1116 range_list[i].upper = range_list[i].lower + interpsh_apply_func_code(func_code, data_limit); 1117 } 1118 else 1119 { 1120 range_list[i].upper = data_limit - bounds_list[i].lower + 1; 1121 } 1122 if ( range_list[i].upper > (bounds_list[i].upper 1123 - bounds_list[i].lower + 1) ) 1124 DCETHREAD_RAISE( rpc_x_invalid_bound ); 1125 } 1126 else 1127 range_list[i].upper = -1; 1128 } 1129#ifdef DEBUG_INTERP 1130 if (unmarshalled_list == NULL || unmarshalled_list[i]) 1131 printf("dim %lu range upr: %ld lwr: %ld func: %d\n", i, 1132 range_list[i].upper, range_list[i].lower, func_code); 1133#endif 1134 /* Inside out limits mean "transmit no elements" */ 1135 if (range_list[i].upper < range_list[i].lower) 1136 range_list[i].upper = range_list[i].lower; 1137 } 1138 1139 *p_defn_vec_ptr = defn_vec_ptr; 1140} 1141 1142/******************************************************************************/ 1143/* */ 1144/* Get the size of string storage for the base type of an array of string */ 1145/* and the index value of the start of the string's array description */ 1146/* */ 1147/******************************************************************************/ 1148void rpc_ss_get_string_base_desc 1149( 1150 /* [in] */ idl_byte *defn_vec_ptr, /* Pointer to DT_STRING in base type 1151 specification in definition vector */ 1152 /* [out] */ idl_ulong_int *p_array_size, 1153 /* [out] */ idl_ulong_int *p_array_defn_index, 1154 IDL_msp_t IDL_msp 1155) 1156{ 1157 idl_byte *array_defn_ptr; 1158 idl_long_int string_lower_bound, string_upper_bound; 1159 idl_ulong_int array_element_count; 1160 1161 defn_vec_ptr += 3; /* DT_STRING, DT_VARYING_ARRAY, properties */ 1162 IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); 1163 /* Ignore the full array definition and look at the flattened one */ 1164 IDL_GET_LONG_FROM_VECTOR(*p_array_defn_index, defn_vec_ptr); 1165 array_defn_ptr = IDL_msp->IDL_type_vec + *p_array_defn_index; 1166 array_defn_ptr++; /* Discard dimensionality */ 1167 IDL_GET_LONG_FROM_VECTOR(string_lower_bound, array_defn_ptr); 1168 IDL_GET_LONG_FROM_VECTOR(string_upper_bound, array_defn_ptr); 1169 array_element_count = string_upper_bound - string_lower_bound + 1; 1170 *p_array_size = 1171 array_element_count * IDL_DATA_LIMIT_PAIR_CHAR_SIZE(array_defn_ptr); 1172} 1173 1174/******************************************************************************/ 1175/* */ 1176/* Point at the union arm definition for the supplied switch value */ 1177/* Returns FALSE if there is no match, TRUE otherwise */ 1178/* */ 1179/******************************************************************************/ 1180idl_boolean rpc_ss_find_union_arm_defn 1181( 1182 /* [in] */ idl_byte *defn_vec_ptr, /* Points at first union arm defn */ 1183 /* [in] */ idl_ulong_int arm_count, /* Number of non-default arms */ 1184 /* [in] */ idl_ulong_int switch_value, /* to be matched */ 1185 /* [out] */ idl_byte **p_arm_type_ptr, 1186 /* Pointer to type part of arm with matching switch value */ 1187 /* [in] */ IDL_msp_t IDL_msp 1188 /* marshall state ptr needed for IDL_ARM macro */ 1189) 1190{ 1191 idl_long_int low, mid, high; /* Element indices */ 1192 idl_ulong_int arm_switch_value; /* To test supplied value against */ 1193 1194 /* If there are no elements to search, then return no match found. */ 1195 1196 if (arm_count == 0) 1197 return(idl_false); 1198 1199 /* Initialize the search interval to include all elements. */ 1200 1201 low = 0; 1202 high = arm_count - 1; 1203 1204 /* Loop, computing the midpoint element and comparing it to the desired 1205 element until a match is found or all elements are exhausted. 1206 Note that the midpoint index by convention is always 1207 rounded down if there is a remainder after division. 1208 */ 1209 do { 1210 mid = (low + high) / 2; /* Compute midpoint element */ 1211 arm_switch_value = IDL_ARM_SWITCH_VALUE(defn_vec_ptr, mid); 1212 if (switch_value > arm_switch_value) 1213 { 1214 /* If element is beyond the midpoint */ 1215 low = mid + 1; /* adjust low index past midpoint */ 1216 } 1217 else if (switch_value < arm_switch_value) 1218 { 1219 /* If element is prior to the midpoint */ 1220 high = mid - 1; /* adjust high index below midpoint */ 1221 } 1222 else 1223 break; /* Otherwise, element was found! */ 1224 } while (high >= low); 1225 1226 if (high >= low) 1227 { 1228 /* Match was found - point at arm that matched */ 1229 *p_arm_type_ptr = defn_vec_ptr + mid * IDL_UNION_ARM_DESC_WIDTH; 1230 /* Advance pointer over switch value */ 1231 IDL_DISCARD_LONG_FROM_VECTOR( *p_arm_type_ptr ); 1232 return(idl_true); 1233 } 1234 else 1235 return(idl_false); 1236} 1237 1238/******************************************************************************/ 1239/* */ 1240/* Get, from data in memory, the value of the discriminant of a */ 1241/* non-encapsulated union */ 1242/* */ 1243/******************************************************************************/ 1244void rpc_ss_get_switch_from_data 1245( 1246 /* [in] */ idl_ulong_int switch_index, 1247 /* If union is parameter, index in param list of discriminant */ 1248 /* If union is field, index in offset list for discriminant */ 1249 /* [in] */ idl_byte switch_type, 1250 /* [in] */ rpc_void_p_t struct_addr, /* Address of structure union is 1251 field of. NULL if union is parameter */ 1252 /* [in] */ idl_ulong_int *struct_offset_vec_ptr, 1253 /* NULL if union is parameter */ 1254 /* [out] */ idl_ulong_int *p_switch_value, 1255 IDL_msp_t IDL_msp 1256) 1257{ 1258 rpc_void_p_t switch_addr; 1259 1260 if ( struct_addr == NULL ) 1261 switch_addr = IDL_msp->IDL_param_vec[switch_index]; 1262 else 1263 switch_addr = (rpc_void_p_t)((idl_byte *)struct_addr 1264 + struct_offset_vec_ptr[switch_index]); 1265 1266 *p_switch_value = rpc_ss_get_typed_integer( switch_type, switch_addr, 1267 IDL_msp ); 1268} 1269 1270/******************************************************************************/ 1271/* */ 1272/* Return TRUE if a -bug flag in the range 1-31 is set */ 1273/* */ 1274/******************************************************************************/ 1275idl_boolean rpc_ss_bug_1_thru_31 1276( 1277 /* [in] */ idl_ulong_int bug_mask, 1278 IDL_msp_t IDL_msp 1279) 1280{ 1281 idl_byte *defn_vec_ptr; 1282 idl_ulong_int defn_index; 1283 idl_ulong_int flags; 1284 1285 /* Get position of bug flags */ 1286 defn_vec_ptr = IDL_msp->IDL_type_vec + 40; 1287 IDL_GET_LONG_FROM_VECTOR( defn_index, defn_vec_ptr ); 1288 1289 /* Get flags longword for bugs 1-31 */ 1290 defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index; 1291 IDL_GET_LONG_FROM_VECTOR( flags, defn_vec_ptr ); 1292 1293 return( (flags & bug_mask) != 0 ); 1294} 1295 1296/******************************************************************************/ 1297/* */ 1298/* If -bug 1 is set and we are marshalling a [v1_array] with no elements, */ 1299/* alignment must be forced to the last scalar that would have been */ 1300/* marshalled if we had marshalled an array element. */ 1301/* This function returns the alignment to be applied. */ 1302/* */ 1303/******************************************************************************/ 1304idl_ulong_int rpc_ss_ndr_bug_1_align 1305( 1306 /* [in] */ idl_byte *defn_vec_ptr, /* Points at array base type unless 1307 in recursive call. In recursive call, points at defn 1308 of structure field, union arm, or transmitted type */ 1309 IDL_msp_t IDL_msp 1310) 1311{ 1312 idl_ulong_int defn_index; 1313 idl_byte *struct_defn_ptr; 1314 idl_byte *last_field_defn_ptr = NULL; /* Points to the definition of the last 1315 field of a structure */ 1316 idl_byte type_byte; 1317 idl_ulong_int array_defn_index; 1318 idl_byte *array_defn_ptr; 1319 idl_ulong_int dimensionality; 1320 idl_byte *union_defn_ptr; 1321 idl_ulong_int arm_count; 1322 idl_ulong_int min_union_align; /* Minimum alignment forced by any 1323 union arm */ 1324 idl_ulong_int arm_align; /* Alignment for last field of current arm */ 1325 unsigned32 i; 1326 1327 type_byte = *defn_vec_ptr; 1328 switch (type_byte) 1329 { 1330 case IDL_DT_BYTE: 1331 case IDL_DT_CHAR: 1332 case IDL_DT_BOOLEAN: 1333 case IDL_DT_SMALL: 1334 case IDL_DT_USMALL: 1335 return 1; 1336 case IDL_DT_SHORT: 1337 case IDL_DT_USHORT: 1338 return 2; 1339 case IDL_DT_FLOAT: 1340 case IDL_DT_LONG: 1341 case IDL_DT_ULONG: 1342 case IDL_DT_V1_ENUM: 1343 case IDL_DT_ERROR_STATUS: 1344 return 4; 1345 case IDL_DT_DOUBLE: 1346 case IDL_DT_HYPER: 1347 case IDL_DT_UHYPER: 1348 return 8; 1349 case IDL_DT_FIXED_STRUCT: 1350 /* Structure analysis follows switch statement */ 1351 break; 1352 case IDL_DT_FIXED_ARRAY: 1353 case IDL_DT_VARYING_ARRAY: 1354 case IDL_DT_OPEN_ARRAY: 1355 /* Alignment forced by array base type */ 1356 defn_vec_ptr += 2; /* DT_ARRAY and properties byte */ 1357 IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); 1358 /* Full array definition */ 1359 IDL_GET_LONG_FROM_VECTOR( array_defn_index, defn_vec_ptr ); 1360 array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; 1361 dimensionality = (idl_ulong_int)*array_defn_ptr; 1362 if (type_byte == IDL_DT_FIXED_ARRAY) 1363 array_defn_ptr += dimensionality * sizeof(IDL_bound_pair_t); 1364 else if (type_byte == IDL_DT_VARYING_ARRAY) 1365 { 1366 array_defn_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH; 1367 array_defn_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH; 1368 } 1369 else /* type_byte == IDL_OPEN_VARYING_ARRAY */ 1370 { 1371 IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr, dimensionality ); 1372 array_defn_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH; 1373 } 1374 return rpc_ss_ndr_bug_1_align(array_defn_ptr, IDL_msp); 1375 case IDL_DT_V1_ARRAY: 1376 case IDL_DT_V1_STRING: 1377 /* Discard modiier - do array alignment */ 1378 defn_vec_ptr++; 1379 return rpc_ss_ndr_bug_1_align(defn_vec_ptr, IDL_msp); 1380 case IDL_DT_ENC_UNION: 1381 /* Weakest alignment forced by any union arm */ 1382 defn_vec_ptr += 2; /* DT_ENC_UNION and properties byte */ 1383 IDL_GET_LONG_FROM_VECTOR( defn_index, defn_vec_ptr ); 1384 union_defn_ptr = IDL_msp->IDL_type_vec + defn_index; 1385 IDL_GET_LONG_FROM_VECTOR( arm_count, union_defn_ptr ); 1386 IDL_DISCARD_LONG_FROM_VECTOR( union_defn_ptr ); 1387 /* Point at type of first arm */ 1388 min_union_align = 8; /* Maximum alignment required by NDR */ 1389 for (i=0; i<arm_count+1; i++) 1390 { 1391 if (*union_defn_ptr != IDL_DT_VOID) 1392 { 1393 arm_align = rpc_ss_ndr_bug_1_align(union_defn_ptr, IDL_msp); 1394 if (arm_align < min_union_align) 1395 min_union_align = arm_align; 1396 } 1397 union_defn_ptr += IDL_UNION_ARM_DESC_WIDTH; 1398 } 1399 return min_union_align; 1400 case IDL_DT_TRANSMIT_AS: 1401 /* Resolve down to non-[transmit_as] type */ 1402 while (*defn_vec_ptr == IDL_DT_TRANSMIT_AS) 1403 { 1404 defn_vec_ptr += 2; /* DT_TRANSMIT_AS and properties byte */ 1405 IDL_GET_LONG_FROM_VECTOR( defn_index, defn_vec_ptr ); 1406 defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index; 1407 } 1408 return rpc_ss_ndr_bug_1_align(defn_vec_ptr, IDL_msp); 1409 default: 1410 /* Other flags cannot occur in a [v1_struct] */ 1411#ifdef DEBUG_INTERP 1412 printf( 1413 "rpc_ss_ndr_bug_1_struct_align:unrecognized alignment type %d\n", 1414 type_byte); 1415 exit(0); 1416#endif 1417 DCETHREAD_RAISE(rpc_x_coding_error); 1418 } 1419 1420 /* Return alignment required for last field of structure */ 1421 defn_vec_ptr += 2; /* DT_FIXED_STRUCT and properties byte */ 1422 IDL_GET_LONG_FROM_VECTOR(defn_index, defn_vec_ptr); 1423 struct_defn_ptr = IDL_msp->IDL_type_vec + defn_index; 1424 1425 /* Find the last field of the structure */ 1426 do { 1427 type_byte = *struct_defn_ptr; 1428 if (type_byte != IDL_DT_EOL) 1429 last_field_defn_ptr = struct_defn_ptr; 1430 struct_defn_ptr++; 1431 switch(type_byte) 1432 { 1433 case IDL_DT_BYTE: 1434 case IDL_DT_CHAR: 1435 case IDL_DT_BOOLEAN: 1436 case IDL_DT_DOUBLE: 1437 case IDL_DT_FLOAT: 1438 case IDL_DT_SMALL: 1439 case IDL_DT_SHORT: 1440 case IDL_DT_LONG: 1441 case IDL_DT_HYPER: 1442 case IDL_DT_USMALL: 1443 case IDL_DT_USHORT: 1444 case IDL_DT_ULONG: 1445 case IDL_DT_UHYPER: 1446 case IDL_DT_V1_ENUM: 1447 case IDL_DT_ERROR_STATUS: 1448 break; 1449 case IDL_DT_FIXED_ARRAY: 1450 struct_defn_ptr++; /* Skip over properties byte */ 1451 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1452 /* Full array definition */ 1453 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1454 /* Flattened array definition */ 1455 break; 1456 case IDL_DT_VARYING_ARRAY: 1457 struct_defn_ptr++; /* Skip over properties byte */ 1458 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1459 /* Full array definition */ 1460 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1461 /* Flattened array definition */ 1462 break; 1463 case IDL_DT_OPEN_ARRAY: 1464 struct_defn_ptr++; /* Skip over properties byte */ 1465 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1466 /* Full array definition */ 1467 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1468 /* Flattened array definition */ 1469 break; 1470 case IDL_DT_ENC_UNION: 1471 struct_defn_ptr++; /* Skip over properties byte */ 1472 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1473 /* Union definition */ 1474 break; 1475 case IDL_DT_TRANSMIT_AS: 1476 case IDL_DT_REPRESENT_AS: 1477 struct_defn_ptr++; /* Skip over properties byte */ 1478 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1479 /* [transmit_as] definition */ 1480 break; 1481 case IDL_DT_V1_ARRAY: 1482 break; 1483 case IDL_DT_V1_STRING: 1484 struct_defn_ptr += 2; /* DT_VARYING_ARRAY and properties */ 1485 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1486 /* Full array defn */ 1487 IDL_DISCARD_LONG_FROM_VECTOR(struct_defn_ptr); 1488 /* Flattened array defn */ 1489 break; 1490 1491 case IDL_DT_EOL: 1492 break; 1493 default: 1494 /* Other flags cannot occur in a [v1_struct] */ 1495#ifdef DEBUG_INTERP 1496 printf( 1497 "rpc_ss_ndr_bug_1_struct_align:unrecognized field type %d\n", 1498 type_byte); 1499 exit(0); 1500#endif 1501 DCETHREAD_RAISE(rpc_x_coding_error); 1502 } 1503 } while (type_byte != IDL_DT_EOL); 1504 1505 /* Do alignment for last field */ 1506 return rpc_ss_ndr_bug_1_align(last_field_defn_ptr, IDL_msp); 1507} 1508 1509/******************************************************************************/ 1510/* */ 1511/* Check type vector consistent with interpreter version */ 1512/* */ 1513/******************************************************************************/ 1514void rpc_ss_type_vec_vers_check 1515( 1516 IDL_msp_t IDL_msp 1517) 1518{ 1519 idl_short_int interp_major_version, interp_minor_version; 1520 1521 interp_major_version = IDL_VERSION_NUMBER(IDL_INTERP_ENCODE_MAJOR); 1522 interp_minor_version = IDL_VERSION_NUMBER(IDL_INTERP_ENCODE_MINOR); 1523 if ((interp_major_version != 3) || (interp_minor_version > 2)) 1524 { 1525#ifdef DEBUG_INTERP 1526 printf("Expecting data structure version 3.0, 3.1 or 3.2 - found %d.%d\n", 1527 interp_major_version, interp_minor_version); 1528 exit(0); 1529#endif 1530 DCETHREAD_RAISE( rpc_x_unknown_stub_rtl_if_vers ); 1531 } 1532} 1533 1534static rpc_void_p_t 1535rpc_ss_default_alloc(idl_size_t size) 1536{ 1537 return (rpc_void_p_t) malloc((size_t) size); 1538} 1539 1540static void 1541rpc_ss_default_free(rpc_void_p_t obj) 1542{ 1543 free ((void*) obj); 1544} 1545 1546static void 1547rpc_ss_init_mem_handle(rpc_ss_mem_handle* handle) 1548{ 1549 handle->memory = NULL; 1550 handle->node_table = NULL; 1551 1552 handle->alloc = rpc_ss_default_alloc; 1553 handle->free = rpc_ss_default_free; 1554} 1555 1556/******************************************************************************/ 1557/* */ 1558/* Initialize the marshalling state block */ 1559/* */ 1560/******************************************************************************/ 1561void rpc_ss_init_marsh_state 1562( 1563 idl_byte IDL_type_vec[], 1564 IDL_msp_t IDL_msp 1565) 1566{ 1567 rpc_ss_init_mem_handle(&IDL_msp->IDL_mem_handle); 1568 IDL_msp->IDL_status = error_status_ok; 1569 IDL_msp->IDL_elts_in_use = 0; 1570 IDL_msp->IDL_buff_addr = NULL; 1571 IDL_msp->IDL_left_in_buff = 0; 1572 IDL_msp->IDL_mp_start_offset = 0; 1573 IDL_msp->IDL_type_vec = IDL_type_vec; 1574 IDL_msp->IDL_pickling_handle = NULL; 1575 /* Protect against old stubs that haven't allocated a stack packet */ 1576 IDL_msp->IDL_stack_packet_addr = NULL; 1577 IDL_msp->IDL_stack_packet_status = IDL_stack_packet_used_k; 1578 1579 if (IDL_type_vec == NULL) 1580 { 1581 /* Pickling call, version check will be done later */ 1582 return; 1583 } 1584 rpc_ss_type_vec_vers_check( IDL_msp ); 1585} 1586 1587/* always include these routines to read type vecs in either endian */ 1588 1589/******************************************************************************/ 1590/* */ 1591/* Build a bounds list from fixed bounds in the definition vector */ 1592/* */ 1593/******************************************************************************/ 1594void rpc_ss_fixed_bounds_from_vector 1595( 1596 /* [in] */ idl_ulong_int dimensionality, 1597 /* [in] */ idl_byte *array_defn_ptr, /* Points at array bounds */ 1598 /* [out] */ IDL_bound_pair_t **p_bounds_list, 1599 IDL_msp_t IDL_msp 1600) 1601{ 1602 IDL_bound_pair_t *bounds_list; 1603 unsigned32 i; 1604 1605 bounds_list = (IDL_bound_pair_t *)rpc_ss_mem_alloc 1606 (&IDL_msp->IDL_mem_handle, (dimensionality * sizeof(IDL_bound_pair_t))); 1607 for (i=0; i<dimensionality; i++) 1608 { 1609 IDL_GET_LONG_FROM_VECTOR(bounds_list[i].lower,array_defn_ptr); 1610 IDL_GET_LONG_FROM_VECTOR(bounds_list[i].upper,array_defn_ptr); 1611 } 1612 *p_bounds_list = bounds_list; 1613} 1614 1615/******************************************************************************/ 1616/* */ 1617/* Return the switch value for the specified union arm */ 1618/* */ 1619/******************************************************************************/ 1620idl_ulong_int rpc_ss_arm_switch_value 1621( 1622 /* [in] */ idl_byte *defn_vec_ptr, /* Points at first union arm defn */ 1623 /* [in] */ idl_long_int index, /* Index of union arm desc */ 1624 /* [in] */ IDL_msp_t IDL_msp /* Needed for GET_LONG macro */ 1625) 1626{ 1627 idl_byte *switch_value_ptr; /* Points to switch value in defn vec */ 1628 idl_ulong_int switch_value; 1629 1630 switch_value_ptr = defn_vec_ptr + index * IDL_UNION_ARM_DESC_WIDTH; 1631 IDL_GET_LONG_FROM_VECTOR(switch_value, switch_value_ptr); 1632 return(switch_value); 1633} 1634 1635/******************************************************************************/ 1636/* */ 1637/* Write an unsigned value of specified integer type to an untyped location */ 1638/* */ 1639/******************************************************************************/ 1640void rpc_ss_put_typed_integer 1641( 1642 /* in */ idl_ulong_int value, 1643 /* in */ idl_byte type, 1644 /* in */ rpc_void_p_t address 1645) 1646{ 1647 switch (type) 1648 { 1649 case IDL_DT_SMALL: 1650 *(idl_small_int *)address = (idl_small_int)value; 1651 break; 1652 case IDL_DT_USMALL: 1653 *(idl_usmall_int *)address = (idl_usmall_int)value; 1654 break; 1655 case IDL_DT_SHORT: 1656 *(idl_short_int *)address = (idl_short_int)value; 1657 break; 1658 case IDL_DT_USHORT: 1659 *(idl_ushort_int *)address = (idl_ushort_int)value; 1660 break; 1661 case IDL_DT_LONG: 1662 *(idl_long_int *)address = (idl_long_int)value; 1663 break; 1664 case IDL_DT_ULONG: 1665 *(idl_ulong_int *)address = (idl_ulong_int)value; 1666 break; 1667 default: 1668 DCETHREAD_RAISE(rpc_x_coding_error); 1669 } 1670} 1671