Peng Zhang
Peng Zhang

Reputation: 3585

What are .LFB .LBB .LBE .LVL .loc in the compiler generated assembly code

When I look into the assembly code generated by GCC, there are many lines begining with .LBB and a number. It seems to that they are not instructions of operations. More like marking something of the file or what.

What are .LFB, .LVL, LBB, LBE etc are in the compiler generated assembly code? Does the .loc means "line of code". Do those lines just indicate symbol table?

Here is a piece of code,

main:
.LFB1:
  .loc 1 8 0
  .cfi_startproc
.LVL2:
.LBB4:
.LBB5:
  .loc 1 2 0
  movsd b(%rip), %xmm0
.LBE5:
.LBE4:
  .loc 1 10 0
  xorl  %eax, %eax
.LBB7:
.LBB6:
  .loc 1 2 0
  mulsd a(%rip), %xmm0
.LBE6:
.LBE7:
  .loc 1 9 0
  movsd %xmm0, a(%rip)
.LVL3:
  .loc 1 10 0
  ret
  .cfi_endproc

Upvotes: 28

Views: 13463

Answers (2)

.loc

As mentioned by Ferruccio .loc is a debugging directive, and it only appears in GCC 4.8.2 if you tell the compiler to generate debugging information with -ggdb.

.loc is documented at https://sourceware.org/binutils/docs-2.18/as/LNS-directives.html#LNS-directives and the exact output depends on the debug data format (DWARF2, etc.).

The other are labels.

.L prefix

GCC uses the .L for local labels.

GAS will not generate any symbols on the compiled output by default as documented at: https://sourceware.org/binutils/docs-2.18/as/Symbol-Names.html

A local symbol is any symbol beginning with certain local label prefixes. By default, the local label prefix is `.L' for ELF systems

Local symbols are defined and used within the assembler, but they are normally not saved in object files. Thus, they are not visible when debugging. You may use the `-L' option (see Include Local Symbols: -L) to retain the local symbols in the object files.

So if you compile with: as -c a.S, nm a.o does not show those labels at all.

This only makes sense because you cannot generate such labels from a C program.

There are also options that manage it like:

  • man as: --keep-locals
  • man ld: --discard-all

This seems to be a GCC toolchain specific convention, not part an ELF ABI nor NASM.

Furthermore, both NASM and GAS use the convention that labels that start with a period (except .L in GAS) generate local symbols: http://www.nasm.us/doc/nasmdoc3.html#section-3.9 which are still present on the output but not used across object files.

Suffixes

The suffixes you mention all appear to be debugging related, as they are all defined under gcc/dwarf2out.c on GCC 4.8.2 and DWARF2 is a major debugging information format for ELF:

#define FUNC_BEGIN_LABEL  "LFB"
#define FUNC_END_LABEL    "LFE"
#define BLOCK_BEGIN_LABEL "LBB"
#define BLOCK_END_LABEL   "LBE"
ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);

From my experiments, some of them are generated only with gcc -g, others even without g.

Once we have those define names, it is easy to generate C code that generates them to see what they mean:

  • LFB and LFE are generated at the beginning and end of functions

  • LBB and LBE were generated by the following code with gcc -g on internal function block scopes:

    #include <stdio.h>
    
    int main() {
        int i = 0;
        {
            int i = 1;
            printf("%d\n", i);
        }
        return 0;
    }
    
  • LVL: TODO I was not able to easily understand it. We'd need to interpret the source some more.

Upvotes: 29

Ferruccio
Ferruccio

Reputation: 100668

The .loc directive is used to indicate the corresponding line of source code. It indicates the file number, line number and column number of the corresponding source code.

The rest look like labels.

Upvotes: 4

Related Questions