[llvm-dev] [BUG Report] -dead_strip, strips prefix data unconditionally on macOS
Peter Collingbourne via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 6 18:02:46 PST 2017
On Mon, Mar 6, 2017 at 5:54 PM, Moritz Angermann <moritz.angermann at gmail.com
> wrote:
> Hi Peter,
>
> I’ve just experimented with this a bit:
>
> Say we would end up with the following assembly:
>
> .section __TEXT,__text
> .globl _main
>
> .long 1
> _main:
> inc %eax
> ret
>
> .globl _main.dsp
> .alt_entry _main.dsp
>
What happens if you try ".alt_entry _main" instead? The alt_entry is
supposed to be bound to the atom appearing *before* it.
> _main.dsp = _main-4
>
> .subsections_via_symbols
>
> (e.g. we inject the .alt_entry after the fact, pointing to the start of
> the prefix data)
>
> this will yield:
>
> $ clang test.s -dead_strip
> ld: warning: N_ALT_ENTRY bit set on first atom in section __TEXT/__text
> And the prefix data will be stripped again.
>
> E.g. what you end up getting is:
>
> $ otool -vVtdj a.out
> a.out:
> _main:
> 0000000100000fb5 ff c0 incl %eax
> 0000000100000fb7 c3 retq
>
> instead of what we’d like to get:
>
> otool -vVtdj a.out
> a.out:
> _main.dsp:
> 0000000100000fb1 01 00 addl %eax, (%rax)
> 0000000100000fb3 00 00 addb %al, (%rax)
> _main:
> 0000000100000fb5 ff c0 incl %eax
> 0000000100000fb7 c3 retq
>
> .alt_entry’s are not dead_strip protected, and this makes sense I guess,
> as if the alt_entry is never
> actually called visibly from anywhere, it’s probably not needed. However
> there is the .no_daed_strip
directive. Thus if we graft this slightly different:
>
> .section __TEXT,__text
> .globl _main
>
> .long 1
> _main:
> inc %eax
> ret
>
> .no_dead_strip _main.dsp
> .alt_entry _main.dsp
> _main.dsp = _main-4
>
> .subsections_via_symbols
>
> we still get a warning, but it won’t get stripped. At that point however,
> we don’t need the .alt_entry
> anymore (and can drop the warning).
>
> Thus, I’d propose that for functions with prefix_data, a second symbol
> with .no_dead_strip is emitted
> for the prefix data entry point.
I don't think that is sufficient. I believe that the linker is allowed to
move the function away from the prefix data even if the function is not
dead stripped.
Peter
> Cheers,
> Moritz
>
>
> > On Mar 7, 2017, at 3:35 AM, Peter Collingbourne <peter at pcc.me.uk> wrote:
> >
> > That is in theory what omitting the .subsections_via_symbols directive
> is supposed to do, but in an experiment I ran a year or two ago I found
> that the Mach-O linker was still dead stripping on symbol boundaries with
> this directive omitted.
> >
> > In any case, a more precise approach has more recently (~a few months
> ago) become possible. There is a relatively new asm directive called
> .altentry that, as I understand it, tells the linker to disregard a given
> symbol as a section boundary (LLVM already uses this for aliases pointing
> into the middle of a global). So what you would do is to use .altentry on
> the function symbol, with an internal symbol appearing before the prefix
> data to ensure that it is not considered part of the body of the previous
> function.
> >
> > Peter
> >
> > On Mon, 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.
> >
> > 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
> >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > llvm-dev at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> >
> >
> >
> >
> > --
> > --
> > Peter
>
>
--
--
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170306/83ac9f46/attachment.html>
More information about the llvm-dev
mailing list