Index: include/lld/Core/Endian.h =================================================================== --- /dev/null +++ include/lld/Core/Endian.h @@ -0,0 +1,67 @@ +//===--- Endian.h - utility functions for endian-aware reads/writes -----*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_ENDIAN_H +#define LLD_CORE_ENDIAN_H + +#include "llvm/Support/Endian.h" + +namespace lld { + +inline uint16_t read16le(const void *p) { + return *reinterpret_cast(p); +} + +inline uint32_t read32le(const void *p) { + return *reinterpret_cast(p); +} + +inline uint64_t read64le(const void *p) { + return *reinterpret_cast(p); +} + +inline void write16le(void *p, uint16_t v) { + *reinterpret_cast(p) = v; +} + +inline void write32le(void *p, uint32_t v) { + *reinterpret_cast(p) = v; +} + +inline void write64le(void *p, uint64_t v) { + *reinterpret_cast(p) = v; +} + +inline uint16_t read16be(const void *p) { + return *reinterpret_cast(p); +} + +inline uint32_t read32be(const void *p) { + return *reinterpret_cast(p); +} + +inline uint64_t read64be(const void *p) { + return *reinterpret_cast(p); +} + +inline void write16be(void *p, uint16_t v) { + *reinterpret_cast(p) = v; +} + +inline void write32be(void *p, uint32_t v) { + *reinterpret_cast(p) = v; +} + +inline void write64be(void *p, uint64_t v) { + *reinterpret_cast(p) = v; +} + +} // namespace lld + +#endif Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -9,6 +9,7 @@ #include "AArch64TargetHandler.h" #include "AArch64LinkingContext.h" +#include "lld/Core/Endian.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" @@ -32,18 +33,14 @@ llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int64_t) * reinterpret_cast(location); + write64le(location, result | read64le(location)); } /// \brief R_AARCH64_PREL32 - word32: S + A - P static void relocR_AARCH64_PREL32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { int32_t result = (int32_t)((S + A) - P); - *reinterpret_cast(location) = - result + - (int32_t) * reinterpret_cast(location); + write32le(location, result + (int32_t)read32le(location)); } /// \brief R_AARCH64_ABS32 - word32: S + A @@ -58,9 +55,7 @@ llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); return std::error_code(); } @@ -81,9 +76,7 @@ llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - immlo | immhi | - (int32_t) * reinterpret_cast(location); + write32le(location, immlo | immhi | read32le(location)); // TODO: Make sure this is correct! } @@ -103,9 +96,7 @@ llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - immlo | immhi | - (int32_t) * reinterpret_cast(location); + write32le(location, immlo | immhi | read32le(location)); // TODO: Make sure this is correct! } @@ -120,9 +111,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } static void relocJump26(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { @@ -135,9 +124,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_CONDBR19 @@ -152,9 +139,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_LDST8_ABS_LO12_NC - S + A @@ -168,9 +153,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_LDST16_ABS_LO12_NC @@ -185,9 +168,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_LDST32_ABS_LO12_NC @@ -202,9 +183,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_LDST64_ABS_LO12_NC @@ -219,9 +198,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_LDST128_ABS_LO12_NC @@ -236,9 +213,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } static void relocR_AARCH64_ADR_GOT_PAGE(uint8_t *location, uint64_t P, @@ -257,9 +232,7 @@ llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - immlo | immhi | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } // R_AARCH64_LD64_GOT_LO12_NC @@ -274,9 +247,7 @@ llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); result &= 0xFF8; result <<= 7; - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } // ADD_AARCH64_GOTRELINDEX @@ -291,9 +262,7 @@ llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); result &= 0xFFF; result <<= 10; - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } // R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 @@ -314,9 +283,7 @@ llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - immlo | immhi | - (int32_t) * reinterpret_cast(location); + write32le(location, immlo | immhi | read32le(location)); } // R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC @@ -332,9 +299,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_TLSLE_ADD_TPREL_HI12 @@ -349,9 +314,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } /// \brief R_AARCH64_TLSLE_ADD_TPREL_LO12_NC @@ -367,9 +330,7 @@ llvm::dbgs() << " A: " << Twine::utohexstr(A); llvm::dbgs() << " P: " << Twine::utohexstr(P); llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); } std::error_code AArch64TargetRelocationHandler::applyRelocation( Index: lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp +++ lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp @@ -10,6 +10,7 @@ #include "ARMTargetHandler.h" #include "ARMLinkingContext.h" +#include "lld/Core/Endian.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" @@ -17,10 +18,8 @@ using namespace elf; static Reference::Addend readAddend_THM_MOV(const uint8_t *location) { - const auto halfHi = uint16_t( - *reinterpret_cast(location)); - const auto halfLo = uint16_t( - *reinterpret_cast(location + 2)); + const uint16_t halfHi = read16le(location); + const uint16_t halfLo = read16le(location + 2); const uint16_t imm8 = halfLo & 0xFF; const uint16_t imm3 = (halfLo >> 12) & 0x7; @@ -33,8 +32,7 @@ } static Reference::Addend readAddend_ARM_MOV(const uint8_t *location) { - const auto value = uint32_t( - *reinterpret_cast(location)); + const uint32_t value = read32le(location); const uint32_t imm12 = value & 0xFFF; const uint32_t imm4 = (value >> 16) & 0xF; @@ -44,10 +42,8 @@ } static Reference::Addend readAddend_THM_CALL(const uint8_t *location) { - const auto halfHi = uint16_t( - *reinterpret_cast(location)); - const auto halfLo = uint16_t( - *reinterpret_cast(location + 2)); + const uint16_t halfHi = read16le(location); + const uint16_t halfLo = read16le(location + 2); const uint16_t imm10 = halfHi & 0x3FF; const uint16_t bitS = (halfHi >> 10) & 0x1; @@ -64,8 +60,7 @@ } static Reference::Addend readAddend_ARM_CALL(const uint8_t *location) { - const auto value = uint32_t( - *reinterpret_cast(location)); + const uint32_t value = read32le(location); const bool isBLX = (value & 0xF0000000) == 0xF0000000; const uint32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0; @@ -78,8 +73,7 @@ Reference::KindValue kindValue) { switch (kindValue) { case R_ARM_ABS32: - return int32_t( - *reinterpret_cast(location)); + return (int32_t)read32le(location); case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: return readAddend_THM_CALL(location); @@ -100,22 +94,16 @@ static inline void applyArmReloc(uint8_t *location, uint32_t result, uint32_t mask = 0xFFFFFFFF) { assert(!(result & ~mask)); - *reinterpret_cast(location) = - (uint32_t(*reinterpret_cast(location)) & - ~mask) | (result & mask); + write32le(location, (read32le(location) & ~mask) | (result & mask)); } static inline void applyThmReloc(uint8_t *location, uint16_t resHi, uint16_t resLo, uint16_t maskHi, uint16_t maskLo = 0xFFFF) { assert(!(resHi & ~maskHi) && !(resLo & ~maskLo)); - *reinterpret_cast(location) = - (uint16_t(*reinterpret_cast(location)) & - ~maskHi) | (resHi & maskHi); + write16le(location, (read16le(location) & ~maskHi) | (resHi & maskHi)); location += 2; - *reinterpret_cast(location) = - (uint16_t(*reinterpret_cast(location)) & - ~maskLo) | (resLo & maskLo); + write16le(location, (read16le(location) & ~maskLo) | (resLo & maskLo)); } /// \brief R_ARM_ABS32 - (S + A) | T Index: lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp +++ lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp @@ -7,10 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "HexagonTargetHandler.h" #include "HexagonLinkingContext.h" #include "HexagonRelocationFunctions.h" +#include "HexagonTargetHandler.h" #include "HexagonRelocationHandler.h" +#include "lld/Core/Endian.h" using namespace lld; using namespace elf; @@ -18,9 +19,7 @@ using namespace llvm::ELF; #define APPLY_RELOC(result) \ - *reinterpret_cast(location) = \ - result | \ - (uint32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); static int relocBNPCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A, int32_t nBits) { @@ -349,5 +348,3 @@ return std::error_code(); } - - Index: lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp @@ -9,6 +9,7 @@ #include "X86LinkingContext.h" #include "X86TargetHandler.h" +#include "lld/Core/Endian.h" using namespace lld; using namespace elf; @@ -17,18 +18,14 @@ /// \brief R_386_32 - word32: S + A static int reloc32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) { int32_t result = (uint32_t)(S + A); - *reinterpret_cast(location) = - result | - (uint32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); return 0; } /// \brief R_386_PC32 - word32: S + A - P static int relocPC32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) { uint32_t result = (uint32_t)((S + A) - P); - *reinterpret_cast(location) = - result + - (uint32_t) * reinterpret_cast(location); + write32le(location, result + read32le(location)); return 0; } } Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp @@ -9,6 +9,7 @@ #include "X86_64LinkingContext.h" #include "X86_64TargetHandler.h" +#include "lld/Core/Endian.h" using namespace lld; using namespace elf; @@ -16,52 +17,40 @@ /// \brief R_X86_64_64 - word64: S + A static void reloc64(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { uint64_t result = S + A; - *reinterpret_cast(location) = - result | - (uint64_t) * reinterpret_cast(location); + write64le(location, result | read64le(location)); } /// \brief R_X86_64_PC32 - word32: S + A - P static void relocPC32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { uint32_t result = (uint32_t)((S + A) - P); - *reinterpret_cast(location) = - result + - (uint32_t) * reinterpret_cast(location); + write32le(location, result + read32le(location)); } /// \brief R_X86_64_32 - word32: S + A static void reloc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { int32_t result = (uint32_t)(S + A); - *reinterpret_cast(location) = - result | - (uint32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); // TODO: Make sure that the result zero extends to the 64bit value. } /// \brief R_X86_64_32S - word32: S + A static void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { int32_t result = (int32_t)(S + A); - *reinterpret_cast(location) = - result | - (int32_t) * reinterpret_cast(location); + write32le(location, result | read32le(location)); // TODO: Make sure that the result sign extends to the 64bit value. } /// \brief R_X86_64_16 - word16: S + A static void reloc16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { uint16_t result = (uint16_t)(S + A); - *reinterpret_cast(location) = - result | - (uint16_t) * reinterpret_cast(location); + write16le(location, result | read16le(location)); // TODO: Check for overflow. } /// \brief R_X86_64_PC64 - word64: S + A - P static void relocPC64(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) { int64_t result = (uint64_t)((S + A) - P); - *reinterpret_cast(location) = - result | - (uint64_t) * reinterpret_cast(location); + write64le(location, result | read64le(location)); } std::error_code X86_64TargetRelocationHandler::applyRelocation( @@ -100,11 +89,9 @@ _tlsSize = _x86_64Layout.getTLSSize(); if (ref.kindValue() == R_X86_64_TPOFF32 || ref.kindValue() == R_X86_64_DTPOFF32) { - int32_t result = (int32_t)(targetVAddress - _tlsSize); - *reinterpret_cast(location) = result; + write32le(location, targetVAddress - _tlsSize); } else { - int64_t result = (int64_t)(targetVAddress - _tlsSize); - *reinterpret_cast(location) = result; + write64le(location, targetVAddress - _tlsSize); } break; } Index: lib/ReaderWriter/PECOFF/IdataPass.cpp =================================================================== --- lib/ReaderWriter/PECOFF/IdataPass.cpp +++ lib/ReaderWriter/PECOFF/IdataPass.cpp @@ -9,6 +9,7 @@ #include "IdataPass.h" #include "Pass.h" +#include "lld/Core/Endian.h" #include "lld/Core/File.h" #include "lld/Core/Pass.h" #include "lld/Core/Simple.h" @@ -45,7 +46,7 @@ std::vector ret(size); ret[importName.size()] = 0; ret[importName.size() - 1] = 0; - *reinterpret_cast(&ret[0]) = hint; + write16le(&ret[0], hint); std::memcpy(&ret[2], importName.data(), importName.size()); return ret; } @@ -56,11 +57,11 @@ // in PE+. In PE+, bits 62-31 are filled with zero. if (is64) { std::vector ret(8); - *reinterpret_cast(&ret[0]) = rva; + write64le(&ret[0], rva); return ret; } std::vector ret(4); - *reinterpret_cast(&ret[0]) = rva; + write32le(&ret[0], rva); return ret; } Index: lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp =================================================================== --- lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp +++ lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp @@ -119,6 +119,7 @@ //===----------------------------------------------------------------------===// #include "Atoms.h" +#include "lld/Core/Endian.h" #include "lld/Core/Error.h" #include "lld/Core/File.h" #include "lld/Core/SharedLibraryAtom.h" @@ -245,22 +246,20 @@ const char *end = _mb->getBufferEnd(); // The size of the string that follows the header. - uint32_t dataSize = *reinterpret_cast( - buf + offsetof(COFF::ImportHeader, SizeOfData)); + uint32_t dataSize + = read32le(buf + offsetof(COFF::ImportHeader, SizeOfData)); // Check if the total size is valid. if (std::size_t(end - buf) != sizeof(COFF::ImportHeader) + dataSize) return make_error_code(NativeReaderError::unknown_file_format); - uint16_t hint = *reinterpret_cast( - buf + offsetof(COFF::ImportHeader, OrdinalHint)); + uint16_t hint = read16le(buf + offsetof(COFF::ImportHeader, OrdinalHint)); StringRef symbolName(buf + sizeof(COFF::ImportHeader)); StringRef dllName(buf + sizeof(COFF::ImportHeader) + symbolName.size() + 1); // TypeInfo is a bitfield. The least significant 2 bits are import // type, followed by 3 bit import name type. - uint16_t typeInfo = *reinterpret_cast( - buf + offsetof(COFF::ImportHeader, TypeInfo)); + uint16_t typeInfo = read16le(buf + offsetof(COFF::ImportHeader, TypeInfo)); int type = typeInfo & 0x3; int nameType = (typeInfo >> 2) & 0x7; Index: lib/ReaderWriter/PECOFF/WriterPECOFF.cpp =================================================================== --- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -22,6 +22,7 @@ #include "Atoms.h" #include "WriterImportLibrary.h" #include "lld/Core/DefinedAtom.h" +#include "lld/Core/Endian.h" #include "lld/Core/File.h" #include "lld/Core/Writer.h" #include "lld/ReaderWriter/AtomLayout.h" @@ -198,7 +199,7 @@ // Set the name of the dummy symbol to the first string table entry. // It's better than letting dumpbin print out a garabage as a symbol name. char *off = _stringTable.data() + 4; - *reinterpret_cast(off) = 4; + write32le(off, 4); } uint32_t offset = _stringTable.size(); _stringTable.insert(_stringTable.end(), sectionName.begin(), @@ -213,7 +214,7 @@ if (_stringTable.empty()) return; char *off = _stringTable.data() + sizeof(llvm::object::coff_symbol16); - *reinterpret_cast(off) = _stringTable.size(); + write32le(off, _stringTable.size()); std::memcpy(buffer, _stringTable.data(), _stringTable.size()); } @@ -1005,17 +1006,17 @@ uint8_t *ptr = &contents[0]; // The first four bytes is the page RVA. - *reinterpret_cast(ptr) = pageAddr; + write32le(ptr, pageAddr); ptr += sizeof(ulittle32_t); // The second four bytes is the size of the block, including the the page // RVA and this size field. - *reinterpret_cast(ptr) = size; + write32le(ptr, size); ptr += sizeof(ulittle32_t); for (const auto &reloc : relocs) { assert(reloc.first < _ctx.getPageSize()); - *reinterpret_cast(ptr) = (reloc.second << 12) | reloc.first; + write16le(ptr, (reloc.second << 12) | reloc.first); ptr += sizeof(ulittle16_t); } return contents;