Commit Graph

92 Commits

Author SHA1 Message Date
Nico Weber 1dce82636c llvm-undname: Correctly demangle vararg parameters
FunctionSignatureNode already had an IsVariadic field,
but it wasn't used anywhere yet. Set it and use it.

llvm-svn: 362541
2019-06-04 19:10:08 +00:00
Nico Weber 4638548468 llvm-undname: More coverage-related cleanups
- The loop in demangleFunctionParameterList() only exits
  on Error, @, and Z. All 3 cases were handled, so the
  rest of the function is DEMANGLE_UNREACHABLE.

- The loop in demangleTemplateParameterList() always returns
  on Error, so there's no need to check for that in the loop
  header and after the loop.

- Add test cases for invalid function parameter manglings.

- Add a (redundant) test case for a simple template parameter
  list mangling.

- Add a test case pointing out that varargs functions aren't
  demangled correctly.

llvm-svn: 362540
2019-06-04 18:49:05 +00:00
Nico Weber 878df1c2a9 llvm-undname: Add test coverage for demangleInitFiniStub()
llvm-svn: 362536
2019-06-04 18:06:28 +00:00
Nico Weber d98a0a362f llvm-undname: Yet more coverage for error paths
- For error returns in demangleSpecialTableNode(),
  demangleLocalStaticGuard(), RTTITypeDescriptor,
  demangleRttiBaseClassDescriptorNode(), demangleUnsigned(),
  demangleUntypedVariable() (via RttiBaseClassArray)

- For ?_A and ?_P which are handled at early levels of the
  demangler but are not implemented in a later stage; this
  is now more obvious

- Replace a "default:" with an explicit list of cases, to
  get -Wswitch check we list all cases

llvm-svn: 362520
2019-06-04 16:25:28 +00:00
Nico Weber dc2a8c7d7f llvm-undname: Add coverage for startsWithLocalScopePattern()
llvm-svn: 362515
2019-06-04 15:47:25 +00:00
Nico Weber c1a0e6fe6b llvm-undname: More no-op changes to increase test coverage
- Add test coverage around invalid anon namespaces and
  for error paths in demanglePrimitiveType() and in
  demangleFullyQualifiedTypeName()

- Use DEMANGLE_UNREACHABLE in two more unreachable places

llvm-svn: 362514
2019-06-04 15:38:00 +00:00
Nico Weber 880d21d3cb llvm-undname: Several behavior-preserving changes to increase coverage
- Replace `Error = true` in a few branches that are truly unreachable
  with DEMANGLE_UNREACHABLE

- Remove early return early in startsWithLocalScopePattern() because
  it's redundant with the next two early returns

- Remove unreachable `case '0'` (it's handled in the branch below)

- Remove an unused bool return

- Add test coverage for several early error returns, mostly in
  array type parsing

llvm-svn: 362506
2019-06-04 15:13:30 +00:00
Nico Weber 3cbb8b8391 llvm-undname: Add coverage for some error paths
llvm-svn: 362346
2019-06-02 23:48:28 +00:00
Nico Weber 54362477c7 llvm-undname; Add more test coverage for demangleFunctionClass()
Also add two FC_Far that seem to be missing, by symmetry from
the public and protected cases. (But FC_Far isn't really a thing
anymore, so this doesn't really have an observable effect.)

llvm-svn: 362344
2019-06-02 23:26:57 +00:00
Nico Weber 869308dd55 Add demangling test coverage for unsigned short, unsigned long
llvm-svn: 362332
2019-06-02 17:29:26 +00:00
Nico Weber dfe02bc4e9 Add mangling test coverage for non-volatile const member pointers
llvm-svn: 362331
2019-06-02 17:23:53 +00:00
Nico Weber d0d32c35d9 Add test coverage for __pascal mangling
llvm-svn: 362329
2019-06-02 16:47:07 +00:00
Nico Weber a2ca6e7803 llvm-undname: Support demangling char8_t
Ports clang's mangling support added in r354633 to llvm-undname.

llvm-svn: 361839
2019-05-28 15:30:04 +00:00
Nico Weber 88ab281b4d llvm-undname: Add support for local static thread guards
llvm-svn: 361835
2019-05-28 14:54:49 +00:00
Nico Weber cfe08bc7d6 llvm-undname: Make demangling of MD5 names more robust
Demangler::parse() for MD5 names would:

1. Put all remaining text into the MD5 name sight unseen
2. Not modify MangledName

This meant that if the demangler recursively called parse() (e.g. in
demangleLocallyScopedNamePiece()), every recursive call that started on
an MD5 name would add all remaining bytes to the output buffer but
only advance the input by a byte.  For valid inputs, MD5 types are
never (well, see comments for 2 exceptions) nested, but for invalid
input this could cause memory use quadratic in the input size.

llvm-svn: 361744
2019-05-27 00:48:59 +00:00
Nico Weber 09fb2029e5 llvm-undname: Fix an assert-on-invalid, found by oss-fuzz
If a template parameter refers to a pointer to member, but the mangling
of that was a string literal instead of a real symbol, llvm-undname used
to crash instead of rejecting the input.

llvm-svn: 361402
2019-05-22 15:53:23 +00:00
Nico Weber 8d05eb8556 llvm-undname: Fix assert-on->4GiB-string-literal, found by oss-fuzz
llvm-svn: 359109
2019-04-24 16:09:38 +00:00
Nico Weber e8f21b1a6b llvm-undname: Support demangling the spaceship operator
Also add a test for demanling the co_await operator.

llvm-svn: 359007
2019-04-23 16:20:27 +00:00
Nico Weber f5c7f3ad33 llvm-undname: Fix an assert-on-invalid, found by oss-fuzz
llvm-svn: 358891
2019-04-22 15:05:18 +00:00
Nico Weber ce67a41741 llvm-undname: Fix hex escapes in wchar_t, char16_t, char32_t strings
llvm-undname used to put '\x' in front of every pair of nibbles, but
u"\xD7\xFF" produces a string with 6 bytes: \xD7 \0 \xFF \0 (and \0\0). Correct
for a single character (plus terminating \0) is u\xD7FF instead.
Now, wchar_t, char16_t, and char32_t strings roundtrip from source to
clang-cl (and cl.exe) and then llvm-undname.

(...at least as long as it's not a string like L"\xD7FF" L"foo" which
gets demangled as L"\xD7FFfoo", where the compiler then considers the
"f" as part of the hex escape. That seems ok.)

Also add a comment saying that the "almost-valid" char32_t string I
added in my last commit is actually produced by compilers.

llvm-svn: 358857
2019-04-21 17:19:27 +00:00
Nico Weber 8fc9902bbb llvm-undname: Fix stack overflow on almost-valid
If a unsigned with all 4 bytes non-0 was passed to outputHex(), there
were two off-by-ones in it:

- Both MaxPos and Pos left space for the final \0, which left the buffer
  one byte to small. Set MaxPos to 16 instead of 15 to fix.

- The `assert(Pos >= 0);` was after a `Pos--`, move it up one line.

Since valid Unicode codepoints are <= 0x10ffff, this could never really
happen in practice.

Found by oss-fuzz.

llvm-svn: 358856
2019-04-21 16:58:25 +00:00
Nico Weber aa162682ca llvm-undname: Fix stack overflow on invalid found by oss-fuzz
llvm-svn: 358852
2019-04-21 14:25:07 +00:00
Nico Weber 8eeaf5178d llvm-undname: Improve string literal demangling with embedded \0 chars
- Don't assert when a string looks like a u32 string to the heuristic
  but doesn't have a length that's 0 mod 4.  Instead, classify those
  as u16 with embedded \0 chars. Found by oss-fuzz.
- Print embedded nul bytes as \0 instead of \x00.

llvm-svn: 358835
2019-04-20 23:59:06 +00:00
Nico Weber a0ac65c98f llvm-undname: Fix two more asserts-on-invalid, found by oss-fuzz
llvm-svn: 358708
2019-04-18 19:52:32 +00:00
Nico Weber 502cf4bd19 llvm-undname: Fix two asserts-on-invalid
llvm-svn: 358707
2019-04-18 19:30:21 +00:00
Nico Weber c035c243da llvm-undname: Fix nullptr deref on invalid structor names in template args
Similar to r358421: A StructorIndentifierNode has a Class field which
is read when printing it, but if the StructorIndentifierNode appears in
a template argument then demangleFullyQualifiedSymbolName() which sets
Class isn't called. Since StructorIndentifierNodes are always leaf
names, we can just reject them as well.

Found by oss-fuzz.

llvm-svn: 358491
2019-04-16 14:10:34 +00:00
Nico Weber aa18ae862d llvm-undname: Tweak arena allocator
- Make `allocUnalignedBuffer` look more like `allocArray` and `alloc`.
  No behavior change.
- Change `Head->Used < Head->Capacity` to `Head->Used <= Head->Capacity`
  in `allocArray` and `alloc`. No intended behavior change, might be a
  minuscule memory usage improvement. Noticed this since it was the logic
  used in `allocUnalignedBuffer`.
- Don't let `allocArray` alloc too small buffers for names that have
  more than 512 levels of nesting (in 64-bit builds). Fixes a heap
  buffer overflow found by oss-fuzz.

Differential Revision: https://reviews.llvm.org/D60774

llvm-svn: 358489
2019-04-16 13:52:30 +00:00
Nico Weber 5961b0203a llvm-undname: add a missing CHECK: to a passing test
llvm-svn: 358488
2019-04-16 13:30:50 +00:00
Nico Weber ff92e715d3 Fix llvm-undname tests after r358485
llvm-svn: 358487
2019-04-16 13:18:51 +00:00
Nico Weber 64041d7b90 llvm-undname: Fix nullptr deref on invalid conversion operator names in template args
A ConversionOperatorIdentifierNode has a TargetType which is read when
printing it, but if the ConversionOperatorIdentifierNode appears in a
template argument there's nothing that can provide the TargetType.
Normally the COIN is a symbol (leaf) name and takes its TargetType from the
symbol's type, but in a template argument context the COIN can only be
either a non-leaf name piece or a type, and must hence be invalid.

Similar to the COIN check in demangleDeclarator().

Found by oss-fuzz.

llvm-svn: 358421
2019-04-15 16:42:44 +00:00
Nico Weber ae050d214b llvm-undname: Fix oss-fuzz-foudn crash-on-invalid with incomplete special table nodes
llvm-svn: 358367
2019-04-14 23:32:37 +00:00
Nico Weber 63fe2593ae llvm-undname: Fix another crash-on-invalid found by oss-fuzz
llvm-svn: 358363
2019-04-14 23:08:12 +00:00
Nico Weber 03db625c13 llvm-undname: Fix out-of-bounds read on invalid intrinsic function code
Found by inspection.

llvm-svn: 358239
2019-04-11 23:11:33 +00:00
Nico Weber e5b62654a5 llvm-undname: Don't crash on incomplete enum tag manglings
Found by inspection.

llvm-svn: 358238
2019-04-11 22:59:25 +00:00
Nico Weber b4f33bbbb0 llvm-undname: Fix crash on incomplete virtual this adjusts
Found by oss-fuzz.

Also remove an else-after-return, this part has no behavior change.

llvm-svn: 358237
2019-04-11 22:47:18 +00:00
Nico Weber f2d8f09d5d llvm-undname: Fix crash on invalid name in a template parameter pointer to member arg
Found by oss-fuzz.

llvm-svn: 358234
2019-04-11 22:23:35 +00:00
Nico Weber 5f6eb1817a llvm-undname: Fix another crash-on-invalid
This fixes a regression from https://reviews.llvm.org/D60354. We used to

  SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
  if (Symbol) {
    Symbol->Name = QN;
  }

but changed that to
  SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
  if (Error)
    return nullptr;
  Symbol->Name = QN;

and one branch somewhere returned a nullptr without setting Error.

Looking at the code changed in r340083 and r340710 that branch looks
like a remnant from an earlier attempt to demangle RTTI descriptors
that has since been rewritten -- so just remove this branch. It
shouldn't change behavior for correctly mangled symbols.

llvm-svn: 358112
2019-04-10 17:31:34 +00:00
Nico Weber 63b97d2a67 llvm-undname: Fix more crashes and asserts on invalid inputs
For functions whose callers don't check that enough input is present,
add checks at the start of the function that enough input is there and
set Error otherwise.

For functions that return AST objects, return nullptr instead of
incomplete AST objects with nullptr fields if an error occurred during
the function.

Introduce a new function demangleDeclarator() for the sequence
demangleFullyQualifiedSymbolName(); demangleEncodedSymbol() and
use it in the two places that had this sequence. Let this new function
check that ConversionOperatorIdentifiers have a valid TargetType.

Some of the bad inputs found by oss-fuzz, others by inspection.

Differential Revision: https://reviews.llvm.org/D60354

llvm-svn: 357936
2019-04-08 19:46:53 +00:00
Nico Weber 1672581e96 llvm-undname: Fix a crash-on-invalid
Found by oss-fuzz, fixes issue 13260 on oss-fuzz.

Differential Revision: https://reviews.llvm.org/D60207

llvm-svn: 357649
2019-04-03 23:27:18 +00:00
Nico Weber a9886f8278 llvm-undame: Fix an assert-on-invalid
Found by oss-fuzz, fixes issue 12432 on os-fuzz.

Differential Revision: https://reviews.llvm.org/D60206

llvm-svn: 357648
2019-04-03 23:23:32 +00:00
Nico Weber 321de48a94 llvm-undname: Fix an assert-on-invalid
Found by oss-fuzz, fixes issues 12428 and 12429 on oss-fuzz.

Differential Revision: https://reviews.llvm.org/D60204

llvm-svn: 357647
2019-04-03 23:19:39 +00:00
Nico Weber c7444ddfe5 llvm-undname: Fix a crash-on-invalid
Found by oss-fuzz, fixes issues 12435 and 12438 on oss-fuzz.

Differential Revision: https://reviews.llvm.org/D60202

llvm-svn: 357646
2019-04-03 23:15:56 +00:00
Zachary Turner 2fe4900525 [llvm-undname] Add support for demangling msvc's noexcept types.
Starting in C++17, MSVC introduced a new mangling for function
parameters that are themselves noexcept functions.  This patch
makes llvm-undname properly demangle them.

Patch by Zachary Henkel
Differential Revision: https://reviews.llvm.org/D55769

llvm-svn: 350656
2019-01-08 21:05:51 +00:00
Zachary Turner 8fb9a71dde [MS Demangler] Fail gracefully on invalid pointer types.
Once we detect a 'P', we know we a pointer type is upcoming, so
we make some assumptions about the output that follows.  If those
assumptions didn't hold, we would assert.  Instead, we should
fail gracefully and propagate the error up.

llvm-svn: 349169
2018-12-14 18:10:13 +00:00
Zachary Turner f47d8be7be [MS Demangler] Add a regression test for an invalid mangled name.
llvm-svn: 349168
2018-12-14 17:59:27 +00:00
Nico Weber a92b463955 [MS Demangler] Print public:, protected:, private: if set in FunctionClass or a variable's StorageClass.
undname prints them, and the information is in the decorated name, so we probably shouldn't lose it when undecorating.

I spot-checked a few of the funnier-looking outputs, and undname has the same output.

Differential Revision: https://reviews.llvm.org/D54396

llvm-svn: 346791
2018-11-13 20:18:26 +00:00
Nico Weber dfc08baceb [MS demangler] Use a slightly shorter unmangling for mangled strings.
Before: const wchar_t * {L"%"}
Now: L"%"

See also PR39593.
Differential Revision: https://reviews.llvm.org/D54294

llvm-svn: 346544
2018-11-09 19:28:50 +00:00
Zachary Turner 78ab3cb238 [MS Demangler] Add support for $$Z parameter pack separator.
$$Z appears between adjacent expanded parameter packs in the
same template instantiation.  We don't need to print it, it's
only there to disambiguate between manglings that would otherwise
be ambiguous.  So we just need to parse it and throw it away.

llvm-svn: 341119
2018-08-30 20:53:29 +00:00
Zachary Turner 32a8a2028c [MS Demangler] Fix several crashes and demangling bugs.
These bugs were found by writing a Python script which spidered
the entire Chromium build directory tree demangling every symbol
in every object file.  At the start, the tool printed:

  Processed 27443 object files.
  2926377/2936108 symbols successfully demangled (99.6686%)
  9731 symbols could not be demangled (0.3314%)
  14589 files crashed while demangling (53.1611%)

After this patch, it prints:

  Processed 27443 object files.
  41295518/41295617 symbols successfully demangled (99.9998%)
  99 symbols could not be demangled (0.0002%)
  0 files crashed while demangling (0.0000%)

The issues fixed in this patch are:

  * Ignore empty parameter packs.  Previously we would encounter
    a mangling for an empty parameter pack and add a null node
    to the AST.  Since we don't print these anyway, we now just
    don't add anything to the AST and ignore it entirely.  This
    fixes some of the crashes.

  * Account for "incorrect" string literal demanglings.  Apparently
    an older version of clang would not truncate mangled string
    literals to 32 bytes of encoded character data.  The demangling
    code however would allocate a 32 byte buffer thinking that it
    would not encounter more than this, and overrun the buffer.
    We now demangle up to 128 bytes of data, since the buggy
    clang would encode up to 32 *characters* of data.

  * Extended support for demangling init-fini stubs.  If you had
    something like
      struct Foo {
        static vector<string> S;
      };
    this would generate a dynamic atexit initializer *for the
    variable*.  We didn't handle this, but now we print something
    nice.  This is actually an improvement over undname, which will
    fail to demangle this at all.

  * Fixed one case of static this adjustment.  We weren't handling
    several thunk codes so we didn't recognize the mangling.  These
    are now handled.

  * Fixed a back-referencing problem.  Member pointer templates
    should have their components considered for back-referencing

The remaining 99 symbols which can't be demangled are all symbols
which are compiler-generated and undname can't demangle either.

llvm-svn: 341000
2018-08-29 23:56:09 +00:00
Zachary Turner b2fef1a0b0 Add support for various C++14 demanglings.
Mostly this includes <auto> and <decltype-auto> return values.
Additionally, this fixes a fairly obscure back-referencing bug
that was encountered in one of the C++14 tests, which is that
if you have something like Foo<&bar, &bar> then the `bar`
forms a backreference.

llvm-svn: 340896
2018-08-29 04:12:44 +00:00