LLVM API Documentation
00001 //=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Methods to output values to a data buffer. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_SUPPORT_OUTPUTBUFFER_H 00015 #define LLVM_SUPPORT_OUTPUTBUFFER_H 00016 00017 #include <string> 00018 #include <vector> 00019 00020 namespace llvm { 00021 00022 class OutputBuffer { 00023 /// Output buffer. 00024 std::vector<unsigned char> &Output; 00025 00026 /// is64Bit/isLittleEndian - This information is inferred from the target 00027 /// machine directly, indicating what header values and flags to set. 00028 bool is64Bit, isLittleEndian; 00029 public: 00030 OutputBuffer(std::vector<unsigned char> &Out, 00031 bool is64bit, bool le) 00032 : Output(Out), is64Bit(is64bit), isLittleEndian(le) {} 00033 00034 // align - Emit padding into the file until the current output position is 00035 // aligned to the specified power of two boundary. 00036 void align(unsigned Boundary) { 00037 assert(Boundary && (Boundary & (Boundary - 1)) == 0 && 00038 "Must align to 2^k boundary"); 00039 size_t Size = Output.size(); 00040 00041 if (Size & (Boundary - 1)) { 00042 // Add padding to get alignment to the correct place. 00043 size_t Pad = Boundary - (Size & (Boundary - 1)); 00044 Output.resize(Size + Pad); 00045 } 00046 } 00047 00048 //===------------------------------------------------------------------===// 00049 // Out Functions - Output the specified value to the data buffer. 00050 00051 void outbyte(unsigned char X) { 00052 Output.push_back(X); 00053 } 00054 void outhalf(unsigned short X) { 00055 if (isLittleEndian) { 00056 Output.push_back(X & 255); 00057 Output.push_back(X >> 8); 00058 } else { 00059 Output.push_back(X >> 8); 00060 Output.push_back(X & 255); 00061 } 00062 } 00063 void outword(unsigned X) { 00064 if (isLittleEndian) { 00065 Output.push_back((X >> 0) & 255); 00066 Output.push_back((X >> 8) & 255); 00067 Output.push_back((X >> 16) & 255); 00068 Output.push_back((X >> 24) & 255); 00069 } else { 00070 Output.push_back((X >> 24) & 255); 00071 Output.push_back((X >> 16) & 255); 00072 Output.push_back((X >> 8) & 255); 00073 Output.push_back((X >> 0) & 255); 00074 } 00075 } 00076 void outxword(uint64_t X) { 00077 if (isLittleEndian) { 00078 Output.push_back(unsigned(X >> 0) & 255); 00079 Output.push_back(unsigned(X >> 8) & 255); 00080 Output.push_back(unsigned(X >> 16) & 255); 00081 Output.push_back(unsigned(X >> 24) & 255); 00082 Output.push_back(unsigned(X >> 32) & 255); 00083 Output.push_back(unsigned(X >> 40) & 255); 00084 Output.push_back(unsigned(X >> 48) & 255); 00085 Output.push_back(unsigned(X >> 56) & 255); 00086 } else { 00087 Output.push_back(unsigned(X >> 56) & 255); 00088 Output.push_back(unsigned(X >> 48) & 255); 00089 Output.push_back(unsigned(X >> 40) & 255); 00090 Output.push_back(unsigned(X >> 32) & 255); 00091 Output.push_back(unsigned(X >> 24) & 255); 00092 Output.push_back(unsigned(X >> 16) & 255); 00093 Output.push_back(unsigned(X >> 8) & 255); 00094 Output.push_back(unsigned(X >> 0) & 255); 00095 } 00096 } 00097 void outaddr32(unsigned X) { 00098 outword(X); 00099 } 00100 void outaddr64(uint64_t X) { 00101 outxword(X); 00102 } 00103 void outaddr(uint64_t X) { 00104 if (!is64Bit) 00105 outword((unsigned)X); 00106 else 00107 outxword(X); 00108 } 00109 void outstring(const std::string &S, unsigned Length) { 00110 unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length 00111 ? static_cast<unsigned>(S.length()) : Length; 00112 unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length 00113 ? Length - static_cast<unsigned>(S.length()) : 0; 00114 00115 for (unsigned i = 0; i < len_to_copy; ++i) 00116 outbyte(S[i]); 00117 00118 for (unsigned i = 0; i < len_to_fill; ++i) 00119 outbyte(0); 00120 } 00121 00122 //===------------------------------------------------------------------===// 00123 // Fix Functions - Replace an existing entry at an offset. 00124 00125 void fixhalf(unsigned short X, unsigned Offset) { 00126 unsigned char *P = &Output[Offset]; 00127 P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255; 00128 P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255; 00129 } 00130 void fixword(unsigned X, unsigned Offset) { 00131 unsigned char *P = &Output[Offset]; 00132 P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255; 00133 P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255; 00134 P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255; 00135 P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255; 00136 } 00137 void fixaddr(uint64_t X, unsigned Offset) { 00138 if (!is64Bit) 00139 fixword((unsigned)X, Offset); 00140 else 00141 assert(0 && "Emission of 64-bit data not implemented yet!"); 00142 } 00143 00144 unsigned char &operator[](unsigned Index) { 00145 return Output[Index]; 00146 } 00147 const unsigned char &operator[](unsigned Index) const { 00148 return Output[Index]; 00149 } 00150 }; 00151 00152 } // end llvm namespace 00153 00154 #endif // LLVM_SUPPORT_OUTPUTBUFFER_H
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.