B
bocadillodeatun
Hi everyone.
Hope any of you has an idea bout how to
solve my "problem".
Let me explain what we are trying to do first:
Our code is made up of "private" (binary) objects
and "public" (source code) files.
Our clients then receive a bunch of *.o files together
with many other *.c files they can modify.
Also, our system contains both a fast (and small)
memory chip (let's call it "chip A") and a much bigger
and slower one ("chip B")
Most of the private code is placed in "chip A", but
we also want to leave a small area of this chip so
that our clients can place a few critical functions
(they might create) in there.
Except for these "public" critical functions, the rest of
the client code should be placed in "chip B".
This is how the final memory map would look like:
chip A
***********
* *
* *
* *
* private *
* objects *
* *
***********
* public *
* objects *
***********
chip B
***********
* *
* *
* *
* public *
* objects *
* *
* *
***********
OK then... in order to do this, what we have been doing
(up to today) is giving our clients the following files:
- Private *.o files
- Public *.c files for them to compile and turn into public *.o files
- A linker script, "linker1.lds", that looks like this:
MEMORY
{
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
}
SECTIONS
{
.chipA :
{
*(.chipA)
} > chipA
.chipB :
{
*(.chipB)
} > chipA
}
Then we would "mark" most of our private code with
__attribute__((section(".chipA"))), and tell our clients
that they should do the same for those speed-critical
functions.
By doing this, we were all happy... well, until this very
same morning, when some "clever" PR guy came to
us with this "great" requirement from now on:
"Our clients should THINK our chipA is just 100KB
in size".
Right now, by inspecting the "linker1.lds" file they
will read this:
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
which is a definition of its real size: 1MB
We could just create three memory regions, like this:
secret (rwax) : ORIGIN = 0x40000000, LENGTH = 900K
chipA (rwax) : ORIGIN = 0x4000e100, LENGTH = 100K
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
and name "secret" something else, like "internal_buffers" or something
even scarier, so that they don't dare to start playing with it
Then I found out about incremental linking, and I thought it might
solve my problem.
The idea was to pre-link all private objects into private.out, using
the original linker script:
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
Then we would give our clients this "private.out" object together
with all the public *.c files and a DIFFERENT (and new) linker
script which would look something like this:
chipA (rwax) : ORIGIN = 0x4000e100, LENGTH = 100K
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
I thougth (erroneously) that memory addresses assigned to
private symbols in "private.out" would remain in the final
object. However, when the client links "private.out" together
with the rest of public objects AND the new linker script,
everything tagged as "chipA" (including private objects)
gets re-placed into addresses 0x4000e100 and up.
So... the "incremental linking" ld option ("-r") all it seems to do is
create a "relocatable" object (hmm... maybe that's where the
"-r" comes from ), that gets later *relocated* according to
the final linker script.
So, here is my question: Is there any way to tell the linker "ok,
create a pre-linked object that will later have to be modified
so that addresses of those functions that have not yet been
resolved are filled, BUT don't touch (not even in the future)
those addresses of functions that you can resolve NOW" ????
I guess is not that easy, because if there are fixed memory
addresses in the pre-linked object, then the final linker step
will have to take into consideration these "already taken"
addresses before start filling regions defined on its linker
script...
I also know the client has MANY ways to find out the real
size of chipA if he wanted... but, hey!, I have already told
the PR guys what I think about all this, and they have
basically told me, "yes, we understand, but do it", as
they usually do...
Anyway... any type of help or idea would be greately
appreciated.
Thanks for your time
Fernando.
Hope any of you has an idea bout how to
solve my "problem".
Let me explain what we are trying to do first:
Our code is made up of "private" (binary) objects
and "public" (source code) files.
Our clients then receive a bunch of *.o files together
with many other *.c files they can modify.
Also, our system contains both a fast (and small)
memory chip (let's call it "chip A") and a much bigger
and slower one ("chip B")
Most of the private code is placed in "chip A", but
we also want to leave a small area of this chip so
that our clients can place a few critical functions
(they might create) in there.
Except for these "public" critical functions, the rest of
the client code should be placed in "chip B".
This is how the final memory map would look like:
chip A
***********
* *
* *
* *
* private *
* objects *
* *
***********
* public *
* objects *
***********
chip B
***********
* *
* *
* *
* public *
* objects *
* *
* *
***********
OK then... in order to do this, what we have been doing
(up to today) is giving our clients the following files:
- Private *.o files
- Public *.c files for them to compile and turn into public *.o files
- A linker script, "linker1.lds", that looks like this:
MEMORY
{
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
}
SECTIONS
{
.chipA :
{
*(.chipA)
} > chipA
.chipB :
{
*(.chipB)
} > chipA
}
Then we would "mark" most of our private code with
__attribute__((section(".chipA"))), and tell our clients
that they should do the same for those speed-critical
functions.
By doing this, we were all happy... well, until this very
same morning, when some "clever" PR guy came to
us with this "great" requirement from now on:
"Our clients should THINK our chipA is just 100KB
in size".
Right now, by inspecting the "linker1.lds" file they
will read this:
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
which is a definition of its real size: 1MB
We could just create three memory regions, like this:
secret (rwax) : ORIGIN = 0x40000000, LENGTH = 900K
chipA (rwax) : ORIGIN = 0x4000e100, LENGTH = 100K
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
and name "secret" something else, like "internal_buffers" or something
even scarier, so that they don't dare to start playing with it
Then I found out about incremental linking, and I thought it might
solve my problem.
The idea was to pre-link all private objects into private.out, using
the original linker script:
chipA (rwax) : ORIGIN = 0x40000000, LENGTH = 1M
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
Then we would give our clients this "private.out" object together
with all the public *.c files and a DIFFERENT (and new) linker
script which would look something like this:
chipA (rwax) : ORIGIN = 0x4000e100, LENGTH = 100K
chipB (rwx) : ORIGIN = 0x60000000, LENGTH = 4M
I thougth (erroneously) that memory addresses assigned to
private symbols in "private.out" would remain in the final
object. However, when the client links "private.out" together
with the rest of public objects AND the new linker script,
everything tagged as "chipA" (including private objects)
gets re-placed into addresses 0x4000e100 and up.
So... the "incremental linking" ld option ("-r") all it seems to do is
create a "relocatable" object (hmm... maybe that's where the
"-r" comes from ), that gets later *relocated* according to
the final linker script.
So, here is my question: Is there any way to tell the linker "ok,
create a pre-linked object that will later have to be modified
so that addresses of those functions that have not yet been
resolved are filled, BUT don't touch (not even in the future)
those addresses of functions that you can resolve NOW" ????
I guess is not that easy, because if there are fixed memory
addresses in the pre-linked object, then the final linker step
will have to take into consideration these "already taken"
addresses before start filling regions defined on its linker
script...
I also know the client has MANY ways to find out the real
size of chipA if he wanted... but, hey!, I have already told
the PR guys what I think about all this, and they have
basically told me, "yes, we understand, but do it", as
they usually do...
Anyway... any type of help or idea would be greately
appreciated.
Thanks for your time
Fernando.