]>
git.saurik.com Git - apple/libc.git/blob - mach.subproj/mach_subsystem_join.c
5 #include <string.h> /* To get NULL */
6 #include <mach/boolean.h>
7 #include <mach/kern_return.h>
12 # define debug(x) printf x
18 * Routine: mach_subsystem_join
20 * Create a new subsystem, suitable for registering with
21 * mach_subsystem_create, that consists of the union of
22 * the routines of subsys_1 and subsys_2.
25 * If there is a big gap between the routine numbers of
26 * the two subsystems, a correspondingly large amount of
27 * space will be wasted in the new subsystem.
30 mach_subsystem_join(rpc_subsystem_t subsys_1
, /* First input subsystem */
31 rpc_subsystem_t subsys_2
, /* Second input subsystem */
32 unsigned int *num_bytes_p
, /* Size of output subsystem */
33 void *(*malloc_func
)(int) /* Allocation routine to use */
36 rpc_subsystem_t sp
, subsys_new
;
37 int num_routines
, num_args
, num_bytes
;
39 struct routine_arg_descriptor
*ap
;
40 struct routine_descriptor
*rp
;
42 /* Make sure the two routine number ranges do not overlap:
44 if (subsys_1
->start
<= subsys_2
->start
&& subsys_1
->end
> subsys_2
->start
46 subsys_2
->start
<= subsys_1
->start
&& subsys_2
->end
> subsys_1
->start
)
49 /* Arrange that subsys_1 is the subsystem with the lower numbered
52 if (subsys_2
->start
< subsys_1
->start
||
53 subsys_2
->end
< subsys_1
->end
) {
54 /* Exchange the two input subsystem pointers: */
55 sp
= subsys_2
; subsys_2
= subsys_1
; subsys_1
= sp
;
58 debug(("subys_join: Lower subsys: (%d, %d); Higher subsys: (%d, %d)\n",
59 subsys_1
->start
, subsys_1
->end
, subsys_2
->start
, subsys_2
->end
));
62 * Calculate size needed for new subsystem and allocate it:
69 nr
= sp
->end
- sp
->start
;
72 for (rp
= &sp
->routine
[0]; rp
< &sp
->routine
[nr
]; rp
++) {
73 /* Make sure this routine is non-null: */
74 if (rp
->impl_routine
!= NULL
)
75 num_args
+= rp
->descr_count
;
81 num_routines
= subsys_2
->end
- subsys_1
->start
;
83 /* A struct rpc_subsystem, which is just a template for a real
84 * subsystem descriptor, has one dummy routine descriptor in it
85 * and one arg descriptor, so we have to subtract these out, when
86 * calculating room for the routine and arg arrays:
88 num_bytes
= sizeof(struct rpc_subsystem
) +
89 (num_routines
- 1) * sizeof(struct routine_descriptor
) +
90 (num_args
- 1) * sizeof(struct routine_arg_descriptor
);
92 debug(("subys_new: %x; #routines: %d; #args: %d; #bytes: %d\n",
93 subsys_new
, num_routines
, num_args
, num_bytes
));
95 subsys_new
= (rpc_subsystem_t
) (*malloc_func
)(num_bytes
);
96 if (subsys_new
== NULL
)
99 /* Initialize the new subsystem, then copy the lower-numbered
100 * subsystem into the new subsystem, then the higher-numbered one:
103 subsys_new
->subsystem
= NULL
; /* Reserved for system use */
104 subsys_new
->start
= subsys_1
->start
;
105 subsys_new
->end
= subsys_2
->end
;
106 subsys_new
->maxsize
= subsys_1
->maxsize
> subsys_2
->maxsize
?
107 subsys_1
->maxsize
: subsys_2
->maxsize
;
108 subsys_new
->base_addr
= (vm_address_t
)subsys_new
;
110 /* Point ap at the beginning of the arg_descriptors for the
111 * joined subystem, i.e. just after the end of the combined
112 * array of routine descriptors:
114 ap
= (struct routine_arg_descriptor
*)
115 &(subsys_new
->routine
[num_routines
]);
116 rp
= &(subsys_new
->routine
[0]);
118 /* Copy subsys_1 into subsys_new: */
119 debug(("subys_join: Copying lower subsys: rp=%x, ap=%x\n", rp
, ap
));
120 for (i
= 0; i
< subsys_1
->end
- subsys_1
->start
; i
++, rp
++) {
121 *rp
= subsys_1
->routine
[i
];
122 if (rp
->impl_routine
!= NULL
) {
124 for (j
= 0; j
< rp
->descr_count
; j
++)
125 *ap
++ = subsys_1
->routine
[i
].arg_descr
[j
];
127 rp
->arg_descr
= NULL
;
130 /* Fill in the gap, if any, between subsys_1 routine numbers
131 * and subsys_2 routine numbers:
133 for (i
= subsys_1
->end
; i
< subsys_2
->start
; i
++, rp
++) {
134 rp
->impl_routine
= NULL
;
135 rp
->arg_descr
= NULL
;
138 /* Copy subsys_2 into subsys_new: */
139 debug(("subys_join: Copying higher subsys: rp=%x, ap=%x\n", rp
, ap
));
140 for (i
= 0; i
< subsys_2
->end
- subsys_2
->start
; i
++, rp
++) {
141 *rp
= subsys_2
->routine
[i
];
142 if (rp
->impl_routine
!= NULL
) {
144 for (j
= 0; j
< rp
->descr_count
; j
++)
145 *ap
++ = subsys_2
->routine
[i
].arg_descr
[j
];
147 rp
->arg_descr
= NULL
;
149 debug(("subys_join: Done: rp=%x, ap=%x\n", rp
, ap
));
151 *num_bytes_p
= num_bytes
;