This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Dynamic libs (--linux, --pic) and linker command files



Hi All,

I am creating a dynamic library with options --linux, --pic=far --dbst. While compiling if i add a linker command file along with the build the elf file generated is not a valid one. it has the following errors

  • One of the program headers PT_LOAD has memory size  as 0 and file size as non-zero number
  • The dynamic symbol table offset (DT_SYMTAB) present in the dynamic header is set to 0
  • The values of the offset in the section headers though are the correct ones.

All of these errors goes away as soon as i exclude the linker.cmd file from the build. The 2 generated elf files are compared using ofd6x.exe, there is a lot of difference between them including the program headers. The elf file generated without linker.cmd has the PT_INTERP & PT_PHDR sections which is missing in the elf file generated with the linker.cmd. I have attached the main.c that i am trying to compile along with the linker.cmd.

#include <stdio.h>

__declspec(dllexport) int AnalyticsProcess (int* , void* b);
__declspec(dllexport) int AnalyticsCreate (int**, void* );
__declspec(dllexport) int AnalyticsDestruct(void*);
__declspec(dllexport) int AnalyticsControl (void*, int, void*);


int AnalyticsProcess(int* handle, void* buffer)
{
	printf("In AnalyticsProcess \n ");
	return 0;
}

int AnalyticsCreate(int** handle, void* param)
{
	printf("In AnalyticsCreate \n ");
	return 0;
}

int AnalyticsDestruct(void* handle)
{
	printf("In AnalyticsDestruct \n ");
	return 0;
}

int AnalyticsControl(void* handle, int cmd_id, void* buf)
{
	printf("In AnalyticsControl \n ");
	return 0;
}
MEMORY
{

    HDVICP:       o = 0x00400000  l = 0x00040000  // 256kB HDVICP SL2
    DSPL2RAM:     o = 0x00800000  l = 0x00040000  // 256kB DSP L2 RAM
    DSPL1PRAM:    o = 0x00E00000  l = 0x00008000  // 32kB DSP L1 Program RAM
    DSPL1DRAM:    o = 0x00F00000  l = 0x00008000  // 32kB DSP L1 Data RAM
    DDR3:         o = 0x85000000  l = 0x04000000  // 64MB DDR3

}


SECTIONS
{
  GROUP
    {
		.dsbt
		.got
		.neardata
    }>DSPL2RAM
}


/*
SECTIONS
{
    .text          >  DSPL2RAM
    .stack         >  DSPL2RAM
    //.bss         >  DSPL2RAM
    .cio           >  DSPL2RAM
    .const         >  DSPL2RAM
    .data          >  DSPL2RAM
    .switch        >  DSPL2RAM
    .sysmem        >  DDR3
    .far           >  DSPL2RAM
    .args          >  DSPL2RAM
    .ppinfo        >  DSPL2RAM
    .ppdata        >  DSPL2RAM
    .heap          >  DDR3

  GROUP
    {
            .dsbt
            .got
//            .bss
            .neardata
//            .rodata
    }>DSPL2RAM


    // TI-ABI or COFF sections
    .pinit         >  DSPL2RAM
    .cinit         >  DSPL2RAM

    // EABI sections
    .binit         >  DSPL2RAM
    .init_array    >  DSPL2RAM
    //.neardata    >  DSPL2RAM
    .fardata       >  DSPL2RAM
    //.rodata      >  DSPL2RAM
    .c6xabi.exidx  >  DSPL2RAM
    .c6xabi.extab  >  DSPL2RAM
    .plt           >  DSPL2RAM

}
*/

command lines options are

"C:/Tools/TI/ccsv5/tools/compiler/c6000_7.4.4/bin/cl6x" -mv6740 --abi=eabi -g --dsbt --pic=far --linux -z -i"C
:/Tools/TI/ccsv5/tools/compiler/c6000_7.4.4/lib" -i"C:/Tools/TI/ccsv5/tools/compiler/c6000_7.4.4/include" --export=AnalyticsProcess --export=AnalyticsCreate --export=AnalyticsControl --export=AnalyticsDestruct --bind_now --dynamic=lib -o "DynamicLib.dll"  "./main.obj" "../linker.cmd"

Can anyone shed some light on why the linker.cmd file is causing the compiler to generate such different elf files ? Please note I need the linker cmd file for grouping various DATA_SECTIONS present in the code. I am on 8127 and with complier version 7.4.4

Regards

Krishna

  • Krishna,

    The Linux dynamic linking model assumes complete control over the creation of segments as the Linux ABI requires that all read/write sections be combined into a single segment. This preserves position independence of read/write data as the offset between the static base (what the DP will be set to when executing code in the current module) and the definition of the data being referenced will remain consistent. If a user specifies a linker command file, the linker assumes all bets are off with regards to a contiguous read/write segment.

    Regards,

    Todd Snider

    C6000 Code Generation Tools

    Texas Instruments Incorporated

  • Hi Todd,

    Thanks Todd, In a case where I passed the linker command file that just groups dbst, got and neardata,  the tags in the the dynamic section is all wrong. I understand that the placement will be different. DT_SYMTAB is marked as zero. DT_STRTAB has a non zero value but not the same as in the 'dynstr' section header. 
    Also the program header that contains PT_DYNAMIC has memsz = 0, I am not sure how to interpret the same. I SYSV standards says that memsz can be 0 but I am not sure if this is the expected behavior.

    Are the 3 mentioned above an expected behavior in case a linker cmd file is passed.

    Also if i just pass a linker cmd file that just has section grouping of my algorithm DATA and CODE sections along with the memory regions the linker gives an error that ."fatal error: the section ".dsbt" should be allocated to memory explicitly in the linker command file". So this leaves me no option but to group all EABI sections.

    Regards

    Krishna

  • Hi Krishna,

    There should be no need to specify a linker command file under the Linux Dynamic Linking model. The static linker will group all read-only / execute sections into a read-only PT_LOAD segment and it will group all read/write sections into a read/write PT_LOAD segment. The static linker will place sections that use static-base-relative addressing (DP-relative, for example) near the front of the read/write segment so that they are within range of the static base for the dynamic module. The .dsbt section will also be grouped into the read/write PT_LOAD segment and should be accessible via static base relative addressing.

    For example, consider this ofd6x -v output of a simple Linux output file:

     Program Segment Table

        <0>
           Segment Type:  PT_PHDR     File Offset:   0x00000034
           Run Address:   0x00000034  Load Address:  0x00000034
           File Size:     0xc0        Memory Size:   0xc0
           Flags:         r--         Alignment:     0

        <1>
           Segment Type:  PT_LOAD     File Offset:   0x00000000
           Run Address:   0x00000000  Load Address:  0x00000000
           File Size:     0x9760      Memory Size:   0x9760
           Flags:         r-x         Alignment:     4096
                                      Contains:      Elf File Header
                                      Contains:      Segment 0 (PT_PHDR)
                                      Contains:      Segment 5 (PT_INTERP)
                                      Contains:      Section 1 (.rela.dyn)
                                      Contains:      Section 4 (.text)
                                      Contains:      Section 6 (.const)
                                      Contains:      Section 19 (.plt)
                                      Contains:      Section 23 (.dynsym)
                                      Contains:      Section 25 (.dynstr)
                                      Contains:      Section 26 (.hash)

        <2>
           Segment Type:  PT_LOAD     File Offset:   0x0000a000
           Run Address:   0x08000000  Load Address:  0x08000000
           File Size:     0x4f8       Memory Size:   0x768
           Flags:         rw-         Alignment:     4096
                                      Contains:      Segment 4 (PT_DYNAMIC)
                                      Contains:      Section 5 (.neardata)
                                      Contains:      Section 14 (.fardata)
                                      Contains:      Section 15 (.cio)
                                      Contains:      Section 16 (.sysmem)
                                      Contains:      Section 17 (.far:.common)
                                      Contains:      Section 18 (.dsbt)
                                      Contains:      Section 20 (.got)

        <3>
           Segment Type:  PT_GNU_STACK  File Offset:   0x00000000
           Run Address:   0x00000000    Load Address:  0x00000000
           File Size:     0x0           Memory Size:   0x20000
           Flags:         rwx           Alignment:     16

        <4>
           Segment Type:  PT_DYNAMIC  File Offset:   0x0000a118
           Run Address:   0x08000118  Load Address:  0x08000118
           File Size:     0xb8        Memory Size:   0x0
           Flags:         rw-         Alignment:     0
                                      Contains:      Section 24 (.dynamic)

        <5>
           Segment Type:  PT_INTERP   File Offset:   0x000000f4
           Run Address:   0x000000f4  Load Address:  0x000000f4
           File Size:     0x14        Memory Size:   0x0
           Flags:         r--         Alignment:     0
                                      Contains:      Section 3 (.interp)

    The PT_DYNAMIC segment contains the dynamic information from the .dynamic section:

     Dynamic Information in ".dynamic"

        id tag                 value    
        -- ---                 -----    
         0 DT_PLTRELSZ         0        
         1 DT_PLTGOT           0x08000108
         2 DT_HASH             0x00000b30
         3 DT_STRTAB           0x00000728
         4 DT_SYMTAB           0x00000108
         5 DT_RELA             0x00000e54
         6 DT_RELASZ           192      
         7 DT_RELAENT          12       
         8 DT_STRSZ            1031     
         9 DT_SYMENT           16
        10 DT_SONAME           hello.out
        11 DT_PLTREL           7        
        12 DT_JMPREL           0x00000f14
        13 DT_FLAGS            0        
        14 DT_C6000_DSBT_BASE  0x08000000
        15 DT_C6000_DSBT_SIZE  64       
        16 DT_C6000_DSBT_INDEX 0
        17 DT_NULL
        18 DT_NULL                      
        19 DT_NULL                      
        20 DT_NULL
        21 DT_NULL
        22 DT_NULL

    Its memsz is 0 because it does not occupy any target memory when the module is dynamically loaded.

    It is the dynamic loader that is reponsible for:

    - allocating target memory for the placement of the code and data in the PT_LOAD segments (the core part of the RIDL understands the details of the program header table in the ELF file and can help retrieve details that are needed by the client side of the dynamic loader).

    - resolving the value of all symbols defined in the module being loaded and adding those symbols to the dynamic loader's internal symbol table

    - resolving references to symbols that are not defined in the module that is currently being loaded (resolving dynamic relocations)

    Hope this helps.

    Regards,

    Todd Snider

    C6000 Code Generation Tools Team

    Texas Instruments Incorporated