]>
git.saurik.com Git - apple/libinfo.git/blob - lookup.subproj/ils.c
2 * Copyright (c) 1999-2010 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);
220 // reserve space for the terminator
221 slen
+= sizeof(char *);
228 /* NULL-terminated list of 4-byte values */
229 if (largest
< sizeof(char *)) largest
= sizeof(char *);
231 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
232 list
= va_arg(ap
, char **);
235 for (i
= 0; list
[i
] != NULL
; i
++)
237 slen
+= sizeof(char *);
241 slen
+= sizeof(char *);
249 /* NULL-terminated list of 8-byte values */
250 if (largest
< sizeof(char *)) largest
= sizeof(char *);
252 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
253 list
= va_arg(ap
, char **);
256 for (i
= 0; list
[i
] != NULL
; i
++)
258 slen
+= sizeof(char *);
262 slen
+= sizeof(char *);
270 /* NULL-terminated list of 16-byte values */
271 if (largest
< sizeof(char *)) largest
= sizeof(char *);
273 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
274 list
= va_arg(ap
, char **);
277 for (i
= 0; list
[i
] != NULL
; i
++)
279 slen
+= sizeof(char *);
283 slen
+= sizeof(char *);
291 if (largest
< 4) largest
= 4;
292 csizep1
= 4 + padsize(hsize
, 4, align
);
293 slen
= va_arg(ap
, uint32_t);
295 if (largest
< sizeof(char *)) largest
= sizeof(char *);
296 csizep2
= sizeof(char *) + padsize(hsize
+ csizep1
, sizeof(char *), align
);
297 arg
= va_arg(ap
, char *);
299 csize
= csizep1
+ csizep2
;
304 default: return NULL
;
314 pad
= padsize(hsize
, largest
, align
);
318 ils
= malloc(memsize
);
325 /* insert magic cookie */
327 memcpy(dp
, ILS_MAGIC
, ILS_MAGIC_SIZE
);
328 dp
+= ILS_MAGIC_SIZE
;
333 /* second pass: copy data */
335 for (f
= fmt
; (*f
) != '\0'; f
++)
341 pad
= padsize(hsize
, sizeof(char *), align
);
349 arg
= va_arg(ap
, char *);
352 memset(hp
, 0, sizeof(char *));
356 memcpy(hp
, &dp
, sizeof(char *));
357 slen
= strlen(arg
) + 1;
358 memcpy(dp
, arg
, slen
);
362 hp
+= sizeof(char *);
363 hsize
+= sizeof(char *);
370 u8
= va_arg(ap
, int);
371 memcpy(hp
, &u8
, sizeof(uint8_t));
372 hp
+= sizeof(uint8_t);
379 pad
= padsize(hsize
, 2, align
);
387 u16
= va_arg(ap
, int);
388 memcpy(hp
, &u16
, sizeof(uint16_t));
390 hp
+= sizeof(uint16_t);
391 hsize
+= sizeof(uint16_t);
398 pad
= padsize(hsize
, 4, align
);
406 u32
= va_arg(ap
, uint32_t);
407 memcpy(hp
, &u32
, sizeof(uint32_t));
409 hp
+= sizeof(uint32_t);
410 hsize
+= sizeof(uint32_t);
417 pad
= padsize(hsize
, 8, align
);
425 u64
= va_arg(ap
, uint64_t);
426 memcpy(hp
, &u64
, sizeof(uint64_t));
428 hp
+= sizeof(uint64_t);
429 hsize
+= sizeof(uint64_t);
436 pad
= padsize(hsize
, 4, align
);
444 sdata
= va_arg(ap
, socket_data_t
);
445 memcpy(hp
, (char *)(sdata
.x
), sizeof(socket_data_t
));
447 hp
+= sizeof(socket_data_t
);
448 hsize
+= sizeof(socket_data_t
);
455 pad
= padsize(hsize
, sizeof(unsigned long), align
);
463 l
= va_arg(ap
, unsigned long);
464 memcpy(hp
, &l
, sizeof(unsigned long));
466 hp
+= sizeof(unsigned long);
467 hsize
+= sizeof(unsigned long);
474 pad
= padsize(hsize
, sizeof(mach_port_t
), align
);
482 m
= va_arg(ap
, mach_port_t
);
483 memcpy(hp
, &m
, sizeof(mach_port_t
));
485 hp
+= sizeof(mach_port_t
);
486 hsize
+= sizeof(mach_port_t
);
493 pad
= padsize(hsize
, sizeof(char *), align
);
501 list
= va_arg(ap
, char **);
503 memcpy(hp
, &dp
, sizeof(char *));
505 for (i
= 0; list
&& list
[i
] != NULL
; i
++);
508 dp
+= ((i
+ 1) * sizeof(char *));
510 for (i
= 0; list
&& list
[i
] != NULL
; i
++)
512 memcpy(lp
, &dp
, sizeof(char *));
513 lp
+= sizeof(char *);
514 slen
= strlen(list
[i
]) + 1;
515 memcpy(dp
, list
[i
], slen
);
519 memset(lp
, 0, sizeof(char *));
521 hp
+= sizeof(char *);
522 hsize
+= sizeof(char *);
529 pad
= padsize(hsize
, sizeof(char *), align
);
537 list
= va_arg(ap
, char **);
541 memset(hp
, 0, sizeof(char *));
545 memcpy(hp
, &dp
, sizeof(char *));
547 for (i
= 0; list
[i
] != NULL
; i
++);
550 dp
+= ((i
+ 1) * sizeof(char *));
552 for (i
= 0; list
[i
] != NULL
; i
++)
554 memcpy(lp
, &dp
, sizeof(char *));
555 lp
+= sizeof(char *);
557 memcpy(dp
, list
[i
], slen
);
561 memset(lp
, 0, sizeof(char *));
564 hp
+= sizeof(char *);
565 hsize
+= sizeof(char *);
572 pad
= padsize(hsize
, sizeof(char *), align
);
580 list
= va_arg(ap
, char **);
584 memset(hp
, 0, sizeof(char *));
588 memcpy(hp
, &dp
, sizeof(char *));
590 for (i
= 0; list
[i
] != NULL
; i
++);
593 dp
+= ((i
+ 1) * sizeof(char *));
595 for (i
= 0; list
[i
] != NULL
; i
++)
597 memcpy(lp
, &dp
, sizeof(char *));
598 lp
+= sizeof(char *);
600 memcpy(dp
, list
[i
], slen
);
604 memset(lp
, 0, sizeof(char *));
607 hp
+= sizeof(char *);
608 hsize
+= sizeof(char *);
615 pad
= padsize(hsize
, sizeof(char *), align
);
623 list
= va_arg(ap
, char **);
627 memset(hp
, 0, sizeof(char *));
631 memcpy(hp
, &dp
, sizeof(char *));
633 for (i
= 0; list
[i
] != NULL
; i
++);
636 dp
+= ((i
+ 1) * sizeof(char *));
638 for (i
= 0; list
[i
] != NULL
; i
++)
640 memcpy(lp
, &dp
, sizeof(char *));
641 lp
+= sizeof(char *);
643 memcpy(dp
, list
[i
], slen
);
647 memset(lp
, 0, sizeof(char *));
650 hp
+= sizeof(char *);
651 hsize
+= sizeof(char *);
658 pad
= padsize(hsize
, 4, align
);
666 slen
= va_arg(ap
, uint32_t);
667 memcpy(hp
, &slen
, sizeof(uint32_t));
669 hp
+= sizeof(uint32_t);
670 hsize
+= sizeof(uint32_t);
672 pad
= padsize(hsize
, sizeof(char *), align
);
680 arg
= va_arg(ap
, char *);
683 memset(hp
, 0, sizeof(char *));
687 memcpy(hp
, &dp
, sizeof(char *));
688 memcpy(dp
, arg
, slen
);
692 hp
+= sizeof(char *);
693 hsize
+= sizeof(char *);
700 pad
= padsize(hsize
, largest
, align
);
701 if (pad
> 0) memset(hp
, 0, pad
);