#include "nextstep-nat-mutils.h"
#include "nextstep-nat-inferior.h"
#include "nextstep-threads.h"
#include "defs.h"
#include "inferior.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "target.h"
#include "gdbcore.h"
#import "SegmentManagerThreads.h"
#include <sys/time.h>
int current_core_thread = 0;
static struct target_ops core_ops;
extern void child_attach (char *name, int from_tty);
extern void child_create_inferior (char *exec, char *args, char **env);
extern RegionManager *regionManager;
extern void core_get_registers (int regnum);
extern CORE_ADDR getThreadPCAndNameFromState (REGS_STRUCT *regsState, char **pName);
extern char *getThreadNameFromState (USER_REG_STRUCT *userRegState, int n);
static void
core_cleanup ()
{
if (regionManager) {
[regionManager free];
regionManager = nil;
}
}
void
core_open (filename, from_tty)
char *filename;
int from_tty;
{
char *temp;
struct cleanup *old_chain;
SegmentManager *newCM;
if (filename == NULL) {
error (regionManager
? "No core file specified."
"(Use `detach' to stop debugging a core file.)"
: "No core file specified.");
}
filename = tilde_expand (filename);
if (filename[0] != '/') {
temp = concat (current_directory, "/", filename, NULL);
free (filename);
filename = temp;
}
old_chain = make_cleanup (free, filename);
newCM = [SegmentManager newCore: filename];
if (newCM == NULL) {
error ("\"%s\" is not a core file.", filename);
}
if (! [newCM validate]) {
error ("\"%s\" is an invalid core file.", filename);
}
discard_cleanups (old_chain);
core_cleanup ();
regionManager = (RegionManager *) newCM;
old_chain = make_cleanup (core_cleanup, NULL);
push_target (&core_ops);
core_get_registers (-1);
set_current_frame (create_new_frame (read_register(FP_REGNUM), read_pc ()));
select_frame (get_current_frame (), 0);
print_sel_frame (0);
#ifdef GDB414
if (state_change_hook) {
state_change_hook(STATE_INFERIOR_STOPPED);
}
#endif
discard_cleanups (old_chain);
}
void
core_detach (quitting)
{
core_cleanup ();
}
int
have_core_file_p ()
{
return regionManager != NULL;
}
static void
core_files_info ()
{
}
static int
core_xfer_memory (memaddr, myaddr, len, write)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
{
if (write) {
error ("Can't write to core files.");
}
return [regionManager getDataAt: (void *)memaddr nbytes: len into: myaddr];
}
void
core_thread_list ()
{
int numThreads, i;
ThreadInfo *tInfos, *tInfo;
SegmentManager *coreManager = (SegmentManager *)regionManager;
char *name, *fName;
CORE_ADDR pc;
numThreads = [coreManager numThreads];
if (numThreads == 1)
printf_filtered("There is 1 thread.\n");
else
printf_filtered("There are %d threads.\n", numThreads);
if (numThreads == 0)
return;
tInfos = [coreManager threadInfos];
printf_filtered("Thread PC Name Function\n");
for (i = 0; i < numThreads; i++) {
name = getThreadNameFromState(THREADINFO_NAME_STATE(tInfos[i]), i);
pc = getThreadPCAndNameFromState(THREADINFO_PC_STATE(tInfos[i]), &fName);
printf_filtered ("%-6d 0x%-8x %-15s %-40s\n", i, pc, name, fName);
}
free(tInfos);
}
void
core_thread_select (args, from_tty)
char *args;
int from_tty;
{
int numThreads, numThread;
SegmentManager *coreManager = (SegmentManager *)regionManager;
if (!args)
error_no_arg ("thread index to select");
numThreads = [coreManager numThreads];
numThread = atoi(args);
if ((numThreads < numThreads) || (numThreads <= numThread))
error("Invalid thread.\n");
else
current_core_thread = numThread;
}
static struct target_ops core_ops = {
"core",
"Local core dump file",
"Use a core file as a target.\n"
"Specify the filename of the core file.",
core_open,
core_detach,
0,
core_detach,
0,
0,
core_get_registers,
0,
0,
core_xfer_memory,
core_files_info,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
find_default_create_inferior,
0,
0,
0,
0,
0,
core_stratum,
0,
0,
1,
1,
1,
0,
0,
0,
OPS_MAGIC
};
void (*exec_file_display_hook) () = NULL;
void
_initialize_next_core ()
{
add_target (&core_ops);
}