Use a memcpy to avoid unaligned store UB.
authorPete Cooper <peter_cooper@apple.com>
Thu, 24 Mar 2016 01:05:17 +0000 (01:05 +0000)
committerPete Cooper <peter_cooper@apple.com>
Thu, 24 Mar 2016 01:05:17 +0000 (01:05 +0000)
On a 32-bit output, we may write LC_MAIN (which contains a uint64_t) to
an unaligned address.  This changes it to use a memcpy instead which is UB safe.

llvm-svn: 264232

lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp

index a0a3df4..f85dbba 100644 (file)
@@ -943,13 +943,16 @@ std::error_code MachOFileLayout::writeLoadCommands() {
     // If main executable, add LC_MAIN.
     if (_file.fileType == llvm::MachO::MH_EXECUTE) {
       // Build LC_MAIN load command.
-      entry_point_command* ep = reinterpret_cast<entry_point_command*>(lc);
-      ep->cmd       = LC_MAIN;
-      ep->cmdsize   = sizeof(entry_point_command);
-      ep->entryoff  = _file.entryAddress - _seg1addr;
-      ep->stacksize = _file.stackSize;
+      // Note, using a temporary here to appease UB as we may not be aligned
+      // enough for a struct containing a uint64_t when emitting a 32-bit binary
+      entry_point_command ep;
+      ep.cmd       = LC_MAIN;
+      ep.cmdsize   = sizeof(entry_point_command);
+      ep.entryoff  = _file.entryAddress - _seg1addr;
+      ep.stacksize = _file.stackSize;
       if (_swap)
-        swapStruct(*ep);
+        swapStruct(ep);
+      memcpy(lc, &ep, sizeof(entry_point_command));
       lc += sizeof(entry_point_command);
     }