MichaelFarthing wrote:
Currently the OS handles static executables only and so I am implementing ELF with a program Header but no sections and no Section Header Table (which is only really needed for dynamic linking).
Nope, you can have a PT_DYNAMIC record in the program headers to include all information needed for dynamic linking, meaning no sections required at all. Section header could be missing entirely.
MichaelFarthing wrote:
However, without sections it seems difficult to identify the specific functions of particular segments.
Yes, that's the reason why in PHDRS block you can map sections into different segments, to help you with those identifications.
MichaelFarthing wrote:
At present I am planning to use the operating system specific range of values for p_type to identify segment type to enable the program loader to do these tasks (which are done in my existing loader):
This is the expected way. You should be able to load ELF binaries without section headers (only program headers should count on execution).
MichaelFarthing wrote:
(1) Load code and some read-only data relative to the cs selector and other data (including a heap and stack null initialised area) relative to the other (identical) selectors. This enables further instances of the program to share the same code area but with different (write) data areas.
Just put the read-only data sections to the same segment as the code and you'll be fine. You must have a different segment for the heap and the stack, since those cannot be read-only, and probably should be non-executable.
MichaelFarthing wrote:
(2) Preset the stack pointer before entering the program. Maybe that should be a program responsibility but it seems a useful service to provide and would also enable debuggers to alert on detecting some stack problems (ie overflow).
Setting the initial stack pointer is always a task for the kernel, and cannot be the program's responsibility because the command line arguments of the invocation must be placed there, therefore the stack must be set up independently to the ELF executable. Kernel setting its own stack in _start is the exception, not the rule. Normal programs should assume they were provided with a valid stack on execution.
MichaelFarthing wrote:
(3) Enable my debugger to independently load the symbol data from the file image and orientate itself to the program structure (eg matching symbolic names relative to cs or ds/ss as appropriate)
You won't have symbol data by default in an ELF executable (shstr, symstr and symtab are sections not segments). There's a bug in the GNU ld which prevents you to put those in a segment, however some symbols (depending on visibility) can be added to the dynamic segment if you're linking a shared library. FYI, debuggers usually use additional debugger information, and not the "basic" symbol table section, however that could be done for sure too (this is what gcc's "-g" flag is for).
MichaelFarthing wrote:
I think my flag method will work quite satisfactorily but I feel uneasy in using custom flags for what looks like a common need. Can anyone advise me how (for example) Linux tackles these questions (or indeed other operating systems)? [I recognise that perhaps the answer will be to specify sections as well - but it would be nice not to have to].
They usually don't care about sections, require a dynamic segment, and propagate the linking to an "interpreter" (which is independent to the kernel, is a separate user-space library). Sections are only used for compile-time static linking, but not for execution (neither for run-time linking).
Hope these help.
Cheers,
bzt