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
-----------
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;
// 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();
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);
+ // 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);
+ } else if (Symbol.Type != IFSSymbolType::Func) {
+ IO.mapOptional("Size", Symbol.Size);
}
IO.mapOptional("Undefined", Symbol.Undefined, false);
IO.mapOptional("Weak", Symbol.Weak, false);
--- /dev/null
+# 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 }
+...
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 "
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) {
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);
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);
IFSSymbol const &SymFoo = *Iterator++;
EXPECT_STREQ(SymFoo.Name.c_str(), "foo");
- EXPECT_EQ(SymFoo.Size, 0u);
+ EXPECT_FALSE(SymFoo.Size.hasValue());
EXPECT_EQ(SymFoo.Type, IFSSymbolType::Func);
EXPECT_FALSE(SymFoo.Undefined);
EXPECT_FALSE(SymFoo.Weak);
IFSSymbol const &SymNor = *Iterator++;
EXPECT_STREQ(SymNor.Name.c_str(), "nor");
- EXPECT_EQ(SymNor.Size, 0u);
+ EXPECT_FALSE(SymNor.Size.hasValue());
EXPECT_EQ(SymNor.Type, IFSSymbolType::NoType);
EXPECT_TRUE(SymNor.Undefined);
EXPECT_FALSE(SymNor.Weak);
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);