gdb: Bootstrapping

 
 20.5.2 What You Must Do for the Stub
 ------------------------------------
 
 The debugging stubs that come with GDB are set up for a particular chip
 architecture, but they have no information about the rest of your
 debugging target machine.
 
    First of all you need to tell the stub how to communicate with the
 serial port.
 
 'int getDebugChar()'
      Write this subroutine to read a single character from the serial
      port.  It may be identical to 'getchar' for your target system; a
      different name is used to allow you to distinguish the two if you
      wish.
 
 'void putDebugChar(int)'
      Write this subroutine to write a single character to the serial
      port.  It may be identical to 'putchar' for your target system; a
      different name is used to allow you to distinguish the two if you
      wish.
 
    If you want GDB to be able to stop your program while it is running,
 you need to use an interrupt-driven serial driver, and arrange for it to
 stop when it receives a '^C' ('\003', the control-C character).  That is
 the character which GDB uses to tell the remote system to stop.
 
    Getting the debugging target to return the proper status to GDB
 probably requires changes to the standard stub; one quick and dirty way
 is to just execute a breakpoint instruction (the "dirty" part is that
 GDB reports a 'SIGTRAP' instead of a 'SIGINT').
 
    Other routines you need to supply are:
 
 'void exceptionHandler (int EXCEPTION_NUMBER, void *EXCEPTION_ADDRESS)'
      Write this function to install EXCEPTION_ADDRESS in the exception
      handling tables.  You need to do this because the stub does not
      have any way of knowing what the exception handling tables on your
      target system are like (for example, the processor's table might be
      in ROM, containing entries which point to a table in RAM).  The
      EXCEPTION_NUMBER specifies the exception which should be changed;
      its meaning is architecture-dependent (for example, different
      numbers might represent divide by zero, misaligned access, etc).
      When this exception occurs, control should be transferred directly
      to EXCEPTION_ADDRESS, and the processor state (stack, registers,
      and so on) should be just as it is when a processor exception
      occurs.  So if you want to use a jump instruction to reach
      EXCEPTION_ADDRESS, it should be a simple jump, not a jump to
      subroutine.
 
      For the 386, EXCEPTION_ADDRESS should be installed as an interrupt
      gate so that interrupts are masked while the handler runs.  The
      gate should be at privilege level 0 (the most privileged level).
      The SPARC and 68k stubs are able to mask interrupts themselves
      without help from 'exceptionHandler'.
 
 'void flush_i_cache()'
      On SPARC and SPARCLITE only, write this subroutine to flush the
      instruction cache, if any, on your target machine.  If there is no
      instruction cache, this subroutine may be a no-op.
 
      On target machines that have instruction caches, GDB requires this
      function to make certain that the state of your program is stable.
 
 You must also make sure this library routine is available:
 
 'void *memset(void *, int, int)'
      This is the standard library function 'memset' that sets an area of
      memory to a known value.  If you have one of the free versions of
      'libc.a', 'memset' can be found there; otherwise, you must either
      obtain it from your hardware manufacturer, or write your own.
 
    If you do not use the GNU C compiler, you may need other standard
 library subroutines as well; this varies from one stub to another, but
 in general the stubs are likely to use any of the common library
 subroutines which 'GCC' generates as inline code.