#include <mach/flipc_cb.h>
static void flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t,
flipc_data_buffer_t);
void flipcdbg_print_unowned_buffers(void);
void flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr);
#ifdef __GNUC__
__inline__
#endif
static void
flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t cb_ctl,
flipc_data_buffer_t buffer)
{
unsigned char *buffer_base = flipc_cb_base + cb_ctl->data_buffer.start;
int bitpos = ((((unsigned char *) buffer) - buffer_base)
/ cb_ctl->data_buffer_size);
int element = bitpos / (sizeof(unsigned long) * 8);
int subbitpos = bitpos - element * sizeof(unsigned long) * 8;
if (flipc_debug_buffer_bitvec[element] & (1 << subbitpos))
printf("Buffer 0x%x (idx: %d, cbptr: 0x%x) is multiply referenced.\n",
buffer, bitpos, FLIPC_CBPTR(buffer));
flipc_debug_buffer_bitvec[element] |= (1 << subbitpos);
}
void
flipcdbg_print_unowned_buffers(void)
{
flipc_comm_buffer_ctl_t cb_ctl =
(flipc_comm_buffer_ctl_t) flipc_cb_base;
int i;
unsigned long bitvec_length = ((cb_ctl->data_buffer.number + sizeof(unsigned long) * 8)
/ (sizeof(unsigned int) * 8));
flipc_data_buffer_t current_buffer;
flipc_endpoint_t current_endpoint;
flipc_cb_ptr current_cbptr;
int header_printed = 0;
for (i = 0; i < bitvec_length; i++)
flipc_debug_buffer_bitvec[i] = 0;
for (current_cbptr = cb_ctl->data_buffer.free;
current_cbptr != FLIPC_CBPTR_NULL;
current_cbptr = current_buffer->u.free) {
int bitpos;
int element, subbitpos;
current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
}
for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
(current_endpoint
< (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
+ cb_ctl->endpoint.number));
current_endpoint++) {
if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
flipc_cb_ptr current_ptr =
(EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
? current_endpoint->sme_process_ptr
: current_endpoint->shrd_acquire_ptr);
flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
while (current_ptr != limit_ptr) {
flipc_cb_ptr current_buffer_cbptr =
*FLIPC_BUFFERLIST_PTR(current_ptr);
flipc_data_buffer_t current_buffer =
FLIPC_DATA_BUFFER_PTR(current_buffer_cbptr);
flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
current_endpoint);
}
}
}
for (i = 0; i < bitvec_length; i++) {
int this_limit =
((i == bitvec_length - 1)
? cb_ctl->data_buffer.number % (sizeof(unsigned long)*8)
: sizeof(unsigned long)*8);
if (flipc_debug_buffer_bitvec[i] != (unsigned long) -1) {
int j;
for (j = 0; j < this_limit; j++) {
if (!(flipc_debug_buffer_bitvec[i] & (1 << j))) {
int buffer_bitpos = i * sizeof(unsigned long) * 8 + j;
flipc_cb_ptr buffer_cbptr =
(buffer_bitpos * cb_ctl->data_buffer_size
+ cb_ctl->data_buffer.start);
flipc_data_buffer_t buffer_ptr =
FLIPC_DATA_BUFFER_PTR(buffer_cbptr);
if (!header_printed) {
header_printed = 1;
printf("Unreferenced buffers (ptr,idx,cbptr):");
}
printf(" (0x%x,%d,0x%x)", buffer_ptr, buffer_bitpos,
buffer_cbptr);
}
}
}
}
if (header_printed)
printf("\n");
}
void
flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr)
{
flipc_comm_buffer_ctl_t cb_ctl =
(flipc_comm_buffer_ctl_t) flipc_cb_base;
int found_on_freelist = 0;
int found_on_endpoints = 0;
int i;
flipc_endpoint_t current_endpoint;
flipc_cb_ptr current_cbptr;
flipc_data_buffer_t current_buffer;
for (i = 0, current_cbptr = cb_ctl->data_buffer.free;
current_cbptr != FLIPC_CBPTR_NULL;
i++, current_cbptr = current_buffer->u.free) {
if (current_cbptr == buffer_cbptr) {
printf("Buffer found on freelist in position %d\n", i);
found_on_freelist = 1;
}
current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
if (i > cb_ctl->data_buffer.number) {
printf ("**Some form of corruption following freelist.**");
return;
}
}
if (found_on_freelist)
printf("(Total buffers on freelist: %d/%d)\n", i,
cb_ctl->data_buffer.number);
for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
(current_endpoint
< (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
+ cb_ctl->endpoint.number));
current_endpoint++) {
if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
flipc_cb_ptr current_ptr =
(EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
? current_endpoint->sme_process_ptr
: current_endpoint->shrd_acquire_ptr);
flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
while (current_ptr != limit_ptr) {
current_cbptr = *FLIPC_BUFFERLIST_PTR(current_ptr);
if (current_cbptr == buffer_cbptr) {
printf("Buffer found on endpoint 0x%x (idx: %d)\n",
current_endpoint,
(current_endpoint
- FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)));
found_on_endpoints = 1;
}
current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
current_endpoint);
}
}
}
}