[PATCH] D41277: Implement --just-symbols
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 25 17:35:27 PST 2017
The version *without* the -R alias LGTM.
Do you have commit access?
Thanks,
Rafael
Chih-Mao Chen via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:
> PkmX updated this revision to Diff 127465.
> PkmX added a comment.
>
> Added a check to only allow `ET_EXEC` and the corresponding test.
>
> On Tue, Dec 19, 2017 at 9:54 AM, Rafael Avila de Espindola <rafael.espindola at gmail.com> wrote:
>
>> 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.
>
> `ld.bfd` accepts `ET_EXEC` and `ET_REL` but not `ET_DYN`. However I don't think this option makes much sense for `ET_REL` inputs so I'm restricting it to `ET_EXEC` for now.
>
>
> 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,23 @@
> +# 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
> +
> +# RUN: not ld.lld -just-symbols=%t1 2>&1 | FileCheck %s --check-prefix CHECK-REL
> +# CHECK-REL: error: {{.*}}: --just-symbols only accepts ET_EXEC files
> +
> +.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,38 @@
> 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();
> +
> + if (Obj.getHeader()->e_type != ET_EXEC)
> + error(toString(this) + ": --just-symbols only accepts ET_EXEC files");
> +
> + 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 +1078,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 +1200,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