Known bugs in GCC
-----------------

Inlining:

  There is a known bug in GCC when performing function inlining
  (-finline-functions or -O3) and the function that is being
  inlined uses a union containing an unsigned 64-bit type and
  two unsigned 32-bit types, ie a union like this:

    union
     {
       unsigned long long value;
       struct
         {
            unsigned long low;
            unsigned long high;
         } s;
     }

  Under these circumstances, if the values in the union are
  constants rather than variables then the function code
  inliner can mislead the constant expression evaluator
  inside the compiler so that it incorrectly collapses the
  constant expressions.

  Workarounds for this problem are to compile with the
  -fno-inline-functions switch, or to put the constants
  into variables, so that the compiler cannot try to
  simplify the expressions. 

Variable arguements:

  There is a known bug in GCC's handling of code which passes a
  variable sized array as an unnamed argument to a vararg function.
  ie code like this:

    extern void foo (int, ...);
    void bar (int len)
    {
      int array[len];
      foo (len, array);
    }

  In cases like this, gcc will compute the wrong stack address
  for the variadic argument when it is being handled inside foo().
  This means that foo() will see the wrong values for array[].

  The workaround is to not pass variable sized arrays to variadic
  functions.

Optimizer Bug:

    There is a bug in gcc that causes the optimizer to lose track of which
    registers need to be saved, which seems to occur when all of the
    following are true for a given function:

    * The user uses the "register" and "asm" keywords to assign a variable
      to the frame pointer ($a3).

    * The frame pointer is not used for anything else.

    * The function is compiled with -O3.

    * The frame pointer needs to be preserved due to that variable being
      possibly modified.

    In this case, gcc will not save $a3 on entry, but will attempt to
    restore it on exit, causing a stack inconsistency.

    The workaround is to use -O2 to compile these functions.

    So far, the only case we've found that presents this scenario is the
    syscall definitions.  Since they are only compiled as part of glibc,
    and we've changed the glibc spec to always use -O2, user applications
    should not normally see this problem.

Nested functions:

  The GCC compiler supports an extension to the C programming
  language in the form of nested functions.  These are
  functions which are defined inside other functions.  This
  can be useful for modular programming but they are very
  complicated to handle properly, especially when the code
  takes the address of a nested function.

  In order to support nested functions it is necessary for the
  compiler to create code which will place machine instructions
  on the execution stack.  When the nested function is accessed
  these instructions are used to jump to the correct place and
  then to correctly return to the caller once the nested
  function has finished.

  Unfortunately placing executable machine instructions on the
  stack does not always work when the target architecture uses
  an instruction cache and/or a data cache.  This is the case
  for the MN10300 and AM33, and so GCC's support for this
  (unofficial) language extension does not work. 


Debugging Shared Libraries on a Remote Target with GDB
------------------------------------------------------

Using GDB to debug programs which make use of shared libraries should
be largely automatic.  I.e, during the course of debugging, no user
intervention should normally be required to cause a shared library's
symbol table to be loaded and correctly relocated.  GDB will detect
when the remote target has loaded a new shared library and will
attempt to load a a copy of that library using a location (path) on the
host's filesystem.

Since the target's shared library machinery specifies paths which may
only make sense on the target, GDB needs a mechanism for translating
the target specific paths into paths which are usable on the host
(since it is from the host that GDB loads the symbols associated with
a shared library).  GDB has two variables that may be set to cause
this to happen.  These are:

    - solib-absolute-prefix
    - solib-search-path

The string associated with ``solib-absolute-prefix'' is prepended to
the target specific path to form a host-specific path.  So, e.g, if
``solib-absolute-prefix'' has been set to "/path/to/target-fs-root"
and GDB is attempting to load the symbols associated with
/lib/libc.so, prepending the value of ``solib-absolute-prefix'' yields
"/path/to/target-fs-root/lib/libc.so".  GDB uses this path on the
host system to (attempt to) load libc.so's symbols.

If GDB fails to load the shared library's symbols by prepending
``solib-absolute-prefix'', it will strip off the directory specific
components from the path (yielding the shared library's basename)
and then prepend each of the paths found in the colon-separated
``solib-search-patch'' variable, stopping on the first one that it
successfully opens.

``solib-absolute-prefix'' is normally used in conjunction with "system"
libraries such as those found in /lib, /usr/lib, and other "standard"
locations for libraries.  If the shared library machinery communicates
an absolute path for a library to GDB, it is usually best to have a
directory on the host which is populated with the libraries found on
the target, taking care to preserve the directory structure associated
with those libraries.  E.g, suppose you had the following three libraries
on the target:

	/lib/libc.so
	/usr/lib/libdb.so
	/usr/local/lib/libmp3lame.so

Then, on the host, you might have the following isomorphic structure:

	/path/to/target-fs-root/lib/libc.so
	/path/to/target-fs-root/usr/lib/libdb.so
	/path/to/target-fs-root/usr/local/lib/libmp3lame.so

In GDB (or in a .gdbinit file), you'd do:

    set solib-absolute-prefix /path/to/target-fs-root

``solib-relative-path'' is normally used to locate application specific
libraries whose paths are specified to GDB as relative paths.

It is critical that the libraries on the target are kept in sync
with those on the host.  If there's a mismatch, i.e, if the
target contains a newer version of a library than the host, or
vice versa, then strange errors may occur.  E.g, it's possible
to see an illegal instruction exception, segmentation fault, or
other memory related fault on the target due to a breakpoint being
placed at incorrect locations.  The debugging of multi-threaded
programs almost always requires that the shared library machinery
is working correctly, so if you're having trouble debugging a
multi-threaded program, a good place to start diagnosing the problem
is to make sure that ``solib-absolute-prefix'' and
``solib-absolute-path'' are set correctly and that the contents of the
libraries on the target match the contents of the corresponding
host-located libraries exactly.


Known Bugs in Multithread Debugging
-----------------------------------

Debugging of multithreaded programs using RDA can be slow at times. 
Running the following GDB command will avoid remote protocol timeouts
on some operations:

    set remotetimeout 60

The value provided to remotetimeout may be increased or decreased as
desired.

Debugging with debuginfo files
------------------------------
GDB will automatically use separate debug files under either of the following
circumstances:

  1.  The debug files are placed in the same directory as the libraries
      to be debugged.

  2.  The debug files are in a subdirectory, named .debug, of the directory
      containing the libraries.

