diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -589,6 +589,47 @@ // We populate subsecMap by repeatedly splitting the last (highest address) // subsection. SubsectionEntry subsecEntry = subsecMap.back(); + + if (sectionType(sectionHeaders[i].flags) == S_CSTRING_LITERALS) { + size_t off = 0; + StringRef s = toStringRef(subsecEntry.isec->data); + size_t nextSymIdxIdx = 0; + while (!s.empty()) { + InputSection *isec = subsecEntry.isec; + size_t end = s.find(0); + if (end == StringRef::npos) + fatal(toString(this) + ": string is not null terminated"); + size_t size = end + 1; + isec->data = ArrayRef( + reinterpret_cast(s.substr(0, size).data()), size); + s = s.substr(size); + + while (nextSymIdxIdx < symbolIndices.size()) { + uint32_t symIndex = symbolIndices[nextSymIdxIdx]; + const NList &sym = nList[symIndex]; + uint64_t subsecAddr = sectionAddr + off; + if (sym.n_value >= subsecAddr + size) + break; + nextSymIdxIdx++; + StringRef name = strtab + sym.n_strx; + uint64_t symbolOffset = sym.n_value - subsecAddr; + symbols[symIndex] = + createDefined(sym, name, isec, symbolOffset, size - symbolOffset); + } + + if (s.empty()) + break; + + auto *nextIsec = make(*isec); + nextIsec->numRefs = 0; + nextIsec->wasCoalesced = false; + off += size; + subsecMap.push_back({off, nextIsec}); + subsecEntry = subsecMap.back(); + } + continue; + } + for (size_t j = 0; j < symbolIndices.size(); ++j) { uint32_t symIndex = symbolIndices[j]; const NList &sym = nList[symIndex];