You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 7133 Reporter: bartjacobs Status: closed (set by @damiendoligez on 2016-02-10T14:26:25Z) Resolution: fixed Priority: low Severity: tweak Platform: Mac OS: OS X OS Version: 10.10.1 Version: 4.02.3 Target version: 4.03.0+dev / +beta1 Fixed in version: 4.03.0+dev / +beta1 Category: back end (clambda to assembly)
Bug description
On 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 reproduce
Enter 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) foocamlFoo__entry .
Additional information
The 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:
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.
The text was updated successfully, but these errors were encountered:
Original bug ID: 7133
Reporter: bartjacobs
Status: closed (set by @damiendoligez on 2016-02-10T14:26:25Z)
Resolution: fixed
Priority: low
Severity: tweak
Platform: Mac
OS: OS X
OS Version: 10.10.1
Version: 4.02.3
Target version: 4.03.0+dev / +beta1
Fixed in version: 4.03.0+dev / +beta1
Category: back end (clambda to assembly)
Bug description
On 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:
Steps to reproduce
Enter the following code into foo.ml:
Build foo:
Load foo into LLDB:
Run it
LLDB will stop at the segmentation fault. Ask for a backtrace:
The backtrace will show the current function as foo
.L100 instead of the correct (and more informative) foo
camlFoo__entry .Additional information
The 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:
Edit foo.s and replace each occurrence of .Lnnn by Lnnn (i.e. remove the dots).
Compile the assembly file:
Build the executable:
Load the executable into LLDB:
Run the executable:
Ask for a backtrace:
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:
Generate assembly code for this program into bar.s:
Edit the assembly code file bar.s: replace each .Lnnn by Lnnn. In vi:
Compile the assembly code file:
Build the executable:
This produces the following error message:
Explanation: for the match expression in bar.ml, ocamlopt generates the following jump table into bar.s:
.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.
The text was updated successfully, but these errors were encountered: