3

Want to define same local label in multiple functions:

    .text
    .globl main
func:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret

main:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret

Strangely get error:

$ clang -c main.s
main.s:13:1: error: invalid symbol redefinition
.a:
^

When I was using yasm it allowed same local labels in multiple functions. Do you have any clues?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Bulat M.
  • 680
  • 9
  • 25

1 Answers1

6

Unlike NASM, .label isn't local to the function (actually preceding non-. label) in gas syntax.

.Llabel is a "local" symbol name, meaning it doesn't go in the symbol table. It's still visible throughout the file, so the GNU as manual doesn't call it a local label.


There are local labels in gas syntax, but they're not function scoped. (See the above link). You have to use forward/back annotations to references them, otherwise they're numeric constants instead of labels. (e.g. mov $1, %eax puts a literal 1 into eax, not the address of the most recent 1:).

More importantly, you can't give them meaningful names, like .Lcopy_loop or .Linput_non_zero. They're useful inside macro definitions, or in inline asm that might be inlined into multiple places or otherwise duplicated by the optimizer. Otherwise meaningful names should be preferred.

func1:
    test
    jcc 1f    # you need the forward/back annotation, otherwise it's an absolute address to jump to.
    ...
1:
    ...
    ret

func2:
    test
    # jcc 1b    # BAD!!! jumps to 1: in func1, which is still in scope.  This could bite you after moving some blocks around but missing the f/b annotations.
    jcc 1f      # good: will jump forward to the next definition of 1:
    ...
1:
    ...
    ret

It may be better to just write func1.a or func2.a.


On some targets (not including x86-64 and i386), there are restricted-scope local labels that let you avoid accidentally jumping to the wrong definition of a label, but you still can't use meaningful label names: See Dollar Local Labels on the same page of the manual (link above).

1$: is a syntax error in gas and clang, for x86 targets.

That's unfortunate, because it would be function-scoped, unless you use any labels with meaningful names inside your functions (like .Lmain_loop:).

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • I read the manual too. Do you have any tips/good habits of using labels instead of using numeric labels? – Bulat M. Sep 21 '16 at 03:53
  • 1
    @BulatM.: it's basically the same principle as making up variable names or `static inline` helper-function names in C. Usually the name should either describe why you go there (`.Linput_was_zero`), or what the block there does (`.Learly_out`), or something like that. – Peter Cordes Sep 21 '16 at 06:01
  • 1
    @BulatM. My most successful strategy so far has been prefixing meaningful label names with with `.L + function name + __`. The problem I ran into with just `.L + meaningful name` was that I often end up copying code around, which creates conflicts, given the unfortunate globalness of the labels. While the strategy does not eliminate them, it makes them trivial to fix with a quick regex substitution to replace the prefixes in a given source text range. – Petr Skocik Dec 16 '22 at 22:11