Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: src/IceGlobalContext.cpp

Issue 1766233002: Subzero: Fix symbol name mangling. Make flags global. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceGlobalInits.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceGlobalContext.cpp
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index af3e6c7065e657aa98a4c989f89d64c5a120bc28..25a4ab30ff924798a77be47e401ea40b115278e8 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -18,6 +18,7 @@
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceClFlags.h"
+#include "IceClFlagsExtra.h"
#include "IceDefs.h"
#include "IceELFObjectWriter.h"
#include "IceGlobalInits.h"
@@ -38,8 +39,6 @@
#endif // __clang__
#include <algorithm> // max()
-#include <cctype> // isdigit(), isupper()
-#include <locale> // locale
namespace std {
template <> struct hash<Ice::RelocatableTuple> {
@@ -250,9 +249,9 @@ void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) {
}
GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
- ELFStreamer *ELFStr, const ClFlags &Flags)
+ ELFStreamer *ELFStr)
: ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
- StrEmit(OsEmit), StrError(OsError), Flags(Flags), ObjectWriter(),
+ StrEmit(OsEmit), StrError(OsError), ObjectWriter(),
OptQ(/*Sequential=*/Flags.isSequential(),
/*MaxSize=*/Flags.getNumTranslationThreads()),
// EmitQ is allowed unlimited size.
@@ -293,15 +292,13 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
// ProfileBlockInfoVarDecl is initialized here because it takes this as a
// parameter -- we want to
// ensure that at least this' member variables are initialized.
- ProfileBlockInfoVarDecl = VariableDeclaration::create(this);
+ ProfileBlockInfoVarDecl = VariableDeclaration::createExternal(this);
ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64));
ProfileBlockInfoVarDecl->setIsConstant(true);
// Note: if you change this symbol, make sure to update
// runtime/szrt_profiler.c as well.
ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info");
- ProfileBlockInfoVarDecl->setSuppressMangling();
- ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage);
TargetLowering::staticInit(this);
}
@@ -418,7 +415,7 @@ void GlobalContext::lowerGlobals(const IceString &SectionSuffix) {
OstreamLocker L(this);
Ostream &Stream = getStrDump();
for (const Ice::VariableDeclaration *Global : Globals) {
- Global->dump(this, Stream);
+ Global->dump(Stream);
}
}
if (Flags.getDisableTranslation())
@@ -545,15 +542,15 @@ void GlobalContext::emitItems() {
std::unique_ptr<Assembler> Asm = Item->getAsm();
Asm->alignFunction();
- IceString MangledName = mangleName(Asm->getFunctionName());
+ const IceString &Name = Asm->getFunctionName();
switch (getFlags().getOutFileType()) {
case FT_Elf:
- getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(),
+ getObjectWriter()->writeFunctionCode(Name, Asm->getInternal(),
Asm.get());
break;
case FT_Iasm: {
OstreamLocker L(this);
- Cfg::emitTextHeader(MangledName, this, Asm.get());
+ Cfg::emitTextHeader(Name, this, Asm.get());
Asm->emitIASBytes(this);
} break;
case FT_Asm:
@@ -587,169 +584,6 @@ void GlobalContext::emitItems() {
lowerGlobalsIfNoCodeHasBeenSeen();
}
-// Scan a string for S[0-9A-Z]*_ patterns and replace them with
-// S<num>_ where <num> is the next base-36 value. If a type name
-// legitimately contains that pattern, then the substitution will be
-// made in error and most likely the link will fail. In this case,
-// the test classes can be rewritten not to use that pattern, which is
-// much simpler and more reliable than implementing a full demangling
-// parser. Another substitution-in-error may occur if a type
-// identifier ends with the pattern S[0-9A-Z]*, because an immediately
-// following substitution string like "S1_" or "PS1_" may be combined
-// with the previous type.
-void GlobalContext::incrementSubstitutions(ManglerVector &OldName) const {
- const std::locale CLocale("C");
- // Provide extra space in case the length of <num> increases.
- ManglerVector NewName(OldName.size() * 2);
- size_t OldPos = 0;
- size_t NewPos = 0;
- size_t OldLen = OldName.size();
- for (; OldPos < OldLen; ++OldPos, ++NewPos) {
- if (OldName[OldPos] == '\0')
- break;
- if (OldName[OldPos] == 'S') {
- // Search forward until we find _ or invalid character (including \0).
- bool AllZs = true;
- bool Found = false;
- size_t Last;
- for (Last = OldPos + 1; Last < OldLen; ++Last) {
- char Ch = OldName[Last];
- if (Ch == '_') {
- Found = true;
- break;
- } else if (std::isdigit(Ch) || std::isupper(Ch, CLocale)) {
- if (Ch != 'Z')
- AllZs = false;
- } else {
- // Invalid character, stop searching.
- break;
- }
- }
- if (Found) {
- NewName[NewPos++] = OldName[OldPos++]; // 'S'
- size_t Length = Last - OldPos;
- // NewPos and OldPos point just past the 'S'.
- assert(NewName[NewPos - 1] == 'S');
- assert(OldName[OldPos - 1] == 'S');
- assert(OldName[OldPos + Length] == '_');
- if (AllZs) {
- // Replace N 'Z' characters with a '0' (if N=0) or '1' (if N>0)
- // followed by N '0' characters.
- NewName[NewPos++] = (Length ? '1' : '0');
- for (size_t i = 0; i < Length; ++i) {
- NewName[NewPos++] = '0';
- }
- } else {
- // Iterate right-to-left and increment the base-36 number.
- bool Carry = true;
- for (size_t i = 0; i < Length; ++i) {
- size_t Offset = Length - 1 - i;
- char Ch = OldName[OldPos + Offset];
- if (Carry) {
- Carry = false;
- switch (Ch) {
- case '9':
- Ch = 'A';
- break;
- case 'Z':
- Ch = '0';
- Carry = true;
- break;
- default:
- ++Ch;
- break;
- }
- }
- NewName[NewPos + Offset] = Ch;
- }
- NewPos += Length;
- }
- OldPos = Last;
- // Fall through and let the '_' be copied across.
- }
- }
- NewName[NewPos] = OldName[OldPos];
- }
- assert(NewName[NewPos] == '\0');
- OldName = NewName;
-}
-
-// In this context, name mangling means to rewrite a symbol using a given
-// prefix. For a C++ symbol, nest the original symbol inside the "prefix"
-// namespace. For other symbols, just prepend the prefix.
-IceString GlobalContext::mangleName(const IceString &Name) const {
- // An already-nested name like foo::bar() gets pushed down one level, making
- // it equivalent to Prefix::foo::bar().
- // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
- // A non-nested but mangled name like bar() gets nested, making it equivalent
- // to Prefix::bar().
- // _Z3barxyz ==> ZN6Prefix3barExyz
- // An unmangled, extern "C" style name, gets a simple prefix:
- // bar ==> Prefixbar
- if (!BuildDefs::dump() || getFlags().getTestPrefix().empty())
- return Name;
-
- const IceString &TestPrefix = getFlags().getTestPrefix();
- unsigned PrefixLength = TestPrefix.length();
- ManglerVector NameBase(1 + Name.length());
- const size_t BufLen = 30 + Name.length() + PrefixLength;
- ManglerVector NewName(BufLen);
- uint32_t BaseLength = 0; // using uint32_t due to sscanf format string
-
- int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase.data());
- if (ItemsParsed == 1) {
- // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
- // (splice in "6Prefix") ^^^^^^^
- snprintf(NewName.data(), BufLen, "_ZN%u%s%s", PrefixLength,
- TestPrefix.c_str(), NameBase.data());
- // We ignore the snprintf return value (here and below). If we somehow
- // miscalculated the output buffer length, the output will be truncated,
- // but it will be truncated consistently for all mangleName() calls on the
- // same input string.
- incrementSubstitutions(NewName);
- return NewName.data();
- }
-
- // Artificially limit BaseLength to 9 digits (less than 1 billion) because
- // sscanf behavior is undefined on integer overflow. If there are more than 9
- // digits (which we test by looking at the beginning of NameBase), then we
- // consider this a failure to parse a namespace mangling, and fall back to
- // the simple prefixing.
- ItemsParsed = sscanf(Name.c_str(), "_Z%9u%s", &BaseLength, NameBase.data());
- if (ItemsParsed == 2 && BaseLength <= strlen(NameBase.data()) &&
- !isdigit(NameBase[0])) {
- // Transform _Z3barxyz ==> _ZN6Prefix3barExyz
- // ^^^^^^^^ ^
- // (splice in "N6Prefix", and insert "E" after "3bar") But an "I" after the
- // identifier indicates a template argument list terminated with "E";
- // insert the new "E" before/after the old "E". E.g.:
- // Transform _Z3barIabcExyz ==> _ZN6Prefix3barIabcEExyz
- // ^^^^^^^^ ^
- // (splice in "N6Prefix", and insert "E" after "3barIabcE")
- ManglerVector OrigName(Name.length());
- ManglerVector OrigSuffix(Name.length());
- uint32_t ActualBaseLength = BaseLength;
- if (NameBase[ActualBaseLength] == 'I') {
- ++ActualBaseLength;
- while (NameBase[ActualBaseLength] != 'E' &&
- NameBase[ActualBaseLength] != '\0')
- ++ActualBaseLength;
- }
- strncpy(OrigName.data(), NameBase.data(), ActualBaseLength);
- OrigName[ActualBaseLength] = '\0';
- strcpy(OrigSuffix.data(), NameBase.data() + ActualBaseLength);
- snprintf(NewName.data(), BufLen, "_ZN%u%s%u%sE%s", PrefixLength,
- TestPrefix.c_str(), BaseLength, OrigName.data(),
- OrigSuffix.data());
- incrementSubstitutions(NewName);
- return NewName.data();
- }
-
- // Transform bar ==> Prefixbar
- // ^^^^^^
- return TestPrefix + Name;
-}
-
GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(AllThreadContexts);
LockedPtr<DestructorArray> Dtors = getDestructors();
@@ -812,25 +646,21 @@ Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
Constant *GlobalContext::getConstantSym(const RelocOffsetT Offset,
const RelocOffsetArray &OffsetExpr,
const IceString &Name,
- const IceString &EmitString,
- bool SuppressMangling) {
+ const IceString &EmitString) {
return getConstPool()->Relocatables.getOrAdd(
- this,
- RelocatableTuple(Offset, OffsetExpr, Name, EmitString, SuppressMangling));
+ this, RelocatableTuple(Offset, OffsetExpr, Name, EmitString));
}
Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
- const IceString &Name,
- bool SuppressMangling) {
+ const IceString &Name) {
constexpr char EmptyEmitString[] = "";
- return getConstantSym(Offset, {}, Name, EmptyEmitString, SuppressMangling);
+ return getConstantSym(Offset, {}, Name, EmptyEmitString);
}
Constant *GlobalContext::getConstantExternSym(const IceString &Name) {
constexpr RelocOffsetT Offset = 0;
- constexpr bool SuppressMangling = true;
return getConstPool()->ExternRelocatables.getOrAdd(
- this, RelocatableTuple(Offset, {}, Name, SuppressMangling));
+ this, RelocatableTuple(Offset, {}, Name));
}
Constant *GlobalContext::getConstantUndef(Type Ty) {
@@ -937,7 +767,7 @@ JumpTableDataList GlobalContext::getJumpTables() {
}
JumpTableData &
-GlobalContext::addJumpTable(IceString FuncName, SizeT Id,
+GlobalContext::addJumpTable(const IceString &FuncName, SizeT Id,
const JumpTableData::TargetList &TargetList) {
auto JumpTableList = getJumpTableList();
JumpTableList->emplace_back(FuncName, Id, TargetList);
@@ -1030,6 +860,9 @@ void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) {
Timers->at(StackID).dump(getStrDump(), DumpCumulative);
}
+ClFlags GlobalContext::Flags;
+ClFlagsExtra GlobalContext::ExtraFlags;
+
void TimerMarker::push() {
switch (StackID) {
case GlobalContext::TSK_Default:
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceGlobalInits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698