18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file opd_image.c
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Management of binary images
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_image.h"
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_printf.h"
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_sample_files.h"
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_24_stats.h"
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprofiled.h"
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_file.h"
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_config_24.h"
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_libiberty.h"
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_string.h"
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string.h>
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdlib.h>
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdio.h>
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* maintained for statistics purpose only */
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int nr_images;
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* list of images */
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define OPD_IMAGE_HASH_SIZE 2048
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct list_head opd_images[OPD_IMAGE_HASH_SIZE];
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_init_images(void)
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int i;
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = 0; i < OPD_IMAGE_HASH_SIZE; ++i)
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		list_init(&opd_images[i]);
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint opd_get_nr_images(void)
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return nr_images;
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_delete_image(struct opd_image * image)
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	verbprintf(vmisc, "Deleting image: name %s app_name %s, kernel %d, "
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	           "tid %d, tgid %d ref count %u\n",
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	           image->name, image->app_name, image->kernel,
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	           image->tid, image->tgid, (int)image->ref_count);
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->ref_count <= 0) {
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		printf("image->ref_count < 0 for image: name %s app_name %s, "
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       "kernel %d, tid %d, tgid %d ref count %u\n",
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       image->name, image->app_name, image->kernel,
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       image->tid, image->tgid, image->ref_count);
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		abort();
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (--image->ref_count != 0)
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->name)
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		free(image->name);
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->app_name)
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		free(image->app_name);
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list_del(&image->hash_next);
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	opd_close_image_samples_files(image);
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	free(image);
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_images--;
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_for_each_image(opd_image_cb image_cb)
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct list_head * pos;
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct list_head * pos2;
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int i;
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = 0; i < OPD_IMAGE_HASH_SIZE; ++i) {
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		list_for_each_safe(pos, pos2, &opd_images[i]) {
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			struct opd_image * image =
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				list_entry(pos, struct opd_image, hash_next);
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_cb(image);
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_hash_image - hash an image
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param hash  hash of image name
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tid  thread id
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tgid  thread group id
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * return the hash code for the passed parameters
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic size_t opd_hash_image(char const * name, pid_t tid, pid_t tgid)
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t hash = op_hash_string(name);
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (separate_thread)
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		hash += tid + tgid;
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return  hash % OPD_IMAGE_HASH_SIZE;
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_new_image - create an image sample file
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param app_name  the application name where belongs this image
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param name  name of the image to add
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param kernel  is the image a kernel/module image
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tid  thread id
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tgid  thread group id
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * image at funtion entry is uninitialised
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * name is copied i.e. should be GC'd separately from the
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * image structure if appropriate.
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Initialise an opd_image struct for the image image
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * without opening the associated samples files. At return
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the image is fully initialized.
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_image *
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddopd_new_image(char const * name, char const * app_name, int kernel,
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd              pid_t tid, pid_t tgid)
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t hash_image;
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct opd_image * image;
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	verbprintf(vmisc, "Creating image: %s %s, kernel %d, tid %d, "
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	           "tgid %d\n", name, app_name, kernel, tid, tgid);
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image = xmalloc(sizeof(struct opd_image));
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list_init(&image->hash_next);
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->name = xstrdup(name);
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->kernel = kernel;
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->tid = tid;
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->tgid = tgid;
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->ref_count = 0;
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->app_name = app_name ? xstrdup(app_name) : NULL;
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->mtime = op_get_mtime(image->name);
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	image->ignored = 1;
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (separate_lib && app_name)
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image->ignored = is_image_ignored(app_name);
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->ignored)
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image->ignored = is_image_ignored(name);
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	memset(image->sfiles, '\0', NR_CPUS * sizeof(struct opd_24_sfile **));
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	hash_image = opd_hash_image(name, tid, tgid);
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list_add(&image->hash_next, &opd_images[hash_image]);
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_images++;
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return image;
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * is_same_image - check for identical image
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param image  image to compare
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param name  name of image
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param app_name image must belong to this application name
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tid  thread id
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tgid  thread group id
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * on entry caller have checked than strcmp(image->name, name) == 0
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * return 0 if the couple (name, app_name) refers to same image
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int is_same_image(struct opd_image const * image, char const * app_name,
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                         pid_t tid, pid_t tgid)
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* correctness is really important here, if we fail to recognize
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * identical image we will open/mmap multiple time the same samples
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * files which is not supported by the kernel, strange assertion
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * failure in libfd is a typical symptom of that */
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (separate_thread) {
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (image->tid != tid || image->tgid != tgid)
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return 1;
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* if !separate_lib, the comparison made by caller is enough */
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!separate_lib)
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return 0;
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->app_name == NULL && app_name == NULL)
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return 0;
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->app_name != NULL && app_name != NULL &&
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	    !strcmp(image->app_name, app_name))
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return 0;
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* /proc parsed image come with a non null app_name but notification
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * for application itself come with a null app_name, in this case
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * the test above fail so check for this case. */
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (image->app_name && !app_name && !strcmp(image->app_name, image->name))
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return 0;
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return 1;
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_find_image - find an image
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param name  name of image to find
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param hash  hash of image to find
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param app_name  the application name where belongs this image
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tid  thread id
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tgid  thread group id
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Returns the image pointer for the file specified by name, or %NULL.
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_image * opd_find_image(char const * name,
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                                char const * app_name, pid_t tid, pid_t tgid)
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* suppress uninitialized use warning */
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct opd_image * image = 0;
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct list_head * pos;
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t bucket;
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	opd_24_stats[OPD_IMAGE_HASH_ACCESS]++;
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bucket = opd_hash_image(name, tid, tgid);
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list_for_each(pos, &opd_images[bucket]) {
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		opd_24_stats[OPD_IMAGE_HASH_DEPTH]++;
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image = list_entry(pos, struct opd_image, hash_next);
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (!strcmp(image->name, name)) {
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (!is_same_image(image, app_name, tid, tgid))
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				break;
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (pos == &opd_images[bucket])
2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return NULL;
2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* The app_name field is always valid */
2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return image;
2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct opd_image * opd_get_image(char const * name, char const * app_name,
2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                                 int kernel, pid_t tid, pid_t tgid)
2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct opd_image * image;
2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if ((image = opd_find_image(name, app_name, tid, tgid)) == NULL)
2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image = opd_new_image(name, app_name, kernel, tid, tgid);
2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return image;
2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct opd_image * opd_get_kernel_image(char const * name,
2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                               char const * app_name, pid_t tid, pid_t tgid)
2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return opd_get_image(name, app_name, 1, tid, tgid);
2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
265