//===-- Debugger.cpp - LLVM debugger library implementation ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the main implementation of the LLVM debugger library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Debugger/Debugger.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Debugger/InferiorProcess.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;

/// Debugger constructor - Initialize the debugger to its initial, empty, state.
///
Debugger::Debugger() : Environment(0), Program(0), Process(0) {
}

Debugger::~Debugger() {
  // Killing the program could throw an exception.  We don't want to progagate
  // the exception out of our destructor though.
  try {
    killProgram();
  } catch (const char *) {
  } catch (const std::string &) {
  }

  unloadProgram();
}

/// getProgramPath - Get the path of the currently loaded program, or an
/// empty string if none is loaded.
std::string Debugger::getProgramPath() const {
  return Program ? Program->getModuleIdentifier() : "";
}

static Module *
getMaterializedModuleProvider(const std::string &Filename) {
  try {
    std::auto_ptr<ModuleProvider> Result(getBytecodeModuleProvider(Filename));
    if (!Result.get()) return 0;

    Result->materializeModule();
    return Result.release()->releaseModule();
  } catch (...) {
    return 0;
  }
}

/// loadProgram - If a program is currently loaded, unload it.  Then search
/// the PATH for the specified program, loading it when found.  If the
/// specified program cannot be found, an exception is thrown to indicate the
/// error.
void Debugger::loadProgram(const std::string &Filename) {
  if ((Program = getMaterializedModuleProvider(Filename)) ||
      (Program = getMaterializedModuleProvider(Filename+".bc")))
    return;   // Successfully loaded the program.

  // Search the program path for the file...
  if (const char *PathS = getenv("PATH")) {
    std::string Path = PathS;

    std::string Directory = getToken(Path, ":");
    while (!Directory.empty()) {
      if ((Program = getMaterializedModuleProvider(Directory +"/"+ Filename)) ||
          (Program = getMaterializedModuleProvider(Directory +"/"+ Filename
                                                                      + ".bc")))
        return;   // Successfully loaded the program.

      Directory = getToken(Path, ":");
    }
  }

  throw "Could not find program '" + Filename + "'!";
}

/// unloadProgram - If a program is running, kill it, then unload all traces
/// of the current program.  If no program is loaded, this method silently
/// succeeds.
void Debugger::unloadProgram() {
  if (!isProgramLoaded()) return;
  killProgram();
  delete Program;
  Program = 0;
}


/// createProgram - Create an instance of the currently loaded program,
/// killing off any existing one.  This creates the program and stops it at
/// the first possible moment.  If there is no program loaded or if there is a
/// problem starting the program, this method throws an exception.
void Debugger::createProgram() {
  if (!isProgramLoaded())
    throw "Cannot start program: none is loaded.";

  // Kill any existing program.
  killProgram();

  // Add argv[0] to the arguments vector..
  std::vector<std::string> Args(ProgramArguments);
  Args.insert(Args.begin(), getProgramPath());

  // Start the new program... this could throw if the program cannot be started.
  Process = InferiorProcess::create(Program, Args, Environment);
}

/// killProgram - If the program is currently executing, kill off the
/// process and free up any state related to the currently running program.  If
/// there is no program currently running, this just silently succeeds.
void Debugger::killProgram() {
  // The destructor takes care of the dirty work.
  try {
    delete Process;
  } catch (...) {
    Process = 0;
    throw;
  }
  Process = 0;
}

/// stepProgram - Implement the 'step' command, continuing execution until
/// the next possible stop point.
void Debugger::stepProgram() {
  assert(isProgramRunning() && "Cannot step if the program isn't running!");
  try {
    Process->stepProgram();
  } catch (InferiorProcessDead &IPD) {
    killProgram();
    throw NonErrorException("The program stopped with exit code " +
                            itostr(IPD.getExitCode()));
  } catch (...) {
    killProgram();
    throw;
  }
}

/// nextProgram - Implement the 'next' command, continuing execution until
/// the next possible stop point that is in the current function.
void Debugger::nextProgram() {
  assert(isProgramRunning() && "Cannot next if the program isn't running!");
  try {
    // This should step the process.  If the process enters a function, then it
    // should 'finish' it.  However, figuring this out is tricky.  In
    // particular, the program can do any of:
    //  0. Not change current frame.
    //  1. Entering or exiting a region within the current function
    //     (which changes the frame ID, but which we shouldn't 'finish')
    //  2. Exiting the current function (which changes the frame ID)
    //  3. Entering a function (which should be 'finish'ed)
    // For this reason, we have to be very careful about when we decide to do
    // the 'finish'.

    // Get the current frame, but don't trust it.  It could change...
    void *CurrentFrame = Process->getPreviousFrame(0);

    // Don't trust the current frame: get the caller frame.
    void *ParentFrame  = Process->getPreviousFrame(CurrentFrame);

    // Ok, we have some information, run the program one step.
    Process->stepProgram();

    // Where is the new frame?  The most common case, by far is that it has not
    // been modified (Case #0), in which case we don't need to do anything more.
    void *NewFrame = Process->getPreviousFrame(0);
    if (NewFrame != CurrentFrame) {
      // Ok, the frame changed.  If we are case #1, then the parent frame will
      // be identical.
      void *NewParentFrame = Process->getPreviousFrame(NewFrame);
      if (ParentFrame != NewParentFrame) {
        // Ok, now we know we aren't case #0 or #1.  Check to see if we entered
        // a new function.  If so, the parent frame will be "CurrentFrame".
        if (CurrentFrame == NewParentFrame)
          Process->finishProgram(NewFrame);
      }
    }

  } catch (InferiorProcessDead &IPD) {
    killProgram();
    throw NonErrorException("The program stopped with exit code " +
                            itostr(IPD.getExitCode()));
  } catch (...) {
    killProgram();
    throw;
  }
}

/// finishProgram - Implement the 'finish' command, continuing execution
/// until the specified frame ID returns.
void Debugger::finishProgram(void *Frame) {
  assert(isProgramRunning() && "Cannot cont if the program isn't running!");
  try {
    Process->finishProgram(Frame);
  } catch (InferiorProcessDead &IPD) {
    killProgram();
    throw NonErrorException("The program stopped with exit code " +
                            itostr(IPD.getExitCode()));
  } catch (...) {
    killProgram();
    throw;
  }
}

/// contProgram - Implement the 'cont' command, continuing execution until
/// the next breakpoint is encountered.
void Debugger::contProgram() {
  assert(isProgramRunning() && "Cannot cont if the program isn't running!");
  try {
    Process->contProgram();
  } catch (InferiorProcessDead &IPD) {
    killProgram();
    throw NonErrorException("The program stopped with exit code " +
                            itostr(IPD.getExitCode()));
  } catch (...) {
    killProgram();
    throw;
  }
}
