[ELF] Implement infrastructure for thunk code creation

Description

[ELF] Implement infrastructure for thunk code creation

Some targets might require creation of thunks. For example, MIPS targets
require stubs to call PIC code from non-PIC one. The patch implements
infrastructure for thunk code creation and provides support for MIPS
LA25 stubs. Any MIPS PIC code function is invoked with its address
in register $t9. So if we have a branch instruction from non-PIC code
to the PIC one we cannot make the jump directly and need to create a small
stub to save the target function address.
See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf

  • In relocation scanning phase we ask target about thunk creation necessity

by calling TagetInfo::needsThunk method. The InputSection class
maintains list of Symbols requires thunk creation.

  • Reassigning offsets performed for each input sections after relocation

scanning complete because position of each section might change due
thunk creation.

  • The patch introduces new dedicated value for DefinedSynthetic symbols

DefinedSynthetic::SectionEnd. Synthetic symbol with that value always
points to the end of the corresponding output section. That allows to
escape updating synthetic symbols if output sections sizes changes after
relocation scanning due thunk creation.

  • In the InputSection::writeTo method we write thunks after corresponding

input section. Each thunk is written by calling TargetInfo::writeThunk method.

  • The patch supports the only type of thunk code for each target. For now,

it is enough.

Differential Revision: http://reviews.llvm.org/D17934

Details

Committed
atanasyanMar 31 2016, 2:26 PM
Differential Revision
D17934: [ELF] Implement infrastructure for thunk code creation
Parents
rL265058: ELF: Add more variants of ignored flags.
Branches
Unknown
Tags
Unknown
krasin added a subscriber: krasin.Apr 4 2016, 1:24 PM

FYI: this change has broken asan lld tests: http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/11552

==25361==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 56 byte(s) in 1 object(s) allocated from:
    #0 0x5935d0 in operator new(unsigned long) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:62
    #1 0x6f8d4d in llvm::TinyPtrVector<lld::elf::SymbolBody const*>::push_back(lld::elf::SymbolBody const*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/TinyPtrVector.h:206:13
    #2 0x880fbe in scanRelocsForThunks<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<llvm::support::endianness::big, false>, false> > /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:319:5
    #3 0x880fbe in scanRelocs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<llvm::support::endianness::big, false>, false> > /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:507
    #4 0x880fbe in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)0, false> >::scanRelocs(lld::elf::InputSectionBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >&, llvm::object::Elf_Shdr_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false> > const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:523
    #5 0x838c16 in scanRelocs /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:513:7
    #6 0x838c16 in createSections /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:1064
    #7 0x838c16 in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)0, false> >::run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:215
    #8 0x833d3e in void lld::elf::writeResult<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::SymbolTable<llvm::object::ELFType<(llvm::support::endianness)0, false> >*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Writer.cpp:207:3
    #9 0x6827e0 in void lld::elf::LinkerDriver::link<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::opt::InputArgList&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Driver.cpp:433:3
    #10 0x679a96 in lld::elf::LinkerDriver::main(llvm::ArrayRef<char const*>) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Driver.cpp:213:5
    #11 0x678f73 in lld::elf::link(llvm::ArrayRef<char const*>, llvm::raw_ostream&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/ELF/Driver.cpp:44:3
    #12 0x596874 in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/lld/tools/lld/lld.cpp:107:13
    #13 0x7f378cdf6ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 1 allocation(s).