[clang] 42a1fb5 - [LinkerWrapper][Fix} Fix bad alignment from extracted archive members

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Wed May 11 13:57:00 PDT 2022


Author: Joseph Huber
Date: 2022-05-11T16:56:41-04:00
New Revision: 42a1fb5ca56c494e25419a97057a9526f3e8608d

URL: https://github.com/llvm/llvm-project/commit/42a1fb5ca56c494e25419a97057a9526f3e8608d
DIFF: https://github.com/llvm/llvm-project/commit/42a1fb5ca56c494e25419a97057a9526f3e8608d.diff

LOG: [LinkerWrapper][Fix} Fix bad alignment from extracted archive members

Summary:
We use embedded binaries to extract offloading device code from the host
fatbinary. This uses a binary format whose necessary alignment is
eight bytes. The alignment is included within the ELF section type so
the data extracted from the ELF should always be aligned at that amount.
However, if this file was extraqcted from a static archive, it was being
sent as an offset in the archive file which did not have the same
alignment guaruntees as the ELF file. This was causing errors in the
UB-sanitizer build as it would occasionally try to access a misaligned
address. To fix this, I simply copy the memory directly to a new buffer
which is guarnteed to have worst-case alignment of 16 in the case that
it's not properly aligned.

Added: 
    

Modified: 
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Removed: 
    


################################################################################
diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 670e1af943046..ad9f6c9b55770 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -536,11 +536,18 @@ extractFromArchive(const Archive &Library,
   // offloading code removed.
   Error Err = Error::success();
   for (auto Child : Library.children(Err)) {
-    auto ChildBufferRefOrErr = Child.getMemoryBufferRef();
-    if (!ChildBufferRefOrErr)
-      return ChildBufferRefOrErr.takeError();
+    auto ChildBufferOrErr = Child.getMemoryBufferRef();
+    if (!ChildBufferOrErr)
+      return ChildBufferOrErr.takeError();
     std::unique_ptr<MemoryBuffer> ChildBuffer =
-        MemoryBuffer::getMemBuffer(*ChildBufferRefOrErr, false);
+        MemoryBuffer::getMemBuffer(*ChildBufferOrErr, false);
+
+    // Check if the buffer has the required alignment.
+    if (!isAddrAligned(Align(OffloadBinary::getAlignment()),
+                       ChildBuffer->getBufferStart()))
+      ChildBuffer = MemoryBuffer::getMemBufferCopy(
+          ChildBufferOrErr->getBuffer(),
+          ChildBufferOrErr->getBufferIdentifier());
 
     auto FileOrErr = extractFromBuffer(std::move(ChildBuffer), DeviceFiles,
                                        /*IsLibrary*/ true);


        


More information about the cfe-commits mailing list