1193323Sed//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// Methods to output values to a data buffer. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H 15193323Sed#define LLVM_SUPPORT_OUTPUTBUFFER_H 16193323Sed 17198953Srdivacky#include <cassert> 18193323Sed#include <string> 19193323Sed#include <vector> 20193323Sed 21193323Sednamespace llvm { 22193323Sed 23193323Sed class OutputBuffer { 24193323Sed /// Output buffer. 25193323Sed std::vector<unsigned char> &Output; 26193323Sed 27193323Sed /// is64Bit/isLittleEndian - This information is inferred from the target 28193323Sed /// machine directly, indicating what header values and flags to set. 29193323Sed bool is64Bit, isLittleEndian; 30193323Sed public: 31193323Sed OutputBuffer(std::vector<unsigned char> &Out, 32193323Sed bool is64bit, bool le) 33193323Sed : Output(Out), is64Bit(is64bit), isLittleEndian(le) {} 34193323Sed 35193323Sed // align - Emit padding into the file until the current output position is 36193323Sed // aligned to the specified power of two boundary. 37193323Sed void align(unsigned Boundary) { 38193323Sed assert(Boundary && (Boundary & (Boundary - 1)) == 0 && 39193323Sed "Must align to 2^k boundary"); 40193323Sed size_t Size = Output.size(); 41193323Sed 42193323Sed if (Size & (Boundary - 1)) { 43193323Sed // Add padding to get alignment to the correct place. 44193323Sed size_t Pad = Boundary - (Size & (Boundary - 1)); 45193323Sed Output.resize(Size + Pad); 46193323Sed } 47193323Sed } 48193323Sed 49193323Sed //===------------------------------------------------------------------===// 50193323Sed // Out Functions - Output the specified value to the data buffer. 51193323Sed 52193323Sed void outbyte(unsigned char X) { 53193323Sed Output.push_back(X); 54193323Sed } 55193323Sed void outhalf(unsigned short X) { 56193323Sed if (isLittleEndian) { 57193323Sed Output.push_back(X & 255); 58193323Sed Output.push_back(X >> 8); 59193323Sed } else { 60193323Sed Output.push_back(X >> 8); 61193323Sed Output.push_back(X & 255); 62193323Sed } 63193323Sed } 64193323Sed void outword(unsigned X) { 65193323Sed if (isLittleEndian) { 66193323Sed Output.push_back((X >> 0) & 255); 67193323Sed Output.push_back((X >> 8) & 255); 68193323Sed Output.push_back((X >> 16) & 255); 69193323Sed Output.push_back((X >> 24) & 255); 70193323Sed } else { 71193323Sed Output.push_back((X >> 24) & 255); 72193323Sed Output.push_back((X >> 16) & 255); 73193323Sed Output.push_back((X >> 8) & 255); 74193323Sed Output.push_back((X >> 0) & 255); 75193323Sed } 76193323Sed } 77193323Sed void outxword(uint64_t X) { 78193323Sed if (isLittleEndian) { 79193323Sed Output.push_back(unsigned(X >> 0) & 255); 80193323Sed Output.push_back(unsigned(X >> 8) & 255); 81193323Sed Output.push_back(unsigned(X >> 16) & 255); 82193323Sed Output.push_back(unsigned(X >> 24) & 255); 83193323Sed Output.push_back(unsigned(X >> 32) & 255); 84193323Sed Output.push_back(unsigned(X >> 40) & 255); 85193323Sed Output.push_back(unsigned(X >> 48) & 255); 86193323Sed Output.push_back(unsigned(X >> 56) & 255); 87193323Sed } else { 88193323Sed Output.push_back(unsigned(X >> 56) & 255); 89193323Sed Output.push_back(unsigned(X >> 48) & 255); 90193323Sed Output.push_back(unsigned(X >> 40) & 255); 91193323Sed Output.push_back(unsigned(X >> 32) & 255); 92193323Sed Output.push_back(unsigned(X >> 24) & 255); 93193323Sed Output.push_back(unsigned(X >> 16) & 255); 94193323Sed Output.push_back(unsigned(X >> 8) & 255); 95193323Sed Output.push_back(unsigned(X >> 0) & 255); 96193323Sed } 97193323Sed } 98193323Sed void outaddr32(unsigned X) { 99193323Sed outword(X); 100193323Sed } 101193323Sed void outaddr64(uint64_t X) { 102193323Sed outxword(X); 103193323Sed } 104193323Sed void outaddr(uint64_t X) { 105193323Sed if (!is64Bit) 106193323Sed outword((unsigned)X); 107193323Sed else 108193323Sed outxword(X); 109193323Sed } 110193323Sed void outstring(const std::string &S, unsigned Length) { 111193323Sed unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length 112193323Sed ? static_cast<unsigned>(S.length()) : Length; 113193323Sed unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length 114193323Sed ? Length - static_cast<unsigned>(S.length()) : 0; 115193323Sed 116193323Sed for (unsigned i = 0; i < len_to_copy; ++i) 117193323Sed outbyte(S[i]); 118193323Sed 119193323Sed for (unsigned i = 0; i < len_to_fill; ++i) 120193323Sed outbyte(0); 121193323Sed } 122193323Sed 123193323Sed //===------------------------------------------------------------------===// 124193323Sed // Fix Functions - Replace an existing entry at an offset. 125193323Sed 126193323Sed void fixhalf(unsigned short X, unsigned Offset) { 127193323Sed unsigned char *P = &Output[Offset]; 128193323Sed P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255; 129193323Sed P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255; 130193323Sed } 131193323Sed void fixword(unsigned X, unsigned Offset) { 132193323Sed unsigned char *P = &Output[Offset]; 133193323Sed P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255; 134193323Sed P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255; 135193323Sed P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255; 136193323Sed P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255; 137193323Sed } 138193724Sed void fixxword(uint64_t X, unsigned Offset) { 139193724Sed unsigned char *P = &Output[Offset]; 140193724Sed P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255; 141193724Sed P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255; 142193724Sed P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255; 143193724Sed P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255; 144193724Sed P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255; 145193724Sed P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255; 146193724Sed P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255; 147193724Sed P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255; 148193724Sed } 149193323Sed void fixaddr(uint64_t X, unsigned Offset) { 150193323Sed if (!is64Bit) 151193323Sed fixword((unsigned)X, Offset); 152193323Sed else 153193724Sed fixxword(X, Offset); 154193323Sed } 155193323Sed 156193323Sed unsigned char &operator[](unsigned Index) { 157193323Sed return Output[Index]; 158193323Sed } 159193323Sed const unsigned char &operator[](unsigned Index) const { 160193323Sed return Output[Index]; 161193323Sed } 162193323Sed }; 163193323Sed 164193323Sed} // end llvm namespace 165193323Sed 166193323Sed#endif // LLVM_SUPPORT_OUTPUTBUFFER_H 167