如何修改Erlang程序集?有资源吗?

时间:2011-10-28 21:21:43

标签: assembly erlang

我怀疑任何人都可以帮助解决这个问题,因为Erlang's compile documentation中有以下内容:

  

请注意,汇编程序文件的格式没有记录,可能会在不同版本之间发生变化 - 此选项主要用于内部调试。

...但是为了以防万一,这里是故事的堆栈跟踪:

  • 使用['S']编译:file / 2以生成汇编代码
  • 读取.S文件并创建一个键值数据结构,其中键是.S文件中的'function'元组,value是函数的主体,即实现该函数的汇编指令。
  • 通过添加程序集来修改数据结构,以便在某些函数中进行外部函数调用。
  • 碰撞...

不幸的是,我只是快速浏览了在编译包含以下函数的模块时生成的.S文件,包含和不注释函数中的第一个表达式:

spawn_worker(Which) ->
    %syner:sync_pt(),
    case Which of
            ?NAIVE -> spawn(err1, naive_worker_loop, [])
    end.

当我这样做时,我认为唯一改变的是元组:

  

{call_ext,0,{extfunc,syner,sync_pt,0}}

...所以我认为在程序集中注入一个函数调用唯一需要的就是添加那个元组...但是现在我必须实际注入元组...我看到了程序集生成有一些额外的指示:

没有 syner:sync_pt()

{function, spawn_worker, 1, 4}.
{label,3}.
    {func_info,{atom,err1},{atom,spawn_worker},1}.
{label,4}.
    {test,is_eq_exact,{f,5},[{x,0},{atom,naive}]}.
    {move,{atom,naive_worker_loop},{x,1}}.
    {move,nil,{x,2}}.
    {move,{atom,err1},{x,0}}.
    {call_ext_only,3,{extfunc,erlang,spawn,3}}.
{label,5}.
    {case_end,{x,0}}.

使用 syner:sync_pt()

{function, spawn_worker, 1, 4}.
{label,3}.
    {func_info,{atom,err1},{atom,spawn_worker},1}.
{label,4}.
    {allocate,1,1}.
    {move,{x,0},{y,0}}.
    {call_ext,0,{extfunc,syner,sync_pt,0}}.
    {test,is_eq_exact,{f,5},[{y,0},{atom,naive}]}.
    {move,{atom,naive_worker_loop},{x,1}}.
    {move,nil,{x,2}}.
    {move,{atom,err1},{x,0}}.
    {call_ext_last,3,{extfunc,erlang,spawn,3},1}.
{label,5}.
    {case_end,{y,0}}.

我不能只是总结说添加如下内容:

   {allocate,1,1}.
   {move,{x,0},{y,0}}.
   {call_ext,0,{extfunc,syner,sync_pt,0}}.

对于我想要注入外部函数调用的每个函数,都会有所作为。

  1. 因为我不确定该汇编代码是否适用于我想要注入的所有函数(例如 {allocate,1,1} 总是正常)
  2. 因为如果仔细查看程序集的其余部分,它会略有变化(例如 {call_ext_only,3,{extfunc,erlang,spawn,3}}。更改为 {call_ext_last,3,{extfunc,二郎,产卵,3},1}。)。
  3. 所以现在的问题是,是否有任何资源可用于理解和操作Erlang编译生成的程序集:file / 2?

    为了以防万一,我问这个问题。我怀疑有这方面的资源,因为文件清楚地说明没有,但我猜没有什么可失去的。即使有,似乎操纵汇编代码会比我想要的更棘手。使用parse_transform / 2肯定更容易,我确实设法得到类似的东西来处理...只是尝试不同的替代方案。

    感谢您的时间。

3 个答案:

答案 0 :(得分:2)

我不确定你想用这个来实现什么,但核心erlang可能是一个更好的代码操作级别。这是有记录的(无论如何它的一个版本,但这仍然比没有好)这里(并且还有更多只是谷歌的核心erlang):

要在核心erlang之间进行编译,请使用'to_core'和'from_core'(遗憾的是未记录的)选项:

c(my_module, to_core). %%this generates my_module.core
c(my_module, from_core). %%this loads my_module.core

答案 1 :(得分:2)

我所知道的唯一使用beam asm的工具是HiPE,在https://github.com/erlang/otp/tree/master/lib/hipe/icode中有很多代码示例等,但我不建议使用这种格式,因为它一直在变化。

答案 2 :(得分:1)

在我看来,通过操纵抽象代码可以轻松解决您尝试做的事情。只需编写一个parse_transform模块,您可以在其中将函数调用插入到相关函数中。

我根据erlang ?funclog写了一个decorators。见https://github.com/nicoster/erl-decorator-pt#funclog