[llvm-dev] [BUG Report] -dead_strip, strips prefix data unconditionally on macOS
Moritz Angermann via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 6 17:42:55 PST 2017
Hi James,
this is the route we just went. We simply post process the generated assembly and strip out the
.subsections_via_symbols. Quite ugly, I must say. However we did some post asm mangling already,
so this was rather straight forward to implement: https://phabricator.haskell.org/D3287
However the drawback is that on any mach-o platform, you now don’t get the benefit of -dead_code
stripping if you use prefix data. And this might for, say iOS, not be such a great deal.
Cheers,
Moritz
> On Mar 7, 2017, at 3:19 AM, James Y Knight <jyknight at google.com> 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.
>
> 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
>
More information about the llvm-dev
mailing list