[PATCH] D39348: Implement --just-symbols.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 17:45:04 PST 2017


Please make sure we error if the given file is a .o or a .so.

Please add a test showing that a duplicated symbol is reported as an
error.

Cheers,
Rafael

Rui Ueyama via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:

> ruiu updated this revision to Diff 125075.
> ruiu added a comment.
>
> - address review comments
>
>
> https://reviews.llvm.org/D39348
>
> Files:
>   lld/ELF/Driver.cpp
>   lld/ELF/InputFiles.cpp
>   lld/ELF/InputFiles.h
>   lld/ELF/Options.td
>   lld/test/ELF/Inputs/just-symbols.s
>   lld/test/ELF/just-symbols.s
>
> Index: lld/test/ELF/just-symbols.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/just-symbols.s
> @@ -0,0 +1,15 @@
> +# REQUIRES: x86
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/just-symbols.s -o %t1
> +# RUN: ld.lld %t1 -o %t1.exe -Ttext=0x10000
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
> +# RUN: ld.lld %t2 -just-symbols=%t1.exe -o %t2.exe
> +# RUN: llvm-readelf -symbols %t2.exe | FileCheck %s
> +
> +# CHECK: 0000000000010000     0 NOTYPE  GLOBAL DEFAULT  ABS foo
> +
> +.globl _start, foo
> +_start:
> +  call foo
> +  ret
> Index: lld/test/ELF/Inputs/just-symbols.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/Inputs/just-symbols.s
> @@ -0,0 +1,3 @@
> +.globl foo
> +foo:
> +  ret
> Index: lld/ELF/Options.td
> ===================================================================
> --- lld/ELF/Options.td
> +++ lld/ELF/Options.td
> @@ -147,6 +147,8 @@
>  defm init: Eq<"init">, HelpText<"Specify an initializer function">,
>    MetaVarName<"<symbol>">;
>  
> +defm just_symbols: Eq<"just-symbols">, HelpText<"Just link symbols">;
> +
>  defm library: Eq<"library">, HelpText<"Root name of library to use">,
>    MetaVarName<"<libName>">;
>  
> Index: lld/ELF/InputFiles.h
> ===================================================================
> --- lld/ELF/InputFiles.h
> +++ lld/ELF/InputFiles.h
> @@ -59,6 +59,10 @@
>  // Opens a given file.
>  llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
>  
> +// For --just-symbols.
> +template <class ELFT>
> +std::vector<std::pair<StringRef, uint64_t>> readSymbols(MemoryBufferRef);
> +
>  // The root class of input files.
>  class InputFile {
>  public:
> Index: lld/ELF/InputFiles.cpp
> ===================================================================
> --- lld/ELF/InputFiles.cpp
> +++ lld/ELF/InputFiles.cpp
> @@ -1129,6 +1129,38 @@
>    }
>  }
>  
> +// Reads defined symbols from a given ELF file, and returns their
> +// names and values. This is used for --just-symbols.
> +template <class ELFT>
> +std::vector<std::pair<StringRef, uint64_t>>
> +elf::readSymbols(MemoryBufferRef MB) {
> +  typedef typename ELFT::Shdr Elf_Shdr;
> +  typedef typename ELFT::Sym Elf_Sym;
> +  typedef typename ELFT::SymRange Elf_Sym_Range;
> +
> +  StringRef ObjName = MB.getBufferIdentifier();
> +  ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
> +  ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), ObjName);
> +
> +  for (const Elf_Shdr &Sec : Sections) {
> +    if (Sec.sh_type != SHT_SYMTAB)
> +      continue;
> +
> +    Elf_Sym_Range Syms = check(Obj.symbols(&Sec), ObjName);
> +    uint32_t FirstNonLocal = Sec.sh_info;
> +    StringRef StringTable =
> +        check(Obj.getStringTableForSymtab(Sec, Sections), ObjName);
> +
> +    std::vector<std::pair<StringRef, uint64_t>> Ret;
> +    for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal))
> +      if (Sym.st_shndx != SHN_UNDEF)
> +        Ret.emplace_back(check(Sym.getName(StringTable), ObjName),
> +                         Sym.st_value);
> +    return Ret;
> +  }
> +  return {};
> +}
> +
>  template void ArchiveFile::parse<ELF32LE>();
>  template void ArchiveFile::parse<ELF32BE>();
>  template void ArchiveFile::parse<ELF64LE>();
> @@ -1163,3 +1195,12 @@
>  template void BinaryFile::parse<ELF32BE>();
>  template void BinaryFile::parse<ELF64LE>();
>  template void BinaryFile::parse<ELF64BE>();
> +
> +template std::vector<std::pair<StringRef, uint64_t>>
> +    elf::readSymbols<ELF32LE>(MemoryBufferRef);
> +template std::vector<std::pair<StringRef, uint64_t>>
> +    elf::readSymbols<ELF32BE>(MemoryBufferRef);
> +template std::vector<std::pair<StringRef, uint64_t>>
> +    elf::readSymbols<ELF64LE>(MemoryBufferRef);
> +template std::vector<std::pair<StringRef, uint64_t>>
> +    elf::readSymbols<ELF64BE>(MemoryBufferRef);
> Index: lld/ELF/Driver.cpp
> ===================================================================
> --- lld/ELF/Driver.cpp
> +++ lld/ELF/Driver.cpp
> @@ -1033,6 +1033,20 @@
>    if (errorCount())
>      return;
>  
> +  // Handle a rarely-used, --just-symbols option.
> +  //
> +  // This option allows you to link your output against other existing
> +  // program, so that if you load both the other program and your
> +  // output to memory, your output can refer other program's symbols.
> +  //
> +  // What we are doing here is to read defined symbols from given ELF
> +  // files and add them as absolute symbols.
> +  for (auto *Arg : Args.filtered(OPT_just_symbols))
> +    if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue()))
> +      for (std::pair<StringRef, uint64_t> KV : readSymbols<ELFT>(*MB))
> +        Symtab->addAbsolute<ELFT>(KV.first, STV_DEFAULT, STB_GLOBAL)->Value =
> +            KV.second;
> +
>    // Handle undefined symbols in DSOs.
>    Symtab->scanShlibUndefined<ELFT>();
>  
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list