Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007133OCamlback end (clambda to assembly)public2016-01-30 01:392016-02-10 15:26
Reporterbartjacobs 
Assigned To 
PrioritylowSeveritytweakReproducibilityalways
StatusclosedResolutionfixed 
PlatformMacOSOS XOS Version10.10.1
Product Version4.02.3 
Target Version4.03.0+dev / +beta1Fixed in Version4.03.0+dev / +beta1 
Summary0007133: Jump labels in assembly code end up as symbols in the executable on OS X
DescriptionOn OS X 10.10.1, the myriad jump labels (of the form .L101:) emitted into the assembly code by ocamlopt are included by the LLVM assembler as symbols into the object file, and thence by the OS X linker (ld64) into the executable. This is undesirable for at least the following reasons:
- Various native backtrace generators, including the OS X crash log generator and lldb, will interpret each jump label as starting a new function, and show the nearest preceding jump label, instead of the actual function name, in the backtrace.
- This also hurts the lldb experience in other ways. For example, when asking lldb to disassemble a function, it only shows the assembly code up to the first jump label.
- It has space and time costs at build time and at load/run time.
Steps To ReproduceEnter the following code into foo.ml:

    let x: unit -> unit = Obj.magic ()
    let () = x ()

Build foo:

    ocamlopt -o foo -S foo.ml

Load foo into LLDB:

    lldb ./foo

Run it

    run

LLDB will stop at the segmentation fault. Ask for a backtrace:

    bt

The backtrace will show the current function as foo`.L100 instead of the correct (and more informative) foo`camlFoo__entry .
Additional InformationThe problem is solved by dropping the dot from the jump label names.

This can be confirmed easily for the abovementioned foo.ml example, as follows:

Generate an assembly code file for foo.ml:

    ocamlopt -c -S foo.ml

Edit foo.s and replace each occurrence of .Lnnn by Lnnn (i.e. remove the dots).

Compile the assembly file:

    clang -arch x86_64 -c foo.s

Build the executable:

    ocamlopt -o foo foo.cmx

Load the executable into LLDB:

    lldb ./foo

Run the executable:

    run

Ask for a backtrace:

    bt

Notice that the current function is now correctly identified as foo`camlFoo__entry .

Explanation: the LLVM assembler seems to treat labels that start with the letter 'L' specially: it considers them local to the file and does not emit them as symbols into the object file.

Fix: dropping the dot from the label names is a single-line fix function emit_label in asmcomp/amd64/emit.mlp.

Complication: by itself, the above fix does not work; in particular, programs for which ocamlopt generates jump tables cause the OS X linker (ld64) to fail.

To see this, create file bar.ml with the following contents:

    let x: int -> unit = Obj.magic ()

    let () =
        match (Obj.magic (): int) with
        | 0 -> x 1
        | 1 -> x 0
        | 2 -> x 20
        | 3 -> x 30

Generate assembly code for this program into bar.s:

    ocamlopt -c -S bar.ml

Edit the assembly code file bar.s: replace each .Lnnn by Lnnn. In vi:

    :1,$s/\.L/L/g
    :wq

Compile the assembly code file:

    clang -c -arch x86_64 bar.s

Build the executable:

    ocamlopt -o bar bar.cmx

This produces the following error message:

    ld: in section __TEXT,__const reloc 0: X86_64_RELOC_SUBTRACTOR must have r_extern=1 file 'bar.o' for architecture x86_64

Explanation: for the match expression in bar.ml, ocamlopt generates the following jump table into bar.s:

        .section __TEXT,__const
        .align 2
.L108:
        .long .L104 - .L108
        .long .L103 - .L108
        .long .L102 - .L108
        .long .L101 - .L108
        .text
.L104:

After replacing .L by L, the LLVM assembler still generates relocation entries for these subtractions, even though the labels are now local. This is because the labels for the cases (L101, L102, L103 and L104) are in the .text section, whereas the expression occurs in the __TEXT,__const section. The linker fails on this relocation entry mentioning a local label.

Fix: Dropping the .section __TEXT,__const directive fixes the problem. It does not seem to be required (anymore) on OS X.

I have prepared a patch and will create a pull request.
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0015291)
bartjacobs (reporter)
2016-01-30 01:54

I have created pull request 0000450 (https://github.com/ocaml/ocaml/pull/450 [^]).
(0015336)
doligez (administrator)
2016-02-10 15:26

Merged in trunk (commit 0a914a4765b8b97f230806706fedc6112a033f77).

Thanks.

- Issue History
Date Modified Username Field Change
2016-01-30 01:39 bartjacobs New Issue
2016-01-30 01:54 bartjacobs Note Added: 0015291
2016-02-05 13:39 doligez Status new => acknowledged
2016-02-05 13:39 doligez Target Version => 4.03.0+dev / +beta1
2016-02-10 15:26 doligez Note Added: 0015336
2016-02-10 15:26 doligez Status acknowledged => closed
2016-02-10 15:26 doligez Resolution open => fixed
2016-02-10 15:26 doligez Fixed in Version => 4.03.0+dev / +beta1
2017-02-23 16:35 doligez Category OCaml backend (code generation) => Back end (clambda to assembly)
2017-02-23 16:44 doligez Category Back end (clambda to assembly) => back end (clambda to assembly)


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker