Re: [PING]: [PATCH] ld: Account for .tbss size on ARM EABI targets
Alan Modra <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 31, 2026 at 10:21:16AM +0200, Torbjorn SVENSSON wrote:
>
>
> On 2026-08-30 11:49, Alan Modra wrote:
> > On Sat, Aug 29, 2026 at 09:46:23AM +0200, Torbjorn SVENSSON wrote:
> > >
> > >
> > > On 2026-08-29 09:35, Alan Modra wrote:
> > > > On Fri, Aug 28, 2026 at 03:10:09PM +0200, Torbjorn SVENSSON wrote:
> > > > > > Bare-metal ARM EABI programs allocate TLS storage directly, so if .tdata
> > > > > > consumses VMA, then .tbss must also do so. Otherwise, a following
> > > > > > section such as .bss can overlap it.
> > > >
> > > > In other words, the loader is broken for TLS. Why break the linker as
> > > > well?
> > > >
> > >
> > > What loader?
> > > I'm taking about bare-metal, i.e. there is nothing doing any loading.
> > > The CPU is executing straight from flash without any ram copy of the
> > > program or similar loader activities that normally exist on a pc.
> >
> > Yes, TLS is not supported there. How do you expect it is supposed to
> > work?
> >
>
> Arm decided to enable TLS for their arm-none-eabi toolchain in this commit:
> https://gitlab.arm.com/tooling/gnu-devtools-for-arm/-/commit/f6a8633309c850d62817859986a165c94f11babf
>
> To my understanding, the local-exec TLS mode should be supported for
> bare-metal targets. In this mode, the memory block for TLS would be
> allocated while linking the application and thus, when the application
> boots, it will only need to do the initialization of .tbss and .tdata,
> just like .bss and .data, for the initial thread. Any additional thread
> would allocate it's own block of memory and again initialize the values
> from what was stored in flash / clear the region that should be cleared.
>
> Does this make sense or am I totally missing something here?
.tdata is not supposed to be used directly by the first thread. It is
for initialisation of each thread's TLS and must be kept pristine.
That's why it doesn't make much sense for the first thread to use it
directly, or to allocate vma space for .tbss.
I doubt very much your target systems are running out of flash for
very long. Even back when I was designing hardware, support chips in
the mid 80s were starting to provide RAM shadowing of ROM. The system
only ran out of ROM until it was copied to RAM, at which point the RAM
shadow took over. ROM was *much* slower, not only due to a slower
access time but also due to the support chips allowing it to be 8-bit
memory when main memory was 32-bit. I haven't been in the hardware
game for a long time, but I expect the speed difference between ROM
and RAM still holds. Which means you wouldn't want to access ROM for
a pristine copy of .tdata when setting up the second thread (and you
might not even be able to access ROM again without a reboot).
The only case I can see where using .tdata/.tbss directly makes sense
is when you in fact have only one thread, but you stupidly enabled
threads or your software accidentally pulls in some library with
thread support, *and* your bootup code doesn't understand TLS. In
that case I think you could link with this little extra script
SECTIONS {
.bogustls : { *(.tdata) *(.tbss) LONG (0); }
}
which would more or less do the same as your patch.
> Note, LLVM linker already has this behavior.
That is likely just a bug, I think.
> From some testing, it looks
> like LLVM linker has the same output, regardless if linking for
> bare-metal or PC. I think that the solution that binutils has is
> correct for PC, but not for bare-metal, hence my suggestion for special
> handling.
>
> Kind regards,
> Torbjörn
--
Alan Modra