Add an ELFSymbolRef type.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 25 Jun 2015 22:10:04 +0000 (22:10 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 25 Jun 2015 22:10:04 +0000 (22:10 +0000)
This allows user code to say Sym.getSize() instead of having to manually fetch
the object.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240708 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELFObjectFile.h
lib/Object/SymbolSize.cpp
lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
tools/llvm-nm/llvm-nm.cpp
tools/llvm-objdump/llvm-objdump.cpp

index 9ace1b06a65ba19441beafeee76f99cd8065b5f6..d78949cb505f84b8562cef698c5c7447809bb82b 100644 (file)
 namespace llvm {
 namespace object {
 
+class elf_symbol_iterator;
+class ELFSymbolRef;
+
 class ELFObjectFileBase : public ObjectFile {
+  friend class ELFSymbolRef;
+
 protected:
   ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
 
+  virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
+
 public:
   virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
 
@@ -46,17 +53,55 @@ public:
   // and addend or not.
   virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
 
-  virtual symbol_iterator_range getDynamicSymbolIterators() const = 0;
+  typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
+  virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
 
   virtual uint64_t getSectionFlags(SectionRef Sec) const = 0;
   virtual uint32_t getSectionType(SectionRef Sec) const = 0;
 
-  virtual uint64_t getSymbolSize(SymbolRef Symb) const = 0;
+  elf_symbol_iterator_range symbols() const;
 
   static inline bool classof(const Binary *v) { return v->isELF(); }
 };
 
+class ELFSymbolRef : public SymbolRef {
+public:
+  ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
+    assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
+  }
+
+  const ELFObjectFileBase *getObject() const {
+    return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
+  }
+
+  uint64_t getSize() const {
+    return getObject()->getSymbolSize(getRawDataRefImpl());
+  }
+};
+
+class elf_symbol_iterator : public symbol_iterator {
+public:
+  elf_symbol_iterator(const basic_symbol_iterator &B)
+      : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+                                  cast<ELFObjectFileBase>(B->getObject()))) {}
+
+  const ELFSymbolRef *operator->() const {
+    return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
+  }
+
+  const ELFSymbolRef &operator*() const {
+    return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
+  }
+};
+
+inline ELFObjectFileBase::elf_symbol_iterator_range
+ELFObjectFileBase::symbols() const {
+  return elf_symbol_iterator_range(symbol_begin(), symbol_end());
+}
+
 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
+  uint64_t getSymbolSize(DataRefImpl Sym) const override;
+
 public:
   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
 
@@ -73,8 +118,6 @@ public:
   typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
   typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
 
-  uint64_t getSymbolSize(SymbolRef Symb) const override;
-
 protected:
   ELFFile<ELFT> EF;
 
@@ -206,8 +249,8 @@ public:
   basic_symbol_iterator symbol_begin_impl() const override;
   basic_symbol_iterator symbol_end_impl() const override;
 
-  symbol_iterator dynamic_symbol_begin() const;
-  symbol_iterator dynamic_symbol_end() const;
+  elf_symbol_iterator dynamic_symbol_begin() const;
+  elf_symbol_iterator dynamic_symbol_end() const;
 
   section_iterator section_begin() const override;
   section_iterator section_end() const override;
@@ -236,7 +279,7 @@ public:
                                       ELFT::Is64Bits);
   }
 
-  symbol_iterator_range getDynamicSymbolIterators() const override;
+  elf_symbol_iterator_range getDynamicSymbolIterators() const override;
 
   bool isRelocatableObject() const override;
 };
@@ -327,8 +370,8 @@ uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
 }
 
 template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSymbolSize(SymbolRef Symb) const {
-  return toELFSymIter(Symb.getRawDataRefImpl())->st_size;
+uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
+  return toELFSymIter(Sym)->st_size;
 }
 
 template <class ELFT>
@@ -734,12 +777,12 @@ basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
 }
 
 template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
   return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
 }
 
 template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
   return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
 }
 
@@ -862,7 +905,7 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
 }
 
 template <class ELFT>
-ObjectFile::symbol_iterator_range
+ELFObjectFileBase::elf_symbol_iterator_range
 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
   return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
 }
index 78d620503a88f8d387b21c79cc216b46a6874f1e..730e54cf33052087d98fe4872aa8e35a74365e3c 100644 (file)
@@ -55,8 +55,8 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) {
     auto Syms = E->symbols();
     if (Syms.begin() == Syms.end())
       Syms = E->getDynamicSymbolIterators();
-    for (SymbolRef Sym : Syms)
-      Ret.push_back({Sym, E->getSymbolSize(Sym)});
+    for (ELFSymbolRef Sym : Syms)
+      Ret.push_back({Sym, Sym.getSize()});
     return Ret;
   }
 
index a84c4c584949325de09bf446cb1b2f51a99fd6a5..6c7fb0d3e1e6740c857fa4190df0aa0519a8147a 100644 (file)
@@ -27,12 +27,12 @@ public:
 
   const MCExpr *createExprForRelocation(RelocationRef Rel) override {
     uint64_t RelType; Rel.getType(RelType);
-    symbol_iterator SymI = Rel.getSymbol();
+    elf_symbol_iterator SymI = Rel.getSymbol();
 
     StringRef SymName; SymI->getName(SymName);
     uint64_t  SymAddr; SymI->getAddress(SymAddr);
     auto *Obj = cast<ELFObjectFileBase>(Rel.getObjectFile());
-    uint64_t SymSize = Obj->getSymbolSize(*SymI);
+    uint64_t SymSize = SymI->getSize();
     int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl());
 
     MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
index feff6aa487b6de401d48099b0c860aa1f399f6c8..16579883d75190ea70ab239dc49dc651a056c59b 100644 (file)
@@ -930,8 +930,8 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
     S.Size = 0;
     S.Address = UnknownAddress;
     if (PrintSize) {
-      if (auto *E = dyn_cast<ELFObjectFileBase>(&Obj))
-        S.Size = E->getSymbolSize(Sym);
+      if (isa<ELFObjectFileBase>(&Obj))
+        S.Size = ELFSymbolRef(Sym).getSize();
     }
     if (PrintAddress && isa<ObjectFile>(Obj)) {
       if (error(SymbolRef(Sym).getAddress(S.Address)))
index 518d6de34fac323cc6f297f544f52fe7d54cf434..24cedb38297f9e69b0216785ce0e20e08f6e5c82 100644 (file)
@@ -1149,8 +1149,8 @@ void llvm::PrintSymbolTable(const ObjectFile *o) {
 
     outs() << '\t';
     if (Common || isa<ELFObjectFileBase>(o)) {
-      uint64_t Val = Common ? Symbol.getAlignment()
-                            : cast<ELFObjectFileBase>(o)->getSymbolSize(Symbol);
+      uint64_t Val =
+          Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
       outs() << format("\t %08" PRIx64 " ", Val);
     }