[llvm-dev] [BUG Report] -dead_strip, strips prefix data unconditionally on macOS

James Y Knight via llvm-dev llvm-dev at lists.llvm.org
Mon Mar 6 11:19:35 PST 2017


AFAIK, this cannot actually work on Apple platforms, because its object
file format (Mach-O) doesn't use sections to determine the ranges of
code/data to keep together, but instead _infers_ boundaries based on the
range between global symbols in the symbol table.

So, the symbol pointing to the beginning of @main *necessarily* makes that
be a section boundary.

I think the best that could be done in LLVM is to not emit the
".subsections_via_symbols" asm directive (effectively disabling dead
stripping on that object) if any prefix data exists. Currently it emits
that flag unconditionally for MachO.

On Mon, Mar 6, 2017 at 4:40 AM, Moritz Angermann via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hi,
>
> I just came across a rather annoying behavior with llvm 3.9. Assuming the
> following
> samle code in test.ll:
>
> ; Lets have some global int x = 4
> @x = global i32 10, align 4
> ; and two strings "p = %d\n" for the prefix data,
> ; as well as "x = %d\n" to print the (global) x value.
> @.str = private unnamed_addr constant [8 x i8] c"x = %d\0A\00", align 1
> @.str2 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 1
>
> ; declare printf, we'll use this later for printf style debugging.
> declare i32 @printf(i8*, ...)
>
> ; define a main function.
> define i32 @main() prefix i32 123 {
>   ; obtain a i32 pointer to the main function.
>   ; the prefix data is right before that pointer.
>   %main = bitcast i32 ()* @main to i32*
>
>   ; use the gep, to cmpute the start of the prefix data.
>   %prefix_ptr = getelementptr inbounds i32, i32* %main, i32 -1
>   ; and load it.
>   %prefix_val = load i32, i32* %prefix_ptr
>
>   ; print that value.
>   %ret = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8],
> [8 x i8]* @.str2, i32 0, i32 0), i32 %prefix_val)
>
>   ; similarly let's do the same with the global x.
>   %1 = alloca i32, align 4
>   store i32 0, i32* %1, align 4
>   %2 = load i32, i32* @x, align 4
>   %3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8],
> [8 x i8]* @.str, i32 0, i32 0), i32 %2)
>   ret i32 0
> }
>
> gives the following result (expected)
>
>    $ clang test.ll
>    $ ./a.out
>    p = 123
>    x = 10
>
> however, with -dead_strip on macOS, we see the following:
>
>    $ clang test.ll -dead_strip
>    $ ./a.out
>    p = 0
>    x = 10
>
> Thus I believe we are incorrectly stripping prefix data when linking with
> -dead_strip on macOS.
>
> As I do not have a bugzilla account, and hence cannot post this as a
> proper bug report.
>
> Cheers,
>  Moritz
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170306/9bc3748a/attachment.html>


More information about the llvm-dev mailing list