Sharc 21065L: Moving c-run-time library to external memory

From DSignT Support Database
Jump to: navigation, search

1 Problem

When library libc.dlb is linked into external memory, strange effects occur depending on where code is linked and how many code is linked. E.g:

  1. many printf() are executed right, but one printf() lacks some data
  2. code is not executed
  3. malloc() returns out of memory, although heap is large enough
  4. in single step mode the PC does not return from subroutine and walks through the next function
  5. different behaviour when code parts are commented out


2 Explanation

C-Runtime library module seg_init_rtheap.asm defines a heap info structure located in .segment/pm seg_pmco;:


    .segment/pm seg_pmco;

    /* The maximum number of multiple heaps that can be setup at run-time. */
    #define MAXHEAPS 4

    /* The structure in memory. Matched heap_descriptions for backwards compatibility.
    typedef struct {
      char *seg_;
      char *heap;
      unsigned long userid;
      char *base;
      size_t length;
    } heapinfo;
     */

    .global __heaps;
    .var __heaps[5 * MAXHEAPS];
    .__heaps.end:
    
    .global __nheaps;
    .var __nheaps = 0;
    .__nheaps.end:

    .endseg;


The heap CRT initialization function ___lib_init_heaps() tries to initialize this heapinfo structure by modifying the program memory (self modifying code??). Unfortunately when accessing external program code the address is one half of the address of accessing the same in data memory (only the lower 16bits are affected). In the example below instruction pm(i12,m14)=px accesses address 0x20360 instead of 0x206c0:

SharcCrtlibExtern2.png


When linked to external memory CRT-Function ___lib_init_heaps overwrites code randomly, depending on what was linked before heapinfo structure. In the example above the code at address 0x20360 is overwritten with nops:

external memory before ___lib_init_heaps external memory after ___lib_init_heaps
SharcCrtlibExtern1.png SharcCrtlibExtern3.png


3 Solution

Always link CRT module seg_init_rtheap.doj into internal memory. Fragment from linker description file d21065.ldf:

  MEMORY
  {
    ...
    seg_pmco { TYPE(PM RAM) START(0x000081c0) END(0x000097ff) WIDTH(48) }
    ...
  }
  PROCESSOR p0
  {
    LINK_AGAINST( $COMMAND_LINE_LINK_AGAINST)
    OUTPUT( $COMMAND_LINE_OUTPUT_FILE )

    SECTIONS
    {
      ...
      int_heap_code   // RTS heap initialization code must be linked internally
      {
          INPUT_SECTIONS( libc.dlb [ seg_init_rtheap.doj (seg_pmco) ])
      } > seg_pmco
      ...

      external_code
      {
      ...

4 Additional Tags

VDSP, CRT, c run-time



Contact Post.png Support Tool.png