Re: [PATCH] cross-architecture ELF clean up

From: Jeremy Fitzhardinge
Date: Fri Jun 29 2007 - 10:54:50 EST


Roman Zippel wrote:
The problem I have is that you want to separate _all_ constants, which doesn't really make sense to me, because many of them are useless without the correspending structures.

It seems cleanest to just put all the constants in one place rather than scatter them around based on how they happen to be used.


module.h does indeed pull in way too much, but instead of hacking headers
into little pieces, IMO it would be better to solve the real problem.
No, that's not the real problem; its a side-effect of the real problem. The
real problem is that linux/elf.h ends up bringing in too much.

Please define the problem more specific. :)

I want to be able to include a header to get just the ELF type and constant definitions with no other crud. Both arch-independent ELF definitions, and the ones parameterised by ELF_CLASS.

I want this for three reasons:

1. one is the general cleanup that allows people to use
forward-declared ELF types in general kernel headers without
needing to pull in the full set of ELF headers
2. and to be able to pull full ELF declarations into code which can't
deal with Linux headers, such as bootloader code which doesn't
compile in the same universe as the rest of the kernel
3. a way of getting arch-dependent but broadly common ELF parameters
in a consistent way

This is complicated by the fact that each architecture needs to define some arch-dependent ELF structures which will end up having wider dependencies. The classic example is the ELF note for core files which contains register and other process state, and that will naturally pull in a bunch of other headers to implement that. Unfortunately, the current structure of the ELF headers mean that any user with the slightest interest in ELF structures will end up pulling in half the kernel headers via the asm/elf.h includes.

So my solution was to factor the ELF definitions into useful groups that allow the various users to pull in what they need. The breakdown is:

* arch-independent ELF forward declarations: linux/elf-decl.h
* arch-independent constants: linux/elf-const.h
* arch-independent ELF structure definitions: linux/elf-defn.h
* arch-parameterised ELF declarations: asm/elf-defines.h

and because more or less all the architectures do the same thing for their parameterised ELF types (albeit inconsistently), I pulled the implementation into asm-generic/elf{32,64}-defines.h, and the typical asm/elf-defines.h ends up being a single line to include the appropriate one.

I'd agree that linux/elf-const.h and linux/elf-decl.h could probably be folded together.

arch/powerpc,
for example, has its own stripped down copy of elf.h for bootloader stuff in
order to avoid this extra crud. The fix is to make it possible to get just
the appropriate ELF definitions without getting everything else.

The bootloader is no kernel code and thus the elf header pull in a lot less:

$ gcc -c foo.c -Iusr/include --trace-includes
. usr/include/linux/elf.h
.. usr/include/linux/types.h
... usr/include/linux/posix_types.h
.... usr/include/linux/stddef.h
.... usr/include/asm/posix_types.h
... usr/include/asm/types.h
.. usr/include/linux/auxvec.h
... usr/include/asm/auxvec.h
.. usr/include/linux/elf-em.h
.. usr/include/asm/elf.h
... usr/include/asm/ptrace.h
.... usr/include/asm/ptrace-abi.h
... usr/include/asm/user.h
.... usr/include/asm/page.h

One could remove ptrace.h but otherwise the result looks quite reasonable.

Which architecture? The variation of other includes in the various asm-*/elf.h headers is very broad.

On i386, it ends up being dependent on the mach-* subarch mess, which doesn't work in the boot code. Since there's nothing about the ELF definitions which is subarch-dependent, so that's clearly a bogus dependency.

There's the secondary problem that lots of ELF stuff is copy'n'paste
duplicated across all the architectures, but all they really care about is one
of two sets of parallel definitions (32 or 64 ELF structures). That was the
secondary

Some of it you could put into linux/elf, e.g.:

#if ELF_CLASS == ELFCLASS32

typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Sym Elf_Sym;
typedef Elf32_Dyn Elf_Dyn;
typedef Elf32_Rel Elf_Rel;
typedef Elf32_Rela Elf_Rela;

typedef Elf32_Addr Elf_Addr;

#elif ELF_CLASS == ELFCLASS64

typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Sym Elf_Sym;
typedef Elf64_Dyn Elf_Dyn;
typedef Elf64_Rel Elf_Rel;
typedef Elf64_Rela Elf_Rela;

typedef Elf64_Addr Elf_Addr;

#else
#error
#endif

Yes, but it does get a bit subtle. x86-64 does strange things with redefining the ELF class to compile a 32-bit binfmt_elf, and I think other architectures play similar games. Rearranging these headers is pretty fragile, and I think my approach is a bit less likely to (possibly) break things. But I haven't cross-compiled all the architectures, so I may have broken stuff anyway.

The patch does help you quite a bit, you don't have to cleanup elf.h so it's usable by the whole kernel. Only few parts now really need it and depend on it, which makes the extensive splitup unnecessary only to reduce header dependencies.

Yes, but only for the module.h case. My concerns are wider.

J
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/