2 * Copyright (c) 1999-2018 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@
24 #include "libinfo_common.h"
29 #include <mach/mach.h>
30 #include <servers/bootstrap.h>
41 #define ILS_MAGIC_SIZE 8
42 #define ILS_MAGIC "ILSMAGIC"
46 #if __ARM_ARCH_7K__ || __ARM64_ARCH_8_32__
47 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
49 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
52 static const uint32_t align_64
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
55 padsize(size_t curr
, size_t item
, const uint32_t *align
)
59 if (item
> 8) item
= 8;
62 if (na
== 0) return 0;
65 if (diff
== 0) return 0;
71 * Create a structure using in-line memory (i.e. all one blob).
72 * This reduces malloc/free workload.
74 * Structure components may be strings, 1, 2, 4, or 8-byte values,
75 * lists of strings, or lists of 4, 8, or 16-byte values.
78 * s NUL terminated string
83 * S 128 byte value (_SS_MAXSIZE for a sockaddr)
84 * L long (32 or 64 bits, depending on architecture)
86 * * NULL-terminated list of strings
87 * a NULL-terminated list of 4-byte values
88 * b NULL-terminated list of 8-byte values
89 * c NULL-terminated list of 16-byte values
90 * @ length (4 bytes) and buffer (requires two parameters)
95 LI_ils_create(char *fmt
, ...)
100 void *hp
, *dp
, *lp
, *ils
;
103 uint32_t u32
, i
, pad
;
108 size_t memsize
, hsize
, csize
, csizep1
, csizep2
, slen
, largest
;
109 const uint32_t *align
;
111 if (fmt
== NULL
) return NULL
;
115 if (sizeof(char *) == 8) align
= align_64
;
117 /* first pass: calculate size */
118 memsize
= ILS_MAGIC_SIZE
;
123 for (f
= fmt
; (*f
) != '\0'; f
++)
132 if (largest
< sizeof(char *)) largest
= sizeof(char *);
134 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
135 arg
= va_arg(ap
, char *);
136 if (arg
!= NULL
) slen
= strlen(arg
) + 1;
143 if (largest
< 1) largest
= 1;
146 u8
= va_arg(ap
, int);
153 if (largest
< 2) largest
= 2;
155 csize
= 2 + padsize(hsize
, 2, align
);
156 u16
= va_arg(ap
, int);
163 if (largest
< 4) largest
= 4;
165 csize
= 4 + padsize(hsize
, 4, align
);
166 u32
= va_arg(ap
, uint32_t);
173 if (largest
< 8) largest
= 8;
175 csize
= 8 + padsize(hsize
, 8, align
);
176 u64
= va_arg(ap
, uint64_t);
183 if (largest
< 128) largest
= 128;
185 /* 4-byte-align since a socket_data_t is really just a buffer */
186 csize
= 128 + padsize(hsize
, 4, align
);
187 sdata
= va_arg(ap
, socket_data_t
);
194 if (largest
< sizeof(unsigned long)) largest
= sizeof(unsigned long);
196 csize
= sizeof(unsigned long) + padsize(hsize
, sizeof(unsigned long), align
);
197 l
= va_arg(ap
, unsigned long);
204 if (largest
< sizeof(mach_port_t
)) largest
= sizeof(mach_port_t
);
206 csize
= sizeof(mach_port_t
) + padsize(hsize
, sizeof(mach_port_t
), align
);
207 m
= va_arg(ap
, mach_port_t
);
214 // NULL-terminated list of strings
215 if (largest
< sizeof(char *)) largest
= sizeof(char *);
217 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
218 list
= va_arg(ap
, char **);
221 for (i
= 0; list
[i
] != NULL
; i
++)
223 slen
+= sizeof(char *);
224 slen
+= (strlen(list
[i
]) + 1);
228 // reserve space for the terminator
229 slen
+= sizeof(char *);
236 /* NULL-terminated list of 4-byte values */
237 if (largest
< sizeof(char *)) largest
= sizeof(char *);
239 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
240 list
= va_arg(ap
, char **);
243 for (i
= 0; list
[i
] != NULL
; i
++)
245 slen
+= sizeof(char *);
249 slen
+= sizeof(char *);
257 /* NULL-terminated list of 8-byte values */
258 if (largest
< sizeof(char *)) largest
= sizeof(char *);
260 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
261 list
= va_arg(ap
, char **);
264 for (i
= 0; list
[i
] != NULL
; i
++)
266 slen
+= sizeof(char *);
270 slen
+= sizeof(char *);
278 /* NULL-terminated list of 16-byte values */
279 if (largest
< sizeof(char *)) largest
= sizeof(char *);
281 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
282 list
= va_arg(ap
, char **);
285 for (i
= 0; list
[i
] != NULL
; i
++)
287 slen
+= sizeof(char *);
291 slen
+= sizeof(char *);
299 if (largest
< 4) largest
= 4;
300 csizep1
= 4 + padsize(hsize
, 4, align
);
301 slen
= va_arg(ap
, uint32_t);
303 if (largest
< sizeof(char *)) largest
= sizeof(char *);
304 csizep2
= sizeof(char *) + padsize(hsize
+ csizep1
, sizeof(char *), align
);
305 arg
= va_arg(ap
, char *);
307 csize
= csizep1
+ csizep2
;
312 default: return NULL
;
322 pad
= padsize(hsize
, largest
, align
);
326 ils
= malloc(memsize
);
333 /* insert magic cookie */
335 memcpy(dp
, ILS_MAGIC
, ILS_MAGIC_SIZE
);
336 dp
+= ILS_MAGIC_SIZE
;
341 /* second pass: copy data */
343 for (f
= fmt
; (*f
) != '\0'; f
++)
349 pad
= padsize(hsize
, sizeof(char *), align
);
357 arg
= va_arg(ap
, char *);
360 memset(hp
, 0, sizeof(char *));
364 memcpy(hp
, &dp
, sizeof(char *));
365 slen
= strlen(arg
) + 1;
366 memcpy(dp
, arg
, slen
);
370 hp
+= sizeof(char *);
371 hsize
+= sizeof(char *);
378 u8
= va_arg(ap
, int);
379 memcpy(hp
, &u8
, sizeof(uint8_t));
380 hp
+= sizeof(uint8_t);
387 pad
= padsize(hsize
, 2, align
);
395 u16
= va_arg(ap
, int);
396 memcpy(hp
, &u16
, sizeof(uint16_t));
398 hp
+= sizeof(uint16_t);
399 hsize
+= sizeof(uint16_t);
406 pad
= padsize(hsize
, 4, align
);
414 u32
= va_arg(ap
, uint32_t);
415 memcpy(hp
, &u32
, sizeof(uint32_t));
417 hp
+= sizeof(uint32_t);
418 hsize
+= sizeof(uint32_t);
425 pad
= padsize(hsize
, 8, align
);
433 u64
= va_arg(ap
, uint64_t);
434 memcpy(hp
, &u64
, sizeof(uint64_t));
436 hp
+= sizeof(uint64_t);
437 hsize
+= sizeof(uint64_t);
444 pad
= padsize(hsize
, 4, align
);
452 sdata
= va_arg(ap
, socket_data_t
);
453 memcpy(hp
, (char *)(sdata
.x
), sizeof(socket_data_t
));
455 hp
+= sizeof(socket_data_t
);
456 hsize
+= sizeof(socket_data_t
);
463 pad
= padsize(hsize
, sizeof(unsigned long), align
);
471 l
= va_arg(ap
, unsigned long);
472 memcpy(hp
, &l
, sizeof(unsigned long));
474 hp
+= sizeof(unsigned long);
475 hsize
+= sizeof(unsigned long);
482 pad
= padsize(hsize
, sizeof(mach_port_t
), align
);
490 m
= va_arg(ap
, mach_port_t
);
491 memcpy(hp
, &m
, sizeof(mach_port_t
));
493 hp
+= sizeof(mach_port_t
);
494 hsize
+= sizeof(mach_port_t
);
501 pad
= padsize(hsize
, sizeof(char *), align
);
509 list
= va_arg(ap
, char **);
511 memcpy(hp
, &dp
, sizeof(char *));
513 for (i
= 0; list
&& list
[i
] != NULL
; i
++);
516 dp
+= ((i
+ 1) * sizeof(char *));
518 for (i
= 0; list
&& list
[i
] != NULL
; i
++)
520 memcpy(lp
, &dp
, sizeof(char *));
521 lp
+= sizeof(char *);
522 slen
= strlen(list
[i
]) + 1;
523 memcpy(dp
, list
[i
], slen
);
527 memset(lp
, 0, sizeof(char *));
529 hp
+= sizeof(char *);
530 hsize
+= sizeof(char *);
537 pad
= padsize(hsize
, sizeof(char *), align
);
545 list
= va_arg(ap
, char **);
549 memset(hp
, 0, sizeof(char *));
553 memcpy(hp
, &dp
, sizeof(char *));
555 for (i
= 0; list
[i
] != NULL
; i
++);
558 dp
+= ((i
+ 1) * sizeof(char *));
560 for (i
= 0; list
[i
] != NULL
; i
++)
562 memcpy(lp
, &dp
, sizeof(char *));
563 lp
+= sizeof(char *);
565 memcpy(dp
, list
[i
], slen
);
569 memset(lp
, 0, sizeof(char *));
572 hp
+= sizeof(char *);
573 hsize
+= sizeof(char *);
580 pad
= padsize(hsize
, sizeof(char *), align
);
588 list
= va_arg(ap
, char **);
592 memset(hp
, 0, sizeof(char *));
596 memcpy(hp
, &dp
, sizeof(char *));
598 for (i
= 0; list
[i
] != NULL
; i
++);
601 dp
+= ((i
+ 1) * sizeof(char *));
603 for (i
= 0; list
[i
] != NULL
; i
++)
605 memcpy(lp
, &dp
, sizeof(char *));
606 lp
+= sizeof(char *);
608 memcpy(dp
, list
[i
], slen
);
612 memset(lp
, 0, sizeof(char *));
615 hp
+= sizeof(char *);
616 hsize
+= sizeof(char *);
623 pad
= padsize(hsize
, sizeof(char *), align
);
631 list
= va_arg(ap
, char **);
635 memset(hp
, 0, sizeof(char *));
639 memcpy(hp
, &dp
, sizeof(char *));
641 for (i
= 0; list
[i
] != NULL
; i
++);
644 dp
+= ((i
+ 1) * sizeof(char *));
646 for (i
= 0; list
[i
] != NULL
; i
++)
648 memcpy(lp
, &dp
, sizeof(char *));
649 lp
+= sizeof(char *);
651 memcpy(dp
, list
[i
], slen
);
655 memset(lp
, 0, sizeof(char *));
658 hp
+= sizeof(char *);
659 hsize
+= sizeof(char *);
666 pad
= padsize(hsize
, 4, align
);
674 slen
= va_arg(ap
, uint32_t);
675 memcpy(hp
, &slen
, sizeof(uint32_t));
677 hp
+= sizeof(uint32_t);
678 hsize
+= sizeof(uint32_t);
680 pad
= padsize(hsize
, sizeof(char *), align
);
688 arg
= va_arg(ap
, char *);
691 memset(hp
, 0, sizeof(char *));
695 memcpy(hp
, &dp
, sizeof(char *));
696 memcpy(dp
, arg
, slen
);
700 hp
+= sizeof(char *);
701 hsize
+= sizeof(char *);
708 pad
= padsize(hsize
, largest
, align
);
709 if (pad
> 0) memset(hp
, 0, pad
);