[PATCH] D41277: Implement --just-symbols

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 18 17:54:30 PST 2017


This patch allows --just-symbols to be a ET_DYN, ET_REL or ET_EXEC. Do
you need all 3? ET_REL in particular seems problematic since st_value
has a different meaning in relocatable files.

If you don't need ET_DYN or ET_REL, please reject them. If you need
them, please add a test.


Chih-Mao Chen via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:

> PkmX updated this revision to Diff 127237.
> PkmX added a comment.
>
> - Copy symbol type, size, binding, etc, like https://reviews.llvm.org/D39348.
> - Update test cases.
>
>
> https://reviews.llvm.org/D41277
>
> Files:
>   ELF/Driver.cpp
>   ELF/InputFiles.cpp
>   ELF/InputFiles.h
>   ELF/Options.td
>   ELF/SymbolTable.cpp
>   test/ELF/Inputs/just-symbols.s
>   test/ELF/just-symbols.s
>
> Index: test/ELF/just-symbols.s
> ===================================================================
> --- /dev/null
> +++ test/ELF/just-symbols.s
> @@ -0,0 +1,20 @@
> +# 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 -Tdata=0x11000
> +
> +# 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
> +#
> +# RUN: ld.lld -just-symbols=%t1.exe -o %t3.exe
> +# RUN: llvm-readelf -symbols %t3.exe | FileCheck %s
> +
> +# CHECK: 0000000000011000    40 OBJECT  GLOBAL DEFAULT  ABS bar
> +# CHECK: 0000000000010000     0 NOTYPE  GLOBAL DEFAULT  ABS foo
> +
> +.globl _start
> +_start:
> +  call foo
> +  call bar
> +  ret
> Index: test/ELF/Inputs/just-symbols.s
> ===================================================================
> --- /dev/null
> +++ test/ELF/Inputs/just-symbols.s
> @@ -0,0 +1,9 @@
> +.globl foo, bar
> +foo:
> +  ret
> +
> +.section .data
> +.type bar, @object
> +.size bar, 40
> +bar:
> +  .zero 40
> Index: ELF/SymbolTable.cpp
> ===================================================================
> --- ELF/SymbolTable.cpp
> +++ ELF/SymbolTable.cpp
> @@ -74,6 +74,12 @@
>      return;
>    }
>  
> +  // --just-symbols file
> +  if (auto *F = dyn_cast<JustSymbolsFile<ELFT>>(File)) {
> +    F->parse();
> +    return;
> +  }
> +
>    // .a file
>    if (auto *F = dyn_cast<ArchiveFile>(File)) {
>      F->parse<ELFT>();
> Index: ELF/Options.td
> ===================================================================
> --- ELF/Options.td
> +++ ELF/Options.td
> @@ -153,6 +153,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: ELF/InputFiles.h
> ===================================================================
> --- ELF/InputFiles.h
> +++ ELF/InputFiles.h
> @@ -68,6 +68,7 @@
>      ArchiveKind,
>      BitcodeKind,
>      BinaryKind,
> +    JustSymbolsKind,
>    };
>  
>    Kind kind() const { return FileKind; }
> @@ -123,7 +124,7 @@
>    ELFFileBase(Kind K, MemoryBufferRef M);
>    static bool classof(const InputFile *F) {
>      Kind K = F->kind();
> -    return K == ObjKind || K == SharedKind;
> +    return K == ObjKind || K == SharedKind || K == JustSymbolsKind;
>    }
>  
>    llvm::object::ELFFile<ELFT> getObj() const {
> @@ -328,9 +329,20 @@
>    template <class ELFT> void parse();
>  };
>  
> +template <class ELFT> class JustSymbolsFile : public ELFFileBase<ELFT> {
> +public:
> +  explicit JustSymbolsFile(MemoryBufferRef M)
> +      : ELFFileBase<ELFT>(InputFile::JustSymbolsKind, M) {}
> +  static bool classof(const InputFile *F) {
> +    return F->kind() == InputFile::JustSymbolsKind;
> +  }
> +  void parse();
> +};
> +
>  InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
>                              uint64_t OffsetInArchive = 0);
>  InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
> +InputFile *createJustSymbolsFile(MemoryBufferRef MB);
>  
>  extern std::vector<BinaryFile *> BinaryFiles;
>  extern std::vector<BitcodeFile *> BitcodeFiles;
> Index: ELF/InputFiles.cpp
> ===================================================================
> --- ELF/InputFiles.cpp
> +++ ELF/InputFiles.cpp
> @@ -1007,6 +1007,34 @@
>                             Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
>  }
>  
> +template <class ELFT> void JustSymbolsFile<ELFT>::parse() {
> +  typedef typename ELFT::Shdr Elf_Shdr;
> +  typedef typename ELFT::Sym Elf_Sym;
> +  typedef typename ELFT::SymRange Elf_Sym_Range;
> +
> +  StringRef ObjName = this->getName();
> +  ELFFile<ELFT> Obj = this->getObj();
> +  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);
> +
> +    for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal))
> +      if (Sym.st_shndx != SHN_UNDEF) {
> +        StringRef SymName = CHECK(Sym.getName(StringTable), ObjName);
> +        Symtab->addRegular<ELFT>(SymName, Sym.st_other, Sym.getType(),
> +                                 Sym.st_value, Sym.st_size, Sym.getBinding(),
> +                                 nullptr, nullptr);
> +      }
> +  }
> +}
> +
>  static bool isBitcode(MemoryBufferRef MB) {
>    using namespace sys::fs;
>    return identify_magic(MB.getBuffer()) == file_magic::bitcode;
> @@ -1046,6 +1074,21 @@
>    }
>  }
>  
> +InputFile *elf::createJustSymbolsFile(MemoryBufferRef MB) {
> +  switch (getELFKind(MB)) {
> +  case ELF32LEKind:
> +    return make<JustSymbolsFile<ELF32LE>>(MB);
> +  case ELF32BEKind:
> +    return make<JustSymbolsFile<ELF32BE>>(MB);
> +  case ELF64LEKind:
> +    return make<JustSymbolsFile<ELF64LE>>(MB);
> +  case ELF64BEKind:
> +    return make<JustSymbolsFile<ELF64BE>>(MB);
> +  default:
> +    llvm_unreachable("getELFKind");
> +  }
> +}
> +
>  MemoryBufferRef LazyObjFile::getBuffer() {
>    if (Seen)
>      return MemoryBufferRef();
> @@ -1153,3 +1196,8 @@
>  template void BinaryFile::parse<ELF32BE>();
>  template void BinaryFile::parse<ELF64LE>();
>  template void BinaryFile::parse<ELF64BE>();
> +
> +template class elf::JustSymbolsFile<ELF32LE>;
> +template class elf::JustSymbolsFile<ELF32BE>;
> +template class elf::JustSymbolsFile<ELF64LE>;
> +template class elf::JustSymbolsFile<ELF64BE>;
> Index: ELF/Driver.cpp
> ===================================================================
> --- ELF/Driver.cpp
> +++ ELF/Driver.cpp
> @@ -832,6 +832,20 @@
>        }
>        error(Twine("cannot find linker script ") + Arg->getValue());
>        break;
> +    // 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.
> +    case OPT_just_symbols: {
> +      Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue());
> +      if (Buffer.hasValue())
> +        Files.push_back(createJustSymbolsFile(*Buffer));
> +      break;
> +    }
>      case OPT_as_needed:
>        Config->AsNeeded = true;
>        break;
> _______________________________________________
> 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