Search code examples
linkerstatic-linkingvxworkslinker-scripts

(vxworks) In the binary produced using this linker script, why doesn't the first address encountered start at the text segment start address?


I have a project I'm working on in vxWorks, constructing a vxsim binary for testing. There's three stages to the link process; the relevant portions of the makefile look roughly like the following:

partialImage.o: ${SYSTEM_OBJS} ${OBJS} version.o
    ldsparc ${appropriate LDFLAGS go here} ${^} -o ${@}

# Don't ask me why they did it this way; it seems redundant to re-use
# all the other objects as well as partialImage.o, but I'm also not extremely
# versed in what's necessary for munch.tcl to do its thing.
ctdt.o: partialImage.o ${SYSTEM_OBJS} ${OBJS} version.o
    ${VXSIMNM} ${^} | tclsh ${path to munch.tcl} > ${@:%.o=%.c}
    ccsparc ${appropriate CFLAGS go here} ${@:%.o=%.c} -o ${@}

${FINAL_IMAGE}: ${a list of dependencies here}
    ldsparc -N -e _sysInit -Ttext 60010000 \
      ${appropriately ordered list of objects} \
      -defsym _VX_DATA_ALIGN=16 \
      -T link.RAM \
      -o ${@}

If more information is necessary (flags & the like) let me know. I'm not at that computer at the moment, but in about an hour I'll update this question with further details if no answer is forthcoming by that time.

The following is a rough sketch of the linker script. If you have access to vxWorks 6.x, it's just the default 'link.RAM' script:

START(_sysInit)
SECTIONS {
  .text {
    wrs_kernel_text_start = .;
    /* A few other variable declarations and inclusions from various other segments */
    . = ALIGN(16);
  }
. = ALIGN(16);
/* The rest of the linker script */
}

Take note of the fact that wrs_kernel_text_start occurs at the beginning of the text segment before anything is included and before any ALIGN statements.

In other vxWorks projects I've done, wrs_kernel_text_start = 0x60010000; however, on this particular project it's some other address roughly on par with 0x6025XXXX. You're not reading that wrong, the address is 1 order of magnitude higher than the address I expect -- that is, it isn't 0x60025XXX. _sysInit starts right at 0x60010000 as I expect.


Solution

  • I was going to delete the question, but I suppose someone out there might get some value from the answer. The makefile ACTUALLY looked like this:

    outfile: ${SYSTEM_OBJS} ${OBJS} version.o link.RAM
        ldsparc ${appropriate LDFLAGS go here} ${^} -o ${@}
    (...)
    

    Note that the linker script was in the dependency list, and I was including it with ${^} as one of the input files. When I removed the linker script from the dependency list, everything looks normal now.