On Thu, Aug 02, 2012 at 09:26:56PM +0200, Ulrich Weigand wrote:
Steve McIntyre wrote:
I really think the only sane thing to do is fix glibc so it can fetch the attributes from their standard locations.
I've already proposed (and written code for) that, and they refused to accept that method.
Unfortunately I haven't really followed this discussion, so I don't know the reasons why they didn't like your code.
My suspicion would be that it relates to the fundamental distiction in ELF between link-time and load-time fields: the ELF format holds both contents that are supposed to be manipulated on-file by tools like a linker, and contents that are supposed to be accessed in-memory by tools like a dynamic loader.
Exactly, yes.
glibc / ld.so --quite reasonably in my opinion-- would use only those parts of ELF that are readily available at run time. This includes everything available off a program header (and thus part of the memory-mapped part of the file), but *not* things available only in a section.
Unfortunately, the .ARM.attribute section is of the second class. It is avilable to link-time tools that operate on an ELF file, but not readily available to run-time tools like ld.so that operate on the memory-mapped image. Having ld.so bypass this very fundamental separation between link-time and run-time by itself opening the ELF file and reading pieces that are not memory-mapped really seems not a good idea.
A number of people have said this, but I've yet to any explanation beyond "I have a bad feeling", tbh. Where I plumbed in in ld.so in glibc, nearby functions are already calling __lseek and __libc_read. Don't get me wrong, the code I've added is not especially clean! But it works, and I'm not seeing any ill-effects from this approach.
However, there are ways to solve this type of problem, which usually involve changing the linker to make a piece of information that used to be available only at link-time also available at run-time. Typically this means moving the section into the memory-mapped part of the file, and also covering it by a new program header so that it can be found by run-time tools.
This is done e.g. for the .note.ABI-tag section (which serves a similar purpose as .ARM.attributes). While this is primarily a *section* used at link time, it is also made available as part of the NOTE program header in the memory-mapped part at run-time (and this is where ld.so actually uses it).
My suggestion to address this issue would therefore be to have the linker create a new program header ARM_ATTRIBUTES to cover the .ARM.attributes section (and move it into the memory-mapped area also covered by a LOAD program header). ld.so would then be able to use its contents just as it today uses .note.ABI-tag.
This solution obviously still requires all programs to be recompiled before they present the new program header. However, it avoids the two drawbacks of your method Mans pointed out:
- there is no duplication of data (there is a bit of extra meta
data in the form of the new program header, but the actual data covered by it is not duplicated)
- there are no future extensibility issues due to the use of a
single byte
Thoughts?
Hmmm, maybe. Others have said that parsing the attributes is slow and not designed for runtime use like this... I'd been investigating defining and using the existing PT_ARM_ARCHEXT segment instead, but the ARM ABI folks seem happier to use existing ELF header fields. Hence the proposal to use OSABI. BUT: the glibc folks have already appropriated that field for their own nefarious^Wends, e.g. using OSABI_GNU to denote the use of ifunc. Now looking at using some bits in the e_flags field instead...
I don't really care all *that* much about how this is done, but some consistency across groups would be really helpful sometimes. :-/
Cheers,