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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <strings.h> 30 #include <string.h> 31 #include "ndrgen.h" 32 #include "y.tab.h" 33 34 35 #define ALLOW_NOTHING 0 36 #define ALLOW_VARSIZE 1 37 #define ALLOW_INOUT 2 38 #define ALLOW_CASE 4 39 #define ALLOW_NO_UNIONS 8 /* for topmost structures */ 40 #define ALLOW_NO_SWITCH 16 41 42 struct tup { 43 struct tup *up; 44 ndr_typeinfo_t *ti; 45 }; 46 47 static void type_ident_decl(ndr_typeinfo_t *, char *, size_t, char *); 48 static void type_ident_decl1(struct tup *, char *, size_t, char *); 49 static void analyze_typeinfo_list(void); 50 static void analyze_typeinfo_typedef(ndr_typeinfo_t *); 51 static void analyze_typeinfo_struct(ndr_typeinfo_t *); 52 static void analyze_typeinfo_union(ndr_typeinfo_t *); 53 static void analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *); 54 static void analyze_member(ndr_node_t *, ndr_member_t *, unsigned long *, int); 55 static void seed_basic_types(void); 56 static void seed_construct_types(void); 57 static void append_typeinfo(ndr_typeinfo_t *); 58 static ndr_typeinfo_t *bind_typeinfo(ndr_typeinfo_t *); 59 static ndr_typeinfo_t *find_typeinfo_by_name(ndr_node_t *); 60 static void determine_advice(ndr_advice_t *, ndr_node_t *); 61 static ndr_node_t *find_advice(ndr_node_t *advice_list, int label); 62 63 64 void 65 analyze(void) 66 { 67 seed_basic_types(); 68 seed_construct_types(); 69 70 analyze_typeinfo_list(); 71 } 72 73 void 74 show_typeinfo_list(void) 75 { 76 ndr_typeinfo_t *ti; 77 ndr_typeinfo_t *tdti; 78 int i; 79 ndr_member_t *mem; 80 char *p; 81 char fname_type[NDLBUFSZ]; 82 83 for (ti = typeinfo_list; ti; ti = ti->next) { 84 switch (ti->type_op) { 85 case STRUCT_KW: 86 p = "struct"; 87 break; 88 89 case UNION_KW: 90 p = "union"; 91 break; 92 93 case TYPEDEF_KW: 94 p = "typedef"; 95 break; 96 97 case STRING_KW: 98 case STAR: 99 case LB: 100 case BASIC_TYPE: 101 type_extern_suffix(ti, fname_type, NDLBUFSZ); 102 if (ti->is_extern) { 103 (void) printf("extern ndr_%s()\n", 104 fname_type); 105 } else if (!ti->is_referenced) { 106 (void) printf("implied ndr_%s\n", fname_type); 107 } 108 continue; 109 110 default: 111 (void) printf("show_typeinfo skipping %d\n", 112 ti->type_op); 113 continue; 114 } 115 116 (void) printf("\n\n"); 117 show_advice(&ti->advice, 0); 118 (void) printf("%s %s {\n", p, ti->type_name->n_sym->name); 119 120 for (i = 0; i < ti->n_member; i++) { 121 mem = &ti->member[i]; 122 show_advice(&mem->advice, 2); 123 type_extern_suffix(mem->type, fname_type, NDLBUFSZ); 124 (void) printf(" %-16s ndr_%-13s", 125 mem->name, fname_type); 126 127 tdti = mem->type; 128 (void) printf(" fsiz=%d vsiz=%d algn=%d off=%d\n", 129 tdti->size_fixed_part, 130 tdti->size_variable_part, 131 tdti->alignment, 132 mem->pdu_offset); 133 } 134 135 (void) printf("} fsiz=%d vsiz=%d algn=%d comp=%d ptrs=%d\n", 136 ti->size_fixed_part, 137 ti->size_variable_part, 138 ti->alignment, 139 ti->complete, 140 ti->has_pointers); 141 } 142 } 143 144 void 145 type_extern_suffix(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen) 146 { 147 ndr_typeinfo_t *ti; 148 char *p_fb = funcbuf; 149 150 *p_fb = 0; 151 152 for (ti = tsti; ti; ti = ti->type_down) { 153 switch (ti->type_op) { 154 case BASIC_TYPE: 155 case STRUCT_KW: 156 case TYPEDEF_KW: 157 case UNION_KW: 158 (void) snprintf(p_fb, buflen, "_%s", 159 ti->type_name->n_sym->name); 160 break; 161 162 case STAR: 163 (void) strlcpy(p_fb, "p", buflen); 164 break; 165 166 case LB: 167 if (ti->type_dim) { 168 (void) snprintf(p_fb, buflen, "a%ld", 169 ti->type_dim->n_int); 170 } else { 171 (void) snprintf(p_fb, buflen, "ac"); 172 } 173 break; 174 175 case STRING_KW: 176 (void) strlcpy(p_fb, "s", buflen); 177 break; 178 179 default: 180 (void) snprintf(p_fb, buflen, "?<%d>", ti->type_op); 181 break; 182 } 183 while (*p_fb) 184 p_fb++; 185 } 186 } 187 188 static void 189 type_ident_decl1(struct tup *tup, char *funcbuf, size_t buflen, char *ident) 190 { 191 ndr_typeinfo_t *ti; 192 char fb[NDLBUFSZ]; 193 char *p; 194 195 if (!tup) { 196 (void) strlcpy(funcbuf, ident, buflen); 197 return; 198 } 199 ti = tup->ti; 200 201 switch (ti->type_op) { 202 case BASIC_TYPE: 203 case TYPEDEF_KW: 204 type_ident_decl1(tup->up, fb, NDLBUFSZ, ident); 205 (void) snprintf(funcbuf, buflen, "%s%s%s%s", 206 "", ti->type_name->n_sym->name, *fb ? " " : "", fb); 207 break; 208 209 case STRUCT_KW: 210 type_ident_decl1(tup->up, fb, NDLBUFSZ, ident); 211 (void) snprintf(funcbuf, buflen, "%s%s%s%s", 212 "struct ", ti->type_name->n_sym->name, *fb ? " " : "", fb); 213 break; 214 215 case UNION_KW: 216 type_ident_decl1(tup->up, fb, NDLBUFSZ, ident); 217 (void) snprintf(funcbuf, buflen, "%s%s%s%s", 218 "union ", ti->type_name->n_sym->name, *fb ? " " : "", fb); 219 break; 220 221 case STAR: 222 *funcbuf = '*'; 223 type_ident_decl1(tup->up, funcbuf+1, buflen - 1, ident); 224 break; 225 226 case LB: 227 p = fb; 228 *p++ = '('; 229 type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident); 230 if (*p == '*') { 231 p = fb; 232 (void) strlcat(p, ")", NDLBUFSZ); 233 } 234 if (ti->type_dim) { 235 (void) snprintf(funcbuf, buflen, "%s[%ld]", 236 p, ti->type_dim->n_int); 237 } else { 238 (void) snprintf(funcbuf, buflen, 239 "%s[NDR_ANYSIZE_DIM]", p); 240 } 241 break; 242 243 case STRING_KW: 244 p = fb; 245 *p++ = '('; 246 type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident); 247 if (*p == '*') { 248 p = fb; 249 (void) strlcat(p, ")", NDLBUFSZ); 250 } 251 (void) snprintf(funcbuf, buflen, "%s[NDR_STRING_DIM]", p); 252 break; 253 254 default: 255 compile_error("unknown type or keyword <%d>", ti->type_op); 256 break; 257 } 258 } 259 260 static void 261 type_ident_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *ident) 262 { 263 ndr_typeinfo_t *ti; 264 struct tup tup_tab[40]; 265 struct tup *tup; 266 struct tup *up = 0; 267 int n_tt = 0; 268 269 for (ti = tsti; ti; ti = ti->type_down, n_tt++) { 270 tup = &tup_tab[n_tt]; 271 tup->up = up; 272 tup->ti = ti; 273 up = tup; 274 } 275 276 type_ident_decl1(up, funcbuf, buflen, ident); 277 } 278 279 void 280 type_null_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen) 281 { 282 funcbuf[0] = '('; 283 type_ident_decl(tsti, funcbuf+1, buflen, ""); 284 (void) strlcat(funcbuf, ")", buflen); 285 } 286 287 void 288 type_name_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *name) 289 { 290 type_ident_decl(tsti, funcbuf, buflen, name); 291 } 292 293 void 294 show_advice(ndr_advice_t *adv, int indent) 295 { 296 int i; 297 int n = 0; 298 299 for (i = 0; i < N_ADVICE; i++) { 300 if (!adv->a_nodes[i]) 301 continue; 302 303 if (n++ == 0) 304 (void) printf("%-*s[", indent, ""); 305 else 306 (void) printf(" "); 307 308 print_node(adv->a_nodes[i]); 309 } 310 311 if (n) 312 (void) printf("]\n"); 313 } 314 315 static void 316 analyze_typeinfo_list(void) 317 { 318 ndr_typeinfo_t *ti; 319 320 for (ti = typeinfo_list; ti; ti = ti->next) { 321 switch (ti->type_op) { 322 case STRUCT_KW: 323 analyze_typeinfo_struct(ti); 324 break; 325 326 case UNION_KW: 327 analyze_typeinfo_union(ti); 328 break; 329 330 case TYPEDEF_KW: 331 analyze_typeinfo_typedef(ti); 332 break; 333 } 334 } 335 } 336 337 static void 338 analyze_typeinfo_typedef(ndr_typeinfo_t *ti) 339 { 340 ndr_node_t *mem_np; 341 ndr_member_t *mem; 342 int i; 343 int allow; 344 unsigned long offset; 345 346 assert(ti->type_op == TYPEDEF_KW); 347 348 /* 349 * Snarf the advice. 350 */ 351 determine_advice(&ti->advice, ti->definition->n_c_advice); 352 353 /* 354 * Convert the members to table. 355 * Determine layout metrics along the way. 356 */ 357 mem_np = ti->definition->n_c_members; 358 i = 0; 359 offset = 0; 360 assert(i < ti->n_member); 361 mem = &ti->member[i]; 362 363 allow = ALLOW_NO_SWITCH; 364 365 analyze_member(mem_np, mem, 366 &offset, /* progress offset */ 367 allow); /* see above */ 368 369 assert(1 == ti->n_member); 370 371 analyze_typeinfo_aggregate_finish(ti); 372 373 /* Align offset to determine overall size */ 374 while (offset & ti->alignment) 375 offset++; 376 377 ti->size_fixed_part = offset; 378 } 379 380 static void 381 analyze_typeinfo_struct(ndr_typeinfo_t *ti) 382 { 383 ndr_node_t *mem_np; 384 ndr_member_t *mem; 385 int i; 386 int allow; 387 unsigned long offset; 388 389 assert(ti->type_op == STRUCT_KW); 390 391 /* 392 * Snarf the advice. Only recognize [operation()] for 393 * struct definitions. 394 */ 395 determine_advice(&ti->advice, ti->definition->n_c_advice); 396 397 /* 398 * Convert the members from list to table. 399 * Determine layout metrics along the way. 400 */ 401 mem_np = ti->definition->n_c_members; 402 i = 0; 403 offset = 0; 404 for (; mem_np; i++, mem_np = mem_np->n_next) { 405 assert(i < ti->n_member); 406 mem = &ti->member[i]; 407 408 if (!ti->advice.a_operation /* no var-size in op param */ && 409 i == ti->n_member-1) /* only last mem may be var-size */ 410 allow = ALLOW_VARSIZE; 411 else 412 allow = 0; 413 414 analyze_member(mem_np, mem, &offset, allow); 415 } 416 assert(i == ti->n_member); 417 418 analyze_typeinfo_aggregate_finish(ti); /* align,complete,ptrs,etc */ 419 420 /* Align offset to determine overall size */ 421 while (offset & ti->alignment) 422 offset++; 423 424 ti->size_fixed_part = offset; 425 426 /* If last member is var-sized, so is this struct */ 427 mem = &ti->member[ti->n_member-1]; 428 ti->size_variable_part = mem->type->size_variable_part; 429 430 if (ti->size_variable_part) 431 ti->is_conformant = 1; 432 } 433 434 static void 435 analyze_typeinfo_union(ndr_typeinfo_t *ti) 436 { 437 ndr_node_t *mem_np; 438 ndr_member_t *mem; 439 int i; 440 unsigned long offset; 441 unsigned long size; 442 443 assert(ti->type_op == UNION_KW); 444 445 /* 446 * Snarf the advice. None supported for union definitions. 447 * Only [switch_is()] supported for union instances. 448 */ 449 determine_advice(&ti->advice, ti->definition->n_c_advice); 450 451 /* 452 * Convert the members from list to table. 453 * Determine layout metrics along the way. 454 */ 455 mem_np = ti->definition->n_c_members; 456 i = 0; 457 size = 0; 458 for (; mem_np; i++, mem_np = mem_np->n_next) { 459 assert(i < ti->n_member); 460 mem = &ti->member[i]; 461 462 offset = 0; /* all members offset=0 */ 463 analyze_member(mem_np, mem, 464 &offset, 465 ALLOW_CASE+ALLOW_NO_UNIONS); /* var-size disallowed */ 466 467 if (size < mem->type->size_fixed_part) 468 size = mem->type->size_fixed_part; 469 } 470 assert(i == ti->n_member); 471 472 analyze_typeinfo_aggregate_finish(ti); /* align,complete,ptrs,etc */ 473 474 /* align size to determine overall size */ 475 while (size & ti->alignment) 476 size++; 477 478 ti->size_fixed_part = size; 479 } 480 481 static void 482 analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *ti) 483 { 484 int i; 485 ndr_member_t *mem; 486 int complete = 1; 487 int has_pointers = 0; 488 489 for (i = 0; i < ti->n_member; i++) { 490 mem = &ti->member[i]; 491 492 complete &= mem->type->complete; 493 has_pointers |= mem->type->has_pointers; 494 ti->alignment |= mem->type->alignment; 495 } 496 497 ti->complete = complete; 498 ti->has_pointers = has_pointers; 499 } 500 501 static void 502 analyze_member(ndr_node_t *mem_np, ndr_member_t *mem, 503 unsigned long *offsetp, int allow) 504 { 505 int i, n_decl_ops; 506 ndr_node_t *decl_ops[NDLBUFSZ]; 507 ndr_typeinfo_t *type_down; 508 ndr_typeinfo_t proto_ti; 509 ndr_node_t *np; 510 511 /* 512 * Set line_number for error reporting (so we know where to look) 513 */ 514 line_number = mem_np->line_number; 515 516 /* 517 * Simple parts of member 518 */ 519 mem->definition = mem_np; 520 determine_advice(&mem->advice, mem_np->n_m_advice); 521 522 /* 523 * The node list for the declarator is in outside-to-inside 524 * order. It is also decorated with the LP nodes for 525 * precedence, which are in our way at this point. 526 * 527 * These two loops reverse the list, which is easier 528 * to analyze. For example, the declaration: 529 * 530 * ulong * (id[100]); 531 * 532 * will have the node list (=> indicates n_d_descend): 533 * 534 * ulong => STAR => LP => LB[100] => id 535 * 536 * and the conversion will result in type info (=> indicates 537 * type_down): 538 * 539 * id => LB[100] => STAR => ulong 540 * 541 * which is closer to how you would pronounce the declaration: 542 * 543 * id is an array size 100 of pointers to ulong. 544 */ 545 546 /* first pass -- turn the list into a table */ 547 n_decl_ops = 0; 548 for (np = mem_np->n_m_decl; np; np = np->n_d_descend) { 549 if (np->label == IDENTIFIER) { 550 break; /* done */ 551 } 552 553 if (np->label == LP) 554 continue; /* ignore precedence nodes */ 555 556 decl_ops[n_decl_ops++] = np; 557 } 558 if (!np) { 559 compile_error("declaration error"); 560 print_node(mem_np->n_m_decl); 561 (void) printf("\n"); 562 } else { 563 mem->name = np->n_sym->name; 564 } 565 566 /* second pass -- turn the table into push-back list */ 567 type_down = find_typeinfo_by_name(mem_np->n_m_type); 568 569 if (type_down->type_op == TYPEDEF_KW) 570 type_down = type_down->member[0].type; 571 572 if (mem->advice.a_string) { 573 bzero(&proto_ti, sizeof (proto_ti)); 574 proto_ti.type_op = STRING_KW; 575 proto_ti.type_down = type_down; 576 type_down = bind_typeinfo(&proto_ti); 577 } 578 579 for (i = n_decl_ops; i-- > 0; ) { 580 np = decl_ops[i]; 581 582 bzero(&proto_ti, sizeof (proto_ti)); 583 584 proto_ti.type_op = np->label; 585 proto_ti.type_down = type_down; 586 587 switch (np->label) { 588 case LB: 589 proto_ti.type_dim = np->n_d_dim; 590 break; 591 } 592 593 /* 594 * bind_typeinfo() reuses (interns) typeinfo's to 595 * make later code generation easier. It will report 596 * some errors. 597 */ 598 type_down = bind_typeinfo(&proto_ti); 599 } 600 601 /* bind the member to its type info */ 602 mem->type = type_down; 603 type_down->is_referenced = 1; /* we handle first-level indirection */ 604 605 /* 606 * Now, apply the type info to the member layout metrics. 607 */ 608 609 /* alignment */ 610 while (*offsetp & type_down->alignment) 611 ++*offsetp; 612 613 mem->pdu_offset = *offsetp; 614 615 *offsetp += type_down->size_fixed_part; 616 617 if (mem->advice.a_length_is) 618 compile_error("[length_is()] is not supported"); 619 620 if (mem->advice.a_transmit_as) 621 compile_error("[transmit_as()] is not supported"); 622 623 if (mem->advice.a_arg_is) 624 compile_error("[arg_is()] is not supported"); 625 626 /* 627 * Disallow 628 * [case(x)] TYPE xxx; 629 * [default] TYPE xxx; 630 * 631 * These only make sense within unions. 632 */ 633 if (allow & ALLOW_CASE) { 634 int n = 0; 635 636 if (mem->advice.a_case) 637 n++; 638 if (mem->advice.a_default) 639 n++; 640 641 if (n == 0) 642 compile_error("no [case/default] advice"); 643 else if (n > 1) 644 compile_error("too many [case/default] advice"); 645 } else { 646 if (mem->advice.a_case && mem->advice.a_default) 647 compile_error("[case/default] advice not allowed"); 648 } 649 650 /* 651 * Disallow 652 * [operation(x)] TYPE foo; 653 * [interface(x)] TYPE foo; 654 * [uuid(x)] TYPE foo; 655 * 656 * The [operation()] advice may only appear on a struct to 657 * indicate that the structure is a top-most (parameter) 658 * structure, and the opcode associated with the parameters. 659 */ 660 if (mem->advice.a_operation) 661 compile_error("[operation()] advice not allowed"); 662 663 if (mem->advice.a_interface) 664 compile_error("[interface()] advice not allowed"); 665 666 if (mem->advice.a_uuid) 667 compile_error("[uuid()] advice not allowed"); 668 669 /* 670 * Allow 671 * [switch_is(x)] union foo xxx; 672 * 673 * Disallow [switch_is] on anything which is not a union. 674 */ 675 if (mem->advice.a_switch_is && type_down->type_op != UNION_KW) { 676 compile_error("[switch_is()] advice not allowed"); 677 } 678 679 /* 680 * Allow 681 * [size_is(x)] TYPE * ptr; 682 * [size_is(x)] TYPE arr[]; 683 * 684 * Disallow [size_is()] on anything other than pointer and 685 * variable length array. 686 */ 687 if (mem->advice.a_size_is && 688 type_down->type_op != STAR && 689 !(type_down->type_op == LB && 690 type_down->type_dim == 0)) { 691 compile_error("[size_is()] advice not allowed"); 692 } 693 694 /* 695 * Allow 696 * [string] char * ptr_string; 697 * 698 * Disallow [string] on anything else. The determination 699 * of size (for the outer header) on anything else is 700 * impossible. 701 */ 702 if (mem->advice.a_string && type_down->type_op != STAR) { 703 compile_error("[string] advice not allowed"); 704 } 705 706 if (type_down->type_op == LB && 707 type_down->type_dim == 0) { /* var-length array of some sort */ 708 709 int n = 0; 710 711 /* 712 * Requires [size_is()] directive 713 * [size_is(x)] TYPE array[] 714 */ 715 716 if (mem->advice.a_size_is) 717 n++; 718 719 if (!n) 720 compile_error("var-size missing sizing directive"); 721 else if (n > 1) 722 compile_error("var-size too many sizing directives"); 723 } 724 725 /* 726 * Nested unions and struct members, other than the last one, 727 * cannot contain variable sized members. 728 */ 729 if (type_down->size_variable_part && !(allow & ALLOW_VARSIZE)) { 730 compile_error("var-size member not allowed"); 731 } 732 733 /* 734 * Disallow unions in operations (i.e. [operation()] struct ...), 735 * The switch_is() value is not reliably available. DCE/RPC 736 * automatically synthesizes an encapsulated union for 737 * these situations, which we have to do by hand: 738 * 739 * struct { long switch_value; union foo x; } synth; 740 * 741 * We also can not allow unions within unions because 742 * there is no way to pass the separate [switch_is(x)] selector. 743 */ 744 if (type_down->type_op == UNION_KW) { 745 if (allow & ALLOW_NO_UNIONS) { 746 compile_error("unencapsulated union not allowed"); 747 } else if (!mem->advice.a_switch_is && 748 !(allow & ALLOW_NO_SWITCH)) { 749 compile_error("union instance without selector"); 750 } 751 } 752 } 753 754 static void 755 seed_basic_types(void) 756 { 757 ndr_symbol_t *sym; 758 ndr_typeinfo_t *ti; 759 ndr_typeinfo_t proto_ti; 760 761 for (sym = symbol_list; sym; sym = sym->next) { 762 if (!sym->kw) 763 continue; 764 765 if (sym->kw->token != BASIC_TYPE) 766 continue; 767 768 ti = ndr_alloc(1, sizeof (ndr_typeinfo_t)); 769 770 ti->type_op = BASIC_TYPE; 771 ti->definition = &sym->s_node; 772 ti->type_name = &sym->s_node; 773 ti->size_fixed_part = sym->kw->value; 774 ti->alignment = ti->size_fixed_part - 1; 775 ti->complete = 1; 776 ti->is_extern = 1; 777 778 append_typeinfo(ti); 779 780 bzero(&proto_ti, sizeof (proto_ti)); 781 proto_ti.type_op = STRING_KW; 782 proto_ti.type_down = ti; 783 784 ti = bind_typeinfo(&proto_ti); 785 ti->is_extern = 1; 786 } 787 } 788 789 static void 790 seed_construct_types(void) 791 { 792 ndr_node_t *construct; 793 ndr_node_t *np; 794 unsigned n_member; 795 ndr_typeinfo_t *ti; 796 797 construct = construct_list; 798 for (; construct; construct = construct->n_next) { 799 ti = ndr_alloc(1, sizeof (ndr_typeinfo_t)); 800 801 ti->type_op = construct->label; 802 ti->definition = construct; 803 804 switch (ti->type_op) { 805 case TYPEDEF_KW: 806 case STRUCT_KW: 807 case UNION_KW: 808 ti->type_name = construct->n_c_typename; 809 810 np = construct->n_c_members; 811 n_member = 0; 812 for (; np; np = np->n_next) 813 n_member++; 814 815 ti->n_member = n_member; 816 if (n_member > 0) 817 ti->member = ndr_alloc(n_member, 818 sizeof (ndr_member_t)); 819 break; 820 821 default: 822 fatal_error("seed_construct unknown %d\n", ti->type_op); 823 break; 824 } 825 826 determine_advice(&ti->advice, construct->n_c_advice); 827 828 ti->is_referenced = 1; /* always generate */ 829 830 append_typeinfo(ti); 831 } 832 } 833 834 static void 835 append_typeinfo(ndr_typeinfo_t *ti) 836 { 837 ndr_typeinfo_t **pp; 838 839 for (pp = &typeinfo_list; *pp; pp = &(*pp)->next) 840 ; 841 842 *pp = ti; 843 ti->next = 0; 844 } 845 846 static ndr_typeinfo_t * 847 bind_typeinfo(ndr_typeinfo_t *proto_ti) 848 { 849 ndr_typeinfo_t *ti; 850 ndr_typeinfo_t *tdti = proto_ti->type_down; 851 852 for (ti = typeinfo_list; ti; ti = ti->next) { 853 if (ti->type_op != proto_ti->type_op) 854 continue; 855 856 switch (ti->type_op) { 857 case STAR: 858 if (ti->type_down != proto_ti->type_down) 859 continue; 860 break; 861 862 case STRING_KW: 863 if (ti->type_down != proto_ti->type_down) 864 continue; 865 break; 866 867 case LB: 868 if (ti->type_down != proto_ti->type_down) 869 continue; 870 if (ti->type_dim != proto_ti->type_dim) 871 continue; 872 break; 873 874 case BASIC_TYPE: 875 case STRUCT_KW: 876 case TYPEDEF_KW: 877 case UNION_KW: 878 if (ti->type_name != proto_ti->type_name) 879 continue; 880 break; 881 882 default: 883 fatal_error("bind_typeinfo unknown %d\n", ti->type_op); 884 break; 885 } 886 887 return (ti); 888 } 889 890 ti = ndr_alloc(1, sizeof (ndr_typeinfo_t)); 891 892 *ti = *proto_ti; 893 append_typeinfo(ti); 894 895 switch (ti->type_op) { 896 case STAR: 897 ti->size_fixed_part = 4; 898 ti->alignment = 3; 899 ti->complete = 1; 900 ti->has_pointers = 1; 901 break; 902 903 case STRING_KW: 904 case LB: 905 if (tdti->complete) { 906 ti->alignment = tdti->alignment; 907 if (tdti->size_variable_part) { 908 compile_error("array of var-size type"); 909 } else if (ti->type_dim) { 910 ti->size_fixed_part = tdti->size_fixed_part * 911 ti->type_dim->n_int; 912 } else { 913 ti->size_variable_part = tdti->size_fixed_part; 914 ti->is_conformant = 1; 915 } 916 } else { 917 compile_error("array of incomplete type"); 918 } 919 920 ti->has_pointers = tdti->has_pointers; 921 ti->complete = 1; 922 break; 923 924 default: 925 compile_error("bind_type internal error op=%d", ti->type_op); 926 break; 927 } 928 929 /* 930 * Disallow 931 * union foo *ptrfoo; 932 * There is no way to pass the selector (switch_is)in 933 */ 934 if (ti->type_op == STAR && ti->type_down->type_op == UNION_KW) { 935 compile_error("pointers to unions not allowed"); 936 } 937 938 /* 939 * Disallow 940 * union foo fooarr[n]; 941 * Each element needs a distinct selector 942 */ 943 if (ti->type_op == LB && ti->type_down->type_op == UNION_KW) { 944 compile_error("arrays of unions not allowed"); 945 } 946 947 return (ti); 948 } 949 950 static ndr_typeinfo_t * 951 find_typeinfo_by_name(ndr_node_t *typename) 952 { 953 ndr_typeinfo_t *ti; 954 955 for (ti = typeinfo_list; ti; ti = ti->next) { 956 if (ti->type_name == typename) 957 return (ti); 958 } 959 960 compile_error("unknown type %s", typename->n_sym->name); 961 962 /* fake BASIC_TYPE */ 963 ti = ndr_alloc(1, sizeof (ndr_typeinfo_t)); 964 ti->type_op = BASIC_TYPE; 965 ti->definition = typename; 966 ti->type_name = typename; 967 ti->size_fixed_part = 0; 968 ti->alignment = 0; 969 970 append_typeinfo(ti); 971 return (ti); 972 } 973 974 static void 975 determine_advice(ndr_advice_t *advice, ndr_node_t *advice_list) 976 { 977 /* alias for basic types */ 978 advice->a_transmit_as = find_advice(advice_list, TRANSMIT_AS_KW); 979 980 /* arg used for size, union, or generic purpose */ 981 advice->a_arg_is = find_advice(advice_list, ARG_IS_KW); 982 983 /* operation parameter in/out stuff */ 984 advice->a_operation = find_advice(advice_list, OPERATION_KW); 985 advice->a_in = find_advice(advice_list, IN_KW); 986 advice->a_out = find_advice(advice_list, OUT_KW); 987 988 /* size stuff */ 989 advice->a_string = find_advice(advice_list, STRING_KW); 990 advice->a_size_is = find_advice(advice_list, SIZE_IS_KW); 991 advice->a_length_is = find_advice(advice_list, LENGTH_IS_KW); 992 993 /* union stuff */ 994 advice->a_case = find_advice(advice_list, CASE_KW); 995 advice->a_default = find_advice(advice_list, DEFAULT_KW); 996 advice->a_switch_is = find_advice(advice_list, SWITCH_IS_KW); 997 998 /* interface stuff */ 999 advice->a_interface = find_advice(advice_list, INTERFACE_KW); 1000 advice->a_uuid = find_advice(advice_list, UUID_KW); 1001 advice->a_no_reorder = find_advice(advice_list, _NO_REORDER_KW); 1002 advice->a_extern = find_advice(advice_list, EXTERN_KW); 1003 1004 advice->a_reference = find_advice(advice_list, REFERENCE_KW); 1005 advice->a_align = find_advice(advice_list, ALIGN_KW); 1006 } 1007 1008 static ndr_node_t * 1009 find_advice(ndr_node_t *advice_list, int label) 1010 { 1011 ndr_node_t *np; 1012 1013 for (np = advice_list; np; np = np->n_next) 1014 if (np->label == label) 1015 break; 1016 1017 return (np); 1018 } 1019 1020 void 1021 member_fixup(ndr_node_t *member_np) 1022 { 1023 ndr_node_t *np; 1024 1025 for (np = member_np->n_m_decl; np; np = np->n_d_descend) 1026 if (np->label == IDENTIFIER) 1027 break; 1028 1029 member_np->n_m_name = np; 1030 } 1031 1032 void 1033 construct_fixup(ndr_node_t *construct_np) 1034 { 1035 construct_np->n_c_typename->n_sym->typedefn = construct_np; 1036 } 1037