summaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support')
-rw-r--r--contrib/llvm/lib/Support/APInt.cpp323
-rw-r--r--contrib/llvm/lib/Support/BinaryStreamReader.cpp13
-rw-r--r--contrib/llvm/lib/Support/BinaryStreamWriter.cpp13
-rw-r--r--contrib/llvm/lib/Support/DataExtractor.cpp10
-rw-r--r--contrib/llvm/lib/Support/DynamicLibrary.cpp237
-rw-r--r--contrib/llvm/lib/Support/Host.cpp1
-rw-r--r--contrib/llvm/lib/Support/PrettyStackTrace.cpp1
-rw-r--r--contrib/llvm/lib/Support/ScopedPrinter.cpp6
-rw-r--r--contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp58
-rw-r--r--contrib/llvm/lib/Support/SourceMgr.cpp4
-rw-r--r--contrib/llvm/lib/Support/Triple.cpp4
-rw-r--r--contrib/llvm/lib/Support/Unix/DynamicLibrary.inc131
-rw-r--r--contrib/llvm/lib/Support/Windows/DynamicLibrary.inc218
13 files changed, 567 insertions, 452 deletions
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp
index 1227d7528c8f..fa81b28cd083 100644
--- a/contrib/llvm/lib/Support/APInt.cpp
+++ b/contrib/llvm/lib/Support/APInt.cpp
@@ -76,34 +76,31 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) {
void APInt::initSlowCase(uint64_t val, bool isSigned) {
- VAL = 0;
- pVal = getClearedMemory(getNumWords());
- pVal[0] = val;
+ U.pVal = getClearedMemory(getNumWords());
+ U.pVal[0] = val;
if (isSigned && int64_t(val) < 0)
for (unsigned i = 1; i < getNumWords(); ++i)
- pVal[i] = WORD_MAX;
+ U.pVal[i] = WORD_MAX;
clearUnusedBits();
}
void APInt::initSlowCase(const APInt& that) {
- VAL = 0;
- pVal = getMemory(getNumWords());
- memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);
+ U.pVal = getMemory(getNumWords());
+ memcpy(U.pVal, that.U.pVal, getNumWords() * APINT_WORD_SIZE);
}
void APInt::initFromArray(ArrayRef<uint64_t> bigVal) {
assert(BitWidth && "Bitwidth too small");
assert(bigVal.data() && "Null pointer detected!");
if (isSingleWord())
- VAL = bigVal[0];
+ U.VAL = bigVal[0];
else {
// Get memory, cleared to 0
- VAL = 0;
- pVal = getClearedMemory(getNumWords());
+ U.pVal = getClearedMemory(getNumWords());
// Calculate the number of words to copy
unsigned words = std::min<unsigned>(bigVal.size(), getNumWords());
// Copy the words from bigVal to pVal
- memcpy(pVal, bigVal.data(), words * APINT_WORD_SIZE);
+ memcpy(U.pVal, bigVal.data(), words * APINT_WORD_SIZE);
}
// Make sure unused high bits are cleared
clearUnusedBits();
@@ -120,7 +117,7 @@ APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
}
APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix)
- : VAL(0), BitWidth(numbits) {
+ : BitWidth(numbits) {
assert(BitWidth && "Bitwidth too small");
fromString(numbits, Str, radix);
}
@@ -133,25 +130,24 @@ void APInt::AssignSlowCase(const APInt& RHS) {
if (BitWidth == RHS.getBitWidth()) {
// assume same bit-width single-word case is already handled
assert(!isSingleWord());
- memcpy(pVal, RHS.pVal, getNumWords() * APINT_WORD_SIZE);
+ memcpy(U.pVal, RHS.U.pVal, getNumWords() * APINT_WORD_SIZE);
return;
}
if (isSingleWord()) {
// assume case where both are single words is already handled
assert(!RHS.isSingleWord());
- VAL = 0;
- pVal = getMemory(RHS.getNumWords());
- memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ U.pVal = getMemory(RHS.getNumWords());
+ memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
} else if (getNumWords() == RHS.getNumWords())
- memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
else if (RHS.isSingleWord()) {
- delete [] pVal;
- VAL = RHS.VAL;
+ delete [] U.pVal;
+ U.VAL = RHS.U.VAL;
} else {
- delete [] pVal;
- pVal = getMemory(RHS.getNumWords());
- memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ delete [] U.pVal;
+ U.pVal = getMemory(RHS.getNumWords());
+ memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
}
BitWidth = RHS.BitWidth;
clearUnusedBits();
@@ -162,30 +158,30 @@ void APInt::Profile(FoldingSetNodeID& ID) const {
ID.AddInteger(BitWidth);
if (isSingleWord()) {
- ID.AddInteger(VAL);
+ ID.AddInteger(U.VAL);
return;
}
unsigned NumWords = getNumWords();
for (unsigned i = 0; i < NumWords; ++i)
- ID.AddInteger(pVal[i]);
+ ID.AddInteger(U.pVal[i]);
}
/// @brief Prefix increment operator. Increments the APInt by one.
APInt& APInt::operator++() {
if (isSingleWord())
- ++VAL;
+ ++U.VAL;
else
- tcIncrement(pVal, getNumWords());
+ tcIncrement(U.pVal, getNumWords());
return clearUnusedBits();
}
/// @brief Prefix decrement operator. Decrements the APInt by one.
APInt& APInt::operator--() {
if (isSingleWord())
- --VAL;
+ --U.VAL;
else
- tcDecrement(pVal, getNumWords());
+ tcDecrement(U.pVal, getNumWords());
return clearUnusedBits();
}
@@ -195,17 +191,17 @@ APInt& APInt::operator--() {
APInt& APInt::operator+=(const APInt& RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL += RHS.VAL;
+ U.VAL += RHS.U.VAL;
else
- tcAdd(pVal, RHS.pVal, 0, getNumWords());
+ tcAdd(U.pVal, RHS.U.pVal, 0, getNumWords());
return clearUnusedBits();
}
APInt& APInt::operator+=(uint64_t RHS) {
if (isSingleWord())
- VAL += RHS;
+ U.VAL += RHS;
else
- tcAddPart(pVal, RHS, getNumWords());
+ tcAddPart(U.pVal, RHS, getNumWords());
return clearUnusedBits();
}
@@ -215,17 +211,17 @@ APInt& APInt::operator+=(uint64_t RHS) {
APInt& APInt::operator-=(const APInt& RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL -= RHS.VAL;
+ U.VAL -= RHS.U.VAL;
else
- tcSubtract(pVal, RHS.pVal, 0, getNumWords());
+ tcSubtract(U.pVal, RHS.U.pVal, 0, getNumWords());
return clearUnusedBits();
}
APInt& APInt::operator-=(uint64_t RHS) {
if (isSingleWord())
- VAL -= RHS;
+ U.VAL -= RHS;
else
- tcSubtractPart(pVal, RHS, getNumWords());
+ tcSubtractPart(U.pVal, RHS, getNumWords());
return clearUnusedBits();
}
@@ -300,7 +296,7 @@ static void mul(uint64_t dest[], uint64_t x[], unsigned xlen, uint64_t y[],
APInt& APInt::operator*=(const APInt& RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) {
- VAL *= RHS.VAL;
+ U.VAL *= RHS.U.VAL;
clearUnusedBits();
return *this;
}
@@ -326,12 +322,12 @@ APInt& APInt::operator*=(const APInt& RHS) {
uint64_t *dest = getMemory(destWords);
// Perform the long multiply
- mul(dest, pVal, lhsWords, RHS.pVal, rhsWords);
+ mul(dest, U.pVal, lhsWords, RHS.U.pVal, rhsWords);
// Copy result back into *this
clearAllBits();
unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
- memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
+ memcpy(U.pVal, dest, wordsToCopy * APINT_WORD_SIZE);
clearUnusedBits();
// delete dest array and return
@@ -340,43 +336,43 @@ APInt& APInt::operator*=(const APInt& RHS) {
}
void APInt::AndAssignSlowCase(const APInt& RHS) {
- tcAnd(pVal, RHS.pVal, getNumWords());
+ tcAnd(U.pVal, RHS.U.pVal, getNumWords());
}
void APInt::OrAssignSlowCase(const APInt& RHS) {
- tcOr(pVal, RHS.pVal, getNumWords());
+ tcOr(U.pVal, RHS.U.pVal, getNumWords());
}
void APInt::XorAssignSlowCase(const APInt& RHS) {
- tcXor(pVal, RHS.pVal, getNumWords());
+ tcXor(U.pVal, RHS.U.pVal, getNumWords());
}
APInt APInt::operator*(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- return APInt(BitWidth, VAL * RHS.VAL);
+ return APInt(BitWidth, U.VAL * RHS.U.VAL);
APInt Result(*this);
Result *= RHS;
return Result;
}
bool APInt::EqualSlowCase(const APInt& RHS) const {
- return std::equal(pVal, pVal + getNumWords(), RHS.pVal);
+ return std::equal(U.pVal, U.pVal + getNumWords(), RHS.U.pVal);
}
int APInt::compare(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison");
if (isSingleWord())
- return VAL < RHS.VAL ? -1 : VAL > RHS.VAL;
+ return U.VAL < RHS.U.VAL ? -1 : U.VAL > RHS.U.VAL;
- return tcCompare(pVal, RHS.pVal, getNumWords());
+ return tcCompare(U.pVal, RHS.U.pVal, getNumWords());
}
int APInt::compareSigned(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison");
if (isSingleWord()) {
- int64_t lhsSext = SignExtend64(VAL, BitWidth);
- int64_t rhsSext = SignExtend64(RHS.VAL, BitWidth);
+ int64_t lhsSext = SignExtend64(U.VAL, BitWidth);
+ int64_t rhsSext = SignExtend64(RHS.U.VAL, BitWidth);
return lhsSext < rhsSext ? -1 : lhsSext > rhsSext;
}
@@ -389,14 +385,7 @@ int APInt::compareSigned(const APInt& RHS) const {
// Otherwise we can just use an unsigned comparison, because even negative
// numbers compare correctly this way if both have the same signed-ness.
- return tcCompare(pVal, RHS.pVal, getNumWords());
-}
-
-void APInt::setBit(unsigned bitPosition) {
- if (isSingleWord())
- VAL |= maskBit(bitPosition);
- else
- pVal[whichWord(bitPosition)] |= maskBit(bitPosition);
+ return tcCompare(U.pVal, RHS.U.pVal, getNumWords());
}
void APInt::setBitsSlowCase(unsigned loBit, unsigned hiBit) {
@@ -416,28 +405,19 @@ void APInt::setBitsSlowCase(unsigned loBit, unsigned hiBit) {
if (hiWord == loWord)
loMask &= hiMask;
else
- pVal[hiWord] |= hiMask;
+ U.pVal[hiWord] |= hiMask;
}
// Apply the mask to the low word.
- pVal[loWord] |= loMask;
+ U.pVal[loWord] |= loMask;
// Fill any words between loWord and hiWord with all ones.
for (unsigned word = loWord + 1; word < hiWord; ++word)
- pVal[word] = WORD_MAX;
-}
-
-/// Set the given bit to 0 whose position is given as "bitPosition".
-/// @brief Set a given bit to 0.
-void APInt::clearBit(unsigned bitPosition) {
- if (isSingleWord())
- VAL &= ~maskBit(bitPosition);
- else
- pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition);
+ U.pVal[word] = WORD_MAX;
}
/// @brief Toggle every bit to its opposite value.
void APInt::flipAllBitsSlowCase() {
- tcComplement(pVal, getNumWords());
+ tcComplement(U.pVal, getNumWords());
clearUnusedBits();
}
@@ -464,8 +444,8 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) {
// Single word result can be done as a direct bitmask.
if (isSingleWord()) {
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - subBitWidth);
- VAL &= ~(mask << bitPosition);
- VAL |= (subBits.VAL << bitPosition);
+ U.VAL &= ~(mask << bitPosition);
+ U.VAL |= (subBits.U.VAL << bitPosition);
return;
}
@@ -476,8 +456,8 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) {
// Insertion within a single word can be done as a direct bitmask.
if (loWord == hi1Word) {
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - subBitWidth);
- pVal[loWord] &= ~(mask << loBit);
- pVal[loWord] |= (subBits.VAL << loBit);
+ U.pVal[loWord] &= ~(mask << loBit);
+ U.pVal[loWord] |= (subBits.U.VAL << loBit);
return;
}
@@ -485,15 +465,15 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) {
if (loBit == 0) {
// Direct copy whole words.
unsigned numWholeSubWords = subBitWidth / APINT_BITS_PER_WORD;
- memcpy(pVal + loWord, subBits.getRawData(),
+ memcpy(U.pVal + loWord, subBits.getRawData(),
numWholeSubWords * APINT_WORD_SIZE);
// Mask+insert remaining bits.
unsigned remainingBits = subBitWidth % APINT_BITS_PER_WORD;
if (remainingBits != 0) {
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - remainingBits);
- pVal[hi1Word] &= ~mask;
- pVal[hi1Word] |= subBits.getWord(subBitWidth - 1);
+ U.pVal[hi1Word] &= ~mask;
+ U.pVal[hi1Word] |= subBits.getWord(subBitWidth - 1);
}
return;
}
@@ -515,7 +495,7 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const {
"Illegal bit extraction");
if (isSingleWord())
- return APInt(numBits, VAL >> bitPosition);
+ return APInt(numBits, U.VAL >> bitPosition);
unsigned loBit = whichBit(bitPosition);
unsigned loWord = whichWord(bitPosition);
@@ -523,12 +503,12 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const {
// Single word result extracting bits from a single word source.
if (loWord == hiWord)
- return APInt(numBits, pVal[loWord] >> loBit);
+ return APInt(numBits, U.pVal[loWord] >> loBit);
// Extracting bits that start on a source word boundary can be done
// as a fast memory copy.
if (loBit == 0)
- return APInt(numBits, makeArrayRef(pVal + loWord, 1 + hiWord - loWord));
+ return APInt(numBits, makeArrayRef(U.pVal + loWord, 1 + hiWord - loWord));
// General case - shift + copy source words directly into place.
APInt Result(numBits, 0);
@@ -536,10 +516,10 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const {
unsigned NumDstWords = Result.getNumWords();
for (unsigned word = 0; word < NumDstWords; ++word) {
- uint64_t w0 = pVal[loWord + word];
+ uint64_t w0 = U.pVal[loWord + word];
uint64_t w1 =
- (loWord + word + 1) < NumSrcWords ? pVal[loWord + word + 1] : 0;
- Result.pVal[word] = (w0 >> loBit) | (w1 << (APINT_BITS_PER_WORD - loBit));
+ (loWord + word + 1) < NumSrcWords ? U.pVal[loWord + word + 1] : 0;
+ Result.U.pVal[word] = (w0 >> loBit) | (w1 << (APINT_BITS_PER_WORD - loBit));
}
return Result.clearUnusedBits();
@@ -600,9 +580,9 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {
hash_code llvm::hash_value(const APInt &Arg) {
if (Arg.isSingleWord())
- return hash_combine(Arg.VAL);
+ return hash_combine(Arg.U.VAL);
- return hash_combine_range(Arg.pVal, Arg.pVal + Arg.getNumWords());
+ return hash_combine_range(Arg.U.pVal, Arg.U.pVal + Arg.getNumWords());
}
bool APInt::isSplat(unsigned SplatSizeInBits) const {
@@ -625,10 +605,21 @@ APInt APInt::getLoBits(unsigned numBits) const {
return Result;
}
+/// Return a value containing V broadcasted over NewLen bits.
+APInt APInt::getSplat(unsigned NewLen, const APInt &V) {
+ assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
+
+ APInt Val = V.zextOrSelf(NewLen);
+ for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
+ Val |= Val << I;
+
+ return Val;
+}
+
unsigned APInt::countLeadingZerosSlowCase() const {
unsigned Count = 0;
for (int i = getNumWords()-1; i >= 0; --i) {
- uint64_t V = pVal[i];
+ uint64_t V = U.pVal[i];
if (V == 0)
Count += APINT_BITS_PER_WORD;
else {
@@ -644,7 +635,7 @@ unsigned APInt::countLeadingZerosSlowCase() const {
unsigned APInt::countLeadingOnes() const {
if (isSingleWord())
- return llvm::countLeadingOnes(VAL << (APINT_BITS_PER_WORD - BitWidth));
+ return llvm::countLeadingOnes(U.VAL << (APINT_BITS_PER_WORD - BitWidth));
unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;
unsigned shift;
@@ -655,13 +646,13 @@ unsigned APInt::countLeadingOnes() const {
shift = APINT_BITS_PER_WORD - highWordBits;
}
int i = getNumWords() - 1;
- unsigned Count = llvm::countLeadingOnes(pVal[i] << shift);
+ unsigned Count = llvm::countLeadingOnes(U.pVal[i] << shift);
if (Count == highWordBits) {
for (i--; i >= 0; --i) {
- if (pVal[i] == WORD_MAX)
+ if (U.pVal[i] == WORD_MAX)
Count += APINT_BITS_PER_WORD;
else {
- Count += llvm::countLeadingOnes(pVal[i]);
+ Count += llvm::countLeadingOnes(U.pVal[i]);
break;
}
}
@@ -671,23 +662,23 @@ unsigned APInt::countLeadingOnes() const {
unsigned APInt::countTrailingZeros() const {
if (isSingleWord())
- return std::min(unsigned(llvm::countTrailingZeros(VAL)), BitWidth);
+ return std::min(unsigned(llvm::countTrailingZeros(U.VAL)), BitWidth);
unsigned Count = 0;
unsigned i = 0;
- for (; i < getNumWords() && pVal[i] == 0; ++i)
+ for (; i < getNumWords() && U.pVal[i] == 0; ++i)
Count += APINT_BITS_PER_WORD;
if (i < getNumWords())
- Count += llvm::countTrailingZeros(pVal[i]);
+ Count += llvm::countTrailingZeros(U.pVal[i]);
return std::min(Count, BitWidth);
}
unsigned APInt::countTrailingOnesSlowCase() const {
unsigned Count = 0;
unsigned i = 0;
- for (; i < getNumWords() && pVal[i] == WORD_MAX; ++i)
+ for (; i < getNumWords() && U.pVal[i] == WORD_MAX; ++i)
Count += APINT_BITS_PER_WORD;
if (i < getNumWords())
- Count += llvm::countTrailingOnes(pVal[i]);
+ Count += llvm::countTrailingOnes(U.pVal[i]);
assert(Count <= BitWidth);
return Count;
}
@@ -695,13 +686,13 @@ unsigned APInt::countTrailingOnesSlowCase() const {
unsigned APInt::countPopulationSlowCase() const {
unsigned Count = 0;
for (unsigned i = 0; i < getNumWords(); ++i)
- Count += llvm::countPopulation(pVal[i]);
+ Count += llvm::countPopulation(U.pVal[i]);
return Count;
}
bool APInt::intersectsSlowCase(const APInt &RHS) const {
for (unsigned i = 0, e = getNumWords(); i != e; ++i)
- if ((pVal[i] & RHS.pVal[i]) != 0)
+ if ((U.pVal[i] & RHS.U.pVal[i]) != 0)
return true;
return false;
@@ -709,7 +700,7 @@ bool APInt::intersectsSlowCase(const APInt &RHS) const {
bool APInt::isSubsetOfSlowCase(const APInt &RHS) const {
for (unsigned i = 0, e = getNumWords(); i != e; ++i)
- if ((pVal[i] & ~RHS.pVal[i]) != 0)
+ if ((U.pVal[i] & ~RHS.U.pVal[i]) != 0)
return false;
return true;
@@ -718,22 +709,22 @@ bool APInt::isSubsetOfSlowCase(const APInt &RHS) const {
APInt APInt::byteSwap() const {
assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!");
if (BitWidth == 16)
- return APInt(BitWidth, ByteSwap_16(uint16_t(VAL)));
+ return APInt(BitWidth, ByteSwap_16(uint16_t(U.VAL)));
if (BitWidth == 32)
- return APInt(BitWidth, ByteSwap_32(unsigned(VAL)));
+ return APInt(BitWidth, ByteSwap_32(unsigned(U.VAL)));
if (BitWidth == 48) {
- unsigned Tmp1 = unsigned(VAL >> 16);
+ unsigned Tmp1 = unsigned(U.VAL >> 16);
Tmp1 = ByteSwap_32(Tmp1);
- uint16_t Tmp2 = uint16_t(VAL);
+ uint16_t Tmp2 = uint16_t(U.VAL);
Tmp2 = ByteSwap_16(Tmp2);
return APInt(BitWidth, (uint64_t(Tmp2) << 32) | Tmp1);
}
if (BitWidth == 64)
- return APInt(BitWidth, ByteSwap_64(VAL));
+ return APInt(BitWidth, ByteSwap_64(U.VAL));
APInt Result(getNumWords() * APINT_BITS_PER_WORD, 0);
for (unsigned I = 0, N = getNumWords(); I != N; ++I)
- Result.pVal[I] = ByteSwap_64(pVal[N - I - 1]);
+ Result.U.pVal[I] = ByteSwap_64(U.pVal[N - I - 1]);
if (Result.BitWidth != BitWidth) {
Result.lshrInPlace(Result.BitWidth - BitWidth);
Result.BitWidth = BitWidth;
@@ -744,13 +735,13 @@ APInt APInt::byteSwap() const {
APInt APInt::reverseBits() const {
switch (BitWidth) {
case 64:
- return APInt(BitWidth, llvm::reverseBits<uint64_t>(VAL));
+ return APInt(BitWidth, llvm::reverseBits<uint64_t>(U.VAL));
case 32:
- return APInt(BitWidth, llvm::reverseBits<uint32_t>(VAL));
+ return APInt(BitWidth, llvm::reverseBits<uint32_t>(U.VAL));
case 16:
- return APInt(BitWidth, llvm::reverseBits<uint16_t>(VAL));
+ return APInt(BitWidth, llvm::reverseBits<uint16_t>(U.VAL));
case 8:
- return APInt(BitWidth, llvm::reverseBits<uint8_t>(VAL));
+ return APInt(BitWidth, llvm::reverseBits<uint8_t>(U.VAL));
default:
break;
}
@@ -844,7 +835,7 @@ APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, unsigned width) {
// Otherwise, we have to shift the mantissa bits up to the right location
APInt Tmp(width, mantissa);
- Tmp = Tmp.shl((unsigned)exp - 52);
+ Tmp <<= (unsigned)exp - 52;
return isNeg ? -Tmp : Tmp;
}
@@ -895,13 +886,13 @@ double APInt::roundToDouble(bool isSigned) const {
uint64_t mantissa;
unsigned hiWord = whichWord(n-1);
if (hiWord == 0) {
- mantissa = Tmp.pVal[0];
+ mantissa = Tmp.U.pVal[0];
if (n > 52)
mantissa >>= n - 52; // shift down, we want the top 52 bits.
} else {
assert(hiWord > 0 && "huh?");
- uint64_t hibits = Tmp.pVal[hiWord] << (52 - n % APINT_BITS_PER_WORD);
- uint64_t lobits = Tmp.pVal[hiWord-1] >> (11 + n % APINT_BITS_PER_WORD);
+ uint64_t hibits = Tmp.U.pVal[hiWord] << (52 - n % APINT_BITS_PER_WORD);
+ uint64_t lobits = Tmp.U.pVal[hiWord-1] >> (11 + n % APINT_BITS_PER_WORD);
mantissa = hibits | lobits;
}
@@ -928,12 +919,12 @@ APInt APInt::trunc(unsigned width) const {
// Copy full words.
unsigned i;
for (i = 0; i != width / APINT_BITS_PER_WORD; i++)
- Result.pVal[i] = pVal[i];
+ Result.U.pVal[i] = U.pVal[i];
// Truncate and copy any partial word.
unsigned bits = (0 - width) % APINT_BITS_PER_WORD;
if (bits != 0)
- Result.pVal[i] = pVal[i] << bits >> bits;
+ Result.U.pVal[i] = U.pVal[i] << bits >> bits;
return Result;
}
@@ -943,20 +934,20 @@ APInt APInt::sext(unsigned Width) const {
assert(Width > BitWidth && "Invalid APInt SignExtend request");
if (Width <= APINT_BITS_PER_WORD)
- return APInt(Width, SignExtend64(VAL, BitWidth));
+ return APInt(Width, SignExtend64(U.VAL, BitWidth));
APInt Result(getMemory(getNumWords(Width)), Width);
// Copy words.
- std::memcpy(Result.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
+ std::memcpy(Result.U.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
// Sign extend the last word since there may be unused bits in the input.
- Result.pVal[getNumWords() - 1] =
- SignExtend64(Result.pVal[getNumWords() - 1],
+ Result.U.pVal[getNumWords() - 1] =
+ SignExtend64(Result.U.pVal[getNumWords() - 1],
((BitWidth - 1) % APINT_BITS_PER_WORD) + 1);
// Fill with sign bits.
- std::memset(Result.pVal + getNumWords(), isNegative() ? -1 : 0,
+ std::memset(Result.U.pVal + getNumWords(), isNegative() ? -1 : 0,
(Result.getNumWords() - getNumWords()) * APINT_WORD_SIZE);
Result.clearUnusedBits();
return Result;
@@ -967,15 +958,15 @@ APInt APInt::zext(unsigned width) const {
assert(width > BitWidth && "Invalid APInt ZeroExtend request");
if (width <= APINT_BITS_PER_WORD)
- return APInt(width, VAL);
+ return APInt(width, U.VAL);
APInt Result(getMemory(getNumWords(width)), width);
// Copy words.
- std::memcpy(Result.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
+ std::memcpy(Result.U.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
// Zero remaining words.
- std::memset(Result.pVal + getNumWords(), 0,
+ std::memset(Result.U.pVal + getNumWords(), 0,
(Result.getNumWords() - getNumWords()) * APINT_WORD_SIZE);
return Result;
@@ -1032,28 +1023,28 @@ void APInt::ashrSlowCase(unsigned ShiftAmt) {
unsigned WordsToMove = getNumWords() - WordShift;
if (WordsToMove != 0) {
// Sign extend the last word to fill in the unused bits.
- pVal[getNumWords() - 1] = SignExtend64(
- pVal[getNumWords() - 1], ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1);
+ U.pVal[getNumWords() - 1] = SignExtend64(
+ U.pVal[getNumWords() - 1], ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1);
// Fastpath for moving by whole words.
if (BitShift == 0) {
- std::memmove(pVal, pVal + WordShift, WordsToMove * APINT_WORD_SIZE);
+ std::memmove(U.pVal, U.pVal + WordShift, WordsToMove * APINT_WORD_SIZE);
} else {
// Move the words containing significant bits.
for (unsigned i = 0; i != WordsToMove - 1; ++i)
- pVal[i] = (pVal[i + WordShift] >> BitShift) |
- (pVal[i + WordShift + 1] << (APINT_BITS_PER_WORD - BitShift));
+ U.pVal[i] = (U.pVal[i + WordShift] >> BitShift) |
+ (U.pVal[i + WordShift + 1] << (APINT_BITS_PER_WORD - BitShift));
// Handle the last word which has no high bits to copy.
- pVal[WordsToMove - 1] = pVal[WordShift + WordsToMove - 1] >> BitShift;
+ U.pVal[WordsToMove - 1] = U.pVal[WordShift + WordsToMove - 1] >> BitShift;
// Sign extend one more time.
- pVal[WordsToMove - 1] =
- SignExtend64(pVal[WordsToMove - 1], APINT_BITS_PER_WORD - BitShift);
+ U.pVal[WordsToMove - 1] =
+ SignExtend64(U.pVal[WordsToMove - 1], APINT_BITS_PER_WORD - BitShift);
}
}
// Fill in the remainder based on the original sign.
- std::memset(pVal + WordsToMove, Negative ? -1 : 0,
+ std::memset(U.pVal + WordsToMove, Negative ? -1 : 0,
WordShift * APINT_WORD_SIZE);
clearUnusedBits();
}
@@ -1067,18 +1058,19 @@ void APInt::lshrInPlace(const APInt &shiftAmt) {
/// Logical right-shift this APInt by shiftAmt.
/// @brief Logical right-shift function.
void APInt::lshrSlowCase(unsigned ShiftAmt) {
- tcShiftRight(pVal, getNumWords(), ShiftAmt);
+ tcShiftRight(U.pVal, getNumWords(), ShiftAmt);
}
/// Left-shift this APInt by shiftAmt.
/// @brief Left-shift function.
-APInt APInt::shl(const APInt &shiftAmt) const {
+APInt &APInt::operator<<=(const APInt &shiftAmt) {
// It's undefined behavior in C to shift by BitWidth or greater.
- return shl((unsigned)shiftAmt.getLimitedValue(BitWidth));
+ *this <<= (unsigned)shiftAmt.getLimitedValue(BitWidth);
+ return *this;
}
void APInt::shlSlowCase(unsigned ShiftAmt) {
- tcShiftLeft(pVal, getNumWords(), ShiftAmt);
+ tcShiftLeft(U.pVal, getNumWords(), ShiftAmt);
clearUnusedBits();
}
@@ -1141,7 +1133,7 @@ APInt APInt::sqrt() const {
/* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/* 31 */ 6
};
- return APInt(BitWidth, results[ (isSingleWord() ? VAL : pVal[0]) ]);
+ return APInt(BitWidth, results[ (isSingleWord() ? U.VAL : U.pVal[0]) ]);
}
// If the magnitude of the value fits in less than 52 bits (the precision of
@@ -1150,7 +1142,8 @@ APInt APInt::sqrt() const {
// This should be faster than the algorithm below.
if (magnitude < 52) {
return APInt(BitWidth,
- uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0])))));
+ uint64_t(::round(::sqrt(double(isSingleWord() ? U.VAL
+ : U.pVal[0])))));
}
// Okay, all the short cuts are exhausted. We must compute it. The following
@@ -1528,7 +1521,7 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
// Initialize the dividend
memset(U, 0, (m+n+1)*sizeof(unsigned));
for (unsigned i = 0; i < lhsWords; ++i) {
- uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]);
+ uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.U.VAL : LHS.U.pVal[i]);
U[i * 2] = (unsigned)(tmp & mask);
U[i * 2 + 1] = (unsigned)(tmp >> (sizeof(unsigned)*CHAR_BIT));
}
@@ -1537,7 +1530,7 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
// Initialize the divisor
memset(V, 0, (n)*sizeof(unsigned));
for (unsigned i = 0; i < rhsWords; ++i) {
- uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]);
+ uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.U.VAL : RHS.U.pVal[i]);
V[i * 2] = (unsigned)(tmp & mask);
V[i * 2 + 1] = (unsigned)(tmp >> (sizeof(unsigned)*CHAR_BIT));
}
@@ -1597,12 +1590,12 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
// Set up the Quotient value's memory.
if (Quotient->BitWidth != LHS.BitWidth) {
if (Quotient->isSingleWord())
- Quotient->VAL = 0;
+ Quotient->U.VAL = 0;
else
- delete [] Quotient->pVal;
+ delete [] Quotient->U.pVal;
Quotient->BitWidth = LHS.BitWidth;
if (!Quotient->isSingleWord())
- Quotient->pVal = getClearedMemory(Quotient->getNumWords());
+ Quotient->U.pVal = getClearedMemory(Quotient->getNumWords());
} else
Quotient->clearAllBits();
@@ -1614,13 +1607,13 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
uint64_t tmp =
uint64_t(Q[0]) | (uint64_t(Q[1]) << (APINT_BITS_PER_WORD / 2));
if (Quotient->isSingleWord())
- Quotient->VAL = tmp;
+ Quotient->U.VAL = tmp;
else
- Quotient->pVal[0] = tmp;
+ Quotient->U.pVal[0] = tmp;
} else {
assert(!Quotient->isSingleWord() && "Quotient APInt not large enough");
for (unsigned i = 0; i < lhsWords; ++i)
- Quotient->pVal[i] =
+ Quotient->U.pVal[i] =
uint64_t(Q[i*2]) | (uint64_t(Q[i*2+1]) << (APINT_BITS_PER_WORD / 2));
}
}
@@ -1630,12 +1623,12 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
// Set up the Remainder value's memory.
if (Remainder->BitWidth != RHS.BitWidth) {
if (Remainder->isSingleWord())
- Remainder->VAL = 0;
+ Remainder->U.VAL = 0;
else
- delete [] Remainder->pVal;
+ delete [] Remainder->U.pVal;
Remainder->BitWidth = RHS.BitWidth;
if (!Remainder->isSingleWord())
- Remainder->pVal = getClearedMemory(Remainder->getNumWords());
+ Remainder->U.pVal = getClearedMemory(Remainder->getNumWords());
} else
Remainder->clearAllBits();
@@ -1645,13 +1638,13 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
uint64_t tmp =
uint64_t(R[0]) | (uint64_t(R[1]) << (APINT_BITS_PER_WORD / 2));
if (Remainder->isSingleWord())
- Remainder->VAL = tmp;
+ Remainder->U.VAL = tmp;
else
- Remainder->pVal[0] = tmp;
+ Remainder->U.pVal[0] = tmp;
} else {
assert(!Remainder->isSingleWord() && "Remainder APInt not large enough");
for (unsigned i = 0; i < rhsWords; ++i)
- Remainder->pVal[i] =
+ Remainder->U.pVal[i] =
uint64_t(R[i*2]) | (uint64_t(R[i*2+1]) << (APINT_BITS_PER_WORD / 2));
}
}
@@ -1670,8 +1663,8 @@ APInt APInt::udiv(const APInt& RHS) const {
// First, deal with the easy case
if (isSingleWord()) {
- assert(RHS.VAL != 0 && "Divide by zero?");
- return APInt(BitWidth, VAL / RHS.VAL);
+ assert(RHS.U.VAL != 0 && "Divide by zero?");
+ return APInt(BitWidth, U.VAL / RHS.U.VAL);
}
// Get some facts about the LHS and RHS number of bits and words
@@ -1693,7 +1686,7 @@ APInt APInt::udiv(const APInt& RHS) const {
return APInt(BitWidth, 1);
} else if (lhsWords == 1 && rhsWords == 1) {
// All high words are zero, just use native divide
- return APInt(BitWidth, this->pVal[0] / RHS.pVal[0]);
+ return APInt(BitWidth, this->U.pVal[0] / RHS.U.pVal[0]);
}
// We have to compute it the hard way. Invoke the Knuth divide algorithm.
@@ -1716,8 +1709,8 @@ APInt APInt::sdiv(const APInt &RHS) const {
APInt APInt::urem(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) {
- assert(RHS.VAL != 0 && "Remainder by zero?");
- return APInt(BitWidth, VAL % RHS.VAL);
+ assert(RHS.U.VAL != 0 && "Remainder by zero?");
+ return APInt(BitWidth, U.VAL % RHS.U.VAL);
}
// Get some facts about the LHS
@@ -1741,7 +1734,7 @@ APInt APInt::urem(const APInt& RHS) const {
return APInt(BitWidth, 0);
} else if (lhsWords == 1) {
// All high words are zero, just use native remainder
- return APInt(BitWidth, pVal[0] % RHS.pVal[0]);
+ return APInt(BitWidth, U.pVal[0] % RHS.U.pVal[0]);
}
// We have to compute it the hard way. Invoke the Knuth divide algorithm.
@@ -1767,9 +1760,9 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
// First, deal with the easy case
if (LHS.isSingleWord()) {
- assert(RHS.VAL != 0 && "Divide by zero?");
- uint64_t QuotVal = LHS.VAL / RHS.VAL;
- uint64_t RemVal = LHS.VAL % RHS.VAL;
+ assert(RHS.U.VAL != 0 && "Divide by zero?");
+ uint64_t QuotVal = LHS.U.VAL / RHS.U.VAL;
+ uint64_t RemVal = LHS.U.VAL % RHS.U.VAL;
Quotient = APInt(LHS.BitWidth, QuotVal);
Remainder = APInt(LHS.BitWidth, RemVal);
return;
@@ -1802,8 +1795,8 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
if (lhsWords == 1 && rhsWords == 1) {
// There is only one word to consider so use the native versions.
- uint64_t lhsValue = LHS.isSingleWord() ? LHS.VAL : LHS.pVal[0];
- uint64_t rhsValue = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
+ uint64_t lhsValue = LHS.isSingleWord() ? LHS.U.VAL : LHS.U.pVal[0];
+ uint64_t rhsValue = RHS.isSingleWord() ? RHS.U.VAL : RHS.U.pVal[0];
Quotient = APInt(LHS.getBitWidth(), lhsValue / rhsValue);
Remainder = APInt(LHS.getBitWidth(), lhsValue % rhsValue);
return;
@@ -1930,9 +1923,11 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
assert((((slen-1)*64)/22 <= numbits || radix != 10) &&
"Insufficient bit width");
- // Allocate memory
- if (!isSingleWord())
- pVal = getClearedMemory(getNumWords());
+ // Allocate memory if needed
+ if (isSingleWord())
+ U.VAL = 0;
+ else
+ U.pVal = getClearedMemory(getNumWords());
// Figure out if we can shift instead of multiply
unsigned shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0);
diff --git a/contrib/llvm/lib/Support/BinaryStreamReader.cpp b/contrib/llvm/lib/Support/BinaryStreamReader.cpp
index c7a2e0ddb179..702d98770e05 100644
--- a/contrib/llvm/lib/Support/BinaryStreamReader.cpp
+++ b/contrib/llvm/lib/Support/BinaryStreamReader.cpp
@@ -93,3 +93,16 @@ uint8_t BinaryStreamReader::peek() const {
llvm::consumeError(std::move(EC));
return Buffer[0];
}
+
+std::pair<BinaryStreamReader, BinaryStreamReader>
+BinaryStreamReader::split(uint32_t Off) const {
+ assert(getLength() >= Off);
+
+ BinaryStreamRef First = Stream.drop_front(Offset);
+
+ BinaryStreamRef Second = First.drop_front(Off);
+ First = First.keep_front(Off);
+ BinaryStreamReader W1{First};
+ BinaryStreamReader W2{Second};
+ return std::make_pair(W1, W2);
+} \ No newline at end of file
diff --git a/contrib/llvm/lib/Support/BinaryStreamWriter.cpp b/contrib/llvm/lib/Support/BinaryStreamWriter.cpp
index d60b75642d0f..d78dbc68f593 100644
--- a/contrib/llvm/lib/Support/BinaryStreamWriter.cpp
+++ b/contrib/llvm/lib/Support/BinaryStreamWriter.cpp
@@ -59,6 +59,19 @@ Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
return Error::success();
}
+std::pair<BinaryStreamWriter, BinaryStreamWriter>
+BinaryStreamWriter::split(uint32_t Off) const {
+ assert(getLength() >= Off);
+
+ WritableBinaryStreamRef First = Stream.drop_front(Offset);
+
+ WritableBinaryStreamRef Second = First.drop_front(Off);
+ First = First.keep_front(Off);
+ BinaryStreamWriter W1{First};
+ BinaryStreamWriter W2{Second};
+ return std::make_pair(W1, W2);
+}
+
Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
uint32_t NewOffset = alignTo(Offset, Align);
if (NewOffset > getLength())
diff --git a/contrib/llvm/lib/Support/DataExtractor.cpp b/contrib/llvm/lib/Support/DataExtractor.cpp
index 5d6d60a87fbf..53c10bcc562e 100644
--- a/contrib/llvm/lib/Support/DataExtractor.cpp
+++ b/contrib/llvm/lib/Support/DataExtractor.cpp
@@ -128,6 +128,16 @@ const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
return nullptr;
}
+StringRef DataExtractor::getCStrRef(uint32_t *OffsetPtr) const {
+ uint32_t Start = *OffsetPtr;
+ StringRef::size_type Pos = Data.find('\0', Start);
+ if (Pos != StringRef::npos) {
+ *OffsetPtr = Pos + 1;
+ return StringRef(Data.data() + Start, Pos - Start);
+ }
+ return StringRef();
+}
+
uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
uint64_t result = 0;
if (Data.empty())
diff --git a/contrib/llvm/lib/Support/DynamicLibrary.cpp b/contrib/llvm/lib/Support/DynamicLibrary.cpp
index 22fb3f2cb9c9..1541a5726302 100644
--- a/contrib/llvm/lib/Support/DynamicLibrary.cpp
+++ b/contrib/llvm/lib/Support/DynamicLibrary.cpp
@@ -20,169 +20,164 @@
#include "llvm/Support/Mutex.h"
#include <cstdio>
#include <cstring>
+#include <vector>
-// Collection of symbol name/value pairs to be searched prior to any libraries.
-static llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols;
-static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex;
-
-void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
- void *symbolValue) {
- SmartScopedLock<true> lock(*SymbolsMutex);
- (*ExplicitSymbols)[symbolName] = symbolValue;
-}
-
-char llvm::sys::DynamicLibrary::Invalid = 0;
-
-#ifdef LLVM_ON_WIN32
-
-#include "Windows/DynamicLibrary.inc"
-
-#else
-
-#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
-#include <dlfcn.h>
using namespace llvm;
using namespace llvm::sys;
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
+// All methods for HandleSet should be used holding SymbolsMutex.
+class DynamicLibrary::HandleSet {
+ typedef std::vector<void *> HandleList;
+ HandleList Handles;
+ void *Process;
-static llvm::ManagedStatic<DenseSet<void *> > OpenedHandles;
+public:
+ static void *DLOpen(const char *Filename, std::string *Err);
+ static void DLClose(void *Handle);
+ static void *DLSym(void *Handle, const char *Symbol);
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
- std::string *errMsg) {
- SmartScopedLock<true> lock(*SymbolsMutex);
+ HandleSet() : Process(nullptr) {}
+ ~HandleSet();
- void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
- if (!handle) {
- if (errMsg) *errMsg = dlerror();
- return DynamicLibrary();
+ HandleList::iterator Find(void *Handle) {
+ return std::find(Handles.begin(), Handles.end(), Handle);
}
-#ifdef __CYGWIN__
- // Cygwin searches symbols only in the main
- // with the handle of dlopen(NULL, RTLD_GLOBAL).
- if (!filename)
- handle = RTLD_DEFAULT;
-#endif
+ bool Contains(void *Handle) {
+ return Handle == Process || Find(Handle) != Handles.end();
+ }
- // If we've already loaded this library, dlclose() the handle in order to
- // keep the internal refcount at +1.
- if (!OpenedHandles->insert(handle).second)
- dlclose(handle);
+ bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true) {
+#ifdef LLVM_ON_WIN32
+ assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
+#endif
- return DynamicLibrary(handle);
-}
+ if (LLVM_LIKELY(!IsProcess)) {
+ if (Find(Handle) != Handles.end()) {
+ if (CanClose)
+ DLClose(Handle);
+ return false;
+ }
+ Handles.push_back(Handle);
+ } else {
+#ifndef LLVM_ON_WIN32
+ if (Process) {
+ if (CanClose)
+ DLClose(Process);
+ if (Process == Handle)
+ return false;
+ }
+#endif
+ Process = Handle;
+ }
+ return true;
+ }
-DynamicLibrary DynamicLibrary::addPermanentLibrary(void *handle,
- std::string *errMsg) {
- SmartScopedLock<true> lock(*SymbolsMutex);
- // If we've already loaded this library, tell the caller.
- if (!OpenedHandles->insert(handle).second) {
- if (errMsg) *errMsg = "Library already loaded";
- return DynamicLibrary();
+ void *Lookup(const char *Symbol) {
+ // Process handle gets first try.
+ if (Process) {
+ if (void *Ptr = DLSym(Process, Symbol))
+ return Ptr;
+#ifndef NDEBUG
+ for (void *Handle : Handles)
+ assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle");
+#endif
+ } else {
+ // Iterate in reverse, so newer libraries/symbols override older.
+ for (auto &&I = Handles.rbegin(), E = Handles.rend(); I != E; ++I) {
+ if (void *Ptr = DLSym(*I, Symbol))
+ return Ptr;
+ }
+ }
+ return nullptr;
}
+};
- return DynamicLibrary(handle);
+namespace {
+// Collection of symbol name/value pairs to be searched prior to any libraries.
+static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols;
+// Collection of known library handles.
+static llvm::ManagedStatic<DynamicLibrary::HandleSet> OpenedHandles;
+// Lock for ExplicitSymbols and OpenedHandles.
+static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex;
}
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
- if (!isValid())
- return nullptr;
- return dlsym(Data, symbolName);
-}
+#ifdef LLVM_ON_WIN32
+
+#include "Windows/DynamicLibrary.inc"
#else
-using namespace llvm;
-using namespace llvm::sys;
+#include "Unix/DynamicLibrary.inc"
+
+#endif
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
- std::string *errMsg) {
- if (errMsg) *errMsg = "dlopen() not supported on this platform";
- return DynamicLibrary();
+char DynamicLibrary::Invalid;
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
+ return DoSearch(SymbolName); // DynamicLibrary.inc
+}
}
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
- return NULL;
+void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) {
+ SmartScopedLock<true> Lock(*SymbolsMutex);
+ (*ExplicitSymbols)[SymbolName] = SymbolValue;
}
-#endif
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName,
+ std::string *Err) {
+ SmartScopedLock<true> Lock(*SymbolsMutex);
+ void *Handle = HandleSet::DLOpen(FileName, Err);
+ if (Handle != &Invalid)
+ OpenedHandles->AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(const char* symbolName);
+ return DynamicLibrary(Handle);
}
-void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
+DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle,
+ std::string *Err) {
SmartScopedLock<true> Lock(*SymbolsMutex);
+ // If we've already loaded this library, tell the caller.
+ if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false))
+ *Err = "Library already loaded";
- // First check symbols added via AddSymbol().
- if (ExplicitSymbols.isConstructed()) {
- StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
+ return DynamicLibrary(Handle);
+}
- if (i != ExplicitSymbols->end())
- return i->second;
- }
+void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
+ if (!isValid())
+ return nullptr;
+ return HandleSet::DLSym(Data, SymbolName);
+}
-#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
- // Now search the libraries.
- if (OpenedHandles.isConstructed()) {
- for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
- E = OpenedHandles->end(); I != E; ++I) {
- //lt_ptr ptr = lt_dlsym(*I, symbolName);
- void *ptr = dlsym(*I, symbolName);
- if (ptr) {
- return ptr;
- }
- }
- }
-#endif
+void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
+ {
+ SmartScopedLock<true> Lock(*SymbolsMutex);
- if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
- return Result;
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols.isConstructed()) {
+ StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
-// This macro returns the address of a well-known, explicit symbol
-#define EXPLICIT_SYMBOL(SYM) \
- if (!strcmp(symbolName, #SYM)) return &SYM
+ if (i != ExplicitSymbols->end())
+ return i->second;
+ }
-// On linux we have a weird situation. The stderr/out/in symbols are both
-// macros and global variables because of standards requirements. So, we
-// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
-#if defined(__linux__) and !defined(__ANDROID__)
- {
- EXPLICIT_SYMBOL(stderr);
- EXPLICIT_SYMBOL(stdout);
- EXPLICIT_SYMBOL(stdin);
- }
-#else
- // For everything else, we want to check to make sure the symbol isn't defined
- // as a macro before using EXPLICIT_SYMBOL.
- {
-#ifndef stdin
- EXPLICIT_SYMBOL(stdin);
-#endif
-#ifndef stdout
- EXPLICIT_SYMBOL(stdout);
-#endif
-#ifndef stderr
- EXPLICIT_SYMBOL(stderr);
-#endif
+ // Now search the libraries.
+ if (OpenedHandles.isConstructed()) {
+ if (void *Ptr = OpenedHandles->Lookup(SymbolName))
+ return Ptr;
+ }
}
-#endif
-#undef EXPLICIT_SYMBOL
- return nullptr;
+ return llvm::SearchForAddressOfSpecialSymbol(SymbolName);
}
-#endif // LLVM_ON_WIN32
-
//===----------------------------------------------------------------------===//
// C API.
//===----------------------------------------------------------------------===//
-LLVMBool LLVMLoadLibraryPermanently(const char* Filename) {
+LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename);
}
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
index 970ecfd7df90..6a0b64fb884d 100644
--- a/contrib/llvm/lib/Support/Host.cpp
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -1363,6 +1363,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
+ Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
diff --git a/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
index 5b079ff211fe..abf61b73a70d 100644
--- a/contrib/llvm/lib/Support/PrettyStackTrace.cpp
+++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/raw_ostream.h"
#include <cstdarg>
+#include <cstdio>
#include <tuple>
#ifdef HAVE_CRASHREPORTERCLIENT_H
diff --git a/contrib/llvm/lib/Support/ScopedPrinter.cpp b/contrib/llvm/lib/Support/ScopedPrinter.cpp
index d8ee1efd8f3e..537ff62c7b09 100644
--- a/contrib/llvm/lib/Support/ScopedPrinter.cpp
+++ b/contrib/llvm/lib/Support/ScopedPrinter.cpp
@@ -21,7 +21,8 @@ const std::string to_hexString(uint64_t Value, bool UpperCase) {
}
void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
- ArrayRef<uint8_t> Data, bool Block) {
+ ArrayRef<uint8_t> Data, bool Block,
+ uint32_t StartOffset) {
if (Data.size() > 16)
Block = true;
@@ -31,7 +32,8 @@ void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
OS << ": " << Str;
OS << " (\n";
if (!Data.empty())
- OS << format_bytes_with_ascii(Data, 0, 16, 4, (IndentLevel + 1) * 2, true)
+ OS << format_bytes_with_ascii(Data, StartOffset, 16, 4,
+ (IndentLevel + 1) * 2, true)
<< "\n";
startLine() << ")\n";
} else {
diff --git a/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp b/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp
deleted file mode 100644
index 55f3320f640f..000000000000
--- a/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file pulls the addresses of certain symbols out of the linker. It must
-// include as few header files as possible because it declares the symbols as
-// void*, which would conflict with the actual symbol type if any header
-// declared it.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string.h>
-
-// Must declare the symbols in the global namespace.
-static void *DoSearch(const char* symbolName) {
-#define EXPLICIT_SYMBOL(SYM) \
- extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
-
- // If this is darwin, it has some funky issues, try to solve them here. Some
- // important symbols are marked 'private external' which doesn't allow
- // SearchForAddressOfSymbol to find them. As such, we special case them here,
- // there is only a small handful of them.
-
-#ifdef __APPLE__
- {
- // __eprintf is sometimes used for assert() handling on x86.
- //
- // FIXME: Currently disabled when using Clang, as we don't always have our
- // runtime support libraries available.
-#ifndef __clang__
-#ifdef __i386__
- EXPLICIT_SYMBOL(__eprintf);
-#endif
-#endif
- }
-#endif
-
-#ifdef __CYGWIN__
- {
- EXPLICIT_SYMBOL(_alloca);
- EXPLICIT_SYMBOL(__main);
- }
-#endif
-
-#undef EXPLICIT_SYMBOL
- return nullptr;
-}
-
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
- return DoSearch(symbolName);
-}
-} // namespace llvm
diff --git a/contrib/llvm/lib/Support/SourceMgr.cpp b/contrib/llvm/lib/Support/SourceMgr.cpp
index ca2391c10ff1..5199fad7d9e9 100644
--- a/contrib/llvm/lib/Support/SourceMgr.cpp
+++ b/contrib/llvm/lib/Support/SourceMgr.cpp
@@ -51,9 +51,7 @@ static LineNoCacheTy *getCache(void *Ptr) {
}
SourceMgr::~SourceMgr() {
- // Delete the line # cache if allocated.
- if (LineNoCacheTy *Cache = getCache(LineNoCache))
- delete Cache;
+ delete getCache(LineNoCache);
}
unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp
index f3a654d7d2bd..eb8108908ac5 100644
--- a/contrib/llvm/lib/Support/Triple.cpp
+++ b/contrib/llvm/lib/Support/Triple.cpp
@@ -459,7 +459,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("kfreebsd", Triple::KFreeBSD)
.StartsWith("linux", Triple::Linux)
.StartsWith("lv2", Triple::Lv2)
- .StartsWith("macosx", Triple::MacOSX)
+ .StartsWith("macos", Triple::MacOSX)
.StartsWith("netbsd", Triple::NetBSD)
.StartsWith("openbsd", Triple::OpenBSD)
.StartsWith("solaris", Triple::Solaris)
@@ -984,6 +984,8 @@ void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
StringRef OSTypeName = getOSTypeName(getOS());
if (OSName.startswith(OSTypeName))
OSName = OSName.substr(OSTypeName.size());
+ else if (getOS() == MacOSX)
+ OSName.consume_front("macos");
parseVersionFromName(OSName, Major, Minor, Micro);
}
diff --git a/contrib/llvm/lib/Support/Unix/DynamicLibrary.inc b/contrib/llvm/lib/Support/Unix/DynamicLibrary.inc
new file mode 100644
index 000000000000..a0110e7044ee
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/DynamicLibrary.inc
@@ -0,0 +1,131 @@
+//===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the UNIX specific implementation of DynamicLibrary.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
+#include <dlfcn.h>
+
+DynamicLibrary::HandleSet::~HandleSet() {
+ for (void *Handle : Handles)
+ ::dlclose(Handle);
+ if (Process)
+ ::dlclose(Process);
+}
+
+void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
+ void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
+ if (!Handle) {
+ if (Err) *Err = ::dlerror();
+ return &DynamicLibrary::Invalid;
+ }
+
+#ifdef __CYGWIN__
+ // Cygwin searches symbols only in the main
+ // with the handle of dlopen(NULL, RTLD_GLOBAL).
+ if (!Filename)
+ Handle = RTLD_DEFAULT;
+#endif
+
+ return Handle;
+}
+
+void DynamicLibrary::HandleSet::DLClose(void *Handle) {
+ ::dlclose(Handle);
+}
+
+void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
+ return ::dlsym(Handle, Symbol);
+}
+
+#else // !HAVE_DLOPEN
+
+DynamicLibrary::HandleSet::~HandleSet() {}
+
+void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
+ if (Err) *Err = "dlopen() not supported on this platform";
+ return &Invalid;
+}
+
+void DynamicLibrary::HandleSet::DLClose(void *Handle) {
+}
+
+void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
+ return nullptr;
+}
+
+#endif
+
+// Must declare the symbols in the global namespace.
+static void *DoSearch(const char* SymbolName) {
+#define EXPLICIT_SYMBOL(SYM) \
+ extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM
+
+ // If this is darwin, it has some funky issues, try to solve them here. Some
+ // important symbols are marked 'private external' which doesn't allow
+ // SearchForAddressOfSymbol to find them. As such, we special case them here,
+ // there is only a small handful of them.
+
+#ifdef __APPLE__
+ {
+ // __eprintf is sometimes used for assert() handling on x86.
+ //
+ // FIXME: Currently disabled when using Clang, as we don't always have our
+ // runtime support libraries available.
+#ifndef __clang__
+#ifdef __i386__
+ EXPLICIT_SYMBOL(__eprintf);
+#endif
+#endif
+ }
+#endif
+
+#ifdef __CYGWIN__
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ }
+#endif
+
+#undef EXPLICIT_SYMBOL
+
+// This macro returns the address of a well-known, explicit symbol
+#define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(SymbolName, #SYM)) return &SYM
+
+// On linux we have a weird situation. The stderr/out/in symbols are both
+// macros and global variables because of standards requirements. So, we
+// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
+#if defined(__linux__) and !defined(__ANDROID__)
+ {
+ EXPLICIT_SYMBOL(stderr);
+ EXPLICIT_SYMBOL(stdout);
+ EXPLICIT_SYMBOL(stdin);
+ }
+#else
+ // For everything else, we want to check to make sure the symbol isn't defined
+ // as a macro before using EXPLICIT_SYMBOL.
+ {
+#ifndef stdin
+ EXPLICIT_SYMBOL(stdin);
+#endif
+#ifndef stdout
+ EXPLICIT_SYMBOL(stdout);
+#endif
+#ifndef stderr
+ EXPLICIT_SYMBOL(stderr);
+#endif
+ }
+#endif
+#undef EXPLICIT_SYMBOL
+
+ return nullptr;
+}
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
index 709499deeafa..0b54b5dfdbc5 100644
--- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
+++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
@@ -12,98 +12,140 @@
//===----------------------------------------------------------------------===//
#include "WindowsSupport.h"
+#include "llvm/Support/raw_ostream.h"
-#ifdef __MINGW32__
- #include <imagehlp.h>
-#else
- #include <dbghelp.h>
-#endif
-
-#ifdef _MSC_VER
- #include <ntverp.h>
-#endif
-
-namespace llvm {
+#include <psapi.h>
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only Win32 specific code
//=== and must not be UNIX code.
//===----------------------------------------------------------------------===//
-typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
-static fpEnumerateLoadedModules fEnumerateLoadedModules;
-static llvm::ManagedStatic<DenseSet<HMODULE> > OpenedHandles;
-static bool loadDebugHelp(void) {
- HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
- if (hLib) {
- fEnumerateLoadedModules = (fpEnumerateLoadedModules)
- ::GetProcAddress(hLib, "EnumerateLoadedModules64");
- }
- return fEnumerateLoadedModules != 0;
-}
+DynamicLibrary::HandleSet::~HandleSet() {
+ for (void *Handle : Handles)
+ FreeLibrary(HMODULE(Handle));
-static BOOL CALLBACK
-ELM_Callback(PCSTR ModuleName, DWORD64 ModuleBase,
- ULONG ModuleSize, PVOID UserContext) {
- OpenedHandles->insert((HMODULE)ModuleBase);
- return TRUE;
+ // 'Process' should not be released on Windows.
+ assert((!Process || Process==this) && "Bad Handle");
}
-sys::DynamicLibrary
-sys::DynamicLibrary::getPermanentLibrary(const char *filename,
- std::string *errMsg) {
- SmartScopedLock<true> lock(*SymbolsMutex);
-
- if (!filename) {
- // When no file is specified, enumerate all DLLs and EXEs in the process.
- if (!fEnumerateLoadedModules) {
- if (!loadDebugHelp()) {
- assert(false && "These APIs should always be available");
- return DynamicLibrary();
- }
- }
+void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
+ // Create the instance and return it to be the *Process* handle
+ // simillar to dlopen(NULL, RTLD_LAZY|RTLD_GLOBAL)
+ if (!File)
+ return &(*OpenedHandles);
- fEnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
- // Dummy library that represents "search all handles".
- // This is mostly to ensure that the return value still shows up as "valid".
- return DynamicLibrary(&OpenedHandles);
- }
-
- SmallVector<wchar_t, MAX_PATH> filenameUnicode;
- if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
+ SmallVector<wchar_t, MAX_PATH> FileUnicode;
+ if (std::error_code ec = windows::UTF8ToUTF16(File, FileUnicode)) {
SetLastError(ec.value());
- MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16");
- return DynamicLibrary();
+ MakeErrMsg(Err, std::string(File) + ": Can't convert to UTF-16");
+ return &DynamicLibrary::Invalid;
}
- HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
-
- if (a_handle == 0) {
- MakeErrMsg(errMsg, std::string(filename) + ": Can't open");
- return DynamicLibrary();
+ HMODULE Handle = LoadLibraryW(FileUnicode.data());
+ if (Handle == NULL) {
+ MakeErrMsg(Err, std::string(File) + ": Can't open");
+ return &DynamicLibrary::Invalid;
}
- // If we've already loaded this library, FreeLibrary() the handle in order to
- // keep the internal refcount at +1.
- if (!OpenedHandles->insert(a_handle).second)
- FreeLibrary(a_handle);
+ return reinterpret_cast<void*>(Handle);
+}
- return DynamicLibrary(a_handle);
+static DynamicLibrary::HandleSet *IsOpenedHandlesInstance(void *Handle) {
+ if (!OpenedHandles.isConstructed())
+ return nullptr;
+ DynamicLibrary::HandleSet &Inst = *OpenedHandles;
+ return Handle == &Inst ? &Inst : nullptr;
}
-sys::DynamicLibrary
-sys::DynamicLibrary::addPermanentLibrary(void *handle, std::string *errMsg) {
- SmartScopedLock<true> lock(*SymbolsMutex);
- // If we've already loaded this library, tell the caller.
- if (!OpenedHandles->insert((HMODULE)handle).second) {
- MakeErrMsg(errMsg, "Library already loaded");
- return DynamicLibrary();
+void DynamicLibrary::HandleSet::DLClose(void *Handle) {
+ if (HandleSet* HS = IsOpenedHandlesInstance(Handle))
+ HS->Process = nullptr; // Just drop the *Process* handle.
+ else
+ FreeLibrary((HMODULE)Handle);
+}
+
+static bool GetProcessModules(HANDLE H, DWORD &Bytes, HMODULE *Data = nullptr) {
+ // EnumProcessModules will fail on Windows 64 while some versions of
+ // MingW-32 don't have EnumProcessModulesEx.
+ if (
+#ifdef _WIN64
+ !EnumProcessModulesEx(H, Data, Bytes, &Bytes, LIST_MODULES_64BIT)
+#else
+ !EnumProcessModules(H, Data, Bytes, &Bytes)
+#endif
+ ) {
+ std::string Err;
+ if (MakeErrMsg(&Err, "EnumProcessModules failure"))
+ llvm::errs() << Err << "\n";
+ return false;
}
+ return true;
+}
- return DynamicLibrary(handle);
+void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
+ HandleSet* HS = IsOpenedHandlesInstance(Handle);
+ if (!HS)
+ return (void *)uintptr_t(GetProcAddress((HMODULE)Handle, Symbol));
+
+ // Could have done a dlclose on the *Process* handle
+ if (!HS->Process)
+ return nullptr;
+
+ // Trials indicate EnumProcessModulesEx is consistantly faster than using
+ // EnumerateLoadedModules64 or CreateToolhelp32Snapshot.
+ //
+ // | Handles | DbgHelp.dll | CreateSnapshot | EnumProcessModulesEx
+ // |=========|=============|========================================
+ // | 37 | 0.0000585 * | 0.0003031 | 0.0000152
+ // | 1020 | 0.0026310 * | 0.0121598 | 0.0002683
+ // | 2084 | 0.0149418 * | 0.0369936 | 0.0005610
+ //
+ // * Not including the load time of Dbghelp.dll (~.005 sec)
+ //
+ // There's still a case to somehow cache the result of EnumProcessModulesEx
+ // across invocations, but the complication of doing that properly...
+ // Possibly using LdrRegisterDllNotification to invalidate the cache?
+
+ DWORD Bytes = 0;
+ HMODULE Self = HMODULE(GetCurrentProcess());
+ if (!GetProcessModules(Self, Bytes))
+ return nullptr;
+
+ // Get the most recent list in case any modules added/removed between calls
+ // to EnumProcessModulesEx that gets the amount of, then copies the HMODULES.
+ // MSDN is pretty clear that if the module list changes during the call to
+ // EnumProcessModulesEx the results should not be used.
+ std::vector<HMODULE> Handles;
+ do {
+ assert(Bytes && ((Bytes % sizeof(HMODULE)) == 0) &&
+ "Should have at least one module and be aligned");
+ Handles.resize(Bytes / sizeof(HMODULE));
+ if (!GetProcessModules(Self, Bytes, Handles.data()))
+ return nullptr;
+ } while (Bytes != (Handles.size() * sizeof(HMODULE)));
+
+ // Try EXE first, mirroring what dlsym(dlopen(NULL)) does.
+ if (FARPROC Ptr = GetProcAddress(HMODULE(Handles.front()), Symbol))
+ return (void *) uintptr_t(Ptr);
+
+ if (Handles.size() > 1) {
+ // This is different behaviour than what Posix dlsym(dlopen(NULL)) does.
+ // Doing that here is causing real problems for the JIT where msvc.dll
+ // and ucrt.dll can define the same symbols. The runtime linker will choose
+ // symbols from ucrt.dll first, but iterating NOT in reverse here would
+ // mean that the msvc.dll versions would be returned.
+
+ for (auto I = Handles.rbegin(), E = Handles.rend()-1; I != E; ++I) {
+ if (FARPROC Ptr = GetProcAddress(HMODULE(*I), Symbol))
+ return (void *) uintptr_t(Ptr);
+ }
+ }
+ return nullptr;
}
+
// Stack probing routines are in the support library (e.g. libgcc), but we don't
// have dynamic linking on windows. Provide a hook.
#define EXPLICIT_SYMBOL(SYM) \
@@ -129,38 +171,18 @@ sys::DynamicLibrary::addPermanentLibrary(void *handle, std::string *errMsg) {
#undef INLINE_DEF_SYMBOL1
#undef INLINE_DEF_SYMBOL2
-void *sys::DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
- SmartScopedLock<true> Lock(*SymbolsMutex);
-
- // First check symbols added via AddSymbol().
- if (ExplicitSymbols.isConstructed()) {
- StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
-
- if (i != ExplicitSymbols->end())
- return i->second;
- }
-
- // Now search the libraries.
- if (OpenedHandles.isConstructed()) {
- for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
- E = OpenedHandles->end(); I != E; ++I) {
- FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
- if (ptr) {
- return (void *)(intptr_t)ptr;
- }
- }
- }
+static void *DoSearch(const char *SymbolName) {
#define EXPLICIT_SYMBOL(SYM) \
- if (!strcmp(symbolName, #SYM)) \
+ if (!strcmp(SymbolName, #SYM)) \
return (void *)&SYM;
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
- if (!strcmp(symbolName, #SYMFROM)) \
+ if (!strcmp(SymbolName, #SYMFROM)) \
return (void *)&SYMTO;
#ifdef _M_IX86
#define INLINE_DEF_SYMBOL1(TYP, SYM) \
- if (!strcmp(symbolName, #SYM)) \
+ if (!strcmp(SymbolName, #SYM)) \
return (void *)&inline_##SYM;
#define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
#endif
@@ -174,15 +196,5 @@ void *sys::DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
#undef INLINE_DEF_SYMBOL1
#undef INLINE_DEF_SYMBOL2
- return 0;
-}
-
-void *sys::DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
- if (!isValid())
- return NULL;
- if (Data == &OpenedHandles)
- return SearchForAddressOfSymbol(symbolName);
- return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
-}
-
+ return nullptr;
}