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

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Mon Mar 6 12:05:42 PST 2017


> On Mar 6, 2017, at 11:19 AM, James Y Knight via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> 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.

Even disassembling dead-code stripping, how can you guarantee that the linker won’t change the order in which atoms are laid out?

— 
Mehdi


> 
> On Mon, Mar 6, 2017 at 4:40 AM, Moritz Angermann via llvm-dev <llvm-dev at lists.llvm.org <mailto: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 <mailto:llvm-dev at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
> 
> _______________________________________________
> 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/ace68cb4/attachment.html>


More information about the llvm-dev mailing list