Handling section indexes larger than 0xff00

59 views
Skip to first unread message

Ian Lance Taylor

unread,
Mar 10, 2008, 1:34:22 PM3/10/08
to gener...@googlegroups.com, hjl....@gmail.com
I believe that the GNU binutils currently do not correctly handle
section indexes larger than 0xff00. H.J. Lu asked me to raise the
issue here.

I find the ELF ABI to be unambiguous. When the shstrndx value in the
ELF header is larger than or equal to 0xff00 (SHN_LORESERVE), the
value should be stored in the sh_link field of section header 0. I
believe that the value that should be stored there is simply the
offset of the section header in the list of section headers. That is,
if there are N sections, then we refer to the sections using indexes
from 0 to N-1, inclusive.

The GNU binutils do not do this. They effectively number the sections
from 0 to 0xfeff and then from 0x10000 to N + 0x100. Thus when the
shstrndx value is too large, the GNU binutils store a value 0x100
larger than I believe the ELF ABI specifies.

A similar issue arises for symbols defined in sections larger than or
equal to 0xff00. The ELF ABI says that SHN_XINDEX should be stored in
the st_shndx field, and that the real section index should be stored
in the SHT_SYMTAB_SHNDX section. Here too the GNU binutils store a
value 0x100 larger than what I believe the ELF ABI specifies.

I don't see any support in the ELF ABI for adding 0x100 like this. I
don't see any ambiguity in the ELF ABI. Any section index from
SHN_LORESERVE to SHN_HIRESERVE must be treated as a special code, not
an actual index into the section headers.

Intel's icc compiler follows my reading of the ELF ABI.

My bug report against the GNU binutils is here:
http://sourceware.org/bugzilla/show_bug.cgi?id=5900
In that bug report, H.J. says this:

> I think it is up for debate. I can see the point for the current BFD
> behavior. That is each section index is unique, including special
> ones. When I say section index 0xfff2, there is no ambiguity about
> which section it refers to. Would you mind raising your concern at
> http://groups.google.com/group/generic-abi

Would anybody care to support the position of the GNU binutils over
what I believe is written in the ELF ABI?

Ian

H.J.

unread,
Mar 10, 2008, 2:40:04 PM3/10/08
to Generic System V Application Binary Interface
On Mar 10, 10:34 am, Ian Lance Taylor <ianlancetay...@gmail.com>
wrote:
From GNU binutils point of view, all indexes, including those
special ones from SHN_LORESERVE to SHN_HIRESERVE, are
valid "section indexes" and are in the same name space. That
is when I specify a section with section index, 0xfff1, it will be
the ABS section, not the section whose index in section header
table is 0xfff1. For a section whose index in section header table
is > 0xff00, its "section index" will have a bias of 256.

H.J.

H.J.

unread,
Mar 10, 2008, 4:45:41 PM3/10/08
to Generic System V Application Binary Interface
gABI says

---
Some section header table indexes are reserved in contexts where index
size is restricted, for example, the st_shndx member of a symbol table
entry and the e_shnum and e_shstrndx members of the ELF header. In
such contexts, the reserved values do not represent actual sections in
the object file. Also in such contexts, an escape value indicates that
the actual section index is to be found elsewhere, in a larger field.
----

Do those special values have the same special means where the index
size isn't restricted?

Roland McGrath

unread,
Mar 10, 2008, 5:12:01 PM3/10/08
to gener...@googlegroups.com, hjl....@gmail.com
I concur with Ian's assessment. H.J. has explained why it's convenient for
an implementation to exclude [SHN_LORESERVE,SHN_HIRESERVE] from the indices
it actually uses for sections it emits. But he has not shown anything to
suggest the spec requires this.

I think the clause that H.J. just cited is unambiguous that the reserved
values are reserved only in contexts where index size is restricted.
There is a little ambiguity in the SHN_HIRESERVE clause:

This value specifies the upper bound of the range of reserved indexes. The
system reserves indexes between SHN_LORESERVE and SHN_HIRESERVE, inclusive;
the values do not reference the section header table. The section header
table does not contain entries for the reserved indexes.

But this "_the_ reserved indexes" is in the context of the introductory
paragraph that says "in contexts where index size is restricted".

Certainly an ELF producer is free to eschew using any index >= 0xff00 as
an actual section index. But that means skipping 256 unused section
headers in the table before the section with index 0x10000. However, I
don't see any defense for an ELF consumer taking st_shndx = SHN_XINDEX
with the corresponding SHT_SYMTAB_SHNDX entry being 0xfff1 as a SHN_ABS
symbol. It is a normal symbol in the section whose header is at e_shoff
+ 0xfff1 * e_shentsize.


Thanks,
Roland

Cary Coutant

unread,
Mar 10, 2008, 6:28:30 PM3/10/08
to gener...@googlegroups.com
> gABI says
>
> ---
> Some section header table indexes are reserved in contexts where index
> size is restricted, for example, the st_shndx member of a symbol table
> entry and the e_shnum and e_shstrndx members of the ELF header. In
> such contexts, the reserved values do not represent actual sections in
> the object file. Also in such contexts, an escape value indicates that
> the actual section index is to be found elsewhere, in a larger field.
> ----
>
> Do those special values have the same special means where the index
> size isn't restricted?

No. The wording of the ABI does not restrict the use of those values
as section indexes; it only reserves those values when used in the two
places it mentions (st_shndx, e_shnum, and e_shstrndx), and provides
extension mechanisms for providing the actual section index (or count).

Pay close attention to the wording here:

e_shnum
This member holds the number of entries in the section header
table. Thus the product of e_shentsize and e_shnum gives the
section header table's size in bytes. If a file has no section
header table, e_shnum holds the value zero.

If the number of sections is greater than or equal to
SHN_LORESERVE (0xff00), this member has the value zero and the
actual number of section header table entries is contained in
the sh_size field of the section header at index 0. (Otherwise,
the sh_size member of the initial entry contains 0.)

e_shstrndx
This member holds the section header table index of the entry
associated with the section name string table. If the file has
no section name string table, this member holds the value
SHN_UNDEF. See ``Sections'' and ``String Table'' below for more
information.

If the section name string table section index is greater than
or equal to SHN_LORESERVE (0xff00), this member has the value
SHN_XINDEX (0xffff) and the actual index of the section name
string table section is contained in the sh_link field of the
section header at index 0. (Otherwise, the sh_link member of
the initial entry contains 0.)

Notice that it refers to "the actual number of section header table
entries," which could indeed be a value between 0xff00 and 0xffff.
There is not even a hint that those values are reserved in the
alternate location.

And here:

SHT_SYMTAB_SHNDX
This section is associated with a section of
type SHT_SYMTAB and is required if any of the section header
indexes referenced by that symbol table contain the escape
value SHN_XINDEX. The section is an array of Elf32_Word values.
Each value corresponds one to one with a symbol table entry and
appear in the same order as those entries. The values represent
the section header indexes against which the symbol table
entries are defined. Only if corresponding symbol table
entry's st_shndx field contains the escape
value SHN_XINDEX will the matching Elf32_Word hold the actual
section header index; otherwise, the entry must
be SHN_UNDEF (0).

Notice here it says "the actual section header index," again with no
hint that any indexes are reserved. These aren't really reserved
section header indexes; they are instead reserved values for the
st_shndx and e_shstrndx fields.

By the way, that last sentence of the SHT_SYMTAB_SHNDX description is
something that is often overlooked, in my experience. I've seen tools
that put the section index into the extended index table for all
entries, not just those where the st_shndx field has the value
SHN_XINDEX. It may not seem important, but there is value in doing
this according to spec.

I'll grant that this could have been worded more clearly, but speaking
as a first-hand participant in the discussions that designed this
escape mechanism, the behavior Ian is looking for is the correct
behavior, and I believe the spec does in fact say that unambiguously.

(I ran across this problem while I was still at HP, while porting some
in-house ELF tools to Linux, and I'm pretty sure I raised the issue
with H.J. at the time. I ended up doing an ugly hack to deal with it.)

-cary

Reply all
Reply to author
Forward
0 new messages