]>
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 #if __ARM_ARCH_7K__ && __BIGGEST_ALIGNMENT__ > 4
45 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
47 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
50 static const uint32_t align_64
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
53 padsize(size_t curr
, size_t item
, const uint32_t *align
)
57 if (item
> 8) item
= 8;
60 if (na
== 0) return 0;
63 if (diff
== 0) return 0;
69 * Create a structure using in-line memory (i.e. all one blob).
70 * This reduces malloc/free workload.
72 * Structure components may be strings, 1, 2, 4, or 8-byte values,
73 * lists of strings, or lists of 4, 8, or 16-byte values.
76 * s NUL terminated string
81 * S 128 byte value (_SS_MAXSIZE for a sockaddr)
82 * L long (32 or 64 bits, depending on architecture)
84 * * NULL-terminated list of strings
85 * a NULL-terminated list of 4-byte values
86 * b NULL-terminated list of 8-byte values
87 * c NULL-terminated list of 16-byte values
88 * @ length (4 bytes) and buffer (requires two parameters)
92 LI_ils_create(char *fmt
, ...)
97 void *hp
, *dp
, *lp
, *ils
;
100 uint32_t u32
, i
, pad
;
105 size_t memsize
, hsize
, csize
, csizep1
, csizep2
, slen
, largest
;
106 const uint32_t *align
;
108 if (fmt
== NULL
) return NULL
;
112 if (sizeof(char *) == 8) align
= align_64
;
114 /* first pass: calculate size */
115 memsize
= ILS_MAGIC_SIZE
;
120 for (f
= fmt
; (*f
) != '\0'; f
++)
129 if (largest
< sizeof(char *)) largest
= sizeof(char *);
131 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
132 arg
= va_arg(ap
, char *);
133 if (arg
!= NULL
) slen
= strlen(arg
) + 1;
140 if (largest
< 1) largest
= 1;
143 u8
= va_arg(ap
, int);
150 if (largest
< 2) largest
= 2;
152 csize
= 2 + padsize(hsize
, 2, align
);
153 u16
= va_arg(ap
, int);
160 if (largest
< 4) largest
= 4;
162 csize
= 4 + padsize(hsize
, 4, align
);
163 u32
= va_arg(ap
, uint32_t);
170 if (largest
< 8) largest
= 8;
172 csize
= 8 + padsize(hsize
, 8, align
);
173 u64
= va_arg(ap
, uint64_t);
180 if (largest
< 128) largest
= 128;
182 /* 4-byte-align since a socket_data_t is really just a buffer */
183 csize
= 128 + padsize(hsize
, 4, align
);
184 sdata
= va_arg(ap
, socket_data_t
);
191 if (largest
< sizeof(unsigned long)) largest
= sizeof(unsigned long);
193 csize
= sizeof(unsigned long) + padsize(hsize
, sizeof(unsigned long), align
);
194 l
= va_arg(ap
, unsigned long);
201 if (largest
< sizeof(mach_port_t
)) largest
= sizeof(mach_port_t
);
203 csize
= sizeof(mach_port_t
) + padsize(hsize
, sizeof(mach_port_t
), align
);
204 m
= va_arg(ap
, mach_port_t
);
211 // NULL-terminated list of strings
212 if (largest
< sizeof(char *)) largest
= sizeof(char *);
214 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
215 list
= va_arg(ap
, char **);
218 for (i
= 0; list
[i
] != NULL
; i
++)
220 slen
+= sizeof(char *);
221 slen
+= (strlen(list
[i
]) + 1);
225 // reserve space for the terminator
226 slen
+= sizeof(char *);
233 /* NULL-terminated list of 4-byte values */
234 if (largest
< sizeof(char *)) largest
= sizeof(char *);
236 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
237 list
= va_arg(ap
, char **);
240 for (i
= 0; list
[i
] != NULL
; i
++)
242 slen
+= sizeof(char *);
246 slen
+= sizeof(char *);
254 /* NULL-terminated list of 8-byte values */
255 if (largest
< sizeof(char *)) largest
= sizeof(char *);
257 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
258 list
= va_arg(ap
, char **);
261 for (i
= 0; list
[i
] != NULL
; i
++)
263 slen
+= sizeof(char *);
267 slen
+= sizeof(char *);
275 /* NULL-terminated list of 16-byte values */
276 if (largest
< sizeof(char *)) largest
= sizeof(char *);
278 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
279 list
= va_arg(ap
, char **);
282 for (i
= 0; list
[i
] != NULL
; i
++)
284 slen
+= sizeof(char *);
288 slen
+= sizeof(char *);
296 if (largest
< 4) largest
= 4;
297 csizep1
= 4 + padsize(hsize
, 4, align
);
298 slen
= va_arg(ap
, uint32_t);
300 if (largest
< sizeof(char *)) largest
= sizeof(char *);
301 csizep2
= sizeof(char *) + padsize(hsize
+ csizep1
, sizeof(char *), align
);
302 arg
= va_arg(ap
, char *);
304 csize
= csizep1
+ csizep2
;
309 default: return NULL
;
319 pad
= padsize(hsize
, largest
, align
);
323 ils
= malloc(memsize
);
330 /* insert magic cookie */
332 memcpy(dp
, ILS_MAGIC
, ILS_MAGIC_SIZE
);
333 dp
+= ILS_MAGIC_SIZE
;
338 /* second pass: copy data */
340 for (f
= fmt
; (*f
) != '\0'; f
++)
346 pad
= padsize(hsize
, sizeof(char *), align
);
354 arg
= va_arg(ap
, char *);
357 memset(hp
, 0, sizeof(char *));
361 memcpy(hp
, &dp
, sizeof(char *));
362 slen
= strlen(arg
) + 1;
363 memcpy(dp
, arg
, slen
);
367 hp
+= sizeof(char *);
368 hsize
+= sizeof(char *);
375 u8
= va_arg(ap
, int);
376 memcpy(hp
, &u8
, sizeof(uint8_t));
377 hp
+= sizeof(uint8_t);
384 pad
= padsize(hsize
, 2, align
);
392 u16
= va_arg(ap
, int);
393 memcpy(hp
, &u16
, sizeof(uint16_t));
395 hp
+= sizeof(uint16_t);
396 hsize
+= sizeof(uint16_t);
403 pad
= padsize(hsize
, 4, align
);
411 u32
= va_arg(ap
, uint32_t);
412 memcpy(hp
, &u32
, sizeof(uint32_t));
414 hp
+= sizeof(uint32_t);
415 hsize
+= sizeof(uint32_t);
422 pad
= padsize(hsize
, 8, align
);
430 u64
= va_arg(ap
, uint64_t);
431 memcpy(hp
, &u64
, sizeof(uint64_t));
433 hp
+= sizeof(uint64_t);
434 hsize
+= sizeof(uint64_t);
441 pad
= padsize(hsize
, 4, align
);
449 sdata
= va_arg(ap
, socket_data_t
);
450 memcpy(hp
, (char *)(sdata
.x
), sizeof(socket_data_t
));
452 hp
+= sizeof(socket_data_t
);
453 hsize
+= sizeof(socket_data_t
);
460 pad
= padsize(hsize
, sizeof(unsigned long), align
);
468 l
= va_arg(ap
, unsigned long);
469 memcpy(hp
, &l
, sizeof(unsigned long));
471 hp
+= sizeof(unsigned long);
472 hsize
+= sizeof(unsigned long);
479 pad
= padsize(hsize
, sizeof(mach_port_t
), align
);
487 m
= va_arg(ap
, mach_port_t
);
488 memcpy(hp
, &m
, sizeof(mach_port_t
));
490 hp
+= sizeof(mach_port_t
);
491 hsize
+= sizeof(mach_port_t
);
498 pad
= padsize(hsize
, sizeof(char *), align
);
506 list
= va_arg(ap
, char **);
508 memcpy(hp
, &dp
, sizeof(char *));
510 for (i
= 0; list
&& list
[i
] != NULL
; i
++);
513 dp
+= ((i
+ 1) * sizeof(char *));
515 for (i
= 0; list
&& 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 *));
526 hp
+= sizeof(char *);
527 hsize
+= sizeof(char *);
534 pad
= padsize(hsize
, sizeof(char *), align
);
542 list
= va_arg(ap
, char **);
546 memset(hp
, 0, sizeof(char *));
550 memcpy(hp
, &dp
, sizeof(char *));
552 for (i
= 0; list
[i
] != NULL
; i
++);
555 dp
+= ((i
+ 1) * sizeof(char *));
557 for (i
= 0; list
[i
] != NULL
; i
++)
559 memcpy(lp
, &dp
, sizeof(char *));
560 lp
+= sizeof(char *);
562 memcpy(dp
, list
[i
], slen
);
566 memset(lp
, 0, sizeof(char *));
569 hp
+= sizeof(char *);
570 hsize
+= sizeof(char *);
577 pad
= padsize(hsize
, sizeof(char *), align
);
585 list
= va_arg(ap
, char **);
589 memset(hp
, 0, sizeof(char *));
593 memcpy(hp
, &dp
, sizeof(char *));
595 for (i
= 0; list
[i
] != NULL
; i
++);
598 dp
+= ((i
+ 1) * sizeof(char *));
600 for (i
= 0; list
[i
] != NULL
; i
++)
602 memcpy(lp
, &dp
, sizeof(char *));
603 lp
+= sizeof(char *);
605 memcpy(dp
, list
[i
], slen
);
609 memset(lp
, 0, sizeof(char *));
612 hp
+= sizeof(char *);
613 hsize
+= sizeof(char *);
620 pad
= padsize(hsize
, sizeof(char *), align
);
628 list
= va_arg(ap
, char **);
632 memset(hp
, 0, sizeof(char *));
636 memcpy(hp
, &dp
, sizeof(char *));
638 for (i
= 0; list
[i
] != NULL
; i
++);
641 dp
+= ((i
+ 1) * sizeof(char *));
643 for (i
= 0; list
[i
] != NULL
; i
++)
645 memcpy(lp
, &dp
, sizeof(char *));
646 lp
+= sizeof(char *);
648 memcpy(dp
, list
[i
], slen
);
652 memset(lp
, 0, sizeof(char *));
655 hp
+= sizeof(char *);
656 hsize
+= sizeof(char *);
663 pad
= padsize(hsize
, 4, align
);
671 slen
= va_arg(ap
, uint32_t);
672 memcpy(hp
, &slen
, sizeof(uint32_t));
674 hp
+= sizeof(uint32_t);
675 hsize
+= sizeof(uint32_t);
677 pad
= padsize(hsize
, sizeof(char *), align
);
685 arg
= va_arg(ap
, char *);
688 memset(hp
, 0, sizeof(char *));
692 memcpy(hp
, &dp
, sizeof(char *));
693 memcpy(dp
, arg
, slen
);
697 hp
+= sizeof(char *);
698 hsize
+= sizeof(char *);
705 pad
= padsize(hsize
, largest
, align
);
706 if (pad
> 0) memset(hp
, 0, pad
);