Is dynamic symbol table required for executable with only relative relocations?

250 views
Skip to first unread message

H.J. Lu

unread,
Feb 14, 2016, 10:47:22 AM2/14/16
to Generic System V Application Binary Interface
I created a binary with only relative relocations. It doesn't have a
dynamic symbol table since relative relocations don't need a symbol.
Is this a valid ELF binary?

I am enclosing the i386 binary here.

Thanks.

--
H.J.
foo

Suprateeka R Hegde

unread,
Feb 14, 2016, 2:02:34 PM2/14/16
to gener...@googlegroups.com
Of course yes. Why should a fully archive bound (static) executable have
a .dynsym? In fact section headers are not mandatory at all in
executable. Only program headers are mandatory.

Same thing holds good for shared executable. A valid PT_INTERP is
mandatory. But I am clueless why should such executable be a shared
object? Why not fully-archive-bound-static?

What happens when you strip? What about debug-ability?


--
Supra

Suprateeka R Hegde

unread,
Feb 14, 2016, 2:37:53 PM2/14/16
to gener...@googlegroups.com
Some clarification:

"of course yes" below is for the ELF validity question, not the subject
of the mail.

And I meant binary is a valid ELF as per the spec. But may not be valid
with any existing loaders (or dynamic linker). They may need code changes.

--
Supra

Ali Bahrami

unread,
Feb 14, 2016, 5:39:34 PM2/14/16
to gener...@googlegroups.com, Rod Evans
I think it might not be valid, on a technicality
that depends a bit on how you read the gABI.

This object does in fact have a dynamic symbol table:

% elfdump -c foo

Section Header[2]: sh_name: .hash
sh_addr: 0xe8 sh_flags: [ SHF_ALLOC ]
sh_size: 0xc sh_type: [ SHT_HASH ]
sh_offset: 0xe8 sh_entsize: 0x4 (3 entries)
sh_link: 3 sh_info: 0
sh_addralign: 0x4

Section Header[3]: sh_name: .dynsym
sh_addr: 0xf4 sh_flags: [ SHF_ALLOC ]
sh_size: 0 sh_type: [ SHT_DYNSYM ]
sh_offset: 0xf4 sh_entsize: 0x10 (0 entries)
sh_link: 4 sh_info: 1
sh_addralign: 0x4

Section Header[4]: sh_name: .dynstr
sh_addr: 0xf4 sh_flags: [ SHF_ALLOC ]
sh_size: 0x1 sh_type: [ SHT_STRTAB ]
sh_offset: 0xf4 sh_entsize: 0
sh_link: 0 sh_info: 0
sh_addralign: 0x1

The .dynsym has size 0. Its related string table has size 1, which
is the expected NULL byte always found at the front of
a string table, so it's essentially empty also. I think the
problem here is that symbol tables are expected to always have a
zeroed first element, and that's missing here. The gABI says:

Symbol Table
An object file’s symbol table holds information needed to locate
and relocate a program’s symbolic definitions and references. A
symbol table index is a subscript into this array. Index 0 both
designates the first entry in the table and serves as the undefined
symbol index. The contents of the initial entry are specified later
in this section.

One could quibble about whether these words require a 0th element, or
whether it simply defined what has to be there if one is present.
Our implementation, which has roots in the original ATT code does assume
that it's required, and elfdump issues warnings:

% elfdump -h foo
foo: .dynsym: zero sh_size information
foo: .hash: sh_link: 3: does not point to a valid symbol table

I presume that this object has a .dynsym for the benefit of
the hash table. If you didn't have .hash, and didn't issue
DT_HASH in the dynamic section, I think it would be valid not
to have the symbol table. Whether or not it's valid, I think
you'll probably find some tools that will be confused if all
three of these sections are not present.

The other way forward is to ensure that your .dynsym always has
a zeroth element, even if it's otherwise empty. I think that
would be my choice, since it's easy to do, requires no one else
to get involved, and seems to implement the intent of the gABI.
Although this object is self contained, it is a dynamic object
(has program headers, is managed by a runtime linker), so it would
satisfy expectations for it to provide them.

- Ali

Michael Matz

unread,
Feb 15, 2016, 8:17:12 AM2/15/16
to gener...@googlegroups.com
Hi,

On Mon, 15 Feb 2016, Suprateeka R Hegde wrote:

> Of course yes. Why should a fully archive bound (static) executable have
> a .dynsym?

But that's not what H.J. asks, an executable with relocations (even
relative ones) is not static, so it's dynamic. And for those the answere
is: because the gABI says so.

> In fact section headers are not mandatory at all in executable. Only
> program headers are mandatory.

This is not about section headers. A dynamic executable must have a
PT_DYNAMIC array, and that one must contain a DT_SYMTAB and DT_STRTAB
entry (and a DT_HASH one), all of these are mandatory.

The correct question to H.J. is: why do you ask? (the hash table, .dynsym
and .dynstr may all be empty)

> Same thing holds good for shared executable.

No.


Ciao,
Michael.

Michael Matz

unread,
Feb 15, 2016, 8:23:13 AM2/15/16
to gener...@googlegroups.com, Rod Evans
Hi,

On Sun, 14 Feb 2016, Ali Bahrami wrote:

> I think it might not be valid, on a technicality that depends a bit
> on how you read the gABI.

Not to me. To cite:

DT_HASH 4 d_ptr mandatory mandatory
DT_STRTAB 5 d_ptr mandatory mandatory
DT_SYMTAB 6 d_ptr mandatory mandatory

So, it has to contain these dynamic entries. They may of course point to
empty ELF structures, and that's where the ABI isn't that clear, I agree
(my interpretation is that also an empty symtab needs to contain the 0th
entry).

> I presume that this object has a .dynsym for the benefit of
> the hash table. If you didn't have .hash, and didn't issue
> DT_HASH in the dynamic section, I think it would be valid not
> to have the symbol table. Whether or not it's valid, I think
> you'll probably find some tools that will be confused if all
> three of these sections are not present.

And that's for sure, but I think all these tools are right :)

> The other way forward is to ensure that your .dynsym always has
> a zeroth element, even if it's otherwise empty. I think that
> would be my choice, since it's easy to do, requires no one else
> to get involved, and seems to implement the intent of the gABI.

Agreed.


Ciao,
Michael.

Suprateeka R Hegde

unread,
Feb 15, 2016, 9:10:15 AM2/15/16
to gener...@googlegroups.com, Rod Evans
On 15-Feb-2016 04:09 AM, Ali Bahrami wrote:
> Our implementation, which has roots in the original ATT code does assume
> that it's required, and elfdump issues warnings:
>
> % elfdump -h foo
> foo: .dynsym: zero sh_size information
> foo: .hash: sh_link: 3: does not point to a valid symbol table

Simlar things on HP-UX. Our implementation of elfdump, did not warn with
-h. I had implemented a ELF verification option +vall, which flagged the
sh_link error.

I created a similar binary on HP-UX, but there were no runtime issues
that the loader could not handle. Execution was fine.

(I keep calling this dynamic linker as dynamic loader as that is what we
call it on HP-UX)

Also elfdump +interp on this foo, shows libc.so.1 as the program
interpret. That is also interesting.

> I presume that this object has a .dynsym for the benefit of
> the hash table. If you didn't have .hash, and didn't issue
> DT_HASH in the dynamic section, I think it would be valid not
> to have the symbol table.

Thats exactly what I meant. I saw many sections that are for runtime,
like dyn rel, etc. But going by the subject line, I thought these would
be eventually removed along with .dynsym. And hence I got the question,
why such a self contained dynamic object at all.

> The other way forward is to ensure that your .dynsym always has
> a zeroth element, even if it's otherwise empty. I think that
> would be my choice, since it's easy to do, requires no one else
> to get involved, and seems to implement the intent of the gABI.

This looks neat. A failsafe way, definitely.

--
Supra

Suprateeka R Hegde

unread,
Feb 15, 2016, 10:02:44 AM2/15/16
to gener...@googlegroups.com
On 15-Feb-2016 06:47 PM, Michael Matz wrote:
> Hi,
>
> On Mon, 15 Feb 2016, Suprateeka R Hegde wrote:
>
>> Of course yes. Why should a fully archive bound (static) executable have
>> a .dynsym?
>
> But that's not what H.J. asks, an executable with relocations (even
> relative ones) is not static,

I understood, but I just wanted to bring that out also. Apologies if
that confused.

\so it's dynamic. And for those the answere
> is: because the gABI says so.

I indeed thought about DT_SYMTAB. But I could not find anywhere that
DT_SYMTAB should point to .dynsym. I thought it has to point to "a"
symbol table with Elf[32|64]_Sym entries. And .symtab is also same. I
have NOT re-read the gABI for this discussion. Apologies if there is a
mandatory rule that says DT_SYMTAB should point to .dynsym.

And assuming that .symtab would still exist, I asked what happen when
stripped as strip tool is taught to remove .symtab. Eventually there is
no symtab at all.

>> In fact section headers are not mandatory at all in executable. Only
>> program headers are mandatory.
>
> This is not about section headers.

I wanted to connote that optional section headers means sections are
also optional. And hence .dynsym (as a section) is also optional.

A dynamic executable must have a
> PT_DYNAMIC array, and that one must contain a DT_SYMTAB and DT_STRTAB
> entry (and a DT_HASH one), all of these are mandatory.

The gABI says "If an object file participates in dynamic linking, its
program header table will have an element of type PT_DYNAMIC". I failed
to understand how a fully self contained, self relocated, object (that
too an executable) can participate in dynamic "linking". I could not
think of a possible case.

In case, it means PT_DYNAMIC is a "must" even when there is no dynamic
"linking", I agree with you. I might have misinterpreted the spec then.


> The correct question to H.J. is: why do you ask? (the hash table, .dynsym
> and .dynstr may all be empty)

That I agree. But I thought HJ "really" wants too remove .dynsym eventually.

As Ali said, empty ones are neat idea with failsafe operations.

--
Supra

H.J. Lu

unread,
Feb 15, 2016, 10:15:54 AM2/15/16
to Generic System V Application Binary Interface
This is my motivation:

https://sourceware.org/bugzilla/show_bug.cgi?id=19636

> As Ali said, empty ones are neat idea with failsafe operations.
>

I keep the empty dynsym section in my fix:

https://sourceware.org/ml/binutils/2016-02/msg00195.html

--
H.J.

Michael Matz

unread,
Feb 15, 2016, 10:53:53 AM2/15/16
to gener...@googlegroups.com
Hi,

On Mon, 15 Feb 2016, Suprateeka R Hegde wrote:

> I indeed thought about DT_SYMTAB. But I could not find anywhere that
> DT_SYMTAB should point to .dynsym. I thought it has to point to "a"
> symbol table with Elf[32|64]_Sym entries. And .symtab is also same. I
> have NOT re-read the gABI for this discussion. Apologies if there is a
> mandatory rule that says DT_SYMTAB should point to .dynsym.

No, I don't find such language, it can point to any symbol table at all.
Of course, it has to point into some allocated segment, and .symtab isn't
usually allocated, so it would still have to point to something else (even
if empty), but if you made .symtab allocated it could point to that one.
Then you'd need to change the rules for stripping executables to not strip
.symtab. (all in all I'd think making DT_SYMTAB point to .symtab, and not
to .dynsym would be confusing, despite the suggestive names :) ).

> I wanted to connote that optional section headers means sections are
> also optional. And hence .dynsym (as a section) is also optional.
>
> A dynamic executable must have a
> > PT_DYNAMIC array, and that one must contain a DT_SYMTAB and DT_STRTAB
> > entry (and a DT_HASH one), all of these are mandatory.
>
> The gABI says "If an object file participates in dynamic linking, its
> program header table will have an element of type PT_DYNAMIC". I failed
> to understand how a fully self contained, self relocated, object (that
> too an executable) can participate in dynamic "linking". I could not
> think of a possible case.

Usual problem with non-formal language describing concepts. In my reading
it's an identity, an ELF file participates in dynamic linking iff it
contains a PT_DYNAMIC program header (from which then follows that it must
contain the three dynamic tags we're talking about here).

> That I agree. But I thought HJ "really" wants too remove .dynsym
> eventually.
>
> As Ali said, empty ones are neat idea with failsafe operations.

IMHO even the only correct one given the constraints of the gABI.


Ciao,
Michael.
Reply all
Reply to author
Forward
0 new messages