Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Jump labels in assembly code end up as symbols in the executable on OS X #7133
Original bug ID: 7133
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:
Load foo into LLDB:
LLDB will stop at the segmentation fault. Ask for a backtrace:
The backtrace will show the current function as foo
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:
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.