Thank you, everyone. I now understand much better the issues at hand.
William
Grant Edwards wrote:
On 2007-04-12, David Brown <[email protected]> wrote:
FWIW the linker will "recognize" both segments just fine. The
problem is that it recognizes them as two separate memory
segments (hey, they _are_ two separate memory segments -- blame
TI for that). AFAIK, gnu ld doesn't support non-contiguous
memory segments. [If you want an authoritative answer, ask on
the binutils mailing list.] That means that the linker script
is going to have to tell the linker which modules go in which
"text" segment.
Supporting non-contiguous memory segments in a efficient manner
is an example of the classic "bin packing problem". It's a
combinatorial NP-hard problem. That's why a CPU with
non-contiguous code space is a bad idea.
Yes, that's the problem. When you know what functions or data
you want in the upper half of memory, it's easy - make a new
output section in the linker (called ".text2", for
convenience), and put all ".text2" input sections there. In
the C code, use "__attribute__ ((section(".text2"))) to force
specific items into this section. Alternatively, you could
specify the ".text" section from specific object files or
libraries to be put in the new section.
It is also perfectly feasible to drop the "vectors" from the
"memory" command, and just have a single "text" section
covering the entire flash. The issue then is how to get the
"vectors" input section to link at the specific absolute
address of 0xffc0. It's easy enough to link it there by
specifying it in the "sections" command. The trouble is
trying to get the normal ".text" sections to flow around it.
As you say, it doing this optimally is a hard problem, but
doing it lazily is not.
I've been thinking more about the problem. I think with the
degenerate case of only 2 bins, the problem isn't actually that
hard. If I've got it figured correctly, doing it optimally is
O(N^B), where N is the number of input sections and B is the
numbr of bins. With N==2, a brute force optimal solution
should be feasible (especially for a small number of input
sections).
A slightly sub-optimal solution would be fairly simple. As you
note, if you enable -ffunction-sections even the most naive
algorithm should produce good results.
I have used other linkers (for other processors) that handle
this reasonably well. When faced with a selection of normal
relocatable input sections and some fixed absolute input
sections, the linker starts by placing the absolute input
sections first. Then it places the relocatable input sections
as normal, starting from the top. If an input section would
crash with an absolute section, the location counter is set to
the end of the absolute section and the process continues.
You'll end up with a sub-optimal gap before the absolute
section(s), but so what? In this particular case, there is
only the one absolute section - and if there is too much space
taken up, you can always use -ffunction-sections for finer
grained sections.
Exactly
I don't know whether ld has this functionality or not
I believe that it doesn't (but I could be wrong). Adding it
shouldn't be a huge effort, but I think it's going to touch a
lot of stuff deep inside the linker. IOW, for somebody who
already knows the details, it shouldn't be hard. But, for
somebody like me who only tinkers around the edges, it would
take quite a while to get up to speed to the point where I
would know how to add it. Hopefully that makes sense.
- I can't see any way to get it. But the binutils mailing
list is definitely the place to ask for it if this is the way
to go.