Does a function with instructions before the entry-point label cause problems for anything (linking)?

可紊 提交于 2019-11-28 14:19:25

There's a simple way to make this look totally normal: put a non-global label in front of the code. This makes it look like (or actually be) a static helper function.

Non-global functions can call each other with any calling convention they want. C compilers can even make code like this with link-time / whole-program optimization, or even just optimization of static functions within a compilation unit. Jumps (rather than calls) to another function are already used for tail-call optimization.

The "helper function" code can jump into the main function at somewhere other than the entry point. I'm sure that's not a problem for linkers though. That would only break if a linker changed the distance between the helper and the main function (by inserting something between them) without adjusting relative jumps that cross the gap that it widened. I don't think any linker would insert anything that way in the first place, and doing so without fixing any branches is clearly a bug.

I'm not sure if there are any pitfalls in generating .size ELF metadata. I think I've read that it's important for functions that will be linked into shared libraries.

The following should work fine with any tool that deals with object files:

.globl __nextafter_pjc      // double __nextafter_pjc(double x, double y)
.p2align 6  // unrealistic 64B alignment, just for the sake of argument


nextafter_helper:  # not a local label, but not .globl either
.Lequal_or_unordered:
    jp  .Lunordered
    movaps  %xmm1, %xmm0    # ISO C11 requires returning y, not x.  (matters for  -0.0 == +0.0)
    ret

######### Function entry point / global symbol here #############    
// .p2align something?
__nextafter_pjc:
    ucomisd %xmm1, %xmm0
    je  .Lequal_or_unordered

    ...    
    ret

We don't need a plain label and a "local" label, but using different labels for different purposes means less modification is needed when re-arranging things. (e.g. you can put the .Lequal_or_unordered block somewhere else without renaming it back to a .L and changing all the jumps that target it.) nextafter_equal_or_unordered would work as a single name.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!