Beispiel #1
0
/* DARWIN uses locking, and so must provide its own */
void
shutdown_osisleep(void)
{
    afs_event_t *tmp;
    int i;

    for (i=0;i<AFS_EVHASHSIZE;i++) {
	while ((tmp = afs_evhasht[i]) != NULL) {
	    afs_evhasht[i] = tmp->next;
	    if (tmp->refcount > 0) {
		afs_warn("nonzero refcount in shutdown_osisleep()\n");
	    } else {
#if defined(AFS_AIX_ENV)
		xmfree(tmp);
#elif defined(AFS_FBSD_ENV)
		afs_osi_Free(tmp, sizeof(*tmp));
#elif defined(AFS_SGI_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_SUN5_ENV)
		osi_FreeSmallSpace(tmp);
#elif defined(AFS_LINUX26_ENV)
		kfree(tmp);
#elif defined(AFS_LINUX20_ENV)
		osi_linux_free(tmp);
#endif
	    }
	}
    }
}
Beispiel #2
0
static void
nlm_symfile_finish (struct objfile *objfile)
{
  if (objfile->sym_private != NULL)
    {
      xmfree (objfile->md, objfile->sym_private);
    }
}
Beispiel #3
0
static void
elf_symfile_finish (struct objfile *objfile)
{
  if (objfile->sym_stab_info != NULL)
    {
      xmfree (objfile->md, objfile->sym_stab_info);
    }
}
Beispiel #4
0
static void
free_elfinfo (void *objp)
{
  struct objfile *objfile = (struct objfile *) objp;
  struct dbx_symfile_info *dbxinfo = objfile->sym_stab_info;
  struct stab_section_info *ssi, *nssi;

  ssi = dbxinfo->stab_section_info;
  while (ssi)
    {
      nssi = ssi->next;
      xmfree (objfile->md, ssi);
      ssi = nssi;
    }

  dbxinfo->stab_section_info = 0;	/* Just say No mo info about this.  */
}
Beispiel #5
0
/*
 * NAME:        jfs_rename
 *
 * FUNCTION:    rename a file or directory
 *
 * PARAMETER:   from_vp         - pointer to source vnode
 *              frompar_vp      - pointer to source parent vnode
 *              from_name       - original name
 *              to_vp           - pointer to target vnode (if it exists)
 *              topar_vp        - pointer to target parent vnode
 *              to_name         - new name
 *              crp             - pointer to caller's credentials
 *
 * RETURN:      errors from subroutines
 *
 * JFS supports sticky bit permission.
 *
 * normally, to rename an object, user needs execute and write
 * permission of the directory containing the object as well as
 * on the target directory.
 * EACCESS: if S_ISVTX (aka sticky) bit is set for a directory,
 * a file in the directory can be renamed only if
 * the user has write permission for the directory, and
 * either owns the file, owns the directory, or
 * is the superuser (or have appropriate privileges).
 * (e.g., /tmp in which any user can create a file but
 * should not be able to delete or rename files owned
 * by others) [XPG4.2]
 *
 * Basic algorithm is:
 *
 * 1) Check validity of parameters and then obtain locks on the source parent
 *    directory, destination parent directory, source, and the destination
 *    inode.  This ensures neither the source or destination will be deleted out
 *    from underneath us.  It also ensures the source or destination won't be
 *    modified before we finish.
 * 2) Link source to destination.  If destination already exists,
 *    delete it first.
 * 3) Unlink source reference to inode if still around. If a
 *    directory was moved and the parent of the destination
 *    is different from the source, patch the ".." entry in the
 *    directory.
 *
 * The transaction log needs to have the changes journalled in such a
 * way that a crash meets the requirement that the destination always
 * exists (if it existed before).  For directory objects it is critical
 * that the changes in i-numbers occur in such a way that loops and
 * orphans aren't created by a crash.
 */
int32
jfs_rename(
        struct vnode    *from_vp,       /* source vnode */
        struct vnode    *frompar_vp,    /* source parent vnode */
	UniChar		*from_name,     /* source name */
        struct vnode    *to_vp,         /* destination vnode */
        struct vnode    *topar_vp,      /* destination parent vnode */
	UniChar		*to_name,       /* destination name */
        struct dasd_usage  *from_dlim,	/* dasd usage structure for source  F226941 */
        struct dasd_usage  *to_dlim,	/* dasd usage structure for dest  F226941 */
	uint32		flags)		/* INEWNAME if new pathname not 8.3 */
{
	inode_t	*ipmnt;
        int32   tid = -1;               /* Transaction ID */
        int32   txCount = 0;            /* Count of inodes in txList */
        inode_t *txList[4];             /* List of modified inodes */
        inode_t *from_ip = VP2IP (from_vp);     /* Source inode */
        inode_t *frompar_ip = VP2IP (frompar_vp); /* Source parent inode */
        inode_t *to_ip = to_vp ? VP2IP (to_vp) : 0;
                                        /* Target inode (if it exists) */
        inode_t *topar_ip = VP2IP (topar_vp);   /* Target parent inode */
        struct vfs      *vfsf = frompar_vp->v_vfsp;
        struct vfs      *vfst = topar_vp->v_vfsp;
        int32   doingdirectory = 0,     /* Source inode is a directory */
                newparent = 0;          /* New i-number of parent */
        int32   got_from = 0, got_to = 0;
        btstack_t btstack;              /* Temporary stack for B-tree struct */
        component_t     dname;          /* Directory name structure */
        ino_t   ino;                    /* I-number for directory searches */
        int32   error = 0, rc;
	tlock_t		*tlck;		/* Transaction lock */
	dtlock_t	*dtlck;		/* dtree line lock */
	lv_t		*lv;		/* line lock vector */

// BEGIN F226941

#ifdef	_JFS_OS2
	int64		blocks_moving;	/* Number of blocks being moved */
	int64		orig_fromblocks; /* original dasd usage of from dir */
	int64		orig_toblocks;	/* original dasd usage of to dir */
	uint32		start_here;	/* index in limits array */
	int32		i;
	inode_t		*lock_arr[64];	/* Array of inodes to lock */
	inode_t		**lock_list;	/* List of inodes to lock */
	int32		num_locks;	/* Number of inodes to lock */
	int32		upper_limit;	/* Upper limit to number of inodes
					 * we need to lock */
#ifdef _JFS_FASTDASD
	int32		first_locked;	/* index in lock_list array of first
					 * inode still locked.		D233382
					 */
#endif /* _JFS_FASTDASD */
#endif	/* _JFS_OS2 */

// BEGIN F226941

        assert( to_name != NULL && from_name != NULL);

	ipmnt = frompar_ip->i_ipmnt;
	RENAME_LOCK(ipmnt);

        /*
         * Make sure that we are not renaming the "." or ".." entries in
         * a directory.
         */

        if (from_name[0] == '.' &&
                (!from_name[1] || (from_name[1] == '.' && !from_name[2])))
        {
                error = EINVAL;
                goto abortit;
        }

        /*
         * Now we want to verify the proper realationship between the inodes.
         * If everything checks out we need to obtain locks on the source parent
         * directory, destination parent directory, source, and destination
         * inodes.  This allows us to proceed knowing that noone can delete
         * either the source or destination from underneath us.  It also allows
         * us to know noone will be modifying the destination so we can delete
         * it safely.  We need the lock on the source since we might need to
         * modify its .. entry.
         */

	/*
	 * In OS/2, the destination cannot exist unless it is the same as
	 * the source.  This is to allow DosMove to change the case of a
	 * filename.
	 */
	if (to_ip && (from_ip != to_ip))
	{
		error = EINVAL;
		goto abortit;
	}

	/*
	 * Check for cross-device rename.
	 */
	if (frompar_ip->i_dev != topar_ip->i_dev)
	{
		error = EXDEV;
		goto abortit;
	}

	/*
	 * Check if source is the destination parent.  Can't do this
	 * since this would orphan everything under the source.
	 */
	if (from_ip == topar_ip)
	{
		error = EINVAL;
		goto abortit;
	}

	/*
	 * Now we know both the parents are okay.  We will lock both the
	 * parent inodes so we can guarantee the children will not be
	 * deleted underneath us.  We will also lock the source.
	 * When locking the inodes we will use the protocol of locking
	 * regular files first, then directories.  When locking more than
	 * one of each type, we do it in descending inode order.  We also need
	 * to make sure we don't attempt to lock one inode twice if the
	 * two parents are the same.
	 */
	if ((from_ip->i_mode & IFMT) == IFDIR)
		doingdirectory = 1;

// BEGIN F226941
	if (from_dlim->num_limits)
	{
		/* We need to lock all directories from the root to each of
		 * the from and to parent directories.  The DASD usage lists
		 * will contain at least one common entry (the root).  We need
		 * to compile a list of all unique inodes to lock.  The upper
		 * limit will be the sum of both num_limits fields.
		 */
		if (frompar_ip == topar_ip)
			upper_limit = from_dlim->num_limits + 1;
		else
			upper_limit = from_dlim->num_limits +
				       to_dlim->num_limits;
		if (upper_limit > 64)
			lock_list = (inode_t **)
					xmalloc(upper_limit* sizeof(inode_t *),
						0, kernel_heap);
		else
			lock_list = lock_arr;

		/* Put from parents dasd usage list into lock_list */
		for (num_locks = 0; num_locks < from_dlim->num_limits;
		     num_locks++)
			lock_list[num_locks] = from_dlim->pLimits[num_locks];

		/*
		 * We need to lock regular files before directories.  If
		 * we are moving a regular file, lock it now, otherwise add
		 * it to the lock list.
		 */
		if (doingdirectory)
			lock_list[num_locks++] = from_ip;
		else
			IWRITE_LOCK(from_ip);

		if (frompar_ip != topar_ip)
		{
			/* Add unique members of to parent's dasd usage list */
			for (i = 0; i < to_dlim->num_limits; i++)
				if (to_dlim->pLimits[i] != lock_list[i])
					break;
			start_here = i;		/* Needed by over_limit() */
			while (i < to_dlim->num_limits)
				lock_list[num_locks++] = to_dlim->pLimits[i++];
		}

		/* Lock them! */
		sort_and_lock(0, num_locks, lock_list);

		/*
		 * If this was a regular file, add the inode to the lock list
		 * now, so we include it in the txCommit, and unlock it
		 */
		if (!doingdirectory)
			lock_list[num_locks++] = from_ip;

		from_dlim->flag |= DLIM_DIRS_LOCKED;

		frompar_ip->i_dasdlim = from_dlim;
		if (frompar_ip != topar_ip)			// D230860
		{
			to_dlim->flag |= DLIM_DIRS_LOCKED;
			topar_ip->i_dasdlim = to_dlim;
		}
	}
	else
// END F226941

	{
		if (doingdirectory)
		{
			if (frompar_ip == topar_ip)
				iwritelocklist(2, frompar_ip, from_ip);
			else
				iwritelocklist(3, frompar_ip, topar_ip,
					       from_ip);
		}
		else
		{
			if (frompar_ip == topar_ip)
			{
				IWRITE_LOCK(from_ip);
				IWRITE_LOCK(frompar_ip);
			}
			else
			{
				IWRITE_LOCK(from_ip);
				iwritelocklist(2, frompar_ip, topar_ip);
			}
		}
	}
	/*
	 * Now that we have the source parent locked we can lookup the
	 * source inode to make sure it hasn't changed since we did our
	 * initial verification.  If it has we will need to release our
	 * locks and repeat our verification with the new version.
	 * Otherwise we know the source is valid and we can continue.
	 */
	dname.name = from_name;
	dname.namlen = UniStrlen (from_name);

	rc = dtSearch(frompar_ip, &dname, &ino, &btstack, JFS_LOOKUP);
	switch (rc)
	{
		case 0:
			/*
			 * An entry was found, need to see if it is the
			 * same inode as we had before.
			 */
			if (ino != from_ip->i_number)
			{
					rc = ENOENT;
					goto cleanup;
			}
			break;
		default:
			/*
			 * Either the source cannot be found or
			 * something went wrong in the search
			 */
			error = rc;
			goto cleanup;
	}

	/*
	 * If changing case, no need to search for destination inode
	 */
	if (!to_ip)
	{
		/*
		 * Now we can lookup the destination inode to make sure it
		 * hasn't been created since we did our verifications.  If it
		 * has we abort.
		 */
		dname.name = to_name;
		dname.namlen = UniStrlen (to_name);
		if (dname.namlen > JFS_NAME_MAX-1)
		{
			error = ERROR_FILENAME_EXCED_RANGE;
			goto cleanup;
		}
		rc = dtSearch(topar_ip, &dname, &ino, &btstack, JFS_LOOKUP);

		switch (rc)
		{
			case 0:
				/*
				 * We found an entry; fail with EEXIST
				 */
				rc = EEXIST;
				goto cleanup;
			case ENOENT:
				break;
			default:
				/*
				 * Some error from dtSearch().  cleanup and
				 * return
				 */
				error = rc;
				goto cleanup;
		}
	}

	/*
	 * Now we need to validate parameters and check for proper inodes
	 */

	/*
	 * Make sure the source inode has a positive link count
	 */
	if (from_ip->i_nlink <= 0)
	{
		error = EINVAL;
		goto cleanup;
	}

	if ((topar_ip->i_mode & IFMT) != IFDIR)
	{
		error = EINVAL;
		goto cleanup;
	}

	/* Check for the appropriate permissions on the source */

	if (doingdirectory && (frompar_ip->i_number != topar_ip->i_number))
	{
		/*
		 * Account for ".." in new directory.  When source and
		 * destination have the same parent we don't fool with the link
		 * count.
		 */
		if ((nlink_t)topar_ip->i_nlink >= LINK_MAX)
		{
			error = EMLINK;
			goto cleanup;
		}

		/*
		 * If ".." must be changed (i.e. the directory gets a new
		 * parent) then the source directory must not be in the
		 * directory hierarchy above the target, as this would orphan
		 * everything below the source directory.
		 */

		newparent = topar_ip->i_number;
		/* RENAME_LOCK(topar_ip->i_ipmnt); */
		if (error = jfs_checkpath(from_ip, frompar_ip, topar_ip, vfst))
			goto cleanup;
	}

	/*
	 * Check for write-protected media
	 */
	if (isReadOnly(topar_ip))
	{
		error = EROFS;
		goto cleanup;
	}

// BEGIN F226941
	/*
	 * Check to see if there is room in the destination directory
	 */
	blocks_moving = doingdirectory ? DASDUSED(&from_ip->i_DASD) :
					 from_ip->i_nblocks;

	if ((topar_ip != frompar_ip) && (topar_ip->i_dasdlim) &&
	    over_limit(topar_ip->i_dasdlim, blocks_moving, start_here))
	{
		error = ERROR_DISK_FULL;
		goto cleanup;
	}

	orig_fromblocks = frompar_ip->i_nblocks;
	if (topar_ip != frompar_ip)
		orig_toblocks = topar_ip->i_nblocks;
// END F226941

	/*
	 * Perform rename
	 */
	txBegin(topar_ip->i_ipmnt, &tid, 0);

	dname.name = to_name;
	dname.namlen = UniStrlen (to_name);

	if (to_ip != NULL)
	{
		/*
		 * We change the case of the name in place.
		 */
		ino = to_ip->i_number;

		if (error = dtChangeCase(tid, frompar_ip, &dname, &ino,
					 JFS_RENAME))
			goto cleanup;

		imark(topar_ip, ICHG|IUPD|IFSYNC);
	}
	else
	{
		/*
		 * We already know the destination does not exist, so link
		 * source inode as destination.
		 */
		if (error = dtSearch(topar_ip, &dname, &ino, &btstack,
				JFS_CREATE))
		{
			/*
			 * Problem, can't find where to put this guy, or it
			 * already exists!!
			 */
			goto cleanup;
		}

		ino = from_ip->i_number;
		if (error = dtInsert(tid, topar_ip, &dname, &ino, &btstack))
		{
			/*
			 * Failed adding source to destination parent
			 */
			goto cleanup;
		}

		imark(topar_ip, ICHG|IUPD|IFSYNC);

		/* Insert entry for the new file to name cache */
		ncEnter(topar_ip->i_ipimap, topar_ip->i_number, &dname,
			from_ip->i_number, NULL);

		/* Remove source name from source parent and name cache */
		dname.name = from_name;
		dname.namlen = UniStrlen (from_name);
		ino = from_ip->i_number;

		ncDelete(frompar_ip->i_ipimap, frompar_ip->i_number, &dname);

		if (error = dtDelete(tid, frompar_ip, &dname, &ino, JFS_REMOVE))
		{
			/*
		 	* Another unexpected error -- the original file does not
		 	* appear to exist ...
		 	*/
			assert(0);
		}
		imark(frompar_ip, ICHG|IUPD|IFSYNC);

		/*
		 * If this is a directory we need to update the ".." i-number
		 * in the inode.  Also, there is now one fewer ".." referencing
		 * the source parent directory.  Decrement the link count to
		 * the source parent directory for this.
		 */
		if (doingdirectory && newparent)
		{
			/* linelock header of dtree root (containing idotdot)
		 	*/
			tlck = txLock(tid, from_ip,
				      (jbuf_t *)&from_ip->i_bxflag,
				      tlckDTREE|tlckBTROOT);
			dtlck = (dtlock_t *)&tlck->lock;
			ASSERT(dtlck->index == 0);
			lv = (lv_t *)&dtlck->lv[0];
			lv->offset = 0;
			lv->length = 1;
			dtlck->index++;

			((dtroot_t *) &from_ip->i_btroot)->header.idotdot =
					newparent;

			frompar_ip->i_nlink--;
			topar_ip->i_nlink++;
			/* RENAME_UNLOCK(topar_ip->i_ipmnt); */
		}

		/* Set or reset INEWNAME flag as appropriate */
		from_ip->i_mode = (from_ip->i_mode & ~INEWNAME) |
				  (flags & INEWNAME);
		imark(from_ip, ICHG|IFSYNC);			// D231252
		txList[txCount++] = from_ip;			// D231252
	}

// BEGIN F226941
	/*
	 * Modify dasd usage for source and destination directories.
	 * Number of blocks for object being moved didn't change.
	 */
	if (frompar_ip == topar_ip)
	{
		DLIM_UPDATE(tid, frompar_ip, frompar_ip->i_nblocks
			    - orig_fromblocks);
	}
	else
	{
		DLIM_UPDATE(tid, topar_ip, topar_ip->i_nblocks +
			    blocks_moving - orig_toblocks);
		DLIM_UPDATE(tid, frompar_ip, frompar_ip->i_nblocks -
			    (orig_fromblocks + blocks_moving));
	}

// BEGIN D233382
#ifdef _JFS_FASTDASD
	if (from_dlim->num_limits)
	{
		/*
		 * Let's remove any ancestor directories at the beginning of
		 * the lock list that aren't directly involved in the rename.
		 * i_dasdlim will be non-zero for frompar_ip & topar_ip
		 */
		for(i = 0; i < num_locks; i++)
		{
			if (lock_list[i]->i_dasdlim)
			{
				first_locked = i;
				break;
			}
			IWRITE_UNLOCK(lock_list[i]);
		}
		ASSERT(i < num_locks);	// We shouldn't have unlocked them all.
	}
#endif /* _JFS_FASTDASD */
// END D233382

#ifndef _JFS_FASTDASD						// D233382
	if ((from_dlim->flag & DLIM_LOGGED) || (to_dlim->flag & DLIM_LOGGED))
	{
		error = txCommit(tid, num_locks, lock_list, 0);
		from_dlim->flag &= ~DLIM_LOGGED;
		to_dlim->flag &= ~DLIM_LOGGED;
	}
	else
#endif /* _JFS_FASTDASD */					// D233382
// END F226941

	{
		if (frompar_ip != topar_ip)
		{
			/*
			 * Different parent, so we need to add the other parent
			 * to our transaction list
			 */
			txList[txCount++] = topar_ip;
		}

		/* Add source parent directory to transaction list */
		txList[txCount++] = frompar_ip;

		assert(txCount <= 4);
		error = txCommit(tid, txCount, txList, 0);
	}

cleanup:
	/*
	 * Come to this label when all locks have been taken and ready to leave.
	 * error should be set to return value.
	 */
	if (tid != -1) txEnd(tid);

// BEGIN F226941
	if (from_dlim->num_limits)
	{
		frompar_ip->i_dasdlim->flag &= ~DLIM_DIRS_LOCKED;
		frompar_ip->i_dasdlim = 0;
		if (frompar_ip != topar_ip)
		{
			topar_ip->i_dasdlim->flag &= ~DLIM_DIRS_LOCKED;
			topar_ip->i_dasdlim = 0;
		}

#ifdef _JFS_FASTDASD
		for(i = first_locked; i < num_locks; i++)	// D233382
#else
		for(i = 0; i < num_locks; i++)
#endif
			IWRITE_UNLOCK(lock_list[i]);

		if (lock_list != lock_arr)
			xmfree((void *)lock_list, kernel_heap);
	}
	else
// END F226941
	{
		IWRITE_UNLOCK(from_ip);

		IWRITE_UNLOCK(frompar_ip);
		if (frompar_ip != topar_ip)
		{
			IWRITE_UNLOCK(topar_ip);
		}
	}


abortit:
	/*
	 * Come to this label when none of the locks have been taken and ready
	 * to leave.  error should be set to return value.
	 */
	if (to_ip && got_to)
	{
		ICACHE_LOCK();
		iput(to_ip, vfst);
		ICACHE_UNLOCK();
	}
	if (got_from)
	{
		ICACHE_LOCK();
		iput(from_ip, vfsf);
		ICACHE_UNLOCK();
	}

	RENAME_UNLOCK(ipmnt);

	return error;
}
Beispiel #6
0
void
free_objfile (struct objfile *objfile)
{
  if (objfile->separate_debug_objfile)
    {
      free_objfile (objfile->separate_debug_objfile);
    }
  
  if (objfile->separate_debug_objfile_backlink)
    {
      /* We freed the separate debug file, make sure the base objfile
	 doesn't reference it.  */
      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
    }
  
  /* First do any symbol file specific actions required when we are
     finished with a particular symbol file.  Note that if the objfile
     is using reusable symbol information (via mmalloc) then each of
     these routines is responsible for doing the correct thing, either
     freeing things which are valid only during this particular gdb
     execution, or leaving them to be reused during the next one. */

  if (objfile->sf != NULL)
    {
      (*objfile->sf->sym_finish) (objfile);
    }

  /* We always close the bfd. */

  if (objfile->obfd != NULL)
    {
      char *name = bfd_get_filename (objfile->obfd);
      if (!bfd_close (objfile->obfd))
	warning ("cannot close \"%s\": %s",
		 name, bfd_errmsg (bfd_get_error ()));
      xfree (name);
    }

  /* Remove it from the chain of all objfiles. */

  unlink_objfile (objfile);

  /* If we are going to free the runtime common objfile, mark it
     as unallocated.  */

  if (objfile == rt_common_objfile)
    rt_common_objfile = NULL;

  /* Before the symbol table code was redone to make it easier to
     selectively load and remove information particular to a specific
     linkage unit, gdb used to do these things whenever the monolithic
     symbol table was blown away.  How much still needs to be done
     is unknown, but we play it safe for now and keep each action until
     it is shown to be no longer needed. */

  /* I *think* all our callers call clear_symtab_users.  If so, no need
     to call this here.  */
  clear_pc_function_cache ();

  /* The last thing we do is free the objfile struct itself. */

  objfile_free_data (objfile);
  if (objfile->name != NULL)
    {
      xmfree (objfile->md, objfile->name);
    }
  if (objfile->global_psymbols.list)
    xmfree (objfile->md, objfile->global_psymbols.list);
  if (objfile->static_psymbols.list)
    xmfree (objfile->md, objfile->static_psymbols.list);
  /* Free the obstacks for non-reusable objfiles */
  bcache_xfree (objfile->psymbol_cache);
  bcache_xfree (objfile->macro_cache);
  if (objfile->demangled_names_hash)
    htab_delete (objfile->demangled_names_hash);
  obstack_free (&objfile->objfile_obstack, 0);
  xmfree (objfile->md, objfile);
  objfile = NULL;
}
Beispiel #7
0
struct objfile *
allocate_objfile (bfd *abfd, int flags)
{
  struct objfile *objfile = NULL;
  struct objfile *last_one = NULL;

  /* If we don't support mapped symbol files, didn't ask for the file to be
     mapped, or failed to open the mapped file for some reason, then revert
     back to an unmapped objfile. */

  if (objfile == NULL)
    {
      objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
      memset (objfile, 0, sizeof (struct objfile));
      objfile->md = NULL;
      objfile->psymbol_cache = bcache_xmalloc ();
      objfile->macro_cache = bcache_xmalloc ();
      /* We could use obstack_specify_allocation here instead, but
	 gdb_obstack.h specifies the alloc/dealloc functions.  */
      obstack_init (&objfile->objfile_obstack);
      terminate_minimal_symbol_table (objfile);
    }

  objfile_alloc_data (objfile);

  /* Update the per-objfile information that comes from the bfd, ensuring
     that any data that is reference is saved in the per-objfile data
     region. */

  objfile->obfd = abfd;
  if (objfile->name != NULL)
    {
      xmfree (objfile->md, objfile->name);
    }
  if (abfd != NULL)
    {
      objfile->name = mstrsave (objfile->md, bfd_get_filename (abfd));
      objfile->mtime = bfd_get_mtime (abfd);

      /* Build section table.  */

      if (build_objfile_section_table (objfile))
	{
	  error ("Can't find the file sections in `%s': %s",
		 objfile->name, bfd_errmsg (bfd_get_error ()));
	}
    }
  else
    {
      objfile->name = mstrsave (objfile->md, "<<anonymous objfile>>");
    }

  /* Initialize the section indexes for this objfile, so that we can
     later detect if they are used w/o being properly assigned to. */

  objfile->sect_index_text = -1;
  objfile->sect_index_data = -1;
  objfile->sect_index_bss = -1;
  objfile->sect_index_rodata = -1;

  /* We don't yet have a C++-specific namespace symtab.  */

  objfile->cp_namespace_symtab = NULL;

  /* Add this file onto the tail of the linked list of other such files. */

  objfile->next = NULL;
  if (object_files == NULL)
    object_files = objfile;
  else
    {
      for (last_one = object_files;
	   last_one->next;
	   last_one = last_one->next);
      last_one->next = objfile;
    }

  /* Save passed in flag bits. */
  objfile->flags |= flags;

  return (objfile);
}
Beispiel #8
0
void btk_mem_free(
    void * kmem_p, 
    size_t size
    )
{
    FUNCTION("btk_mem_free");
    LOG_UNKNOWN_UNIT;
    FENTRY;

    TRC_MSG((BT_TRC_ALLOC | BT_TRC_DETAIL), 
            (LOG_FMT "ptr: " PTR_FMT "  size %d.\n",
            LOG_ARG, kmem_p, (int) size));


#if     defined (_AIX)
    {
        int     retvalue;

        retvalue = (int) xmfree(kmem_p, pinned_heap);
        if (o != retvalue) {
            INFO_MSG((LOG_FMT "Error %d from xmfree().\n"));
        }
    }

#elif   defined(__hpux)

    sys_memfree(kmem_p, size);

#elif   defined(__sun)

    kmem_free( kmem_p, size ); /* returns default value of retvalue */

#elif   defined(__sgi)

    kmem_free(kmem_p, size);

#elif   defined(__vxworks)

    free(kmem_p);

#elif   defined(_NTDDK_)

    ExFreePool(kmem_p);

#elif   defined(BT_uCOS)

    free(kmem_p);

#elif	defined(__linux__)

    kfree(kmem_p);

#endif  /* _AIX, __hpux, __sun, __sgi, __vxworks, _NTDDK_ */


    btk_mutex_enter(&kmem_mutex);

    btk_alloc_total_g -= size;    /* running total of kmem */
    if (btk_alloc_total_g < 0) {
        FATAL_STR("Allocated kernel memory went negative.\n");
    }

    TRC_MSG((BT_TRC_ALLOC), 
            (LOG_FMT "ptr " PTR_FMT "; size %d; total %d.\n",
            LOG_ARG, kmem_p, (int) size, btk_alloc_total_g));

    btk_mutex_exit(&kmem_mutex);

    FEXIT(0);
    return;
}