The VDSP linker utility is invoked as linker while the GNU linker is invoked as ld.
Here is a comparison of the command line options:
| VDSP | GNU | Description |
|---|---|---|
@filename | same | Read additional options from file |
-e | GC | Eliminate unused symbols |
-ek <section> | GC | Filter section from symbol elimination |
-entry <sym> | --entry <sym> | Set the entry point |
-es <section> | GC | Eliminate unused symbols from specified section |
-ev | GC | Verbosely eliminate unused symbols |
-flags-meminit | N/A | Pass options to memory initializer utility |
-flags-pp | CPP | Pass options to the preprocessor |
-h | same | Display utility help |
-i <path> | CPP | Add path to include search |
-I <path> | CPP | Add path to include search |
-ip | N/A | Fill in fragmented holes with free objects |
-jcs21 | (1) | Convert out-of-range jumps to usable variant |
-keep <sym> | GC | Keep unused symbol |
-L <path> | same | Add path to library search |
-M | (2) | Output dependency info for make |
-Map <file> | same | Output map to file 1) |
-MDmacro=def | CPP | Define a macro |
-MM | (2) | Output dependency info for make and then do link |
-MUDmacro | CPP | Undefine a macro |
-meminit | N/A | Run the memory initializer utility |
-nomemcheck | N/A | Turn off memory checking |
-o <output> | same | Select output file |
-od <dir> | N/A | Control output directory for LDF file |
-pp | CPP | Stop after preprocessing |
-proc <proc> | (3) | Select processor |
-reserve-null | N/A | Reserve 4 bytes at address 0 |
-s | same | Strip all symbols |
-S | same | Strip debug symbols |
-save-temps | (4) | Save temporary files |
-si-revision | (3) | Select processor silicon revision |
-sp | CPP | Skip preprocessing |
-T <ldf> | same | Select linker script |
-t | N/A | Enable short file trace output |
-tx | -t | Enable full path file trace output |
-v | --verbose | Perform linking steps verbosely |
-version | --version | Output version information |
-warnonce | --warn-once | Warn only once per undefined symbol |
-Wnumber | N/A | Control warnings |
-Wwarn | N/A | Control warnings |
-xref | N/A | Output an XML cross reference file |
-M and related options to get automatic make dependency information.-save-temps option.
The main documentation for the GNU linker script format can be found here:
http://sourceware.org/binutils/docs/ld/Scripts.html
| VDSP | GNU | Description |
|---|---|---|
ABSOLUTE(exp) | same | Return absolute value of expression |
ADDR(section) | same | Return start address of section |
DEFINED(symbol) | same | Return 1 if symbol is defined |
MEMORY_END(segment) | N/A | Return end address of segment (start + sizeof) |
MEMORY_SIZEOF(segment) | LENGTH(memory) | Return size (in bytes) of segment |
MEMORY_START(segment) | ORIGIN(memory) | Return start address of segment |
SIZEOF(section) | same | Return size (in bytes) of segment |
. | same | The location counter |
| VDSP | GNU | Description |
|---|---|---|
ALIGN(num) | same | Align by number |
ARCHITECTURE(proc) | (4) | Specify output processor |
COMMON_MEMORY{} | (1) | Declare memory common for multicore systems |
ELIMINATE() | GC | Eliminate unused symbols |
ELIMINATE_SECTIONS() | GC | Eliminate unused symbols from specified section |
ENTRY(symbol) | same | Set executable entry point |
FILL(num) | same | Fill holes with number |
FORCE_CONTIGUITY | N/A | Force contiguous output |
INCLUDE(file) | INCLUDE file | Include the linker script file |
INPUT_SECTION_ALIGN(num) | ALIGN(num) | Align input by num |
INPUT_SECTIONS() | (3) | Map an input file to multiple outputs |
KEEP() | same | Do not eliminate the unused symbols/sections |
KEEP_SECTIONS(sections) | GC | Do not do elimination in the sections |
LINK_AGAINST(file) | N/A | Use file to resolve symbols |
MAP(file) | N/A | Output an XML map file |
MEMORYP{} | same | Define memory regions for output |
MPMEMORY{} | (1) | Declare core-specific memory for multicore systems |
NOFORCE_CONTIGUITY | N/A | Do not warn about discontiguous memory output |
OVERLAY_INPUT{} | OVERLAY{} | Create an overlay |
PACKING() | N/A | Output memory in a different byte order |
PLIT{} | N/A | Create a procedure linkage table for overlays |
PROCESSOR{} | CPP | Run commands only for certain processors |
RESERVE() | (2) | Reserve space for a symbol |
RESERVE_EXPAND() | (2) | Reserve unused space for a symbol |
RESOLVE(sym, addr) | sym = addr | Define a symbol and its address |
SEARCH_DIR(paths) | same | Add paths to the input search list |
SECTIONS{} | same | Define output sections |
SHARED_MEMORY{} | (1) | Declare shared memory for multicore systems |
MEMORY{} and then output objects to the appropriate places using SECTIONS{}.ALIGN(), set the symbol with the location counter, then update the location counter.http://sourceware.org/binutils/docs/ld/MEMORY.html
The VDSP linker uses the term segment when referring to the ranges defined by the MEMORY{} command. The GNU linker describes them as memory regions as it uses segment for something else (which is used infrequently).
A VDSP LDF file takes the form:
MEMORY
{
segment_name: TYPE(...) START(...) LENGTH(...) END(...) WIDTH(...)
}
While the GNU LDS file takes the form:
MEMORY
{
name (attr): ORIGIN = ..., LENGTH = ...
}
| LDF | LDS | How to convert |
|---|---|---|
TYPE() | (attr) | Use the R attribute for read-only section |
START() | ORIGIN = | They're the same |
LENGTH() | LENGTH = | They're the same |
END() | N/A | Use LENGTH = instead |
WIDTH() | N/A | The GNU linker does not care about address widths and the VDSP option makes no sense -- it can only ever be one value for Blackfin systems |
http://sourceware.org/binutils/docs/ld/SECTIONS.html
A VDSP LDF file takes the form:
SECTIONS
{
section [type] [init] {
section_commands
} > memory
}
While the GNU LDS file takes the form:
SECTIONS
{
section [addr] [type] : [AT(addr)] [ALIGN(num)] {
section_commands
} [>memory] [AT>memory] [=fill]
}
TBD
TBD
http://sourceware.org/binutils/docs/ld/Overlay-Description.html
ALGORITHM ALL_FIT BEST_FIT FIRST_FIT NUMBER_OF_OVERLAYS OVERLAY_GROUP OVERLAY_ID OVERLAY_INPUT OVERLAY_OUTPUT
The VDSP linker supports elimination on a per-symbol and per-section basis. The GNU toolchain also supports this same functionality in the end, but it takes a completely different tact.
When compiling C code, the compiler flags -ffunction-sections and -fdata-sections instruct GCC to place every function and variable in its own dedicated section. These typically take the form of .text.function and .data.variable where function and variable get replaced with the actual symbol name.
Then when linking, the --gc-sections flag instructs the linker to discard all sections that are not referenced. If you want to prevent specific symbols from being discarded in your linker script, you can use the KEEP() command.
While VDSP supports preprocessing in the linker itself, the GNU toolchain does not. Instead, these steps are kept logically separate by design -- have one tool do one thing and one thing only, and have it do it well. As such, if you want to have a dynamic linker script (i.e. preprocess it), then you can first run it through the preprocessor before passing it to the linker. This is how many projects work such as Das U-Boot and the Linux kernel.
Typically you'll see rules like the following in the Makefile:
.... myscript.lds: myscript.lds.S $(CPP) $(CFLAGS) $(CPPFLAGS) $< > $@ .... myapp: myscript.lds $(LD) -Wl,-T,myscript.lds .... ....
This allows you to use all the normal CPP magic such as the -DDEFINE=value and -Ipath flags and the #if logic in the source itself. Since you have access to all the same defines as normal C code, you can do processor/silicon specific stuff by checking the normal ADSPBF### and related defines.
If the ported program is a library, you will need to link the library with your uClinux application. You may use Gnu Linker Scripts to direct the Gnu linker.
By default, the Linker uses Linker scripts defined in <bfin-uclinux-toolchain>/bfin-uclinux/lib/ldscripts/. when the ported library defines its sections, you may dump the scripts and define your section in the file:
For example, supposing the library defines “my_data_1” section and you want the linker copy this secions from all the source files to data section:
# Dump default linker script
./bfin-uclinux-ld --verbose > my_ld.x
# Modify my_ld.x, add in the .data{} definition:
SECTIONS
{
...
.data
{
*(.data .data.* .gnu.linkonce.d.*)
*(my_data_1) /* Add my data secton here */
}
}