[llvm] b6b0fd6 - [ifs] Add --strip-size flag

Alex Brachet via llvm-commits llvm-commits at lists.llvm.org
Sat May 14 10:25:58 PDT 2022


Author: Alex Brachet
Date: 2022-05-14T17:25:50Z
New Revision: b6b0fd6a940b7006ced344736decccffaa583b8a

URL: https://github.com/llvm/llvm-project/commit/b6b0fd6a940b7006ced344736decccffaa583b8a
DIFF: https://github.com/llvm/llvm-project/commit/b6b0fd6a940b7006ced344736decccffaa583b8a.diff

LOG: [ifs] Add --strip-size flag

st_size may not be of importance to the abi if you are not using
copy relocations. This is helpful when you want to check the abi
of a shared object both when instrumented and not because asan
will increase the size of objects to include the redzone.

Differential revision: https://reviews.llvm.org/D124792

Added: 
    llvm/test/tools/llvm-ifs/strip-size.test

Modified: 
    llvm/docs/CommandGuide/llvm-ifs.rst
    llvm/include/llvm/InterfaceStub/IFSStub.h
    llvm/lib/InterfaceStub/ELFObjHandler.cpp
    llvm/lib/InterfaceStub/IFSHandler.cpp
    llvm/tools/llvm-ifs/llvm-ifs.cpp
    llvm/unittests/InterfaceStub/ELFYAMLTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-ifs.rst b/llvm/docs/CommandGuide/llvm-ifs.rst
index 0e81806ec985a..1fe81c20e15dd 100644
--- a/llvm/docs/CommandGuide/llvm-ifs.rst
+++ b/llvm/docs/CommandGuide/llvm-ifs.rst
@@ -194,6 +194,13 @@ OPTIONS
  When this flag is set, llvm-ifs will only write the output file if it does not
  already exist or the content will be 
diff erent 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
 -----------
 

diff  --git a/llvm/include/llvm/InterfaceStub/IFSStub.h b/llvm/include/llvm/InterfaceStub/IFSStub.h
index 8747bd1bd35d1..0f935cd478d50 100644
--- a/llvm/include/llvm/InterfaceStub/IFSStub.h
+++ b/llvm/include/llvm/InterfaceStub/IFSStub.h
@@ -53,7 +53,7 @@ struct IFSSymbol {
   IFSSymbol() = default;
   explicit IFSSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {}
   std::string Name;
-  uint64_t Size;
+  Optional<uint64_t> Size;
   IFSSymbolType Type;
   bool Undefined;
   bool Weak;

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index 7420e159456ae..6f37cf6f7e8a9 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -217,7 +217,8 @@ template <class ELFT> class ELFStubBuilder {
       // 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();

diff  --git a/llvm/lib/InterfaceStub/IFSHandler.cpp b/llvm/lib/InterfaceStub/IFSHandler.cpp
index 92c88309a1587..82d65adbe43c3 100644
--- a/llvm/lib/InterfaceStub/IFSHandler.cpp
+++ b/llvm/lib/InterfaceStub/IFSHandler.cpp
@@ -118,11 +118,12 @@ template <> struct MappingTraits<IFSSymbol> {
     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);

diff  --git a/llvm/test/tools/llvm-ifs/strip-size.test b/llvm/test/tools/llvm-ifs/strip-size.test
new file mode 100644
index 0000000000000..2a89a20b7eea7
--- /dev/null
+++ b/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 }
+...

diff  --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp
index 1ac8c0df9d006..444a6d2dd58a5 100644
--- a/llvm/tools/llvm-ifs/llvm-ifs.cpp
+++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp
@@ -107,6 +107,10 @@ cl::opt<bool>
 cl::opt<bool> StripNeededLibs("strip-needed",
                               cl::desc("Strip needed libs from output"),
                               cl::cat(IfsCategory));
+cl::opt<bool> StripSize("strip-size",
+                        cl::desc("Remove object size from the output"),
+                        cl::cat(IfsCategory));
+
 cl::list<std::string>
     ExcludeSyms("exclude",
                 cl::desc("Remove symbols which match the pattern. Can be "
@@ -432,6 +436,10 @@ int main(int argc, char *argv[]) {
   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) {

diff  --git a/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp b/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp
index f6418f8f2a251..6e61d35947b7c 100644
--- a/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp
+++ b/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp
@@ -82,7 +82,7 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
   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 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
 
   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 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
 
   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 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
 
   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 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
 
   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);


        


More information about the llvm-commits mailing list