PERFORCE change 130927 for review
John Birrell
jb at FreeBSD.org
Fri Dec 14 18:30:33 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=130927
Change 130927 by jb at jb_freebsd1 on 2007/12/15 02:29:50
MFdtrace
Affected files ...
.. //depot/projects/dtrace7/src/sys/kern/kern_linker.c#2 edit
.. //depot/projects/dtrace7/src/sys/kern/linker_if.m#2 edit
.. //depot/projects/dtrace7/src/sys/sys/linker.h#2 edit
Differences ...
==== //depot/projects/dtrace7/src/sys/kern/kern_linker.c#2 (text+ko) ====
@@ -97,6 +97,12 @@
static struct sx kld_sx; /* kernel linker lock */
+/*
+ * Load counter used by clients to determine if a linker file has been
+ * re-loaded. This counter is incremented for each file load.
+ */
+static int loadcnt;
+
static linker_class_list_t classes;
static linker_file_list_t linker_files;
static int next_file_id = 1;
@@ -534,7 +540,7 @@
KLD_LOCK_ASSERT();
filename = linker_basename(pathname);
- KLD_DPF(FILE, ("linker_make_file: new file, filename=%s\n", filename));
+ KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for pathname='%s'\n", filename, pathname));
lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
if (lf == NULL)
return (NULL);
@@ -542,9 +548,13 @@
lf->userrefs = 0;
lf->flags = 0;
lf->filename = linker_strdup(filename);
+ lf->pathname = linker_strdup(pathname);
LINKER_GET_NEXT_FILE_ID(lf->id);
lf->ndeps = 0;
lf->deps = NULL;
+ lf->loadcnt = ++loadcnt;
+ lf->sdt_probes = NULL;
+ lf->sdt_nprobes = 0;
STAILQ_INIT(&lf->common);
TAILQ_INIT(&lf->modules);
TAILQ_INSERT_TAIL(&linker_files, lf, link);
@@ -629,6 +639,10 @@
free(file->filename, M_LINKER);
file->filename = NULL;
}
+ if (file->pathname) {
+ free(file->pathname, M_LINKER);
+ file->pathname = NULL;
+ }
kobj_delete((kobj_t) file, M_LINKER);
return (0);
}
@@ -676,6 +690,16 @@
return (error);
}
+/*
+ * List all functions in a file.
+ */
+int
+linker_file_function_listall(linker_file_t lf,
+ int (*callback_func)(linker_file_t, linker_symval_t *, void *), void *arg)
+{
+ return (LINKER_EACH_FUNCTION_NAMEVAL(lf, callback_func, arg));
+}
+
caddr_t
linker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
{
@@ -920,7 +944,13 @@
lf = linker_find_file_by_id(fileid);
if (lf) {
KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
- if (lf->userrefs == 0) {
+
+ /* Check if there are DTrace probes enabled on this file. */
+ if (lf->nenabled > 0) {
+ printf("kldunload: attempt to unload file that has"
+ " DTrace probes enabled\n");
+ error = EBUSY;
+ } else if (lf->userrefs == 0) {
/*
* XXX: maybe LINKER_UNLOAD_FORCE should override ?
*/
@@ -1041,15 +1071,18 @@
{
struct kld_file_stat stat;
linker_file_t lf;
- int error, namelen;
+ int error, namelen, version, version_num;
/*
* Check the version of the user's structure.
*/
- error = copyin(uap->stat, &stat, sizeof(struct kld_file_stat));
- if (error)
+ if ((error = copyin(&uap->stat->version, &version, sizeof(version))) != 0)
return (error);
- if (stat.version != sizeof(struct kld_file_stat))
+ if (version == sizeof(struct kld_file_stat_1))
+ version_num = 1;
+ else if (version == sizeof(struct kld_file_stat))
+ version_num = 2;
+ else
return (EINVAL);
#ifdef MAC
@@ -1065,6 +1098,7 @@
return (ENOENT);
}
+ /* Version 1 fields: */
namelen = strlen(lf->filename) + 1;
if (namelen > MAXPATHLEN)
namelen = MAXPATHLEN;
@@ -1073,6 +1107,13 @@
stat.id = lf->id;
stat.address = lf->address;
stat.size = lf->size;
+ if (version_num > 1) {
+ /* Version 2 fields: */
+ namelen = strlen(lf->pathname) + 1;
+ if (namelen > MAXPATHLEN)
+ namelen = MAXPATHLEN;
+ bcopy(lf->pathname, &stat.pathname[0], namelen);
+ }
KLD_UNLOCK();
td->td_retval[0] = 0;
==== //depot/projects/dtrace7/src/sys/kern/linker_if.m#2 (text+ko) ====
@@ -64,6 +64,17 @@
};
#
+# Call the callback with each specified function and it's value
+# defined in the file.
+# Stop and return the error if the callback returns an error.
+#
+METHOD int each_function_nameval {
+ linker_file_t file;
+ linker_function_nameval_callback_t callback;
+ void* opaque;
+};
+
+#
# Search for a linker set in a file. Return a pointer to the first
# entry (which is itself a pointer), and the number of entries.
# "stop" points to the entry beyond the last valid entry.
==== //depot/projects/dtrace7/src/sys/sys/linker.h#2 (text+ko) ====
@@ -59,6 +59,8 @@
size_t size;
} linker_symval_t;
+typedef int (*linker_function_nameval_callback_t)(linker_file_t, linker_symval_t *, void *);
+
struct common_symbol {
STAILQ_ENTRY(common_symbol) link;
char* name;
@@ -73,6 +75,7 @@
#define LINKER_FILE_LINKED 0x1 /* file has been fully linked */
TAILQ_ENTRY(linker_file) link; /* list of all loaded files */
char* filename; /* file which was loaded */
+ char* pathname; /* file name with full path */
int id; /* unique id */
caddr_t address; /* load address */
size_t size; /* size of file */
@@ -81,6 +84,18 @@
STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
TAILQ_HEAD(, module) modules; /* modules in this file */
TAILQ_ENTRY(linker_file) loaded; /* preload dependency support */
+ int loadcnt; /* load counter value */
+
+ /*
+ * Function Boundary Tracing (FBT) or Statically Defined Tracing (SDT)
+ * fields.
+ */
+ int nenabled; /* number of enabled probes. */
+ int fbt_nentries; /* number of fbt entries created. */
+ void *sdt_probes;
+ int sdt_nentries;
+ size_t sdt_nprobes;
+ size_t sdt_size;
};
/*
@@ -141,6 +156,12 @@
void *_start, void *_stop, int *_count);
/*
+ * List all functions in a file.
+ */
+int linker_file_function_listall(linker_file_t, int (*)(linker_file_t,
+ linker_symval_t *, void *), void *);
+
+/*
* Functions soley for use by the linker class handlers.
*/
int linker_add_class(linker_class_t _cls);
@@ -245,15 +266,28 @@
#define ELF_RELOC_REL 1
#define ELF_RELOC_RELA 2
+/*
+ * This is version 1 of the KLD file status structure. It is identified
+ * by its _size_ in the version field.
+ */
+struct kld_file_stat_1 {
+ int version; /* set to sizeof(struct kld_file_stat_1) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ caddr_t address; /* load address */
+ size_t size; /* size in bytes */
+};
#endif /* _KERNEL */
struct kld_file_stat {
- int version; /* set to sizeof(linker_file_stat) */
+ int version; /* set to sizeof(struct kld_file_stat) */
char name[MAXPATHLEN];
int refs;
int id;
caddr_t address; /* load address */
size_t size; /* size in bytes */
+ char pathname[MAXPATHLEN];
};
struct kld_sym_lookup {
More information about the p4-projects
mailing list