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.
> 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?
> 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.
> > 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?
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.
> On Mar 10, 10:34 am, Ian Lance Taylor <ianlancetay...@gmail.com>
> wrote:
> > 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.
> > > 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?
> 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.
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?
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.
> --- > 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.)