🎉 We're happy to announce new public releases 🎉

  • TriCore v6.3r1 Inspector - v1.0r9 - A family of tools that provide an automated method for identifying toolset issues in compiled output code
  • VX-toolset for RH850 - v5.0r1 - Industry’s First End-to-End Compile, Debug and Test Toolchain for Renesas RH850 Microcontrollers
  • VX-toolset for TriCore - v6.4r1 - Software development environment of certified compiler toolsets for Infineon AURIX TC2xx/TC3xx microcontrollers
Contact us to get access

Linker Error E121 caused by mixed near and far addressing

15-Jul-2026

Applies to

  • TriCore VX-toolset
  • SmartCode


Symptoms

ltc E121: relocation error in "task1": relocation value 0xd0005000, type abs18 space, offset 0x2, section ".text.file_2.func" at 
address 0x8000036c is not a valid address in R_TRICORE_18ABS. Hint: check the mapfile for a section that occupies this address.

Another variant:

ltc E121: relocation error in "task1": relocation value 0xd0005000, type R_TRICORE_16SM, offset 0x0, section ".text.file_2.func" at 
address 0x8000036c is not within a 16-bit signed range from the value of A0 as defined by the symbol _SMALL_DATA_


Causes

Mixed near and far addressing

In the TriCore CPU, near-addressable data must be located within the first 16 kB of a 256 MB segment (offset 0x0 to 0x00003FFF within a segment). 
The E121 error occurs when a variable is defined as a far-addressable variable, but an extern declaration is made for a near-addressable variable instead. Then the linker may place the variable anywhere in memory. In the C modules where the variable is declared extern, a near access is made, which requires that the variable be placed within the first 16 kB.

Example:

/* file_1.c */
void func(void);
__far char var_1 __at(0xD0005000); /* __at is used to ensure the variable is placed outside of the near addressable range */
int main (void)
{
func();
return 0;
}
/* file_2.c */
extern __near char var_1; /* __near is used, while it should have been __far */
void func(void)
{
var_1 = 10;
}

Invocation:
cctc file_1.c file_2.c -o result.elf -t -v -s

Generated linker error:

ltc E121: relocation error in "task1": relocation value 0xd0005000, type abs18 space, offset 0x2, section ".text.file_2.func" at 
address 0x8000036c is not a valid address in R_TRICORE_18ABS. Hint: check the mapfile for a section that occupies this address.


Different values used for the compiler option -N

Although the error in the example above is obvious, the problem can also be hidden. This applies when different default-near-size options are used (C compiler option -N). This option is used to specify the maximum size of a data object for automatic near allocation. The default value is 8, which means that all data with a size smaller than or equal to 8 bytes is near-addressed and, as a result, must be located in a near-addressable memory range.

The problematic situation shows up when the C source file wherein the variable is defined is, for example, compiled using the option -N0. This forces the compiler to access all data that is not explicitly defined/declared using a __near qualifier using a far addressing mode. When the C source files, which include the 'extern' declarations for that variable, are compiled using the option -N8 (or the option is not used at all, which is equal to using -N8), then the access to the variable will be a near access. 

Modified example:

/* file_1.c */
void func(void);
char var_1 __at(0xD0005000); /* __at is used to ensure the variable is placed
outside of the near addressable range */
int main (void)
{
func();
return 0;
}
/* file_2.c */
extern char var_1;
void func(void)
{
var_1 = 10;
}

Invocation:
cctc file_1.c -o file_1.o -N0 -t -v -s -co
cctc file_2.c file_1.o -o result.elf -N8 -t -v -s

Here __near and __far are not used in the source code, but the problem is the same due to the different default near size values used with the -N option.


When using A0, A1, A8 or A9 addressing

This kind of E121 error can also show up when, instead of a near/far address mixture, a different, non-far address method like A0, A1, A8, or A9 addressing is used. Using the address register, indexed access requires the data to be located within +/- 32 kB of the address the address register points to. For example, when the A0 register content is 0xD0018000, then the address range where all A0-addressed variables must be placed in is 0xD0010000 to 0xD001FFFF. When an A0 access is made to a variable placed outside of the range, the linker error E121 is generated:

ltc E121: relocation error in "task1": relocation value 0xd0005000, type R_TRICORE_16SM, offset 0x0, section ".text.file_2.func" at 
address 0x8000036c is not within a 16-bit signed range from the value of A0 as defined by the symbol _SMALL_DATA_

The linker will ensure a correct placement of the address register accessed variables within the 64kB range, if the __aX (__a0, __a1, __a8, __a9) memory qualifier is used for the variable definition as well as the extern declaration.


Possible solutions


Ensure consistent addressing qualifiers

Match __near, __far and __aX between:

  • Variable definition
  • All extern declarations


Use consistent compiler -N options

Compile all modules with the same -N value, and avoid mixing:

  • -N0 (forces far)
  • -N8 (default near behavior)


Override addressing locally using pragma

It is possible to overrule the -N option locally using a pragma. E.g.:

#pragma for_extern_data_use_memory __far

Then all extern declared variables following that pragma will be far accessed, independent of the -N value used.


Expected Result

After applying one of the solutions, the E121 relocation error disappears.


Verify

1. Rebuild the project.

2. Confirm the E121 linker error is no longer reported.


More resources

Was this answer helpful?