草庐IT

c++ - 在 C 和 C++ 中解析 typedef

coder 2023-11-15 原文

我正在尝试自动解析任意 C++ 或 C 项目中的 typedef。

因为一些 typedef 是在系统头文件中定义的(例如 uint32),我目前正试图通过在我的代码文件上运行 gcc 预处理器然后扫描预处理文件来实现这一点对于 typedef。然后我应该能够替换项目代码文件中的 typedef。

我想知道,是否还有另一种可能更简单的方法,我想念。你能想到一个吗?

我想这样做的原因:我正在使用不同的工具从 C/C++ 项目中提取代码指标。指标是基于方法的。提取指标后,我必须合并由不同工具生成的数据。问题是,其中一种工具可以解析 typedef,而其他工具则不能。如果有用于方法参数类型的 typedef,我会将指标映射到不同的方法名称,这些方法名称实际上指的是源代码中的相同方法。

想想源码中的这个方法:int test(uint32 par1, int par2)
运行我的工具后,我有指标,映射到名为 int test(uint32 par1, int par2) 的方法,我的一些指标映射到 int test(unsigned int par1, int par2)

最佳答案

如果您不关心它们的定义位置,您可以使用 objdump转储解析 typedef 的 C++ 符号表。

lorien$ objdump --demangle --syms foo

foo:     file format mach-o-i386

SYMBOL TABLE:
00001a24 g       1e SECT   01 0000 .text dyld_stub_binding_helper
00001a38 g       1e SECT   01 0000 .text _dyld_func_lookup
...
00001c7c g       0f SECT   01 0080 .text foo::foo(char const*)
...

此片段来自以下结构定义:

typedef char const* c_string;
struct foo {
    typedef c_string ntcstring;
    foo(ntcstring s): buf(s) {}
    std::string buf;
};

这确实需要您编译所有内容,并且它只会在生成的可执行文件中显示符号,因此存在一些限制。另一种选择是让链接器转储符号映射。对于 GNU 工具,添加 -Wl,-map-Wl,name,其中 name 是要生成的文件的名称(请参阅注释)。这种方法不会对名称进行分解,但通过一些工作,您可以对编译器的分解约定进行逆向工程。上一个代码片段的输出将包括如下内容:

0x00001CBE  0x0000005E  [  2] __ZN3fooC2EPKc
0x00001D1C  0x0000001A  [  2] __ZN3fooC1EPKc

您可以使用 C++ ABI 解码这些规范。一旦您熟悉了它的工作原理,mangling table包含在 ABI 中变得无价。这种情况下的推导是:

<mangled-name>           ::= '_Z' <encoding>
<encoding>               ::= <name> <bare-function-type>
  <name>                 ::= <nested-name>
    <nested-name>        ::= 'N' <source-name> <ctor-dtor-name> 'E'
      <source-name>      ::= <number> <identifier>
      <ctor-dtor-name>   ::= 'C2' # base object constructor
    <bare-function-type> ::= <type>+
      <type>             ::= 'P' <type> # pointer to
        <type>           ::= <cv-qualifier> <type>
          <cv-qualifier> ::= 'K' # constant
            <type>       ::= 'c' # character

注意:看起来 GNU 将参数更改为 ld 因此您可能需要查看您的本地手册 (man ld) 以进行确保 map 文件生成命令在您的版本中是 -mapfilename。在最近的版本中,use -Wl,-M and redirect stdout to a file .

关于c++ - 在 C 和 C++ 中解析 typedef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2167802/

有关c++ - 在 C 和 C++ 中解析 typedef的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 如何使用 Nokogiri 解析纯 HTML 表格? - 2

    我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐