}
}
+// Maximum offsets for different string table entry encodings.
+static const unsigned Max6DecimalOffset = 999999;
+static const unsigned Max7DecimalOffset = 9999999;
+static const uint64_t MaxBase64Offset = 0xFFFFFFFFFULL; // 64^6, including 0
+
+// Encode a string table entry offset in base 64, padded to 6 chars, and
+// prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
+// Buffer must be at least 8 bytes large. No terminating null appended.
+static void encodeBase64StringEntry(char* Buffer, uint64_t Value) {
+ assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
+ "Illegal section name encoding for value");
+
+ static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+ Buffer[0] = '/';
+ Buffer[1] = '/';
+
+ char* Ptr = Buffer + 7;
+ for (unsigned i = 0; i < 6; ++i) {
+ unsigned Rem = Value % 64;
+ Value /= 64;
+ *(Ptr--) = Alphabet[Rem];
+ }
+}
+
/// making a section real involves assigned it a number and putting
/// name into the string table if needed
void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
if (S.Name.size() > COFF::NameSize) {
- const unsigned Max6DecimalSize = 999999;
- const unsigned Max7DecimalSize = 9999999;
uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
- if (StringTableEntry <= Max6DecimalSize) {
+ if (StringTableEntry <= Max6DecimalOffset) {
std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
- } else if (StringTableEntry <= Max7DecimalSize) {
+ } else if (StringTableEntry <= Max7DecimalOffset) {
// With seven digits, we have to skip the terminating null. Because
// sprintf always appends it, we use a larger temporary buffer.
char buffer[9] = { };
std::sprintf(buffer, "/%d", unsigned(StringTableEntry));
std::memcpy(S.Header.Name, buffer, 8);
+ } else if (StringTableEntry <= MaxBase64Offset) {
+ // Starting with 10,000,000, offsets are encoded as base64.
+ encodeBase64StringEntry(S.Header.Name, StringTableEntry);
} else {
- report_fatal_error("COFF string table is greater than 9,999,999 bytes.");
+ report_fatal_error("COFF string table is greater than 64 GB.");
}
} else
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
const MCSymbol &A = Symbol.AliasedSymbol();
+ if (!Asm.hasSymbolData(A))
+ Asm.getContext().FatalError(
+ Fixup.getLoc(),
+ Twine("symbol '") + A.getName() + "' can not be undefined");
+
MCSymbolData &A_SD = Asm.getSymbolData(A);
MCSectionData const *SectionData = Fragment->getParent();