diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-25 03:07:42 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-25 03:07:42 +0000 |
commit | 3d3cc32f5fe815b7a38c2cb558b9d5f40fb0bbb1 (patch) | |
tree | a79a77e59f3f7eead86414dc850defb77dad7ea2 /tools/yaml2obj | |
parent | 24b56e94f68e58605450c4cea8f8644b722a4bae (diff) |
Don't compute a std::vector<uint8_t> just to write it out a stream.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180247 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/yaml2obj')
-rw-r--r-- | tools/yaml2obj/yaml2obj.cpp | 100 |
1 files changed, 17 insertions, 83 deletions
diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 2185b4f176..32dee54dc5 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -37,80 +37,6 @@ using namespace llvm; static cl::opt<std::string> Input(cl::Positional, cl::desc("<input>"), cl::init("-")); -template<class T> -typename llvm::enable_if_c<std::numeric_limits<T>::is_integer, bool>::type -getAs(const llvm::yaml::ScalarNode *SN, T &Result) { - SmallString<4> Storage; - StringRef Value = SN->getValue(Storage); - if (Value.getAsInteger(0, Result)) - return false; - return true; -} - -// Given a container with begin and end with ::value_type of a character type. -// Iterate through pairs of characters in the the set of [a-fA-F0-9] ignoring -// all other characters. -struct hex_pair_iterator { - StringRef::const_iterator Current, End; - typedef SmallVector<char, 2> value_type; - value_type Pair; - bool IsDone; - - hex_pair_iterator(StringRef C) - : Current(C.begin()), End(C.end()), IsDone(false) { - // Initalize Pair. - ++*this; - } - - // End iterator. - hex_pair_iterator() : Current(), End(), IsDone(true) {} - - value_type operator *() const { - return Pair; - } - - hex_pair_iterator operator ++() { - // We're at the end of the input. - if (Current == End) { - IsDone = true; - return *this; - } - Pair = value_type(); - for (; Current != End && Pair.size() != 2; ++Current) { - // Is a valid hex digit. - if ((*Current >= '0' && *Current <= '9') || - (*Current >= 'a' && *Current <= 'f') || - (*Current >= 'A' && *Current <= 'F')) - Pair.push_back(*Current); - } - // Hit the end without getting 2 hex digits. Pair is invalid. - if (Pair.size() != 2) - IsDone = true; - return *this; - } - - bool operator ==(const hex_pair_iterator Other) { - return (IsDone == Other.IsDone) || - (Current == Other.Current && End == Other.End); - } - - bool operator !=(const hex_pair_iterator Other) { - return !(*this == Other); - } -}; - -template <class ContainerOut> -static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { - for (hex_pair_iterator I(Str), E; I != E; ++I) { - typename hex_pair_iterator::value_type Pair = *I; - typename ContainerOut::value_type Byte; - if (StringRef(Pair.data(), 2).getAsInteger(16, Byte)) - return false; - Out.push_back(Byte); - } - return true; -} - // 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 { @@ -311,6 +237,21 @@ binary_le_impl<value_type> binary_le(value_type V) { return binary_le_impl<value_type>(V); } +static bool writeHexData(StringRef Data, raw_ostream &OS) { + unsigned Size = Data.size(); + if (Size % 2) + return false; + + for (unsigned I = 0; I != Size; I += 2) { + uint8_t Byte; + if (Data.substr(I, 2).getAsInteger(16, Byte)) + return false; + OS.write(Byte); + } + + return true; +} + bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS << binary_le(CP.Obj.Header.Machine) << binary_le(CP.Obj.Header.NumberOfSections) @@ -341,13 +282,10 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { e = CP.Obj.Sections.end(); i != e; ++i) { if (!i->SectionData.empty()) { - std::vector<uint8_t> Data; - if (!hexStringToByteArray(i->SectionData, Data)) { + if (!writeHexData(i->SectionData, OS)) { errs() << "SectionData must be a collection of pairs of hex bytes"; return false; } - - OS.write(reinterpret_cast<const char*>(&Data[0]), Data.size()); } for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) { const COFF::relocation &R = i->Relocations[I2]; @@ -369,14 +307,10 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); if (!i->AuxiliaryData.empty()) { - std::vector<uint8_t> AuxSymbols; - if (!hexStringToByteArray(i->AuxiliaryData, AuxSymbols)) { + if (!writeHexData(i->AuxiliaryData, OS)) { errs() << "AuxiliaryData must be a collection of pairs of hex bytes"; return false; } - - OS.write(reinterpret_cast<const char*>(&AuxSymbols[0]), - AuxSymbols.size()); } } |