Index: llvm/docs/CommandGuide/llvm-ifs.rst =================================================================== --- llvm/docs/CommandGuide/llvm-ifs.rst +++ llvm/docs/CommandGuide/llvm-ifs.rst @@ -194,6 +194,13 @@ When this flag is set, llvm-ifs will only write the output file if it does not already exist or the content will be different from the existing file. +.. option:: --strip-size + + When this flag is set, llvm-ifs will remove the size field from the output ifs + file. This is useful for shared objects that only intend to be linked against + position independent code which doesn't need copy relocations, or where the size + of an object is not a useful part of the abi to track. + EXIT STATUS ----------- Index: llvm/include/llvm/InterfaceStub/IFSStub.h =================================================================== --- llvm/include/llvm/InterfaceStub/IFSStub.h +++ llvm/include/llvm/InterfaceStub/IFSStub.h @@ -53,7 +53,7 @@ IFSSymbol() = default; explicit IFSSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {} std::string Name; - uint64_t Size; + Optional Size; IFSSymbolType Type; bool Undefined; bool Weak; Index: llvm/lib/InterfaceStub/ELFObjHandler.cpp =================================================================== --- llvm/lib/InterfaceStub/ELFObjHandler.cpp +++ llvm/lib/InterfaceStub/ELFObjHandler.cpp @@ -217,7 +217,8 @@ // time as long as it is not SHN_UNDEF. Set shndx to 1, which // points to ".dynsym". uint16_t Shndx = Sym.Undefined ? SHN_UNDEF : 1; - DynSym.Content.add(DynStr.Content.getOffset(Sym.Name), Sym.Size, Bind, + uint64_t Size = Sym.Size ? *Sym.Size : 0; + DynSym.Content.add(DynStr.Content.getOffset(Sym.Name), Size, Bind, convertIFSSymbolTypeToELF(Sym.Type), 0, Shndx); } DynSym.Size = DynSym.Content.getSize(); Index: llvm/lib/InterfaceStub/IFSHandler.cpp =================================================================== --- llvm/lib/InterfaceStub/IFSHandler.cpp +++ llvm/lib/InterfaceStub/IFSHandler.cpp @@ -118,11 +118,12 @@ IO.mapRequired("Type", Symbol.Type); // The need for symbol size depends on the symbol type. if (Symbol.Type == IFSSymbolType::NoType) { - IO.mapOptional("Size", Symbol.Size, (uint64_t)0); - } else if (Symbol.Type == IFSSymbolType::Func) { - Symbol.Size = 0; - } else { - IO.mapRequired("Size", Symbol.Size); + // Either Size is None, so we are reading it in, or it is non 0 so we + // should emit it. + if (!Symbol.Size || *Symbol.Size) + IO.mapOptional("Size", Symbol.Size, (uint64_t)0); + } else if (Symbol.Type != IFSSymbolType::Func) { + IO.mapOptional("Size", Symbol.Size); } IO.mapOptional("Undefined", Symbol.Undefined, false); IO.mapOptional("Weak", Symbol.Weak, false); Index: llvm/test/tools/llvm-ifs/strip-size.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-ifs/strip-size.test @@ -0,0 +1,20 @@ +# RUN: llvm-ifs %s --output-ifs - --strip-size | FileCheck %s + +# CHECK: Symbols: +# CHECK-NEXT: - { Name: sym, Type: Object } +# CHECK-NEXT: ... + +## Check that the size when emitting to elf defaults to 1. +# RUN: llvm-ifs %s --output-elf - --strip-size | llvm-ifs - --output-ifs - | \ +# RUN: FileCheck %s --check-prefix=ELF + +# ELF: Symbols: +# ELF-NEXT: - { Name: sym, Type: Object, Size: 0 } +# ELF-NEXT: ... + +--- !ifs-v1 +IfsVersion: 3.0 +Target: x86_64 +Symbols: + - { Name: sym, Type: Object, Size: 2 } +... Index: llvm/tools/llvm-ifs/llvm-ifs.cpp =================================================================== --- llvm/tools/llvm-ifs/llvm-ifs.cpp +++ llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -107,6 +107,10 @@ cl::opt StripNeededLibs("strip-needed", cl::desc("Strip needed libs from output"), cl::cat(IfsCategory)); +cl::opt StripSize("strip-size", + cl::desc("Remove object size from the output"), + cl::cat(IfsCategory)); + cl::list ExcludeSyms("exclude", cl::desc("Remove symbols which match the pattern. Can be " @@ -432,6 +436,10 @@ if (Error E = filterIFSSyms(Stub, StripUndefined, ExcludeSyms)) fatalError(std::move(E)); + if (StripSize) + for (IFSSymbol &Sym : Stub.Symbols) + Sym.Size.reset(); + if (OutputELFFilePath.getNumOccurrences() == 0 && OutputIFSFilePath.getNumOccurrences() == 0 && OutputTBDFilePath.getNumOccurrences() == 0) { Index: llvm/unittests/InterfaceStub/ELFYAMLTest.cpp =================================================================== --- llvm/unittests/InterfaceStub/ELFYAMLTest.cpp +++ llvm/unittests/InterfaceStub/ELFYAMLTest.cpp @@ -82,7 +82,7 @@ auto Iterator = Stub->Symbols.begin(); IFSSymbol const &SymBar = *Iterator++; EXPECT_STREQ(SymBar.Name.c_str(), "bar"); - EXPECT_EQ(SymBar.Size, 42u); + EXPECT_EQ(*SymBar.Size, 42u); EXPECT_EQ(SymBar.Type, IFSSymbolType::Object); EXPECT_FALSE(SymBar.Undefined); EXPECT_FALSE(SymBar.Weak); @@ -90,7 +90,7 @@ IFSSymbol const &SymBaz = *Iterator++; EXPECT_STREQ(SymBaz.Name.c_str(), "baz"); - EXPECT_EQ(SymBaz.Size, 3u); + EXPECT_EQ(*SymBaz.Size, 3u); EXPECT_EQ(SymBaz.Type, IFSSymbolType::TLS); EXPECT_FALSE(SymBaz.Undefined); EXPECT_FALSE(SymBaz.Weak); @@ -98,7 +98,7 @@ IFSSymbol const &SymFoo = *Iterator++; EXPECT_STREQ(SymFoo.Name.c_str(), "foo"); - EXPECT_EQ(SymFoo.Size, 0u); + EXPECT_EQ(*SymFoo.Size, 0u); EXPECT_EQ(SymFoo.Type, IFSSymbolType::Func); EXPECT_FALSE(SymFoo.Undefined); EXPECT_FALSE(SymFoo.Weak); @@ -107,7 +107,7 @@ IFSSymbol const &SymNor = *Iterator++; EXPECT_STREQ(SymNor.Name.c_str(), "nor"); - EXPECT_EQ(SymNor.Size, 0u); + EXPECT_EQ(*SymNor.Size, 0u); EXPECT_EQ(SymNor.Type, IFSSymbolType::NoType); EXPECT_TRUE(SymNor.Undefined); EXPECT_FALSE(SymNor.Weak); @@ -115,7 +115,7 @@ IFSSymbol const &SymNot = *Iterator++; EXPECT_STREQ(SymNot.Name.c_str(), "not"); - EXPECT_EQ(SymNot.Size, 111u); + EXPECT_EQ(*SymNot.Size, 111u); EXPECT_EQ(SymNot.Type, IFSSymbolType::Unknown); EXPECT_TRUE(SymNot.Undefined); EXPECT_TRUE(SymNot.Weak);