This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: x86 - linker optimization of "call *constant_variable" - feasible?
On Sat, Aug 16, 2003 at 12:50:49AM -0700, Zack Weinberg wrote:
> direct form easily. What I don't know how to do is look up the target
> address of the relocation being applied, determine whether it's in a
> read-only segment (otherwise the optimization is invalid), and then
> look up the relocation *for that address* and use it to determine the
> appropriate value for the displacement field of the call instruction.
Doing this from relocate_section could be rather expensive, as you would
need to read and scan through the relocs of the target section, for each
GNU_INDJUMP reloc you come across. I would do the following instead:
o In check_relocs, make a list of all GNU_INDJUMP relocs that might be
candidates for optimization, and attach to the hash table. Any
GNU_INDJUMP with its symbol defined in a rw section can't be
optimized, but you may not know that yet (because the symbol might not
yet be defined or because a ro input section might be mapped to a rw
output section).
o Write a new function to process the list, marking entries that can be
optimized and saving final destinations. Avoid reading relocs for any
given section more than once by processing all list entries that
reference symbols defined in that section. Sorting the list by symbol
section is probably a good idea. I think you can safely assume that
reloc r_offset is monotonically increasing in the relocs for any
section.
Call the function from some place in the linker after input sections
have been mapped to output sections. You might like to take a look at
ppc64_elf_tls_optimize or ppc64_elf_edit_opd which both rummage
through relocs and are called via ldemul_before_allocation, which is
the right place for your function to go too.
o Use the list in relocate_section.
> + case R_386_32_GNU_INDJUMP:
This belongs just above case R_386_32, so you can fall through
> + /* ??? How to ensure that the output BFD gets a plain
> + R_386_32 reloc, so that the dynamic linker never sees
> + R_386_32_GNU_INDJUMP? */
> + r_type = R_386_32;
and setting r_type will then "just work".
You need to handle R_386_32_GNU_INDJUMP in a few more places in
elf32-i386.c too. Accounting for dynamic relocs might be a little
tricky: Consider that "call *var" will need a dynamic reloc if you're
building a shared lib and the call can't be optimized, while if the call
is optimized you won't need a dynamic reloc.
--
Alan Modra
IBM OzLabs - Linux Technology Centre