This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cleanup PT_GNU_STACK size handling

In working on a uclinux port, I came across the hacks that are in the current 5 uclinux backends of bfd (bfin, frv, lm32, sh, tic6x).

The kernel relies on a non-zero memsz in a PT_GNU_STACK segment to know how much stack to allocate.

They all have the same set of overrides
* modify_program_headers, munge the hdrs, updating a PT_GNU_STACK segment.
* always_size_sections, looking for __stacksize variable and defaulting or setting it, if it is unset.
* copy_private_data, propagating a PT_GNU_STACK segment size

That's quite a bunch of duplicated code, and I find the way of overriding the default via '--defsym __stacksize=VALUE' rather unpleasant. Actually, it doesn't work, because such a defsym gets a type NOTYPE and the check in always_size_sections for 'h->type == STT_OBJECT' fails. One ends up with a duplicate symbol error. I have no idea how long that's been broken.

Anyway, this patch removes all that duplicate code and adds a new way of setting the stack size. I found the handling of the EXEC flag on PT_GNU_STACK somewhat random too, and have tried to clean that up and contain it in one place.

*) a new elf linker option '-z stack-size=VALUE'. This is available to all elf backends. This is passed via a new field in link_info. We distinguish between 'user said zero' and 'use the default', by using the value -1 for the former and zero for the latter. This is a little ugly, but seemed to be the best way to ensure default initialize to zero did the right thing.

*) a new elf backend default, elf_backend_stack_align, to set the default alignment. I defaulted this to 16.

*) In bfd_elf_map_sections_to_segments, when creating the PT_GNU_STACK segment, we copy the backends alignment, and the link info's stack size.

*) In assign_file_positions_for_non_load_sections, we set the p_memsz value for a PT_GNU_STACK segment.

*) In copy_elf_program_header we propagate the memsz field likewise. This and the previous 3 changes allow removal of the uclinux backend's overriding of modify_program_headers and copy_private_data.

*) Add a new function 'bfd_elf_stack_segment_size' to elflink.c. This sets the linkinfo size from __stacksize or default, unless it was specified by the user already. It'd be nice to get rid of the __stacksize handling (given it doesn't apparently work), but I thought that might be a change too far. Rather than unconditionally set __stacksize, we only set it if it is undefined (i.e. it's referenced from somewhere). It is an error to define __stacksize and use '-z stack-size='

*) Modify bfd_elf_size_dynamic_sections. First, move the handling of PT_GNU_STACK segment flags to after the backend's size_sections hook has been called. The logic there's been rewritten to avoid things like creating a PT_GNU_STACK for -z noexecstack with no size specified. We set the segment flags if it needs to be executable, or the size is non-zero.

Then I changed all the uclinux backends to remove the now unneeded hooks, and have the always_size_sections hook call the new bfd_elf_stack_segment_size helper.

I tested this on i686-pc-linux-gnu and all the above mentioned uclinux backends. There was one progression (ld-sh/fdpic-stack-size, the above-mentioned problem with '--defsym __stacksize') The new tests pass. I manually checked that objcopy et all preserved PT_GNU_STACK memsz, but my dejagnu-fu was insufficient to automate that.

Comments? Ok?

Nathan Sidwell

Attachment: all.diff
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]