GithubHelp home page GithubHelp logo

rui314 / rust-demangle.c Goto Github PK

View Code? Open in Web Editor NEW

This project forked from lykensol/rust-demangle.c

0.0 2.0 1.0 72 KB

C port of the Rust symbol demangler (rustc-demangle)

License: Apache License 2.0

C 43.70% Rust 56.30%

rust-demangle.c's Introduction

rust-demangle.c

This is a single-file C99 port of the official Rust symbol demangler (rustc-demangle, a Rust library).

Usecases

This C port is intended for situations in which a Rust dependency is hard to justify, or effectively impossible (e.g. platform toolchains, that would be used while building Rust, not the other way around).

If a Rust dependency is acceptable, using rustc-demangle from C (or other languages via FFI) is possible, and may be preferred over this C port.

Status

As this C port was originally (see the History section) only for the rustc-demangle code demangling the (new at the time) Rust RFC2603 (aka "v0") mangling scheme, it may lag behind rustc-demangle in functionality, for now.

The current port status by category is:

Notable differences (intentionally) introduced by porting:

  • rustc-demangle can't use the heap (as it's #![no_std]), but the C port does
    • this is mainly dictated by the ergonomics of the rust_demangle API, which requires malloc/realloc to return a new C string allocation
    • if there is demand for it, rust_demangle support could be made optional, forcing heap-less users to always use rust_demangle_with_callback instead
    • a subtler consequence is that rustc-demangle uses a fixed-size buffer on the stack for punycode decoding, while the C port can allocate it on the heap
  • Unicode support is always handrolled in the C port, and often simplified

Usage

Get rust-demangle.c and rust-demangle.h (via git submodule, vendoring, etc.), add them to your project's build system (as C source, and include path, respectively), then you can call rust_demangle with a symbol and some flags, e.g.:

#include <rust-demangle.h>
#include <stdio.h>

int main() {
    const char *sym = "_RNvNtCsbmNqQUJIY6D_4core3foo3bar";

    printf("demangle(%s) = %s\n", sym, rust_demangle(sym, 0));

    printf(
        "demangle(%s, VERBOSE) = %s\n", sym,
        rust_demangle(sym, RUST_DEMANGLE_FLAG_VERBOSE)
    );
}

which prints out, when ran:

demangle(_RNvNtCsbmNqQUJIY6D_4core3foo3bar) = core::foo::bar
demangle(_RNvNtCsbmNqQUJIY6D_4core3foo3bar, VERBOSE) = core[846817f741e54dfd]::foo::bar

Note that the example leaks the returned C strings, ideally you would free them.

Advanced usage (callback-based API)

If you want to avoid the cost of allocating the output in memory, you can also use rust_demangle_with_callback, which takes a "printing" callback instead, e.g.:

#include <rust-demangle.h>
#include <stdio.h>

static void fwrite_callback(const char *data, size_t len, void *opaque) {
    fwrite(data, len, 1, (FILE *)opaque);
}

int main() {
    const char *sym = "_RNvNtCsbmNqQUJIY6D_4core3foo3bar";

    printf("demangle(%s) = ", sym);
    rust_demangle_with_callback(sym, 0, fwrite_callback, stdout);
    printf("\n");

    printf("demangle(%s, VERBOSE) = ", sym);
    rust_demangle_with_callback(
        sym, RUST_DEMANGLE_FLAG_VERBOSE, fwrite_callback, stdout
    );
    printf("\n");
}

(with identical output to the simpler example)

Testing

cargo test will run built-in tests - it's implemented in Rust (in test-harness) so that it can depend on rustc-demangle itself for comparisons.

Additionally, cargo run -q --release --example check-csv-dataset path/to/syms/*.csv can be used to provide CSV files with additional mangled symbols test data, but such datasets aren't trivial to obtain (existing ones required building rust-lang/rust with a compiler patch that reacts to a custom environment variable). They're also quite large (~1GiB uncompressed) so none have been published anywhere yet.

History

This C port was started while the Rust RFC2603 (aka "v0") mangling scheme was still being developed, with the intent of upstreaming it into libiberty (which provides demangling for binutils, gdb, Linux perf, etc.) and other projects (e.g. valgrind) - you can see some of that upstreaming history on the v0 tracking issue.

At the time, the expectation was that most projects could either depend on libiberty, or vendor a copy of its code, so the C port focused on upstreaming to it, rather than producing an independent reusable C codebase.

That meant that instead of a git repository, the code revisions were only tracked by a gist, and the GNU code style was followed (including C89 comments and variable declarations).

However, the LGPL license of libiberty turned out to be a problem for adoption, compared to the typical MIT/Apache-2.0 dual licensing of Rust projects.

The rust-demangle.c fork

This repository started out as a fork of the original gist, at commit e2c30407516a87c0f8c3820cf152640bd08805dd, just before libiberty integration (which was in commit 0e6f57b0e86ccec4395f8850f4885b1e391a9f4b).

Any changes since that gist are either fresh C ports of the Rust rustc-demangle code, or completely new code, in order to maintain the MIT/Apache-2.0 dual licensing.

While this has the disadvantage of starting behind libiberty (which kept its Rust legacy demangler, and also got a few more features during/since upstreaming), the relationship may reverse eventually, where this port could get new features that would then have to be upstreamed into libiberty.

License

Like rustc-demangle, this project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in rust-demangle.c you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

rust-demangle.c's People

Contributors

eddyb avatar rui314 avatar

Watchers

James Cloos avatar  avatar

Forkers

sarvex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.