Absolute symbols

120 views
Skip to first unread message

Alan Modra

unread,
May 2, 2012, 9:43:20 PM5/2/12
to binu...@sourceware.org, gener...@googlegroups.com
I started of writing the following as a comment in binutils PR14502,
then decided it may be worth airing this to a wider audience.


Absolute symbols in an executable or shared library should be treated
no differently to any other symbol. If a binary is relocated by a
given amount, so should all symbols defined by the binary. The ELF
spec says of symbol values:

"In executable and shared object files, st_value holds a virtual
address. To make these files' symbols more useful for the dynamic
linker, the section offset (file interpretation) gives way to a
virtual address (memory interpretation) for which the section number
is irrelevant."

Take note "the section number is irrelevant". That's why I say that
an absolute symbol (so designated by having a section number of
SHN_ABS) should be treated no differently to any other symbol in an
executable. If grub or any other kernel relocation code treats
SHN_ABS symbols specially then that is a bug in the loader.

Another data point backing up this interpretation of the ELF
specification is the behaviour of glibc ld.so, which treats a SHN_ABS
symbol just like any other symbol. In fact, this is a necessary
behaviour since certain symbols, eg. _GLOBAL_OFFSET_TABLE_ and
_DYNAMIC, are made SHN_ABS by GNU ld to be compatible with old linkers
on other systems. The value of _GLOBAL_OFFSET_TABLE_ and _DYNAMIC
must relocate in step with the executable or shared library, otherwise
your program won't operate properly.

This of course is in sharp disagreement with another sentence in the
ELF spec that says:

"SHN_ABS
The symbol has an absolute value that will not change because of
relocation."

I believe the "relocation" referred to here is that performed by the
linker on relocatable object files, *not* relocation of executables
and shared libraries performed by a program loader. That seems to be
the only interpretation that makes the ELF spec self-consistent. In
any case, actual practice trumps the specification.

--
Alan Modra
Australia Development Lab, IBM

Cary Coutant

unread,
May 2, 2012, 11:55:11 PM5/2/12
to gener...@googlegroups.com, binu...@sourceware.org
> Take note "the section number is irrelevant".

SHN_ABS isn't a section number. I'll admit this is a weak point in the
ELF spec -- since the section header table in an executable is
optional, there's no real guidance on what to put in the st_shndx
field to mark a non-absolute symbol. In the absence of any sections at
all (not that I've ever seen such an ELF file in practice), I'd go
with 0.

> Another data point backing up this interpretation of the ELF
> specification is the behaviour of glibc ld.so, which treats a SHN_ABS
> symbol just like any other symbol. In fact, this is a necessary
> behaviour since certain symbols, eg. _GLOBAL_OFFSET_TABLE_ and
> _DYNAMIC, are made SHN_ABS by GNU ld to be compatible with old linkers
> on other systems. The value of _GLOBAL_OFFSET_TABLE_ and _DYNAMIC
> must relocate in step with the executable or shared library, otherwise
> your program won't operate properly.

I think this is an existing problem with Gnu ld. Gold sets st_shndx
for these symbols to the section in which they're defined. It doesn't
seem to have caused any compatibility problems. This is a difference
I've noticed between Gnu ld and gold, and I've concluded that gold is
doing the right thing.

> This of course is in sharp disagreement with another sentence in the
> ELF spec that says:
>
> "SHN_ABS
>    The symbol has an absolute value that will not change because of
>    relocation."
>
> I believe the "relocation" referred to here is that performed by the
> linker on relocatable object files, *not* relocation of executables
> and shared libraries performed by a program loader. That seems to be
> the only interpretation that makes the ELF spec self-consistent. In
> any case, actual practice trumps the specification.

On the contrary, the only interpretation that makes sense to me is
that it will not change because of relocation at link time or at load
time. Absolute symbols, from the days of the earliest linking loaders,
have been used to represent addresses that are outside the address
space of the module (e.g., memory-mapped addresses or kernel gateway
pages). They've even been used to represent true symbolic constants
(e.g., system entry point numbers, sizes, version numbers). There's no
other way to represent a true absolute symbol, while the meaning you
seek is easily represented by giving the symbol a non-negative
st_shndx value.

-cary

Alan Modra

unread,
May 3, 2012, 12:53:26 AM5/3/12
to gener...@googlegroups.com, binu...@sourceware.org
On Wed, May 02, 2012 at 08:55:11PM -0700, Cary Coutant wrote:
> Absolute symbols, from the days of the earliest linking loaders,
> have been used to represent addresses that are outside the address
> space of the module (e.g., memory-mapped addresses or kernel gateway
> pages). They've even been used to represent true symbolic constants
> (e.g., system entry point numbers, sizes, version numbers). There's no
> other way to represent a true absolute symbol, while the meaning you
> seek is easily represented by giving the symbol a non-negative
> st_shndx value.

You've taken the wind out of my sails. I've got to admit that the
only reasonable conclusion to make in resolving this contradiction
between GNU ld behaviour and the ELF spec is that GNU ld was simply
wrong to copy SysV linker bugs. We've had this habit of making
_DYNAMIC and other syms SHN_ABS for a long time. x86, sparc, powerpc
all do the same.
Reply all
Reply to author
Forward
0 new messages