//===-- 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,
                                          (Type *)0);

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