1*3add3e9cSRafael Espindola //===- yaml2obj - Convert YAML to a binary object file --------------------===// 2*3add3e9cSRafael Espindola // 3*3add3e9cSRafael Espindola // The LLVM Compiler Infrastructure 4*3add3e9cSRafael Espindola // 5*3add3e9cSRafael Espindola // This file is distributed under the University of Illinois Open Source 6*3add3e9cSRafael Espindola // License. See LICENSE.TXT for details. 7*3add3e9cSRafael Espindola // 8*3add3e9cSRafael Espindola //===----------------------------------------------------------------------===// 9*3add3e9cSRafael Espindola // 10*3add3e9cSRafael Espindola // This program takes a YAML description of an object file and outputs the 11*3add3e9cSRafael Espindola // binary equivalent. 12*3add3e9cSRafael Espindola // 13*3add3e9cSRafael Espindola // This is used for writing tests that require binary files. 14*3add3e9cSRafael Espindola // 15*3add3e9cSRafael Espindola //===----------------------------------------------------------------------===// 16*3add3e9cSRafael Espindola 17*3add3e9cSRafael Espindola #include "llvm/ADT/SmallString.h" 18*3add3e9cSRafael Espindola #include "llvm/ADT/StringExtras.h" 19*3add3e9cSRafael Espindola #include "llvm/ADT/StringMap.h" 20*3add3e9cSRafael Espindola #include "llvm/ADT/StringSwitch.h" 21*3add3e9cSRafael Espindola #include "llvm/Support/COFF.h" 22*3add3e9cSRafael Espindola #include "llvm/Support/Casting.h" 23*3add3e9cSRafael Espindola #include "llvm/Support/CommandLine.h" 24*3add3e9cSRafael Espindola #include "llvm/Support/Endian.h" 25*3add3e9cSRafael Espindola #include "llvm/Support/ManagedStatic.h" 26*3add3e9cSRafael Espindola #include "llvm/Support/MemoryBuffer.h" 27*3add3e9cSRafael Espindola #include "llvm/Support/PrettyStackTrace.h" 28*3add3e9cSRafael Espindola #include "llvm/Support/Signals.h" 29*3add3e9cSRafael Espindola #include "llvm/Support/SourceMgr.h" 30*3add3e9cSRafael Espindola #include "llvm/Support/YAMLTraits.h" 31*3add3e9cSRafael Espindola #include "llvm/Support/raw_ostream.h" 32*3add3e9cSRafael Espindola #include "llvm/Support/system_error.h" 33*3add3e9cSRafael Espindola #include <vector> 34*3add3e9cSRafael Espindola 35*3add3e9cSRafael Espindola using namespace llvm; 36*3add3e9cSRafael Espindola 37*3add3e9cSRafael Espindola static cl::opt<std::string> 38*3add3e9cSRafael Espindola Input(cl::Positional, cl::desc("<input>"), cl::init("-")); 39*3add3e9cSRafael Espindola 40*3add3e9cSRafael Espindola template<class T> 41*3add3e9cSRafael Espindola typename llvm::enable_if_c<std::numeric_limits<T>::is_integer, bool>::type 42*3add3e9cSRafael Espindola getAs(const llvm::yaml::ScalarNode *SN, T &Result) { 43*3add3e9cSRafael Espindola SmallString<4> Storage; 44*3add3e9cSRafael Espindola StringRef Value = SN->getValue(Storage); 45*3add3e9cSRafael Espindola if (Value.getAsInteger(0, Result)) 46*3add3e9cSRafael Espindola return false; 47*3add3e9cSRafael Espindola return true; 48*3add3e9cSRafael Espindola } 49*3add3e9cSRafael Espindola 50*3add3e9cSRafael Espindola // Given a container with begin and end with ::value_type of a character type. 51*3add3e9cSRafael Espindola // Iterate through pairs of characters in the the set of [a-fA-F0-9] ignoring 52*3add3e9cSRafael Espindola // all other characters. 53*3add3e9cSRafael Espindola struct hex_pair_iterator { 54*3add3e9cSRafael Espindola StringRef::const_iterator Current, End; 55*3add3e9cSRafael Espindola typedef SmallVector<char, 2> value_type; 56*3add3e9cSRafael Espindola value_type Pair; 57*3add3e9cSRafael Espindola bool IsDone; 58*3add3e9cSRafael Espindola 59*3add3e9cSRafael Espindola hex_pair_iterator(StringRef C) 60*3add3e9cSRafael Espindola : Current(C.begin()), End(C.end()), IsDone(false) { 61*3add3e9cSRafael Espindola // Initalize Pair. 62*3add3e9cSRafael Espindola ++*this; 63*3add3e9cSRafael Espindola } 64*3add3e9cSRafael Espindola 65*3add3e9cSRafael Espindola // End iterator. 66*3add3e9cSRafael Espindola hex_pair_iterator() : Current(), End(), IsDone(true) {} 67*3add3e9cSRafael Espindola 68*3add3e9cSRafael Espindola value_type operator *() const { 69*3add3e9cSRafael Espindola return Pair; 70*3add3e9cSRafael Espindola } 71*3add3e9cSRafael Espindola 72*3add3e9cSRafael Espindola hex_pair_iterator operator ++() { 73*3add3e9cSRafael Espindola // We're at the end of the input. 74*3add3e9cSRafael Espindola if (Current == End) { 75*3add3e9cSRafael Espindola IsDone = true; 76*3add3e9cSRafael Espindola return *this; 77*3add3e9cSRafael Espindola } 78*3add3e9cSRafael Espindola Pair = value_type(); 79*3add3e9cSRafael Espindola for (; Current != End && Pair.size() != 2; ++Current) { 80*3add3e9cSRafael Espindola // Is a valid hex digit. 81*3add3e9cSRafael Espindola if ((*Current >= '0' && *Current <= '9') || 82*3add3e9cSRafael Espindola (*Current >= 'a' && *Current <= 'f') || 83*3add3e9cSRafael Espindola (*Current >= 'A' && *Current <= 'F')) 84*3add3e9cSRafael Espindola Pair.push_back(*Current); 85*3add3e9cSRafael Espindola } 86*3add3e9cSRafael Espindola // Hit the end without getting 2 hex digits. Pair is invalid. 87*3add3e9cSRafael Espindola if (Pair.size() != 2) 88*3add3e9cSRafael Espindola IsDone = true; 89*3add3e9cSRafael Espindola return *this; 90*3add3e9cSRafael Espindola } 91*3add3e9cSRafael Espindola 92*3add3e9cSRafael Espindola bool operator ==(const hex_pair_iterator Other) { 93*3add3e9cSRafael Espindola return (IsDone == Other.IsDone) || 94*3add3e9cSRafael Espindola (Current == Other.Current && End == Other.End); 95*3add3e9cSRafael Espindola } 96*3add3e9cSRafael Espindola 97*3add3e9cSRafael Espindola bool operator !=(const hex_pair_iterator Other) { 98*3add3e9cSRafael Espindola return !(*this == Other); 99*3add3e9cSRafael Espindola } 100*3add3e9cSRafael Espindola }; 101*3add3e9cSRafael Espindola 102*3add3e9cSRafael Espindola template <class ContainerOut> 103*3add3e9cSRafael Espindola static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { 104*3add3e9cSRafael Espindola for (hex_pair_iterator I(Str), E; I != E; ++I) { 105*3add3e9cSRafael Espindola typename hex_pair_iterator::value_type Pair = *I; 106*3add3e9cSRafael Espindola typename ContainerOut::value_type Byte; 107*3add3e9cSRafael Espindola if (StringRef(Pair.data(), 2).getAsInteger(16, Byte)) 108*3add3e9cSRafael Espindola return false; 109*3add3e9cSRafael Espindola Out.push_back(Byte); 110*3add3e9cSRafael Espindola } 111*3add3e9cSRafael Espindola return true; 112*3add3e9cSRafael Espindola } 113*3add3e9cSRafael Espindola 114*3add3e9cSRafael Espindola // The structure of the yaml files is not an exact 1:1 match to COFF. In order 115*3add3e9cSRafael Espindola // to use yaml::IO, we use these structures which are closer to the source. 116*3add3e9cSRafael Espindola namespace COFFYAML { 117*3add3e9cSRafael Espindola struct Relocation { 118*3add3e9cSRafael Espindola uint32_t VirtualAddress; 119*3add3e9cSRafael Espindola uint32_t SymbolTableIndex; 120*3add3e9cSRafael Espindola COFF::RelocationTypeX86 Type; 121*3add3e9cSRafael Espindola }; 122*3add3e9cSRafael Espindola 123*3add3e9cSRafael Espindola struct Section { 124*3add3e9cSRafael Espindola COFF::SectionCharacteristics Characteristics; 125*3add3e9cSRafael Espindola StringRef SectionData; 126*3add3e9cSRafael Espindola std::vector<Relocation> Relocations; 127*3add3e9cSRafael Espindola StringRef Name; 128*3add3e9cSRafael Espindola }; 129*3add3e9cSRafael Espindola 130*3add3e9cSRafael Espindola struct Header { 131*3add3e9cSRafael Espindola COFF::MachineTypes Machine; 132*3add3e9cSRafael Espindola COFF::Characteristics Characteristics; 133*3add3e9cSRafael Espindola }; 134*3add3e9cSRafael Espindola 135*3add3e9cSRafael Espindola struct Symbol { 136*3add3e9cSRafael Espindola COFF::SymbolBaseType SimpleType; 137*3add3e9cSRafael Espindola uint8_t NumberOfAuxSymbols; 138*3add3e9cSRafael Espindola StringRef Name; 139*3add3e9cSRafael Espindola COFF::SymbolStorageClass StorageClass; 140*3add3e9cSRafael Espindola StringRef AuxillaryData; 141*3add3e9cSRafael Espindola COFF::SymbolComplexType ComplexType; 142*3add3e9cSRafael Espindola uint32_t Value; 143*3add3e9cSRafael Espindola uint16_t SectionNumber; 144*3add3e9cSRafael Espindola }; 145*3add3e9cSRafael Espindola 146*3add3e9cSRafael Espindola struct Object { 147*3add3e9cSRafael Espindola Header HeaderData; 148*3add3e9cSRafael Espindola std::vector<Section> Sections; 149*3add3e9cSRafael Espindola std::vector<Symbol> Symbols; 150*3add3e9cSRafael Espindola }; 151*3add3e9cSRafael Espindola } 152*3add3e9cSRafael Espindola 153*3add3e9cSRafael Espindola /// This parses a yaml stream that represents a COFF object file. 154*3add3e9cSRafael Espindola /// See docs/yaml2obj for the yaml scheema. 155*3add3e9cSRafael Espindola struct COFFParser { 156*3add3e9cSRafael Espindola COFFParser(COFFYAML::Object &Obj) : Obj(Obj) { 157*3add3e9cSRafael Espindola std::memset(&Header, 0, sizeof(Header)); 158*3add3e9cSRafael Espindola // A COFF string table always starts with a 4 byte size field. Offsets into 159*3add3e9cSRafael Espindola // it include this size, so allocate it now. 160*3add3e9cSRafael Espindola StringTable.append(4, 0); 161*3add3e9cSRafael Espindola } 162*3add3e9cSRafael Espindola 163*3add3e9cSRafael Espindola void parseHeader() { 164*3add3e9cSRafael Espindola Header.Machine = Obj.HeaderData.Machine; 165*3add3e9cSRafael Espindola Header.Characteristics = Obj.HeaderData.Characteristics; 166*3add3e9cSRafael Espindola } 167*3add3e9cSRafael Espindola 168*3add3e9cSRafael Espindola bool parseSections() { 169*3add3e9cSRafael Espindola for (std::vector<COFFYAML::Section>::iterator i = Obj.Sections.begin(), 170*3add3e9cSRafael Espindola e = Obj.Sections.end(); i != e; ++i) { 171*3add3e9cSRafael Espindola const COFFYAML::Section &YamlSection = *i; 172*3add3e9cSRafael Espindola Section Sec; 173*3add3e9cSRafael Espindola std::memset(&Sec.Header, 0, sizeof(Sec.Header)); 174*3add3e9cSRafael Espindola 175*3add3e9cSRafael Espindola // If the name is less than 8 bytes, store it in place, otherwise 176*3add3e9cSRafael Espindola // store it in the string table. 177*3add3e9cSRafael Espindola StringRef Name = YamlSection.Name; 178*3add3e9cSRafael Espindola std::fill_n(Sec.Header.Name, unsigned(COFF::NameSize), 0); 179*3add3e9cSRafael Espindola if (Name.size() <= COFF::NameSize) { 180*3add3e9cSRafael Espindola std::copy(Name.begin(), Name.end(), Sec.Header.Name); 181*3add3e9cSRafael Espindola } else { 182*3add3e9cSRafael Espindola // Add string to the string table and format the index for output. 183*3add3e9cSRafael Espindola unsigned Index = getStringIndex(Name); 184*3add3e9cSRafael Espindola std::string str = utostr(Index); 185*3add3e9cSRafael Espindola if (str.size() > 7) { 186*3add3e9cSRafael Espindola errs() << "String table got too large"; 187*3add3e9cSRafael Espindola return false; 188*3add3e9cSRafael Espindola } 189*3add3e9cSRafael Espindola Sec.Header.Name[0] = '/'; 190*3add3e9cSRafael Espindola std::copy(str.begin(), str.end(), Sec.Header.Name + 1); 191*3add3e9cSRafael Espindola } 192*3add3e9cSRafael Espindola 193*3add3e9cSRafael Espindola Sec.Header.Characteristics = YamlSection.Characteristics; 194*3add3e9cSRafael Espindola 195*3add3e9cSRafael Espindola StringRef Data = YamlSection.SectionData; 196*3add3e9cSRafael Espindola if (!hexStringToByteArray(Data, Sec.Data)) { 197*3add3e9cSRafael Espindola errs() << "SectionData must be a collection of pairs of hex bytes"; 198*3add3e9cSRafael Espindola return false; 199*3add3e9cSRafael Espindola } 200*3add3e9cSRafael Espindola Sections.push_back(Sec); 201*3add3e9cSRafael Espindola } 202*3add3e9cSRafael Espindola return true; 203*3add3e9cSRafael Espindola } 204*3add3e9cSRafael Espindola 205*3add3e9cSRafael Espindola bool parseSymbols() { 206*3add3e9cSRafael Espindola for (std::vector<COFFYAML::Symbol>::iterator i = Obj.Symbols.begin(), 207*3add3e9cSRafael Espindola e = Obj.Symbols.end(); i != e; ++i) { 208*3add3e9cSRafael Espindola COFFYAML::Symbol YamlSymbol = *i; 209*3add3e9cSRafael Espindola Symbol Sym; 210*3add3e9cSRafael Espindola std::memset(&Sym.Header, 0, sizeof(Sym.Header)); 211*3add3e9cSRafael Espindola 212*3add3e9cSRafael Espindola // If the name is less than 8 bytes, store it in place, otherwise 213*3add3e9cSRafael Espindola // store it in the string table. 214*3add3e9cSRafael Espindola StringRef Name = YamlSymbol.Name; 215*3add3e9cSRafael Espindola std::fill_n(Sym.Header.Name, unsigned(COFF::NameSize), 0); 216*3add3e9cSRafael Espindola if (Name.size() <= COFF::NameSize) { 217*3add3e9cSRafael Espindola std::copy(Name.begin(), Name.end(), Sym.Header.Name); 218*3add3e9cSRafael Espindola } else { 219*3add3e9cSRafael Espindola // Add string to the string table and format the index for output. 220*3add3e9cSRafael Espindola unsigned Index = getStringIndex(Name); 221*3add3e9cSRafael Espindola *reinterpret_cast<support::aligned_ulittle32_t*>( 222*3add3e9cSRafael Espindola Sym.Header.Name + 4) = Index; 223*3add3e9cSRafael Espindola } 224*3add3e9cSRafael Espindola 225*3add3e9cSRafael Espindola Sym.Header.Value = YamlSymbol.Value; 226*3add3e9cSRafael Espindola Sym.Header.Type |= YamlSymbol.SimpleType; 227*3add3e9cSRafael Espindola Sym.Header.Type |= YamlSymbol.ComplexType << COFF::SCT_COMPLEX_TYPE_SHIFT; 228*3add3e9cSRafael Espindola Sym.Header.StorageClass = YamlSymbol.StorageClass; 229*3add3e9cSRafael Espindola Sym.Header.SectionNumber = YamlSymbol.SectionNumber; 230*3add3e9cSRafael Espindola 231*3add3e9cSRafael Espindola StringRef Data = YamlSymbol.AuxillaryData; 232*3add3e9cSRafael Espindola if (!hexStringToByteArray(Data, Sym.AuxSymbols)) { 233*3add3e9cSRafael Espindola errs() << "AuxillaryData must be a collection of pairs of hex bytes"; 234*3add3e9cSRafael Espindola return false; 235*3add3e9cSRafael Espindola } 236*3add3e9cSRafael Espindola Symbols.push_back(Sym); 237*3add3e9cSRafael Espindola } 238*3add3e9cSRafael Espindola return true; 239*3add3e9cSRafael Espindola } 240*3add3e9cSRafael Espindola 241*3add3e9cSRafael Espindola bool parse() { 242*3add3e9cSRafael Espindola parseHeader(); 243*3add3e9cSRafael Espindola if (!parseSections()) 244*3add3e9cSRafael Espindola return false; 245*3add3e9cSRafael Espindola if (!parseSymbols()) 246*3add3e9cSRafael Espindola return false; 247*3add3e9cSRafael Espindola return true; 248*3add3e9cSRafael Espindola } 249*3add3e9cSRafael Espindola 250*3add3e9cSRafael Espindola unsigned getStringIndex(StringRef Str) { 251*3add3e9cSRafael Espindola StringMap<unsigned>::iterator i = StringTableMap.find(Str); 252*3add3e9cSRafael Espindola if (i == StringTableMap.end()) { 253*3add3e9cSRafael Espindola unsigned Index = StringTable.size(); 254*3add3e9cSRafael Espindola StringTable.append(Str.begin(), Str.end()); 255*3add3e9cSRafael Espindola StringTable.push_back(0); 256*3add3e9cSRafael Espindola StringTableMap[Str] = Index; 257*3add3e9cSRafael Espindola return Index; 258*3add3e9cSRafael Espindola } 259*3add3e9cSRafael Espindola return i->second; 260*3add3e9cSRafael Espindola } 261*3add3e9cSRafael Espindola 262*3add3e9cSRafael Espindola COFFYAML::Object &Obj; 263*3add3e9cSRafael Espindola COFF::header Header; 264*3add3e9cSRafael Espindola 265*3add3e9cSRafael Espindola struct Section { 266*3add3e9cSRafael Espindola COFF::section Header; 267*3add3e9cSRafael Espindola std::vector<uint8_t> Data; 268*3add3e9cSRafael Espindola std::vector<COFF::relocation> Relocations; 269*3add3e9cSRafael Espindola }; 270*3add3e9cSRafael Espindola 271*3add3e9cSRafael Espindola struct Symbol { 272*3add3e9cSRafael Espindola COFF::symbol Header; 273*3add3e9cSRafael Espindola std::vector<uint8_t> AuxSymbols; 274*3add3e9cSRafael Espindola }; 275*3add3e9cSRafael Espindola 276*3add3e9cSRafael Espindola std::vector<Section> Sections; 277*3add3e9cSRafael Espindola std::vector<Symbol> Symbols; 278*3add3e9cSRafael Espindola StringMap<unsigned> StringTableMap; 279*3add3e9cSRafael Espindola std::string StringTable; 280*3add3e9cSRafael Espindola }; 281*3add3e9cSRafael Espindola 282*3add3e9cSRafael Espindola // Take a CP and assign addresses and sizes to everything. Returns false if the 283*3add3e9cSRafael Espindola // layout is not valid to do. 284*3add3e9cSRafael Espindola static bool layoutCOFF(COFFParser &CP) { 285*3add3e9cSRafael Espindola uint32_t SectionTableStart = 0; 286*3add3e9cSRafael Espindola uint32_t SectionTableSize = 0; 287*3add3e9cSRafael Espindola 288*3add3e9cSRafael Espindola // The section table starts immediately after the header, including the 289*3add3e9cSRafael Espindola // optional header. 290*3add3e9cSRafael Espindola SectionTableStart = sizeof(COFF::header) + CP.Header.SizeOfOptionalHeader; 291*3add3e9cSRafael Espindola SectionTableSize = sizeof(COFF::section) * CP.Sections.size(); 292*3add3e9cSRafael Espindola 293*3add3e9cSRafael Espindola uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize; 294*3add3e9cSRafael Espindola 295*3add3e9cSRafael Espindola // Assign each section data address consecutively. 296*3add3e9cSRafael Espindola for (std::vector<COFFParser::Section>::iterator i = CP.Sections.begin(), 297*3add3e9cSRafael Espindola e = CP.Sections.end(); 298*3add3e9cSRafael Espindola i != e; ++i) { 299*3add3e9cSRafael Espindola if (!i->Data.empty()) { 300*3add3e9cSRafael Espindola i->Header.SizeOfRawData = i->Data.size(); 301*3add3e9cSRafael Espindola i->Header.PointerToRawData = CurrentSectionDataOffset; 302*3add3e9cSRafael Espindola CurrentSectionDataOffset += i->Header.SizeOfRawData; 303*3add3e9cSRafael Espindola // TODO: Handle alignment. 304*3add3e9cSRafael Espindola } else { 305*3add3e9cSRafael Espindola i->Header.SizeOfRawData = 0; 306*3add3e9cSRafael Espindola i->Header.PointerToRawData = 0; 307*3add3e9cSRafael Espindola } 308*3add3e9cSRafael Espindola } 309*3add3e9cSRafael Espindola 310*3add3e9cSRafael Espindola uint32_t SymbolTableStart = CurrentSectionDataOffset; 311*3add3e9cSRafael Espindola 312*3add3e9cSRafael Espindola // Calculate number of symbols. 313*3add3e9cSRafael Espindola uint32_t NumberOfSymbols = 0; 314*3add3e9cSRafael Espindola for (std::vector<COFFParser::Symbol>::iterator i = CP.Symbols.begin(), 315*3add3e9cSRafael Espindola e = CP.Symbols.end(); 316*3add3e9cSRafael Espindola i != e; ++i) { 317*3add3e9cSRafael Espindola if (i->AuxSymbols.size() % COFF::SymbolSize != 0) { 318*3add3e9cSRafael Espindola errs() << "AuxillaryData size not a multiple of symbol size!\n"; 319*3add3e9cSRafael Espindola return false; 320*3add3e9cSRafael Espindola } 321*3add3e9cSRafael Espindola i->Header.NumberOfAuxSymbols = i->AuxSymbols.size() / COFF::SymbolSize; 322*3add3e9cSRafael Espindola NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; 323*3add3e9cSRafael Espindola } 324*3add3e9cSRafael Espindola 325*3add3e9cSRafael Espindola // Store all the allocated start addresses in the header. 326*3add3e9cSRafael Espindola CP.Header.NumberOfSections = CP.Sections.size(); 327*3add3e9cSRafael Espindola CP.Header.NumberOfSymbols = NumberOfSymbols; 328*3add3e9cSRafael Espindola CP.Header.PointerToSymbolTable = SymbolTableStart; 329*3add3e9cSRafael Espindola 330*3add3e9cSRafael Espindola *reinterpret_cast<support::ulittle32_t *>(&CP.StringTable[0]) 331*3add3e9cSRafael Espindola = CP.StringTable.size(); 332*3add3e9cSRafael Espindola 333*3add3e9cSRafael Espindola return true; 334*3add3e9cSRafael Espindola } 335*3add3e9cSRafael Espindola 336*3add3e9cSRafael Espindola template <typename value_type> 337*3add3e9cSRafael Espindola struct binary_le_impl { 338*3add3e9cSRafael Espindola value_type Value; 339*3add3e9cSRafael Espindola binary_le_impl(value_type V) : Value(V) {} 340*3add3e9cSRafael Espindola }; 341*3add3e9cSRafael Espindola 342*3add3e9cSRafael Espindola template <typename value_type> 343*3add3e9cSRafael Espindola raw_ostream &operator <<( raw_ostream &OS 344*3add3e9cSRafael Espindola , const binary_le_impl<value_type> &BLE) { 345*3add3e9cSRafael Espindola char Buffer[sizeof(BLE.Value)]; 346*3add3e9cSRafael Espindola support::endian::write<value_type, support::little, support::unaligned>( 347*3add3e9cSRafael Espindola Buffer, BLE.Value); 348*3add3e9cSRafael Espindola OS.write(Buffer, sizeof(BLE.Value)); 349*3add3e9cSRafael Espindola return OS; 350*3add3e9cSRafael Espindola } 351*3add3e9cSRafael Espindola 352*3add3e9cSRafael Espindola template <typename value_type> 353*3add3e9cSRafael Espindola binary_le_impl<value_type> binary_le(value_type V) { 354*3add3e9cSRafael Espindola return binary_le_impl<value_type>(V); 355*3add3e9cSRafael Espindola } 356*3add3e9cSRafael Espindola 357*3add3e9cSRafael Espindola void writeCOFF(COFFParser &CP, raw_ostream &OS) { 358*3add3e9cSRafael Espindola OS << binary_le(CP.Header.Machine) 359*3add3e9cSRafael Espindola << binary_le(CP.Header.NumberOfSections) 360*3add3e9cSRafael Espindola << binary_le(CP.Header.TimeDateStamp) 361*3add3e9cSRafael Espindola << binary_le(CP.Header.PointerToSymbolTable) 362*3add3e9cSRafael Espindola << binary_le(CP.Header.NumberOfSymbols) 363*3add3e9cSRafael Espindola << binary_le(CP.Header.SizeOfOptionalHeader) 364*3add3e9cSRafael Espindola << binary_le(CP.Header.Characteristics); 365*3add3e9cSRafael Espindola 366*3add3e9cSRafael Espindola // Output section table. 367*3add3e9cSRafael Espindola for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(), 368*3add3e9cSRafael Espindola e = CP.Sections.end(); 369*3add3e9cSRafael Espindola i != e; ++i) { 370*3add3e9cSRafael Espindola OS.write(i->Header.Name, COFF::NameSize); 371*3add3e9cSRafael Espindola OS << binary_le(i->Header.VirtualSize) 372*3add3e9cSRafael Espindola << binary_le(i->Header.VirtualAddress) 373*3add3e9cSRafael Espindola << binary_le(i->Header.SizeOfRawData) 374*3add3e9cSRafael Espindola << binary_le(i->Header.PointerToRawData) 375*3add3e9cSRafael Espindola << binary_le(i->Header.PointerToRelocations) 376*3add3e9cSRafael Espindola << binary_le(i->Header.PointerToLineNumbers) 377*3add3e9cSRafael Espindola << binary_le(i->Header.NumberOfRelocations) 378*3add3e9cSRafael Espindola << binary_le(i->Header.NumberOfLineNumbers) 379*3add3e9cSRafael Espindola << binary_le(i->Header.Characteristics); 380*3add3e9cSRafael Espindola } 381*3add3e9cSRafael Espindola 382*3add3e9cSRafael Espindola // Output section data. 383*3add3e9cSRafael Espindola for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(), 384*3add3e9cSRafael Espindola e = CP.Sections.end(); 385*3add3e9cSRafael Espindola i != e; ++i) { 386*3add3e9cSRafael Espindola if (!i->Data.empty()) 387*3add3e9cSRafael Espindola OS.write(reinterpret_cast<const char*>(&i->Data[0]), i->Data.size()); 388*3add3e9cSRafael Espindola } 389*3add3e9cSRafael Espindola 390*3add3e9cSRafael Espindola // Output symbol table. 391*3add3e9cSRafael Espindola 392*3add3e9cSRafael Espindola for (std::vector<COFFParser::Symbol>::const_iterator i = CP.Symbols.begin(), 393*3add3e9cSRafael Espindola e = CP.Symbols.end(); 394*3add3e9cSRafael Espindola i != e; ++i) { 395*3add3e9cSRafael Espindola OS.write(i->Header.Name, COFF::NameSize); 396*3add3e9cSRafael Espindola OS << binary_le(i->Header.Value) 397*3add3e9cSRafael Espindola << binary_le(i->Header.SectionNumber) 398*3add3e9cSRafael Espindola << binary_le(i->Header.Type) 399*3add3e9cSRafael Espindola << binary_le(i->Header.StorageClass) 400*3add3e9cSRafael Espindola << binary_le(i->Header.NumberOfAuxSymbols); 401*3add3e9cSRafael Espindola if (!i->AuxSymbols.empty()) 402*3add3e9cSRafael Espindola OS.write( reinterpret_cast<const char*>(&i->AuxSymbols[0]) 403*3add3e9cSRafael Espindola , i->AuxSymbols.size()); 404*3add3e9cSRafael Espindola } 405*3add3e9cSRafael Espindola 406*3add3e9cSRafael Espindola // Output string table. 407*3add3e9cSRafael Espindola OS.write(&CP.StringTable[0], CP.StringTable.size()); 408*3add3e9cSRafael Espindola } 409*3add3e9cSRafael Espindola 410*3add3e9cSRafael Espindola LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation) 411*3add3e9cSRafael Espindola LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) 412*3add3e9cSRafael Espindola LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) 413*3add3e9cSRafael Espindola 414*3add3e9cSRafael Espindola namespace llvm { 415*3add3e9cSRafael Espindola 416*3add3e9cSRafael Espindola namespace COFF { 417*3add3e9cSRafael Espindola Characteristics operator|(Characteristics a, Characteristics b) { 418*3add3e9cSRafael Espindola uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b); 419*3add3e9cSRafael Espindola return static_cast<Characteristics>(Ret); 420*3add3e9cSRafael Espindola } 421*3add3e9cSRafael Espindola 422*3add3e9cSRafael Espindola SectionCharacteristics 423*3add3e9cSRafael Espindola operator|(SectionCharacteristics a, SectionCharacteristics b) { 424*3add3e9cSRafael Espindola uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b); 425*3add3e9cSRafael Espindola return static_cast<SectionCharacteristics>(Ret); 426*3add3e9cSRafael Espindola } 427*3add3e9cSRafael Espindola } 428*3add3e9cSRafael Espindola 429*3add3e9cSRafael Espindola namespace yaml { 430*3add3e9cSRafael Espindola 431*3add3e9cSRafael Espindola #define BCase(X) IO.bitSetCase(Value, #X, COFF::X); 432*3add3e9cSRafael Espindola 433*3add3e9cSRafael Espindola template <> 434*3add3e9cSRafael Espindola struct ScalarBitSetTraits<COFF::SectionCharacteristics> { 435*3add3e9cSRafael Espindola static void bitset(IO &IO, COFF::SectionCharacteristics &Value) { 436*3add3e9cSRafael Espindola BCase(IMAGE_SCN_TYPE_NO_PAD); 437*3add3e9cSRafael Espindola BCase(IMAGE_SCN_CNT_CODE); 438*3add3e9cSRafael Espindola BCase(IMAGE_SCN_CNT_INITIALIZED_DATA); 439*3add3e9cSRafael Espindola BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA); 440*3add3e9cSRafael Espindola BCase(IMAGE_SCN_LNK_OTHER); 441*3add3e9cSRafael Espindola BCase(IMAGE_SCN_LNK_INFO); 442*3add3e9cSRafael Espindola BCase(IMAGE_SCN_LNK_REMOVE); 443*3add3e9cSRafael Espindola BCase(IMAGE_SCN_LNK_COMDAT); 444*3add3e9cSRafael Espindola BCase(IMAGE_SCN_GPREL); 445*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_PURGEABLE); 446*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_16BIT); 447*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_LOCKED); 448*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_PRELOAD); 449*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_1BYTES); 450*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_2BYTES); 451*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_4BYTES); 452*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_8BYTES); 453*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_16BYTES); 454*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_32BYTES); 455*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_64BYTES); 456*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_128BYTES); 457*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_256BYTES); 458*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_512BYTES); 459*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_1024BYTES); 460*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_2048BYTES); 461*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_4096BYTES); 462*3add3e9cSRafael Espindola BCase(IMAGE_SCN_ALIGN_8192BYTES); 463*3add3e9cSRafael Espindola BCase(IMAGE_SCN_LNK_NRELOC_OVFL); 464*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_DISCARDABLE); 465*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_NOT_CACHED); 466*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_NOT_PAGED); 467*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_SHARED); 468*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_EXECUTE); 469*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_READ); 470*3add3e9cSRafael Espindola BCase(IMAGE_SCN_MEM_WRITE); 471*3add3e9cSRafael Espindola } 472*3add3e9cSRafael Espindola }; 473*3add3e9cSRafael Espindola 474*3add3e9cSRafael Espindola template <> 475*3add3e9cSRafael Espindola struct ScalarBitSetTraits<COFF::Characteristics> { 476*3add3e9cSRafael Espindola static void bitset(IO &IO, COFF::Characteristics &Value) { 477*3add3e9cSRafael Espindola BCase(IMAGE_FILE_RELOCS_STRIPPED); 478*3add3e9cSRafael Espindola BCase(IMAGE_FILE_EXECUTABLE_IMAGE); 479*3add3e9cSRafael Espindola BCase(IMAGE_FILE_LINE_NUMS_STRIPPED); 480*3add3e9cSRafael Espindola BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED); 481*3add3e9cSRafael Espindola BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM); 482*3add3e9cSRafael Espindola BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE); 483*3add3e9cSRafael Espindola BCase(IMAGE_FILE_BYTES_REVERSED_LO); 484*3add3e9cSRafael Espindola BCase(IMAGE_FILE_32BIT_MACHINE); 485*3add3e9cSRafael Espindola BCase(IMAGE_FILE_DEBUG_STRIPPED); 486*3add3e9cSRafael Espindola BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP); 487*3add3e9cSRafael Espindola BCase(IMAGE_FILE_NET_RUN_FROM_SWAP); 488*3add3e9cSRafael Espindola BCase(IMAGE_FILE_SYSTEM); 489*3add3e9cSRafael Espindola BCase(IMAGE_FILE_DLL); 490*3add3e9cSRafael Espindola BCase(IMAGE_FILE_UP_SYSTEM_ONLY); 491*3add3e9cSRafael Espindola BCase(IMAGE_FILE_BYTES_REVERSED_HI); 492*3add3e9cSRafael Espindola } 493*3add3e9cSRafael Espindola }; 494*3add3e9cSRafael Espindola #undef BCase 495*3add3e9cSRafael Espindola 496*3add3e9cSRafael Espindola #define ECase(X) IO.enumCase(Value, #X, COFF::X); 497*3add3e9cSRafael Espindola 498*3add3e9cSRafael Espindola template <> 499*3add3e9cSRafael Espindola struct ScalarEnumerationTraits<COFF::SymbolComplexType> { 500*3add3e9cSRafael Espindola static void enumeration(IO &IO, COFF::SymbolComplexType &Value) { 501*3add3e9cSRafael Espindola ECase(IMAGE_SYM_DTYPE_NULL); 502*3add3e9cSRafael Espindola ECase(IMAGE_SYM_DTYPE_POINTER); 503*3add3e9cSRafael Espindola ECase(IMAGE_SYM_DTYPE_FUNCTION); 504*3add3e9cSRafael Espindola ECase(IMAGE_SYM_DTYPE_ARRAY); 505*3add3e9cSRafael Espindola } 506*3add3e9cSRafael Espindola }; 507*3add3e9cSRafael Espindola 508*3add3e9cSRafael Espindola template <> 509*3add3e9cSRafael Espindola struct ScalarEnumerationTraits<COFF::SymbolStorageClass> { 510*3add3e9cSRafael Espindola static void enumeration(IO &IO, COFF::SymbolStorageClass &Value) { 511*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION); 512*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_NULL); 513*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_AUTOMATIC); 514*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_EXTERNAL); 515*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_STATIC); 516*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_REGISTER); 517*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF); 518*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_LABEL); 519*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL); 520*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT); 521*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_ARGUMENT); 522*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_STRUCT_TAG); 523*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION); 524*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_UNION_TAG); 525*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION); 526*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC); 527*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_ENUM_TAG); 528*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM); 529*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_REGISTER_PARAM); 530*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_BIT_FIELD); 531*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_BLOCK); 532*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_FUNCTION); 533*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_END_OF_STRUCT); 534*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_FILE); 535*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_SECTION); 536*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL); 537*3add3e9cSRafael Espindola ECase(IMAGE_SYM_CLASS_CLR_TOKEN); 538*3add3e9cSRafael Espindola } 539*3add3e9cSRafael Espindola }; 540*3add3e9cSRafael Espindola 541*3add3e9cSRafael Espindola template <> 542*3add3e9cSRafael Espindola struct ScalarEnumerationTraits<COFF::SymbolBaseType> { 543*3add3e9cSRafael Espindola static void enumeration(IO &IO, COFF::SymbolBaseType &Value) { 544*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_NULL); 545*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_VOID); 546*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_CHAR); 547*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_SHORT); 548*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_INT); 549*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_LONG); 550*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_FLOAT); 551*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_DOUBLE); 552*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_STRUCT); 553*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_UNION); 554*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_ENUM); 555*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_MOE); 556*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_BYTE); 557*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_WORD); 558*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_UINT); 559*3add3e9cSRafael Espindola ECase(IMAGE_SYM_TYPE_DWORD); 560*3add3e9cSRafael Espindola } 561*3add3e9cSRafael Espindola }; 562*3add3e9cSRafael Espindola 563*3add3e9cSRafael Espindola template <> 564*3add3e9cSRafael Espindola struct ScalarEnumerationTraits<COFF::MachineTypes> { 565*3add3e9cSRafael Espindola static void enumeration(IO &IO, COFF::MachineTypes &Value) { 566*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_UNKNOWN); 567*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_AM33); 568*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_AMD64); 569*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_ARM); 570*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_ARMV7); 571*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_EBC); 572*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_I386); 573*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_IA64); 574*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_M32R); 575*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_MIPS16); 576*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_MIPSFPU); 577*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_MIPSFPU16); 578*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_POWERPC); 579*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_POWERPCFP); 580*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_R4000); 581*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_SH3); 582*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_SH3DSP); 583*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_SH4); 584*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_SH5); 585*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_THUMB); 586*3add3e9cSRafael Espindola ECase(IMAGE_FILE_MACHINE_WCEMIPSV2); 587*3add3e9cSRafael Espindola } 588*3add3e9cSRafael Espindola }; 589*3add3e9cSRafael Espindola 590*3add3e9cSRafael Espindola template <> 591*3add3e9cSRafael Espindola struct ScalarEnumerationTraits<COFF::RelocationTypeX86> { 592*3add3e9cSRafael Espindola static void enumeration(IO &IO, COFF::RelocationTypeX86 &Value) { 593*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_ABSOLUTE); 594*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_DIR16); 595*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_REL16); 596*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_DIR32); 597*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_DIR32NB); 598*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_SEG12); 599*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_SECTION); 600*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_SECREL); 601*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_TOKEN); 602*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_SECREL7); 603*3add3e9cSRafael Espindola ECase(IMAGE_REL_I386_REL32); 604*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_ABSOLUTE); 605*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_ADDR64); 606*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_ADDR32); 607*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_ADDR32NB); 608*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32); 609*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32_1); 610*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32_2); 611*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32_3); 612*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32_4); 613*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_REL32_5); 614*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_SECTION); 615*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_SECREL); 616*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_SECREL7); 617*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_TOKEN); 618*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_SREL32); 619*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_PAIR); 620*3add3e9cSRafael Espindola ECase(IMAGE_REL_AMD64_SSPAN32); 621*3add3e9cSRafael Espindola } 622*3add3e9cSRafael Espindola }; 623*3add3e9cSRafael Espindola 624*3add3e9cSRafael Espindola #undef ECase 625*3add3e9cSRafael Espindola 626*3add3e9cSRafael Espindola template <> 627*3add3e9cSRafael Espindola struct MappingTraits<COFFYAML::Symbol> { 628*3add3e9cSRafael Espindola static void mapping(IO &IO, COFFYAML::Symbol &S) { 629*3add3e9cSRafael Espindola IO.mapRequired("SimpleType", S.SimpleType); 630*3add3e9cSRafael Espindola IO.mapOptional("NumberOfAuxSymbols", S.NumberOfAuxSymbols); 631*3add3e9cSRafael Espindola IO.mapRequired("Name", S.Name); 632*3add3e9cSRafael Espindola IO.mapRequired("StorageClass", S.StorageClass); 633*3add3e9cSRafael Espindola IO.mapOptional("AuxillaryData", S.AuxillaryData); // FIXME: typo 634*3add3e9cSRafael Espindola IO.mapRequired("ComplexType", S.ComplexType); 635*3add3e9cSRafael Espindola IO.mapRequired("Value", S.Value); 636*3add3e9cSRafael Espindola IO.mapRequired("SectionNumber", S.SectionNumber); 637*3add3e9cSRafael Espindola } 638*3add3e9cSRafael Espindola }; 639*3add3e9cSRafael Espindola 640*3add3e9cSRafael Espindola template <> 641*3add3e9cSRafael Espindola struct MappingTraits<COFFYAML::Header> { 642*3add3e9cSRafael Espindola static void mapping(IO &IO, COFFYAML::Header &H) { 643*3add3e9cSRafael Espindola IO.mapRequired("Machine", H.Machine); 644*3add3e9cSRafael Espindola IO.mapOptional("Characteristics", H.Characteristics); 645*3add3e9cSRafael Espindola } 646*3add3e9cSRafael Espindola }; 647*3add3e9cSRafael Espindola 648*3add3e9cSRafael Espindola template <> 649*3add3e9cSRafael Espindola struct MappingTraits<COFFYAML::Relocation> { 650*3add3e9cSRafael Espindola static void mapping(IO &IO, COFFYAML::Relocation &Rel) { 651*3add3e9cSRafael Espindola IO.mapRequired("Type", Rel.Type); 652*3add3e9cSRafael Espindola IO.mapRequired("VirtualAddress", Rel.VirtualAddress); 653*3add3e9cSRafael Espindola IO.mapRequired("SymbolTableIndex", Rel.SymbolTableIndex); 654*3add3e9cSRafael Espindola } 655*3add3e9cSRafael Espindola }; 656*3add3e9cSRafael Espindola 657*3add3e9cSRafael Espindola template <> 658*3add3e9cSRafael Espindola struct MappingTraits<COFFYAML::Section> { 659*3add3e9cSRafael Espindola static void mapping(IO &IO, COFFYAML::Section &Sec) { 660*3add3e9cSRafael Espindola IO.mapOptional("Relocations", Sec.Relocations); 661*3add3e9cSRafael Espindola IO.mapRequired("SectionData", Sec.SectionData); 662*3add3e9cSRafael Espindola IO.mapRequired("Characteristics", Sec.Characteristics); 663*3add3e9cSRafael Espindola IO.mapRequired("Name", Sec.Name); 664*3add3e9cSRafael Espindola } 665*3add3e9cSRafael Espindola }; 666*3add3e9cSRafael Espindola 667*3add3e9cSRafael Espindola template <> 668*3add3e9cSRafael Espindola struct MappingTraits<COFFYAML::Object> { 669*3add3e9cSRafael Espindola static void mapping(IO &IO, COFFYAML::Object &Obj) { 670*3add3e9cSRafael Espindola IO.mapRequired("sections", Obj.Sections); 671*3add3e9cSRafael Espindola IO.mapRequired("header", Obj.HeaderData); 672*3add3e9cSRafael Espindola IO.mapRequired("symbols", Obj.Symbols); 673*3add3e9cSRafael Espindola } 674*3add3e9cSRafael Espindola }; 675*3add3e9cSRafael Espindola } // end namespace yaml 676*3add3e9cSRafael Espindola } // end namespace llvm 677*3add3e9cSRafael Espindola 678*3add3e9cSRafael Espindola int main(int argc, char **argv) { 679*3add3e9cSRafael Espindola cl::ParseCommandLineOptions(argc, argv); 680*3add3e9cSRafael Espindola sys::PrintStackTraceOnErrorSignal(); 681*3add3e9cSRafael Espindola PrettyStackTraceProgram X(argc, argv); 682*3add3e9cSRafael Espindola llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 683*3add3e9cSRafael Espindola 684*3add3e9cSRafael Espindola OwningPtr<MemoryBuffer> Buf; 685*3add3e9cSRafael Espindola if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) 686*3add3e9cSRafael Espindola return 1; 687*3add3e9cSRafael Espindola 688*3add3e9cSRafael Espindola yaml::Input YIn(Buf->getBuffer()); 689*3add3e9cSRafael Espindola COFFYAML::Object Doc; 690*3add3e9cSRafael Espindola YIn >> Doc; 691*3add3e9cSRafael Espindola if (YIn.error()) { 692*3add3e9cSRafael Espindola errs() << "yaml2obj: Failed to parse YAML file!\n"; 693*3add3e9cSRafael Espindola return 1; 694*3add3e9cSRafael Espindola } 695*3add3e9cSRafael Espindola 696*3add3e9cSRafael Espindola COFFParser CP(Doc); 697*3add3e9cSRafael Espindola if (!CP.parse()) { 698*3add3e9cSRafael Espindola errs() << "yaml2obj: Failed to parse YAML file!\n"; 699*3add3e9cSRafael Espindola return 1; 700*3add3e9cSRafael Espindola } 701*3add3e9cSRafael Espindola 702*3add3e9cSRafael Espindola if (!layoutCOFF(CP)) { 703*3add3e9cSRafael Espindola errs() << "yaml2obj: Failed to layout COFF file!\n"; 704*3add3e9cSRafael Espindola return 1; 705*3add3e9cSRafael Espindola } 706*3add3e9cSRafael Espindola writeCOFF(CP, outs()); 707*3add3e9cSRafael Espindola } 708