EmbeddedRelated.com
Forums

Is their a position independant code library (CLIB) for use with IAR compiler?

Started by jamie_risk March 28, 2006
The proclaimed "position indepenant code" option for the IAR
compiler 
doesn't appear to be supported by their own libraries.

The compiler generates PIC to correctly call functions, but loading
addresses to constant data is done with abosolute addressing.  

I can't use the CLIB at all.  The objects in the library were compiled
to use absolute addressing.


Is their a position indepenand code library replacement for the CLIB
supplied with the IAR compiler?

- Jamie










Beginning Microcontrollers with the MSP430

jamie_risk wrote:
> The proclaimed "position indepenant
code" option for the IAR compiler 
> doesn't appear to be supported by their own libraries.
> 
> The compiler generates PIC to correctly call functions, but loading
> addresses to constant data is done with abosolute addressing.  
> 
> I can't use the CLIB at all.  The objects in the library were compiled
> to use absolute addressing.
> 
> 
> Is their a position indepenand code library replacement for the CLIB
> supplied with the IAR compiler?

Hi!

Unfortunately, the position-independent option is limited to position 
independent code. Handling position-independent data is a much more 
complex problem, both in terms of implementation in the compiler and the 
required overhead in the application.

The libraries, well, they can move their code around, but the data area 
has to stay fixed. I know that this limits the usability of this mode, 
but that is the way the situation is...

     -- Anders Lindgren, IAR Systems
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.


Hi Anders,

It's not a question of absolute data addressing, it has to do with
absolute constant addressing.  On any processor, PIC is rarely as
efficient as non-PIC, and if one doesn't know that when the option is
selected, then they likely don't know what PIC is for.  

As the briefest example, I want to be able to 'download' code (with
constants) to an available address and have it call a function like
"printf" with a constant string argument.

The relative distance between code/constants and data can change from
linker to run time.  Fine.  The result of this is that I'm quite used
to giving up initialized data with pointers to constants, knowing 
constants, code, literals etc, are generally linked together (and
potentially seperate from data).  I'm comfortable knowing that my data
is statically located, or better, addressed relative to a base register.


Instead of generating (from c, assembly) code to load a pointer to a
constant like this:
	mov.w	#var_address_at_link_time, R12

I'd like to see the compiler generate:
	mov.w	#var_address_at_link_time, R12
	add.w	PC,	R12		; Current PC at run time
	sub.w	#$,	R12    		; '#$' PC at linker time

The above three lines work out to be redundant if the constant (read
code) is at the location the linker intended, but now the addressing
is wholly relative (to code position).  

Code bloat to be sure, but it works, and I'm using it in C like this:
  ...
  extern void * lea(void *);
  #define LEA(a) (lea)((void *)(a))  
  ...
  printf(LEA("Hello World!"));
  printf(LEA("Do you think this is an annoyance?
%s"),LEA("Yes"));
  ...
  /* Some where in an assembly code section */
	PUBLIC lea
lea	add.w	PC,	R12		; Current PC at run time
	sub.w	#$,	R12    		; '#$' PC at linker time
	add.w	#4,	0(SP)
	ret  
  ...

The point is there are functions in the provided library that refer to
constant data (ctype.h for instance) which fall apart the momement the
code is moved from where it was linked.  Not very position independant.

This is probably a holy war on embedded linking philosophy, but since
I have an ear at IAR, I find it is easier to imagine situations where
the ROMable sections of code (again, code, strings, const, literals
etc) stay intact and monolithic than situations where the const data
is loaded seperately (and at a static location to boot) from code.


The end result is that I've implemented my own library, addressing a
number of frustrations, whilst creating a bigger frustration of "Why
should I have too?"




On a seperate note, doing run time relocatable data addressing isn't
exceedingly difficult to accomplish with some C tricks and ones own
cstartup routines, but it seems a waste to have to.  Has their ever
been any plan to a support a global data option that uses register
relative addressing (say, R4 relative)?

- Jamie

> Hi!
> 
> Unfortunately, the position-independent option is limited to position 
> independent code. Handling position-independent data is a much more 
> complex problem, both in terms of implementation in the compiler and
the 
> required overhead in the application.
> 
> The libraries, well, they can move their code around, but the data area 
> has to stay fixed. I know that this limits the usability of this mode, 
> but that is the way the situation is...
> 
>      -- Anders Lindgren, IAR Systems
> -- 
> Disclaimer: Opinions expressed in this posting are strictly my own and
> not necessarily those of my employer.
>





Hi Jamie!

The problem with relocatable data is where to draw the line. Should you
make sure everything works, some thing (which?), nothing?

For example, if you have two global variables:

const int x = 10;
const int const * p = &x;

How should you generate the initializers for these? Obviously, if you
had a loader (which we don't) then you could let the loader fix the
"p"
for you, somehow...

Of course, one strategy would be to limit the relocatable part to string
literals, but then again, what should you handle a global variable on
the form:

char * q = "foo";

We drew the line that we shouldn't do any data relocation what so ever.

Of course we could redraw the map in the future, but only if there is a
legitimate business case behind this, like broad customer demand or
someone willing to put up the funding.

However, what you could do is that, instead of writing your own library,
you could simply modify the source code we provide with your LEA macro
and re-build it. It's a lot of work, but it shouldn't be as much work
as
writing your own library from scratch.


 > I'd like to see the compiler generate:
 >	mov.w	#var_address_at_link_time, R12
 >	add.w	PC,	R12		; Current PC at run time
 >	sub.w	#$,	R12    		; '#$' PC at linker time

The following is shorter and does the same thing:
	mov.w	#LWRD(var_address_at_link_time - $), R12
	add.w	PC,	R12		; Current PC at run time


> Has their ever been any plan to a support a global
data option that
 > uses register relative addressing (say, R4 relative)?

I did something similar in our V850 compiler many years ago, it works, 
but only barely. The user still has to be aware of the fact that 
globally initialized pointers doesn't work -- I hate it when the 
customers easily can shoot of themselves in their own feet using a gun I 
provided...

But no, we haven't considered it for the MSP430.


It would be intersting to know how the distribution of applications is 
out there in the real world. I've always been under the impression that 
most applications are ROM-based and linked to absolute locations. If I'm 
wrong, please let me know. If you are prevented from doing more advanced 
things due to lack of features in the tools, then I *really* would like 
to know!

     -- Anders Lindgren, IAR Systems (Author of the compiler)
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.


> We drew the line that we shouldn't do any data relocation what so
ever.

I'm not disagreeing, it _is_ simply a line in the sand - my argument
is that the line would be drawn based on ROM/RAM criteria, rather than
a code/data criteria.  


>  > I'd like to see the compiler generate:
>  >	mov.w	#var_address_at_link_time, R12
>  >	add.w	PC,	R12		; Current PC at run time
>  >	sub.w	#$,	R12    		; '#$' PC at linker time
> 
> The following is shorter and does the same thing:
> 	mov.w	#LWRD(var_address_at_link_time - $), R12
> 	add.w	PC,	R12		; Current PC at run time

You're right, I sacrificed brevity to illustrate the three steps you
collasped into two.


> > Has their ever been any plan to a support a
global data option that
>  > uses register relative addressing (say, R4 relative)?
> 
> I did something similar in our V850 compiler many years ago, it works, 
> but only barely. The user still has to be aware of the fact that 
> globally initialized pointers doesn't work -- I hate it when the 
> customers easily can shoot of themselves in their own feet using a
gun I 
> provided...
> 
> But no, we haven't considered it for the MSP430.


That's too bad; it makes me chuckle when I'm introduced to
"embedded"
programmers who wished they had a better implementation of Corba or
Java or the like.  I tend to think an embedded tool is allowed to
expect more of it's users in that the platform, and tools are not
heavily abstracted.


As I'd like to reiterate, initialized pointers are a small sacrifice.
(i.e. "declared objects")  Without much effort, initializing data
(that doesn't contain pointers) requires only a few modifications to a
 cstartup routine.  I come from a background of multi-processor task
switching OS development, where global variables are frowned upon. 
Certainly the criteria I apply when choosing to use a global variable
is more strict than than the norm.  My criteria for having declared
objects is restricted further.

 
> It would be intersting to know how the
distribution of applications is 
> out there in the real world. I've always been under the impression
that 
> most applications are ROM-based and linked to absolute locations. If
I'm 
> wrong, please let me know. If you are prevented
from doing more
advanced 
> things due to lack of features in the tools, then
I *really* would like 
> to know!


Any time I have the ability to connect serially to in-circuit
programmable flash, I am inevitably pushed towards writing boot
loaders.  If I were using a true ROM (as opposed to FLASH or an
in-circuit EEPROM) then
the model of static absolute linking works well.

As for modifying the library; it still puts me in the position of
using a code base that has only me to test it.  Whether its IAR's
library that I modify or someone elses, it really amounts to the same
uncertainty.

Thanks for responding,

- Jamie

p.s. It doesn't appear I got the complete source code to your library
anyway, so your modification point is moot ...





On Thu, 30 Mar 2006 17:38:58 +0200, Anders wrote:

>The problem with relocatable data is where to draw
the line. Should you
>make sure everything works, some thing (which?), nothing?

In assembly code, this is easy to apply.  Another limitation of C? Not
really, because vendors have already added the necessary features
related to a target processor to make a practical system.

Libraries have a clear and legitimate need for absolute addressing to
access hardware and for PC-relative addressing for local static
constants (and other data, I suppose, for non-re-entrant routines)
related to the module if it is, itself, compiled for PIC.

Not supporting this mode of programming in C seems a terrible
oversight to me.  One that should be remedied.

I'm sure you've thought this through far more than I have, but have
you considered the idea of using a qualifier, such as __relative and
__absolute?

Jon

P.S.  Just as a note, Anders, I gather we've already purchased two of
the IAR C compiler sets for Luxtron.  They are currently in use by two
other developers in Santa Clara.  I'm considering the purchase of a
3rd, right now.  So I'm interested in answers to this from all
vendors.

Hi Jonathan!

I originally wrote:

> > The problem with relocatable data is where to
draw the line. Should you
> > make sure everything works, some thing (which?), nothing?

Jonathan Kirwan wrote:

> In assembly code, this is easy to apply.  Another
limitation of C? Not
> really, because vendors have already added the necessary features
> related to a target processor to make a practical system.
> 
> Libraries have a clear and legitimate need for absolute addressing to
> access hardware and for PC-relative addressing for local static
> constants (and other data, I suppose, for non-re-entrant routines)
> related to the module if it is, itself, compiled for PIC.
> 
> Not supporting this mode of programming in C seems a terrible
> oversight to me.  One that should be remedied.

This is one of those things that, admittedly, is tough in C. Or rather, 
you have to choose between a limited subset of C, or live with some kind 
of "loader" or "patcher".


> I'm sure you've thought this through far
more than I have, but have
> you considered the idea of using a qualifier, such as __relative and
> __absolute?

Well, yes, if you need this kind of division then you would model it as 
"memory types". In the V850 case I mentioned we have, among else,
__near 
(+- 32 kb around address zero) and __brel (+- 32 kb around the BR register).


> P.S.  Just as a note, Anders, I gather we've
already purchased two of
> the IAR C compiler sets for Luxtron.  They are currently in use by two
> other developers in Santa Clara.  I'm considering the purchase of a
> 3rd, right now.  So I'm interested in answers to this from all
> vendors.

I'm pretty confident that there are no other vendor out there that have 
data position independence, for MSP430. In fact, I think that we have 
the only product that offer support for position independent code.

     -- Anders Lindgren, IAR Systems
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.


--- In msp430@msp4..., "jamie_risk" <jamie_risk@...> wrote:
>
> > We drew the line that we shouldn't do any data relocation what so
ever.
> 
> I'm not disagreeing, it _is_ simply a line in the sand - my argument
> is that the line would be drawn based on ROM/RAM criteria, rather than
> a code/data criteria.  
> 

I'm still curious; Has anyone reading this found the line drawn by IAR
useful?

Giving up initialized data pointing to global variables but not
constant data (i.e. a string pointer) still seems less impactful than
giving up all initialized pointer data (constant or otherwise).

I'm trying to understand the business case for IAR's business decision
in their current compiler's PIC feature set.

- Jamie







On Mon, 03 Apr 2006 16:16:52 -0000, Jamie wrote:

>--- In msp430@msp4..., "jamie_risk"
<jamie_risk@...> wrote:
>>
>> > We drew the line that we shouldn't do any data relocation
what so
>ever.
>> 
>> I'm not disagreeing, it _is_ simply a line in the sand - my
argument
>> is that the line would be drawn based on ROM/RAM criteria, rather than
>> a code/data criteria.  
>
>I'm still curious; Has anyone reading this found the line drawn by IAR
>useful?

I'm still unclear on the details.  But I gather that an argument is
hinted at which says that the current MSP430 mix of flash and RAM
doesn't make PC-relative references to static data all that useful,
anyway.  (A reference by Anders to a need for a "patcher" brings this
to my mind.)  However, I don't find that argument persuasive because
there are many very important cases where the static data is constant
(FIR filter constants, transcendental table values, etc., etc.) and
can move around in the flash along with the position independent
library code.  I could also, potentially, include the idea that a
position independent library module be built on the concept of
requiring a following block of flash for its saved static data and
that there needs to be a method to allow a block of flash code and an
associated block of flash data to move around.  Also, finally, code
doesn't only run in flash.  It is very possible to contain the idea in
an embedded product where code and its associated data is laid out
into the scarce RAM for execution and that the ability to allocate
small blocks for that purpose and to download code shouldn't require
the need for a "patcher", if the compiler supported the concept of PIC
fully.

>Giving up initialized data pointing to global
variables but not
>constant data (i.e. a string pointer) still seems less impactful than
>giving up all initialized pointer data (constant or otherwise).
>
>I'm trying to understand the business case for IAR's business
decision
>in their current compiler's PIC feature set.

My bitter side says:  Magazine articles, check-off boxes, a hack added
to provide a "differentiating point" in some write-up, words on paper,
not so carefully considered.  A hack designed to pit one product
against another in the check-off box wars and not about what real
programmers writing real libraries might care about.  Marketing, in
other words.  (Can you hear me spitting on the floor, now?)

My sweet side says:  It wasn't too hard to goose the compiler to emit
PIC code, but it was "too difficult" in the context of business
pressures to really think it out more carefully for the data side.  So
adding the feature might help _some_ folks on _certain_ tasks and,
what the heck, it's also a check-off box in the write-up wars. 
"Let's
do it.  We can always argue that it helps at least some folks some of
the time.  And we get one more thing to club our competition with."

Anyway, if IAR has gone this far, perhaps they will take the next
logical step and clean up the details.  One can hope.

So far, Anders has said that he doesn't think the other vendors even
bothered to do it at all (this goes to my above point and doesn't
suggest crafted technical reasons were in play) and that "this is one
of those things that is difficult in C" (however that should be
taken.)  And although I love to speculate, I probably have no business
saying what his reasoning was, as he is here to say what it actually
was.  And hopefully, I'll learn something.

Jon

Jonathan Kirwan wrote:

>>>>We drew the line that we shouldn't
do any data relocation what so
>>>>ever.

>>>I'm not disagreeing, it _is_ simply a
line in the sand - my argument
>>>is that the line would be drawn based on ROM/RAM criteria, rather
than
>>>a code/data criteria.  

>>I'm still curious; Has anyone reading this
found the line drawn by IAR
>>useful?

> I'm still unclear on the details.  But I
gather that an argument is
> hinted at which says that the current MSP430 mix of flash and RAM
> doesn't make PC-relative references to static data all that useful,
> anyway.  (A reference by Anders to a need for a "patcher" brings
this
> to my mind.)  However, I don't find that argument persuasive because
> there are many very important cases where the static data is constant
> (FIR filter constants, transcendental table values, etc., etc.) and
> can move around in the flash along with the position independent
> library code.  I could also, potentially, include the idea that a
> position independent library module be built on the concept of
> requiring a following block of flash for its saved static data and
> that there needs to be a method to allow a block of flash code and an
> associated block of flash data to move around.  Also, finally, code
> doesn't only run in flash.  It is very possible to contain the idea in
> an embedded product where code and its associated data is laid out
> into the scarce RAM for execution and that the ability to allocate
> small blocks for that purpose and to download code shouldn't require
> the need for a "patcher", if the compiler supported the concept
of PIC
> fully.
> 
> 
>>Giving up initialized data pointing to global variables but not
>>constant data (i.e. a string pointer) still seems less impactful than
>>giving up all initialized pointer data (constant or otherwise).
>>
>>I'm trying to understand the business case for IAR's business
decision
>>in their current compiler's PIC feature set.
> 
> 
> My bitter side says:  Magazine articles, check-off boxes, a hack added
> to provide a "differentiating point" in some write-up, words on
paper,
> not so carefully considered.  A hack designed to pit one product
> against another in the check-off box wars and not about what real
> programmers writing real libraries might care about.  Marketing, in
> other words.  (Can you hear me spitting on the floor, now?)
> 
> My sweet side says:  It wasn't too hard to goose the compiler to emit
> PIC code, but it was "too difficult" in the context of business
> pressures to really think it out more carefully for the data side.  So
> adding the feature might help _some_ folks on _certain_ tasks and,
> what the heck, it's also a check-off box in the write-up wars. 
"Let's
> do it.  We can always argue that it helps at least some folks some of
> the time.  And we get one more thing to club our competition with."
> 
> Anyway, if IAR has gone this far, perhaps they will take the next
> logical step and clean up the details.  One can hope.
> 
> So far, Anders has said that he doesn't think the other vendors even
> bothered to do it at all (this goes to my above point and doesn't
> suggest crafted technical reasons were in play) and that "this is one
> of those things that is difficult in C" (however that should be
> taken.)  And although I love to speculate, I probably have no business
> saying what his reasoning was, as he is here to say what it actually
> was.  And hopefully, I'll learn something.

I'm interested to know myself ;)  This was added before I started 
working on the compiler, which was when I wrote V2.xx, so from my point 
of view it's spelled "backward compatibility".

I think that you have conviced me that this feature is of broader 
interest that I've thought so far. Although I can't make any
commitments 
at this time, I will take a deep look into this and see if I can improve 
the situation.

I'm a bit suprised that very few, if any, have contacted our support 
orgianization concerning this...

     -- Anders Lindgren, IAR Systems
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.