This is the mail archive of the binutils@sources.redhat.com 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]

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


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