1a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer//===- yaml2obj - Convert YAML to a binary object file --------------------===// 2a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 3a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// The LLVM Compiler Infrastructure 4a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 5a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// This file is distributed under the University of Illinois Open Source 6a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// License. See LICENSE.TXT for details. 7a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 8a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer//===----------------------------------------------------------------------===// 9a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 10a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// This program takes a YAML description of an object file and outputs the 11a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// binary equivalent. 12a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 13a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// This is used for writing tests that require binary files. 14a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// 15a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer//===----------------------------------------------------------------------===// 16a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 17a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/ADT/SmallString.h" 18a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/ADT/StringExtras.h" 19a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/ADT/StringMap.h" 20a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/ADT/StringSwitch.h" 21a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/COFF.h" 22a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/Casting.h" 23a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/CommandLine.h" 24a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/Endian.h" 25a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/ManagedStatic.h" 26a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/MemoryBuffer.h" 27a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h" 28a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/raw_ostream.h" 29a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/Signals.h" 30a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/SourceMgr.h" 31a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/system_error.h" 32a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include "llvm/Support/YAMLParser.h" 33a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 34a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer#include <vector> 35a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 36a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerusing namespace llvm; 37a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 38a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstatic cl::opt<std::string> 39a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Input(cl::Positional, cl::desc("<input>"), cl::init("-")); 40a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 41a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencertemplate<class T> 421de266be13c956f4af9566b000b67ef75454d0a8Michael J. Spencertypename llvm::enable_if_c<std::numeric_limits<T>::is_integer, bool>::type 43a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. SpencergetAs(const llvm::yaml::ScalarNode *SN, T &Result) { 44a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<4> Storage; 45a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Value = SN->getValue(Storage); 46a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Value.getAsInteger(0, Result)) 47a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 48a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 49a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 50a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 51a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// Given a container with begin and end with ::value_type of a character type. 52a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// Iterate through pairs of characters in the the set of [a-fA-F0-9] ignoring 53a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// all other characters. 54a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstruct hex_pair_iterator { 55a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef::const_iterator Current, End; 56a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer typedef SmallVector<char, 2> value_type; 57a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer value_type Pair; 58a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool IsDone; 59a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 60a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer hex_pair_iterator(StringRef C) 61a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer : Current(C.begin()), End(C.end()), IsDone(false) { 62a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Initalize Pair. 63a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer ++*this; 64a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 65a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 66a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // End iterator. 67a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer hex_pair_iterator() : Current(), End(), IsDone(true) {} 68a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 69a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer value_type operator *() const { 70a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return Pair; 71a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 72a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 73a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer hex_pair_iterator operator ++() { 74a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // We're at the end of the input. 75a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Current == End) { 76a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer IsDone = true; 77a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return *this; 78a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 79a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Pair = value_type(); 80a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (; Current != End && Pair.size() != 2; ++Current) { 81a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Is a valid hex digit. 82a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if ((*Current >= '0' && *Current <= '9') || 83a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer (*Current >= 'a' && *Current <= 'f') || 84a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer (*Current >= 'A' && *Current <= 'F')) 85a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Pair.push_back(*Current); 86a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 87a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Hit the end without getting 2 hex digits. Pair is invalid. 88a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Pair.size() != 2) 89a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer IsDone = true; 90a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return *this; 91a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 92a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 93a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool operator ==(const hex_pair_iterator Other) { 947b07d69958b865bb83500f0a8dc348a62969e7a8Richard Trieu return (IsDone == Other.IsDone) || 95a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer (Current == Other.Current && End == Other.End); 96a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 97a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 98a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool operator !=(const hex_pair_iterator Other) { 99a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return !(*this == Other); 100a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 101a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer}; 102a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 103a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencertemplate <class ContainerOut> 104a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstatic bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { 105a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (hex_pair_iterator I(Str), E; I != E; ++I) { 106a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer typename hex_pair_iterator::value_type Pair = *I; 107a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer typename ContainerOut::value_type Byte; 108a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (StringRef(Pair.data(), 2).getAsInteger(16, Byte)) 109a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 110a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Out.push_back(Byte); 111a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 112a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 113a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 114a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 115a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer/// This parses a yaml stream that represents a COFF object file. 116a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer/// See docs/yaml2obj for the yaml scheema. 117a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstruct COFFParser { 118a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer COFFParser(yaml::Stream &Input) : YS(Input) { 119a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::memset(&Header, 0, sizeof(Header)); 120a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // A COFF string table always starts with a 4 byte size field. Offsets into 121a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // it include this size, so allocate it now. 122a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringTable.append(4, 0); 123a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 124a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 125a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool parseHeader(yaml::Node *HeaderN) { 126a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::MappingNode *MN = dyn_cast<yaml::MappingNode>(HeaderN); 127a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!MN) { 128a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(HeaderN, "header's value must be a mapping node"); 129a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 130a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 131a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::MappingNode::iterator i = MN->begin(), e = MN->end(); 132a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 133a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Key = dyn_cast<yaml::ScalarNode>(i->getKey()); 134a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Key) { 135a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(i->getKey(), "Keys must be scalar values"); 136a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 137a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 138a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 139a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef KeyValue = Key->getValue(Storage); 140a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (KeyValue == "Characteristics") { 141a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!parseHeaderCharacteristics(i->getValue())) 142a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 143a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 144a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Value = dyn_cast<yaml::ScalarNode>(i->getValue()); 145a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Value) { 146a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, 147a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Twine(KeyValue) + " must be a scalar value"); 148a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 149a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 150a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (KeyValue == "Machine") { 151a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint16_t Machine; 152a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Machine)) { 153a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // It's not a raw number, try matching the string. 154a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef ValueValue = Value->getValue(Storage); 155a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Machine = StringSwitch<COFF::MachineTypes>(ValueValue) 156a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_UNKNOWN" 157a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_UNKNOWN) 158a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_AM33" 159a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_AM33) 160a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_AMD64" 161a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_AMD64) 162a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_ARM" 163a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_ARM) 164a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_ARMV7" 165a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_ARMV7) 166a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_EBC" 167a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_EBC) 168a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_I386" 169a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_I386) 170a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_IA64" 171a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_IA64) 172a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_M32R" 173a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_M32R) 174a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_MIPS16" 175a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_MIPS16) 176a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_MIPSFPU" 177a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_MIPSFPU) 178a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_MIPSFPU16" 179a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_MIPSFPU16) 180a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_POWERPC" 181a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_POWERPC) 182a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_POWERPCFP" 183a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_POWERPCFP) 184a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_R4000" 185a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_R4000) 186a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_SH3" 187a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_SH3) 188a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_SH3DSP" 189a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_SH3DSP) 190a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_SH4" 191a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_SH4) 192a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_SH5" 193a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_SH5) 194a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_THUMB" 195a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_THUMB) 196a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_MACHINE_WCEMIPSV2" 197a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_MACHINE_WCEMIPSV2) 198a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::MT_Invalid); 199a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Machine == COFF::MT_Invalid) { 200a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for Machine"); 201a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 202a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 203a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 204a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Header.Machine = Machine; 205a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "NumberOfSections") { 206a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.NumberOfSections)) { 207a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for NumberOfSections"); 208a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 209a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 210a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "TimeDateStamp") { 211a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.TimeDateStamp)) { 212a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for TimeDateStamp"); 213a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 214a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 215a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "PointerToSymbolTable") { 216a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.PointerToSymbolTable)) { 217a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for PointerToSymbolTable"); 218a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 219a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 220a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "NumberOfSymbols") { 221a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.NumberOfSymbols)) { 222a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for NumberOfSymbols"); 223a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 224a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 225a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "SizeOfOptionalHeader") { 226a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.SizeOfOptionalHeader)) { 227a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for SizeOfOptionalHeader"); 228a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 229a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 230a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 231a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Key, "Unrecognized key in header"); 232a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 233a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 234a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 235a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 236a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 237a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 238a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 239a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool parseHeaderCharacteristics(yaml::Node *Characteristics) { 240a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Value = dyn_cast<yaml::ScalarNode>(Characteristics); 241a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::SequenceNode *SeqValue 242a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer = dyn_cast<yaml::SequenceNode>(Characteristics); 243a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Value && !SeqValue) { 244a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Characteristics, 245a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "Characteristics must either be a number or sequence"); 246a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 247a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 248a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Value) { 249a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Header.Characteristics)) { 250a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for Characteristics"); 251a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 252a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 253a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 254a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::SequenceNode::iterator ci = SeqValue->begin(), 255a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer ce = SeqValue->end(); 256a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer ci != ce; ++ci) { 257a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *CharValue = dyn_cast<yaml::ScalarNode>(&*ci); 258a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!CharValue) { 259a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(CharValue, 260a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "Characteristics must be scalar values"); 261a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 262a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 263a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 264a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Char = CharValue->getValue(Storage); 265a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint16_t Characteristic = StringSwitch<COFF::Characteristics>(Char) 266a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_RELOCS_STRIPPED" 267a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_RELOCS_STRIPPED) 268a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_EXECUTABLE_IMAGE" 269a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_EXECUTABLE_IMAGE) 270a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_LINE_NUMS_STRIPPED" 271a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_LINE_NUMS_STRIPPED) 272a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_LOCAL_SYMS_STRIPPED" 273a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_LOCAL_SYMS_STRIPPED) 274a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_AGGRESSIVE_WS_TRIM" 275a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_AGGRESSIVE_WS_TRIM) 276a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_LARGE_ADDRESS_AWARE" 277a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_LARGE_ADDRESS_AWARE) 278a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_BYTES_REVERSED_LO" 279a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_BYTES_REVERSED_LO) 280a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_32BIT_MACHINE" 281a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_32BIT_MACHINE) 282a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_DEBUG_STRIPPED" 283a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_DEBUG_STRIPPED) 284a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP" 285a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) 286a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_SYSTEM" 287a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_SYSTEM) 288a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_DLL" 289a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_DLL) 290a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_FILE_UP_SYSTEM_ONLY" 291a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_FILE_UP_SYSTEM_ONLY) 292a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::C_Invalid); 293a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Characteristic == COFF::C_Invalid) { 294a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // TODO: Typo-correct. 295a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(CharValue, 296a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "Invalid value for Characteristic"); 297a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 298a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 299a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Header.Characteristics |= Characteristic; 300a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 301a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 302a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 303a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 304a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 305a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool parseSections(yaml::Node *SectionsN) { 306a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::SequenceNode *SN = dyn_cast<yaml::SequenceNode>(SectionsN); 307a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!SN) { 308a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(SectionsN, "Sections must be a sequence"); 309a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 310a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 311a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::SequenceNode::iterator i = SN->begin(), e = SN->end(); 312a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 313a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Section Sec; 314a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::memset(&Sec.Header, 0, sizeof(Sec.Header)); 315a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::MappingNode *SecMap = dyn_cast<yaml::MappingNode>(&*i); 316a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!SecMap) { 317a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(&*i, "Section entry must be a map"); 318a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 319a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 320a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::MappingNode::iterator si = SecMap->begin(), se = SecMap->end(); 321a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer si != se; ++si) { 322a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Key = dyn_cast<yaml::ScalarNode>(si->getKey()); 323a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Key) { 324a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(si->getKey(), "Keys must be scalar values"); 325a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 326a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 327a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 328a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef KeyValue = Key->getValue(Storage); 329a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 330a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Value = dyn_cast<yaml::ScalarNode>(si->getValue()); 331a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (KeyValue == "Name") { 332a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // If the name is less than 8 bytes, store it in place, otherwise 333a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // store it in the string table. 334a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Name = Value->getValue(Storage); 335a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::fill_n(Sec.Header.Name, unsigned(COFF::NameSize), 0); 336a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Name.size() <= COFF::NameSize) { 337a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::copy(Name.begin(), Name.end(), Sec.Header.Name); 338a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 339a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Add string to the string table and format the index for output. 340a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer unsigned Index = getStringIndex(Name); 341a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::string str = utostr(Index); 342a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (str.size() > 7) { 343a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "String table got too large"); 344a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 345a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 346a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sec.Header.Name[0] = '/'; 347a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::copy(str.begin(), str.end(), Sec.Header.Name + 1); 348a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 349a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "VirtualSize") { 350a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.VirtualSize)) { 351a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for VirtualSize"); 352a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 353a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 354a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "VirtualAddress") { 355a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.VirtualAddress)) { 356a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for VirtualAddress"); 357a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 358a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 359a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "SizeOfRawData") { 360a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.SizeOfRawData)) { 361a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for SizeOfRawData"); 362a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 363a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 364a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "PointerToRawData") { 365a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.PointerToRawData)) { 366a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for PointerToRawData"); 367a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 368a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 369a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "PointerToRelocations") { 370a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.PointerToRelocations)) { 371a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for PointerToRelocations"); 372a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 373a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 374a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "PointerToLineNumbers") { 375a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.PointerToLineNumbers)) { 376a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for PointerToLineNumbers"); 377a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 378a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 379a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "NumberOfRelocations") { 380a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.NumberOfRelocations)) { 381a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for NumberOfRelocations"); 382a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 383a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 384a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "NumberOfLineNumbers") { 385a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.NumberOfLineNumbers)) { 386a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for NumberOfLineNumbers"); 387a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 388a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 389a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "Characteristics") { 390a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::SequenceNode *SeqValue 391a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer = dyn_cast<yaml::SequenceNode>(si->getValue()); 392a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Value && !SeqValue) { 393a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(si->getValue(), 394a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "Characteristics must either be a number or sequence"); 395a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 396a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 397a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Value) { 398a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sec.Header.Characteristics)) { 399a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for Characteristics"); 400a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 401a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 402a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 403a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::SequenceNode::iterator ci = SeqValue->begin(), 404a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer ce = SeqValue->end(); 405a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer ci != ce; ++ci) { 406a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *CharValue = dyn_cast<yaml::ScalarNode>(&*ci); 407a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!CharValue) { 408a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(CharValue, "Invalid value for Characteristics"); 409a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 410a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 411a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Char = CharValue->getValue(Storage); 412a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t Characteristic = 413a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringSwitch<COFF::SectionCharacteristics>(Char) 414a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_TYPE_NO_PAD" 415a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_TYPE_NO_PAD) 416a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_CNT_CODE" 417a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_CNT_CODE) 418a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_CNT_INITIALIZED_DATA" 419a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 420a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_CNT_UNINITIALIZED_DATA" 421a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 422a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_LNK_OTHER" 423a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_LNK_OTHER) 424a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_LNK_INFO" 425a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_LNK_INFO) 426a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_LNK_REMOVE" 427a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_LNK_REMOVE) 428a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_LNK_COMDAT" 429a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_LNK_COMDAT) 430a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_GPREL" 431a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_GPREL) 432a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_PURGEABLE" 433a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_PURGEABLE) 434a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_16BIT" 435a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_16BIT) 436a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_LOCKED" 437a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_LOCKED) 438a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_PRELOAD" 439a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_PRELOAD) 440a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_1BYTES" 441a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_1BYTES) 442a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_2BYTES" 443a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_2BYTES) 444a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_4BYTES" 445a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_4BYTES) 446a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_8BYTES" 447a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_8BYTES) 448a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_16BYTES" 449a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_16BYTES) 450a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_32BYTES" 451a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_32BYTES) 452a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_64BYTES" 453a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_64BYTES) 454a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_128BYTES" 455a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_128BYTES) 456a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_256BYTES" 457a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_256BYTES) 458a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_512BYTES" 459a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_512BYTES) 460a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_1024BYTES" 461a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_1024BYTES) 462a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_2048BYTES" 463a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_2048BYTES) 464a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_4096BYTES" 465a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_4096BYTES) 466a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_ALIGN_8192BYTES" 467a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_ALIGN_8192BYTES) 468a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_LNK_NRELOC_OVFL" 469a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_LNK_NRELOC_OVFL) 470a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_DISCARDABLE" 471a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_DISCARDABLE) 472a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_NOT_CACHED" 473a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_NOT_CACHED) 474a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_NOT_PAGED" 475a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_NOT_PAGED) 476a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_SHARED" 477a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_SHARED) 478a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_EXECUTE" 479a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_EXECUTE) 480a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_READ" 481a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_READ) 482a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SCN_MEM_WRITE" 483a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SCN_MEM_WRITE) 484a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::SC_Invalid); 485a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Characteristic == COFF::SC_Invalid) { 486a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(CharValue, "Invalid value for Characteristic"); 487a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 488a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 489a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sec.Header.Characteristics |= Characteristic; 490a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 491a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 492a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "SectionData") { 493a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Value = dyn_cast<yaml::ScalarNode>(si->getValue()); 494a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 495a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Data = Value->getValue(Storage); 496a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!hexStringToByteArray(Data, Sec.Data)) { 497a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "SectionData must be a collection of pairs of" 498a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "hex bytes"); 499a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 500a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 501a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else 502a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer si->skip(); 503a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 504a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sections.push_back(Sec); 505a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 506a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 507a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 508a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 509a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool parseSymbols(yaml::Node *SymbolsN) { 510a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::SequenceNode *SN = dyn_cast<yaml::SequenceNode>(SymbolsN); 511a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!SN) { 512a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(SymbolsN, "Symbols must be a sequence"); 513a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 514a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 515a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::SequenceNode::iterator i = SN->begin(), e = SN->end(); 516a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 517a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Symbol Sym; 518a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::memset(&Sym.Header, 0, sizeof(Sym.Header)); 519a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::MappingNode *SymMap = dyn_cast<yaml::MappingNode>(&*i); 520a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!SymMap) { 521a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(&*i, "Symbol must be a map"); 522a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 523a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 524a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::MappingNode::iterator si = SymMap->begin(), se = SymMap->end(); 525a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer si != se; ++si) { 526a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Key = dyn_cast<yaml::ScalarNode>(si->getKey()); 527a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Key) { 528a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(si->getKey(), "Keys must be scalar values"); 529a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 530a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 531a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 532a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef KeyValue = Key->getValue(Storage); 533a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 534a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Value = dyn_cast<yaml::ScalarNode>(si->getValue()); 535a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Value) { 536a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(si->getValue(), "Must be a scalar value"); 537a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 538a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 539a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (KeyValue == "Name") { 540a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // If the name is less than 8 bytes, store it in place, otherwise 541a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // store it in the string table. 542a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Name = Value->getValue(Storage); 543a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::fill_n(Sym.Header.Name, unsigned(COFF::NameSize), 0); 544a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Name.size() <= COFF::NameSize) { 545a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::copy(Name.begin(), Name.end(), Sym.Header.Name); 546a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 547a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Add string to the string table and format the index for output. 548a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer unsigned Index = getStringIndex(Name); 549a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer *reinterpret_cast<support::aligned_ulittle32_t*>( 550a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sym.Header.Name + 4) = Index; 551a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 552a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "Value") { 553a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sym.Header.Value)) { 554a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for Value"); 555a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 556a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 557a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "SimpleType") { 558a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sym.Header.Type |= StringSwitch<COFF::SymbolBaseType>( 559a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Value->getValue(Storage)) 560a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_NULL", COFF::IMAGE_SYM_TYPE_NULL) 561a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_VOID", COFF::IMAGE_SYM_TYPE_VOID) 562a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_CHAR", COFF::IMAGE_SYM_TYPE_CHAR) 563a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_SHORT", COFF::IMAGE_SYM_TYPE_SHORT) 564a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_INT", COFF::IMAGE_SYM_TYPE_INT) 565a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_LONG", COFF::IMAGE_SYM_TYPE_LONG) 566a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_FLOAT", COFF::IMAGE_SYM_TYPE_FLOAT) 567a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_DOUBLE", COFF::IMAGE_SYM_TYPE_DOUBLE) 568a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_STRUCT", COFF::IMAGE_SYM_TYPE_STRUCT) 569a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_UNION", COFF::IMAGE_SYM_TYPE_UNION) 570a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_ENUM", COFF::IMAGE_SYM_TYPE_ENUM) 571a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_MOE", COFF::IMAGE_SYM_TYPE_MOE) 572a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_BYTE", COFF::IMAGE_SYM_TYPE_BYTE) 573a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_WORD", COFF::IMAGE_SYM_TYPE_WORD) 574a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_UINT", COFF::IMAGE_SYM_TYPE_UINT) 575a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_TYPE_DWORD", COFF::IMAGE_SYM_TYPE_DWORD) 576a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::IMAGE_SYM_TYPE_NULL); 577a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "ComplexType") { 578a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sym.Header.Type |= StringSwitch<COFF::SymbolComplexType>( 579a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Value->getValue(Storage)) 580a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_DTYPE_NULL", COFF::IMAGE_SYM_DTYPE_NULL) 581a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_DTYPE_POINTER", COFF::IMAGE_SYM_DTYPE_POINTER) 582a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_DTYPE_FUNCTION", COFF::IMAGE_SYM_DTYPE_FUNCTION) 583a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case("IMAGE_SYM_DTYPE_ARRAY", COFF::IMAGE_SYM_DTYPE_ARRAY) 584a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::IMAGE_SYM_DTYPE_NULL) 585a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << COFF::SCT_COMPLEX_TYPE_SHIFT; 586a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "StorageClass") { 587a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Sym.Header.StorageClass = StringSwitch<COFF::SymbolStorageClass>( 588a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Value->getValue(Storage)) 589a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_END_OF_FUNCTION" 590a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION) 591a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_NULL" 592a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_NULL) 593a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_AUTOMATIC" 594a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_AUTOMATIC) 595a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_EXTERNAL" 596a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_EXTERNAL) 597a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_STATIC" 598a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_STATIC) 599a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_REGISTER" 600a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_REGISTER) 601a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_EXTERNAL_DEF" 602a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF) 603a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_LABEL" 604a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_LABEL) 605a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_UNDEFINED_LABEL" 606a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL) 607a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_MEMBER_OF_STRUCT" 608a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT) 609a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_ARGUMENT" 610a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_ARGUMENT) 611a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_STRUCT_TAG" 612a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_STRUCT_TAG) 613a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_MEMBER_OF_UNION" 614a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION) 615a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_UNION_TAG" 616a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_UNION_TAG) 617a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_TYPE_DEFINITION" 618a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION) 619a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_UNDEFINED_STATIC" 620a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC) 621a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_ENUM_TAG" 622a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_ENUM_TAG) 623a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_MEMBER_OF_ENUM" 624a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM) 625a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_REGISTER_PARAM" 626a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM) 627a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_BIT_FIELD" 628a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_BIT_FIELD) 629a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_BLOCK" 630a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_BLOCK) 631a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_FUNCTION" 632a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_FUNCTION) 633a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_END_OF_STRUCT" 634a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT) 635a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_FILE" 636a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_FILE) 637a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_SECTION" 638a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_SECTION) 639a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_WEAK_EXTERNAL" 640a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 641a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Case( "IMAGE_SYM_CLASS_CLR_TOKEN" 642a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , COFF::IMAGE_SYM_CLASS_CLR_TOKEN) 643a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer .Default(COFF::SSC_Invalid); 644a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (Sym.Header.StorageClass == COFF::SSC_Invalid) { 645a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for StorageClass"); 646a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 647a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 648a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "SectionNumber") { 649a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!getAs(Value, Sym.Header.SectionNumber)) { 650a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "Invalid value for SectionNumber"); 651a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 652a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 653a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "AuxillaryData") { 654a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef Data = Value->getValue(Storage); 655a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!hexStringToByteArray(Data, Sym.AuxSymbols)) { 656a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(Value, "AuxillaryData must be a collection of pairs" 657a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer "of hex bytes"); 658a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 659a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 660a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else 661a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer si->skip(); 662a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 663a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer Symbols.push_back(Sym); 664a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 665a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 666a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 667a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 668a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer bool parse() { 669a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::Document &D = *YS.begin(); 670a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::MappingNode *Root = dyn_cast<yaml::MappingNode>(D.getRoot()); 671a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Root) { 672a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(D.getRoot(), "Root node must be a map"); 673a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 674a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 675a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (yaml::MappingNode::iterator i = Root->begin(), e = Root->end(); 676a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 677a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::ScalarNode *Key = dyn_cast<yaml::ScalarNode>(i->getKey()); 678a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!Key) { 679a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer YS.printError(i->getKey(), "Keys must be scalar values"); 680a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 681a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 682a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SmallString<32> Storage; 683a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringRef KeyValue = Key->getValue(Storage); 684a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (KeyValue == "header") { 685a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!parseHeader(i->getValue())) 686a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 687a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "sections") { 688a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!parseSections(i->getValue())) 689a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 690a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else if (KeyValue == "symbols") { 691a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!parseSymbols(i->getValue())) 692a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 693a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 694a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 695a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return !YS.failed(); 696a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 697a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 698a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer unsigned getStringIndex(StringRef Str) { 699a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringMap<unsigned>::iterator i = StringTableMap.find(Str); 700a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (i == StringTableMap.end()) { 701a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer unsigned Index = StringTable.size(); 702a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringTable.append(Str.begin(), Str.end()); 703a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringTable.push_back(0); 704a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringTableMap[Str] = Index; 705a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return Index; 706a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 707a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return i->second; 708a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 709a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 710a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::Stream &YS; 711a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer COFF::header Header; 712a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 713a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer struct Section { 714a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer COFF::section Header; 715a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::vector<uint8_t> Data; 716a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::vector<COFF::relocation> Relocations; 717a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer }; 718a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 719a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer struct Symbol { 720a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer COFF::symbol Header; 721a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::vector<uint8_t> AuxSymbols; 722a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer }; 723a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 724a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::vector<Section> Sections; 725a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::vector<Symbol> Symbols; 726a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer StringMap<unsigned> StringTableMap; 727a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer std::string StringTable; 728a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer}; 729a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 730a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// Take a CP and assign addresses and sizes to everything. Returns false if the 731a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer// layout is not valid to do. 732a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstatic bool layoutCOFF(COFFParser &CP) { 733a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t SectionTableStart = 0; 734a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t SectionTableSize = 0; 735a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 736a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // The section table starts immediately after the header, including the 737a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // optional header. 738a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SectionTableStart = sizeof(COFF::header) + CP.Header.SizeOfOptionalHeader; 739a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SectionTableSize = sizeof(COFF::section) * CP.Sections.size(); 740a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 741a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize; 742a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 743a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Assign each section data address consecutively. 744a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (std::vector<COFFParser::Section>::iterator i = CP.Sections.begin(), 745a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer e = CP.Sections.end(); 746a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 747a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!i->Data.empty()) { 748a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i->Header.SizeOfRawData = i->Data.size(); 749a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i->Header.PointerToRawData = CurrentSectionDataOffset; 750a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer CurrentSectionDataOffset += i->Header.SizeOfRawData; 751a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // TODO: Handle alignment. 752a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } else { 753a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i->Header.SizeOfRawData = 0; 754a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i->Header.PointerToRawData = 0; 755a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 756a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 757a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 758a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t SymbolTableStart = CurrentSectionDataOffset; 759a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 760a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Calculate number of symbols. 761a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer uint32_t NumberOfSymbols = 0; 762a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (std::vector<COFFParser::Symbol>::iterator i = CP.Symbols.begin(), 763a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer e = CP.Symbols.end(); 764a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 765a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (i->AuxSymbols.size() % COFF::SymbolSize != 0) { 766a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer errs() << "AuxillaryData size not a multiple of symbol size!\n"; 767a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return false; 768a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 769a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i->Header.NumberOfAuxSymbols = i->AuxSymbols.size() / COFF::SymbolSize; 770a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; 771a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 772a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 773a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Store all the allocated start addresses in the header. 774a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer CP.Header.NumberOfSections = CP.Sections.size(); 775a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer CP.Header.NumberOfSymbols = NumberOfSymbols; 776a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer CP.Header.PointerToSymbolTable = SymbolTableStart; 777a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 778a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer *reinterpret_cast<support::ulittle32_t *>(&CP.StringTable[0]) 779a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer = CP.StringTable.size(); 780a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 781a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return true; 782a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 783a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 784a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencertemplate <typename value_type> 785a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerstruct binary_le_impl { 786a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer value_type Value; 787a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer binary_le_impl(value_type V) : Value(V) {} 788a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer}; 789a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 790a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencertemplate <typename value_type> 791a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerraw_ostream &operator <<( raw_ostream &OS 792a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , const binary_le_impl<value_type> &BLE) { 793a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer char Buffer[sizeof(BLE.Value)]; 794a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer support::endian::write_le<value_type, support::unaligned>(Buffer, BLE.Value); 795a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write(Buffer, sizeof(BLE.Value)); 796a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return OS; 797a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 798a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 799a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencertemplate <typename value_type> 800a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerbinary_le_impl<value_type> binary_le(value_type V) { 801a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return binary_le_impl<value_type>(V); 802a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 803a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 804a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencervoid writeCOFF(COFFParser &CP, raw_ostream &OS) { 805a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS << binary_le(CP.Header.Machine) 806a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.NumberOfSections) 807a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.TimeDateStamp) 808a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.PointerToSymbolTable) 809a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.NumberOfSymbols) 810a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.SizeOfOptionalHeader) 811a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(CP.Header.Characteristics); 812a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 813a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Output section table. 814a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(), 815a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer e = CP.Sections.end(); 816a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 817a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write(i->Header.Name, COFF::NameSize); 818a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS << binary_le(i->Header.VirtualSize) 819a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.VirtualAddress) 820a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.SizeOfRawData) 821a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.PointerToRawData) 822a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.PointerToRelocations) 823a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.PointerToLineNumbers) 824a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.NumberOfRelocations) 825a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.NumberOfLineNumbers) 826a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.Characteristics); 827a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 828a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 829a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Output section data. 830a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(), 831a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer e = CP.Sections.end(); 832a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 833a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!i->Data.empty()) 834a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write(reinterpret_cast<const char*>(&i->Data[0]), i->Data.size()); 835a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 836a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 837a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Output symbol table. 838a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 839a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer for (std::vector<COFFParser::Symbol>::const_iterator i = CP.Symbols.begin(), 840a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer e = CP.Symbols.end(); 841a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer i != e; ++i) { 842a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write(i->Header.Name, COFF::NameSize); 843a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS << binary_le(i->Header.Value) 844a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.SectionNumber) 845a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.Type) 846a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.StorageClass) 847a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer << binary_le(i->Header.NumberOfAuxSymbols); 848a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!i->AuxSymbols.empty()) 849a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write( reinterpret_cast<const char*>(&i->AuxSymbols[0]) 850a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer , i->AuxSymbols.size()); 851a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 852a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 853a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer // Output string table. 854a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OS.write(&CP.StringTable[0], CP.StringTable.size()); 855a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 856a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 857a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencerint main(int argc, char **argv) { 858a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer cl::ParseCommandLineOptions(argc, argv); 859a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer sys::PrintStackTraceOnErrorSignal(); 860a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer PrettyStackTraceProgram X(argc, argv); 861a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 862a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 863a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer OwningPtr<MemoryBuffer> Buf; 864a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) 865a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return 1; 866a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer 867a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer SourceMgr SM; 868a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer yaml::Stream S(Buf->getBuffer(), SM); 869a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer COFFParser CP(S); 870a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!CP.parse()) { 871a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer errs() << "yaml2obj: Failed to parse YAML file!\n"; 872a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return 1; 873a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 874a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer if (!layoutCOFF(CP)) { 875a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer errs() << "yaml2obj: Failed to layout COFF file!\n"; 876a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer return 1; 877a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer } 878a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer writeCOFF(CP, outs()); 879a915f247f72570a994d55cd0d2961cd2d7bbd0e1Michael J. Spencer} 880