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** NAME: 79** 80** mtsbacke.c 81** 82** FACILITY: 83** 84** Interface Definition Language (IDL) Compiler 85** 86** ABSTRACT: 87** 88** Backend control for MTS compiler 89** 90*/ 91 92#include <nidl.h> 93#include <ast.h> 94#include <irep.h> /* Intermediate Representation defs */ 95#include <command.h> 96#include <ddbe.h> /* Data Driven Backend defs */ 97#include <mtsbacke.h> 98#include <hdgen.h> 99#include <cstubmts.h> 100#include <sstubmts.h> 101 102/* 103 * Global type instances and boolean 104 */ 105boolean *BE_cmd_opt; 106void **BE_cmd_val; 107AST_type_n_t *BE_ulong_int_p, *BE_ushort_int_p, *BE_pointer_p, *BE_function_p; 108AST_type_n_t *BE_short_null_p, *BE_long_null_p, *BE_hyper_null_p; 109boolean BE_space_opt, BE_bug_array_align, BE_bug_array_align2, 110 BE_bug_boolean_def 111 ; 112 113#ifdef DUMPERS 114boolean BE_dump_debug, BE_dump_flat, BE_dump_mnode, BE_dump_mool, 115 BE_dump_recs, BE_dump_sends, BE_dump_unode, BE_dump_uool, 116 BE_zero_mem; 117#endif 118 119/* 120 * be_init 121 * 122 * Initialize the various backend globals 123 */ 124static void be_init 125( 126 boolean *cmd_opt, 127 void **cmd_val 128) 129{ 130 boolean *bugs; 131 132 /* 133 * initialize various options-related globals 134 */ 135 BE_cmd_opt = cmd_opt; 136 BE_cmd_val = cmd_val; 137 BE_space_opt = cmd_opt[opt_space_opt]; 138#ifdef DUMPERS 139 BE_dump_debug = cmd_opt[opt_dump_debug]; 140 BE_dump_flat = cmd_opt[opt_dump_flat]; 141 BE_dump_mnode = cmd_opt[opt_dump_mnode]; 142 BE_dump_mool = cmd_opt[opt_dump_mool]; 143 BE_dump_recs = cmd_opt[opt_dump_recs]; 144 BE_dump_sends = cmd_opt[opt_dump_sends]; 145 BE_dump_unode = cmd_opt[opt_dump_unode]; 146 BE_dump_uool = cmd_opt[opt_dump_uool]; 147 BE_zero_mem = (getenv("IDL_zero_mem") != NULL); 148#endif 149 150 /* 151 * Backwards compatibility marshalling 152 */ 153 bugs = (boolean *)cmd_val[opt_do_bug]; 154 BE_bug_array_align = bugs[bug_array_align]; 155 BE_bug_array_align2 = bugs[bug_array_align2]; 156 BE_bug_boolean_def = bugs[bug_boolean_def]; 157 158 /* 159 * initialize global type instances 160 */ 161 BE_ulong_int_p = BE_get_type_node (AST_long_unsigned_k); 162 BE_ulong_int_p->alignment_size = 4; 163 BE_ulong_int_p->ndr_size = 4; 164 165 BE_ushort_int_p = BE_get_type_node (AST_short_unsigned_k); 166 BE_ushort_int_p->alignment_size = 2; 167 BE_ushort_int_p->ndr_size = 2; 168 169 BE_pointer_p = BE_get_type_node (AST_pointer_k); 170 BE_pointer_p->alignment_size = 4; 171 BE_pointer_p->ndr_size = 4; 172 173 BE_function_p = BE_get_type_node (AST_function_k); 174 BE_function_p->alignment_size = 0; 175 BE_function_p->ndr_size = 0; 176 177 BE_short_null_p = BE_get_type_node (AST_null_k); 178 BE_short_null_p->alignment_size = 2; 179 BE_short_null_p->ndr_size = 0; 180 181 BE_long_null_p = BE_get_type_node (AST_null_k); 182 BE_long_null_p->alignment_size = 4; 183 BE_long_null_p->ndr_size = 0; 184 185 BE_hyper_null_p = BE_get_type_node (AST_null_k); 186 BE_hyper_null_p->alignment_size = 8; 187 BE_hyper_null_p->ndr_size = 0; 188 189} 190 191/******************************************************************************/ 192/* BE Temporary-Memory Management */ 193/******************************************************************************/ 194/* ABSTRACT: */ 195/* Special BE memory management routines. The following three routines */ 196/* provides memory management in contexts (heap zones). When entering a */ 197/* context the BE_push_malloc_ctx routine is called, upon entering a */ 198/* context all calls to BE_ctx_malloc to allocate memory will be associated */ 199/* with the context. When the context is exited by calling */ 200/* BE_pop_malloc_ctx, all memory allocated with BE_ctx_malloc, is freed. */ 201/* */ 202/* NOTE: */ 203/* Memory allocated via BE_ctx_malloc, cannot be freed other than by */ 204/* exiting the current malloc context as it adds a header to the memory */ 205/* in order to keep a list of active allocations. Calls to free() with */ 206/* allocations returned from BE_ctx_malloc, will cause heap corruption. */ 207/* */ 208/* ROUTINES: */ 209/* BE_cxt_malloc -- Same interface as MALLOC, if not within a context */ 210/* returns memory directly from malloc() */ 211/* BE_push_malloc_ctx -- Start new temporary context */ 212/* is used directly and the memory never freed */ 213/* BE_push_perm_malloc_ctx -- Start new temporary context in which MALLOC */ 214/* BE_pop_malloc_ctx -- Free all memory allocated since start of context */ 215/* */ 216/******************************************************************************/ 217 218/* 219 * Type used to add our context header to allocations returned from MALLOC 220 */ 221typedef struct malloc_t { 222 struct malloc_t *next; /* Pointer to next allocation on this chain */ 223 void *data; /* Start of memory returned to caller */ 224 } malloc_t; 225 226/* 227 * Type used to maintain a list of allocation contexts. 228 */ 229typedef struct malloc_ctx_t { 230 struct malloc_ctx_t *next; /* Pointer to next context */ 231 malloc_t *list; /* Head of allocation chain for this context. */ 232 boolean permanent; /* If true, this is a permanent context */ 233 } malloc_ctx_t; 234 235/* 236 * Current malloc context, initially NULL so normal MALLOC is used 237 */ 238static malloc_ctx_t *malloc_ctx = NULL; 239 240/* 241** BE_ctx_malloc: allocate memory in the current context. 242*/ 243heap_mem *BE_ctx_malloc 244( 245 size_t size 246) 247{ 248 malloc_t *new; 249 250 /* If no malloc context, just return memory */ 251 if (malloc_ctx == NULL) 252 return MALLOC (size); 253 254 /* If current malloc context is permanent, then just return memory */ 255 if (malloc_ctx->permanent == true) 256 return MALLOC (size); 257 258 /* Allocate memory with our context header */ 259 new = MALLOC (size + sizeof(malloc_t)); 260 261 /* Link the new allocation on the current context list */ 262 new->next = malloc_ctx->list; 263 malloc_ctx->list = new; 264 265#ifdef DUMPERS 266 /* If BE_zero_mem set, initialize allocated memory to help find bugs */ 267 if (BE_zero_mem) 268 memset(&new->data, 0xFF, size); 269#endif 270 271 /* Return the value after our header for use by the caller */ 272 return &new->data; 273} 274 275/* 276** BE_push_malloc_ctx: Push a new context in which memory is allocated 277*/ 278void BE_push_malloc_ctx 279( 280 void 281) 282{ 283 /* 284 * Allocate a malloc context block to hang allocations made in this 285 * context off of. 286 */ 287 malloc_ctx_t *new = NEW (malloc_ctx_t); 288 289 /* Link new context on the top of the context stack */ 290 new->next = malloc_ctx; 291 new->list = NULL; 292 new->permanent = false; 293 malloc_ctx = new; 294} 295 296/* 297** BE_pop_malloc_ctx: Pop the current context, freeing all memory allocated 298** within this context (unless it was a permanent context). 299*/ 300void BE_pop_malloc_ctx 301( 302 void 303) 304{ 305 malloc_t *list,*curr; 306 malloc_ctx_t *ctx; 307 308 /* If we are called with an empty stack, then abort */ 309 if (malloc_ctx == NULL) 310 error(NIDL_INTERNAL_ERROR,__FILE__,__LINE__); 311 312 /* Loop through the context freeing all memory */ 313 list = malloc_ctx->list; 314 while (list != NULL) 315 { 316 curr = list; 317 list = list->next; 318 free(curr); 319 } 320 321 /* Remove context from the stack, and free the context header */ 322 ctx = malloc_ctx; 323 malloc_ctx = malloc_ctx->next; 324 free(ctx); 325} 326 327/* 328 * BE_main 329 */ 330boolean BE_main /* returns true on successful completion */ 331( 332 boolean *cmd_opt, /* [in] array of cmd option flags */ 333 void **cmd_val, /* [in] array of cmd option values */ 334 FILE *h_fid, /* [in] header file handle, or NULL */ 335 FILE *caux_fid ATTRIBUTE_UNUSED, /* [in] client aux file handle, or NULL */ 336 FILE *saux_fid ATTRIBUTE_UNUSED, /* [in] server aux file handle, or NULL */ 337 FILE *cstub_fid, /* [in] cstub file handle, or NULL */ 338 FILE *sstub_fid, /* [in] sstub file handle, or NULL */ 339 AST_interface_n_t *int_p /* [in] ptr to interface node */ 340) 341{ 342 DDBE_vectors_t *dd_vip; /* Data driven BE vector information ptr */ 343 344 be_init (cmd_opt, cmd_val); 345 346 /* Generate the intermediate representation if stubs are required. */ 347 if (cstub_fid || sstub_fid) { 348 IR_gen_irep(cmd_opt, cmd_val, int_p); 349 } 350 351 /* Print accumulated errors and warnings generated by irep, if any. */ 352 if (!cmd_opt[opt_confirm]) 353 print_errors(); 354 355#if DUMPERS && 0 356 /* XXX: ??? */ 357 /* Dump the IREP if requested. */ 358 if (cmd_opt[opt_dump_flat]) 359 IR_dump_irep(int_p); 360#endif 361 362 /* Call the Data Driven Backend if stubs are required. */ 363 if (cstub_fid || sstub_fid) 364 DDBE_main(cmd_opt, cmd_val, int_p, &dd_vip); 365 366 if (h_fid) 367 { 368 BE_gen_c_header(h_fid, int_p, 369 (boolean *)cmd_val[opt_do_bug], cmd_opt); 370 } 371 372 /* 373 * emit client stub file if requested 374 */ 375 if (cstub_fid && error_count == 0) 376 DDBE_gen_cstub(cstub_fid, int_p, lang_c_k, 377 (char *)cmd_val[opt_header], cmd_opt, cmd_val, dd_vip); 378 379 /* 380 * emit server stub file if requested 381 */ 382 if (sstub_fid && error_count == 0) 383 BE_gen_sstub (sstub_fid, int_p, lang_c_k, (char *)cmd_val[opt_header], 384 cmd_opt, cmd_val, dd_vip); 385 386 return (error_count == 0); 387} 388 389/* 390 * Output #includes needed at the start of MTS stubs 391 */ 392void CSPELL_mts_includes 393( 394 FILE *fid, 395 char header_name[] 396) 397{ 398 399 fprintf (fid, USER_INCLUDE_TEMPLATE, header_name); 400 401 fprintf (fid, INCLUDE_TEMPLATE, "idlddefs.h"); 402} 403 404/* 405 * BE_get_name 406 * 407 * Returns a character string given a NAMETABLE_id_t 408 */ 409char const *BE_get_name 410( 411 NAMETABLE_id_t id 412) 413{ 414 char const *retval; 415 416 NAMETABLE_id_to_string(id, &retval); 417 return retval; 418} 419 420/* 421 * BE_get_type_node 422 * 423 * Allocates and returns a type node 424 */ 425AST_type_n_t *BE_get_type_node 426( 427 AST_type_k_t kind 428) 429{ 430 AST_type_n_t *new_type = (AST_type_n_t *)BE_ctx_malloc(sizeof(AST_type_n_t)); 431 432 new_type->fe_info = NULL; 433 new_type->be_info.other = NULL; 434 new_type->name = NAMETABLE_NIL_ID; 435 new_type->defined_as = NULL; 436 new_type->kind = kind; 437 new_type->flags = 0; 438 new_type->xmit_as_type = NULL; 439 new_type->rep_as_type = NULL; 440 new_type->cs_char_type = NULL; 441 442 return new_type; 443} 444 445/******************************************************************************/ 446/* */ 447/* Dummy - Control of generation of pipe routine declarations */ 448/* */ 449/******************************************************************************/ 450void BE_gen_pipe_routine_decls 451( 452 FILE *fid ATTRIBUTE_UNUSED, 453 AST_interface_n_t *p_interface ATTRIBUTE_UNUSED 454) 455{ 456} 457