COFF.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //===- llvm/BinaryFormat/COFF.cpp - The COFF format -----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/BinaryFormat/COFF.h"
  9. #include "llvm/ADT/SmallVector.h"
  10. #include "llvm/ADT/Twine.h"
  11. // Maximum offsets for different string table entry encodings.
  12. enum : unsigned { Max7DecimalOffset = 9999999U };
  13. enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
  14. // Encode a string table entry offset in base 64, padded to 6 chars, and
  15. // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
  16. // Buffer must be at least 8 bytes large. No terminating null appended.
  17. static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
  18. assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
  19. "Illegal section name encoding for value");
  20. static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  21. "abcdefghijklmnopqrstuvwxyz"
  22. "0123456789+/";
  23. Buffer[0] = '/';
  24. Buffer[1] = '/';
  25. char *Ptr = Buffer + 7;
  26. for (unsigned i = 0; i < 6; ++i) {
  27. unsigned Rem = Value % 64;
  28. Value /= 64;
  29. *(Ptr--) = Alphabet[Rem];
  30. }
  31. }
  32. bool llvm::COFF::encodeSectionName(char *Out, uint64_t Offset) {
  33. if (Offset <= Max7DecimalOffset) {
  34. // Offsets of 7 digits or less are encoded in ASCII.
  35. SmallVector<char, COFF::NameSize> Buffer;
  36. Twine('/').concat(Twine(Offset)).toVector(Buffer);
  37. assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
  38. std::memcpy(Out, Buffer.data(), Buffer.size());
  39. return true;
  40. }
  41. if (Offset <= MaxBase64Offset) {
  42. // Starting with 10,000,000, offsets are encoded as base64.
  43. encodeBase64StringEntry(Out, Offset);
  44. return true;
  45. }
  46. // The offset is too large to be encoded.
  47. return false;
  48. }