Page MenuHomePhabricator

[lld-macho] Ensure reads from nlist_64 structs are aligned when necessary
Needs ReviewPublic

Authored by int3 on Thu, May 21, 3:29 PM.



My test refactoring in D80217 seems to have caused yaml2obj to emit unaligned
nlist_64 structs, causing ASAN'd lld to be unhappy. I don't think this is an
issue with yaml2obj though -- llvm-mc also seems to emit unaligned nlist_64s.
This diff makes lld able to safely do aligned reads under ASAN builds while
hopefully creating no overhead for regular builds on architectures that support
unaligned reads.

Depends on D80217.

Diff Detail

Unit TestsFailed

100 msClang.CodeGen::attr-nomerge.cpp
Script: -- : 'RUN: at line 1'; c:\ws\prod\llvm-project\build\bin\clang.exe -cc1 -internal-isystem c:\ws\prod\llvm-project\build\lib\clang\11.0.0\include -nostdsysteminc -S -emit-llvm C:\ws\prod\llvm-project\clang\test\CodeGen\attr-nomerge.cpp -o - | c:\ws\prod\llvm-project\build\bin\filecheck.exe C:\ws\prod\llvm-project\clang\test\CodeGen\attr-nomerge.cpp

Event Timeline

int3 created this revision.Thu, May 21, 3:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptThu, May 21, 3:29 PM
int3 edited the summary of this revision. (Show Details)Thu, May 21, 5:57 PM

Hmm. We're in for a world of hurt if this memcpy doesn't get optimized, so I wanna have a good sense of how reliable that is. Adding Reid and Kostya to see if they've dealt with similar issues/have thoughts on this.

Looking at a basic example, seems like clang, gcc and MSVC are all able to elide the memcpy (though interestingly enough, MSVC doesn't do this when it's optimizing for size, and ends up generating larger code as a result). Our case is a bit more complex though (it involes loops and ArrayRefs), so it's probably worth examining the generated assembly to confirm the elision is still happening.

Additionally, it seems unfortunate to have to rely on this optimization. An alternative would be making llvm-mc and yaml2obj create aligned outputs; I don't know what the potential downsides are (I'm sure there's some reason they aren't doing this already), but I'm also wondering how those tools aren't invoking UB if they're writing an nlist_64 out to an unaligned location (I guess it'd be fine if they're writing to the file directly instead of using memory mapping). From a brief look into ld64's object file parsing, it's also accessing the nlist_64 structs directly from the input file via a cast, so the same alignment issue exists there.