Skip to content

LLD for Mach-O incorrectly dead-strips merged CFStringsΒ #104625

@smeenai

Description

@smeenai

#101222 recently landed which enables private symbols to be merged, which includes CFString constants. On a Clang containing that patch, if you build the following C code:

$ cat merge.c
void *__CFConstantStringClassReference;
int main(int argc, char *argv[]) {
  return argc ? (long)__builtin___CFStringMakeConstantString("foo")
              : (long)__builtin___CFStringMakeConstantString("bar");
}

$ clang -target arm64-apple-macos11 -O3 -S -o merge.s merge.c

It generates the assembly in https://gist.github.com/smeenai/9fe473bcb5c4cb4a2b97eb147b23f671 (I changed a .set directive changed to = to avoid #104623 and match the object file generated by Clang directly). If you compile and link this assembly:

$ llvm-mc --triple=arm64-apple-macos11 --filetype=obj -o merge.o merge.s
$ ld64.lld -arch arm64 -platform_version macos 11 11 -dead_strip -o merge merge.o

you'll discover that the second cfstring constant has been incorrectly dead-stripped:

$ llvm-objdump -h merge.o | grep cfstring
  3 __cfstring       00000040 0000000000000020 DATA

$ llvm-objdump -h merge | grep cfstring
  3 __cfstring    00000020 0000000100004000 DATA

Note the size of 0x20 instead of 0x40 in the output binary. The code in the binary still references the second string though:

$ llvm-objdump -d merge
0000000100000470 <_main>:
100000470: 1001dc88     adr     x8, 0x100004000 <__MergedGlobals>
100000474: d503201f     nop
100000478: 11008109     add     w9, w8, #0x20
10000047c: 7100001f     cmp     w0, #0x0
100000480: 1a880120     csel    w0, w9, w8, eq
100000484: d65f03c0     ret

Which causes crashes at runtime in an actual program.

This might be a general problem with dead-stripping sections with alt_entry symbols and not something specific to CFStrings, but I haven't experimented further yet.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions