//===-- UnixLocalInferiorProcess.cpp - A Local process on a Unixy system --===//
// 
//                     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 provides one implementation of the InferiorProcess class, which is
// designed to be used on unixy systems (those that support pipe, fork, exec,
// and signals).
//
// When the process is started, the debugger creates a pair of pipes, forks, and
// makes the child start executing the program.  The child executes the process
// with an IntrinsicLowering instance that turns debugger intrinsics into actual
// callbacks.
//
// This target takes advantage of the fact that the Module* addresses in the
// parent and the Module* addresses in the child will be the same, due to the
// use of fork().  As such, global addresses looked up in the child can be sent
// over the pipe to the debugger.
//
//===----------------------------------------------------------------------===//

#include "llvm/Debugger/InferiorProcess.h"
#include "llvm/Constant.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/ADT/StringExtras.h"
#include "FDHandle.h"
#include <cerrno>
#include <csignal>
#include <unistd.h>        // Unix-specific debugger support
#include <sys/types.h>
#include <sys/wait.h>
using namespace llvm;

// runChild - Entry point for the child process.
static void runChild(Module *M, const std::vector<std::string> &Arguments,
                     const char * const *envp,
                     FDHandle ReadFD, FDHandle WriteFD);

//===----------------------------------------------------------------------===//
//                        Parent/Child Pipe Protocol
//===----------------------------------------------------------------------===//
//
// The parent/child communication protocol is designed to have the child process
// responding to requests that the debugger makes.  Whenever the child process
// has stopped (due to a break point, single stepping, etc), the child process
// enters a message processing loop, where it reads and responds to commands
// until the parent decides that it wants to continue execution in some way.
//
// Whenever the child process stops, it notifies the debugger by sending a
// character over the wire.
//

namespace {
  /// LocationToken - Objects of this type are sent across the pipe from the
  /// child to the parent to indicate where various stack frames are located.
  struct LocationToken {
    unsigned Line, Col;
    const GlobalVariable *File;
    LocationToken(unsigned L = 0, unsigned C = 0, const GlobalVariable *F = 0)
      : Line(L), Col(C), File(F) {}
  };
}

// Once the debugger process has received the LocationToken, it can make
// requests of the child by sending one of the following enum values followed by
// any data required by that command.  The child responds with data appropriate
// to the command.
//
namespace {
  /// CommandID - This enum defines all of the commands that the child process
  /// can respond to.  The actual expected data and responses are defined as the
  /// enum values are defined.
  ///
  enum CommandID {
    //===------------------------------------------------------------------===//
    // Execution commands - These are sent to the child to from the debugger to
    // get it to do certain things.
    //

    // StepProgram: void->char - This command causes the program to continue
    // execution, but stop as soon as it reaches another stoppoint.
    StepProgram,

    // FinishProgram: FrameDesc*->char - This command causes the program to
    // continue execution until the specified function frame returns.
    FinishProgram, 

    // ContProgram: void->char - This command causes the program to continue
    // execution, stopping at some point in the future.
    ContProgram,

    // GetSubprogramDescriptor: FrameDesc*->GlobalValue* - This command returns
    // the GlobalValue* descriptor object for the specified stack frame.
    GetSubprogramDescriptor,

    // GetParentFrame: FrameDesc*->FrameDesc* - This command returns the frame
    // descriptor for the parent stack frame to the specified one, or null if
    // there is none.
    GetParentFrame,

    // GetFrameLocation - FrameDesc*->LocationToken - This command returns the
    // location that a particular stack frame is stopped at.
    GetFrameLocation,

    // AddBreakpoint - LocationToken->unsigned - This command instructs the
    // target to install a breakpoint at the specified location.
    AddBreakpoint,

    // RemoveBreakpoint - unsigned->void - This command instructs the target to
    // remove a breakpoint.
    RemoveBreakpoint,
  };
}




//===----------------------------------------------------------------------===//
//                            Parent Process Code
//===----------------------------------------------------------------------===//

namespace {
  class IP : public InferiorProcess {
    // ReadFD, WriteFD - The file descriptors to read/write to the inferior
    // process.
    FDHandle ReadFD, WriteFD;

    // ChildPID - The unix PID of the child process we forked.
    mutable pid_t ChildPID;
  public:
    IP(Module *M, const std::vector<std::string> &Arguments,
       const char * const *envp);
    ~IP();

    std::string getStatus() const;

    /// Execution method implementations...
    virtual void stepProgram();
    virtual void finishProgram(void *Frame);
    virtual void contProgram();


    // Stack frame method implementations...
    virtual void *getPreviousFrame(void *Frame) const;
    virtual const GlobalVariable *getSubprogramDesc(void *Frame) const;
    virtual void getFrameLocation(void *Frame, unsigned &LineNo,
                                  unsigned &ColNo,
                                  const GlobalVariable *&SourceDesc) const;

    // Breakpoint implementation methods
    virtual unsigned addBreakpoint(unsigned LineNo, unsigned ColNo,
                                   const GlobalVariable *SourceDesc);
    virtual void removeBreakpoint(unsigned ID);


  private:
    /// startChild - This starts up the child process, and initializes the
    /// ChildPID member.
    ///
    void startChild(Module *M, const std::vector<std::string> &Arguments,
                    const char * const *envp);

    /// killChild - Kill or reap the child process.  This throws the
    /// InferiorProcessDead exception an exit code if the process had already
    /// died, otherwise it just kills it and returns.
    void killChild() const;

  private:
    // Methods for communicating with the child process.  If the child exits or
    // dies while attempting to communicate with it, ChildPID is set to zero and
    // an exception is thrown.

    /// readFromChild - Low-level primitive to read some data from the child,
    /// throwing an exception if it dies.
    void readFromChild(void *Buffer, unsigned Size) const;

    /// writeToChild - Low-level primitive to send some data to the child
    /// process, throwing an exception if the child died.
    void writeToChild(void *Buffer, unsigned Size) const;

    /// sendCommand - Send a command token and the request data to the child.
    ///
    void sendCommand(CommandID Command, void *Data, unsigned Size) const;

    /// waitForStop - This method waits for the child process to reach a stop
    /// point.
    void waitForStop();
  };
}

// create - This is the factory method for the InferiorProcess class.  Since
// there is currently only one subclass of InferiorProcess, we just define it
// here.
InferiorProcess *
InferiorProcess::create(Module *M, const std::vector<std::string> &Arguments,
                        const char * const *envp) {
  return new IP(M, Arguments, envp);
}

/// IP constructor - Create some pipes, them fork a child process.  The child
/// process should start execution of the debugged program, but stop at the
/// first available opportunity.
IP::IP(Module *M, const std::vector<std::string> &Arguments,
       const char * const *envp)
  : InferiorProcess(M) {

  // Start the child running...
  startChild(M, Arguments, envp);
  
  // Okay, we created the program and it is off and running.  Wait for it to
  // stop now.
  try {
    waitForStop();
  } catch (InferiorProcessDead &IPD) {
    throw "Error waiting for the child process to stop.  "
          "It exited with status " + itostr(IPD.getExitCode());
  }
}

IP::~IP() {
  // If the child is still running, kill it.
  if (!ChildPID) return;

  killChild();
}

/// getStatus - Return information about the unix process being debugged.
///
std::string IP::getStatus() const {
  if (ChildPID == 0)
    return "Unix target.  ERROR: child process appears to be dead!\n";

  return "Unix target: PID #" + utostr((unsigned)ChildPID) + "\n";
}


/// startChild - This starts up the child process, and initializes the
/// ChildPID member.
///
void IP::startChild(Module *M, const std::vector<std::string> &Arguments,
                    const char * const *envp) {
  // Create the pipes.  Make sure to immediately assign the returned file
  // descriptors to FDHandle's so they get destroyed if an exception is thrown.
  int FDs[2];
  if (pipe(FDs)) throw "Error creating a pipe!";
  FDHandle ChildReadFD(FDs[0]);
  WriteFD = FDs[1];

  if (pipe(FDs)) throw "Error creating a pipe!";
  ReadFD = FDs[0];
  FDHandle ChildWriteFD(FDs[1]);

  // Fork off the child process.
  switch (ChildPID = fork()) {
  case -1: throw "Error forking child process!";
  case 0:  // child
    delete this;       // Free parent pipe file descriptors
    runChild(M, Arguments, envp, ChildReadFD, ChildWriteFD);
    exit(1);
  default: break;
  }
}

/// sendCommand - Send a command token and the request data to the child.
///
void IP::sendCommand(CommandID Command, void *Data, unsigned Size) const {
  writeToChild(&Command, sizeof(Command));
  writeToChild(Data, Size);
}

/// stepProgram - Implement the 'step' command, continuing execution until
/// the next possible stop point.
void IP::stepProgram() {
  sendCommand(StepProgram, 0, 0);
  waitForStop();
}

/// finishProgram - Implement the 'finish' command, executing the program until
/// the current function returns to its caller.
void IP::finishProgram(void *Frame) {
  sendCommand(FinishProgram, &Frame, sizeof(Frame));
  waitForStop();
}

/// contProgram - Implement the 'cont' command, continuing execution until
/// a breakpoint is encountered.
void IP::contProgram() {
  sendCommand(ContProgram, 0, 0);
  waitForStop();
}


//===----------------------------------------------------------------------===//
// Stack manipulation methods
//

/// getPreviousFrame - Given the descriptor for the current stack frame,
/// return the descriptor for the caller frame.  This returns null when it
/// runs out of frames.
void *IP::getPreviousFrame(void *Frame) const {
  sendCommand(GetParentFrame, &Frame, sizeof(Frame));
  readFromChild(&Frame, sizeof(Frame));
  return Frame;
}

/// getSubprogramDesc - Return the subprogram descriptor for the current
/// stack frame.
const GlobalVariable *IP::getSubprogramDesc(void *Frame) const {
  sendCommand(GetSubprogramDescriptor, &Frame, sizeof(Frame));
  const GlobalVariable *Desc;
  readFromChild(&Desc, sizeof(Desc));
  return Desc;
}

/// getFrameLocation - This method returns the source location where each stack
/// frame is stopped.
void IP::getFrameLocation(void *Frame, unsigned &LineNo, unsigned &ColNo, 
                          const GlobalVariable *&SourceDesc) const {
  sendCommand(GetFrameLocation, &Frame, sizeof(Frame));
  LocationToken Loc;
  readFromChild(&Loc, sizeof(Loc));
  LineNo     = Loc.Line;
  ColNo      = Loc.Col;
  SourceDesc = Loc.File;
}


//===----------------------------------------------------------------------===//
// Breakpoint manipulation methods
//
unsigned IP::addBreakpoint(unsigned LineNo, unsigned ColNo,
                           const GlobalVariable *SourceDesc) {
  LocationToken Loc;
  Loc.Line = LineNo;
  Loc.Col = ColNo;
  Loc.File = SourceDesc;
  sendCommand(AddBreakpoint, &Loc, sizeof(Loc));
  unsigned ID;
  readFromChild(&ID, sizeof(ID));
  return ID;
}

void IP::removeBreakpoint(unsigned ID) {
  sendCommand(RemoveBreakpoint, &ID, sizeof(ID));
}


//===----------------------------------------------------------------------===//
//             Methods for communication with the child process
//
// Methods for communicating with the child process.  If the child exits or dies
// while attempting to communicate with it, ChildPID is set to zero and an
// exception is thrown.
//

/// readFromChild - Low-level primitive to read some data from the child,
/// throwing an exception if it dies.
void IP::readFromChild(void *Buffer, unsigned Size) const {
  assert(ChildPID &&
         "Child process died and still attempting to communicate with it!");
  while (Size) {
    ssize_t Amount = read(ReadFD, Buffer, Size);
    if (Amount == 0) {
      // If we cannot communicate with the process, kill it.
      killChild();
      // If killChild succeeded, then the process must have closed the pipe FD
      // or something, because the child existed, but we cannot communicate with
      // it.
      throw InferiorProcessDead(-1);
    } else if (Amount == -1) {
      if (errno != EINTR) {
        ChildPID = 0;
        killChild();
        throw "Error reading from child process!";
      }
    } else {
      // We read a chunk.
      Buffer = (char*)Buffer + Amount;
      Size -= Amount;
    }
  }
}

/// writeToChild - Low-level primitive to send some data to the child
/// process, throwing an exception if the child died.
void IP::writeToChild(void *Buffer, unsigned Size) const {
  while (Size) {
    ssize_t Amount = write(WriteFD, Buffer, Size);
    if (Amount < 0 && errno == EINTR) continue;
    if (Amount <= 0) {
      // If we cannot communicate with the process, kill it.
      killChild();

      // If killChild succeeded, then the process must have closed the pipe FD
      // or something, because the child existed, but we cannot communicate with
      // it.
      throw InferiorProcessDead(-1);
    } else {
      // We wrote a chunk.
      Buffer = (char*)Buffer + Amount;
      Size -= Amount;
    }
  }
}

/// killChild - Kill or reap the child process.  This throws the
/// InferiorProcessDead exception an exit code if the process had already
/// died, otherwise it just returns the exit code if it had to be killed.
void IP::killChild() const {
  assert(ChildPID != 0 && "Child has already been reaped!");
  
  // If the process terminated on its own accord, closing the pipe file
  // descriptors, we will get here.  Check to see if the process has already
  // died in this manner, gracefully.
  int Status = 0;
  int PID;
  do {
    PID = waitpid(ChildPID, &Status, WNOHANG);
  } while (PID < 0 && errno == EINTR);
  if (PID < 0) throw "Error waiting for child to exit!";

  // Ok, there is a slight race condition here.  It's possible that we will find
  // out that the file descriptor closed before waitpid will indicate that the
  // process gracefully died.  If we don't know that the process gracefully
  // died, wait a bit and try again.  This is pretty nasty.
  if (PID == 0) {
    usleep(10000);   // Wait a bit.

    // Try again.
    Status = 0;
    do {
      PID = waitpid(ChildPID, &Status, WNOHANG);
    } while (PID < 0 && errno == EINTR);
    if (PID < 0) throw "Error waiting for child to exit!";
  }

  // If the child process was already dead, then indicate that the process
  // terminated on its own.
  if (PID) {
    assert(PID == ChildPID && "Didn't reap child?");
    ChildPID = 0;            // Child has been reaped
    if (WIFEXITED(Status))
      throw InferiorProcessDead(WEXITSTATUS(Status));
    else if (WIFSIGNALED(Status))
      throw InferiorProcessDead(WTERMSIG(Status));
    throw InferiorProcessDead(-1);
  }
  
  // Otherwise, the child exists and has not yet been killed.
  if (kill(ChildPID, SIGKILL) < 0)
    throw "Error killing child process!";

  do {
    PID = waitpid(ChildPID, 0, 0);
  } while (PID < 0 && errno == EINTR);
  if (PID <= 0) throw "Error waiting for child to exit!";

  assert(PID == ChildPID && "Didn't reap child?");
}


/// waitForStop - This method waits for the child process to reach a stop
/// point.  When it does, it fills in the CurLocation member and returns.
void IP::waitForStop() {
  char Dummy;
  readFromChild(&Dummy, sizeof(char));
}


//===----------------------------------------------------------------------===//
//                             Child Process Code
//===----------------------------------------------------------------------===//

namespace {
  class SourceSubprogram;

  /// SourceRegion - Instances of this class represent the regions that are
  /// active in the program.
  class SourceRegion {
    /// Parent - A pointer to the region that encloses the current one.
    SourceRegion *Parent;

    /// CurSubprogram - The subprogram that contains this region.  This allows
    /// efficient stack traversals.
    SourceSubprogram *CurSubprogram;

    /// CurLine, CurCol, CurFile - The last location visited by this region.
    /// This is used for getting the source location of callers in stack frames.
    unsigned CurLine, CurCol;
    void *CurFileDesc;

    //std::vector<void*> ActiveObjects;
  public:
    SourceRegion(SourceRegion *p, SourceSubprogram *Subprogram = 0)
     : Parent(p), CurSubprogram(Subprogram ? Subprogram : p->getSubprogram()) {
      CurLine = 0; CurCol = 0;
      CurFileDesc = 0;
    }

    virtual ~SourceRegion() {}

    SourceRegion *getParent() const { return Parent; }
    SourceSubprogram *getSubprogram() const { return CurSubprogram; }

    void updateLocation(unsigned Line, unsigned Col, void *File) {
      CurLine = Line;
      CurCol = Col;
      CurFileDesc = File;
    }

    /// Return a LocationToken for the place that this stack frame stopped or
    /// called a sub-function.
    LocationToken getLocation(ExecutionEngine *EE) {
      LocationToken LT;
      LT.Line = CurLine;
      LT.Col = CurCol;
      const GlobalValue *GV = EE->getGlobalValueAtAddress(CurFileDesc);
      LT.File = dyn_cast_or_null<GlobalVariable>(GV);
      return LT;
    }
  };

  /// SourceSubprogram - This is a stack-frame that represents a source program.
  ///
  class SourceSubprogram : public SourceRegion {
    /// Desc - A pointer to the descriptor for the subprogram that this frame
    /// represents.
    void *Desc;
  public:
    SourceSubprogram(SourceRegion *P, void *desc)
      : SourceRegion(P, this), Desc(desc) {}
    void *getDescriptor() const { return Desc; }
  };


  /// Child class - This class contains all of the information and methods used
  /// by the child side of the debugger.  The single instance of this object is
  /// pointed to by the "TheChild" global variable.
  class Child {
    /// M - The module for the program currently being debugged.
    ///
    Module *M;

    /// EE - The execution engine that we are using to run the program.
    ///
    ExecutionEngine *EE;

    /// ReadFD, WriteFD - The file descriptor handles for this side of the
    /// debugger pipe.
    FDHandle ReadFD, WriteFD;

    /// RegionStack - A linked list of all of the regions dynamically active.
    ///
    SourceRegion *RegionStack;

    /// StopAtNextOpportunity - If this flag is set, the child process will stop
    /// and report to the debugger at the next possible chance it gets.
    volatile bool StopAtNextOpportunity;

    /// StopWhenSubprogramReturns - If this is non-null, the debugger requests
    /// that the program stops when the specified function frame is destroyed.
    SourceSubprogram *StopWhenSubprogramReturns;

    /// Breakpoints - This contains a list of active breakpoints and their IDs.
    ///
    std::vector<std::pair<unsigned, LocationToken> > Breakpoints;

    /// CurBreakpoint - The last assigned breakpoint.
    ///
    unsigned CurBreakpoint;

  public:
    Child(Module *m, ExecutionEngine *ee, FDHandle &Read, FDHandle &Write)
      : M(m), EE(ee), ReadFD(Read), WriteFD(Write),
        RegionStack(0), CurBreakpoint(0) {
      StopAtNextOpportunity = true;
      StopWhenSubprogramReturns = 0;
    }

    /// writeToParent - Send the specified buffer of data to the debugger
    /// process.
    ///
    void writeToParent(const void *Buffer, unsigned Size);

    /// readFromParent - Read the specified number of bytes from the parent.
    ///
    void readFromParent(void *Buffer, unsigned Size);

    /// childStopped - This method is called whenever the child has stopped
    /// execution due to a breakpoint, step command, interruption, or whatever.
    /// This stops the process, responds to any requests from the debugger, and
    /// when commanded to, can continue execution by returning.
    ///
    void childStopped();

    /// startSubprogram - This method creates a new region for the subroutine
    /// with the specified descriptor.
    ///
    void startSubprogram(void *FuncDesc);

    /// startRegion - This method initiates the creation of an anonymous region.
    ///
    void startRegion();

    /// endRegion - This method terminates the last active region.
    ///
    void endRegion();

    /// reachedLine - This method is automatically called by the program every
    /// time it executes an llvm.dbg.stoppoint intrinsic.  If the debugger wants
    /// us to stop here, we do so, otherwise we continue execution.
    ///
    void reachedLine(unsigned Line, unsigned Col, void *SourceDesc);
  };

  /// TheChild - The single instance of the Child class, which only gets created
  /// in the child process.
  Child *TheChild = 0;
} // end anonymous namespace


// writeToParent - Send the specified buffer of data to the debugger process.
void Child::writeToParent(const void *Buffer, unsigned Size) {
  while (Size) {
    ssize_t Amount = write(WriteFD, Buffer, Size);
    if (Amount < 0 && errno == EINTR) continue;
    if (Amount <= 0) {
      write(2, "ERROR: Connection to debugger lost!\n", 36);
      abort();
    } else {
      // We wrote a chunk.
      Buffer = (const char*)Buffer + Amount;
      Size -= Amount;
    }
  }
}

// readFromParent - Read the specified number of bytes from the parent.
void Child::readFromParent(void *Buffer, unsigned Size) {
  while (Size) {
    ssize_t Amount = read(ReadFD, Buffer, Size);
    if (Amount < 0 && errno == EINTR) continue;
    if (Amount <= 0) {
      write(2, "ERROR: Connection to debugger lost!\n", 36);
      abort();
    } else {
      // We read a chunk.
      Buffer = (char*)Buffer + Amount;
      Size -= Amount;
    }
  }
}

/// childStopped - This method is called whenever the child has stopped
/// execution due to a breakpoint, step command, interruption, or whatever.
/// This stops the process, responds to any requests from the debugger, and when
/// commanded to, can continue execution by returning.
///
void Child::childStopped() {
  // Since we stopped, notify the parent that we did so.
  char Token = 0;
  writeToParent(&Token, sizeof(char));

  StopAtNextOpportunity = false;
  StopWhenSubprogramReturns = 0;

  // Now that the debugger knows that we stopped, read commands from it and
  // respond to them appropriately.
  CommandID Command;
  while (1) {
    SourceRegion *Frame;
    const void *Result;
    readFromParent(&Command, sizeof(CommandID));

    switch (Command) {
    case StepProgram:
      // To step the program, just return.
      StopAtNextOpportunity = true;
      return;

    case FinishProgram:         // Run until exit from the specified function...
      readFromParent(&Frame, sizeof(Frame));
      // The user wants us to stop when the specified FUNCTION exits, not when
      // the specified REGION exits.
      StopWhenSubprogramReturns = Frame->getSubprogram();
      return;

    case ContProgram:
      // To continue, just return back to execution.
      return;

    case GetSubprogramDescriptor:
      readFromParent(&Frame, sizeof(Frame));
      Result =
        EE->getGlobalValueAtAddress(Frame->getSubprogram()->getDescriptor());
      writeToParent(&Result, sizeof(Result));
      break;

    case GetParentFrame:
      readFromParent(&Frame, sizeof(Frame));
      Result = Frame ? Frame->getSubprogram()->getParent() : RegionStack;
      writeToParent(&Result, sizeof(Result));
      break;

    case GetFrameLocation: {
      readFromParent(&Frame, sizeof(Frame));
      LocationToken LT = Frame->getLocation(EE);
      writeToParent(&LT, sizeof(LT));
      break;
    }
    case AddBreakpoint: {
      LocationToken Loc;
      readFromParent(&Loc, sizeof(Loc));
      // Convert the GlobalVariable pointer to the address it was emitted to.
      Loc.File = (GlobalVariable*)EE->getPointerToGlobal(Loc.File);
      unsigned ID = CurBreakpoint++;
      Breakpoints.push_back(std::make_pair(ID, Loc));
      writeToParent(&ID, sizeof(ID));
      break;
    }
    case RemoveBreakpoint: {
      unsigned ID = 0;
      readFromParent(&ID, sizeof(ID));
      for (unsigned i = 0, e = Breakpoints.size(); i != e; ++i)
        if (Breakpoints[i].first == ID) {
          Breakpoints.erase(Breakpoints.begin()+i);
          break;
        }
      break;
    }
    default:
      assert(0 && "Unknown command!");
    }
  }
}



/// startSubprogram - This method creates a new region for the subroutine
/// with the specified descriptor.
void Child::startSubprogram(void *SPDesc) {
  RegionStack = new SourceSubprogram(RegionStack, SPDesc);
}

/// startRegion - This method initiates the creation of an anonymous region.
///
void Child::startRegion() {
  RegionStack = new SourceRegion(RegionStack);
}

/// endRegion - This method terminates the last active region.
///
void Child::endRegion() {
  SourceRegion *R = RegionStack->getParent();

  // If the debugger wants us to stop when this frame is destroyed, do so.
  if (RegionStack == StopWhenSubprogramReturns) {
    StopAtNextOpportunity = true;
    StopWhenSubprogramReturns = 0;
  }

  delete RegionStack;
  RegionStack = R;
}




/// reachedLine - This method is automatically called by the program every time
/// it executes an llvm.dbg.stoppoint intrinsic.  If the debugger wants us to
/// stop here, we do so, otherwise we continue execution.  Note that the Data
/// pointer coming in is a pointer to the LLVM global variable that represents
/// the source file we are in.  We do not use the contents of the global
/// directly in the child, but we do use its address.
///
void Child::reachedLine(unsigned Line, unsigned Col, void *SourceDesc) {
  if (RegionStack)
    RegionStack->updateLocation(Line, Col, SourceDesc);

  // If we hit a breakpoint, stop the program.
  for (unsigned i = 0, e = Breakpoints.size(); i != e; ++i)
    if (Line       == Breakpoints[i].second.Line &&
        SourceDesc == (void*)Breakpoints[i].second.File &&
        Col        == Breakpoints[i].second.Col) {
      childStopped();
      return;
    }

  // If we are single stepping the program, make sure to stop it.
  if (StopAtNextOpportunity)
    childStopped();
}




//===----------------------------------------------------------------------===//
//                        Child class wrapper functions
//
// These functions are invoked directly by the program as it executes, in place
// of the debugging intrinsic functions that it contains.
//


/// llvm_debugger_stop - Every time the program reaches a new source line, it
/// will call back to this function.  If the debugger has a breakpoint or
/// otherwise wants us to stop on this line, we do so, and notify the debugger
/// over the pipe.
///
extern "C"
void *llvm_debugger_stop(void *Dummy, unsigned Line, unsigned Col,
                         void *SourceDescriptor) {
  TheChild->reachedLine(Line, Col, SourceDescriptor);
  return Dummy;
}


/// llvm_dbg_region_start - This function is invoked every time an anonymous
/// region of the source program is entered.
///
extern "C"
void *llvm_dbg_region_start(void *Dummy) {
  TheChild->startRegion();
  return Dummy;
}

/// llvm_dbg_subprogram - This function is invoked every time a source-language
/// subprogram has been entered.
///
extern "C"
void *llvm_dbg_subprogram(void *FuncDesc) {
  TheChild->startSubprogram(FuncDesc);
  return 0;
}

/// llvm_dbg_region_end - This function is invoked every time a source-language
/// region (started with llvm.dbg.region.start or llvm.dbg.func.start) is
/// terminated.
///
extern "C"
void llvm_dbg_region_end(void *Dummy) {
  TheChild->endRegion();
}




namespace {
  /// DebuggerIntrinsicLowering - This class implements a simple intrinsic
  /// lowering class that revectors debugging intrinsics to call actual
  /// functions (defined above), instead of being turned into noops.
  struct DebuggerIntrinsicLowering : public DefaultIntrinsicLowering {
    virtual void LowerIntrinsicCall(CallInst *CI) {
      Module *M = CI->getParent()->getParent()->getParent();
      switch (CI->getCalledFunction()->getIntrinsicID()) {
      case Intrinsic::dbg_stoppoint:
        // Turn call into a call to llvm_debugger_stop
        CI->setOperand(0, M->getOrInsertFunction("llvm_debugger_stop",
                                  CI->getCalledFunction()->getFunctionType()));
        break;
      case Intrinsic::dbg_region_start:
        // Turn call into a call to llvm_dbg_region_start
        CI->setOperand(0, M->getOrInsertFunction("llvm_dbg_region_start",
                                  CI->getCalledFunction()->getFunctionType()));
        break;

      case Intrinsic::dbg_region_end:
        // Turn call into a call to llvm_dbg_region_end
        CI->setOperand(0, M->getOrInsertFunction("llvm_dbg_region_end",
                                  CI->getCalledFunction()->getFunctionType()));
        break;
      case Intrinsic::dbg_func_start:
        // Turn call into a call to llvm_dbg_subprogram
        CI->setOperand(0, M->getOrInsertFunction("llvm_dbg_subprogram",
                                  CI->getCalledFunction()->getFunctionType()));
        break;
      default:
        DefaultIntrinsicLowering::LowerIntrinsicCall(CI);
        break;
      }
    }
  };
} // end anonymous namespace


static void runChild(Module *M, const std::vector<std::string> &Arguments,
                     const char * const *envp,
                     FDHandle ReadFD, FDHandle WriteFD) {

  // Create an execution engine that uses our custom intrinsic lowering object
  // to revector debugging intrinsic functions into actual functions defined
  // above.
  ExecutionEngine *EE =
    ExecutionEngine::create(new ExistingModuleProvider(M), false,
                            new DebuggerIntrinsicLowering());
  assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?");
  
  // Call the main function from M as if its signature were:
  //   int main (int argc, char **argv, const char **envp)
  // using the contents of Args to determine argc & argv, and the contents of
  // EnvVars to determine envp.
  //
  Function *Fn = M->getMainFunction();
  if (!Fn) exit(1);

  // Create the child class instance which will be used by the debugger
  // callbacks to keep track of the current state of the process.
  assert(TheChild == 0 && "A child process has already been created??");
  TheChild = new Child(M, EE, ReadFD, WriteFD);

  // Run main...
  int Result = EE->runFunctionAsMain(Fn, Arguments, envp);

  // If the program didn't explicitly call exit, call exit now, for the program.
  // This ensures that any atexit handlers get called correctly.
  Function *Exit = M->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, 0);

  std::vector<GenericValue> Args;
  GenericValue ResultGV;
  ResultGV.IntVal = Result;
  Args.push_back(ResultGV);
  EE->runFunction(Exit, Args);
  abort();
}
