Don't allocate temporary string for section data.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 31 May 2013 20:26:44 +0000 (20:26 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 31 May 2013 20:26:44 +0000 (20:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183040 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/COFFYaml.h
lib/Object/COFFYAML.cpp
tools/obj2yaml/coff2yaml.cpp
tools/yaml2obj/yaml2obj.cpp

index 08cbab428c0635b3f7132d80dfe76ba186f9d62b..f4732e23bc00030431cd94d284331e00c23a9c0b 100644 (file)
@@ -36,10 +36,34 @@ inline SectionCharacteristics operator|(SectionCharacteristics a,
 // The structure of the yaml files is not an exact 1:1 match to COFF. In order
 // to use yaml::IO, we use these structures which are closer to the source.
 namespace COFFYAML {
+  /// In an object file this is just a binary blob. In an yaml file it is an hex
+  /// string. Using this avoid having to allocate temporary strings.
+  /// FIXME: not COFF specific.
+  class BinaryRef {
+    union {
+      ArrayRef<uint8_t> BinaryData;
+      StringRef HexData;
+    };
+    bool isBinary;
+  public:
+    BinaryRef(ArrayRef<uint8_t> BinaryData)
+        : BinaryData(BinaryData), isBinary(true) {}
+    BinaryRef(StringRef HexData) : HexData(HexData), isBinary(false) {}
+    BinaryRef() : isBinary(false) {}
+    StringRef getHex() const {
+      assert(!isBinary);
+      return HexData;
+    }
+    ArrayRef<uint8_t> getBinary() const {
+      assert(isBinary);
+      return BinaryData;
+    }
+  };
+
   struct Section {
     COFF::section Header;
     unsigned Alignment;
-    StringRef SectionData;
+    BinaryRef SectionData;
     std::vector<COFF::relocation> Relocations;
     StringRef Name;
     Section();
@@ -49,7 +73,7 @@ namespace COFFYAML {
     COFF::symbol Header;
     COFF::SymbolBaseType SimpleType;
     COFF::SymbolComplexType ComplexType;
-    StringRef AuxiliaryData;
+    BinaryRef AuxiliaryData;
     StringRef Name;
     Symbol();
   };
@@ -70,6 +94,12 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(COFF::relocation)
 namespace llvm {
 namespace yaml {
 
+template<>
+struct ScalarTraits<COFFYAML::BinaryRef> {
+  static void output(const COFFYAML::BinaryRef &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, COFFYAML::BinaryRef &);
+};
+
 template <>
 struct ScalarEnumerationTraits<COFF::MachineTypes> {
   static void enumeration(IO &IO, COFF::MachineTypes &Value);
index 7a154525e2a3a406021cb0424491c4620ca0d6f2..0ece09f460bc98c49c55f881539681bef5988889 100644 (file)
@@ -229,6 +229,23 @@ struct NType {
 
 }
 
+void ScalarTraits<COFFYAML::BinaryRef>::output(const COFFYAML::BinaryRef &Val,
+                                               void *, llvm::raw_ostream &Out) {
+  ArrayRef<uint8_t> Data = Val.getBinary();
+  for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
+       ++I) {
+    uint8_t Byte = *I;
+    Out << hexdigit(Byte >> 4);
+    Out << hexdigit(Byte & 0xf);
+  }
+}
+
+StringRef ScalarTraits<COFFYAML::BinaryRef>::input(StringRef Scalar, void *,
+                                                   COFFYAML::BinaryRef &Val) {
+  Val = COFFYAML::BinaryRef(Scalar);
+  return StringRef();
+}
+
 void MappingTraits<COFF::relocation>::mapping(IO &IO, COFF::relocation &Rel) {
   MappingNormalization<NType, uint16_t> NT(IO, Rel.Type);
 
index 0bb3e24c3cad375c5b14a60abe316404ee8302c3..b41edc1e8a01ae0d56f3d98bb4ce018b791c4e24 100644 (file)
@@ -13,8 +13,6 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/YAMLTraits.h"
 
-#include <list>
-
 using namespace llvm;
 
 namespace {
@@ -25,8 +23,6 @@ class COFFDumper {
   void dumpHeader(const object::coff_file_header *Header);
   void dumpSections(unsigned numSections);
   void dumpSymbols(unsigned numSymbols);
-  StringRef getHexString(ArrayRef<uint8_t> Data);
-  std::list<std::string> Strings;
 
 public:
   COFFDumper(const object::COFFObjectFile &Obj);
@@ -68,7 +64,7 @@ void COFFDumper::dumpSections(unsigned NumSections) {
 
     ArrayRef<uint8_t> sectionData;
     Obj.getSectionContents(Sect, sectionData);
-    Sec.SectionData = getHexString(sectionData);
+    Sec.SectionData = COFFYAML::BinaryRef(sectionData);
 
     std::vector<COFF::relocation> Relocations;
     for (object::relocation_iterator rIter = iter->begin_relocations();
@@ -100,23 +96,11 @@ void COFFDumper::dumpSymbols(unsigned NumSymbols) {
     Sym.Header.Value = Symbol->Value;
     Sym.Header.SectionNumber = Symbol->SectionNumber;
     Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
-    Sym.AuxiliaryData = getHexString(Obj.getSymbolAuxData(Symbol));
+    Sym.AuxiliaryData = COFFYAML::BinaryRef(Obj.getSymbolAuxData(Symbol));
     Symbols.push_back(Sym);
   }
 }
 
-StringRef COFFDumper::getHexString(ArrayRef<uint8_t> Data) {
-  std::string S;
-  for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
-       ++I) {
-    uint8_t Byte = *I;
-    S.push_back(hexdigit(Byte >> 4));
-    S.push_back(hexdigit(Byte & 0xf));
-  }
-  Strings.push_back(S);
-  return Strings.back();
-}
-
 COFFYAML::Object &COFFDumper::getYAMLObj() {
   return YAMLObj;
 }
index d9843463cc0eb7d55ba44b8bc644cf83e01e7da6..0c285c2fd8c62584b3d7e5efe9a68a476461f653 100644 (file)
@@ -139,8 +139,9 @@ static bool layoutCOFF(COFFParser &CP) {
   for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
                                                 e = CP.Obj.Sections.end();
                                                 i != e; ++i) {
-    if (!i->SectionData.empty()) {
-      i->Header.SizeOfRawData = i->SectionData.size()/2;
+    StringRef SecData = i->SectionData.getHex();
+    if (!SecData.empty()) {
+      i->Header.SizeOfRawData = SecData.size()/2;
       i->Header.PointerToRawData = CurrentSectionDataOffset;
       CurrentSectionDataOffset += i->Header.SizeOfRawData;
       if (!i->Relocations.empty()) {
@@ -163,7 +164,7 @@ static bool layoutCOFF(COFFParser &CP) {
   for (std::vector<COFFYAML::Symbol>::iterator i = CP.Obj.Symbols.begin(),
                                                e = CP.Obj.Symbols.end();
                                                i != e; ++i) {
-    unsigned AuxBytes = i->AuxiliaryData.size() / 2;
+    unsigned AuxBytes = i->AuxiliaryData.getHex().size() / 2;
     if (AuxBytes % COFF::SymbolSize != 0) {
       errs() << "AuxiliaryData size not a multiple of symbol size!\n";
       return false;
@@ -248,8 +249,9 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
   for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
                                                 e = CP.Obj.Sections.end();
                                                 i != e; ++i) {
-    if (!i->SectionData.empty()) {
-      if (!writeHexData(i->SectionData, OS)) {
+    StringRef SecData = i->SectionData.getHex();
+    if (!SecData.empty()) {
+      if (!writeHexData(SecData, OS)) {
         errs() << "SectionData must be a collection of pairs of hex bytes";
         return false;
       }
@@ -273,8 +275,9 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
        << binary_le(i->Header.Type)
        << binary_le(i->Header.StorageClass)
        << binary_le(i->Header.NumberOfAuxSymbols);
-    if (!i->AuxiliaryData.empty()) {
-      if (!writeHexData(i->AuxiliaryData, OS)) {
+    StringRef Data = i->AuxiliaryData.getHex();
+    if (!Data.empty()) {
+      if (!writeHexData(Data, OS)) {
         errs() << "AuxiliaryData must be a collection of pairs of hex bytes";
         return false;
       }