Subject: kdump & emulation-pid map
To: None <tech-userlevel@NetBSD.ORG>
From: Niklas Hallqvist <niklas@appli.se>
List: tech-userlevel
Date: 08/22/1995 19:46:21
OK I went ahead as I needed the functionality anyway, here's the
patch. I hope the style is OK, I'm mostly a GNU style coder
otherwise. It works OK on my testcase, I might add.
Niklas
Index: kdump.c
===================================================================
RCS file: /u3/CVSROOT/NetBSD/src/usr.bin/kdump/kdump.c,v
retrieving revision 1.1.1.6
retrieving revision 1.1.1.1.2.9
diff -c -r1.1.1.6 -r1.1.1.1.2.9
*** kdump.c 1995/07/31 12:15:29 1.1.1.6
--- kdump.c 1995/08/22 18:11:11 1.1.1.1.2.9
***************
*** 109,116 ****
--- 109,134 ----
{ NULL, NULL, NULL }
};
+ struct emulation_map {
+ struct emulation_map *em_link;
+ pid_t em_pid;
+ struct emulation *em_emulation;
+ };
+
+ /* Forward decls. */
+ struct emulation *emulation_from_name __P((char *name));
+ struct emulation *emulation_from_pid __P((pid_t pid));
+ void bind_emulation_to_pid __P((struct emulation *, pid_t));
+
+ /* A mapping between pids and emulations currently in charge. */
+ struct emulation_map *current_emulations;
+
+ /* The current emulation (cache during a single trace event). */
struct emulation *current;
+ /* The default emulation, if nothing else is known. */
+ struct emulation *default_emulation;
+
static char *ptrace_ops[] = {
"PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
***************
*** 127,138 ****
register void *m;
int trpoints = ALL_POINTS;
! current = &emulations[0]; /* NetBSD */
while ((ch = getopt(argc, argv, "e:f:dlm:nRTt:")) != -1)
switch (ch) {
case 'e':
! setemul(optarg);
break;
case 'f':
tracefile = optarg;
--- 145,156 ----
register void *m;
int trpoints = ALL_POINTS;
! default_emulation = &emulations[0]; /* NetBSD */
while ((ch = getopt(argc, argv, "e:f:dlm:nRTt:")) != -1)
switch (ch) {
case 'e':
! default_emulation = emulation_from_name(optarg);
break;
case 'f':
tracefile = optarg;
***************
*** 175,180 ****
--- 193,199 ----
if (!freopen(tracefile, "r", stdin))
err(1, "%s", tracefile);
while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
+ current = emulation_from_pid(ktr_header.ktr_pid);
if (trpoints & (1<<ktr_header.ktr_type))
dumpheader(&ktr_header);
if ((ktrlen = ktr_header.ktr_len) < 0)
***************
*** 209,215 ****
ktrcsw((struct ktr_csw *)m);
break;
case KTR_EMUL:
! ktremul(m, ktrlen);
break;
}
if (tail)
--- 228,234 ----
ktrcsw((struct ktr_csw *)m);
break;
case KTR_EMUL:
! ktremul(m, ktrlen, ktr_header.ktr_pid);
break;
}
if (tail)
***************
*** 378,385 ****
(void)printf("\"%.*s\"\n", len, cp);
}
! ktremul(cp, len)
char *cp;
{
char name[1024];
--- 397,405 ----
(void)printf("\"%.*s\"\n", len, cp);
}
! ktremul(cp, len, pid)
char *cp;
+ pid_t pid;
{
char name[1024];
***************
*** 390,396 ****
name[len] = '\0';
(void)printf("\"%s\"\n", name);
! setemul(name);
}
ktrgenio(ktr, len)
--- 410,416 ----
name[len] = '\0';
(void)printf("\"%s\"\n", name);
! bind_emulation_to_pid(emulation_from_name(name), pid);
}
ktrgenio(ktr, len)
***************
*** 481,494 ****
exit(1);
}
! setemul(name)
char *name;
{
int i;
for (i = 0; emulations[i].name != NULL; i++)
if (strcmp(emulations[i].name, name) == 0) {
! current = &emulations[i];
! return;
}
warnx("Emulation `%s' unknown", name);
}
--- 501,549 ----
exit(1);
}
! struct emulation *
! emulation_from_name(name)
char *name;
{
int i;
for (i = 0; emulations[i].name != NULL; i++)
if (strcmp(emulations[i].name, name) == 0) {
! return &emulations[i];
}
warnx("Emulation `%s' unknown", name);
+ return default_emulation;
+ }
+
+ struct emulation *
+ emulation_from_pid(pid)
+ pid_t pid;
+ {
+ struct emulation_map *entry;
+
+ for (entry = current_emulations; entry; entry = entry->em_link)
+ if (entry->em_pid == pid)
+ return entry->em_emulation;
+ return default_emulation;
+ }
+
+ void
+ bind_emulation_to_pid(emulation, pid)
+ struct emulation *emulation;
+ pid_t pid;
+ {
+ struct emulation_map *entry;
+
+ for (entry = current_emulations; entry; entry = entry->em_link)
+ if (entry->em_pid == pid) {
+ entry->em_emulation = emulation;
+ return;
+ }
+ entry = current_emulations;
+ current_emulations =
+ (struct emulation_map *)malloc(sizeof(struct emulation_map));
+ if (current_emulations == NULL)
+ errx(1, "%s", strerror(ENOMEM));
+ current_emulations->em_link = entry;
+ current_emulations->em_pid = pid;
+ current_emulations->em_emulation = emulation;
}