[lld] r262158 - Remove the old ELF linker.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 27 16:11:02 PST 2016
Author: rafael
Date: Sat Feb 27 18:10:58 2016
New Revision: 262158
URL: http://llvm.org/viewvc/llvm-project?rev=262158&view=rev
Log:
Remove the old ELF linker.
I think it is clear by now that the new linker is viable.
Removed:
lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/Driver/GnuLdOptions.td
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/AArch64/TODO.rst
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/ARM/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/ARM/TODO.rst
lld/trunk/lib/ReaderWriter/ELF/Atoms.cpp
lld/trunk/lib/ReaderWriter/ELF/Atoms.h
lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/Chunk.h
lld/trunk/lib/ReaderWriter/ELF/DynamicFile.cpp
lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/ELFFile.cpp
lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/FileCommon.cpp
lld/trunk/lib/ReaderWriter/ELF/FileCommon.h
lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
lld/trunk/lib/ReaderWriter/ELF/OrderPass.h
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.cpp
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
lld/trunk/lib/ReaderWriter/ELF/TODO.txt
lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp
lld/trunk/lib/ReaderWriter/ELF/TargetLayout.h
lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
lld/trunk/lib/ReaderWriter/ELF/Writer.h
lld/trunk/lib/ReaderWriter/ELF/X86/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/TODO.rst
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
lld/trunk/test/Driver/def-lib-search.test
lld/trunk/test/Driver/flavor-option.test
lld/trunk/test/Driver/lib-search.test
lld/trunk/test/Driver/so-whole-archive.test
lld/trunk/test/Driver/trivial-driver.test
lld/trunk/test/Driver/undef-basic.objtxt
lld/trunk/test/old-elf/AArch64/Inputs/fn.c
lld/trunk/test/old-elf/AArch64/Inputs/fn.o
lld/trunk/test/old-elf/AArch64/Inputs/general-dyn-tls-0.yaml
lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.c
lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.o
lld/trunk/test/old-elf/AArch64/Inputs/initfini.c
lld/trunk/test/old-elf/AArch64/Inputs/initfini.o
lld/trunk/test/old-elf/AArch64/Inputs/initial-exec-tls-1.yaml
lld/trunk/test/old-elf/AArch64/Inputs/main.c
lld/trunk/test/old-elf/AArch64/Inputs/main.o
lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.c
lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.o
lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.o
lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.s
lld/trunk/test/old-elf/AArch64/defsym.test
lld/trunk/test/old-elf/AArch64/dontignorezerosize-sections.test
lld/trunk/test/old-elf/AArch64/dynamicvars.test
lld/trunk/test/old-elf/AArch64/dynlib-nointerp-section.test
lld/trunk/test/old-elf/AArch64/general-dyn-tls-0.test
lld/trunk/test/old-elf/AArch64/initfini.test
lld/trunk/test/old-elf/AArch64/initial-exec-tls-0.test
lld/trunk/test/old-elf/AArch64/local-tls.test
lld/trunk/test/old-elf/AArch64/rel-abs16-overflow.test
lld/trunk/test/old-elf/AArch64/rel-abs16.test
lld/trunk/test/old-elf/AArch64/rel-abs32-overflow.test
lld/trunk/test/old-elf/AArch64/rel-abs32.test
lld/trunk/test/old-elf/AArch64/rel-abs64.test
lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21-overflow.test
lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21.test
lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21-overflow.test
lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21.test
lld/trunk/test/old-elf/AArch64/rel-bad.test
lld/trunk/test/old-elf/AArch64/rel-prel16-overflow.test
lld/trunk/test/old-elf/AArch64/rel-prel16.test
lld/trunk/test/old-elf/AArch64/rel-prel32-overflow.test
lld/trunk/test/old-elf/AArch64/rel-prel32.test
lld/trunk/test/old-elf/AArch64/rel-prel64.test
lld/trunk/test/old-elf/ARM/Inputs/fn.c
lld/trunk/test/old-elf/ARM/Inputs/libfn.so
lld/trunk/test/old-elf/ARM/Inputs/libobj.so
lld/trunk/test/old-elf/ARM/Inputs/obj.c
lld/trunk/test/old-elf/ARM/arm-symbols.test
lld/trunk/test/old-elf/ARM/defsym.test
lld/trunk/test/old-elf/ARM/dynamic-symbols.test
lld/trunk/test/old-elf/ARM/entry-point.test
lld/trunk/test/old-elf/ARM/exidx.test
lld/trunk/test/old-elf/ARM/header-flags.test
lld/trunk/test/old-elf/ARM/mapping-code-model.test
lld/trunk/test/old-elf/ARM/mapping-symbols.test
lld/trunk/test/old-elf/ARM/missing-symbol.test
lld/trunk/test/old-elf/ARM/plt-dynamic.test
lld/trunk/test/old-elf/ARM/plt-ifunc-interwork.test
lld/trunk/test/old-elf/ARM/plt-ifunc-mapping.test
lld/trunk/test/old-elf/ARM/rel-abs32.test
lld/trunk/test/old-elf/ARM/rel-arm-call.test
lld/trunk/test/old-elf/ARM/rel-arm-jump24-veneer-b.test
lld/trunk/test/old-elf/ARM/rel-arm-jump24-veneer-bl.test
lld/trunk/test/old-elf/ARM/rel-arm-jump24.test
lld/trunk/test/old-elf/ARM/rel-arm-mov.test
lld/trunk/test/old-elf/ARM/rel-arm-prel31.test
lld/trunk/test/old-elf/ARM/rel-arm-target1.test
lld/trunk/test/old-elf/ARM/rel-arm-thm-interwork.test
lld/trunk/test/old-elf/ARM/rel-base-prel.test
lld/trunk/test/old-elf/ARM/rel-copy.test
lld/trunk/test/old-elf/ARM/rel-glob-dat.test
lld/trunk/test/old-elf/ARM/rel-got-brel.test
lld/trunk/test/old-elf/ARM/rel-group-relocs.test
lld/trunk/test/old-elf/ARM/rel-ifunc.test
lld/trunk/test/old-elf/ARM/rel-jump-slot.test
lld/trunk/test/old-elf/ARM/rel-rel32.test
lld/trunk/test/old-elf/ARM/rel-thm-call.test
lld/trunk/test/old-elf/ARM/rel-thm-jump11.test
lld/trunk/test/old-elf/ARM/rel-thm-jump24-veneer.test
lld/trunk/test/old-elf/ARM/rel-thm-jump24.test
lld/trunk/test/old-elf/ARM/rel-thm-mov.test
lld/trunk/test/old-elf/ARM/rel-tls-ie32.test
lld/trunk/test/old-elf/ARM/rel-tls-le32.test
lld/trunk/test/old-elf/ARM/rel-v4bx.test
lld/trunk/test/old-elf/ARM/thm-symbols.test
lld/trunk/test/old-elf/ARM/two-got-for-symbol.test
lld/trunk/test/old-elf/ARM/undef-lazy-symbol.test
lld/trunk/test/old-elf/ARM/veneer-mapping.test
lld/trunk/test/old-elf/ARM/weak-branch.test
lld/trunk/test/old-elf/Hexagon/Inputs/dynobj-data.c
lld/trunk/test/old-elf/Hexagon/Inputs/dynobj-data.o
lld/trunk/test/old-elf/Hexagon/Inputs/dynobj.c
lld/trunk/test/old-elf/Hexagon/Inputs/dynobj.o
lld/trunk/test/old-elf/Hexagon/Inputs/got-plt-order.c
lld/trunk/test/old-elf/Hexagon/Inputs/got-plt-order.o
lld/trunk/test/old-elf/Hexagon/Inputs/libMaxAlignment.a
lld/trunk/test/old-elf/Hexagon/Inputs/sda-base.o
lld/trunk/test/old-elf/Hexagon/Inputs/sdata1.c
lld/trunk/test/old-elf/Hexagon/Inputs/sdata1.o
lld/trunk/test/old-elf/Hexagon/Inputs/sdata2.c
lld/trunk/test/old-elf/Hexagon/Inputs/sdata2.o
lld/trunk/test/old-elf/Hexagon/Inputs/use-shared.hexagon
lld/trunk/test/old-elf/Hexagon/dynlib-data.test
lld/trunk/test/old-elf/Hexagon/dynlib-gotoff.test
lld/trunk/test/old-elf/Hexagon/dynlib-hash.test
lld/trunk/test/old-elf/Hexagon/dynlib-rela.test
lld/trunk/test/old-elf/Hexagon/dynlib-syms.test
lld/trunk/test/old-elf/Hexagon/dynlib.test
lld/trunk/test/old-elf/Hexagon/hexagon-got-plt-order.test
lld/trunk/test/old-elf/Hexagon/hexagon-plt-setup.test
lld/trunk/test/old-elf/Hexagon/maxalignment.test
lld/trunk/test/old-elf/Hexagon/rela-order.test
lld/trunk/test/old-elf/Hexagon/sda-base.test
lld/trunk/test/old-elf/Hexagon/zerofillquick-sdata.test
lld/trunk/test/old-elf/Inputs/abs-test.i386
lld/trunk/test/old-elf/Inputs/allowduplicates.objtxt
lld/trunk/test/old-elf/Inputs/bar.o.x86-64
lld/trunk/test/old-elf/Inputs/branch-test.hexagon
lld/trunk/test/old-elf/Inputs/branch-test.ppc
lld/trunk/test/old-elf/Inputs/consecutive-weak-defs.o.yaml
lld/trunk/test/old-elf/Inputs/constants-merge.x86-64
lld/trunk/test/old-elf/Inputs/constdata.x86-64
lld/trunk/test/old-elf/Inputs/foo.o.x86-64
lld/trunk/test/old-elf/Inputs/globalconst.c
lld/trunk/test/old-elf/Inputs/globalconst.o.x86-64
lld/trunk/test/old-elf/Inputs/gotpcrel.S
lld/trunk/test/old-elf/Inputs/gotpcrel.x86-64
lld/trunk/test/old-elf/Inputs/group-cmd-search-1.ls
lld/trunk/test/old-elf/Inputs/group-cmd-search-2.ls
lld/trunk/test/old-elf/Inputs/group-cmd-search-3.ls
lld/trunk/test/old-elf/Inputs/ifunc.S
lld/trunk/test/old-elf/Inputs/ifunc.cpp
lld/trunk/test/old-elf/Inputs/ifunc.cpp.x86-64
lld/trunk/test/old-elf/Inputs/ifunc.x86-64
lld/trunk/test/old-elf/Inputs/libfnarchive.a
lld/trunk/test/old-elf/Inputs/libifunc.x86-64.so
lld/trunk/test/old-elf/Inputs/libundef.so
lld/trunk/test/old-elf/Inputs/libweaksym.so
lld/trunk/test/old-elf/Inputs/main-with-global-def.o.yaml
lld/trunk/test/old-elf/Inputs/mainobj.x86_64
lld/trunk/test/old-elf/Inputs/no-unique-section-names.x86-64
lld/trunk/test/old-elf/Inputs/object-test.elf-hexagon
lld/trunk/test/old-elf/Inputs/object-test.elf-i386
lld/trunk/test/old-elf/Inputs/phdr.i386
lld/trunk/test/old-elf/Inputs/quickdata-sort-test.o.elf-hexagon
lld/trunk/test/old-elf/Inputs/quickdata-sortcommon-test.o.elf-hexagon
lld/trunk/test/old-elf/Inputs/quickdata-test.elf-hexagon
lld/trunk/test/old-elf/Inputs/reloc-test.elf-i386
lld/trunk/test/old-elf/Inputs/reloc-xb.x86
lld/trunk/test/old-elf/Inputs/reloc-xt.x86
lld/trunk/test/old-elf/Inputs/relocs-dynamic.x86-64
lld/trunk/test/old-elf/Inputs/relocs.x86-64
lld/trunk/test/old-elf/Inputs/responsefile
lld/trunk/test/old-elf/Inputs/rodata-test.hexagon
lld/trunk/test/old-elf/Inputs/rodata-test.i386
lld/trunk/test/old-elf/Inputs/rodata.c
lld/trunk/test/old-elf/Inputs/rodata.o
lld/trunk/test/old-elf/Inputs/section-test.i386
lld/trunk/test/old-elf/Inputs/shared.c
lld/trunk/test/old-elf/Inputs/shared.so-x86-64
lld/trunk/test/old-elf/Inputs/shndx.o-x86_64
lld/trunk/test/old-elf/Inputs/stripped-empty.x86_64
lld/trunk/test/old-elf/Inputs/target-test.hexagon
lld/trunk/test/old-elf/Inputs/target-test.ppc
lld/trunk/test/old-elf/Inputs/tls-tbss-size.yaml
lld/trunk/test/old-elf/Inputs/tls.S
lld/trunk/test/old-elf/Inputs/tls.c
lld/trunk/test/old-elf/Inputs/tls.x86-64
lld/trunk/test/old-elf/Inputs/tlsAddr.x86-64
lld/trunk/test/old-elf/Inputs/tlsaddr.c
lld/trunk/test/old-elf/Inputs/undef-from-main-so.c
lld/trunk/test/old-elf/Inputs/undef-from-main.c
lld/trunk/test/old-elf/Inputs/undef-pc32.o
lld/trunk/test/old-elf/Inputs/undef.o
lld/trunk/test/old-elf/Inputs/undef2-so.o.yaml
lld/trunk/test/old-elf/Inputs/use-shared-32s.c
lld/trunk/test/old-elf/Inputs/use-shared-32s.x86-64
lld/trunk/test/old-elf/Inputs/use-shared.c
lld/trunk/test/old-elf/Inputs/use-shared.x86-64
lld/trunk/test/old-elf/Inputs/weaksym.o
lld/trunk/test/old-elf/Inputs/writersyms.o
lld/trunk/test/old-elf/Inputs/x86-64-relocs.S
lld/trunk/test/old-elf/Mips/abi-flags-01.test
lld/trunk/test/old-elf/Mips/abi-flags-02.test
lld/trunk/test/old-elf/Mips/abi-flags-03.test
lld/trunk/test/old-elf/Mips/abi-flags-04.test
lld/trunk/test/old-elf/Mips/abi-flags-05.test
lld/trunk/test/old-elf/Mips/abi-flags-06.test
lld/trunk/test/old-elf/Mips/abi-flags-07.test
lld/trunk/test/old-elf/Mips/abi-flags-08.test
lld/trunk/test/old-elf/Mips/abi-flags-09.test
lld/trunk/test/old-elf/Mips/abi-flags-10.test
lld/trunk/test/old-elf/Mips/abi-flags-11.test
lld/trunk/test/old-elf/Mips/base-address-64.test
lld/trunk/test/old-elf/Mips/base-address.test
lld/trunk/test/old-elf/Mips/ctors-order.test
lld/trunk/test/old-elf/Mips/driver-hash-style.test
lld/trunk/test/old-elf/Mips/dt-textrel-64.test
lld/trunk/test/old-elf/Mips/dt-textrel.test
lld/trunk/test/old-elf/Mips/dynamic-linking.test
lld/trunk/test/old-elf/Mips/dynamic-sym.test
lld/trunk/test/old-elf/Mips/dynlib-dynamic.test
lld/trunk/test/old-elf/Mips/dynlib-dynsym-micro.test
lld/trunk/test/old-elf/Mips/dynlib-dynsym.test
lld/trunk/test/old-elf/Mips/dynlib-fileheader-64.test
lld/trunk/test/old-elf/Mips/dynlib-fileheader-micro-64.test
lld/trunk/test/old-elf/Mips/dynlib-fileheader-micro.test
lld/trunk/test/old-elf/Mips/dynlib-fileheader.test
lld/trunk/test/old-elf/Mips/dynsym-table-1.test
lld/trunk/test/old-elf/Mips/dynsym-table-2.test
lld/trunk/test/old-elf/Mips/e-flags-merge-1-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-1.test
lld/trunk/test/old-elf/Mips/e-flags-merge-10.test
lld/trunk/test/old-elf/Mips/e-flags-merge-11.test
lld/trunk/test/old-elf/Mips/e-flags-merge-12.test
lld/trunk/test/old-elf/Mips/e-flags-merge-2-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-2.test
lld/trunk/test/old-elf/Mips/e-flags-merge-3-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-3.test
lld/trunk/test/old-elf/Mips/e-flags-merge-4-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-4.test
lld/trunk/test/old-elf/Mips/e-flags-merge-5-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-5.test
lld/trunk/test/old-elf/Mips/e-flags-merge-6-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-6.test
lld/trunk/test/old-elf/Mips/e-flags-merge-7-64.test
lld/trunk/test/old-elf/Mips/e-flags-merge-7.test
lld/trunk/test/old-elf/Mips/e-flags-merge-8.test
lld/trunk/test/old-elf/Mips/e-flags-merge-9.test
lld/trunk/test/old-elf/Mips/entry-name.test
lld/trunk/test/old-elf/Mips/exe-dynamic.test
lld/trunk/test/old-elf/Mips/exe-dynsym-micro.test
lld/trunk/test/old-elf/Mips/exe-dynsym.test
lld/trunk/test/old-elf/Mips/exe-fileheader-02.test
lld/trunk/test/old-elf/Mips/exe-fileheader-03.test
lld/trunk/test/old-elf/Mips/exe-fileheader-64.test
lld/trunk/test/old-elf/Mips/exe-fileheader-be-64.test
lld/trunk/test/old-elf/Mips/exe-fileheader-be.test
lld/trunk/test/old-elf/Mips/exe-fileheader-micro-64.test
lld/trunk/test/old-elf/Mips/exe-fileheader-micro.test
lld/trunk/test/old-elf/Mips/exe-fileheader-n32.test
lld/trunk/test/old-elf/Mips/exe-fileheader.test
lld/trunk/test/old-elf/Mips/exe-got-micro.test
lld/trunk/test/old-elf/Mips/exe-got.test
lld/trunk/test/old-elf/Mips/got-page-32-micro.test
lld/trunk/test/old-elf/Mips/got-page-32.test
lld/trunk/test/old-elf/Mips/got-page-64-micro.test
lld/trunk/test/old-elf/Mips/got-page-64.test
lld/trunk/test/old-elf/Mips/got16-2.test
lld/trunk/test/old-elf/Mips/got16-micro.test
lld/trunk/test/old-elf/Mips/got16.test
lld/trunk/test/old-elf/Mips/gotsym.test
lld/trunk/test/old-elf/Mips/gp-sym-1-micro.test
lld/trunk/test/old-elf/Mips/gp-sym-1.test
lld/trunk/test/old-elf/Mips/gp-sym-2.test
lld/trunk/test/old-elf/Mips/hilo16-1.test
lld/trunk/test/old-elf/Mips/hilo16-2.test
lld/trunk/test/old-elf/Mips/hilo16-3-overflow.test
lld/trunk/test/old-elf/Mips/hilo16-3.test
lld/trunk/test/old-elf/Mips/hilo16-4.test
lld/trunk/test/old-elf/Mips/hilo16-5.test
lld/trunk/test/old-elf/Mips/hilo16-8-micro.test
lld/trunk/test/old-elf/Mips/hilo16-9-micro.test
lld/trunk/test/old-elf/Mips/initfini-micro.test
lld/trunk/test/old-elf/Mips/interpreter-64.test
lld/trunk/test/old-elf/Mips/interpreter-n32.test
lld/trunk/test/old-elf/Mips/interpreter.test
lld/trunk/test/old-elf/Mips/invalid-reginfo.test
lld/trunk/test/old-elf/Mips/jalx-align-err.test
lld/trunk/test/old-elf/Mips/jalx-jalr.test
lld/trunk/test/old-elf/Mips/jalx.test
lld/trunk/test/old-elf/Mips/jump-fix-err.test
lld/trunk/test/old-elf/Mips/la25-stub-be.test
lld/trunk/test/old-elf/Mips/la25-stub-micro-be.test
lld/trunk/test/old-elf/Mips/la25-stub-micro.test
lld/trunk/test/old-elf/Mips/la25-stub-npic-01.test
lld/trunk/test/old-elf/Mips/la25-stub-npic-02.test
lld/trunk/test/old-elf/Mips/la25-stub-npic-shared.test
lld/trunk/test/old-elf/Mips/la25-stub-pic.test
lld/trunk/test/old-elf/Mips/la25-stub.test
lld/trunk/test/old-elf/Mips/mips-options-01.test
lld/trunk/test/old-elf/Mips/mips-options-02.test
lld/trunk/test/old-elf/Mips/mips-options-03.test
lld/trunk/test/old-elf/Mips/mips-options-04.test
lld/trunk/test/old-elf/Mips/mips-options-05.test
lld/trunk/test/old-elf/Mips/mips-options-gp0.test
lld/trunk/test/old-elf/Mips/n32-rela-chain.test
lld/trunk/test/old-elf/Mips/n64-rel-chain.test
lld/trunk/test/old-elf/Mips/n64-rel-shift.test
lld/trunk/test/old-elf/Mips/opt-emulation.test
lld/trunk/test/old-elf/Mips/pc23-range.test
lld/trunk/test/old-elf/Mips/plt-entry-mixed-1.test
lld/trunk/test/old-elf/Mips/plt-entry-mixed-2.test
lld/trunk/test/old-elf/Mips/plt-entry-mixed-3.test
lld/trunk/test/old-elf/Mips/plt-entry-mixed-4.test
lld/trunk/test/old-elf/Mips/plt-entry-r6-be.test
lld/trunk/test/old-elf/Mips/plt-entry-r6.test
lld/trunk/test/old-elf/Mips/plt-header-be.test
lld/trunk/test/old-elf/Mips/plt-header-micro-be.test
lld/trunk/test/old-elf/Mips/plt-header-micro.test
lld/trunk/test/old-elf/Mips/plt-header-mixed.test
lld/trunk/test/old-elf/Mips/plt-header.test
lld/trunk/test/old-elf/Mips/r26-1-micro.test
lld/trunk/test/old-elf/Mips/r26-1.test
lld/trunk/test/old-elf/Mips/r26-2-micro.test
lld/trunk/test/old-elf/Mips/r26-2.test
lld/trunk/test/old-elf/Mips/reginfo-01.test
lld/trunk/test/old-elf/Mips/reginfo-02.test
lld/trunk/test/old-elf/Mips/reginfo-03.test
lld/trunk/test/old-elf/Mips/reginfo-04.test
lld/trunk/test/old-elf/Mips/reginfo-05.test
lld/trunk/test/old-elf/Mips/rel-16-overflow.test
lld/trunk/test/old-elf/Mips/rel-16.test
lld/trunk/test/old-elf/Mips/rel-32-be.test
lld/trunk/test/old-elf/Mips/rel-32.test
lld/trunk/test/old-elf/Mips/rel-64.test
lld/trunk/test/old-elf/Mips/rel-call-hilo-01.test
lld/trunk/test/old-elf/Mips/rel-call-hilo-micro.test
lld/trunk/test/old-elf/Mips/rel-copy-micro.test
lld/trunk/test/old-elf/Mips/rel-copy-pc.test
lld/trunk/test/old-elf/Mips/rel-copy.test
lld/trunk/test/old-elf/Mips/rel-dynamic-01-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-01.test
lld/trunk/test/old-elf/Mips/rel-dynamic-02.test
lld/trunk/test/old-elf/Mips/rel-dynamic-03-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-03.test
lld/trunk/test/old-elf/Mips/rel-dynamic-04-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-04.test
lld/trunk/test/old-elf/Mips/rel-dynamic-05-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-05.test
lld/trunk/test/old-elf/Mips/rel-dynamic-06-64.test
lld/trunk/test/old-elf/Mips/rel-dynamic-06.test
lld/trunk/test/old-elf/Mips/rel-dynamic-07-64.test
lld/trunk/test/old-elf/Mips/rel-dynamic-07.test
lld/trunk/test/old-elf/Mips/rel-dynamic-08-64.test
lld/trunk/test/old-elf/Mips/rel-dynamic-08-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-08.test
lld/trunk/test/old-elf/Mips/rel-dynamic-09-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-09.test
lld/trunk/test/old-elf/Mips/rel-dynamic-10-micro.test
lld/trunk/test/old-elf/Mips/rel-dynamic-10.test
lld/trunk/test/old-elf/Mips/rel-dynamic-11.test
lld/trunk/test/old-elf/Mips/rel-dynamic-12.test
lld/trunk/test/old-elf/Mips/rel-dynamic-13.test
lld/trunk/test/old-elf/Mips/rel-dynamic-14.test
lld/trunk/test/old-elf/Mips/rel-dynamic-15.test
lld/trunk/test/old-elf/Mips/rel-eh-01.test
lld/trunk/test/old-elf/Mips/rel-eh-02.test
lld/trunk/test/old-elf/Mips/rel-eh-03.test
lld/trunk/test/old-elf/Mips/rel-got-hilo-01.test
lld/trunk/test/old-elf/Mips/rel-got-hilo-micro.test
lld/trunk/test/old-elf/Mips/rel-gprel16-micro-overflow.test
lld/trunk/test/old-elf/Mips/rel-gprel16-micro.test
lld/trunk/test/old-elf/Mips/rel-gprel16-overflow.test
lld/trunk/test/old-elf/Mips/rel-gprel16.test
lld/trunk/test/old-elf/Mips/rel-gprel32-64.test
lld/trunk/test/old-elf/Mips/rel-gprel32.test
lld/trunk/test/old-elf/Mips/rel-gprel7-micro-overflow.test
lld/trunk/test/old-elf/Mips/rel-gprel7-micro.test
lld/trunk/test/old-elf/Mips/rel-hi0-lo16-micro.test
lld/trunk/test/old-elf/Mips/rel-high-01.test
lld/trunk/test/old-elf/Mips/rel-high-02.test
lld/trunk/test/old-elf/Mips/rel-jalr-01.test
lld/trunk/test/old-elf/Mips/rel-jalr-02.test
lld/trunk/test/old-elf/Mips/rel-lit-micro.test
lld/trunk/test/old-elf/Mips/rel-lit.test
lld/trunk/test/old-elf/Mips/rel-pc-hilo.test
lld/trunk/test/old-elf/Mips/rel-pc16-align.test
lld/trunk/test/old-elf/Mips/rel-pc16-overflow.test
lld/trunk/test/old-elf/Mips/rel-pc16.test
lld/trunk/test/old-elf/Mips/rel-pc18-s3-align.test
lld/trunk/test/old-elf/Mips/rel-pc18-s3-micro.test
lld/trunk/test/old-elf/Mips/rel-pc18-s3.test
lld/trunk/test/old-elf/Mips/rel-pc19-s2-align.test
lld/trunk/test/old-elf/Mips/rel-pc19-s2-micro.test
lld/trunk/test/old-elf/Mips/rel-pc19-s2.test
lld/trunk/test/old-elf/Mips/rel-pc21-s2-align.test
lld/trunk/test/old-elf/Mips/rel-pc21-s2-micro.test
lld/trunk/test/old-elf/Mips/rel-pc21-s2-overflow.test
lld/trunk/test/old-elf/Mips/rel-pc21-s2.test
lld/trunk/test/old-elf/Mips/rel-pc26-s2-align.test
lld/trunk/test/old-elf/Mips/rel-pc26-s2-micro.test
lld/trunk/test/old-elf/Mips/rel-pc26-s2.test
lld/trunk/test/old-elf/Mips/rel-pc32.test
lld/trunk/test/old-elf/Mips/rel-pc7-10-16-23.test
lld/trunk/test/old-elf/Mips/rel-sub-micro.test
lld/trunk/test/old-elf/Mips/rel-sub.test
lld/trunk/test/old-elf/Mips/rld_map.test
lld/trunk/test/old-elf/Mips/sign-rela.test
lld/trunk/test/old-elf/Mips/st-other.test
lld/trunk/test/old-elf/Mips/static-01.test
lld/trunk/test/old-elf/Mips/tls-1-micro.test
lld/trunk/test/old-elf/Mips/tls-1.test
lld/trunk/test/old-elf/Mips/tls-2-64-static.test
lld/trunk/test/old-elf/Mips/tls-2-64.test
lld/trunk/test/old-elf/Mips/tls-2-micro.test
lld/trunk/test/old-elf/Mips/tls-2-static.test
lld/trunk/test/old-elf/Mips/tls-2.test
lld/trunk/test/old-elf/Mips/tls-3-64-static.test
lld/trunk/test/old-elf/Mips/tls-3-micro.test
lld/trunk/test/old-elf/Mips/tls-3-static.test
lld/trunk/test/old-elf/Mips/tls-3.test
lld/trunk/test/old-elf/Mips/tls-4-64-static.test
lld/trunk/test/old-elf/Mips/tls-4-micro.test
lld/trunk/test/old-elf/Mips/tls-4-static.test
lld/trunk/test/old-elf/Mips/tls-4.test
lld/trunk/test/old-elf/Mips/tls-5-64.test
lld/trunk/test/old-elf/Mips/tls-5-micro.test
lld/trunk/test/old-elf/Mips/tls-5.test
lld/trunk/test/old-elf/Mips/validate-rel-01.test
lld/trunk/test/old-elf/Mips/validate-rel-03.test
lld/trunk/test/old-elf/X86_64/ExampleTarget/triple.test
lld/trunk/test/old-elf/X86_64/Inputs/constint.c
lld/trunk/test/old-elf/X86_64/Inputs/constint.o
lld/trunk/test/old-elf/X86_64/Inputs/debug0.c
lld/trunk/test/old-elf/X86_64/Inputs/debug0.x86-64
lld/trunk/test/old-elf/X86_64/Inputs/debug1.c
lld/trunk/test/old-elf/X86_64/Inputs/debug1.x86-64
lld/trunk/test/old-elf/X86_64/Inputs/externtls.c
lld/trunk/test/old-elf/X86_64/Inputs/externtls.x86-64
lld/trunk/test/old-elf/X86_64/Inputs/fn.c
lld/trunk/test/old-elf/X86_64/Inputs/fn.o
lld/trunk/test/old-elf/X86_64/Inputs/generaltls-so.o.yaml
lld/trunk/test/old-elf/X86_64/Inputs/group/1.c
lld/trunk/test/old-elf/X86_64/Inputs/group/1.o
lld/trunk/test/old-elf/X86_64/Inputs/group/fn.c
lld/trunk/test/old-elf/X86_64/Inputs/group/fn.o
lld/trunk/test/old-elf/X86_64/Inputs/group/fn1.c
lld/trunk/test/old-elf/X86_64/Inputs/group/fn1.o
lld/trunk/test/old-elf/X86_64/Inputs/group/fn2.c
lld/trunk/test/old-elf/X86_64/Inputs/group/fn2.o
lld/trunk/test/old-elf/X86_64/Inputs/group/group.sh
lld/trunk/test/old-elf/X86_64/Inputs/group/libfn.a
lld/trunk/test/old-elf/X86_64/Inputs/group/libfn.so
lld/trunk/test/old-elf/X86_64/Inputs/group/libfn1.a
lld/trunk/test/old-elf/X86_64/Inputs/group/libfn2.so
lld/trunk/test/old-elf/X86_64/Inputs/initfini-option.c
lld/trunk/test/old-elf/X86_64/Inputs/initfini-option.o
lld/trunk/test/old-elf/X86_64/Inputs/initfini.c
lld/trunk/test/old-elf/X86_64/Inputs/initfini.o
lld/trunk/test/old-elf/X86_64/Inputs/largebss.c
lld/trunk/test/old-elf/X86_64/Inputs/largebss.o
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/1.c
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/1.o
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/2.c
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/2.o
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/3.c
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/3.o
lld/trunk/test/old-elf/X86_64/Inputs/layoutpass/lib2.a
lld/trunk/test/old-elf/X86_64/Inputs/libfn.a
lld/trunk/test/old-elf/X86_64/Inputs/libfn.so
lld/trunk/test/old-elf/X86_64/Inputs/main.c
lld/trunk/test/old-elf/X86_64/Inputs/main.o
lld/trunk/test/old-elf/X86_64/Inputs/multi-ovrd.c
lld/trunk/test/old-elf/X86_64/Inputs/multi-ovrd.o
lld/trunk/test/old-elf/X86_64/Inputs/multi-weak.c
lld/trunk/test/old-elf/X86_64/Inputs/multi-weak.o
lld/trunk/test/old-elf/X86_64/Inputs/multiweaksyms.o
lld/trunk/test/old-elf/X86_64/Inputs/nmagic.c
lld/trunk/test/old-elf/X86_64/Inputs/nmagic.o
lld/trunk/test/old-elf/X86_64/Inputs/no-interp-section.c
lld/trunk/test/old-elf/X86_64/Inputs/no-interp-section.o
lld/trunk/test/old-elf/X86_64/Inputs/note.o
lld/trunk/test/old-elf/X86_64/Inputs/note.s
lld/trunk/test/old-elf/X86_64/Inputs/note_ro_rw.o
lld/trunk/test/old-elf/X86_64/Inputs/note_ro_rw.s
lld/trunk/test/old-elf/X86_64/Inputs/ovrd.c
lld/trunk/test/old-elf/X86_64/Inputs/ovrd.o
lld/trunk/test/old-elf/X86_64/Inputs/rodata.c
lld/trunk/test/old-elf/X86_64/Inputs/rodata.o
lld/trunk/test/old-elf/X86_64/Inputs/rodata.s
lld/trunk/test/old-elf/X86_64/Inputs/rwint.c
lld/trunk/test/old-elf/X86_64/Inputs/rwint.o
lld/trunk/test/old-elf/X86_64/Inputs/sectionmap.c
lld/trunk/test/old-elf/X86_64/Inputs/sectionmap.o
lld/trunk/test/old-elf/X86_64/Inputs/undefcpp.c
lld/trunk/test/old-elf/X86_64/Inputs/undefcpp.o
lld/trunk/test/old-elf/X86_64/Inputs/weak-zero-sized.o
lld/trunk/test/old-elf/X86_64/Inputs/weak.c
lld/trunk/test/old-elf/X86_64/Inputs/weak.o
lld/trunk/test/old-elf/X86_64/Inputs/weak.s
lld/trunk/test/old-elf/X86_64/Inputs/zerosizedsection.o
lld/trunk/test/old-elf/X86_64/Inputs/zerosizedsection.s
lld/trunk/test/old-elf/X86_64/alignoffset.test
lld/trunk/test/old-elf/X86_64/debug.test
lld/trunk/test/old-elf/X86_64/defsym.test
lld/trunk/test/old-elf/X86_64/demangle.test
lld/trunk/test/old-elf/X86_64/dontignorezerosize-sections.test
lld/trunk/test/old-elf/X86_64/dynamicvars.test
lld/trunk/test/old-elf/X86_64/dynlib-nointerp-section.test
lld/trunk/test/old-elf/X86_64/dynlib-search.test
lld/trunk/test/old-elf/X86_64/dynsym-weak.test
lld/trunk/test/old-elf/X86_64/extern-tls.test
lld/trunk/test/old-elf/X86_64/general-dynamic-tls.test
lld/trunk/test/old-elf/X86_64/imagebase.test
lld/trunk/test/old-elf/X86_64/initfini-order.test
lld/trunk/test/old-elf/X86_64/initfini.test
lld/trunk/test/old-elf/X86_64/largebss.test
lld/trunk/test/old-elf/X86_64/layoutpass-order.test
lld/trunk/test/old-elf/X86_64/maxpagesize.test
lld/trunk/test/old-elf/X86_64/mergesimilarstrings.test
lld/trunk/test/old-elf/X86_64/multi-weak-layout.test
lld/trunk/test/old-elf/X86_64/multi-weak-override.test
lld/trunk/test/old-elf/X86_64/multi-weak-syms-order.test
lld/trunk/test/old-elf/X86_64/nmagic.test
lld/trunk/test/old-elf/X86_64/noalignsegments.test
lld/trunk/test/old-elf/X86_64/note-sections-ro_plus_rw.test
lld/trunk/test/old-elf/X86_64/note-sections.test
lld/trunk/test/old-elf/X86_64/omagic.test
lld/trunk/test/old-elf/X86_64/outputsegments.test
lld/trunk/test/old-elf/X86_64/reloc_r_x86_64_16.test
lld/trunk/test/old-elf/X86_64/reloc_r_x86_64_pc16.test
lld/trunk/test/old-elf/X86_64/reloc_r_x86_64_pc64.test
lld/trunk/test/old-elf/X86_64/rodata.test
lld/trunk/test/old-elf/X86_64/sectionchoice.test
lld/trunk/test/old-elf/X86_64/sectionmap.test
lld/trunk/test/old-elf/X86_64/startGroupEndGroup.test
lld/trunk/test/old-elf/X86_64/startGroupEndGroupWithDynlib.test
lld/trunk/test/old-elf/X86_64/staticlib-search.test
lld/trunk/test/old-elf/X86_64/undef.test
lld/trunk/test/old-elf/X86_64/underscore-end.test
lld/trunk/test/old-elf/X86_64/weak-override.test
lld/trunk/test/old-elf/X86_64/weak-zero-sized.test
lld/trunk/test/old-elf/X86_64/weaksym.test
lld/trunk/test/old-elf/X86_64/yamlinput.test
lld/trunk/test/old-elf/abs-dup.objtxt
lld/trunk/test/old-elf/abs.test
lld/trunk/test/old-elf/allowduplicates.objtxt
lld/trunk/test/old-elf/archive-elf-forceload.test
lld/trunk/test/old-elf/archive-elf.test
lld/trunk/test/old-elf/as-needed.test
lld/trunk/test/old-elf/branch.test
lld/trunk/test/old-elf/check.test
lld/trunk/test/old-elf/checkrodata.test
lld/trunk/test/old-elf/common.test
lld/trunk/test/old-elf/consecutive-weak-sym-defs.test
lld/trunk/test/old-elf/defsym.objtxt
lld/trunk/test/old-elf/discard-all.test
lld/trunk/test/old-elf/discard-locals.test
lld/trunk/test/old-elf/dynamic-segorder.test
lld/trunk/test/old-elf/dynamic-undef.test
lld/trunk/test/old-elf/dynamic.test
lld/trunk/test/old-elf/eh_frame_hdr.test
lld/trunk/test/old-elf/entry.objtxt
lld/trunk/test/old-elf/export-dynamic.test
lld/trunk/test/old-elf/filenotfound.test
lld/trunk/test/old-elf/gnulinkonce/gnulinkonce-report-discarded-reference.test
lld/trunk/test/old-elf/gnulinkonce/gnulinkonce-report-undef.test
lld/trunk/test/old-elf/gnulinkonce/gnulinkonce.test
lld/trunk/test/old-elf/gotpcrel.test
lld/trunk/test/old-elf/gottpoff.test
lld/trunk/test/old-elf/group-cmd-search.test
lld/trunk/test/old-elf/hexagon-quickdata-sort.test
lld/trunk/test/old-elf/hexagon-quickdata-sortcommon.test
lld/trunk/test/old-elf/ifunc.test
lld/trunk/test/old-elf/ignore-unknownoption.test
lld/trunk/test/old-elf/init_array-order.test
lld/trunk/test/old-elf/init_array.test
lld/trunk/test/old-elf/initfini-options.test-1.test
lld/trunk/test/old-elf/initfini-options.test-2.test
lld/trunk/test/old-elf/initfini-options.test-3.test
lld/trunk/test/old-elf/librarynotfound.test
lld/trunk/test/old-elf/linker-as-ld.test
lld/trunk/test/old-elf/linkerscript/Inputs/externs.ls
lld/trunk/test/old-elf/linkerscript/Inputs/invalid.ls
lld/trunk/test/old-elf/linkerscript/Inputs/prog1.o.yaml
lld/trunk/test/old-elf/linkerscript/Inputs/prog2.o.yaml
lld/trunk/test/old-elf/linkerscript/Inputs/prog3.o.yaml
lld/trunk/test/old-elf/linkerscript/Inputs/simple-pic.o.yaml
lld/trunk/test/old-elf/linkerscript/Inputs/simple.o.yaml
lld/trunk/test/old-elf/linkerscript/Inputs/valid.ls
lld/trunk/test/old-elf/linkerscript/externs.objtxt
lld/trunk/test/old-elf/linkerscript/filename-with-wildcards.test
lld/trunk/test/old-elf/linkerscript/invalid-script-cli-1.test
lld/trunk/test/old-elf/linkerscript/invalid-script-cli-2.test
lld/trunk/test/old-elf/linkerscript/invalid.test
lld/trunk/test/old-elf/linkerscript/phdrs-all-none.test
lld/trunk/test/old-elf/linkerscript/phdrs-custom-none.test
lld/trunk/test/old-elf/linkerscript/phdrs-default.test
lld/trunk/test/old-elf/linkerscript/phdrs-different.test
lld/trunk/test/old-elf/linkerscript/phdrs-extra-program.test
lld/trunk/test/old-elf/linkerscript/phdrs-flags.test
lld/trunk/test/old-elf/linkerscript/phdrs-has-program.test
lld/trunk/test/old-elf/linkerscript/phdrs-invalid.test
lld/trunk/test/old-elf/linkerscript/phdrs-misplaced-program.test
lld/trunk/test/old-elf/linkerscript/phdrs-no-program.test
lld/trunk/test/old-elf/linkerscript/phdrs-one-none.test
lld/trunk/test/old-elf/linkerscript/phdrs-program-flags.test
lld/trunk/test/old-elf/linkerscript/phdrs-program-good-phdrs.test
lld/trunk/test/old-elf/linkerscript/phdrs-program-no-phdrs.test
lld/trunk/test/old-elf/linkerscript/phdrs-program-wrong-phdrs.test
lld/trunk/test/old-elf/linkerscript/phdrs-same-flags.test
lld/trunk/test/old-elf/linkerscript/phdrs-same.test
lld/trunk/test/old-elf/linkerscript/phdrs/sections-empty-phdrs.script
lld/trunk/test/old-elf/linkerscript/phdrs/sections-no-phdrs.script
lld/trunk/test/old-elf/linkerscript/phdrs/sections-none-phdrs.script
lld/trunk/test/old-elf/linkerscript/phdrs/undef-empty-phdrs.script
lld/trunk/test/old-elf/linkerscript/phdrs/undef-id-phdrs.script
lld/trunk/test/old-elf/linkerscript/phdrs/undef-no-phdrs.script
lld/trunk/test/old-elf/linkerscript/sections-order.test
lld/trunk/test/old-elf/linkerscript/sections-with-wildcards.test
lld/trunk/test/old-elf/linkerscript/symbol-definition-so.test
lld/trunk/test/old-elf/linkerscript/symbol-definition.test
lld/trunk/test/old-elf/linkerscript/valid-script-cli.objtxt
lld/trunk/test/old-elf/loginputfiles.test
lld/trunk/test/old-elf/mergeatoms.test
lld/trunk/test/old-elf/mergeconstants.test
lld/trunk/test/old-elf/mergeglobalatoms.test
lld/trunk/test/old-elf/no-unique-section-names.test
lld/trunk/test/old-elf/note.test
lld/trunk/test/old-elf/options/dynamic-linker.test
lld/trunk/test/old-elf/options/target-specific-args.test
lld/trunk/test/old-elf/phdr.test
lld/trunk/test/old-elf/quickdata.test
lld/trunk/test/old-elf/reloc.test
lld/trunk/test/old-elf/responsefile.test
lld/trunk/test/old-elf/rodata.test
lld/trunk/test/old-elf/rosegment.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-new-members.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-simple.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-undef-member-other.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-undef-member.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-with-globalsymbols.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-with-undef-external-reference.test
lld/trunk/test/old-elf/sectionGroups/sectiongroup-with-undef-signature.test
lld/trunk/test/old-elf/sections.test
lld/trunk/test/old-elf/sh_addralign.test
lld/trunk/test/old-elf/shndx.test
lld/trunk/test/old-elf/soname.test
lld/trunk/test/old-elf/start-stop-sym.test
lld/trunk/test/old-elf/strip-all.test
lld/trunk/test/old-elf/stripped-empty.test
lld/trunk/test/old-elf/symbols.test
lld/trunk/test/old-elf/tls-tbss-size.test
lld/trunk/test/old-elf/tls.test
lld/trunk/test/old-elf/tlsAddr.test
lld/trunk/test/old-elf/undef-from-dso-to-main.test
lld/trunk/test/old-elf/undef-from-main-dso.test
lld/trunk/test/old-elf/weaksym.test
lld/trunk/test/old-elf/wrap.test
lld/trunk/test/old-elf/x86-64-dynamic-relocs.test
lld/trunk/test/old-elf/x86-64-dynamic.test
lld/trunk/test/old-elf/x86.test
lld/trunk/test/old-elf/x86_64-kinds.test
lld/trunk/test/old-elf/zoption_dtflags.test
lld/trunk/unittests/DriverTests/GnuLdDriverTest.cpp
Modified:
lld/trunk/include/lld/Core/LinkingContext.h
lld/trunk/include/lld/Core/Reader.h
lld/trunk/include/lld/Core/Writer.h
lld/trunk/include/lld/Driver/Driver.h
lld/trunk/lib/Driver/CMakeLists.txt
lld/trunk/lib/Driver/UniversalDriver.cpp
lld/trunk/lib/ReaderWriter/CMakeLists.txt
lld/trunk/unittests/DriverTests/CMakeLists.txt
lld/trunk/unittests/DriverTests/UniversalDriverTest.cpp
Modified: lld/trunk/include/lld/Core/LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LinkingContext.h (original)
+++ lld/trunk/include/lld/Core/LinkingContext.h Sat Feb 27 18:10:58 2016
@@ -33,8 +33,7 @@ class SharedLibraryFile;
///
/// The base class LinkingContext contains the options needed by core linking.
/// Subclasses of LinkingContext have additional options needed by specific
-/// Writers. For example, ELFLinkingContext has methods that supplies
-/// options to the ELF Writer and ELF Passes.
+/// Writers.
class LinkingContext {
public:
/// \brief The types of output file that the linker creates.
Modified: lld/trunk/include/lld/Core/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reader.h?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Reader.h (original)
+++ lld/trunk/include/lld/Core/Reader.h Sat Feb 27 18:10:58 2016
@@ -27,7 +27,6 @@ class IO;
}
namespace lld {
-class ELFLinkingContext;
class File;
class LinkingContext;
class PECOFFLinkingContext;
@@ -117,8 +116,6 @@ public:
void addSupportCOFFObjects(PECOFFLinkingContext &);
void addSupportCOFFImportLibraries(PECOFFLinkingContext &);
void addSupportMachOObjects(MachOLinkingContext &);
- void addSupportELFObjects(ELFLinkingContext &);
- void addSupportELFDynamicSharedObjects(ELFLinkingContext &);
/// To convert between kind values and names, the registry walks the list
/// of registered kind tables. Each table is a zero terminated array of
Modified: lld/trunk/include/lld/Core/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Writer.h?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Writer.h (original)
+++ lld/trunk/include/lld/Core/Writer.h Sat Feb 27 18:10:58 2016
@@ -15,7 +15,6 @@
#include <vector>
namespace lld {
-class ELFLinkingContext;
class File;
class LinkingContext;
class MachOLinkingContext;
@@ -41,7 +40,6 @@ protected:
Writer();
};
-std::unique_ptr<Writer> createWriterELF(const ELFLinkingContext &);
std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &);
std::unique_ptr<Writer> createWriterPECOFF(const PECOFFLinkingContext &);
std::unique_ptr<Writer> createWriterYAML(const LinkingContext &);
Modified: lld/trunk/include/lld/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/Driver.h?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/Driver.h (original)
+++ lld/trunk/include/lld/Driver/Driver.h Sat Feb 27 18:10:58 2016
@@ -30,7 +30,6 @@ class LinkingContext;
class CoreLinkingContext;
class MachOLinkingContext;
class PECOFFLinkingContext;
-class ELFLinkingContext;
typedef std::vector<std::unique_ptr<File>> FileVector;
@@ -65,42 +64,6 @@ private:
UniversalDriver() = delete;
};
-/// Driver for gnu/binutil 'ld' command line options.
-class GnuLdDriver : public Driver {
-public:
- /// Parses command line arguments same as gnu/binutils ld and performs link.
- /// Returns true iff an error occurred.
- static bool linkELF(llvm::ArrayRef<const char *> args,
- raw_ostream &diag = llvm::errs());
-
- /// Uses gnu/binutils style ld command line options to fill in options struct.
- /// Returns true iff there was an error.
- static bool parse(llvm::ArrayRef<const char *> args,
- std::unique_ptr<ELFLinkingContext> &context,
- raw_ostream &diag = llvm::errs());
-
- /// Parses a given memory buffer as a linker script and evaluate that.
- /// Public function for testing.
- static std::error_code evalLinkerScript(ELFLinkingContext &ctx,
- std::unique_ptr<MemoryBuffer> mb,
- raw_ostream &diag, bool nostdlib);
-
- /// A factory method to create an instance of ELFLinkingContext.
- static std::unique_ptr<ELFLinkingContext>
- createELFLinkingContext(llvm::Triple triple);
-
-private:
- static llvm::Triple getDefaultTarget(const char *progName);
- static bool applyEmulation(llvm::Triple &triple,
- llvm::opt::InputArgList &args,
- raw_ostream &diag);
- static void addPlatformSearchDirs(ELFLinkingContext &ctx,
- llvm::Triple &triple,
- llvm::Triple &baseTriple);
-
- GnuLdDriver() = delete;
-};
-
/// Driver for darwin/ld64 'ld' command line options.
class DarwinLdDriver : public Driver {
public:
Removed: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (removed)
@@ -1,422 +0,0 @@
-//===- lld/ReaderWriter/ELFLinkingContext.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_LINKER_CONTEXT_H
-#define LLD_READER_WRITER_ELF_LINKER_CONTEXT_H
-
-#include "lld/Core/LinkingContext.h"
-#include "lld/Core/Pass.h"
-#include "lld/Core/PassManager.h"
-#include "lld/Core/STDExtras.h"
-#include "lld/Core/range.h"
-#include "lld/Core/Reader.h"
-#include "lld/Core/Writer.h"
-#include "lld/ReaderWriter/LinkerScript.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-#include <map>
-#include <memory>
-#include <set>
-
-namespace llvm {
-class FileOutputBuffer;
-}
-
-namespace lld {
-struct AtomLayout;
-class File;
-class Reference;
-
-namespace elf {
-using llvm::object::ELF32LE;
-using llvm::object::ELF32BE;
-using llvm::object::ELF64LE;
-using llvm::object::ELF64BE;
-
-class ELFWriter;
-
-std::unique_ptr<ELFLinkingContext> createAArch64LinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createAMDGPULinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createARMLinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createExampleLinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createHexagonLinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createMipsLinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createX86LinkingContext(llvm::Triple);
-std::unique_ptr<ELFLinkingContext> createX86_64LinkingContext(llvm::Triple);
-
-class TargetRelocationHandler {
-public:
- virtual ~TargetRelocationHandler() {}
-
- virtual std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const lld::AtomLayout &,
- const Reference &) const = 0;
-};
-
-} // namespace elf
-
-/// \brief TargetHandler contains all the information responsible to handle a
-/// a particular target on ELF. A target might wish to override implementation
-/// of creating atoms and how the atoms are written to the output file.
-class TargetHandler {
-public:
- virtual ~TargetHandler() {}
-
- /// Determines how relocations need to be applied.
- virtual const elf::TargetRelocationHandler &getRelocationHandler() const = 0;
-
- /// Returns a reader for object files.
- virtual std::unique_ptr<Reader> getObjReader() = 0;
-
- /// Returns a reader for .so files.
- virtual std::unique_ptr<Reader> getDSOReader() = 0;
-
- /// Returns a writer to write an ELF file.
- virtual std::unique_ptr<Writer> getWriter() = 0;
-};
-
-class ELFLinkingContext : public LinkingContext {
-public:
- /// \brief The type of ELF executable that the linker
- /// creates.
- enum class OutputMagic : uint8_t {
- // The default mode, no specific magic set
- DEFAULT,
- // Disallow shared libraries and don't align sections
- // PageAlign Data, Mark Text Segment/Data segment RW
- NMAGIC,
- // Disallow shared libraries and don't align sections,
- // Mark Text Segment/Data segment RW
- OMAGIC,
- };
-
- /// \brief ELF DT_FLAGS.
- enum DTFlag : uint32_t {
- DT_NOW = 1 << 1,
- DT_ORIGIN = 1 << 2,
- };
-
- llvm::Triple getTriple() const { return _triple; }
-
- uint64_t getPageSize() const { return _maxPageSize; }
- void setMaxPageSize(uint64_t v) { _maxPageSize = v; }
-
- OutputMagic getOutputMagic() const { return _outputMagic; }
- uint16_t getOutputELFType() const { return _outputELFType; }
- uint16_t getOutputMachine() const;
- bool mergeCommonStrings() const { return _mergeCommonStrings; }
- virtual int getMachineType() const = 0;
- virtual uint64_t getBaseAddress() const { return _baseAddress; }
- virtual void setBaseAddress(uint64_t address) { _baseAddress = address; }
-
- void notifySymbolTableCoalesce(const Atom *existingAtom, const Atom *newAtom,
- bool &useNew) override;
-
- /// This controls if undefined atoms need to be created for undefines that are
- /// present in a SharedLibrary. If this option is set, undefined atoms are
- /// created for every undefined symbol that are present in the dynamic table
- /// in the shared library
- bool useShlibUndefines() const { return _useShlibUndefines; }
-
- /// \brief Returns true if a given relocation should be added to the
- /// dynamic relocation table.
- ///
- /// This table is evaluated at loadtime by the dynamic loader and is
- /// referenced by the DT_RELA{,ENT,SZ} entries in the dynamic table.
- /// Relocations that return true will be added to the dynamic relocation
- /// table.
- virtual bool isDynamicRelocation(const Reference &) const { return false; }
-
- /// \brief Returns true if a given reference is a copy relocation.
- ///
- /// If this is a copy relocation, its target must be an ObjectAtom. We must
- /// include in DT_NEEDED the name of the library where this object came from.
- virtual bool isCopyRelocation(const Reference &) const { return false; }
-
- bool validateImpl(raw_ostream &diagnostics) override;
-
- /// \brief Returns true if the linker allows dynamic libraries to be
- /// linked with.
- ///
- /// This is true when the output mode of the executable is set to be
- /// having NMAGIC/OMAGIC
- bool allowLinkWithDynamicLibraries() const {
- if (_outputMagic == OutputMagic::NMAGIC ||
- _outputMagic == OutputMagic::OMAGIC || _noAllowDynamicLibraries)
- return false;
- return true;
- }
-
- /// \brief Use Elf_Rela format to output relocation tables.
- virtual bool isRelaOutputFormat() const { return true; }
-
- /// \brief Returns true if a given relocation should be added to PLT.
- ///
- /// This table holds all of the relocations used for delayed symbol binding.
- /// It will be evaluated at load time if LD_BIND_NOW is set. It is referenced
- /// by the DT_{JMPREL,PLTRELSZ} entries in the dynamic table.
- /// Relocations that return true will be added to the dynamic plt relocation
- /// table.
- virtual bool isPLTRelocation(const Reference &) const { return false; }
-
- /// \brief The path to the dynamic interpreter
- virtual StringRef getDefaultInterpreter() const {
- return "/lib64/ld-linux-x86-64.so.2";
- }
-
- /// \brief The dynamic linker path set by the --dynamic-linker option
- StringRef getInterpreter() const {
- if (_dynamicLinkerPath.hasValue())
- return _dynamicLinkerPath.getValue();
- return getDefaultInterpreter();
- }
-
- /// \brief Returns true if the output have dynamic sections.
- bool isDynamic() const;
-
- /// \brief Returns true if we are creating a shared library.
- bool isDynamicLibrary() const { return _outputELFType == llvm::ELF::ET_DYN; }
-
- /// \brief Returns true if a given relocation is a relative relocation.
- virtual bool isRelativeReloc(const Reference &r) const;
-
- TargetHandler &getTargetHandler() const {
- assert(_targetHandler && "Got null TargetHandler!");
- return *_targetHandler;
- }
-
- virtual void registerRelocationNames(Registry &) = 0;
-
- void addPasses(PassManager &pm) override;
-
- void setTriple(llvm::Triple trip) { _triple = trip; }
- void setNoInhibitExec(bool v) { _noInhibitExec = v; }
- void setExportDynamic(bool v) { _exportDynamic = v; }
- void setIsStaticExecutable(bool v) { _isStaticExecutable = v; }
- void setMergeCommonStrings(bool v) { _mergeCommonStrings = v; }
- void setUseShlibUndefines(bool use) { _useShlibUndefines = use; }
- void setOutputELFType(uint32_t type) { _outputELFType = type; }
-
- bool shouldExportDynamic() const { return _exportDynamic; }
-
- void createInternalFiles(std::vector<std::unique_ptr<File>> &) const override;
-
- void finalizeInputFiles() override;
-
- /// \brief Set the dynamic linker path
- void setInterpreter(StringRef s) { _dynamicLinkerPath = s; }
-
- /// \brief Set NMAGIC output kind when the linker specifies --nmagic
- /// or -n in the command line
- /// Set OMAGIC output kind when the linker specifies --omagic
- /// or -N in the command line
- void setOutputMagic(OutputMagic magic) { _outputMagic = magic; }
-
- /// \brief Disallow dynamic libraries during linking
- void setNoAllowDynamicLibraries() { _noAllowDynamicLibraries = true; }
-
- /// Searches directories for a match on the input File
- ErrorOr<StringRef> searchLibrary(StringRef libName) const;
-
- /// \brief Searches directories for a match on the input file.
- /// If \p fileName is an absolute path and \p isSysRooted is true, check
- /// the file under sysroot directory. If \p fileName is a relative path
- /// and is not in the current directory, search the file through library
- /// search directories.
- ErrorOr<StringRef> searchFile(StringRef fileName, bool isSysRooted) const;
-
- /// Get the entry symbol name
- StringRef entrySymbolName() const override;
-
- /// \brief Set new initializer function
- void setInitFunction(StringRef name) { _initFunction = name; }
-
- /// \brief Return an initializer function name.
- /// Either default "_init" or configured by the -init command line option.
- StringRef initFunction() const { return _initFunction; }
-
- /// \brief Set new finalizer function
- void setFiniFunction(StringRef name) { _finiFunction = name; }
-
- /// \brief Return a finalizer function name.
- /// Either default "_fini" or configured by the -fini command line option.
- StringRef finiFunction() const { return _finiFunction; }
-
- /// Add an absolute symbol. Used for --defsym.
- void addInitialAbsoluteSymbol(StringRef name, uint64_t addr) {
- _absoluteSymbols[name] = addr;
- }
-
- StringRef sharedObjectName() const { return _soname; }
- void setSharedObjectName(StringRef soname) { _soname = soname; }
-
- StringRef getSysroot() const { return _sysrootPath; }
- void setSysroot(StringRef path) { _sysrootPath = path; }
-
- void addRpath(StringRef path) { _rpathList.push_back(path); }
- range<const StringRef *> getRpathList() const { return _rpathList; }
-
- void addRpathLink(StringRef path) { _rpathLinkList.push_back(path); }
- range<const StringRef *> getRpathLinkList() const { return _rpathLinkList; }
-
- const std::map<std::string, uint64_t> &getAbsoluteSymbols() const {
- return _absoluteSymbols;
- }
-
- /// \brief Helper function to allocate strings.
- StringRef allocateString(StringRef ref) const {
- char *x = _allocator.Allocate<char>(ref.size() + 1);
- memcpy(x, ref.data(), ref.size());
- x[ref.size()] = '\0';
- return x;
- }
-
- // add search path to list.
- void addSearchPath(StringRef ref) { _inputSearchPaths.push_back(ref); }
-
- // Retrieve search path list.
- StringRefVector getSearchPaths() { return _inputSearchPaths; }
-
- // By default, the linker would merge sections that are read only with
- // segments that have read and execute permissions. When the user specifies a
- // flag --rosegment, a separate segment needs to be created.
- bool mergeRODataToTextSegment() const { return _mergeRODataToTextSegment; }
-
- void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; }
-
- bool isDynamicallyExportedSymbol(StringRef name) const {
- return _dynamicallyExportedSymbols.count(name) != 0;
- }
-
- /// \brief Demangle symbols.
- std::string demangle(StringRef symbolName) const override;
- bool demangleSymbols() const { return _demangle; }
- void setDemangleSymbols(bool d) { _demangle = d; }
-
- /// \brief Align segments.
- bool alignSegments() const { return _alignSegments; }
- void setAlignSegments(bool align) { _alignSegments = align; }
-
- /// \brief Enable new dtags.
- /// If this flag is set lld emits DT_RUNPATH instead of
- /// DT_RPATH. They are functionally equivalent except for
- /// the following two differences:
- /// - DT_RUNPATH is searched after LD_LIBRARY_PATH, while
- /// DT_RPATH is searched before.
- /// - DT_RUNPATH is used only to search for direct dependencies
- /// of the object it's contained in, while DT_RPATH is used
- /// for indirect dependencies as well.
- bool getEnableNewDtags() const { return _enableNewDtags; }
- void setEnableNewDtags(bool e) { _enableNewDtags = e; }
-
- /// \brief Discard local symbols.
- bool discardLocals() const { return _discardLocals; }
- void setDiscardLocals(bool d) { _discardLocals = d; }
-
- /// \brief Discard temprorary local symbols.
- bool discardTempLocals() const { return _discardTempLocals; }
- void setDiscardTempLocals(bool d) { _discardTempLocals = d; }
-
- /// \brief Strip symbols.
- bool stripSymbols() const { return _stripSymbols; }
- void setStripSymbols(bool strip) { _stripSymbols = strip; }
-
- /// \brief Collect statistics.
- bool collectStats() const { return _collectStats; }
- void setCollectStats(bool s) { _collectStats = s; }
-
- // --wrap option.
- void addWrapForSymbol(StringRef sym) { _wrapCalls.insert(sym); }
-
- // \brief Set DT_FLAGS flag.
- void setDTFlag(DTFlag f) { _dtFlags |= f; }
- bool getDTFlag(DTFlag f) { return (_dtFlags & f); }
-
- const llvm::StringSet<> &wrapCalls() const { return _wrapCalls; }
-
- void setUndefinesResolver(std::unique_ptr<File> resolver);
-
- script::Sema &linkerScriptSema() { return _linkerScriptSema; }
- const script::Sema &linkerScriptSema() const { return _linkerScriptSema; }
-
- /// Notify the ELFLinkingContext when the new ELF section is read.
- void notifyInputSectionName(StringRef name);
- /// Encountered C-ident input section names.
- const llvm::StringSet<> &cidentSectionNames() const {
- return _cidentSections;
- }
-
- // Set R_ARM_TARGET1 relocation behaviour
- bool armTarget1Rel() const { return _armTarget1Rel; }
- void setArmTarget1Rel(bool value) { _armTarget1Rel = value; }
-
- // Set R_MIPS_EH relocation behaviour.
- bool mipsPcRelEhRel() const { return _mipsPcRelEhRel; }
- void setMipsPcRelEhRel(bool value) { _mipsPcRelEhRel = value; }
-
-protected:
- ELFLinkingContext(llvm::Triple triple, std::unique_ptr<TargetHandler> handler)
- : _triple(triple), _targetHandler(std::move(handler)) {}
-
- Writer &writer() const override;
-
- /// Method to create a internal file for an undefined symbol
- std::unique_ptr<File> createUndefinedSymbolFile() const override;
-
- uint16_t _outputELFType = llvm::ELF::ET_EXEC;
- llvm::Triple _triple;
- std::unique_ptr<TargetHandler> _targetHandler;
- uint64_t _baseAddress = 0;
- bool _isStaticExecutable = false;
- bool _noInhibitExec = false;
- bool _exportDynamic = false;
- bool _mergeCommonStrings = false;
- bool _useShlibUndefines = true;
- bool _dynamicLinkerArg = false;
- bool _noAllowDynamicLibraries = false;
- bool _mergeRODataToTextSegment = true;
- bool _demangle = true;
- bool _discardTempLocals = false;
- bool _discardLocals = false;
- bool _stripSymbols = false;
- bool _alignSegments = true;
- bool _enableNewDtags = false;
- bool _collectStats = false;
- bool _armTarget1Rel = false;
- bool _mipsPcRelEhRel = false;
- uint64_t _maxPageSize = 0x1000;
- uint32_t _dtFlags = 0;
-
- OutputMagic _outputMagic = OutputMagic::DEFAULT;
- StringRefVector _inputSearchPaths;
- std::unique_ptr<Writer> _writer;
- llvm::Optional<StringRef> _dynamicLinkerPath;
- StringRef _initFunction = "_init";
- StringRef _finiFunction = "_fini";
- StringRef _sysrootPath = "";
- StringRef _soname;
- StringRefVector _rpathList;
- StringRefVector _rpathLinkList;
- llvm::StringSet<> _wrapCalls;
- std::map<std::string, uint64_t> _absoluteSymbols;
- llvm::StringSet<> _dynamicallyExportedSymbols;
- std::unique_ptr<File> _resolver;
- std::mutex _cidentMutex;
- llvm::StringSet<> _cidentSections;
-
- // The linker script semantic object, which owns all script ASTs, is stored
- // in the current linking context via _linkerScriptSema.
- script::Sema _linkerScriptSema;
-};
-
-} // end namespace lld
-
-#endif
Modified: lld/trunk/lib/Driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CMakeLists.txt?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CMakeLists.txt (original)
+++ lld/trunk/lib/Driver/CMakeLists.txt Sat Feb 27 18:10:58 2016
@@ -1,7 +1,5 @@
set(LLVM_TARGET_DEFINITIONS UniversalDriverOptions.td)
tablegen(LLVM UniversalDriverOptions.inc -gen-opt-parser-defs)
-set(LLVM_TARGET_DEFINITIONS GnuLdOptions.td)
-tablegen(LLVM GnuLdOptions.inc -gen-opt-parser-defs)
set(LLVM_TARGET_DEFINITIONS CoreOptions.td)
tablegen(LLVM CoreOptions.inc -gen-opt-parser-defs)
set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td)
@@ -12,7 +10,6 @@ add_lld_library(lldDriver
CoreDriver.cpp
DarwinLdDriver.cpp
Driver.cpp
- GnuLdDriver.cpp
UniversalDriver.cpp
ADDITIONAL_HEADER_DIRS
@@ -22,15 +19,7 @@ add_lld_library(lldDriver
lldConfig
lldMachO
lldCOFF
- lldELF
lldELF2
- lldAArch64ELFTarget
- lldARMELFTarget
- lldHexagonELFTarget
- lldMipsELFTarget
- lldX86ELFTarget
- lldExampleSubTarget
- lldX86_64ELFTarget
lldCore
lldReaderWriter
lldYAML
Removed: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp (removed)
@@ -1,782 +0,0 @@
-//===- lib/Driver/GnuLdDriver.cpp -----------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Concrete instance of the Driver for GNU's ld.
-///
-//===----------------------------------------------------------------------===//
-
-#include "lld/Driver/Driver.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/LinkerScript.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/Support/StringSaver.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstring>
-#include <tuple>
-
-using namespace lld;
-
-using llvm::BumpPtrAllocator;
-
-namespace {
-
-// Create enum with OPT_xxx values for each option in GnuLdOptions.td
-enum {
- OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
-#include "GnuLdOptions.inc"
-#undef OPTION
-};
-
-// Create prefix string literals used in GnuLdOptions.td
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "GnuLdOptions.inc"
-#undef PREFIX
-
-// Create table mapping all options defined in GnuLdOptions.td
-static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "GnuLdOptions.inc"
-#undef OPTION
-};
-
-
-// Create OptTable class for parsing actual command line arguments
-class GnuLdOptTable : public llvm::opt::OptTable {
-public:
- GnuLdOptTable() : OptTable(infoTable){}
-};
-
-} // anonymous namespace
-
-// If a command line option starts with "@", the driver reads its suffix as a
-// file, parse its contents as a list of command line options, and insert them
-// at the original @file position. If file cannot be read, @file is not expanded
-// and left unmodified. @file can appear in a response file, so it's a recursive
-// process.
-static llvm::ArrayRef<const char *>
-maybeExpandResponseFiles(llvm::ArrayRef<const char *> args,
- BumpPtrAllocator &alloc) {
- // Expand response files.
- SmallVector<const char *, 256> smallvec;
- for (const char *arg : args)
- smallvec.push_back(arg);
- llvm::StringSaver saver(alloc);
- llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec);
-
- // Pack the results to a C-array and return it.
- const char **copy = alloc.Allocate<const char *>(smallvec.size() + 1);
- std::copy(smallvec.begin(), smallvec.end(), copy);
- copy[smallvec.size()] = nullptr;
- return llvm::makeArrayRef(copy, smallvec.size() + 1);
-}
-
-// Parses an argument of --defsym=<sym>=<number>
-static bool parseDefsymAsAbsolute(StringRef opt, StringRef &sym,
- uint64_t &addr) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- sym = opt.substr(0, equalPos);
- if (opt.substr(equalPos + 1).getAsInteger(0, addr))
- return false;
- return true;
-}
-
-// Parses an argument of --defsym=<sym>=<sym>
-static bool parseDefsymAsAlias(StringRef opt, StringRef &sym,
- StringRef &target) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- sym = opt.substr(0, equalPos);
- target = opt.substr(equalPos + 1);
- return !target.empty();
-}
-
-// Parses -z max-page-size=<value>
-static bool parseMaxPageSize(StringRef opt, uint64_t &val) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- StringRef value = opt.substr(equalPos + 1);
- val = 0;
- if (value.getAsInteger(0, val) || !val)
- return false;
- return true;
-}
-
-bool GnuLdDriver::linkELF(llvm::ArrayRef<const char *> args,
- raw_ostream &diag) {
- BumpPtrAllocator alloc;
- args = maybeExpandResponseFiles(args, alloc);
- std::unique_ptr<ELFLinkingContext> options;
- if (!parse(args, options, diag))
- return false;
- if (!options)
- return true;
- bool linked = link(*options, diag);
-
- // Handle --stats.
- if (options->collectStats()) {
- llvm::TimeRecord t = llvm::TimeRecord::getCurrentTime(true);
- diag << "total time in link " << t.getProcessTime() << "\n";
- diag << "data size " << t.getMemUsed() << "\n";
- }
- return linked;
-}
-
-static llvm::Optional<llvm::Triple::ArchType>
-getArchType(const llvm::Triple &triple, StringRef value) {
- switch (triple.getArch()) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (value == "elf_i386")
- return llvm::Triple::x86;
- if (value == "elf_x86_64")
- return llvm::Triple::x86_64;
- return llvm::None;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return llvm::StringSwitch<llvm::Optional<llvm::Triple::ArchType>>(value)
- .Cases("elf32btsmip", "elf32btsmipn32", llvm::Triple::mips)
- .Cases("elf32ltsmip", "elf32ltsmipn32", llvm::Triple::mipsel)
- .Case("elf64btsmip", llvm::Triple::mips64)
- .Case("elf64ltsmip", llvm::Triple::mips64el)
- .Default(llvm::None);
- case llvm::Triple::aarch64:
- if (value == "aarch64linux")
- return llvm::Triple::aarch64;
- return llvm::None;
- case llvm::Triple::arm:
- if (value == "armelf_linux_eabi")
- return llvm::Triple::arm;
- return llvm::None;
- default:
- return llvm::None;
- }
-}
-
-static bool isLinkerScript(StringRef path, raw_ostream &diag) {
- llvm::sys::fs::file_magic magic = llvm::sys::fs::file_magic::unknown;
- if (std::error_code ec = llvm::sys::fs::identify_magic(path, magic)) {
- diag << "unknown input file format: " << path << ": "
- << ec.message() << "\n";
- return false;
- }
- return magic == llvm::sys::fs::file_magic::unknown;
-}
-
-static ErrorOr<StringRef>
-findFile(ELFLinkingContext &ctx, StringRef path, bool dashL) {
- // If the path was referred to by using a -l argument, let's search
- // for the file in the search path.
- if (dashL) {
- ErrorOr<StringRef> pathOrErr = ctx.searchLibrary(path);
- if (std::error_code ec = pathOrErr.getError())
- return make_dynamic_error_code(
- Twine("Unable to find library -l") + path + ": " + ec.message());
- path = pathOrErr.get();
- }
- if (!llvm::sys::fs::exists(path))
- return make_dynamic_error_code(
- Twine("lld: cannot find file ") + path);
- return path;
-}
-
-static bool isPathUnderSysroot(StringRef sysroot, StringRef path) {
- if (sysroot.empty())
- return false;
- while (!path.empty() && !llvm::sys::fs::equivalent(sysroot, path))
- path = llvm::sys::path::parent_path(path);
- return !path.empty();
-}
-
-static std::error_code
-addFilesFromLinkerScript(ELFLinkingContext &ctx, StringRef scriptPath,
- const std::vector<script::Path> &inputPaths,
- raw_ostream &diag) {
- bool sysroot = (!ctx.getSysroot().empty()
- && isPathUnderSysroot(ctx.getSysroot(), scriptPath));
- for (const script::Path &path : inputPaths) {
- ErrorOr<StringRef> pathOrErr = path._isDashlPrefix
- ? ctx.searchLibrary(path._path) : ctx.searchFile(path._path, sysroot);
- if (std::error_code ec = pathOrErr.getError()) {
- auto file = llvm::make_unique<ErrorFile>(path._path, ec);
- ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
- continue;
- }
-
- std::vector<std::unique_ptr<File>> files
- = loadFile(ctx, pathOrErr.get(), false);
- for (std::unique_ptr<File> &file : files) {
- if (ctx.logInputFiles())
- diag << file->path() << "\n";
- ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
- }
- }
- return std::error_code();
-}
-
-std::error_code GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx,
- std::unique_ptr<MemoryBuffer> mb,
- raw_ostream &diag,
- bool nostdlib) {
- // Read the script file from disk and parse.
- StringRef path = mb->getBufferIdentifier();
- auto parser = llvm::make_unique<script::Parser>(std::move(mb));
- if (std::error_code ec = parser->parse())
- return ec;
- script::LinkerScript *script = parser->get();
- if (!script)
- return LinkerScriptReaderError::parse_error;
- // Evaluate script commands.
- // Currently we only recognize this subset of linker script commands.
- for (const script::Command *c : script->_commands) {
- if (auto *input = dyn_cast<script::Input>(c))
- if (std::error_code ec = addFilesFromLinkerScript(
- ctx, path, input->getPaths(), diag))
- return ec;
- if (auto *group = dyn_cast<script::Group>(c)) {
- int origSize = ctx.getNodes().size();
- if (std::error_code ec = addFilesFromLinkerScript(
- ctx, path, group->getPaths(), diag))
- return ec;
- size_t groupSize = ctx.getNodes().size() - origSize;
- ctx.getNodes().push_back(llvm::make_unique<GroupEnd>(groupSize));
- }
- if (auto *searchDir = dyn_cast<script::SearchDir>(c))
- if (!nostdlib)
- ctx.addSearchPath(searchDir->getSearchPath());
- if (auto *entry = dyn_cast<script::Entry>(c))
- ctx.setEntrySymbolName(entry->getEntryName());
- if (auto *output = dyn_cast<script::Output>(c))
- ctx.setOutputPath(output->getOutputFileName());
- if (auto *externs = dyn_cast<script::Extern>(c)) {
- for (auto symbol : *externs) {
- ctx.addInitialUndefinedSymbol(symbol);
- }
- }
- }
- // Transfer ownership of the script to the linking context
- ctx.linkerScriptSema().addLinkerScript(std::move(parser));
- return std::error_code();
-}
-
-bool GnuLdDriver::applyEmulation(llvm::Triple &triple,
- llvm::opt::InputArgList &args,
- raw_ostream &diag) {
- llvm::opt::Arg *arg = args.getLastArg(OPT_m);
- if (!arg)
- return true;
- llvm::Optional<llvm::Triple::ArchType> arch =
- getArchType(triple, arg->getValue());
- if (!arch) {
- diag << "error: unsupported emulation '" << arg->getValue() << "'.\n";
- return false;
- }
- triple.setArch(*arch);
- return true;
-}
-
-void GnuLdDriver::addPlatformSearchDirs(ELFLinkingContext &ctx,
- llvm::Triple &triple,
- llvm::Triple &baseTriple) {
- if (triple.getOS() == llvm::Triple::NetBSD &&
- triple.getArch() == llvm::Triple::x86 &&
- baseTriple.getArch() == llvm::Triple::x86_64) {
- ctx.addSearchPath("=/usr/lib/i386");
- return;
- }
- ctx.addSearchPath("=/usr/lib");
-}
-
-std::unique_ptr<ELFLinkingContext>
-GnuLdDriver::createELFLinkingContext(llvm::Triple triple) {
- std::unique_ptr<ELFLinkingContext> p;
- if ((p = elf::createAArch64LinkingContext(triple))) return p;
- if ((p = elf::createARMLinkingContext(triple))) return p;
- if ((p = elf::createExampleLinkingContext(triple))) return p;
- if ((p = elf::createHexagonLinkingContext(triple))) return p;
- if ((p = elf::createMipsLinkingContext(triple))) return p;
- if ((p = elf::createX86LinkingContext(triple))) return p;
- if ((p = elf::createX86_64LinkingContext(triple))) return p;
- return nullptr;
-}
-
-static llvm::Optional<bool>
-getBool(const llvm::opt::InputArgList &parsedArgs,
- unsigned yesFlag, unsigned noFlag) {
- if (auto *arg = parsedArgs.getLastArg(yesFlag, noFlag))
- return arg->getOption().getID() == yesFlag;
- return llvm::None;
-}
-
-bool GnuLdDriver::parse(llvm::ArrayRef<const char *> args,
- std::unique_ptr<ELFLinkingContext> &context,
- raw_ostream &diag) {
- // Parse command line options using GnuLdOptions.td
- GnuLdOptTable table;
- unsigned missingIndex;
- unsigned missingCount;
-
- llvm::opt::InputArgList parsedArgs =
- table.ParseArgs(args.slice(1), missingIndex, missingCount);
- if (missingCount) {
- diag << "error: missing arg value for '"
- << parsedArgs.getArgString(missingIndex) << "' expected "
- << missingCount << " argument(s).\n";
- return false;
- }
-
- // Handle --help
- if (parsedArgs.hasArg(OPT_help)) {
- table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
- return true;
- }
-
- // Use -target or use default target triple to instantiate LinkingContext
- llvm::Triple baseTriple;
- if (auto *arg = parsedArgs.getLastArg(OPT_target)) {
- baseTriple = llvm::Triple(arg->getValue());
- } else {
- baseTriple = getDefaultTarget(args[0]);
- }
- llvm::Triple triple(baseTriple);
-
- if (!applyEmulation(triple, parsedArgs, diag))
- return false;
-
- std::unique_ptr<ELFLinkingContext> ctx(createELFLinkingContext(triple));
-
- if (!ctx) {
- diag << "unknown target triple\n";
- return false;
- }
-
- // Copy mllvm
- for (auto *arg : parsedArgs.filtered(OPT_mllvm))
- ctx->appendLLVMOption(arg->getValue());
-
- // Ignore unknown arguments.
- for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN))
- diag << "warning: ignoring unknown argument: "
- << unknownArg->getValue() << "\n";
-
- // Set sys root path.
- if (auto *arg = parsedArgs.getLastArg(OPT_sysroot))
- ctx->setSysroot(arg->getValue());
-
- // Handle --demangle option(For compatibility)
- if (parsedArgs.hasArg(OPT_demangle))
- ctx->setDemangleSymbols(true);
-
- // Handle --no-demangle option.
- if (parsedArgs.hasArg(OPT_no_demangle))
- ctx->setDemangleSymbols(false);
-
- // Figure out output kind (-r, -static, -shared)
- if (parsedArgs.hasArg(OPT_relocatable)) {
- ctx->setOutputELFType(llvm::ELF::ET_REL);
- ctx->setPrintRemainingUndefines(false);
- ctx->setAllowRemainingUndefines(true);
- }
-
- if (parsedArgs.hasArg(OPT_static)) {
- ctx->setOutputELFType(llvm::ELF::ET_EXEC);
- ctx->setIsStaticExecutable(true);
- }
-
- if (parsedArgs.hasArg(OPT_shared)) {
- ctx->setOutputELFType(llvm::ELF::ET_DYN);
- ctx->setAllowShlibUndefines(true);
- ctx->setUseShlibUndefines(false);
- ctx->setPrintRemainingUndefines(false);
- ctx->setAllowRemainingUndefines(true);
- }
-
- // Handle --stats.
- if (parsedArgs.hasArg(OPT_stats)) {
- ctx->setCollectStats(true);
- }
-
- // Figure out if the output type is nmagic/omagic
- if (auto *arg =
- parsedArgs.getLastArg(OPT_nmagic, OPT_omagic, OPT_no_omagic)) {
- switch (arg->getOption().getID()) {
- case OPT_nmagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC);
- ctx->setIsStaticExecutable(true);
- break;
- case OPT_omagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC);
- ctx->setIsStaticExecutable(true);
- break;
- case OPT_no_omagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT);
- ctx->setNoAllowDynamicLibraries();
- break;
- }
- }
-
- if (parsedArgs.hasArg(OPT_discard_loc))
- ctx->setDiscardLocals(true);
-
- if (parsedArgs.hasArg(OPT_discard_temp_loc))
- ctx->setDiscardTempLocals(true);
-
- if (parsedArgs.hasArg(OPT_strip_all))
- ctx->setStripSymbols(true);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_soname))
- ctx->setSharedObjectName(arg->getValue());
-
- if (parsedArgs.hasArg(OPT_rosegment))
- ctx->setCreateSeparateROSegment();
-
- if (parsedArgs.hasArg(OPT_no_align_segments))
- ctx->setAlignSegments(false);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_image_base)) {
- uint64_t baseAddress = 0;
- StringRef inputValue = arg->getValue();
- if (inputValue.getAsInteger(0, baseAddress) || !baseAddress) {
- diag << "invalid value for image base " << inputValue << "\n";
- return false;
- }
- ctx->setBaseAddress(baseAddress);
- }
-
- if (parsedArgs.hasArg(OPT_merge_strings))
- ctx->setMergeCommonStrings(true);
-
- if (parsedArgs.hasArg(OPT_t))
- ctx->setLogInputFiles(true);
-
- if (parsedArgs.hasArg(OPT_use_shlib_undefs))
- ctx->setUseShlibUndefines(true);
-
- if (auto val = getBool(parsedArgs, OPT_allow_shlib_undefs,
- OPT_no_allow_shlib_undefs))
- ctx->setAllowShlibUndefines(*val);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_e))
- ctx->setEntrySymbolName(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_output))
- ctx->setOutputPath(arg->getValue());
-
- if (parsedArgs.hasArg(OPT_noinhibit_exec))
- ctx->setAllowRemainingUndefines(true);
-
- if (auto val = getBool(parsedArgs, OPT_export_dynamic, OPT_no_export_dynamic))
- ctx->setExportDynamic(*val);
-
- if (parsedArgs.hasArg(OPT_allow_multiple_definition))
- ctx->setAllowDuplicates(true);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_dynamic_linker))
- ctx->setInterpreter(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_init))
- ctx->setInitFunction(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_fini))
- ctx->setFiniFunction(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_output_filetype))
- ctx->setOutputFileType(arg->getValue());
-
- // Process ELF/ARM specific options
- bool hasArmTarget1Rel = parsedArgs.hasArg(OPT_target1_rel);
- bool hasArmTarget1Abs = parsedArgs.hasArg(OPT_target1_abs);
- if (triple.getArch() == llvm::Triple::arm) {
- if (hasArmTarget1Rel && hasArmTarget1Abs) {
- diag << "error: options --target1-rel and --target1-abs"
- " can't be used together.\n";
- return false;
- } else if (hasArmTarget1Rel || hasArmTarget1Abs) {
- ctx->setArmTarget1Rel(hasArmTarget1Rel && !hasArmTarget1Abs);
- }
- } else {
- for (const auto *arg : parsedArgs.filtered(OPT_grp_arm_targetopts)) {
- diag << "warning: ignoring unsupported ARM/ELF specific argument: "
- << arg->getSpelling() << "\n";
- }
- }
-
- // Process MIPS specific options.
- if (triple.getArch() == llvm::Triple::mips ||
- triple.getArch() == llvm::Triple::mipsel ||
- triple.getArch() == llvm::Triple::mips64 ||
- triple.getArch() == llvm::Triple::mips64el) {
- ctx->setMipsPcRelEhRel(parsedArgs.hasArg(OPT_pcrel_eh_reloc));
- auto *hashArg = parsedArgs.getLastArg(OPT_hash_style);
- if (hashArg && hashArg->getValue() != StringRef("sysv")) {
- diag << "error: .gnu.hash is incompatible with the MIPS ABI\n";
- return false;
- }
- }
- else {
- for (const auto *arg : parsedArgs.filtered(OPT_grp_mips_targetopts)) {
- diag << "warning: ignoring unsupported MIPS specific argument: "
- << arg->getSpelling() << "\n";
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_L))
- ctx->addSearchPath(arg->getValue());
-
- // Add the default search directory specific to the target.
- if (!parsedArgs.hasArg(OPT_nostdlib))
- addPlatformSearchDirs(*ctx, triple, baseTriple);
-
- for (auto *arg : parsedArgs.filtered(OPT_u))
- ctx->addInitialUndefinedSymbol(arg->getValue());
-
- for (auto *arg : parsedArgs.filtered(OPT_defsym)) {
- StringRef sym, target;
- uint64_t addr;
- if (parseDefsymAsAbsolute(arg->getValue(), sym, addr)) {
- ctx->addInitialAbsoluteSymbol(sym, addr);
- } else if (parseDefsymAsAlias(arg->getValue(), sym, target)) {
- ctx->addAlias(sym, target);
- } else {
- diag << "invalid --defsym: " << arg->getValue() << "\n";
- return false;
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_z)) {
- StringRef opt = arg->getValue();
- if (opt == "muldefs")
- ctx->setAllowDuplicates(true);
- else if (opt == "now")
- ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_NOW);
- else if (opt == "origin")
- ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN);
- else if (opt.startswith("max-page-size")) {
- // Parse -z max-page-size option.
- // The default page size is considered the minimum page size the user
- // can set, check the user input if its atleast the minimum page size
- // and does not exceed the maximum page size allowed for the target.
- uint64_t maxPageSize = 0;
-
- // Error if the page size user set is less than the maximum page size
- // and greather than the default page size and the user page size is a
- // modulo of the default page size.
- if ((!parseMaxPageSize(opt, maxPageSize)) ||
- (maxPageSize < ctx->getPageSize()) ||
- (maxPageSize % ctx->getPageSize())) {
- diag << "invalid option: " << opt << "\n";
- return false;
- }
- ctx->setMaxPageSize(maxPageSize);
- } else {
- diag << "warning: ignoring unknown argument for -z: " << opt << "\n";
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_rpath)) {
- SmallVector<StringRef, 2> rpaths;
- StringRef(arg->getValue()).split(rpaths, ":");
- for (auto path : rpaths)
- ctx->addRpath(path);
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_rpath_link)) {
- SmallVector<StringRef, 2> rpaths;
- StringRef(arg->getValue()).split(rpaths, ":");
- for (auto path : rpaths)
- ctx->addRpathLink(path);
- }
-
- // Enable new dynamic tags.
- if (parsedArgs.hasArg(OPT_enable_newdtags))
- ctx->setEnableNewDtags(true);
-
- // Support --wrap option.
- for (auto *arg : parsedArgs.filtered(OPT_wrap))
- ctx->addWrapForSymbol(arg->getValue());
-
- // Register possible input file parsers.
- ctx->registry().addSupportELFObjects(*ctx);
- ctx->registry().addSupportArchives(ctx->logInputFiles());
- ctx->registry().addSupportYamlFiles();
- if (ctx->allowLinkWithDynamicLibraries())
- ctx->registry().addSupportELFDynamicSharedObjects(*ctx);
-
- // Parse the LLVM options before we process files in case the file handling
- // makes use of things like DEBUG().
- parseLLVMOptions(*ctx);
-
- std::stack<int> groupStack;
- int numfiles = 0;
- bool asNeeded = false;
- bool wholeArchive = false;
-
- // Process files
- for (auto arg : parsedArgs) {
- switch (arg->getOption().getID()) {
- case OPT_no_whole_archive:
- wholeArchive = false;
- break;
-
- case OPT_whole_archive:
- wholeArchive = true;
- break;
-
- case OPT_as_needed:
- asNeeded = true;
- break;
-
- case OPT_no_as_needed:
- asNeeded = false;
- break;
-
- case OPT_start_group:
- groupStack.push(numfiles);
- break;
-
- case OPT_end_group: {
- if (groupStack.empty()) {
- diag << "stray --end-group\n";
- return false;
- }
- int startGroupPos = groupStack.top();
- ctx->getNodes().push_back(
- llvm::make_unique<GroupEnd>(numfiles - startGroupPos));
- groupStack.pop();
- break;
- }
-
- case OPT_INPUT:
- case OPT_l:
- case OPT_T: {
- bool dashL = (arg->getOption().getID() == OPT_l);
- StringRef path = arg->getValue();
-
- ErrorOr<StringRef> pathOrErr = findFile(*ctx, path, dashL);
- if (std::error_code ec = pathOrErr.getError()) {
- auto file = llvm::make_unique<ErrorFile>(path, ec);
- auto node = llvm::make_unique<FileNode>(std::move(file));
- node->setAsNeeded(asNeeded);
- ctx->getNodes().push_back(std::move(node));
- break;
- }
- StringRef realpath = pathOrErr.get();
-
- bool isScript =
- (!path.endswith(".objtxt") && isLinkerScript(realpath, diag));
- if (isScript) {
- if (ctx->logInputFiles())
- diag << path << "\n";
- ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
- MemoryBuffer::getFileOrSTDIN(realpath);
- if (std::error_code ec = mb.getError()) {
- diag << "Cannot open " << path << ": " << ec.message() << "\n";
- return false;
- }
- bool nostdlib = parsedArgs.hasArg(OPT_nostdlib);
- std::error_code ec =
- evalLinkerScript(*ctx, std::move(mb.get()), diag, nostdlib);
- if (ec) {
- diag << path << ": Error parsing linker script: "
- << ec.message() << "\n";
- return false;
- }
- break;
- }
- std::vector<std::unique_ptr<File>> files
- = loadFile(*ctx, realpath, wholeArchive);
- for (std::unique_ptr<File> &file : files) {
- if (ctx->logInputFiles())
- diag << file->path() << "\n";
- auto node = llvm::make_unique<FileNode>(std::move(file));
- node->setAsNeeded(asNeeded);
- ctx->getNodes().push_back(std::move(node));
- }
- numfiles += files.size();
- break;
- }
- }
- }
-
- if (ctx->getNodes().empty()) {
- diag << "No input files\n";
- return false;
- }
-
- // Set default output file name if the output file was not specified.
- if (ctx->outputPath().empty()) {
- switch (ctx->outputFileType()) {
- case LinkingContext::OutputFileType::YAML:
- ctx->setOutputPath("-");
- break;
- default:
- ctx->setOutputPath("a.out");
- break;
- }
- }
-
- // Validate the combination of options used.
- if (!ctx->validate(diag))
- return false;
-
- // Perform linker script semantic actions
- if (auto ec = ctx->linkerScriptSema().perform()) {
- diag << "Error in the linker script's semantics: " << ec.message() << "\n";
- return false;
- }
-
- context.swap(ctx);
- return true;
-}
-
-/// Get the default target triple based on either the program name
-/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for.
-llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) {
- SmallVector<StringRef, 4> components;
- llvm::SplitString(llvm::sys::path::stem(progName), components, "-");
- // If has enough parts to be start with a triple.
- if (components.size() >= 4) {
- llvm::Triple triple(components[0], components[1], components[2],
- components[3]);
- // If first component looks like an arch.
- if (triple.getArch() != llvm::Triple::UnknownArch)
- return triple;
- }
-
- // Fallback to use whatever default triple llvm was configured for.
- return llvm::Triple(llvm::sys::getDefaultTargetTriple());
-}
Removed: lld/trunk/lib/Driver/GnuLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdOptions.td?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/Driver/GnuLdOptions.td (original)
+++ lld/trunk/lib/Driver/GnuLdOptions.td (removed)
@@ -1,378 +0,0 @@
-include "llvm/Option/OptParser.td"
-
-//===----------------------------------------------------------------------===//
-/// Utility Functions
-//===----------------------------------------------------------------------===//
-// Single and multiple dash options combined
-multiclass smDash<string opt1, string opt2, string help> {
- // Option
- def "" : Separate<["-"], opt1>, HelpText<help>;
- def opt1_eq : Joined<["-"], opt1#"=">,
- Alias<!cast<Option>(opt1)>;
- // Compatibility aliases
- def opt2_dashdash : Separate<["--"], opt2>,
- Alias<!cast<Option>(opt1)>;
- def opt2_dashdash_eq : Joined<["--"], opt2#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-// Support -<option>,-<option>=
-multiclass dashEq<string opt1, string opt2, string help> {
- // Option
- def "" : Separate<["-"], opt1>, HelpText<help>;
- // Compatibility aliases
- def opt2_eq : Joined<["-"], opt2#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-// Support --<option>,--<option>=
-multiclass mDashEq<string opt1, string help> {
- // Option
- def "" : Separate<["--"], opt1>, HelpText<help>;
- // Compatibility aliases
- def opt2_eq : Joined<["--"], opt1#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-//===----------------------------------------------------------------------===//
-/// LLVM and Target options
-//===----------------------------------------------------------------------===//
-def grp_llvmtarget : OptionGroup<"opts">,
- HelpText<"LLVM and Target Options">;
-def mllvm : Separate<["-"], "mllvm">,
- HelpText<"Options to pass to LLVM">, Group<grp_llvmtarget>;
-def target : Separate<["-"], "target">, MetaVarName<"<triple>">,
- HelpText<"Target triple to link for">,
- Group<grp_llvmtarget>;
-
-//===----------------------------------------------------------------------===//
-/// Output Kinds
-//===----------------------------------------------------------------------===//
-def grp_kind : OptionGroup<"outs">,
- HelpText<"OUTPUT KIND">;
-def relocatable : Flag<["-"], "r">,
- HelpText<"Create relocatable object file">, Group<grp_kind>;
-def static : Flag<["-"], "static">,
- HelpText<"Create static executable">, Group<grp_kind>;
-def dynamic : Flag<["-"], "dynamic">,
- HelpText<"Create dynamic executable (default)">,Group<grp_kind>;
-def shared : Flag<["-"], "shared">,
- HelpText<"Create dynamic library">, Group<grp_kind>;
-
-// output kinds - compatibility aliases
-def Bstatic : Flag<["-"], "Bstatic">, Alias<static>;
-def Bshareable : Flag<["-"], "Bshareable">, Alias<shared>;
-
-//===----------------------------------------------------------------------===//
-/// General Options
-//===----------------------------------------------------------------------===//
-def grp_general : OptionGroup<"opts">,
- HelpText<"GENERAL OPTIONS">;
-def output : Separate<["-"], "o">, MetaVarName<"<path>">,
- HelpText<"Path to file to write output">,
- Group<grp_general>;
-def m : JoinedOrSeparate<["-"], "m">, MetaVarName<"<emulation>">,
- HelpText<"Select target emulation">,
- Group<grp_general>;
-def build_id : Flag<["--"], "build-id">,
- HelpText<"Request creation of \".note.gnu.build-id\" ELF note section">,
- Group<grp_general>;
-def sysroot : Joined<["--"], "sysroot=">,
- HelpText<"Set the system root">,
- Group<grp_general>;
-
-
-//===----------------------------------------------------------------------===//
-/// Executable Options
-//===----------------------------------------------------------------------===//
-def grp_main : OptionGroup<"opts">,
- HelpText<"EXECUTABLE OPTIONS">;
-def L : Joined<["-"], "L">, MetaVarName<"<dir>">,
- HelpText<"Directory to search for libraries">,
- Group<grp_main>;
-def l : Joined<["-"], "l">, MetaVarName<"<libName>">,
- HelpText<"Root name of library to use">,
- Group<grp_main>;
-def noinhibit_exec : Flag<["--"], "noinhibit-exec">,
- HelpText<"Retain the executable output file whenever"
- " it is still usable">,
- Group<grp_main>;
-defm e : smDash<"e", "entry",
- "Name of entry point symbol">,
- Group<grp_main>;
-defm init: dashEq<"init", "init",
- "Specify an initializer function">,
- Group<grp_main>;
-defm fini: dashEq<"fini", "fini",
- "Specify a finalizer function">,
- Group<grp_main>;
-def whole_archive: Flag<["--"], "whole-archive">,
- HelpText<"Force load of all members in a static library">,
- Group<grp_main>;
-def no_whole_archive: Flag<["--"], "no-whole-archive">,
- HelpText<"Restores the default behavior of loading archive members">,
- Group<grp_main>;
-def nostdlib : Flag<["-"], "nostdlib">,
- HelpText<"Disable default search path for libraries">,
- Group<grp_main>;
-def image_base : Separate<["--"], "image-base">,
- HelpText<"Set the base address">,
- Group<grp_main>;
-
-//===----------------------------------------------------------------------===//
-/// Static Executable Options
-//===----------------------------------------------------------------------===//
-def grp_staticexec : OptionGroup<"opts">,
- HelpText<"STATIC EXECUTABLE OPTIONS">;
-def nmagic : Flag<["--"], "nmagic">,
- HelpText<"Turn off page alignment of sections,"
- " and disable linking against shared libraries">,
- Group<grp_staticexec>;
-def omagic : Flag<["--"], "omagic">,
- HelpText<"Set the text and data sections to be readable and writable."
- " Also, do not page-align the data segment, and"
- " disable linking against shared libraries.">,
- Group<grp_staticexec>;
-def no_omagic : Flag<["--"], "no-omagic">,
- HelpText<"This option negates most of the effects of the -N option."
- "Disable linking with shared libraries">,
- Group<grp_staticexec>;
-// Compatible Aliases
-def nmagic_alias : Flag<["-"], "n">,
- Alias<nmagic>;
-def omagic_alias : Flag<["-"], "N">,
- Alias<omagic>;
-
-//===----------------------------------------------------------------------===//
-/// Dynamic Library/Executable Options
-//===----------------------------------------------------------------------===//
-def grp_dynlibexec : OptionGroup<"opts">,
- HelpText<"DYNAMIC LIBRARY/EXECUTABLE OPTIONS">;
-def dynamic_linker : Joined<["--"], "dynamic-linker=">,
- HelpText<"Set the path to the dynamic linker">, Group<grp_dynlibexec>;
-// Executable options - compatibility aliases
-def dynamic_linker_alias : Separate<["-", "--"], "dynamic-linker">,
- Alias<dynamic_linker>;
-defm rpath : dashEq<"rpath", "rpath",
- "Add a directory to the runtime library search path">,
- Group<grp_dynlibexec>;
-def rpath_link : Separate<["-"], "rpath-link">,
- HelpText<"Specifies the first set of directories to search">,
- Group<grp_dynlibexec>;
-def export_dynamic : Flag<["-", "--"], "export-dynamic">,
- HelpText<"Add all symbols to the dynamic symbol table"
- " when creating executables">,
- Group<grp_main>;
-def alias_export_dynamic: Flag<["-"], "E">,
- Alias<export_dynamic>;
-def no_export_dynamic : Flag<["--"], "no-export-dynamic">,
- Group<grp_main>;
-
-//===----------------------------------------------------------------------===//
-/// Dynamic Library Options
-//===----------------------------------------------------------------------===//
-def grp_dynlib : OptionGroup<"opts">,
- HelpText<"DYNAMIC LIBRARY OPTIONS">;
-def soname : Joined<["-", "--"], "soname=">,
- HelpText<"Set the internal DT_SONAME field to the specified name">,
- Group<grp_dynlib>;
-def soname_separate : Separate<["-", "--"], "soname">, Alias<soname>;
-def soname_h : Separate<["-"], "h">, Alias<soname>;
-
-//===----------------------------------------------------------------------===//
-/// Resolver Options
-//===----------------------------------------------------------------------===//
-def grp_resolveropt : OptionGroup<"opts">,
- HelpText<"SYMBOL RESOLUTION OPTIONS">;
-defm u : smDash<"u", "undefined",
- "Force symbol to be entered in the output file"
- " as an undefined symbol">,
- Group<grp_resolveropt>;
-def start_group : Flag<["--"], "start-group">,
- HelpText<"Start a group">,
- Group<grp_resolveropt>;
-def alias_start_group: Flag<["-"], "(">,
- Alias<start_group>;
-def end_group : Flag<["--"], "end-group">,
- HelpText<"End a group">,
- Group<grp_resolveropt>;
-def alias_end_group: Flag<["-"], ")">,
- Alias<end_group>;
-def as_needed : Flag<["--"], "as-needed">,
- HelpText<"This option affects ELF DT_NEEDED tags for "
- "dynamic libraries mentioned on the command line">,
- Group<grp_resolveropt>;
-def no_as_needed : Flag<["--"], "no-as-needed">,
- HelpText<"This option restores the default behavior"
- " of adding DT_NEEDED entries">,
- Group<grp_resolveropt>;
-def no_allow_shlib_undefs : Flag<["--"], "no-allow-shlib-undefined">,
- HelpText<"Do not allow undefined symbols from dynamic"
- " library when creating executables">,
- Group<grp_resolveropt>;
-def allow_shlib_undefs : Flag<["-", "--"], "allow-shlib-undefined">,
- HelpText<"Allow undefined symbols from dynamic"
- " library when creating executables">,
- Group<grp_resolveropt>;
-def use_shlib_undefs: Flag<["--"], "use-shlib-undefines">,
- HelpText<"Resolve undefined symbols from dynamic libraries">,
- Group<grp_resolveropt>;
-def allow_multiple_definition: Flag<["--"], "allow-multiple-definition">,
- HelpText<"Allow multiple definitions">,
- Group<grp_resolveropt>;
-defm defsym : mDashEq<"defsym",
- "Create a global symbol in the output file "
- "containing the absolute address given by expression">,
- MetaVarName<"symbol=<expression>">,
- Group<grp_resolveropt>;
-
-//===----------------------------------------------------------------------===//
-/// Custom Options
-//===----------------------------------------------------------------------===//
-def grp_customopts : OptionGroup<"opts">,
- HelpText<"CUSTOM OPTIONS">;
-def disable_newdtags: Flag<["--"], "disable-new-dtags">,
- HelpText<"Disable new dynamic tags">,
- Group<grp_customopts>;
-def enable_newdtags: Flag<["--"], "enable-new-dtags">,
- HelpText<"Enable new dynamic tags">,
- Group<grp_customopts>;
-def rosegment: Flag<["--"], "rosegment">,
- HelpText<"Put read-only non-executable sections in their own segment">,
- Group<grp_customopts>;
-def z : Separate<["-"], "z">,
- HelpText<"Linker Option extensions">,
- Group<grp_customopts>;
-def no_align_segments: Flag<["--"], "no-align-segments">,
- HelpText<"Don't align ELF segments(virtualaddress/fileoffset) to page boundaries">,
- Group<grp_customopts>;
-
-//===----------------------------------------------------------------------===//
-/// Symbol options
-//===----------------------------------------------------------------------===//
-def grp_symbolopts : OptionGroup<"opts">,
- HelpText<"SYMBOL OPTIONS">;
-def demangle : Flag<["--"], "demangle">,
- HelpText<"Demangle C++ symbols">,
- Group<grp_symbolopts>;
-def discard_loc : Flag<["--"], "discard-all">,
- HelpText<"Discard all local symbols">,
- Group<grp_symbolopts>;
-def alias_discard_loc: Flag<["-"], "x">,
- Alias<discard_loc>;
-def discard_temp_loc : Flag<["--"], "discard-locals">,
- HelpText<"Discard temporary local symbols">,
- Group<grp_symbolopts>;
-def alias_discard_temp_loc : Flag<["-"], "X">,
- Alias<discard_temp_loc>;
-def no_demangle : Flag<["--"], "no-demangle">,
- HelpText<"Dont demangle C++ symbols">,
- Group<grp_symbolopts>;
-def strip_all : Flag<["--"], "strip-all">,
- HelpText<"Omit all symbol informations from output">,
- Group<grp_symbolopts>;
-def alias_strip_all : Flag<["-"], "s">,
- Alias<strip_all>;
-defm wrap : smDash<"wrap", "wrap",
- "Use a wrapper function for symbol. Any "
- " undefined reference to symbol will be resolved to "
- "\"__wrap_symbol\". Any undefined reference to \"__real_symbol\""
- " will be resolved to symbol.">,
- MetaVarName<"<symbol>">,
- Group<grp_symbolopts>;
-
-//===----------------------------------------------------------------------===//
-/// Script Options
-//===----------------------------------------------------------------------===//
-def grp_scriptopts : OptionGroup<"opts">,
- HelpText<"SCRIPT OPTIONS">;
-defm T : smDash<"T", "script",
- "Use the given linker script in place of the default script.">,
- Group<grp_scriptopts>;
-
-//===----------------------------------------------------------------------===//
-/// Optimization Options
-//===----------------------------------------------------------------------===//
-def grp_opts : OptionGroup<"opts">,
- HelpText<"OPTIMIZATIONS">;
-def hash_style : Joined <["--"], "hash-style=">,
- HelpText<"Set the type of linker's hash table(s)">,
- Group<grp_opts>;
-def merge_strings : Flag<["--"], "merge-strings">,
- HelpText<"Merge common strings across mergeable sections">,
- Group<grp_opts>;
-def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">,
- HelpText<"Request creation of .eh_frame_hdr section and ELF "
- " PT_GNU_EH_FRAME segment header">,
- Group<grp_opts>;
-
-//===----------------------------------------------------------------------===//
-/// Tracing Options
-//===----------------------------------------------------------------------===//
-def grp_tracingopts : OptionGroup<"opts">,
- HelpText<"TRACING OPTIONS">;
-def t : Flag<["-"], "t">,
- HelpText<"Print the names of the input files as ld processes them">,
- Group<grp_tracingopts>;
-def stats : Flag<["--"], "stats">,
- HelpText<"Print time and memory usage stats">, Group<grp_tracingopts>;
-
-//===----------------------------------------------------------------------===//
-/// Extensions
-//===----------------------------------------------------------------------===//
-def grp_extns : OptionGroup<"opts">,
- HelpText<"Extensions">;
-def output_filetype: Separate<["--"], "output-filetype">,
- HelpText<"Specify yaml to create an output in YAML format">,
- Group<grp_extns>;
-def alias_output_filetype: Joined<["--"], "output-filetype=">,
- Alias<output_filetype>;
-
-//===----------------------------------------------------------------------===//
-/// Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_targetopts : OptionGroup<"opts">,
- HelpText<"ARCH SPECIFIC OPTIONS">;
-
-//===----------------------------------------------------------------------===//
-/// ARM Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_arm_targetopts : OptionGroup<"ARM SPECIFIC OPTIONS">,
- Group<grp_targetopts>;
-def target1_rel : Flag<["--"], "target1-rel">,
- Group<grp_arm_targetopts>, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">;
-def target1_abs : Flag<["--"], "target1-abs">,
- Group<grp_arm_targetopts>, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">;
-
-//===----------------------------------------------------------------------===//
-/// MIPS Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_mips_targetopts : OptionGroup<"MIPS SPECIFIC OPTIONS">,
- Group<grp_targetopts>;
-def pcrel_eh_reloc : Flag<["-", "--"], "pcrel-eh-reloc">,
- Group<grp_mips_targetopts>,
- HelpText<"Interpret R_MIPS_EH as R_MIPS_PC32">;
-
-//===----------------------------------------------------------------------===//
-/// Ignored options
-//===----------------------------------------------------------------------===//
-def grp_ignored: OptionGroup<"ignored">,
- HelpText<"GNU Options ignored for Compatibility ">;
-def dashg : Flag<["-"], "g">,
- HelpText<"Ignored.">,
- Group<grp_ignored>;
-def Qy : Flag<["-"], "Qy">,
- HelpText<"Ignored for SVR4 Compatibility">,
- Group<grp_ignored>;
-def qmagic : Flag<["-"], "qmagic">,
- HelpText<"Ignored for Linux Compatibility">,
- Group<grp_ignored>;
-def G : Separate<["-"], "G">,
- HelpText<"Ignored for MIPS GNU Linker Compatibility">,
- Group<grp_ignored>;
-
-//===----------------------------------------------------------------------===//
-/// Help
-//===----------------------------------------------------------------------===//
-def help : Flag<["--"], "help">,
- HelpText<"Display this help message">;
Modified: lld/trunk/lib/Driver/UniversalDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/UniversalDriver.cpp?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/lib/Driver/UniversalDriver.cpp (original)
+++ lld/trunk/lib/Driver/UniversalDriver.cpp Sat Feb 27 18:10:58 2016
@@ -68,7 +68,6 @@ public:
enum class Flavor {
invalid,
- old_gnu_ld, // -flavor old-gnu
gnu_ld, // -flavor gnu
win_link, // -flavor link
darwin_ld, // -flavor darwin
@@ -84,7 +83,6 @@ struct ProgramNameParts {
static Flavor strToFlavor(StringRef str) {
return llvm::StringSwitch<Flavor>(str)
- .Case("old-gnu", Flavor::old_gnu_ld)
.Case("gnu", Flavor::gnu_ld)
.Case("ld.lld", Flavor::gnu_ld)
.Case("link", Flavor::win_link)
@@ -202,8 +200,6 @@ bool UniversalDriver::link(llvm::Mutable
// Switch to appropriate driver.
switch (flavor) {
- case Flavor::old_gnu_ld:
- return GnuLdDriver::linkELF(args, diagnostics);
case Flavor::gnu_ld:
return elf2::link(args, diagnostics);
case Flavor::darwin_ld:
Modified: lld/trunk/lib/ReaderWriter/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CMakeLists.txt?rev=262158&r1=262157&r2=262158&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/CMakeLists.txt Sat Feb 27 18:10:58 2016
@@ -1,4 +1,3 @@
-add_subdirectory(ELF)
add_subdirectory(MachO)
add_subdirectory(YAML)
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h (removed)
@@ -1,45 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h ---------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef AARCH64_DYNAMIC_LIBRARY_WRITER_H
-#define AARCH64_DYNAMIC_LIBRARY_WRITER_H
-
-#include "AArch64LinkingContext.h"
-#include "AArch64TargetHandler.h"
-#include "DynamicLibraryWriter.h"
-
-namespace lld {
-namespace elf {
-
-class AArch64DynamicLibraryWriter : public DynamicLibraryWriter<ELF64LE> {
-public:
- AArch64DynamicLibraryWriter(AArch64LinkingContext &ctx,
- TargetLayout<ELF64LE> &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-};
-
-AArch64DynamicLibraryWriter::AArch64DynamicLibraryWriter(
- AArch64LinkingContext &ctx, TargetLayout<ELF64LE> &layout)
- : DynamicLibraryWriter(ctx, layout) {}
-
-void AArch64DynamicLibraryWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter::createImplicitFiles(result);
- auto gotFile = llvm::make_unique<SimpleFile>("GOTFile", File::kindELFObject);
- gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile));
- gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile));
- result.push_back(std::move(gotFile));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp (removed)
@@ -1,52 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64LinkingContext.h"
-#include "AArch64ExecutableWriter.h"
-#include "AArch64TargetHandler.h"
-#include "AArch64SectionChunks.h"
-
-namespace lld {
-namespace elf {
-
-AArch64ExecutableWriter::AArch64ExecutableWriter(AArch64LinkingContext &ctx,
- AArch64TargetLayout &layout)
- : ExecutableWriter(ctx, layout), _targetLayout(layout) {}
-
-void AArch64ExecutableWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter::createImplicitFiles(result);
- auto gotFile = llvm::make_unique<SimpleFile>("GOTFile", File::kindELFObject);
- gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile));
- if (this->_ctx.isDynamic())
- gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile));
- result.push_back(std::move(gotFile));
-}
-
-void AArch64ExecutableWriter::buildDynamicSymbolTable(const File &file) {
- for (auto sec : this->_layout.sections()) {
- if (auto section = dyn_cast<AtomSection<ELF64LE>>(sec)) {
- for (const auto &atom : section->atoms()) {
- // Add all globals GOT symbols (in both .got and .got.plt sections)
- // on dynamic symbol table.
- for (const auto §ion : _targetLayout.getGOTSections()) {
- if (section->hasGlobalGOTEntry(atom->_atom))
- _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
- }
- }
- }
-
- ExecutableWriter<ELF64LE>::buildDynamicSymbolTable(file);
-}
-
-} // namespace elf
-} // namespace lld
-
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h (removed)
@@ -1,38 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef AARCH64_EXECUTABLE_WRITER_H
-#define AARCH64_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-
-namespace lld {
-namespace elf {
-
-class AArch64TargetLayout;
-class AArch64LinkingContext;
-
-class AArch64ExecutableWriter : public ExecutableWriter<ELF64LE> {
-public:
- AArch64ExecutableWriter(AArch64LinkingContext &ctx,
- AArch64TargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void buildDynamicSymbolTable(const File &file) override;
-
-private:
- AArch64TargetLayout &_targetLayout;
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp (removed)
@@ -1,45 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64LinkingContext.h"
-#include "AArch64RelocationPass.h"
-#include "AArch64TargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<ELFLinkingContext>
-elf::createAArch64LinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::aarch64)
- return llvm::make_unique<AArch64LinkingContext>(triple);
- return nullptr;
-}
-
-AArch64LinkingContext::AArch64LinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, std::unique_ptr<TargetHandler>(
- new AArch64TargetHandler(*this))) {}
-
-void AArch64LinkingContext::addPasses(PassManager &pm) {
- auto pass = createAArch64RelocationPass(*this);
- if (pass)
- pm.add(std::move(pass));
- ELFLinkingContext::addPasses(pm);
-}
-
-static const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/AArch64.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_END
-};
-
-void AArch64LinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF,
- Reference::KindArch::AArch64, kindStrings);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h (removed)
@@ -1,101 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_LINKING_CONTEXT_H
-#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_LINKING_CONTEXT_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-enum {
- /// \brief The offset to add operation for a R_AARCH64_ADR_GOT_PAGE
- ADD_AARCH64_GOTRELINDEX = 0xE000,
-};
-
-class AArch64LinkingContext final : public ELFLinkingContext {
-public:
- int getMachineType() const override { return llvm::ELF::EM_AARCH64; }
- AArch64LinkingContext(llvm::Triple);
-
- void addPasses(PassManager &) override;
- void registerRelocationNames(Registry &r) override;
-
- uint64_t getBaseAddress() const override {
- if (_baseAddress == 0)
- return 0x400000;
- return _baseAddress;
- }
-
- bool isDynamicRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::AArch64);
- switch (r.kindValue()) {
- case llvm::ELF::R_AARCH64_COPY:
- case llvm::ELF::R_AARCH64_GLOB_DAT:
- case llvm::ELF::R_AARCH64_RELATIVE:
- case llvm::ELF::R_AARCH64_TLS_DTPREL64:
- case llvm::ELF::R_AARCH64_TLS_DTPMOD64:
- case llvm::ELF::R_AARCH64_TLS_TPREL64:
- case llvm::ELF::R_AARCH64_TLSDESC:
- case llvm::ELF::R_AARCH64_IRELATIVE:
- return true;
- default:
- return false;
- }
- }
-
- bool isCopyRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::AArch64);
- if (r.kindValue() == llvm::ELF::R_AARCH64_COPY)
- return true;
- return false;
- }
-
- bool isPLTRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::AArch64);
- switch (r.kindValue()) {
- case llvm::ELF::R_AARCH64_JUMP_SLOT:
- case llvm::ELF::R_AARCH64_IRELATIVE:
- return true;
- default:
- return false;
- }
- }
-
- bool isRelativeReloc(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::AArch64);
- switch (r.kindValue()) {
- case llvm::ELF::R_AARCH64_IRELATIVE:
- case llvm::ELF::R_AARCH64_RELATIVE:
- return true;
- default:
- return false;
- }
- }
-
- /// \brief The path to the dynamic interpreter
- StringRef getDefaultInterpreter() const override {
- return "/lib/ld-linux-aarch64.so.1";
- }
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp (removed)
@@ -1,556 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp ----------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64TargetHandler.h"
-#include "AArch64LinkingContext.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/MathExtras.h"
-
-#define DEBUG_TYPE "AArch64"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm;
-using namespace llvm::support::endian;
-
-static int64_t page(int64_t v) { return v & ~int64_t(0xFFF); }
-
-/// \brief Check X is in the interval (-2^(bits-1), 2^bits]
-static bool withinSignedUnsignedRange(int64_t X, int bits) {
- return isIntN(bits - 1, X) || isUIntN(bits, X);
-}
-
-/// \brief R_AARCH64_ABS64 - word64: S + A
-static void relocR_AARCH64_ABS64(uint8_t *location, uint64_t P, uint64_t S,
- int64_t A) {
- int64_t result = (int64_t)S + A;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write64le(location, result | read64le(location));
-}
-
-/// \brief R_AARCH64_ABS32 - word32: S + A
-static std::error_code relocR_AARCH64_ABS32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A;
- if (!withinSignedUnsignedRange(result, 32))
- return make_out_of_range_reloc_error();
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_ABS16 - word16: S + A
-static std::error_code relocR_AARCH64_ABS16(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A;
- if (!withinSignedUnsignedRange(result, 16))
- return make_out_of_range_reloc_error();
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write16le(location, result | read16le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_PREL64 - word64: S + A - P
-static void relocR_AARCH64_PREL64(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A - P;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write64le(location, result + read64le(location));
-}
-
-/// \brief R_AARCH64_PREL32 - word32: S + A - P
-static std::error_code relocR_AARCH64_PREL32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A - P;
- // ELF for the ARM 64-bit architecture manual states the overflow
- // for R_AARCH64_PREL32 to be -2^(-31) <= X < 2^32
- if (!withinSignedUnsignedRange(result, 32))
- return make_out_of_range_reloc_error();
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write32le(location, result + read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_PREL16 - word16: S + A - P
-static std::error_code relocR_AARCH64_PREL16(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A - P;
- if (!withinSignedUnsignedRange(result, 16))
- return make_out_of_range_reloc_error();
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- write16le(location, result + read16le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_ADR_PREL_PG_HI21 - Page(S+A) - Page(P)
-static std::error_code relocR_AARCH64_ADR_PREL_PG_HI21(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- int64_t result = page(S + A) - page(P);
- if (!isInt<32>(result))
- return make_out_of_range_reloc_error();
- result = result >> 12;
- uint32_t immlo = result & 0x3;
- uint32_t immhi = result & 0x1FFFFC;
- immlo = immlo << 29;
- immhi = immhi << 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi);
- llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, immlo | immhi | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_ADR_PREL_LO21 - S + A - P
-static std::error_code relocR_AARCH64_ADR_PREL_LO21(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint64_t result = S + A - P;
- if (!isInt<20>(result))
- return make_out_of_range_reloc_error();
- uint32_t immlo = result & 0x3;
- uint32_t immhi = result & 0x1FFFFC;
- immlo = immlo << 29;
- immhi = immhi << 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi);
- llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, immlo | immhi | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_ADD_ABS_LO12_NC
-static void relocR_AARCH64_ADD_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)((S + A) & 0xFFF);
- result <<= 10;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_CALL26 and R_AARCH64_JUMP26
-static std::error_code relocJump26(uint8_t *location, uint64_t P, uint64_t S,
- int64_t A) {
- int64_t result = S + A - P;
- if (!isInt<27>(result))
- return make_out_of_range_reloc_error();
- result &= 0x0FFFFFFC;
- result >>= 2;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_CONDBR19
-static std::error_code relocR_AARCH64_CONDBR19(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int64_t result = S + A - P;
- if (!isInt<20>(result))
- return make_out_of_range_reloc_error();
- result &= 0x01FFFFC;
- result <<= 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_LDST8_ABS_LO12_NC - S + A
-static void relocR_AARCH64_LDST8_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)((S + A) & 0xFFF);
- result <<= 10;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_LDST16_ABS_LO12_NC
-static void relocR_AARCH64_LDST16_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- result &= 0x0FFC;
- result <<= 9;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_LDST32_ABS_LO12_NC
-static void relocR_AARCH64_LDST32_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- result &= 0x0FFC;
- result <<= 8;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_LDST64_ABS_LO12_NC
-static void relocR_AARCH64_LDST64_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- result &= 0x0FF8;
- result <<= 7;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_LDST128_ABS_LO12_NC
-static void relocR_AARCH64_LDST128_ABS_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- result &= 0x0FF8;
- result <<= 6;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-static std::error_code relocR_AARCH64_ADR_GOT_PAGE(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- uint64_t result = page(S + A) - page(P);
- if (!isInt<32>(result))
- return make_out_of_range_reloc_error();
- result = (result >> 12) & 0x3FFFF;
- uint32_t immlo = result & 0x3;
- uint32_t immhi = result & 0x1FFFFC;
- immlo = immlo << 29;
- immhi = immhi << 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi);
- llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, immlo | immhi | read32le(location));
- return std::error_code();
-}
-
-// R_AARCH64_LD64_GOT_LO12_NC
-static std::error_code relocR_AARCH64_LD64_GOT_LO12_NC(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- int32_t result = S + A;
- DEBUG(llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- if ((result & 0x7) != 0)
- return make_unaligned_range_reloc_error();
- result &= 0xFF8;
- result <<= 7;
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-// ADD_AARCH64_GOTRELINDEX
-static void relocADD_AARCH64_GOTRELINDEX(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = S + A;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- result &= 0xFFF;
- result <<= 10;
- write32le(location, result | read32le(location));
-}
-
-// R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
-static std::error_code relocR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21(uint8_t *location,
- uint64_t P,
- uint64_t S,
- int64_t A) {
- int64_t result = page(S + A) - page(P);
- if (!isInt<32>(result))
- return make_out_of_range_reloc_error();
- result >>= 12;
- uint32_t immlo = result & 0x3;
- uint32_t immhi = result & 0x1FFFFC;
- immlo = immlo << 29;
- immhi = immhi << 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi);
- llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, immlo | immhi | read32le(location));
- return std::error_code();
-}
-
-// R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
-static void relocR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- int32_t result = S + A;
- result &= 0xFF8;
- result <<= 7;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_TLSLE_ADD_TPREL_HI12
-static std::error_code relocR_AARCH64_TLSLE_ADD_TPREL_HI12(uint8_t *location,
- uint64_t P,
- uint64_t S,
- int64_t A) {
- int64_t result = S + A;
- if (!isUInt<24>(result))
- return make_out_of_range_reloc_error();
- result &= 0x0FFF000;
- result >>= 2;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
-static void relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- int32_t result = S + A;
- result &= 0x0FFF;
- result <<= 10;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-/// \brief R_AARCH64_TLSDESC_ADR_PAGE21 - Page(G(GTLSDESC(S+A))) - Page(P)
-static std::error_code relocR_AARCH64_TLSDESC_ADR_PAGE21(uint8_t *location,
- uint64_t P, uint64_t S,
- int64_t A) {
- int64_t result = page(S + A) - page(P);
- if (!isInt<32>(result))
- return make_out_of_range_reloc_error();
- result = result >> 12;
- uint32_t immlo = result & 0x3;
- uint32_t immhi = result & 0x1FFFFC;
- immlo = immlo << 29;
- immhi = immhi << 3;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi);
- llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, immlo | immhi | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_TLSDESC_LD64_LO12_NC - G(GTLSDESC(S+A)) -> S + A
-static std::error_code relocR_AARCH64_TLSDESC_LD64_LO12_NC(uint8_t *location,
- uint64_t P,
- uint64_t S,
- int64_t A) {
- int32_t result = S + A;
- DEBUG(llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- if ((result & 0x7) != 0)
- return make_unaligned_range_reloc_error();
- result &= 0xFF8;
- result <<= 7;
- write32le(location, result | read32le(location));
- return std::error_code();
-}
-
-/// \brief R_AARCH64_TLSDESC_ADD_LO12_NC - G(GTLSDESC(S+A)) -> S + A
-static void relocR_AARCH64_TLSDESC_ADD_LO12_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)((S + A) & 0xFFF);
- result <<= 10;
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: " << Twine::utohexstr(S);
- llvm::dbgs() << " A: " << Twine::utohexstr(A);
- llvm::dbgs() << " P: " << Twine::utohexstr(P);
- llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n");
- write32le(location, result | read32le(location));
-}
-
-std::error_code AArch64TargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
- int64_t addend = ref.addend();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::AArch64);
- switch (ref.kindValue()) {
- case R_AARCH64_NONE:
- break;
- case R_AARCH64_ABS64:
- relocR_AARCH64_ABS64(loc, reloc, target, addend);
- break;
- case R_AARCH64_ABS32:
- return relocR_AARCH64_ABS32(loc, reloc, target, addend);
- case R_AARCH64_ABS16:
- return relocR_AARCH64_ABS16(loc, reloc, target, addend);
- case R_AARCH64_PREL64:
- relocR_AARCH64_PREL64(loc, reloc, target, addend);
- break;
- case R_AARCH64_PREL32:
- return relocR_AARCH64_PREL32(loc, reloc, target, addend);
- case R_AARCH64_PREL16:
- return relocR_AARCH64_PREL16(loc, reloc, target, addend);
- case R_AARCH64_ADR_PREL_PG_HI21:
- return relocR_AARCH64_ADR_PREL_PG_HI21(loc, reloc, target, addend);
- case R_AARCH64_ADR_PREL_LO21:
- return relocR_AARCH64_ADR_PREL_LO21(loc, reloc, target, addend);
- case R_AARCH64_ADD_ABS_LO12_NC:
- relocR_AARCH64_ADD_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_CALL26:
- case R_AARCH64_JUMP26:
- return relocJump26(loc, reloc, target, addend);
- case R_AARCH64_CONDBR19:
- return relocR_AARCH64_CONDBR19(loc, reloc, target, addend);
- case R_AARCH64_ADR_GOT_PAGE:
- return relocR_AARCH64_ADR_GOT_PAGE(loc, reloc, target, addend);
- case R_AARCH64_LD64_GOT_LO12_NC:
- return relocR_AARCH64_LD64_GOT_LO12_NC(loc, reloc, target, addend);
- case R_AARCH64_LDST8_ABS_LO12_NC:
- relocR_AARCH64_LDST8_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_LDST16_ABS_LO12_NC:
- relocR_AARCH64_LDST16_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_LDST32_ABS_LO12_NC:
- relocR_AARCH64_LDST32_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_LDST64_ABS_LO12_NC:
- relocR_AARCH64_LDST64_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_LDST128_ABS_LO12_NC:
- relocR_AARCH64_LDST128_ABS_LO12_NC(loc, reloc, target, addend);
- break;
- case ADD_AARCH64_GOTRELINDEX:
- relocADD_AARCH64_GOTRELINDEX(loc, reloc, target, addend);
- break;
- case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
- return relocR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21(loc, reloc, target, addend);
- case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
- relocR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_TLSLE_ADD_TPREL_HI12:
- case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: {
- auto tpoffset = _layout.getTPOffset();
- if (ref.kindValue() == R_AARCH64_TLSLE_ADD_TPREL_HI12)
- return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target + tpoffset,
- addend);
- else
- relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target + tpoffset,
- addend);
- } break;
- case R_AARCH64_TLSDESC_ADR_PAGE21:
- return relocR_AARCH64_TLSDESC_ADR_PAGE21(loc, reloc, target, addend);
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
- return relocR_AARCH64_TLSDESC_LD64_LO12_NC(loc, reloc, target, addend);
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
- relocR_AARCH64_TLSDESC_ADD_LO12_NC(loc, reloc, target, addend);
- break;
- case R_AARCH64_TLSDESC_CALL:
- // Relaxation only to optimize TLS access. Ignore for now.
- break;
- // Runtime only relocations. Ignore here.
- case R_AARCH64_RELATIVE:
- case R_AARCH64_IRELATIVE:
- case R_AARCH64_JUMP_SLOT:
- case R_AARCH64_GLOB_DAT:
- case R_AARCH64_TLS_TPREL64:
- case R_AARCH64_TLSDESC:
- break;
- default:
- return make_unhandled_reloc_error();
- }
- return std::error_code();
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h (removed)
@@ -1,36 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h ------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef AARCH64_RELOCATION_HANDLER_H
-#define AARCH64_RELOCATION_HANDLER_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class AArch64TargetLayout;
-
-class AArch64TargetRelocationHandler final : public TargetRelocationHandler {
-public:
- AArch64TargetRelocationHandler(AArch64TargetLayout &layout)
- : _layout(layout) {}
-
- std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const AtomLayout &,
- const Reference &) const override;
-
-private:
- AArch64TargetLayout &_layout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // AArch64_RELOCATION_HANDLER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp (removed)
@@ -1,613 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the relocation processing pass for AArch64. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-/// This also includes additional behavior that gnu-ld and gold implement but
-/// which is not specified anywhere.
-///
-//===----------------------------------------------------------------------===//
-
-#include "AArch64RelocationPass.h"
-#include "AArch64LinkingContext.h"
-#include "Atoms.h"
-#include "lld/Core/Simple.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Debug.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-
-// .got values
-static const uint8_t AArch64GotAtomContent[8] = {0};
-
-// tls descriptor .got values, the layout is:
-// struct tlsdesc {
-// ptrdiff_t (*entry) (struct tlsdesc *);
-// void *arg;
-// };
-static const uint8_t AArch64TlsdescGotAtomContent[16] = {0};
-
-// .plt value (entry 0)
-static const uint8_t AArch64Plt0AtomContent[32] = {
- 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
- 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(eh_frame)
- 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16,#offset]
- 0x10, 0x02, 0x00, 0x91, // add x16, x16, #offset
- 0x20, 0x02, 0x1f, 0xd6, // br x17
- 0x1f, 0x20, 0x03, 0xd5, // nop
- 0x1f, 0x20, 0x03, 0xd5, // nop
- 0x1f, 0x20, 0x03, 0xd5 // nop
-};
-
-// .plt values (other entries)
-static const uint8_t AArch64PltAtomContent[16] = {
- 0x10, 0x00, 0x00, 0x90, // adrp x16, PAGE(<GLOBAL_OFFSET_TABLE>)
- 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16,#offset]
- 0x10, 0x02, 0x00, 0x91, // add x16, x16, #offset
- 0x20, 0x02, 0x1f, 0xd6 // br x17
-};
-
-// .plt tlsdesc values
-static const uint8_t AArch64PltTlsdescAtomContent[32] = {
- 0xe2, 0x0f, 0xbf, 0xa9, // stp x2, x3, [sp, #-16]
- 0x02, 0x00, 0x00, 0x90, // adpr x2, 0
- 0x03, 0x00, 0x00, 0x90, // adpr x3, 0
- 0x42, 0x00, 0x40, 0xf9, // ldr x2, [x2, #0]
- 0x63, 0x00, 0x00, 0x91, // add x3, x3, 0
- 0x40, 0x00, 0x1f, 0xd6, // br x2
- 0x1f, 0x20, 0x03, 0xd5, // nop
- 0x1f, 0x20, 0x03, 0xd5 // nop
-};
-
-namespace {
-
-/// \brief Atoms that are used by AArch64 dynamic linking
-class AArch64GOTAtom : public GOTAtom {
-public:
- AArch64GOTAtom(const File &f) : GOTAtom(f, ".got") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(AArch64GotAtomContent, 8);
- }
-
-protected:
- // Constructor for AArch64GOTAtom
- AArch64GOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {}
-};
-
-class AArch64GOTPLTAtom : public AArch64GOTAtom {
-public:
- AArch64GOTPLTAtom(const File &f) : AArch64GOTAtom(f, ".got.plt") {}
-};
-
-class AArch64TLSDESCGOTAtom : public AArch64GOTPLTAtom {
-public:
- AArch64TLSDESCGOTAtom(const File &f) : AArch64GOTPLTAtom(f) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(AArch64TlsdescGotAtomContent, 16);
- }
-};
-
-
-class AArch64PLT0Atom : public PLT0Atom {
-public:
- AArch64PLT0Atom(const File &f) : PLT0Atom(f) {}
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(AArch64Plt0AtomContent, 32);
- }
-};
-
-class AArch64PLTAtom : public PLTAtom {
-public:
- AArch64PLTAtom(const File &f) : PLTAtom(f, ".plt") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(AArch64PltAtomContent, 16);
- }
-};
-
-class AArch64PLTTLSDESCAtom : public PLTAtom {
-public:
- AArch64PLTTLSDESCAtom(const File &f) : PLTAtom(f, ".plt") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(AArch64PltTlsdescAtomContent, 32);
- }
-};
-
-class ELFPassFile : public SimpleFile {
-public:
- ELFPassFile(const ELFLinkingContext &eti)
- : SimpleFile("ELFPassFile", kindELFObject) {
- setOrdinal(eti.getNextOrdinalAndIncrement());
- }
-
- llvm::BumpPtrAllocator _alloc;
-};
-
-/// \brief CRTP base for handling relocations.
-template <class Derived> class AArch64RelocationPass : public Pass {
- /// \brief Handle a specific reference.
- void handleReference(const DefinedAtom &atom, const Reference &ref) {
- DEBUG_WITH_TYPE(
- "AArch64", llvm::dbgs()
- << "\t" << LLVM_FUNCTION_NAME << "()"
- << ": Name of Defined Atom: " << atom.name().str();
- llvm::dbgs() << " kindValue: " << ref.kindValue() << "\n");
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return;
- assert(ref.kindArch() == Reference::KindArch::AArch64);
- switch (ref.kindValue()) {
- case R_AARCH64_ABS32:
- case R_AARCH64_ABS16:
- case R_AARCH64_ABS64:
- case R_AARCH64_PREL16:
- case R_AARCH64_PREL32:
- case R_AARCH64_PREL64:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_GOTREL32:
- case R_AARCH64_GOTREL64:
- static_cast<Derived *>(this)->handleGOT(ref);
- break;
- case R_AARCH64_ADR_PREL_PG_HI21:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_LDST8_ABS_LO12_NC:
- case R_AARCH64_LDST16_ABS_LO12_NC:
- case R_AARCH64_LDST32_ABS_LO12_NC:
- case R_AARCH64_LDST64_ABS_LO12_NC:
- case R_AARCH64_LDST128_ABS_LO12_NC:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_ADD_ABS_LO12_NC:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_CALL26:
- case R_AARCH64_JUMP26:
- case R_AARCH64_CONDBR19:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_TLSLE_ADD_TPREL_HI12:
- case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_AARCH64_ADR_GOT_PAGE:
- case R_AARCH64_LD64_GOT_LO12_NC:
- static_cast<Derived *>(this)->handleGOT(ref);
- break;
- case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
- case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
- static_cast<Derived *>(this)->handleGOTTPREL(ref);
- break;
- case R_AARCH64_TLSDESC_ADR_PAGE21:
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
- static_cast<Derived *>(this)->handleTLSDESC(ref);
- break;
- }
- }
-
-protected:
- /// \brief get the PLT entry for a given IFUNC Atom.
- ///
- /// If the entry does not exist. Both the GOT and PLT entry is created.
- const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da) {
- auto plt = _pltMap.find(da);
- if (plt != _pltMap.end())
- return plt->second;
- auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file);
- ga->addReferenceELF_AArch64(R_AARCH64_IRELATIVE, 0, da, 0);
- auto pa = new (_file._alloc) AArch64PLTAtom(_file);
- pa->addReferenceELF_AArch64(R_AARCH64_PREL32, 2, ga, -4);
-#ifndef NDEBUG
- ga->_name = "__got_ifunc_";
- ga->_name += da->name();
- pa->_name = "__plt_ifunc_";
- pa->_name += da->name();
-#endif
- _gotMap[da] = ga;
- _pltMap[da] = pa;
- _gotVector.push_back(ga);
- _pltVector.push_back(pa);
- return pa;
- }
-
- /// \brief Redirect the call to the PLT stub for the target IFUNC.
- ///
- /// This create a PLT and GOT entry for the IFUNC if one does not exist. The
- /// GOT entry and a IRELATIVE relocation to the original target resolver.
- std::error_code handleIFUNC(const Reference &ref) {
- auto target = dyn_cast_or_null<const DefinedAtom>(ref.target());
- if (target && target->contentType() == DefinedAtom::typeResolver)
- const_cast<Reference &>(ref).setTarget(getIFUNCPLTEntry(target));
- return std::error_code();
- }
-
- /// \brief Create a GOT entry for the TP offset of a TLS atom.
- const GOTAtom *getGOTTPREL(const Atom *atom) {
- auto got = _gotMap.find(atom);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) AArch64GOTAtom(_file);
- g->addReferenceELF_AArch64(R_AARCH64_TLS_TPREL64, 0, atom, 0);
-#ifndef NDEBUG
- g->_name = "__got_tls_";
- g->_name += atom->name();
-#endif
- _gotMap[atom] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
- /// \brief Create a GOT TPREL entry to local or external TLS variable.
- std::error_code handleGOTTPREL(const Reference &ref) {
- if (isa<DefinedAtom>(ref.target()) ||
- isa<SharedLibraryAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOTTPREL(ref.target()));
- return std::error_code();
- }
-
- /// \brief Generates a double GOT entry with R_AARCH64_TLSDESC dynamic
- /// relocation reference. Since the dynamic relocation is resolved
- /// lazily so the GOT associated should be in .got.plt.
- const GOTAtom *getTLSDESCPLTEntry(const Atom *da) {
- auto got = _gotMap.find(da);
- if (got != _gotMap.end())
- return got->second;
- auto ga = new (_file._alloc) AArch64TLSDESCGOTAtom(_file);
- ga->addReferenceELF_AArch64(R_AARCH64_TLSDESC, 0, da, 0);
- auto pa = new (_file._alloc) AArch64PLTTLSDESCAtom(_file);
- pa->addReferenceELF_AArch64(R_AARCH64_ADR_PREL_PG_HI21, 4, ga, 0);
- pa->addReferenceELF_AArch64(R_AARCH64_ADR_PREL_PG_HI21, 8, ga, 0);
- pa->addReferenceELF_AArch64(R_AARCH64_LDST64_ABS_LO12_NC, 12, ga, 0);
- pa->addReferenceELF_AArch64(R_AARCH64_ADD_ABS_LO12_NC, 16, ga, 0);
-#ifndef NDEBUG
- ga->_name = "__got_tlsdesc_";
- ga->_name += da->name();
- pa->_name = "__plt_tlsdesc_";
- pa->_name += da->name();
-#endif
- _gotMap[da] = ga;
- _pltMap[da] = pa;
- _tlsdescVector.push_back(ga);
- _pltVector.push_back(pa);
- return ga;
- }
-
- std::error_code handleTLSDESC(const Reference &ref) {
- if (isa<DefinedAtom>(ref.target()) ||
- isa<SharedLibraryAtom>(ref.target())) {
- const_cast<Reference &>(ref).setTarget(getTLSDESCPLTEntry(ref.target()));
- }
- return std::error_code();
- }
-
- /// \brief Create a GOT entry containing 0.
- const GOTAtom *getNullGOT() {
- if (!_null) {
- _null = new (_file._alloc) AArch64GOTPLTAtom(_file);
-#ifndef NDEBUG
- _null->_name = "__got_null";
-#endif
- }
- return _null;
- }
-
- const GOTAtom *getGOT(const DefinedAtom *da) {
- auto got = _gotMap.find(da);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) AArch64GOTAtom(_file);
- g->addReferenceELF_AArch64(R_AARCH64_ABS64, 0, da, 0);
-#ifndef NDEBUG
- g->_name = "__got_";
- g->_name += da->name();
-#endif
- _gotMap[da] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
-public:
- AArch64RelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {}
-
- /// \brief Do the pass.
- ///
- /// The goal here is to first process each reference individually. Each call
- /// to handleReference may modify the reference itself and/or create new
- /// atoms which must be stored in one of the maps below.
- ///
- /// After all references are handled, the atoms created during that are all
- /// added to mf.
- std::error_code perform(SimpleFile &mf) override {
- ScopedTask task(getDefaultDomain(), "AArch64 GOT/PLT Pass");
- DEBUG_WITH_TYPE(
- "AArch64", llvm::dbgs() << "Undefined Atoms"
- << "\n";
- for (const auto &atom
- : mf.undefined()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- } llvm::dbgs()
- << "Shared Library Atoms"
- << "\n";
- for (const auto &atom
- : mf.sharedLibrary()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- } llvm::dbgs()
- << "Absolute Atoms"
- << "\n";
- for (const auto &atom
- : mf.absolute()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- }
- // Process all references.
- llvm::dbgs()
- << "Defined Atoms"
- << "\n");
- for (const auto &atom : mf.defined()) {
- for (const auto &ref : *atom) {
- handleReference(*atom, *ref);
- }
- }
-
- // Add all created atoms to the link.
- uint64_t ordinal = 0;
- if (_plt0) {
- _plt0->setOrdinal(ordinal++);
- mf.addAtom(*_plt0);
- }
- for (auto &plt : _pltVector) {
- plt->setOrdinal(ordinal++);
- mf.addAtom(*plt);
- }
- if (_null) {
- _null->setOrdinal(ordinal++);
- mf.addAtom(*_null);
- }
- if (_plt0) {
- _got0->setOrdinal(ordinal++);
- _got1->setOrdinal(ordinal++);
- mf.addAtom(*_got0);
- mf.addAtom(*_got1);
- }
- for (auto &got : _gotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
- // Add any tlsdesc GOT relocation after default PLT and iFUNC entries.
- for (auto &tlsdesc : _tlsdescVector) {
- tlsdesc->setOrdinal(ordinal++);
- mf.addAtom(*tlsdesc);
- }
- for (auto obj : _objectVector) {
- obj->setOrdinal(ordinal++);
- mf.addAtom(*obj);
- }
-
- return std::error_code();
- }
-
-protected:
- /// \brief Owner of all the Atoms created by this pass.
- ELFPassFile _file;
- const ELFLinkingContext &_ctx;
-
- /// \brief Map Atoms to their GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
-
- /// \brief Map Atoms to their PLT entries.
- llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
-
- /// \brief Map Atoms to their Object entries.
- llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
-
- /// \brief the list of GOT/PLT atoms
- std::vector<GOTAtom *> _gotVector;
- std::vector<GOTAtom *> _tlsdescVector;
- std::vector<PLTAtom *> _pltVector;
- std::vector<ObjectAtom *> _objectVector;
-
- /// \brief GOT entry that is always 0. Used for undefined weaks.
- GOTAtom *_null = nullptr;
-
- /// \brief The got and plt entries for .PLT0. This is used to call into the
- /// dynamic linker for symbol resolution.
- /// @{
- PLT0Atom *_plt0 = nullptr;
- GOTAtom *_got0 = nullptr;
- GOTAtom *_got1 = nullptr;
- /// @}
-};
-
-/// This implements the static relocation model. Meaning GOT and PLT entries are
-/// not created for references that can be directly resolved. These are
-/// converted to a direct relocation. For entries that do require a GOT or PLT
-/// entry, that entry is statically bound.
-///
-/// TLS always assumes module 1 and attempts to remove indirection.
-class AArch64StaticRelocationPass final
- : public AArch64RelocationPass<AArch64StaticRelocationPass> {
-public:
- AArch64StaticRelocationPass(const elf::AArch64LinkingContext &ctx)
- : AArch64RelocationPass(ctx) {}
-
- std::error_code handlePlain(const Reference &ref) { return handleIFUNC(ref); }
-
- std::error_code handlePLT32(const Reference &ref) {
- // __tls_get_addr is handled elsewhere.
- if (ref.target() && ref.target()->name() == "__tls_get_addr") {
- const_cast<Reference &>(ref).setKindValue(R_AARCH64_NONE);
- return std::error_code();
- }
- // Static code doesn't need PLTs.
- const_cast<Reference &>(ref).setKindValue(R_AARCH64_PREL32);
- // Handle IFUNC.
- if (const DefinedAtom *da =
- dyn_cast_or_null<const DefinedAtom>(ref.target()))
- if (da->contentType() == DefinedAtom::typeResolver)
- return handleIFUNC(ref);
- return std::error_code();
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getNullGOT());
- else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOT(da));
- return std::error_code();
- }
-};
-
-class AArch64DynamicRelocationPass final
- : public AArch64RelocationPass<AArch64DynamicRelocationPass> {
-public:
- AArch64DynamicRelocationPass(const elf::AArch64LinkingContext &ctx)
- : AArch64RelocationPass(ctx) {}
-
- const PLT0Atom *getPLT0() {
- if (_plt0)
- return _plt0;
- // Fill in the null entry.
- getNullGOT();
- _plt0 = new (_file._alloc) AArch64PLT0Atom(_file);
- _got0 = new (_file._alloc) AArch64GOTPLTAtom(_file);
- _got1 = new (_file._alloc) AArch64GOTPLTAtom(_file);
- _plt0->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 4, _got0, 0);
- _plt0->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 8, _got1, 0);
- _plt0->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 12, _got1, 0);
-#ifndef NDEBUG
- _plt0->_name = "__PLT0";
- _got0->_name = "__got0";
- _got1->_name = "__got1";
-#endif
- return _plt0;
- }
-
- const PLTAtom *getPLTEntry(const Atom *a) {
- auto plt = _pltMap.find(a);
- if (plt != _pltMap.end())
- return plt->second;
- auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file);
- ga->addReferenceELF_AArch64(R_AARCH64_JUMP_SLOT, 0, a, 0);
- auto pa = new (_file._alloc) AArch64PLTAtom(_file);
- pa->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 0, ga, 0);
- pa->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 4, ga, 0);
- pa->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 8, ga, 0);
- pa->addReferenceELF_AArch64(R_AARCH64_NONE, 12, getPLT0(), 0);
- // Set the starting address of the got entry to the first instruction in
- // the plt0 entry.
- ga->addReferenceELF_AArch64(R_AARCH64_ABS32, 0, getPLT0(), 0);
-#ifndef NDEBUG
- ga->_name = "__got_";
- ga->_name += a->name();
- pa->_name = "__plt_";
- pa->_name += a->name();
-#endif
- _gotMap[a] = ga;
- _pltMap[a] = pa;
- _gotVector.push_back(ga);
- _pltVector.push_back(pa);
- return pa;
- }
-
- const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
- auto obj = _objectMap.find(a);
- if (obj != _objectMap.end())
- return obj->second;
-
- auto oa = new (_file._alloc) ObjectAtom(_file);
- // This needs to point to the atom that we just created.
- oa->addReferenceELF_AArch64(R_AARCH64_COPY, 0, oa, 0);
-
- oa->_name = a->name();
- oa->_size = a->size();
-
- _objectMap[a] = oa;
- _objectVector.push_back(oa);
- return oa;
- }
-
- std::error_code handlePlain(const Reference &ref) {
- if (!ref.target())
- return std::error_code();
- if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
- if (sla->type() == SharedLibraryAtom::Type::Data)
- const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
- else if (sla->type() == SharedLibraryAtom::Type::Code)
- const_cast<Reference &>(ref).setTarget(getPLTEntry(sla));
- } else
- return handleIFUNC(ref);
- return std::error_code();
- }
-
- std::error_code handlePLT32(const Reference &ref) {
- // Turn this into a PC32 to the PLT entry.
- const_cast<Reference &>(ref).setKindValue(R_AARCH64_PREL32);
- // Handle IFUNC.
- if (const DefinedAtom *da =
- dyn_cast_or_null<const DefinedAtom>(ref.target()))
- if (da->contentType() == DefinedAtom::typeResolver)
- return handleIFUNC(ref);
- if (isa<const SharedLibraryAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
- return std::error_code();
- }
-
- const GOTAtom *getSharedGOT(const SharedLibraryAtom *sla) {
- auto got = _gotMap.find(sla);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) AArch64GOTAtom(_file);
- g->addReferenceELF_AArch64(R_AARCH64_GLOB_DAT, 0, sla, 0);
-#ifndef NDEBUG
- g->_name = "__got_";
- g->_name += sla->name();
-#endif
- _gotMap[sla] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getNullGOT());
- else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOT(da));
- else if (const auto sla = dyn_cast<const SharedLibraryAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getSharedGOT(sla));
- return std::error_code();
- }
-};
-} // end anon namespace
-
-std::unique_ptr<Pass>
-lld::elf::createAArch64RelocationPass(const AArch64LinkingContext &ctx) {
- switch (ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- if (ctx.isDynamic())
- return llvm::make_unique<AArch64DynamicRelocationPass>(ctx);
- return llvm::make_unique<AArch64StaticRelocationPass>(ctx);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<AArch64DynamicRelocationPass>(ctx);
- case llvm::ELF::ET_REL:
- return nullptr;
- default:
- llvm_unreachable("Unhandled output file type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h (removed)
@@ -1,32 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Declares the relocation processing pass for AArch64. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_RELOCATION_PASS_H
-#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_RELOCATION_PASS_H
-
-#include <memory>
-
-namespace lld {
-class Pass;
-namespace elf {
-class AArch64LinkingContext;
-
-/// \brief Create AArch64 relocation pass for the given linking context.
-std::unique_ptr<Pass>
-createAArch64RelocationPass(const AArch64LinkingContext &);
-}
-}
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp (removed)
@@ -1,39 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64SectionChunks.h"
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx,
- StringRef name, int32_t order)
- : AtomSection<ELF64LE>(ctx, name, DefinedAtom::typeGOT, DefinedAtom::permRW_,
- order) {
- _alignment = 8;
-}
-
-const AtomLayout *AArch64GOTSection::appendAtom(const Atom *atom) {
- const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::AArch64);
- if ((r->kindValue() == R_AARCH64_TLS_TPREL64) ||
- (r->kindValue() == R_AARCH64_TLSDESC))
- _tlsMap[r->target()] = _tlsMap.size();
- }
-
- return AtomSection<ELF64LE>::appendAtom(atom);
-}
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h (removed)
@@ -1,37 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_SECTION_CHUNKS_H
-
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-class AArch64GOTSection : public AtomSection<ELF64LE> {
-public:
- AArch64GOTSection(const ELFLinkingContext &ctx, StringRef name,
- int32_t order);
-
- bool hasGlobalGOTEntry(const Atom *a) const {
- return _tlsMap.count(a);
- }
-
- const AtomLayout *appendAtom(const Atom *atom) override;
-
-private:
- /// \brief Map TLS Atoms to their GOT entry index.
- llvm::DenseMap<const Atom *, std::size_t> _tlsMap;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp (removed)
@@ -1,51 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Atoms.h"
-#include "AArch64DynamicLibraryWriter.h"
-#include "AArch64ExecutableWriter.h"
-#include "AArch64LinkingContext.h"
-#include "AArch64TargetHandler.h"
-#include "AArch64SectionChunks.h"
-
-using namespace lld;
-using namespace elf;
-
-AArch64TargetLayout::AArch64TargetLayout(ELFLinkingContext &ctx) :
- TargetLayout(ctx) {}
-
-AtomSection<ELF64LE> *AArch64TargetLayout::createSection(
- StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions,
- TargetLayout<ELF64LE>::SectionOrder order) {
- if (type == DefinedAtom::typeGOT && (name == ".got" || name == ".got.plt")) {
- auto section = new (this->_allocator) AArch64GOTSection(this->_ctx, name,
- order);
- _gotSections.push_back(section);
- return section;
- }
- return TargetLayout<ELF64LE>::createSection(name, type, permissions, order);
-}
-
-
-AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new AArch64TargetLayout(ctx)),
- _relocationHandler(new AArch64TargetRelocationHandler(*_targetLayout)) {}
-
-std::unique_ptr<Writer> AArch64TargetHandler::getWriter() {
- switch (this->_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<AArch64ExecutableWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<AArch64DynamicLibraryWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h (removed)
@@ -1,90 +0,0 @@
-//===- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_TARGET_HANDLER_H
-
-#include "AArch64RelocationHandler.h"
-#include "ELFReader.h"
-#include "TargetLayout.h"
-#include "lld/Core/Simple.h"
-
-namespace lld {
-namespace elf {
-
-class AArch64LinkingContext;
-class AArch64GOTSection;
-
-class AArch64TargetLayout final : public TargetLayout<ELF64LE> {
- typedef llvm::object::Elf_Shdr_Impl<ELF64LE> Elf_Shdr;
-
-public:
- AArch64TargetLayout(ELFLinkingContext &ctx);
-
- AtomSection<ELF64LE> *
- createSection(StringRef name, int32_t type,
- DefinedAtom::ContentPermissions permissions,
- TargetLayout<ELF64LE>::SectionOrder order) override;
-
- const std::vector<AArch64GOTSection *> &getGOTSections() const {
- return _gotSections;
- }
-
- uint64_t getTPOffset() {
- std::call_once(_tpOffOnce, [this]() {
- for (const auto &phdr : *_programHeader) {
- if (phdr->p_type == llvm::ELF::PT_TLS) {
- _tpOff = llvm::alignTo(TCB_SIZE, phdr->p_align);
- break;
- }
- }
- assert(_tpOff != 0 && "TLS segment not found");
- });
- return _tpOff;
- }
-
-private:
- enum {
- TCB_SIZE = 16,
- };
-
-private:
- std::vector<AArch64GOTSection *> _gotSections;
- uint64_t _tpOff = 0;
- std::once_flag _tpOffOnce;
-};
-
-class AArch64TargetHandler final : public TargetHandler {
-public:
- AArch64TargetHandler(AArch64LinkingContext &ctx);
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<ELFFile<ELF64LE>>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELF64LE>>>(_ctx);
- }
-
- std::unique_ptr<Writer> getWriter() override;
-
-private:
- AArch64LinkingContext &_ctx;
- std::unique_ptr<AArch64TargetLayout> _targetLayout;
- std::unique_ptr<AArch64TargetRelocationHandler> _relocationHandler;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt (removed)
@@ -1,14 +0,0 @@
-add_lld_library(lldAArch64ELFTarget
- AArch64LinkingContext.cpp
- AArch64TargetHandler.cpp
- AArch64RelocationHandler.cpp
- AArch64RelocationPass.cpp
- AArch64ExecutableWriter.cpp
- AArch64SectionChunks.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/AArch64/TODO.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/TODO.rst?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/TODO.rst (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/TODO.rst (removed)
@@ -1,15 +0,0 @@
-ELF AArch64
-~~~~~~~~~~~
-
-Unimplemented Features
-######################
-
-* Just about everything!
-
-Unimplemented Relocations
-#########################
-
-All of these relocations are defined in:
-http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
-
-
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h (removed)
@@ -1,49 +0,0 @@
-//===- lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h -----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_DYNAMIC_LIBRARY_WRITER_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "ARMELFWriters.h"
-#include "ARMLinkingContext.h"
-#include "ARMTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class ARMDynamicLibraryWriter
- : public ARMELFWriter<DynamicLibraryWriter<ELF32LE>> {
-public:
- ARMDynamicLibraryWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
-private:
- ARMLinkingContext &_ctx;
-};
-
-ARMDynamicLibraryWriter::ARMDynamicLibraryWriter(ARMLinkingContext &ctx,
- ARMTargetLayout &layout)
- : ARMELFWriter(ctx, layout), _ctx(ctx) {}
-
-void ARMDynamicLibraryWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter::createImplicitFiles(result);
- auto file = llvm::make_unique<RuntimeFile<ELF32LE>>(_ctx, "ARM dynamic file");
- file->addAbsoluteAtom(gotSymbol);
- file->addAbsoluteAtom(dynamicSymbol);
- result.push_back(std::move(file));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_DYNAMIC_LIBRARY_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h (removed)
@@ -1,154 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMELFFile.h ----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_ELF_FILE_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_ELF_FILE_H
-
-#include "ELFReader.h"
-
-namespace lld {
-namespace elf {
-
-class ARMLinkingContext;
-
-class ARMELFBaseDefinedAtom : public ELFDefinedAtom<ELF32LE> {
-public:
- /// The values of custom content type enum must not interfere
- /// with ones in base defined atom class' enum.
- enum ARMContentType {
- typeARMExidx = 0x1000, // Identifies ARM_EXIDX section
- };
-
- template <typename... T>
- ARMELFBaseDefinedAtom(T &&... args)
- : ELFDefinedAtom<ELF32LE>(std::forward<T>(args)...) {}
-
- DefinedAtom::ContentPermissions permissions() const override {
- if (_permissions != DefinedAtom::permUnknown)
- return _permissions;
-
- switch (_section->sh_type) {
- case llvm::ELF::SHT_ARM_EXIDX:
- return _permissions = permR__;
- }
- return ELFDefinedAtom::permissions();
- }
-
- DefinedAtom::ContentType contentType() const override {
- if (_contentType != DefinedAtom::typeUnknown)
- return _contentType;
-
- switch (_section->sh_type) {
- case llvm::ELF::SHT_ARM_EXIDX:
- return _contentType = (DefinedAtom::ContentType)typeARMExidx;
- }
- return ELFDefinedAtom::contentType();
- }
-};
-
-class ARMELFMappingAtom : public ARMELFBaseDefinedAtom {
-public:
- template <typename... T>
- ARMELFMappingAtom(DefinedAtom::CodeModel model, T &&... args)
- : ARMELFBaseDefinedAtom(std::forward<T>(args)...), _model(model) {}
-
- DefinedAtom::CodeModel codeModel() const override { return _model; }
-
-private:
- DefinedAtom::CodeModel _model;
-};
-
-class ARMELFDefinedAtom : public ARMELFBaseDefinedAtom {
-public:
- template <typename... T>
- ARMELFDefinedAtom(T &&... args)
- : ARMELFBaseDefinedAtom(std::forward<T>(args)...) {}
-
- bool isThumbFunc() const {
- const auto *symbol = _symbol;
- return symbol->getType() == llvm::ELF::STT_FUNC &&
- (static_cast<uint64_t>(symbol->st_value) & 0x1);
- }
-
- /// Correct st_value for symbols addressing Thumb instructions
- /// by removing its zero bit.
- uint64_t getSymbolValue() const override {
- const auto value = static_cast<uint64_t>(_symbol->st_value);
- return isThumbFunc() ? value & ~0x1 : value;
- }
-
- DefinedAtom::CodeModel codeModel() const override {
- return isThumbFunc() ? DefinedAtom::codeARMThumb : DefinedAtom::codeNA;
- }
-};
-
-class ARMELFFile : public ELFFile<ELF32LE> {
- typedef llvm::object::Elf_Rel_Impl<ELF32LE, false> Elf_Rel;
-
-public:
- ARMELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
- : ELFFile(std::move(mb), ctx) {}
-
-protected:
- /// Returns initial addend; for ARM it is 0, because it is read
- /// during the relocations applying
- Reference::Addend getInitialAddend(ArrayRef<uint8_t>, uint64_t,
- const Elf_Rel &) const override {
- return 0;
- }
-
-private:
- typedef llvm::object::Elf_Sym_Impl<ELF32LE> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELF32LE> Elf_Shdr;
-
- /// Correct st_value for symbols addressing Thumb instructions
- /// by removing its zero bit.
- uint64_t getSymbolValue(const Elf_Sym *symbol) const override {
- const auto value = static_cast<uint64_t>(symbol->st_value);
- return symbol->getType() == llvm::ELF::STT_FUNC ? value & ~0x1 : value;
- }
-
- /// Process the Defined symbol and create an atom for it.
- ELFDefinedAtom<ELF32LE> *createDefinedAtom(
- StringRef symName, StringRef sectionName, const Elf_Sym *sym,
- const Elf_Shdr *sectionHdr, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELF32LE> *> &referenceList) override {
- if (symName.size() >= 2 && symName[0] == '$') {
- switch (symName[1]) {
- case 'a':
- return new (_readerStorage)
- ARMELFMappingAtom(DefinedAtom::codeARM_a, *this, symName,
- sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- case 'd':
- return new (_readerStorage)
- ARMELFMappingAtom(DefinedAtom::codeARM_d, *this, symName,
- sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- case 't':
- return new (_readerStorage)
- ARMELFMappingAtom(DefinedAtom::codeARM_t, *this, symName,
- sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- default:
- // Fall through and create regular defined atom.
- break;
- }
- }
- return new (_readerStorage) ARMELFDefinedAtom(
- *this, symName, sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- }
-};
-
-} // elf
-} // lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_ELF_FILE_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h (removed)
@@ -1,120 +0,0 @@
-//===- lib/ReaderWriter/ELF/ARM/ARMELFWriters.h ---------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_ELF_WRITERS_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_ELF_WRITERS_H
-
-#include "ARMLinkingContext.h"
-#include "ARMSymbolTable.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-template <class WriterT> class ARMELFWriter : public WriterT {
-public:
- ARMELFWriter(ARMLinkingContext &ctx, TargetLayout<ELF32LE> &layout);
-
- void finalizeDefaultAtomValues() override;
-
- /// \brief Create symbol table.
- unique_bump_ptr<SymbolTable<ELF32LE>> createSymbolTable() override;
-
- // Setup the ELF header.
- std::error_code setELFHeader() override;
-
-protected:
- static const char *gotSymbol;
- static const char *dynamicSymbol;
-
-private:
- ARMLinkingContext &_ctx;
- TargetLayout<ELF32LE> &_armLayout;
-};
-
-template <class WriterT>
-const char *ARMELFWriter<WriterT>::gotSymbol = "_GLOBAL_OFFSET_TABLE_";
-template <class WriterT>
-const char *ARMELFWriter<WriterT>::dynamicSymbol = "_DYNAMIC";
-
-template <class WriterT>
-ARMELFWriter<WriterT>::ARMELFWriter(ARMLinkingContext &ctx,
- TargetLayout<ELF32LE> &layout)
- : WriterT(ctx, layout), _ctx(ctx), _armLayout(layout) {}
-
-template <class WriterT>
-void ARMELFWriter<WriterT>::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- WriterT::finalizeDefaultAtomValues();
-
- if (auto *gotAtom = _armLayout.findAbsoluteAtom(gotSymbol)) {
- if (auto gotpltSection = _armLayout.findOutputSection(".got.plt"))
- gotAtom->_virtualAddr = gotpltSection->virtualAddr();
- else if (auto gotSection = _armLayout.findOutputSection(".got"))
- gotAtom->_virtualAddr = gotSection->virtualAddr();
- else
- gotAtom->_virtualAddr = 0;
- }
-
- if (auto *dynamicAtom = _armLayout.findAbsoluteAtom(dynamicSymbol)) {
- if (auto dynamicSection = _armLayout.findOutputSection(".dynamic"))
- dynamicAtom->_virtualAddr = dynamicSection->virtualAddr();
- else
- dynamicAtom->_virtualAddr = 0;
- }
-
- // Set required by gcc libc __ehdr_start symbol with pointer to ELF header
- if (auto ehdr = _armLayout.findAbsoluteAtom("__ehdr_start"))
- ehdr->_virtualAddr = this->_elfHeader->virtualAddr();
-
- // Set required by gcc libc symbols __exidx_start/__exidx_end
- this->updateScopeAtomValues("exidx", ".ARM.exidx");
-}
-
-template <class WriterT>
-unique_bump_ptr<SymbolTable<ELF32LE>>
-ARMELFWriter<WriterT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELF32LE>>(new (this->_alloc)
- ARMSymbolTable(_ctx));
-}
-
-template <class WriterT> std::error_code ARMELFWriter<WriterT>::setELFHeader() {
- if (std::error_code ec = WriterT::setELFHeader())
- return ec;
-
- // Set ARM-specific flags.
- this->_elfHeader->e_flags(llvm::ELF::EF_ARM_EABI_VER5 |
- llvm::ELF::EF_ARM_VFP_FLOAT);
-
- StringRef entryName = _ctx.entrySymbolName();
- if (const AtomLayout *al = _armLayout.findAtomLayoutByName(entryName)) {
- if (const auto *ea = dyn_cast<DefinedAtom>(al->_atom)) {
- switch (ea->codeModel()) {
- case DefinedAtom::codeNA:
- if (al->_virtualAddr & 0x3) {
- llvm::report_fatal_error(
- "Two least bits must be zero for ARM entry point");
- }
- break;
- case DefinedAtom::codeARMThumb:
- // Fixup entry point for Thumb code.
- this->_elfHeader->e_entry(al->_virtualAddr | 0x1);
- break;
- default:
- llvm_unreachable("Wrong code model of entry point atom");
- }
- }
- }
-
- return std::error_code();
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_ELF_WRITERS_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h (removed)
@@ -1,68 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "ARMELFWriters.h"
-#include "ARMLinkingContext.h"
-#include "ARMTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class ARMExecutableWriter : public ARMELFWriter<ExecutableWriter<ELF32LE>> {
-public:
- ARMExecutableWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void processUndefinedSymbol(StringRef symName,
- RuntimeFile<ELF32LE> &file) const override;
-
-private:
- ARMLinkingContext &_ctx;
-};
-
-ARMExecutableWriter::ARMExecutableWriter(ARMLinkingContext &ctx,
- ARMTargetLayout &layout)
- : ARMELFWriter(ctx, layout), _ctx(ctx) {}
-
-void ARMExecutableWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter::createImplicitFiles(result);
- // Add default atoms for ARM.
- if (_ctx.isDynamic()) {
- auto file = llvm::make_unique<RuntimeFile<ELF32LE>>(_ctx, "ARM exec file");
- file->addAbsoluteAtom(gotSymbol);
- file->addAbsoluteAtom(dynamicSymbol);
- result.push_back(std::move(file));
- }
-}
-
-void ARMExecutableWriter::processUndefinedSymbol(
- StringRef symName, RuntimeFile<ELF32LE> &file) const {
- ARMELFWriter<ExecutableWriter<ELF32LE>>::processUndefinedSymbol(symName,
- file);
- if (symName == gotSymbol) {
- file.addAbsoluteAtom(gotSymbol);
- } else if (symName.startswith("__exidx")) {
- file.addAbsoluteAtom("__exidx_start");
- file.addAbsoluteAtom("__exidx_end");
- } else if (symName == "__ehdr_start") {
- file.addAbsoluteAtom("__ehdr_start");
- }
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp (removed)
@@ -1,64 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARMLinkingContext.h"
-#include "ARMRelocationPass.h"
-#include "ARMTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-std::unique_ptr<ELFLinkingContext>
-createARMLinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::arm)
- return llvm::make_unique<ARMLinkingContext>(triple);
- return nullptr;
-}
-
-ARMLinkingContext::ARMLinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, llvm::make_unique<ARMTargetHandler>(*this)) {}
-
-void ARMLinkingContext::addPasses(PassManager &pm) {
- auto pass = createARMRelocationPass(*this);
- if (pass)
- pm.add(std::move(pass));
- ELFLinkingContext::addPasses(pm);
-}
-
-bool isARMCode(const DefinedAtom *atom) {
- return isARMCode(atom->codeModel());
-}
-
-bool isARMCode(DefinedAtom::CodeModel codeModel) {
- return !isThumbCode(codeModel);
-}
-
-bool isThumbCode(const DefinedAtom *atom) {
- return isThumbCode(atom->codeModel());
-}
-
-bool isThumbCode(DefinedAtom::CodeModel codeModel) {
- return codeModel == DefinedAtom::codeARMThumb ||
- codeModel == DefinedAtom::codeARM_t;
-}
-
-static const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/ARM.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_END
-};
-
-void ARMLinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF, Reference::KindArch::ARM,
- kindStrings);
-}
-
-} // namespace elf
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h (removed)
@@ -1,80 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_LINKING_CONTEXT_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_LINKING_CONTEXT_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-class ARMLinkingContext final : public ELFLinkingContext {
-public:
- int getMachineType() const override { return llvm::ELF::EM_ARM; }
- ARMLinkingContext(llvm::Triple);
-
- void addPasses(PassManager &) override;
- void registerRelocationNames(Registry &r) override;
-
- bool isRelaOutputFormat() const override { return false; }
-
- uint64_t getBaseAddress() const override {
- if (_baseAddress == 0)
- return 0x400000;
- return _baseAddress;
- }
-
- bool isDynamicRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::ARM);
- switch (r.kindValue()) {
- case llvm::ELF::R_ARM_GLOB_DAT:
- case llvm::ELF::R_ARM_TLS_TPOFF32:
- case llvm::ELF::R_ARM_COPY:
- return true;
- default:
- return false;
- }
- }
-
- bool isCopyRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::ARM);
- return r.kindValue() == llvm::ELF::R_ARM_COPY;
- }
-
- bool isPLTRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::ARM);
- switch (r.kindValue()) {
- case llvm::ELF::R_ARM_JUMP_SLOT:
- case llvm::ELF::R_ARM_IRELATIVE:
- return true;
- default:
- return false;
- }
- }
-};
-
-// Special methods to check code model of atoms.
-bool isARMCode(const DefinedAtom *atom);
-bool isARMCode(DefinedAtom::CodeModel codeModel);
-bool isThumbCode(const DefinedAtom *atom);
-bool isThumbCode(DefinedAtom::CodeModel codeModel);
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (removed)
@@ -1,680 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp ----------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARMTargetHandler.h"
-#include "ARMLinkingContext.h"
-
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/MathExtras.h"
-
-#define DEBUG_TYPE "ARM"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::support::endian;
-
-static Reference::Addend readAddend_THM_MOV(const uint8_t *location) {
- const uint16_t halfHi = read16le(location);
- const uint16_t halfLo = read16le(location + 2);
-
- const uint16_t imm8 = halfLo & 0xFF;
- const uint16_t imm3 = (halfLo >> 12) & 0x7;
-
- const uint16_t imm4 = halfHi & 0xF;
- const uint16_t bitI = (halfHi >> 10) & 0x1;
-
- const auto result = int16_t((imm4 << 12) | (bitI << 11) | (imm3 << 8) | imm8);
- return result;
-}
-
-static Reference::Addend readAddend_ARM_MOV(const uint8_t *location) {
- const uint32_t value = read32le(location);
-
- const uint32_t imm12 = value & 0xFFF;
- const uint32_t imm4 = (value >> 16) & 0xF;
-
- const auto result = int32_t((imm4 << 12) | imm12);
- return result;
-}
-
-static Reference::Addend readAddend_THM_CALL(const uint8_t *location) {
- const uint16_t halfHi = read16le(location);
- const uint16_t halfLo = read16le(location + 2);
-
- const uint16_t imm10 = halfHi & 0x3FF;
- const uint16_t bitS = (halfHi >> 10) & 0x1;
-
- const uint16_t imm11 = halfLo & 0x7FF;
- const uint16_t bitJ2 = (halfLo >> 11) & 0x1;
- const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
- const uint16_t bitJ1 = (halfLo >> 13) & 0x1;
- const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
-
- const auto result = int32_t((bitS << 24) | (bitI1 << 23) | (bitI2 << 22) |
- (imm10 << 12) | (imm11 << 1));
- return llvm::SignExtend64<25>(result);
-}
-
-static Reference::Addend readAddend_ARM_CALL(const uint8_t *location) {
- const uint32_t value = read32le(location);
-
- const bool isBLX = (value & 0xF0000000) == 0xF0000000;
- const uint32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0;
-
- const auto result = int32_t(((value & 0xFFFFFF) << 2) | (bitH << 1));
- return llvm::SignExtend64<26>(result);
-}
-
-static Reference::Addend readAddend_THM_JUMP11(const uint8_t *location) {
- const auto value = read16le(location);
- const uint16_t imm11 = value & 0x7FF;
-
- return llvm::SignExtend64<12>(imm11 << 1);
-}
-
-static Reference::Addend readAddend(const uint8_t *location,
- Reference::KindValue kindValue) {
- switch (kindValue) {
- case R_ARM_ABS32:
- case R_ARM_REL32:
- case R_ARM_TARGET1:
- case R_ARM_GOT_BREL:
- case R_ARM_BASE_PREL:
- case R_ARM_TLS_IE32:
- case R_ARM_TLS_LE32:
- case R_ARM_TLS_TPOFF32:
- return (int32_t)read32le(location);
- case R_ARM_PREL31:
- return llvm::SignExtend64<31>(read32le(location) & 0x7FFFFFFF);
- case R_ARM_THM_CALL:
- case R_ARM_THM_JUMP24:
- return readAddend_THM_CALL(location);
- case R_ARM_THM_JUMP11:
- return readAddend_THM_JUMP11(location);
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- return readAddend_ARM_CALL(location);
- case R_ARM_MOVW_ABS_NC:
- case R_ARM_MOVT_ABS:
- return readAddend_ARM_MOV(location);
- case R_ARM_THM_MOVW_ABS_NC:
- case R_ARM_THM_MOVT_ABS:
- return readAddend_THM_MOV(location);
- default:
- return 0;
- }
-}
-
-static inline void report_unsupported_range_group_reloc_error() {
- llvm::report_fatal_error(
- "Negative offsets for group relocations are not implemented");
-}
-
-static inline std::error_code applyArmReloc(uint8_t *location, uint32_t result,
- uint32_t mask = 0xFFFFFFFF) {
- assert(!(result & ~mask));
- write32le(location, (read32le(location) & ~mask) | (result & mask));
- return std::error_code();
-}
-
-static inline std::error_code applyThumb32Reloc(uint8_t *location,
- uint16_t resHi, uint16_t resLo,
- uint16_t maskHi,
- uint16_t maskLo = 0xFFFF) {
- assert(!(resHi & ~maskHi) && !(resLo & ~maskLo));
- write16le(location, (read16le(location) & ~maskHi) | (resHi & maskHi));
- location += 2;
- write16le(location, (read16le(location) & ~maskLo) | (resLo & maskLo));
- return std::error_code();
-}
-
-static inline std::error_code
-applyThumb16Reloc(uint8_t *location, uint16_t result, uint16_t mask = 0xFFFF) {
- assert(!(result & ~mask));
- write16le(location, (read16le(location) & ~mask) | (result & mask));
- return std::error_code();
-}
-
-/// \brief R_ARM_ABS32 - (S + A) | T
-static std::error_code relocR_ARM_ABS32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)((S + A) | T);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_REL32 - ((S + A) | T) - P
-static std::error_code relocR_ARM_REL32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)(((S + A) | T) - P);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_PREL31 - ((S + A) | T) - P
-static std::error_code relocR_ARM_PREL31(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)(((S + A) | T) - P);
- if (!llvm::isInt<31>((int32_t)result))
- return make_out_of_range_reloc_error();
-
- const uint32_t mask = 0x7FFFFFFF;
- uint32_t rel31 = result & mask;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result);
- llvm::dbgs() << " rel31: 0x" << Twine::utohexstr(rel31) << "\n");
-
- return applyArmReloc(location, rel31, mask);
-}
-
-/// \brief Relocate B/BL instructions. useJs defines whether J1 & J2 are used
-static std::error_code relocR_ARM_THM_B_L(uint8_t *location, uint32_t result,
- bool useJs) {
- if ((useJs && !llvm::isInt<25>((int32_t)result)) ||
- (!useJs && !llvm::isInt<23>((int32_t)result)))
- return make_out_of_range_reloc_error();
-
- result = (result & 0x01FFFFFE) >> 1;
-
- const uint16_t imm10 = (result >> 11) & 0x3FF;
- const uint16_t bitS = (result >> 23) & 0x1;
- const uint16_t resHi = (bitS << 10) | imm10;
-
- const uint16_t imm11 = result & 0x7FF;
- const uint16_t bitJ2 = useJs ? ((result >> 21) & 0x1) : bitS;
- const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
- const uint16_t bitJ1 = useJs ? ((result >> 22) & 0x1) : bitS;
- const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
- const uint16_t resLo = (bitI1 << 13) | (bitI2 << 11) | imm11;
-
- return applyThumb32Reloc(location, resHi, resLo, 0x7FF, 0x2FFF);
-}
-
-/// \brief R_ARM_THM_CALL - ((S + A) | T) - P
-static std::error_code relocR_ARM_THM_CALL(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A, bool useJs,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- const bool switchMode = !addressesThumb;
-
- if (switchMode) {
- P &= ~0x3; // Align(P, 4) by rounding down
- }
-
- uint32_t result = (uint32_t)(((S + A) | T) - P);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- if (auto ec = relocR_ARM_THM_B_L(location, result, useJs))
- return ec;
-
- if (switchMode) {
- return applyThumb32Reloc(location, 0, 0, 0, 0x1001);
- }
- return std::error_code();
-}
-
-/// \brief R_ARM_THM_JUMP24 - ((S + A) | T) - P
-static std::error_code relocR_ARM_THM_JUMP24(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)(((S + A) | T) - P);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return relocR_ARM_THM_B_L(location, result, true);
-}
-
-/// \brief R_ARM_THM_JUMP11 - S + A - P
-static std::error_code relocR_ARM_THM_JUMP11(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
-
- if (!llvm::isInt<12>((int32_t)result))
- return make_out_of_range_reloc_error();
-
- // we cut off first bit because it is always 1 according to p. 4.5.3
- result = (result & 0x0FFE) >> 1;
- return applyThumb16Reloc(location, result, 0x7FF);
-}
-
-/// \brief R_ARM_BASE_PREL - B(S) + A - P => S + A - P
-static std::error_code relocR_ARM_BASE_PREL(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_GOT_BREL - GOT(S) + A - GOT_ORG => S + A - GOT_ORG
-static std::error_code relocR_ARM_GOT_BREL(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- uint64_t GOT_ORG) {
- uint32_t result = (uint32_t)(S + A - GOT_ORG);
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_CALL - ((S + A) | T) - P
-static std::error_code relocR_ARM_CALL(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- const bool switchMode = addressesThumb;
-
- uint32_t result = (uint32_t)(((S + A) | T) - P);
- if (!llvm::isInt<26>((int32_t)result))
- return make_out_of_range_reloc_error();
-
- const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- if (auto ec = applyArmReloc(location, imm24, 0xFFFFFF))
- return ec;
-
- if (switchMode) {
- const uint32_t bitH = (result & 0x2) >> 1;
- return applyArmReloc(location, (0xFA | bitH) << 24, 0xFF000000);
- }
- return std::error_code();
-}
-
-/// \brief R_ARM_JUMP24 - ((S + A) | T) - P
-static std::error_code relocR_ARM_JUMP24(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)(((S + A) | T) - P);
- if (!llvm::isInt<26>((int32_t)result))
- return make_out_of_range_reloc_error();
-
- const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, imm24, 0xFFFFFF);
-}
-
-/// \brief Relocate ARM MOVW/MOVT instructions
-static std::error_code relocR_ARM_MOV(uint8_t *location, uint32_t result) {
- const uint32_t imm12 = result & 0xFFF;
- const uint32_t imm4 = (result >> 12) & 0xF;
-
- return applyArmReloc(location, (imm4 << 16) | imm12, 0xF0FFF);
-}
-
-/// \brief R_ARM_MOVW_ABS_NC - (S + A) | T
-static std::error_code relocR_ARM_MOVW_ABS_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)((S + A) | T);
- const uint32_t arg = result & 0x0000FFFF;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return relocR_ARM_MOV(location, arg);
-}
-
-/// \brief R_ARM_MOVT_ABS - S + A
-static std::error_code relocR_ARM_MOVT_ABS(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A);
- const uint32_t arg = (result & 0xFFFF0000) >> 16;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return relocR_ARM_MOV(location, arg);
-}
-
-/// \brief Relocate Thumb MOVW/MOVT instructions
-static std::error_code relocR_ARM_THM_MOV(uint8_t *location, uint32_t result) {
- const uint16_t imm8 = result & 0xFF;
- const uint16_t imm3 = (result >> 8) & 0x7;
- const uint16_t resLo = (imm3 << 12) | imm8;
-
- const uint16_t imm4 = (result >> 12) & 0xF;
- const uint16_t bitI = (result >> 11) & 0x1;
- const uint16_t resHi = (bitI << 10) | imm4;
-
- return applyThumb32Reloc(location, resHi, resLo, 0x40F, 0x70FF);
-}
-
-/// \brief R_ARM_THM_MOVW_ABS_NC - (S + A) | T
-static std::error_code relocR_ARM_THM_MOVW_ABS_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- bool addressesThumb) {
- uint64_t T = addressesThumb;
- uint32_t result = (uint32_t)((S + A) | T);
- const uint32_t arg = result & 0x0000FFFF;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return relocR_ARM_THM_MOV(location, arg);
-}
-
-/// \brief R_ARM_THM_MOVT_ABS - S + A
-static std::error_code relocR_ARM_THM_MOVT_ABS(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A);
- const uint32_t arg = (result & 0xFFFF0000) >> 16;
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return relocR_ARM_THM_MOV(location, arg);
-}
-
-/// \brief R_ARM_TLS_IE32 - GOT(S) + A - P => S + A - P
-static std::error_code relocR_ARM_TLS_IE32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_TLS_LE32 - S + A - tp => S + A + tpoff
-static std::error_code relocR_ARM_TLS_LE32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A,
- uint64_t tpoff) {
- uint32_t result = (uint32_t)(S + A + tpoff);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-/// \brief R_ARM_TLS_TPOFF32 - S + A - tp => S + A (offset within TLS block)
-static std::error_code relocR_ARM_TLS_TPOFF32(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A);
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
- return applyArmReloc(location, result);
-}
-
-template <uint32_t lshift>
-static std::error_code relocR_ARM_ALU_PC_GN_NC(uint8_t *location,
- uint32_t result) {
- static_assert(lshift < 32 && lshift % 2 == 0,
- "lshift must be even and less than word size");
-
- const uint32_t rshift = 32 - lshift;
- result = ((result >> lshift) & 0xFF) | ((rshift / 2) << 8);
-
- return applyArmReloc(location, result, 0xFFF);
-}
-
-/// \brief R_ARM_ALU_PC_G0_NC - ((S + A) | T) - P => S + A - P
-static std::error_code relocR_ARM_ALU_PC_G0_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A - P);
- if (result < 0)
- report_unsupported_range_group_reloc_error();
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result)
- << "\n");
-
- return relocR_ARM_ALU_PC_GN_NC<20>(location, (uint32_t)result);
-}
-
-/// \brief R_ARM_ALU_PC_G1_NC - ((S + A) | T) - P => S + A - P
-static std::error_code relocR_ARM_ALU_PC_G1_NC(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A - P);
- if (result < 0)
- report_unsupported_range_group_reloc_error();
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result)
- << "\n");
-
- return relocR_ARM_ALU_PC_GN_NC<12>(location, (uint32_t)result);
-}
-
-/// \brief R_ARM_LDR_PC_G2 - S + A - P
-static std::error_code relocR_ARM_LDR_PC_G2(uint8_t *location, uint64_t P,
- uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A - P);
- if (result < 0)
- report_unsupported_range_group_reloc_error();
-
- DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
- llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
- llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
- llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
- llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result)
- << "\n");
-
- const uint32_t mask = 0xFFF;
- return applyArmReloc(location, (uint32_t)result & mask, mask);
-}
-
-/// \brief Fixup unresolved weak reference with NOP instruction
-static bool fixupUnresolvedWeakCall(uint8_t *location,
- Reference::KindValue kindValue) {
- // TODO: workaround for archs without NOP instruction
- switch (kindValue) {
- case R_ARM_THM_CALL:
- case R_ARM_THM_JUMP24:
- // Thumb32 NOP.W
- write32le(location, 0x8000F3AF);
- break;
- case R_ARM_THM_JUMP11:
- // Thumb16 NOP
- write16le(location, 0xBF00);
- break;
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- // A1 NOP<c>, save condition bits
- applyArmReloc(location, 0x320F000, 0xFFFFFFF);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-std::error_code ARMTargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::ARM);
-
- // Fixup unresolved weak references
- if (!target) {
- bool isCallFixed = fixupUnresolvedWeakCall(loc, ref.kindValue());
-
- if (isCallFixed) {
- DEBUG(llvm::dbgs() << "\t\tFixup unresolved weak reference '";
- llvm::dbgs() << ref.target()->name() << "'";
- llvm::dbgs() << " at address: 0x" << Twine::utohexstr(reloc);
- llvm::dbgs() << (isCallFixed ? "\n" : " isn't possible\n"));
- return std::error_code();
- }
- }
-
- // Calculate proper initial addend for the relocation
- const Reference::Addend addend =
- readAddend(loc, ref.kindValue()) + ref.addend();
-
- // Flags that the relocation addresses Thumb instruction
- bool thumb = false;
- if (const auto *definedAtom = dyn_cast<DefinedAtom>(ref.target())) {
- thumb = isThumbCode(definedAtom);
- }
-
- switch (ref.kindValue()) {
- case R_ARM_NONE:
- return std::error_code();
- case R_ARM_ABS32:
- return relocR_ARM_ABS32(loc, reloc, target, addend, thumb);
- case R_ARM_REL32:
- return relocR_ARM_REL32(loc, reloc, target, addend, thumb);
- case R_ARM_TARGET1:
- if (_armLayout.target1Rel())
- return relocR_ARM_REL32(loc, reloc, target, addend, thumb);
- else
- return relocR_ARM_ABS32(loc, reloc, target, addend, thumb);
- case R_ARM_THM_CALL:
- // TODO: consider adding bool variable to disable J1 & J2 for archs
- // before ARMv6
- return relocR_ARM_THM_CALL(loc, reloc, target, addend, true, thumb);
- case R_ARM_CALL:
- return relocR_ARM_CALL(loc, reloc, target, addend, thumb);
- case R_ARM_JUMP24:
- return relocR_ARM_JUMP24(loc, reloc, target, addend, thumb);
- case R_ARM_THM_JUMP24:
- return relocR_ARM_THM_JUMP24(loc, reloc, target, addend, thumb);
- case R_ARM_THM_JUMP11:
- return relocR_ARM_THM_JUMP11(loc, reloc, target, addend);
- case R_ARM_MOVW_ABS_NC:
- return relocR_ARM_MOVW_ABS_NC(loc, reloc, target, addend, thumb);
- case R_ARM_MOVT_ABS:
- return relocR_ARM_MOVT_ABS(loc, reloc, target, addend);
- case R_ARM_THM_MOVW_ABS_NC:
- return relocR_ARM_THM_MOVW_ABS_NC(loc, reloc, target, addend, thumb);
- case R_ARM_THM_MOVT_ABS:
- return relocR_ARM_THM_MOVT_ABS(loc, reloc, target, addend);
- case R_ARM_PREL31:
- return relocR_ARM_PREL31(loc, reloc, target, addend, thumb);
- case R_ARM_TLS_IE32:
- return relocR_ARM_TLS_IE32(loc, reloc, target, addend);
- case R_ARM_TLS_LE32:
- return relocR_ARM_TLS_LE32(loc, reloc, target, addend,
- _armLayout.getTPOffset());
- case R_ARM_TLS_TPOFF32:
- return relocR_ARM_TLS_TPOFF32(loc, reloc, target, addend);
- case R_ARM_GOT_BREL:
- return relocR_ARM_GOT_BREL(loc, reloc, target, addend,
- _armLayout.getGOTSymAddr());
- case R_ARM_BASE_PREL:
- // GOT origin is used for NULL symbol and when explicitly specified
- if (!target || ref.target()->name().equals("_GLOBAL_OFFSET_TABLE_")) {
- target = _armLayout.getGOTSymAddr();
- } else {
- return make_dynamic_error_code(
- "Segment-base relative addressing is not supported");
- }
- return relocR_ARM_BASE_PREL(loc, reloc, target, addend);
- case R_ARM_ALU_PC_G0_NC:
- return relocR_ARM_ALU_PC_G0_NC(loc, reloc, target, addend);
- case R_ARM_ALU_PC_G1_NC:
- return relocR_ARM_ALU_PC_G1_NC(loc, reloc, target, addend);
- case R_ARM_LDR_PC_G2:
- return relocR_ARM_LDR_PC_G2(loc, reloc, target, addend);
- case R_ARM_JUMP_SLOT:
- case R_ARM_GLOB_DAT:
- case R_ARM_IRELATIVE:
- // Runtime only relocations. Ignore here.
- return std::error_code();
- case R_ARM_V4BX:
- // TODO implement
- return std::error_code();
- default:
- return make_unhandled_reloc_error();
- }
-
- llvm_unreachable("All switch cases must return directly");
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h (removed)
@@ -1,35 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h ------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_RELOCATION_HANDLER_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_RELOCATION_HANDLER_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class ARMTargetLayout;
-
-class ARMTargetRelocationHandler final : public TargetRelocationHandler {
-public:
- ARMTargetRelocationHandler(ARMTargetLayout &layout) : _armLayout(layout) {}
-
- std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const AtomLayout &,
- const Reference &) const override;
-
-private:
- ARMTargetLayout &_armLayout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_RELOCATION_HANDLER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp (removed)
@@ -1,986 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the relocation processing pass for ARM. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-/// This also includes additional behavior that gnu-ld and gold implement but
-/// which is not specified anywhere.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ARMRelocationPass.h"
-#include "ARMLinkingContext.h"
-#include "Atoms.h"
-#include "lld/Core/Simple.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Debug.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-
-namespace {
-// ARM B/BL instructions of absolute relocation veneer.
-// TODO: consider different instruction set for archs below ARMv5
-// (one as for Thumb may be used though it's less optimal).
-static const uint8_t Veneer_ARM_B_BL_Abs_a_AtomContent[4] = {
- 0x04, 0xf0, 0x1f, 0xe5 // ldr pc, [pc, #-4]
-};
-static const uint8_t Veneer_ARM_B_BL_Abs_d_AtomContent[4] = {
- 0x00, 0x00, 0x00, 0x00 // <target_symbol_address>
-};
-
-// Thumb B/BL instructions of absolute relocation veneer.
-// TODO: consider different instruction set for archs above ARMv5
-// (one as for ARM may be used since it's more optimal).
-static const uint8_t Veneer_THM_B_BL_Abs_t_AtomContent[4] = {
- 0x78, 0x47, // bx pc
- 0x00, 0x00 // nop
-};
-static const uint8_t Veneer_THM_B_BL_Abs_a_AtomContent[4] = {
- 0xfe, 0xff, 0xff, 0xea // b <target_symbol_address>
-};
-
-// .got values
-static const uint8_t ARMGotAtomContent[4] = {0};
-
-// .plt value (entry 0)
-static const uint8_t ARMPlt0_a_AtomContent[16] = {
- 0x04, 0xe0, 0x2d, 0xe5, // push {lr}
- 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, [pc, #4]
- 0x0e, 0xe0, 0x8f, 0xe0, // add lr, pc, lr
- 0x00, 0xf0, 0xbe, 0xe5 // ldr pc, [lr, #0]!
-};
-static const uint8_t ARMPlt0_d_AtomContent[4] = {
- 0x00, 0x00, 0x00, 0x00 // <got1_symbol_address>
-};
-
-// .plt values (other entries)
-static const uint8_t ARMPltAtomContent[12] = {
- 0x00, 0xc0, 0x8f, 0xe2, // add ip, pc, #offset[G0]
- 0x00, 0xc0, 0x8c, 0xe2, // add ip, ip, #offset[G1]
- 0x00, 0xf0, 0xbc, 0xe5 // ldr pc, [ip, #offset[G2]]!
-};
-
-// Veneer for switching from Thumb to ARM code for PLT entries.
-static const uint8_t ARMPltVeneerAtomContent[4] = {
- 0x78, 0x47, // bx pc
- 0x00, 0x00 // nop
-};
-
-// Determine proper names for mapping symbols.
-static std::string getMappingAtomName(DefinedAtom::CodeModel model,
- const std::string &part) {
- switch (model) {
- case DefinedAtom::codeARM_a:
- return part.empty() ? "$a" : "$a." + part;
- case DefinedAtom::codeARM_d:
- return part.empty() ? "$d" : "$d." + part;
- case DefinedAtom::codeARM_t:
- return part.empty() ? "$t" : "$t." + part;
- default:
- llvm_unreachable("Wrong code model of mapping atom");
- }
-}
-
-/// \brief Atoms that hold veneer code.
-class VeneerAtom : public SimpleELFDefinedAtom {
- StringRef _section;
-
-public:
- VeneerAtom(const File &f, StringRef secName, const std::string &name = "")
- : SimpleELFDefinedAtom(f), _section(secName), _name(name) {}
-
- Scope scope() const override { return DefinedAtom::scopeTranslationUnit; }
-
- SectionChoice sectionChoice() const override {
- return DefinedAtom::sectionBasedOnContent;
- }
-
- StringRef customSectionName() const override { return _section; }
-
- ContentType contentType() const override { return DefinedAtom::typeCode; }
-
- uint64_t size() const override { return rawContent().size(); }
-
- ContentPermissions permissions() const override { return permR_X; }
-
- Alignment alignment() const override { return 4; }
-
- StringRef name() const override { return _name; }
-
-private:
- std::string _name;
-};
-
-/// \brief Atoms that hold veneer for relocated ARM B/BL instructions
-/// in absolute code.
-class Veneer_ARM_B_BL_Abs_a_Atom : public VeneerAtom {
-public:
- Veneer_ARM_B_BL_Abs_a_Atom(const File &f, StringRef secName,
- const std::string &name)
- : VeneerAtom(f, secName, name) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(Veneer_ARM_B_BL_Abs_a_AtomContent);
- }
-};
-
-class Veneer_ARM_B_BL_Abs_d_Atom : public VeneerAtom {
-public:
- Veneer_ARM_B_BL_Abs_d_Atom(const File &f, StringRef secName)
- : VeneerAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(Veneer_ARM_B_BL_Abs_d_AtomContent);
- }
-};
-
-/// \brief Atoms that hold veneer for relocated Thumb B/BL instructions
-/// in absolute code.
-class Veneer_THM_B_BL_Abs_t_Atom : public VeneerAtom {
-public:
- Veneer_THM_B_BL_Abs_t_Atom(const File &f, StringRef secName,
- const std::string &name)
- : VeneerAtom(f, secName, name) {}
-
- DefinedAtom::CodeModel codeModel() const override {
- return DefinedAtom::codeARMThumb;
- }
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(Veneer_THM_B_BL_Abs_t_AtomContent);
- }
-};
-
-class Veneer_THM_B_BL_Abs_a_Atom : public VeneerAtom {
-public:
- Veneer_THM_B_BL_Abs_a_Atom(const File &f, StringRef secName)
- : VeneerAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(Veneer_THM_B_BL_Abs_a_AtomContent);
- }
-};
-
-template <DefinedAtom::CodeModel Model>
-class ARMVeneerMappingAtom : public VeneerAtom {
-public:
- ARMVeneerMappingAtom(const File &f, StringRef secName, StringRef name)
- : VeneerAtom(f, secName, getMappingAtomName(Model, name)) {
- static_assert((Model == DefinedAtom::codeARM_a ||
- Model == DefinedAtom::codeARM_d ||
- Model == DefinedAtom::codeARM_t),
- "Only mapping atom types are allowed");
- }
-
- uint64_t size() const override { return 0; }
-
- ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
-
- DefinedAtom::CodeModel codeModel() const override { return Model; }
-};
-
-template <class BaseAtom, DefinedAtom::CodeModel Model>
-class BaseMappingAtom : public BaseAtom {
-public:
- BaseMappingAtom(const File &f, StringRef secName, StringRef name)
- : BaseAtom(f, secName) {
- static_assert((Model == DefinedAtom::codeARM_a ||
- Model == DefinedAtom::codeARM_d ||
- Model == DefinedAtom::codeARM_t),
- "Only mapping atom types are allowed");
-#ifndef NDEBUG
- _name = name;
-#else
- _name = getMappingAtomName(Model, name);
-#endif
- }
-
- DefinedAtom::CodeModel codeModel() const override {
-#ifndef NDEBUG
- return isThumbCode(Model) ? DefinedAtom::codeARMThumb : DefinedAtom::codeNA;
-#else
- return Model;
-#endif
- }
-
- StringRef name() const override { return _name; }
-
-private:
- std::string _name;
-};
-
-/// \brief Atoms that are used by ARM dynamic linking
-class ARMGOTAtom : public GOTAtom {
-public:
- ARMGOTAtom(const File &f) : GOTAtom(f, ".got") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(ARMGotAtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-
-protected:
- // Constructor for PLTGOT atom.
- ARMGOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {}
-};
-
-class ARMGOTPLTAtom : public ARMGOTAtom {
-public:
- ARMGOTPLTAtom(const File &f) : ARMGOTAtom(f, ".got.plt") {}
-};
-
-/// \brief Proxy class to keep type compatibility with PLT0Atom.
-class ARMPLT0Atom : public PLT0Atom {
-public:
- ARMPLT0Atom(const File &f, StringRef) : PLT0Atom(f) {}
-};
-
-/// \brief PLT0 entry atom.
-/// Serves as a mapping symbol in the release mode.
-class ARMPLT0_a_Atom
- : public BaseMappingAtom<ARMPLT0Atom, DefinedAtom::codeARM_a> {
-public:
- ARMPLT0_a_Atom(const File &f, const std::string &name)
- : BaseMappingAtom(f, ".plt", name) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(ARMPlt0_a_AtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-class ARMPLT0_d_Atom
- : public BaseMappingAtom<ARMPLT0Atom, DefinedAtom::codeARM_d> {
-public:
- ARMPLT0_d_Atom(const File &f, const std::string &name)
- : BaseMappingAtom(f, ".plt", name) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(ARMPlt0_d_AtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-/// \brief PLT entry atom.
-/// Serves as a mapping symbol in the release mode.
-class ARMPLTAtom : public BaseMappingAtom<PLTAtom, DefinedAtom::codeARM_a> {
-public:
- ARMPLTAtom(const File &f, const std::string &name)
- : BaseMappingAtom(f, ".plt", name) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(ARMPltAtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-/// \brief Veneer atom for PLT entry.
-/// Serves as a mapping symbol in the release mode.
-class ARMPLTVeneerAtom
- : public BaseMappingAtom<PLTAtom, DefinedAtom::codeARM_t> {
-public:
- ARMPLTVeneerAtom(const File &f, const std::string &name)
- : BaseMappingAtom(f, ".plt", name) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(ARMPltVeneerAtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-/// \brief Atom which represents an object for which a COPY relocation will
-/// be generated.
-class ARMObjectAtom : public ObjectAtom {
-public:
- ARMObjectAtom(const File &f) : ObjectAtom(f) {}
- Alignment alignment() const override { return 4; }
-};
-
-class ELFPassFile : public SimpleFile {
-public:
- ELFPassFile(const ELFLinkingContext &eti)
- : SimpleFile("ELFPassFile", kindELFObject) {
- setOrdinal(eti.getNextOrdinalAndIncrement());
- }
-
- llvm::BumpPtrAllocator _alloc;
-};
-
-/// \brief CRTP base for handling relocations.
-template <class Derived> class ARMRelocationPass : public Pass {
- /// \brief Handle a specific reference.
- void handleReference(const DefinedAtom &atom, const Reference &ref) {
- DEBUG_WITH_TYPE(
- "ARM", llvm::dbgs() << "\t" << LLVM_FUNCTION_NAME << "()"
- << ": Name of Defined Atom: " << atom.name().str();
- llvm::dbgs() << " kindValue: " << ref.kindValue() << "\n");
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return;
- assert(ref.kindArch() == Reference::KindArch::ARM);
- switch (ref.kindValue()) {
- case R_ARM_ABS32:
- case R_ARM_REL32:
- case R_ARM_TARGET1:
- case R_ARM_MOVW_ABS_NC:
- case R_ARM_MOVT_ABS:
- case R_ARM_THM_MOVW_ABS_NC:
- case R_ARM_THM_MOVT_ABS:
- static_cast<Derived *>(this)->handlePlain(isThumbCode(&atom), ref);
- break;
- case R_ARM_THM_CALL:
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- case R_ARM_THM_JUMP24:
- case R_ARM_THM_JUMP11: {
- const auto actualModel = actualSourceCodeModel(atom, ref);
- const bool fromThumb = isThumbCode(actualModel);
- static_cast<Derived *>(this)->handlePlain(fromThumb, ref);
- static_cast<Derived *>(this)->handleVeneer(atom, fromThumb, ref);
- } break;
- case R_ARM_TLS_IE32:
- static_cast<Derived *>(this)->handleTLSIE32(ref);
- break;
- case R_ARM_GOT_BREL:
- static_cast<Derived *>(this)->handleGOT(ref);
- break;
- default:
- break;
- }
- }
-
-protected:
- /// \brief Determine source atom's actual code model.
- ///
- /// Actual code model may differ from the existing one if fixup
- /// is possible on the later stages for given relocation type.
- DefinedAtom::CodeModel actualSourceCodeModel(const DefinedAtom &atom,
- const Reference &ref) {
- const auto kindValue = ref.kindValue();
- if (kindValue != R_ARM_CALL && kindValue != R_ARM_THM_CALL)
- return atom.codeModel();
-
- // TODO: For unconditional jump instructions (R_ARM_CALL and R_ARM_THM_CALL)
- // fixup isn't possible without veneer generation for archs below ARMv5.
-
- auto actualModel = atom.codeModel();
- if (const auto *da = dyn_cast<DefinedAtom>(ref.target())) {
- actualModel = da->codeModel();
- } else if (const auto *sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
- if (sla->type() == SharedLibraryAtom::Type::Code) {
- // PLT entry will be generated here - assume we don't want a veneer
- // on top of it and prefer instruction fixup if needed.
- actualModel = DefinedAtom::codeNA;
- }
- }
- return actualModel;
- }
-
- std::error_code handleVeneer(const DefinedAtom &atom, bool fromThumb,
- const Reference &ref) {
- // Actual instruction mode differs meaning that further fixup will be
- // applied.
- if (isThumbCode(&atom) != fromThumb)
- return std::error_code();
-
- const VeneerAtom *(Derived::*getVeneer)(const DefinedAtom *, StringRef) =
- nullptr;
- const auto kindValue = ref.kindValue();
- switch (kindValue) {
- case R_ARM_JUMP24:
- getVeneer = &Derived::getVeneer_ARM_B_BL;
- break;
- case R_ARM_THM_JUMP24:
- getVeneer = &Derived::getVeneer_THM_B_BL;
- break;
- default:
- return std::error_code();
- }
-
- // Target symbol and relocated place should have different
- // instruction sets in order a veneer to be generated in between.
- const auto *target = dyn_cast<DefinedAtom>(ref.target());
- if (!target || isThumbCode(target) == isThumbCode(&atom))
- return std::error_code();
-
- // Veneers may only be generated for STT_FUNC target symbols
- // or for symbols located in sections different to the place of relocation.
- StringRef secName = atom.customSectionName();
- if (DefinedAtom::typeCode != target->contentType() &&
- !target->customSectionName().equals(secName)) {
- StringRef kindValStr;
- if (!this->_ctx.registry().referenceKindToString(
- ref.kindNamespace(), ref.kindArch(), kindValue, kindValStr)) {
- kindValStr = "unknown";
- }
-
- std::string errStr =
- (Twine("Reference of type ") + Twine(kindValue) + " (" + kindValStr +
- ") from " + atom.name() + "+" + Twine(ref.offsetInAtom()) + " to " +
- ref.target()->name() + "+" + Twine(ref.addend()) +
- " cannot be effected without a veneer").str();
-
- llvm_unreachable(errStr.c_str());
- }
-
- assert(getVeneer && "The veneer handler is missing");
- const Atom *veneer =
- (static_cast<Derived *>(this)->*getVeneer)(target, secName);
-
- assert(veneer && "The veneer is not set");
- const_cast<Reference &>(ref).setTarget(veneer);
- return std::error_code();
- }
-
- /// \brief Get the veneer for ARM B/BL instructions
- /// in absolute code.
- const VeneerAtom *getVeneer_ARM_B_BL_Abs(const DefinedAtom *da,
- StringRef secName) {
- auto veneer = _veneerAtoms.lookup(da);
- if (!veneer.empty())
- return veneer._veneer;
-
- std::string name = "__";
- name += da->name();
- name += "_from_arm";
- // Create parts of veneer with mapping symbols.
- auto v_a =
- new (_file._alloc) Veneer_ARM_B_BL_Abs_a_Atom(_file, secName, name);
- addVeneerWithMapping<DefinedAtom::codeARM_a>(da, v_a, name);
- auto v_d = new (_file._alloc) Veneer_ARM_B_BL_Abs_d_Atom(_file, secName);
- addVeneerWithMapping<DefinedAtom::codeARM_d>(v_a, v_d, name);
-
- // Fake reference to show connection between parts of veneer.
- v_a->addReferenceELF_ARM(R_ARM_NONE, 0, v_d, 0);
- // Real reference to fixup.
- v_d->addReferenceELF_ARM(R_ARM_ABS32, 0, da, 0);
- return v_a;
- }
-
- /// \brief Get the veneer for Thumb B/BL instructions
- /// in absolute code.
- const VeneerAtom *getVeneer_THM_B_BL_Abs(const DefinedAtom *da,
- StringRef secName) {
- auto veneer = _veneerAtoms.lookup(da);
- if (!veneer.empty())
- return veneer._veneer;
-
- std::string name = "__";
- name += da->name();
- name += "_from_thumb";
- // Create parts of veneer with mapping symbols.
- auto v_t =
- new (_file._alloc) Veneer_THM_B_BL_Abs_t_Atom(_file, secName, name);
- addVeneerWithMapping<DefinedAtom::codeARM_t>(da, v_t, name);
- auto v_a = new (_file._alloc) Veneer_THM_B_BL_Abs_a_Atom(_file, secName);
- addVeneerWithMapping<DefinedAtom::codeARM_a>(v_t, v_a, name);
-
- // Fake reference to show connection between parts of veneer.
- v_t->addReferenceELF_ARM(R_ARM_NONE, 0, v_a, 0);
- // Real reference to fixup.
- v_a->addReferenceELF_ARM(R_ARM_JUMP24, 0, da, 0);
- return v_t;
- }
-
- std::error_code handleTLSIE32(const Reference &ref) {
- if (const auto *target = dyn_cast<DefinedAtom>(ref.target())) {
- const_cast<Reference &>(ref)
- .setTarget(static_cast<Derived *>(this)->getTLSTPOFF32(target));
- return std::error_code();
- }
- llvm_unreachable("R_ARM_TLS_IE32 reloc targets wrong atom type");
- }
-
- /// \brief Create a GOT entry for TLS with reloc type and addend specified.
- template <Reference::KindValue R_ARM_TLS, Reference::Addend A = 0>
- const GOTAtom *getGOTTLSEntry(const DefinedAtom *da) {
- StringRef source;
-#ifndef NDEBUG
- source = "_tls_";
-#endif
- return getGOT<R_ARM_TLS, A>(da, source);
- }
-
- /// \brief Add veneer with mapping symbol.
- template <DefinedAtom::CodeModel Model>
- void addVeneerWithMapping(const DefinedAtom *da, VeneerAtom *va,
- const std::string &name) {
- assert(_veneerAtoms.lookup(da).empty() &&
- "Veneer or mapping already exists");
- auto *ma = new (_file._alloc)
- ARMVeneerMappingAtom<Model>(_file, va->customSectionName(), name);
-
- // Fake reference to show connection between the mapping symbol and veneer.
- va->addReferenceELF_ARM(R_ARM_NONE, 0, ma, 0);
- _veneerAtoms[da] = VeneerWithMapping(va, ma);
- }
-
- /// \brief get a veneer for a PLT entry.
- const PLTAtom *getPLTVeneer(const Atom *da, PLTAtom *pa, StringRef source) {
- std::string name = "__plt_from_thumb";
- name += source.empty() ? "_" : source;
- name += da->name();
- // Create veneer for PLT entry.
- auto va = new (_file._alloc) ARMPLTVeneerAtom(_file, name);
- // Fake reference to show connection between veneer and PLT entry.
- va->addReferenceELF_ARM(R_ARM_NONE, 0, pa, 0);
-
- _pltAtoms[da] = PLTWithVeneer(pa, va);
- return va;
- }
-
- typedef const GOTAtom *(Derived::*GOTFactory)(const Atom *);
-
- /// \brief get a PLT entry referencing PLTGOT entry.
- ///
- /// If the entry does not exist, both GOT and PLT entry are created.
- const PLTAtom *getPLT(const Atom *da, bool fromThumb, GOTFactory gotFactory,
- StringRef source = "") {
- auto pltVeneer = _pltAtoms.lookup(da);
- if (!pltVeneer.empty()) {
- // Return clean PLT entry provided it is ARM code.
- if (!fromThumb)
- return pltVeneer._plt;
-
- // Check if veneer is present for Thumb to ARM transition.
- if (pltVeneer._veneer)
- return pltVeneer._veneer;
-
- // Create veneer for existing PLT entry.
- return getPLTVeneer(da, pltVeneer._plt, source);
- }
-
- // Create specific GOT entry.
- const auto *ga = (static_cast<Derived *>(this)->*gotFactory)(da);
- assert(_gotpltAtoms.lookup(da) == ga &&
- "GOT entry should be added to the PLTGOT map");
- assert(ga->customSectionName() == ".got.plt" &&
- "GOT entry should be in a special section");
-
- std::string name = "__plt";
- name += source.empty() ? "_" : source;
- name += da->name();
- // Create PLT entry for the GOT entry.
- auto pa = new (_file._alloc) ARMPLTAtom(_file, name);
- pa->addReferenceELF_ARM(R_ARM_ALU_PC_G0_NC, 0, ga, -8);
- pa->addReferenceELF_ARM(R_ARM_ALU_PC_G1_NC, 4, ga, -4);
- pa->addReferenceELF_ARM(R_ARM_LDR_PC_G2, 8, ga, 0);
-
- // Since all PLT entries are in ARM code, Thumb to ARM
- // switching should be added if the relocated place contais Thumb code.
- if (fromThumb)
- return getPLTVeneer(da, pa, source);
-
- // Otherwise just add PLT entry and return it to the caller.
- _pltAtoms[da] = PLTWithVeneer(pa);
- return pa;
- }
-
- /// \brief Create the GOT entry for a given IFUNC Atom.
- const GOTAtom *createIFUNCGOT(const Atom *da) {
- assert(!_gotpltAtoms.lookup(da) && "IFUNC GOT entry already exists");
- auto g = new (_file._alloc) ARMGOTPLTAtom(_file);
- g->addReferenceELF_ARM(R_ARM_ABS32, 0, da, 0);
- g->addReferenceELF_ARM(R_ARM_IRELATIVE, 0, da, 0);
-#ifndef NDEBUG
- g->_name = "__got_ifunc_";
- g->_name += da->name();
-#endif
- _gotpltAtoms[da] = g;
- return g;
- }
-
- /// \brief get the PLT entry for a given IFUNC Atom.
- const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da, bool fromThumb) {
- return getPLT(da, fromThumb, &Derived::createIFUNCGOT, "_ifunc_");
- }
-
- /// \brief Redirect the call to the PLT stub for the target IFUNC.
- ///
- /// This create a PLT and GOT entry for the IFUNC if one does not exist. The
- /// GOT entry and a IRELATIVE relocation to the original target resolver.
- std::error_code handleIFUNC(bool fromThumb, const Reference &ref) {
- auto target = dyn_cast<const DefinedAtom>(ref.target());
- if (target && target->contentType() == DefinedAtom::typeResolver) {
- const_cast<Reference &>(ref)
- .setTarget(getIFUNCPLTEntry(target, fromThumb));
- }
- return std::error_code();
- }
-
- /// \brief Create a GOT entry containing 0.
- const GOTAtom *getNullGOT() {
- if (!_null) {
- _null = new (_file._alloc) ARMGOTPLTAtom(_file);
-#ifndef NDEBUG
- _null->_name = "__got_null";
-#endif
- }
- return _null;
- }
-
- /// \brief Create regular GOT entry which cannot be used in PLTGOT operation.
- template <Reference::KindValue R_ARM_REL, Reference::Addend A = 0>
- const GOTAtom *getGOT(const Atom *da, StringRef source = "") {
- if (auto got = _gotAtoms.lookup(da))
- return got;
- auto g = new (_file._alloc) ARMGOTAtom(_file);
- g->addReferenceELF_ARM(R_ARM_REL, 0, da, A);
-#ifndef NDEBUG
- g->_name = "__got";
- g->_name += source.empty() ? "_" : source;
- g->_name += da->name();
-#endif
- _gotAtoms[da] = g;
- return g;
- }
-
- /// \brief get GOT entry for a regular defined atom.
- const GOTAtom *getGOTEntry(const DefinedAtom *da) {
- return getGOT<R_ARM_ABS32>(da);
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getNullGOT());
- else if (const auto *da = dyn_cast<DefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOTEntry(da));
- return std::error_code();
- }
-
-public:
- ARMRelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {}
-
- /// \brief Do the pass.
- ///
- /// The goal here is to first process each reference individually. Each call
- /// to handleReference may modify the reference itself and/or create new
- /// atoms which must be stored in one of the maps below.
- ///
- /// After all references are handled, the atoms created during that are all
- /// added to mf.
- std::error_code perform(SimpleFile &mf) override {
- ScopedTask task(getDefaultDomain(), "ARM GOT/PLT Pass");
- DEBUG_WITH_TYPE(
- "ARM", llvm::dbgs() << "Undefined Atoms" << "\n";
- for (const auto &atom
- : mf.undefined()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- }
-
- llvm::dbgs() << "Shared Library Atoms" << "\n";
- for (const auto &atom
- : mf.sharedLibrary()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- }
-
- llvm::dbgs() << "Absolute Atoms" << "\n";
- for (const auto &atom
- : mf.absolute()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- }
-
- llvm::dbgs() << "Defined Atoms" << "\n";
- for (const auto &atom
- : mf.defined()) {
- llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n";
- });
-
- // Process all references.
- for (const auto &atom : mf.defined()) {
- for (const auto &ref : *atom) {
- handleReference(*atom, *ref);
- }
- }
-
- // Add all created atoms to the link.
- uint64_t ordinal = 0;
- if (_plt0) {
- _plt0->setOrdinal(ordinal++);
- mf.addAtom(*_plt0);
- _plt0_d->setOrdinal(ordinal++);
- mf.addAtom(*_plt0_d);
- }
- for (auto &pltKV : _pltAtoms) {
- auto &plt = pltKV.second;
- if (auto *v = plt._veneer) {
- v->setOrdinal(ordinal++);
- mf.addAtom(*v);
- }
- auto *p = plt._plt;
- p->setOrdinal(ordinal++);
- mf.addAtom(*p);
- }
- if (_null) {
- _null->setOrdinal(ordinal++);
- mf.addAtom(*_null);
- }
- if (_plt0) {
- _got0->setOrdinal(ordinal++);
- mf.addAtom(*_got0);
- _got1->setOrdinal(ordinal++);
- mf.addAtom(*_got1);
- }
- for (auto &gotKV : _gotAtoms) {
- auto &got = gotKV.second;
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
- for (auto &gotKV : _gotpltAtoms) {
- auto &got = gotKV.second;
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
- for (auto &objectKV : _objectAtoms) {
- auto &obj = objectKV.second;
- obj->setOrdinal(ordinal++);
- mf.addAtom(*obj);
- }
- for (auto &veneerKV : _veneerAtoms) {
- auto &veneer = veneerKV.second;
- auto *m = veneer._mapping;
- m->setOrdinal(ordinal++);
- mf.addAtom(*m);
- auto *v = veneer._veneer;
- v->setOrdinal(ordinal++);
- mf.addAtom(*v);
- }
-
- return std::error_code();
- }
-
-protected:
- /// \brief Owner of all the Atoms created by this pass.
- ELFPassFile _file;
- const ELFLinkingContext &_ctx;
-
- /// \brief Map Atoms to their GOT entries.
- llvm::MapVector<const Atom *, GOTAtom *> _gotAtoms;
-
- /// \brief Map Atoms to their PLTGOT entries.
- llvm::MapVector<const Atom *, GOTAtom *> _gotpltAtoms;
-
- /// \brief Map Atoms to their Object entries.
- llvm::MapVector<const Atom *, ObjectAtom *> _objectAtoms;
-
- /// \brief Map Atoms to their PLT entries depending on the code model.
- struct PLTWithVeneer {
- PLTWithVeneer(PLTAtom *p = nullptr, PLTAtom *v = nullptr)
- : _plt(p), _veneer(v) {}
-
- bool empty() const {
- assert((_plt || !_veneer) && "Veneer appears without PLT entry");
- return !_plt && !_veneer;
- }
-
- PLTAtom *_plt;
- PLTAtom *_veneer;
- };
- llvm::MapVector<const Atom *, PLTWithVeneer> _pltAtoms;
-
- /// \brief Map Atoms to their veneers.
- struct VeneerWithMapping {
- VeneerWithMapping(VeneerAtom *v = nullptr, VeneerAtom *m = nullptr)
- : _veneer(v), _mapping(m) {}
-
- bool empty() const {
- assert(((bool)_veneer == (bool)_mapping) &&
- "Mapping symbol should always be paired with veneer");
- return !_veneer && !_mapping;
- }
-
- VeneerAtom *_veneer;
- VeneerAtom *_mapping;
- };
- llvm::MapVector<const Atom *, VeneerWithMapping> _veneerAtoms;
-
- /// \brief GOT entry that is always 0. Used for undefined weaks.
- GOTAtom *_null = nullptr;
-
- /// \brief The got and plt entries for .PLT0. This is used to call into the
- /// dynamic linker for symbol resolution.
- /// @{
- PLT0Atom *_plt0 = nullptr;
- PLT0Atom *_plt0_d = nullptr;
- GOTAtom *_got0 = nullptr;
- GOTAtom *_got1 = nullptr;
- /// @}
-};
-
-/// This implements the static relocation model. Meaning GOT and PLT entries are
-/// not created for references that can be directly resolved. These are
-/// converted to a direct relocation. For entries that do require a GOT or PLT
-/// entry, that entry is statically bound.
-///
-/// TLS always assumes module 1 and attempts to remove indirection.
-class ARMStaticRelocationPass final
- : public ARMRelocationPass<ARMStaticRelocationPass> {
-public:
- ARMStaticRelocationPass(const elf::ARMLinkingContext &ctx)
- : ARMRelocationPass(ctx) {}
-
- /// \brief Handle ordinary relocation references.
- std::error_code handlePlain(bool fromThumb, const Reference &ref) {
- return handleIFUNC(fromThumb, ref);
- }
-
- /// \brief Get the veneer for ARM B/BL instructions.
- const VeneerAtom *getVeneer_ARM_B_BL(const DefinedAtom *da,
- StringRef secName) {
- return getVeneer_ARM_B_BL_Abs(da, secName);
- }
-
- /// \brief Get the veneer for Thumb B/BL instructions.
- const VeneerAtom *getVeneer_THM_B_BL(const DefinedAtom *da,
- StringRef secName) {
- return getVeneer_THM_B_BL_Abs(da, secName);
- }
-
- /// \brief Create a GOT entry for R_ARM_TLS_TPOFF32 reloc.
- const GOTAtom *getTLSTPOFF32(const DefinedAtom *da) {
- return getGOTTLSEntry<R_ARM_TLS_LE32>(da);
- }
-};
-
-/// This implements the dynamic relocation model. GOT and PLT entries are
-/// created for references that cannot be directly resolved.
-class ARMDynamicRelocationPass final
- : public ARMRelocationPass<ARMDynamicRelocationPass> {
-public:
- ARMDynamicRelocationPass(const elf::ARMLinkingContext &ctx)
- : ARMRelocationPass(ctx) {}
-
- /// \brief get the PLT entry for a given atom.
- const PLTAtom *getPLTEntry(const SharedLibraryAtom *sla, bool fromThumb) {
- return getPLT(sla, fromThumb, &ARMDynamicRelocationPass::createPLTGOT);
- }
-
- /// \brief Create the GOT entry for a given atom.
- const GOTAtom *createPLTGOT(const Atom *da) {
- assert(!_gotpltAtoms.lookup(da) && "PLTGOT entry already exists");
- auto g = new (_file._alloc) ARMGOTPLTAtom(_file);
- g->addReferenceELF_ARM(R_ARM_ABS32, 0, getPLT0(), 0);
- g->addReferenceELF_ARM(R_ARM_JUMP_SLOT, 0, da, 0);
-#ifndef NDEBUG
- g->_name = "__got_plt0_";
- g->_name += da->name();
-#endif
- _gotpltAtoms[da] = g;
- return g;
- }
-
- const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
- if (auto obj = _objectAtoms.lookup(a))
- return obj;
-
- auto oa = new (_file._alloc) ARMObjectAtom(_file);
- oa->addReferenceELF_ARM(R_ARM_COPY, 0, oa, 0);
-
- oa->_name = a->name();
- oa->_size = a->size();
-
- _objectAtoms[a] = oa;
- return oa;
- }
-
- /// \brief Handle ordinary relocation references.
- std::error_code handlePlain(bool fromThumb, const Reference &ref) {
- if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
- if (sla->type() == SharedLibraryAtom::Type::Data &&
- _ctx.getOutputELFType() == llvm::ELF::ET_EXEC) {
- const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
- } else if (sla->type() == SharedLibraryAtom::Type::Code) {
- const_cast<Reference &>(ref).setTarget(getPLTEntry(sla, fromThumb));
- }
- return std::error_code();
- }
- return handleIFUNC(fromThumb, ref);
- }
-
- /// \brief Get the veneer for ARM B/BL instructions.
- const VeneerAtom *getVeneer_ARM_B_BL(const DefinedAtom *da,
- StringRef secName) {
- if (_ctx.getOutputELFType() == llvm::ELF::ET_EXEC) {
- return getVeneer_ARM_B_BL_Abs(da, secName);
- }
- llvm_unreachable("Handle ARM veneer for DSOs");
- }
-
- /// \brief Get the veneer for Thumb B/BL instructions.
- const VeneerAtom *getVeneer_THM_B_BL(const DefinedAtom *da,
- StringRef secName) {
- if (_ctx.getOutputELFType() == llvm::ELF::ET_EXEC) {
- return getVeneer_THM_B_BL_Abs(da, secName);
- }
- llvm_unreachable("Handle Thumb veneer for DSOs");
- }
-
- /// \brief Create a GOT entry for R_ARM_TLS_TPOFF32 reloc.
- const GOTAtom *getTLSTPOFF32(const DefinedAtom *da) {
- return getGOTTLSEntry<R_ARM_TLS_TPOFF32>(da);
- }
-
- const PLT0Atom *getPLT0() {
- if (_plt0)
- return _plt0;
- // Fill in the null entry.
- getNullGOT();
- _plt0 = new (_file._alloc) ARMPLT0_a_Atom(_file, "__PLT0");
- _plt0_d = new (_file._alloc) ARMPLT0_d_Atom(_file, "__PLT0_d");
- _got0 = new (_file._alloc) ARMGOTPLTAtom(_file);
- _got1 = new (_file._alloc) ARMGOTPLTAtom(_file);
- _plt0_d->addReferenceELF_ARM(R_ARM_REL32, 0, _got1, 0);
- // Fake reference to show connection between the GOT and PLT entries.
- _plt0->addReferenceELF_ARM(R_ARM_NONE, 0, _got0, 0);
- // Fake reference to show connection between parts of PLT entry.
- _plt0->addReferenceELF_ARM(R_ARM_NONE, 0, _plt0_d, 0);
-#ifndef NDEBUG
- _got0->_name = "__got0";
- _got1->_name = "__got1";
-#endif
- return _plt0;
- }
-
- const GOTAtom *getSharedGOTEntry(const SharedLibraryAtom *sla) {
- return getGOT<R_ARM_GLOB_DAT>(sla);
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (const auto sla = dyn_cast<const SharedLibraryAtom>(ref.target())) {
- const_cast<Reference &>(ref).setTarget(getSharedGOTEntry(sla));
- return std::error_code();
- }
- return ARMRelocationPass::handleGOT(ref);
- }
-};
-
-} // end of anon namespace
-
-std::unique_ptr<Pass>
-lld::elf::createARMRelocationPass(const ARMLinkingContext &ctx) {
- switch (ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- if (ctx.isDynamic())
- return llvm::make_unique<ARMDynamicRelocationPass>(ctx);
- return llvm::make_unique<ARMStaticRelocationPass>(ctx);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<ARMDynamicRelocationPass>(ctx);
- default:
- llvm_unreachable("Unhandled output file type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h (removed)
@@ -1,31 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMRelocationPass.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Declares the relocation processing pass for ARM. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_RELOCATION_PASS_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_RELOCATION_PASS_H
-
-#include <memory>
-
-namespace lld {
-class Pass;
-namespace elf {
-class ARMLinkingContext;
-
-/// \brief Create ARM relocation pass for the given linking context.
-std::unique_ptr<Pass> createARMRelocationPass(const ARMLinkingContext &);
-}
-}
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h (removed)
@@ -1,59 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_SYMBOL_TABLE_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_SYMBOL_TABLE_H
-
-#include "SectionChunks.h"
-#include "TargetLayout.h"
-#include "ARMELFFile.h"
-
-namespace lld {
-namespace elf {
-
-/// \brief The SymbolTable class represents the symbol table in a ELF file
-class ARMSymbolTable : public SymbolTable<ELF32LE> {
-public:
- typedef llvm::object::Elf_Sym_Impl<ELF32LE> Elf_Sym;
-
- ARMSymbolTable(const ELFLinkingContext &ctx);
-
- void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) override;
-};
-
-ARMSymbolTable::ARMSymbolTable(const ELFLinkingContext &ctx)
- : SymbolTable(ctx, ".symtab", TargetLayout<ELF32LE>::ORDER_SYMBOL_TABLE) {}
-
-void ARMSymbolTable::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) {
- SymbolTable::addDefinedAtom(sym, da, addr);
-
- if ((ARMELFDefinedAtom::ARMContentType)da->contentType() ==
- ARMELFDefinedAtom::typeARMExidx)
- sym.st_value = addr;
-
- // Set zero bit to distinguish real symbols addressing Thumb instructions.
- // Don't care about mapping symbols like $t and others.
- if (DefinedAtom::codeARMThumb == da->codeModel())
- sym.st_value = static_cast<int64_t>(sym.st_value) | 0x1;
-
- // Mapping symbols should have special values of binding, type and size set.
- if ((DefinedAtom::codeARM_a == da->codeModel()) ||
- (DefinedAtom::codeARM_d == da->codeModel()) ||
- (DefinedAtom::codeARM_t == da->codeModel())) {
- sym.setBindingAndType(llvm::ELF::STB_LOCAL, llvm::ELF::STT_NOTYPE);
- sym.st_size = 0;
- }
-}
-
-} // elf
-} // lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_SYMBOL_TABLE_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp (removed)
@@ -1,32 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMTargetHandler.cpp --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Atoms.h"
-#include "ARMExecutableWriter.h"
-#include "ARMDynamicLibraryWriter.h"
-#include "ARMTargetHandler.h"
-#include "ARMLinkingContext.h"
-
-using namespace lld;
-using namespace elf;
-
-ARMTargetHandler::ARMTargetHandler(ARMLinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new ARMTargetLayout(ctx)),
- _relocationHandler(new ARMTargetRelocationHandler(*_targetLayout)) {}
-
-std::unique_ptr<Writer> ARMTargetHandler::getWriter() {
- switch (this->_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<ARMExecutableWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<ARMDynamicLibraryWriter>(_ctx, *_targetLayout);
- default:
- llvm_unreachable("unsupported output type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h (removed)
@@ -1,174 +0,0 @@
-//===--------- lib/ReaderWriter/ELF/ARM/ARMTargetHandler.h ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ARM_ARM_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_ARM_ARM_TARGET_HANDLER_H
-
-#include "ARMELFFile.h"
-#include "ARMRelocationHandler.h"
-#include "ELFReader.h"
-#include "TargetLayout.h"
-
-namespace lld {
-class ELFLinkingContext;
-
-namespace elf {
-
-/// \brief ARM specific section (.ARM.exidx) with indexes to exception handlers
-class ARMExidxSection : public AtomSection<ELF32LE> {
- typedef AtomSection<ELF32LE> Base;
-
-public:
- ARMExidxSection(const ELFLinkingContext &ctx, StringRef sectionName,
- int32_t permissions, int32_t order)
- : Base(ctx, sectionName, ARMELFDefinedAtom::typeARMExidx, permissions,
- order) {
- this->_type = SHT_ARM_EXIDX;
- this->_isLoadedInMemory = true;
- }
-
- bool hasOutputSegment() const override { return true; }
-
- const AtomLayout *appendAtom(const Atom *atom) override {
- const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
- assert((ARMELFDefinedAtom::ARMContentType)definedAtom->contentType() ==
- ARMELFDefinedAtom::typeARMExidx &&
- "atom content type for .ARM.exidx section has to be typeARMExidx");
-
- DefinedAtom::Alignment atomAlign = definedAtom->alignment();
- uint64_t fOffset = alignOffset(this->fileSize(), atomAlign);
- uint64_t mOffset = alignOffset(this->memSize(), atomAlign);
-
- _atoms.push_back(new (_alloc) AtomLayout(atom, fOffset, 0));
- this->_fsize = fOffset + definedAtom->size();
- this->_msize = mOffset + definedAtom->size();
- DEBUG_WITH_TYPE("Section", llvm::dbgs()
- << "[" << this->name() << " " << this << "] "
- << "Adding atom: " << atom->name() << "@"
- << fOffset << "\n");
-
- uint64_t alignment = atomAlign.value;
- if (this->_alignment < alignment)
- this->_alignment = alignment;
-
- return _atoms.back();
- }
-};
-
-class ARMTargetLayout : public TargetLayout<ELF32LE> {
-public:
- enum ARMSectionOrder {
- ORDER_ARM_EXIDX = TargetLayout::ORDER_EH_FRAME + 1,
- };
-
- ARMTargetLayout(ELFLinkingContext &ctx) : TargetLayout(ctx) {}
-
- SectionOrder getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) override {
- switch (contentType) {
- case ARMELFDefinedAtom::typeARMExidx:
- return ORDER_ARM_EXIDX;
- default:
- return TargetLayout::getSectionOrder(name, contentType,
- contentPermissions);
- }
- }
-
- StringRef getOutputSectionName(StringRef archivePath, StringRef memberPath,
- StringRef inputSectionName) const override {
- return llvm::StringSwitch<StringRef>(inputSectionName)
- .StartsWith(".ARM.exidx", ".ARM.exidx")
- .StartsWith(".ARM.extab", ".ARM.extab")
- .Default(TargetLayout::getOutputSectionName(archivePath, memberPath,
- inputSectionName));
- }
-
- SegmentType getSegmentType(const Section<ELF32LE> *section) const override {
- switch (section->order()) {
- case ORDER_ARM_EXIDX:
- return llvm::ELF::PT_ARM_EXIDX;
- default:
- return TargetLayout::getSegmentType(section);
- }
- }
-
- AtomSection<ELF32LE> *
- createSection(StringRef name, int32_t contentType,
- DefinedAtom::ContentPermissions contentPermissions,
- SectionOrder sectionOrder) override {
- if ((ARMELFDefinedAtom::ARMContentType)contentType ==
- ARMELFDefinedAtom::typeARMExidx)
- return new ARMExidxSection(_ctx, name, contentPermissions, sectionOrder);
-
- return TargetLayout::createSection(name, contentType, contentPermissions,
- sectionOrder);
- }
-
- uint64_t getGOTSymAddr() {
- std::call_once(_gotSymOnce, [this]() {
- if (AtomLayout *gotAtom = findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"))
- _gotSymAddr = gotAtom->_virtualAddr;
- });
- return _gotSymAddr;
- }
-
- uint64_t getTPOffset() {
- std::call_once(_tpOffOnce, [this]() {
- for (const auto &phdr : *_programHeader) {
- if (phdr->p_type == llvm::ELF::PT_TLS) {
- _tpOff = llvm::alignTo(TCB_SIZE, phdr->p_align);
- break;
- }
- }
- assert(_tpOff != 0 && "TLS segment not found");
- });
- return _tpOff;
- }
-
- bool target1Rel() const { return _ctx.armTarget1Rel(); }
-
-private:
- // TCB block size of the TLS.
- enum { TCB_SIZE = 0x8 };
-
-private:
- uint64_t _gotSymAddr = 0;
- uint64_t _tpOff = 0;
- std::once_flag _gotSymOnce;
- std::once_flag _tpOffOnce;
-};
-
-class ARMTargetHandler final : public TargetHandler {
-public:
- ARMTargetHandler(ARMLinkingContext &ctx);
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<ARMELFFile>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELF32LE>>>(_ctx);
- }
-
- std::unique_ptr<Writer> getWriter() override;
-
-private:
- ARMLinkingContext &_ctx;
- std::unique_ptr<ARMTargetLayout> _targetLayout;
- std::unique_ptr<ARMTargetRelocationHandler> _relocationHandler;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ARM_ARM_TARGET_HANDLER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/CMakeLists.txt (removed)
@@ -1,12 +0,0 @@
-add_lld_library(lldARMELFTarget
- ARMLinkingContext.cpp
- ARMTargetHandler.cpp
- ARMRelocationHandler.cpp
- ARMRelocationPass.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/ARM/TODO.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/TODO.rst?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/TODO.rst (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/TODO.rst (removed)
@@ -1,21 +0,0 @@
-ELF ARM
-~~~~~~~~~~~
-
-Unimplemented Features
-######################
-
-* DSO linking
-* C++ code linking
-* PLT entries' generation for images larger than 2^28 bytes (see Sec. A.3 of the ARM ELF reference)
-* ARM/Thumb interwork veneers in position-independent code
-* .ARM.exidx section (exception handling)
-* -init/-fini options
-* Proper debug information (DWARF data)
-* TLS relocations for dynamic models
-* Lots of other relocations
-
-Unimplemented Relocations
-#########################
-
-All of these relocations are defined in:
-http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
Removed: lld/trunk/lib/ReaderWriter/ELF/Atoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.cpp (removed)
@@ -1,297 +0,0 @@
-//===- lib/ReaderWriter/ELF/Atoms.cpp -------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Atoms.h"
-#include "DynamicFile.h"
-#include "ELFFile.h"
-#include "TargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> AbsoluteAtom::Scope ELFAbsoluteAtom<ELFT>::scope() const {
- if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() == llvm::ELF::STB_LOCAL)
- return scopeTranslationUnit;
- return scopeGlobal;
-}
-
-template <class ELFT>
-UndefinedAtom::CanBeNull ELFUndefinedAtom<ELFT>::canBeNull() const {
- if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
- return CanBeNull::canBeNullAtBuildtime;
- return CanBeNull::canBeNullNever;
-}
-
-template <class ELFT> uint64_t ELFDefinedAtom<ELFT>::size() const {
- // Common symbols are not allocated in object files,
- // so use st_size to tell how many bytes are required.
- if (_symbol && (_symbol->getType() == llvm::ELF::STT_COMMON ||
- _symbol->st_shndx == llvm::ELF::SHN_COMMON))
- return (uint64_t)_symbol->st_size;
-
- return _contentData.size();
-}
-
-template <class ELFT> AbsoluteAtom::Scope ELFDefinedAtom<ELFT>::scope() const {
- if (!_symbol)
- return scopeGlobal;
- if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
- return scopeGlobal;
- return scopeTranslationUnit;
-}
-
-template <class ELFT> DefinedAtom::Merge ELFDefinedAtom<ELFT>::merge() const {
- if (!_symbol)
- return mergeNo;
- if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
- return mergeAsWeak;
- if (_symbol->getType() == llvm::ELF::STT_COMMON ||
- _symbol->st_shndx == llvm::ELF::SHN_COMMON)
- return mergeAsTentative;
- return mergeNo;
-}
-
-template <class ELFT>
-DefinedAtom::ContentType ELFDefinedAtom<ELFT>::doContentType() const {
- using namespace llvm::ELF;
-
- if (_section->sh_type == SHT_GROUP)
- return typeGroupComdat;
- if (!_symbol && _sectionName.startswith(".gnu.linkonce"))
- return typeGnuLinkOnce;
-
- uint64_t flags = _section->sh_flags;
-
- if (!(flags & SHF_ALLOC)) {
- if (_section->sh_type == SHT_NOTE)
- return (flags == SHF_WRITE) ? typeRWNote : typeRONote;
- return _contentType = typeNoAlloc;
- }
-
- if (_section->sh_flags == (SHF_ALLOC | SHF_WRITE | SHF_TLS))
- return _section->sh_type == SHT_NOBITS ? typeThreadZeroFill
- : typeThreadData;
-
- if (_section->sh_flags == SHF_ALLOC && _section->sh_type == SHT_PROGBITS)
- return _contentType = typeConstant;
- if (_symbol->getType() == STT_GNU_IFUNC)
- return _contentType = typeResolver;
- if (_symbol->st_shndx == SHN_COMMON)
- return _contentType = typeZeroFill;
-
- if (_section->sh_type == SHT_PROGBITS) {
- flags &= ~SHF_ALLOC;
- flags &= ~SHF_GROUP;
- if ((flags & SHF_STRINGS) || (flags & SHF_MERGE))
- return typeConstant;
- if (flags == SHF_WRITE)
- return typeData;
- return typeCode;
- }
- if (_section->sh_type == SHT_NOTE) {
- flags &= ~SHF_ALLOC;
- return (flags == SHF_WRITE) ? typeRWNote : typeRONote;
- }
- if (_section->sh_type == SHT_NOBITS)
- return typeZeroFill;
-
- if (_section->sh_type == SHT_NULL)
- if (_symbol->getType() == STT_COMMON || _symbol->st_shndx == SHN_COMMON)
- return typeZeroFill;
-
- if (_section->sh_type == SHT_INIT_ARRAY ||
- _section->sh_type == SHT_FINI_ARRAY)
- return typeData;
- return typeUnknown;
-}
-
-template <class ELFT>
-DefinedAtom::ContentType ELFDefinedAtom<ELFT>::contentType() const {
- if (_contentType != typeUnknown)
- return _contentType;
- _contentType = doContentType();
- return _contentType;
-}
-
-template <class ELFT>
-DefinedAtom::Alignment ELFDefinedAtom<ELFT>::alignment() const {
- if (!_symbol)
- return 1;
-
- // Obtain proper value of st_value field.
- const auto symValue = getSymbolValue();
-
- // Unallocated common symbols specify their alignment constraints in
- // st_value.
- if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
- _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
- return symValue;
- }
- if (_section->sh_addralign == 0) {
- // sh_addralign of 0 means no alignment
- return Alignment(1, symValue);
- }
- return Alignment(_section->sh_addralign, symValue % _section->sh_addralign);
-}
-
-// Do we have a choice for ELF? All symbols live in explicit sections.
-template <class ELFT>
-DefinedAtom::SectionChoice ELFDefinedAtom<ELFT>::sectionChoice() const {
- switch (contentType()) {
- case typeCode:
- case typeData:
- case typeZeroFill:
- case typeThreadZeroFill:
- case typeThreadData:
- case typeConstant:
- if ((_sectionName == ".text") || (_sectionName == ".data") ||
- (_sectionName == ".bss") || (_sectionName == ".rodata") ||
- (_sectionName == ".tdata") || (_sectionName == ".tbss"))
- return sectionBasedOnContent;
- default:
- break;
- }
- return sectionCustomRequired;
-}
-
-template <class ELFT>
-StringRef ELFDefinedAtom<ELFT>::customSectionName() const {
- if ((contentType() == typeZeroFill) ||
- (_symbol && _symbol->st_shndx == llvm::ELF::SHN_COMMON))
- return ".bss";
- return _sectionName;
-}
-
-template <class ELFT>
-DefinedAtom::ContentPermissions ELFDefinedAtom<ELFT>::permissions() const {
- if (_permissions != permUnknown)
- return _permissions;
-
- uint64_t flags = _section->sh_flags;
-
- if (!(flags & llvm::ELF::SHF_ALLOC))
- return _permissions = perm___;
-
- switch (_section->sh_type) {
- // permRW_L is for sections modified by the runtime
- // loader.
- case llvm::ELF::SHT_REL:
- case llvm::ELF::SHT_RELA:
- return _permissions = permRW_L;
-
- case llvm::ELF::SHT_DYNAMIC:
- case llvm::ELF::SHT_PROGBITS:
- case llvm::ELF::SHT_NOTE:
- flags &= ~llvm::ELF::SHF_ALLOC;
- flags &= ~llvm::ELF::SHF_GROUP;
- switch (flags) {
- // Code
- case llvm::ELF::SHF_EXECINSTR:
- return _permissions = permR_X;
- case (llvm::ELF::SHF_WRITE | llvm::ELF::SHF_EXECINSTR):
- return _permissions = permRWX;
- // Data
- case llvm::ELF::SHF_WRITE:
- return _permissions = permRW_;
- // Strings
- case llvm::ELF::SHF_MERGE:
- case llvm::ELF::SHF_STRINGS:
- return _permissions = permR__;
-
- default:
- if (flags & llvm::ELF::SHF_WRITE)
- return _permissions = permRW_;
- return _permissions = permR__;
- }
-
- case llvm::ELF::SHT_NOBITS:
- return _permissions = permRW_;
-
- case llvm::ELF::SHT_INIT_ARRAY:
- case llvm::ELF::SHT_FINI_ARRAY:
- return _permissions = permRW_;
-
- default:
- return _permissions = perm___;
- }
-}
-
-template <class ELFT>
-DefinedAtom::reference_iterator ELFDefinedAtom<ELFT>::begin() const {
- uintptr_t index = _referenceStartIndex;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
-}
-
-template <class ELFT>
-DefinedAtom::reference_iterator ELFDefinedAtom<ELFT>::end() const {
- uintptr_t index = _referenceEndIndex;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
-}
-
-template <class ELFT>
-const Reference *ELFDefinedAtom<ELFT>::derefIterator(const void *It) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(It);
- assert(index >= _referenceStartIndex);
- assert(index < _referenceEndIndex);
- return ((_referenceList)[index]);
-}
-
-template <class ELFT>
-void ELFDefinedAtom<ELFT>::incrementIterator(const void *&It) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(It);
- ++index;
- It = reinterpret_cast<const void *>(index);
-}
-
-template <class ELFT>
-void ELFDefinedAtom<ELFT>::addReference(ELFReference<ELFT> *reference) {
- _referenceList.push_back(reference);
- _referenceEndIndex = _referenceList.size();
-}
-
-template <class ELFT> AbsoluteAtom::Scope ELFDynamicAtom<ELFT>::scope() const {
- if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
- return scopeGlobal;
- return scopeTranslationUnit;
-}
-
-template <class ELFT>
-SharedLibraryAtom::Type ELFDynamicAtom<ELFT>::type() const {
- switch (_symbol->getType()) {
- case llvm::ELF::STT_FUNC:
- case llvm::ELF::STT_GNU_IFUNC:
- return Type::Code;
- case llvm::ELF::STT_OBJECT:
- return Type::Data;
- default:
- return Type::Unknown;
- }
-}
-
-#define INSTANTIATE(klass) \
- template class klass<ELF32LE>; \
- template class klass<ELF32BE>; \
- template class klass<ELF64LE>; \
- template class klass<ELF64BE>
-
-INSTANTIATE(ELFAbsoluteAtom);
-INSTANTIATE(ELFDefinedAtom);
-INSTANTIATE(ELFDynamicAtom);
-INSTANTIATE(ELFUndefinedAtom);
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h (removed)
@@ -1,495 +0,0 @@
-//===- lib/ReaderWriter/ELF/Atoms.h ---------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ATOMS_H
-#define LLD_READER_WRITER_ELF_ATOMS_H
-
-#include "TargetHandler.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/Simple.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include <memory>
-#include <vector>
-
-namespace lld {
-namespace elf {
-template <class ELFT> class DynamicFile;
-template <typename ELFT> class ELFFile;
-
-/// \brief Relocation References: Defined Atoms may contain references that will
-/// need to be patched before the executable is written.
-///
-/// Construction of ELFReferences is two pass process. ELFReferences are
-/// instantiated while we are iterating over symbol tables to atomize
-/// symbols. At that time we only know the index of relocation target symbol
-/// (not target atom) about a relocation, so we store the index to
-/// ELFREference. In the second pass, ELFReferences are revisited to update
-/// target atoms by target symbol indexes.
-template <class ELFT> class ELFReference : public Reference {
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFReference(const Elf_Rela *rela, uint64_t off, Reference::KindArch arch,
- Reference::KindValue relocType, uint32_t idx)
- : Reference(Reference::KindNamespace::ELF, arch, relocType),
- _targetSymbolIndex(idx), _offsetInAtom(off), _addend(rela->r_addend) {}
-
- ELFReference(uint64_t off, Reference::KindArch arch,
- Reference::KindValue relocType, uint32_t idx)
- : Reference(Reference::KindNamespace::ELF, arch, relocType),
- _targetSymbolIndex(idx), _offsetInAtom(off) {}
-
- ELFReference(uint32_t edgeKind)
- : Reference(Reference::KindNamespace::all, Reference::KindArch::all,
- edgeKind) {}
-
- uint64_t offsetInAtom() const override { return _offsetInAtom; }
-
- const Atom *target() const override { return _target; }
-
- /// \brief The symbol table index that contains the target reference.
- uint64_t targetSymbolIndex() const {
- return _targetSymbolIndex;
- }
-
- Addend addend() const override { return _addend; }
-
- virtual void setOffset(uint64_t off) { _offsetInAtom = off; }
-
- void setAddend(Addend A) override { _addend = A; }
-
- void setTarget(const Atom *newAtom) override { _target = newAtom; }
-
-private:
- const Atom *_target = nullptr;
- uint64_t _targetSymbolIndex = 0;
- uint64_t _offsetInAtom = 0;
- Addend _addend = 0;
-};
-
-/// \brief These atoms store symbols that are fixed to a particular address.
-/// This atom has no content its address will be used by the writer to fixup
-/// references that point to it.
-template <class ELFT> class ELFAbsoluteAtom : public AbsoluteAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFAbsoluteAtom(const ELFFile<ELFT> &file, StringRef name,
- const Elf_Sym *symbol, uint64_t value)
- : _owningFile(file), _name(name), _symbol(symbol), _value(value) {}
-
- const ELFFile<ELFT> &file() const override { return _owningFile; }
- Scope scope() const override;
- StringRef name() const override { return _name; }
- uint64_t value() const override { return _value; }
-
-private:
- const ELFFile<ELFT> &_owningFile;
- StringRef _name;
- const Elf_Sym *_symbol;
- uint64_t _value;
-};
-
-/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
-/// holders that will be replaced by defined atoms later in the linking process.
-template <class ELFT> class ELFUndefinedAtom : public UndefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFUndefinedAtom(const File &file, StringRef name, const Elf_Sym *symbol)
- : _owningFile(file), _name(name), _symbol(symbol) {}
-
- const File &file() const override { return _owningFile; }
- StringRef name() const override { return _name; }
-
- // A symbol in ELF can be undefined at build time if the symbol is a undefined
- // weak symbol.
- CanBeNull canBeNull() const override;
-
-private:
- const File &_owningFile;
- StringRef _name;
- const Elf_Sym *_symbol;
-};
-
-/// \brief This atom stores defined symbols and will contain either data or
-/// code.
-template <class ELFT> class ELFDefinedAtom : public DefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
-public:
- ELFDefinedAtom(const ELFFile<ELFT> &file, StringRef symbolName,
- StringRef sectionName, const Elf_Sym *symbol,
- const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList)
- : _owningFile(file), _symbolName(symbolName), _sectionName(sectionName),
- _symbol(symbol), _section(section), _contentData(contentData),
- _referenceStartIndex(referenceStart), _referenceEndIndex(referenceEnd),
- _referenceList(referenceList), _contentType(typeUnknown),
- _permissions(permUnknown) {}
-
- ~ELFDefinedAtom() override = default;
-
- const ELFFile<ELFT> &file() const override { return _owningFile; }
- StringRef name() const override { return _symbolName; }
- uint64_t ordinal() const override { return _ordinal; }
- const Elf_Sym *symbol() const { return _symbol; }
- const Elf_Shdr *section() const { return _section; }
- uint64_t size() const override;
- Scope scope() const override;
-
- // FIXME: Need to revisit this in future.
- Interposable interposable() const override { return interposeNo; }
-
- Merge merge() const override;
- ContentType contentType() const override;
- Alignment alignment() const override;
- SectionChoice sectionChoice() const override;
- StringRef customSectionName() const override;
-
- // It isn't clear that __attribute__((used)) is transmitted to the ELF object
- // file.
- DeadStripKind deadStrip() const override { return deadStripNormal; }
-
- ContentPermissions permissions() const override;
- ArrayRef<uint8_t> rawContent() const override { return _contentData; }
-
- DefinedAtom::reference_iterator begin() const override;
- DefinedAtom::reference_iterator end() const override;
- const Reference *derefIterator(const void *It) const override;
- void incrementIterator(const void *&It) const override;
-
- using DefinedAtom::addReference;
- void addReference(ELFReference<ELFT> *reference);
-
- virtual void setOrdinal(uint64_t ord) { _ordinal = ord; }
-
-protected:
- /// Returns correct st_value for the symbol depending on the architecture.
- /// For most architectures it's just a regular st_value with no changes.
- virtual uint64_t getSymbolValue() const {
- return _symbol->st_value;
- }
-
- ContentType doContentType() const;
-
- const ELFFile<ELFT> &_owningFile;
- StringRef _symbolName;
- StringRef _sectionName;
- const Elf_Sym *_symbol;
- const Elf_Shdr *_section;
- /// \brief Holds the bits that make up the atom.
- ArrayRef<uint8_t> _contentData;
-
- uint64_t _ordinal;
- unsigned int _referenceStartIndex;
- unsigned int _referenceEndIndex;
- std::vector<ELFReference<ELFT> *> &_referenceList;
- mutable ContentType _contentType;
- mutable ContentPermissions _permissions;
-};
-
-/// \brief This atom stores mergeable Strings
-template <class ELFT> class ELFMergeAtom : public DefinedAtom {
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
-public:
- ELFMergeAtom(const ELFFile<ELFT> &file, StringRef sectionName,
- const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
- uint64_t offset)
- : _owningFile(file), _sectionName(sectionName), _section(section),
- _contentData(contentData), _offset(offset) {
- }
-
- const ELFFile<ELFT> &file() const override { return _owningFile; }
- StringRef name() const override { return ""; }
- virtual uint64_t section() const { return _section->sh_name; }
- virtual uint64_t offset() const { return _offset; }
- virtual void setOrdinal(uint64_t ord) { _ordinal = ord; }
- uint64_t ordinal() const override { return _ordinal; }
- uint64_t size() const override { return _contentData.size(); }
- Scope scope() const override { return scopeTranslationUnit; }
- Interposable interposable() const override { return interposeNo; }
- Merge merge() const override { return mergeByContent; }
- ContentType contentType() const override { return typeConstant; }
-
- Alignment alignment() const override {
- return Alignment(_section->sh_addralign);
- }
-
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return _sectionName; }
- DeadStripKind deadStrip() const override { return deadStripNormal; }
- ContentPermissions permissions() const override { return permR__; }
- ArrayRef<uint8_t> rawContent() const override { return _contentData; }
-
- DefinedAtom::reference_iterator begin() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- const Reference *derefIterator(const void *It) const override {
- return nullptr;
- }
-
- void incrementIterator(const void *&It) const override {}
-
-private:
- const ELFFile<ELFT> &_owningFile;
- StringRef _sectionName;
- const Elf_Shdr *_section;
- /// \brief Holds the bits that make up the atom.
- ArrayRef<uint8_t> _contentData;
- uint64_t _ordinal;
- uint64_t _offset;
-};
-
-template <class ELFT> class ELFCommonAtom : public DefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-public:
- ELFCommonAtom(const ELFFile<ELFT> &file, StringRef symbolName,
- const Elf_Sym *symbol)
- : _owningFile(file), _symbolName(symbolName), _symbol(symbol) {}
-
- const ELFFile<ELFT> &file() const override { return _owningFile; }
- StringRef name() const override { return _symbolName; }
- uint64_t ordinal() const override { return _ordinal; }
- virtual void setOrdinal(uint64_t ord) { _ordinal = ord; }
- uint64_t size() const override { return _symbol->st_size; }
-
- Scope scope() const override {
- if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
- return scopeGlobal;
- return scopeTranslationUnit;
- }
-
- Interposable interposable() const override { return interposeNo; }
- Merge merge() const override { return mergeAsTentative; }
- ContentType contentType() const override { return typeZeroFill; }
- Alignment alignment() const override { return Alignment(_symbol->st_value); }
- SectionChoice sectionChoice() const override { return sectionBasedOnContent; }
- StringRef customSectionName() const override { return ".bss"; }
- DeadStripKind deadStrip() const override { return deadStripNormal; }
- ContentPermissions permissions() const override { return permRW_; }
- ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
-
- DefinedAtom::reference_iterator begin() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
-protected:
- const Reference *derefIterator(const void *iter) const override {
- return nullptr;
- }
-
- void incrementIterator(const void *&iter) const override {}
-
- const ELFFile<ELFT> &_owningFile;
- StringRef _symbolName;
- const Elf_Sym *_symbol;
- uint64_t _ordinal;
-};
-
-/// \brief An atom from a shared library.
-template <class ELFT> class ELFDynamicAtom : public SharedLibraryAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFDynamicAtom(const DynamicFile<ELFT> &file, StringRef symbolName,
- StringRef loadName, const Elf_Sym *symbol)
- : _owningFile(file), _symbolName(symbolName), _loadName(loadName),
- _symbol(symbol) {}
-
- const DynamicFile<ELFT> &file() const override { return _owningFile; }
- StringRef name() const override { return _symbolName; }
- virtual Scope scope() const;
- StringRef loadName() const override { return _loadName; }
-
- bool canBeNullAtRuntime() const override {
- return _symbol->getBinding() == llvm::ELF::STB_WEAK;
- }
-
- Type type() const override;
- uint64_t size() const override { return _symbol->st_size; }
-
-private:
-
- const DynamicFile<ELFT> &_owningFile;
- StringRef _symbolName;
- StringRef _loadName;
- const Elf_Sym *_symbol;
-};
-
-class SimpleELFDefinedAtom : public SimpleDefinedAtom {
-public:
- SimpleELFDefinedAtom(const File &f) : SimpleDefinedAtom(f) {}
-
- void addReferenceELF(Reference::KindArch arch, Reference::KindValue kindValue,
- uint64_t off, const Atom *t, Reference::Addend a) {
- addReference(Reference::KindNamespace::ELF, arch, kindValue, off, t, a);
- }
-
- void addReferenceELF_Hexagon(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::Hexagon, relocType, off, t, a);
- }
-
- void addReferenceELF_x86_64(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::x86_64, relocType, off, t, a);
- }
-
- void addReferenceELF_Mips(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::Mips, relocType, off, t, a);
- }
-
- void addReferenceELF_AArch64(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::AArch64, relocType, off, t, a);
- }
-
- void addReferenceELF_ARM(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::ARM, relocType, off, t, a);
- }
-};
-
-/// \brief Atom which represents an object for which a COPY relocation will be
-/// generated.
-class ObjectAtom : public SimpleELFDefinedAtom {
-public:
- ObjectAtom(const File &f) : SimpleELFDefinedAtom(f) {}
- Scope scope() const override { return scopeGlobal; }
- SectionChoice sectionChoice() const override { return sectionBasedOnContent; }
- ContentType contentType() const override { return typeZeroFill; }
- uint64_t size() const override { return _size; }
- DynamicExport dynamicExport() const override { return dynamicExportAlways; }
- ContentPermissions permissions() const override { return permRW_; }
- ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
- Alignment alignment() const override { return 8; }
- StringRef name() const override { return _name; }
-
- std::string _name;
- uint64_t _size;
-};
-
-class GOTAtom : public SimpleELFDefinedAtom {
- StringRef _section;
-
-public:
- GOTAtom(const File &f, StringRef secName)
- : SimpleELFDefinedAtom(f), _section(secName) {}
-
- Scope scope() const override { return scopeTranslationUnit; }
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return _section; }
- ContentType contentType() const override { return typeGOT; }
- uint64_t size() const override { return rawContent().size(); }
- ContentPermissions permissions() const override { return permRW_; }
- Alignment alignment() const override { return 8; }
-
-#ifndef NDEBUG
- StringRef name() const override { return _name; }
- std::string _name;
-#else
- StringRef name() const override { return ""; }
-#endif
-};
-
-class PLTAtom : public SimpleELFDefinedAtom {
- StringRef _section;
-
-public:
- PLTAtom(const File &f, StringRef secName)
- : SimpleELFDefinedAtom(f), _section(secName) {}
-
- Scope scope() const override { return scopeTranslationUnit; }
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return _section; }
- ContentType contentType() const override { return typeStub; }
- uint64_t size() const override { return rawContent().size(); }
- ContentPermissions permissions() const override { return permR_X; }
- Alignment alignment() const override { return 16; }
-
-#ifndef NDEBUG
- StringRef name() const override { return _name; }
- std::string _name;
-#else
- StringRef name() const override { return ""; }
-#endif
-};
-
-class PLT0Atom : public PLTAtom {
-public:
- PLT0Atom(const File &f) : PLTAtom(f, ".plt") {
-#ifndef NDEBUG
- _name = ".PLT0";
-#endif
- }
-};
-
-class GlobalOffsetTableAtom : public SimpleELFDefinedAtom {
-public:
- GlobalOffsetTableAtom(const File &f) : SimpleELFDefinedAtom(f) {}
-
- StringRef name() const override { return "_GLOBAL_OFFSET_TABLE_"; }
- Scope scope() const override { return scopeLinkageUnit; }
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return ".got.plt"; }
- ContentType contentType() const override { return typeGOT; }
- uint64_t size() const override { return 0; }
- ContentPermissions permissions() const override { return permRW_; }
- Alignment alignment() const override { return 8; }
- ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
-};
-
-class DynamicAtom : public SimpleELFDefinedAtom {
-public:
- DynamicAtom(const File &f) : SimpleELFDefinedAtom(f) {}
-
- StringRef name() const override { return "_DYNAMIC"; }
- Scope scope() const override { return scopeLinkageUnit; }
- Merge merge() const override { return mergeNo; }
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return ".dynamic"; }
- ContentType contentType() const override { return typeData; }
- uint64_t size() const override { return 0; }
- ContentPermissions permissions() const override { return permRW_; }
- Alignment alignment() const override { return 1; }
- ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_ATOMS_H
Removed: lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt (removed)
@@ -1,29 +0,0 @@
-add_lld_library(lldELF
- Atoms.cpp
- DynamicFile.cpp
- ELFFile.cpp
- ELFLinkingContext.cpp
- FileCommon.cpp
- HeaderChunks.cpp
- OutputELFWriter.cpp
- Reader.cpp
- SectionChunks.cpp
- SegmentChunks.cpp
- TargetLayout.cpp
- Writer.cpp
- LINK_LIBS
- lldReaderWriter
- lldCore
- lldYAML
- LLVMObject
- LLVMSupport
- )
-
-include_directories(.)
-
-add_subdirectory(X86)
-add_subdirectory(X86_64)
-add_subdirectory(Mips)
-add_subdirectory(Hexagon)
-add_subdirectory(AArch64)
-add_subdirectory(ARM)
Removed: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h (removed)
@@ -1,111 +0,0 @@
-//===- lib/ReaderWriter/ELF/Chunks.h --------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_CHUNKS_H
-#define LLD_READER_WRITER_ELF_CHUNKS_H
-
-#include "lld/Core/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include <memory>
-
-namespace lld {
-class ELFLinkingContext;
-
-namespace elf {
-class ELFWriter;
-template <class ELFT> class TargetLayout;
-
-/// \brief A chunk is a contiguous region of space
-template <class ELFT> class Chunk {
-public:
- /// \brief Describes the type of Chunk
- enum Kind : uint8_t {
- ELFHeader, ///< ELF Header
- ProgramHeader, ///< Program Header
- SectionHeader, ///< Section header
- ELFSegment, ///< Segment
- ELFSection, ///< Section
- AtomSection, ///< A section containing atoms
- Expression ///< A linker script expression
- };
-
- /// \brief the ContentType of the chunk
- enum ContentType : uint8_t { Unknown, Header, Code, Data, Note, TLS };
-
- Chunk(StringRef name, Kind kind, const ELFLinkingContext &ctx)
- : _name(name), _kind(kind), _ctx(ctx) {}
-
- virtual ~Chunk() {}
-
- // The name of the chunk
- StringRef name() const { return _name; }
-
- // Kind of chunk
- Kind kind() const { return _kind; }
- virtual uint64_t fileSize() const { return _fsize; }
- virtual void setFileSize(uint64_t sz) { _fsize = sz; }
- virtual void setAlign(uint64_t align) { _alignment = align; }
- virtual uint64_t alignment() const { return _alignment; }
-
- // The ordinal value of the chunk
- uint64_t ordinal() const { return _ordinal; }
- void setOrdinal(uint64_t newVal) { _ordinal = newVal; }
-
- // The order in which the chunk would appear in the output file
- uint64_t order() const { return _order; }
- void setOrder(uint32_t order) { _order = order; }
-
- // Output file offset of the chunk
- uint64_t fileOffset() const { return _fileoffset; }
- void setFileOffset(uint64_t offset) { _fileoffset = offset; }
-
- // Output start address of the chunk
- virtual void setVirtualAddr(uint64_t start) { _start = start; }
- virtual uint64_t virtualAddr() const { return _start; }
-
- // Memory size of the chunk
- uint64_t memSize() const { return _msize; }
- void setMemSize(uint64_t msize) { _msize = msize; }
-
- // Returns the ContentType of the chunk
- virtual int getContentType() const = 0;
-
- // Writer the chunk
- virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) = 0;
-
- // Finalize the chunk before assigning offsets/virtual addresses
- virtual void doPreFlight() {}
-
- // Finalize the chunk before writing
- virtual void finalize() {}
-
-protected:
- StringRef _name;
- Kind _kind;
- const ELFLinkingContext &_ctx;
- uint64_t _fsize = 0;
- uint64_t _msize = 0;
- uint64_t _alignment = 1;
- uint32_t _order = 0;
- uint64_t _ordinal = 1;
- uint64_t _start = 0;
- uint64_t _fileoffset = 0;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.cpp (removed)
@@ -1,146 +0,0 @@
-//===- lib/ReaderWriter/ELF/DynamicFile.cpp -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DynamicFile.h"
-#include "FileCommon.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/Path.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-DynamicFile<ELFT>::DynamicFile(std::unique_ptr<MemoryBuffer> mb,
- ELFLinkingContext &ctx)
- : SharedLibraryFile(mb->getBufferIdentifier()), _mb(std::move(mb)),
- _ctx(ctx), _useShlibUndefines(ctx.useShlibUndefines()) {}
-
-template <typename ELFT>
-std::error_code DynamicFile<ELFT>::isCompatible(MemoryBufferRef mb,
- ELFLinkingContext &ctx) {
- return elf::isCompatible<ELFT>(mb, ctx);
-}
-
-template <class ELFT>
-const SharedLibraryAtom *DynamicFile<ELFT>::exports(StringRef name,
- bool dataSymbolOnly) const {
- assert(!dataSymbolOnly && "Invalid option for ELF exports!");
- // See if we have the symbol.
- auto sym = _nameToSym.find(name);
- if (sym == _nameToSym.end())
- return nullptr;
- // Have we already created a SharedLibraryAtom for it?
- if (sym->second._atom)
- return sym->second._atom;
- // Create a SharedLibraryAtom for this symbol.
- return sym->second._atom = new (_alloc)
- ELFDynamicAtom<ELFT>(*this, name, _soname, sym->second._symbol);
-}
-
-template <class ELFT> StringRef DynamicFile<ELFT>::getDSOName() const {
- return _soname;
-}
-
-template <class ELFT> bool DynamicFile<ELFT>::canParse(file_magic magic) {
- return magic == file_magic::elf_shared_object;
-}
-
-template <class ELFT> std::error_code DynamicFile<ELFT>::doParse() {
- typedef llvm::object::ELFFile<ELFT> ELFO;
- typedef typename ELFO::Elf_Shdr Elf_Shdr;
- typedef typename ELFO::Elf_Dyn Elf_Dyn;
-
- std::error_code ec;
- _objFile.reset(new ELFO(_mb->getBuffer(), ec));
- if (ec)
- return ec;
-
- ELFO &obj = *_objFile;
-
- const char *base = _mb->getBuffer().data();
- const Elf_Dyn *dynStart = nullptr;
- const Elf_Dyn *dynEnd = nullptr;
-
- const Elf_Shdr *dynSymSec = nullptr;
- for (const Elf_Shdr &sec : obj.sections()) {
- switch (sec.sh_type) {
- case llvm::ELF::SHT_DYNAMIC: {
- dynStart = reinterpret_cast<const Elf_Dyn *>(base + sec.sh_offset);
- uint64_t size = sec.sh_size;
- if (size % sizeof(Elf_Dyn))
- return llvm::object::object_error::parse_failed;
- dynEnd = dynStart + size / sizeof(Elf_Dyn);
- break;
- }
- case llvm::ELF::SHT_DYNSYM:
- dynSymSec = &sec;
- break;
- }
- }
-
- ErrorOr<StringRef> strTableOrErr = obj.getStringTableForSymtab(*dynSymSec);
- if (std::error_code ec = strTableOrErr.getError())
- return ec;
- StringRef stringTable = *strTableOrErr;
-
- for (const Elf_Dyn &dyn : llvm::make_range(dynStart, dynEnd)) {
- if (dyn.d_tag == llvm::ELF::DT_SONAME) {
- uint64_t offset = dyn.getVal();
- if (offset >= stringTable.size())
- return llvm::object::object_error::parse_failed;
- _soname = StringRef(stringTable.data() + offset);
- break;
- }
- }
-
- if (_soname.empty())
- _soname = llvm::sys::path::filename(path());
-
- // Create a map from names to dynamic symbol table entries.
- // TODO: This should use the object file's build in hash table instead if
- // it exists.
- for (auto i = obj.symbol_begin(dynSymSec), e = obj.symbol_end(dynSymSec);
- i != e; ++i) {
- auto name = i->getName(stringTable);
- if ((ec = name.getError()))
- return ec;
-
- // Dont add local symbols to dynamic entries. The first symbol in the
- // dynamic symbol table is a local symbol.
- if (i->getBinding() == llvm::ELF::STB_LOCAL)
- continue;
-
- // TODO: Add absolute symbols
- if (i->st_shndx == llvm::ELF::SHN_ABS)
- continue;
-
- if (i->st_shndx == llvm::ELF::SHN_UNDEF) {
- if (!_useShlibUndefines)
- continue;
- // Create an undefined atom.
- if (!name->empty()) {
- auto *newAtom = new (_alloc) ELFUndefinedAtom<ELFT>(*this, *name, &*i);
- _undefinedAtoms.push_back(newAtom);
- }
- continue;
- }
- _nameToSym[*name]._symbol = &*i;
- }
- return std::error_code();
-}
-
-template class DynamicFile<ELF32LE>;
-template class DynamicFile<ELF32BE>;
-template class DynamicFile<ELF64LE>;
-template class DynamicFile<ELF64BE>;
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (removed)
@@ -1,59 +0,0 @@
-//===- lib/ReaderWriter/ELF/DynamicFile.h ---------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_DYNAMIC_FILE_H
-#define LLD_READER_WRITER_ELF_DYNAMIC_FILE_H
-
-#include "Atoms.h"
-#include "lld/Core/SharedLibraryFile.h"
-#include <unordered_map>
-
-namespace lld {
-class ELFLinkingContext;
-
-namespace elf {
-
-template <class ELFT> class DynamicFile : public SharedLibraryFile {
-public:
- DynamicFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
-
- static std::error_code isCompatible(MemoryBufferRef mb,
- ELFLinkingContext &ctx);
-
- const SharedLibraryAtom *exports(StringRef name,
- bool dataSymbolOnly) const override;
-
- StringRef getDSOName() const override;
-
- static bool canParse(file_magic magic);
-
-protected:
- std::error_code doParse() override;
-
-private:
- mutable llvm::BumpPtrAllocator _alloc;
- std::unique_ptr<llvm::object::ELFFile<ELFT>> _objFile;
- /// \brief DT_SONAME
- StringRef _soname;
-
- struct SymAtomPair {
- const typename llvm::object::ELFFile<ELFT>::Elf_Sym *_symbol = nullptr;
- const SharedLibraryAtom *_atom = nullptr;
- };
-
- std::unique_ptr<MemoryBuffer> _mb;
- ELFLinkingContext &_ctx;
- bool _useShlibUndefines;
- mutable std::unordered_map<StringRef, SymAtomPair> _nameToSym;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (removed)
@@ -1,86 +0,0 @@
-//===- lib/ReaderWriter/ELF/DynamicLibraryWriter.h ------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
-#define LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
-
-#include "OutputELFWriter.h"
-
-namespace lld {
-namespace elf {
-using namespace llvm;
-using namespace llvm::object;
-
-//===----------------------------------------------------------------------===//
-// DynamicLibraryWriter Class
-//===----------------------------------------------------------------------===//
-template<class ELFT>
-class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
-public:
- DynamicLibraryWriter(ELFLinkingContext &ctx, TargetLayout<ELFT> &layout)
- : OutputELFWriter<ELFT>(ctx, layout) {}
-
-protected:
- void buildDynamicSymbolTable(const File &file) override;
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
- void finalizeDefaultAtomValues() override;
-};
-
-//===----------------------------------------------------------------------===//
-// DynamicLibraryWriter
-//===----------------------------------------------------------------------===//
-template <class ELFT>
-void DynamicLibraryWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- // Add all the defined symbols to the dynamic symbol table
- // we need hooks into the Atom to find out which atoms need
- // to be exported
- for (auto sec : this->_layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms()) {
- const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
- if (da && (da->scope() == DefinedAtom::scopeGlobal))
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
-
- for (const UndefinedAtom *a : file.undefined())
- this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
-
- OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
-}
-
-/// \brief Hook in lld to add CRuntime file
-template <class ELFT>
-void DynamicLibraryWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File> > &result) {
- OutputELFWriter<ELFT>::createImplicitFiles(result);
- // Add the default atoms as defined by executables
- auto file = llvm::make_unique<RuntimeFile<ELFT>>(this->_ctx, "C runtime");
- file->addAbsoluteAtom("_end");
- result.push_back(std::move(file));
-}
-
-template <class ELFT>
-void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
- OutputELFWriter<ELFT>::finalizeDefaultAtomValues();
- AtomLayout *underScoreEndAtom = this->_layout.findAbsoluteAtom("_end");
- assert(underScoreEndAtom);
-
- if (auto bssSection = this->_layout.findOutputSection(".bss")) {
- underScoreEndAtom->_virtualAddr =
- bssSection->virtualAddr() + bssSection->memSize();
- } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
- underScoreEndAtom->_virtualAddr =
- dataSection->virtualAddr() + dataSection->memSize();
- }
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ELFFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFFile.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFFile.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFFile.cpp (removed)
@@ -1,830 +0,0 @@
-//===- lib/ReaderWriter/ELF/ELFFile.cpp -------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ELFFile.h"
-#include "FileCommon.h"
-#include "llvm/ADT/STLExtras.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT>
-ELFFile<ELFT>::ELFFile(StringRef name, ELFLinkingContext &ctx)
- : SimpleFile(name, kindELFObject), _ordinal(0),
- _doStringsMerge(ctx.mergeCommonStrings()), _useWrap(false), _ctx(ctx) {
- setLastError(std::error_code());
-}
-
-template <typename ELFT>
-ELFFile<ELFT>::ELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
- : SimpleFile(mb->getBufferIdentifier(), kindELFObject),
- _mb(std::move(mb)), _ordinal(0),
- _doStringsMerge(ctx.mergeCommonStrings()),
- _useWrap(ctx.wrapCalls().size()), _ctx(ctx) {}
-
-template <typename ELFT>
-std::error_code ELFFile<ELFT>::isCompatible(MemoryBufferRef mb,
- ELFLinkingContext &ctx) {
- return elf::isCompatible<ELFT>(mb, ctx);
-}
-
-template <typename ELFT>
-Atom *ELFFile<ELFT>::findAtom(const Elf_Sym *sourceSym,
- const Elf_Sym *targetSym) {
- // Return the atom for targetSym if we can do so.
- Atom *target = _symbolToAtomMapping.lookup(targetSym);
- if (!target)
- // Some realocations (R_ARM_V4BX) do not have a defined
- // target. For this cases make it points to itself.
- target = _symbolToAtomMapping.lookup(sourceSym);
-
- if (target->definition() != Atom::definitionRegular)
- return target;
- Atom::Scope scope = llvm::cast<DefinedAtom>(target)->scope();
- if (scope == DefinedAtom::scopeTranslationUnit)
- return target;
- if (!redirectReferenceUsingUndefAtom(sourceSym, targetSym))
- return target;
-
- // Otherwise, create a new undefined symbol and returns it.
- StringRef targetName = target->name();
- auto it = _undefAtomsForGroupChild.find(targetName);
- if (it != _undefAtomsForGroupChild.end())
- return it->getValue();
- auto atom = new (_readerStorage) SimpleUndefinedAtom(*this, targetName);
- _undefAtomsForGroupChild[targetName] = atom;
- addAtom(*atom);
- return atom;
-}
-
-template <typename ELFT>
-ErrorOr<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *shdr) const {
- if (!shdr)
- return StringRef();
- return _objFile->getSectionName(shdr);
-}
-
-template <class ELFT> std::error_code ELFFile<ELFT>::doParse() {
- std::error_code ec;
- _objFile.reset(new llvm::object::ELFFile<ELFT>(_mb->getBuffer(), ec));
- if (ec)
- return ec;
-
- if ((ec = createAtomsFromContext()))
- return ec;
-
- // Read input sections from the input file that need to be converted to
- // atoms
- if ((ec = createAtomizableSections()))
- return ec;
-
- // For mergeable strings, we would need to split the section into various
- // atoms
- if ((ec = createMergeableAtoms()))
- return ec;
-
- // Create the necessary symbols that are part of the section that we
- // created in createAtomizableSections function
- if ((ec = createSymbolsFromAtomizableSections()))
- return ec;
-
- // Create the appropriate atoms from the file
- if ((ec = createAtoms()))
- return ec;
- return std::error_code();
-}
-
-template <class ELFT> Reference::KindArch ELFFile<ELFT>::kindArch() {
- switch (_objFile->getHeader()->e_machine) {
- case llvm::ELF::EM_X86_64:
- return Reference::KindArch::x86_64;
- case llvm::ELF::EM_386:
- return Reference::KindArch::x86;
- case llvm::ELF::EM_ARM:
- return Reference::KindArch::ARM;
- case llvm::ELF::EM_HEXAGON:
- return Reference::KindArch::Hexagon;
- case llvm::ELF::EM_MIPS:
- return Reference::KindArch::Mips;
- case llvm::ELF::EM_AARCH64:
- return Reference::KindArch::AArch64;
- }
- llvm_unreachable("unsupported e_machine value");
-}
-
-template <class ELFT>
-std::error_code ELFFile<ELFT>::createAtomizableSections() {
- // Handle: SHT_REL and SHT_RELA sections:
- // Increment over the sections, when REL/RELA section types are found add
- // the contents to the RelocationReferences map.
- // Record the number of relocs to guess at preallocating the buffer.
- uint64_t totalRelocs = 0;
- for (const Elf_Shdr §ion : _objFile->sections()) {
- switch (section.sh_type) {
- case llvm::ELF::SHT_SYMTAB:
- _symtab = §ion;
- continue;
- case llvm::ELF::SHT_SYMTAB_SHNDX: {
- ErrorOr<ArrayRef<Elf_Word>> tableOrErr = _objFile->getSHNDXTable(section);
- if (std::error_code ec = tableOrErr.getError())
- return ec;
- _shndxTable = *tableOrErr;
- continue;
- }
- }
-
- if (isIgnoredSection(§ion))
- continue;
-
- if (isMergeableStringSection(§ion)) {
- _mergeStringSections.push_back(§ion);
- continue;
- }
-
- if (section.sh_type == llvm::ELF::SHT_RELA) {
- auto sHdrOrErr = _objFile->getSection(section.sh_info);
- if (std::error_code ec = sHdrOrErr.getError())
- return ec;
- auto sHdr = *sHdrOrErr;
- auto rai = _objFile->rela_begin(§ion);
- auto rae = _objFile->rela_end(§ion);
- _relocationAddendReferences[sHdr] = make_range(rai, rae);
- totalRelocs += std::distance(rai, rae);
- } else if (section.sh_type == llvm::ELF::SHT_REL) {
- auto sHdrOrErr = _objFile->getSection(section.sh_info);
- if (std::error_code ec = sHdrOrErr.getError())
- return ec;
- auto sHdr = *sHdrOrErr;
- auto ri = _objFile->rel_begin(§ion);
- auto re = _objFile->rel_end(§ion);
- _relocationReferences[sHdr] = §ion;
- totalRelocs += std::distance(ri, re);
- } else {
- auto sectionName = _objFile->getSectionName(§ion);
- if (std::error_code ec = sectionName.getError())
- return ec;
- _ctx.notifyInputSectionName(*sectionName);
- _sectionSymbols[§ion];
- }
- }
- _references.reserve(totalRelocs);
- return std::error_code();
-}
-
-template <class ELFT> std::error_code ELFFile<ELFT>::createMergeableAtoms() {
- // Divide the section that contains mergeable strings into tokens
- // TODO
- // a) add resolver support to recognize multibyte chars
- // b) Create a separate section chunk to write mergeable atoms
- std::vector<MergeString *> tokens;
- for (const Elf_Shdr *msi : _mergeStringSections) {
- auto sectionName = getSectionName(msi);
- if (std::error_code ec = sectionName.getError())
- return ec;
-
- auto sectionContents = getSectionContents(msi);
- if (std::error_code ec = sectionContents.getError())
- return ec;
-
- StringRef secCont(reinterpret_cast<const char *>(sectionContents->begin()),
- sectionContents->size());
-
- unsigned int prev = 0;
- for (std::size_t i = 0, e = sectionContents->size(); i != e; ++i) {
- if ((*sectionContents)[i] == '\0') {
- tokens.push_back(new (_readerStorage) MergeString(
- prev, secCont.slice(prev, i + 1), msi, *sectionName));
- prev = i + 1;
- }
- }
- }
-
- // Create Mergeable atoms
- for (const MergeString *tai : tokens) {
- ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
- tai->_string.size());
- ELFMergeAtom<ELFT> *atom = createMergedString(tai->_sectionName, tai->_shdr,
- content, tai->_offset);
- atom->setOrdinal(++_ordinal);
- addAtom(*atom);
- _mergeAtoms.push_back(atom);
- }
- return std::error_code();
-}
-
-template <class ELFT>
-std::error_code ELFFile<ELFT>::createSymbolsFromAtomizableSections() {
- // Increment over all the symbols collecting atoms and symbol names for
- // later use.
- if (!_symtab)
- return std::error_code();
-
- ErrorOr<StringRef> strTableOrErr =
- _objFile->getStringTableForSymtab(*_symtab);
- if (std::error_code ec = strTableOrErr.getError())
- return ec;
- StringRef strTable = *strTableOrErr;
-
- auto SymI = _objFile->symbol_begin(_symtab),
- SymE = _objFile->symbol_end(_symtab);
- // Skip over dummy sym.
- ++SymI;
-
- for (; SymI != SymE; ++SymI) {
- ErrorOr<const Elf_Shdr *> section =
- _objFile->getSection(SymI, _symtab, _shndxTable);
- if (std::error_code ec = section.getError())
- return ec;
-
- auto symbolName = SymI->getName(strTable);
- if (std::error_code ec = symbolName.getError())
- return ec;
-
- if (SymI->isAbsolute()) {
- ELFAbsoluteAtom<ELFT> *absAtom = createAbsoluteAtom(
- *symbolName, &*SymI, (int64_t)getSymbolValue(&*SymI));
- addAtom(*absAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, absAtom));
- } else if (SymI->isUndefined()) {
- if (_useWrap &&
- (_wrapSymbolMap.find(*symbolName) != _wrapSymbolMap.end())) {
- auto wrapAtom = _wrapSymbolMap.find(*symbolName);
- _symbolToAtomMapping.insert(
- std::make_pair(&*SymI, wrapAtom->getValue()));
- continue;
- }
- ELFUndefinedAtom<ELFT> *undefAtom =
- createUndefinedAtom(*symbolName, &*SymI);
- addAtom(*undefAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, undefAtom));
- } else if (isCommonSymbol(&*SymI)) {
- ELFCommonAtom<ELFT> *commonAtom = createCommonAtom(*symbolName, &*SymI);
- commonAtom->setOrdinal(++_ordinal);
- addAtom(*commonAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, commonAtom));
- } else if (SymI->isDefined()) {
- _sectionSymbols[*section].push_back(SymI);
- } else {
- llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
- return llvm::object::object_error::parse_failed;
- }
- }
-
- return std::error_code();
-}
-
-template <class ELFT> std::error_code ELFFile<ELFT>::createAtoms() {
- // Holds all the atoms that are part of the section. They are the targets of
- // the kindGroupChild reference.
- llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> atomsForSection;
-
- // Contains a list of comdat sections for a group.
- for (auto &i : _sectionSymbols) {
- const Elf_Shdr *section = i.first;
- std::vector<const Elf_Sym *> &symbols = i.second;
-
- // Sort symbols by position.
- std::stable_sort(symbols.begin(), symbols.end(),
- [this](const Elf_Sym *a, const Elf_Sym *b) {
- return getSymbolValue(&*a) < getSymbolValue(&*b);
- });
-
- ErrorOr<StringRef> sectionName = this->getSectionName(section);
- if (std::error_code ec = sectionName.getError())
- return ec;
-
- auto sectionContents = getSectionContents(section);
- if (std::error_code ec = sectionContents.getError())
- return ec;
-
- // SHT_GROUP sections are handled in the following loop.
- if (isGroupSection(section))
- continue;
-
- bool addAtoms = (!isGnuLinkOnceSection(*sectionName) &&
- !isSectionMemberOfGroup(section));
-
- if (handleSectionWithNoSymbols(section, symbols)) {
- ELFDefinedAtom<ELFT> *newAtom =
- createSectionAtom(section, *sectionName, *sectionContents);
- newAtom->setOrdinal(++_ordinal);
- if (addAtoms)
- addAtom(*newAtom);
- else
- atomsForSection[*sectionName].push_back(newAtom);
- continue;
- }
-
- ELFDefinedAtom<ELFT> *previousAtom = nullptr;
- ELFReference<ELFT> *anonFollowedBy = nullptr;
-
- if (!_symtab)
- continue;
- ErrorOr<StringRef> strTableOrErr =
- _objFile->getStringTableForSymtab(*_symtab);
- if (std::error_code ec = strTableOrErr.getError())
- return ec;
- StringRef strTable = *strTableOrErr;
- for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
- auto symbol = *si;
- StringRef symbolName = "";
- if (symbol->getType() != llvm::ELF::STT_SECTION) {
- auto symName = symbol->getName(strTable);
- if (std::error_code ec = symName.getError())
- return ec;
- symbolName = *symName;
- }
-
- uint64_t contentSize = symbolContentSize(
- section, &*symbol, (si + 1 == se) ? nullptr : &**(si + 1));
-
- // Check to see if we need to add the FollowOn Reference
- ELFReference<ELFT> *followOn = nullptr;
- if (previousAtom) {
- // Replace the followon atom with the anonymous atom that we created,
- // so that the next symbol that we create is a followon from the
- // anonymous atom.
- if (anonFollowedBy) {
- followOn = anonFollowedBy;
- } else {
- followOn = new (_readerStorage)
- ELFReference<ELFT>(Reference::kindLayoutAfter);
- previousAtom->addReference(followOn);
- }
- }
-
- ArrayRef<uint8_t> symbolData((const uint8_t *)sectionContents->data() +
- getSymbolValue(&*symbol),
- contentSize);
-
- // If the linker finds that a section has global atoms that are in a
- // mergeable section, treat them as defined atoms as they shouldn't be
- // merged away as well as these symbols have to be part of symbol
- // resolution
- if (isMergeableStringSection(section)) {
- if (symbol->getBinding() != llvm::ELF::STB_GLOBAL)
- continue;
- ELFDefinedAtom<ELFT> *atom = createDefinedAtom(
- symbolName, *sectionName, &**si, section, symbolData,
- _references.size(), _references.size(), _references);
- atom->setOrdinal(++_ordinal);
- if (addAtoms)
- addAtom(*atom);
- else
- atomsForSection[*sectionName].push_back(atom);
- continue;
- }
-
- // Don't allocate content to a weak symbol, as they may be merged away.
- // Create an anonymous atom to hold the data.
- ELFDefinedAtom<ELFT> *anonAtom = nullptr;
- anonFollowedBy = nullptr;
- if (symbol->getBinding() == llvm::ELF::STB_WEAK) {
- // Create anonymous new non-weak ELF symbol that holds the symbol
- // data.
- auto sym = new (_readerStorage) Elf_Sym(*symbol);
- sym->setBinding(llvm::ELF::STB_GLOBAL);
- anonAtom = createDefinedAtomAndAssignRelocations(
- "", *sectionName, sym, section, symbolData, *sectionContents);
- symbolData = ArrayRef<uint8_t>();
-
- // If this is the last atom, let's not create a followon reference.
- if (anonAtom && (si + 1) != se) {
- anonFollowedBy = new (_readerStorage)
- ELFReference<ELFT>(Reference::kindLayoutAfter);
- anonAtom->addReference(anonFollowedBy);
- }
- }
-
- ELFDefinedAtom<ELFT> *newAtom = createDefinedAtomAndAssignRelocations(
- symbolName, *sectionName, &*symbol, section, symbolData,
- *sectionContents);
- newAtom->setOrdinal(++_ordinal);
-
- // If the atom was a weak symbol, let's create a followon reference to
- // the anonymous atom that we created.
- if (anonAtom)
- createEdge(newAtom, anonAtom, Reference::kindLayoutAfter);
-
- if (previousAtom) {
- // Set the followon atom to the weak atom that we have created, so
- // that they would alias when the file gets written.
- followOn->setTarget(anonAtom ? anonAtom : newAtom);
- }
-
- // The previous atom is always the atom created before unless the atom
- // is a weak atom.
- previousAtom = anonAtom ? anonAtom : newAtom;
-
- if (addAtoms)
- addAtom(*newAtom);
- else
- atomsForSection[*sectionName].push_back(newAtom);
-
- _symbolToAtomMapping.insert(std::make_pair(&*symbol, newAtom));
- if (anonAtom) {
- anonAtom->setOrdinal(++_ordinal);
- if (addAtoms)
- addAtom(*anonAtom);
- else
- atomsForSection[*sectionName].push_back(anonAtom);
- }
- }
- }
-
- for (auto &i : _sectionSymbols)
- if (std::error_code ec = handleSectionGroup(i.first, atomsForSection))
- return ec;
- for (auto &i : _sectionSymbols)
- if (std::error_code ec = handleGnuLinkOnceSection(i.first, atomsForSection))
- return ec;
-
- updateReferences();
- return std::error_code();
-}
-
-template <class ELFT>
-std::error_code ELFFile<ELFT>::handleGnuLinkOnceSection(
- const Elf_Shdr *section,
- llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection) {
- ErrorOr<StringRef> sectionName = this->getSectionName(section);
- if (std::error_code ec = sectionName.getError())
- return ec;
- if (!isGnuLinkOnceSection(*sectionName))
- return std::error_code();
-
- unsigned int referenceStart = _references.size();
- std::vector<ELFReference<ELFT> *> refs;
- for (auto ha : atomsForSection[*sectionName]) {
- _groupChild[ha->symbol()] = std::make_pair(*sectionName, section);
- auto *ref =
- new (_readerStorage) ELFReference<ELFT>(Reference::kindGroupChild);
- ref->setTarget(ha);
- refs.push_back(ref);
- }
- atomsForSection[*sectionName].clear();
- // Create a gnu linkonce atom.
- ELFDefinedAtom<ELFT> *atom = createDefinedAtom(
- *sectionName, *sectionName, nullptr, section, ArrayRef<uint8_t>(),
- referenceStart, _references.size(), _references);
- atom->setOrdinal(++_ordinal);
- addAtom(*atom);
- for (auto reference : refs)
- atom->addReference(reference);
- return std::error_code();
-}
-
-template <class ELFT>
-std::error_code ELFFile<ELFT>::handleSectionGroup(
- const Elf_Shdr *section,
- llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection) {
- ErrorOr<StringRef> sectionName = this->getSectionName(section);
- if (std::error_code ec = sectionName.getError())
- return ec;
- if (!isGroupSection(section))
- return std::error_code();
-
- auto sectionContents = getSectionContents(section);
- if (std::error_code ec = sectionContents.getError())
- return ec;
-
- // A section of type SHT_GROUP defines a grouping of sections. The
- // name of a symbol from one of the containing object's symbol tables
- // provides a signature for the section group. The section header of
- // the SHT_GROUP section specifies the identifying symbol entry, as
- // described: the sh_link member contains the section header index of
- // the symbol table section that contains the entry. The sh_info
- // member contains the symbol table index of the identifying entry.
- // The sh_flags member of the section header contains 0. The name of
- // the section (sh_name) is not specified.
- std::vector<StringRef> sectionNames;
- const Elf_Word *groupMembers =
- reinterpret_cast<const Elf_Word *>(sectionContents->data());
- const size_t count = section->sh_size / sizeof(Elf_Word);
- for (size_t i = 1; i < count; i++) {
- ErrorOr<const Elf_Shdr *> shdr = _objFile->getSection(groupMembers[i]);
- if (std::error_code ec = shdr.getError())
- return ec;
- ErrorOr<StringRef> sectionName = _objFile->getSectionName(*shdr);
- if (std::error_code ec = sectionName.getError())
- return ec;
- sectionNames.push_back(*sectionName);
- }
- ErrorOr<const Elf_Shdr *> symtab = _objFile->getSection(section->sh_link);
- if (std::error_code ec = symtab.getError())
- return ec;
- const Elf_Sym *symbol = _objFile->getSymbol(*symtab, section->sh_info);
- ErrorOr<const Elf_Shdr *> strtab_sec =
- _objFile->getSection((*symtab)->sh_link);
- if (std::error_code ec = strtab_sec.getError())
- return ec;
- ErrorOr<StringRef> strtab_or_err = _objFile->getStringTable(*strtab_sec);
- if (std::error_code ec = strtab_or_err.getError())
- return ec;
- StringRef strtab = *strtab_or_err;
- ErrorOr<StringRef> symbolName = symbol->getName(strtab);
- if (std::error_code ec = symbolName.getError())
- return ec;
-
- unsigned int referenceStart = _references.size();
- std::vector<ELFReference<ELFT> *> refs;
- for (auto name : sectionNames) {
- for (auto ha : atomsForSection[name]) {
- _groupChild[ha->symbol()] = std::make_pair(*symbolName, section);
- auto *ref =
- new (_readerStorage) ELFReference<ELFT>(Reference::kindGroupChild);
- ref->setTarget(ha);
- refs.push_back(ref);
- }
- atomsForSection[name].clear();
- }
-
- // Create an atom for comdat signature.
- ELFDefinedAtom<ELFT> *atom = createDefinedAtom(
- *symbolName, *sectionName, nullptr, section, ArrayRef<uint8_t>(),
- referenceStart, _references.size(), _references);
- atom->setOrdinal(++_ordinal);
- addAtom(*atom);
- for (auto reference : refs)
- atom->addReference(reference);
- return std::error_code();
-}
-
-template <class ELFT> std::error_code ELFFile<ELFT>::createAtomsFromContext() {
- if (!_useWrap)
- return std::error_code();
- // Steps:
- // a) Create an undefined atom for the symbol specified by the --wrap option,
- // as that may be needed to be pulled from an archive.
- // b) Create an undefined atom for __wrap_<symbolname>.
- // c) All references to the symbol specified by wrap should point to
- // __wrap_<symbolname>
- // d) All references to __real_symbol should point to the <symbol>
- for (auto &wrapsym : _ctx.wrapCalls()) {
- StringRef wrapStr = wrapsym.getKey();
- // Create a undefined symbol fror the wrap symbol.
- UndefinedAtom *wrapSymAtom =
- new (_readerStorage) SimpleUndefinedAtom(*this, wrapStr);
- StringRef wrapCallSym =
- _ctx.allocateString((llvm::Twine("__wrap_") + wrapStr).str());
- StringRef realCallSym =
- _ctx.allocateString((llvm::Twine("__real_") + wrapStr).str());
- UndefinedAtom *wrapCallAtom =
- new (_readerStorage) SimpleUndefinedAtom(*this, wrapCallSym);
- // Create maps, when there is call to sym, it should point to wrapCallSym.
- _wrapSymbolMap.insert(std::make_pair(wrapStr, wrapCallAtom));
- // Whenever there is a reference to realCall it should point to the symbol
- // created for each wrap usage.
- _wrapSymbolMap.insert(std::make_pair(realCallSym, wrapSymAtom));
- addAtom(*wrapSymAtom);
- addAtom(*wrapCallAtom);
- }
- return std::error_code();
-}
-
-template <class ELFT>
-ELFDefinedAtom<ELFT> *ELFFile<ELFT>::createDefinedAtomAndAssignRelocations(
- StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
- const Elf_Shdr *section, ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent) {
- unsigned int referenceStart = _references.size();
-
- // Add Rela (those with r_addend) references:
- auto rari = _relocationAddendReferences.find(section);
- if (rari != _relocationAddendReferences.end())
- createRelocationReferences(symbol, symContent, rari->second);
-
- // Add Rel references.
- auto rri = _relocationReferences.find(section);
- if (rri != _relocationReferences.end())
- createRelocationReferences(symbol, symContent, secContent, rri->second);
-
- // Create the DefinedAtom and add it to the list of DefinedAtoms.
- return createDefinedAtom(symbolName, sectionName, symbol, section, symContent,
- referenceStart, _references.size(), _references);
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> content,
- range<const Elf_Rela *> rels) {
- bool isMips64EL = _objFile->isMips64EL();
- const auto symValue = getSymbolValue(symbol);
- for (const auto &rel : rels) {
- if (rel.r_offset < symValue || symValue + content.size() <= rel.r_offset)
- continue;
- auto elfRelocation = new (_readerStorage)
- ELFReference<ELFT>(&rel, rel.r_offset - symValue, kindArch(),
- rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
- addReferenceToSymbol(elfRelocation, symbol);
- _references.push_back(elfRelocation);
- }
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent,
- const Elf_Shdr *relSec) {
- auto rels = _objFile->rels(relSec);
- bool isMips64EL = _objFile->isMips64EL();
- const auto symValue = getSymbolValue(symbol);
- for (const auto &rel : rels) {
- if (rel.r_offset < symValue || symValue + symContent.size() <= rel.r_offset)
- continue;
- auto elfRelocation = new (_readerStorage)
- ELFReference<ELFT>(rel.r_offset - symValue, kindArch(),
- rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
- Reference::Addend addend = getInitialAddend(symContent, symValue, rel);
- elfRelocation->setAddend(addend);
- addReferenceToSymbol(elfRelocation, symbol);
- _references.push_back(elfRelocation);
- }
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::updateReferenceForMergeStringAccess(ELFReference<ELFT> *ref,
- const Elf_Sym *symbol,
- const Elf_Shdr *shdr) {
- // If the target atom is mergeable strefng atom, the atom might have been
- // merged with other atom having the same contents. Try to find the
- // merged one if that's the case.
- int64_t addend = ref->addend();
- if (addend < 0)
- addend = 0;
-
- const MergeSectionKey ms = {shdr, addend};
- auto msec = _mergedSectionMap.find(ms);
- if (msec != _mergedSectionMap.end()) {
- ref->setTarget(msec->second);
- return;
- }
-
- // The target atom was not merged. Mergeable atoms are not in
- // _symbolToAtomMapping, so we cannot find it by calling findAtom(). We
- // instead call findMergeAtom().
- if (symbol->getType() != llvm::ELF::STT_SECTION)
- addend = getSymbolValue(symbol) + addend;
- ELFMergeAtom<ELFT> *mergedAtom = findMergeAtom(shdr, addend);
- ref->setOffset(addend - mergedAtom->offset());
- ref->setAddend(0);
- ref->setTarget(mergedAtom);
-}
-
-template <class ELFT> void ELFFile<ELFT>::updateReferences() {
- for (auto &ri : _references) {
- if (ri->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- const Elf_Sym *symbol =
- _objFile->getSymbol(_symtab, ri->targetSymbolIndex());
- ErrorOr<const Elf_Shdr *> shdr =
- _objFile->getSection(symbol, _symtab, _shndxTable);
-
- // If the atom is not in mergeable string section, the target atom is
- // simply that atom.
- if (isMergeableStringSection(*shdr))
- updateReferenceForMergeStringAccess(ri, symbol, *shdr);
- else
- ri->setTarget(findAtom(findSymbolForReference(ri), symbol));
- }
-}
-
-template <class ELFT>
-bool ELFFile<ELFT>::isIgnoredSection(const Elf_Shdr *section) {
- switch (section->sh_type) {
- case llvm::ELF::SHT_NULL:
- case llvm::ELF::SHT_STRTAB:
- case llvm::ELF::SHT_SYMTAB:
- case llvm::ELF::SHT_SYMTAB_SHNDX:
- return true;
- default:
- break;
- }
- return false;
-}
-
-template <class ELFT>
-bool ELFFile<ELFT>::isMergeableStringSection(const Elf_Shdr *section) {
- if (_doStringsMerge && section) {
- int64_t sectionFlags = section->sh_flags;
- sectionFlags &= ~llvm::ELF::SHF_ALLOC;
- // Mergeable string sections have both SHF_MERGE and SHF_STRINGS flags
- // set. sh_entsize is the size of each character which is normally 1.
- if ((section->sh_entsize < 2) &&
- (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
- return true;
- }
- }
- return false;
-}
-
-template <class ELFT>
-ELFDefinedAtom<ELFT> *
-ELFFile<ELFT>::createSectionAtom(const Elf_Shdr *section, StringRef sectionName,
- ArrayRef<uint8_t> content) {
- auto *sym = new (_readerStorage) Elf_Sym;
- sym->st_name = 0;
- sym->setBindingAndType(llvm::ELF::STB_LOCAL, llvm::ELF::STT_SECTION);
- sym->st_other = 0;
- sym->st_shndx = 0;
- sym->st_value = 0;
- sym->st_size = 0;
- auto *newAtom = createDefinedAtomAndAssignRelocations(
- "", sectionName, sym, section, content, content);
- newAtom->setOrdinal(++_ordinal);
- return newAtom;
-}
-
-template <class ELFT>
-uint64_t ELFFile<ELFT>::symbolContentSize(const Elf_Shdr *section,
- const Elf_Sym *symbol,
- const Elf_Sym *nextSymbol) {
- const auto symValue = getSymbolValue(symbol);
- // if this is the last symbol, take up the remaining data.
- return nextSymbol ? getSymbolValue(nextSymbol) - symValue
- : section->sh_size - symValue;
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::createEdge(ELFDefinedAtom<ELFT> *from,
- ELFDefinedAtom<ELFT> *to, uint32_t edgeKind) {
- auto reference = new (_readerStorage) ELFReference<ELFT>(edgeKind);
- reference->setTarget(to);
- from->addReference(reference);
-}
-
-/// Does the atom need to be redirected using a separate undefined atom?
-template <class ELFT>
-bool ELFFile<ELFT>::redirectReferenceUsingUndefAtom(
- const Elf_Sym *sourceSymbol, const Elf_Sym *targetSymbol) const {
- auto groupChildTarget = _groupChild.find(targetSymbol);
-
- // If the reference is not to a group child atom, there is no need to redirect
- // using a undefined atom. Its also not needed if the source and target are
- // from the same section.
- if ((groupChildTarget == _groupChild.end()) ||
- (sourceSymbol->st_shndx == targetSymbol->st_shndx))
- return false;
-
- auto groupChildSource = _groupChild.find(sourceSymbol);
-
- // If the source symbol is not in a group, use a undefined symbol too.
- if (groupChildSource == _groupChild.end())
- return true;
-
- // If the source and child are from the same group, we dont need the
- // relocation to go through a undefined symbol.
- if (groupChildSource->second.second == groupChildTarget->second.second)
- return false;
- return true;
-}
-
-template <class ELFT>
-void RuntimeFile<ELFT>::addAbsoluteAtom(StringRef symbolName, bool isHidden) {
- assert(!symbolName.empty() && "AbsoluteAtoms must have a name");
- auto *sym = new (this->_readerStorage) Elf_Sym;
- sym->st_name = 0;
- sym->st_value = 0;
- sym->st_shndx = llvm::ELF::SHN_ABS;
- sym->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT);
- if (isHidden)
- sym->setVisibility(llvm::ELF::STV_HIDDEN);
- else
- sym->setVisibility(llvm::ELF::STV_DEFAULT);
- sym->st_size = 0;
- ELFAbsoluteAtom<ELFT> *atom = this->createAbsoluteAtom(symbolName, sym, -1);
- this->addAtom(*atom);
-}
-
-template <class ELFT>
-void RuntimeFile<ELFT>::addUndefinedAtom(StringRef symbolName) {
- assert(!symbolName.empty() && "UndefinedAtoms must have a name");
- auto *sym = new (this->_readerStorage) Elf_Sym;
- sym->st_name = 0;
- sym->st_value = 0;
- sym->st_shndx = llvm::ELF::SHN_UNDEF;
- sym->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_NOTYPE);
- sym->setVisibility(llvm::ELF::STV_DEFAULT);
- sym->st_size = 0;
- ELFUndefinedAtom<ELFT> *atom = this->createUndefinedAtom(symbolName, sym);
- this->addAtom(*atom);
-}
-
-template class ELFFile<ELF32LE>;
-template class ELFFile<ELF32BE>;
-template class ELFFile<ELF64LE>;
-template class ELFFile<ELF64BE>;
-
-template class RuntimeFile<ELF32LE>;
-template class RuntimeFile<ELF32BE>;
-template class RuntimeFile<ELF64LE>;
-template class RuntimeFile<ELF64BE>;
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFFile.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFFile.h (removed)
@@ -1,395 +0,0 @@
-//===- lib/ReaderWriter/ELF/ELFFile.h ---------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_FILE_H
-#define LLD_READER_WRITER_ELF_FILE_H
-
-#include "Atoms.h"
-#include "FileCommon.h"
-#include "llvm/ADT/MapVector.h"
-#include <map>
-#include <unordered_map>
-
-namespace lld {
-
-namespace elf {
-/// \brief Read a binary, find out based on the symbol table contents what kind
-/// of symbol it is and create corresponding atoms for it
-template <class ELFT> class ELFFile : public SimpleFile {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
-
- // A Map is used to hold the atoms that have been divided up
- // after reading the section that contains Merge String attributes
- struct MergeSectionKey {
- const Elf_Shdr *_shdr;
- int64_t _offset;
- };
-
- struct MergeSectionEq {
- int64_t operator()(const MergeSectionKey &k) const {
- return llvm::hash_combine((int64_t)(k._shdr->sh_name),
- (int64_t)k._offset);
- }
- bool operator()(const MergeSectionKey &lhs,
- const MergeSectionKey &rhs) const {
- return ((lhs._shdr->sh_name == rhs._shdr->sh_name) &&
- (lhs._offset == rhs._offset));
- }
- };
-
- struct MergeString {
- MergeString(int64_t offset, StringRef str, const Elf_Shdr *shdr,
- StringRef sectionName)
- : _offset(offset), _string(str), _shdr(shdr),
- _sectionName(sectionName) {}
- // the offset of this atom
- int64_t _offset;
- // The content
- StringRef _string;
- // Section header
- const Elf_Shdr *_shdr;
- // Section name
- StringRef _sectionName;
- };
-
- // This is used to find the MergeAtom given a relocation
- // offset
- typedef std::vector<ELFMergeAtom<ELFT> *> MergeAtomsT;
-
- /// \brief find a merge atom given a offset
- ELFMergeAtom<ELFT> *findMergeAtom(const Elf_Shdr *shdr, int64_t offset) {
- auto it = std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
- [=](const ELFMergeAtom<ELFT> *a) {
- int64_t off = a->offset();
- return shdr->sh_name == a->section() &&
- offset >= off &&
- offset <= off + (int64_t)a->size();
- });
- assert(it != _mergeAtoms.end());
- return *it;
- }
-
- typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
- MergeSectionEq> MergedSectionMapT;
- typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
-
-public:
- ELFFile(StringRef name, ELFLinkingContext &ctx);
- ELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
-
- static std::error_code isCompatible(MemoryBufferRef mb,
- ELFLinkingContext &ctx);
-
- static bool canParse(file_magic magic) {
- return magic == file_magic::elf_relocatable;
- }
-
- virtual Reference::KindArch kindArch();
-
- /// \brief Create symbols from LinkingContext.
- std::error_code createAtomsFromContext();
-
- /// \brief Read input sections and populate necessary data structures
- /// to read them later and create atoms
- std::error_code createAtomizableSections();
-
- /// \brief Create mergeable atoms from sections that have the merge attribute
- /// set
- std::error_code createMergeableAtoms();
-
- /// \brief Add the symbols that the sections contain. The symbols will be
- /// converted to atoms for
- /// Undefined symbols, absolute symbols
- std::error_code createSymbolsFromAtomizableSections();
-
- /// \brief Create individual atoms
- std::error_code createAtoms();
-
- // Assuming sourceSymbol has a reference to targetSym, find an atom
- // for targetSym. Usually it's just the atom for targetSym.
- // However, if an atom is in a section group, we may want to return an
- // undefined atom for targetSym to let the resolver to resolve the
- // symbol. (It's because if targetSym is in a section group A, and the
- // group A is not linked in because other file already provides a
- // section group B, we want to resolve references to B, not to A.)
- Atom *findAtom(const Elf_Sym *sourceSym, const Elf_Sym *targetSym);
-
-protected:
- ELFDefinedAtom<ELFT> *createDefinedAtomAndAssignRelocations(
- StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
- const Elf_Shdr *section, ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent);
-
- std::error_code doParse() override;
-
- /// \brief Iterate over Elf_Rela relocations list and create references.
- virtual void createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> content,
- range<const Elf_Rela *> rels);
-
- /// \brief Iterate over Elf_Rel relocations list and create references.
- virtual void createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent,
- const Elf_Shdr *relSec);
-
- /// \brief After all the Atoms and References are created, update each
- /// Reference's target with the Atom pointer it refers to.
- void updateReferences();
-
- /// \brief Update the reference if the access corresponds to a merge string
- /// section.
- void updateReferenceForMergeStringAccess(ELFReference<ELFT> *ref,
- const Elf_Sym *symbol,
- const Elf_Shdr *shdr);
-
- /// \brief Do we want to ignore the section. Ignored sections are
- /// not processed to create atoms
- bool isIgnoredSection(const Elf_Shdr *section);
-
- /// \brief Is the current section be treated as a mergeable string section.
- /// The contents of a mergeable string section are null-terminated strings.
- /// If the section have mergeable strings, the linker would need to split
- /// the section into multiple atoms and mark them mergeByContent.
- bool isMergeableStringSection(const Elf_Shdr *section);
-
- /// \brief Returns a new anonymous atom whose size is equal to the
- /// section size. That atom will be used to represent the entire
- /// section that have no symbols.
- ELFDefinedAtom<ELFT> *createSectionAtom(const Elf_Shdr *section,
- StringRef sectionName,
- ArrayRef<uint8_t> contents);
-
- /// Returns the symbol's content size. The nextSymbol should be null if the
- /// symbol is the last one in the section.
- uint64_t symbolContentSize(const Elf_Shdr *section,
- const Elf_Sym *symbol,
- const Elf_Sym *nextSymbol);
-
- void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
- uint32_t edgeKind);
-
- /// Get the section name for a section.
- ErrorOr<StringRef> getSectionName(const Elf_Shdr *shdr) const;
-
- /// Determines if the section occupy memory space.
- bool sectionOccupiesMemorySpace(const Elf_Shdr *shdr) const {
- return (shdr->sh_type != llvm::ELF::SHT_NOBITS);
- }
-
- /// Return the section contents.
- ErrorOr<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *shdr) const {
- if (!shdr || !sectionOccupiesMemorySpace(shdr))
- return ArrayRef<uint8_t>();
- return _objFile->getSectionContents(shdr);
- }
-
- /// Determines if the target wants to create an atom for a section that has no
- /// symbol references.
- bool
- handleSectionWithNoSymbols(const Elf_Shdr *shdr,
- std::vector<const Elf_Sym *> &syms) const {
- return shdr &&
- (shdr->sh_type == llvm::ELF::SHT_PROGBITS ||
- shdr->sh_type == llvm::ELF::SHT_INIT_ARRAY ||
- shdr->sh_type == llvm::ELF::SHT_FINI_ARRAY ||
- shdr->sh_type == llvm::ELF::SHT_NOTE) &&
- syms.empty();
- }
-
- /// Handle creation of atoms for .gnu.linkonce sections.
- std::error_code handleGnuLinkOnceSection(
- const Elf_Shdr *section,
- llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection);
-
- // Handle COMDAT scetions.
- std::error_code handleSectionGroup(
- const Elf_Shdr *section,
- llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection);
-
- /// Process the Undefined symbol and create an atom for it.
- ELFUndefinedAtom<ELFT> *createUndefinedAtom(StringRef symName,
- const Elf_Sym *sym) {
- return new (_readerStorage) ELFUndefinedAtom<ELFT>(*this, symName, sym);
- }
-
- /// Process the Absolute symbol and create an atom for it.
- ELFAbsoluteAtom<ELFT> *createAbsoluteAtom(StringRef symName,
- const Elf_Sym *sym, int64_t value) {
- return new (_readerStorage)
- ELFAbsoluteAtom<ELFT>(*this, symName, sym, value);
- }
-
- /// Returns true if the symbol is common symbol. A common symbol represents a
- /// tentive definition in C. It has name, size and alignment constraint, but
- /// actual storage has not yet been allocated. (The linker will allocate
- /// storage for them in the later pass after coalescing tentative symbols by
- /// name.)
- virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
- return symbol->getType() == llvm::ELF::STT_COMMON ||
- symbol->st_shndx == llvm::ELF::SHN_COMMON;
- }
-
- /// Returns true if the section is a gnulinkonce section.
- bool isGnuLinkOnceSection(StringRef sectionName) const {
- return sectionName.startswith(".gnu.linkonce.");
- }
-
- /// Returns true if the section is a COMDAT group section.
- bool isGroupSection(const Elf_Shdr *shdr) const {
- return (shdr->sh_type == llvm::ELF::SHT_GROUP);
- }
-
- /// Returns true if the section is a member of some group.
- bool isSectionMemberOfGroup(const Elf_Shdr *shdr) const {
- return (shdr->sh_flags & llvm::ELF::SHF_GROUP);
- }
-
- /// Returns correct st_value for the symbol depending on the architecture.
- /// For most architectures it's just a regular st_value with no changes.
- virtual uint64_t getSymbolValue(const Elf_Sym *symbol) const {
- return symbol->st_value;
- }
-
- /// Returns initial addend
- virtual Reference::Addend getInitialAddend(ArrayRef<uint8_t> symContent,
- uint64_t symbolValue,
- const Elf_Rel& reference) const {
- return *(symContent.data() + reference.r_offset - symbolValue);
- }
-
- /// Process the common symbol and create an atom for it.
- virtual ELFCommonAtom<ELFT> *createCommonAtom(StringRef symName,
- const Elf_Sym *sym) {
- return new (_readerStorage) ELFCommonAtom<ELFT>(*this, symName, sym);
- }
-
- /// Creates an atom for a given defined symbol.
- virtual ELFDefinedAtom<ELFT> *
- createDefinedAtom(StringRef symName, StringRef sectionName,
- const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
- ArrayRef<uint8_t> contentData, unsigned int referenceStart,
- unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList) {
- return new (_readerStorage) ELFDefinedAtom<ELFT>(
- *this, symName, sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- }
-
- /// Process the Merge string and create an atom for it.
- ELFMergeAtom<ELFT> *createMergedString(StringRef sectionName,
- const Elf_Shdr *sectionHdr,
- ArrayRef<uint8_t> contentData,
- unsigned int offset) {
- auto *mergeAtom = new (_readerStorage)
- ELFMergeAtom<ELFT>(*this, sectionName, sectionHdr, contentData, offset);
- const MergeSectionKey mergedSectionKey = {sectionHdr, offset};
- if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
- _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
- return mergeAtom;
- }
-
- /// References to the sections comprising a group, from sections
- /// outside the group, must be made via global UNDEF symbols,
- /// referencing global symbols defined as addresses in the group
- /// sections. They may not reference local symbols for addresses in
- /// the group's sections, including section symbols.
- /// ABI Doc : https://mentorembedded.github.io/cxx-abi/abi/prop-72-comdat.html
- /// Does the atom need to be redirected using a separate undefined atom?
- bool redirectReferenceUsingUndefAtom(const Elf_Sym *sourceSymbol,
- const Elf_Sym *targetSymbol) const;
-
- void addReferenceToSymbol(const ELFReference<ELFT> *r, const Elf_Sym *sym) {
- _referenceToSymbol[r] = sym;
- }
-
- const Elf_Sym *findSymbolForReference(const ELFReference<ELFT> *r) const {
- auto elfReferenceToSymbol = _referenceToSymbol.find(r);
- if (elfReferenceToSymbol != _referenceToSymbol.end())
- return elfReferenceToSymbol->second;
- return nullptr;
- }
-
- llvm::BumpPtrAllocator _readerStorage;
- std::unique_ptr<llvm::object::ELFFile<ELFT> > _objFile;
- const Elf_Shdr *_symtab = nullptr;
- ArrayRef<Elf_Word> _shndxTable;
-
- /// \brief _relocationAddendReferences and _relocationReferences contain the
- /// list of relocations references. In ELF, if a section named, ".text" has
- /// relocations will also have a section named ".rel.text" or ".rela.text"
- /// which will hold the entries.
- std::unordered_map<const Elf_Shdr *, range<const Elf_Rela *>>
- _relocationAddendReferences;
- MergedSectionMapT _mergedSectionMap;
- std::unordered_map<const Elf_Shdr *, const Elf_Shdr *> _relocationReferences;
- std::vector<ELFReference<ELFT> *> _references;
- llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
- llvm::DenseMap<const ELFReference<ELFT> *, const Elf_Sym *>
- _referenceToSymbol;
- // Group child atoms have a pair corresponding to the signature and the
- // section header of the section that was used for generating the signature.
- llvm::DenseMap<const Elf_Sym *, std::pair<StringRef, const Elf_Shdr *>>
- _groupChild;
- llvm::StringMap<Atom *> _undefAtomsForGroupChild;
-
- /// \brief Atoms that are created for a section that has the merge property
- /// set
- MergeAtomsT _mergeAtoms;
-
- /// \brief the section and the symbols that are contained within it to create
- /// used to create atoms
- llvm::MapVector<const Elf_Shdr *, std::vector<const Elf_Sym *>>
- _sectionSymbols;
-
- /// \brief Sections that have merge string property
- std::vector<const Elf_Shdr *> _mergeStringSections;
-
- std::unique_ptr<MemoryBuffer> _mb;
- int64_t _ordinal;
-
- /// \brief the cached options relevant while reading the ELF File
- bool _doStringsMerge;
-
- /// \brief Is --wrap on?
- bool _useWrap;
-
- /// \brief The LinkingContext.
- ELFLinkingContext &_ctx;
-
- // Wrap map
- llvm::StringMap<UndefinedAtom *> _wrapSymbolMap;
-};
-
-/// \brief All atoms are owned by a File. To add linker specific atoms
-/// the atoms need to be inserted to a file called (RuntimeFile) which
-/// are basically additional symbols required by libc and other runtime
-/// libraries part of executing a program. This class provides support
-/// for adding absolute symbols and undefined symbols
-template <class ELFT> class RuntimeFile : public ELFFile<ELFT> {
-public:
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- RuntimeFile(ELFLinkingContext &ctx, StringRef name)
- : ELFFile<ELFT>(name, ctx) {}
-
- /// \brief add a global absolute atom
- virtual void addAbsoluteAtom(StringRef symbolName, bool isHidden = false);
-
- /// \brief add an undefined atom
- virtual void addUndefinedAtom(StringRef symbolName);
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_FILE_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (removed)
@@ -1,263 +0,0 @@
-//===- lib/ReaderWriter/ELF/ELFLinkingContext.cpp -------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "ELFFile.h"
-#include "OrderPass.h"
-#include "TargetHandler.h"
-#include "lld/Core/Instrumentation.h"
-#include "lld/Core/SharedLibraryFile.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Config/config.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-
-#if defined(HAVE_CXXABI_H)
-#include <cxxabi.h>
-#endif
-
-using llvm::sys::fs::exists;
-using llvm::sys::path::is_absolute;
-
-namespace lld {
-
-class CommandLineUndefinedAtom : public SimpleUndefinedAtom {
-public:
- CommandLineUndefinedAtom(const File &f, StringRef name)
- : SimpleUndefinedAtom(f, name) {}
-
- CanBeNull canBeNull() const override {
- return CanBeNull::canBeNullAtBuildtime;
- }
-};
-
-void ELFLinkingContext::addPasses(PassManager &pm) {
- pm.add(llvm::make_unique<elf::OrderPass>());
-}
-
-uint16_t ELFLinkingContext::getOutputMachine() const {
- switch (getTriple().getArch()) {
- case llvm::Triple::x86:
- return llvm::ELF::EM_386;
- case llvm::Triple::x86_64:
- return llvm::ELF::EM_X86_64;
- case llvm::Triple::hexagon:
- return llvm::ELF::EM_HEXAGON;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return llvm::ELF::EM_MIPS;
- case llvm::Triple::aarch64:
- return llvm::ELF::EM_AARCH64;
- case llvm::Triple::arm:
- return llvm::ELF::EM_ARM;
- default:
- llvm_unreachable("Unhandled arch");
- }
-}
-
-StringRef ELFLinkingContext::entrySymbolName() const {
- if (_outputELFType == llvm::ELF::ET_EXEC && _entrySymbolName.empty())
- return "_start";
- return _entrySymbolName;
-}
-
-bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
- switch (outputFileType()) {
- case LinkingContext::OutputFileType::YAML:
- _writer = createWriterYAML(*this);
- break;
- default:
- _writer = createWriterELF(*this);
- break;
- }
-
- // If -dead_strip, set up initial live symbols.
- if (deadStrip())
- addDeadStripRoot(entrySymbolName());
- return true;
-}
-
-bool ELFLinkingContext::isDynamic() const {
- switch (_outputELFType) {
- case llvm::ELF::ET_EXEC:
- return !_isStaticExecutable;
- case llvm::ELF::ET_DYN:
- return true;
- }
- return false;
-}
-
-bool ELFLinkingContext::isRelativeReloc(const Reference &) const {
- return false;
-}
-
-Writer &ELFLinkingContext::writer() const { return *_writer; }
-
-static void buildSearchPath(SmallString<128> &path, StringRef dir,
- StringRef sysRoot) {
- if (dir.startswith("=/")) {
- // If a search directory begins with "=", "=" is replaced
- // with the sysroot path.
- path.assign(sysRoot);
- path.append(dir.substr(1));
- } else {
- path.assign(dir);
- }
-}
-
-ErrorOr<StringRef> ELFLinkingContext::searchLibrary(StringRef libName) const {
- bool hasColonPrefix = libName[0] == ':';
- SmallString<128> path;
- for (StringRef dir : _inputSearchPaths) {
- // Search for dynamic library
- if (!_isStaticExecutable) {
- buildSearchPath(path, dir, _sysrootPath);
- llvm::sys::path::append(path, hasColonPrefix
- ? libName.drop_front()
- : Twine("lib", libName) + ".so");
- if (exists(path.str()))
- return path.str().copy(_allocator);
- }
- // Search for static libraries too
- buildSearchPath(path, dir, _sysrootPath);
- llvm::sys::path::append(path, hasColonPrefix
- ? libName.drop_front()
- : Twine("lib", libName) + ".a");
- if (exists(path.str()))
- return path.str().copy(_allocator);
- }
- if (hasColonPrefix && exists(libName.drop_front()))
- return libName.drop_front();
-
- return make_error_code(llvm::errc::no_such_file_or_directory);
-}
-
-ErrorOr<StringRef> ELFLinkingContext::searchFile(StringRef fileName,
- bool isSysRooted) const {
- SmallString<128> path;
- if (is_absolute(fileName) && isSysRooted) {
- path.assign(_sysrootPath);
- path.append(fileName);
- if (exists(path.str()))
- return path.str().copy(_allocator);
- } else if (exists(fileName)) {
- return fileName;
- }
-
- if (is_absolute(fileName))
- return make_error_code(llvm::errc::no_such_file_or_directory);
-
- for (StringRef dir : _inputSearchPaths) {
- buildSearchPath(path, dir, _sysrootPath);
- llvm::sys::path::append(path, fileName);
- if (exists(path.str()))
- return path.str().copy(_allocator);
- }
- return make_error_code(llvm::errc::no_such_file_or_directory);
-}
-
-void ELFLinkingContext::createInternalFiles(
- std::vector<std::unique_ptr<File>> &files) const {
- std::unique_ptr<SimpleFile> file(
- new SimpleFile("<internal file for --defsym>", File::kindELFObject));
- for (auto &i : getAbsoluteSymbols()) {
- StringRef sym = i.first;
- uint64_t val = i.second;
- file->addAtom(*(new (_allocator) SimpleAbsoluteAtom(
- *file, sym, Atom::scopeGlobal, val)));
- }
- files.push_back(std::move(file));
- LinkingContext::createInternalFiles(files);
-}
-
-void ELFLinkingContext::finalizeInputFiles() {
- // Add virtual archive that resolves undefined symbols.
- if (_resolver)
- getNodes().push_back(llvm::make_unique<FileNode>(std::move(_resolver)));
-}
-
-std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() const {
- if (_initialUndefinedSymbols.empty())
- return nullptr;
- std::unique_ptr<SimpleFile> undefinedSymFile(
- new SimpleFile("command line option -u", File::kindELFObject));
- for (auto undefSymStr : _initialUndefinedSymbols)
- undefinedSymFile->addAtom(*(new (_allocator) CommandLineUndefinedAtom(
- *undefinedSymFile, undefSymStr)));
- return std::move(undefinedSymFile);
-}
-
-void ELFLinkingContext::notifySymbolTableCoalesce(const Atom *existingAtom,
- const Atom *newAtom,
- bool &useNew) {
- // First suppose that the `existingAtom` is defined
- // and the `newAtom` is undefined.
- auto *da = dyn_cast<DefinedAtom>(existingAtom);
- auto *ua = dyn_cast<UndefinedAtom>(newAtom);
- if (!da && !ua) {
- // Then try to reverse the assumption.
- da = dyn_cast<DefinedAtom>(newAtom);
- ua = dyn_cast<UndefinedAtom>(existingAtom);
- }
-
- if (da && ua && da->scope() == Atom::scopeGlobal &&
- isa<SharedLibraryFile>(ua->file()))
- // If strong defined atom coalesces away an atom declared
- // in the shared object the strong atom needs to be dynamically exported.
- // Save its name.
- _dynamicallyExportedSymbols.insert(ua->name());
-}
-
-std::string ELFLinkingContext::demangle(StringRef symbolName) const {
-#if defined(HAVE_CXXABI_H)
- if (!demangleSymbols())
- return symbolName;
-
- // Only try to demangle symbols that look like C++ symbols
- if (!symbolName.startswith("_Z"))
- return symbolName;
-
- SmallString<256> symBuff;
- StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
- const char *cstr = nullTermSym.data();
- int status;
- char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
- if (!demangled)
- return symbolName;
- std::string result(demangled);
- // __cxa_demangle() always uses a malloc'ed buffer to return the result.
- free(demangled);
- return result;
-#else
- return symbolName;
-#endif
-}
-
-void ELFLinkingContext::setUndefinesResolver(std::unique_ptr<File> resolver) {
- assert(isa<ArchiveLibraryFile>(resolver.get()) && "Wrong resolver type");
- _resolver = std::move(resolver);
-}
-
-void ELFLinkingContext::notifyInputSectionName(StringRef name) {
- // Save sections names which can be represented as a C identifier.
- if (name.find_first_not_of("0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "_") == StringRef::npos) {
- std::lock_guard<std::mutex> lock(_cidentMutex);
- _cidentSections.insert(name);
- }
-}
-
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFReader.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (removed)
@@ -1,47 +0,0 @@
-//===- lib/ReaderWriter/ELF/ELFReader.h -----------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_READER_H
-#define LLD_READER_WRITER_ELF_READER_H
-
-#include "DynamicFile.h"
-#include "ELFFile.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Reader.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Object/ELF.h"
-
-namespace lld {
-namespace elf {
-
-template <typename FileT> class ELFReader : public Reader {
-public:
- ELFReader(ELFLinkingContext &ctx) : _ctx(ctx) {}
-
- bool canParse(file_magic magic, MemoryBufferRef mb) const override {
- return FileT::canParse(magic);
- }
-
- ErrorOr<std::unique_ptr<File>>
- loadFile(std::unique_ptr<MemoryBuffer> mb,
- const class Registry &) const override {
- if (std::error_code ec = FileT::isCompatible(mb->getMemBufferRef(), _ctx))
- return ec;
- std::unique_ptr<File> ret = llvm::make_unique<FileT>(std::move(mb), _ctx);
- return std::move(ret);
- }
-
-private:
- ELFLinkingContext &_ctx;
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_READER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (removed)
@@ -1,157 +0,0 @@
-//===- lib/ReaderWriter/ELF/ExecutableWriter.h ----------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_EXECUTABLE_WRITER_H
-
-#include "OutputELFWriter.h"
-
-namespace lld {
-namespace elf {
-using namespace llvm;
-using namespace llvm::object;
-
-//===----------------------------------------------------------------------===//
-// ExecutableWriter Class
-//===----------------------------------------------------------------------===//
-template<class ELFT>
-class ExecutableWriter : public OutputELFWriter<ELFT> {
-public:
- ExecutableWriter(ELFLinkingContext &ctx, TargetLayout<ELFT> &layout)
- : OutputELFWriter<ELFT>(ctx, layout) {}
-
-protected:
- void buildDynamicSymbolTable(const File &file) override;
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
-
- bool isNeededTagRequired(const SharedLibraryAtom *sla) const override {
- return this->_layout.isCopied(sla);
- }
-
- unique_bump_ptr<InterpSection<ELFT>> _interpSection;
-
-private:
- std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile();
-};
-
-//===----------------------------------------------------------------------===//
-// ExecutableWriter
-//===----------------------------------------------------------------------===//
-template<class ELFT>
-void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- for (auto sec : this->_layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms()) {
- const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
- if (!da)
- continue;
- if (da->dynamicExport() != DefinedAtom::dynamicExportAlways &&
- !this->_ctx.isDynamicallyExportedSymbol(da->name()) &&
- !(this->_ctx.shouldExportDynamic() &&
- da->scope() == Atom::Scope::scopeGlobal))
- continue;
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
-
- // Put weak symbols in the dynamic symbol table.
- if (this->_ctx.isDynamic()) {
- for (const UndefinedAtom *a : file.undefined()) {
- if (this->_layout.isReferencedByDefinedAtom(a) &&
- a->canBeNull() != UndefinedAtom::canBeNullNever)
- this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
- }
- }
-
- OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
-}
-
-template<class ELFT>
-std::unique_ptr<RuntimeFile<ELFT>> ExecutableWriter<ELFT>::createRuntimeFile() {
- auto file = llvm::make_unique<RuntimeFile<ELFT>>(this->_ctx, "C runtime");
- file->addUndefinedAtom(this->_ctx.entrySymbolName());
- file->addAbsoluteAtom("__bss_start");
- file->addAbsoluteAtom("__bss_end");
- file->addAbsoluteAtom("_end");
- file->addAbsoluteAtom("end");
- file->addAbsoluteAtom("__preinit_array_start", true);
- file->addAbsoluteAtom("__preinit_array_end", true);
- file->addAbsoluteAtom("__init_array_start", true);
- file->addAbsoluteAtom("__init_array_end", true);
- if (this->_ctx.isRelaOutputFormat()) {
- file->addAbsoluteAtom("__rela_iplt_start");
- file->addAbsoluteAtom("__rela_iplt_end");
- } else {
- file->addAbsoluteAtom("__rel_iplt_start");
- file->addAbsoluteAtom("__rel_iplt_end");
- }
- file->addAbsoluteAtom("__fini_array_start", true);
- file->addAbsoluteAtom("__fini_array_end", true);
- return file;
-}
-
-/// \brief Hook in lld to add CRuntime file
-template <class ELFT>
-void ExecutableWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File> > &result) {
- OutputELFWriter<ELFT>::createImplicitFiles(result);
- result.push_back(createRuntimeFile());
-}
-
-template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() {
- OutputELFWriter<ELFT>::createDefaultSections();
- if (this->_ctx.isDynamic()) {
- _interpSection.reset(new (this->_alloc) InterpSection<ELFT>(
- this->_ctx, ".interp", TargetLayout<ELFT>::ORDER_INTERP,
- this->_ctx.getInterpreter()));
- this->_layout.addSection(_interpSection.get());
- }
-}
-
-/// Finalize the value of all the absolute symbols that we
-/// created
-template <class ELFT> void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- OutputELFWriter<ELFT>::finalizeDefaultAtomValues();
- AtomLayout *bssStartAtom = this->_layout.findAbsoluteAtom("__bss_start");
- AtomLayout *bssEndAtom = this->_layout.findAbsoluteAtom("__bss_end");
- AtomLayout *underScoreEndAtom = this->_layout.findAbsoluteAtom("_end");
- AtomLayout *endAtom = this->_layout.findAbsoluteAtom("end");
-
- assert((bssStartAtom || bssEndAtom || underScoreEndAtom || endAtom) &&
- "Unable to find the absolute atoms that have been added by lld");
-
- this->updateScopeAtomValues("preinit_array", ".preinit_array");
- this->updateScopeAtomValues("init_array", ".init_array");
- if (this->_ctx.isRelaOutputFormat())
- this->updateScopeAtomValues("rela_iplt", ".rela.plt");
- else
- this->updateScopeAtomValues("rel_iplt", ".rel.plt");
- this->updateScopeAtomValues("fini_array", ".fini_array");
-
- auto bssSection = this->_layout.findOutputSection(".bss");
-
- // If we don't find a bss section, then don't set these values
- if (bssSection) {
- bssStartAtom->_virtualAddr = bssSection->virtualAddr();
- bssEndAtom->_virtualAddr =
- bssSection->virtualAddr() + bssSection->memSize();
- underScoreEndAtom->_virtualAddr = bssEndAtom->_virtualAddr;
- endAtom->_virtualAddr = bssEndAtom->_virtualAddr;
- } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
- underScoreEndAtom->_virtualAddr =
- dataSection->virtualAddr() + dataSection->memSize();
- endAtom->_virtualAddr = underScoreEndAtom->_virtualAddr;
- }
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_EXECUTABLE_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/FileCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/FileCommon.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/FileCommon.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/FileCommon.cpp (removed)
@@ -1,66 +0,0 @@
-//===- lib/ReaderWriter/ELF/FileCommon.cpp --------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ELFFile.h"
-#include "FileCommon.h"
-
-using namespace llvm::ELF;
-
-namespace lld {
-namespace elf {
-
-static const char *elf32_expected = "ELF32 expected, but got ELF64";
-static const char *elf64_expected = "ELF64 expected, but got ELF32";
-static const char *le_expected =
- "Little endian files are expected, but got a big endian file.";
-static const char *be_expected =
- "Big endian files are expected, but got a little endian file.";
-
-template <>
-std::error_code checkCompatibility<ELF32LE>(unsigned char size,
- unsigned char endian) {
- if (size == ELFCLASS64)
- return make_dynamic_error_code(elf32_expected);
- if (endian == ELFDATA2MSB)
- return make_dynamic_error_code(le_expected);
- return std::error_code();
-}
-
-template <>
-std::error_code checkCompatibility<ELF32BE>(unsigned char size,
- unsigned char endian) {
- if (size == ELFCLASS64)
- return make_dynamic_error_code(elf32_expected);
- if (endian == ELFDATA2LSB)
- return make_dynamic_error_code(be_expected);
- return std::error_code();
-}
-
-template <>
-std::error_code checkCompatibility<ELF64LE>(unsigned char size,
- unsigned char endian) {
- if (size == ELFCLASS32)
- return make_dynamic_error_code(elf64_expected);
- if (endian == ELFDATA2MSB)
- return make_dynamic_error_code(le_expected);
- return std::error_code();
-}
-
-template <>
-std::error_code checkCompatibility<ELF64BE>(unsigned char size,
- unsigned char endian) {
- if (size == ELFCLASS32)
- return make_dynamic_error_code(elf64_expected);
- if (endian == ELFDATA2LSB)
- return make_dynamic_error_code(be_expected);
- return std::error_code();
-}
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/FileCommon.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/FileCommon.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/FileCommon.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/FileCommon.h (removed)
@@ -1,45 +0,0 @@
-//===- lib/ReaderWriter/ELF/FileCommon.h ----------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_FILE_COMMON_H
-#define LLD_READER_WRITER_ELF_FILE_COMMON_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-std::error_code checkCompatibility(unsigned char size, unsigned char endian);
-
-template <typename ELFT>
-std::error_code isCompatible(MemoryBufferRef mb, ELFLinkingContext &ctx) {
- typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
-
- if (uintptr_t(mb.getBufferStart()) & 1)
- return make_dynamic_error_code("invalid alignment");
-
- auto *hdr = reinterpret_cast<const Elf_Ehdr *>(mb.getBuffer().data());
- if (hdr->e_machine != ctx.getMachineType())
- return make_dynamic_error_code("incompatible machine type");
-
- unsigned char size;
- unsigned char endian;
- std::tie(size, endian) = llvm::object::getElfArchType(mb.getBuffer());
- if (std::error_code ec = checkCompatibility<ELFT>(size, endian))
- return ec;
- return std::error_code();
-}
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.cpp (removed)
@@ -1,205 +0,0 @@
-//===- lib/ReaderWriter/ELF/HeaderChunks.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HeaderChunks.h"
-#include "TargetLayout.h"
-#include "llvm/ADT/STLExtras.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> void ELFHeader<ELFT>::finalize() {
- _eh.e_ident[llvm::ELF::EI_CLASS] =
- (ELFT::Is64Bits) ? llvm::ELF::ELFCLASS64 : llvm::ELF::ELFCLASS32;
- _eh.e_ident[llvm::ELF::EI_DATA] =
- (ELFT::TargetEndianness == llvm::support::little)
- ? llvm::ELF::ELFDATA2LSB
- : llvm::ELF::ELFDATA2MSB;
- _eh.e_type = this->_ctx.getOutputELFType();
- _eh.e_machine = this->_ctx.getOutputMachine();
-}
-
-template <class ELFT>
-ELFHeader<ELFT>::ELFHeader(const ELFLinkingContext &ctx)
- : Chunk<ELFT>("elfhdr", Chunk<ELFT>::Kind::ELFHeader, ctx) {
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- this->_fsize = sizeof(Elf_Ehdr);
- this->_msize = sizeof(Elf_Ehdr);
- memset(_eh.e_ident, 0, llvm::ELF::EI_NIDENT);
- e_ident(llvm::ELF::EI_MAG0, 0x7f);
- e_ident(llvm::ELF::EI_MAG1, 'E');
- e_ident(llvm::ELF::EI_MAG2, 'L');
- e_ident(llvm::ELF::EI_MAG3, 'F');
- e_ehsize(sizeof(Elf_Ehdr));
- e_flags(0);
-}
-
-template <class ELFT>
-void ELFHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *atomContent = chunkBuffer + this->fileOffset();
- memcpy(atomContent, &_eh, fileSize());
-}
-
-template <class ELFT>
-bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
- bool allocatedNew = false;
- ELFLinkingContext::OutputMagic outputMagic = this->_ctx.getOutputMagic();
- // For segments that are not a loadable segment, we
- // just pick the values directly from the segment as there
- // wouldnt be any slices within that
- if (segment->segmentType() != llvm::ELF::PT_LOAD) {
- Elf_Phdr *phdr = allocateProgramHeader(allocatedNew);
- phdr->p_type = segment->segmentType();
- phdr->p_offset = segment->fileOffset();
- phdr->p_vaddr = segment->virtualAddr();
- phdr->p_paddr = segment->virtualAddr();
- phdr->p_filesz = segment->fileSize();
- phdr->p_memsz = segment->memSize();
- phdr->p_flags = segment->flags();
- phdr->p_align = segment->alignment();
- this->_fsize = fileSize();
- this->_msize = this->_fsize;
- return allocatedNew;
- }
- // For all other segments, use the slice
- // to derive program headers
- for (auto slice : segment->slices()) {
- Elf_Phdr *phdr = allocateProgramHeader(allocatedNew);
- phdr->p_type = segment->segmentType();
- phdr->p_offset = slice->fileOffset();
- phdr->p_vaddr = slice->virtualAddr();
- phdr->p_paddr = slice->virtualAddr();
- phdr->p_filesz = slice->fileSize();
- phdr->p_memsz = slice->memSize();
- phdr->p_flags = segment->flags();
- phdr->p_align = slice->alignment();
- uint64_t segPageSize = segment->pageSize();
- uint64_t sliceAlign = slice->alignment();
- // Alignment of PT_LOAD segments are set to the page size, but if the
- // alignment of the slice is greater than the page size, set the alignment
- // of the segment appropriately.
- if (outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
- outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
- phdr->p_align =
- (phdr->p_type == llvm::ELF::PT_LOAD)
- ? (segPageSize < sliceAlign) ? sliceAlign : segPageSize
- : sliceAlign;
- } else
- phdr->p_align = slice->alignment();
- }
- this->_fsize = fileSize();
- this->_msize = this->_fsize;
-
- return allocatedNew;
-}
-
-template <class ELFT>
-void ProgramHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- for (auto phi : _ph) {
- memcpy(dest, phi, sizeof(Elf_Phdr));
- dest += sizeof(Elf_Phdr);
- }
-}
-
-template <class ELFT>
-typename ProgramHeader<ELFT>::Elf_Phdr *
-ProgramHeader<ELFT>::allocateProgramHeader(bool &allocatedNew) {
- Elf_Phdr *phdr;
- if (_phi == _ph.end()) {
- phdr = new (_allocator) Elf_Phdr;
- _ph.push_back(phdr);
- _phi = _ph.end();
- allocatedNew = true;
- } else {
- phdr = (*_phi);
- ++_phi;
- }
- return phdr;
-}
-
-template <class ELFT>
-SectionHeader<ELFT>::SectionHeader(const ELFLinkingContext &ctx, int32_t order)
- : Chunk<ELFT>("shdr", Chunk<ELFT>::Kind::SectionHeader, ctx) {
- this->_fsize = 0;
- this->_alignment = 8;
- this->setOrder(order);
- // The first element in the list is always NULL
- auto *nullshdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;
- ::memset(nullshdr, 0, sizeof(Elf_Shdr));
- _sectionInfo.push_back(nullshdr);
- this->_fsize += sizeof(Elf_Shdr);
-}
-
-template <class ELFT>
-void SectionHeader<ELFT>::appendSection(OutputSection<ELFT> *section) {
- auto *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;
- shdr->sh_name = _stringSection->addString(section->name());
- shdr->sh_type = section->type();
- shdr->sh_flags = section->flags();
- shdr->sh_offset = section->fileOffset();
- shdr->sh_addr = section->virtualAddr();
- if (section->isLoadableSection())
- shdr->sh_size = section->memSize();
- else
- shdr->sh_size = section->fileSize();
- shdr->sh_link = section->link();
- shdr->sh_info = section->shinfo();
- shdr->sh_addralign = section->alignment();
- shdr->sh_entsize = section->entsize();
- _sectionInfo.push_back(shdr);
-}
-
-template <class ELFT>
-void SectionHeader<ELFT>::updateSection(Section<ELFT> *section) {
- Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
- shdr->sh_type = section->getType();
- shdr->sh_flags = section->getFlags();
- shdr->sh_offset = section->fileOffset();
- shdr->sh_addr = section->virtualAddr();
- shdr->sh_size = section->fileSize();
- shdr->sh_link = section->getLink();
- shdr->sh_info = section->getInfo();
- shdr->sh_addralign = section->alignment();
- shdr->sh_entsize = section->getEntSize();
-}
-
-template <class ELFT>
-void SectionHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- for (auto shi : _sectionInfo) {
- memcpy(dest, shi, sizeof(Elf_Shdr));
- dest += sizeof(Elf_Shdr);
- }
- _stringSection->write(writer, layout, buffer);
-}
-
-template class ELFHeader<ELF32LE>;
-template class ELFHeader<ELF32BE>;
-template class ELFHeader<ELF64LE>;
-template class ELFHeader<ELF64BE>;
-
-template class ProgramHeader<ELF32LE>;
-template class ProgramHeader<ELF32BE>;
-template class ProgramHeader<ELF64LE>;
-template class ProgramHeader<ELF64BE>;
-
-template class SectionHeader<ELF32LE>;
-template class SectionHeader<ELF32BE>;
-template class SectionHeader<ELF64LE>;
-template class SectionHeader<ELF64BE>;
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (removed)
@@ -1,154 +0,0 @@
-//===- lib/ReaderWriter/ELF/HeaderChunks.h --------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_HEADER_CHUNKS_H
-#define LLD_READER_WRITER_ELF_HEADER_CHUNKS_H
-
-#include "SegmentChunks.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileOutputBuffer.h"
-
-/// \brief An Header represents the Elf[32/64]_Ehdr structure at the
-/// start of an ELF executable file.
-namespace lld {
-namespace elf {
-
-template <class ELFT> class ELFHeader : public Chunk<ELFT> {
-public:
- typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
-
- ELFHeader(const ELFLinkingContext &);
-
- void e_ident(int I, unsigned char C) { _eh.e_ident[I] = C; }
- void e_type(uint16_t type) { _eh.e_type = type; }
- void e_machine(uint16_t machine) { _eh.e_machine = machine; }
- void e_version(uint32_t version) { _eh.e_version = version; }
- void e_entry(int64_t entry) { _eh.e_entry = entry; }
- void e_phoff(int64_t phoff) { _eh.e_phoff = phoff; }
- void e_shoff(int64_t shoff) { _eh.e_shoff = shoff; }
- void e_flags(uint32_t flags) { _eh.e_flags = flags; }
- void e_ehsize(uint16_t ehsize) { _eh.e_ehsize = ehsize; }
- void e_phentsize(uint16_t phentsize) { _eh.e_phentsize = phentsize; }
- void e_phnum(uint16_t phnum) { _eh.e_phnum = phnum; }
- void e_shentsize(uint16_t shentsize) { _eh.e_shentsize = shentsize; }
- void e_shnum(uint16_t shnum) { _eh.e_shnum = shnum; }
- void e_shstrndx(uint16_t shstrndx) { _eh.e_shstrndx = shstrndx; }
- uint64_t fileSize() const override { return sizeof(Elf_Ehdr); }
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::ELFHeader;
- }
-
- int getContentType() const override {
- return Chunk<ELFT>::ContentType::Header;
- }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- void finalize() override;
-
-private:
- Elf_Ehdr _eh;
-};
-
-/// \brief An ProgramHeader represents the Elf[32/64]_Phdr structure at the
-/// start of an ELF executable file.
-template<class ELFT>
-class ProgramHeader : public Chunk<ELFT> {
-public:
- typedef llvm::object::Elf_Phdr_Impl<ELFT> Elf_Phdr;
- typedef typename std::vector<Elf_Phdr *>::iterator PhIterT;
- typedef typename std::reverse_iterator<PhIterT> ReversePhIterT;
-
- ProgramHeader(const ELFLinkingContext &ctx)
- : Chunk<ELFT>("elfphdr", Chunk<ELFT>::Kind::ProgramHeader, ctx) {
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- resetProgramHeaders();
- }
-
- bool addSegment(Segment<ELFT> *segment);
- void resetProgramHeaders() { _phi = _ph.begin(); }
- uint64_t fileSize() const override { return sizeof(Elf_Phdr) * _ph.size(); }
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::ProgramHeader;
- }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- PhIterT begin() { return _ph.begin(); }
- PhIterT end() { return _ph.end(); }
- ReversePhIterT rbegin() { return _ph.rbegin(); }
- ReversePhIterT rend() { return _ph.rend(); }
-
- int64_t entsize() { return sizeof(Elf_Phdr); }
- int64_t numHeaders() { return _ph.size(); }
-
- int getContentType() const override {
- return Chunk<ELFT>::ContentType::Header;
- }
-
-private:
- Elf_Phdr *allocateProgramHeader(bool &allocatedNew);
-
- std::vector<Elf_Phdr *> _ph;
- PhIterT _phi;
- llvm::BumpPtrAllocator _allocator;
-};
-
-/// \brief An SectionHeader represents the Elf[32/64]_Shdr structure
-/// at the end of the file
-template<class ELFT>
-class SectionHeader : public Chunk<ELFT> {
-public:
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
- SectionHeader(const ELFLinkingContext &, int32_t order);
- void appendSection(OutputSection<ELFT> *section);
- void updateSection(Section<ELFT> *section);
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::SectionHeader;
- }
-
- void setStringSection(StringTable<ELFT> *s) {
- _stringSection = s;
- }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- uint64_t fileSize() const override {
- return sizeof(Elf_Shdr) * _sectionInfo.size();
- }
-
- uint64_t entsize() { return sizeof(Elf_Shdr); }
-
- int getContentType() const override {
- return Chunk<ELFT>::ContentType::Header;
- }
-
- uint64_t numHeaders() { return _sectionInfo.size(); }
-
-private:
- StringTable<ELFT> *_stringSection;
- std::vector<Elf_Shdr *> _sectionInfo;
- llvm::BumpPtrAllocator _sectionAllocate;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt (removed)
@@ -1,11 +0,0 @@
-add_lld_library(lldHexagonELFTarget
- HexagonLinkingContext.cpp
- HexagonRelocationHandler.cpp
- HexagonTargetHandler.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h (removed)
@@ -1,67 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h ---------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef HEXAGON_DYNAMIC_LIBRARY_WRITER_H
-#define HEXAGON_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "HexagonLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class HexagonTargetLayout;
-
-class HexagonDynamicLibraryWriter : public DynamicLibraryWriter<ELF32LE> {
-public:
- HexagonDynamicLibraryWriter(HexagonLinkingContext &ctx,
- HexagonTargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
-
- std::error_code setELFHeader() override {
- DynamicLibraryWriter::setELFHeader();
- setHexagonELFHeader(*_elfHeader);
- return std::error_code();
- }
-
-private:
- HexagonLinkingContext &_ctx;
- HexagonTargetLayout &_targetLayout;
-};
-
-HexagonDynamicLibraryWriter::HexagonDynamicLibraryWriter(
- HexagonLinkingContext &ctx, HexagonTargetLayout &layout)
- : DynamicLibraryWriter(ctx, layout), _ctx(ctx), _targetLayout(layout) {}
-
-void HexagonDynamicLibraryWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter::createImplicitFiles(result);
- // Add the default atoms as defined for hexagon
- auto file =
- llvm::make_unique<RuntimeFile<ELF32LE>>(_ctx, "Hexagon runtime file");
- file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- file->addAbsoluteAtom("_DYNAMIC");
- result.push_back(std::move(file));
-}
-
-void HexagonDynamicLibraryWriter::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- DynamicLibraryWriter::finalizeDefaultAtomValues();
- if (_ctx.isDynamic())
- finalizeHexagonRuntimeAtomValues(_targetLayout);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // HEXAGON_DYNAMIC_LIBRARY_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h (removed)
@@ -1,149 +0,0 @@
-//===- lib/ReaderWriter/ELF/HexagonELFFile.h ------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
-#define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
-
-#include "ELFReader.h"
-#include "HexagonLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class HexagonELFFile;
-
-class HexagonELFDefinedAtom : public ELFDefinedAtom<ELF32LE> {
- typedef llvm::object::Elf_Sym_Impl<ELF32LE> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELF32LE> Elf_Shdr;
-
-public:
- template <typename... T>
- HexagonELFDefinedAtom(T &&... args)
- : ELFDefinedAtom(std::forward<T>(args)...) {}
-
- DefinedAtom::ContentType contentType() const override {
- if (_contentType != DefinedAtom::typeUnknown)
- return _contentType;
- if (_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) {
- if (_section->sh_type == llvm::ELF::SHT_NOBITS)
- return (_contentType = DefinedAtom::typeZeroFillFast);
- return (_contentType = DefinedAtom::typeDataFast);
- }
- return ELFDefinedAtom::contentType();
- }
-
- DefinedAtom::ContentPermissions permissions() const override {
- if (_section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
- return DefinedAtom::permRW_;
- return ELFDefinedAtom::permissions();
- }
-};
-
-class HexagonELFCommonAtom : public ELFCommonAtom<ELF32LE> {
- typedef llvm::object::Elf_Sym_Impl<ELF32LE> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELF32LE> Elf_Shdr;
-
-public:
- HexagonELFCommonAtom(const ELFFile<ELF32LE> &file, StringRef symbolName,
- const Elf_Sym *symbol)
- : ELFCommonAtom(file, symbolName, symbol) {}
-
- virtual bool isSmallCommonSymbol() const {
- switch (_symbol->st_shndx) {
- // Common symbols
- case llvm::ELF::SHN_HEXAGON_SCOMMON:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
- return true;
- default:
- break;
- }
- return false;
- }
-
- uint64_t size() const override {
- if (isSmallCommonSymbol())
- return _symbol->st_size;
- return ELFCommonAtom::size();
- }
-
- DefinedAtom::Merge merge() const override {
- if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
- return DefinedAtom::mergeAsWeak;
- if (isSmallCommonSymbol())
- return DefinedAtom::mergeAsTentative;
- return ELFCommonAtom::merge();
- }
-
- DefinedAtom::ContentType contentType() const override {
- if (isSmallCommonSymbol())
- return DefinedAtom::typeZeroFillFast;
- return ELFCommonAtom::contentType();
- }
-
- DefinedAtom::Alignment alignment() const override {
- if (isSmallCommonSymbol())
- return DefinedAtom::Alignment(_symbol->st_value);
- return 1;
- }
-
- DefinedAtom::ContentPermissions permissions() const override {
- if (isSmallCommonSymbol())
- return DefinedAtom::permRW_;
- return ELFCommonAtom::permissions();
- }
-};
-
-class HexagonELFFile : public ELFFile<ELF32LE> {
- typedef llvm::object::Elf_Sym_Impl<ELF32LE> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELF32LE> Elf_Shdr;
-
-public:
- HexagonELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
- : ELFFile(std::move(mb), ctx) {}
-
- bool isCommonSymbol(const Elf_Sym *symbol) const override {
- switch (symbol->st_shndx) {
- // Common symbols
- case llvm::ELF::SHN_HEXAGON_SCOMMON:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
- return true;
- default:
- break;
- }
- return ELFFile::isCommonSymbol(symbol);
- }
-
- /// Process the Defined symbol and create an atom for it.
- ELFDefinedAtom<ELF32LE> *createDefinedAtom(
- StringRef symName, StringRef sectionName, const Elf_Sym *sym,
- const Elf_Shdr *sectionHdr, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELF32LE> *> &referenceList) override {
- return new (_readerStorage) HexagonELFDefinedAtom(
- *this, symName, sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- }
-
- /// Process the Common symbol and create an atom for it.
- ELFCommonAtom<ELF32LE> *createCommonAtom(StringRef symName,
- const Elf_Sym *sym) override {
- return new (_readerStorage) HexagonELFCommonAtom(*this, symName, sym);
- }
-};
-
-} // elf
-} // lld
-
-#endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h (removed)
@@ -1,638 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h -------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace lld {
-namespace elf {
-
-/// \brief Applying fixup on Hexagon requires the relocator to fetch the fixup
-/// mask from the instruction. To fetch the fixup encoding, the linker uses a
-/// static array that contains the instruction mask, the compare mask and the
-/// relocation mask.
-typedef struct {
- uint32_t insnMask; // Instruction mask.
- uint32_t insnCmpMask; // Compare mask.
- uint32_t insnBitMask; // Relocation mask.
- bool isDuplex; // Indicates if the instruction is a duplex instruction.
-} Instruction;
-
-Instruction insn_encodings[] = {
- // InsnMask CompareMask BitMask IsDuplexInstruction
- { 0xffe00004, 0x40000000, 0x20f8, 0x0 },
- { 0xffe03080, 0x9ca03080, 0xf60, 0x0 },
- { 0xf9e00000, 0x48c00000, 0x61f20ff, 0x0 },
- { 0xf7c02300, 0x13802100, 0x3000fe, 0x0 },
- { 0xffe00000, 0x60c00000, 0x1f18, 0x0 },
- { 0xffe00000, 0x69c00000, 0x1f18, 0x0 },
- { 0xffe02000, 0x43000000, 0x7e0, 0x0 },
- { 0xff602060, 0x3e000060, 0x1f80, 0x0 },
- { 0xffe03000, 0x9ae01000, 0xf60, 0x0 },
- { 0xf9e00000, 0x91600000, 0x6003fe0, 0x0 },
- { 0xffe02084, 0xaf000084, 0x30078, 0x0 },
- { 0xff602060, 0x3e000020, 0x1f80, 0x0 },
- { 0xff602060, 0x3e200040, 0x1f80, 0x0 },
- { 0xf7c02000, 0x10c02000, 0x3000fe, 0x0 },
- { 0xffe00000, 0x60200000, 0x1f18, 0x0 },
- { 0xffe00000, 0x69200000, 0x1f18, 0x0 },
- { 0xffe038c0, 0xada00880, 0x3f, 0x0 },
- { 0xff602000, 0x73002000, 0x1fe0, 0x0 },
- { 0xf7c02000, 0x26c02000, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9f403880, 0x1f0100, 0x0 },
- { 0xf9e00000, 0x48400000, 0x61f20ff, 0x0 },
- { 0xffe02000, 0x41600000, 0x7e0, 0x0 },
- { 0xffe02084, 0xaf000080, 0x30078, 0x0 },
- { 0xf7c02300, 0x13800100, 0x3000fe, 0x0 },
- { 0xffe01804, 0x46a00000, 0x20f8, 0x0 },
- { 0xffe00004, 0x42400000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x22400000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x12402000, 0x3000fe, 0x0 },
- { 0xfc003d18, 0x28003c18, 0x3f00000, 0x1 },
- { 0xffe00000, 0x39000000, 0x201f, 0x0 },
- { 0xff601018, 0xdd400008, 0xfe0, 0x0 },
- { 0xffc0001c, 0x75400000, 0x203fe0, 0x0 },
- { 0xfc003fc7, 0x48003f47, 0x3f00000, 0x1 },
- { 0xffe03080, 0x9ca03000, 0xf60, 0x0 },
- { 0xf9e00000, 0x90800000, 0x6003fe0, 0x0 },
- { 0xf8003fc7, 0x40003fc4, 0x7f00000, 0x1 },
- { 0xfc003e00, 0x68003c00, 0x3f00000, 0x1 },
- { 0xf8003fc7, 0x40003fc5, 0x7f00000, 0x1 },
- { 0xf9e00000, 0x91800000, 0x6003fe0, 0x0 },
- { 0xff602060, 0x3e400060, 0x1f80, 0x0 },
- { 0xff602060, 0x3e000000, 0x1f80, 0x0 },
- { 0xf8003d18, 0x20003c18, 0x7f00000, 0x1 },
- { 0xf8003f00, 0x20003800, 0x7f00000, 0x1 },
- { 0xf8003d18, 0x20003c10, 0x7f00000, 0x1 },
- { 0xff602000, 0x73602000, 0x1fe0, 0x0 },
- { 0xffe03880, 0x9f002080, 0x1f0100, 0x0 },
- { 0xffe02000, 0x47000000, 0x7e0, 0x0 },
- { 0xf9e00000, 0x91400000, 0x6003fe0, 0x0 },
- { 0xffe02080, 0xabc00080, 0x3f, 0x0 },
- { 0xf7c02000, 0x20802000, 0x3000fe, 0x0 },
- { 0xf8003fc7, 0x40003f44, 0x7f00000, 0x1 },
- { 0xffe03884, 0xafa03084, 0x30078, 0x0 },
- { 0xffe03000, 0x9b001000, 0xf60, 0x0 },
- { 0xffe01804, 0x42a00800, 0x20f8, 0x0 },
- { 0xfc003f00, 0x28003100, 0x3f00000, 0x1 },
- { 0xffe02080, 0xab800080, 0x3f, 0x0 },
- { 0xf7c02000, 0x24c00000, 0x3000fe, 0x0 },
- { 0xffe00000, 0x39a00000, 0x201f, 0x0 },
- { 0xf7c02300, 0x13802300, 0x3000fe, 0x0 },
- { 0xffe01804, 0x46a00800, 0x20f8, 0x0 },
- { 0xffe020c0, 0xad602080, 0x3f, 0x0 },
- { 0xfc003f00, 0x28003500, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x28003400, 0x3f00000, 0x1 },
- { 0xffe020c0, 0xad6000c0, 0x3f, 0x0 },
- { 0xffe00000, 0x60000000, 0x1f18, 0x0 },
- { 0xf8003000, 0x40000000, 0x7f00000, 0x1 },
- { 0xffe00000, 0x69000000, 0x1f18, 0x0 },
- { 0xffe03080, 0x9c601080, 0xf60, 0x0 },
- { 0xffe03080, 0x9ce01000, 0xf60, 0x0 },
- { 0xffe03080, 0x9c601000, 0xf60, 0x0 },
- { 0xf7c02000, 0x13402000, 0x3000fe, 0x0 },
- { 0xffe03080, 0x9c603000, 0xf60, 0x0 },
- { 0xf7c02000, 0x21c00000, 0x3000fe, 0x0 },
- { 0xfc003000, 0x68000000, 0x3f00000, 0x1 },
- { 0xf8003800, 0x60002000, 0x7f00000, 0x1 },
- { 0xffe02084, 0xaf802084, 0x30078, 0x0 },
- { 0xfc003000, 0x48000000, 0x3f00000, 0x1 },
- { 0xf7c02300, 0x11c02100, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x12800000, 0x3000fe, 0x0 },
- { 0xfc003e70, 0x28003a40, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x28003300, 0x3f00000, 0x1 },
- { 0xff800000, 0xe0000000, 0x1fe0, 0x0 },
- { 0xff602060, 0x3f400000, 0x1f80, 0x0 },
- { 0xffe00004, 0x42000000, 0x20f8, 0x0 },
- { 0xf8003f00, 0x60003300, 0x7f00000, 0x1 },
- { 0xffe01804, 0x42a00000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x12c00000, 0x3000fe, 0x0 },
- { 0xf0000000, 0x0, 0xfff3fff, 0x0 },
- { 0xff000016, 0xde000016, 0xe020e8, 0x0 },
- { 0xffe03000, 0x9b201000, 0xf60, 0x0 },
- { 0xffe03880, 0xaba00880, 0x3f, 0x0 },
- { 0xf8003e00, 0x40003c00, 0x7f00000, 0x1 },
- { 0xff602060, 0x3f200040, 0x1f80, 0x0 },
- { 0xffe03880, 0x9f203880, 0x1f0100, 0x0 },
- { 0xf7c02000, 0x20c00000, 0x3000fe, 0x0 },
- { 0xf9e01800, 0x48a00800, 0x61f20ff, 0x0 },
- { 0xf9e00000, 0x90a00000, 0x6003fe0, 0x0 },
- { 0xff802000, 0x74802000, 0x1fe0, 0x0 },
- { 0xffe03000, 0x9a401000, 0xf60, 0x0 },
- { 0xf7c02000, 0x10002000, 0x3000fe, 0x0 },
- { 0xf7c03000, 0x14803000, 0x3000fe, 0x0 },
- { 0xffe020c0, 0xad0020c0, 0x3f, 0x0 },
- { 0xffe0001c, 0x75800000, 0x3fe0, 0x0 },
- { 0xf9e01800, 0x48a01000, 0x61f20ff, 0x0 },
- { 0xffe03080, 0x9dc03000, 0xf60, 0x0 },
- { 0xffe03080, 0x9dc03080, 0xf60, 0x0 },
- { 0xffe03080, 0x9dc01000, 0xf60, 0x0 },
- { 0xffe03080, 0x9dc01080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d601000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d601080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d603000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d603080, 0xf60, 0x0 },
- { 0xfc003e00, 0x48003c00, 0x3f00000, 0x1 },
- { 0xffe02084, 0xaf402084, 0x30078, 0x0 },
- { 0xffe00004, 0x46600000, 0x20f8, 0x0 },
- { 0xffe03880, 0x9f203080, 0x1f0100, 0x0 },
- { 0xf8003f00, 0x20003100, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x11402000, 0x3000fe, 0x0 },
- { 0xf8003d08, 0x20003d00, 0x7f00000, 0x1 },
- { 0xffe03080, 0x9ca01080, 0xf60, 0x0 },
- { 0xffe03080, 0x9ca01000, 0xf60, 0x0 },
- { 0xffe00000, 0x38a00000, 0x201f, 0x0 },
- { 0xf7c02300, 0x11800000, 0x3000fe, 0x0 },
- { 0xf7c02300, 0x13c02300, 0x3000fe, 0x0 },
- { 0xffe03080, 0x9ce03000, 0xf60, 0x0 },
- { 0xf9e00000, 0x90e00000, 0x6003fe0, 0x0 },
- { 0xffe02084, 0xaf400080, 0x30078, 0x0 },
- { 0xffe03080, 0x9ce03080, 0xf60, 0x0 },
- { 0xff000000, 0x78000000, 0xdf3fe0, 0x0 },
- { 0xffe03080, 0x9ce01080, 0xf60, 0x0 },
- { 0xffe03880, 0xaba01080, 0x3f, 0x0 },
- { 0xffe020c0, 0xad002080, 0x3f, 0x0 },
- { 0xffe020c0, 0xad0000c0, 0x3f, 0x0 },
- { 0xffe020c0, 0xad000080, 0x3f, 0x0 },
- { 0xf7c02000, 0x25000000, 0x3000fe, 0x0 },
- { 0xff602060, 0x3f200020, 0x1f80, 0x0 },
- { 0xffe02084, 0xafc00084, 0x30078, 0x0 },
- { 0xf7c02000, 0x24400000, 0x3000fe, 0x0 },
- { 0xfc003000, 0x48001000, 0x3f00000, 0x1 },
- { 0xf9e01800, 0xa1a01000, 0x60020ff, 0x0 },
- { 0xff602060, 0x3f000040, 0x1f80, 0x0 },
- { 0xffe02084, 0xaf602084, 0x30078, 0x0 },
- { 0xf8003f00, 0x20003400, 0x7f00000, 0x1 },
- { 0xffe02084, 0xaf400084, 0x30078, 0x0 },
- { 0xffe01804, 0x44a01000, 0x20f8, 0x0 },
- { 0xff602060, 0x3e200000, 0x1f80, 0x0 },
- { 0xf8003e70, 0x20003a70, 0x7f00000, 0x1 },
- { 0xf8003f00, 0x40003e00, 0x7f00000, 0x1 },
- { 0xf8003f00, 0x20003300, 0x7f00000, 0x1 },
- { 0xf7c02300, 0x13800300, 0x3000fe, 0x0 },
- { 0xffe038c0, 0xada00080, 0x3f, 0x0 },
- { 0xf9e00000, 0x49400000, 0x61f3fe0, 0x0 },
- { 0xf8003800, 0x40002800, 0x7f00000, 0x1 },
- { 0xffe038c0, 0xada020c0, 0x3f, 0x0 },
- { 0xffe03884, 0xafa00880, 0x30078, 0x0 },
- { 0xf9e00000, 0x49000000, 0x61f3fe0, 0x0 },
- { 0xff800000, 0xd7000000, 0x6020e0, 0x0 },
- { 0xffc00000, 0xda000000, 0x203fe0, 0x0 },
- { 0xf7c02000, 0x12802000, 0x3000fe, 0x0 },
- { 0xf9e00000, 0x49600000, 0x61f3fe0, 0x0 },
- { 0xffe02000, 0x47400000, 0x7e0, 0x0 },
- { 0xf9e00000, 0x49c00000, 0x61f3fe0, 0x0 },
- { 0xffe03000, 0x9bc01000, 0xf60, 0x0 },
- { 0xf7c02300, 0x13c00100, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9f002880, 0x1f0100, 0x0 },
- { 0xffe03000, 0x9b601000, 0xf60, 0x0 },
- { 0xffe01804, 0x40a00800, 0x20f8, 0x0 },
- { 0xffe00004, 0x42800000, 0x20f8, 0x0 },
- { 0xf7c03000, 0x14800000, 0x3000fe, 0x0 },
- { 0xfc003000, 0x68001000, 0x3f00000, 0x1 },
- { 0xfc003fc7, 0x48003f44, 0x3f00000, 0x1 },
- { 0xfc003fc7, 0x48003f45, 0x3f00000, 0x1 },
- { 0xf7c02000, 0x10800000, 0x3000fe, 0x0 },
- { 0xf8003e70, 0x20003a50, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x21002000, 0x3000fe, 0x0 },
- { 0xf8003fc4, 0x40003fc0, 0x7f00000, 0x1 },
- { 0xf9e00000, 0x48000000, 0x61f20ff, 0x0 },
- { 0xffc0001c, 0x75000010, 0x203fe0, 0x0 },
- { 0xf8003f00, 0x20003800, 0x7f00000, 0x1 },
- { 0xf9e00000, 0xa1800000, 0x60020ff, 0x0 },
- { 0xffc01000, 0x61c00000, 0x202ffe, 0x0 },
- { 0xffe02084, 0xaf402080, 0x30078, 0x0 },
- { 0xffe03880, 0x9f602880, 0x1f0100, 0x0 },
- { 0xfc003f00, 0x68003000, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x68003100, 0x3f00000, 0x1 },
- { 0xff602060, 0x3f200000, 0x1f80, 0x0 },
- { 0xffe03000, 0x9a801000, 0xf60, 0x0 },
- { 0xf7c02000, 0x24802000, 0x3000fe, 0x0 },
- { 0xffe00004, 0x42c00000, 0x20f8, 0x0 },
- { 0xf7c02300, 0x11802000, 0x3000fe, 0x0 },
- { 0xffc01000, 0x61401000, 0x202ffe, 0x0 },
- { 0xffe02000, 0x43c00000, 0x7e0, 0x0 },
- { 0xf7c02000, 0x11400000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x21800000, 0x3000fe, 0x0 },
- { 0xfc003c00, 0x28002c00, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x28003200, 0x3f00000, 0x1 },
- { 0xffe03080, 0x9c803080, 0xf60, 0x0 },
- { 0xf7c03000, 0x14c03000, 0x3000fe, 0x0 },
- { 0xff800000, 0xdb800000, 0x6020e0, 0x0 },
- { 0xf7c02000, 0x22402000, 0x3000fe, 0x0 },
- { 0xffe00004, 0x46800000, 0x20f8, 0x0 },
- { 0xffe00000, 0x69a00000, 0x1f18, 0x0 },
- { 0xfc003e00, 0x68002a00, 0x3f00000, 0x1 },
- { 0xffe00000, 0x60a00000, 0x1f18, 0x0 },
- { 0xf7c02000, 0x25400000, 0x3000fe, 0x0 },
- { 0xfc003e70, 0x28003a70, 0x3f00000, 0x1 },
- { 0xffe03080, 0x9c803000, 0xf60, 0x0 },
- { 0xffc01000, 0x61400000, 0x202ffe, 0x0 },
- { 0xffe01804, 0x42a01000, 0x20f8, 0x0 },
- { 0xffc0001c, 0x75000000, 0x203fe0, 0x0 },
- { 0xffe02084, 0xafc02080, 0x30078, 0x0 },
- { 0xffe03884, 0xafa00884, 0x30078, 0x0 },
- { 0xffe03884, 0xafa02080, 0x30078, 0x0 },
- { 0xffe00000, 0x38c00000, 0x201f, 0x0 },
- { 0xffc01000, 0x61001000, 0x202ffe, 0x0 },
- { 0xf9e00000, 0x48800000, 0x61f20ff, 0x0 },
- { 0xf8003800, 0x40003000, 0x7f00000, 0x1 },
- { 0xf7c03000, 0x15403000, 0x3000fe, 0x0 },
- { 0xf7c03000, 0x15400000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x21000000, 0x3000fe, 0x0 },
- { 0xffe00004, 0x40c00000, 0x20f8, 0x0 },
- { 0xffe01804, 0x46a01000, 0x20f8, 0x0 },
- { 0xf8003d08, 0x20003d08, 0x7f00000, 0x1 },
- { 0xffe038c0, 0xada02080, 0x3f, 0x0 },
- { 0xffe03080, 0x9c203000, 0xf60, 0x0 },
- { 0xfc003800, 0x68002000, 0x3f00000, 0x1 },
- { 0xf9e00000, 0x90600000, 0x6003fe0, 0x0 },
- { 0xf7c03000, 0x14000000, 0x3000fe, 0x0 },
- { 0xf8003e70, 0x20003a40, 0x7f00000, 0x1 },
- { 0xff201800, 0x5c000800, 0xdf20fe, 0x0 },
- { 0xffe02000, 0x41800000, 0x7e0, 0x0 },
- { 0xff800000, 0xdb000000, 0x6020e0, 0x0 },
- { 0xfc003f00, 0x48003e00, 0x3f00000, 0x1 },
- { 0xf7c03000, 0x14002000, 0x3000fe, 0x0 },
- { 0xf7c02300, 0x11800100, 0x3000fe, 0x0 },
- { 0xfc003e00, 0x68002800, 0x3f00000, 0x1 },
- { 0xffe00004, 0x44c00000, 0x20f8, 0x0 },
- { 0xffe03880, 0x9f003880, 0x1f0100, 0x0 },
- { 0xff602000, 0x73402000, 0x1fe0, 0x0 },
- { 0xffe00000, 0x38200000, 0x201f, 0x0 },
- { 0xf7c02000, 0x24800000, 0x3000fe, 0x0 },
- { 0xf7c03000, 0x15001000, 0x3000fe, 0x0 },
- { 0xff800000, 0x7c800000, 0x1f2000, 0x0 },
- { 0xf8003fc7, 0x40003fc6, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x12000000, 0x3000fe, 0x0 },
- { 0xff602000, 0x73202000, 0x1fe0, 0x0 },
- { 0xf7c02300, 0x13c00000, 0x3000fe, 0x0 },
- { 0xff602060, 0x3f400040, 0x1f80, 0x0 },
- { 0xf7c02000, 0x24002000, 0x3000fe, 0x0 },
- { 0xffe02084, 0xaf800080, 0x30078, 0x0 },
- { 0xffe00000, 0x38800000, 0x201f, 0x0 },
- { 0xfc003f00, 0x28003800, 0x3f00000, 0x1 },
- { 0xffe03080, 0x9c801080, 0xf60, 0x0 },
- { 0xffe020c0, 0xad4000c0, 0x3f, 0x0 },
- { 0xffe00000, 0x39400000, 0x201f, 0x0 },
- { 0xf7c02300, 0x13c02100, 0x3000fe, 0x0 },
- { 0xffe020c0, 0xad400080, 0x3f, 0x0 },
- { 0xffe03880, 0x9f603880, 0x1f0100, 0x0 },
- { 0xff000016, 0xde000002, 0xe020e8, 0x0 },
- { 0xfc003d08, 0x28003d00, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x28003000, 0x3f00000, 0x1 },
- { 0xffe03080, 0x9c401000, 0xf60, 0x0 },
- { 0xf7c02000, 0x21402000, 0x3000fe, 0x0 },
- { 0xff201800, 0x5c200800, 0xdf20fe, 0x0 },
- { 0xffe01804, 0x40a01000, 0x20f8, 0x0 },
- { 0xfc003f00, 0x68003300, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x68003200, 0x3f00000, 0x1 },
- { 0xf7c03000, 0x15401000, 0x3000fe, 0x0 },
- { 0xffe01804, 0x44a00800, 0x20f8, 0x0 },
- { 0xf7c02000, 0x26000000, 0x3000fe, 0x0 },
- { 0xffc00000, 0xda400000, 0x203fe0, 0x0 },
- { 0xffe00004, 0x40600000, 0x20f8, 0x0 },
- { 0xffe02080, 0xab600080, 0x3f, 0x0 },
- { 0xf8003f00, 0x20003600, 0x7f00000, 0x1 },
- { 0xf7c02300, 0x11c00300, 0x3000fe, 0x0 },
- { 0xf8003f00, 0x20003700, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x25c00000, 0x3000fe, 0x0 },
- { 0xf7c02300, 0x11800300, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9f802880, 0x1f0100, 0x0 },
- { 0xfc003800, 0x48003000, 0x3f00000, 0x1 },
- { 0xf8003c00, 0x20002c00, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x10400000, 0x3000fe, 0x0 },
- { 0xff602060, 0x3f400060, 0x1f80, 0x0 },
- { 0xffe03080, 0x9c801000, 0xf60, 0x0 },
- { 0xff602060, 0x3e400040, 0x1f80, 0x0 },
- { 0xf7c03000, 0x14402000, 0x3000fe, 0x0 },
- { 0xffe0001c, 0x75800010, 0x3fe0, 0x0 },
- { 0xff000016, 0xde000014, 0xe020e8, 0x0 },
- { 0xf7c02300, 0x11c02000, 0x3000fe, 0x0 },
- { 0xff600018, 0xdd200008, 0x1fe0, 0x0 },
- { 0xff602060, 0x3e200060, 0x1f80, 0x0 },
- { 0xff000016, 0xde000006, 0xe020e8, 0x0 },
- { 0xffe00004, 0x44600000, 0x20f8, 0x0 },
- { 0xf8003e00, 0x60002800, 0x7f00000, 0x1 },
- { 0xfe600000, 0x3c000000, 0x207f, 0x0 },
- { 0xffe03884, 0xafa02884, 0x30078, 0x0 },
- { 0xf7c02300, 0x11802300, 0x3000fe, 0x0 },
- { 0xffe00000, 0x38000000, 0x201f, 0x0 },
- { 0xff200800, 0x5c000000, 0xdf20fe, 0x0 },
- { 0xf7c02000, 0x13400000, 0x3000fe, 0x0 },
- { 0xff200800, 0x5c200000, 0xdf20fe, 0x0 },
- { 0xffe02000, 0x41000000, 0x7e0, 0x0 },
- { 0xffe03880, 0x9fc02880, 0x1f0100, 0x0 },
- { 0xffe00004, 0x46000000, 0x20f8, 0x0 },
- { 0xff602060, 0x3f000020, 0x1f80, 0x0 },
- { 0xfc003d08, 0x28003d08, 0x3f00000, 0x1 },
- { 0xff602060, 0x3f200060, 0x1f80, 0x0 },
- { 0xffe038c0, 0xada028c0, 0x3f, 0x0 },
- { 0xffe038c0, 0xada008c0, 0x3f, 0x0 },
- { 0xf8003f00, 0x20003500, 0x7f00000, 0x1 },
- { 0xfc003fc4, 0x48003f40, 0x3f00000, 0x1 },
- { 0xf9e01800, 0x48a00000, 0x61f20ff, 0x0 },
- { 0xf7c03000, 0x14802000, 0x3000fe, 0x0 },
- { 0xfc003f00, 0x28003900, 0x3f00000, 0x1 },
- { 0xf8003fc7, 0x40003fc7, 0x7f00000, 0x1 },
- { 0xffe02000, 0x45400000, 0x7e0, 0x0 },
- { 0xffe038c0, 0xada02880, 0x3f, 0x0 },
- { 0xffe02084, 0xaf002080, 0x30078, 0x0 },
- { 0xffe03880, 0x9f803880, 0x1f0100, 0x0 },
- { 0xf7c03000, 0x15000000, 0x3000fe, 0x0 },
- { 0xfc003f00, 0x28003700, 0x3f00000, 0x1 },
- { 0xfc003f00, 0x28003600, 0x3f00000, 0x1 },
- { 0xffe02000, 0x47200000, 0x7e0, 0x0 },
- { 0xffe03880, 0xaba00080, 0x3f, 0x0 },
- { 0xffe02084, 0xafc00080, 0x30078, 0x0 },
- { 0xff802000, 0x73800000, 0x1fe0, 0x0 },
- { 0xffe03880, 0x9f202880, 0x1f0100, 0x0 },
- { 0xf8003d18, 0x20003c00, 0x7f00000, 0x1 },
- { 0xf9e00000, 0xa1600000, 0x60020ff, 0x0 },
- { 0xffe00004, 0x44800000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x21802000, 0x3000fe, 0x0 },
- { 0xff000000, 0xd8000000, 0x6020e0, 0x0 },
- { 0xf9e00000, 0xa1000000, 0x60020ff, 0x0 },
- { 0xffe03884, 0xafa00084, 0x30078, 0x0 },
- { 0xff201800, 0x5c201800, 0xdf20fe, 0x0 },
- { 0xff000016, 0xde000010, 0xe020e8, 0x0 },
- { 0xffe03880, 0x9f603080, 0x1f0100, 0x0 },
- { 0xffe02000, 0x41c00000, 0x7e0, 0x0 },
- { 0xf7c02000, 0x20402000, 0x3000fe, 0x0 },
- { 0xff800000, 0xe1000000, 0x1fe0, 0x0 },
- { 0xf9e00000, 0xa1400000, 0x60020ff, 0x0 },
- { 0xf7c03000, 0x14c00000, 0x3000fe, 0x0 },
- { 0xf8003fc7, 0x40003f47, 0x7f00000, 0x1 },
- { 0xffe00004, 0x40800000, 0x20f8, 0x0 },
- { 0xff800000, 0xe1800000, 0x1fe0, 0x0 },
- { 0xf7c02300, 0x11802100, 0x3000fe, 0x0 },
- { 0xf9e00000, 0x49800000, 0x61f3fe0, 0x0 },
- { 0xf7c02000, 0x26400000, 0x3000fe, 0x0 },
- { 0xf8003c00, 0x20002800, 0x7f00000, 0x1 },
- { 0xff902000, 0x7e002000, 0xf1fe0, 0x0 },
- { 0xff902000, 0x7e802000, 0xf1fe0, 0x0 },
- { 0xf9e00000, 0x91c00000, 0x6003fe0, 0x0 },
- { 0xffe03884, 0xafa02880, 0x30078, 0x0 },
- { 0xf7c02000, 0x22000000, 0x3000fe, 0x0 },
- { 0xffe03080, 0x9d203000, 0xf60, 0x0 },
- { 0xf7c02000, 0x26002000, 0x3000fe, 0x0 },
- { 0xff800000, 0xe2000000, 0x1fe0, 0x0 },
- { 0xf7c02000, 0x26c00000, 0x3000fe, 0x0 },
- { 0xff602060, 0x3e400000, 0x1f80, 0x0 },
- { 0xffe00000, 0x38400000, 0x201f, 0x0 },
- { 0xfc003800, 0x48002000, 0x3f00000, 0x1 },
- { 0xff000016, 0xde000000, 0xe020e8, 0x0 },
- { 0xf8003f00, 0x20003000, 0x7f00000, 0x1 },
- { 0xf8003e70, 0x20003a60, 0x7f00000, 0x1 },
- { 0xff902000, 0x7e800000, 0xf1fe0, 0x0 },
- { 0xffe020c0, 0xad6020c0, 0x3f, 0x0 },
- { 0xf7c02300, 0x13802000, 0x3000fe, 0x0 },
- { 0xffe020c0, 0xad600080, 0x3f, 0x0 },
- { 0xff902000, 0x7e000000, 0xf1fe0, 0x0 },
- { 0xf7000000, 0x17000000, 0x3000fe, 0x0 },
- { 0xf7000000, 0x16000000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x25002000, 0x3000fe, 0x0 },
- { 0xfc003fc7, 0x48003fc7, 0x3f00000, 0x1 },
- { 0xffc01000, 0x61801000, 0x202ffe, 0x0 },
- { 0xffe03884, 0xafa03080, 0x30078, 0x0 },
- { 0xf8003fc4, 0x40003f40, 0x7f00000, 0x1 },
- { 0xfc003e70, 0x28003a60, 0x3f00000, 0x1 },
- { 0xf7c02300, 0x13800000, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9f802080, 0x1f0100, 0x0 },
- { 0xf0000000, 0xb0000000, 0xfe03fe0, 0x0 },
- { 0xffe03880, 0x9f402080, 0x1f0100, 0x0 },
- { 0xffe02000, 0x43200000, 0x7e0, 0x0 },
- { 0xffe00000, 0x39800000, 0x201f, 0x0 },
- { 0xffe03880, 0x9fc03880, 0x1f0100, 0x0 },
- { 0xffe02000, 0x45600000, 0x7e0, 0x0 },
- { 0xf9e00000, 0x91200000, 0x6003fe0, 0x0 },
- { 0xffe02000, 0x43600000, 0x7e0, 0x0 },
- { 0xfc003f00, 0x28003800, 0x3f00000, 0x1 },
- { 0xff802000, 0x74000000, 0x1fe0, 0x0 },
- { 0xffe02084, 0xaf002084, 0x30078, 0x0 },
- { 0xff802000, 0x74800000, 0x1fe0, 0x0 },
- { 0xf7c03000, 0x14c02000, 0x3000fe, 0x0 },
- { 0xfe000001, 0x5a000000, 0x1ff3ffe, 0x0 },
- { 0xff602060, 0x3f400020, 0x1f80, 0x0 },
- { 0xf7c02000, 0x10802000, 0x3000fe, 0x0 },
- { 0xffe02084, 0xaf802080, 0x30078, 0x0 },
- { 0xffe00004, 0x46400000, 0x20f8, 0x0 },
- { 0xffe020c0, 0xad800080, 0x3f, 0x0 },
- { 0xffe020c0, 0xad8000c0, 0x3f, 0x0 },
- { 0xf8003fc7, 0x40003f45, 0x7f00000, 0x1 },
- { 0xf8003e00, 0x60002a00, 0x7f00000, 0x1 },
- { 0xffe02084, 0xaf600084, 0x30078, 0x0 },
- { 0xffe03080, 0x9c201000, 0xf60, 0x0 },
- { 0xffe02000, 0x43400000, 0x7e0, 0x0 },
- { 0xffe03080, 0x9c203080, 0xf60, 0x0 },
- { 0xffe02000, 0x41200000, 0x7e0, 0x0 },
- { 0xffe03080, 0x9c201080, 0xf60, 0x0 },
- { 0xf7c02300, 0x11c02300, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9fc03080, 0x1f0100, 0x0 },
- { 0xffe03880, 0x9f402880, 0x1f0100, 0x0 },
- { 0xf8003800, 0x40002000, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x24402000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x20c02000, 0x3000fe, 0x0 },
- { 0xf7c02300, 0x11c00000, 0x3000fe, 0x0 },
- { 0xffe02000, 0x45200000, 0x7e0, 0x0 },
- { 0xf8003f00, 0x20003900, 0x7f00000, 0x1 },
- { 0xf7c02300, 0x11c00100, 0x3000fe, 0x0 },
- { 0xffe02084, 0xaf800084, 0x30078, 0x0 },
- { 0xfe600000, 0x3c200000, 0x207f, 0x0 },
- { 0xf7c02000, 0x26800000, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9f003080, 0x1f0100, 0x0 },
- { 0xffe03884, 0xafa01084, 0x30078, 0x0 },
- { 0xffc00000, 0x76000000, 0x203fe0, 0x0 },
- { 0xff602060, 0x3e000040, 0x1f80, 0x0 },
- { 0xffe020c0, 0xadc020c0, 0x3f, 0x0 },
- { 0xffe00004, 0x44400000, 0x20f8, 0x0 },
- { 0xffe020c0, 0xadc02080, 0x3f, 0x0 },
- { 0xfe600000, 0x3c400000, 0x207f, 0x0 },
- { 0xf7c02000, 0x20400000, 0x3000fe, 0x0 },
- { 0xff800000, 0x7c000000, 0x1fe0, 0x0 },
- { 0xffe03884, 0xafa00080, 0x30078, 0x0 },
- { 0xff201800, 0x5c001800, 0xdf20fe, 0x0 },
- { 0xffe02000, 0x47800000, 0x7e0, 0x0 },
- { 0xff601018, 0xdd400000, 0xfe0, 0x0 },
- { 0xffe020c0, 0xad4020c0, 0x3f, 0x0 },
- { 0xffe020c0, 0xad402080, 0x3f, 0x0 },
- { 0xf8003000, 0x40001000, 0x7f00000, 0x1 },
- { 0xffe02084, 0xafc02084, 0x30078, 0x0 },
- { 0xffe03080, 0x9c403080, 0xf60, 0x0 },
- { 0xfc003e40, 0x28003a00, 0x3f00000, 0x1 },
- { 0xffe038c0, 0xada010c0, 0x3f, 0x0 },
- { 0xffe038c0, 0xada01080, 0x3f, 0x0 },
- { 0xffe038c0, 0xada030c0, 0x3f, 0x0 },
- { 0xffe038c0, 0xada03080, 0x3f, 0x0 },
- { 0xf7c02000, 0x20800000, 0x3000fe, 0x0 },
- { 0xfc003fc7, 0x48003f46, 0x3f00000, 0x1 },
- { 0xffe01804, 0x44a00000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x20002000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x12c02000, 0x3000fe, 0x0 },
- { 0xffe03000, 0x9a601000, 0xf60, 0x0 },
- { 0xffc00000, 0xda800000, 0x203fe0, 0x0 },
- { 0xf9e00000, 0x90400000, 0x6003fe0, 0x0 },
- { 0xffe02000, 0x47600000, 0x7e0, 0x0 },
- { 0xffe03080, 0x9d403000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d403080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d401000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d401080, 0xf60, 0x0 },
- { 0xffe02000, 0x41400000, 0x7e0, 0x0 },
- { 0xff800000, 0xdf800000, 0x6020e0, 0x0 },
- { 0xffc01000, 0x61000000, 0x202ffe, 0x0 },
- { 0xffe03880, 0x9f202080, 0x1f0100, 0x0 },
- { 0xfc003fc7, 0x48003fc6, 0x3f00000, 0x1 },
- { 0xfe000000, 0x7a000000, 0x1fe0, 0x0 },
- { 0xffff0000, 0x6a490000, 0x1f80, 0x0 },
- { 0xff802000, 0x73000000, 0x1fe0, 0x0 },
- { 0xff602060, 0x3e200020, 0x1f80, 0x0 },
- { 0xf7c02000, 0x24000000, 0x3000fe, 0x0 },
- { 0xf8003e40, 0x20003a00, 0x7f00000, 0x1 },
- { 0xf7c03000, 0x14401000, 0x3000fe, 0x0 },
- { 0xf8003f00, 0x20003200, 0x7f00000, 0x1 },
- { 0xffc00000, 0x76400000, 0x203fe0, 0x0 },
- { 0xf7c02000, 0x22002000, 0x3000fe, 0x0 },
- { 0xffc01000, 0x61c01000, 0x202ffe, 0x0 },
- { 0xf7c03000, 0x14801000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x12002000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x10402000, 0x3000fe, 0x0 },
- { 0xff201800, 0x5d200000, 0xdf20fe, 0x0 },
- { 0xf7c02000, 0x21400000, 0x3000fe, 0x0 },
- { 0xff201800, 0x5d000000, 0xdf20fe, 0x0 },
- { 0xffe02000, 0x45c00000, 0x7e0, 0x0 },
- { 0xf7c02000, 0x25802000, 0x3000fe, 0x0 },
- { 0xfc003e70, 0x28003a50, 0x3f00000, 0x1 },
- { 0xf7c02300, 0x13c00300, 0x3000fe, 0x0 },
- { 0xf9e01800, 0xa1a00800, 0x60020ff, 0x0 },
- { 0xffe02000, 0x43800000, 0x7e0, 0x0 },
- { 0xfc003fc4, 0x48003fc0, 0x3f00000, 0x1 },
- { 0xff800000, 0xe2800000, 0x1fe0, 0x0 },
- { 0xf7c02300, 0x13c02000, 0x3000fe, 0x0 },
- { 0xffe03080, 0x9d803080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d803000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d801080, 0xf60, 0x0 },
- { 0xf8003fc4, 0x40003f00, 0x7f00000, 0x1 },
- { 0xffe00000, 0x39c00000, 0x201f, 0x0 },
- { 0xffe03080, 0x9d203080, 0xf60, 0x0 },
- { 0xffe02080, 0xab000080, 0x3f, 0x0 },
- { 0xf8003e00, 0x60003c00, 0x7f00000, 0x1 },
- { 0xffe03880, 0x9f602080, 0x1f0100, 0x0 },
- { 0xffc00000, 0x76800000, 0x203fe0, 0x0 },
- { 0xffe03884, 0xafa02084, 0x30078, 0x0 },
- { 0xf7c02000, 0x13002000, 0x3000fe, 0x0 },
- { 0xf9e00000, 0x91000000, 0x6003fe0, 0x0 },
- { 0xffe03080, 0x9d201080, 0xf60, 0x0 },
- { 0xf7c03000, 0x15002000, 0x3000fe, 0x0 },
- { 0xf8003000, 0x60000000, 0x7f00000, 0x1 },
- { 0xffc01000, 0x61800000, 0x202ffe, 0x0 },
- { 0xf7c03000, 0x14400000, 0x3000fe, 0x0 },
- { 0xffe03000, 0x9b401000, 0xf60, 0x0 },
- { 0xf7c03000, 0x14003000, 0x3000fe, 0x0 },
- { 0xffe03880, 0x9fc02080, 0x1f0100, 0x0 },
- { 0xfc003fc4, 0x48003f00, 0x3f00000, 0x1 },
- { 0xffe02000, 0x45000000, 0x7e0, 0x0 },
- { 0xfc003800, 0x48002800, 0x3f00000, 0x1 },
- { 0xfc003fc7, 0x48003fc5, 0x3f00000, 0x1 },
- { 0xfc003d18, 0x28003c00, 0x3f00000, 0x1 },
- { 0xfc003fc7, 0x48003fc4, 0x3f00000, 0x1 },
- { 0xf8003f00, 0x60003200, 0x7f00000, 0x1 },
- { 0xffe02084, 0xaf600080, 0x30078, 0x0 },
- { 0xf9e01800, 0xa1a00000, 0x60020ff, 0x0 },
- { 0xf7c03000, 0x14001000, 0x3000fe, 0x0 },
- { 0xf7c03000, 0x14c01000, 0x3000fe, 0x0 },
- { 0xffe00004, 0x46c00000, 0x20f8, 0x0 },
- { 0xf7c03000, 0x15003000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x10000000, 0x3000fe, 0x0 },
- { 0xf8003d18, 0x20003c08, 0x7f00000, 0x1 },
- { 0xffc0001c, 0x75400010, 0x203fe0, 0x0 },
- { 0xf9e00000, 0x48600000, 0x61f20ff, 0x0 },
- { 0xffe03080, 0x9c603080, 0xf60, 0x0 },
- { 0xfe000000, 0x58000000, 0x1ff3ffe, 0x0 },
- { 0xffe03000, 0x9a201000, 0xf60, 0x0 },
- { 0xffe00000, 0x69e00000, 0x1f18, 0x0 },
- { 0xffe020c0, 0xad802080, 0x3f, 0x0 },
- { 0xffe02000, 0x47c00000, 0x7e0, 0x0 },
- { 0xffe00000, 0x60e00000, 0x1f18, 0x0 },
- { 0xf7c03000, 0x15402000, 0x3000fe, 0x0 },
- { 0xffe020c0, 0xad8020c0, 0x3f, 0x0 },
- { 0xff000016, 0xde000012, 0xe020e8, 0x0 },
- { 0xf7c02000, 0x25c02000, 0x3000fe, 0x0 },
- { 0xf8003f00, 0x60003100, 0x7f00000, 0x1 },
- { 0xf8003f00, 0x60003000, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x25800000, 0x3000fe, 0x0 },
- { 0xf7c03000, 0x14403000, 0x3000fe, 0x0 },
- { 0xfc003d18, 0x28003c08, 0x3f00000, 0x1 },
- { 0xffe03880, 0x9f403080, 0x1f0100, 0x0 },
- { 0xf7c02000, 0x25402000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x10c00000, 0x3000fe, 0x0 },
- { 0xffe02000, 0x45800000, 0x7e0, 0x0 },
- { 0xffe03880, 0x9f803080, 0x1f0100, 0x0 },
- { 0xffe03080, 0x9d001000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d001080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d003000, 0xf60, 0x0 },
- { 0xffe03080, 0x9d003080, 0xf60, 0x0 },
- { 0xffe03080, 0x9d801000, 0xf60, 0x0 },
- { 0xf9e00000, 0x49200000, 0x61f3fe0, 0x0 },
- { 0xf9e00000, 0xa1c00000, 0x60020ff, 0x0 },
- { 0xf9e00000, 0x90200000, 0x6003fe0, 0x0 },
- { 0xffe03080, 0x9d201000, 0xf60, 0x0 },
- { 0xffe03884, 0xafa01080, 0x30078, 0x0 },
- { 0xffe02084, 0xaf602080, 0x30078, 0x0 },
- { 0xffe038c0, 0xada000c0, 0x3f, 0x0 },
- { 0xffe02080, 0xab400080, 0x3f, 0x0 },
- { 0xff000016, 0xde000004, 0xe020e8, 0x0 },
- { 0xffe00004, 0x44000000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x20000000, 0x3000fe, 0x0 },
- { 0xfc003d18, 0x28003c10, 0x3f00000, 0x1 },
- { 0xff600018, 0xdd000008, 0x1fe0, 0x0 },
- { 0xffe020c0, 0xadc000c0, 0x3f, 0x0 },
- { 0xffe020c0, 0xadc00080, 0x3f, 0x0 },
- { 0xffe03000, 0x9b801000, 0xf60, 0x0 },
- { 0xf8003fc7, 0x40003f46, 0x7f00000, 0x1 },
- { 0xf7c02000, 0x21c02000, 0x3000fe, 0x0 },
- { 0xffe01804, 0x40a00000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x26402000, 0x3000fe, 0x0 },
- { 0xffe03080, 0x9c401080, 0xf60, 0x0 },
- { 0xffe00000, 0x39200000, 0x201f, 0x0 },
- { 0xffe03080, 0x9c403000, 0xf60, 0x0 },
- { 0xf7c02000, 0x11002000, 0x3000fe, 0x0 },
- { 0xfc003c00, 0x28002800, 0x3f00000, 0x1 },
- { 0xffe00004, 0x40400000, 0x20f8, 0x0 },
- { 0xf7c02000, 0x26802000, 0x3000fe, 0x0 },
- { 0xf7c02000, 0x13000000, 0x3000fe, 0x0 },
- { 0xffe00004, 0x42600000, 0x20f8, 0x0 },
- { 0xf8003000, 0x60001000, 0x7f00000, 0x1 },
- { 0xff602060, 0x3e400020, 0x1f80, 0x0 },
- { 0xff602060, 0x3f000000, 0x1f80, 0x0 },
- { 0xf7c02000, 0x24c02000, 0x3000fe, 0x0 },
- { 0xff802000, 0x74002000, 0x1fe0, 0x0 },
- { 0xf8003800, 0x20002000, 0x7f00000, 0x1 },
- { 0xffe03000, 0x9aa01000, 0xf60, 0x0 },
- { 0xf7c02000, 0x12400000, 0x3000fe, 0x0 },
- { 0xff602060, 0x3f000060, 0x1f80, 0x0 },
- { 0xf7c02000, 0x11000000, 0x3000fe, 0x0 },
-};
-
-/// \brief finds the scatter Bits that need to be used to apply relocations
-inline uint32_t findv4bitmask(uint8_t *location) {
- uint32_t insn = llvm::support::endian::read32le(location);
- for (int32_t i = 0, e = llvm::array_lengthof(insn_encodings); i < e; i++) {
- if ((insn & 0xc000) == 0 && !insn_encodings[i].isDuplex)
- continue;
- if ((insn & 0xc000) != 0 && insn_encodings[i].isDuplex)
- continue;
- if ((insn_encodings[i].insnMask & insn) == insn_encodings[i].insnCmpMask)
- return insn_encodings[i].insnBitMask;
- }
- llvm_unreachable("found unknown Hexagon instruction");
-}
-
-} // namespace elf
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h (removed)
@@ -1,73 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef HEXAGON_EXECUTABLE_WRITER_H
-#define HEXAGON_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "HexagonLinkingContext.h"
-#include "HexagonTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class HexagonTargetLayout;
-
-class HexagonExecutableWriter : public ExecutableWriter<ELF32LE> {
-public:
- HexagonExecutableWriter(HexagonLinkingContext &ctx,
- HexagonTargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
-
- std::error_code setELFHeader() override {
- ExecutableWriter::setELFHeader();
- setHexagonELFHeader(*_elfHeader);
- return std::error_code();
- }
-
-private:
- HexagonLinkingContext &_ctx;
- HexagonTargetLayout &_targetLayout;
-};
-
-HexagonExecutableWriter::HexagonExecutableWriter(HexagonLinkingContext &ctx,
- HexagonTargetLayout &layout)
- : ExecutableWriter(ctx, layout), _ctx(ctx), _targetLayout(layout) {}
-
-void HexagonExecutableWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter::createImplicitFiles(result);
- // Add the default atoms as defined for hexagon
- auto file =
- llvm::make_unique<RuntimeFile<ELF32LE>>(_ctx, "Hexagon runtime file");
- file->addAbsoluteAtom("_SDA_BASE_");
- if (_ctx.isDynamic()) {
- file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- file->addAbsoluteAtom("_DYNAMIC");
- }
- result.push_back(std::move(file));
-}
-
-void HexagonExecutableWriter::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- ExecutableWriter::finalizeDefaultAtomValues();
- AtomLayout *sdabaseAtom = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
- sdabaseAtom->_virtualAddr = _targetLayout.getSDataSection()->virtualAddr();
- if (_ctx.isDynamic())
- finalizeHexagonRuntimeAtomValues(_targetLayout);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif // HEXAGON_EXECUTABLE_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (removed)
@@ -1,47 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp -------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonLinkingContext.h"
-#include "HexagonTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-std::unique_ptr<ELFLinkingContext>
-createHexagonLinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::hexagon)
- return llvm::make_unique<HexagonLinkingContext>(triple);
- return nullptr;
-}
-
-HexagonLinkingContext::HexagonLinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, std::unique_ptr<TargetHandler>(
- new HexagonTargetHandler(*this))) {}
-
-static const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/Hexagon.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_END
-};
-
-void HexagonLinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF,
- Reference::KindArch::Hexagon, kindStrings);
-}
-
-void setHexagonELFHeader(ELFHeader<ELF32LE> &elfHeader) {
- elfHeader.e_ident(llvm::ELF::EI_VERSION, 1);
- elfHeader.e_ident(llvm::ELF::EI_OSABI, 0);
- elfHeader.e_version(1);
- elfHeader.e_flags(0x3);
-}
-
-} // namespace elf
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (removed)
@@ -1,61 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
-
-#include "OutputELFWriter.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-class HexagonLinkingContext final : public ELFLinkingContext {
-public:
- int getMachineType() const override { return llvm::ELF::EM_HEXAGON; }
- HexagonLinkingContext(llvm::Triple triple);
-
- void addPasses(PassManager &) override;
- void registerRelocationNames(Registry &r) override;
-
- bool isDynamicRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- switch (r.kindValue()) {
- case llvm::ELF::R_HEX_RELATIVE:
- case llvm::ELF::R_HEX_GLOB_DAT:
- return true;
- default:
- return false;
- }
- }
-
- bool isPLTRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- return r.kindValue() == llvm::ELF::R_HEX_JMP_SLOT;
- }
-
- /// \brief Hexagon has only one relative relocation
- /// a) for supporting relative relocs - R_HEX_RELATIVE
- bool isRelativeReloc(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- return r.kindValue() == llvm::ELF::R_HEX_RELATIVE;
- }
-};
-
-void setHexagonELFHeader(ELFHeader<ELF32LE> &elfHeader);
-
-} // elf
-} // lld
-
-#endif // LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (removed)
@@ -1,330 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp ---------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonEncodings.h"
-#include "HexagonLinkingContext.h"
-#include "HexagonRelocationHandler.h"
-#include "HexagonTargetHandler.h"
-#include "llvm/Support/Endian.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-using namespace llvm::support::endian;
-
-// Scatter val's bits as specified by the mask. Example:
-//
-// Val: 0bABCDEFG
-// Mask: 0b10111100001011
-// Output: 0b00ABCD0000E0FG
-static uint32_t scatterBits(uint32_t val, uint32_t mask) {
- uint32_t result = 0;
- size_t off = 0;
- for (size_t bit = 0; bit < 32; ++bit) {
- if ((mask >> bit) & 1) {
- uint32_t valBit = (val >> off) & 1;
- result |= valBit << bit;
- ++off;
- }
- }
- return result;
-}
-
-static void relocBNPCREL(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- int32_t nBits) {
- int32_t result = (S + A - P) >> 2;
- int32_t range = 1 << nBits;
- if (result < range && result > -range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-/// \brief Word32_LO: 0x00c03fff : (S + A) : Truncate
-static void relocLO16(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_LO: 0x00c03fff : (S + A) >> 16 : Truncate
-static void relocHI16(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = (S + A) >> 16;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32: 0xffffffff : (S + A) : Truncate
-static void reloc32(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- write32le(loc, result | read32le(loc));
-}
-
-static void reloc32_6_X(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- int64_t result = (S + A) >> 6;
- int64_t range = int64_t(1) << 32;
- if (result > range)
- result = scatterBits(result, 0xfff3fff);
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_B32_PCREL_X
-static void relocHexB32PCRELX(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A) {
- int64_t result = (S + A - P) >> 6;
- result = scatterBits(result, 0xfff3fff);
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_BN_PCREL_X
-static void relocHexBNPCRELX(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- int nbits) {
- int32_t result = (S + A - P) & 0x3f;
- int32_t range = 1 << nbits;
- if (result < range && result > -range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-// R_HEX_6_PCREL_X
-static void relocHex6PCRELX(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- int32_t result = S + A - P;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-// R_HEX_N_X : Word32_U6 : (S + A) : Unsigned Truncate
-static void relocHex_N_X(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = S + A;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-// GP REL relocs
-static void relocHexGPRELN(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- uint64_t GP, int nShiftBits) {
- int32_t result = (S + A - GP) >> nShiftBits;
- int32_t range = 1L << 16;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-/// \brief Word32_LO: 0x00c03fff : (G) : Truncate
-static void relocHexGOTLO16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = A - GOT;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_LO: 0x00c03fff : (G) >> 16 : Truncate
-static void relocHexGOTHI16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = (A - GOT) >> 16;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32: 0xffffffff : (G) : Truncate
-static void relocHexGOT32(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = GOT - A;
- write32le(loc, result | read32le(loc));
-}
-
-/// \brief Word32_U16 : (G) : Truncate
-static void relocHexGOT16(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = GOT - A;
- int32_t range = 1L << 16;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-static void relocHexGOT32_6_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = (A - GOT) >> 6;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOT16_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- int32_t result = A - GOT;
- int32_t range = 1L << 6;
- if (result <= range) {
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
- }
-}
-
-static void relocHexGOT11_X(uint8_t *loc, uint64_t A, uint64_t GOT) {
- uint32_t result = A - GOT;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTRELSigned(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT, int shiftBits) {
- int32_t result = (S + A - GOT) >> shiftBits;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTRELUnsigned(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT) {
- uint32_t result = S + A - GOT;
- result = scatterBits(result, findv4bitmask(loc));
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTREL_HILO16(uint8_t *loc, uint64_t P, uint64_t S,
- uint64_t A, uint64_t GOT, int shiftBits) {
- int32_t result = (S + A - GOT) >> shiftBits;
- result = scatterBits(result, 0x00c03fff);
- write32le(loc, result | read32le(loc));
-}
-
-static void relocHexGOTREL_32(uint8_t *loc, uint64_t P, uint64_t S, uint64_t A,
- uint64_t GOT) {
- int32_t result = S + A - GOT;
- write32le(loc, result | read32le(loc));
-}
-
-std::error_code HexagonTargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::Hexagon);
- switch (ref.kindValue()) {
- case R_HEX_B22_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 21);
- break;
- case R_HEX_B15_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 14);
- break;
- case R_HEX_B9_PCREL:
- relocBNPCREL(loc, reloc, target, ref.addend(), 8);
- break;
- case R_HEX_LO16:
- relocLO16(loc, reloc, target, ref.addend());
- break;
- case R_HEX_HI16:
- relocHI16(loc, reloc, target, ref.addend());
- break;
- case R_HEX_32:
- reloc32(loc, reloc, target, ref.addend());
- break;
- case R_HEX_32_6_X:
- reloc32_6_X(loc, reloc, target, ref.addend());
- break;
- case R_HEX_B32_PCREL_X:
- relocHexB32PCRELX(loc, reloc, target, ref.addend());
- break;
- case R_HEX_B22_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 21);
- break;
- case R_HEX_B15_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 14);
- break;
- case R_HEX_B13_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 12);
- break;
- case R_HEX_B9_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 8);
- break;
- case R_HEX_B7_PCREL_X:
- relocHexBNPCRELX(loc, reloc, target, ref.addend(), 6);
- break;
- case R_HEX_GPREL16_0:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 0);
- break;
- case R_HEX_GPREL16_1:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 1);
- break;
- case R_HEX_GPREL16_2:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 2);
- break;
- case R_HEX_GPREL16_3:
- relocHexGPRELN(loc, reloc, target, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 3);
- break;
- case R_HEX_16_X:
- case R_HEX_12_X:
- case R_HEX_11_X:
- case R_HEX_10_X:
- case R_HEX_9_X:
- case R_HEX_8_X:
- case R_HEX_7_X:
- case R_HEX_6_X:
- relocHex_N_X(loc, reloc, target, ref.addend());
- break;
- case R_HEX_6_PCREL_X:
- relocHex6PCRELX(loc, reloc, target, ref.addend());
- break;
- case R_HEX_JMP_SLOT:
- case R_HEX_GLOB_DAT:
- break;
- case R_HEX_GOTREL_32:
- relocHexGOTREL_32(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOTREL_LO16:
- relocHexGOTREL_HILO16(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 0);
- break;
- case R_HEX_GOTREL_HI16:
- relocHexGOTREL_HILO16(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 16);
- break;
- case R_HEX_GOT_LO16:
- relocHexGOTLO16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_HI16:
- relocHexGOTHI16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_32:
- relocHexGOT32(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_16:
- relocHexGOT16(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_32_6_X:
- relocHexGOT32_6_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_16_X:
- relocHexGOT16_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOT_11_X:
- relocHexGOT11_X(loc, target, _targetLayout.getGOTSymAddr());
- break;
- case R_HEX_GOTREL_32_6_X:
- relocHexGOTRELSigned(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr(), 6);
- break;
- case R_HEX_GOTREL_16_X:
- case R_HEX_GOTREL_11_X:
- relocHexGOTRELUnsigned(loc, reloc, target, ref.addend(),
- _targetLayout.getGOTSymAddr());
- break;
-
- default:
- return make_unhandled_reloc_error();
- }
-
- return std::error_code();
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h (removed)
@@ -1,33 +0,0 @@
-//===- lld/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h -----------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_HANDLER_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_HANDLER_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-class HexagonTargetHandler;
-class HexagonTargetLayout;
-
-class HexagonTargetRelocationHandler final : public TargetRelocationHandler {
-public:
- HexagonTargetRelocationHandler(HexagonTargetLayout &layout)
- : _targetLayout(layout) {}
-
- std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const AtomLayout &,
- const Reference &) const override;
-
-private:
- HexagonTargetLayout &_targetLayout;
-};
-} // elf
-} // lld
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (removed)
@@ -1,383 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonExecutableWriter.h"
-#include "HexagonDynamicLibraryWriter.h"
-#include "HexagonLinkingContext.h"
-#include "HexagonTargetHandler.h"
-
-using namespace llvm::ELF;
-
-using llvm::makeArrayRef;
-
-namespace lld {
-namespace elf {
-
-HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new HexagonTargetLayout(ctx)),
- _relocationHandler(new HexagonTargetRelocationHandler(*_targetLayout)) {}
-
-std::unique_ptr<Writer> HexagonTargetHandler::getWriter() {
- switch (_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<HexagonExecutableWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<HexagonDynamicLibraryWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
-
-using namespace llvm::ELF;
-
-// .got atom
-const uint8_t hexagonGotAtomContent[4] = { 0 };
-// .got.plt atom (entry 0)
-const uint8_t hexagonGotPlt0AtomContent[16] = { 0 };
-// .got.plt atom (all other entries)
-const uint8_t hexagonGotPltAtomContent[4] = { 0 };
-// .plt (entry 0)
-const uint8_t hexagonPlt0AtomContent[28] = {
- 0x00, 0x40, 0x00, 0x00, // { immext (#0)
- 0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0 at PCREL) } # address of GOT0
- 0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn from GOTa
- 0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
- 0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
- 0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
- 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
-};
-
-// .plt (other entries)
-const uint8_t hexagonPltAtomContent[16] = {
- 0x00, 0x40, 0x00, 0x00, // { immext (#0)
- 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn at PCREL) } # address of GOTn
- 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14) # contents of GOTn
- 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 # call it
-};
-
-class HexagonGOTAtom : public GOTAtom {
-public:
- HexagonGOTAtom(const File &f) : GOTAtom(f, ".got") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return makeArrayRef(hexagonGotAtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-class HexagonGOTPLTAtom : public GOTAtom {
-public:
- HexagonGOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return makeArrayRef(hexagonGotPltAtomContent);
- }
-
- Alignment alignment() const override { return 4; }
-};
-
-class HexagonGOTPLT0Atom : public GOTAtom {
-public:
- HexagonGOTPLT0Atom(const File &f) : GOTAtom(f, ".got.plt") {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return makeArrayRef(hexagonGotPlt0AtomContent);
- }
-
- Alignment alignment() const override { return 8; }
-};
-
-class HexagonPLT0Atom : public PLT0Atom {
-public:
- HexagonPLT0Atom(const File &f) : PLT0Atom(f) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return makeArrayRef(hexagonPlt0AtomContent);
- }
-};
-
-class HexagonPLTAtom : public PLTAtom {
-
-public:
- HexagonPLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return makeArrayRef(hexagonPltAtomContent);
- }
-};
-
-class ELFPassFile : public SimpleFile {
-public:
- ELFPassFile(const ELFLinkingContext &eti)
- : SimpleFile("ELFPassFile", kindELFObject) {
- setOrdinal(eti.getNextOrdinalAndIncrement());
- }
-
- llvm::BumpPtrAllocator _alloc;
-};
-
-/// \brief Create GOT and PLT entries for relocations. Handles standard GOT/PLT
-template <class Derived> class GOTPLTPass : public Pass {
- /// \brief Handle a specific reference.
- void handleReference(const DefinedAtom &atom, const Reference &ref) {
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return;
- assert(ref.kindArch() == Reference::KindArch::Hexagon);
- switch (ref.kindValue()) {
- case R_HEX_PLT_B22_PCREL:
- case R_HEX_B22_PCREL:
- static_cast<Derived *>(this)->handlePLT32(ref);
- break;
- case R_HEX_GOT_LO16:
- case R_HEX_GOT_HI16:
- case R_HEX_GOT_32_6_X:
- case R_HEX_GOT_16_X:
- case R_HEX_GOT_11_X:
- static_cast<Derived *>(this)->handleGOTREL(ref);
- break;
- }
- }
-
-protected:
- /// \brief Create a GOT entry containing 0.
- const GOTAtom *getNullGOT() {
- if (!_null) {
- _null = new (_file._alloc) HexagonGOTPLTAtom(_file);
-#ifndef NDEBUG
- _null->_name = "__got_null";
-#endif
- }
- return _null;
- }
-
-public:
- GOTPLTPass(const ELFLinkingContext &ctx) : _file(ctx) {}
-
- /// \brief Do the pass.
- ///
- /// The goal here is to first process each reference individually. Each call
- /// to handleReference may modify the reference itself and/or create new
- /// atoms which must be stored in one of the maps below.
- ///
- /// After all references are handled, the atoms created during that are all
- /// added to mf.
- std::error_code perform(SimpleFile &mf) override {
- // Process all references.
- for (const auto &atom : mf.defined())
- for (const auto &ref : *atom)
- handleReference(*atom, *ref);
-
- // Add all created atoms to the link.
- uint64_t ordinal = 0;
- if (_plt0) {
- _plt0->setOrdinal(ordinal++);
- mf.addAtom(*_plt0);
- }
- for (auto &plt : _pltVector) {
- plt->setOrdinal(ordinal++);
- mf.addAtom(*plt);
- }
- if (_null) {
- _null->setOrdinal(ordinal++);
- mf.addAtom(*_null);
- }
- if (_got0) {
- _got0->setOrdinal(ordinal++);
- mf.addAtom(*_got0);
- }
- for (auto &got : _gotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
-
- return std::error_code();
- }
-
-protected:
- /// \brief Owner of all the Atoms created by this pass.
- ELFPassFile _file;
-
- /// \brief Map Atoms to their GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
-
- /// \brief Map Atoms to their PLT entries.
- llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
-
- /// \brief the list of GOT/PLT atoms
- std::vector<GOTAtom *> _gotVector;
- std::vector<PLTAtom *> _pltVector;
-
- /// \brief GOT entry that is always 0. Used for undefined weaks.
- GOTAtom *_null = nullptr;
-
- /// \brief The got and plt entries for .PLT0. This is used to call into the
- /// dynamic linker for symbol resolution.
- /// @{
- PLT0Atom *_plt0 = nullptr;
- GOTAtom *_got0 = nullptr;
- /// @}
-};
-
-class DynamicGOTPLTPass final : public GOTPLTPass<DynamicGOTPLTPass> {
-public:
- DynamicGOTPLTPass(const HexagonLinkingContext &ctx) : GOTPLTPass(ctx) {
- _got0 = new (_file._alloc) HexagonGOTPLT0Atom(_file);
-#ifndef NDEBUG
- _got0->_name = "__got0";
-#endif
- }
-
- const PLT0Atom *getPLT0() {
- if (_plt0)
- return _plt0;
- _plt0 = new (_file._alloc) HexagonPLT0Atom(_file);
- _plt0->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, _got0, 0);
- _plt0->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, _got0, 4);
- DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[ PLT0/GOT0 ] "
- << "Adding plt0/got0 \n");
- return _plt0;
- }
-
- const PLTAtom *getPLTEntry(const Atom *a) {
- auto plt = _pltMap.find(a);
- if (plt != _pltMap.end())
- return plt->second;
- auto ga = new (_file._alloc) HexagonGOTPLTAtom(_file);
- ga->addReferenceELF_Hexagon(R_HEX_JMP_SLOT, 0, a, 0);
- auto pa = new (_file._alloc) HexagonPLTAtom(_file, ".plt");
- pa->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, ga, 0);
- pa->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, ga, 4);
-
- // Point the got entry to the PLT0 atom initially
- ga->addReferenceELF_Hexagon(R_HEX_32, 0, getPLT0(), 0);
-#ifndef NDEBUG
- ga->_name = "__got_";
- ga->_name += a->name();
- pa->_name = "__plt_";
- pa->_name += a->name();
- DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[" << a->name() << "] "
- << "Adding plt/got: " << pa->_name
- << "/" << ga->_name << "\n");
-#endif
- _gotMap[a] = ga;
- _pltMap[a] = pa;
- _gotVector.push_back(ga);
- _pltVector.push_back(pa);
- return pa;
- }
-
- const GOTAtom *getGOTEntry(const Atom *a) {
- auto got = _gotMap.find(a);
- if (got != _gotMap.end())
- return got->second;
- auto ga = new (_file._alloc) HexagonGOTAtom(_file);
- ga->addReferenceELF_Hexagon(R_HEX_GLOB_DAT, 0, a, 0);
-
-#ifndef NDEBUG
- ga->_name = "__got_";
- ga->_name += a->name();
- DEBUG_WITH_TYPE("GOT", llvm::dbgs() << "[" << a->name() << "] "
- << "Adding got: " << ga->_name << "\n");
-#endif
- _gotMap[a] = ga;
- _gotVector.push_back(ga);
- return ga;
- }
-
- std::error_code handleGOTREL(const Reference &ref) {
- // Turn this so that the target is set to the GOT entry
- const_cast<Reference &>(ref).setTarget(getGOTEntry(ref.target()));
- return std::error_code();
- }
-
- std::error_code handlePLT32(const Reference &ref) {
- // Turn this into a PC32 to the PLT entry.
- assert(ref.kindNamespace() == Reference::KindNamespace::ELF);
- assert(ref.kindArch() == Reference::KindArch::Hexagon);
- const_cast<Reference &>(ref).setKindValue(R_HEX_B22_PCREL);
- const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
- return std::error_code();
- }
-};
-
-void HexagonLinkingContext::addPasses(PassManager &pm) {
- if (isDynamic())
- pm.add(llvm::make_unique<DynamicGOTPLTPass>(*this));
- ELFLinkingContext::addPasses(pm);
-}
-
-void SDataSection::doPreFlight() {
- // sort the atoms on the alignments they have been set
- std::stable_sort(_atoms.begin(), _atoms.end(), [](const AtomLayout *A,
- const AtomLayout *B) {
- const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom);
- const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom);
- int64_t alignmentA = definedAtomA->alignment().value;
- int64_t alignmentB = definedAtomB->alignment().value;
- if (alignmentA == alignmentB) {
- if (definedAtomA->merge() == DefinedAtom::mergeAsTentative)
- return false;
- if (definedAtomB->merge() == DefinedAtom::mergeAsTentative)
- return true;
- }
- return alignmentA < alignmentB;
- });
-
- // Set the fileOffset, and the appropriate size of the section
- for (auto &ai : _atoms) {
- const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
- DefinedAtom::Alignment atomAlign = definedAtom->alignment();
- uint64_t fOffset = alignOffset(fileSize(), atomAlign);
- uint64_t mOffset = alignOffset(memSize(), atomAlign);
- ai->_fileOffset = fOffset;
- _fsize = fOffset + definedAtom->size();
- _msize = mOffset + definedAtom->size();
- }
-} // finalize
-
-SDataSection::SDataSection(const HexagonLinkingContext &ctx)
- : AtomSection(ctx, ".sdata", DefinedAtom::typeDataFast, 0,
- HexagonTargetLayout::ORDER_SDATA) {
- _type = SHT_PROGBITS;
- _flags = SHF_ALLOC | SHF_WRITE;
- _alignment = 4096;
-}
-
-const AtomLayout *SDataSection::appendAtom(const Atom *atom) {
- const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
- DefinedAtom::Alignment atomAlign = definedAtom->alignment();
- uint64_t alignment = atomAlign.value;
- _atoms.push_back(new (_alloc) AtomLayout(atom, 0, 0));
- // Set the section alignment to the largest alignment
- // std::max doesn't support uint64_t
- if (_alignment < alignment)
- _alignment = alignment;
- return _atoms.back();
-}
-
-void finalizeHexagonRuntimeAtomValues(HexagonTargetLayout &layout) {
- AtomLayout *gotAtom = layout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- OutputSection<ELF32LE> *gotpltSection = layout.findOutputSection(".got.plt");
- if (gotpltSection)
- gotAtom->_virtualAddr = gotpltSection->virtualAddr();
- else
- gotAtom->_virtualAddr = 0;
- AtomLayout *dynamicAtom = layout.findAbsoluteAtom("_DYNAMIC");
- OutputSection<ELF32LE> *dynamicSection = layout.findOutputSection(".dynamic");
- if (dynamicSection)
- dynamicAtom->_virtualAddr = dynamicSection->virtualAddr();
- else
- dynamicAtom->_virtualAddr = 0;
-}
-
-} // namespace elf
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (removed)
@@ -1,134 +0,0 @@
-//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXAGON_TARGET_HANDLER_H
-#define HEXAGON_TARGET_HANDLER_H
-
-#include "ELFReader.h"
-#include "HexagonELFFile.h"
-#include "HexagonRelocationHandler.h"
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-class HexagonLinkingContext;
-
-/// \brief Handle Hexagon SData section
-class SDataSection : public AtomSection<ELF32LE> {
-public:
- SDataSection(const HexagonLinkingContext &ctx);
-
- /// \brief Finalize the section contents before writing
- void doPreFlight() override;
-
- /// \brief Does this section have an output segment.
- bool hasOutputSegment() const override { return true; }
-
- const AtomLayout *appendAtom(const Atom *atom) override;
-};
-
-/// \brief TargetLayout for Hexagon
-class HexagonTargetLayout final : public TargetLayout<ELF32LE> {
-public:
- enum HexagonSectionOrder {
- ORDER_SDATA = 205
- };
-
- HexagonTargetLayout(HexagonLinkingContext &ctx)
- : TargetLayout(ctx), _sdataSection(ctx) {}
-
- /// \brief Return the section order for a input section
- TargetLayout::SectionOrder
- getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) override {
- if (contentType == DefinedAtom::typeDataFast ||
- contentType == DefinedAtom::typeZeroFillFast)
- return ORDER_SDATA;
- return TargetLayout::getSectionOrder(name, contentType, contentPermissions);
- }
-
- /// \brief Return the appropriate input section name.
- StringRef getInputSectionName(const DefinedAtom *da) const override {
- switch (da->contentType()) {
- case DefinedAtom::typeDataFast:
- case DefinedAtom::typeZeroFillFast:
- return ".sdata";
- default:
- break;
- }
- return TargetLayout::getInputSectionName(da);
- }
-
- /// \brief Gets or creates a section.
- AtomSection<ELF32LE> *
- createSection(StringRef name, int32_t contentType,
- DefinedAtom::ContentPermissions contentPermissions,
- TargetLayout::SectionOrder sectionOrder) override {
- if (contentType == DefinedAtom::typeDataFast ||
- contentType == DefinedAtom::typeZeroFillFast)
- return &_sdataSection;
- return TargetLayout::createSection(name, contentType, contentPermissions,
- sectionOrder);
- }
-
- /// \brief get the segment type for the section thats defined by the target
- TargetLayout::SegmentType
- getSegmentType(const Section<ELF32LE> *section) const override {
- if (section->order() == ORDER_SDATA)
- return PT_LOAD;
- return TargetLayout::getSegmentType(section);
- }
-
- Section<ELF32LE> *getSDataSection() { return &_sdataSection; }
-
- uint64_t getGOTSymAddr() {
- std::call_once(_gotOnce, [this]() {
- if (AtomLayout *got = findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"))
- _gotAddr = got->_virtualAddr;
- });
- return _gotAddr;
- }
-
-private:
- SDataSection _sdataSection;
- uint64_t _gotAddr = 0;
- std::once_flag _gotOnce;
-};
-
-/// \brief TargetHandler for Hexagon
-class HexagonTargetHandler final : public TargetHandler {
-public:
- HexagonTargetHandler(HexagonLinkingContext &targetInfo);
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<HexagonELFFile>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELF32LE>>>(_ctx);
- }
-
- std::unique_ptr<Writer> getWriter() override;
-
-private:
- HexagonLinkingContext &_ctx;
- std::unique_ptr<HexagonTargetLayout> _targetLayout;
- std::unique_ptr<HexagonTargetRelocationHandler> _relocationHandler;
-};
-
-void finalizeHexagonRuntimeAtomValues(HexagonTargetLayout &layout);
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (removed)
@@ -1,18 +0,0 @@
-add_lld_library(lldMipsELFTarget
- MipsAbiInfoHandler.cpp
- MipsCtorsOrderPass.cpp
- MipsELFFile.cpp
- MipsELFWriters.cpp
- MipsLinkingContext.cpp
- MipsRelocationHandler.cpp
- MipsRelocationPass.cpp
- MipsSectionChunks.cpp
- MipsTargetHandler.cpp
- MipsTargetLayout.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp (removed)
@@ -1,675 +0,0 @@
-//===- lib/ReaderWriter/ELF/MipsAbiInfoHandler.cpp ------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsAbiInfoHandler.h"
-#include "lld/Core/Error.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/MipsABIFlags.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm;
-using namespace llvm::ELF;
-using namespace llvm::Mips;
-
-namespace {
-
-// The joined set of MIPS ISAs and MIPS ISA extensions.
-enum MipsISAs {
- ArchNone,
-
- // General ISAs
- Arch1,
- Arch2,
- Arch3,
- Arch4,
- Arch5,
- Arch32,
- Arch32r2,
- Arch32r3,
- Arch32r5,
- Arch32r6,
- Arch64,
- Arch64r2,
- Arch64r3,
- Arch64r5,
- Arch64r6,
-
- // CPU specific ISAs
- Arch3900,
- Arch4010,
- Arch4100,
- Arch4111,
- Arch4120,
- Arch4650,
- Arch5400,
- Arch5500,
- Arch5900,
- Arch9000,
- Arch10000,
- ArchLs2e,
- ArchLs2f,
- ArchLs3a,
- ArchOcteon,
- ArchOcteonP,
- ArchOcteon2,
- ArchOcteon3,
- ArchSB1,
- ArchXLR
-};
-
-struct MipsISATreeEdge {
- MipsISAs child;
- MipsISAs parent;
-};
-
-struct ElfArchPair {
- uint32_t _elfFlag;
- MipsISAs _arch;
-};
-
-struct AbiIsaArchPair {
- uint8_t _isaLevel;
- uint8_t _isaRev;
- uint8_t _isaExt;
- MipsISAs _arch;
-};
-}
-
-static const MipsISATreeEdge isaTree[] = {
- // MIPS32R6 and MIPS64R6 are not compatible with other extensions
-
- // MIPS64R2 extensions.
- {ArchOcteon3, ArchOcteon2},
- {ArchOcteon2, ArchOcteonP},
- {ArchOcteonP, ArchOcteon},
- {ArchOcteon, Arch64r2},
- {ArchLs3a, Arch64r2},
-
- // MIPS64 extensions.
- {Arch64r2, Arch64},
- {ArchSB1, Arch64},
- {ArchXLR, Arch64},
-
- // MIPS V extensions.
- {Arch64, Arch5},
-
- // R5000 extensions.
- {Arch5500, Arch5400},
-
- // MIPS IV extensions.
- {Arch5, Arch4},
- {Arch5400, Arch4},
- {Arch9000, Arch4},
-
- // VR4100 extensions.
- {Arch4120, Arch4100},
- {Arch4111, Arch4100},
-
- // MIPS III extensions.
- {ArchLs2e, Arch3},
- {ArchLs2f, Arch3},
- {Arch4650, Arch3},
- {Arch4100, Arch3},
- {Arch4010, Arch3},
- {Arch5900, Arch3},
- {Arch4, Arch3},
-
- // MIPS32 extensions.
- {Arch32r2, Arch32},
-
- // MIPS II extensions.
- {Arch3, Arch2},
- {Arch32, Arch2},
-
- // MIPS I extensions.
- {Arch3900, Arch1},
- {Arch2, Arch1},
-};
-
-// Conversion ELF arch flags => MipsISAs
-static const ElfArchPair elfArchPairs[] = {
- {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, Arch3900},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, Arch4010},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, Arch4100},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, Arch4111},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, Arch4120},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, Arch4650},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, Arch5400},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, Arch5500},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, Arch5900},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, Arch9000},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, ArchLs2e},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, ArchLs2f},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, ArchLs3a},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteon},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, ArchOcteon2},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, ArchOcteon3},
- {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchSB1},
- {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, ArchXLR},
- {EF_MIPS_ARCH_1, Arch1},
- {EF_MIPS_ARCH_2, Arch2},
- {EF_MIPS_ARCH_3, Arch3},
- {EF_MIPS_ARCH_4, Arch4},
- {EF_MIPS_ARCH_5, Arch5},
- {EF_MIPS_ARCH_32, Arch32},
- {EF_MIPS_ARCH_32R2, Arch32r2},
- {EF_MIPS_ARCH_32R6, Arch32r6},
- {EF_MIPS_ARCH_64, Arch64},
- {EF_MIPS_ARCH_64R2, Arch64r2},
- {EF_MIPS_ARCH_64R6, Arch64r6}
-};
-
-// Conversion MipsISAs => ELF arch flags
-static const ElfArchPair archElfPairs[] = {
- {EF_MIPS_ARCH_1, Arch1},
- {EF_MIPS_ARCH_2, Arch2},
- {EF_MIPS_ARCH_3, Arch3},
- {EF_MIPS_ARCH_4, Arch4},
- {EF_MIPS_ARCH_5, Arch5},
- {EF_MIPS_ARCH_32, Arch32},
- {EF_MIPS_ARCH_32R2, Arch32r2},
- {EF_MIPS_ARCH_32R2, Arch32r3},
- {EF_MIPS_ARCH_32R2, Arch32r5},
- {EF_MIPS_ARCH_32R6, Arch32r6},
- {EF_MIPS_ARCH_64, Arch64},
- {EF_MIPS_ARCH_64R2, Arch64r2},
- {EF_MIPS_ARCH_64R2, Arch64r3},
- {EF_MIPS_ARCH_64R2, Arch64r5},
- {EF_MIPS_ARCH_64R6, Arch64r6},
- {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, Arch3900},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, Arch4010},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, Arch4100},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, Arch4111},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, Arch4120},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, Arch4650},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, Arch5400},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, Arch5500},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, Arch5900},
- {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, Arch9000},
- {EF_MIPS_ARCH_4, Arch10000},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, ArchLs2e},
- {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, ArchLs2f},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, ArchLs3a},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteon},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteonP},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, ArchOcteon2},
- {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, ArchOcteon3},
- {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchSB1},
- {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchXLR}
-};
-
-// Conversion .MIPS.abiflags isa/level/extension <=> MipsISAs
-static const AbiIsaArchPair abiIsaArchPair[] = {
- { 0, 0, 0, ArchNone},
- { 1, 0, 0, Arch1},
- { 2, 0, 0, Arch2},
- { 3, 0, 0, Arch3},
- { 4, 0, 0, Arch4},
- { 5, 0, 0, Arch5},
- {32, 1, 0, Arch32},
- {32, 2, 0, Arch32r2},
- {32, 3, 0, Arch32r3},
- {32, 5, 0, Arch32r5},
- {32, 6, 0, Arch32r6},
- {64, 1, 0, Arch64},
- {64, 2, 0, Arch64r2},
- {64, 3, 0, Arch64r3},
- {64, 5, 0, Arch64r5},
- {64, 6, 0, Arch64r6},
- { 1, 0, AFL_EXT_3900, Arch3900},
- { 3, 0, AFL_EXT_4010, Arch4010},
- { 3, 0, AFL_EXT_4100, Arch4100},
- { 3, 0, AFL_EXT_4111, Arch4111},
- { 3, 0, AFL_EXT_4120, Arch4120},
- { 3, 0, AFL_EXT_4650, Arch4650},
- { 4, 0, AFL_EXT_5400, Arch5400},
- { 4, 0, AFL_EXT_5500, Arch5500},
- { 3, 0, AFL_EXT_5900, Arch5900},
- { 4, 0, AFL_EXT_10000, Arch10000},
- { 3, 0, AFL_EXT_LOONGSON_2E, ArchLs2e},
- { 3, 0, AFL_EXT_LOONGSON_2F, ArchLs2f},
- {64, 2, AFL_EXT_LOONGSON_3A, ArchLs3a},
- {64, 2, AFL_EXT_OCTEON, ArchOcteon},
- {64, 2, AFL_EXT_OCTEON2, ArchOcteon2},
- {64, 2, AFL_EXT_OCTEON3, ArchOcteon3},
- {64, 1, AFL_EXT_SB1, ArchSB1},
- {64, 1, AFL_EXT_XLR, ArchXLR}
-};
-
-static bool matchMipsISA(MipsISAs base, MipsISAs ext) {
- if (base == ext)
- return true;
- if (base == Arch32 && matchMipsISA(Arch64, ext))
- return true;
- if (base == Arch32r2 && matchMipsISA(Arch64r2, ext))
- return true;
- for (const auto &edge : isaTree) {
- if (ext == edge.child) {
- ext = edge.parent;
- if (ext == base)
- return true;
- }
- }
- return false;
-}
-
-static bool is32BitElfFlags(unsigned flags) {
- if (flags & EF_MIPS_32BITMODE)
- return true;
-
- unsigned arch = flags & EF_MIPS_ARCH;
- if (arch == EF_MIPS_ARCH_1 || arch == EF_MIPS_ARCH_2 ||
- arch == EF_MIPS_ARCH_32 || arch == EF_MIPS_ARCH_32R2 ||
- arch == EF_MIPS_ARCH_32R6)
- return true;
-
- unsigned abi = flags & EF_MIPS_ABI;
- if (abi == EF_MIPS_ABI_O32 || abi == EF_MIPS_ABI_EABI32)
- return true;
-
- return false;
-}
-
-static ErrorOr<MipsISAs> headerFlagsToIsa(uint32_t flags) {
- uint32_t arch = flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
- for (const auto &p : elfArchPairs)
- if (p._elfFlag == arch)
- return p._arch;
- return make_dynamic_error_code(
- StringRef("Unknown EF_MIPS_ARCH | EF_MIPS_MACH flags (0x") +
- Twine::utohexstr(arch) + ")");
-}
-
-static uint32_t isaToHeaderFlags(unsigned isa) {
- for (const auto &p : archElfPairs)
- if (p._arch == isa)
- return p._elfFlag;
- llvm_unreachable("Unknown MIPS ISA");
-}
-
-static ErrorOr<uint32_t> flagsToAses(uint32_t flags) {
- uint32_t ases = flags & EF_MIPS_ARCH_ASE;
- switch (ases) {
- case 0:
- return 0;
- case EF_MIPS_MICROMIPS:
- return AFL_ASE_MICROMIPS;
- case EF_MIPS_ARCH_ASE_M16:
- return AFL_ASE_MIPS16;
- case EF_MIPS_ARCH_ASE_MDMX:
- return AFL_ASE_MDMX;
- default:
- return make_dynamic_error_code(
- StringRef("Unknown EF_MIPS_ARCH_ASE flag (0x") +
- Twine::utohexstr(ases) + ")");
- }
-}
-
-static uint32_t asesToFlags(uint32_t ases) {
- switch (ases) {
- case AFL_ASE_MICROMIPS:
- return EF_MIPS_MICROMIPS;
- case AFL_ASE_MIPS16:
- return EF_MIPS_ARCH_ASE_M16;
- case AFL_ASE_MDMX:
- return EF_MIPS_ARCH_ASE_MDMX;
- default:
- return 0;
- }
-}
-
-static ErrorOr<MipsISAs> sectionFlagsToIsa(uint8_t isaLevel, uint8_t isaRev,
- uint8_t isaExt) {
- for (const auto &p : abiIsaArchPair)
- if (p._isaLevel == isaLevel && p._isaRev == isaRev && p._isaExt == isaExt)
- return p._arch;
- return make_dynamic_error_code(
- StringRef("Unknown ISA level/revision/extension ") + Twine(isaLevel) +
- "/" + Twine(isaRev) + "/" + Twine(isaExt));
-}
-
-static std::tuple<uint8_t, uint8_t, uint32_t> isaToSectionFlags(unsigned isa) {
- for (const auto &p : abiIsaArchPair)
- if (p._arch == isa)
- return std::make_tuple(p._isaLevel, p._isaRev, p._isaExt);
- llvm_unreachable("Unknown MIPS ISA");
-}
-
-static bool checkCompatibility(const MipsAbiFlags &hdr,
- const MipsAbiFlags &sec) {
- uint32_t secIsa = ArchNone;
- switch (sec._isa) {
- case Arch32r3:
- case Arch32r5:
- secIsa = Arch32r2;
- break;
- case Arch64r3:
- case Arch64r5:
- secIsa = Arch64r2;
- break;
- default:
- secIsa = sec._isa;
- break;
- }
- if (secIsa != hdr._isa) {
- llvm::errs() << "inconsistent ISA between .MIPS.abiflags "
- "and ELF header e_flags field\n";
- return false;
- }
- if ((sec._ases & hdr._ases) != hdr._ases) {
- llvm::errs() << "inconsistent ASEs between .MIPS.abiflags "
- "and ELF header e_flags field\n";
- return false;
- }
- return true;
-}
-
-static int compareFpAbi(uint32_t fpA, uint32_t fpB) {
- if (fpA == fpB)
- return 0;
- if (fpB == Val_GNU_MIPS_ABI_FP_ANY)
- return 1;
- if (fpB == Val_GNU_MIPS_ABI_FP_64A && fpA == Val_GNU_MIPS_ABI_FP_64)
- return 1;
- if (fpB != Val_GNU_MIPS_ABI_FP_XX)
- return -1;
- if (fpA == Val_GNU_MIPS_ABI_FP_DOUBLE || fpA == Val_GNU_MIPS_ABI_FP_64 ||
- fpA == Val_GNU_MIPS_ABI_FP_64A)
- return 1;
- return -1;
-}
-
-static StringRef getFpAbiName(uint32_t fpAbi) {
- switch (fpAbi) {
- case Val_GNU_MIPS_ABI_FP_ANY:
- return "<any>";
- case Val_GNU_MIPS_ABI_FP_DOUBLE:
- return "-mdouble-float";
- case Val_GNU_MIPS_ABI_FP_SINGLE:
- return "-msingle-float";
- case Val_GNU_MIPS_ABI_FP_SOFT:
- return "-msoft-float";
- case Val_GNU_MIPS_ABI_FP_OLD_64:
- return "-mips32r2 -mfp64 (old)";
- case Val_GNU_MIPS_ABI_FP_XX:
- return "-mfpxx";
- case Val_GNU_MIPS_ABI_FP_64:
- return "-mgp32 -mfp64";
- case Val_GNU_MIPS_ABI_FP_64A:
- return "-mgp32 -mfp64 -mno-odd-spreg";
- default:
- return "<unknown>";
- }
-}
-
-static uint32_t selectFpAbiFlag(uint32_t oldFp, uint32_t newFp) {
- if (compareFpAbi(newFp, oldFp) >= 0)
- return newFp;
- if (compareFpAbi(oldFp, newFp) < 0)
- llvm::errs() << "FP ABI " << getFpAbiName(oldFp) << " is incompatible with "
- << getFpAbiName(newFp) << "\n";
- return oldFp;
-}
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> bool MipsAbiInfoHandler<ELFT>::isMicroMips() const {
- assert(_abiFlags.hasValue());
- return _abiFlags->_ases & AFL_ASE_MICROMIPS;
-}
-
-template <class ELFT> bool MipsAbiInfoHandler<ELFT>::isMipsR6() const {
- assert(_abiFlags.hasValue());
- return _abiFlags->_isa == Arch32r6 || _abiFlags->_isa == Arch64r6;
-}
-
-template <class ELFT> bool MipsAbiInfoHandler<ELFT>::isFp64() const {
- assert(_abiFlags.hasValue());
- return _abiFlags->_fpAbi == Val_GNU_MIPS_ABI_FP_64 ||
- _abiFlags->_fpAbi == Val_GNU_MIPS_ABI_FP_64A;
-}
-
-template <class ELFT> bool MipsAbiInfoHandler<ELFT>::isCPicOnly() const {
- assert(_abiFlags.hasValue());
- return _abiFlags->_isCPic && !_abiFlags->_isPic;
-}
-
-template <class ELFT> uint32_t MipsAbiInfoHandler<ELFT>::getFlags() const {
- std::lock_guard<std::mutex> lock(_mutex);
- uint32_t flags = 0;
- if (_abiFlags.hasValue()) {
- flags |= isaToHeaderFlags(_abiFlags->_isa);
- flags |= asesToFlags(_abiFlags->_ases);
- flags |= _abiFlags->_abi;
- flags |= _abiFlags->_isPic ? EF_MIPS_PIC : 0u;
- flags |= _abiFlags->_isCPic ? EF_MIPS_CPIC : 0u;
- flags |= _abiFlags->_isNoReorder ? EF_MIPS_NOREORDER : 0u;
- flags |= _abiFlags->_is32BitMode ? EF_MIPS_32BITMODE : 0u;
- flags |= _abiFlags->_isNan2008 ? EF_MIPS_NAN2008 : 0u;
- }
- return flags;
-}
-
-template <class ELFT>
-llvm::Optional<typename MipsAbiInfoHandler<ELFT>::Elf_Mips_RegInfo>
-MipsAbiInfoHandler<ELFT>::getRegistersMask() const {
- std::lock_guard<std::mutex> lock(_mutex);
- return _regMask;
-}
-
-template <class ELFT>
-llvm::Optional<typename MipsAbiInfoHandler<ELFT>::Elf_Mips_ABIFlags>
-MipsAbiInfoHandler<ELFT>::getAbiFlags() const {
- std::lock_guard<std::mutex> lock(_mutex);
- if (!_hasAbiSection)
- return llvm::Optional<Elf_Mips_ABIFlags>();
-
- Elf_Mips_ABIFlags sec;
- sec.version = 0;
- std::tie(sec.isa_level, sec.isa_rev, sec.isa_ext) =
- isaToSectionFlags(_abiFlags->_isa);
- sec.gpr_size = _abiFlags->_gprSize;
- sec.cpr1_size = _abiFlags->_cpr1Size;
- sec.cpr2_size = _abiFlags->_cpr2Size;
- sec.fp_abi = _abiFlags->_fpAbi;
- sec.ases = _abiFlags->_ases;
- sec.flags1 = _abiFlags->_flags1;
- sec.flags2 = 0;
- return sec;
-}
-
-template <class ELFT> MipsAbi MipsAbiInfoHandler<ELFT>::getAbi() const {
- if (!_abiFlags.hasValue())
- return ELFT::Is64Bits ? MipsAbi::N64 : MipsAbi::O32;
- switch (_abiFlags->_abi & (EF_MIPS_ABI_O32 | EF_MIPS_ABI2)) {
- case EF_MIPS_ABI_O32:
- return MipsAbi::O32;
- case EF_MIPS_ABI2:
- return MipsAbi::N32;
- case 0:
- return MipsAbi::N64;
- default:
- llvm_unreachable("Unknown ABI flag");
- }
-}
-
-template <class ELFT>
-std::error_code
-MipsAbiInfoHandler<ELFT>::mergeFlags(uint32_t newFlags,
- const Elf_Mips_ABIFlags *newSec) {
- std::lock_guard<std::mutex> lock(_mutex);
-
- ErrorOr<MipsAbiFlags> abiFlags = createAbiFlags(newFlags, newSec);
- if (auto ec = abiFlags.getError())
- return ec;
-
- // We support three ABI: O32, N32, and N64. The last one does not have
- // the corresponding ELF flag.
- if (ELFT::Is64Bits) {
- if (abiFlags->_abi)
- return make_dynamic_error_code("Unsupported ABI");
- } else {
- if (!(abiFlags->_abi & (EF_MIPS_ABI_O32 | EF_MIPS_ABI2)))
- return make_dynamic_error_code("Unsupported ABI");
- }
-
- // ... and still do not support MIPS-16 extension.
- if (abiFlags->_ases & AFL_ASE_MIPS16)
- return make_dynamic_error_code("Unsupported extension: MIPS16");
-
- // PIC code is inherently CPIC and may not set CPIC flag explicitly.
- // Ensure that this flag will exist in the linked file.
- if (abiFlags->_isPic)
- abiFlags->_isCPic = true;
-
- // If the old set of flags is empty, use the new one as a result.
- if (!_abiFlags.hasValue()) {
- _abiFlags = *abiFlags;
- return std::error_code();
- }
-
- // Check ABI compatibility.
- if (abiFlags->_abi != _abiFlags->_abi)
- return make_dynamic_error_code("Linking modules with incompatible ABI");
-
- // Check PIC / CPIC flags compatibility.
- if (abiFlags->_isCPic != _abiFlags->_isCPic)
- llvm::errs() << "lld warning: linking abicalls and non-abicalls files\n";
-
- if (!abiFlags->_isPic)
- _abiFlags->_isPic = false;
- if (abiFlags->_isCPic)
- _abiFlags->_isCPic = true;
-
- // Check mixing -mnan=2008 / -mnan=legacy modules.
- if (abiFlags->_isNan2008 != _abiFlags->_isNan2008)
- return make_dynamic_error_code(
- "Linking -mnan=2008 and -mnan=legacy modules");
-
- // Check ISA compatibility and update the extension flag.
- if (!matchMipsISA(MipsISAs(abiFlags->_isa), MipsISAs(_abiFlags->_isa))) {
- if (!matchMipsISA(MipsISAs(_abiFlags->_isa), MipsISAs(abiFlags->_isa)))
- return make_dynamic_error_code("Linking modules with incompatible ISA");
- _abiFlags->_isa = abiFlags->_isa;
- }
-
- _abiFlags->_ases |= abiFlags->_ases;
- _abiFlags->_isNoReorder = _abiFlags->_isNoReorder || abiFlags->_isNoReorder;
- _abiFlags->_is32BitMode = _abiFlags->_is32BitMode || abiFlags->_is32BitMode;
-
- _abiFlags->_fpAbi = selectFpAbiFlag(_abiFlags->_fpAbi, abiFlags->_fpAbi);
- _abiFlags->_gprSize = std::max(_abiFlags->_gprSize, abiFlags->_gprSize);
- _abiFlags->_cpr1Size = std::max(_abiFlags->_cpr1Size, abiFlags->_cpr1Size);
- _abiFlags->_cpr2Size = std::max(_abiFlags->_cpr2Size, abiFlags->_cpr2Size);
- _abiFlags->_flags1 |= abiFlags->_flags1;
-
- return std::error_code();
-}
-
-template <class ELFT>
-void MipsAbiInfoHandler<ELFT>::mergeRegistersMask(
- const Elf_Mips_RegInfo &info) {
- std::lock_guard<std::mutex> lock(_mutex);
- if (!_regMask.hasValue()) {
- _regMask = info;
- return;
- }
- _regMask->ri_gprmask = _regMask->ri_gprmask | info.ri_gprmask;
- _regMask->ri_cprmask[0] = _regMask->ri_cprmask[0] | info.ri_cprmask[0];
- _regMask->ri_cprmask[1] = _regMask->ri_cprmask[1] | info.ri_cprmask[1];
- _regMask->ri_cprmask[2] = _regMask->ri_cprmask[2] | info.ri_cprmask[2];
- _regMask->ri_cprmask[3] = _regMask->ri_cprmask[3] | info.ri_cprmask[3];
-}
-
-template <class ELFT>
-ErrorOr<MipsAbiFlags>
-MipsAbiInfoHandler<ELFT>::createAbiFlags(uint32_t flags,
- const Elf_Mips_ABIFlags *sec) {
- ErrorOr<MipsAbiFlags> hdrFlags = createAbiFromHeaderFlags(flags);
- if (auto ec = hdrFlags.getError())
- return ec;
- if (!sec)
- return *hdrFlags;
- ErrorOr<MipsAbiFlags> secFlags = createAbiFromSection(*sec);
- if (auto ec = secFlags.getError())
- return ec;
- if (!checkCompatibility(*hdrFlags, *secFlags))
- return *hdrFlags;
-
- _hasAbiSection = true;
-
- secFlags->_abi = hdrFlags->_abi;
- secFlags->_isPic = hdrFlags->_isPic;
- secFlags->_isCPic = hdrFlags->_isCPic;
- secFlags->_isNoReorder = hdrFlags->_isNoReorder;
- secFlags->_is32BitMode = hdrFlags->_is32BitMode;
- secFlags->_isNan2008 = hdrFlags->_isNan2008;
- return *secFlags;
-}
-
-template <class ELFT>
-ErrorOr<MipsAbiFlags>
-MipsAbiInfoHandler<ELFT>::createAbiFromHeaderFlags(uint32_t flags) {
- MipsAbiFlags abi;
- ErrorOr<MipsISAs> isa = headerFlagsToIsa(flags);
- if (auto ec = isa.getError())
- return ec;
- abi._isa = *isa;
-
- abi._fpAbi = Val_GNU_MIPS_ABI_FP_ANY;
- abi._cpr1Size = AFL_REG_NONE;
- abi._cpr2Size = AFL_REG_NONE;
- abi._gprSize = is32BitElfFlags(flags) ? AFL_REG_32 : AFL_REG_64;
-
- ErrorOr<uint32_t> ases = flagsToAses(flags);
- if (auto ec = ases.getError())
- return ec;
- abi._ases = *ases;
- abi._flags1 = 0;
- abi._abi = flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
- abi._isPic = flags & EF_MIPS_PIC;
- abi._isCPic = flags & EF_MIPS_CPIC;
- abi._isNoReorder = flags & EF_MIPS_NOREORDER;
- abi._is32BitMode = flags & EF_MIPS_32BITMODE;
- abi._isNan2008 = flags & EF_MIPS_NAN2008;
- return abi;
-}
-
-template <class ELFT>
-ErrorOr<MipsAbiFlags>
-MipsAbiInfoHandler<ELFT>::createAbiFromSection(const Elf_Mips_ABIFlags &sec) {
- MipsAbiFlags abi;
- ErrorOr<MipsISAs> isa =
- sectionFlagsToIsa(sec.isa_level, sec.isa_rev, sec.isa_ext);
- if (auto ec = isa.getError())
- return ec;
- abi._isa = *isa;
- abi._fpAbi = sec.fp_abi;
- abi._cpr1Size = sec.cpr1_size;
- abi._cpr2Size = sec.cpr2_size;
- abi._gprSize = sec.gpr_size;
- abi._ases = sec.ases;
- abi._flags1 = sec.flags1;
- if (sec.flags2 != 0)
- return make_dynamic_error_code("unexpected non-zero 'flags2' value");
- return abi;
-}
-
-template class MipsAbiInfoHandler<ELF32BE>;
-template class MipsAbiInfoHandler<ELF32LE>;
-template class MipsAbiInfoHandler<ELF64BE>;
-template class MipsAbiInfoHandler<ELF64LE>;
-
-}
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h (removed)
@@ -1,83 +0,0 @@
-//===- lib/ReaderWriter/ELF/MipsAbiInfoHandler.h --------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ABI_INFO_HANDLER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_ABI_INFO_HANDLER_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/ErrorOr.h"
-#include <mutex>
-#include <system_error>
-
-namespace lld {
-namespace elf {
-
-enum class MipsAbi { O32, N32, N64 };
-
-struct MipsAbiFlags {
- unsigned _isa = 0;
- unsigned _fpAbi = 0;
- unsigned _ases = 0;
- unsigned _flags1 = 0;
- unsigned _gprSize = 0;
- unsigned _cpr1Size = 0;
- unsigned _cpr2Size = 0;
-
- unsigned _abi = 0;
-
- bool _isPic = false;
- bool _isCPic = false;
- bool _isNoReorder = false;
- bool _is32BitMode = false;
- bool _isNan2008 = false;
-};
-
-template <class ELFT> class MipsAbiInfoHandler {
-public:
- typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
- typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
-
- MipsAbiInfoHandler() = default;
-
- bool hasMipsAbiSection() const { return _hasAbiSection; }
- bool isMicroMips() const;
- bool isMipsR6() const;
- bool isFp64() const;
- bool isCPicOnly() const;
-
- uint32_t getFlags() const;
- llvm::Optional<Elf_Mips_RegInfo> getRegistersMask() const;
- llvm::Optional<Elf_Mips_ABIFlags> getAbiFlags() const;
-
- MipsAbi getAbi() const;
-
- /// \brief Merge saved ELF header flags and the new set of flags.
- std::error_code mergeFlags(uint32_t newFlags,
- const Elf_Mips_ABIFlags *newAbi);
-
- /// \brief Merge saved and new sets of registers usage masks.
- void mergeRegistersMask(const Elf_Mips_RegInfo &info);
-
-private:
- mutable std::mutex _mutex;
- bool _hasAbiSection = false;
- llvm::Optional<MipsAbiFlags> _abiFlags;
- llvm::Optional<Elf_Mips_RegInfo> _regMask;
-
- llvm::ErrorOr<MipsAbiFlags> createAbiFlags(uint32_t flags,
- const Elf_Mips_ABIFlags *sec);
- static llvm::ErrorOr<MipsAbiFlags> createAbiFromHeaderFlags(uint32_t flags);
- static llvm::ErrorOr<MipsAbiFlags>
- createAbiFromSection(const Elf_Mips_ABIFlags &sec);
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp (removed)
@@ -1,76 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/Mips/CtorsOrderPass.cpp ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsCtorsOrderPass.h"
-#include "lld/Core/Simple.h"
-#include <algorithm>
-#include <climits>
-
-using namespace lld;
-using namespace lld::elf;
-
-static bool matchCrtObjName(StringRef objName, StringRef objPath) {
- if (!objPath.endswith(".o"))
- return false;
-
- // check *<objName> case
- objPath = objPath.drop_back(2);
- if (objPath.endswith(objName))
- return true;
-
- // check *<objName>? case
- return !objPath.empty() && objPath.drop_back(1).endswith(objName);
-}
-
-static int32_t getSectionPriority(StringRef path, StringRef sectionName) {
- // Arrange .ctors/.dtors sections in the following order:
- // .ctors from crtbegin.o or crtbegin?.o
- // .ctors from regular object files
- // .ctors.* (sorted) from regular object files
- // .ctors from crtend.o or crtend?.o
-
- if (matchCrtObjName("crtbegin", path))
- return std::numeric_limits<int32_t>::min();
- if (matchCrtObjName("crtend", path))
- return std::numeric_limits<int32_t>::max();
-
- StringRef num = sectionName.drop_front().rsplit('.').second;
-
- int32_t priority = std::numeric_limits<int32_t>::min() + 1;
- if (!num.empty())
- num.getAsInteger(10, priority);
-
- return priority;
-}
-
-std::error_code MipsCtorsOrderPass::perform(SimpleFile &f) {
- auto definedAtoms = f.definedAtoms();
-
- auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(),
- [](const DefinedAtom *atom) {
- if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired)
- return false;
-
- StringRef name = atom->customSectionName();
- return name.startswith(".ctors") || name.startswith(".dtors");
- });
-
- std::stable_sort(definedAtoms.begin(), last,
- [](const DefinedAtom *left, const DefinedAtom *right) {
- StringRef leftSec = left->customSectionName();
- StringRef rightSec = right->customSectionName();
-
- int32_t leftPriority = getSectionPriority(left->file().path(), leftSec);
- int32_t rightPriority = getSectionPriority(right->file().path(), rightSec);
-
- return leftPriority < rightPriority;
- });
-
- return std::error_code();
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h (removed)
@@ -1,25 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_CTORS_ORDER_PASS_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_CTORS_ORDER_PASS_H
-
-#include "lld/Core/Pass.h"
-
-namespace lld {
-namespace elf {
-/// \brief This pass sorts atoms in .{ctors,dtors}.<priority> sections.
-class MipsCtorsOrderPass : public Pass {
-public:
- std::error_code perform(SimpleFile &mergedFile) override;
-};
-}
-}
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h (removed)
@@ -1,124 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h -----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_TABLE_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_TABLE_H
-
-#include "TargetLayout.h"
-#include "SectionChunks.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> class MipsTargetLayout;
-
-template <class ELFT> class MipsDynamicTable : public DynamicTable<ELFT> {
-public:
- MipsDynamicTable(const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
- : DynamicTable<ELFT>(ctx, layout, ".dynamic",
- TargetLayout<ELFT>::ORDER_DYNAMIC),
- _targetLayout(layout) {}
-
- void createDefaultEntries() override {
- DynamicTable<ELFT>::createDefaultEntries();
-
- // Version id for the Runtime Linker Interface.
- this->addEntry(DT_MIPS_RLD_VERSION, 1);
-
- // The .rld_map section address.
- if (this->_ctx.getOutputELFType() == ET_EXEC) {
- _dt_rldmap = this->addEntry(DT_MIPS_RLD_MAP, 0);
- _dt_rldmaprel = this->addEntry(DT_MIPS_RLD_MAP_REL, 0);
- }
-
- // MIPS flags.
- this->addEntry(DT_MIPS_FLAGS, RHF_NOTPOT);
-
- // The base address of the segment.
- _dt_baseaddr = this->addEntry(DT_MIPS_BASE_ADDRESS, 0);
-
- // Number of local global offset table entries.
- _dt_localgot = this->addEntry(DT_MIPS_LOCAL_GOTNO, 0);
-
- // Number of entries in the .dynsym section.
- _dt_symtabno = this->addEntry(DT_MIPS_SYMTABNO, 0);
-
- // The index of the first dynamic symbol table entry that corresponds
- // to an entry in the global offset table.
- _dt_gotsym = this->addEntry(DT_MIPS_GOTSYM, 0);
-
- // Address of the .got section.
- _dt_pltgot = this->addEntry(DT_PLTGOT, 0);
- }
-
- void doPreFlight() override {
- DynamicTable<ELFT>::doPreFlight();
-
- if (_targetLayout.findOutputSection(".MIPS.options")) {
- _dt_options = this->addEntry(DT_MIPS_OPTIONS, 0);
- }
- }
-
- void updateDynamicTable() override {
- DynamicTable<ELFT>::updateDynamicTable();
-
- // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag.
- auto baseAddr = std::numeric_limits<uint64_t>::max();
- for (auto si : _targetLayout.segments())
- if (si->segmentType() != llvm::ELF::PT_NULL)
- baseAddr = std::min(baseAddr, si->virtualAddr());
- this->_entries[_dt_baseaddr].d_un.d_val = baseAddr;
-
- auto &got = _targetLayout.getGOTSection();
-
- this->_entries[_dt_symtabno].d_un.d_val = this->getSymbolTable()->size();
- this->_entries[_dt_gotsym].d_un.d_val =
- this->getSymbolTable()->size() - got.getGlobalCount();
- this->_entries[_dt_localgot].d_un.d_val = got.getLocalCount();
- this->_entries[_dt_pltgot].d_un.d_ptr = got.virtualAddr();
-
- if (const auto *sec = _targetLayout.findOutputSection(".MIPS.options"))
- this->_entries[_dt_options].d_un.d_ptr = sec->virtualAddr();
-
- if (const auto *sec = _targetLayout.findOutputSection(".rld_map")) {
- this->_entries[_dt_rldmap].d_un.d_ptr = sec->virtualAddr();
- this->_entries[_dt_rldmaprel].d_un.d_ptr =
- sec->virtualAddr() -
- (this->virtualAddr() +
- _dt_rldmaprel * sizeof(typename DynamicTable<ELFT>::Elf_Dyn));
- }
- }
-
- int64_t getGotPltTag() override { return DT_MIPS_PLTGOT; }
-
-protected:
- /// \brief Adjust the symbol's value for microMIPS code.
- uint64_t getAtomVirtualAddress(const AtomLayout *al) const override {
- if (const auto *da = dyn_cast<DefinedAtom>(al->_atom))
- if (da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC)
- return al->_virtualAddr | 1;
- return al->_virtualAddr;
- }
-
-private:
- std::size_t _dt_symtabno;
- std::size_t _dt_localgot;
- std::size_t _dt_gotsym;
- std::size_t _dt_pltgot;
- std::size_t _dt_baseaddr;
- std::size_t _dt_options;
- std::size_t _dt_rldmap;
- std::size_t _dt_rldmaprel;
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp (removed)
@@ -1,348 +0,0 @@
-//===- lib/ReaderWriter/ELF/MipsELFFile.cpp -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsELFFile.h"
-#include "MipsTargetHandler.h"
-#include "llvm/ADT/StringExtras.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-MipsELFDefinedAtom<ELFT>::MipsELFDefinedAtom(
- const MipsELFFile<ELFT> &file, StringRef symbolName, StringRef sectionName,
- const Elf_Sym *symbol, const Elf_Shdr *section,
- ArrayRef<uint8_t> contentData, unsigned int referenceStart,
- unsigned int referenceEnd, std::vector<ELFReference<ELFT> *> &referenceList)
- : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
- contentData, referenceStart, referenceEnd,
- referenceList) {}
-
-template <class ELFT>
-const MipsELFFile<ELFT> &MipsELFDefinedAtom<ELFT>::file() const {
- return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
-}
-
-template <class ELFT>
-DefinedAtom::CodeModel MipsELFDefinedAtom<ELFT>::codeModel() const {
- switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
- case llvm::ELF::STO_MIPS_MIPS16:
- return DefinedAtom::codeMips16;
- case llvm::ELF::STO_MIPS_PIC:
- return DefinedAtom::codeMipsPIC;
- case llvm::ELF::STO_MIPS_MICROMIPS:
- return DefinedAtom::codeMipsMicro;
- case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
- return DefinedAtom::codeMipsMicroPIC;
- default:
- return DefinedAtom::codeNA;
- }
-}
-
-template <class ELFT> bool MipsELFDefinedAtom<ELFT>::isPIC() const {
- return file().isPIC() || codeModel() == DefinedAtom::codeMipsMicroPIC ||
- codeModel() == DefinedAtom::codeMipsPIC;
-}
-
-template class MipsELFDefinedAtom<ELF32BE>;
-template class MipsELFDefinedAtom<ELF32LE>;
-template class MipsELFDefinedAtom<ELF64BE>;
-template class MipsELFDefinedAtom<ELF64LE>;
-
-template <class ELFT> static bool isMips64EL() {
- return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-}
-
-template <class ELFT, bool isRela>
-static uint32_t
-extractTag(const llvm::object::Elf_Rel_Impl<ELFT, isRela> &rel) {
- return (rel.getType(isMips64EL<ELFT>()) & 0xffffff00) >> 8;
-}
-
-template <class ELFT>
-MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rela &rel)
- : ELFReference<ELFT>(&rel, rel.r_offset - symValue,
- Reference::KindArch::Mips,
- rel.getType(isMips64EL<ELFT>()) & 0xff,
- rel.getSymbol(isMips64EL<ELFT>())),
- _tag(extractTag(rel)) {}
-
-template <class ELFT>
-MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
- : ELFReference<ELFT>(rel.r_offset - symValue, Reference::KindArch::Mips,
- rel.getType(isMips64EL<ELFT>()) & 0xff,
- rel.getSymbol(isMips64EL<ELFT>())),
- _tag(extractTag(rel)) {}
-
-template class MipsELFReference<ELF32BE>;
-template class MipsELFReference<ELF32LE>;
-template class MipsELFReference<ELF64BE>;
-template class MipsELFReference<ELF64LE>;
-
-template <class ELFT>
-MipsELFFile<ELFT>::MipsELFFile(std::unique_ptr<MemoryBuffer> mb,
- ELFLinkingContext &ctx)
- : ELFFile<ELFT>(std::move(mb), ctx) {}
-
-template <class ELFT> bool MipsELFFile<ELFT>::isPIC() const {
- return this->_objFile->getHeader()->e_flags & llvm::ELF::EF_MIPS_PIC;
-}
-
-template <class ELFT> std::error_code MipsELFFile<ELFT>::doParse() {
- if (std::error_code ec = ELFFile<ELFT>::doParse())
- return ec;
- // Retrieve some auxiliary data like GP value, TLS section address etc
- // from the object file.
- return readAuxData();
-}
-
-template <class ELFT>
-ELFDefinedAtom<ELFT> *MipsELFFile<ELFT>::createDefinedAtom(
- StringRef symName, StringRef sectionName, const Elf_Sym *sym,
- const Elf_Shdr *sectionHdr, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList) {
- return new (this->_readerStorage) MipsELFDefinedAtom<ELFT>(
- *this, symName, sectionName, sym, sectionHdr, contentData, referenceStart,
- referenceEnd, referenceList);
-}
-
-template <class ELFT>
-const typename MipsELFFile<ELFT>::Elf_Shdr *
-MipsELFFile<ELFT>::findSectionByType(uint64_t type) const {
- for (const Elf_Shdr §ion : this->_objFile->sections())
- if (section.sh_type == type)
- return §ion;
- return nullptr;
-}
-
-template <class ELFT>
-const typename MipsELFFile<ELFT>::Elf_Shdr *
-MipsELFFile<ELFT>::findSectionByFlags(uint64_t flags) const {
- for (const Elf_Shdr §ion : this->_objFile->sections())
- if (section.sh_flags & flags)
- return §ion;
- return nullptr;
-}
-
-template <class ELFT>
-ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_RegInfo *>
-MipsELFFile<ELFT>::findRegInfoSec() const {
- using namespace llvm::ELF;
- if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
- auto contents = this->getSectionContents(sec);
- if (std::error_code ec = contents.getError())
- return ec;
-
- ArrayRef<uint8_t> raw = contents.get();
- while (!raw.empty()) {
- if (raw.size() < sizeof(Elf_Mips_Options))
- return make_dynamic_error_code(
- StringRef("Invalid size of MIPS_OPTIONS section"));
-
- const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
- if (opt->kind == ODK_REGINFO)
- return &opt->getRegInfo();
- raw = raw.slice(opt->size);
- }
- } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
- auto contents = this->getSectionContents(sec);
- if (std::error_code ec = contents.getError())
- return ec;
-
- ArrayRef<uint8_t> raw = contents.get();
- if (raw.size() != sizeof(Elf_Mips_RegInfo))
- return make_dynamic_error_code(
- StringRef("Invalid size of MIPS_REGINFO section"));
-
- return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
- }
- return nullptr;
-}
-
-template <class ELFT>
-ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_ABIFlags *>
-MipsELFFile<ELFT>::findAbiFlagsSec() const {
- const Elf_Shdr *sec = findSectionByType(SHT_MIPS_ABIFLAGS);
- if (!sec)
- return nullptr;
-
- auto contents = this->getSectionContents(sec);
- if (std::error_code ec = contents.getError())
- return ec;
-
- ArrayRef<uint8_t> raw = contents.get();
- if (raw.size() != sizeof(Elf_Mips_ABIFlags))
- return make_dynamic_error_code(
- StringRef("Invalid size of MIPS_ABIFLAGS section"));
-
- const auto *abi = reinterpret_cast<const Elf_Mips_ABIFlags *>(raw.data());
- if (abi->version != 0)
- return make_dynamic_error_code(
- StringRef(".MIPS.abiflags section has unsupported version '") +
- llvm::utostr(abi->version) + "'");
-
- return abi;
-}
-
-template <class ELFT> std::error_code MipsELFFile<ELFT>::readAuxData() {
- using namespace llvm::ELF;
- if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
- _tpOff = sec->sh_addr + TP_OFFSET;
- _dtpOff = sec->sh_addr + DTP_OFFSET;
- }
-
- auto &handler =
- static_cast<MipsTargetHandler<ELFT> &>(this->_ctx.getTargetHandler());
- auto &abi = handler.getAbiInfoHandler();
-
- ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec();
- if (auto ec = regInfoSec.getError())
- return ec;
- if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) {
- abi.mergeRegistersMask(*regInfo);
- _gp0 = regInfo->ri_gp_value;
- }
-
- ErrorOr<const Elf_Mips_ABIFlags *> abiFlagsSec = findAbiFlagsSec();
- if (auto ec = abiFlagsSec.getError())
- return ec;
-
- const Elf_Ehdr *hdr = this->_objFile->getHeader();
- if (std::error_code ec = abi.mergeFlags(hdr->e_flags, abiFlagsSec.get()))
- return ec;
-
- return std::error_code();
-}
-
-template <class ELFT>
-void MipsELFFile<ELFT>::createRelocationReferences(
- const Elf_Sym *symbol, ArrayRef<uint8_t> content,
- range<const Elf_Rela *> rels) {
- const auto value = this->getSymbolValue(symbol);
- unsigned numInGroup = 0;
- for (const auto &rel : rels) {
- if (rel.r_offset < value || value + content.size() <= rel.r_offset) {
- numInGroup = 0;
- continue;
- }
- if (numInGroup > 0) {
- auto &last =
- *static_cast<MipsELFReference<ELFT> *>(this->_references.back());
- if (last.offsetInAtom() + value == rel.r_offset) {
- last.setTag(last.tag() |
- (rel.getType(isMips64EL<ELFT>()) << 8 * (numInGroup - 1)));
- ++numInGroup;
- continue;
- }
- }
- auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, rel);
- this->addReferenceToSymbol(r, symbol);
- this->_references.push_back(r);
- numInGroup = 1;
- }
-}
-
-template <class ELFT>
-void MipsELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent,
- const Elf_Shdr *relSec) {
- const Elf_Shdr *symtab = *this->_objFile->getSection(relSec->sh_link);
- auto rels = this->_objFile->rels(relSec);
- const auto value = this->getSymbolValue(symbol);
- for (const Elf_Rel *rit = rels.begin(), *eit = rels.end(); rit != eit;
- ++rit) {
- if (rit->r_offset < value || value + symContent.size() <= rit->r_offset)
- continue;
-
- auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, *rit);
- this->addReferenceToSymbol(r, symbol);
- this->_references.push_back(r);
-
- auto addend = readAddend(*rit, secContent);
- auto pairRelType = getPairRelocation(symtab, *rit);
- if (pairRelType != llvm::ELF::R_MIPS_NONE) {
- addend <<= 16;
- auto mit = findMatchingRelocation(pairRelType, rit, eit);
- if (mit != eit)
- addend += int16_t(readAddend(*mit, secContent));
- else
- // FIXME (simon): Show detailed warning.
- llvm::errs() << "lld warning: cannot matching LO16 relocation\n";
- }
- this->_references.back()->setAddend(addend);
- }
-}
-
-template <class ELFT>
-static uint8_t
-getPrimaryType(const llvm::object::Elf_Rel_Impl<ELFT, false> &rel) {
- return rel.getType(isMips64EL<ELFT>()) & 0xff;
-}
-
-template <class ELFT>
-Reference::Addend
-MipsELFFile<ELFT>::readAddend(const Elf_Rel &ri,
- const ArrayRef<uint8_t> content) const {
- return readMipsRelocAddend<ELFT>(getPrimaryType(ri),
- content.data() + ri.r_offset);
-}
-
-template <class ELFT>
-uint32_t MipsELFFile<ELFT>::getPairRelocation(const Elf_Shdr *symtab,
- const Elf_Rel &rel) const {
- switch (getPrimaryType(rel)) {
- case llvm::ELF::R_MIPS_HI16:
- return llvm::ELF::R_MIPS_LO16;
- case llvm::ELF::R_MIPS_PCHI16:
- return llvm::ELF::R_MIPS_PCLO16;
- case llvm::ELF::R_MIPS_GOT16:
- if (isLocalBinding(symtab, rel))
- return llvm::ELF::R_MIPS_LO16;
- break;
- case llvm::ELF::R_MICROMIPS_HI16:
- return llvm::ELF::R_MICROMIPS_LO16;
- case llvm::ELF::R_MICROMIPS_GOT16:
- if (isLocalBinding(symtab, rel))
- return llvm::ELF::R_MICROMIPS_LO16;
- break;
- default:
- // Nothing to do.
- break;
- }
- return llvm::ELF::R_MIPS_NONE;
-}
-
-template <class ELFT>
-const typename MipsELFFile<ELFT>::Elf_Rel *
-MipsELFFile<ELFT>::findMatchingRelocation(uint32_t pairRelType,
- const Elf_Rel *rit,
- const Elf_Rel *eit) const {
- return std::find_if(rit, eit, [&](const Elf_Rel &rel) {
- return getPrimaryType(rel) == pairRelType &&
- rel.getSymbol(isMips64EL<ELFT>()) ==
- rit->getSymbol(isMips64EL<ELFT>());
- });
-}
-
-template <class ELFT>
-bool MipsELFFile<ELFT>::isLocalBinding(const Elf_Shdr *symtab,
- const Elf_Rel &rel) const {
- return this->_objFile->getSymbol(symtab, rel.getSymbol(isMips64EL<ELFT>()))
- ->getBinding() == llvm::ELF::STB_LOCAL;
-}
-
-template class MipsELFFile<ELF32BE>;
-template class MipsELFFile<ELF32LE>;
-template class MipsELFFile<ELF64BE>;
-template class MipsELFFile<ELF64LE>;
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (removed)
@@ -1,126 +0,0 @@
-//===- lib/ReaderWriter/ELF/MipsELFFile.h ---------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FILE_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FILE_H
-
-#include "ELFReader.h"
-#include "MipsLinkingContext.h"
-#include "MipsRelocationHandler.h"
-#include "llvm/ADT/STLExtras.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> class MipsELFFile;
-
-template <class ELFT>
-class MipsELFDefinedAtom : public ELFDefinedAtom<ELFT> {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
-public:
- MipsELFDefinedAtom(const MipsELFFile<ELFT> &file, StringRef symbolName,
- StringRef sectionName, const Elf_Sym *symbol,
- const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList);
-
- const MipsELFFile<ELFT>& file() const override;
- DefinedAtom::CodeModel codeModel() const override;
-
- bool isPIC() const;
-};
-
-template <class ELFT> class MipsELFReference : public ELFReference<ELFT> {
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
-
-public:
- MipsELFReference(uint64_t symValue, const Elf_Rela &rel);
- MipsELFReference(uint64_t symValue, const Elf_Rel &rel);
-
- uint32_t tag() const override { return _tag; }
- void setTag(uint32_t tag) { _tag = tag; }
-
-private:
- uint32_t _tag;
-};
-
-template <class ELFT> class MipsELFFile : public ELFFile<ELFT> {
-public:
- MipsELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
-
- bool isPIC() const;
-
- /// \brief gp register value stored in the .reginfo section.
- int64_t getGP0() const { return _gp0; }
-
- /// \brief .tdata section address plus fixed offset.
- uint64_t getTPOffset() const { return _tpOff; }
- uint64_t getDTPOffset() const { return _dtpOff; }
-
-protected:
- std::error_code doParse() override;
-
-private:
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
-
- enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 };
-
- int64_t _gp0 = 0;
- uint64_t _tpOff = 0;
- uint64_t _dtpOff = 0;
-
- ELFDefinedAtom<ELFT> *
- createDefinedAtom(StringRef symName, StringRef sectionName,
- const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
- ArrayRef<uint8_t> contentData, unsigned int referenceStart,
- unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList) override;
-
- void createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> content,
- range<const Elf_Rela *> rels) override;
- void createRelocationReferences(const Elf_Sym *symbol,
- ArrayRef<uint8_t> symContent,
- ArrayRef<uint8_t> secContent,
- const Elf_Shdr *RelSec) override;
-
- const Elf_Shdr *findSectionByType(uint64_t type) const;
- const Elf_Shdr *findSectionByFlags(uint64_t flags) const;
-
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
- typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
- typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
- typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
-
- ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const;
- ErrorOr<const Elf_Mips_ABIFlags*> findAbiFlagsSec() const;
-
- std::error_code readAuxData();
-
- Reference::Addend readAddend(const Elf_Rel &ri,
- const ArrayRef<uint8_t> content) const;
-
- uint32_t getPairRelocation(const Elf_Shdr *Symtab, const Elf_Rel &rel) const;
-
- const Elf_Rel *findMatchingRelocation(uint32_t pairRelType,
- const Elf_Rel *rit,
- const Elf_Rel *eit) const;
-
- bool isLocalBinding(const Elf_Shdr *Symtab, const Elf_Rel &rel) const;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp (removed)
@@ -1,292 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp -----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsDynamicTable.h"
-#include "MipsELFWriters.h"
-#include "MipsLinkingContext.h"
-#include "MipsTargetHandler.h"
-#include "MipsTargetLayout.h"
-
-namespace {
-class MipsDynamicAtom : public lld::elf::DynamicAtom {
-public:
- MipsDynamicAtom(const lld::File &f) : DynamicAtom(f) {}
-
- ContentPermissions permissions() const override { return permR__; }
-};
-}
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-MipsELFWriter<ELFT>::MipsELFWriter(MipsLinkingContext &ctx,
- MipsTargetLayout<ELFT> &targetLayout,
- const MipsAbiInfoHandler<ELFT> &abiInfo)
- : _ctx(ctx), _targetLayout(targetLayout), _abiInfo(abiInfo) {}
-
-template <class ELFT>
-void MipsELFWriter<ELFT>::setELFHeader(ELFHeader<ELFT> &elfHeader) {
- elfHeader.e_version(1);
- elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
- elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
-
- unsigned char abiVer = 0;
- if (_ctx.getOutputELFType() == ET_EXEC && _abiInfo.isCPicOnly())
- abiVer = 1;
- if (_abiInfo.isFp64())
- abiVer = 3;
-
- elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, abiVer);
- elfHeader.e_flags(_abiInfo.getFlags());
-}
-
-template <class ELFT>
-void MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues() {
- auto gotSection = _targetLayout.findOutputSection(".got");
- auto got = gotSection ? gotSection->virtualAddr() : 0;
- auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
-
- setAtomValue("_gp", gp);
- setAtomValue("_gp_disp", gp);
- setAtomValue("__gnu_local_gp", gp);
-
- if (_ctx.isDynamic() && _ctx.getOutputELFType() == ET_EXEC)
- setAtomValue("_DYNAMIC_LINKING", 1);
-}
-
-template <class ELFT>
-std::unique_ptr<RuntimeFile<ELFT>> MipsELFWriter<ELFT>::createRuntimeFile() {
- auto file = llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Mips runtime file");
- file->addAbsoluteAtom("_gp");
- file->addAbsoluteAtom("_gp_disp");
- file->addAbsoluteAtom("__gnu_local_gp");
- if (_ctx.isDynamic()) {
- file->addAtom(*new (file->allocator()) MipsDynamicAtom(*file));
- if (_ctx.getOutputELFType() == ET_EXEC)
- file->addAbsoluteAtom("_DYNAMIC_LINKING");
- }
- return file;
-}
-
-template <class ELFT>
-unique_bump_ptr<Section<ELFT>>
-MipsELFWriter<ELFT>::createOptionsSection(llvm::BumpPtrAllocator &alloc) {
- typedef unique_bump_ptr<Section<ELFT>> Ptr;
- const auto ®Mask = _abiInfo.getRegistersMask();
- if (!regMask.hasValue())
- return Ptr();
- return ELFT::Is64Bits
- ? Ptr(new (alloc)
- MipsOptionsSection<ELFT>(_ctx, _targetLayout, *regMask))
- : Ptr(new (alloc)
- MipsReginfoSection<ELFT>(_ctx, _targetLayout, *regMask));
-}
-
-template <class ELFT>
-unique_bump_ptr<Section<ELFT>>
-MipsELFWriter<ELFT>::createAbiFlagsSection(llvm::BumpPtrAllocator &alloc) {
- typedef unique_bump_ptr<Section<ELFT>> Ptr;
- const auto &abi = _abiInfo.getAbiFlags();
- if (!abi.hasValue())
- return Ptr();
- return Ptr(new (alloc) MipsAbiFlagsSection<ELFT>(_ctx, _targetLayout, *abi));
-}
-
-template <class ELFT>
-void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) {
- AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
- assert(atom);
- atom->_virtualAddr = value;
-}
-
-template <class ELFT>
-MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
- MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
- const MipsAbiInfoHandler<ELFT> &abiInfo)
- : DynamicLibraryWriter<ELFT>(ctx, layout),
- _writeHelper(ctx, layout, abiInfo), _targetLayout(layout) {}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
- result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
- DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
- _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() {
- DynamicLibraryWriter<ELFT>::createDefaultSections();
- _reginfo = _writeHelper.createOptionsSection(this->_alloc);
- if (_reginfo)
- this->_layout.addSection(_reginfo.get());
- _abiFlags = _writeHelper.createAbiFlagsSection(this->_alloc);
- if (_abiFlags)
- this->_layout.addSection(_abiFlags.get());
-}
-
-template <class ELFT>
-std::error_code MipsDynamicLibraryWriter<ELFT>::setELFHeader() {
- DynamicLibraryWriter<ELFT>::setELFHeader();
- _writeHelper.setELFHeader(*this->_elfHeader);
- return std::error_code();
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
-MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELFT>>(
- new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
-MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
- return unique_bump_ptr<DynamicTable<ELFT>>(
- new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
-MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
- this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-template class MipsDynamicLibraryWriter<ELF32BE>;
-template class MipsDynamicLibraryWriter<ELF32LE>;
-template class MipsDynamicLibraryWriter<ELF64BE>;
-template class MipsDynamicLibraryWriter<ELF64LE>;
-
-template <class ELFT>
-MipsExecutableWriter<ELFT>::MipsExecutableWriter(
- MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
- const MipsAbiInfoHandler<ELFT> &abiInfo)
- : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout, abiInfo),
- _targetLayout(layout) {}
-
-template <class ELFT>
-std::error_code MipsExecutableWriter<ELFT>::setELFHeader() {
- std::error_code ec = ExecutableWriter<ELFT>::setELFHeader();
- if (ec)
- return ec;
-
- StringRef entryName = this->_ctx.entrySymbolName();
- if (const AtomLayout *al = this->_layout.findAtomLayoutByName(entryName)) {
- const auto *ea = cast<DefinedAtom>(al->_atom);
- if (ea->codeModel() == DefinedAtom::codeMipsMicro ||
- ea->codeModel() == DefinedAtom::codeMipsMicroPIC)
- // Adjust entry symbol value if this symbol is microMIPS encoded.
- this->_elfHeader->e_entry(al->_virtualAddr | 1);
- }
-
- _writeHelper.setELFHeader(*this->_elfHeader);
- return std::error_code();
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- // MIPS ABI requires to add to dynsym even undefined symbols
- // if they have a corresponding entries in a global part of GOT.
- for (auto sec : this->_layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms()) {
- if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) {
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- continue;
- }
-
- const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
- if (!da)
- continue;
-
- if (da->dynamicExport() != DefinedAtom::dynamicExportAlways &&
- !this->_ctx.isDynamicallyExportedSymbol(da->name()) &&
- !(this->_ctx.shouldExportDynamic() &&
- da->scope() == Atom::Scope::scopeGlobal))
- continue;
-
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
-
- for (const UndefinedAtom *a : file.undefined())
- // FIXME (simon): Consider to move this check to the
- // MipsELFUndefinedAtom class method. That allows to
- // handle more complex coditions in the future.
- if (_targetLayout.getGOTSection().hasGlobalGOTEntry(a))
- this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
-
- // Skip our immediate parent class method
- // ExecutableWriter<ELFT>::buildDynamicSymbolTable because we replaced it
- // with our own version. Call OutputELFWriter directly.
- OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter<ELFT>::createImplicitFiles(result);
- result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
- _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT> void MipsExecutableWriter<ELFT>::createDefaultSections() {
- ExecutableWriter<ELFT>::createDefaultSections();
- _reginfo = _writeHelper.createOptionsSection(this->_alloc);
- if (_reginfo)
- this->_layout.addSection(_reginfo.get());
- _abiFlags = _writeHelper.createAbiFlagsSection(this->_alloc);
- if (_abiFlags)
- this->_layout.addSection(_abiFlags.get());
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
-MipsExecutableWriter<ELFT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELFT>>(
- new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
-MipsExecutableWriter<ELFT>::createDynamicTable() {
- return unique_bump_ptr<DynamicTable<ELFT>>(
- new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
-MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
- this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-template class MipsExecutableWriter<ELF32BE>;
-template class MipsExecutableWriter<ELF32LE>;
-template class MipsExecutableWriter<ELF64BE>;
-template class MipsExecutableWriter<ELF64LE>;
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (removed)
@@ -1,102 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.h -------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
-
-#include "DynamicLibraryWriter.h"
-#include "ExecutableWriter.h"
-#include "MipsAbiInfoHandler.h"
-#include "MipsLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT> class MipsTargetLayout;
-
-template <typename ELFT> class MipsELFWriter {
-public:
- MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
- const MipsAbiInfoHandler<ELFT> &abiInfo);
-
- void setELFHeader(ELFHeader<ELFT> &elfHeader);
-
- void finalizeMipsRuntimeAtomValues();
-
- std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile();
- unique_bump_ptr<Section<ELFT>>
- createOptionsSection(llvm::BumpPtrAllocator &alloc);
- unique_bump_ptr<Section<ELFT>>
- createAbiFlagsSection(llvm::BumpPtrAllocator &alloc);
-
-private:
- MipsLinkingContext &_ctx;
- MipsTargetLayout<ELFT> &_targetLayout;
- const MipsAbiInfoHandler<ELFT> &_abiInfo;
-
- void setAtomValue(StringRef name, uint64_t value);
-};
-
-template <class ELFT>
-class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
-public:
- MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout,
- const MipsAbiInfoHandler<ELFT> &abiInfo);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
-
- std::error_code setELFHeader() override;
-
- unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
- unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
- MipsELFWriter<ELFT> _writeHelper;
- MipsTargetLayout<ELFT> &_targetLayout;
- unique_bump_ptr<Section<ELFT>> _reginfo;
- unique_bump_ptr<Section<ELFT>> _abiFlags;
-};
-
-template <class ELFT>
-class MipsExecutableWriter : public ExecutableWriter<ELFT> {
-public:
- MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
- const MipsAbiInfoHandler<ELFT> &abiInfo);
-
-protected:
- void buildDynamicSymbolTable(const File &file) override;
-
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
- std::error_code setELFHeader() override;
-
- unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
- unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
- MipsELFWriter<ELFT> _writeHelper;
- MipsTargetLayout<ELFT> &_targetLayout;
- unique_bump_ptr<Section<ELFT>> _reginfo;
- unique_bump_ptr<Section<ELFT>> _abiFlags;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (removed)
@@ -1,164 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp -------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Atoms.h"
-#include "MipsCtorsOrderPass.h"
-#include "MipsLinkingContext.h"
-#include "MipsRelocationPass.h"
-#include "MipsTargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<ELFLinkingContext>
-elf::createMipsLinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::mips ||
- triple.getArch() == llvm::Triple::mipsel ||
- triple.getArch() == llvm::Triple::mips64 ||
- triple.getArch() == llvm::Triple::mips64el)
- return llvm::make_unique<MipsLinkingContext>(triple);
- return nullptr;
-}
-
-static std::unique_ptr<TargetHandler> createTarget(llvm::Triple triple,
- MipsLinkingContext &ctx) {
- switch (triple.getArch()) {
- case llvm::Triple::mips:
- return llvm::make_unique<MipsTargetHandler<ELF32BE>>(ctx);
- case llvm::Triple::mipsel:
- return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
- case llvm::Triple::mips64:
- return llvm::make_unique<MipsTargetHandler<ELF64BE>>(ctx);
- case llvm::Triple::mips64el:
- return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
- default:
- llvm_unreachable("Unhandled arch");
- }
-}
-
-MipsLinkingContext::MipsLinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, createTarget(triple, *this)) {}
-
-uint64_t MipsLinkingContext::getBaseAddress() const {
- if (_baseAddress != 0 || getOutputELFType() != llvm::ELF::ET_EXEC)
- return _baseAddress;
- switch (getAbi()) {
- case MipsAbi::O32:
- return 0x0400000;
- case MipsAbi::N32:
- return 0x10000000;
- case MipsAbi::N64:
- return 0x120000000;
- }
- llvm_unreachable("unknown MIPS ABI flag");
-}
-
-StringRef MipsLinkingContext::entrySymbolName() const {
- if (_outputELFType == elf::ET_EXEC && _entrySymbolName.empty())
- return "__start";
- return _entrySymbolName;
-}
-
-StringRef MipsLinkingContext::getDefaultInterpreter() const {
- switch (getAbi()) {
- case MipsAbi::O32:
- return "/lib/ld.so.1";
- case MipsAbi::N32:
- return "/lib32/ld.so.1";
- case MipsAbi::N64:
- return "/lib64/ld.so.1";
- }
- llvm_unreachable("unknown MIPS ABI flag");
-}
-
-void MipsLinkingContext::addPasses(PassManager &pm) {
- auto pass = createMipsRelocationPass(*this);
- if (pass)
- pm.add(std::move(pass));
- ELFLinkingContext::addPasses(pm);
- pm.add(llvm::make_unique<elf::MipsCtorsOrderPass>());
-}
-
-bool MipsLinkingContext::isDynamicRelocation(const Reference &r) const {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::Mips);
- switch (r.kindValue()) {
- case llvm::ELF::R_MIPS_COPY:
- case llvm::ELF::R_MIPS_REL32:
- return true;
- case llvm::ELF::R_MIPS_TLS_DTPMOD32:
- case llvm::ELF::R_MIPS_TLS_DTPREL32:
- case llvm::ELF::R_MIPS_TLS_TPREL32:
- case llvm::ELF::R_MIPS_TLS_DTPMOD64:
- case llvm::ELF::R_MIPS_TLS_DTPREL64:
- case llvm::ELF::R_MIPS_TLS_TPREL64:
- return isDynamic();
- default:
- return false;
- }
-}
-
-bool MipsLinkingContext::isCopyRelocation(const Reference &r) const {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::Mips);
- if (r.kindValue() == llvm::ELF::R_MIPS_COPY)
- return true;
- return false;
-}
-
-bool MipsLinkingContext::isPLTRelocation(const Reference &r) const {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::Mips);
- switch (r.kindValue()) {
- case llvm::ELF::R_MIPS_JUMP_SLOT:
- return true;
- default:
- return false;
- }
-}
-
-bool MipsLinkingContext::isRelativeReloc(const Reference &r) const {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::Mips);
- switch (r.kindValue()) {
- case llvm::ELF::R_MIPS_REL32:
- case llvm::ELF::R_MIPS_GPREL16:
- case llvm::ELF::R_MIPS_GPREL32:
- return true;
- default:
- return false;
- }
-}
-
-MipsAbi MipsLinkingContext::getAbi() const {
- auto &handler = static_cast<MipsBaseTargetHandler &>(getTargetHandler());
- return handler.getAbi();
-}
-
-const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/Mips.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
- LLD_KIND_STRING_ENTRY(LLD_R_MIPS_32_HI16),
- LLD_KIND_STRING_ENTRY(LLD_R_MIPS_64_HI16),
- LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
- LLD_KIND_STRING_ENTRY(LLD_R_MIPS_STO_PLT),
- LLD_KIND_STRING_ENTRY(LLD_R_MICROMIPS_GLOBAL_26_S1),
- LLD_KIND_STRING_END
-};
-
-void MipsLinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF,
- Reference::KindArch::Mips, kindStrings);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (removed)
@@ -1,56 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_LINKING_CONTEXT_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_LINKING_CONTEXT_H
-
-#include "MipsAbiInfoHandler.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-/// \brief Mips internal references.
-enum {
- /// \brief Do nothing but mark GOT entry as a global one.
- LLD_R_MIPS_GLOBAL_GOT = 1024,
- /// \brief Apply high 16 bits of symbol + addend.
- LLD_R_MIPS_32_HI16 = 1025,
- /// \brief The same as R_MIPS_26 but for global symbols.
- LLD_R_MIPS_GLOBAL_26 = 1026,
- /// \brief Represents a reference between PLT and dynamic symbol.
- LLD_R_MIPS_STO_PLT = 1029,
- /// \brief The same as R_MICROMIPS_26_S1 but for global symbols.
- LLD_R_MICROMIPS_GLOBAL_26_S1 = 1030,
- /// \brief Apply high 32+16 bits of symbol + addend.
- LLD_R_MIPS_64_HI16 = 1031,
-};
-
-class MipsLinkingContext final : public ELFLinkingContext {
-public:
- MipsLinkingContext(llvm::Triple triple);
-
- void registerRelocationNames(Registry &r) override;
- int getMachineType() const override { return llvm::ELF::EM_MIPS; }
- uint64_t getBaseAddress() const override;
- StringRef entrySymbolName() const override;
- StringRef getDefaultInterpreter() const override;
- void addPasses(PassManager &pm) override;
- bool isRelaOutputFormat() const override { return false; }
- bool isDynamicRelocation(const Reference &r) const override;
- bool isCopyRelocation(const Reference &r) const override;
- bool isPLTRelocation(const Reference &r) const override;
- bool isRelativeReloc(const Reference &r) const override;
-
- MipsAbi getAbi() const;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (removed)
@@ -1,687 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsLinkingContext.h"
-#include "MipsRelocationHandler.h"
-#include "MipsTargetLayout.h"
-#include "llvm/Support/Format.h"
-
-using namespace lld;
-using namespace elf;
-using namespace llvm::ELF;
-using namespace llvm::support;
-
-namespace {
-enum class CrossJumpMode {
- None, // Not a jump or non-isa-cross jump
- ToRegular, // cross isa jump to regular symbol
- ToMicro, // cross isa jump to microMips symbol
- ToMicroJalr// cross isa jump to microMips symbol referenced by R_MIPS_JALR
-};
-
-typedef std::function<std::error_code(int64_t, bool)> OverflowChecker;
-
-static std::error_code dummyCheck(int64_t, bool) {
- return std::error_code();
-}
-
-template <int BITS> static std::error_code signedCheck(int64_t res, bool) {
- if (llvm::isInt<BITS>(res))
- return std::error_code();
- return make_out_of_range_reloc_error();
-}
-
-template <int BITS>
-static std::error_code gpDispCheck(int64_t res, bool isGpDisp) {
- if (!isGpDisp || llvm::isInt<BITS>(res))
- return std::error_code();
- return make_out_of_range_reloc_error();
-}
-
-struct MipsRelocationParams {
- uint8_t _size; // Relocations's size in bytes
- uint64_t _mask; // Read/write mask of relocation
- uint8_t _shift; // Relocation's addendum left shift size
- bool _shuffle; // Relocation's addendum/result needs to be shuffled
- OverflowChecker _overflow; // Check the relocation result
-};
-
-template <class ELFT> class RelocationHandler : public TargetRelocationHandler {
-public:
- RelocationHandler(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
- : _ctx(ctx), _targetLayout(layout) {}
-
- std::error_code applyRelocation(ELFWriter &writer,
- llvm::FileOutputBuffer &buf,
- const AtomLayout &atom,
- const Reference &ref) const override;
-
-private:
- MipsLinkingContext &_ctx;
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-}
-
-static MipsRelocationParams getRelocationParams(uint32_t rType) {
- switch (rType) {
- case R_MIPS_NONE:
- return {4, 0x0, 0, false, dummyCheck};
- case R_MIPS_64:
- case R_MIPS_SUB:
- return {8, 0xffffffffffffffffull, 0, false, dummyCheck};
- case R_MICROMIPS_SUB:
- return {8, 0xffffffffffffffffull, 0, true, dummyCheck};
- case R_MIPS_32:
- case R_MIPS_GPREL32:
- case R_MIPS_REL32:
- case R_MIPS_PC32:
- case R_MIPS_EH:
- return {4, 0xffffffff, 0, false, dummyCheck};
- case LLD_R_MIPS_32_HI16:
- return {4, 0xffff0000, 0, false, dummyCheck};
- case LLD_R_MIPS_64_HI16:
- return {8, 0xffffffffffff0000ull, 0, false, dummyCheck};
- case R_MIPS_26:
- case LLD_R_MIPS_GLOBAL_26:
- return {4, 0x3ffffff, 2, false, dummyCheck};
- case R_MIPS_PC16:
- return {4, 0xffff, 2, false, signedCheck<18>};
- case R_MIPS_PC18_S3:
- return {4, 0x3ffff, 3, false, signedCheck<21>};
- case R_MIPS_PC19_S2:
- return {4, 0x7ffff, 2, false, signedCheck<21>};
- case R_MIPS_PC21_S2:
- return {4, 0x1fffff, 2, false, signedCheck<23>};
- case R_MIPS_PC26_S2:
- return {4, 0x3ffffff, 2, false, signedCheck<28>};
- case R_MIPS_HI16:
- return {4, 0xffff, 0, false, gpDispCheck<16>};
- case R_MIPS_LO16:
- case R_MIPS_HIGHER:
- case R_MIPS_HIGHEST:
- return {4, 0xffff, 0, false, dummyCheck};
- case R_MIPS_16:
- case R_MIPS_PCHI16:
- case R_MIPS_PCLO16:
- case R_MIPS_GOT16:
- case R_MIPS_CALL16:
- case R_MIPS_GOT_DISP:
- case R_MIPS_GOT_PAGE:
- case R_MIPS_GOT_OFST:
- case R_MIPS_GPREL16:
- case R_MIPS_TLS_GD:
- case R_MIPS_TLS_LDM:
- case R_MIPS_TLS_GOTTPREL:
- case R_MIPS_LITERAL:
- return {4, 0xffff, 0, false, signedCheck<16>};
- case R_MIPS_GOT_HI16:
- case R_MIPS_GOT_LO16:
- case R_MIPS_CALL_HI16:
- case R_MIPS_CALL_LO16:
- case R_MIPS_TLS_DTPREL_HI16:
- case R_MIPS_TLS_DTPREL_LO16:
- case R_MIPS_TLS_TPREL_HI16:
- case R_MIPS_TLS_TPREL_LO16:
- return {4, 0xffff, 0, false, dummyCheck};
- case R_MICROMIPS_GPREL16:
- case R_MICROMIPS_LITERAL:
- return {4, 0xffff, 0, true, signedCheck<16>};
- case R_MICROMIPS_GPREL7_S2:
- return {4, 0x7f, 2, false, signedCheck<9>};
- case R_MICROMIPS_GOT_HI16:
- case R_MICROMIPS_GOT_LO16:
- case R_MICROMIPS_CALL_HI16:
- case R_MICROMIPS_CALL_LO16:
- case R_MICROMIPS_TLS_DTPREL_HI16:
- case R_MICROMIPS_TLS_DTPREL_LO16:
- case R_MICROMIPS_TLS_TPREL_HI16:
- case R_MICROMIPS_TLS_TPREL_LO16:
- return {4, 0xffff, 0, true, dummyCheck};
- case R_MICROMIPS_26_S1:
- case LLD_R_MICROMIPS_GLOBAL_26_S1:
- return {4, 0x3ffffff, 1, true, dummyCheck};
- case R_MICROMIPS_HI16:
- return {4, 0xffff, 0, true, gpDispCheck<16>};
- case R_MICROMIPS_LO16:
- case R_MICROMIPS_HI0_LO16:
- case R_MICROMIPS_HIGHER:
- case R_MICROMIPS_HIGHEST:
- return {4, 0xffff, 0, true, dummyCheck};
- case R_MICROMIPS_PC16_S1:
- return {4, 0xffff, 1, true, signedCheck<17>};
- case R_MICROMIPS_PC7_S1:
- return {4, 0x7f, 1, false, signedCheck<8>};
- case R_MICROMIPS_PC10_S1:
- return {4, 0x3ff, 1, false, signedCheck<11>};
- case R_MICROMIPS_PC23_S2:
- return {4, 0x7fffff, 2, true, signedCheck<25>};
- case R_MICROMIPS_PC18_S3:
- return {4, 0x3ffff, 3, true, signedCheck<21>};
- case R_MICROMIPS_PC19_S2:
- return {4, 0x7ffff, 2, true, signedCheck<21>};
- case R_MICROMIPS_PC21_S2:
- return {4, 0x1fffff, 2, true, signedCheck<23>};
- case R_MICROMIPS_PC26_S2:
- return {4, 0x3ffffff, 2, true, signedCheck<28>};
- case R_MICROMIPS_GOT16:
- case R_MICROMIPS_CALL16:
- case R_MICROMIPS_TLS_GD:
- case R_MICROMIPS_TLS_LDM:
- case R_MICROMIPS_TLS_GOTTPREL:
- case R_MICROMIPS_GOT_DISP:
- case R_MICROMIPS_GOT_PAGE:
- case R_MICROMIPS_GOT_OFST:
- return {4, 0xffff, 0, true, signedCheck<16>};
- case R_MIPS_JALR:
- return {4, 0xffffffff, 0, false, dummyCheck};
- case R_MICROMIPS_JALR:
- return {4, 0x0, 0, true, dummyCheck};
- case R_MIPS_JUMP_SLOT:
- case R_MIPS_COPY:
- case R_MIPS_TLS_DTPMOD32:
- case R_MIPS_TLS_DTPREL32:
- case R_MIPS_TLS_TPREL32:
- return {4, 0xffffffff, 0, false, dummyCheck};
- case R_MIPS_TLS_DTPMOD64:
- case R_MIPS_TLS_DTPREL64:
- case R_MIPS_TLS_TPREL64:
- return {8, 0xffffffffffffffffull, 0, false, dummyCheck};
- case LLD_R_MIPS_GLOBAL_GOT:
- case LLD_R_MIPS_STO_PLT:
- // Do nothing.
- return {4, 0x0, 0, false, dummyCheck};
- default:
- llvm_unreachable("Unknown relocation");
- }
-}
-
-template <class ELFT>
-static uint64_t relocRead(const MipsRelocationParams ¶ms,
- const uint8_t *loc);
-
-static int64_t getHi16(int64_t value) {
- return ((value + 0x8000) >> 16) & 0xffff;
-}
-
-static int64_t getHigher16(int64_t value) {
- return ((value + 0x80008000ull) >> 32) & 0xffff;
-}
-
-static int64_t getHighest16(int64_t value) {
- return ((value + 0x800080008000ull) >> 48) & 0xffff;
-}
-
-static int64_t maskLow16(int64_t value) {
- return (value + 0x8000) & ~0xffff;
-}
-
-/// R_MIPS_GOT_OFST, R_MICROMIPS_GOT_OFST
-/// rel16 offset of (S+A) from the page pointer (verify)
-static int32_t relocGOTOfst(uint64_t S, int64_t A) {
- int64_t page = maskLow16(S + A);
- return S + A - page;
-}
-
-/// \brief R_MIPS_PC16
-/// local/external: (S + A - P) >> 2
-static ErrorOr<int64_t> relocPc16(uint64_t P, uint64_t S, int64_t A) {
- if ((S + A) & 3)
- return make_unaligned_range_reloc_error();
- return S + A - P;
-}
-
-/// \brief R_MIPS_PC18_S3, R_MICROMIPS_PC18_S3
-/// local/external: (S + A - P) >> 3 (P with cleared 3 less significant bits)
-static ErrorOr<int64_t> relocPc18(uint64_t P, uint64_t S, int64_t A) {
- if ((S + A) & 6)
- return make_unaligned_range_reloc_error();
- return S + A - ((P | 7) ^ 7);
-}
-
-/// \brief R_MIPS_PC19_S2, R_MICROMIPS_PC19_S2, R_MIPS_PC21_S2,
-/// R_MICROMIPS_PC21_S2, R_MIPS_PC26_S2, R_MICROMIPS_PC26_S2
-/// local/external: (S + A - P) >> 2
-static ErrorOr<int64_t> relocPcS2(uint64_t P, uint64_t S, int64_t A) {
- if ((S + A) & 2)
- return make_unaligned_range_reloc_error();
- return S + A - P;
-}
-
-template <class ELFT>
-static ErrorOr<int64_t> relocJalr(uint64_t P, uint64_t S, bool isCrossJump,
- uint8_t *location) {
- uint64_t ins = relocRead<ELFT>(getRelocationParams(R_MIPS_JALR), location);
- if (isCrossJump)
- return ins;
- int64_t off = S - P - 4;
- if (!llvm::isInt<18>(off))
- return ins;
- if (ins == 0x0320f809) // jalr t9
- return 0x04110000 | ((off >> 2) & 0xffff);
- if (ins == 0x03200008) // jr t9
- return 0x10000000 | ((off >> 2) & 0xffff);
- return ins;
-}
-
-static int64_t relocRel32(uint64_t S, int64_t A, bool isLocal) {
- // If output relocation format is REL and the input one is RELA, the only
- // method to transfer the relocation addend from the input relocation
- // to the output dynamic relocation is to save this addend to the location
- // modified by R_MIPS_REL32.
- return isLocal ? S + A : A;
-}
-
-static std::error_code adjustJumpOpCode(uint64_t &ins, uint64_t tgt,
- CrossJumpMode mode) {
- if (mode == CrossJumpMode::None || mode == CrossJumpMode::ToMicroJalr)
- return std::error_code();
-
- bool toMicro = mode == CrossJumpMode::ToMicro;
- uint32_t opNative = toMicro ? 0x03 : 0x3d;
- uint32_t opCross = toMicro ? 0x1d : 0x3c;
-
- if ((tgt & 1) != toMicro)
- return make_dynamic_error_code("Incorrect bit 0 for the jalx target");
-
- if (tgt & 2)
- return make_dynamic_error_code(Twine("The jalx target 0x") +
- Twine::utohexstr(tgt) +
- " is not word-aligned");
- uint8_t op = ins >> 26;
- if (op != opNative && op != opCross)
- return make_dynamic_error_code(Twine("Unsupported jump opcode (0x") +
- Twine::utohexstr(op) +
- ") for ISA modes cross call");
-
- ins = (ins & ~(0x3f << 26)) | (opCross << 26);
- return std::error_code();
-}
-
-static bool isMicroMipsAtom(const Atom *a) {
- if (const auto *da = dyn_cast<DefinedAtom>(a))
- return da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC;
- return false;
-}
-
-static CrossJumpMode getCrossJumpMode(const Reference &ref) {
- if (!isa<DefinedAtom>(ref.target()))
- return CrossJumpMode::None;
- bool isTgtMicro = isMicroMipsAtom(ref.target());
- switch (ref.kindValue()) {
- case R_MIPS_JALR:
- return isTgtMicro ? CrossJumpMode::ToMicroJalr : CrossJumpMode::None;
- case R_MIPS_26:
- case LLD_R_MIPS_GLOBAL_26:
- return isTgtMicro ? CrossJumpMode::ToMicro : CrossJumpMode::None;
- case R_MICROMIPS_26_S1:
- case LLD_R_MICROMIPS_GLOBAL_26_S1:
- return isTgtMicro ? CrossJumpMode::None : CrossJumpMode::ToRegular;
- default:
- return CrossJumpMode::None;
- }
-}
-
-template <class ELFT>
-static ErrorOr<int64_t>
-calculateRelocation(Reference::KindValue kind, Reference::Addend addend,
- uint64_t tgtAddr, uint64_t relAddr, uint64_t gpAddr,
- uint8_t *location, bool isGP, bool isCrossJump,
- bool isDynamic, bool isLocalSym) {
- switch (kind) {
- case R_MIPS_NONE:
- return 0;
- case R_MIPS_16:
- case R_MIPS_32:
- case R_MIPS_64:
- case R_MIPS_TLS_DTPREL_LO16:
- case R_MIPS_TLS_TPREL_LO16:
- case R_MICROMIPS_TLS_DTPREL_LO16:
- case R_MICROMIPS_TLS_TPREL_LO16:
- case LLD_R_MIPS_GLOBAL_26:
- case LLD_R_MICROMIPS_GLOBAL_26_S1:
- return tgtAddr + addend;
- case R_MIPS_SUB:
- case R_MICROMIPS_SUB:
- return tgtAddr - addend;
- case R_MIPS_26:
- return tgtAddr + (addend | (relAddr & 0xf0000000));
- case R_MICROMIPS_26_S1:
- return tgtAddr + (addend | (relAddr & 0xf8000000));
- case R_MIPS_HI16:
- case R_MICROMIPS_HI16:
- return getHi16(tgtAddr + addend - (isGP ? relAddr : 0));
- case R_MIPS_PCHI16:
- return getHi16(tgtAddr + addend - relAddr);
- case R_MIPS_LO16:
- return tgtAddr + addend - (isGP ? relAddr - 4 : 0);
- case R_MICROMIPS_LO16:
- case R_MICROMIPS_HI0_LO16:
- return tgtAddr + addend - (isGP ? relAddr - 3 : 0);
- case R_MIPS_GOT_HI16:
- case R_MIPS_CALL_HI16:
- case R_MICROMIPS_GOT_HI16:
- case R_MICROMIPS_CALL_HI16:
- return getHi16(tgtAddr - gpAddr);
- case R_MIPS_HIGHER:
- case R_MICROMIPS_HIGHER:
- return getHigher16(tgtAddr + addend);
- case R_MIPS_HIGHEST:
- case R_MICROMIPS_HIGHEST:
- return getHighest16(tgtAddr + addend);
- case R_MIPS_GOT_LO16:
- case R_MIPS_CALL_LO16:
- case R_MICROMIPS_GOT_LO16:
- case R_MICROMIPS_CALL_LO16:
- case R_MIPS_EH:
- case R_MIPS_GOT16:
- case R_MIPS_CALL16:
- case R_MIPS_GOT_DISP:
- case R_MIPS_GOT_PAGE:
- case R_MICROMIPS_GOT_DISP:
- case R_MICROMIPS_GOT_PAGE:
- case R_MICROMIPS_GOT16:
- case R_MICROMIPS_CALL16:
- case R_MIPS_TLS_GD:
- case R_MIPS_TLS_LDM:
- case R_MIPS_TLS_GOTTPREL:
- case R_MICROMIPS_TLS_GD:
- case R_MICROMIPS_TLS_LDM:
- case R_MICROMIPS_TLS_GOTTPREL:
- return tgtAddr - gpAddr;
- case R_MIPS_GPREL16:
- case R_MIPS_GPREL32:
- case R_MIPS_LITERAL:
- case R_MICROMIPS_GPREL16:
- case R_MICROMIPS_GPREL7_S2:
- case R_MICROMIPS_LITERAL:
- return tgtAddr + addend - gpAddr;
- case R_MIPS_GOT_OFST:
- case R_MICROMIPS_GOT_OFST:
- return relocGOTOfst(tgtAddr, addend);
- case R_MIPS_PC16:
- return relocPc16(relAddr, tgtAddr, addend);
- case R_MIPS_PC18_S3:
- case R_MICROMIPS_PC18_S3:
- return relocPc18(relAddr, tgtAddr, addend);
- case R_MIPS_PC19_S2:
- case R_MICROMIPS_PC19_S2:
- case R_MIPS_PC21_S2:
- case R_MICROMIPS_PC21_S2:
- case R_MIPS_PC26_S2:
- case R_MICROMIPS_PC26_S2:
- return relocPcS2(relAddr, tgtAddr, addend);
- case R_MIPS_PC32:
- case R_MIPS_PCLO16:
- case R_MICROMIPS_PC7_S1:
- case R_MICROMIPS_PC10_S1:
- case R_MICROMIPS_PC16_S1:
- case R_MICROMIPS_PC23_S2:
- return tgtAddr + addend - relAddr;
- case R_MIPS_TLS_DTPREL_HI16:
- case R_MIPS_TLS_TPREL_HI16:
- case R_MICROMIPS_TLS_DTPREL_HI16:
- case R_MICROMIPS_TLS_TPREL_HI16:
- return getHi16(tgtAddr + addend);
- case R_MIPS_JALR:
- return relocJalr<ELFT>(relAddr, tgtAddr, isCrossJump, location);
- case R_MICROMIPS_JALR:
- // We do not do JALR optimization now.
- return 0;
- case R_MIPS_REL32:
- return relocRel32(tgtAddr, addend, isLocalSym);
- case R_MIPS_JUMP_SLOT:
- case R_MIPS_COPY:
- // Ignore runtime relocations.
- return 0;
- case R_MIPS_TLS_DTPMOD32:
- case R_MIPS_TLS_DTPMOD64:
- return isDynamic ? 0 : 1;
- case R_MIPS_TLS_DTPREL32:
- case R_MIPS_TLS_DTPREL64:
- return isDynamic ? 0 : tgtAddr + addend - 0x8000;
- case R_MIPS_TLS_TPREL32:
- case R_MIPS_TLS_TPREL64:
- return isDynamic ? 0 : tgtAddr + addend - 0x7000;
- case LLD_R_MIPS_32_HI16:
- case LLD_R_MIPS_64_HI16:
- return maskLow16(tgtAddr + addend);
- case LLD_R_MIPS_STO_PLT:
- case LLD_R_MIPS_GLOBAL_GOT:
- // Do nothing.
- return 0;
- default:
- return make_unhandled_reloc_error();
- }
-}
-
-template <class ELFT>
-static uint64_t relocRead(const MipsRelocationParams ¶ms,
- const uint8_t *loc) {
- assert((params._size == 4 || params._size == 8) && "Unexpected size");
- uint64_t data = 0;
- memcpy(&data, loc, params._size);
- if (params._shuffle) {
- using namespace endian;
- auto p = reinterpret_cast<const uint8_t *>(&data);
- uint32_t a = readNext<uint16_t, ELFT::TargetEndianness, unaligned>(p);
- uint32_t b = read<uint16_t, ELFT::TargetEndianness, unaligned>(p);
- write<uint32_t, ELFT::TargetEndianness, unaligned>(&data, a << 16 | b);
- }
- switch (params._size) {
- case 4:
- return endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(&data);
- case 8:
- return endian::read<uint64_t, ELFT::TargetEndianness, unaligned>(&data);
- default:
- llvm_unreachable("Unexpected size");
- }
-}
-
-template <class ELFT>
-static void relocWrite(uint64_t data, const MipsRelocationParams ¶ms,
- uint8_t *loc) {
- switch (params._size) {
- case 4:
- endian::write<uint32_t, ELFT::TargetEndianness, unaligned>(loc, data);
- break;
- case 8:
- endian::write<uint64_t, ELFT::TargetEndianness, unaligned>(loc, data);
- break;
- default:
- llvm_unreachable("Unexpected size");
- }
- if (params._shuffle) {
- uint32_t v = endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(loc);
- uint16_t a = v >> 16;
- uint16_t b = v & 0xffff;
- endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc, a);
- endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc + 2, b);
- }
-}
-
-static uint32_t getRelKind(const Reference &ref, size_t num) {
- if (num == 0)
- return ref.kindValue();
- if (num > 2)
- return R_MIPS_NONE;
- return (ref.tag() >> (8 * (num - 1))) & 0xff;
-}
-
-static uint8_t getRelShift(Reference::KindValue kind,
- const MipsRelocationParams ¶ms,
- bool isCrossJump) {
- uint8_t shift = params._shift;
- if (isCrossJump &&
- (kind == R_MICROMIPS_26_S1 || kind == LLD_R_MICROMIPS_GLOBAL_26_S1))
- return 2;
- return shift;
-}
-
-static bool isLocalTarget(const Atom *a) {
- if (auto *da = dyn_cast<DefinedAtom>(a))
- return da->scope() == Atom::scopeTranslationUnit;
- return false;
-}
-
-template <class ELFT>
-std::error_code RelocationHandler<ELFT>::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::Mips);
-
- uint64_t gpAddr = _targetLayout.getGPAddr();
- bool isGpDisp = ref.target()->name() == "_gp_disp";
- bool isLocalSym = isLocalTarget(ref.target());
-
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *location = atomContent + ref.offsetInAtom();
- uint64_t tgtAddr = writer.addressOfAtom(ref.target());
- uint64_t relAddr = atom._virtualAddr + ref.offsetInAtom();
-
- if (isMicroMipsAtom(ref.target()))
- tgtAddr |= 1;
-
- CrossJumpMode jumpMode = getCrossJumpMode(ref);
- bool isCrossJump = jumpMode != CrossJumpMode::None;
-
- uint64_t sym = tgtAddr;
- ErrorOr<int64_t> res = ref.addend();
- Reference::KindValue lastRel = R_MIPS_NONE;
-
- for (size_t relNum = 0; relNum < 3; ++relNum) {
- Reference::KindValue kind = getRelKind(ref, relNum);
- if (kind == R_MIPS_NONE)
- break;
- auto params = getRelocationParams(kind);
- res = calculateRelocation<ELFT>(kind, *res, sym, relAddr, gpAddr, location,
- isGpDisp, isCrossJump, _ctx.isDynamic(),
- isLocalSym);
- if (auto ec = res.getError())
- return ec;
- // Check result for the last relocation only.
- if (getRelKind(ref, relNum + 1) == R_MIPS_NONE) {
- if (auto ec = params._overflow(*res, isGpDisp))
- return ec;
- }
- res = *res >> getRelShift(kind, params, isCrossJump);
- // FIXME (simon): Handle r_ssym value.
- sym = 0;
- isGpDisp = false;
- isCrossJump = false;
- lastRel = kind;
- }
-
- auto params = getRelocationParams(lastRel);
- uint64_t ins = relocRead<ELFT>(params, location);
- if (auto ec = adjustJumpOpCode(ins, tgtAddr, jumpMode))
- return ec;
-
- ins = (ins & ~params._mask) | (*res & params._mask);
- relocWrite<ELFT>(ins, params, location);
-
- return std::error_code();
-}
-
-namespace lld {
-namespace elf {
-
-template <>
-std::unique_ptr<TargetRelocationHandler>
-createMipsRelocationHandler<ELF32BE>(MipsLinkingContext &ctx,
- MipsTargetLayout<ELF32BE> &layout) {
- return llvm::make_unique<RelocationHandler<ELF32BE>>(ctx, layout);
-}
-
-template <>
-std::unique_ptr<TargetRelocationHandler>
-createMipsRelocationHandler<ELF32LE>(MipsLinkingContext &ctx,
- MipsTargetLayout<ELF32LE> &layout) {
- return llvm::make_unique<RelocationHandler<ELF32LE>>(ctx, layout);
-}
-
-template <>
-std::unique_ptr<TargetRelocationHandler>
-createMipsRelocationHandler<ELF64BE>(MipsLinkingContext &ctx,
- MipsTargetLayout<ELF64BE> &layout) {
- return llvm::make_unique<RelocationHandler<ELF64BE>>(ctx, layout);
-}
-
-template <>
-std::unique_ptr<TargetRelocationHandler>
-createMipsRelocationHandler<ELF64LE>(MipsLinkingContext &ctx,
- MipsTargetLayout<ELF64LE> &layout) {
- return llvm::make_unique<RelocationHandler<ELF64LE>>(ctx, layout);
-}
-
-template <class ELFT>
-Reference::Addend readMipsRelocAddend(Reference::KindValue kind,
- const uint8_t *content) {
- auto params = getRelocationParams(kind);
- uint64_t ins = relocRead<ELFT>(params, content);
- int64_t res = (ins & params._mask) << params._shift;
- switch (kind) {
- case R_MIPS_GPREL16:
- case R_MICROMIPS_GPREL16:
- case R_MIPS_PCLO16:
- case R_MIPS_LITERAL:
- case R_MICROMIPS_LITERAL:
- return llvm::SignExtend32<16>(res);
- case R_MIPS_PC16:
- return llvm::SignExtend32<18>(res);
- case R_MICROMIPS_GPREL7_S2:
- return llvm::SignExtend32<9>(res);
- case R_MICROMIPS_PC7_S1:
- return llvm::SignExtend32<8>(res);
- case R_MICROMIPS_PC10_S1:
- return llvm::SignExtend32<11>(res);
- case R_MIPS_16:
- return llvm::SignExtend32<16>(res);
- case R_MICROMIPS_PC16_S1:
- return llvm::SignExtend32<17>(res);
- case R_MIPS_PC18_S3:
- case R_MIPS_PC19_S2:
- case R_MICROMIPS_PC18_S3:
- case R_MICROMIPS_PC19_S2:
- return llvm::SignExtend32<21>(res);
- case R_MIPS_PC21_S2:
- case R_MICROMIPS_PC21_S2:
- return llvm::SignExtend32<23>(res);
- case R_MICROMIPS_PC23_S2:
- return llvm::SignExtend32<25>(res);
- case R_MICROMIPS_26_S1:
- return llvm::SignExtend32<27>(res);
- case R_MIPS_26:
- case R_MIPS_PC26_S2:
- case R_MICROMIPS_PC26_S2:
- return llvm::SignExtend32<28>(res);
- default:
- // Nothing to do
- break;
- }
- return res;
-}
-
-template
-Reference::Addend readMipsRelocAddend<ELF32BE>(Reference::KindValue kind,
- const uint8_t *content);
-template
-Reference::Addend readMipsRelocAddend<ELF32LE>(Reference::KindValue kind,
- const uint8_t *content);
-template
-Reference::Addend readMipsRelocAddend<ELF64BE>(Reference::KindValue kind,
- const uint8_t *content);
-template
-Reference::Addend readMipsRelocAddend<ELF64LE>(Reference::KindValue kind,
- const uint8_t *content);
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h (removed)
@@ -1,31 +0,0 @@
-//===- lld/ReaderWriter/ELF/Mips/MipsRelocationHandler.h ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_HANDLER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_HANDLER_H
-
-#include "lld/Core/Reference.h"
-
-namespace lld {
-namespace elf {
-
-class MipsLinkingContext;
-template<typename ELFT> class MipsTargetLayout;
-
-template <class ELFT>
-std::unique_ptr<TargetRelocationHandler>
-createMipsRelocationHandler(MipsLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout);
-
-template <class ELFT>
-Reference::Addend readMipsRelocAddend(Reference::KindValue kind,
- const uint8_t *content);
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (removed)
@@ -1,1415 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp -------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsELFFile.h"
-#include "MipsLinkingContext.h"
-#include "MipsRelocationPass.h"
-#include "MipsTargetHandler.h"
-#include "llvm/ADT/DenseSet.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-
-// Lazy resolver
-static const uint8_t mipsGot0AtomContent[] = {
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
-};
-
-// Module pointer
-static const uint8_t mipsGotModulePointerAtomContent[] = {
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80
-};
-
-// TLS GD Entry
-static const uint8_t mipsGotTlsGdAtomContent[] = {
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
-};
-
-// Regular big-endian PLT0 entry
-static const uint8_t mipsBePlt0AtomContent[] = {
- 0x3c, 0x1c, 0x00, 0x00, // lui $28, %hi(&GOTPLT[0])
- 0x8f, 0x99, 0x00, 0x00, // lw $25, %lo(&GOTPLT[0])($28)
- 0x27, 0x9c, 0x00, 0x00, // addiu $28, $28, %lo(&GOTPLT[0])
- 0x03, 0x1c, 0xc0, 0x23, // subu $24, $24, $28
- 0x03, 0xe0, 0x78, 0x25, // move $15, $31
- 0x00, 0x18, 0xc0, 0x82, // srl $24, $24, 2
- 0x03, 0x20, 0xf8, 0x09, // jalr $25
- 0x27, 0x18, 0xff, 0xfe // subu $24, $24, 2
-};
-
-// Regular little-endian PLT0 entry
-static const uint8_t mipsLePlt0AtomContent[] = {
- 0x00, 0x00, 0x1c, 0x3c, // lui $28, %hi(&GOTPLT[0])
- 0x00, 0x00, 0x99, 0x8f, // lw $25, %lo(&GOTPLT[0])($28)
- 0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0])
- 0x23, 0xc0, 0x1c, 0x03, // subu $24, $24, $28
- 0x25, 0x78, 0xe0, 0x03, // move $15, $31
- 0x82, 0xc0, 0x18, 0x00, // srl $24, $24, 2
- 0x09, 0xf8, 0x20, 0x03, // jalr $25
- 0xfe, 0xff, 0x18, 0x27 // subu $24, $24, 2
-};
-
-// N32 big-endian PLT0 entry
-static const uint8_t mipsN32BePlt0AtomContent[] = {
- 0x3c, 0x0e, 0x00, 0x00, // lui $14, %hi(&GOTPLT[0])
- 0x8d, 0xd9, 0x00, 0x00, // lw $25, %lo(&GOTPLT[0])($14)
- 0x25, 0xce, 0x00, 0x00, // addiu $14, $14, %lo(&GOTPLT[0])
- 0x03, 0x0e, 0xc0, 0x23, // subu $24, $24, $14
- 0x03, 0xe0, 0x78, 0x25, // move $15, $31
- 0x00, 0x18, 0xc0, 0x82, // srl $24, $24, 2
- 0x03, 0x20, 0xf8, 0x09, // jalr $25
- 0x27, 0x18, 0xff, 0xfe // subu $24, $24, 2
-};
-
-// N32 little-endian PLT0 entry
-static const uint8_t mipsN32LePlt0AtomContent[] = {
- 0x00, 0x00, 0x0e, 0x3c, // lui $14, %hi(&GOTPLT[0])
- 0x00, 0x00, 0xd9, 0x8d, // lw $25, %lo(&GOTPLT[0])($14)
- 0x00, 0x00, 0xce, 0x25, // addiu $14, $14, %lo(&GOTPLT[0])
- 0x23, 0xc0, 0x0e, 0x03, // subu $24, $24, $14
- 0x25, 0x78, 0xe0, 0x03, // move $15, $31
- 0x82, 0xc0, 0x18, 0x00, // srl $24, $24, 2
- 0x09, 0xf8, 0x20, 0x03, // jalr $25
- 0xfe, 0xff, 0x18, 0x27 // subu $24, $24, 2
-};
-
-// microMIPS big-endian PLT0 entry
-static const uint8_t microMipsBePlt0AtomContent[] = {
- 0x79, 0x80, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - .
- 0xff, 0x23, 0x00, 0x00, // lw $25, 0($3)
- 0x05, 0x35, // subu $2, $2, $3
- 0x25, 0x25, // srl $2, $2, 2
- 0x33, 0x02, 0xff, 0xfe, // subu $24, $2, 2
- 0x0d, 0xff, // move $15, $31
- 0x45, 0xf9, // jalrs $25
- 0x0f, 0x83, // move $28, $3
- 0x0c, 0x00 // nop
-};
-
-// microMIPS little-endian PLT0 entry
-static const uint8_t microMipsLePlt0AtomContent[] = {
- 0x80, 0x79, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - .
- 0x23, 0xff, 0x00, 0x00, // lw $25, 0($3)
- 0x35, 0x05, // subu $2, $2, $3
- 0x25, 0x25, // srl $2, $2, 2
- 0x02, 0x33, 0xfe, 0xff, // subu $24, $2, 2
- 0xff, 0x0d, // move $15, $31
- 0xf9, 0x45, // jalrs $25
- 0x83, 0x0f, // move $28, $3
- 0x00, 0x0c // nop
-};
-
-// Regular big-endian PLT entry
-static const uint8_t mipsBePltAAtomContent[] = {
- 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry)
- 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
- 0x03, 0x20, 0x00, 0x08, // jr $25
- 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// Regular little-endian PLT entry
-static const uint8_t mipsLePltAAtomContent[] = {
- 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry)
- 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
- 0x08, 0x00, 0x20, 0x03, // jr $25
- 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// microMIPS big-endian PLT entry
-static const uint8_t microMipsBePltAAtomContent[] = {
- 0x79, 0x00, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
- 0xff, 0x22, 0x00, 0x00, // lw $25, 0($2)
- 0x45, 0x99, // jr $25
- 0x0f, 0x02 // move $24, $2
-};
-
-// microMIPS little-endian PLT entry
-static const uint8_t microMipsLePltAAtomContent[] = {
- 0x00, 0x79, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
- 0x22, 0xff, 0x00, 0x00, // lw $25, 0($2)
- 0x99, 0x45, // jr $25
- 0x02, 0x0f // move $24, $2
-};
-
-// R6 big-endian PLT entry
-static const uint8_t mipsR6BePltAAtomContent[] = {
- 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry)
- 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
- 0x03, 0x20, 0x00, 0x09, // jr $25
- 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// R6 little-endian PLT entry
-static const uint8_t mipsR6LePltAAtomContent[] = {
- 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry)
- 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
- 0x09, 0x00, 0x20, 0x03, // jr $25
- 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// LA25 big-endian stub entry
-static const uint8_t mipsBeLA25AtomContent[] = {
- 0x3c, 0x19, 0x00, 0x00, // lui $25, %hi(func)
- 0x08, 0x00, 0x00, 0x00, // j func
- 0x27, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
- 0x00, 0x00, 0x00, 0x00 // nop
-};
-
-// LA25 little-endian stub entry
-static const uint8_t mipsLeLA25AtomContent[] = {
- 0x00, 0x00, 0x19, 0x3c, // lui $25, %hi(func)
- 0x00, 0x00, 0x00, 0x08, // j func
- 0x00, 0x00, 0x39, 0x27, // addiu $25, $25, %lo(func)
- 0x00, 0x00, 0x00, 0x00 // nop
-};
-
-// microMIPS LA25 big-endian stub entry
-static const uint8_t microMipsBeLA25AtomContent[] = {
- 0x41, 0xbe, 0x00, 0x00, // lui $25, %hi(func)
- 0xd4, 0x00, 0x00, 0x00, // j func
- 0x33, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
- 0x00, 0x00, 0x00, 0x00 // nop
-};
-
-// microMIPS LA25 little-endian stub entry
-static const uint8_t microMipsLeLA25AtomContent[] = {
- 0xb9, 0x41, 0x00, 0x00, // lui $25, %hi(func)
- 0x00, 0xd4, 0x00, 0x00, // j func
- 0x39, 0x33, 0x00, 0x00, // addiu $25, $25, %lo(func)
- 0x00, 0x00, 0x00, 0x00 // nop
-};
-
-namespace {
-
-/// \brief Abstract base class represent MIPS GOT entries.
-class MipsGOTAtom : public GOTAtom {
-public:
- MipsGOTAtom(const File &f) : GOTAtom(f, ".got") {}
-
- Alignment alignment() const override { return 4; }
-};
-
-/// \brief MIPS GOT entry initialized by zero.
-template <typename ELFT> class GOT0Atom : public MipsGOTAtom {
-public:
- GOT0Atom(const File &f) : MipsGOTAtom(f) {}
-
- ArrayRef<uint8_t> rawContent() const override;
-};
-
-template <> ArrayRef<uint8_t> GOT0Atom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
-}
-template <> ArrayRef<uint8_t> GOT0Atom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
-}
-template <> ArrayRef<uint8_t> GOT0Atom<ELF64BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGot0AtomContent);
-}
-template <> ArrayRef<uint8_t> GOT0Atom<ELF64LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGot0AtomContent);
-}
-
-/// \brief MIPS GOT entry initialized by zero.
-template <typename ELFT> class GOTModulePointerAtom : public MipsGOTAtom {
-public:
- GOTModulePointerAtom(const File &f) : MipsGOTAtom(f) {}
-
- ArrayRef<uint8_t> rawContent() const override;
-};
-
-template <>
-ArrayRef<uint8_t> GOTModulePointerAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
-}
-template <>
-ArrayRef<uint8_t> GOTModulePointerAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
-}
-template <>
-ArrayRef<uint8_t> GOTModulePointerAtom<ELF64BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
-}
-template <>
-ArrayRef<uint8_t> GOTModulePointerAtom<ELF64LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
-}
-
-/// \brief MIPS GOT TLS GD entry.
-template <typename ELFT> class GOTTLSGdAtom : public MipsGOTAtom {
-public:
- GOTTLSGdAtom(const File &f) : MipsGOTAtom(f) {}
-
- ArrayRef<uint8_t> rawContent() const override;
-};
-
-template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
-}
-template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
-}
-template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64BE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
-}
-template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
-}
-
-class GOTPLTAtom : public GOTAtom {
-public:
- GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
- GOTPLTAtom(const Atom *a, const File &f) : GOTAtom(f, ".got.plt") {
- // Create dynamic relocation to adjust the .got.plt entry at runtime.
- addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
- }
-
- /// Setup reference to assign initial value to the .got.plt entry.
- void setPLT0(const PLTAtom *plt0) {
- addReferenceELF_Mips(R_MIPS_32, 0, plt0, 0);
- }
-
- Alignment alignment() const override { return 4; }
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
- }
-};
-
-template <class ELFT> class PLT0Atom : public PLTAtom {
-public:
- PLT0Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
- // Setup reference to fixup the PLT0 entry.
- addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 8, got, 0);
- }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT0 is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLT0Atom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsBePlt0AtomContent);
-}
-template <> ArrayRef<uint8_t> PLT0Atom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsLePlt0AtomContent);
-}
-
-template <class ELFT> class PLT0N32Atom : public PLTAtom {
-public:
- PLT0N32Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
- // Setup reference to fixup the PLT0 entry.
- addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 8, got, 0);
- }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT0 is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLT0N32Atom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsN32BePlt0AtomContent);
-}
-template <> ArrayRef<uint8_t> PLT0N32Atom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsN32LePlt0AtomContent);
-}
-
-template <class ELFT> class PLT0MicroAtom : public PLTAtom {
-public:
- PLT0MicroAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
- // Setup reference to fixup the PLT0 entry.
- addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
- }
-
- CodeModel codeModel() const override { return codeMipsMicro; }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT0 is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(microMipsBePlt0AtomContent);
-}
-template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(microMipsLePlt0AtomContent);
-}
-
-class PLTAAtom : public PLTAtom {
-public:
- PLTAAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
- // Setup reference to fixup the PLT entry.
- addReferenceELF_Mips(R_MIPS_HI16, 0, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 12, got, 0);
- }
-};
-
-template <class ELFT> class PLTARegAtom : public PLTAAtom {
-public:
- PLTARegAtom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLTARegAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsBePltAAtomContent);
-}
-template <> ArrayRef<uint8_t> PLTARegAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsLePltAAtomContent);
-}
-
-template <class ELFT> class PLTR6Atom : public PLTAAtom {
-public:
- PLTR6Atom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLTR6Atom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsR6BePltAAtomContent);
-}
-template <> ArrayRef<uint8_t> PLTR6Atom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsR6LePltAAtomContent);
-}
-
-template <class ELFT> class PLTMicroAtom : public PLTAtom {
-public:
- PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
- // Setup reference to fixup the microMIPS PLT entry.
- addReferenceELF_Mips(R_MICROMIPS_PC23_S2, 0, got, 0);
- }
-
- Alignment alignment() const override { return 2; }
- CodeModel codeModel() const override { return codeMipsMicro; }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("PLT is not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(microMipsBePltAAtomContent);
-}
-template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(microMipsLePltAAtomContent);
-}
-
-class LA25Atom : public PLTAtom {
-public:
- LA25Atom(const File &f) : PLTAtom(f, ".text") {}
-};
-
-template <typename ELFT> class LA25RegAtom : public LA25Atom {
-public:
- LA25RegAtom(const Atom *a, const File &f) : LA25Atom(f) {
- // Setup reference to fixup the LA25 stub entry.
- addReferenceELF_Mips(R_MIPS_HI16, 0, a, 0);
- addReferenceELF_Mips(R_MIPS_26, 4, a, 0);
- addReferenceELF_Mips(R_MIPS_LO16, 8, a, 0);
- }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("LA25 stubs are not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> LA25RegAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(mipsBeLA25AtomContent);
-}
-template <> ArrayRef<uint8_t> LA25RegAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsLeLA25AtomContent);
-}
-
-template <typename ELFT> class LA25MicroAtom : public LA25Atom {
-public:
- LA25MicroAtom(const Atom *a, const File &f) : LA25Atom(f) {
- // Setup reference to fixup the microMIPS LA25 stub entry.
- addReferenceELF_Mips(R_MICROMIPS_HI16, 0, a, 0);
- addReferenceELF_Mips(R_MICROMIPS_26_S1, 4, a, 0);
- addReferenceELF_Mips(R_MICROMIPS_LO16, 8, a, 0);
- }
-
- CodeModel codeModel() const override { return codeMipsMicro; }
-
- ArrayRef<uint8_t> rawContent() const override {
- llvm_unreachable("LA25 stubs are not applicable for this target");
- }
-};
-
-template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32BE>::rawContent() const {
- return llvm::makeArrayRef(microMipsBeLA25AtomContent);
-}
-template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(microMipsLeLA25AtomContent);
-}
-
-class MipsGlobalOffsetTableAtom : public GlobalOffsetTableAtom {
-public:
- MipsGlobalOffsetTableAtom(const File &f) : GlobalOffsetTableAtom(f) {}
-
- StringRef customSectionName() const override { return ".got"; }
-};
-
-template <typename ELFT> class MipsRldAtom : public SimpleELFDefinedAtom {
-public:
- MipsRldAtom(const File &f) : SimpleELFDefinedAtom(f) {}
-
- Scope scope() const override { return scopeGlobal; }
- SectionChoice sectionChoice() const override { return sectionCustomRequired; }
- StringRef customSectionName() const override { return ".rld_map"; }
- ContentType contentType() const override { return typeData; }
- uint64_t size() const override { return rawContent().size(); }
- ContentPermissions permissions() const override { return permRW_; }
- Alignment alignment() const override { return rawContent().size(); }
- StringRef name() const override { return "__RLD_MAP"; }
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(mipsGot0AtomContent)
- .slice(ELFT::Is64Bits ? 0 : 4);
- }
-};
-
-class RelocationPassFile : public SimpleFile {
-public:
- RelocationPassFile(const ELFLinkingContext &ctx)
- : SimpleFile("RelocationPassFile", kindELFObject) {
- setOrdinal(ctx.getNextOrdinalAndIncrement());
- }
-
- llvm::BumpPtrAllocator _alloc;
-};
-
-template <typename ELFT> class RelocationPass : public Pass {
-public:
- RelocationPass(MipsLinkingContext &ctx);
-
- std::error_code perform(SimpleFile &mf) override;
-
-private:
- /// \brief Reference to the linking context.
- const MipsLinkingContext &_ctx;
-
- /// \brief Owner of all the Atoms created by this pass.
- RelocationPassFile _file;
-
- /// \brief Map Atoms and addend to local GOT entries.
- typedef std::pair<const Atom *, int64_t> LocalGotMapKeyT;
- llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalMap;
- llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalPageMap;
-
- /// \brief Map Atoms to global GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotGlobalMap;
-
- /// \brief Map Atoms to TLS GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSMap;
-
- /// \brief Map Atoms to TLS GD GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;
-
- /// \brief GOT entry for the R_xxxMIPS_TLS_LDM relocations.
- GOTTLSGdAtom<ELFT> *_gotLDMEntry = nullptr;
-
- /// \brief the list of local GOT atoms.
- std::vector<GOTAtom *> _localGotVector;
-
- /// \brief the list of global GOT atoms.
- std::vector<GOTAtom *> _globalGotVector;
-
- /// \brief the list of TLS GOT atoms.
- std::vector<GOTAtom *> _tlsGotVector;
-
- /// \brief Map Atoms to their GOTPLT entries.
- llvm::DenseMap<const Atom *, GOTPLTAtom *> _gotpltMap;
-
- /// \brief Map Atoms to their PLT entries.
- llvm::DenseMap<const Atom *, PLTAAtom *> _pltRegMap;
- llvm::DenseMap<const Atom *, PLTMicroAtom<ELFT> *> _pltMicroMap;
-
- /// \brief Map Atoms to their Object entries.
- llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
-
- /// \brief Map Atoms to their LA25 entries.
- llvm::DenseMap<const Atom *, LA25Atom *> _la25RegMap;
- llvm::DenseMap<const Atom *, LA25Atom *> _la25MicroMap;
-
- /// \brief Atoms referenced by static relocations.
- llvm::DenseSet<const Atom *> _hasStaticRelocations;
-
- /// \brief Atoms require pointers equality.
- llvm::DenseSet<const Atom *> _requiresPtrEquality;
-
- /// \brief References which are candidates for converting
- /// to the R_MIPS_REL32 relocation.
- std::vector<Reference *> _rel32Candidates;
-
- /// \brief the list of PLT atoms.
- std::vector<PLTAtom *> _pltRegVector;
- std::vector<PLTAtom *> _pltMicroVector;
-
- /// \brief the list of GOTPLT atoms.
- std::vector<GOTPLTAtom *> _gotpltVector;
-
- /// \brief the list of Object entries.
- std::vector<ObjectAtom *> _objectVector;
-
- /// \brief the list of LA25 entries.
- std::vector<LA25Atom *> _la25Vector;
-
- /// \brief Handle a specific reference.
- void handleReference(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
-
- /// \brief Collect information about the reference to use it
- /// later in the handleReference() routine.
- std::error_code collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
- Reference &ref);
-
- /// \brief Check that the relocation is valid for the current linking mode.
- std::error_code validateRelocation(const DefinedAtom &atom,
- const Reference &ref) const;
-
- void handlePlain(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
- void handleBranch(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
- void handleGOT(Reference &ref);
-
- const GOTAtom *getLocalGOTEntry(const Reference &ref);
- const GOTAtom *getLocalGOTPageEntry(const Reference &ref);
- const GOTAtom *getGlobalGOTEntry(const Atom *a);
- const GOTAtom *getTLSGOTEntry(const Atom *a, Reference::Addend addend);
- const GOTAtom *getTLSGdGOTEntry(const Atom *a, Reference::Addend addend);
- const GOTAtom *getTLSLdmGOTEntry(const Atom *a);
- const GOTPLTAtom *getGOTPLTEntry(const Atom *a);
- const PLTAtom *getPLTEntry(const Atom *a);
- const PLTAtom *getPLTRegEntry(const Atom *a);
- const PLTAtom *getPLTMicroEntry(const Atom *a);
- const LA25Atom *getLA25RegEntry(const Atom *a);
- const LA25Atom *getLA25MicroEntry(const Atom *a);
- const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
-
- PLTAtom *createPLTHeader(bool isMicroMips);
-
- bool isLocal(const Atom *a) const;
- bool isLocalCall(const Atom *a) const;
- bool isDynamic(const Atom *atom) const;
- bool requireLA25Stub(const MipsELFDefinedAtom<ELFT> &atom,
- const Reference &ref) const;
- bool requirePLTEntry(const Atom *a) const;
- bool requireCopy(const Atom *a) const;
- bool mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
- Reference::KindValue refKind) const;
- bool hasPLTEntry(const Atom *atom) const;
-
- /// \brief Linked files contain microMIPS code.
- bool isMicroMips();
- /// \brief Linked files contain MIPS R6 code.
- bool isMipsR6();
-};
-
-template <typename ELFT>
-RelocationPass<ELFT>::RelocationPass(MipsLinkingContext &ctx)
- : _ctx(ctx), _file(ctx) {
- _localGotVector.push_back(new (_file._alloc) GOT0Atom<ELFT>(_file));
- _localGotVector.push_back(new (_file._alloc)
- GOTModulePointerAtom<ELFT>(_file));
-}
-
-template <typename ELFT>
-std::error_code RelocationPass<ELFT>::perform(SimpleFile &mf) {
- for (const auto &atom : mf.defined())
- for (const auto &ref : *atom) {
- const auto &da = *cast<MipsELFDefinedAtom<ELFT>>(atom);
- if (auto ec = collectReferenceInfo(da, const_cast<Reference &>(*ref)))
- return ec;
- }
-
- // Process all references.
- for (const auto &atom : mf.defined())
- for (const auto &ref : *atom)
- handleReference(*cast<MipsELFDefinedAtom<ELFT>>(atom),
- const_cast<Reference &>(*ref));
-
- // Create R_MIPS_REL32 relocations.
- for (auto *ref : _rel32Candidates) {
- bool forceRel = isLocal(ref->target()) && _ctx.getOutputELFType() == ET_DYN;
- if (!forceRel && (!isDynamic(ref->target()) || hasPLTEntry(ref->target())))
- continue;
- ref->setKindValue(R_MIPS_REL32);
- if (ELFT::Is64Bits)
- static_cast<MipsELFReference<ELFT> *>(ref)->setTag(R_MIPS_64);
- if (!isLocalCall(ref->target()))
- getGlobalGOTEntry(ref->target());
- }
-
- uint64_t ordinal = 0;
-
- if (_ctx.isDynamic() && _ctx.getOutputELFType() == ET_EXEC) {
- auto rlda = new (_file._alloc) MipsRldAtom<ELFT>(_file);
- rlda->setOrdinal(ordinal++);
- mf.addAtom(*rlda);
- }
-
- if (!_localGotVector.empty() || !_globalGotVector.empty() ||
- !_tlsGotVector.empty()) {
- SimpleDefinedAtom *ga = new (_file._alloc) MipsGlobalOffsetTableAtom(_file);
- ga->setOrdinal(ordinal++);
- mf.addAtom(*ga);
- }
-
- for (auto &got : _localGotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
-
- for (auto &got : _globalGotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
-
- for (auto &got : _tlsGotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
-
- // Create and emit PLT0 entry.
- PLTAtom *plt0Atom = nullptr;
- if (!_pltRegVector.empty())
- plt0Atom = createPLTHeader(false);
- else if (!_pltMicroVector.empty())
- plt0Atom = createPLTHeader(true);
-
- if (plt0Atom) {
- plt0Atom->setOrdinal(ordinal++);
- mf.addAtom(*plt0Atom);
- }
-
- // Emit regular PLT entries firts.
- for (auto &plt : _pltRegVector) {
- plt->setOrdinal(ordinal++);
- mf.addAtom(*plt);
- }
-
- // microMIPS PLT entries come after regular ones.
- for (auto &plt : _pltMicroVector) {
- plt->setOrdinal(ordinal++);
- mf.addAtom(*plt);
- }
-
- // Assign PLT0 to GOTPLT entries.
- assert(_gotpltMap.empty() || plt0Atom);
- for (auto &a: _gotpltMap)
- a.second->setPLT0(plt0Atom);
-
- for (auto &gotplt : _gotpltVector) {
- gotplt->setOrdinal(ordinal++);
- mf.addAtom(*gotplt);
- }
-
- for (auto obj : _objectVector) {
- obj->setOrdinal(ordinal++);
- mf.addAtom(*obj);
- }
-
- for (auto la25 : _la25Vector) {
- la25->setOrdinal(ordinal++);
- mf.addAtom(*la25);
- }
-
- return std::error_code();
-}
-
-static bool isMicroMipsReloc(Reference::KindValue kind) {
- return R_MICROMIPS_26_S1 <= kind && kind <= R_MICROMIPS_PC19_S2;
-}
-
-static bool isHiLo16Reloc(Reference::KindValue kind) {
- return kind == R_MIPS_HI16 || kind == R_MIPS_LO16 || kind == R_MIPS_PCHI16 ||
- kind == R_MIPS_PCLO16 || kind == R_MICROMIPS_HI16 ||
- kind == R_MICROMIPS_LO16 || kind == R_MICROMIPS_HI0_LO16;
-}
-
-static bool isBranchReloc(Reference::KindValue kind) {
- return kind == R_MIPS_26 || kind == R_MICROMIPS_26_S1 ||
- kind == R_MIPS_PC16 || kind == R_MIPS_PC21_S2 ||
- kind == R_MIPS_PC26_S2 || kind == R_MICROMIPS_PC7_S1 ||
- kind == R_MICROMIPS_PC10_S1 || kind == R_MICROMIPS_PC16_S1 ||
- kind == R_MICROMIPS_PC23_S2;
-}
-
-static bool isGotReloc(Reference::KindValue kind) {
- return kind == R_MIPS_GOT16 || kind == R_MICROMIPS_GOT16;
-}
-
-static bool isAllGotReloc(Reference::KindValue kind) {
- return isGotReloc(kind) || kind == R_MIPS_GOT_HI16 ||
- kind == R_MIPS_GOT_LO16 || kind == R_MICROMIPS_GOT_HI16 ||
- kind == R_MICROMIPS_GOT_LO16;
-}
-
-static bool isCallReloc(Reference::KindValue kind) {
- return kind == R_MIPS_CALL16 || kind == R_MICROMIPS_CALL16;
-}
-
-static bool isAllCallReloc(Reference::KindValue kind) {
- return isCallReloc(kind) || kind == R_MIPS_CALL_HI16 ||
- kind == R_MIPS_CALL_LO16 || kind == R_MICROMIPS_CALL_HI16 ||
- kind == R_MICROMIPS_CALL_LO16;
-}
-
-static bool isGotDispReloc(Reference::KindValue kind) {
- return kind == R_MIPS_GOT_DISP || kind == R_MICROMIPS_GOT_DISP;
-}
-
-static bool isGotPageReloc(Reference::KindValue kind) {
- return kind == R_MIPS_GOT_PAGE || kind == R_MICROMIPS_GOT_PAGE;
-}
-
-static bool isTlsDtpReloc(Reference::KindValue kind) {
- return kind == R_MIPS_TLS_DTPREL_HI16 || kind == R_MIPS_TLS_DTPREL_LO16 ||
- kind == R_MICROMIPS_TLS_DTPREL_HI16 ||
- kind == R_MICROMIPS_TLS_DTPREL_LO16;
-}
-
-static bool isTlsTpReloc(Reference::KindValue kind) {
- return kind == R_MIPS_TLS_TPREL_HI16 || kind == R_MIPS_TLS_TPREL_LO16 ||
- kind == R_MICROMIPS_TLS_TPREL_HI16 ||
- kind == R_MICROMIPS_TLS_TPREL_LO16;
-}
-
-static bool isTlsGdReloc(Reference::KindValue kind) {
- return kind == R_MIPS_TLS_GD || kind == R_MICROMIPS_TLS_GD;
-}
-
-static bool isTlsLdmReloc(Reference::KindValue kind) {
- return kind == R_MIPS_TLS_LDM || kind == R_MICROMIPS_TLS_LDM;
-}
-
-static bool isTlsGotTpReloc(Reference::KindValue kind) {
- return kind == R_MIPS_TLS_GOTTPREL || kind == R_MICROMIPS_TLS_GOTTPREL;
-}
-
-static bool isGpRelReloc(Reference::KindValue kind) {
- return kind == R_MIPS_GPREL32 || kind == R_MIPS_GPREL16 ||
- kind == R_MICROMIPS_GPREL16 || kind == R_MICROMIPS_GPREL7_S2 ||
- kind == R_MIPS_LITERAL || kind == R_MICROMIPS_LITERAL;
-}
-
-template <typename ELFT>
-void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
- Reference &ref) {
- if (!ref.target())
- return;
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return;
-
- assert(ref.kindArch() == Reference::KindArch::Mips);
- Reference::KindValue kind = ref.kindValue();
- if (isHiLo16Reloc(kind) || kind == R_MIPS_32 || kind == R_MIPS_PC32)
- handlePlain(atom, ref);
- else if (isBranchReloc(kind))
- handleBranch(atom, ref);
- else if (isAllGotReloc(kind) || isAllCallReloc(kind) ||
- isGotDispReloc(kind) || isGotPageReloc(kind) || kind == R_MIPS_EH)
- handleGOT(ref);
- else if (isTlsDtpReloc(kind))
- ref.setAddend(ref.addend() - atom.file().getDTPOffset());
- else if (isTlsTpReloc(kind))
- ref.setAddend(ref.addend() - atom.file().getTPOffset());
- else if (isTlsGdReloc(kind))
- ref.setTarget(getTLSGdGOTEntry(ref.target(), ref.addend()));
- else if (isTlsLdmReloc(kind))
- ref.setTarget(getTLSLdmGOTEntry(ref.target()));
- else if (isTlsGotTpReloc(kind))
- ref.setTarget(getTLSGOTEntry(ref.target(), ref.addend()));
- else if (kind == R_MIPS_GPREL32 || (isLocal(ref.target()) && isGpRelReloc(kind)))
- ref.setAddend(ref.addend() + atom.file().getGP0());
- else if (kind == R_MIPS_JALR) {
- if (_ctx.getOutputELFType() != ET_EXEC || !isLocalCall(ref.target()))
- ref.setKindValue(R_MIPS_NONE);
- }
-}
-
-template <typename ELFT>
-static bool isConstrainSym(const MipsELFDefinedAtom<ELFT> &atom,
- Reference::KindValue refKind) {
- if ((atom.section()->sh_flags & SHF_ALLOC) == 0)
- return false;
- switch (refKind) {
- case R_MIPS_NONE:
- case R_MIPS_JALR:
- case R_MICROMIPS_JALR:
- case R_MIPS_GPREL16:
- case R_MIPS_GPREL32:
- case R_MICROMIPS_GPREL16:
- case R_MICROMIPS_GPREL7_S2:
- case R_MIPS_LITERAL:
- case R_MICROMIPS_LITERAL:
- return false;
- default:
- return true;
- }
-}
-
-template <typename ELFT>
-std::error_code
-RelocationPass<ELFT>::collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
- Reference &ref) {
- if (!ref.target())
- return std::error_code();
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
-
- auto refKind = ref.kindValue();
- if (refKind == R_MIPS_EH && this->_ctx.mipsPcRelEhRel())
- ref.setKindValue(R_MIPS_PC32);
-
- if (auto ec = validateRelocation(atom, ref))
- return ec;
-
- if (!isConstrainSym(atom, refKind))
- return std::error_code();
-
- if (!mightBeDynamic(atom, refKind))
- _hasStaticRelocations.insert(ref.target());
- else if (refKind == R_MIPS_32 || refKind == R_MIPS_64)
- _rel32Candidates.push_back(&ref);
-
- if (!isBranchReloc(refKind) && !isAllCallReloc(refKind) &&
- refKind != R_MIPS_EH)
- _requiresPtrEquality.insert(ref.target());
-
- return std::error_code();
-}
-
-static std::error_code
-make_reject_for_shared_lib_reloc_error(const ELFLinkingContext &ctx,
- const DefinedAtom &atom,
- const Reference &ref) {
- StringRef kindValStr = "unknown";
- ctx.registry().referenceKindToString(ref.kindNamespace(), ref.kindArch(),
- ref.kindValue(), kindValStr);
-
- return make_dynamic_error_code(Twine(kindValStr) + " (" +
- Twine(ref.kindValue()) +
- ") relocation cannot be used "
- "when making a shared object, recompile " +
- atom.file().path() + " with -fPIC");
-}
-
-static std::error_code
-make_local_call16_reloc_error(const ELFLinkingContext &ctx,
- const DefinedAtom &atom, const Reference &ref) {
- return make_dynamic_error_code("R_MIPS_CALL16 (11) relocation cannot be used "
- "against local symbol " +
- ref.target()->name() + " in file " +
- atom.file().path());
-}
-
-template <typename ELFT>
-std::error_code
-RelocationPass<ELFT>::validateRelocation(const DefinedAtom &atom,
- const Reference &ref) const {
- if (!ref.target())
- return std::error_code();
-
- if (isCallReloc(ref.kindValue()) && isLocal(ref.target()))
- return make_local_call16_reloc_error(this->_ctx, atom, ref);
-
- if (this->_ctx.getOutputELFType() != ET_DYN)
- return std::error_code();
-
- switch (ref.kindValue()) {
- case R_MIPS16_HI16:
- case R_MIPS_HI16:
- case R_MIPS_HIGHER:
- case R_MIPS_HIGHEST:
- case R_MICROMIPS_HI16:
- case R_MICROMIPS_HIGHER:
- case R_MICROMIPS_HIGHEST:
- // For shared object we accepts "high" relocations
- // against the "_gp_disp" symbol only.
- if (ref.target()->name() != "_gp_disp")
- return make_reject_for_shared_lib_reloc_error(this->_ctx, atom, ref);
- break;
- case R_MIPS16_26:
- case R_MIPS_26:
- case R_MICROMIPS_26_S1:
- // These relocations are position dependent
- // and not acceptable in a shared object.
- return make_reject_for_shared_lib_reloc_error(this->_ctx, atom, ref);
- default:
- break;
- }
- return std::error_code();
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::isLocal(const Atom *a) const {
- if (auto *da = dyn_cast<DefinedAtom>(a))
- return da->scope() == Atom::scopeTranslationUnit;
- return false;
-}
-
-template <typename ELFT>
-static bool isMipsReadonly(const MipsELFDefinedAtom<ELFT> &atom) {
- auto secFlags = atom.section()->sh_flags;
- auto secType = atom.section()->sh_type;
-
- if ((secFlags & SHF_ALLOC) == 0)
- return false;
- if (secType == SHT_NOBITS)
- return false;
- if ((secFlags & SHF_WRITE) != 0)
- return false;
- return true;
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
- Reference::KindValue refKind) const {
- if (isAllGotReloc(refKind) || isAllCallReloc(refKind))
- return true;
-
- if (refKind != R_MIPS_32 && refKind != R_MIPS_64)
- return false;
- if ((atom.section()->sh_flags & SHF_ALLOC) == 0)
- return false;
-
- if (_ctx.getOutputELFType() == ET_DYN)
- return true;
- if (!isMipsReadonly(atom))
- return true;
- if (atom.isPIC())
- return true;
-
- return false;
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::hasPLTEntry(const Atom *atom) const {
- return _pltRegMap.count(atom) || _pltMicroMap.count(atom);
-}
-
-template <typename ELFT> bool RelocationPass<ELFT>::isMicroMips() {
- TargetHandler &handler = this->_ctx.getTargetHandler();
- return static_cast<MipsTargetHandler<ELFT> &>(handler)
- .getAbiInfoHandler()
- .isMicroMips();
-}
-
-template <typename ELFT> bool RelocationPass<ELFT>::isMipsR6() {
- TargetHandler &handler = this->_ctx.getTargetHandler();
- return static_cast<MipsTargetHandler<ELFT> &>(handler)
- .getAbiInfoHandler()
- .isMipsR6();
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::requirePLTEntry(const Atom *a) const {
- if (!_hasStaticRelocations.count(a))
- return false;
- const auto *sa = dyn_cast<ELFDynamicAtom<ELFT>>(a);
- if (sa && sa->type() != SharedLibraryAtom::Type::Code)
- return false;
- const auto *da = dyn_cast<ELFDefinedAtom<ELFT>>(a);
- if (da && da->contentType() != DefinedAtom::typeCode)
- return false;
- if (isLocalCall(a))
- return false;
- return true;
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::requireCopy(const Atom *a) const {
- if (!_hasStaticRelocations.count(a))
- return false;
- const auto *sa = dyn_cast<ELFDynamicAtom<ELFT>>(a);
- return sa && sa->type() == SharedLibraryAtom::Type::Data;
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::isDynamic(const Atom *atom) const {
- const auto *da = dyn_cast<const DefinedAtom>(atom);
- if (da && da->dynamicExport() == DefinedAtom::dynamicExportAlways)
- return true;
- if (isa<SharedLibraryAtom>(atom))
- return true;
- if (_ctx.getOutputELFType() != ET_DYN)
- return false;
- if (da && da->scope() != DefinedAtom::scopeTranslationUnit)
- return true;
- return isa<UndefinedAtom>(atom);
-}
-
-template <typename ELFT>
-static bool isMicroMips(const MipsELFDefinedAtom<ELFT> &atom) {
- return atom.codeModel() == DefinedAtom::codeMipsMicro ||
- atom.codeModel() == DefinedAtom::codeMipsMicroPIC;
-}
-
-template <typename ELFT>
-const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) {
- // If file contains microMIPS code try to reuse compressed PLT entry...
- if (isMicroMips()) {
- auto microPLT = _pltMicroMap.find(a);
- if (microPLT != _pltMicroMap.end())
- return microPLT->second;
- }
-
- // ... then try to reuse a regular PLT entry ...
- auto regPLT = _pltRegMap.find(a);
- if (regPLT != _pltRegMap.end())
- return regPLT->second;
-
- // ... and finally prefer to create new compressed PLT entry.
- return isMicroMips() ? getPLTMicroEntry(a) : getPLTRegEntry(a);
-}
-
-template <typename ELFT>
-void RelocationPass<ELFT>::handlePlain(const MipsELFDefinedAtom<ELFT> &atom,
- Reference &ref) {
- if (!isDynamic(ref.target()))
- return;
-
- if (requirePLTEntry(ref.target()))
- ref.setTarget(getPLTEntry(ref.target()));
- else if (requireCopy(ref.target()))
- ref.setTarget(getObjectEntry(cast<SharedLibraryAtom>(ref.target())));
-}
-
-template <typename ELFT>
-void RelocationPass<ELFT>::handleBranch(const MipsELFDefinedAtom<ELFT> &atom,
- Reference &ref) {
- bool isMicro = isMicroMipsReloc(ref.kindValue());
- if (const auto *sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
- if (sla->type() == SharedLibraryAtom::Type::Code)
- ref.setTarget(isMicro ? getPLTMicroEntry(sla) : getPLTRegEntry(sla));
- } else if (requireLA25Stub(atom, ref)) {
- if (isMicro)
- ref.setTarget(getLA25MicroEntry(ref.target()));
- else
- ref.setTarget(getLA25RegEntry(ref.target()));
- }
-
- if (!isLocal(ref.target())) {
- if (ref.kindValue() == R_MICROMIPS_26_S1)
- ref.setKindValue(LLD_R_MICROMIPS_GLOBAL_26_S1);
- else if (ref.kindValue() == R_MIPS_26)
- ref.setKindValue(LLD_R_MIPS_GLOBAL_26);
- }
-}
-
-template <typename ELFT> void RelocationPass<ELFT>::handleGOT(Reference &ref) {
- if (!isLocalCall(ref.target()))
- ref.setTarget(getGlobalGOTEntry(ref.target()));
- else if (isGotPageReloc(ref.kindValue()))
- ref.setTarget(getLocalGOTPageEntry(ref));
- else if (isLocal(ref.target()) &&
- (isCallReloc(ref.kindValue()) || isGotReloc(ref.kindValue())))
- ref.setTarget(getLocalGOTPageEntry(ref));
- else
- ref.setTarget(getLocalGOTEntry(ref));
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::isLocalCall(const Atom *a) const {
- Atom::Scope scope;
- if (auto *da = dyn_cast<DefinedAtom>(a))
- scope = da->scope();
- else if (auto *aa = dyn_cast<AbsoluteAtom>(a))
- scope = aa->scope();
- else
- return false;
-
- // Local and hidden symbols must be local.
- if (scope == Atom::scopeTranslationUnit || scope == Atom::scopeLinkageUnit)
- return true;
-
- // Calls to external symbols defined in an executable file resolved locally.
- if (_ctx.getOutputELFType() == ET_EXEC)
- return true;
-
- return false;
-}
-
-template <typename ELFT>
-bool RelocationPass<ELFT>::requireLA25Stub(const MipsELFDefinedAtom<ELFT> &atom,
- const Reference &ref) const {
- if (atom.file().isPIC())
- return false;
- if (auto *da = dyn_cast<DefinedAtom>(ref.target()))
- return static_cast<const MipsELFDefinedAtom<ELFT> *>(da)->isPIC();
- return false;
-}
-
-template <typename ELFT>
-const GOTAtom *RelocationPass<ELFT>::getLocalGOTEntry(const Reference &ref) {
- const Atom *a = ref.target();
- LocalGotMapKeyT key(a, ref.addend());
-
- auto got = _gotLocalMap.find(key);
- if (got != _gotLocalMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
- _gotLocalMap[key] = ga;
-
- _localGotVector.push_back(ga);
-
- Reference::KindValue relKind = ELFT::Is64Bits ? R_MIPS_64 : R_MIPS_32;
- ga->addReferenceELF_Mips(relKind, 0, a, 0);
-
- return ga;
-}
-
-template <typename ELFT>
-const GOTAtom *
-RelocationPass<ELFT>::getLocalGOTPageEntry(const Reference &ref) {
- const Atom *a = ref.target();
- LocalGotMapKeyT key(a, ref.addend());
-
- auto got = _gotLocalPageMap.find(key);
- if (got != _gotLocalPageMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
- _gotLocalPageMap[key] = ga;
-
- _localGotVector.push_back(ga);
-
- Reference::KindValue relKind =
- ELFT::Is64Bits ? LLD_R_MIPS_64_HI16 : LLD_R_MIPS_32_HI16;
- ga->addReferenceELF_Mips(relKind, 0, a, ref.addend());
-
- return ga;
-}
-
-template <typename ELFT>
-const GOTAtom *RelocationPass<ELFT>::getGlobalGOTEntry(const Atom *a) {
- auto got = _gotGlobalMap.find(a);
- if (got != _gotGlobalMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
- _gotGlobalMap[a] = ga;
-
- _globalGotVector.push_back(ga);
- ga->addReferenceELF_Mips(LLD_R_MIPS_GLOBAL_GOT, 0, a, 0);
-
- if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
- ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);
-
- return ga;
-}
-
-template <typename ELFT>
-const GOTAtom *RelocationPass<ELFT>::getTLSGOTEntry(const Atom *a,
- Reference::Addend addend) {
- auto got = _gotTLSMap.find(a);
- if (got != _gotTLSMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOT0Atom<ELFT>(_file);
- _gotTLSMap[a] = ga;
-
- _tlsGotVector.push_back(ga);
- Reference::KindValue relKind =
- ELFT::Is64Bits ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32;
- ga->addReferenceELF_Mips(relKind, 0, a, addend);
-
- return ga;
-}
-
-template <typename ELFT>
-const GOTAtom *
-RelocationPass<ELFT>::getTLSGdGOTEntry(const Atom *a,
- Reference::Addend addend) {
- auto got = _gotTLSGdMap.find(a);
- if (got != _gotTLSGdMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
- _gotTLSGdMap[a] = ga;
-
- _tlsGotVector.push_back(ga);
- if (ELFT::Is64Bits) {
- ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, a, addend);
- ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL64, 8, a, addend);
- } else {
- ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, a, addend);
- ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL32, 4, a, addend);
- }
-
- return ga;
-}
-
-template <typename ELFT>
-const GOTAtom *RelocationPass<ELFT>::getTLSLdmGOTEntry(const Atom *a) {
- if (_gotLDMEntry)
- return _gotLDMEntry;
-
- _gotLDMEntry = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
- _tlsGotVector.push_back(_gotLDMEntry);
- if (ELFT::Is64Bits)
- _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, _gotLDMEntry, 0);
- else
- _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, _gotLDMEntry, 0);
-
- return _gotLDMEntry;
-}
-
-template <typename ELFT>
-PLTAtom *RelocationPass<ELFT>::createPLTHeader(bool isMicroMips) {
- auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
- _gotpltVector.insert(_gotpltVector.begin(), ga1);
- auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
- _gotpltVector.insert(_gotpltVector.begin(), ga0);
-
- if (isMicroMips)
- return new (_file._alloc) PLT0MicroAtom<ELFT>(ga0, _file);
- if (_ctx.getAbi() == MipsAbi::N32)
- return new (_file._alloc) PLT0N32Atom<ELFT>(ga0, _file);
- return new (_file._alloc) PLT0Atom<ELFT>(ga0, _file);
-}
-
-template <typename ELFT>
-const GOTPLTAtom *RelocationPass<ELFT>::getGOTPLTEntry(const Atom *a) {
- auto it = _gotpltMap.find(a);
- if (it != _gotpltMap.end())
- return it->second;
-
- auto ga = new (_file._alloc) GOTPLTAtom(a, _file);
- _gotpltMap[a] = ga;
- _gotpltVector.push_back(ga);
- return ga;
-}
-
-template <typename ELFT>
-const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) {
- auto plt = _pltRegMap.find(a);
- if (plt != _pltRegMap.end())
- return plt->second;
-
- PLTAAtom *pa = nullptr;
- if (isMipsR6())
- pa = new (_file._alloc) PLTR6Atom<ELFT>(getGOTPLTEntry(a), _file);
- else
- pa = new (_file._alloc) PLTARegAtom<ELFT>(getGOTPLTEntry(a), _file);
- _pltRegMap[a] = pa;
- _pltRegVector.push_back(pa);
-
- // Check that 'a' dynamic symbol table record should point to the PLT.
- if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
- pa->addReferenceELF_Mips(LLD_R_MIPS_STO_PLT, 0, a, 0);
-
- return pa;
-}
-
-template <typename ELFT>
-const PLTAtom *RelocationPass<ELFT>::getPLTMicroEntry(const Atom *a) {
- auto plt = _pltMicroMap.find(a);
- if (plt != _pltMicroMap.end())
- return plt->second;
-
- auto pa = new (_file._alloc) PLTMicroAtom<ELFT>(getGOTPLTEntry(a), _file);
- _pltMicroMap[a] = pa;
- _pltMicroVector.push_back(pa);
-
- // Check that 'a' dynamic symbol table record should point to the PLT.
- if (_hasStaticRelocations.count(a) && _requiresPtrEquality.count(a))
- pa->addReferenceELF_Mips(LLD_R_MIPS_STO_PLT, 0, a, 0);
-
- return pa;
-}
-
-template <typename ELFT>
-const LA25Atom *RelocationPass<ELFT>::getLA25RegEntry(const Atom *a) {
- auto la25 = _la25RegMap.find(a);
- if (la25 != _la25RegMap.end())
- return la25->second;
-
- auto sa = new (_file._alloc) LA25RegAtom<ELFT>(a, _file);
- _la25RegMap[a] = sa;
- _la25Vector.push_back(sa);
-
- return sa;
-}
-
-template <typename ELFT>
-const LA25Atom *RelocationPass<ELFT>::getLA25MicroEntry(const Atom *a) {
- auto la25 = _la25MicroMap.find(a);
- if (la25 != _la25MicroMap.end())
- return la25->second;
-
- auto sa = new (_file._alloc) LA25MicroAtom<ELFT>(a, _file);
- _la25MicroMap[a] = sa;
- _la25Vector.push_back(sa);
-
- return sa;
-}
-
-template <typename ELFT>
-const ObjectAtom *
-RelocationPass<ELFT>::getObjectEntry(const SharedLibraryAtom *a) {
- auto obj = _objectMap.find(a);
- if (obj != _objectMap.end())
- return obj->second;
-
- auto oa = new (_file._alloc) ObjectAtom(_file);
- oa->addReferenceELF_Mips(R_MIPS_COPY, 0, oa, 0);
- oa->_name = a->name();
- oa->_size = a->size();
-
- _objectMap[a] = oa;
- _objectVector.push_back(oa);
-
- return oa;
-}
-
-} // end anon namespace
-
-static std::unique_ptr<Pass> createPass(MipsLinkingContext &ctx) {
- switch (ctx.getTriple().getArch()) {
- case llvm::Triple::mips:
- return llvm::make_unique<RelocationPass<ELF32BE>>(ctx);
- case llvm::Triple::mipsel:
- return llvm::make_unique<RelocationPass<ELF32LE>>(ctx);
- case llvm::Triple::mips64:
- return llvm::make_unique<RelocationPass<ELF64BE>>(ctx);
- case llvm::Triple::mips64el:
- return llvm::make_unique<RelocationPass<ELF64LE>>(ctx);
- default:
- llvm_unreachable("Unhandled arch");
- }
-}
-
-std::unique_ptr<Pass>
-lld::elf::createMipsRelocationPass(MipsLinkingContext &ctx) {
- switch (ctx.getOutputELFType()) {
- case ET_EXEC:
- case ET_DYN:
- return createPass(ctx);
- case ET_REL:
- return nullptr;
- default:
- llvm_unreachable("Unhandled output file type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h (removed)
@@ -1,25 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsRelocationPass.h ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_PASS_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_RELOCATION_PASS_H
-
-#include <memory>
-
-namespace lld {
-class Pass;
-
-namespace elf {
-class MipsLinkingContext;
-
-std::unique_ptr<Pass> createMipsRelocationPass(MipsLinkingContext &ctx);
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp (removed)
@@ -1,264 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp --------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsLinkingContext.h"
-#include "MipsSectionChunks.h"
-#include "MipsTargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-MipsReginfoSection<ELFT>::MipsReginfoSection(
- const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_RegInfo ®info)
- : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"), _reginfo(reginfo),
- _targetLayout(targetLayout) {
- this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_REGINFO);
- this->_entSize = sizeof(Elf_Mips_RegInfo);
- this->_fsize = sizeof(Elf_Mips_RegInfo);
- this->_msize = sizeof(Elf_Mips_RegInfo);
- this->_alignment = 4;
- this->_type = SHT_MIPS_REGINFO;
- this->_flags = SHF_ALLOC;
-}
-
-template <class ELFT>
-void MipsReginfoSection<ELFT>::write(ELFWriter *writer,
- TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
- std::memcpy(dest, &_reginfo, this->_fsize);
-}
-
-template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
- _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
- if (this->_outputSection)
- this->_outputSection->setType(this->_type);
-}
-
-template class MipsReginfoSection<ELF32BE>;
-template class MipsReginfoSection<ELF32LE>;
-template class MipsReginfoSection<ELF64BE>;
-template class MipsReginfoSection<ELF64LE>;
-
-template <class ELFT>
-MipsOptionsSection<ELFT>::MipsOptionsSection(
- const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_RegInfo ®info)
- : Section<ELFT>(ctx, ".MIPS.options", "MipsOptions"), _reginfo(reginfo),
- _targetLayout(targetLayout) {
- this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_OPTIONS);
- this->_entSize = 1;
- this->_alignment = 8;
- this->_fsize = llvm::alignTo(
- sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo), this->_alignment);
- this->_msize = this->_fsize;
- this->_type = SHT_MIPS_OPTIONS;
- this->_flags = SHF_ALLOC | SHF_MIPS_NOSTRIP;
-
- _header.kind = ODK_REGINFO;
- _header.size = this->_fsize;
- _header.section = 0;
- _header.info = 0;
-}
-
-template <class ELFT>
-void MipsOptionsSection<ELFT>::write(ELFWriter *writer,
- TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
- std::memset(dest, 0, this->_fsize);
- std::memcpy(dest, &_header, sizeof(_header));
- std::memcpy(dest + sizeof(_header), &_reginfo, sizeof(_reginfo));
-}
-
-template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
- _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
- if (this->_outputSection)
- this->_outputSection->setType(this->_type);
-}
-
-template class MipsOptionsSection<ELF32BE>;
-template class MipsOptionsSection<ELF32LE>;
-template class MipsOptionsSection<ELF64BE>;
-template class MipsOptionsSection<ELF64LE>;
-
-template <class ELFT>
-MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(
- const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_ABIFlags &abiFlags)
- : Section<ELFT>(ctx, ".MIPS.abiflags", "MipsAbiFlags"), _abiFlags(abiFlags),
- _targetLayout(targetLayout) {
- this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_ABI_FLAGS);
- this->_alignment = 8;
- this->_fsize = llvm::alignTo(sizeof(_abiFlags), this->_alignment);
- this->_msize = this->_fsize;
- this->_entSize = this->_fsize;
- this->_type = SHT_MIPS_ABIFLAGS;
- this->_flags = SHF_ALLOC;
-}
-
-template <class ELFT>
-void MipsAbiFlagsSection<ELFT>::write(ELFWriter *writer,
- TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
- std::memcpy(dest, &_abiFlags, this->_fsize);
-}
-
-template <class ELFT> void MipsAbiFlagsSection<ELFT>::finalize() {
- if (this->_outputSection)
- this->_outputSection->setType(this->_type);
-}
-
-template class MipsAbiFlagsSection<ELF32BE>;
-template class MipsAbiFlagsSection<ELF32LE>;
-template class MipsAbiFlagsSection<ELF64BE>;
-template class MipsAbiFlagsSection<ELF64LE>;
-
-template <class ELFT>
-MipsGOTSection<ELFT>::MipsGOTSection(const MipsLinkingContext &ctx)
- : AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
- MipsTargetLayout<ELFT>::ORDER_GOT),
- _hasNonLocal(false), _localCount(0) {
- this->_flags |= SHF_MIPS_GPREL;
- this->_alignment = 4;
-}
-
-template <class ELFT>
-bool MipsGOTSection<ELFT>::compare(const Atom *a, const Atom *b) const {
- auto ia = _posMap.find(a);
- auto ib = _posMap.find(b);
-
- if (ia != _posMap.end() && ib != _posMap.end())
- return ia->second < ib->second;
-
- return ia == _posMap.end() && ib != _posMap.end();
-}
-
-template <class ELFT>
-const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) {
- const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
-
- if (atom->name() == "_GLOBAL_OFFSET_TABLE_")
- return AtomSection<ELFT>::appendAtom(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::Mips);
- switch (r->kindValue()) {
- case LLD_R_MIPS_GLOBAL_GOT:
- _hasNonLocal = true;
- _posMap[r->target()] = _posMap.size();
- return AtomSection<ELFT>::appendAtom(atom);
- case R_MIPS_TLS_TPREL32:
- case R_MIPS_TLS_DTPREL32:
- case R_MIPS_TLS_TPREL64:
- case R_MIPS_TLS_DTPREL64:
- _hasNonLocal = true;
- _tlsMap[r->target()] = _tlsMap.size();
- return AtomSection<ELFT>::appendAtom(atom);
- case R_MIPS_TLS_DTPMOD32:
- case R_MIPS_TLS_DTPMOD64:
- _hasNonLocal = true;
- break;
- }
- }
-
- if (!_hasNonLocal)
- ++_localCount;
-
- return AtomSection<ELFT>::appendAtom(atom);
-}
-
-template class MipsGOTSection<ELF32BE>;
-template class MipsGOTSection<ELF32LE>;
-template class MipsGOTSection<ELF64BE>;
-template class MipsGOTSection<ELF64LE>;
-
-template <class ELFT>
-MipsPLTSection<ELFT>::MipsPLTSection(const MipsLinkingContext &ctx)
- : AtomSection<ELFT>(ctx, ".plt", DefinedAtom::typeGOT, DefinedAtom::permR_X,
- MipsTargetLayout<ELFT>::ORDER_PLT) {}
-
-template <class ELFT>
-const AtomLayout *MipsPLTSection<ELFT>::findPLTLayout(const Atom *plt) const {
- auto it = _pltLayoutMap.find(plt);
- return it != _pltLayoutMap.end() ? it->second : nullptr;
-}
-
-template <class ELFT>
-const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) {
- const auto *layout = AtomSection<ELFT>::appendAtom(atom);
-
- const DefinedAtom *da = cast<DefinedAtom>(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::Mips);
- if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
- _pltLayoutMap[r->target()] = layout;
- break;
- }
- }
-
- return layout;
-}
-
-template class MipsPLTSection<ELF32BE>;
-template class MipsPLTSection<ELF32LE>;
-template class MipsPLTSection<ELF64BE>;
-template class MipsPLTSection<ELF64LE>;
-
-template <class ELFT> static bool isMips64EL() {
- return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-}
-
-template <class ELFT>
-MipsRelocationTable<ELFT>::MipsRelocationTable(const ELFLinkingContext &ctx,
- StringRef str, int32_t order)
- : RelocationTable<ELFT>(ctx, str, order) {}
-
-template <class ELFT>
-void MipsRelocationTable<ELFT>::writeRela(ELFWriter *writer, Elf_Rela &r,
- const DefinedAtom &atom,
- const Reference &ref) {
- uint32_t rType = ref.kindValue() | (ref.tag() << 8);
- r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
- isMips64EL<ELFT>());
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
- // The addend is used only by relative relocations
- if (this->_ctx.isRelativeReloc(ref))
- r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
- else
- r.r_addend = 0;
-}
-
-template <class ELFT>
-void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
- const DefinedAtom &atom,
- const Reference &ref) {
- uint32_t rType = ref.kindValue() | (ref.tag() << 8);
- r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
- isMips64EL<ELFT>());
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
-}
-
-template class MipsRelocationTable<ELF32BE>;
-template class MipsRelocationTable<ELF32LE>;
-template class MipsRelocationTable<ELF64BE>;
-template class MipsRelocationTable<ELF64LE>;
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (removed)
@@ -1,150 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h ----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_SECTION_CHUNKS_H
-
-#include "SectionChunks.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class MipsTargetLayout;
-class MipsLinkingContext;
-
-/// \brief Handle Mips .reginfo section
-template <class ELFT> class MipsReginfoSection : public Section<ELFT> {
-public:
- typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
-
- MipsReginfoSection(const ELFLinkingContext &ctx,
- MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_RegInfo ®info);
-
- StringRef segmentKindToStr() const override { return "REGINFO"; }
- bool hasOutputSegment() const override { return true; }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
- void finalize() override;
-
-private:
- Elf_Mips_RegInfo _reginfo;
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-
-/// \brief Handle .MIPS.options section
-template <class ELFT> class MipsOptionsSection : public Section<ELFT> {
-public:
- typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
- typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
-
- MipsOptionsSection(const ELFLinkingContext &ctx,
- MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_RegInfo ®info);
-
- bool hasOutputSegment() const override { return true; }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
- void finalize() override;
-
-private:
- Elf_Mips_Options _header;
- Elf_Mips_RegInfo _reginfo;
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-
-/// \brief Handle .MIPS.abiflags section
-template <class ELFT> class MipsAbiFlagsSection : public Section<ELFT> {
-public:
- typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
-
- MipsAbiFlagsSection(const ELFLinkingContext &ctx,
- MipsTargetLayout<ELFT> &targetLayout,
- const Elf_Mips_ABIFlags &abiFlags);
-
- bool hasOutputSegment() const override { return true; }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
- void finalize() override;
-
-private:
- Elf_Mips_ABIFlags _abiFlags;
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-
-/// \brief Handle Mips GOT section
-template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> {
-public:
- MipsGOTSection(const MipsLinkingContext &ctx);
-
- /// \brief Number of local GOT entries.
- std::size_t getLocalCount() const { return _localCount; }
-
- /// \brief Number of global GOT entries.
- std::size_t getGlobalCount() const { return _posMap.size(); }
-
- /// \brief Does the atom have a global GOT entry?
- bool hasGlobalGOTEntry(const Atom *a) const {
- return _posMap.count(a) || _tlsMap.count(a);
- }
-
- /// \brief Compare two atoms accordingly theirs positions in the GOT.
- bool compare(const Atom *a, const Atom *b) const;
-
- const AtomLayout *appendAtom(const Atom *atom) override;
-
-private:
- /// \brief True if the GOT contains non-local entries.
- bool _hasNonLocal;
-
- /// \brief Number of local GOT entries.
- std::size_t _localCount;
-
- /// \brief Map TLS Atoms to their GOT entry index.
- llvm::DenseMap<const Atom *, std::size_t> _tlsMap;
-
- /// \brief Map Atoms to their GOT entry index.
- llvm::DenseMap<const Atom *, std::size_t> _posMap;
-};
-
-/// \brief Handle Mips PLT section
-template <class ELFT> class MipsPLTSection : public AtomSection<ELFT> {
-public:
- MipsPLTSection(const MipsLinkingContext &ctx);
-
- const AtomLayout *findPLTLayout(const Atom *plt) const;
-
- const AtomLayout *appendAtom(const Atom *atom) override;
-
-private:
- /// \brief Map PLT Atoms to their layouts.
- std::unordered_map<const Atom *, const AtomLayout *> _pltLayoutMap;
-};
-
-template <class ELFT> class MipsRelocationTable : public RelocationTable<ELFT> {
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
-
-public:
- MipsRelocationTable(const ELFLinkingContext &ctx, StringRef str,
- int32_t order);
-
-protected:
- void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
- const Reference &ref) override;
- void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
- const Reference &ref) override;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (removed)
@@ -1,166 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ELFReader.h"
-#include "MipsELFFile.h"
-#include "MipsELFWriters.h"
-#include "MipsTargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-MipsTargetHandler<ELFT>::MipsTargetHandler(MipsLinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new MipsTargetLayout<ELFT>(ctx, _abiInfoHandler)),
- _relocationHandler(
- createMipsRelocationHandler<ELFT>(ctx, *_targetLayout)) {}
-
-template <class ELFT>
-std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getObjReader() {
- return llvm::make_unique<ELFReader<MipsELFFile<ELFT>>>(_ctx);
-}
-
-template <class ELFT>
-std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getDSOReader() {
- return llvm::make_unique<ELFReader<DynamicFile<ELFT>>>(_ctx);
-}
-
-template <class ELFT>
-const TargetRelocationHandler &
-MipsTargetHandler<ELFT>::getRelocationHandler() const {
- return *_relocationHandler;
-}
-
-template <class ELFT>
-std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() {
- switch (_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<MipsExecutableWriter<ELFT>>(_ctx, *_targetLayout,
- _abiInfoHandler);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(
- _ctx, *_targetLayout, _abiInfoHandler);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
-
-template <class ELFT> MipsAbi MipsTargetHandler<ELFT>::getAbi() const {
- return _abiInfoHandler.getAbi();
-}
-
-template class MipsTargetHandler<ELF32BE>;
-template class MipsTargetHandler<ELF32LE>;
-template class MipsTargetHandler<ELF64BE>;
-template class MipsTargetHandler<ELF64LE>;
-
-template <class ELFT>
-MipsSymbolTable<ELFT>::MipsSymbolTable(const ELFLinkingContext &ctx)
- : SymbolTable<ELFT>(ctx, ".symtab",
- TargetLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
-
-template <class ELFT>
-void MipsSymbolTable<ELFT>::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) {
- SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
-
- switch (da->codeModel()) {
- case DefinedAtom::codeMipsMicro:
- sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
- break;
- case DefinedAtom::codeMipsMicroPIC:
- sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
- break;
- default:
- break;
- }
-}
-
-template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) {
- SymbolTable<ELFT>::finalize(sort);
-
- for (auto &ste : this->_symbolTable) {
- if (!ste._atom)
- continue;
- if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
- if (da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
- // Adjust dynamic microMIPS symbol value. That allows a dynamic
- // linker to recognize and handle this symbol correctly.
- ste._symbol.st_value = ste._symbol.st_value | 1;
- }
- }
- }
-}
-
-template class MipsSymbolTable<ELF32BE>;
-template class MipsSymbolTable<ELF32LE>;
-template class MipsSymbolTable<ELF64BE>;
-template class MipsSymbolTable<ELF64LE>;
-
-template <class ELFT>
-MipsDynamicSymbolTable<ELFT>::MipsDynamicSymbolTable(
- const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
- : DynamicSymbolTable<ELFT>(ctx, layout, ".dynsym",
- TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS),
- _targetLayout(layout) {}
-
-template <class ELFT> void MipsDynamicSymbolTable<ELFT>::sortSymbols() {
- typedef typename DynamicSymbolTable<ELFT>::SymbolEntry SymbolEntry;
- std::stable_sort(this->_symbolTable.begin(), this->_symbolTable.end(),
- [this](const SymbolEntry &A, const SymbolEntry &B) {
- if (A._symbol.getBinding() != STB_GLOBAL &&
- B._symbol.getBinding() != STB_GLOBAL)
- return A._symbol.getBinding() < B._symbol.getBinding();
-
- return _targetLayout.getGOTSection().compare(A._atom,
- B._atom);
- });
-}
-
-template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() {
- DynamicSymbolTable<ELFT>::finalize();
-
- const auto &pltSection = _targetLayout.getPLTSection();
-
- for (auto &ste : this->_symbolTable) {
- const Atom *a = ste._atom;
- if (!a)
- continue;
- if (auto *layout = pltSection.findPLTLayout(a)) {
- a = layout->_atom;
- // Under some conditions a dynamic symbol table record should hold
- // a symbol value of the corresponding PLT entry. For details look
- // at the PLT entry creation code in the class MipsRelocationPass.
- // Let's update atomLayout fields for such symbols.
- assert(!ste._atomLayout);
- ste._symbol.st_value = layout->_virtualAddr;
- ste._symbol.st_other |= ELF::STO_MIPS_PLT;
- }
-
- if (const auto *da = dyn_cast<DefinedAtom>(a)) {
- if (da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
- // Adjust dynamic microMIPS symbol value. That allows a dynamic
- // linker to recognize and handle this symbol correctly.
- ste._symbol.st_value = ste._symbol.st_value | 1;
- }
- }
- }
-}
-
-template class MipsDynamicSymbolTable<ELF32BE>;
-template class MipsDynamicSymbolTable<ELF32LE>;
-template class MipsDynamicSymbolTable<ELF64BE>;
-template class MipsDynamicSymbolTable<ELF64LE>;
-
-}
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (removed)
@@ -1,73 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h ----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
-
-#include "MipsAbiInfoHandler.h"
-#include "MipsLinkingContext.h"
-#include "MipsTargetLayout.h"
-#include "TargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class MipsBaseTargetHandler : public TargetHandler {
-public:
- virtual MipsAbi getAbi() const = 0;
-};
-
-/// \brief TargetHandler for Mips
-template <class ELFT>
-class MipsTargetHandler final : public MipsBaseTargetHandler {
-public:
- MipsTargetHandler(MipsLinkingContext &ctx);
-
- MipsAbiInfoHandler<ELFT> &getAbiInfoHandler() { return _abiInfoHandler; }
-
- std::unique_ptr<Reader> getObjReader() override;
- std::unique_ptr<Reader> getDSOReader() override;
- const TargetRelocationHandler &getRelocationHandler() const override;
- std::unique_ptr<Writer> getWriter() override;
- MipsAbi getAbi() const override;
-
-private:
- MipsLinkingContext &_ctx;
- MipsAbiInfoHandler<ELFT> _abiInfoHandler;
- std::unique_ptr<MipsTargetLayout<ELFT>> _targetLayout;
- std::unique_ptr<TargetRelocationHandler> _relocationHandler;
-};
-
-template <class ELFT> class MipsSymbolTable : public SymbolTable<ELFT> {
-public:
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
- MipsSymbolTable(const ELFLinkingContext &ctx);
-
- void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) override;
- void finalize(bool sort) override;
-};
-
-template <class ELFT>
-class MipsDynamicSymbolTable : public DynamicSymbolTable<ELFT> {
-public:
- MipsDynamicSymbolTable(const ELFLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout);
-
- void sortSymbols() override;
- void finalize() override;
-
-private:
- MipsTargetLayout<ELFT> &_targetLayout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp (removed)
@@ -1,111 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsLinkingContext.h"
-#include "MipsTargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-MipsTargetLayout<ELFT>::MipsTargetLayout(MipsLinkingContext &ctx,
- MipsAbiInfoHandler<ELFT> &abi)
- : TargetLayout<ELFT>(ctx), _abiInfo(abi),
- _gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
- _pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
-
-template <class ELFT>
-AtomSection<ELFT> *MipsTargetLayout<ELFT>::createSection(
- StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions,
- typename TargetLayout<ELFT>::SectionOrder order) {
- if (type == DefinedAtom::typeGOT && name == ".got")
- return _gotSection;
- if (type == DefinedAtom::typeStub && name == ".plt")
- return _pltSection;
- return TargetLayout<ELFT>::createSection(name, type, permissions, order);
-}
-
-template <class ELFT>
-typename TargetLayout<ELFT>::SegmentType
-MipsTargetLayout<ELFT>::getSegmentType(const Section<ELFT> *section) const {
- switch (section->order()) {
- case ORDER_MIPS_REGINFO:
- return _abiInfo.hasMipsAbiSection() ? llvm::ELF::PT_LOAD
- : llvm::ELF::PT_MIPS_REGINFO;
- case ORDER_MIPS_OPTIONS:
- return llvm::ELF::PT_LOAD;
- case ORDER_MIPS_ABI_FLAGS:
- return llvm::ELF::PT_MIPS_ABIFLAGS;
- default:
- return TargetLayout<ELFT>::getSegmentType(section);
- }
-}
-
-template <class ELFT> uint64_t MipsTargetLayout<ELFT>::getGPAddr() {
- std::call_once(_gpOnce, [this]() {
- if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
- _gpAddr = a->_virtualAddr;
- });
- return _gpAddr;
-}
-
-template <class ELFT>
-typename TargetLayout<ELFT>::SectionOrder
-MipsTargetLayout<ELFT>::getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) {
- if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
- return TargetLayout<ELFT>::ORDER_TEXT;
-
- return TargetLayout<ELFT>::getSectionOrder(name, contentType,
- contentPermissions);
-}
-
-template <class ELFT>
-unique_bump_ptr<RelocationTable<ELFT>>
-MipsTargetLayout<ELFT>::createRelocationTable(StringRef name, int32_t order) {
- return unique_bump_ptr<RelocationTable<ELFT>>(new (
- this->_allocator) MipsRelocationTable<ELFT>(this->_ctx, name, order));
-}
-
-template <class ELFT>
-uint64_t MipsTargetLayout<ELFT>::getLookupSectionFlags(
- const OutputSection<ELFT> *os) const {
- uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
- return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP;
-}
-
-template <class ELFT> void MipsTargetLayout<ELFT>::sortSegments() {
- using namespace llvm::ELF;
- TargetLayout<ELFT>::sortSegments();
- // Move PT_MIPS_ABIFLAGS or PT_MIPS_REGINFO right after PT_INTERP.
- auto abiIt =
- std::find_if(this->_segments.begin(), this->_segments.end(),
- [](const Segment<ELFT> *s) {
- auto typ = s->segmentType();
- return typ == PT_MIPS_ABIFLAGS || typ == PT_MIPS_REGINFO;
- });
- if (abiIt == this->_segments.end())
- return;
- Segment<ELFT> *abiSeg = *abiIt;
- this->_segments.erase(abiIt);
- auto outIt = std::find_if(this->_segments.begin(), this->_segments.end(),
- [](const Segment<ELFT> *s) {
- auto typ = s->segmentType();
- return typ != PT_PHDR && typ != PT_INTERP;
- });
- this->_segments.insert(outIt, abiSeg);
-}
-
-template class MipsTargetLayout<ELF32BE>;
-template class MipsTargetLayout<ELF32LE>;
-template class MipsTargetLayout<ELF64BE>;
-template class MipsTargetLayout<ELF64LE>;
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h (removed)
@@ -1,71 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h -----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_LAYOUT_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_LAYOUT_H
-
-#include "MipsAbiInfoHandler.h"
-#include "MipsSectionChunks.h"
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-class MipsLinkingContext;
-
-/// \brief TargetLayout for Mips
-template <class ELFT> class MipsTargetLayout final : public TargetLayout<ELFT> {
-public:
- enum MipsSectionOrder {
- ORDER_MIPS_ABI_FLAGS = TargetLayout<ELFT>::ORDER_RO_NOTE + 1,
- ORDER_MIPS_REGINFO,
- ORDER_MIPS_OPTIONS,
- };
-
- MipsTargetLayout(MipsLinkingContext &ctx, MipsAbiInfoHandler<ELFT> &abi);
-
- const MipsGOTSection<ELFT> &getGOTSection() const { return *_gotSection; }
- const MipsPLTSection<ELFT> &getPLTSection() const { return *_pltSection; }
-
- AtomSection<ELFT> *
- createSection(StringRef name, int32_t type,
- DefinedAtom::ContentPermissions permissions,
- typename TargetLayout<ELFT>::SectionOrder order) override;
-
- typename TargetLayout<ELFT>::SegmentType
- getSegmentType(const Section<ELFT> *section) const override;
-
- /// \brief GP offset relative to .got section.
- uint64_t getGPOffset() const { return 0x7FF0; }
-
- /// \brief Get '_gp' symbol address.
- uint64_t getGPAddr();
-
- /// \brief Return the section order for a input section
- typename TargetLayout<ELFT>::SectionOrder
- getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) override;
-
-protected:
- unique_bump_ptr<RelocationTable<ELFT>>
- createRelocationTable(StringRef name, int32_t order) override;
- uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override;
- void sortSegments() override;
-
-private:
- MipsAbiInfoHandler<ELFT> &_abiInfo;
- MipsGOTSection<ELFT> *_gotSection;
- MipsPLTSection<ELFT> *_pltSection;
- uint64_t _gpAddr = 0;
- std::once_flag _gpOnce;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/OrderPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OrderPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OrderPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OrderPass.h (removed)
@@ -1,31 +0,0 @@
-//===- lib/ReaderWriter/ELF/OrderPass.h -----------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_ORDER_PASS_H
-#define LLD_READER_WRITER_ELF_ORDER_PASS_H
-
-#include "lld/Core/Parallel.h"
-#include <limits>
-
-namespace lld {
-namespace elf {
-
-/// \brief This pass sorts atoms by file and atom ordinals.
-class OrderPass : public Pass {
-public:
- std::error_code perform(SimpleFile &file) override {
- parallel_sort(file.definedAtoms().begin(), file.definedAtoms().end(),
- DefinedAtom::compareByPosition);
- return std::error_code();
- }
-};
-}
-}
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.cpp (removed)
@@ -1,514 +0,0 @@
-//===- lib/ReaderWriter/ELF/OutputELFWriter.cpp --------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "OutputELFWriter.h"
-#include "lld/Core/SharedLibraryFile.h"
-#include "lld/Core/Simple.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Support/Path.h"
-
-namespace lld {
-namespace elf {
-
-namespace {
-
-template <class ELFT> class SymbolFile : public RuntimeFile<ELFT> {
-public:
- SymbolFile(ELFLinkingContext &ctx)
- : RuntimeFile<ELFT>(ctx, "Dynamic absolute symbols") {}
-
- void addUndefinedAtom(StringRef) override {
- llvm_unreachable("Cannot add undefined atoms to resolve undefined symbols");
- }
-
- bool hasAtoms() const { return this->absolute().size(); }
-};
-
-template <class ELFT>
-class DynamicSymbolFile : public SimpleArchiveLibraryFile {
- typedef std::function<void(StringRef, RuntimeFile<ELFT> &)> Resolver;
-
-public:
- DynamicSymbolFile(ELFLinkingContext &ctx, Resolver resolver)
- : SimpleArchiveLibraryFile("Dynamically added runtime symbols"),
- _ctx(ctx), _resolver(resolver) {}
-
- File *find(StringRef sym, bool dataSymbolOnly) override {
- if (!_file)
- _file.reset(new (_alloc) SymbolFile<ELFT>(_ctx));
-
- assert(!_file->hasAtoms() && "The file shouldn't have atoms yet");
- _resolver(sym, *_file);
-
- if (!_file->hasAtoms())
- return nullptr;
-
- // If atoms were added - return the file but also store it for later
- // destruction.
- File *result = _file.get();
- _returnedFiles.push_back(std::move(_file));
- return result;
- }
-
-private:
- ELFLinkingContext &_ctx;
- Resolver _resolver;
-
- // The allocator should go before bump pointers because of
- // reversed destruction order.
- llvm::BumpPtrAllocator _alloc;
- unique_bump_ptr<SymbolFile<ELFT>> _file;
- std::vector<unique_bump_ptr<SymbolFile<ELFT>>> _returnedFiles;
-};
-
-} // end anon namespace
-
-template <class ELFT>
-OutputELFWriter<ELFT>::OutputELFWriter(ELFLinkingContext &ctx,
- TargetLayout<ELFT> &layout)
- : _ctx(ctx), _targetHandler(ctx.getTargetHandler()), _layout(layout) {}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::buildChunks(const File &file) {
- ScopedTask task(getDefaultDomain(), "buildChunks");
- for (const DefinedAtom *definedAtom : file.defined()) {
- DefinedAtom::ContentType contentType = definedAtom->contentType();
- // Dont add COMDAT group atoms and GNU linkonce atoms, as they are used for
- // symbol resolution.
- // TODO: handle partial linking.
- if (contentType == DefinedAtom::typeGroupComdat ||
- contentType == DefinedAtom::typeGnuLinkOnce)
- continue;
- _layout.addAtom(definedAtom);
- }
- for (const AbsoluteAtom *absoluteAtom : file.absolute())
- _layout.addAtom(absoluteAtom);
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) {
- ScopedTask task(getDefaultDomain(), "buildStaticSymbolTable");
- for (auto sec : _layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms())
- _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
- for (auto &atom : _layout.absoluteAtoms())
- _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
- for (const UndefinedAtom *a : file.undefined())
- _symtab->addSymbol(a, ELF::SHN_UNDEF);
-}
-
-// Returns the DSO name for a given input file if it's a shared library
-// file and not marked as --as-needed.
-template <class ELFT>
-StringRef OutputELFWriter<ELFT>::maybeGetSOName(Node *node) {
- if (auto *fnode = dyn_cast<FileNode>(node))
- if (!fnode->asNeeded())
- if (auto *file = dyn_cast<SharedLibraryFile>(fnode->getFile()))
- return file->getDSOName();
- return "";
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
- for (const auto &sla : file.sharedLibrary()) {
- if (isDynSymEntryRequired(sla)) {
- _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
- _soNeeded.insert(sla->loadName());
- continue;
- }
- if (isNeededTagRequired(sla))
- _soNeeded.insert(sla->loadName());
- }
- for (const std::unique_ptr<Node> &node : _ctx.getNodes()) {
- StringRef soname = maybeGetSOName(node.get());
- if (!soname.empty())
- _soNeeded.insert(soname);
- }
- // Never mark the dynamic linker as DT_NEEDED
- _soNeeded.erase(sys::path::filename(_ctx.getInterpreter()));
- for (const auto &loadName : _soNeeded)
- _dynamicTable->addEntry(DT_NEEDED,
- _dynamicStringTable->addString(loadName.getKey()));
- const auto &rpathList = _ctx.getRpathList();
- if (!rpathList.empty()) {
- auto rpath =
- new (_alloc) std::string(join(rpathList.begin(), rpathList.end(), ":"));
- _dynamicTable->addEntry(_ctx.getEnableNewDtags() ? DT_RUNPATH : DT_RPATH,
- _dynamicStringTable->addString(*rpath));
- }
- StringRef soname = _ctx.sharedObjectName();
- if (!soname.empty() && _ctx.getOutputELFType() == llvm::ELF::ET_DYN)
- _dynamicTable->addEntry(DT_SONAME, _dynamicStringTable->addString(soname));
-
- // Add DT_FLAGS/DT_FLAGS_1 entries if necessary.
- uint32_t dtflags = 0, dt1flags = 0;
- if (_ctx.getDTFlag(ELFLinkingContext::DTFlag::DT_NOW)) {
- dtflags |= DF_BIND_NOW;
- dt1flags |= DF_1_NOW;
- }
- if (_ctx.getDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN)) {
- dtflags |= DF_ORIGIN;
- dt1flags |= DF_1_ORIGIN;
- }
- if (dtflags != 0)
- _dynamicTable->addEntry(DT_FLAGS, dtflags);
- if (dt1flags != 0)
- _dynamicTable->addEntry(DT_FLAGS_1, dt1flags);
-
- // The dynamic symbol table need to be sorted earlier because the hash
- // table needs to be built using the dynamic symbol table. It would be
- // late to sort the symbols due to that in finalize. In the dynamic symbol
- // table finalize, we call the symbol table finalize and we don't want to
- // sort again
- _dynamicSymbolTable->sortSymbols();
-
- // Add the dynamic symbols into the hash table
- _dynamicSymbolTable->addSymbolsToHashTable();
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::buildAtomToAddressMap(const File &file) {
- ScopedTask task(getDefaultDomain(), "buildAtomToAddressMap");
- int64_t totalAbsAtoms = _layout.absoluteAtoms().size();
- int64_t totalUndefinedAtoms = file.undefined().size();
- int64_t totalDefinedAtoms = 0;
- for (auto sec : _layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec)) {
- totalDefinedAtoms += section->atoms().size();
- for (const auto &atom : section->atoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
- }
- // build the atomToAddressMap that contains absolute symbols too
- for (auto &atom : _layout.absoluteAtoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
-
- // Set the total number of atoms in the symbol table, so that appropriate
- // resizing of the string table can be done.
- // There's no such thing as symbol table if we're stripping all the symbols
- if (!_ctx.stripSymbols())
- _symtab->setNumEntries(totalDefinedAtoms + totalAbsAtoms +
- totalUndefinedAtoms);
-}
-
-template <class ELFT> void OutputELFWriter<ELFT>::buildSectionHeaderTable() {
- ScopedTask task(getDefaultDomain(), "buildSectionHeaderTable");
- for (auto outputSection : _layout.outputSections()) {
- if (outputSection->kind() != Chunk<ELFT>::Kind::ELFSection &&
- outputSection->kind() != Chunk<ELFT>::Kind::AtomSection)
- continue;
- if (outputSection->hasSegment())
- _shdrtab->appendSection(outputSection);
- }
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() {
- ScopedTask task(getDefaultDomain(), "assignSectionsWithNoSegments");
- for (auto outputSection : _layout.outputSections()) {
- if (outputSection->kind() != Chunk<ELFT>::Kind::ELFSection &&
- outputSection->kind() != Chunk<ELFT>::Kind::AtomSection)
- continue;
- if (!outputSection->hasSegment())
- _shdrtab->appendSection(outputSection);
- }
- _layout.assignFileOffsetsForMiscSections();
- for (auto sec : _layout.sections())
- if (auto section = dyn_cast<Section<ELFT>>(sec))
- if (!TargetLayout<ELFT>::hasOutputSegment(section))
- _shdrtab->updateSection(section);
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- // Add the virtual archive to resolve undefined symbols.
- // The file will be added later in the linking context.
- auto callback = [this](StringRef sym, RuntimeFile<ELFT> &file) {
- processUndefinedSymbol(sym, file);
- };
- _ctx.setUndefinesResolver(
- llvm::make_unique<DynamicSymbolFile<ELFT>>(_ctx, std::move(callback)));
- // Add script defined symbols
- auto file =
- llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Linker script runtime");
- for (auto &sym : this->_ctx.linkerScriptSema().getScriptDefinedSymbols())
- file->addAbsoluteAtom(sym.getKey());
- result.push_back(std::move(file));
-}
-
-template <class ELFT> void OutputELFWriter<ELFT>::finalizeDefaultAtomValues() {
- const llvm::StringSet<> &symbols =
- _ctx.linkerScriptSema().getScriptDefinedSymbols();
- for (auto &sym : symbols) {
- uint64_t res =
- _ctx.linkerScriptSema().getLinkerScriptExprValue(sym.getKey());
- AtomLayout *a = _layout.findAbsoluteAtom(sym.getKey());
- assert(a);
- a->_virtualAddr = res;
- }
- // If there is a section named XXX, and XXX is a valid C identifier,
- // and there are undefined or weak __start_XXX/__stop_XXX symbols,
- // set the symbols values to the begin/end of the XXX section
- // correspondingly.
- for (const auto &name : _ctx.cidentSectionNames())
- updateScopeAtomValues((Twine("__start_") + name.getKey()).str(),
- (Twine("__stop_") + name.getKey()).str(),
- name.getKey());
-}
-
-template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
- _elfHeader.reset(new (_alloc) ELFHeader<ELFT>(_ctx));
- _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_ctx));
- _layout.setHeader(_elfHeader.get());
- _layout.setProgramHeader(_programHeader.get());
-
- // Don't create .symtab and .strtab sections if we're going to
- // strip all the symbols.
- if (!_ctx.stripSymbols()) {
- _symtab = this->createSymbolTable();
- _strtab.reset(new (_alloc) StringTable<ELFT>(
- _ctx, ".strtab", TargetLayout<ELFT>::ORDER_STRING_TABLE));
- _layout.addSection(_symtab.get());
- _layout.addSection(_strtab.get());
- _symtab->setStringSection(_strtab.get());
- }
-
- _shstrtab.reset(new (_alloc) StringTable<ELFT>(
- _ctx, ".shstrtab", TargetLayout<ELFT>::ORDER_SECTION_STRINGS));
- _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
- _ctx, TargetLayout<ELFT>::ORDER_SECTION_HEADERS));
- _layout.addSection(_shstrtab.get());
- _shdrtab->setStringSection(_shstrtab.get());
- _layout.addSection(_shdrtab.get());
-
- for (auto sec : _layout.sections()) {
- // TODO: use findOutputSection
- auto section = dyn_cast<Section<ELFT>>(sec);
- if (!section || section->outputSectionName() != ".eh_frame")
- continue;
- _ehFrameHeader.reset(new (_alloc) EHFrameHeader<ELFT>(
- _ctx, ".eh_frame_hdr", _layout, TargetLayout<ELFT>::ORDER_EH_FRAMEHDR));
- _layout.addSection(_ehFrameHeader.get());
- break;
- }
-
- if (_ctx.isDynamic()) {
- _dynamicTable = createDynamicTable();
- _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
- _ctx, ".dynstr", TargetLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true));
- _dynamicSymbolTable = createDynamicSymbolTable();
- _hashTable.reset(new (_alloc) HashSection<ELFT>(
- _ctx, ".hash", TargetLayout<ELFT>::ORDER_HASH));
- // Set the hash table in the dynamic symbol table so that the entries in the
- // hash table can be created
- _dynamicSymbolTable->setHashTable(_hashTable.get());
- _hashTable->setSymbolTable(_dynamicSymbolTable.get());
- _layout.addSection(_dynamicTable.get());
- _layout.addSection(_dynamicStringTable.get());
- _layout.addSection(_dynamicSymbolTable.get());
- _layout.addSection(_hashTable.get());
- _dynamicSymbolTable->setStringSection(_dynamicStringTable.get());
- _dynamicTable->setSymbolTable(_dynamicSymbolTable.get());
- _dynamicTable->setHashTable(_hashTable.get());
- if (_layout.hasDynamicRelocationTable())
- _layout.getDynamicRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
- if (_layout.hasPLTRelocationTable())
- _layout.getPLTRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
- }
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>> OutputELFWriter<ELFT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELFT>>(new (_alloc) SymbolTable<ELFT>(
- this->_ctx, ".symtab", TargetLayout<ELFT>::ORDER_SYMBOL_TABLE));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
-OutputELFWriter<ELFT>::createDynamicTable() {
- return unique_bump_ptr<DynamicTable<ELFT>>(new (_alloc) DynamicTable<ELFT>(
- this->_ctx, _layout, ".dynamic", TargetLayout<ELFT>::ORDER_DYNAMIC));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
-OutputELFWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
- new (_alloc)
- DynamicSymbolTable<ELFT>(this->_ctx, _layout, ".dynsym",
- TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
-}
-
-template <class ELFT>
-std::error_code OutputELFWriter<ELFT>::buildOutput(const File &file) {
- ScopedTask buildTask(getDefaultDomain(), "ELF Writer buildOutput");
- buildChunks(file);
-
- // Create the default sections like the symbol table, string table, and the
- // section string table
- createDefaultSections();
-
- // Set the Layout
- _layout.assignSectionsToSegments();
-
- // Create the dynamic table entries
- if (_ctx.isDynamic()) {
- _dynamicTable->createDefaultEntries();
- buildDynamicSymbolTable(file);
- }
-
- // Call the preFlight callbacks to modify the sections and the atoms
- // contained in them, in anyway the targets may want
- _layout.doPreFlight();
-
- _layout.assignVirtualAddress();
-
- // Finalize the default value of symbols that the linker adds
- finalizeDefaultAtomValues();
-
- // Build the Atom To Address map for applying relocations
- buildAtomToAddressMap(file);
-
- // Create symbol table and section string table
- // Do it only if -s is not specified.
- if (!_ctx.stripSymbols())
- buildStaticSymbolTable(file);
-
- // Finalize the layout by calling the finalize() functions
- _layout.finalize();
-
- // build Section Header table
- buildSectionHeaderTable();
-
- // assign Offsets and virtual addresses
- // for sections with no segments
- assignSectionsWithNoSegments();
-
- if (_ctx.isDynamic())
- _dynamicTable->updateDynamicTable();
-
- return std::error_code();
-}
-
-template <class ELFT> std::error_code OutputELFWriter<ELFT>::setELFHeader() {
- _elfHeader->e_type(_ctx.getOutputELFType());
- _elfHeader->e_machine(_ctx.getOutputMachine());
- _elfHeader->e_ident(ELF::EI_VERSION, 1);
- _elfHeader->e_ident(ELF::EI_OSABI, 0);
- _elfHeader->e_version(1);
- _elfHeader->e_phoff(_programHeader->fileOffset());
- _elfHeader->e_shoff(_shdrtab->fileOffset());
- _elfHeader->e_phentsize(_programHeader->entsize());
- _elfHeader->e_phnum(_programHeader->numHeaders());
- _elfHeader->e_shentsize(_shdrtab->entsize());
- _elfHeader->e_shnum(_shdrtab->numHeaders());
- _elfHeader->e_shstrndx(_shstrtab->ordinal());
- if (const auto *al = _layout.findAtomLayoutByName(_ctx.entrySymbolName()))
- _elfHeader->e_entry(al->_virtualAddr);
- else
- _elfHeader->e_entry(0);
-
- return std::error_code();
-}
-
-template <class ELFT> uint64_t OutputELFWriter<ELFT>::outputFileSize() const {
- return _shdrtab->fileOffset() + _shdrtab->fileSize();
-}
-
-template <class ELFT>
-std::error_code OutputELFWriter<ELFT>::writeOutput(const File &file,
- StringRef path) {
-
- ScopedTask createOutputTask(getDefaultDomain(), "ELF Writer Create Output");
- ErrorOr<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
- FileOutputBuffer::create(path, outputFileSize(),
- FileOutputBuffer::F_executable);
- if (std::error_code ec = bufferOrErr.getError())
- return ec;
- std::unique_ptr<FileOutputBuffer> &buffer = *bufferOrErr;
- createOutputTask.end();
-
- ScopedTask writeTask(getDefaultDomain(), "ELF Writer write to memory");
-
- // HACK: We have to write out the header and program header here even though
- // they are a member of a segment because only sections are written in the
- // following loop.
-
- // Finalize ELF Header / Program Headers.
- _elfHeader->finalize();
- _programHeader->finalize();
-
- _elfHeader->write(this, _layout, *buffer);
- _programHeader->write(this, _layout, *buffer);
-
- auto sections = _layout.sections();
- parallel_for_each(
- sections.begin(), sections.end(),
- [&](Chunk<ELFT> *section) { section->write(this, _layout, *buffer); });
- writeTask.end();
-
- ScopedTask commitTask(getDefaultDomain(), "ELF Writer commit to disk");
- return buffer->commit();
-}
-
-template <class ELFT>
-std::error_code OutputELFWriter<ELFT>::writeFile(const File &file,
- StringRef path) {
- if (std::error_code ec = buildOutput(file))
- return ec;
- if (std::error_code ec = setELFHeader())
- return ec;
- return writeOutput(file, path);
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::processUndefinedSymbol(
- StringRef symName, RuntimeFile<ELFT> &file) const {
- if (symName.startswith("__start_")) {
- if (_ctx.cidentSectionNames().count(symName.drop_front(8)))
- file.addAbsoluteAtom(symName);
- } else if (symName.startswith("__stop_")) {
- if (_ctx.cidentSectionNames().count(symName.drop_front(7)))
- file.addAbsoluteAtom(symName);
- }
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::updateScopeAtomValues(StringRef sym,
- StringRef sec) {
- updateScopeAtomValues(("__" + sym + "_start").str().c_str(),
- ("__" + sym + "_end").str().c_str(), sec);
-}
-
-template <class ELFT>
-void OutputELFWriter<ELFT>::updateScopeAtomValues(StringRef start,
- StringRef end,
- StringRef sec) {
- AtomLayout *s = _layout.findAbsoluteAtom(start);
- AtomLayout *e = _layout.findAbsoluteAtom(end);
- const OutputSection<ELFT> *section = _layout.findOutputSection(sec);
- if (s)
- s->_virtualAddr = section ? section->virtualAddr() : 0;
- if (e)
- e->_virtualAddr = section ? section->virtualAddr() + section->memSize() : 0;
-}
-
-template class OutputELFWriter<ELF32LE>;
-template class OutputELFWriter<ELF32BE>;
-template class OutputELFWriter<ELF64LE>;
-template class OutputELFWriter<ELF64BE>;
-
-} // namespace elf
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (removed)
@@ -1,153 +0,0 @@
-//===- lib/ReaderWriter/ELF/OutputELFWriter.h ----------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
-#define LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
-
-#include "ELFFile.h"
-#include "TargetLayout.h"
-#include "lld/Core/Writer.h"
-#include "llvm/ADT/StringSet.h"
-
-namespace lld {
-class ELFLinkingContext;
-
-namespace elf {
-using namespace llvm;
-using namespace llvm::object;
-
-// OutputELFWriter Class
-//
-/// \brief This acts as the base class for all the ELF writers that are output
-/// for emitting an ELF output file. This class also acts as a common class for
-/// creating static and dynamic executables. All the function in this class
-/// can be overridden and an appropriate writer be created
-template<class ELFT>
-class OutputELFWriter : public ELFWriter {
-public:
- typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
- typedef Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
-
- OutputELFWriter(ELFLinkingContext &ctx, TargetLayout<ELFT> &layout);
-
-protected:
- // build the sections that need to be created
- virtual void createDefaultSections();
-
- // Build all the output sections
- void buildChunks(const File &file) override;
-
- // Build the output file
- virtual std::error_code buildOutput(const File &file);
-
- // Setup the ELF header.
- virtual std::error_code setELFHeader();
-
- // Write the file to the path specified
- std::error_code writeFile(const File &File, StringRef path) override;
-
- // Write to the output file.
- virtual std::error_code writeOutput(const File &file, StringRef path);
-
- // Get the size of the output file that the linker would emit.
- virtual uint64_t outputFileSize() const;
-
- // Build the atom to address map, this has to be called
- // before applying relocations
- virtual void buildAtomToAddressMap(const File &file);
-
- // Build the symbol table for static linking
- virtual void buildStaticSymbolTable(const File &file);
-
- // Build the dynamic symbol table for dynamic linking
- virtual void buildDynamicSymbolTable(const File &file);
-
- // Build the section header table
- virtual void buildSectionHeaderTable();
-
- // Assign sections that have no segments such as the symbol table,
- // section header table, string table etc
- virtual void assignSectionsWithNoSegments();
-
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- // Finalize the default atom values
- virtual void finalizeDefaultAtomValues();
-
- // This is called by the write section to apply relocations
- uint64_t addressOfAtom(const Atom *atom) override {
- auto addr = _atomToAddressMap.find(atom);
- return addr == _atomToAddressMap.end() ? 0 : addr->second;
- }
-
- // This is a hook for creating default dynamic entries
- virtual void createDefaultDynamicEntries() {}
-
- /// \brief Create symbol table.
- virtual unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable();
-
- /// \brief create dynamic table.
- virtual unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable();
-
- /// \brief create dynamic symbol table.
- virtual unique_bump_ptr<DynamicSymbolTable<ELFT>>
- createDynamicSymbolTable();
-
- /// \brief Create entry in the dynamic symbols table for this atom.
- virtual bool isDynSymEntryRequired(const SharedLibraryAtom *sla) const {
- return _layout.isReferencedByDefinedAtom(sla);
- }
-
- /// \brief Create DT_NEEDED dynamic tage for the shared library.
- virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const {
- return false;
- }
-
- /// \brief Process undefined symbols that left after resolution step.
- virtual void processUndefinedSymbol(StringRef symName,
- RuntimeFile<ELFT> &file) const;
-
- /// \brief Assign addresses to atoms marking section's start and end.
- void updateScopeAtomValues(StringRef sym, StringRef sec);
-
- llvm::BumpPtrAllocator _alloc;
-
- ELFLinkingContext &_ctx;
- TargetHandler &_targetHandler;
-
- typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
- AtomToAddress _atomToAddressMap;
- TargetLayout<ELFT> &_layout;
- unique_bump_ptr<ELFHeader<ELFT>> _elfHeader;
- unique_bump_ptr<ProgramHeader<ELFT>> _programHeader;
- unique_bump_ptr<SymbolTable<ELFT>> _symtab;
- unique_bump_ptr<StringTable<ELFT>> _strtab;
- unique_bump_ptr<StringTable<ELFT>> _shstrtab;
- unique_bump_ptr<SectionHeader<ELFT>> _shdrtab;
- unique_bump_ptr<EHFrameHeader<ELFT>> _ehFrameHeader;
- /// \name Dynamic sections.
- /// @{
- unique_bump_ptr<DynamicTable<ELFT>> _dynamicTable;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> _dynamicSymbolTable;
- unique_bump_ptr<StringTable<ELFT>> _dynamicStringTable;
- unique_bump_ptr<HashSection<ELFT>> _hashTable;
- llvm::StringSet<> _soNeeded;
- /// @}
-
-private:
- static StringRef maybeGetSOName(Node *node);
- void updateScopeAtomValues(StringRef start, StringRef end, StringRef sec);
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Reader.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (removed)
@@ -1,43 +0,0 @@
-//===- lib/ReaderWriter/ELF/Reader.cpp ------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the ELF Reader and all helper sub classes to consume an ELF
-/// file and produces atoms out of it.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ELFReader.h"
-#include <map>
-#include <vector>
-
-using llvm::support::endianness;
-using namespace llvm::object;
-
-namespace lld {
-
-// This dynamic registration of a handler causes support for all ELF
-// architectures to be pulled into the linker. If we want to support making a
-// linker that only supports one ELF architecture, we'd need to change this
-// to have a different registration method for each architecture.
-void Registry::addSupportELFObjects(ELFLinkingContext &ctx) {
-
- // Tell registry about the ELF object file parser.
- add(ctx.getTargetHandler().getObjReader());
-
- // Tell registry about the relocation name to number mapping for this arch.
- ctx.registerRelocationNames(*this);
-}
-
-void Registry::addSupportELFDynamicSharedObjects(ELFLinkingContext &ctx) {
- // Tell registry about the ELF dynamic shared library file parser.
- add(ctx.getTargetHandler().getDSOReader());
-}
-
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.cpp (removed)
@@ -1,996 +0,0 @@
-//===- lib/ReaderWriter/ELF/SectionChunks.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SectionChunks.h"
-#include "TargetLayout.h"
-#include "lld/Core/Parallel.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/Dwarf.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-Section<ELFT>::Section(const ELFLinkingContext &ctx, StringRef sectionName,
- StringRef chunkName, typename Chunk<ELFT>::Kind k)
- : Chunk<ELFT>(chunkName, k, ctx), _inputSectionName(sectionName),
- _outputSectionName(sectionName) {}
-
-template <class ELFT> int Section<ELFT>::getContentType() const {
- if (_flags & llvm::ELF::SHF_EXECINSTR)
- return Chunk<ELFT>::ContentType::Code;
- else if (_flags & llvm::ELF::SHF_WRITE)
- return Chunk<ELFT>::ContentType::Data;
- else if (_flags & llvm::ELF::SHF_ALLOC)
- return Chunk<ELFT>::ContentType::Code;
- else
- return Chunk<ELFT>::ContentType::Unknown;
-}
-
-template <class ELFT>
-AtomSection<ELFT>::AtomSection(const ELFLinkingContext &ctx,
- StringRef sectionName, int32_t contentType,
- int32_t permissions, int32_t order)
- : Section<ELFT>(ctx, sectionName, "AtomSection",
- Chunk<ELFT>::Kind::AtomSection),
- _contentType(contentType), _contentPermissions(permissions) {
- this->setOrder(order);
-
- switch (contentType) {
- case DefinedAtom::typeCode:
- case DefinedAtom::typeDataFast:
- case DefinedAtom::typeData:
- case DefinedAtom::typeConstant:
- case DefinedAtom::typeGOT:
- case DefinedAtom::typeStub:
- case DefinedAtom::typeResolver:
- case DefinedAtom::typeThreadData:
- this->_type = SHT_PROGBITS;
- break;
-
- case DefinedAtom::typeThreadZeroFill:
- case DefinedAtom::typeZeroFillFast:
- case DefinedAtom::typeZeroFill:
- this->_type = SHT_NOBITS;
- break;
-
- case DefinedAtom::typeRONote:
- case DefinedAtom::typeRWNote:
- this->_type = SHT_NOTE;
- break;
-
- case DefinedAtom::typeNoAlloc:
- this->_type = SHT_PROGBITS;
- this->_isLoadedInMemory = false;
- break;
- }
-
- switch (permissions) {
- case DefinedAtom::permR__:
- this->_flags = SHF_ALLOC;
- break;
- case DefinedAtom::permR_X:
- this->_flags = SHF_ALLOC | SHF_EXECINSTR;
- break;
- case DefinedAtom::permRW_:
- case DefinedAtom::permRW_L:
- this->_flags = SHF_ALLOC | SHF_WRITE;
- if (_contentType == DefinedAtom::typeThreadData ||
- _contentType == DefinedAtom::typeThreadZeroFill)
- this->_flags |= SHF_TLS;
- break;
- case DefinedAtom::permRWX:
- this->_flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
- break;
- case DefinedAtom::perm___:
- this->_flags = 0;
- break;
- }
-}
-
-template <class ELFT>
-void AtomSection<ELFT>::assignVirtualAddress(uint64_t addr) {
- parallel_for_each(_atoms.begin(), _atoms.end(), [&](AtomLayout *ai) {
- ai->_virtualAddr = addr + ai->_fileOffset;
- });
-}
-
-template <class ELFT>
-void AtomSection<ELFT>::assignFileOffsets(uint64_t offset) {
- parallel_for_each(_atoms.begin(), _atoms.end(), [&](AtomLayout *ai) {
- ai->_fileOffset = offset + ai->_fileOffset;
- });
-}
-
-template <class ELFT>
-const AtomLayout *
-AtomSection<ELFT>::findAtomLayoutByName(StringRef name) const {
- for (auto ai : _atoms)
- if (ai->_atom->name() == name)
- return ai;
- return nullptr;
-}
-
-template <class ELFT>
-std::string AtomSection<ELFT>::formatError(const std::string &errorStr,
- const AtomLayout &atom,
- const Reference &ref) const {
- StringRef kindValStr;
- if (!this->_ctx.registry().referenceKindToString(
- ref.kindNamespace(), ref.kindArch(), ref.kindValue(), kindValStr)) {
- kindValStr = "unknown";
- }
-
- return
- (Twine(errorStr) + " in file " + atom._atom->file().path() +
- ": reference from " + atom._atom->name() + "+" +
- Twine(ref.offsetInAtom()) + " to " + ref.target()->name() + "+" +
- Twine(ref.addend()) + " of type " + Twine(ref.kindValue()) + " (" +
- kindValStr + ")\n")
- .str();
-}
-
-/// Align the offset to the required modulus defined by the atom alignment
-template <class ELFT>
-uint64_t AtomSection<ELFT>::alignOffset(uint64_t offset,
- DefinedAtom::Alignment &atomAlign) {
- uint64_t requiredModulus = atomAlign.modulus;
- uint64_t alignment = atomAlign.value;
- uint64_t currentModulus = (offset % alignment);
- uint64_t retOffset = offset;
- if (currentModulus != requiredModulus) {
- if (requiredModulus > currentModulus)
- retOffset += requiredModulus - currentModulus;
- else
- retOffset += alignment + requiredModulus - currentModulus;
- }
- return retOffset;
-}
-
-// \brief Append an atom to a Section. The atom gets pushed into a vector
-// contains the atom, the atom file offset, the atom virtual address
-// the atom file offset is aligned appropriately as set by the Reader
-template <class ELFT>
-const AtomLayout *AtomSection<ELFT>::appendAtom(const Atom *atom) {
- const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
-
- DefinedAtom::Alignment atomAlign = definedAtom->alignment();
- uint64_t alignment = atomAlign.value;
- // Align the atom to the required modulus/ align the file offset and the
- // memory offset separately this is required so that BSS symbols are handled
- // properly as the BSS symbols only occupy memory size and not file size
- uint64_t fOffset = alignOffset(this->fileSize(), atomAlign);
- uint64_t mOffset = alignOffset(this->memSize(), atomAlign);
- switch (definedAtom->contentType()) {
- case DefinedAtom::typeCode:
- case DefinedAtom::typeConstant:
- case DefinedAtom::typeData:
- case DefinedAtom::typeDataFast:
- case DefinedAtom::typeZeroFillFast:
- case DefinedAtom::typeGOT:
- case DefinedAtom::typeStub:
- case DefinedAtom::typeResolver:
- case DefinedAtom::typeThreadData:
- case DefinedAtom::typeRONote:
- case DefinedAtom::typeRWNote:
- _atoms.push_back(new (_alloc) AtomLayout(atom, fOffset, 0));
- this->_fsize = fOffset + definedAtom->size();
- this->_msize = mOffset + definedAtom->size();
- DEBUG_WITH_TYPE("Section", llvm::dbgs()
- << "[" << this->name() << " " << this << "] "
- << "Adding atom: " << atom->name() << "@"
- << fOffset << "\n");
- break;
- case DefinedAtom::typeNoAlloc:
- _atoms.push_back(new (_alloc) AtomLayout(atom, fOffset, 0));
- this->_fsize = fOffset + definedAtom->size();
- DEBUG_WITH_TYPE("Section", llvm::dbgs()
- << "[" << this->name() << " " << this << "] "
- << "Adding atom: " << atom->name() << "@"
- << fOffset << "\n");
- break;
- case DefinedAtom::typeThreadZeroFill:
- case DefinedAtom::typeZeroFill:
- _atoms.push_back(new (_alloc) AtomLayout(atom, mOffset, 0));
- this->_msize = mOffset + definedAtom->size();
- break;
- default:
- llvm::dbgs() << definedAtom->contentType() << "\n";
- llvm_unreachable("Uexpected content type.");
- }
- // Set the section alignment to the largest alignment
- // std::max doesn't support uint64_t
- if (this->_alignment < alignment)
- this->_alignment = alignment;
-
- if (_atoms.size())
- return _atoms.back();
- return nullptr;
-}
-
-/// \brief convert the segment type to a String for diagnostics
-/// and printing purposes
-template <class ELFT> StringRef Section<ELFT>::segmentKindToStr() const {
- switch (_segmentType) {
- case llvm::ELF::PT_DYNAMIC:
- return "DYNAMIC";
- case llvm::ELF::PT_INTERP:
- return "INTERP";
- case llvm::ELF::PT_LOAD:
- return "LOAD";
- case llvm::ELF::PT_GNU_EH_FRAME:
- return "EH_FRAME";
- case llvm::ELF::PT_GNU_RELRO:
- return "GNU_RELRO";
- case llvm::ELF::PT_NOTE:
- return "NOTE";
- case llvm::ELF::PT_NULL:
- return "NULL";
- case llvm::ELF::PT_TLS:
- return "TLS";
- default:
- return "UNKNOWN";
- }
-}
-
-/// \brief Write the section and the atom contents to the buffer
-template <class ELFT>
-void AtomSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- bool success = true;
-
- // parallel_for_each() doesn't have deterministic order. To guarantee
- // deterministic error output, collect errors in this vector and sort it
- // by atom file offset before printing all errors.
- std::vector<std::pair<size_t, std::string>> errors;
- parallel_for_each(_atoms.begin(), _atoms.end(), [&](AtomLayout *ai) {
- DEBUG_WITH_TYPE("Section", llvm::dbgs()
- << "Writing atom: " << ai->_atom->name()
- << " | " << ai->_fileOffset << "\n");
- const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
- if (!definedAtom->occupiesDiskSpace())
- return;
- // Copy raw content of atom to file buffer.
- ArrayRef<uint8_t> content = definedAtom->rawContent();
- uint64_t contentSize = content.size();
- if (contentSize == 0)
- return;
- uint8_t *atomContent = chunkBuffer + ai->_fileOffset;
- std::memcpy(atomContent, content.data(), contentSize);
- const TargetRelocationHandler &relHandler =
- this->_ctx.getTargetHandler().getRelocationHandler();
- for (const auto ref : *definedAtom) {
- if (std::error_code ec =
- relHandler.applyRelocation(*writer, buffer, *ai, *ref)) {
- std::lock_guard<std::mutex> lock(_outputMutex);
- errors.push_back(std::make_pair(ai->_fileOffset,
- formatError(ec.message(), *ai, *ref)));
- success = false;
- }
- }
- });
- if (!success) {
- std::sort(errors.begin(), errors.end());
- for (auto &&error : errors)
- llvm::errs() << error.second;
- llvm::report_fatal_error("relocating output");
- }
-}
-
-template <class ELFT>
-void OutputSection<ELFT>::appendSection(Section<ELFT> *section) {
- if (section->alignment() > _alignment)
- _alignment = section->alignment();
- assert(!_link && "Section already has a link!");
- _link = section->getLink();
- _shInfo = section->getInfo();
- _entSize = section->getEntSize();
- _type = section->getType();
- if (_flags < section->getFlags())
- _flags = section->getFlags();
- section->setOutputSection(this, (_sections.size() == 0));
- _kind = section->kind();
- _sections.push_back(section);
-}
-
-template <class ELFT>
-StringTable<ELFT>::StringTable(const ELFLinkingContext &ctx, const char *str,
- int32_t order, bool dynamic)
- : Section<ELFT>(ctx, str, "StringTable") {
- // the string table has a NULL entry for which
- // add an empty string
- _strings.push_back("");
- this->_fsize = 1;
- this->_alignment = 1;
- this->setOrder(order);
- this->_type = SHT_STRTAB;
- if (dynamic) {
- this->_flags = SHF_ALLOC;
- this->_msize = this->_fsize;
- }
-}
-
-template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) {
- if (symname.empty())
- return 0;
- StringMapTIter stringIter = _stringMap.find(symname);
- if (stringIter == _stringMap.end()) {
- _strings.push_back(symname);
- uint64_t offset = this->_fsize;
- this->_fsize += symname.size() + 1;
- if (this->_flags & SHF_ALLOC)
- this->_msize = this->_fsize;
- _stringMap[symname] = offset;
- return offset;
- }
- return stringIter->second;
-}
-
-template <class ELFT>
-void StringTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- for (auto si : _strings) {
- memcpy(dest, si.data(), si.size());
- dest += si.size();
- memcpy(dest, "", 1);
- dest += 1;
- }
-}
-
-/// ELF Symbol Table
-template <class ELFT>
-SymbolTable<ELFT>::SymbolTable(const ELFLinkingContext &ctx, const char *str,
- int32_t order)
- : Section<ELFT>(ctx, str, "SymbolTable") {
- this->setOrder(order);
- Elf_Sym symbol;
- std::memset(&symbol, 0, sizeof(Elf_Sym));
- _symbolTable.push_back(SymbolEntry(nullptr, symbol, nullptr));
- this->_entSize = sizeof(Elf_Sym);
- this->_fsize = sizeof(Elf_Sym);
- this->_alignment = sizeof(Elf_Addr);
- this->_type = SHT_SYMTAB;
-}
-
-template <class ELFT>
-void SymbolTable<ELFT>::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) {
- unsigned char binding = 0, type = 0;
- sym.st_size = da->size();
- DefinedAtom::ContentType ct;
- switch (ct = da->contentType()) {
- case DefinedAtom::typeCode:
- case DefinedAtom::typeStub:
- sym.st_value = addr;
- type = llvm::ELF::STT_FUNC;
- break;
- case DefinedAtom::typeResolver:
- sym.st_value = addr;
- type = llvm::ELF::STT_GNU_IFUNC;
- break;
- case DefinedAtom::typeDataFast:
- case DefinedAtom::typeData:
- case DefinedAtom::typeConstant:
- sym.st_value = addr;
- type = llvm::ELF::STT_OBJECT;
- break;
- case DefinedAtom::typeGOT:
- sym.st_value = addr;
- type = llvm::ELF::STT_NOTYPE;
- break;
- case DefinedAtom::typeZeroFill:
- case DefinedAtom::typeZeroFillFast:
- type = llvm::ELF::STT_OBJECT;
- sym.st_value = addr;
- break;
- case DefinedAtom::typeThreadData:
- case DefinedAtom::typeThreadZeroFill:
- type = llvm::ELF::STT_TLS;
- sym.st_value = addr;
- break;
- default:
- type = llvm::ELF::STT_NOTYPE;
- }
- if (da->customSectionName() == da->name())
- type = llvm::ELF::STT_SECTION;
-
- if (da->scope() == DefinedAtom::scopeTranslationUnit)
- binding = llvm::ELF::STB_LOCAL;
- else
- binding = llvm::ELF::STB_GLOBAL;
-
- sym.setBindingAndType(binding, type);
-}
-
-template <class ELFT>
-void SymbolTable<ELFT>::addAbsoluteAtom(Elf_Sym &sym, const AbsoluteAtom *aa,
- int64_t addr) {
- unsigned char binding = 0, type = 0;
- type = llvm::ELF::STT_OBJECT;
- sym.st_shndx = llvm::ELF::SHN_ABS;
- switch (aa->scope()) {
- case AbsoluteAtom::scopeLinkageUnit:
- sym.setVisibility(llvm::ELF::STV_HIDDEN);
- binding = llvm::ELF::STB_LOCAL;
- break;
- case AbsoluteAtom::scopeTranslationUnit:
- binding = llvm::ELF::STB_LOCAL;
- break;
- case AbsoluteAtom::scopeGlobal:
- binding = llvm::ELF::STB_GLOBAL;
- break;
- }
- sym.st_value = addr;
- sym.setBindingAndType(binding, type);
-}
-
-template <class ELFT>
-void SymbolTable<ELFT>::addSharedLibAtom(Elf_Sym &sym,
- const SharedLibraryAtom *aa) {
- unsigned char binding = 0, type = 0;
- if (aa->type() == SharedLibraryAtom::Type::Data) {
- type = llvm::ELF::STT_OBJECT;
- sym.st_size = aa->size();
- } else
- type = llvm::ELF::STT_FUNC;
- sym.st_shndx = llvm::ELF::SHN_UNDEF;
- binding = llvm::ELF::STB_GLOBAL;
- sym.setBindingAndType(binding, type);
-}
-
-template <class ELFT>
-void SymbolTable<ELFT>::addUndefinedAtom(Elf_Sym &sym,
- const UndefinedAtom *ua) {
- unsigned char binding = 0, type = 0;
- sym.st_value = 0;
- type = llvm::ELF::STT_NOTYPE;
- if (ua->canBeNull())
- binding = llvm::ELF::STB_WEAK;
- else
- binding = llvm::ELF::STB_GLOBAL;
- sym.setBindingAndType(binding, type);
-}
-
-/// Add a symbol to the symbol Table, definedAtoms which get added to the symbol
-/// section don't have their virtual addresses set at the time of adding the
-/// symbol to the symbol table(Example: dynamic symbols), the addresses needs
-/// to be updated in the table before writing the dynamic symbol table
-/// information
-template <class ELFT>
-void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex,
- uint64_t addr, const AtomLayout *atomLayout) {
- Elf_Sym symbol;
-
- if (atom->name().empty())
- return;
-
- symbol.st_name = _stringSection->addString(atom->name());
- symbol.st_size = 0;
- symbol.st_shndx = sectionIndex;
- symbol.st_value = 0;
- symbol.st_other = 0;
- symbol.setVisibility(llvm::ELF::STV_DEFAULT);
-
- // Add all the atoms
- if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom))
- addDefinedAtom(symbol, da, addr);
- else if (const AbsoluteAtom *aa = dyn_cast<const AbsoluteAtom>(atom))
- addAbsoluteAtom(symbol, aa, addr);
- else if (isa<const SharedLibraryAtom>(atom))
- addSharedLibAtom(symbol, dyn_cast<SharedLibraryAtom>(atom));
- else
- addUndefinedAtom(symbol, dyn_cast<UndefinedAtom>(atom));
-
- // If --discard-all is on, don't add to the symbol table
- // symbols with local binding.
- if (this->_ctx.discardLocals() && symbol.getBinding() == llvm::ELF::STB_LOCAL)
- return;
-
- // Temporary locals are all the symbols which name starts with .L.
- // This is defined by the ELF standard.
- if (this->_ctx.discardTempLocals() && atom->name().startswith(".L"))
- return;
-
- _symbolTable.push_back(SymbolEntry(atom, symbol, atomLayout));
- this->_fsize += sizeof(Elf_Sym);
- if (this->_flags & SHF_ALLOC)
- this->_msize = this->_fsize;
-}
-
-template <class ELFT> void SymbolTable<ELFT>::finalize(bool sort) {
- // sh_info should be one greater than last symbol with STB_LOCAL binding
- // we sort the symbol table to keep all local symbols at the beginning
- if (sort)
- sortSymbols();
-
- uint16_t shInfo = 0;
- for (const auto &i : _symbolTable) {
- if (i._symbol.getBinding() != llvm::ELF::STB_LOCAL)
- break;
- shInfo++;
- }
- this->_info = shInfo;
- this->_link = _stringSection->ordinal();
- if (this->_outputSection) {
- this->_outputSection->setInfo(this->_info);
- this->_outputSection->setLink(this->_link);
- }
-}
-
-template <class ELFT>
-void SymbolTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- for (const auto &sti : _symbolTable) {
- memcpy(dest, &sti._symbol, sizeof(Elf_Sym));
- dest += sizeof(Elf_Sym);
- }
-}
-
-template <class ELFT>
-DynamicSymbolTable<ELFT>::DynamicSymbolTable(const ELFLinkingContext &ctx,
- TargetLayout<ELFT> &layout,
- const char *str, int32_t order)
- : SymbolTable<ELFT>(ctx, str, order), _layout(layout) {
- this->_type = SHT_DYNSYM;
- this->_flags = SHF_ALLOC;
- this->_msize = this->_fsize;
-}
-
-template <class ELFT> void DynamicSymbolTable<ELFT>::addSymbolsToHashTable() {
- int index = 0;
- for (auto &ste : this->_symbolTable) {
- if (!ste._atom)
- _hashTable->addSymbol("", index);
- else
- _hashTable->addSymbol(ste._atom->name(), index);
- ++index;
- }
-}
-
-template <class ELFT> void DynamicSymbolTable<ELFT>::finalize() {
- // Defined symbols which have been added into the dynamic symbol table
- // don't have their addresses known until addresses have been assigned
- // so let's update the symbol values after they have got assigned
- for (auto &ste : this->_symbolTable) {
- const AtomLayout *atomLayout = ste._atomLayout;
- if (!atomLayout)
- continue;
- ste._symbol.st_value = atomLayout->_virtualAddr;
- }
-
- // Don't sort the symbols
- SymbolTable<ELFT>::finalize(false);
-}
-
-template <class ELFT>
-RelocationTable<ELFT>::RelocationTable(const ELFLinkingContext &ctx,
- StringRef str, int32_t order)
- : Section<ELFT>(ctx, str, "RelocationTable") {
- this->setOrder(order);
- this->_flags = SHF_ALLOC;
- // Set the alignment properly depending on the target architecture
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- if (ctx.isRelaOutputFormat()) {
- this->_entSize = sizeof(Elf_Rela);
- this->_type = SHT_RELA;
- } else {
- this->_entSize = sizeof(Elf_Rel);
- this->_type = SHT_REL;
- }
-}
-
-template <class ELFT>
-uint32_t RelocationTable<ELFT>::addRelocation(const DefinedAtom &da,
- const Reference &r) {
- _relocs.emplace_back(&da, &r);
- this->_fsize = _relocs.size() * this->_entSize;
- this->_msize = this->_fsize;
- return _relocs.size() - 1;
-}
-
-template <class ELFT>
-bool RelocationTable<ELFT>::getRelocationIndex(const Reference &r,
- uint32_t &res) {
- auto rel = std::find_if(
- _relocs.begin(), _relocs.end(),
- [&](const std::pair<const DefinedAtom *, const Reference *> &p) {
- if (p.second == &r)
- return true;
- return false;
- });
- if (rel == _relocs.end())
- return false;
- res = std::distance(_relocs.begin(), rel);
- return true;
-}
-
-template <class ELFT>
-bool RelocationTable<ELFT>::canModifyReadonlySection() const {
- for (const auto &rel : _relocs) {
- const DefinedAtom *atom = rel.first;
- if ((atom->permissions() & DefinedAtom::permRW_) != DefinedAtom::permRW_)
- return true;
- }
- return false;
-}
-
-template <class ELFT> void RelocationTable<ELFT>::finalize() {
- this->_link = _symbolTable ? _symbolTable->ordinal() : 0;
- if (this->_outputSection)
- this->_outputSection->setLink(this->_link);
-}
-
-template <class ELFT>
-void RelocationTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- for (const auto &rel : _relocs) {
- if (this->_ctx.isRelaOutputFormat()) {
- auto &r = *reinterpret_cast<Elf_Rela *>(dest);
- writeRela(writer, r, *rel.first, *rel.second);
- DEBUG_WITH_TYPE("ELFRelocationTable",
- llvm::dbgs()
- << rel.second->kindValue() << " relocation at "
- << rel.first->name() << "@" << r.r_offset << " to "
- << rel.second->target()->name() << "@" << r.r_addend
- << "\n";);
- } else {
- auto &r = *reinterpret_cast<Elf_Rel *>(dest);
- writeRel(writer, r, *rel.first, *rel.second);
- DEBUG_WITH_TYPE("ELFRelocationTable",
- llvm::dbgs() << rel.second->kindValue()
- << " relocation at " << rel.first->name()
- << "@" << r.r_offset << " to "
- << rel.second->target()->name() << "\n";);
- }
- dest += this->_entSize;
- }
-}
-
-template <class ELFT>
-void RelocationTable<ELFT>::writeRela(ELFWriter *writer, Elf_Rela &r,
- const DefinedAtom &atom,
- const Reference &ref) {
- r.setSymbolAndType(getSymbolIndex(ref.target()), ref.kindValue(), false);
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
- // The addend is used only by relative relocations
- if (this->_ctx.isRelativeReloc(ref))
- r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
- else
- r.r_addend = 0;
-}
-
-template <class ELFT>
-void RelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
- const DefinedAtom &atom,
- const Reference &ref) {
- r.setSymbolAndType(getSymbolIndex(ref.target()), ref.kindValue(), false);
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
-}
-
-template <class ELFT>
-uint32_t RelocationTable<ELFT>::getSymbolIndex(const Atom *a) {
- return _symbolTable ? _symbolTable->getSymbolTableIndex(a)
- : (uint32_t)STN_UNDEF;
-}
-
-template <class ELFT>
-DynamicTable<ELFT>::DynamicTable(const ELFLinkingContext &ctx,
- TargetLayout<ELFT> &layout, StringRef str,
- int32_t order)
- : Section<ELFT>(ctx, str, "DynamicSection"), _layout(layout) {
- this->setOrder(order);
- this->_entSize = sizeof(Elf_Dyn);
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- // Reserve space for the DT_NULL entry.
- this->_fsize = sizeof(Elf_Dyn);
- this->_msize = sizeof(Elf_Dyn);
- this->_type = SHT_DYNAMIC;
- this->_flags = SHF_ALLOC;
-}
-
-template <class ELFT>
-std::size_t DynamicTable<ELFT>::addEntry(int64_t tag, uint64_t val) {
- Elf_Dyn dyn;
- dyn.d_tag = tag;
- dyn.d_un.d_val = val;
- _entries.push_back(dyn);
- this->_fsize = (_entries.size() * sizeof(Elf_Dyn)) + sizeof(Elf_Dyn);
- this->_msize = this->_fsize;
- return _entries.size() - 1;
-}
-
-template <class ELFT>
-void DynamicTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- // Add the null entry.
- Elf_Dyn d;
- d.d_tag = 0;
- d.d_un.d_val = 0;
- _entries.push_back(d);
- std::memcpy(dest, _entries.data(), this->_fsize);
-}
-
-template <class ELFT> void DynamicTable<ELFT>::createDefaultEntries() {
- bool isRela = this->_ctx.isRelaOutputFormat();
- _dt_hash = addEntry(DT_HASH, 0);
- _dt_strtab = addEntry(DT_STRTAB, 0);
- _dt_symtab = addEntry(DT_SYMTAB, 0);
- _dt_strsz = addEntry(DT_STRSZ, 0);
- _dt_syment = addEntry(DT_SYMENT, 0);
- if (_layout.hasDynamicRelocationTable()) {
- _dt_rela = addEntry(isRela ? DT_RELA : DT_REL, 0);
- _dt_relasz = addEntry(isRela ? DT_RELASZ : DT_RELSZ, 0);
- _dt_relaent = addEntry(isRela ? DT_RELAENT : DT_RELENT, 0);
- if (_layout.getDynamicRelocationTable()->canModifyReadonlySection())
- _dt_textrel = addEntry(DT_TEXTREL, 0);
- }
- if (_layout.hasPLTRelocationTable()) {
- _dt_pltrelsz = addEntry(DT_PLTRELSZ, 0);
- _dt_pltgot = addEntry(getGotPltTag(), 0);
- _dt_pltrel = addEntry(DT_PLTREL, isRela ? DT_RELA : DT_REL);
- _dt_jmprel = addEntry(DT_JMPREL, 0);
- }
-}
-
-template <class ELFT> void DynamicTable<ELFT>::doPreFlight() {
- auto initArray = _layout.findOutputSection(".init_array");
- auto finiArray = _layout.findOutputSection(".fini_array");
- if (initArray) {
- _dt_init_array = addEntry(DT_INIT_ARRAY, 0);
- _dt_init_arraysz = addEntry(DT_INIT_ARRAYSZ, 0);
- }
- if (finiArray) {
- _dt_fini_array = addEntry(DT_FINI_ARRAY, 0);
- _dt_fini_arraysz = addEntry(DT_FINI_ARRAYSZ, 0);
- }
- if (getInitAtomLayout())
- _dt_init = addEntry(DT_INIT, 0);
- if (getFiniAtomLayout())
- _dt_fini = addEntry(DT_FINI, 0);
-}
-
-template <class ELFT> void DynamicTable<ELFT>::finalize() {
- StringTable<ELFT> *dynamicStringTable = _dynamicSymbolTable->getStringTable();
- this->_link = dynamicStringTable->ordinal();
- if (this->_outputSection) {
- this->_outputSection->setType(this->_type);
- this->_outputSection->setInfo(this->_info);
- this->_outputSection->setLink(this->_link);
- }
-}
-
-template <class ELFT> void DynamicTable<ELFT>::updateDynamicTable() {
- StringTable<ELFT> *dynamicStringTable = _dynamicSymbolTable->getStringTable();
- _entries[_dt_hash].d_un.d_val = _hashTable->virtualAddr();
- _entries[_dt_strtab].d_un.d_val = dynamicStringTable->virtualAddr();
- _entries[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr();
- _entries[_dt_strsz].d_un.d_val = dynamicStringTable->memSize();
- _entries[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize();
- auto initArray = _layout.findOutputSection(".init_array");
- if (initArray) {
- _entries[_dt_init_array].d_un.d_val = initArray->virtualAddr();
- _entries[_dt_init_arraysz].d_un.d_val = initArray->memSize();
- }
- auto finiArray = _layout.findOutputSection(".fini_array");
- if (finiArray) {
- _entries[_dt_fini_array].d_un.d_val = finiArray->virtualAddr();
- _entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize();
- }
- if (const auto *al = getInitAtomLayout())
- _entries[_dt_init].d_un.d_val = getAtomVirtualAddress(al);
- if (const auto *al = getFiniAtomLayout())
- _entries[_dt_fini].d_un.d_val = getAtomVirtualAddress(al);
- if (_layout.hasDynamicRelocationTable()) {
- auto relaTbl = _layout.getDynamicRelocationTable();
- _entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr();
- _entries[_dt_relasz].d_un.d_val = relaTbl->memSize();
- _entries[_dt_relaent].d_un.d_val = relaTbl->getEntSize();
- }
- if (_layout.hasPLTRelocationTable()) {
- auto relaTbl = _layout.getPLTRelocationTable();
- _entries[_dt_jmprel].d_un.d_val = relaTbl->virtualAddr();
- _entries[_dt_pltrelsz].d_un.d_val = relaTbl->memSize();
- auto gotplt = _layout.findOutputSection(".got.plt");
- _entries[_dt_pltgot].d_un.d_val = gotplt->virtualAddr();
- }
-}
-
-template <class ELFT>
-const AtomLayout *DynamicTable<ELFT>::getInitAtomLayout() {
- auto al = _layout.findAtomLayoutByName(this->_ctx.initFunction());
- if (al && isa<DefinedAtom>(al->_atom))
- return al;
- return nullptr;
-}
-
-template <class ELFT>
-const AtomLayout *DynamicTable<ELFT>::getFiniAtomLayout() {
- auto al = _layout.findAtomLayoutByName(this->_ctx.finiFunction());
- if (al && isa<DefinedAtom>(al->_atom))
- return al;
- return nullptr;
-}
-
-template <class ELFT>
-InterpSection<ELFT>::InterpSection(const ELFLinkingContext &ctx, StringRef str,
- int32_t order, StringRef interp)
- : Section<ELFT>(ctx, str, "Dynamic:Interp"), _interp(interp) {
- this->setOrder(order);
- this->_alignment = 1;
- // + 1 for null term.
- this->_fsize = interp.size() + 1;
- this->_msize = this->_fsize;
- this->_type = SHT_PROGBITS;
- this->_flags = SHF_ALLOC;
-}
-
-template <class ELFT>
-void InterpSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- std::memcpy(dest, _interp.data(), _interp.size());
-}
-
-template <class ELFT>
-HashSection<ELFT>::HashSection(const ELFLinkingContext &ctx, StringRef name,
- int32_t order)
- : Section<ELFT>(ctx, name, "Dynamic:Hash") {
- this->setOrder(order);
- this->_entSize = 4;
- this->_type = SHT_HASH;
- this->_flags = SHF_ALLOC;
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- this->_fsize = 0;
- this->_msize = 0;
-}
-
-template <class ELFT>
-void HashSection<ELFT>::addSymbol(StringRef name, uint32_t index) {
- SymbolTableEntry ste;
- ste._name = name;
- ste._index = index;
- _entries.push_back(ste);
-}
-
-/// \brief Set the dynamic symbol table
-template <class ELFT>
-void HashSection<ELFT>::setSymbolTable(
- const DynamicSymbolTable<ELFT> *symbolTable) {
- _symbolTable = symbolTable;
-}
-
-template <class ELFT> void HashSection<ELFT>::doPreFlight() {
- // The number of buckets to use for a certain number of symbols.
- // If there are less than 3 symbols, 1 bucket will be used. If
- // there are less than 17 symbols, 3 buckets will be used, and so
- // forth. The bucket numbers are defined by GNU ld. We use the
- // same rules here so we generate hash sections with the same
- // size as those generated by GNU ld.
- uint32_t hashBuckets[] = {1, 3, 17, 37, 67, 97, 131,
- 197, 263, 521, 1031, 2053, 4099, 8209,
- 16411, 32771, 65537, 131101, 262147};
- int hashBucketsCount = sizeof(hashBuckets) / sizeof(uint32_t);
-
- unsigned int bucketsCount = 0;
- unsigned int dynSymCount = _entries.size();
-
- // Get the number of buckes that we want to use
- for (int i = 0; i < hashBucketsCount; ++i) {
- if (dynSymCount < hashBuckets[i])
- break;
- bucketsCount = hashBuckets[i];
- }
- _buckets.resize(bucketsCount);
- _chains.resize(_entries.size());
-
- // Create the hash table for the dynamic linker
- for (auto ai : _entries) {
- unsigned int dynsymIndex = ai._index;
- unsigned int bucketpos = llvm::object::elf_hash(ai._name) % bucketsCount;
- _chains[dynsymIndex] = _buckets[bucketpos];
- _buckets[bucketpos] = dynsymIndex;
- }
-
- this->_fsize = (2 + _chains.size() + _buckets.size()) * sizeof(uint32_t);
- this->_msize = this->_fsize;
-}
-
-template <class ELFT> void HashSection<ELFT>::finalize() {
- this->_link = _symbolTable ? _symbolTable->ordinal() : 0;
- if (this->_outputSection)
- this->_outputSection->setLink(this->_link);
-}
-
-template <class ELFT>
-void HashSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- Elf_Word bucketChainCounts[2];
- bucketChainCounts[0] = _buckets.size();
- bucketChainCounts[1] = _chains.size();
- std::memcpy(dest, bucketChainCounts, sizeof(bucketChainCounts));
- dest += sizeof(bucketChainCounts);
- // write bucket values
- std::memcpy(dest, _buckets.data(), _buckets.size() * sizeof(Elf_Word));
- dest += _buckets.size() * sizeof(Elf_Word);
- // write chain values
- std::memcpy(dest, _chains.data(), _chains.size() * sizeof(Elf_Word));
-}
-
-template <class ELFT>
-EHFrameHeader<ELFT>::EHFrameHeader(const ELFLinkingContext &ctx, StringRef name,
- TargetLayout<ELFT> &layout, int32_t order)
- : Section<ELFT>(ctx, name, "EHFrameHeader"), _layout(layout) {
- this->setOrder(order);
- this->_entSize = 0;
- this->_type = SHT_PROGBITS;
- this->_flags = SHF_ALLOC;
- this->_alignment = ELFT::Is64Bits ? 8 : 4;
- // Minimum size for empty .eh_frame_hdr.
- this->_fsize = 1 + 1 + 1 + 1 + 4;
- this->_msize = this->_fsize;
-}
-
-template <class ELFT> void EHFrameHeader<ELFT>::doPreFlight() {
- // TODO: Generate a proper binary search table.
-}
-
-template <class ELFT> void EHFrameHeader<ELFT>::finalize() {
- OutputSection<ELFT> *s = _layout.findOutputSection(".eh_frame");
- OutputSection<ELFT> *h = _layout.findOutputSection(".eh_frame_hdr");
- if (s && h)
- _ehFrameOffset = s->virtualAddr() - (h->virtualAddr() + 4);
-}
-
-template <class ELFT>
-void EHFrameHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- uint8_t *chunkBuffer = buffer.getBufferStart();
- uint8_t *dest = chunkBuffer + this->fileOffset();
- int pos = 0;
- dest[pos++] = 1; // version
- dest[pos++] = llvm::dwarf::DW_EH_PE_pcrel |
- llvm::dwarf::DW_EH_PE_sdata4; // eh_frame_ptr_enc
- dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // fde_count_enc
- dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // table_enc
- *reinterpret_cast<typename llvm::object::ELFFile<ELFT>::Elf_Sword *>(
- dest + pos) = _ehFrameOffset;
-}
-
-#define INSTANTIATE(klass) \
- template class klass<ELF32LE>; \
- template class klass<ELF32BE>; \
- template class klass<ELF64LE>; \
- template class klass<ELF64BE>
-
-INSTANTIATE(AtomSection);
-INSTANTIATE(DynamicSymbolTable);
-INSTANTIATE(DynamicTable);
-INSTANTIATE(EHFrameHeader);
-INSTANTIATE(HashSection);
-INSTANTIATE(InterpSection);
-INSTANTIATE(OutputSection);
-INSTANTIATE(RelocationTable);
-INSTANTIATE(Section);
-INSTANTIATE(StringTable);
-INSTANTIATE(SymbolTable);
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (removed)
@@ -1,616 +0,0 @@
-//===- lib/ReaderWriter/ELF/SectionChunks.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_SECTION_CHUNKS_H
-
-#include "Chunk.h"
-#include "TargetHandler.h"
-#include "Writer.h"
-#include "lld/Core/DefinedAtom.h"
-#include "lld/Core/range.h"
-#include "lld/ReaderWriter/AtomLayout.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include <memory>
-#include <mutex>
-
-namespace lld {
-namespace elf {
-template <class> class OutputSection;
-using namespace llvm::ELF;
-template <class ELFT> class Segment;
-template <class ELFT> class TargetLayout;
-
-/// \brief An ELF section.
-template <class ELFT> class Section : public Chunk<ELFT> {
-public:
- Section(const ELFLinkingContext &ctx, StringRef sectionName,
- StringRef chunkName,
- typename Chunk<ELFT>::Kind k = Chunk<ELFT>::Kind::ELFSection);
-
- /// \brief Modify the section contents before assigning virtual addresses
- // or assigning file offsets
-
- /// \brief Finalize the section contents before writing
-
- /// \brief Does this section have an output segment.
- virtual bool hasOutputSegment() const { return false; }
-
- /// Return if the section is a loadable section that occupies memory
- virtual bool isLoadableSection() const { return false; }
-
- /// \brief Assign file offsets starting at offset.
- virtual void assignFileOffsets(uint64_t offset) {}
-
- /// \brief Assign virtual addresses starting at addr.
- virtual void assignVirtualAddress(uint64_t addr) {}
-
- uint64_t getFlags() const { return _flags; }
- uint64_t getEntSize() const { return _entSize; }
- uint32_t getType() const { return _type; }
- uint32_t getLink() const { return _link; }
- uint32_t getInfo() const { return _info; }
-
- typename TargetLayout<ELFT>::SegmentType getSegmentType() const {
- return _segmentType;
- }
-
- /// \brief Return the type of content that the section contains
- int getContentType() const override;
-
- /// \brief convert the segment type to a String for diagnostics and printing
- /// purposes
- virtual StringRef segmentKindToStr() const;
-
- /// \brief Records the segmentType, that this section belongs to
- void
- setSegmentType(const typename TargetLayout<ELFT>::SegmentType segmentType) {
- this->_segmentType = segmentType;
- }
-
- virtual const AtomLayout *findAtomLayoutByName(StringRef) const {
- return nullptr;
- }
-
- const OutputSection<ELFT> *getOutputSection() const {
- return _outputSection;
- }
-
- void setOutputSection(OutputSection<ELFT> *os, bool isFirst = false) {
- _outputSection = os;
- _isFirstSectionInOutputSection = isFirst;
- }
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::ELFSection ||
- c->kind() == Chunk<ELFT>::Kind::AtomSection;
- }
-
- uint64_t alignment() const override {
- return _isFirstSectionInOutputSection ? _outputSection->alignment()
- : this->_alignment;
- }
-
- virtual StringRef inputSectionName() const { return _inputSectionName; }
-
- virtual StringRef outputSectionName() const { return _outputSectionName; }
-
- virtual void setOutputSectionName(StringRef outputSectionName) {
- _outputSectionName = outputSectionName;
- }
-
- void setArchiveNameOrPath(StringRef name) { _archivePath = name; }
-
- void setMemberNameOrPath(StringRef name) { _memberPath = name; }
-
- StringRef archivePath() { return _archivePath; }
-
- StringRef memberPath() { return _memberPath; }
-
-protected:
- /// \brief OutputSection this Section is a member of, or nullptr.
- OutputSection<ELFT> *_outputSection = nullptr;
- /// \brief ELF SHF_* flags.
- uint64_t _flags = 0;
- /// \brief The size of each entity.
- uint64_t _entSize = 0;
- /// \brief ELF SHT_* type.
- uint32_t _type = 0;
- /// \brief sh_link field.
- uint32_t _link = 0;
- /// \brief the sh_info field.
- uint32_t _info = 0;
- /// \brief Is this the first section in the output section.
- bool _isFirstSectionInOutputSection = false;
- /// \brief the output ELF segment type of this section.
- typename TargetLayout<ELFT>::SegmentType _segmentType = SHT_NULL;
- /// \brief Input section name.
- StringRef _inputSectionName;
- /// \brief Output section name.
- StringRef _outputSectionName;
- StringRef _archivePath;
- StringRef _memberPath;
-};
-
-/// \brief A section containing atoms.
-template <class ELFT> class AtomSection : public Section<ELFT> {
-public:
- AtomSection(const ELFLinkingContext &ctx, StringRef sectionName,
- int32_t contentType, int32_t permissions, int32_t order);
-
- /// Align the offset to the required modulus defined by the atom alignment
- uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign);
-
- /// Return if the section is a loadable section that occupies memory
- bool isLoadableSection() const override { return _isLoadedInMemory; }
-
- // \brief Append an atom to a Section. The atom gets pushed into a vector
- // contains the atom, the atom file offset, the atom virtual address
- // the atom file offset is aligned appropriately as set by the Reader
- virtual const AtomLayout *appendAtom(const Atom *atom);
-
- /// \brief Set the virtual address of each Atom in the Section. This
- /// routine gets called after the linker fixes up the virtual address
- /// of the section
- void assignVirtualAddress(uint64_t addr) override;
-
- /// \brief Set the file offset of each Atom in the section. This routine
- /// gets called after the linker fixes up the section offset
- void assignFileOffsets(uint64_t offset) override;
-
- /// \brief Find the Atom address given a name, this is needed to properly
- /// apply relocation. The section class calls this to find the atom address
- /// to fix the relocation
- const AtomLayout *findAtomLayoutByName(StringRef name) const override;
-
- /// \brief Return the raw flags, we need this to sort segments
- int64_t atomflags() const { return _contentPermissions; }
-
- /// Atom Iterators
- typedef typename std::vector<AtomLayout *>::iterator atom_iter;
-
- range<atom_iter> atoms() { return _atoms; }
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::AtomSection;
- }
-
-protected:
- llvm::BumpPtrAllocator _alloc;
- int32_t _contentType;
- int32_t _contentPermissions;
- bool _isLoadedInMemory = true;
- std::vector<AtomLayout *> _atoms;
- mutable std::mutex _outputMutex;
-
- std::string formatError(const std::string &errorStr, const AtomLayout &atom,
- const Reference &ref) const;
-};
-
-/// \brief A OutputSection represents a set of sections grouped by the same
-/// name. The output file that gets written by the linker has sections grouped
-/// by similar names
-template <class ELFT> class OutputSection {
-public:
- // Iterators
- typedef typename std::vector<Section<ELFT> *>::iterator SectionIter;
-
- OutputSection(StringRef name) : _name(name) {}
-
- // Appends a section into the list of sections that are part of this Output
- // Section
- void appendSection(Section<ELFT> *c);
-
- // Set the OutputSection is associated with a segment
- void setHasSegment() { _hasSegment = true; }
-
- /// Sets the ordinal
- void setOrdinal(uint64_t ordinal) { _ordinal = ordinal; }
-
- /// Sets the Memory size
- void setMemSize(uint64_t memsz) { _memSize = memsz; }
-
- /// Sets the size fo the output Section.
- void setSize(uint64_t fsiz) { _size = fsiz; }
-
- // The offset of the first section contained in the output section is
- // contained here.
- void setFileOffset(uint64_t foffset) { _fileOffset = foffset; }
-
- // Sets the starting address of the section
- void setAddr(uint64_t addr) { _virtualAddr = addr; }
-
- // Is the section loadable?
- bool isLoadableSection() const { return _isLoadableSection; }
-
- // Set section Loadable
- void setLoadableSection(bool isLoadable) {
- _isLoadableSection = isLoadable;
- }
-
- void setLink(uint64_t link) { _link = link; }
- void setInfo(uint64_t info) { _shInfo = info; }
- void setFlag(uint64_t flags) { _flags = flags; }
- void setType(int64_t type) { _type = type; }
- range<SectionIter> sections() { return _sections; }
-
- // The below functions returns the properties of the OutputSection.
- bool hasSegment() const { return _hasSegment; }
- StringRef name() const { return _name; }
- int64_t shinfo() const { return _shInfo; }
- uint64_t alignment() const { return _alignment; }
- int64_t link() const { return _link; }
- int64_t type() const { return _type; }
- uint64_t virtualAddr() const { return _virtualAddr; }
- int64_t ordinal() const { return _ordinal; }
- int64_t kind() const { return _kind; }
- uint64_t fileSize() const { return _size; }
- int64_t entsize() const { return _entSize; }
- uint64_t fileOffset() const { return _fileOffset; }
- uint64_t flags() const { return _flags; }
- uint64_t memSize() const { return _memSize; }
-
-private:
- StringRef _name;
- bool _hasSegment = false;
- uint64_t _ordinal = 0;
- uint64_t _flags = 0;
- uint64_t _size = 0;
- uint64_t _memSize = 0;
- uint64_t _fileOffset = 0;
- uint64_t _virtualAddr = 0;
- int64_t _shInfo = 0;
- int64_t _entSize = 0;
- int64_t _link = 0;
- uint64_t _alignment = 1;
- int64_t _kind = 0;
- int64_t _type = 0;
- bool _isLoadableSection = false;
- std::vector<Section<ELFT> *> _sections;
-};
-
-/// \brief The class represents the ELF String Table
-template <class ELFT> class StringTable : public Section<ELFT> {
-public:
- StringTable(const ELFLinkingContext &, const char *str, int32_t order,
- bool dynamic = false);
-
- uint64_t addString(StringRef symname);
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- void setNumEntries(int64_t numEntries) { _stringMap.resize(numEntries); }
-
-private:
- std::vector<StringRef> _strings;
-
- struct StringRefMappingInfo {
- static StringRef getEmptyKey() { return StringRef(); }
- static StringRef getTombstoneKey() { return StringRef(" ", 1); }
- static unsigned getHashValue(StringRef const val) {
- return llvm::HashString(val);
- }
- static bool isEqual(StringRef const lhs, StringRef const rhs) {
- return lhs.equals(rhs);
- }
- };
- typedef typename llvm::DenseMap<StringRef, uint64_t, StringRefMappingInfo>
- StringMapT;
- typedef typename StringMapT::iterator StringMapTIter;
- StringMapT _stringMap;
-};
-
-/// \brief The SymbolTable class represents the symbol table in a ELF file
-template <class ELFT> class SymbolTable : public Section<ELFT> {
- typedef
- typename llvm::object::ELFDataTypeTypedefHelper<ELFT>::Elf_Addr Elf_Addr;
-
-public:
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
- SymbolTable(const ELFLinkingContext &ctx, const char *str, int32_t order);
-
- /// \brief set the number of entries that would exist in the symbol
- /// table for the current link
- void setNumEntries(int64_t numEntries) const {
- if (_stringSection)
- _stringSection->setNumEntries(numEntries);
- }
-
- /// \brief return number of entries
- std::size_t size() const { return _symbolTable.size(); }
-
- void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0,
- const AtomLayout *layout = nullptr);
-
- /// \brief Get the symbol table index for an Atom. If it's not in the symbol
- /// table, return STN_UNDEF.
- uint32_t getSymbolTableIndex(const Atom *a) const {
- for (size_t i = 0, e = _symbolTable.size(); i < e; ++i)
- if (_symbolTable[i]._atom == a)
- return i;
- return STN_UNDEF;
- }
-
- void finalize() override { finalize(true); }
-
- virtual void sortSymbols() {
- std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
- [](const SymbolEntry &A, const SymbolEntry &B) {
- return A._symbol.getBinding() < B._symbol.getBinding();
- });
- }
-
- virtual void addAbsoluteAtom(Elf_Sym &sym, const AbsoluteAtom *aa,
- int64_t addr);
-
- virtual void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr);
-
- virtual void addUndefinedAtom(Elf_Sym &sym, const UndefinedAtom *ua);
-
- virtual void addSharedLibAtom(Elf_Sym &sym, const SharedLibraryAtom *sla);
-
- virtual void finalize(bool sort);
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
-
- StringTable<ELFT> *getStringTable() const { return _stringSection; }
-
-protected:
- struct SymbolEntry {
- SymbolEntry(const Atom *a, const Elf_Sym &sym, const AtomLayout *layout)
- : _atom(a), _atomLayout(layout), _symbol(sym) {}
-
- const Atom *_atom;
- const AtomLayout *_atomLayout;
- Elf_Sym _symbol;
- };
-
- llvm::BumpPtrAllocator _symbolAllocate;
- StringTable<ELFT> *_stringSection;
- std::vector<SymbolEntry> _symbolTable;
-};
-
-template <class ELFT> class HashSection;
-
-template <class ELFT> class DynamicSymbolTable : public SymbolTable<ELFT> {
-public:
- DynamicSymbolTable(const ELFLinkingContext &ctx, TargetLayout<ELFT> &layout,
- const char *str, int32_t order);
-
- // Set the dynamic hash table for symbols to be added into
- void setHashTable(HashSection<ELFT> *hashTable) { _hashTable = hashTable; }
-
- // Add all the dynamic symbos to the hash table
- void addSymbolsToHashTable();
-
- void finalize() override;
-
-protected:
- HashSection<ELFT> *_hashTable = nullptr;
- TargetLayout<ELFT> &_layout;
-};
-
-template <class ELFT> class RelocationTable : public Section<ELFT> {
-public:
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
-
- RelocationTable(const ELFLinkingContext &ctx, StringRef str, int32_t order);
-
- /// \returns the index of the relocation added.
- uint32_t addRelocation(const DefinedAtom &da, const Reference &r);
-
- bool getRelocationIndex(const Reference &r, uint32_t &res);
-
- void setSymbolTable(const DynamicSymbolTable<ELFT> *symbolTable) {
- _symbolTable = symbolTable;
- }
-
- /// \brief Check if any relocation modifies a read-only section.
- bool canModifyReadonlySection() const;
-
- void finalize() override;
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
-protected:
- const DynamicSymbolTable<ELFT> *_symbolTable = nullptr;
-
- virtual void writeRela(ELFWriter *writer, Elf_Rela &r,
- const DefinedAtom &atom, const Reference &ref);
- virtual void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
- const Reference &ref);
- uint32_t getSymbolIndex(const Atom *a);
-
-private:
- std::vector<std::pair<const DefinedAtom *, const Reference *>> _relocs;
-};
-
-template <class ELFT> class HashSection;
-
-template <class ELFT> class DynamicTable : public Section<ELFT> {
-public:
- typedef llvm::object::Elf_Dyn_Impl<ELFT> Elf_Dyn;
- typedef std::vector<Elf_Dyn> EntriesT;
-
- DynamicTable(const ELFLinkingContext &ctx, TargetLayout<ELFT> &layout,
- StringRef str, int32_t order);
-
- range<typename EntriesT::iterator> entries() { return _entries; }
-
- /// \returns the index of the entry.
- std::size_t addEntry(int64_t tag, uint64_t val);
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- virtual void createDefaultEntries();
- void doPreFlight() override;
-
- /// \brief Dynamic table tag for .got.plt section referencing.
- /// Usually but not always targets use DT_PLTGOT for that.
- virtual int64_t getGotPltTag() { return DT_PLTGOT; }
-
- void finalize() override;
-
- void setSymbolTable(DynamicSymbolTable<ELFT> *dynsym) {
- _dynamicSymbolTable = dynsym;
- }
-
- const DynamicSymbolTable<ELFT> *getSymbolTable() const {
- return _dynamicSymbolTable;
- }
-
- void setHashTable(HashSection<ELFT> *hsh) { _hashTable = hsh; }
-
- virtual void updateDynamicTable();
-
-protected:
- EntriesT _entries;
-
- /// \brief Return a virtual address (maybe adjusted) for the atom layout
- /// Some targets like microMIPS and ARM Thumb use the last bit
- /// of a symbol's value to mark 'compressed' code. This function allows
- /// to adjust a virtal address before using it in the dynamic table tag.
- virtual uint64_t getAtomVirtualAddress(const AtomLayout *al) const {
- return al->_virtualAddr;
- }
-
-private:
- std::size_t _dt_hash;
- std::size_t _dt_strtab;
- std::size_t _dt_symtab;
- std::size_t _dt_rela;
- std::size_t _dt_relasz;
- std::size_t _dt_relaent;
- std::size_t _dt_strsz;
- std::size_t _dt_syment;
- std::size_t _dt_pltrelsz;
- std::size_t _dt_pltgot;
- std::size_t _dt_pltrel;
- std::size_t _dt_jmprel;
- std::size_t _dt_init_array;
- std::size_t _dt_init_arraysz;
- std::size_t _dt_fini_array;
- std::size_t _dt_fini_arraysz;
- std::size_t _dt_textrel;
- std::size_t _dt_init;
- std::size_t _dt_fini;
- TargetLayout<ELFT> &_layout;
- DynamicSymbolTable<ELFT> *_dynamicSymbolTable;
- HashSection<ELFT> *_hashTable;
-
- const AtomLayout *getInitAtomLayout();
-
- const AtomLayout *getFiniAtomLayout();
-};
-
-template <class ELFT> class InterpSection : public Section<ELFT> {
-public:
- InterpSection(const ELFLinkingContext &ctx, StringRef str, int32_t order,
- StringRef interp);
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
-private:
- StringRef _interp;
-};
-
-/// The hash table in the dynamic linker is organized into
-///
-/// [ nbuckets ]
-/// [ nchains ]
-/// [ buckets[0] ]
-/// .........................
-/// [ buckets[nbuckets-1] ]
-/// [ chains[0] ]
-/// .........................
-/// [ chains[nchains - 1] ]
-///
-/// nbuckets - total number of hash buckets
-/// nchains is equal to the number of dynamic symbols.
-///
-/// The symbol is searched by the dynamic linker using the below approach.
-/// * Calculate the hash of the symbol that needs to be searched
-/// * Take the value from the buckets[hash % nbuckets] as the index of symbol
-/// * Compare the symbol's name, if true return, if false, look through the
-/// * array since there was a collision
-template <class ELFT> class HashSection : public Section<ELFT> {
- struct SymbolTableEntry {
- StringRef _name;
- uint32_t _index;
- };
-
-public:
- HashSection(const ELFLinkingContext &ctx, StringRef name, int32_t order);
-
- /// \brief add the dynamic symbol into the table so that the
- /// hash could be calculated
- void addSymbol(StringRef name, uint32_t index);
-
- /// \brief Set the dynamic symbol table
- void setSymbolTable(const DynamicSymbolTable<ELFT> *symbolTable);
-
- // The size of the section has to be determined so that fileoffsets
- // may be properly assigned. Let's calculate the buckets and the chains
- // and fill the chains and the buckets hash table used by the dynamic
- // linker and update the filesize and memory size accordingly
- void doPreFlight() override;
-
- void finalize() override;
-
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
-private:
- typedef
- typename llvm::object::ELFDataTypeTypedefHelper<ELFT>::Elf_Word Elf_Word;
-
- std::vector<SymbolTableEntry> _entries;
- std::vector<Elf_Word> _buckets;
- std::vector<Elf_Word> _chains;
- const DynamicSymbolTable<ELFT> *_symbolTable = nullptr;
-};
-
-template <class ELFT> class EHFrameHeader : public Section<ELFT> {
-public:
- EHFrameHeader(const ELFLinkingContext &ctx, StringRef name,
- TargetLayout<ELFT> &layout, int32_t order);
- void doPreFlight() override;
- void finalize() override;
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
-private:
- int32_t _ehFrameOffset = 0;
- TargetLayout<ELFT> &_layout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_SECTION_CHUNKS_H
Removed: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp (removed)
@@ -1,516 +0,0 @@
-//===- lib/ReaderWriter/ELF/SegmentChunks.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SegmentChunks.h"
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-bool SegmentSlice<ELFT>::compare_slices(SegmentSlice<ELFT> *a,
- SegmentSlice<ELFT> *b) {
- return a->startSection() < b->startSection();
-}
-
-template <class ELFT>
-Segment<ELFT>::Segment(const ELFLinkingContext &ctx, StringRef name,
- const typename TargetLayout<ELFT>::SegmentType type)
- : Chunk<ELFT>(name, Chunk<ELFT>::Kind::ELFSegment, ctx), _segmentType(type),
- _flags(0), _atomflags(0), _segmentFlags(false) {
- this->_alignment = 1;
- this->_fsize = 0;
- _outputMagic = ctx.getOutputMagic();
-}
-
-// This function actually is used, but not in all instantiations of Segment.
-LLVM_ATTRIBUTE_UNUSED
-static DefinedAtom::ContentPermissions toAtomPerms(uint64_t flags) {
- switch (flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)) {
- case SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR:
- return DefinedAtom::permRWX;
- case SHF_ALLOC | SHF_EXECINSTR:
- return DefinedAtom::permR_X;
- case SHF_ALLOC:
- return DefinedAtom::permR__;
- case SHF_ALLOC | SHF_WRITE:
- return DefinedAtom::permRW_;
- default:
- return DefinedAtom::permUnknown;
- }
-}
-
-// This function actually is used, but not in all instantiations of Segment.
-LLVM_ATTRIBUTE_UNUSED
-static DefinedAtom::ContentPermissions toAtomPermsSegment(uint64_t flags) {
- switch (flags & (llvm::ELF::PF_R | llvm::ELF::PF_W | llvm::ELF::PF_X)) {
- case llvm::ELF::PF_R | llvm::ELF::PF_W | llvm::ELF::PF_X:
- return DefinedAtom::permRWX;
- case llvm::ELF::PF_R | llvm::ELF::PF_X:
- return DefinedAtom::permR_X;
- case llvm::ELF::PF_R:
- return DefinedAtom::permR__;
- case llvm::ELF::PF_R | llvm::ELF::PF_W:
- return DefinedAtom::permRW_;
- default:
- return DefinedAtom::permUnknown;
- }
-}
-
-template <class ELFT> void Segment<ELFT>::append(Chunk<ELFT> *chunk) {
- _sections.push_back(chunk);
- Section<ELFT> *section = dyn_cast<Section<ELFT>>(chunk);
- if (!section)
- return;
- if (this->_alignment < section->alignment())
- this->_alignment = section->alignment();
-
- if (_segmentFlags)
- return;
- if (_flags < section->getFlags())
- _flags |= section->getFlags();
- if (_atomflags < toAtomPerms(_flags))
- _atomflags = toAtomPerms(_flags);
-}
-
-template <class ELFT>
-bool Segment<ELFT>::compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb) {
- int64_t type1 = sega->segmentType();
- int64_t type2 = segb->segmentType();
-
- if (type1 == type2)
- return sega->atomflags() < segb->atomflags();
-
- // The single PT_PHDR segment is required to precede any loadable
- // segment. We simply make it always first.
- if (type1 == llvm::ELF::PT_PHDR)
- return true;
- if (type2 == llvm::ELF::PT_PHDR)
- return false;
-
- // The single PT_INTERP segment is required to precede any loadable
- // segment. We simply make it always second.
- if (type1 == llvm::ELF::PT_INTERP)
- return true;
- if (type2 == llvm::ELF::PT_INTERP)
- return false;
-
- // We then put PT_LOAD segments before any other segments.
- if (type1 == llvm::ELF::PT_LOAD)
- return true;
- if (type2 == llvm::ELF::PT_LOAD)
- return false;
-
- // We put the PT_GNU_RELRO segment last, because that is where the
- // dynamic linker expects to find it
- if (type1 == llvm::ELF::PT_GNU_RELRO)
- return false;
- if (type2 == llvm::ELF::PT_GNU_RELRO)
- return true;
-
- // We put the PT_TLS segment last except for the PT_GNU_RELRO
- // segment, because that is where the dynamic linker expects to find
- if (type1 == llvm::ELF::PT_TLS)
- return false;
- if (type2 == llvm::ELF::PT_TLS)
- return true;
-
- // Otherwise compare the types to establish an arbitrary ordering.
- // FIXME: Should figure out if we should just make all other types compare
- // equal, but if so, we should probably do the same for atom flags and change
- // users of this to use stable_sort.
- return type1 < type2;
-}
-
-template <class ELFT>
-void Segment<ELFT>::assignFileOffsets(uint64_t startOffset) {
- uint64_t fileOffset = startOffset;
- uint64_t curSliceFileOffset = fileOffset;
- bool isDataPageAlignedForNMagic = false;
- bool alignSegments = this->_ctx.alignSegments();
- uint64_t p_align = this->_ctx.getPageSize();
- uint64_t lastVirtualAddress = 0;
-
- this->setFileOffset(startOffset);
- bool changeOffset = false;
- uint64_t newOffset = 0;
- for (auto &slice : slices()) {
- bool isFirstSection = true;
- for (auto section : slice->sections()) {
- // Handle linker script expressions, which may change the offset
- if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(section)) {
- if (!isFirstSection) {
- changeOffset = true;
- newOffset = fileOffset + expr->virtualAddr() - lastVirtualAddress;
- }
- continue;
- }
- if (changeOffset) {
- changeOffset = false;
- fileOffset = newOffset;
- }
- // Align fileoffset to the alignment of the section.
- fileOffset = llvm::alignTo(fileOffset, section->alignment());
- // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
- // to a page boundary
- if (isFirstSection &&
- _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
- _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
- // Align to a page only if the output is not
- // OutputMagic::NMAGIC/OutputMagic::OMAGIC
- if (alignSegments)
- fileOffset = llvm::alignTo(fileOffset, p_align);
- // Align according to ELF spec.
- // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
- uint64_t virtualAddress = slice->virtualAddr();
- Section<ELFT> *sect = dyn_cast<Section<ELFT>>(section);
- if (sect && sect->isLoadableSection() &&
- ((virtualAddress & (p_align - 1)) != (fileOffset & (p_align - 1))))
- fileOffset =
- llvm::alignTo(fileOffset, p_align) + (virtualAddress % p_align);
- } else if (!isDataPageAlignedForNMagic && needAlign(section)) {
- fileOffset = llvm::alignTo(fileOffset, this->_ctx.getPageSize());
- isDataPageAlignedForNMagic = true;
- }
- if (isFirstSection) {
- slice->setFileOffset(fileOffset);
- isFirstSection = false;
- curSliceFileOffset = fileOffset;
- }
- section->setFileOffset(fileOffset);
- fileOffset += section->fileSize();
- lastVirtualAddress = section->virtualAddr() + section->memSize();
- }
- changeOffset = false;
- slice->setFileSize(fileOffset - curSliceFileOffset);
- }
- this->setFileSize(fileOffset - startOffset);
-}
-
-/// \brief Assign virtual addresses to the slices
-template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t addr) {
- int startSection = 0;
- int currSection = 0;
- SectionIter startSectionIter;
-
- // slice align is set to the max alignment of the chunks that are
- // contained in the slice
- uint64_t sliceAlign = 0;
- // Current slice size
- uint64_t curSliceSize = 0;
- // Current Slice File Offset
- uint64_t curSliceAddress = 0;
-
- startSectionIter = _sections.begin();
- startSection = 0;
- bool isDataPageAlignedForNMagic = false;
- uint64_t startAddr = addr;
- SegmentSlice<ELFT> *slice = nullptr;
- uint64_t tlsStartAddr = 0;
- bool alignSegments = this->_ctx.alignSegments();
- StringRef prevOutputSectionName = StringRef();
- uint64_t tbssMemsize = 0;
-
- // If this is first section in the segment, page align the section start
- // address. The linker needs to align the data section to a page boundary
- // only if NMAGIC is set.
- auto si = _sections.begin();
- if (si != _sections.end()) {
- if (alignSegments &&
- _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
- _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
- // Align to a page only if the output is not
- // OutputMagic::NMAGIC/OutputMagic::OMAGIC
- startAddr = llvm::alignTo(startAddr, this->_ctx.getPageSize());
- } else if (needAlign(*si)) {
- // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
- // Data to a page boundary.
- startAddr = llvm::alignTo(startAddr, this->_ctx.getPageSize());
- isDataPageAlignedForNMagic = true;
- }
- // align the startOffset to the section alignment
- uint64_t newAddr = llvm::alignTo(startAddr, (*si)->alignment());
- // Handle linker script expressions, which *may update newAddr* if the
- // expression assigns to "."
- if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
- expr->evalExpr(newAddr);
- curSliceAddress = newAddr;
- sliceAlign = (*si)->alignment();
- (*si)->setVirtualAddr(curSliceAddress);
-
- // Handle TLS.
- if (auto section = dyn_cast<Section<ELFT>>(*si)) {
- if (section->getSegmentType() == llvm::ELF::PT_TLS) {
- tlsStartAddr = llvm::alignTo(tlsStartAddr, (*si)->alignment());
- section->assignVirtualAddress(tlsStartAddr);
- tlsStartAddr += (*si)->memSize();
- } else {
- section->assignVirtualAddress(newAddr);
- }
- }
- // TBSS section is special in that it doesn't contribute to memory of any
- // segment. If we see a tbss section, don't add memory size to addr The
- // fileOffset is automatically taken care of since TBSS section does not
- // end up using file size
- if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
- curSliceSize = (*si)->memSize();
- tbssMemsize = 0;
- } else {
- tbssMemsize = (*si)->memSize();
- }
- ++currSection;
- ++si;
- }
-
- uint64_t scriptAddr = 0;
- bool forceScriptAddr = false;
- for (auto e = _sections.end(); si != e; ++si) {
- uint64_t curAddr = curSliceAddress + curSliceSize;
- if (!isDataPageAlignedForNMagic && needAlign(*si)) {
- // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
- // Data
- // to a page boundary
- curAddr = llvm::alignTo(curAddr, this->_ctx.getPageSize());
- isDataPageAlignedForNMagic = true;
- }
- uint64_t newAddr = llvm::alignTo(forceScriptAddr ? scriptAddr : curAddr,
- (*si)->alignment());
- forceScriptAddr = false;
-
- // Handle linker script expressions, which may force an address change if
- // the expression assigns to "."
- if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si)) {
- uint64_t oldAddr = newAddr;
- expr->evalExpr(newAddr);
- if (oldAddr != newAddr) {
- forceScriptAddr = true;
- scriptAddr = newAddr;
- }
- (*si)->setVirtualAddr(newAddr);
- continue;
- }
- Section<ELFT> *sec = dyn_cast<Section<ELFT>>(*si);
- StringRef curOutputSectionName =
- sec ? sec->outputSectionName() : (*si)->name();
- bool autoCreateSlice = true;
- if (curOutputSectionName == prevOutputSectionName)
- autoCreateSlice = false;
- // If the newAddress computed is more than a page away, let's create
- // a separate segment, so that memory is not used up while running.
- // Dont create a slice, if the new section falls in the same output
- // section as the previous section.
- if (autoCreateSlice && ((newAddr - curAddr) > this->_ctx.getPageSize()) &&
- (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
- _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
- auto sliceIter =
- std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
- [startSection](SegmentSlice<ELFT> *s) -> bool {
- return s->startSection() == startSection;
- });
- if (sliceIter == _segmentSlices.end()) {
- slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
- SegmentSlice<ELFT>();
- _segmentSlices.push_back(slice);
- } else {
- slice = *sliceIter;
- }
- slice->setStart(startSection);
- slice->setSections(make_range(startSectionIter, si));
- slice->setMemSize(curSliceSize);
- slice->setAlign(sliceAlign);
- slice->setVirtualAddr(curSliceAddress);
- // Start new slice
- curSliceAddress = newAddr;
- if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
- curSliceAddress += tbssMemsize;
- (*si)->setVirtualAddr(curSliceAddress);
- startSectionIter = si;
- startSection = currSection;
- if (auto section = dyn_cast<Section<ELFT>>(*si))
- section->assignVirtualAddress(newAddr);
- curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
- sliceAlign = (*si)->alignment();
- } else {
- if (sliceAlign < (*si)->alignment())
- sliceAlign = (*si)->alignment();
- if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
- newAddr += tbssMemsize;
- (*si)->setVirtualAddr(newAddr);
- // Handle TLS.
- if (auto section = dyn_cast<Section<ELFT>>(*si)) {
- if (section->getSegmentType() == llvm::ELF::PT_TLS) {
- tlsStartAddr = llvm::alignTo(tlsStartAddr, (*si)->alignment());
- section->assignVirtualAddress(tlsStartAddr);
- tlsStartAddr += (*si)->memSize();
- } else {
- section->assignVirtualAddress(newAddr);
- }
- }
- // TBSS section is special in that it doesn't contribute to memory of
- // any segment. If we see a tbss section, don't add memory size to addr
- // The fileOffset is automatically taken care of since TBSS section does
- // not end up using file size.
- if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
- curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
- tbssMemsize = 0;
- } else {
- // Although TBSS section does not contribute to memory of any segment,
- // we still need to keep track its total size to correct write it
- // down. Since it is done based on curSliceAddress, we need to add
- // add it to virtual address.
- tbssMemsize = (*si)->memSize();
- }
- }
- prevOutputSectionName = curOutputSectionName;
- ++currSection;
- }
-
- auto sliceIter = std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
- [startSection](SegmentSlice<ELFT> *s) -> bool {
- return s->startSection() == startSection;
- });
- if (sliceIter == _segmentSlices.end()) {
- slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
- SegmentSlice<ELFT>();
- _segmentSlices.push_back(slice);
- } else {
- slice = *sliceIter;
- }
-
- slice->setStart(startSection);
- slice->setVirtualAddr(curSliceAddress);
- slice->setMemSize(curSliceSize);
- slice->setSections(make_range(startSectionIter, _sections.end()));
- slice->setAlign(sliceAlign);
-
- // Set the segment memory size and the virtual address.
- this->setMemSize(curSliceAddress - startAddr + curSliceSize);
- this->setVirtualAddr(startAddr);
- std::stable_sort(_segmentSlices.begin(), _segmentSlices.end(),
- SegmentSlice<ELFT>::compare_slices);
-}
-
-// Write the Segment
-template <class ELFT>
-void Segment<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) {
- for (auto slice : slices())
- for (auto section : slice->sections())
- section->write(writer, layout, buffer);
-}
-
-template <class ELFT> int64_t Segment<ELFT>::flags() const {
- if (_segmentFlags)
- return (int64_t)_flags;
-
- int64_t fl = 0;
- if (_flags & llvm::ELF::SHF_ALLOC)
- fl |= llvm::ELF::PF_R;
- if (_flags & llvm::ELF::SHF_WRITE)
- fl |= llvm::ELF::PF_W;
- if (_flags & llvm::ELF::SHF_EXECINSTR)
- fl |= llvm::ELF::PF_X;
- return fl;
-}
-
-template <class ELFT> void Segment<ELFT>::setSegmentFlags(uint64_t flags) {
- assert(!_segmentFlags && "Segment flags have already been set");
- _segmentFlags = true;
- _flags = flags;
- _atomflags = toAtomPermsSegment(flags);
-}
-
-template <class ELFT> void Segment<ELFT>::finalize() {
- // We want to finalize the segment values for now only for non loadable
- // segments, since those values are not set in the Layout
- if (_segmentType == llvm::ELF::PT_LOAD)
- return;
- // The size is the difference of the
- // last section to the first section, especially for TLS because
- // the TLS segment contains both .tdata/.tbss
- this->setFileOffset(_sections.front()->fileOffset());
- this->setVirtualAddr(_sections.front()->virtualAddr());
- size_t startFileOffset = _sections.front()->fileOffset();
- size_t startAddr = _sections.front()->virtualAddr();
- for (auto ai : _sections) {
- this->_fsize = ai->fileOffset() + ai->fileSize() - startFileOffset;
- this->_msize = ai->virtualAddr() + ai->memSize() - startAddr;
- }
-}
-
-template <class ELFT> int Segment<ELFT>::getContentType() const {
- int64_t fl = flags();
- switch (_segmentType) {
- case llvm::ELF::PT_LOAD: {
- if (fl && llvm::ELF::PF_X)
- return Chunk<ELFT>::ContentType::Code;
- if (fl && llvm::ELF::PF_W)
- return Chunk<ELFT>::ContentType::Data;
- }
- case llvm::ELF::PT_TLS:
- return Chunk<ELFT>::ContentType::TLS;
- case llvm::ELF::PT_NOTE:
- return Chunk<ELFT>::ContentType::Note;
- default:
- return Chunk<ELFT>::ContentType::Unknown;
- }
-}
-
-template <class ELFT> int64_t Segment<ELFT>::atomflags() const {
- switch (_atomflags) {
- case DefinedAtom::permUnknown:
- return permUnknown;
- case DefinedAtom::permRWX:
- return permRWX;
- case DefinedAtom::permR_X:
- return permRX;
- case DefinedAtom::permR__:
- return permR;
- case DefinedAtom::permRW_L:
- return permRWL;
- case DefinedAtom::permRW_:
- return permRW;
- case DefinedAtom::perm___:
- default:
- return permNonAccess;
- }
-}
-
-/// \brief Check if the chunk needs to be aligned
-template <class ELFT> bool Segment<ELFT>::needAlign(Chunk<ELFT> *chunk) const {
- if (chunk->getContentType() == Chunk<ELFT>::ContentType::Data &&
- _outputMagic == ELFLinkingContext::OutputMagic::NMAGIC)
- return true;
- return false;
-}
-
-template <class ELFT> void ProgramHeaderSegment<ELFT>::finalize() {
- // If the segment is of type Program Header, then the values fileOffset
- // and the fileSize need to be picked up from the last section, the first
- // section points to the ELF header and the second chunk points to the
- // actual program headers
- this->setFileOffset(this->_sections.back()->fileOffset());
- this->setVirtualAddr(this->_sections.back()->virtualAddr());
- this->_fsize = this->_sections.back()->fileSize();
- this->_msize = this->_sections.back()->memSize();
-}
-
-#define INSTANTIATE(klass) \
- template class klass<ELF32LE>; \
- template class klass<ELF32BE>; \
- template class klass<ELF64LE>; \
- template class klass<ELF64BE>
-
-INSTANTIATE(ExpressionChunk);
-INSTANTIATE(ProgramHeaderSegment);
-INSTANTIATE(Segment);
-INSTANTIATE(SegmentSlice);
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (removed)
@@ -1,246 +0,0 @@
-//===- lib/ReaderWriter/ELF/SegmentChunks.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H
-#define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H
-
-#include "Chunk.h"
-#include "SectionChunks.h"
-#include "Writer.h"
-#include "lld/Core/range.h"
-#include "lld/Core/Writer.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include <memory>
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class TargetLayout;
-
-/// \brief A segment can be divided into segment slices
-/// depending on how the segments can be split
-template<class ELFT>
-class SegmentSlice {
-public:
- typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
-
- /// Set the start of the slice.
- void setStart(int32_t s) { _startSection = s; }
-
- // Set the segment slice start and end iterators. This is used to walk through
- // the sections that are part of the Segment slice
- void setSections(range<SectionIter> sections) { _sections = sections; }
-
- // Return the fileOffset of the slice
- uint64_t fileOffset() const { return _offset; }
- void setFileOffset(uint64_t offset) { _offset = offset; }
-
- // Return the size of the slice
- uint64_t fileSize() const { return _fsize; }
- void setFileSize(uint64_t filesz) { _fsize = filesz; }
-
- // Return the start of the slice
- int32_t startSection() const { return _startSection; }
-
- // Return the start address of the slice
- uint64_t virtualAddr() const { return _addr; }
-
- // Return the memory size of the slice
- uint64_t memSize() const { return _memSize; }
-
- // Return the alignment of the slice
- uint64_t alignment() const { return _alignment; }
-
- void setMemSize(uint64_t memsz) { _memSize = memsz; }
-
- void setVirtualAddr(uint64_t addr) { _addr = addr; }
-
- void setAlign(uint64_t align) { _alignment = align; }
-
- static bool compare_slices(SegmentSlice<ELFT> *a, SegmentSlice<ELFT> *b);
-
- range<SectionIter> sections() { return _sections; }
-
-private:
- range<SectionIter> _sections;
- int32_t _startSection;
- uint64_t _addr;
- uint64_t _offset;
- uint64_t _alignment;
- uint64_t _fsize;
- uint64_t _memSize;
-};
-
-/// \brief A segment contains a set of sections, that have similar properties
-// the sections are already separated based on different flags and properties
-// the segment is just a way to concatenate sections to segments
-template<class ELFT>
-class Segment : public Chunk<ELFT> {
-public:
- typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter;
- typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
-
- Segment(const ELFLinkingContext &ctx, StringRef name,
- const typename TargetLayout<ELFT>::SegmentType type);
-
- /// \brief the Order of segments that appear in the output file
- enum SegmentOrder {
- permUnknown,
- permRWX,
- permRX,
- permR,
- permRWL,
- permRW,
- permNonAccess
- };
-
- /// append a section to a segment
- virtual void append(Chunk<ELFT> *chunk);
-
- /// Sort segments depending on the property
- /// If we have a Program Header segment, it should appear first
- /// If we have a INTERP segment, that should appear after the Program Header
- /// All Loadable segments appear next in this order
- /// All Read Write Execute segments follow
- /// All Read Execute segments appear next
- /// All Read only segments appear first
- /// All Write execute segments follow
- static bool compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb);
-
- /// \brief Start assigning file offset to the segment chunks The fileoffset
- /// needs to be page at the start of the segment and in addition the
- /// fileoffset needs to be aligned to the max section alignment within the
- /// segment. This is required so that the ELF property p_poffset % p_align =
- /// p_vaddr mod p_align holds true.
- /// The algorithm starts off by assigning the startOffset thats passed in as
- /// parameter to the first section in the segment, if the difference between
- /// the newly computed offset is greater than a page, then we create a segment
- /// slice, as it would be a waste of virtual memory just to be filled with
- /// zeroes
- void assignFileOffsets(uint64_t startOffset);
-
- /// \brief Assign virtual addresses to the slices
- void assignVirtualAddress(uint64_t addr);
-
- // Write the Segment
- void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override;
-
- int64_t flags() const;
-
- // Set segment flags directly.
- void setSegmentFlags(uint64_t flags);
-
- /// Prepend a generic chunk to the segment.
- void prepend(Chunk<ELFT> *c) {
- _sections.insert(_sections.begin(), c);
- }
-
- /// Finalize the segment, before we want to write the segment header
- /// information
- void finalize() override;
-
- // For LLVM RTTI
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::ELFSegment;
- }
-
- // Getters
- int32_t sectionCount() const { return _sections.size(); }
-
- /// \brief, this function returns the type of segment (PT_*)
- typename TargetLayout<ELFT>::SegmentType segmentType() const {
- return _segmentType;
- }
-
- /// \brief return the segment type depending on the content,
- /// If the content corresponds to Code, this will return Segment::Code
- /// If the content corresponds to Data, this will return Segment::Data
- /// If the content corresponds to TLS, this will return Segment::TLS
- int getContentType() const override;
-
- int pageSize() const { return this->_ctx.getPageSize(); }
- int rawflags() const { return _atomflags; }
- int64_t atomflags() const;
- int64_t numSlices() const { return _segmentSlices.size(); }
- range<SliceIter> slices() { return _segmentSlices; }
- Chunk<ELFT> *firstSection() { return _sections[0]; }
-
-private:
- /// \brief Check if the chunk needs to be aligned
- bool needAlign(Chunk<ELFT> *chunk) const;
-
- // Cached value of outputMagic
- ELFLinkingContext::OutputMagic _outputMagic;
-
-protected:
- /// \brief Section or some other chunk type.
- std::vector<Chunk<ELFT> *> _sections;
- std::vector<SegmentSlice<ELFT> *> _segmentSlices;
- typename TargetLayout<ELFT>::SegmentType _segmentType;
- uint64_t _flags;
- int64_t _atomflags;
- bool _segmentFlags;
- llvm::BumpPtrAllocator _segmentAllocate;
-};
-
-/// This chunk represents a linker script expression that needs to be calculated
-/// at the time the virtual addresses for the parent segment are being assigned.
-template <class ELFT> class ExpressionChunk : public Chunk<ELFT> {
-public:
- ExpressionChunk(ELFLinkingContext &ctx, const script::SymbolAssignment *expr)
- : Chunk<ELFT>(StringRef(), Chunk<ELFT>::Kind::Expression, ctx),
- _expr(expr), _linkerScriptSema(ctx.linkerScriptSema()) {
- this->_alignment = 1;
- }
-
- static bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::Kind::Expression;
- }
-
- int getContentType() const override {
- return Chunk<ELFT>::ContentType::Unknown;
- }
-
- void write(ELFWriter *, TargetLayout<ELFT> &,
- llvm::FileOutputBuffer &) override {}
-
- std::error_code evalExpr(uint64_t &curPos) {
- return _linkerScriptSema.evalExpr(_expr, curPos);
- }
-
-private:
- const script::SymbolAssignment *_expr;
- script::Sema &_linkerScriptSema;
-};
-
-/// \brief A Program Header segment contains a set of chunks instead of sections
-/// The segment doesn't contain any slice
-template <class ELFT> class ProgramHeaderSegment : public Segment<ELFT> {
-public:
- ProgramHeaderSegment(const ELFLinkingContext &ctx)
- : Segment<ELFT>(ctx, "PHDR", llvm::ELF::PT_PHDR) {
- this->_alignment = 8;
- this->_flags = (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR);
- }
-
- /// Finalize the segment, before we want to write the segment header
- /// information
- void finalize() override;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H
Removed: lld/trunk/lib/ReaderWriter/ELF/TODO.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TODO.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TODO.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TODO.txt (removed)
@@ -1,18 +0,0 @@
-lib/ReaderWriter/ELF
-~~~~~~~~~~~~~~~~~~~~
-
-- Implement processing of DT_NEEDED elements including -rpath-link /
- -rpath processing.
-
-- _GLOBAL_OFFSET_TABLE should be hidden and normally dropped from the output.
-
-- Merge SHT_NOTE sections only if applicable.
-
-- Do not create __got_* / __plt_* symbol table entries by default.
-
-- Weak references to symbols defined in a DSO should remain weak.
-
-- Fix section flags as they appear in input (update content permissions)
-
-- Check for errors in the ELFReader when creating atoms for LinkOnce
- sections/Group sections. Add tests to account for the change when it happens.
Removed: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (removed)
@@ -1,35 +0,0 @@
-//===- lib/ReaderWriter/ELF/TargetHandler.h -------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_TARGET_HANDLER_H
-
-#include "lld/Core/Error.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace lld {
-namespace elf {
-
-inline std::error_code make_unhandled_reloc_error() {
- return make_dynamic_error_code("Unhandled reference type");
-}
-
-inline std::error_code make_out_of_range_reloc_error() {
- return make_dynamic_error_code("Relocation out of range");
-}
-
-inline std::error_code make_unaligned_range_reloc_error() {
- return make_dynamic_error_code("Relocation not aligned");
-}
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp (removed)
@@ -1,747 +0,0 @@
-//===- lib/ReaderWriter/ELF/TargetLayout.cpp ------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TargetLayout.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/Errc.h"
-
-namespace lld {
-namespace elf {
-
-template <class ELFT>
-typename TargetLayout<ELFT>::SectionOrder
-TargetLayout<ELFT>::getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) {
- switch (contentType) {
- case DefinedAtom::typeResolver:
- case DefinedAtom::typeCode:
- return llvm::StringSwitch<typename TargetLayout<ELFT>::SectionOrder>(name)
- .StartsWith(".eh_frame_hdr", ORDER_EH_FRAMEHDR)
- .StartsWith(".eh_frame", ORDER_EH_FRAME)
- .StartsWith(".init", ORDER_INIT)
- .StartsWith(".fini", ORDER_FINI)
- .StartsWith(".hash", ORDER_HASH)
- .Default(ORDER_TEXT);
-
- case DefinedAtom::typeConstant:
- return ORDER_RODATA;
-
- case DefinedAtom::typeData:
- case DefinedAtom::typeDataFast:
- return llvm::StringSwitch<typename TargetLayout<ELFT>::SectionOrder>(name)
- .StartsWith(".init_array", ORDER_INIT_ARRAY)
- .StartsWith(".fini_array", ORDER_FINI_ARRAY)
- .StartsWith(".dynamic", ORDER_DYNAMIC)
- .StartsWith(".ctors", ORDER_CTORS)
- .StartsWith(".dtors", ORDER_DTORS)
- .Default(ORDER_DATA);
-
- case DefinedAtom::typeZeroFill:
- case DefinedAtom::typeZeroFillFast:
- return ORDER_BSS;
-
- case DefinedAtom::typeGOT:
- return llvm::StringSwitch<typename TargetLayout<ELFT>::SectionOrder>(name)
- .StartsWith(".got.plt", ORDER_GOT_PLT)
- .Default(ORDER_GOT);
-
- case DefinedAtom::typeStub:
- return ORDER_PLT;
-
- case DefinedAtom::typeRONote:
- return ORDER_RO_NOTE;
-
- case DefinedAtom::typeRWNote:
- return ORDER_RW_NOTE;
-
- case DefinedAtom::typeNoAlloc:
- return ORDER_NOALLOC;
-
- case DefinedAtom::typeThreadData:
- return ORDER_TDATA;
- case DefinedAtom::typeThreadZeroFill:
- return ORDER_TBSS;
- default:
- // If we get passed in a section push it to OTHER
- if (contentPermissions == DefinedAtom::perm___)
- return ORDER_OTHER;
-
- return ORDER_NOT_DEFINED;
- }
-}
-
-/// \brief This maps the input sections to the output section names
-template <class ELFT>
-StringRef TargetLayout<ELFT>::getInputSectionName(const DefinedAtom *da) const {
- if (da->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
- switch (da->contentType()) {
- case DefinedAtom::typeCode:
- return ".text";
- case DefinedAtom::typeData:
- return ".data";
- case DefinedAtom::typeConstant:
- return ".rodata";
- case DefinedAtom::typeZeroFill:
- return ".bss";
- case DefinedAtom::typeThreadData:
- return ".tdata";
- case DefinedAtom::typeThreadZeroFill:
- return ".tbss";
- default:
- break;
- }
- }
- return da->customSectionName();
-}
-
-/// \brief This maps the input sections to the output section names.
-template <class ELFT>
-StringRef
-TargetLayout<ELFT>::getOutputSectionName(StringRef archivePath,
- StringRef memberPath,
- StringRef inputSectionName) const {
- StringRef outputSectionName;
- if (_linkerScriptSema.hasLayoutCommands()) {
- script::Sema::SectionKey key = {archivePath, memberPath, inputSectionName};
- outputSectionName = _linkerScriptSema.getOutputSection(key);
- if (!outputSectionName.empty())
- return outputSectionName;
- }
- return llvm::StringSwitch<StringRef>(inputSectionName)
- .StartsWith(".text", ".text")
- .StartsWith(".ctors", ".ctors")
- .StartsWith(".dtors", ".dtors")
- .StartsWith(".rodata", ".rodata")
- .StartsWith(".gcc_except_table", ".gcc_except_table")
- .StartsWith(".data.rel.ro", ".data.rel.ro")
- .StartsWith(".data.rel.local", ".data.rel.local")
- .StartsWith(".data", ".data")
- .StartsWith(".tdata", ".tdata")
- .StartsWith(".tbss", ".tbss")
- .StartsWith(".init_array", ".init_array")
- .StartsWith(".fini_array", ".fini_array")
- .Default(inputSectionName);
-}
-
-/// \brief Gets the segment for a output section
-template <class ELFT>
-typename TargetLayout<ELFT>::SegmentType
-TargetLayout<ELFT>::getSegmentType(const Section<ELFT> *section) const {
- switch (section->order()) {
- case ORDER_INTERP:
- return llvm::ELF::PT_INTERP;
-
- case ORDER_TEXT:
- case ORDER_HASH:
- case ORDER_DYNAMIC_SYMBOLS:
- case ORDER_DYNAMIC_STRINGS:
- case ORDER_DYNAMIC_RELOCS:
- case ORDER_DYNAMIC_PLT_RELOCS:
- case ORDER_REL:
- case ORDER_INIT:
- case ORDER_PLT:
- case ORDER_FINI:
- case ORDER_RODATA:
- case ORDER_EH_FRAME:
- case ORDER_CTORS:
- case ORDER_DTORS:
- return llvm::ELF::PT_LOAD;
-
- case ORDER_RO_NOTE:
- case ORDER_RW_NOTE:
- return llvm::ELF::PT_NOTE;
-
- case ORDER_DYNAMIC:
- return llvm::ELF::PT_DYNAMIC;
-
- case ORDER_EH_FRAMEHDR:
- return llvm::ELF::PT_GNU_EH_FRAME;
-
- case ORDER_GOT:
- case ORDER_GOT_PLT:
- case ORDER_DATA:
- case ORDER_BSS:
- case ORDER_INIT_ARRAY:
- case ORDER_FINI_ARRAY:
- return llvm::ELF::PT_LOAD;
-
- case ORDER_TDATA:
- case ORDER_TBSS:
- return llvm::ELF::PT_TLS;
-
- default:
- return llvm::ELF::PT_NULL;
- }
-}
-
-template <class ELFT>
-bool TargetLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
- switch (section->order()) {
- case ORDER_INTERP:
- case ORDER_HASH:
- case ORDER_DYNAMIC_SYMBOLS:
- case ORDER_DYNAMIC_STRINGS:
- case ORDER_DYNAMIC_RELOCS:
- case ORDER_DYNAMIC_PLT_RELOCS:
- case ORDER_REL:
- case ORDER_INIT:
- case ORDER_PLT:
- case ORDER_TEXT:
- case ORDER_FINI:
- case ORDER_RODATA:
- case ORDER_EH_FRAME:
- case ORDER_EH_FRAMEHDR:
- case ORDER_TDATA:
- case ORDER_TBSS:
- case ORDER_RO_NOTE:
- case ORDER_RW_NOTE:
- case ORDER_DYNAMIC:
- case ORDER_CTORS:
- case ORDER_DTORS:
- case ORDER_GOT:
- case ORDER_GOT_PLT:
- case ORDER_DATA:
- case ORDER_INIT_ARRAY:
- case ORDER_FINI_ARRAY:
- case ORDER_BSS:
- case ORDER_NOALLOC:
- return true;
- default:
- return section->hasOutputSegment();
- }
-}
-
-template <class ELFT>
-AtomSection<ELFT> *
-TargetLayout<ELFT>::createSection(StringRef sectionName, int32_t contentType,
- DefinedAtom::ContentPermissions permissions,
- SectionOrder sectionOrder) {
- return new (_allocator) AtomSection<ELFT>(_ctx, sectionName, contentType,
- permissions, sectionOrder);
-}
-
-template <class ELFT>
-AtomSection<ELFT> *
-TargetLayout<ELFT>::getSection(StringRef sectionName, int32_t contentType,
- DefinedAtom::ContentPermissions permissions,
- const DefinedAtom *da) {
- const SectionKey sectionKey(sectionName, permissions, da->file().path());
- SectionOrder sectionOrder =
- getSectionOrder(sectionName, contentType, permissions);
- auto sec = _sectionMap.find(sectionKey);
- if (sec != _sectionMap.end())
- return sec->second;
- AtomSection<ELFT> *newSec =
- createSection(sectionName, contentType, permissions, sectionOrder);
-
- newSec->setOutputSectionName(getOutputSectionName(
- da->file().archivePath(), da->file().memberPath(), sectionName));
- newSec->setOrder(sectionOrder);
- newSec->setArchiveNameOrPath(da->file().archivePath());
- newSec->setMemberNameOrPath(da->file().memberPath());
- _sections.push_back(newSec);
- _sectionMap.insert(std::make_pair(sectionKey, newSec));
- return newSec;
-}
-
-template <class ELFT>
-ErrorOr<const AtomLayout *> TargetLayout<ELFT>::addAtom(const Atom *atom) {
- if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
- // HACK: Ignore undefined atoms. We need to adjust the interface so that
- // undefined atoms can still be included in the output symbol table for
- // -noinhibit-exec.
- if (definedAtom->contentType() == DefinedAtom::typeUnknown)
- return make_error_code(llvm::errc::invalid_argument);
- const DefinedAtom::ContentPermissions permissions =
- definedAtom->permissions();
- const DefinedAtom::ContentType contentType = definedAtom->contentType();
-
- StringRef sectionName = getInputSectionName(definedAtom);
- AtomSection<ELFT> *section =
- getSection(sectionName, contentType, permissions, definedAtom);
-
- // Add runtime relocations to the .rela section.
- for (const auto &reloc : *definedAtom) {
- bool isLocalReloc = true;
- if (_ctx.isDynamicRelocation(*reloc)) {
- getDynamicRelocationTable()->addRelocation(*definedAtom, *reloc);
- isLocalReloc = false;
- } else if (_ctx.isPLTRelocation(*reloc)) {
- getPLTRelocationTable()->addRelocation(*definedAtom, *reloc);
- isLocalReloc = false;
- }
-
- if (!reloc->target())
- continue;
-
- // Ignore undefined atoms that are not target of dynamic relocations
- if (isa<UndefinedAtom>(reloc->target()) && isLocalReloc)
- continue;
-
- if (_ctx.isCopyRelocation(*reloc)) {
- _copiedDynSymNames.insert(definedAtom->name());
- continue;
- }
-
- _referencedDynAtoms.insert(reloc->target());
- }
- return section->appendAtom(atom);
- }
-
- const AbsoluteAtom *absoluteAtom = cast<AbsoluteAtom>(atom);
- // Absolute atoms are not part of any section, they are global for the whole
- // link
- _absoluteAtoms.push_back(
- new (_allocator) AtomLayout(absoluteAtom, 0, absoluteAtom->value()));
- return _absoluteAtoms.back();
-}
-
-/// Output sections with the same name into a OutputSection
-template <class ELFT> void TargetLayout<ELFT>::createOutputSections() {
- OutputSection<ELFT> *outputSection;
-
- for (auto &si : _sections) {
- Section<ELFT> *section = dyn_cast<Section<ELFT>>(si);
- if (!section)
- continue;
- const std::pair<StringRef, OutputSection<ELFT> *> currentOutputSection(
- section->outputSectionName(), nullptr);
- std::pair<typename OutputSectionMapT::iterator, bool> outputSectionInsert(
- _outputSectionMap.insert(currentOutputSection));
- if (!outputSectionInsert.second) {
- outputSection = outputSectionInsert.first->second;
- } else {
- outputSection = new (_allocator.Allocate<OutputSection<ELFT>>())
- OutputSection<ELFT>(section->outputSectionName());
- _outputSections.push_back(outputSection);
- outputSectionInsert.first->second = outputSection;
- }
- outputSection->appendSection(section);
- }
-}
-
-template <class ELFT>
-std::vector<typename TargetLayout<ELFT>::SegmentKey>
-TargetLayout<ELFT>::getSegmentsForSection(const OutputSection<ELFT> *os,
- const Section<ELFT> *sec) const {
- std::vector<SegmentKey> segKeys;
- auto phdrs = _linkerScriptSema.getPHDRsForOutputSection(os->name());
- if (!phdrs.empty()) {
- if (phdrs.size() == 1 && phdrs[0]->isNone()) {
- segKeys.emplace_back("NONE", llvm::ELF::PT_NULL, 0, false);
- return segKeys;
- }
-
- for (auto phdr : phdrs) {
- segKeys.emplace_back(phdr->name(), phdr->type(), phdr->flags(), true);
- }
- return segKeys;
- }
-
- uint64_t flags = getLookupSectionFlags(os);
- int64_t segmentType = getSegmentType(sec);
- StringRef segmentName = sec->segmentKindToStr();
-
- // We need a separate segment for sections that don't have
- // the segment type to be PT_LOAD
- if (segmentType != llvm::ELF::PT_LOAD)
- segKeys.emplace_back(segmentName, segmentType, flags, false);
-
- if (segmentType == llvm::ELF::PT_NULL)
- return segKeys;
-
- // If the output magic is set to OutputMagic::NMAGIC or
- // OutputMagic::OMAGIC, Place the data alongside text in one single
- // segment
- ELFLinkingContext::OutputMagic outputMagic = _ctx.getOutputMagic();
- if (outputMagic == ELFLinkingContext::OutputMagic::NMAGIC ||
- outputMagic == ELFLinkingContext::OutputMagic::OMAGIC)
- flags =
- llvm::ELF::SHF_EXECINSTR | llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;
-
- segKeys.emplace_back("LOAD", llvm::ELF::PT_LOAD, flags, false);
- return segKeys;
-}
-
-template <class ELFT>
-uint64_t
-TargetLayout<ELFT>::getLookupSectionFlags(const OutputSection<ELFT> *os) const {
- uint64_t flags = os->flags();
- if (!(flags & llvm::ELF::SHF_WRITE) && _ctx.mergeRODataToTextSegment())
- flags &= ~llvm::ELF::SHF_EXECINSTR;
-
- // Merge string sections into Data segment itself
- flags &= ~(llvm::ELF::SHF_STRINGS | llvm::ELF::SHF_MERGE);
-
- // Merge the TLS section into the DATA segment itself
- flags &= ~(llvm::ELF::SHF_TLS);
- return flags;
-}
-
-template <class ELFT> void TargetLayout<ELFT>::assignSectionsToSegments() {
- ScopedTask task(getDefaultDomain(), "assignSectionsToSegments");
- // sort the sections by their order as defined by the layout
- sortInputSections();
-
- // Create output sections.
- createOutputSections();
-
- // Finalize output section layout.
- finalizeOutputSectionLayout();
-
- // Set the ordinal after sorting the sections
- int ordinal = 1;
- for (auto osi : _outputSections) {
- osi->setOrdinal(ordinal);
- for (auto ai : osi->sections()) {
- ai->setOrdinal(ordinal);
- }
- ++ordinal;
- }
- for (auto osi : _outputSections) {
- for (auto section : osi->sections()) {
- if (!hasOutputSegment(section))
- continue;
-
- osi->setLoadableSection(section->isLoadableSection());
- osi->setHasSegment();
-
- auto segKeys = getSegmentsForSection(osi, section);
- assert(!segKeys.empty() && "Must always be at least one segment");
- section->setSegmentType(segKeys[0]._type);
-
- for (auto key : segKeys) {
- // Try to find non-load (real) segment type if possible
- if (key._type != llvm::ELF::PT_LOAD)
- section->setSegmentType(key._type);
-
- const std::pair<SegmentKey, Segment<ELFT> *> currentSegment(key,
- nullptr);
- std::pair<typename SegmentMapT::iterator, bool> segmentInsert(
- _segmentMap.insert(currentSegment));
- Segment<ELFT> *segment;
- if (!segmentInsert.second) {
- segment = segmentInsert.first->second;
- } else {
- segment = new (_allocator) Segment<ELFT>(_ctx, key._name, key._type);
- if (key._segmentFlags)
- segment->setSegmentFlags(key._flags);
- segmentInsert.first->second = segment;
- _segments.push_back(segment);
- }
- if (key._type == llvm::ELF::PT_LOAD) {
- // Insert chunks with linker script expressions that occur at this
- // point, just before appending a new input section
- addExtraChunksToSegment(segment, section->archivePath(),
- section->memberPath(),
- section->inputSectionName());
- }
- segment->append(section);
- }
- }
- }
-
- // Default values if no linker script is available
- bool hasProgramSegment = _ctx.isDynamic() && !_ctx.isDynamicLibrary();
- bool hasElfHeader = true;
- bool hasProgramHeader = true;
- uint64_t segmentFlags = 0;
-
- // Check if linker script has PHDRS and program segment defined
- if (_linkerScriptSema.hasPHDRs()) {
- if (auto p = _linkerScriptSema.getProgramPHDR()) {
- hasProgramSegment = true;
- hasElfHeader = p->hasFileHdr();
- hasProgramHeader = p->hasPHDRs();
- segmentFlags = p->flags();
- } else {
- hasProgramSegment = false;
- hasElfHeader = false;
- hasProgramHeader = false;
- }
- }
-
- if (hasProgramSegment) {
- Segment<ELFT> *segment = new (_allocator) ProgramHeaderSegment<ELFT>(_ctx);
- _segments.push_back(segment);
- if (segmentFlags)
- segment->setSegmentFlags(segmentFlags);
- if (hasElfHeader)
- segment->append(_elfHeader);
- if (hasProgramHeader)
- segment->append(_programHeader);
- }
-}
-
-template <class ELFT> void TargetLayout<ELFT>::sortSegments() {
- std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments);
-}
-
-template <class ELFT> void TargetLayout<ELFT>::assignVirtualAddress() {
- if (_segments.empty())
- return;
-
- sortSegments();
-
- uint64_t baseAddress = _ctx.getBaseAddress();
-
- // HACK: This is a super dirty hack. The elf header and program header are
- // not part of a section, but we need them to be loaded at the base address
- // so that AT_PHDR is set correctly by the loader and so they are accessible
- // at runtime. To do this we simply prepend them to the first loadable Segment
- // and let the layout logic take care of it.
- Segment<ELFT> *firstLoadSegment = nullptr;
- for (auto si : _segments) {
- if (si->segmentType() == llvm::ELF::PT_LOAD) {
- firstLoadSegment = si;
- si->firstSection()->setAlign(si->alignment());
- break;
- }
- }
- assert(firstLoadSegment != nullptr && "No loadable segment!");
- firstLoadSegment->prepend(_programHeader);
- firstLoadSegment->prepend(_elfHeader);
- bool newSegmentHeaderAdded = true;
- bool virtualAddressAssigned = false;
- bool fileOffsetAssigned = false;
- while (true) {
- for (auto si : _segments) {
- si->finalize();
- // Don't add PT_NULL segments into the program header
- if (si->segmentType() != llvm::ELF::PT_NULL)
- newSegmentHeaderAdded = _programHeader->addSegment(si);
- }
- if (!newSegmentHeaderAdded && virtualAddressAssigned)
- break;
- uint64_t address = baseAddress;
- // start assigning virtual addresses
- for (auto &si : _segments) {
- if ((si->segmentType() != llvm::ELF::PT_LOAD) &&
- (si->segmentType() != llvm::ELF::PT_NULL))
- continue;
-
- if (si->segmentType() == llvm::ELF::PT_NULL) {
- si->assignVirtualAddress(0 /*non loadable*/);
- } else {
- if (virtualAddressAssigned && (address != baseAddress) &&
- (address == si->virtualAddr()))
- break;
- si->assignVirtualAddress(address);
- }
- address = si->virtualAddr() + si->memSize();
- }
- uint64_t baseFileOffset = 0;
- uint64_t fileoffset = baseFileOffset;
- for (auto &si : _segments) {
- if ((si->segmentType() != llvm::ELF::PT_LOAD) &&
- (si->segmentType() != llvm::ELF::PT_NULL))
- continue;
- if (fileOffsetAssigned && (fileoffset != baseFileOffset) &&
- (fileoffset == si->fileOffset()))
- break;
- si->assignFileOffsets(fileoffset);
- fileoffset = si->fileOffset() + si->fileSize();
- }
- virtualAddressAssigned = true;
- fileOffsetAssigned = true;
- _programHeader->resetProgramHeaders();
- }
- Section<ELFT> *section;
- // Fix the offsets of all the atoms within a section
- for (auto &si : _sections) {
- section = dyn_cast<Section<ELFT>>(si);
- if (section && TargetLayout<ELFT>::hasOutputSegment(section))
- section->assignFileOffsets(section->fileOffset());
- }
- // Set the size of the merged Sections
- for (auto osi : _outputSections) {
- uint64_t sectionfileoffset = 0;
- uint64_t startFileOffset = 0;
- uint64_t sectionsize = 0;
- bool isFirstSection = true;
- for (auto si : osi->sections()) {
- if (isFirstSection) {
- startFileOffset = si->fileOffset();
- isFirstSection = false;
- }
- sectionfileoffset = si->fileOffset();
- sectionsize = si->fileSize();
- }
- sectionsize = (sectionfileoffset - startFileOffset) + sectionsize;
- osi->setFileOffset(startFileOffset);
- osi->setSize(sectionsize);
- }
- // Set the virtual addr of the merged Sections
- for (auto osi : _outputSections) {
- uint64_t sectionstartaddr = 0;
- uint64_t startaddr = 0;
- uint64_t sectionsize = 0;
- bool isFirstSection = true;
- for (auto si : osi->sections()) {
- if (isFirstSection) {
- startaddr = si->virtualAddr();
- isFirstSection = false;
- }
- sectionstartaddr = si->virtualAddr();
- sectionsize = si->memSize();
- }
- sectionsize = (sectionstartaddr - startaddr) + sectionsize;
- osi->setMemSize(sectionsize);
- osi->setAddr(startaddr);
- }
-}
-
-template <class ELFT>
-void TargetLayout<ELFT>::assignFileOffsetsForMiscSections() {
- uint64_t fileoffset = 0;
- uint64_t size = 0;
- for (auto si : _segments) {
- // Don't calculate offsets from non loadable segments
- if ((si->segmentType() != llvm::ELF::PT_LOAD) &&
- (si->segmentType() != llvm::ELF::PT_NULL))
- continue;
- fileoffset = si->fileOffset();
- size = si->fileSize();
- }
- fileoffset = fileoffset + size;
- Section<ELFT> *section;
- for (auto si : _sections) {
- section = dyn_cast<Section<ELFT>>(si);
- if (section && TargetLayout<ELFT>::hasOutputSegment(section))
- continue;
- fileoffset = llvm::alignTo(fileoffset, si->alignment());
- si->setFileOffset(fileoffset);
- si->setVirtualAddr(0);
- fileoffset += si->fileSize();
- }
-}
-
-template <class ELFT> void TargetLayout<ELFT>::sortInputSections() {
- // First, sort according to default layout's order
- std::stable_sort(
- _sections.begin(), _sections.end(),
- [](Chunk<ELFT> *A, Chunk<ELFT> *B) { return A->order() < B->order(); });
-
- if (!_linkerScriptSema.hasLayoutCommands())
- return;
-
- // Sort the sections by their order as defined by the linker script
- std::stable_sort(
- this->_sections.begin(), this->_sections.end(),
- [this](Chunk<ELFT> *A, Chunk<ELFT> *B) {
- auto *a = dyn_cast<Section<ELFT>>(A);
- auto *b = dyn_cast<Section<ELFT>>(B);
-
- if (a == nullptr)
- return false;
- if (b == nullptr)
- return true;
-
- return _linkerScriptSema.less(
- {a->archivePath(), a->memberPath(), a->inputSectionName()},
- {b->archivePath(), b->memberPath(), b->inputSectionName()});
- });
- // Now try to arrange sections with no mapping rules to sections with
- // similar content
- auto p = this->_sections.begin();
- // Find first section that has no assigned rule id
- while (p != this->_sections.end()) {
- auto *sect = dyn_cast<AtomSection<ELFT>>(*p);
- if (!sect)
- break;
-
- if (!_linkerScriptSema.hasMapping({sect->archivePath(), sect->memberPath(),
- sect->inputSectionName()}))
- break;
-
- ++p;
- }
- // For all sections that have no assigned rule id, try to move them near a
- // section with similar contents
- if (p != this->_sections.begin()) {
- for (; p != this->_sections.end(); ++p) {
- auto q = p;
- --q;
- while (q != this->_sections.begin() &&
- (*q)->getContentType() != (*p)->getContentType())
- --q;
- if ((*q)->getContentType() != (*p)->getContentType())
- continue;
- ++q;
- for (auto i = p; i != q;) {
- auto next = i--;
- std::iter_swap(i, next);
- }
- }
- }
-}
-
-template <class ELFT>
-const AtomLayout *
-TargetLayout<ELFT>::findAtomLayoutByName(StringRef name) const {
- for (auto sec : _sections)
- if (auto section = dyn_cast<Section<ELFT>>(sec))
- if (auto *al = section->findAtomLayoutByName(name))
- return al;
- return nullptr;
-}
-
-template <class ELFT>
-void TargetLayout<ELFT>::addExtraChunksToSegment(Segment<ELFT> *segment,
- StringRef archivePath,
- StringRef memberPath,
- StringRef sectionName) {
- if (!_linkerScriptSema.hasLayoutCommands())
- return;
- std::vector<const script::SymbolAssignment *> exprs =
- _linkerScriptSema.getExprs({archivePath, memberPath, sectionName});
- for (auto expr : exprs) {
- auto expChunk =
- new (this->_allocator) ExpressionChunk<ELFT>(this->_ctx, expr);
- segment->append(expChunk);
- }
-}
-
-template <class ELFT>
-RelocationTable<ELFT> *TargetLayout<ELFT>::getDynamicRelocationTable() {
- if (!_dynamicRelocationTable) {
- _dynamicRelocationTable = createRelocationTable(
- _ctx.isRelaOutputFormat() ? ".rela.dyn" : ".rel.dyn",
- ORDER_DYNAMIC_RELOCS);
- addSection(_dynamicRelocationTable.get());
- }
- return _dynamicRelocationTable.get();
-}
-
-template <class ELFT>
-RelocationTable<ELFT> *TargetLayout<ELFT>::getPLTRelocationTable() {
- if (!_pltRelocationTable) {
- _pltRelocationTable = createRelocationTable(
- _ctx.isRelaOutputFormat() ? ".rela.plt" : ".rel.plt",
- ORDER_DYNAMIC_PLT_RELOCS);
- addSection(_pltRelocationTable.get());
- }
- return _pltRelocationTable.get();
-}
-
-template <class ELFT> uint64_t TargetLayout<ELFT>::getTLSSize() const {
- for (const auto &phdr : *_programHeader)
- if (phdr->p_type == llvm::ELF::PT_TLS)
- return phdr->p_memsz;
- return 0;
-}
-
-template class TargetLayout<ELF32LE>;
-template class TargetLayout<ELF32BE>;
-template class TargetLayout<ELF64LE>;
-template class TargetLayout<ELF64BE>;
-
-} // end namespace elf
-} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/TargetLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetLayout.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetLayout.h (removed)
@@ -1,327 +0,0 @@
-//===- lib/ReaderWriter/ELF/TargetLayout.h --------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_DEFAULT_LAYOUT_H
-#define LLD_READER_WRITER_ELF_DEFAULT_LAYOUT_H
-
-#include "Atoms.h"
-#include "HeaderChunks.h"
-#include "SectionChunks.h"
-#include "SegmentChunks.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <unordered_map>
-
-namespace lld {
-namespace elf {
-
-/// \brief The TargetLayout class is used by the Writer to arrange
-/// sections and segments in the order determined by the target ELF
-/// format. The writer creates a single instance of the TargetLayout
-/// class
-template <class ELFT> class TargetLayout {
-public:
- typedef uint32_t SectionOrder;
- typedef uint32_t SegmentType;
-
- // The order in which the sections appear in the output file
- // If its determined, that the layout needs to change
- // just changing the order of enumerations would essentially
- // change the layout in the output file
- // Change the enumerations so that Target can override and stick
- // a section anywhere it wants to
- enum DefaultSectionOrder {
- ORDER_NOT_DEFINED = 0,
- ORDER_INTERP = 10,
- ORDER_RO_NOTE = 15,
- ORDER_HASH = 30,
- ORDER_DYNAMIC_SYMBOLS = 40,
- ORDER_DYNAMIC_STRINGS = 50,
- ORDER_DYNAMIC_RELOCS = 52,
- ORDER_DYNAMIC_PLT_RELOCS = 54,
- ORDER_INIT = 60,
- ORDER_PLT = 70,
- ORDER_TEXT = 80,
- ORDER_FINI = 90,
- ORDER_REL = 95,
- ORDER_RODATA = 100,
- ORDER_EH_FRAME = 110,
- ORDER_EH_FRAMEHDR = 120,
- ORDER_TDATA = 124,
- ORDER_TBSS = 128,
- ORDER_CTORS = 130,
- ORDER_DTORS = 140,
- ORDER_INIT_ARRAY = 150,
- ORDER_FINI_ARRAY = 160,
- ORDER_DYNAMIC = 170,
- ORDER_GOT = 180,
- ORDER_GOT_PLT = 190,
- ORDER_DATA = 200,
- ORDER_RW_NOTE = 205,
- ORDER_BSS = 210,
- ORDER_NOALLOC = 215,
- ORDER_OTHER = 220,
- ORDER_SECTION_STRINGS = 230,
- ORDER_SYMBOL_TABLE = 240,
- ORDER_STRING_TABLE = 250,
- ORDER_SECTION_HEADERS = 260
- };
-
-public:
-
- // The Key used for creating Sections
- // The sections are created using
- // SectionName, contentPermissions
- struct SectionKey {
- SectionKey(StringRef name, DefinedAtom::ContentPermissions perm,
- StringRef path)
- : _name(name), _perm(perm), _path(path) {}
-
- // Data members
- StringRef _name;
- DefinedAtom::ContentPermissions _perm;
- StringRef _path;
- };
-
- struct SectionKeyHash {
- int64_t operator()(const SectionKey &k) const {
- return llvm::hash_combine(k._name, k._perm, k._path);
- }
- };
-
- struct SectionKeyEq {
- bool operator()(const SectionKey &lhs, const SectionKey &rhs) const {
- return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm) &&
- (lhs._path == rhs._path));
- }
- };
-
- typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter;
- typedef typename std::vector<Segment<ELFT> *>::iterator SegmentIter;
-
- // Properties used during segment creation
- struct SegmentKey {
- SegmentKey(StringRef name, int64_t type, uint64_t flags, bool segFlags)
- : _name(name), _type(type), _flags(flags),
- _segmentFlags(segFlags && flags != 0) {}
- StringRef _name = "";
- int64_t _type = 0;
- uint64_t _flags = 0;
- bool _segmentFlags = false;
- };
-
- struct SegmentKeyHash {
- int64_t operator()(const SegmentKey &k) const {
- return llvm::hash_combine(k._name, k._type, k._flags);
- }
- };
-
- struct SegmentKeyEq {
- bool operator()(const SegmentKey &lhs, const SegmentKey &rhs) const {
- return ((lhs._name == rhs._name) && (lhs._type == rhs._type) &&
- (lhs._flags == rhs._flags));
- }
- };
-
- // Output Sections contain the map of Section names to a vector of sections,
- // that have been merged to form a single section
- typedef llvm::StringMap<OutputSection<ELFT> *> OutputSectionMapT;
- typedef
- typename std::vector<OutputSection<ELFT> *>::iterator OutputSectionIter;
-
- typedef std::unordered_map<SectionKey, AtomSection<ELFT> *, SectionKeyHash,
- SectionKeyEq> SectionMapT;
- typedef std::unordered_map<SegmentKey, Segment<ELFT> *, SegmentKeyHash,
- SegmentKeyEq> SegmentMapT;
-
- typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT;
-
- typedef llvm::DenseSet<const Atom *> AtomSetT;
-
- TargetLayout(ELFLinkingContext &ctx)
- : _ctx(ctx), _linkerScriptSema(ctx.linkerScriptSema()) {}
-
- virtual ~TargetLayout() = default;
-
- /// \brief Return the section order for a input section
- virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions);
-
- /// \brief Return the name of the input section by decoding the input
- /// sectionChoice.
- virtual StringRef getInputSectionName(const DefinedAtom *da) const;
-
- /// \brief Return the name of the output section from the input section.
- virtual StringRef getOutputSectionName(StringRef archivePath,
- StringRef memberPath,
- StringRef inputSectionName) const;
-
- /// \brief Gets or creates a section.
- AtomSection<ELFT> *
- getSection(StringRef name, int32_t contentType,
- DefinedAtom::ContentPermissions contentPermissions,
- const DefinedAtom *da);
-
- /// \brief Gets the segment for a output section
- virtual SegmentType getSegmentType(const Section<ELFT> *section) const;
-
- /// \brief Returns true/false depending on whether the section has a Output
- // segment or not
- static bool hasOutputSegment(Section<ELFT> *section);
-
- /// \brief Append the Atom to the layout and create appropriate sections.
- /// \returns A reference to the atom layout or an error. The atom layout will
- /// be updated as linking progresses.
- virtual ErrorOr<const AtomLayout *> addAtom(const Atom *atom);
-
- /// \brief Find an output Section given a section name.
- OutputSection<ELFT> *findOutputSection(StringRef name) {
- auto iter = _outputSectionMap.find(name);
- if (iter == _outputSectionMap.end())
- return nullptr;
- return iter->second;
- }
-
- /// \brief find a absolute atom given a name
- AtomLayout *findAbsoluteAtom(StringRef name) {
- auto iter = std::find_if(
- _absoluteAtoms.begin(), _absoluteAtoms.end(),
- [=](const AtomLayout *a) { return a->_atom->name() == name; });
- if (iter == _absoluteAtoms.end())
- return nullptr;
- return *iter;
- }
-
- // Output sections with the same name into a OutputSection
- void createOutputSections();
-
- // Query for segments based on output and input sections
- std::vector<SegmentKey> getSegmentsForSection(const OutputSection<ELFT> *os,
- const Section<ELFT> *sec) const;
-
- /// \brief Sort the sections by their order as defined by the layout,
- /// preparing all sections to be assigned to a segment.
- virtual void sortInputSections();
-
- /// \brief Add extra chunks to a segment just before including the input
- /// section given by <archivePath, memberPath, sectionName>. This
- /// is used to add linker script expressions before each section.
- virtual void addExtraChunksToSegment(Segment<ELFT> *segment,
- StringRef archivePath,
- StringRef memberPath,
- StringRef sectionName);
-
- /// \brief associates a section to a segment
- virtual void assignSectionsToSegments();
-
- /// \brief associates a virtual address to the segment, section, and the atom
- virtual void assignVirtualAddress();
-
- void assignFileOffsetsForMiscSections();
-
- range<AbsoluteAtomIterT> absoluteAtoms() { return _absoluteAtoms; }
-
- void addSection(Chunk<ELFT> *c) { _sections.push_back(c); }
-
- void finalize() {
- ScopedTask task(getDefaultDomain(), "Finalize layout");
- for (auto &si : _sections)
- si->finalize();
- }
-
- void doPreFlight() {
- for (auto &si : _sections)
- si->doPreFlight();
- }
-
- /// \brief find the Atom in the current layout
- virtual const AtomLayout *findAtomLayoutByName(StringRef name) const;
-
- void setHeader(ELFHeader<ELFT> *elfHeader) { _elfHeader = elfHeader; }
-
- void setProgramHeader(ProgramHeader<ELFT> *p) {
- _programHeader = p;
- }
-
- range<OutputSectionIter> outputSections() { return _outputSections; }
-
- range<ChunkIter> sections() { return _sections; }
-
- range<SegmentIter> segments() { return _segments; }
-
- ELFHeader<ELFT> *getHeader() { return _elfHeader; }
-
- bool hasDynamicRelocationTable() const { return !!_dynamicRelocationTable; }
-
- bool hasPLTRelocationTable() const { return !!_pltRelocationTable; }
-
- /// \brief Get or create the dynamic relocation table. All relocations in this
- /// table are processed at startup.
- RelocationTable<ELFT> *getDynamicRelocationTable();
-
- /// \brief Get or create the PLT relocation table. Referenced by DT_JMPREL.
- RelocationTable<ELFT> *getPLTRelocationTable();
-
- uint64_t getTLSSize() const;
-
- bool isReferencedByDefinedAtom(const Atom *a) const {
- return _referencedDynAtoms.count(a);
- }
-
- bool isCopied(const SharedLibraryAtom *sla) const {
- return _copiedDynSymNames.count(sla->name());
- }
-
-protected:
- /// \brief TargetLayouts may use these functions to reorder the input sections
- /// in a order defined by their ABI.
- virtual void finalizeOutputSectionLayout() {}
-
- /// \brief Allocate a new section.
- virtual AtomSection<ELFT> *createSection(
- StringRef name, int32_t contentType,
- DefinedAtom::ContentPermissions contentPermissions,
- SectionOrder sectionOrder);
-
- /// \brief Create a new relocation table.
- virtual unique_bump_ptr<RelocationTable<ELFT>>
- createRelocationTable(StringRef name, int32_t order) {
- return unique_bump_ptr<RelocationTable<ELFT>>(
- new (_allocator) RelocationTable<ELFT>(_ctx, name, order));
- }
-
- virtual uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const;
-
- /// \brief Sort segements stored in the _segments
- virtual void sortSegments();
-
-protected:
- llvm::BumpPtrAllocator _allocator;
- SectionMapT _sectionMap;
- OutputSectionMapT _outputSectionMap;
- SegmentMapT _segmentMap;
- std::vector<Chunk<ELFT> *> _sections;
- std::vector<Segment<ELFT> *> _segments;
- std::vector<OutputSection<ELFT> *> _outputSections;
- ELFHeader<ELFT> *_elfHeader;
- ProgramHeader<ELFT> *_programHeader;
- unique_bump_ptr<RelocationTable<ELFT>> _dynamicRelocationTable;
- unique_bump_ptr<RelocationTable<ELFT>> _pltRelocationTable;
- std::vector<AtomLayout *> _absoluteAtoms;
- AtomSetT _referencedDynAtoms;
- llvm::StringSet<> _copiedDynSymNames;
- ELFLinkingContext &_ctx;
- script::Sema &_linkerScriptSema;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (removed)
@@ -1,23 +0,0 @@
-//===- lib/ReaderWriter/ELF/WriterELF.cpp ---------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/Writer.h"
-#include "DynamicLibraryWriter.h"
-#include "ExecutableWriter.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-namespace lld {
-
-std::unique_ptr<Writer> createWriterELF(const ELFLinkingContext &ctx) {
- return ctx.getTargetHandler().getWriter();
-}
-
-} // namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.h (removed)
@@ -1,35 +0,0 @@
-//===- lib/ReaderWriter/ELF/Writer.h --------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_WRITER_H
-#define LLD_READER_WRITER_ELF_WRITER_H
-
-#include "lld/Core/File.h"
-#include "lld/Core/Writer.h"
-
-namespace lld {
-namespace elf {
-/// \brief The Writer class is a base class for the linker to write
-/// various kinds of ELF files.
-class ELFWriter : public Writer {
-public:
- /// \brief builds the chunks that needs to be written to the output
- /// ELF file
- virtual void buildChunks(const File &file) = 0;
-
- /// \brief Writes the chunks into the output file specified by path
- std::error_code writeFile(const File &file, StringRef path) override = 0;
-
- /// \brief Get the virtual address of \p atom after layout.
- virtual uint64_t addressOfAtom(const Atom *atom) = 0;
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_ELF_WRITER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/CMakeLists.txt (removed)
@@ -1,11 +0,0 @@
-add_lld_library(lldX86ELFTarget
- X86LinkingContext.cpp
- X86TargetHandler.cpp
- X86RelocationHandler.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h (removed)
@@ -1,44 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h -----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef X86_X86_DYNAMIC_LIBRARY_WRITER_H
-#define X86_X86_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "X86LinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class X86DynamicLibraryWriter : public DynamicLibraryWriter<ELF32LE> {
-public:
- X86DynamicLibraryWriter(X86LinkingContext &ctx,
- TargetLayout<ELF32LE> &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-};
-
-X86DynamicLibraryWriter::X86DynamicLibraryWriter(X86LinkingContext &ctx,
- TargetLayout<ELF32LE> &layout)
- : DynamicLibraryWriter(ctx, layout) {}
-
-void X86DynamicLibraryWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter::createImplicitFiles(result);
- auto gotFile = llvm::make_unique<SimpleFile>("GOTFile", File::kindELFObject);
- gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile));
- gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile));
- result.push_back(std::move(gotFile));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h (removed)
@@ -1,39 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86ExecutableWriter.h ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef X86_X86_EXECUTABLE_WRITER_H
-#define X86_X86_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "X86LinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class X86ExecutableWriter : public ExecutableWriter<ELF32LE> {
-public:
- X86ExecutableWriter(X86LinkingContext &ctx, TargetLayout<ELF32LE> &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-};
-
-X86ExecutableWriter::X86ExecutableWriter(X86LinkingContext &ctx,
- TargetLayout<ELF32LE> &layout)
- : ExecutableWriter(ctx, layout) {}
-
-void X86ExecutableWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter::createImplicitFiles(result);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp (removed)
@@ -1,39 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp ---------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86LinkingContext.h"
-#include "X86TargetHandler.h"
-#include "lld/Core/LLVM.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/ErrorOr.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<ELFLinkingContext>
-elf::createX86LinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::x86)
- return llvm::make_unique<X86LinkingContext>(triple);
- return nullptr;
-}
-
-X86LinkingContext::X86LinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, llvm::make_unique<X86TargetHandler>(*this)) {}
-
-static const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/i386.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_END
-};
-
-void X86LinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF, Reference::KindArch::x86,
- kindStrings);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h (removed)
@@ -1,44 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86LinkingContext.h -----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_TARGETINFO_H
-#define LLD_READER_WRITER_ELF_X86_TARGETINFO_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-class X86LinkingContext final : public ELFLinkingContext {
-public:
- static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
- int getMachineType() const override { return llvm::ELF::EM_386; }
- X86LinkingContext(llvm::Triple);
- void registerRelocationNames(Registry &r) override;
-
- /// \brief X86 has only two relative relocation
- /// a) for supporting IFUNC relocs - R_386_IRELATIVE
- /// b) for supporting relative relocs - R_386_RELATIVE
- bool isRelativeReloc(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::x86);
- switch (r.kindValue()) {
- case llvm::ELF::R_386_IRELATIVE:
- case llvm::ELF::R_386_RELATIVE:
- return true;
- default:
- return false;
- }
- }
-};
-} // end namespace elf
-} // end namespace lld
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp (removed)
@@ -1,54 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86LinkingContext.h"
-#include "X86TargetHandler.h"
-#include "llvm/Support/Endian.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::support::endian;
-
-/// \brief R_386_32 - word32: S + A
-static int reloc32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
- int32_t result = (uint32_t)(S + A);
- write32le(location, result | read32le(location));
- return 0;
-}
-
-/// \brief R_386_PC32 - word32: S + A - P
-static int relocPC32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
- write32le(location, result + read32le(location));
- return 0;
-}
-
-std::error_code X86TargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::x86);
- switch (ref.kindValue()) {
- case R_386_32:
- reloc32(loc, reloc, target, ref.addend());
- break;
- case R_386_PC32:
- relocPC32(loc, reloc, target, ref.addend());
- break;
- default:
- return make_unhandled_reloc_error();
- }
- return std::error_code();
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86RelocationHandler.h (removed)
@@ -1,28 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86RelocationHandler.h --------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef X86_X86_RELOCATION_HANDLER_H
-#define X86_X86_RELOCATION_HANDLER_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class X86TargetRelocationHandler final : public TargetRelocationHandler {
-public:
- std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const AtomLayout &,
- const Reference &) const override;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // X86_X86_RELOCATION_HANDLER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp (removed)
@@ -1,36 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp ----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86TargetHandler.h"
-#include "X86DynamicLibraryWriter.h"
-#include "X86ExecutableWriter.h"
-#include "X86LinkingContext.h"
-#include "X86RelocationHandler.h"
-
-using namespace lld;
-using namespace elf;
-
-using namespace llvm::ELF;
-
-std::unique_ptr<Writer> X86TargetHandler::getWriter() {
- switch (_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<X86ExecutableWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<X86DynamicLibraryWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
-
-X86TargetHandler::X86TargetHandler(X86LinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new TargetLayout<ELF32LE>(ctx)),
- _relocationHandler(new X86TargetRelocationHandler()) {}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h (removed)
@@ -1,48 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86TargetHandler.h ------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_X86_TARGET_HANDLER_H
-
-#include "TargetLayout.h"
-#include "ELFReader.h"
-#include "X86RelocationHandler.h"
-
-namespace lld {
-namespace elf {
-
-class X86LinkingContext;
-
-class X86TargetHandler final : public TargetHandler {
-public:
- X86TargetHandler(X86LinkingContext &ctx);
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<ELFFile<ELF32LE>>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELF32LE>>>(_ctx);
- }
-
- std::unique_ptr<Writer> getWriter() override;
-
-protected:
- X86LinkingContext &_ctx;
- std::unique_ptr<TargetLayout<ELF32LE>> _targetLayout;
- std::unique_ptr<X86TargetRelocationHandler> _relocationHandler;
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt (removed)
@@ -1,17 +0,0 @@
-add_lld_library(lldX86_64ELFTarget
- X86_64LinkingContext.cpp
- X86_64TargetHandler.cpp
- X86_64RelocationHandler.cpp
- X86_64RelocationPass.cpp
- X86_64SectionChunks.cpp
- LINK_LIBS
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
-
-include_directories(.)
-
-add_subdirectory(ExampleSubTarget)
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt (removed)
@@ -1,11 +0,0 @@
-add_lld_library(lldExampleSubTarget
- ExampleLinkingContext.cpp
- ExampleTargetHandler.cpp
- LINK_LIBS
- lldX86_64ELFTarget
- lldELF
- lldReaderWriter
- lldCore
- LLVMObject
- LLVMSupport
- )
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp (removed)
@@ -1,35 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/ExampleTarget/ExampleLinkingContext.cpp ----===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ExampleLinkingContext.h"
-#include "ExampleTargetHandler.h"
-
-using namespace lld;
-using namespace elf;
-
-std::unique_ptr<ELFLinkingContext>
-elf::createExampleLinkingContext(llvm::Triple triple) {
- if (triple.getVendorName() == "example")
- return llvm::make_unique<ExampleLinkingContext>(triple);
- return nullptr;
-}
-
-ExampleLinkingContext::ExampleLinkingContext(llvm::Triple triple)
- : X86_64LinkingContext(triple, std::unique_ptr<TargetHandler>(
- new ExampleTargetHandler(*this))) {
- _outputELFType = llvm::ELF::ET_LOPROC;
-}
-
-StringRef ExampleLinkingContext::entrySymbolName() const {
- return "_start";
-}
-
-void ExampleLinkingContext::addPasses(PassManager &p) {
- ELFLinkingContext::addPasses(p);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.h (removed)
@@ -1,31 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/ExampleTarget/ExampleLinkingContext.h --===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_EXAMPLE_TARGET_EXAMPLE_LINKING_CONTEXT
-#define LLD_READER_WRITER_ELF_X86_64_EXAMPLE_TARGET_EXAMPLE_LINKING_CONTEXT
-
-#include "X86_64LinkingContext.h"
-#include "X86_64TargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class ExampleLinkingContext final : public X86_64LinkingContext {
-public:
- static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
- ExampleLinkingContext(llvm::Triple triple);
-
- StringRef entrySymbolName() const override;
- void addPasses(PassManager &) override;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp (removed)
@@ -1,22 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/ExampleTarget/ExampleTargetHandler.cpp -===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ExampleTargetHandler.h"
-#include "X86_64ExecutableWriter.h"
-#include "ExampleLinkingContext.h"
-
-using namespace lld;
-using namespace elf;
-
-ExampleTargetHandler::ExampleTargetHandler(ExampleLinkingContext &c)
- : X86_64TargetHandler(c), _ctx(c) {}
-
-std::unique_ptr<Writer> ExampleTargetHandler::getWriter() {
- return llvm::make_unique<X86_64ExecutableWriter>(_ctx, *_targetLayout);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h (removed)
@@ -1,31 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/ExampleTarget/ExampleTargetHandler.h ---===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_EXAMPLE_TARGET_EXAMPLE_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_X86_64_EXAMPLE_TARGET_EXAMPLE_TARGET_HANDLER_H
-
-#include "X86_64TargetHandler.h"
-
-namespace lld {
-namespace elf {
-class ExampleLinkingContext;
-
-class ExampleTargetHandler final : public X86_64TargetHandler {
-public:
- ExampleTargetHandler(ExampleLinkingContext &c);
-
- std::unique_ptr<Writer> getWriter() override;
-
-private:
- ExampleLinkingContext &_ctx;
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/TODO.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/TODO.rst?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/TODO.rst (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/TODO.rst (removed)
@@ -1,46 +0,0 @@
-ELF x86-64
-~~~~~~~~~~
-
-Unimplemented Features
-######################
-
-* Code models other than the small code model
-* TLS strength reduction
-
-Unimplemented Relocations
-#########################
-
-All of these relocations are defined in:
-http://www.x86-64.org/documentation/abi.pdf
-
-Trivial Relocs
-<<<<<<<<<<<<<<
-
-These are very simple relocation calculations to implement.
-See lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
-
-* R_X86_64_8
-* R_X86_64_PC8
-* R_X86_64_SIZE32
-* R_X86_64_SIZE64
-* R_X86_64_GOTPC32 (this relocation requires there to be a __GLOBAL_OFFSET_TABLE__)
-
-Global Offset Table Relocs
-<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-* R_X86_64_GOTOFF32
-* R_X86_64_GOTOFF64
-
-Global Dynamic Thread Local Storage Relocs
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-These relocations take more effort to implement, but some of them are done.
-Their implementation lives in lib/ReaderWriter/ELF/X86_64/{X86_64RelocationPass.cpp,X86_64RelocationHandler.cpp}.
-
-Documentation on these relocations can be found in:
-http://www.akkadia.org/drepper/tls.pdf
-http://www.fsfla.org/~lxoliva/writeups/TLS/RFC-TLSDESC-x86.txt
-
-* R_X86_64_GOTPC32_TLSDESC
-* R_X86_64_TLSDESC_CALL
-* R_X86_64_TLSDESC
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h (removed)
@@ -1,45 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86_64DynamicLibraryWriter.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef X86_64_DYNAMIC_LIBRARY_WRITER_H
-#define X86_64_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "X86_64LinkingContext.h"
-#include "X86_64TargetHandler.h"
-
-namespace lld {
-namespace elf {
-
-class X86_64DynamicLibraryWriter : public DynamicLibraryWriter<ELF64LE> {
-public:
- X86_64DynamicLibraryWriter(X86_64LinkingContext &ctx,
- X86_64TargetLayout &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-};
-
-X86_64DynamicLibraryWriter::X86_64DynamicLibraryWriter(
- X86_64LinkingContext &ctx, X86_64TargetLayout &layout)
- : DynamicLibraryWriter(ctx, layout) {}
-
-void X86_64DynamicLibraryWriter::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter::createImplicitFiles(result);
- auto gotFile = llvm::make_unique<SimpleFile>("GOTFile", File::kindELFObject);
- gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile));
- gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile));
- result.push_back(std::move(gotFile));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h (removed)
@@ -1,58 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86/X86_64ExecutableWriter.h ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef X86_64_EXECUTABLE_WRITER_H
-#define X86_64_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "X86_64LinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-class X86_64ExecutableWriter : public ExecutableWriter<ELF64LE> {
-public:
- X86_64ExecutableWriter(X86_64LinkingContext &ctx, X86_64TargetLayout &layout)
- : ExecutableWriter(ctx, layout), _targetLayout(layout) {}
-
-protected:
- // Add any runtime files and their atoms to the output
- void
- createImplicitFiles(std::vector<std::unique_ptr<File>> &result) override {
- ExecutableWriter::createImplicitFiles(result);
- auto gotFile = llvm::make_unique<SimpleFile>("GOTFile",
- File::kindELFObject);
- gotFile->addAtom(*new (gotFile->allocator())
- GlobalOffsetTableAtom(*gotFile));
- if (this->_ctx.isDynamic())
- gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile));
- result.push_back(std::move(gotFile));
- }
-
- void buildDynamicSymbolTable(const File &file) override {
- for (auto sec : this->_layout.sections()) {
- if (auto section = dyn_cast<AtomSection<ELF64LE>>(sec)) {
- for (const auto &atom : section->atoms()) {
- if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) {
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
- }
- }
- }
-
- ExecutableWriter<ELF64LE>::buildDynamicSymbolTable(file);
- }
-
- X86_64TargetLayout &_targetLayout;
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp (removed)
@@ -1,50 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86_64LinkingContext.h"
-#include "X86_64RelocationPass.h"
-#include "X86_64TargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-X86_64LinkingContext::X86_64LinkingContext(
- llvm::Triple triple, std::unique_ptr<TargetHandler> handler)
- : ELFLinkingContext(triple, std::move(handler)) {}
-
-X86_64LinkingContext::X86_64LinkingContext(llvm::Triple triple)
- : X86_64LinkingContext(triple,
- llvm::make_unique<X86_64TargetHandler>(*this)) {}
-
-void X86_64LinkingContext::addPasses(PassManager &pm) {
- auto pass = createX86_64RelocationPass(*this);
- if (pass)
- pm.add(std::move(pass));
- ELFLinkingContext::addPasses(pm);
-}
-
-std::unique_ptr<ELFLinkingContext>
-elf::createX86_64LinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::x86_64)
- return llvm::make_unique<X86_64LinkingContext>(triple);
- return nullptr;
-}
-
-static const Registry::KindStrings kindStrings[] = {
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-#include "llvm/Support/ELFRelocs/x86_64.def"
-#undef ELF_RELOC
- LLD_KIND_STRING_ENTRY(LLD_R_X86_64_GOTRELINDEX),
- LLD_KIND_STRING_END
-};
-
-void X86_64LinkingContext::registerRelocationNames(Registry ®istry) {
- registry.addKindTable(Reference::KindNamespace::ELF,
- Reference::KindArch::x86_64, kindStrings);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h (removed)
@@ -1,103 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h -----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_LINKING_CONTEXT_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_LINKING_CONTEXT_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
-
-namespace lld {
-namespace elf {
-
-/// \brief x86-64 internal references.
-enum {
- /// \brief The 32 bit index of the relocation in the got this reference refers
- /// to.
- LLD_R_X86_64_GOTRELINDEX = 1024,
-};
-
-class X86_64LinkingContext : public ELFLinkingContext {
-protected:
- X86_64LinkingContext(llvm::Triple, std::unique_ptr<TargetHandler>);
-
-public:
- static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
- int getMachineType() const override { return llvm::ELF::EM_X86_64; }
- X86_64LinkingContext(llvm::Triple);
-
- void addPasses(PassManager &) override;
- void registerRelocationNames(Registry &r) override;
-
- uint64_t getBaseAddress() const override {
- if (_baseAddress == 0)
- return 0x400000;
- return _baseAddress;
- }
-
- bool isDynamicRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::x86_64);
- switch (r.kindValue()) {
- case llvm::ELF::R_X86_64_RELATIVE:
- case llvm::ELF::R_X86_64_GLOB_DAT:
- case llvm::ELF::R_X86_64_COPY:
- case llvm::ELF::R_X86_64_DTPMOD64:
- case llvm::ELF::R_X86_64_DTPOFF64:
- case llvm::ELF::R_X86_64_TPOFF64:
- return true;
- default:
- return false;
- }
- }
-
- bool isCopyRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::x86_64);
- if (r.kindValue() == llvm::ELF::R_X86_64_COPY)
- return true;
- return false;
- }
-
- bool isPLTRelocation(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::x86_64);
- switch (r.kindValue()) {
- case llvm::ELF::R_X86_64_JUMP_SLOT:
- case llvm::ELF::R_X86_64_IRELATIVE:
- return true;
- default:
- return false;
- }
- }
-
- /// \brief X86_64 has two relative relocations
- /// a) for supporting IFUNC - R_X86_64_IRELATIVE
- /// b) for supporting relative relocs - R_X86_64_RELATIVE
- bool isRelativeReloc(const Reference &r) const override {
- if (r.kindNamespace() != Reference::KindNamespace::ELF)
- return false;
- assert(r.kindArch() == Reference::KindArch::x86_64);
- switch (r.kindValue()) {
- case llvm::ELF::R_X86_64_IRELATIVE:
- case llvm::ELF::R_X86_64_RELATIVE:
- return true;
- default:
- return false;
- }
- }
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp (removed)
@@ -1,147 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp ------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86_64LinkingContext.h"
-#include "X86_64TargetHandler.h"
-#include "llvm/Support/Endian.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::support::endian;
-
-/// \brief R_X86_64_64 - word64: S + A
-static void reloc64(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint64_t result = S + A;
- write64le(location, result | read64le(location));
-}
-
-/// \brief R_X86_64_PC32 - word32: S + A - P
-static void relocPC32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)(S + A - P);
- write32le(location, result + read32le(location));
-}
-
-/// \brief R_X86_64_32 - word32: S + A
-static void reloc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- int32_t result = (uint32_t)(S + A);
- write32le(location, result | read32le(location));
- // TODO: Make sure that the result zero extends to the 64bit value.
-}
-
-/// \brief R_X86_64_32S - word32: S + A
-static void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- int32_t result = (int32_t)(S + A);
- write32le(location, result | read32le(location));
- // TODO: Make sure that the result sign extends to the 64bit value.
-}
-
-/// \brief R_X86_64_16 - word16: S + A
-static void reloc16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint16_t result = (uint16_t)(S + A);
- write16le(location, result | read16le(location));
- // TODO: Check for overflow.
-}
-
-/// \brief R_X86_64_PC16 - word16: S + A - P
-static void relocPC16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint16_t result = (uint16_t)(S + A - P);
- write16le(location, result | read16le(location));
- // TODO: Check for overflow.
-}
-
-/// \brief R_X86_64_PC64 - word64: S + A - P
-static void relocPC64(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
- int64_t result = (uint64_t)(S + A - P);
- write64le(location, result | read64le(location));
-}
-
-std::error_code X86_64TargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
- const Reference &ref) const {
- uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *loc = atomContent + ref.offsetInAtom();
- uint64_t target = writer.addressOfAtom(ref.target());
- uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
-
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return std::error_code();
- assert(ref.kindArch() == Reference::KindArch::x86_64);
- switch (ref.kindValue()) {
- case R_X86_64_NONE:
- break;
- case R_X86_64_64:
- reloc64(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_PC32:
- case R_X86_64_GOTPCREL:
- relocPC32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_32:
- reloc32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_32S:
- reloc32S(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_16:
- reloc16(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_PC16:
- relocPC16(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_DTPOFF32:
- case R_X86_64_TPOFF32:
- _tlsSize = _layout.getTLSSize();
- write32le(loc, target - _tlsSize);
- break;
- case R_X86_64_GOTTPOFF:
- relocPC32(loc, reloc, target, ref.addend());
- break;
- case R_X86_64_TLSGD: {
- relocPC32(loc, reloc, target, ref.addend());
- break;
- }
- case R_X86_64_TLSLD: {
- // Rewrite to move %fs:0 into %rax. Technically we should verify that the
- // next relocation is a PC32 to __tls_get_addr...
- static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25,
- 0x00, 0x00, 0x00, 0x00 };
- std::memcpy(loc - 3, instr, sizeof(instr));
- break;
- }
- case R_X86_64_PC64:
- relocPC64(loc, reloc, target, ref.addend());
- break;
- case LLD_R_X86_64_GOTRELINDEX: {
- const DefinedAtom *target = cast<const DefinedAtom>(ref.target());
- for (const Reference *r : *target) {
- if (r->kindValue() == R_X86_64_JUMP_SLOT) {
- uint32_t index;
- if (!_layout.getPLTRelocationTable()->getRelocationIndex(*r, index))
- llvm_unreachable("Relocation doesn't exist");
- reloc32(loc, 0, index, 0);
- break;
- }
- }
- break;
- }
- // Runtime only relocations. Ignore here.
- case R_X86_64_RELATIVE:
- case R_X86_64_IRELATIVE:
- case R_X86_64_JUMP_SLOT:
- case R_X86_64_GLOB_DAT:
- case R_X86_64_DTPMOD64:
- case R_X86_64_DTPOFF64:
- case R_X86_64_TPOFF64:
- break;
- default:
- return make_unhandled_reloc_error();
- }
-
- return std::error_code();
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h (removed)
@@ -1,37 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef X86_64_RELOCATION_HANDLER_H
-#define X86_64_RELOCATION_HANDLER_H
-
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-
-namespace lld {
-namespace elf {
-class X86_64TargetLayout;
-
-class X86_64TargetRelocationHandler final : public TargetRelocationHandler {
-public:
- X86_64TargetRelocationHandler(X86_64TargetLayout &layout)
- : _tlsSize(0), _layout(layout) {}
-
- std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const AtomLayout &,
- const Reference &) const override;
-
-private:
- // Cached size of the TLS segment.
- mutable uint64_t _tlsSize;
- X86_64TargetLayout &_layout;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif // X86_64_RELOCATION_HANDLER_H
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp (removed)
@@ -1,514 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the relocation processing pass for x86-64. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-/// This is based on section 4.4.1 of the AMD64 ABI (no stable URL as of Oct,
-/// 2013).
-///
-/// This also includes aditional behaivor that gnu-ld and gold implement but
-/// which is not specified anywhere.
-///
-//===----------------------------------------------------------------------===//
-
-#include "X86_64RelocationPass.h"
-#include "Atoms.h"
-#include "X86_64LinkingContext.h"
-#include "lld/Core/Simple.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lld;
-using namespace lld::elf;
-using namespace llvm::ELF;
-
-// .got values
-static const uint8_t x86_64GotAtomContent[8] = {0};
-
-// .plt value (entry 0)
-static const uint8_t x86_64Plt0AtomContent[16] = {
- 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
- 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
- 0x90, 0x90, 0x90, 0x90 // nopnopnop
-};
-
-// .plt values (other entries)
-static const uint8_t x86_64PltAtomContent[16] = {
- 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *gotatom(%rip)
- 0x68, 0x00, 0x00, 0x00, 0x00, // pushq reloc-index
- 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[-1]
-};
-
-// TLS GD Entry
-static const uint8_t x86_64GotTlsGdAtomContent[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-namespace {
-/// \brief Atoms that are used by X86_64 dynamic linking
-class X86_64GOTAtom : public GOTAtom {
-public:
- X86_64GOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(x86_64GotAtomContent, 8);
- }
-};
-
-/// \brief X86_64 GOT TLS GD entry.
-class GOTTLSGdAtom : public X86_64GOTAtom {
-public:
- GOTTLSGdAtom(const File &f, StringRef secName) : X86_64GOTAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(x86_64GotTlsGdAtomContent);
- }
-};
-
-class X86_64PLT0Atom : public PLT0Atom {
-public:
- X86_64PLT0Atom(const File &f) : PLT0Atom(f) {}
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(x86_64Plt0AtomContent, 16);
- }
-};
-
-class X86_64PLTAtom : public PLTAtom {
-public:
- X86_64PLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {}
-
- ArrayRef<uint8_t> rawContent() const override {
- return ArrayRef<uint8_t>(x86_64PltAtomContent, 16);
- }
-};
-
-class ELFPassFile : public SimpleFile {
-public:
- ELFPassFile(const ELFLinkingContext &eti)
- : SimpleFile("ELFPassFile", kindELFObject) {
- setOrdinal(eti.getNextOrdinalAndIncrement());
- }
-
- llvm::BumpPtrAllocator _alloc;
-};
-
-/// \brief CRTP base for handling relocations.
-template <class Derived> class RelocationPass : public Pass {
- /// \brief Handle a specific reference.
- void handleReference(const DefinedAtom &atom, const Reference &ref) {
- if (ref.kindNamespace() != Reference::KindNamespace::ELF)
- return;
- assert(ref.kindArch() == Reference::KindArch::x86_64);
- switch (ref.kindValue()) {
- case R_X86_64_16:
- case R_X86_64_32:
- case R_X86_64_32S:
- case R_X86_64_64:
- case R_X86_64_PC16:
- case R_X86_64_PC32:
- case R_X86_64_PC64:
- static_cast<Derived *>(this)->handlePlain(ref);
- break;
- case R_X86_64_PLT32:
- static_cast<Derived *>(this)->handlePLT32(ref);
- break;
- case R_X86_64_GOT32:
- case R_X86_64_GOTPC32:
- case R_X86_64_GOTPCREL:
- case R_X86_64_GOTOFF64:
- static_cast<Derived *>(this)->handleGOT(ref);
- break;
- case R_X86_64_GOTTPOFF: // GOT Thread Pointer Offset
- static_cast<Derived *>(this)->handleGOTTPOFF(ref);
- break;
- case R_X86_64_TLSGD:
- static_cast<Derived *>(this)->handleTLSGd(ref);
- break;
- }
- }
-
-protected:
- /// \brief get the PLT entry for a given IFUNC Atom.
- ///
- /// If the entry does not exist. Both the GOT and PLT entry is created.
- const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da) {
- auto plt = _pltMap.find(da);
- if (plt != _pltMap.end())
- return plt->second;
- auto ga = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
- ga->addReferenceELF_x86_64(R_X86_64_IRELATIVE, 0, da, 0);
- auto pa = new (_file._alloc) X86_64PLTAtom(_file, ".plt");
- pa->addReferenceELF_x86_64(R_X86_64_PC32, 2, ga, -4);
-#ifndef NDEBUG
- ga->_name = "__got_ifunc_";
- ga->_name += da->name();
- pa->_name = "__plt_ifunc_";
- pa->_name += da->name();
-#endif
- _gotMap[da] = ga;
- _pltMap[da] = pa;
- _gotVector.push_back(ga);
- _pltVector.push_back(pa);
- return pa;
- }
-
- /// \brief Redirect the call to the PLT stub for the target IFUNC.
- ///
- /// This create a PLT and GOT entry for the IFUNC if one does not exist. The
- /// GOT entry and a IRELATIVE relocation to the original target resolver.
- std::error_code handleIFUNC(const Reference &ref) {
- auto target = dyn_cast_or_null<const DefinedAtom>(ref.target());
- if (target && target->contentType() == DefinedAtom::typeResolver)
- const_cast<Reference &>(ref).setTarget(getIFUNCPLTEntry(target));
- return std::error_code();
- }
-
- /// \brief Create a GOT entry for the TP offset of a TLS atom.
- const GOTAtom *getGOTTPOFF(const Atom *atom) {
- auto got = _gotMap.find(atom);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got");
- g->addReferenceELF_x86_64(R_X86_64_TPOFF64, 0, atom, 0);
-#ifndef NDEBUG
- g->_name = "__got_tls_";
- g->_name += atom->name();
-#endif
- _gotMap[atom] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
- /// \brief Create a TPOFF64 GOT entry.
- std::error_code handleGOTTPOFF(const Reference &ref) {
- if (isa<DefinedAtom>(ref.target())) {
- const_cast<Reference &>(ref).setTarget(getGOTTPOFF(ref.target()));
- }
- return std::error_code();
- }
-
- /// \brief Create a TLS GOT entry with DTPMOD64/DTPOFF64 dynamic relocations.
- void handleTLSGd(const Reference &ref) {
- const_cast<Reference &>(ref).setTarget(getTLSGdGOTEntry(ref.target()));
- }
-
- /// \brief Create a GOT entry containing 0.
- const GOTAtom *getNullGOT() {
- if (!_null) {
- _null = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
-#ifndef NDEBUG
- _null->_name = "__got_null";
-#endif
- }
- return _null;
- }
-
- const GOTAtom *getGOT(const DefinedAtom *da) {
- auto got = _gotMap.find(da);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got");
- g->addReferenceELF_x86_64(R_X86_64_64, 0, da, 0);
-#ifndef NDEBUG
- g->_name = "__got_";
- g->_name += da->name();
-#endif
- _gotMap[da] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
- const GOTAtom *getTLSGdGOTEntry(const Atom *a) {
- auto got = _gotTLSGdMap.find(a);
- if (got != _gotTLSGdMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOTTLSGdAtom(_file, ".got");
- _gotTLSGdMap[a] = ga;
-
- _tlsGotVector.push_back(ga);
- ga->addReferenceELF_x86_64(R_X86_64_DTPMOD64, 0, a, 0);
- ga->addReferenceELF_x86_64(R_X86_64_DTPOFF64, 8, a, 0);
-
- return ga;
- }
-
-public:
- RelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {}
-
- /// \brief Do the pass.
- ///
- /// The goal here is to first process each reference individually. Each call
- /// to handleReference may modify the reference itself and/or create new
- /// atoms which must be stored in one of the maps below.
- ///
- /// After all references are handled, the atoms created during that are all
- /// added to mf.
- std::error_code perform(SimpleFile &mf) override {
- ScopedTask task(getDefaultDomain(), "X86-64 GOT/PLT Pass");
- // Process all references.
- for (const auto &atom : mf.defined())
- for (const auto &ref : *atom)
- handleReference(*atom, *ref);
-
- // Add all created atoms to the link.
- uint64_t ordinal = 0;
- if (_plt0) {
- _plt0->setOrdinal(ordinal++);
- mf.addAtom(*_plt0);
- }
- for (auto &plt : _pltVector) {
- plt->setOrdinal(ordinal++);
- mf.addAtom(*plt);
- }
- if (_null) {
- _null->setOrdinal(ordinal++);
- mf.addAtom(*_null);
- }
- if (_plt0) {
- _got0->setOrdinal(ordinal++);
- _got1->setOrdinal(ordinal++);
- mf.addAtom(*_got0);
- mf.addAtom(*_got1);
- }
- for (auto &got : _gotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
- for (auto &got : _tlsGotVector) {
- got->setOrdinal(ordinal++);
- mf.addAtom(*got);
- }
- for (auto obj : _objectVector) {
- obj->setOrdinal(ordinal++);
- mf.addAtom(*obj);
- }
- return std::error_code();
- }
-
-protected:
- /// \brief Owner of all the Atoms created by this pass.
- ELFPassFile _file;
- const ELFLinkingContext &_ctx;
-
- /// \brief Map Atoms to their GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
-
- /// \brief Map Atoms to their PLT entries.
- llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
-
- /// \brief Map Atoms to TLS GD GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;
-
- /// \brief Map Atoms to their Object entries.
- llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
-
- /// \brief the list of GOT/PLT atoms
- std::vector<GOTAtom *> _gotVector;
- std::vector<PLTAtom *> _pltVector;
- std::vector<ObjectAtom *> _objectVector;
-
- /// \brief the list of TLS GOT atoms.
- std::vector<GOTAtom *> _tlsGotVector;
-
- /// \brief GOT entry that is always 0. Used for undefined weaks.
- GOTAtom *_null = nullptr;
-
- /// \brief The got and plt entries for .PLT0. This is used to call into the
- /// dynamic linker for symbol resolution.
- /// @{
- PLT0Atom *_plt0 = nullptr;
- GOTAtom *_got0 = nullptr;
- GOTAtom *_got1 = nullptr;
- /// @}
-};
-
-/// This implements the static relocation model. Meaning GOT and PLT entries are
-/// not created for references that can be directly resolved. These are
-/// converted to a direct relocation. For entries that do require a GOT or PLT
-/// entry, that entry is statically bound.
-///
-/// TLS always assumes module 1 and attempts to remove indirection.
-class StaticRelocationPass final
- : public RelocationPass<StaticRelocationPass> {
-public:
- StaticRelocationPass(const elf::X86_64LinkingContext &ctx)
- : RelocationPass(ctx) {}
-
- std::error_code handlePlain(const Reference &ref) { return handleIFUNC(ref); }
-
- std::error_code handlePLT32(const Reference &ref) {
- // __tls_get_addr is handled elsewhere.
- if (ref.target() && ref.target()->name() == "__tls_get_addr") {
- const_cast<Reference &>(ref).setKindValue(R_X86_64_NONE);
- return std::error_code();
- }
- // Static code doesn't need PLTs.
- const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
- // Handle IFUNC.
- if (const DefinedAtom *da =
- dyn_cast_or_null<const DefinedAtom>(ref.target()))
- if (da->contentType() == DefinedAtom::typeResolver)
- return handleIFUNC(ref);
- return std::error_code();
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getNullGOT());
- else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOT(da));
- return std::error_code();
- }
-};
-
-class DynamicRelocationPass final
- : public RelocationPass<DynamicRelocationPass> {
-public:
- DynamicRelocationPass(const elf::X86_64LinkingContext &ctx)
- : RelocationPass(ctx) {}
-
- const PLT0Atom *getPLT0() {
- if (_plt0)
- return _plt0;
- // Fill in the null entry.
- getNullGOT();
- _plt0 = new (_file._alloc) X86_64PLT0Atom(_file);
- _got0 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
- _got1 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
- _plt0->addReferenceELF_x86_64(R_X86_64_PC32, 2, _got0, -4);
- _plt0->addReferenceELF_x86_64(R_X86_64_PC32, 8, _got1, -4);
-#ifndef NDEBUG
- _got0->_name = "__got0";
- _got1->_name = "__got1";
-#endif
- return _plt0;
- }
-
- const PLTAtom *getPLTEntry(const Atom *a) {
- auto plt = _pltMap.find(a);
- if (plt != _pltMap.end())
- return plt->second;
- auto ga = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
- ga->addReferenceELF_x86_64(R_X86_64_JUMP_SLOT, 0, a, 0);
- auto pa = new (_file._alloc) X86_64PLTAtom(_file, ".plt");
- pa->addReferenceELF_x86_64(R_X86_64_PC32, 2, ga, -4);
- pa->addReferenceELF_x86_64(LLD_R_X86_64_GOTRELINDEX, 7, ga, 0);
- pa->addReferenceELF_x86_64(R_X86_64_PC32, 12, getPLT0(), -4);
- // Set the starting address of the got entry to the second instruction in
- // the plt entry.
- ga->addReferenceELF_x86_64(R_X86_64_64, 0, pa, 6);
-#ifndef NDEBUG
- ga->_name = "__got_";
- ga->_name += a->name();
- pa->_name = "__plt_";
- pa->_name += a->name();
-#endif
- _gotMap[a] = ga;
- _pltMap[a] = pa;
- _gotVector.push_back(ga);
- _pltVector.push_back(pa);
- return pa;
- }
-
- const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
- auto obj = _objectMap.find(a);
- if (obj != _objectMap.end())
- return obj->second;
-
- auto oa = new (_file._alloc) ObjectAtom(_file);
- // This needs to point to the atom that we just created.
- oa->addReferenceELF_x86_64(R_X86_64_COPY, 0, oa, 0);
-
- oa->_name = a->name();
- oa->_size = a->size();
-
- _objectMap[a] = oa;
- _objectVector.push_back(oa);
- return oa;
- }
-
- std::error_code handlePlain(const Reference &ref) {
- if (!ref.target())
- return std::error_code();
- if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
- if (sla->type() == SharedLibraryAtom::Type::Data)
- const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
- else if (sla->type() == SharedLibraryAtom::Type::Code)
- const_cast<Reference &>(ref).setTarget(getPLTEntry(sla));
- } else
- return handleIFUNC(ref);
- return std::error_code();
- }
-
- std::error_code handlePLT32(const Reference &ref) {
- // Turn this into a PC32 to the PLT entry.
- const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
- // Handle IFUNC.
- if (const DefinedAtom *da =
- dyn_cast_or_null<const DefinedAtom>(ref.target()))
- if (da->contentType() == DefinedAtom::typeResolver)
- return handleIFUNC(ref);
- // If it is undefined at link time, push the work to the dynamic linker by
- // creating a PLT entry
- if (isa<SharedLibraryAtom>(ref.target()) ||
- isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
- return std::error_code();
- }
-
- const GOTAtom *getSharedGOT(const Atom *a) {
- auto got = _gotMap.find(a);
- if (got == _gotMap.end()) {
- auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got");
- g->addReferenceELF_x86_64(R_X86_64_GLOB_DAT, 0, a, 0);
-#ifndef NDEBUG
- g->_name = "__got_";
- g->_name += a->name();
-#endif
- _gotMap[a] = g;
- _gotVector.push_back(g);
- return g;
- }
- return got->second;
- }
-
- std::error_code handleGOT(const Reference &ref) {
- if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getGOT(da));
- // Handle undefined atoms in the same way as shared lib atoms: to be
- // resolved at run time.
- else if (isa<SharedLibraryAtom>(ref.target()) ||
- isa<UndefinedAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getSharedGOT(ref.target()));
- return std::error_code();
- }
-};
-} // end anon namespace
-
-std::unique_ptr<Pass>
-lld::elf::createX86_64RelocationPass(const X86_64LinkingContext &ctx) {
- switch (ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- if (ctx.isDynamic())
- return llvm::make_unique<DynamicRelocationPass>(ctx);
- return llvm::make_unique<StaticRelocationPass>(ctx);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<DynamicRelocationPass>(ctx);
- case llvm::ELF::ET_REL:
- return nullptr;
- default:
- llvm_unreachable("Unhandled output file type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h (removed)
@@ -1,32 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h -----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Declares the relocation processing pass for x86-64. This includes
-/// GOT and PLT entries, TLS, COPY, and ifunc.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_PASS_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_PASS_H
-
-#include <memory>
-
-namespace lld {
-class Pass;
-namespace elf {
-class X86_64LinkingContext;
-
-/// \brief Create x86-64 relocation pass for the given linking context.
-std::unique_ptr<Pass>
-createX86_64RelocationPass(const X86_64LinkingContext &);
-}
-}
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp (removed)
@@ -1,37 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp --------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86_64SectionChunks.h"
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-X86_64GOTSection::X86_64GOTSection(const ELFLinkingContext &ctx)
- : AtomSection<ELF64LE>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
- TargetLayout<ELF64LE>::ORDER_GOT) {
- this->_alignment = 8;
-}
-
-const AtomLayout *X86_64GOTSection::appendAtom(const Atom *atom) {
- const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::x86_64);
- if (r->kindValue() == R_X86_64_TPOFF64)
- _tlsMap[r->target()] = _tlsMap.size();
- }
-
- return AtomSection<ELF64LE>::appendAtom(atom);
-}
-
-} // elf
-} // lld
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h (removed)
@@ -1,36 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_SECTION_CHUNKS_H
-
-#include "TargetLayout.h"
-
-namespace lld {
-namespace elf {
-
-class X86_64GOTSection : public AtomSection<ELF64LE> {
-public:
- X86_64GOTSection(const ELFLinkingContext &ctx);
-
- bool hasGlobalGOTEntry(const Atom *a) const {
- return _tlsMap.count(a);
- }
-
- const AtomLayout *appendAtom(const Atom *atom) override;
-
-private:
- /// \brief Map TLS Atoms to their GOT entry index.
- llvm::DenseMap<const Atom *, std::size_t> _tlsMap;
-};
-
-} // elf
-} // lld
-
-#endif
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (removed)
@@ -1,34 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Atoms.h"
-#include "X86_64DynamicLibraryWriter.h"
-#include "X86_64ExecutableWriter.h"
-#include "X86_64LinkingContext.h"
-#include "X86_64TargetHandler.h"
-
-using namespace lld;
-using namespace elf;
-
-X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new X86_64TargetLayout(ctx)),
- _relocationHandler(new X86_64TargetRelocationHandler(*_targetLayout)) {}
-
-std::unique_ptr<Writer> X86_64TargetHandler::getWriter() {
- switch (this->_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<X86_64ExecutableWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<X86_64DynamicLibraryWriter>(_ctx, *_targetLayout);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=262157&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (removed)
@@ -1,104 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h ------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_TARGET_HANDLER_H
-
-#include "ELFReader.h"
-#include "TargetLayout.h"
-#include "X86_64LinkingContext.h"
-#include "X86_64RelocationHandler.h"
-#include "X86_64SectionChunks.h"
-#include "lld/Core/Simple.h"
-
-namespace lld {
-namespace elf {
-
-
-class X86_64TargetLayout : public TargetLayout<ELF64LE> {
-public:
- X86_64TargetLayout(X86_64LinkingContext &ctx) : TargetLayout(ctx),
- _gotSection(new (this->_allocator) X86_64GOTSection(ctx)) {}
-
- AtomSection<ELF64LE> *
- createSection(StringRef name, int32_t type,
- DefinedAtom::ContentPermissions permissions,
- TargetLayout<ELF64LE>::SectionOrder order) override {
- if (type == DefinedAtom::typeGOT && name == ".got")
- return _gotSection;
- return TargetLayout<ELF64LE>::createSection(name, type, permissions, order);
- }
-
- void finalizeOutputSectionLayout() override {
- sortOutputSectionByPriority<ELF64LE>(".init_array");
- sortOutputSectionByPriority<ELF64LE>(".fini_array");
- }
-
- const X86_64GOTSection &getGOTSection() const { return *_gotSection; }
-
-private:
- uint32_t getPriority(StringRef sectionName) const {
- StringRef priority = sectionName.drop_front().rsplit('.').second;
- uint32_t prio;
- if (priority.getAsInteger(10, prio))
- return std::numeric_limits<uint32_t>::max();
- return prio;
- }
-
- template <typename T> void sortOutputSectionByPriority(StringRef prefix) {
- OutputSection<T> *section = findOutputSection(prefix);
- if (!section)
- return;
- auto sections = section->sections();
- std::sort(sections.begin(), sections.end(),
- [&](Chunk<T> *lhs, Chunk<T> *rhs) {
- Section<T> *lhsSection = dyn_cast<Section<T>>(lhs);
- Section<T> *rhsSection = dyn_cast<Section<T>>(rhs);
- if (!lhsSection || !rhsSection)
- return false;
- StringRef lhsName = lhsSection->inputSectionName();
- StringRef rhsName = rhsSection->inputSectionName();
- if (!lhsName.startswith(prefix) || !rhsName.startswith(prefix))
- return false;
- return getPriority(lhsName) < getPriority(rhsName);
- });
- }
-
-private:
- X86_64GOTSection *_gotSection;
-};
-
-class X86_64TargetHandler : public TargetHandler {
-public:
- X86_64TargetHandler(X86_64LinkingContext &ctx);
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<ELFFile<ELF64LE>>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELF64LE>>>(_ctx);
- }
-
- std::unique_ptr<Writer> getWriter() override;
-
-protected:
- X86_64LinkingContext &_ctx;
- std::unique_ptr<X86_64TargetLayout> _targetLayout;
- std::unique_ptr<X86_64TargetRelocationHandler> _relocationHandler;
-};
-
-} // end namespace elf
-} // end namespace lld
-
-#endif
Removed: lld/trunk/test/Driver/def-lib-search.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/def-lib-search.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/def-lib-search.test (original)
+++ lld/trunk/test/Driver/def-lib-search.test (removed)
@@ -1,8 +0,0 @@
-# Check that search paths explicitly provided by the -L option
-# are used in search before default paths.
-
-RUN: not lld -flavor old-gnu -target x86_64 -t -ltest \
-RUN: --sysroot=%p/Inputs -L%p/Inputs 2> %t
-RUN: FileCheck %s < %t
-
-CHECK: {{[^ ]+}}{{[\\/]}}Inputs{{[\\/]}}libtest.a
Removed: lld/trunk/test/Driver/flavor-option.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/flavor-option.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/flavor-option.test (original)
+++ lld/trunk/test/Driver/flavor-option.test (removed)
@@ -1,8 +0,0 @@
-# a) the -flavor option is position independent and does not need to be the 1st
-# argument in the command line (bug 20975);
-# b) UniversalDriver correctly removes -flavor along with its value and the
-# underlying linker does not get a corrupted command line (bug 20977).
-RUN: lld --help -flavor old-gnu | FileCheck %s
-
-CHECK: --noinhibit-exec
-CHECK: --output-filetype
Removed: lld/trunk/test/Driver/lib-search.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/lib-search.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/lib-search.test (original)
+++ lld/trunk/test/Driver/lib-search.test (removed)
@@ -1,24 +0,0 @@
-RUN: not lld -flavor old-gnu -t -ltest -L%p/Inputs 2> %t.err
-RUN: FileCheck %s < %t.err
-
-RUN: not lld -flavor old-gnu -target x86_64--netbsd -t -ltest \
-RUN: --sysroot=%p/Inputs 2> %t2
-RUN: FileCheck -check-prefix=NETBSD-AMD64 %s < %t2
-RUN: not lld -flavor old-gnu -target x86_64--netbsd -nostdlib -t -ltest \
-RUN: --sysroot=%p/Inputs 2> %t3
-RUN: FileCheck -check-prefix=NETBSD-AMD64-NS %s < %t3
-RUN: not lld -flavor old-gnu -target i386--netbsd -t -ltest \
-RUN: --sysroot=%p/Inputs 2> %t4
-RUN: FileCheck -check-prefix=NETBSD-I386 %s < %t4
-RUN: not lld -flavor old-gnu -target x86_64--netbsd -m elf_i386 -t -ltest \
-RUN: --sysroot=%p/Inputs 2> %t5
-RUN: FileCheck -check-prefix=NETBSD-AMD64_32 %s < %t5
-
-# run linker with -t mode to dump full paths to input files
-
-CHECK: {{[^ ]+[\\/]}}Inputs{{[\\/]}}libtest.a
-
-NETBSD-AMD64: {{[^ ]+}}{{[\\/]}}Inputs{{[\\/]}}usr{{[\\/]}}lib{{[\\/]}}libtest.a
-NETBSD-AMD64-NS-NOT: {{[^ ]+}}{{[\\/]}}Inputs{{[\\/]}}usr{{[\\/]}}lib{{[\\/]}}libtest.a
-NETBSD-I386: {{[^ ]+}}{{[\\/]}}Inputs{{[\\/]}}usr{{[\\/]}}lib{{[\\/]}}libtest.a
-NETBSD-AMD64_32: {{[^ ]+}}{{[\\/]}}Inputs{{[\\/]}}usr{{[\\/]}}lib{{[\\/]}}i386{{[\\/]}}libtest.a
Removed: lld/trunk/test/Driver/so-whole-archive.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/so-whole-archive.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/so-whole-archive.test (original)
+++ lld/trunk/test/Driver/so-whole-archive.test (removed)
@@ -1,63 +0,0 @@
-# Check that LLD does not show any error if the --whole-archive
-# is around non-archive.
-
-# RUN: yaml2obj -format=elf -docnum=1 %s > %t-so.o
-# RUN: yaml2obj -format=elf -docnum=2 %s > %t-exe.o
-# RUN: lld -flavor old-gnu -target mipsel -shared -o %t.so %t-so.o
-# RUN: lld -flavor old-gnu -target mipsel -o %t.exe %t-exe.o --whole-archive %t.so
-
-# so.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_MIPS
- Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
- EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x10
- Size: 0x04
-Symbols:
- Global:
- - Name: foo
- Type: STT_FUNC
- Section: .text
- Size: 0x04
-
-# exe.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_MIPS
- Flags: [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
- EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x10
- Size: 0x04
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x04
- Info: .text
- Relocations:
- - Offset: 0x00
- Symbol: foo
- Type: R_MIPS_26
-
-Symbols:
- Global:
- - Name: __start
- Type: STT_FUNC
- Section: .text
- Size: 0x04
- - Name: foo
-...
Removed: lld/trunk/test/Driver/trivial-driver.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/trivial-driver.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/trivial-driver.test (original)
+++ lld/trunk/test/Driver/trivial-driver.test (removed)
@@ -1,5 +0,0 @@
-# This test, tests the Gnu lld option --help
-RUN: lld -flavor old-gnu --help | FileCheck %s
-
-CHECK: --noinhibit-exec
-CHECK: --output-filetype
Removed: lld/trunk/test/Driver/undef-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/undef-basic.objtxt?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/Driver/undef-basic.objtxt (original)
+++ lld/trunk/test/Driver/undef-basic.objtxt (removed)
@@ -1,22 +0,0 @@
-# RUN: lld -flavor old-gnu -u undefinedsymbol -e entrysymbol %s \
-# RUN: --output-filetype=yaml --noinhibit-exec | FileCheck %s
-
-#
-# Test that we are able to add undefined atoms from the command line
-#
-
----
-absolute-atoms:
- - name: putchar
- value: 0xFFFF0040
-
- - name: reset
- value: 0xFFFF0080
-
-...
-
-
-# CHECK: undefined-atoms:
-# CHECK: - name: entrysymbol
-# CHECK: - name: undefinedsymbol
-# CHECK: can-be-null: at-buildtime
Removed: lld/trunk/test/old-elf/AArch64/Inputs/fn.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/fn.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/fn.c (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/fn.c (removed)
@@ -1,4 +0,0 @@
-int fn()
-{
- return 0;
-}
Removed: lld/trunk/test/old-elf/AArch64/Inputs/fn.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/fn.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/fn.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/fn.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/general-dyn-tls-0.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/general-dyn-tls-0.yaml?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/general-dyn-tls-0.yaml (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/general-dyn-tls-0.yaml (removed)
@@ -1,64 +0,0 @@
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- OSABI: ELFOSABI_GNU
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: FF4300D1E00F00B900040011E103002A48D03BD50801009108010091000100B9E10B00B9FF430091C0035FD6
- - Name: .rela.text
- Type: SHT_RELA
- Link: .symtab
- AddressAlign: 0x0000000000000008
- Info: .text
- Relocations:
- - Offset: 0x0000000000000014
- Symbol: var
- Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- - Offset: 0x0000000000000018
- Symbol: var
- Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- - Name: .tbss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
- AddressAlign: 0x0000000000000004
- Size: 4
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
-# - Name: test_tls.c
-# Type: STT_FILE
- - Name: '$d.1'
- Section: .tbss
- - Name: '$x.0'
- Section: .text
- - Name: .tbss
- Type: STT_TLS
- Section: .tbss
- Global:
- - Name: foo
- Type: STT_FUNC
- Section: .text
- Size: 0x000000000000002C
- - Name: var
- Type: STT_TLS
- Section: .tbss
- Size: 0x0000000000000004
-...
Removed: lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.c (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.c (removed)
@@ -1,12 +0,0 @@
-#include <stdio.h>
-
-void init() {
- printf("%s\n", __FUNCTION__);
-}
-
-void fini() {
- printf("%s\n", __FUNCTION__);
-}
-
-int main() {
-}
Removed: lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/initfini-option.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/initfini.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/initfini.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/initfini.c (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/initfini.c (removed)
@@ -1,13 +0,0 @@
-#include <stdio.h>
-
-void __attribute__ ((constructor)) constructor() {
- printf("%s\n", __FUNCTION__);
-}
-
-void __attribute__ ((destructor)) destructor() {
- printf("%s\n", __FUNCTION__);
-}
-
-int main() {
- return 0;
-}
Removed: lld/trunk/test/old-elf/AArch64/Inputs/initfini.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/initfini.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/initfini.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/initfini.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/initial-exec-tls-1.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/initial-exec-tls-1.yaml?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/initial-exec-tls-1.yaml (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/initial-exec-tls-1.yaml (removed)
@@ -1,77 +0,0 @@
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- OSABI: ELFOSABI_GNU
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- - Name: .tbss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
- AddressAlign: 0x0000000000000004
- Size: 16
- - Name: .comment
- Type: SHT_PROGBITS
- Flags: [ SHF_MERGE, SHF_STRINGS ]
- AddressAlign: 0x0000000000000001
- Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742065653461393664373236383264353237636635353336313135366235656531383662303964363138292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420623065376165623639343236646331346637376466626535343533333536366664363866396466632900
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
- - Name: '$d.0'
- Type: STT_TLS
- Section: .tbss
- - Name: '$d.1'
- Section: .comment
- - Name: .tbss
- Type: STT_TLS
- Section: .tbss
- - Type: STT_SECTION
- Section: .text
- - Type: STT_SECTION
- Section: .data
- - Type: STT_SECTION
- Section: .bss
- - Type: STT_SECTION
- Section: .comment
- - Type: STT_SECTION
- Section: .note.GNU-stack
- Global:
- - Name: e0
- Type: STT_TLS
- Section: .tbss
- Size: 0x0000000000000004
- - Name: e1
- Type: STT_TLS
- Section: .tbss
- Value: 0x0000000000000004
- Size: 0x0000000000000004
- - Name: e2
- Type: STT_TLS
- Section: .tbss
- Value: 0x0000000000000008
- Size: 0x0000000000000004
- - Name: e3
- Type: STT_TLS
- Section: .tbss
- Value: 0x000000000000000C
- Size: 0x0000000000000004
-...
Removed: lld/trunk/test/old-elf/AArch64/Inputs/main.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/main.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/main.c (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/main.c (removed)
@@ -1,4 +0,0 @@
-int main() {
- fn();
- return 0;
-}
Removed: lld/trunk/test/old-elf/AArch64/Inputs/main.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/main.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/main.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/main.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.c (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.c (removed)
@@ -1 +0,0 @@
-int c = 10;
Removed: lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/no-interp-section.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.o?rev=262157&view=auto
==============================================================================
Binary files lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.o (original) and lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.o (removed) differ
Removed: lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.s?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.s (original)
+++ lld/trunk/test/old-elf/AArch64/Inputs/zerosizedsection.s (removed)
@@ -1,3 +0,0 @@
-.text
-.data
-.word .text
Removed: lld/trunk/test/old-elf/AArch64/defsym.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/defsym.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/defsym.test (original)
+++ lld/trunk/test/old-elf/AArch64/defsym.test (removed)
@@ -1,22 +0,0 @@
-RUN: lld -flavor old-gnu -target aarch64--linux-gnu --defsym=main=fn \
-RUN: --noinhibit-exec %p/Inputs/fn.o -o %t
-RUN: llvm-readobj -symbols %t | FileCheck %s
-
-CHECK: Symbol {
-CHECK: Name: main (1)
-CHECK: Value: 0x4001A4
-CHECK: Size: 0
-CHECK: Binding: Global (0x1)
-CHECK: Type: Function (0x2)
-CHECK: Other: 0
-CHECK: Section: .text (0x5)
-CHECK: }
-CHECK: Symbol {
-CHECK: Name: fn (11)
-CHECK: Value: 0x4001A4
-CHECK: Size: 8
-CHECK: Binding: Global (0x1)
-CHECK: Type: Function (0x2)
-CHECK: Other: 0
-CHECK: Section: .text (0x5)
-CHECK: }
Removed: lld/trunk/test/old-elf/AArch64/dontignorezerosize-sections.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/dontignorezerosize-sections.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/dontignorezerosize-sections.test (original)
+++ lld/trunk/test/old-elf/AArch64/dontignorezerosize-sections.test (removed)
@@ -1,9 +0,0 @@
-# This tests that lld is not ignoring zero sized sections
-RUN: lld -flavor old-gnu -target aarch64--linux-gnu %p/Inputs/zerosizedsection.o \
-RUN: --noinhibit-exec --output-filetype=yaml -o %t
-RUN: FileCheck %s < %t
-
-CHECK: references:
-CHECK: - kind: layout-after
-CHECK: offset: 0
-CHECK: target: L000
Removed: lld/trunk/test/old-elf/AArch64/dynamicvars.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/dynamicvars.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/dynamicvars.test (original)
+++ lld/trunk/test/old-elf/AArch64/dynamicvars.test (removed)
@@ -1,113 +0,0 @@
-# Tests that the dynamic variables created by the linker are set to the right
-# values.
-
-# RUN: yaml2obj --format elf -docnum 1 %s -o %t.o
-# RUN: lld -flavor old-gnu -target aarch64 -e main %t.o -o %t1 --noinhibit-exec
-# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s
-
-
-# CHECK: Name: .dynamic
-# CHECK: Type: SHT_DYNAMIC
-# CHECK: Address: [[TARGETA:[0xa-fA-f0-9]+]]
-# CHECK: Name: .got.plt
-# CHECK: Type: SHT_PROGBITS
-# CHECK: Address: [[TARGETB:[0xa-fA-f0-9]+]]
-# CHECK: Name: _DYNAMIC
-# CHECK: Value: [[TARGETA]]
-# CHECK: Section: .dynamic
-# CHECK: Name: _GLOBAL_OFFSET_TABLE_
-# CHECK: Value: [[TARGETB]]
-# CHECK: Section: .got.plt
-
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- - Name: .text.startup
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: FD7BBFA900000090FD030091000000910000009400008052FD7BC1A8C0035FD6
- - Name: .rela.text.startup
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Link: .symtab
- AddressAlign: 0x0000000000000008
- Info: .text.startup
- Relocations:
- - Offset: 0x0000000000000004
- Symbol: .rodata.str1.8
- Type: R_AARCH64_ADR_PREL_PG_HI21
- - Offset: 0x000000000000000C
- Symbol: .rodata.str1.8
- Type: R_AARCH64_ADD_ABS_LO12_NC
- - Offset: 0x0000000000000010
- Symbol: puts
- Type: R_AARCH64_CALL26
- - Name: .rodata.str1.8
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
- AddressAlign: 0x0000000000000008
- Content: '7465737400000000'
- - Name: .comment
- Type: SHT_PROGBITS
- Flags: [ SHF_MERGE, SHF_STRINGS ]
- AddressAlign: 0x0000000000000001
- Content: 004743433A2028474E552920342E392E33203230313530333234202870726572656C656173652900
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
- - Name: test.c
- Type: STT_FILE
- - Name: .text
- Type: STT_SECTION
- Section: .text
- - Name: .data
- Type: STT_SECTION
- Section: .data
- - Name: .bss
- Type: STT_SECTION
- Section: .bss
- - Name: .text.startup
- Type: STT_SECTION
- Section: .text.startup
- - Name: '$x'
- Section: .text.startup
- - Name: .rodata.str1.8
- Type: STT_SECTION
- Section: .rodata.str1.8
- - Name: '$d'
- Section: .rodata.str1.8
- - Name: .note.GNU-stack
- Type: STT_SECTION
- Section: .note.GNU-stack
- - Name: .comment
- Type: STT_SECTION
- Section: .comment
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text.startup
- Size: 0x0000000000000020
- - Name: puts
-...
Removed: lld/trunk/test/old-elf/AArch64/dynlib-nointerp-section.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/dynlib-nointerp-section.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/dynlib-nointerp-section.test (original)
+++ lld/trunk/test/old-elf/AArch64/dynlib-nointerp-section.test (removed)
@@ -1,5 +0,0 @@
-RUN: lld -flavor old-gnu -target aarch64--linux-gnu %p/Inputs/no-interp-section.o \
-RUN: -o %t -shared
-RUN: llvm-objdump -section-headers %t | FileCheck %s
-
-CHECK-NOT: .interp
Removed: lld/trunk/test/old-elf/AArch64/general-dyn-tls-0.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/general-dyn-tls-0.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/general-dyn-tls-0.test (original)
+++ lld/trunk/test/old-elf/AArch64/general-dyn-tls-0.test (removed)
@@ -1,103 +0,0 @@
-# Check for correct offsets when handling relocations for general dynamic TLS
-# access in executable binaries.
-#
-# The test case was generated from following code snippet:
-#
-# == test_tls.c ==
-#
-# __thread int var;
-# void foo (int x) {
-# var = x + 1;
-# }
-#
-# == test_main.c ==
-# #include <stdio.h>
-#
-# extern __thread int var;
-# extern void foo (int);
-#
-# int main () {
-# foo (10);
-# return var;
-# }
-#
-# The objects are compiled with -fpic.
-
-#RUN: yaml2obj -format=elf %p/Inputs/general-dyn-tls-0.yaml -o=%t-t1.o
-#RUN: yaml2obj -format=elf %s -o %t-t0.o
-#RUN: lld -flavor old-gnu -target arm64 --noinhibit-exec -o %t.exe %t-t0.o %t-t1.o
-#RUN: llvm-readobj -relocations %t.exe | FileCheck %s -check-prefix=CHECKRELOCATION
-#RUN: llvm-objdump -s -t %t.exe | FileCheck %s
-
-#CHECKRELOCATION: Relocations [
-#CHECKRELOCATION: .rela.dyn {
-#CHECKRELOCATION: 0x401090 R_AARCH64_TLSDESC var 0x0
-#CHECKRELOCATION: }
-
-#CHECK: Contents of section .text:
-#CHECK: 400250 a8c31fb8 40018052 0b000094 000000b0 .... at ..R........
-# \_ adrp x0, 401000 <_DYNAMIC> (R_AARCH64_TLSDESC_ADR_PAGE21)
-#CHECK-NEXT: 400260 014840f9 00400291 20003fd6 49d03bd5 .H at ..@.. .?.I.;.
-# \_ | | ldr x1, [x0,#144] (R_AARCH64_TLSDESC_LD64_LO12_NC)
-# \_ | add x0, x0, #0x90 (R_AARCH64_TLSDESC_ADD_LO12_NC)
-# \_ blr x1 (R_AARCH64_TLSDESC_CALL)
-
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- OSABI: ELFOSABI_GNU
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: FD7BBFA9FD030091FF4300D1E8031F2AA8C31FB8400180520000009400000090010040F90000009120003FD649D03BD5286960B8E003082ABF030091FD7BC1A8C0035FD6
- - Name: .rela.text
- Type: SHT_RELA
- Link: .symtab
- AddressAlign: 0x0000000000000008
- Info: .text
- Relocations:
- - Offset: 0x0000000000000018
- Symbol: foo
- Type: R_AARCH64_CALL26
- - Offset: 0x000000000000001C
- Symbol: var
- Type: R_AARCH64_TLSDESC_ADR_PAGE21
- - Offset: 0x0000000000000020
- Symbol: var
- Type: R_AARCH64_TLSDESC_LD64_LO12_NC
- - Offset: 0x0000000000000024
- Symbol: var
- Type: R_AARCH64_TLSDESC_ADD_LO12_NC
- - Offset: 0x0000000000000028
- Symbol: var
- Type: R_AARCH64_TLSDESC_CALL
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
- - Name: '$x.0'
- Section: .text
- Global:
- - Name: foo
- - Name: main
- Type: STT_FUNC
- Section: .text
- Size: 0x0000000000000044
- - Name: var
- Type: STT_TLS
Removed: lld/trunk/test/old-elf/AArch64/initfini.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/initfini.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/initfini.test (original)
+++ lld/trunk/test/old-elf/AArch64/initfini.test (removed)
@@ -1,23 +0,0 @@
-# This tests the functionality that lld is able to read
-# init_array/fini_array sections in the input ELF. This
-# corresponds to the the .init_array/.fini_array sections
-# in the output ELF.
-
-RUN: lld -flavor old-gnu -target aarch64--linux-gnu %p/Inputs/initfini.o \
-RUN: --noinhibit-exec --output-filetype=yaml -o %t
-RUN: FileCheck %s < %t
-
-CHECK: type: data
-CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
-CHECK: section-name: .init_array
-CHECK: references:
-CHECK: - kind: R_AARCH64_ABS64
-CHECK: offset: 0
-CHECK: target: constructor
-CHECK: type: data
-CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
-CHECK: section-name: .fini_array
-CHECK: references:
-CHECK: - kind: R_AARCH64_ABS64
-CHECK: offset: 0
-CHECK: target: destructor
Removed: lld/trunk/test/old-elf/AArch64/initial-exec-tls-0.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/initial-exec-tls-0.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/initial-exec-tls-0.test (original)
+++ lld/trunk/test/old-elf/AArch64/initial-exec-tls-0.test (removed)
@@ -1,146 +0,0 @@
-# Check for initial executable TLS access across different modules. For
-# this case compiler will emit R_AARCH64_TLSLD_ADR_PAGE21 and
-# R_AARCH64_TLSLD_ADD_LO12_NC static relocations and linker should create
-# a R_AARCH64_TLS_TPREL64 dynamic relocation for variable access.
-
-# The test case was generated from following code snippet:
-#
-# t1.c (initial-exec-tls-1.yaml)
-#
-# __thread int e0;
-# __thread int e1;
-# __thread int e2;
-# __thread int e3;
-#
-# t0.c (initial-exec-tls-0.test)
-#
-# extern __thread int e0;
-# extern __thread int e1;
-# extern __thread int e2;
-# extern __thread int e3;
-#
-# int main ()
-# {
-# e0 = 1;
-# e1 = 2;
-# e1 = 3;
-# e1 = 4;
-# }
-
-#RUN: yaml2obj -format=elf %p/Inputs/initial-exec-tls-1.yaml -o=%t-t1.o
-#RUN: yaml2obj -format=elf %s -o %t-t0.o
-#RUN: lld -flavor old-gnu -target arm64 --noinhibit-exec -o %t.exe %t-t0.o %t-t1.o
-#RUN: llvm-readobj -relocations %t.exe | FileCheck %s -check-prefix=CHECKRELOCATION
-#RUN: llvm-objdump -s -t %t.exe | FileCheck %s
-
-#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e0 0x0
-#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e1 0x0
-#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e2 0x0
-#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e3 0x0
-
-#CHECK: Contents of section .text:
-#CHECK-NEXT: 4002c0 ff4300d1 e8031f2a e9031e32 0a0000b0 .C.....*...2....
-# \_ adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
-#CHECK-NEXT: 4002d0 4a4940f9 4bd03bd5 ec030032 6c692ab8 JI at .K.;....2li*.
-# \_ ldr x10, [x10,#144] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
-#CHECK-NEXT: 4002e0 0a0000b0 4a4d40f9 ec031f32 6c692ab8 ....JM at ....2li*.
-# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
-# \_ ldr x10, [x10,#152] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
-#CHECK-NEXT: 4002f0 0a0000b0 4a5140f9 ec070032 6c692ab8 ....JQ at ....2li*.
-# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
-# \_ ldr x10, [x10,#160] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
-#CHECK-NEXT: 400300 0a0000b0 4a5540f9 ec031e32 6c692ab8 ....JU at ....2li*.
-# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
-# \_ ldr x10, [x10,#168] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
-
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- OSABI: ELFOSABI_GNU
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: FF4300D1E8031F2AE9031E320A0000904A0140F94BD03BD5EC0300326C692AB80A0000904A0140F9EC031F326C692AB80A0000904A0140F9EC0700326C692AB80A0000904A0140F9EC031E326C692AB8E003082AE90F00B9FF430091C0035FD6
- - Name: .rela.text
- Type: SHT_RELA
- Link: .symtab
- AddressAlign: 0x0000000000000008
- Info: .text
- Relocations:
- - Offset: 0x000000000000000C
- Symbol: e0
- Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
- - Offset: 0x0000000000000010
- Symbol: e0
- Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
- - Offset: 0x0000000000000020
- Symbol: e1
- Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
- - Offset: 0x0000000000000024
- Symbol: e1
- Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
- - Offset: 0x0000000000000030
- Symbol: e2
- Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
- - Offset: 0x0000000000000034
- Symbol: e2
- Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
- - Offset: 0x0000000000000040
- Symbol: e3
- Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
- - Offset: 0x0000000000000044
- Symbol: e3
- Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- - Name: .comment
- Type: SHT_PROGBITS
- Flags: [ SHF_MERGE, SHF_STRINGS ]
- AddressAlign: 0x0000000000000001
- Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742065653461393664373236383264353237636635353336313135366235656531383662303964363138292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420623065376165623639343236646331346637376466626535343533333536366664363866396466632900
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
- - Name: '$d.1'
- Section: .comment
- - Name: '$x.0'
- Section: .text
- - Type: STT_SECTION
- Section: .text
- - Type: STT_SECTION
- Section: .data
- - Type: STT_SECTION
- Section: .bss
- - Type: STT_SECTION
- Section: .comment
- - Type: STT_SECTION
- Section: .note.GNU-stack
- Global:
- - Name: e0
- Type: STT_TLS
- - Name: e1
- Type: STT_TLS
- - Name: e2
- Type: STT_TLS
- - Name: e3
- Type: STT_TLS
- - Name: main
- Type: STT_FUNC
- Section: .text
- Size: 0x0000000000000060
-...
Removed: lld/trunk/test/old-elf/AArch64/local-tls.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/local-tls.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/local-tls.test (original)
+++ lld/trunk/test/old-elf/AArch64/local-tls.test (removed)
@@ -1,184 +0,0 @@
-# Check for correct offsets when handling relocations for local TLS
-# access (R_AARCH64_TLSLE_ADD_TPREL_HI12, R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 --noinhibit-exec -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .text:
-# CHECK-NEXT: 4001dc 48d03bd5 08010091 08610091 090140b9 H.;......a.... at .
-# \_ | | <foo1>:
-# \_ | add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
-# \_ add x8, x8, #0x18 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
-# CHECK-NEXT: 4001ec e003092a c0035fd6 48d03bd5 08010091 ...*.._.H.;.....
-# \_ | <foo2>:
-# \_ add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
-# CHECK-NEXT: 4001fc 08710091 090140b9 e003092a c0035fd6 .q.... at ....*.._.
-# \_ add x8, x8, #0x1c (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
-# CHECK-NEXT: 40020c 48d03bd5 08010091 08410091 090140b9 H.;......A.... at .
-# \_ | | <foo3>:
-# \_ | add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
-# \_ add x8, x8, #0x10 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
-# CHECK-NEXT: 40021c e003092a c0035fd6 48d03bd5 08010091 ...*.._.H.;.....
-# \_ | <foo3>:
-# \_ add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
-# CHECK-NEXT: 40022c 08510091 090140b9 e003092a c0035fd6 .Q.... at ....*.._.
-# \_ add x8, x8, #0x14 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
-
----
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- OSABI: ELFOSABI_GNU
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 48D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD6FD7BBFA9FD030091FF8300D1BFC31FB8E4FFFF97A0831FB8E8FFFF97A0431FB8ECFFFF97E01300B9F0FFFF970800009008010091E00F00B9E00308AAA1835FB8A2435FB8E31340B9E40F40B900000094E1031F2AE00B00B9E003012ABF030091FD7BC1A8C0035FD6
- - Name: .rela.text
- Type: SHT_RELA
- Link: .symtab
- AddressAlign: 0x0000000000000008
- Info: .text
- Relocations:
- - Offset: 0x0000000000000004
- Symbol: v1
- Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- - Offset: 0x0000000000000008
- Symbol: v1
- Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- - Offset: 0x000000000000001C
- Symbol: v2
- Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- - Offset: 0x0000000000000020
- Symbol: v2
- Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- - Offset: 0x0000000000000034
- Symbol: v3
- Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- - Offset: 0x0000000000000038
- Symbol: v3
- Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- - Offset: 0x000000000000004C
- Symbol: v4
- Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- - Offset: 0x0000000000000050
- Symbol: v4
- Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- - Offset: 0x000000000000008C
- Symbol: .rodata.str1.1
- Type: R_AARCH64_ADR_PREL_PG_HI21
- - Offset: 0x0000000000000090
- Symbol: .rodata.str1.1
- Type: R_AARCH64_ADD_ABS_LO12_NC
- - Offset: 0x00000000000000AC
- Symbol: printf
- Type: R_AARCH64_CALL26
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- - Name: .tdata
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
- AddressAlign: 0x0000000000000004
- Content: '0300000004000000'
- - Name: .tbss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
- AddressAlign: 0x0000000000000004
- Size: 8
- - Name: .rodata.str1.1
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
- AddressAlign: 0x0000000000000001
- Content: 25692025692025692025690A00
- - Name: .note.GNU-stack
- Type: SHT_PROGBITS
- AddressAlign: 0x0000000000000001
- Content: ''
-Symbols:
- Local:
- - Name: '$d.1'
- Type: STT_TLS
- Section: .tdata
- - Name: '$d.2'
- Type: STT_TLS
- Section: .tbss
- - Name: '$d.3'
- Section: .rodata.str1.1
- - Name: '$x.0'
- Section: .text
- - Name: v2
- Type: STT_TLS
- Section: .tbss
- Value: 0x0000000000000004
- Size: 0x0000000000000004
- - Name: v4
- Type: STT_TLS
- Section: .tdata
- Value: 0x0000000000000004
- Size: 0x0000000000000004
- - Name: .text
- Type: STT_SECTION
- Section: .text
- - Name: .data
- Type: STT_SECTION
- Section: .data
- - Name: .bss
- Type: STT_SECTION
- Section: .bss
- - Name: .tdata
- Type: STT_SECTION
- Section: .tdata
- - Name: .tbss
- Type: STT_SECTION
- Section: .tbss
- - Name: .rodata.str1.1
- Type: STT_SECTION
- Section: .rodata.str1.1
- - Name: .note.GNU-stack
- Type: STT_SECTION
- Section: .note.GNU-stack
- Global:
- - Name: foo1
- Type: STT_FUNC
- Section: .text
- Size: 0x0000000000000018
- - Name: foo2
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000018
- Size: 0x0000000000000018
- - Name: foo3
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000030
- Size: 0x0000000000000018
- - Name: foo4
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000048
- Size: 0x0000000000000018
- - Name: main
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000060
- Size: 0x0000000000000068
- - Name: v1
- Type: STT_TLS
- Section: .tbss
- Size: 0x0000000000000004
- - Name: v3
- Type: STT_TLS
- Section: .tdata
- Size: 0x0000000000000004
- - Name: printf
-...
Removed: lld/trunk/test/old-elf/AArch64/rel-abs16-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-abs16-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-abs16-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-abs16-overflow.test (removed)
@@ -1,44 +0,0 @@
-# Check handling of R_AARCH64_ABS16 relocation overflow.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s
-
-# CHECK: Relocation out of range in file {{.*}}: reference from data1+0 to data1+0 of type 259 (R_AARCH64_ABS16)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0
- Symbol: data1
- Type: R_AARCH64_ABS16
- Addend: 0
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-abs16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-abs16.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-abs16.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-abs16.test (removed)
@@ -1,53 +0,0 @@
-# Check handling of R_AARCH64_ABS16 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 60100000 00000000 `.......
-# ^^ data1 - 0x400000 = 0x1060
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000004 data1
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data1
- Type: R_AARCH64_ABS16
- Addend: -4194304
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
- - Name: data2
- Section: .data
- Value: 0x4
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-abs32-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-abs32-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-abs32-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-abs32-overflow.test (removed)
@@ -1,53 +0,0 @@
-# Check handling of R_AARCH64_ABS32 relocation overflow.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s
-
-# CHECK-DAG: Relocation out of range in file {{.*}}: reference from data1+0 to data2+34359738369 of type 258 (R_AARCH64_ABS32)
-# CHECK-DAG: Relocation out of range in file {{.*}}: reference from data2+0 to data1+34359738369 of type 258 (R_AARCH64_ABS32)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_ABS32
- Addend: 0x800000001
- - Offset: 0x4
- Symbol: data1
- Type: R_AARCH64_ABS32
- Addend: 0x800000001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
- - Name: data2
- Section: .data
- Value: 0x4
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-abs32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-abs32.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-abs32.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-abs32.test (removed)
@@ -1,59 +0,0 @@
-# Check handling of R_AARCH64_ABS32 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 65104080 61104080 e. at .a.@.
-# ^^ data2 + 0x80000001 = 0x80401069
-# ^^ data1 + 0x80000001 = 0x80401061
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000004 data1
-# CHECK: 00401064 g .data 00000004 data2
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_ABS32
- Addend: 0x80000001
- - Offset: 0x4
- Symbol: data1
- Type: R_AARCH64_ABS32
- Addend: 0x80000001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
- - Name: data2
- Section: .data
- Value: 0x4
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-abs64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-abs64.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-abs64.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-abs64.test (removed)
@@ -1,59 +0,0 @@
-# Check handling of R_AARCH64_ABS64 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 69104000 00000080 61104000 00000080 i. at .....a.@.....
-# ^^ data2 + 0x8000000000000001 = 0x8000000000401069
-# ^^ data1 + 0x8000000000000001 = 0x8000000000401061
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000008 data1
-# CHECK: 00401068 g .data 00000008 data2
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000000000000000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_ABS64
- Addend: -9223372036854775807
- - Offset: 0x8
- Symbol: data1
- Type: R_AARCH64_ABS64
- Addend: -9223372036854775807
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
- - Name: data2
- Section: .data
- Value: 0x8
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21-overflow.test (removed)
@@ -1,45 +0,0 @@
-# Check handling of R_AARCH64_ADR_PREL_PG_HI21 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-
-# CHECK: Relocation out of range in file {{.*}}: reference from _start+0 to data1+1048577 of type 274 (R_AARCH64_ADR_PREL_LO21)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000090"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.text
- Type: SHT_RELA
- Info: .text
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data1
- Type: R_AARCH64_ADR_PREL_LO21
- Addend: 0x100001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-adr_prel_lo21.test (removed)
@@ -1,51 +0,0 @@
-# REQUIRES: arm64
-
-# Check handling of R_AARCH64_ADR_PREL_LO21 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -d -t %t-exe | FileCheck %s
-
-# CHECK: Disassembly of section .text:
-# CHECK-NEXT: _start:
-# CHECK-NEXT: 4001b0: 80 75 00 90 adrp x0, #15400960
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000004 data1
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000090"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.text
- Type: SHT_RELA
- Info: .text
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data1
- Type: R_AARCH64_ADR_PREL_LO21
- Addend: 0
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21-overflow.test (removed)
@@ -1,45 +0,0 @@
-# Check handling of R_AARCH64_ADR_PREL_PG_HI21 relocation overflow.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-
-# CHECK-DAG: Relocation out of range in file {{.*}}: reference from _start+0 to data1+2147483649 of type 275 (R_AARCH64_ADR_PREL_PG_HI21)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000090"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 4096
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.text
- Type: SHT_RELA
- Info: .text
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data1
- Type: R_AARCH64_ADR_PREL_PG_HI21
- Addend: 0x80000001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-adr_prel_pg_hi21.test (removed)
@@ -1,52 +0,0 @@
-# REQUIRES: arm64
-
-# Check handling of R_AARCH64_ADR_PREL_PG_HI21 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -d -t %t-exe | FileCheck %s
-
-# CHECK: Disassembly of section .text:
-# CHECK-NEXT: _start:
-# CHECK-NEXT: 4001b0: 00 00 00 d0 adrp x0, #8192
-# CHECK: SYMBOL TABLE:
-# CHECK: 00402000 g .data 00000004 data1
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000090"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 4096
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.text
- Type: SHT_RELA
- Info: .text
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data1
- Type: R_AARCH64_ADR_PREL_PG_HI21
- Addend: 0
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-bad.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-bad.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-bad.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-bad.test (removed)
@@ -1,44 +0,0 @@
-# Check handling of a bad relocation (in this case dynamic in a static object).
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s
-
-# CHECK: Unhandled reference type in file {{.*}}: reference from data1+4 to data1+0 of type 1024 (R_AARCH64_COPY)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x4
- Symbol: data1
- Type: R_AARCH64_COPY
- Addend: 0
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
Removed: lld/trunk/test/old-elf/AArch64/rel-prel16-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-prel16-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-prel16-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-prel16-overflow.test (removed)
@@ -1,53 +0,0 @@
-# Check handling of R_AARCH64_PREL16 relocation overflow.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s
-
-# CHECK: Relocation out of range in file {{.*}}: reference from data1+0 to data2+524289 of type 262 (R_AARCH64_PREL16)
-# CHECK: Relocation out of range in file {{.*}}: reference from data2+0 to data1+524289 of type 262 (R_AARCH64_PREL16)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_PREL16
- Addend: 0x80001
- - Offset: 0x2
- Symbol: data1
- Type: R_AARCH64_PREL16
- Addend: 0x80001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 2
- - Name: data2
- Section: .data
- Value: 0x2
- Size: 2
Removed: lld/trunk/test/old-elf/AArch64/rel-prel16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-prel16.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-prel16.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-prel16.test (removed)
@@ -1,59 +0,0 @@
-# Check handling of R_AARCH64_PREL16 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 0380ff7f 00000000 ........
-# ^^ data2 - data1 + 0x8001 = 0x8003
-# ^^ data1 - data2 + 0x8001 = 0x7fff
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000002 data1
-# CHECK: 00401062 g .data 00000006 data2
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_PREL16
- Addend: 0x8001
- - Offset: 0x2
- Symbol: data1
- Type: R_AARCH64_PREL16
- Addend: 0x8001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 2
- - Name: data2
- Section: .data
- Value: 0x2
- Size: 2
Removed: lld/trunk/test/old-elf/AArch64/rel-prel32-overflow.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-prel32-overflow.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-prel32-overflow.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-prel32-overflow.test (removed)
@@ -1,53 +0,0 @@
-# Check handling of R_AARCH64_PREL32 relocation overflow.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: not lld -flavor old-gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s
-
-# CHECK: Relocation out of range in file {{.*}}: reference from data1+0 to data2+34359738369 of type 261 (R_AARCH64_PREL32)
-# CHECK: Relocation out of range in file {{.*}}: reference from data2+0 to data1+34359738369 of type 261 (R_AARCH64_PREL32)
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_PREL32
- Addend: 0x800000001
- - Offset: 0x4
- Symbol: data1
- Type: R_AARCH64_PREL32
- Addend: 0x800000001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
- - Name: data2
- Section: .data
- Value: 0x4
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-prel32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-prel32.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-prel32.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-prel32.test (removed)
@@ -1,59 +0,0 @@
-# Check handling of R_AARCH64_PREL32 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 05000080 fdffff7f ........
-# ^^ data2 - data1 + 0x80000001 = 0x80000005
-# ^^ data1 - data2 + 0x80000001 = 0x7ffffffd
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000004 data1
-# CHECK: 00401064 g .data 00000004 data2
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "0000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_PREL32
- Addend: 0x80000001
- - Offset: 0x4
- Symbol: data1
- Type: R_AARCH64_PREL32
- Addend: 0x80000001
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 4
- - Name: data2
- Section: .data
- Value: 0x4
- Size: 4
Removed: lld/trunk/test/old-elf/AArch64/rel-prel64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/AArch64/rel-prel64.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/AArch64/rel-prel64.test (original)
+++ lld/trunk/test/old-elf/AArch64/rel-prel64.test (removed)
@@ -1,59 +0,0 @@
-# Check handling of R_AARCH64_PREL64 relocation.
-# RUN: yaml2obj -format=elf %s > %t-obj
-# RUN: lld -flavor old-gnu -target arm64 -o %t-exe %t-obj
-# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
-
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 401060 09000000 00000080 f9ffffff ffffff7f ................
-# ^^ data2 - data1 + 0x8000000000000001 = 0x8000000000000009
-# ^^ data1 - data2 + 0x8000000000000001 = 0x7ffffffffffffff9
-# CHECK: SYMBOL TABLE:
-# CHECK: 00401060 g .data 00000008 data1
-# CHECK: 00401068 g .data 00000008 data2
-
-!ELF
-FileHeader: !FileHeader
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-
-Sections:
-- Name: .text
- Type: SHT_PROGBITS
- Content: "00000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_EXECINSTR]
-- Name: .data
- Type: SHT_PROGBITS
- Content: "00000000000000000000000000000000"
- AddressAlign: 16
- Flags: [SHF_ALLOC, SHF_WRITE]
-
-- Name: .rela.data
- Type: SHT_RELA
- Info: .data
- AddressAlign: 8
- Relocations:
- - Offset: 0x0
- Symbol: data2
- Type: R_AARCH64_PREL64
- Addend: -9223372036854775807
- - Offset: 0x8
- Symbol: data1
- Type: R_AARCH64_PREL64
- Addend: -9223372036854775807
-
-Symbols:
- Global:
- - Name: _start
- Section: .text
- Value: 0x0
- Size: 4
- - Name: data1
- Section: .data
- Size: 8
- - Name: data2
- Section: .data
- Value: 0x8
- Size: 8
Removed: lld/trunk/test/old-elf/ARM/Inputs/fn.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/Inputs/fn.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/Inputs/fn.c (original)
+++ lld/trunk/test/old-elf/ARM/Inputs/fn.c (removed)
@@ -1 +0,0 @@
-int fn() { return 1; }
Removed: lld/trunk/test/old-elf/ARM/Inputs/libfn.so
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/Inputs/libfn.so?rev=262157&view=auto
==============================================================================
Binary file - no diff available.
Removed: lld/trunk/test/old-elf/ARM/Inputs/libobj.so
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/Inputs/libobj.so?rev=262157&view=auto
==============================================================================
Binary file - no diff available.
Removed: lld/trunk/test/old-elf/ARM/Inputs/obj.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/Inputs/obj.c?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/Inputs/obj.c (original)
+++ lld/trunk/test/old-elf/ARM/Inputs/obj.c (removed)
@@ -1,4 +0,0 @@
-static struct S {
-} s;
-
-struct S *const object = &s;
Removed: lld/trunk/test/old-elf/ARM/arm-symbols.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/arm-symbols.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/arm-symbols.test (original)
+++ lld/trunk/test/old-elf/ARM/arm-symbols.test (removed)
@@ -1,51 +0,0 @@
-# Check that symbols formed from ARM instructions are valid:
-# 1. Symbol address.
-# 2. Symbol content size.
-# 3. Symbol content.
-
-# RUN: yaml2obj -format=elf %s > %t-a.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu \
-# RUN: -Bstatic --noinhibit-exec %t-a.o -o %t-a
-# RUN: llvm-readobj -symbols %t-a | FileCheck -check-prefix=SYM-ADDR %s
-# RUN: llvm-readobj -symbols %t-a | FileCheck -check-prefix=SYM-SIZE %s
-# RUN: llvm-objdump -s -t %t-a | FileCheck -check-prefix=SYM-CONTENT %s
-
-# SYM-ADDR: Name: main (1)
-# SYM-ADDR-NEXT: Value: 0x400074
-
-# SYM-SIZE: Name: main (1)
-# SYM-SIZE-NEXT: Value: 0x{{[0-9a-f]+}}
-# SYM-SIZE-NEXT: Size: 28
-
-# SYM-CONTENT: Contents of section .text:
-# SYM-CONTENT-NEXT: 400074 04b02de5 00b08de2 0030a0e3 0300a0e1 ..-......0......
-# SYM-CONTENT-NEXT: 400084 00d04be2 04b09de4 1eff2fe1 ..K......./.
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text
-...
Removed: lld/trunk/test/old-elf/ARM/defsym.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/defsym.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/defsym.test (original)
+++ lld/trunk/test/old-elf/ARM/defsym.test (removed)
@@ -1,50 +0,0 @@
-# Check that defined symbols are present in the generated executable
-
-# RUN: yaml2obj -format=elf %s > %t-o.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu --defsym=main=fn \
-# RUN: -Bstatic --noinhibit-exec %t-o.o -o %t
-# RUN: llvm-readobj -symbols %t | FileCheck %s
-
-# CHECK: Name: main (1)
-# CHECK-NEXT: Value: 0x400074
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Global (0x1)
-# CHECK-NEXT: Type: Function (0x2)
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: .text (0x1)
-# CHECK: Name: fn (6)
-# CHECK-NEXT: Value: 0x400074
-# CHECK-NEXT: Size: {{[0-9]+}}
-# CHECK-NEXT: Binding: Global (0x1)
-# CHECK-NEXT: Type: Function (0x2)
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: .text (0x1)
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: fn
- Type: STT_FUNC
- Section: .text
-...
Removed: lld/trunk/test/old-elf/ARM/dynamic-symbols.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/dynamic-symbols.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/dynamic-symbols.test (original)
+++ lld/trunk/test/old-elf/ARM/dynamic-symbols.test (removed)
@@ -1,83 +0,0 @@
-# Check that proper dynamic symbols are present in the generated executable
-
-# RUN: yaml2obj -format=elf %s > %t-o.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu \
-# RUN: -Bstatic --noinhibit-exec %t-o.o -o %t
-# RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=STATIC %s
-
-# STATIC-NOT: Name: _GLOBAL_OFFSET_TABLE_
-# STATIC-NOT: Name: _DYNAMIC
-
-# RUN: yaml2obj -format=elf %s > %t-o.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu \
-# RUN: --noinhibit-exec %t-o.o -o %t
-# RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=EXEC-DYN %s
-
-# EXEC-DYN: Name: _GLOBAL_OFFSET_TABLE_
-# EXEC-DYN-NEXT: Value: 0x401000
-# EXEC-DYN-NEXT: Size: 0
-# EXEC-DYN-NEXT: Binding: Global (0x1)
-# EXEC-DYN-NEXT: Type: Object (0x1)
-# EXEC-DYN-NEXT: Other: 0
-# EXEC-DYN-NEXT: Section: Absolute (0xFFF1)
-# EXEC-DYN: Name: _DYNAMIC
-# EXEC-DYN-NEXT: Value: 0x400130
-# EXEC-DYN-NEXT: Size: 0
-# EXEC-DYN-NEXT: Binding: Global (0x1)
-# EXEC-DYN-NEXT: Type: Object (0x1)
-# EXEC-DYN-NEXT: Other: 0
-# EXEC-DYN-NEXT: Section: Absolute (0xFFF1)
-
-# RUN: yaml2obj -format=elf %s > %t-o.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu \
-# RUN: -shared --noinhibit-exec %t-o.o -o %t
-# RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=SHARED %s
-
-# SHARED: Name: _GLOBAL_OFFSET_TABLE_
-# SHARED-NEXT: Value: 0x401000
-# SHARED-NEXT: Size: 0
-# SHARED-NEXT: Binding: Global (0x1)
-# SHARED-NEXT: Type: Object (0x1)
-# SHARED-NEXT: Other: 0
-# SHARED-NEXT: Section: Absolute (0xFFF1)
-# SHARED: Name: _DYNAMIC
-# SHARED-NEXT: Value: 0x4000EC
-# SHARED-NEXT: Size: 0
-# SHARED-NEXT: Binding: Global (0x1)
-# SHARED-NEXT: Type: Object (0x1)
-# SHARED-NEXT: Other: 0
-# SHARED-NEXT: Section: Absolute (0xFFF1)
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- - Name: .got
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: 0000
-Symbols:
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text
-...
Removed: lld/trunk/test/old-elf/ARM/entry-point.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/entry-point.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/entry-point.test (original)
+++ lld/trunk/test/old-elf/ARM/entry-point.test (removed)
@@ -1,113 +0,0 @@
-# 1. Check entry point address for ARM code - should be even.
-# RUN: yaml2obj -format=elf -docnum 1 %s > %t-arm.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi -Bstatic \
-# RUN: --noinhibit-exec %t-arm.o -o %t-arm
-# RUN: llvm-readobj -file-headers %t-arm | FileCheck -check-prefix=ARM-ENTRY %s
-#
-# ARM-ENTRY: Entry: 0x400074
-
-# 2. Check entry point address for Thumb code - should be odd.
-# RUN: yaml2obj -format=elf -docnum 2 %s > %t-thm.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi -Bstatic \
-# RUN: --noinhibit-exec %t-thm.o -o %t-thm
-# RUN: llvm-readobj -file-headers %t-thm | FileCheck -check-prefix=THM-ENTRY %s
-#
-# THM-ENTRY: Entry: 0x400075
-
-# 3. Check wrong entry point address align for ARM code.
-# RUN: yaml2obj -format=elf -docnum 3 %s > %t-arm-wrong.o
-# RUN: not lld -flavor old-gnu -target arm -m armelf_linux_eabi -Bstatic \
-# RUN: --noinhibit-exec %t-arm-wrong.o -o %t-arm-wrong 2> %t-error
-# FileCheck -check-prefix=ARM-WRONG %s < %t-error
-#
-# ARM-WRONG: Two least bits must be zero for ARM entry point
-
-# arm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: _start
- Type: STT_FUNC
- Section: .text
-
-# thm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B400AF00231846BD465DF8047B7047
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: _start
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
-
-# arm-wrong.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000006
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: _start
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000002
-...
Removed: lld/trunk/test/old-elf/ARM/exidx.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/exidx.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/exidx.test (original)
+++ lld/trunk/test/old-elf/ARM/exidx.test (removed)
@@ -1,254 +0,0 @@
-# .ARM.exidx contents checking
-# RUN: yaml2obj -format=elf %s > %t.o
-# RUN: lld -flavor old-gnu -target arm-none-linux-eabi -static -o %t %t.o
-# RUN: llvm-objdump -s -t -section-headers %t | FileCheck %s
-#
-# CHECK: Sections:
-# CHECK: Idx Name Size Address Type
-# CHECK: 2 .ARM.extab 0000000c 00000000004000b4 DATA
-# CHECK: 3 .ARM.exidx 00000018 00000000004000c0
-# CHECK: Contents of section .text:
-# CHECK: 4000a4 1846aff3 00801846 0837bd46 80bd00bf
-# ^
-# 4000b0: bd80 pop {r7, pc}
-# CHECK: Contents of section .ARM.extab:
-# CHECK: 4000b4 01970181 b0b00884 00000000
-# CHECK: Contents of section .ARM.exidx:
-# CHECK: 4000c0 b4ffff7f 08809780 bcffff7f 08809780
-# ^ offset to 400074 (__aeabi_unwind_cpp_pr0)
-# CHECK: 4000d0 c4ffff7f e0ffff7f
-# ^ ^
-# offset to 400094 (_start) handler at 4000B0
-#
-# CHECK: SYMBOL TABLE:
-# CHECK: 004000b4 .ARM.extab 00000000 $d.2
-# CHECK: 004000c0 .ARM.exidx 00000000 $d.1
-# CHECK: 00400074 g F .text 00000010 __aeabi_unwind_cpp_pr0
-# CHECK: 00400094 g F .text 00000020 _start
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B400AF00231846BD465DF8047B704780B400AF00231846BD465DF8047B704780B582B000AF3B1D1846FFF7FEFF3B1D1846FFF7FEFF18460837BD4680BD00BF
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text
- Relocations:
- - Offset: 0x000000000000002A
- Symbol: _ZN1AILi1EEC1Ev
- Type: R_ARM_THM_CALL
- - Offset: 0x0000000000000032
- Symbol: _ZN1AILi1EED1Ev
- Type: R_ARM_THM_CALL
- - Name: .ARM.extab
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Content: 01970181B0B0088400000000
- - Name: .ARM.exidx
- Type: SHT_ARM_EXIDX
- Flags: [ SHF_ALLOC, SHF_LINK_ORDER ]
- Link: .text
- AddressAlign: 0x0000000000000004
- Content: '000000000880978010000000088097802000000000000000'
- - Name: .rel.ARM.exidx
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .ARM.exidx
- Relocations:
- - Offset: 0x0000000000000000
- Symbol: .text
- Type: R_ARM_PREL31
- - Offset: 0x0000000000000000
- Symbol: __aeabi_unwind_cpp_pr0
- Type: R_ARM_NONE
- - Offset: 0x0000000000000008
- Symbol: .text
- Type: R_ARM_PREL31
- - Offset: 0x0000000000000010
- Symbol: .text
- Type: R_ARM_PREL31
- - Offset: 0x0000000000000010
- Symbol: __aeabi_unwind_cpp_pr1
- Type: R_ARM_NONE
- - Offset: 0x0000000000000014
- Symbol: .ARM.extab
- Type: R_ARM_PREL31
- - Name: .text._ZN1AILi1EEC2Ev
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
- AddressAlign: 0x0000000000000004
- Content: 80B582B000AF78600120FFF7FEFF7B6818460837BD4680BD
- - Name: .rel.text._ZN1AILi1EEC2Ev
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text._ZN1AILi1EEC2Ev
- Relocations:
- - Offset: 0x000000000000000A
- Symbol: f
- Type: R_ARM_THM_CALL
- - Name: .ARM.extab.text._ZN1AILi1EEC2Ev
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_GROUP ]
- AddressAlign: 0x0000000000000004
- Content: 01970181B0B0088400000000
- - Name: .ARM.exidx.text._ZN1AILi1EEC2Ev
- Type: SHT_ARM_EXIDX
- Flags: [ SHF_ALLOC, SHF_LINK_ORDER, SHF_GROUP ]
- Link: .text._ZN1AILi1EEC2Ev
- AddressAlign: 0x0000000000000004
- Content: '0000000000000000'
- - Name: .rel.ARM.exidx.text._ZN1AILi1EEC2Ev
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .ARM.exidx.text._ZN1AILi1EEC2Ev
- Relocations:
- - Offset: 0x0000000000000000
- Symbol: .text._ZN1AILi1EEC2Ev
- Type: R_ARM_PREL31
- - Offset: 0x0000000000000000
- Symbol: __aeabi_unwind_cpp_pr1
- Type: R_ARM_NONE
- - Offset: 0x0000000000000004
- Symbol: .ARM.extab.text._ZN1AILi1EEC2Ev
- Type: R_ARM_PREL31
- - Name: .text._ZN1AILi1EED2Ev
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
- AddressAlign: 0x0000000000000004
- Content: 80B582B000AF78604FF0FF30FFF7FEFF7B6818460837BD4680BD00BF
- - Name: .rel.text._ZN1AILi1EED2Ev
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text._ZN1AILi1EED2Ev
- Relocations:
- - Offset: 0x000000000000000C
- Symbol: f
- Type: R_ARM_THM_CALL
- - Name: .ARM.extab.text._ZN1AILi1EED2Ev
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_GROUP ]
- AddressAlign: 0x0000000000000004
- Content: 01970181B0B0088400000000
- - Name: .ARM.exidx.text._ZN1AILi1EED2Ev
- Type: SHT_ARM_EXIDX
- Flags: [ SHF_ALLOC, SHF_LINK_ORDER, SHF_GROUP ]
- Link: .text._ZN1AILi1EED2Ev
- AddressAlign: 0x0000000000000004
- Content: '0000000000000000'
- - Name: .rel.ARM.exidx.text._ZN1AILi1EED2Ev
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .ARM.exidx.text._ZN1AILi1EED2Ev
- Relocations:
- - Offset: 0x0000000000000000
- Symbol: .text._ZN1AILi1EED2Ev
- Type: R_ARM_PREL31
- - Offset: 0x0000000000000000
- Symbol: __aeabi_unwind_cpp_pr1
- Type: R_ARM_NONE
- - Offset: 0x0000000000000004
- Symbol: .ARM.extab.text._ZN1AILi1EED2Ev
- Type: R_ARM_PREL31
-Symbols:
- Local:
- - Name: .text
- Type: STT_SECTION
- Section: .text
- - Name: '$t.1'
- Section: .text
- - Name: .ARM.extab
- Type: STT_SECTION
- Section: .ARM.extab
- - Name: .ARM.exidx
- Type: STT_SECTION
- Section: .ARM.exidx
- - Name: '$d.1'
- Section: .ARM.exidx
- - Name: '$d.2'
- Section: .ARM.extab
- - Name: .text._ZN1AILi1EEC2Ev
- Type: STT_SECTION
- Section: .text._ZN1AILi1EEC2Ev
- - Name: '$t.2'
- Section: .text._ZN1AILi1EEC2Ev
- - Name: .ARM.extab.text._ZN1AILi1EEC2Ev
- Type: STT_SECTION
- Section: .ARM.extab.text._ZN1AILi1EEC2Ev
- - Name: '$d.3'
- Section: .ARM.extab.text._ZN1AILi1EEC2Ev
- - Name: .ARM.exidx.text._ZN1AILi1EEC2Ev
- Type: STT_SECTION
- Section: .ARM.exidx.text._ZN1AILi1EEC2Ev
- - Name: '$d.4'
- Section: .ARM.exidx.text._ZN1AILi1EEC2Ev
- - Name: .text._ZN1AILi1EED2Ev
- Type: STT_SECTION
- Section: .text._ZN1AILi1EED2Ev
- - Name: '$t.3'
- Section: .text._ZN1AILi1EED2Ev
- - Name: .ARM.extab.text._ZN1AILi1EED2Ev
- Type: STT_SECTION
- Section: .ARM.extab.text._ZN1AILi1EED2Ev
- - Name: '$d.5'
- Section: .ARM.extab.text._ZN1AILi1EED2Ev
- - Name: .ARM.exidx.text._ZN1AILi1EED2Ev
- Type: STT_SECTION
- Section: .ARM.exidx.text._ZN1AILi1EED2Ev
- - Name: '$d.6'
- Section: .ARM.exidx.text._ZN1AILi1EED2Ev
- Global:
- - Name: __aeabi_unwind_cpp_pr0
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
- Size: 0x0000000000000010
- - Name: __aeabi_unwind_cpp_pr1
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000011
- Size: 0x0000000000000010
- - Name: _start
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000021
- Size: 0x000000000000001E
- Weak:
- - Name: _ZN1AILi1EEC1Ev
- Type: STT_FUNC
- Section: .text._ZN1AILi1EEC2Ev
- Value: 0x0000000000000001
- Size: 0x0000000000000018
- - Name: _ZN1AILi1EED1Ev
- Type: STT_FUNC
- Section: .text._ZN1AILi1EED2Ev
- Value: 0x0000000000000001
- Size: 0x000000000000001A
- - Name: _ZN1AILi1EEC2Ev
- Type: STT_FUNC
- Section: .text._ZN1AILi1EEC2Ev
- Value: 0x0000000000000001
- Size: 0x0000000000000018
- - Name: f
- - Name: _ZN1AILi1EED2Ev
- Type: STT_FUNC
- Section: .text._ZN1AILi1EED2Ev
- Value: 0x0000000000000001
- Size: 0x000000000000001A
-...
Removed: lld/trunk/test/old-elf/ARM/header-flags.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/header-flags.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/header-flags.test (original)
+++ lld/trunk/test/old-elf/ARM/header-flags.test (removed)
@@ -1,57 +0,0 @@
-# Various checks for header flags.
-
-# 1. Check header flags for statically linked executable with default options.
-# RUN: yaml2obj -format=elf %s > %t.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi -Bstatic \
-# RUN: --noinhibit-exec %t.o -o %t
-# RUN: llvm-readobj -file-headers %t | FileCheck -check-prefix=STATIC-DEF %s
-#
-# STATIC-DEF: Flags {{.}} (0x5000400)
-# ABI version 5 + hard float ^^
-
-# 2. Check header flags for dynamically linked executable with default options.
-# RUN: yaml2obj -format=elf %s > %t.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi \
-# RUN: --noinhibit-exec %t.o -o %t
-# RUN: llvm-readobj -file-headers %t | FileCheck -check-prefix=EXEC-DYN-DEF %s
-#
-# EXEC-DYN-DEF: Flags {{.}} (0x5000400)
-# ABI version 5 + hard float ^^
-
-# 3. Check header flags for shared object with default options.
-# RUN: yaml2obj -format=elf %s > %t.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi -shared \
-# RUN: --noinhibit-exec %t.o -o %t
-# RUN: llvm-readobj -file-headers %t | FileCheck -check-prefix=SHARED-DEF %s
-#
-# SHARED-DEF: Flags {{.}} (0x5000400)
-# ABI version 5 + hard float ^^
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text
-...
Removed: lld/trunk/test/old-elf/ARM/mapping-code-model.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/mapping-code-model.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/mapping-code-model.test (original)
+++ lld/trunk/test/old-elf/ARM/mapping-code-model.test (removed)
@@ -1,160 +0,0 @@
-# Check that mapping symbols are treated as ARM or Thumb code properly.
-#
-# 1. ARM <=> Thumb generates both veneers.
-# RUN: yaml2obj -format=elf -docnum 1 %s > %t-a-arm.o
-# RUN: yaml2obj -format=elf -docnum 3 %s > %t-t-thm.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu --defsym=main=f_a \
-# RUN: -Bstatic --noinhibit-exec %t-a-arm.o %t-t-thm.o -o %t
-# RUN: llvm-objdump -t %t | FileCheck -check-prefix=INTER %s
-
-# INTER: SYMBOL TABLE:
-# INTER: {{[0-9a-f]+}} l F .text {{[0-9a-f]+}} __f_t_from_arm
-# INTER: {{[0-9a-f]+}} l F .text {{[0-9a-f]+}} __f_a_from_thumb
-
-# 2. Thumb <=> Thumb doesn't generate veneers.
-# RUN: yaml2obj -format=elf -docnum 2 %s > %t-a-thm.o
-# RUN: yaml2obj -format=elf -docnum 3 %s > %t-t-thm.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu --defsym=main=f_t \
-# RUN: -Bstatic --noinhibit-exec %t-t-thm.o %t-a-thm.o -o %t
-# RUN: llvm-objdump -t %t | FileCheck -check-prefix=THUMB %s
-
-# THUMB: SYMBOL TABLE:
-# THUMB-NOT: {{[0-9a-f]+}} l F .text {{[0-9a-f]+}} __f_t_from_thumb
-# THUMB-NOT: {{[0-9a-f]+}} l F .text {{[0-9a-f]+}} __f_a_from_thumb
-
-# f-a-arm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 00482DE904B08DE2FEFFFFEBFEFFFFEA0030A0E10300A0E10088BDE8
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text
- Relocations:
- - Offset: 0x0000000000000008
- Symbol: f_t
- Type: R_ARM_CALL
- - Offset: 0x000000000000000C
- Symbol: f_t
- Type: R_ARM_JUMP24
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Local:
- - Name: '$a'
- Section: .text
- Size: 0x0000000000000002
- - Name: '$a.f_a'
- Section: .text
- Value: 0x0000000000000002
- Global:
- - Name: f_a
- Type: STT_FUNC
- Section: .text
- - Name: f_t
-
-# f-a-thm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B400AF00231846BD465DF8047B7047
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Local:
- - Name: '$t'
- Section: .text
- Size: 0x0000000000000002
- - Name: '$t.f_a'
- Section: .text
- Value: 0x0000000000000002
- Global:
- - Name: f_a
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
-
-# f-t-thm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B500AFFFF7FEFFFFF7FEBF0346184680BD00BF
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text
- Relocations:
- - Offset: 0x0000000000000004
- Symbol: f_a
- Type: R_ARM_THM_CALL
- - Offset: 0x0000000000000008
- Symbol: f_a
- Type: R_ARM_THM_JUMP24
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Local:
- - Name: '$t'
- Section: .text
- Size: 0x0000000000000002
- - Name: '$t.f_t'
- Section: .text
- Value: 0x0000000000000002
- Global:
- - Name: f_t
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
- - Name: f_a
-...
Removed: lld/trunk/test/old-elf/ARM/mapping-symbols.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/mapping-symbols.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/mapping-symbols.test (original)
+++ lld/trunk/test/old-elf/ARM/mapping-symbols.test (removed)
@@ -1,122 +0,0 @@
-# Check that mapping symbols have zero size, local binding and none type.
-# RUN: yaml2obj -format=elf -docnum 1 %s > %t-a.o
-# RUN: yaml2obj -format=elf -docnum 2 %s > %t-t.o
-# RUN: lld -flavor old-gnu -target arm-linux-gnu \
-# RUN: -Bstatic --noinhibit-exec %t-a.o %t-t.o -o %t
-# RUN: llvm-readobj -symbols %t | FileCheck %s
-
-# CHECK: Name: $a (1)
-# CHECK-NEXT: Value: 0x{{[0-9a-f]+}}
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Local (0x0)
-# CHECK-NEXT: Type: None (0x0)
-# CHECK-NEXT: Other: 0
-#
-# CHECK: Name: $t (9)
-# CHECK-NEXT: Value: 0x{{[0-9a-f]+}}
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Local (0x0)
-# CHECK-NEXT: Type: None (0x0)
-# CHECK-NEXT: Other: 0
-#
-# CHECK: Name: $d (24)
-# CHECK-NEXT: Value: 0x{{[0-9a-f]+}}
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Local (0x0)
-# CHECK-NEXT: Type: None (0x0)
-# CHECK-NEXT: Other: 0
-
-# arm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 00482DE904B08DE2FEFFFFEB0030A0E10300A0E10088BDE8
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text
- Relocations:
- - Offset: 0x0000000000000008
- Symbol: _Z1fv
- Type: R_ARM_CALL
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Local:
- - Name: '$a'
- Section: .text
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text
- - Name: _Z1fv
-
-# thm.o
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B400AF40F20003C0F200031B681846BD465DF8047B7047
- - Name: .rel.text
- Type: SHT_REL
- Link: .symtab
- AddressAlign: 0x0000000000000004
- Info: .text
- Relocations:
- - Offset: 0x0000000000000004
- Symbol: _ZL1i
- Type: R_ARM_THM_MOVW_ABS_NC
- - Offset: 0x0000000000000008
- Symbol: _ZL1i
- Type: R_ARM_THM_MOVT_ABS
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000004
- Size: 4
-Symbols:
- Local:
- - Name: _ZL1i
- Type: STT_OBJECT
- Section: .bss
- Size: 0x0000000000000004
- - Name: '$d'
- Section: .bss
- - Name: '$t'
- Section: .text
- Global:
- - Name: _Z1fv
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
-...
Removed: lld/trunk/test/old-elf/ARM/missing-symbol.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/old-elf/ARM/missing-symbol.test?rev=262157&view=auto
==============================================================================
--- lld/trunk/test/old-elf/ARM/missing-symbol.test (original)
+++ lld/trunk/test/old-elf/ARM/missing-symbol.test (removed)
@@ -1,38 +0,0 @@
-# Check that _MISSING_SYMBOL_ symbol is not resolved
-
-# RUN: yaml2obj -format=elf %s > %t-o.o
-# RUN: lld -flavor old-gnu -target arm -m armelf_linux_eabi -Bstatic \
-# RUN: --noinhibit-exec %t-o.o -o %t 2>&1 | FileCheck %s
-
-# CHECK: Undefined symbol: {{.*}}: _MISSING_SYMBOL_
-
----
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
- Flags: [ EF_ARM_EABI_VER5 ]
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- AddressAlign: 0x0000000000000004
- Content: 80B483B000AF40F20003C0F200037B60002318460C37BD465DF8047B704700BF
- - Name: .data
- Type: SHT_PROGBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
- Content: ''
- - Name: .bss
- Type: SHT_NOBITS
- Flags: [ SHF_WRITE, SHF_ALLOC ]
- AddressAlign: 0x0000000000000001
-Symbols:
- Global:
- - Name: main
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000000001
- - Name: _MISSING_SYMBOL_
-...
More information about the llvm-commits
mailing list