]>
git.saurik.com Git - apple/libinfo.git/blob - lookup.subproj/ils.c
2 * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 #include <mach/mach.h>
28 #include <servers/bootstrap.h>
39 #define ILS_MAGIC_SIZE 8
40 #define ILS_MAGIC "ILSMAGIC"
44 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
45 static const uint32_t align_64
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
48 padsize(size_t curr
, size_t item
, const uint32_t *align
)
52 if (item
> 8) item
= 8;
55 if (na
== 0) return 0;
58 if (diff
== 0) return 0;
64 * Create a structure using in-line memory (i.e. all one blob).
65 * This reduces malloc/free workload.
67 * Structure components may be strings, 1, 2, 4, or 8-byte values,
68 * lists of strings, or lists of 4, 8, or 16-byte values.
71 * s NUL terminated string
76 * S 128 byte value (_SS_MAXSIZE for a sockaddr)
77 * L long (32 or 64 bits, depending on architecture)
79 * * NULL-terminated list of strings
80 * a NULL-terminated list of 4-byte values
81 * b NULL-terminated list of 8-byte values
82 * c NULL-terminated list of 16-byte values
83 * @ length (4 bytes) and buffer (requires two parameters)
87 LI_ils_create(char *fmt
, ...)
92 void *hp
, *dp
, *lp
, *ils
;
100 size_t memsize
, hsize
, csize
, csizep1
, csizep2
, slen
, largest
;
101 const uint32_t *align
;
103 if (fmt
== NULL
) return NULL
;
107 if (sizeof(char *) == 8) align
= align_64
;
109 /* first pass: calculate size */
110 memsize
= ILS_MAGIC_SIZE
;
115 for (f
= fmt
; (*f
) != '\0'; f
++)
124 if (largest
< sizeof(char *)) largest
= sizeof(char *);
126 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
127 arg
= va_arg(ap
, char *);
128 if (arg
!= NULL
) slen
= strlen(arg
) + 1;
135 if (largest
< 1) largest
= 1;
138 u8
= va_arg(ap
, int);
145 if (largest
< 2) largest
= 2;
147 csize
= 2 + padsize(hsize
, 2, align
);
148 u16
= va_arg(ap
, int);
155 if (largest
< 4) largest
= 4;
157 csize
= 4 + padsize(hsize
, 4, align
);
158 u32
= va_arg(ap
, uint32_t);
165 if (largest
< 8) largest
= 8;
167 csize
= 8 + padsize(hsize
, 8, align
);
168 u64
= va_arg(ap
, uint64_t);
175 if (largest
< 128) largest
= 128;
177 /* 4-byte-align since a socket_data_t is really just a buffer */
178 csize
= 128 + padsize(hsize
, 4, align
);
179 sdata
= va_arg(ap
, socket_data_t
);
186 if (largest
< sizeof(unsigned long)) largest
= sizeof(unsigned long);
188 csize
= sizeof(unsigned long) + padsize(hsize
, sizeof(unsigned long), align
);
189 l
= va_arg(ap
, unsigned long);
196 if (largest
< sizeof(mach_port_t
)) largest
= sizeof(mach_port_t
);
198 csize
= sizeof(mach_port_t
) + padsize(hsize
, sizeof(mach_port_t
), align
);
199 m
= va_arg(ap
, mach_port_t
);
206 /* NULL-terminated list of strings */
207 if (largest
< sizeof(char *)) largest
= sizeof(char *);
209 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
210 list
= va_arg(ap
, char **);
213 for (i
= 0; list
[i
] != NULL
; i
++)
215 slen
+= sizeof(char *);
216 slen
+= (strlen(list
[i
]) + 1);
219 slen
+= sizeof(char *);
227 /* NULL-terminated list of 4-byte values */
228 if (largest
< sizeof(char *)) largest
= sizeof(char *);
230 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
231 list
= va_arg(ap
, char **);
234 for (i
= 0; list
[i
] != NULL
; i
++)
236 slen
+= sizeof(char *);
240 slen
+= sizeof(char *);
248 /* NULL-terminated list of 8-byte values */
249 if (largest
< sizeof(char *)) largest
= sizeof(char *);
251 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
252 list
= va_arg(ap
, char **);
255 for (i
= 0; list
[i
] != NULL
; i
++)
257 slen
+= sizeof(char *);
261 slen
+= sizeof(char *);
269 /* NULL-terminated list of 16-byte values */
270 if (largest
< sizeof(char *)) largest
= sizeof(char *);
272 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
273 list
= va_arg(ap
, char **);
276 for (i
= 0; list
[i
] != NULL
; i
++)
278 slen
+= sizeof(char *);
282 slen
+= sizeof(char *);
290 if (largest
< 4) largest
= 4;
291 csizep1
= 4 + padsize(hsize
, 4, align
);
292 slen
= va_arg(ap
, uint32_t);
294 if (largest
< sizeof(char *)) largest
= sizeof(char *);
295 csizep2
= sizeof(char *) + padsize(hsize
+ csizep1
, sizeof(char *), align
);
296 arg
= va_arg(ap
, char *);
298 csize
= csizep1
+ csizep2
;
303 default: return NULL
;
313 pad
= padsize(hsize
, largest
, align
);
317 ils
= malloc(memsize
);
324 /* insert magic cookie */
326 memcpy(dp
, ILS_MAGIC
, ILS_MAGIC_SIZE
);
327 dp
+= ILS_MAGIC_SIZE
;
332 /* second pass: copy data */
334 for (f
= fmt
; (*f
) != '\0'; f
++)
340 pad
= padsize(hsize
, sizeof(char *), align
);
348 arg
= va_arg(ap
, char *);
351 memset(hp
, 0, sizeof(char *));
355 memcpy(hp
, &dp
, sizeof(char *));
356 slen
= strlen(arg
) + 1;
357 memcpy(dp
, arg
, slen
);
361 hp
+= sizeof(char *);
362 hsize
+= sizeof(char *);
369 u8
= va_arg(ap
, int);
370 memcpy(hp
, &u8
, sizeof(uint8_t));
371 hp
+= sizeof(uint8_t);
378 pad
= padsize(hsize
, 2, align
);
386 u16
= va_arg(ap
, int);
387 memcpy(hp
, &u16
, sizeof(uint16_t));
389 hp
+= sizeof(uint16_t);
390 hsize
+= sizeof(uint16_t);
397 pad
= padsize(hsize
, 4, align
);
405 u32
= va_arg(ap
, uint32_t);
406 memcpy(hp
, &u32
, sizeof(uint32_t));
408 hp
+= sizeof(uint32_t);
409 hsize
+= sizeof(uint32_t);
416 pad
= padsize(hsize
, 8, align
);
424 u64
= va_arg(ap
, uint64_t);
425 memcpy(hp
, &u64
, sizeof(uint64_t));
427 hp
+= sizeof(uint64_t);
428 hsize
+= sizeof(uint64_t);
435 pad
= padsize(hsize
, 4, align
);
443 sdata
= va_arg(ap
, socket_data_t
);
444 memcpy(hp
, (char *)(sdata
.x
), sizeof(socket_data_t
));
446 hp
+= sizeof(socket_data_t
);
447 hsize
+= sizeof(socket_data_t
);
454 pad
= padsize(hsize
, sizeof(unsigned long), align
);
462 l
= va_arg(ap
, unsigned long);
463 memcpy(hp
, &l
, sizeof(unsigned long));
465 hp
+= sizeof(unsigned long);
466 hsize
+= sizeof(unsigned long);
473 pad
= padsize(hsize
, sizeof(mach_port_t
), align
);
481 m
= va_arg(ap
, mach_port_t
);
482 memcpy(hp
, &m
, sizeof(mach_port_t
));
484 hp
+= sizeof(mach_port_t
);
485 hsize
+= sizeof(mach_port_t
);
492 pad
= padsize(hsize
, sizeof(char *), align
);
500 list
= va_arg(ap
, char **);
504 memset(hp
, 0, sizeof(char *));
508 memcpy(hp
, &dp
, sizeof(char *));
510 for (i
= 0; list
[i
] != NULL
; i
++);
513 dp
+= ((i
+ 1) * sizeof(char *));
515 for (i
= 0; list
[i
] != NULL
; i
++)
517 memcpy(lp
, &dp
, sizeof(char *));
518 lp
+= sizeof(char *);
519 slen
= strlen(list
[i
]) + 1;
520 memcpy(dp
, list
[i
], slen
);
524 memset(lp
, 0, sizeof(char *));
527 hp
+= sizeof(char *);
528 hsize
+= sizeof(char *);
535 pad
= padsize(hsize
, sizeof(char *), align
);
543 list
= va_arg(ap
, char **);
547 memset(hp
, 0, sizeof(char *));
551 memcpy(hp
, &dp
, sizeof(char *));
553 for (i
= 0; list
[i
] != NULL
; i
++);
556 dp
+= ((i
+ 1) * sizeof(char *));
558 for (i
= 0; list
[i
] != NULL
; i
++)
560 memcpy(lp
, &dp
, sizeof(char *));
561 lp
+= sizeof(char *);
563 memcpy(dp
, list
[i
], slen
);
567 memset(lp
, 0, sizeof(char *));
570 hp
+= sizeof(char *);
571 hsize
+= sizeof(char *);
578 pad
= padsize(hsize
, sizeof(char *), align
);
586 list
= va_arg(ap
, char **);
590 memset(hp
, 0, sizeof(char *));
594 memcpy(hp
, &dp
, sizeof(char *));
596 for (i
= 0; list
[i
] != NULL
; i
++);
599 dp
+= ((i
+ 1) * sizeof(char *));
601 for (i
= 0; list
[i
] != NULL
; i
++)
603 memcpy(lp
, &dp
, sizeof(char *));
604 lp
+= sizeof(char *);
606 memcpy(dp
, list
[i
], slen
);
610 memset(lp
, 0, sizeof(char *));
613 hp
+= sizeof(char *);
614 hsize
+= sizeof(char *);
621 pad
= padsize(hsize
, sizeof(char *), align
);
629 list
= va_arg(ap
, char **);
633 memset(hp
, 0, sizeof(char *));
637 memcpy(hp
, &dp
, sizeof(char *));
639 for (i
= 0; list
[i
] != NULL
; i
++);
642 dp
+= ((i
+ 1) * sizeof(char *));
644 for (i
= 0; list
[i
] != NULL
; i
++)
646 memcpy(lp
, &dp
, sizeof(char *));
647 lp
+= sizeof(char *);
649 memcpy(dp
, list
[i
], slen
);
653 memset(lp
, 0, sizeof(char *));
656 hp
+= sizeof(char *);
657 hsize
+= sizeof(char *);
664 pad
= padsize(hsize
, 4, align
);
672 slen
= va_arg(ap
, uint32_t);
673 memcpy(hp
, &slen
, sizeof(uint32_t));
675 hp
+= sizeof(uint32_t);
676 hsize
+= sizeof(uint32_t);
678 pad
= padsize(hsize
, sizeof(char *), align
);
686 arg
= va_arg(ap
, char *);
689 memset(hp
, 0, sizeof(char *));
693 memcpy(hp
, &dp
, sizeof(char *));
694 memcpy(dp
, arg
, slen
);
698 hp
+= sizeof(char *);
699 hsize
+= sizeof(char *);
706 pad
= padsize(hsize
, largest
, align
);
707 if (pad
> 0) memset(hp
, 0, pad
);