how to find symbols that should be exported











up vote
0
down vote

favorite












If you compile with -fvisibility=hidden or with msvc you have to export your shared library symbols manually. As an experiment, how could you find them automatically with AST matchers (clang-query)?



It's not that easy as a minimal set of export declarations is desired and things quickly get complicated with inline functions, templates, out-of-line template definitions, static data members, etc.



A general answer in LLVM IR or C++ standard parlance is also welcome.










share|improve this question




















  • 1




    automatically? exports should be properly designed and documented
    – VTT
    Nov 11 at 7:48










  • Yeah but that's a different story.
    – Trass3r
    Nov 11 at 8:31















up vote
0
down vote

favorite












If you compile with -fvisibility=hidden or with msvc you have to export your shared library symbols manually. As an experiment, how could you find them automatically with AST matchers (clang-query)?



It's not that easy as a minimal set of export declarations is desired and things quickly get complicated with inline functions, templates, out-of-line template definitions, static data members, etc.



A general answer in LLVM IR or C++ standard parlance is also welcome.










share|improve this question




















  • 1




    automatically? exports should be properly designed and documented
    – VTT
    Nov 11 at 7:48










  • Yeah but that's a different story.
    – Trass3r
    Nov 11 at 8:31













up vote
0
down vote

favorite









up vote
0
down vote

favorite











If you compile with -fvisibility=hidden or with msvc you have to export your shared library symbols manually. As an experiment, how could you find them automatically with AST matchers (clang-query)?



It's not that easy as a minimal set of export declarations is desired and things quickly get complicated with inline functions, templates, out-of-line template definitions, static data members, etc.



A general answer in LLVM IR or C++ standard parlance is also welcome.










share|improve this question















If you compile with -fvisibility=hidden or with msvc you have to export your shared library symbols manually. As an experiment, how could you find them automatically with AST matchers (clang-query)?



It's not that easy as a minimal set of export declarations is desired and things quickly get complicated with inline functions, templates, out-of-line template definitions, static data members, etc.



A general answer in LLVM IR or C++ standard parlance is also welcome.







c++ shared-libraries llvm visibility clang-query






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 12:17

























asked Nov 11 at 7:00









Trass3r

2,8001530




2,8001530








  • 1




    automatically? exports should be properly designed and documented
    – VTT
    Nov 11 at 7:48










  • Yeah but that's a different story.
    – Trass3r
    Nov 11 at 8:31














  • 1




    automatically? exports should be properly designed and documented
    – VTT
    Nov 11 at 7:48










  • Yeah but that's a different story.
    – Trass3r
    Nov 11 at 8:31








1




1




automatically? exports should be properly designed and documented
– VTT
Nov 11 at 7:48




automatically? exports should be properly designed and documented
– VTT
Nov 11 at 7:48












Yeah but that's a different story.
– Trass3r
Nov 11 at 8:31




Yeah but that's a different story.
– Trass3r
Nov 11 at 8:31












2 Answers
2






active

oldest

votes

















up vote
0
down vote













Not sure about clang-query but if clients of your library use existing public headers you can collect declarations by expecting them via libclang. A simple example of this is given in ShlibVisibilityChecker project (it identifies spurious exports from shared libs).






share|improve this answer





















  • Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
    – Trass3r
    Nov 11 at 12:06










  • I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
    – Trass3r
    Nov 11 at 12:18


















up vote
0
down vote













You should be able to get this information through an AST MatchFinder. A simple matcher like



namedDecl().bind("named_decl")


will match all NamedDecl nodes. Then in the callback, you can get the node's Linkage attribute, and process the node accordingly. A callback that printed out which symbols have external linkage might look something like this:



struct LinkagePrinter : public MatchFinder::Callback {
void run(MatchResult const & result) override {
using namespace clang;
NamedDecl const * n_decl =
result.Nodes.getNodeAs<NamedDecl("named_decl");
if(n_decl){
Linkage l = n_decl->getLinkage();
switch(l){
case ExternalLinkage:
std::cout << "symbol " << n_decl->getNameAsString()
<< " has external linkagen";
// ... etc
}
}
return;
}
}; // LinkagePrinter


This is roughly right--I haven't checked that this compiles. Register the matcher and callback with a MatchFinder, load the MatchFinder into a Tool, and you should be in business. There are lots of examples in https://github.com/lanl/CoARCT .






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246543%2fhow-to-find-symbols-that-should-be-exported%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Not sure about clang-query but if clients of your library use existing public headers you can collect declarations by expecting them via libclang. A simple example of this is given in ShlibVisibilityChecker project (it identifies spurious exports from shared libs).






    share|improve this answer





















    • Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
      – Trass3r
      Nov 11 at 12:06










    • I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
      – Trass3r
      Nov 11 at 12:18















    up vote
    0
    down vote













    Not sure about clang-query but if clients of your library use existing public headers you can collect declarations by expecting them via libclang. A simple example of this is given in ShlibVisibilityChecker project (it identifies spurious exports from shared libs).






    share|improve this answer





















    • Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
      – Trass3r
      Nov 11 at 12:06










    • I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
      – Trass3r
      Nov 11 at 12:18













    up vote
    0
    down vote










    up vote
    0
    down vote









    Not sure about clang-query but if clients of your library use existing public headers you can collect declarations by expecting them via libclang. A simple example of this is given in ShlibVisibilityChecker project (it identifies spurious exports from shared libs).






    share|improve this answer












    Not sure about clang-query but if clients of your library use existing public headers you can collect declarations by expecting them via libclang. A simple example of this is given in ShlibVisibilityChecker project (it identifies spurious exports from shared libs).







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 11 at 10:27









    yugr

    6,75221339




    6,75221339












    • Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
      – Trass3r
      Nov 11 at 12:06










    • I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
      – Trass3r
      Nov 11 at 12:18


















    • Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
      – Trass3r
      Nov 11 at 12:06










    • I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
      – Trass3r
      Nov 11 at 12:18
















    Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
    – Trass3r
    Nov 11 at 12:06




    Thanks for the link. The tool simply gets a list of all symbols in the headers though and compares that to readelf output.
    – Trass3r
    Nov 11 at 12:06












    I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
    – Trass3r
    Nov 11 at 12:18




    I guess what I'm looking for is a discriminating attribute such as llvm.org/docs/LangRef.html#linkage-types.
    – Trass3r
    Nov 11 at 12:18












    up vote
    0
    down vote













    You should be able to get this information through an AST MatchFinder. A simple matcher like



    namedDecl().bind("named_decl")


    will match all NamedDecl nodes. Then in the callback, you can get the node's Linkage attribute, and process the node accordingly. A callback that printed out which symbols have external linkage might look something like this:



    struct LinkagePrinter : public MatchFinder::Callback {
    void run(MatchResult const & result) override {
    using namespace clang;
    NamedDecl const * n_decl =
    result.Nodes.getNodeAs<NamedDecl("named_decl");
    if(n_decl){
    Linkage l = n_decl->getLinkage();
    switch(l){
    case ExternalLinkage:
    std::cout << "symbol " << n_decl->getNameAsString()
    << " has external linkagen";
    // ... etc
    }
    }
    return;
    }
    }; // LinkagePrinter


    This is roughly right--I haven't checked that this compiles. Register the matcher and callback with a MatchFinder, load the MatchFinder into a Tool, and you should be in business. There are lots of examples in https://github.com/lanl/CoARCT .






    share|improve this answer

























      up vote
      0
      down vote













      You should be able to get this information through an AST MatchFinder. A simple matcher like



      namedDecl().bind("named_decl")


      will match all NamedDecl nodes. Then in the callback, you can get the node's Linkage attribute, and process the node accordingly. A callback that printed out which symbols have external linkage might look something like this:



      struct LinkagePrinter : public MatchFinder::Callback {
      void run(MatchResult const & result) override {
      using namespace clang;
      NamedDecl const * n_decl =
      result.Nodes.getNodeAs<NamedDecl("named_decl");
      if(n_decl){
      Linkage l = n_decl->getLinkage();
      switch(l){
      case ExternalLinkage:
      std::cout << "symbol " << n_decl->getNameAsString()
      << " has external linkagen";
      // ... etc
      }
      }
      return;
      }
      }; // LinkagePrinter


      This is roughly right--I haven't checked that this compiles. Register the matcher and callback with a MatchFinder, load the MatchFinder into a Tool, and you should be in business. There are lots of examples in https://github.com/lanl/CoARCT .






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        You should be able to get this information through an AST MatchFinder. A simple matcher like



        namedDecl().bind("named_decl")


        will match all NamedDecl nodes. Then in the callback, you can get the node's Linkage attribute, and process the node accordingly. A callback that printed out which symbols have external linkage might look something like this:



        struct LinkagePrinter : public MatchFinder::Callback {
        void run(MatchResult const & result) override {
        using namespace clang;
        NamedDecl const * n_decl =
        result.Nodes.getNodeAs<NamedDecl("named_decl");
        if(n_decl){
        Linkage l = n_decl->getLinkage();
        switch(l){
        case ExternalLinkage:
        std::cout << "symbol " << n_decl->getNameAsString()
        << " has external linkagen";
        // ... etc
        }
        }
        return;
        }
        }; // LinkagePrinter


        This is roughly right--I haven't checked that this compiles. Register the matcher and callback with a MatchFinder, load the MatchFinder into a Tool, and you should be in business. There are lots of examples in https://github.com/lanl/CoARCT .






        share|improve this answer












        You should be able to get this information through an AST MatchFinder. A simple matcher like



        namedDecl().bind("named_decl")


        will match all NamedDecl nodes. Then in the callback, you can get the node's Linkage attribute, and process the node accordingly. A callback that printed out which symbols have external linkage might look something like this:



        struct LinkagePrinter : public MatchFinder::Callback {
        void run(MatchResult const & result) override {
        using namespace clang;
        NamedDecl const * n_decl =
        result.Nodes.getNodeAs<NamedDecl("named_decl");
        if(n_decl){
        Linkage l = n_decl->getLinkage();
        switch(l){
        case ExternalLinkage:
        std::cout << "symbol " << n_decl->getNameAsString()
        << " has external linkagen";
        // ... etc
        }
        }
        return;
        }
        }; // LinkagePrinter


        This is roughly right--I haven't checked that this compiles. Register the matcher and callback with a MatchFinder, load the MatchFinder into a Tool, and you should be in business. There are lots of examples in https://github.com/lanl/CoARCT .







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 17 at 15:48









        Some Who Call Me Tim

        75616




        75616






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246543%2fhow-to-find-symbols-that-should-be-exported%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine