//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h ------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H #define LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H #include "MachONormalizedFile.h" #include "lld/Core/Error.h" #include "lld/Core/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Support/LEB128.h" #include namespace lld { namespace mach_o { namespace normalized { class ByteBuffer { public: ByteBuffer() : _ostream(_bytes) { } void append_byte(uint8_t b) { _ostream << b; } void append_uleb128(uint64_t value) { llvm::encodeULEB128(value, _ostream); } void append_uleb128Fixed(uint64_t value, unsigned byteCount) { unsigned min = llvm::getULEB128Size(value); assert(min <= byteCount); unsigned pad = byteCount - min; llvm::encodeULEB128(value, _ostream, pad); } void append_sleb128(int64_t value) { llvm::encodeSLEB128(value, _ostream); } void append_string(StringRef str) { _ostream << str; append_byte(0); } void align(unsigned alignment) { while ( (_ostream.tell() % alignment) != 0 ) append_byte(0); } size_t size() { return _ostream.tell(); } const uint8_t *bytes() { return reinterpret_cast(_ostream.str().data()); } private: SmallVector _bytes; // Stream ivar must be after SmallVector ivar to construct properly. llvm::raw_svector_ostream _ostream; }; using namespace llvm::support::endian; using llvm::sys::getSwappedBytes; template static inline uint16_t read16(const T *loc, bool isBig) { assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment"); return isBig ? read16be(loc) : read16le(loc); } template static inline uint32_t read32(const T *loc, bool isBig) { assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment"); return isBig ? read32be(loc) : read32le(loc); } template static inline uint64_t read64(const T *loc, bool isBig) { assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment"); return isBig ? read64be(loc) : read64le(loc); } inline void write16(uint8_t *loc, uint16_t value, bool isBig) { if (isBig) write16be(loc, value); else write16le(loc, value); } inline void write32(uint8_t *loc, uint32_t value, bool isBig) { if (isBig) write32be(loc, value); else write32le(loc, value); } inline void write64(uint8_t *loc, uint64_t value, bool isBig) { if (isBig) write64be(loc, value); else write64le(loc, value); } inline uint32_t bitFieldExtract(uint32_t value, bool isBigEndianBigField, uint8_t firstBit, uint8_t bitCount) { const uint32_t mask = ((1<> shift) & mask; } inline void bitFieldSet(uint32_t &bits, bool isBigEndianBigField, uint32_t newBits, uint8_t firstBit, uint8_t bitCount) { const uint32_t mask = ((1< 16 ) return x.substr(0, 16); else return x; } inline void setString16(StringRef str, char s[16]) { memset(s, 0, 16); memcpy(s, str.begin(), (str.size() > 16) ? 16: str.size()); } // Implemented in normalizedToAtoms() and used by normalizedFromAtoms() so // that the same table can be used to map mach-o sections to and from // DefinedAtom::ContentType. void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType, StringRef &segmentName, StringRef §ionName, SectionType §ionType, SectionAttr §ionAttrs, bool &relocsToDefinedCanBeImplicit); } // namespace normalized } // namespace mach_o } // namespace lld #endif // LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H