Esempio n. 1
0
kern_return_t 
lsPorts(task_t TargetTask)
{
    kern_return_t   kr;
    mach_port_name_array_t portNames = NULL;
    mach_msg_type_number_t portNamesCount;
    mach_port_type_array_t portRightTypes = NULL;
    mach_msg_type_number_t portRightTypesCount;
    mach_port_type_t mac_port_type;

    kr = mach_port_names(TargetTask, &portNames, &portNamesCount, &portRightTypes, &portRightTypesCount);
    if (kr != KERN_SUCCESS) {
      fprintf(stderr, "Unable to obtain MACH port names. %d\n", kr);
      return kr;
  }

  for (unsigned int p = 0; p < portNamesCount; p++) {
    printf("Hex Code: ");
    printf("0x%x 0x%x\n", portNames[p], portRightTypes[p]);
    switch(portRightTypes[p])
    {
        case MACH_PORT_TYPE_NONE:
        printf("This port has send right\n");
        break;
        case MACH_PORT_TYPE_RECEIVE:
        printf("This port has receive right\n");
        break;
        case MACH_PORT_TYPE_SEND_ONCE:
        printf("This port has a send-once right\n");
        break;
        case MACH_PORT_TYPE_PORT_SET:
        printf("This port has a port set\n");
        break;
        case MACH_PORT_TYPE_DEAD_NAME:
        printf("The name is a dead name\n");
        break;
        case MACH_PORT_TYPE_DNREQUEST:
        printf("A dead-name request has been registered for the right.\n");
        break;
        case MACH_PORT_TYPE_PORT_RIGHTS:
        case MACH_PORT_TYPE_SEND_RECEIVE:
        printf("Port has both send and receive right\n");
        break;
        case MACH_PORT_TYPE_SEND_RIGHTS:
        printf("Port had send right\n");
        break;
        case MACH_PORT_TYPE_PORT_OR_DEAD:
        printf("Port has send receive rights or is dead\n");
        break;
        case MACH_PORT_TYPE_ALL_RIGHTS:
        printf("Port has all rights\n");
        break;
        default:
        printf("Unknown PORT right 0x%x\n", portRightTypes[p]);
    }
}

return kr;
}
Esempio n. 2
0
/* Return a new port name translator translating names between FROM_TASK and
   TO_TASK, in XLATOR, or an error.  */
error_t
port_name_xlator_create (mach_port_t from_task, mach_port_t to_task,
			 struct port_name_xlator **xlator)
{
  error_t err;
  struct port_name_xlator *x = malloc (sizeof (struct port_name_xlator));

  if (! x)
    return ENOMEM;

  x->from_task = from_task;
  x->to_task = to_task;
  x->to_names = 0;
  x->to_types = 0;
  x->to_names_len = 0;
  x->to_types_len = 0;

  /* Cache a list of names in TO_TASK.  */
  err = mach_port_names (to_task,
			 &x->to_names, &x->to_names_len,
			 &x->to_types, &x->to_types_len);

  if (! err)
    /* Make an array to hold ports from TO_TASK which have been translated
       into our namespace.  */
    {
      x->ports = malloc (sizeof (mach_port_t) * x->to_names_len);
      if (x->ports)
	{
	  int i;
	  for (i = 0; i < x->to_names_len; i++)
	    x->ports[i] = MACH_PORT_NULL;
	}
      else
	{
	  munmap ((caddr_t) x->to_names,
		  x->to_names_len * sizeof (mach_port_t));
	  munmap ((caddr_t) x->to_types,
		  x->to_types_len * sizeof (mach_port_type_t));
	  err = ENOMEM;
	}
    }

  if (err)
    free (x);
  else
    *xlator = x;

  return err;
}
Esempio n. 3
0
static int get_mach_ports(task_t task, task_record_t *tinfo) 
{
     kern_return_t kr;
     mach_msg_type_number_t ncnt, tcnt;
     mach_port_name_array_t names;
     mach_port_type_array_t types;
     
     kr = mach_port_names(task, &names, &ncnt, &types, &tcnt);
     if (kr != KERN_SUCCESS) 
          return 0;

     tinfo->ports = ncnt;

     kr = vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)names, ncnt * sizeof(*names));
     kr = vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)types, tcnt * sizeof(*types));
     
     return kr;
}
Esempio n. 4
0
/*
 * fileport_walk
 *
 * Description: Invoke the action function on every fileport in the task.
 *
 *		This could be more efficient if we refactored mach_port_names()
 *		so that (a) it didn't compute the type information unless asked
 *		and (b) it could be asked to -not- unwire/copyout the memory
 *		and (c) if we could ask for port names by kobject type. Not
 *		clear that it's worth all that complexity, though.
 *
 * Parameters: 	task		The target task
 *		action		The function to invoke on each fileport
 *		arg		Anonymous pointer to caller state.
 */
kern_return_t
fileport_walk(task_t task,
	int (*action)(mach_port_name_t, struct fileglob *, void *arg),
	void *arg)
{
	mach_port_name_t *names;
	mach_msg_type_number_t ncnt, tcnt;
	vm_map_copy_t map_copy_names, map_copy_types;
	vm_map_address_t map_names;
	kern_return_t kr;
	uint_t i;
	int rval;

	/*
	 * mach_port_names returns the 'name' and 'types' in copied-in
	 * form.  Discard 'types' immediately, then copyout 'names'
	 * back into the kernel before walking the array.
	 */

	kr = mach_port_names(task->itk_space,
	    (mach_port_name_t **)&map_copy_names, &ncnt,
	    (mach_port_type_t **)&map_copy_types, &tcnt);
	if (kr != KERN_SUCCESS)
		return (kr);

	vm_map_copy_discard(map_copy_types);

	kr = vm_map_copyout(ipc_kernel_map, &map_names, map_copy_names);
	if (kr != KERN_SUCCESS) {
		vm_map_copy_discard(map_copy_names);
		return (kr);
	}
	names = (mach_port_name_t *)(uintptr_t)map_names;

	for (rval = 0, i = 0; i < ncnt; i++)
		if (fileport_invoke(task, names[i], action, arg,
		    &rval) == KERN_SUCCESS && -1 == rval)
			break;		/* early termination clause */

	vm_deallocate(ipc_kernel_map,
	    (vm_address_t)names, ncnt * sizeof (*names));
	return (KERN_SUCCESS);
}
bool
inferior_namespace_mach_port_num (task_t task, thread_t examine_threads_port, thread_t *inferior_port)
{
    kern_return_t retval;
    mach_port_name_array_t names;
    mach_msg_type_number_t nameslen;
    mach_port_type_array_t types;
    mach_msg_type_number_t typeslen;

    if (inferior_port == NULL)
        return false;

    retval = mach_port_names (task, &names, &nameslen, &types, &typeslen);
    if (retval != KERN_SUCCESS)
    {
        printf ("Error - unable to get mach port names for inferior.\n");
        return false;
    }
    int i = 0;
    for (i = 0; i < nameslen; i++)
    {
        mach_port_t local_name;
        mach_msg_type_name_t local_type;
        retval = mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &local_name, &local_type);
        if (retval == KERN_SUCCESS)
        {
            mach_port_deallocate (mach_task_self(), local_name);
            if (local_name == examine_threads_port)
            {
                *inferior_port = names[i];
                vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
                vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
                return true;
            }
        }
    }
    vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
    vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
    return false;
}
Esempio n. 6
0
/* Prints info about every port common to both tasks in X, but only if the
   port in X->from_task has a type in ONLY, to STREAM.  */
error_t
print_xlated_task_ports_info (struct port_name_xlator *x,
                              mach_port_type_t only,
                              unsigned show, FILE *stream)
{
    mach_port_t *names = 0;
    mach_port_type_t *types = 0;
    mach_msg_type_number_t names_len = 0, types_len = 0, i;
    error_t err =
        mach_port_names (x->from_task, &names, &names_len, &types, &types_len);

    if (err)
        return err;

    for (i = 0; i < names_len; i++)
        if (types[i] & only)
            print_xlated_port_info (names[i], types[i], x, show, stream);

    munmap ((caddr_t) names, names_len * sizeof *names);
    munmap ((caddr_t) types, types_len * sizeof *types);

    return 0;
}
Esempio n. 7
0
static kern_return_t PrintProcessPortSpace(pid_t pid, bool verbose)
// Prints port rights owned by the specified process.
{
    kern_return_t           err;
    kern_return_t           junk;
    mach_port_t             taskSendRight;
    mach_port_name_array_t  rightNames;
    mach_msg_type_number_t  rightNamesCount;
    mach_port_type_array_t  rightTypes;
    mach_msg_type_number_t  rightTypesCount;
    unsigned int            i;

    taskSendRight = MACH_PORT_NULL;
    rightNames    = NULL;
    rightTypes    = NULL;

    // Get the task control port for the process.

    err = task_for_pid(mach_task_self(), pid, &taskSendRight);
    if (err != KERN_SUCCESS) {
        fprintf(stderr, "%s: Could not attach to process %lld (%#08x).\n", gProgramName, (long long) pid, err);
    }

    // Get a snapshot of the port name space for the task.

    if (err == KERN_SUCCESS) {
        err = mach_port_names(taskSendRight, &rightNames, &rightNamesCount, &rightTypes, &rightTypesCount);
    }
    if (err == KERN_SUCCESS) {
        if ( rightNamesCount != rightTypesCount ) {
            fprintf(stderr, "%s: Count mismatch (%u/%u)\n", gProgramName, rightNamesCount, rightTypesCount);
            err = KERN_FAILURE;
        }
    }

    // Print that snapshot.

    if (err == KERN_SUCCESS) {
        fprintf(stdout, "    Name     Send  Receive SendOnce  PortSet DeadName DNR");
        if (verbose) {
            fprintf(stdout, " flg    seqno  mscount   qlimit msgcount sorights     pset");
        }
        fprintf(stdout, "\n");
        fprintf(stdout, "    ----     ----  ------- --------  ------- -------- ---");
        if (verbose) {
            fprintf(stdout, " ---    -----  -------   ------ -------- --------     ----");
        }
        fprintf(stdout, "\n");

        // For each name, print a reference count of each type of right.  If running
        // verbose, print other information as well.

        for (i = 0; i < rightNamesCount; i++) {
            mach_port_right_t   right;

            // We print the right name in hex because it makes it easier to
            // see the index and generation fields.  See <mach/port.h> for
            // information about this.

            fprintf(stdout, "%#8x ", rightNames[i]);

            for (right = MACH_PORT_RIGHT_SEND; right <= MACH_PORT_RIGHT_DEAD_NAME; right++) {
                mach_port_urefs_t   refCount;

                // If the rightTypes for this name has the bit associated
                // with this type of right set (that is, if the name
                // references this type of right), get the name's reference
                // for this right and print it.  Otherwise just print an
                // empty string to keep the columns lined up.

                if (rightTypes[i] & MACH_PORT_TYPE(right)) {

                    err = mach_port_get_refs(taskSendRight, rightNames[i], right, &refCount);
                    if (err == KERN_SUCCESS) {
                        fprintf(stdout, "%8d ", refCount);
                    } else {
                        fprintf(stdout, "%8s ", "???");
                    }
                } else {
                    fprintf(stdout, "%8s ", "");
                }
            }
            if ( rightTypes[i] & MACH_PORT_TYPE_DNREQUEST ) {
                fprintf(stdout, "yes ");
            } else {
                fprintf(stdout, "    ");
            }

            if (verbose) {
                if (rightTypes[i] & MACH_PORT_TYPE_PORT_SET) {
                    PrintPortSetMembers(taskSendRight, rightNames[i]);
                } else if (rightTypes[i] & MACH_PORT_TYPE_RECEIVE) {
                    PrintPortReceiveStatus(taskSendRight, rightNames[i]);
                }
            }
            fprintf(stdout, "\n");
        }
    }

    // Clean up.

    if (rightNames != NULL) {
        junk = vm_deallocate(mach_task_self(), (vm_address_t) rightNames, rightNamesCount * sizeof(*rightNames));
        assert(junk == KERN_SUCCESS);
    }
    if (rightTypes != NULL) {
        junk = vm_deallocate(mach_task_self(), (vm_address_t) rightTypes, rightTypesCount * sizeof(*rightTypes));
        assert(junk == KERN_SUCCESS);
    }
    if (taskSendRight != MACH_PORT_NULL) {
        junk = mach_port_deallocate(mach_task_self(), taskSendRight);
        assert(junk == KERN_SUCCESS);
    }

    return err;
}
Esempio n. 8
0
static void
info_mach_ports_command (char *args, int from_tty)
{
  port_name_array_t names;
  port_type_array_t types;
  unsigned int name_count, type_count;
  kern_return_t result;
  int index;
  task_t task;

  task = get_task_from_args (args);
  if (task == TASK_NULL)
    return;

  result = mach_port_names (task, &names, &name_count, &types, &type_count);
  MACH_CHECK_ERROR (result);

  gdb_assert (name_count == type_count);

  printf_unfiltered (_("Ports for task 0x%x:\n"), task);
  printf_unfiltered (_("port   type\n"));
  for (index = 0; index < name_count; ++index)
    {
      mach_port_t port = names[index];
      unsigned int j;
      struct type_descr
      {
	mach_port_type_t type;
	const char *name;
	mach_port_right_t right;
      };
      static struct type_descr descrs[] =
	{
	  {MACH_PORT_TYPE_SEND, "send", MACH_PORT_RIGHT_SEND},
	  {MACH_PORT_TYPE_SEND_ONCE, "send-once", MACH_PORT_RIGHT_SEND_ONCE},
	  {MACH_PORT_TYPE_RECEIVE, "receive", MACH_PORT_RIGHT_RECEIVE},
	  {MACH_PORT_TYPE_PORT_SET, "port-set", MACH_PORT_RIGHT_PORT_SET},
	  {MACH_PORT_TYPE_DEAD_NAME, "dead", MACH_PORT_RIGHT_DEAD_NAME}
	};

      printf_unfiltered (_("%04x: %08x "), port, types[index]);
      for (j = 0; j < sizeof(descrs) / sizeof(*descrs); j++)
	if (types[index] & descrs[j].type)
	  {
	    mach_port_urefs_t ref;
	    kern_return_t ret;

	    printf_unfiltered (_(" %s("), descrs[j].name);
	    ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
	    if (ret != KERN_SUCCESS)
	      printf_unfiltered (_("??"));
	    else
	      printf_unfiltered (_("%u"), ref);
	    printf_unfiltered (_(" refs)"));
	  }
      
      if (task == task_self ())
	{
	  if (port == task_self())
	    printf_unfiltered (_(" gdb-task"));
	  else if (port == darwin_host_self)
	    printf_unfiltered (_(" host-self"));
	  else if (port == darwin_ex_port)
	    printf_unfiltered (_(" gdb-exception"));
	  else if (port == darwin_port_set)
	    printf_unfiltered (_(" gdb-port_set"));
	  else if (!ptid_equal (inferior_ptid, null_ptid))
	    {
	      struct inferior *inf = current_inferior ();

	      if (port == inf->priv->task)
		printf_unfiltered (_(" inferior-task"));
	      else if (port == inf->priv->notify_port)
		printf_unfiltered (_(" inferior-notify"));
	      else
		{
		  int k;
		  darwin_thread_t *t;

		  for (k = 0; k < inf->priv->exception_info.count; k++)
		    if (port == inf->priv->exception_info.ports[k])
		      {
			printf_unfiltered (_(" inferior-excp-port"));
			break;
		      }

		  if (inf->priv->threads)
		    {
		      for (k = 0;
			   VEC_iterate(darwin_thread_t,
				       inf->priv->threads, k, t);
			   k++)
			if (port == t->gdb_port)
			  {
			    printf_unfiltered (_(" inferior-thread for 0x%x"),
					       inf->priv->task);
			    break;
			  }
		    }
		}
	    }
	}
      printf_unfiltered (_("\n"));
    }

  vm_deallocate (task_self (), (vm_address_t) names,
                 (name_count * sizeof (mach_port_t)));
  vm_deallocate (task_self (), (vm_address_t) types,
                 (type_count * sizeof (mach_port_type_t)));
}