[llvm-branch-commits] [llvm] fddb417 - [llvm-elfabi] Add flag to preserve timestamp when output is the same

2020-12-29 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-12-29T14:43:47-08:00
New Revision: fddb41744958d21635a60622cfb4067122810bcc

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

LOG: [llvm-elfabi] Add flag to preserve timestamp when output is the same

This change adds '--write-if-changed' flag to llvm-elfabi tool. When
enabled, llvm-elfabi will not overwrite the existing file if the
content of the file will not be changed, which preserves the
timestamp.

Differential Revision: https://reviews.llvm.org/D92902

Added: 
llvm/test/tools/llvm-elfabi/preserve-dates-stub.test
llvm/test/tools/llvm-elfabi/preserve-dates-tbe.test

Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 




diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index cbb9420cb666..4ec158c1405f 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -16,6 +16,7 @@
 #include "llvm/InterfaceStub/ELFStub.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/FileSystem.h"
 
 namespace llvm {
 
@@ -35,8 +36,10 @@ Expected> 
readELFFile(MemoryBufferRef Buf);
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 /// @param OutputFormat Target ELFType to write binary as.
+/// @param WriteIfChanged Whether or not to preserve timestamp if
+///the output stays the same.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat);
+  ELFTarget OutputFormat, bool WriteIfChanged = false);
 
 } // end namespace elfabi
 } // end namespace llvm

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index e50ebd7b8ba1..40d8afa88ad2 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Process.h"
 
 using llvm::MemoryBufferRef;
 using llvm::object::ELFObjectFile;
@@ -663,8 +664,25 @@ buildStub(const ELFObjectFile &ElfObj) {
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 template 
-static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub) {
+static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub,
+  bool WriteIfChanged) {
   ELFStubBuilder Builder{Stub};
+  // Write Stub to memory first.
+  std::vector Buf(Builder.getSize());
+  Builder.write(Buf.data());
+
+  if (WriteIfChanged) {
+if (ErrorOr> BufOrError =
+MemoryBuffer::getFile(FilePath)) {
+  // Compare Stub output with existing Stub file.
+  // If Stub file unchanged, abort updating.
+  if ((*BufOrError)->getBufferSize() == Builder.getSize() &&
+  !memcmp((*BufOrError)->getBufferStart(), Buf.data(),
+  Builder.getSize()))
+return Error::success();
+}
+  }
+
   Expected> BufOrError =
   FileOutputBuffer::create(FilePath, Builder.getSize());
   if (!BufOrError)
@@ -674,13 +692,10 @@ static Error writeELFBinaryToFile(StringRef FilePath, 
const ELFStub &Stub) {
  "` for writing");
 
   // Write binary to file.
-  std::unique_ptr Buf = std::move(*BufOrError);
-  Builder.write(Buf->getBufferStart());
+  std::unique_ptr FileBuf = std::move(*BufOrError);
+  memcpy(FileBuf->getBufferStart(), Buf.data(), Buf.size());
 
-  if (Error E = Buf->commit())
-return E;
-
-  return Error::success();
+  return FileBuf->commit();
 }
 
 Expected> readELFFile(MemoryBufferRef Buf) {
@@ -705,15 +720,15 @@ Expected> 
readELFFile(MemoryBufferRef Buf) {
 // This function wraps the ELFT writeELFBinaryToFile() so writeBinaryStub()
 // can be called without having to use ELFType templates directly.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat) {
+  ELFTarget OutputFormat, bool WriteIfChanged) {
   if (OutputFormat == ELFTarget::ELF32LE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
   if (OutputFormat == ELFTarget::ELF32BE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
   if (OutputFormat == ELFTarget::ELF64LE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBina

[llvm-branch-commits] [llvm] d034a94 - Revert "[llvm-elfabi] Add flag to preserve timestamp when output is the same"

2020-12-29 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-12-29T17:26:22-08:00
New Revision: d034a94e7b3c8122acc91c4dad13110d15ed97d0

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

LOG: Revert "[llvm-elfabi] Add flag to preserve timestamp when output is the 
same"

This reverts commit fddb41744958d21635a60622cfb4067122810bcc. which
causes test failures on Mac builders.

Added: 


Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 
llvm/test/tools/llvm-elfabi/preserve-dates-stub.test
llvm/test/tools/llvm-elfabi/preserve-dates-tbe.test



diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index 4ec158c1405f..cbb9420cb666 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -16,7 +16,6 @@
 #include "llvm/InterfaceStub/ELFStub.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/FileSystem.h"
 
 namespace llvm {
 
@@ -36,10 +35,8 @@ Expected> 
readELFFile(MemoryBufferRef Buf);
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 /// @param OutputFormat Target ELFType to write binary as.
-/// @param WriteIfChanged Whether or not to preserve timestamp if
-///the output stays the same.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat, bool WriteIfChanged = false);
+  ELFTarget OutputFormat);
 
 } // end namespace elfabi
 } // end namespace llvm

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index 40d8afa88ad2..e50ebd7b8ba1 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -17,7 +17,6 @@
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Process.h"
 
 using llvm::MemoryBufferRef;
 using llvm::object::ELFObjectFile;
@@ -664,25 +663,8 @@ buildStub(const ELFObjectFile &ElfObj) {
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 template 
-static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub,
-  bool WriteIfChanged) {
+static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub) {
   ELFStubBuilder Builder{Stub};
-  // Write Stub to memory first.
-  std::vector Buf(Builder.getSize());
-  Builder.write(Buf.data());
-
-  if (WriteIfChanged) {
-if (ErrorOr> BufOrError =
-MemoryBuffer::getFile(FilePath)) {
-  // Compare Stub output with existing Stub file.
-  // If Stub file unchanged, abort updating.
-  if ((*BufOrError)->getBufferSize() == Builder.getSize() &&
-  !memcmp((*BufOrError)->getBufferStart(), Buf.data(),
-  Builder.getSize()))
-return Error::success();
-}
-  }
-
   Expected> BufOrError =
   FileOutputBuffer::create(FilePath, Builder.getSize());
   if (!BufOrError)
@@ -692,10 +674,13 @@ static Error writeELFBinaryToFile(StringRef FilePath, 
const ELFStub &Stub,
  "` for writing");
 
   // Write binary to file.
-  std::unique_ptr FileBuf = std::move(*BufOrError);
-  memcpy(FileBuf->getBufferStart(), Buf.data(), Buf.size());
+  std::unique_ptr Buf = std::move(*BufOrError);
+  Builder.write(Buf->getBufferStart());
 
-  return FileBuf->commit();
+  if (Error E = Buf->commit())
+return E;
+
+  return Error::success();
 }
 
 Expected> readELFFile(MemoryBufferRef Buf) {
@@ -720,15 +705,15 @@ Expected> 
readELFFile(MemoryBufferRef Buf) {
 // This function wraps the ELFT writeELFBinaryToFile() so writeBinaryStub()
 // can be called without having to use ELFType templates directly.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat, bool WriteIfChanged) {
+  ELFTarget OutputFormat) {
   if (OutputFormat == ELFTarget::ELF32LE)
-return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
+return writeELFBinaryToFile(FilePath, Stub);
   if (OutputFormat == ELFTarget::ELF32BE)
-return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
+return writeELFBinaryToFile(FilePath, Stub);
   if (OutputFormat == ELFTarget::ELF64LE)
-return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
+return writeELFBinaryToFile(FilePath, Stub);
   if (OutputFormat == ELFTarget::ELF64BE)
-return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged

[llvm-branch-commits] [llvm] a1d0589 - [llvm-elfabi] Add flag to preserve timestamp when output is the same

2020-12-29 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-12-29T20:27:06-08:00
New Revision: a1d0589266865998785c996668d828445f10fc98

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

LOG: [llvm-elfabi] Add flag to preserve timestamp when output is the same

This change adds '--write-if-changed' flag to llvm-elfabi tool. When
enabled, llvm-elfabi will not overwrite the existing file if the
content of the file will not be changed, which preserves the
timestamp.

Differential Revision: https://reviews.llvm.org/D92902

Added: 
llvm/test/tools/llvm-elfabi/preserve-dates-stub.test
llvm/test/tools/llvm-elfabi/preserve-dates-tbe.test

Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 




diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index cbb9420cb666..4ec158c1405f 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -16,6 +16,7 @@
 #include "llvm/InterfaceStub/ELFStub.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/FileSystem.h"
 
 namespace llvm {
 
@@ -35,8 +36,10 @@ Expected> 
readELFFile(MemoryBufferRef Buf);
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 /// @param OutputFormat Target ELFType to write binary as.
+/// @param WriteIfChanged Whether or not to preserve timestamp if
+///the output stays the same.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat);
+  ELFTarget OutputFormat, bool WriteIfChanged = false);
 
 } // end namespace elfabi
 } // end namespace llvm

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index e50ebd7b8ba1..40d8afa88ad2 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Process.h"
 
 using llvm::MemoryBufferRef;
 using llvm::object::ELFObjectFile;
@@ -663,8 +664,25 @@ buildStub(const ELFObjectFile &ElfObj) {
 /// @param FilePath File path for writing the ELF binary.
 /// @param Stub Source ELFStub to generate a binary ELF stub from.
 template 
-static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub) {
+static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub,
+  bool WriteIfChanged) {
   ELFStubBuilder Builder{Stub};
+  // Write Stub to memory first.
+  std::vector Buf(Builder.getSize());
+  Builder.write(Buf.data());
+
+  if (WriteIfChanged) {
+if (ErrorOr> BufOrError =
+MemoryBuffer::getFile(FilePath)) {
+  // Compare Stub output with existing Stub file.
+  // If Stub file unchanged, abort updating.
+  if ((*BufOrError)->getBufferSize() == Builder.getSize() &&
+  !memcmp((*BufOrError)->getBufferStart(), Buf.data(),
+  Builder.getSize()))
+return Error::success();
+}
+  }
+
   Expected> BufOrError =
   FileOutputBuffer::create(FilePath, Builder.getSize());
   if (!BufOrError)
@@ -674,13 +692,10 @@ static Error writeELFBinaryToFile(StringRef FilePath, 
const ELFStub &Stub) {
  "` for writing");
 
   // Write binary to file.
-  std::unique_ptr Buf = std::move(*BufOrError);
-  Builder.write(Buf->getBufferStart());
+  std::unique_ptr FileBuf = std::move(*BufOrError);
+  memcpy(FileBuf->getBufferStart(), Buf.data(), Buf.size());
 
-  if (Error E = Buf->commit())
-return E;
-
-  return Error::success();
+  return FileBuf->commit();
 }
 
 Expected> readELFFile(MemoryBufferRef Buf) {
@@ -705,15 +720,15 @@ Expected> 
readELFFile(MemoryBufferRef Buf) {
 // This function wraps the ELFT writeELFBinaryToFile() so writeBinaryStub()
 // can be called without having to use ELFType templates directly.
 Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat) {
+  ELFTarget OutputFormat, bool WriteIfChanged) {
   if (OutputFormat == ELFTarget::ELF32LE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
   if (OutputFormat == ELFTarget::ELF32BE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBinaryToFile(FilePath, Stub, WriteIfChanged);
   if (OutputFormat == ELFTarget::ELF64LE)
-return writeELFBinaryToFile(FilePath, Stub);
+return writeELFBina

[llvm-branch-commits] [clang] 8deaec1 - [analyzer] Update Fuchsia checker to catch releasing unowned handles.

2021-01-06 Thread Haowei Wu via llvm-branch-commits

Author: Daniel Hwang
Date: 2021-01-06T16:23:49-08:00
New Revision: 8deaec122ec68746c53ec2afb893873124053d8d

URL: 
https://github.com/llvm/llvm-project/commit/8deaec122ec68746c53ec2afb893873124053d8d
DIFF: 
https://github.com/llvm/llvm-project/commit/8deaec122ec68746c53ec2afb893873124053d8d.diff

LOG: [analyzer] Update Fuchsia checker to catch releasing unowned handles.

Certain Fuchsia functions may return handles that are not owned by the
current closure. This adds a check in order to determine when these
handles are released.

Differential Revision: https://reviews.llvm.org/D93868

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
clang/test/Analysis/fuchsia_handle.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
index c246a8db3067..e3f4be0726c8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -20,29 +20,39 @@
 // Art:
 //
 //
-//  +-+-v-+ ++
-//   acquire_func succeeded | | Escape  ||
-//+->  Allocated  +->  Escaped   <--+
-//| | | ||  |
-//| +-+--++ ++  |
-//|   |  |  |
-//| release_func  |  +--+   |
-//|   | | handle  ++|
-//|   | | dies|||
-//|  +v-+   +-> Leaked ||
-//|  |  | |(REPORT)||
-// +--+--+   | Released | Escape  ++|
-// | |   |  +---+
-// | Not tracked <--+++---+-+
-// | |  | |   |As argument by value
-// +--+--+  |release_func |   +--+ in function call
-//| | |  | or by reference in
-//| | |  | use_func call
-//+-++v-+| +---+
-//acquire_func failed| Double   |+-> Use after |
-//   | released |  | released  |
-//   | (REPORT) |  | (REPORT)  |
-//   +--+  +---+
+// +-+ ++
+//  acquire_func succeeded | | Escape  ||
+//   +->  Allocated  +->  Escaped   <--+
+//   | | | ||  |
+//   | +-+--++ ++  |
+//   |   |  |  |
+// acquire_func  | release_func  |  +--+   |
+//failed |   | | handle  ++|
+// +-+   |   | | dies|||
+// | |   |  +v-+   +-> Leaked ||
+// | |   |  |  | |(REPORT)||
+// |  +--+--+   | Released | Escape  ++|
+// |  | |   |  +---+
+// +--> Not tracked |   ++---+-+
+//| ||   |As argument by value
+//+--+--+   release_func |   +--+ in function call
+//   |   |  | or by reference in
+//   |   |  | use_func call
+//unowned|  +v-+| +---+
+//  acquire_func |  | Double   |+-> Use after |
+//   succeeded   |  | released |  | released  |
+//   |  | (REPORT) |  | (REPORT)  |
+//+---+ +--+  +---+
+//| Allocated |
+//| Unowned   |  release_func
+//|   +-+
+//+---+ |
+//  |
+//+-v--+
+//| Release of |
+//| unowned handle |
+//| (REPORT)   |
+//++
 //
 // acquire_func represents the 

[llvm-branch-commits] [clang] 7c0e3a7 - [clang][IR] Add support for leaf attribute

2020-12-14 Thread Haowei Wu via llvm-branch-commits

Author: Gulfem Savrun Yeniceri
Date: 2020-12-14T14:48:17-08:00
New Revision: 7c0e3a77bc43a9c4d05f68ffd4e84d0f75efbd91

URL: 
https://github.com/llvm/llvm-project/commit/7c0e3a77bc43a9c4d05f68ffd4e84d0f75efbd91
DIFF: 
https://github.com/llvm/llvm-project/commit/7c0e3a77bc43a9c4d05f68ffd4e84d0f75efbd91.diff

LOG: [clang][IR] Add support for leaf attribute

This patch adds support for leaf attribute as an optimization hint
in Clang/LLVM.

Differential Revision: https://reviews.llvm.org/D90275

Added: 
clang/test/CodeGen/attr-leaf.c
clang/test/Sema/attr-leaf.c

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/CodeGen/CGCall.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
llvm/include/llvm/Bitcode/LLVMBitCodes.h
llvm/include/llvm/IR/Attributes.td
llvm/lib/AsmParser/LLLexer.cpp
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/AsmParser/LLToken.h
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/IR/Attributes.cpp
llvm/lib/IR/Verifier.cpp
llvm/lib/Transforms/Utils/CodeExtractor.cpp
llvm/test/Bitcode/attributes.ll

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 79902c8f5b89..61eb86ac81a1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1448,6 +1448,13 @@ def LayoutVersion : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [LayoutVersionDocs];
 }
 
+def Leaf : InheritableAttr {
+  let Spellings = [GCC<"leaf">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [LeafDocs];
+  let SimpleHandler = 1;
+}
+
 def LifetimeBound : DeclOrTypeAttr {
   let Spellings = [Clang<"lifetimebound", 0>];
   let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 28f35cf2c0c7..e70596b5ac28 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3976,6 +3976,22 @@ are used to instantiate the specialization.
   }];
 }
 
+def LeafDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+
+The ``leaf`` attribute is used as a compiler hint to improve dataflow analysis
+in library functions. Functions marked with the ``leaf`` attribute are not 
allowed
+to jump back into the caller's translation unit, whether through invoking a
+callback function, an external function call, use of ``longjmp``, or other 
means.
+Therefore, they cannot use or modify any data that does not escape the caller 
function's
+compilation unit.
+
+For more information see
+`gcc documentation 
`
+}];
+}
+
 def NoStackProtectorDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 5db34b693bf3..73194be922dd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1989,6 +1989,8 @@ void CodeGenModule::ConstructAttributeList(
   FuncAttrs.addAttribute("no_caller_saved_registers");
 if (TargetDecl->hasAttr())
   FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
+if (TargetDecl->hasAttr())
+  FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
 
 HasOptnone = TargetDecl->hasAttr();
 if (auto *AllocSize = TargetDecl->getAttr()) {

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 15094854300d..395d0ef57945 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7715,6 +7715,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, 
Decl *D,
   case ParsedAttr::AT_AnyX86NoCfCheck:
 handleNoCfCheckAttr(S, D, AL);
 break;
+  case ParsedAttr::AT_Leaf:
+handleSimpleAttribute(S, D, AL);
+break;
   case ParsedAttr::AT_NoThrow:
 if (!AL.isUsedAsTypeAttr())
   handleSimpleAttribute(S, D, AL);

diff  --git a/clang/test/CodeGen/attr-leaf.c b/clang/test/CodeGen/attr-leaf.c
new file mode 100644
index ..2b2bacf5e725
--- /dev/null
+++ b/clang/test/CodeGen/attr-leaf.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -Oz -o - %s | FileCheck 
%s
+
+// CHECK: define void @f() local_unnamed_addr [[ATTRS:#[0-9]+]] {
+void f() __attribute__((leaf));
+
+void f()
+{
+}
+
+// CHECK: attributes [[ATTRS]] = { {{.*}}nocallback{{.*}} }

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 0ba6769a1a8a..cb1e48217a81 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -68,6 +

[llvm-branch-commits] [llvm] 8a3c41b - [IR] Fixed the typo in attributes test

2020-12-16 Thread Haowei Wu via llvm-branch-commits

Author: Gulfem Savrun Yeniceri
Date: 2020-12-16T15:06:23-08:00
New Revision: 8a3c41be94ca95413522cc423578b72f83f3950c

URL: 
https://github.com/llvm/llvm-project/commit/8a3c41be94ca95413522cc423578b72f83f3950c
DIFF: 
https://github.com/llvm/llvm-project/commit/8a3c41be94ca95413522cc423578b72f83f3950c.diff

LOG: [IR] Fixed the typo in attributes test

Fixed the typo introduced in D90275.

Differential Revision: https://reviews.llvm.org/D93420

Added: 


Modified: 
llvm/test/Bitcode/attributes.ll

Removed: 




diff  --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 36c9ff7ca391..7db9dbe8f89e 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -404,8 +404,8 @@ define void @f68() mustprogress
   ret void
 }
 
-; CHECK; define void @f69() #43
-define void @f70() nocallback
+; CHECK; define void @f69() #42
+define void @f69() nocallback
 {
   ret void
 }



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] d93287c - [scan-build] Supprot relative 'file' in cdb.

2020-11-09 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-11-09T20:06:20-08:00
New Revision: d93287cac89fd50a105ac4a59c079884b8e53e49

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

LOG: [scan-build] Supprot relative 'file' in cdb.

Excluded folders in scan build is turned to absolute path before
comapre to 'file' in cdb. 'file' in cdb might be a path relative
to 'directory', so we need to turn it to absolute path before
comparison.

Patch by Yu Shan

Differential Revision: https://reviews.llvm.org/D90362

Added: 


Modified: 
clang/tools/scan-build-py/libscanbuild/analyze.py

Removed: 




diff  --git a/clang/tools/scan-build-py/libscanbuild/analyze.py 
b/clang/tools/scan-build-py/libscanbuild/analyze.py
index ffdf7f7c7d61..a4bb499f86c9 100644
--- a/clang/tools/scan-build-py/libscanbuild/analyze.py
+++ b/clang/tools/scan-build-py/libscanbuild/analyze.py
@@ -207,10 +207,14 @@ def write_global_map(arch, mangled_ast_pairs):
 def run_analyzer_parallel(args):
 """ Runs the analyzer against the given compilation database. """
 
-def exclude(filename):
+def exclude(filename, directory):
 """ Return true when any excluded directory prefix the filename. """
-return any(re.match(r'^' + directory, filename)
-   for directory in args.excludes)
+if not os.path.isabs(filename):
+# filename is either absolute or relative to directory. Need to 
turn
+# it to absolute since 'args.excludes' are absolute paths.
+filename = os.path.normpath(os.path.join(directory, filename))
+return any(re.match(r'^' + exclude_directory, filename)
+   for exclude_directory in args.excludes)
 
 consts = {
 'clang': args.clang,
@@ -225,7 +229,8 @@ def exclude(filename):
 logging.debug('run analyzer against compilation database')
 with open(args.cdb, 'r') as handle:
 generator = (dict(cmd, **consts)
- for cmd in json.load(handle) if not exclude(cmd['file']))
+ for cmd in json.load(handle) if not exclude(
+cmd['file'], cmd['directory']))
 # when verbose output requested execute sequentially
 pool = multiprocessing.Pool(1 if args.verbose > 2 else None)
 for current in pool.imap_unordered(run, generator):



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 914f6c4 - [StaticAnalyzer] Support struct annotations in FuchsiaHandleChecker

2020-11-21 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-11-21T19:59:51-08:00
New Revision: 914f6c4ff8a42d384cad0bbb07de4dd1a96c78d4

URL: 
https://github.com/llvm/llvm-project/commit/914f6c4ff8a42d384cad0bbb07de4dd1a96c78d4
DIFF: 
https://github.com/llvm/llvm-project/commit/914f6c4ff8a42d384cad0bbb07de4dd1a96c78d4.diff

LOG: [StaticAnalyzer] Support struct annotations in FuchsiaHandleChecker

Support adding handle annotations to sturucture that contains
handles. All the handles referenced by the structure (direct
value or ptr) would be treated as containing the
release/use/acquire annotations directly.

Patch by Yu Shan

Differential Revision: https://reviews.llvm.org/D91223

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
clang/test/Analysis/fuchsia_handle.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
index b2822e5307f3..d4901eb0abbb 100644
--- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -53,7 +53,7 @@
 //
 // Note that, the analyzer does not always know for sure if a function failed
 // or succeeded. In those cases we use the state MaybeAllocated.
-// Thus, the diagramm above captures the intent, not implementation details.
+// Thus, the diagram above captures the intent, not implementation details.
 //
 // Due to the fact that the number of handle related syscalls in Fuchsia
 // is large, we adopt the annotation attributes to descript syscalls'
@@ -226,32 +226,70 @@ static const ExplodedNode *getAcquireSite(const 
ExplodedNode *N, SymbolRef Sym,
   return nullptr;
 }
 
-/// Returns the symbols extracted from the argument or null if it cannot be
-/// found.
-static SymbolRef getFuchsiaHandleSymbol(QualType QT, SVal Arg,
-ProgramStateRef State) {
+namespace {
+class FuchsiaHandleSymbolVisitor final : public SymbolVisitor {
+public:
+  FuchsiaHandleSymbolVisitor(ProgramStateRef State) : State(std::move(State)) 
{}
+  ProgramStateRef getState() const { return State; }
+
+  bool VisitSymbol(SymbolRef S) override {
+if (const auto *HandleType = S->getType()->getAs())
+  if (HandleType->getDecl()->getName() == HandleTypeName)
+Symbols.push_back(S);
+return true;
+  }
+
+  SmallVector GetSymbols() { return Symbols; }
+
+private:
+  SmallVector Symbols;
+  ProgramStateRef State;
+};
+} // end anonymous namespace
+
+/// Returns the symbols extracted from the argument or empty vector if it 
cannot
+/// be found. It is unlikely to have over 1024 symbols in one argument.
+static SmallVector
+getFuchsiaHandleSymbols(QualType QT, SVal Arg, ProgramStateRef State) {
   int PtrToHandleLevel = 0;
   while (QT->isAnyPointerType() || QT->isReferenceType()) {
 ++PtrToHandleLevel;
 QT = QT->getPointeeType();
   }
+  if (QT->isStructureType()) {
+// If we see a structure, see if there is any handle referenced by the
+// structure.
+FuchsiaHandleSymbolVisitor Visitor(State);
+State->scanReachableSymbols(Arg, Visitor);
+return Visitor.GetSymbols();
+  }
   if (const auto *HandleType = QT->getAs()) {
 if (HandleType->getDecl()->getName() != HandleTypeName)
-  return nullptr;
-if (PtrToHandleLevel > 1) {
+  return {};
+if (PtrToHandleLevel > 1)
   // Not supported yet.
-  return nullptr;
-}
+  return {};
 
 if (PtrToHandleLevel == 0) {
-  return Arg.getAsSymbol();
+  SymbolRef Sym = Arg.getAsSymbol();
+  if (Sym) {
+return {Sym};
+  } else {
+return {};
+  }
 } else {
   assert(PtrToHandleLevel == 1);
-  if (Optional ArgLoc = Arg.getAs())
-return State->getSVal(*ArgLoc).getAsSymbol();
+  if (Optional ArgLoc = Arg.getAs()) {
+SymbolRef Sym = State->getSVal(*ArgLoc).getAsSymbol();
+if (Sym) {
+  return {Sym};
+} else {
+  return {};
+}
+  }
 }
   }
-  return nullptr;
+  return {};
 }
 
 void FuchsiaHandleChecker::checkPreCall(const CallEvent &Call,
@@ -273,30 +311,31 @@ void FuchsiaHandleChecker::checkPreCall(const CallEvent 
&Call,
 if (Arg >= FuncDecl->getNumParams())
   break;
 const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
-SymbolRef Handle =
-getFuchsiaHandleSymbol(PVD->getType(), Call.getArgSVal(Arg), State);
-if (!Handle)
-  continue;
+SmallVector Handles =
+getFuchsiaHandleSymbols(PVD->getType(), Call.getArgSVal(Arg), State);
 
 // Handled in checkPostCall.
 if (hasFuchsiaAttr(PVD) ||
 hasFuchsiaAttr(PVD))
   continue;
 
-const HandleState *HState = State->get(Handle);
-if (!HState || HState->isEscaped())
-  continue;
+for (SymbolRef Handle : Handles) {
+  const HandleState *HState = State->get(Handle);
+  

[llvm-branch-commits] [llvm] 53c5fdd - [llvm-elfabi] Emit ELF header and string table sections

2020-11-23 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-11-23T11:31:57-08:00
New Revision: 53c5fdd59a5cf7fbb4dcb7a7e84c9c4a40d32a84

URL: 
https://github.com/llvm/llvm-project/commit/53c5fdd59a5cf7fbb4dcb7a7e84c9c4a40d32a84
DIFF: 
https://github.com/llvm/llvm-project/commit/53c5fdd59a5cf7fbb4dcb7a7e84c9c4a40d32a84.diff

LOG: [llvm-elfabi] Emit ELF header and string table sections

This change serves to create the initial framework for outputting ELF
files from llvm-elfabi.

Differential Revision: https://reviews.llvm.org/D61767

Added: 
llvm/test/tools/llvm-elfabi/fail-file-write-windows.test
llvm/test/tools/llvm-elfabi/fail-file-write.test
llvm/test/tools/llvm-elfabi/output-target-error.test
llvm/test/tools/llvm-elfabi/write-stub.test

Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 




diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index 1ffd9a614eec..cbb9420cb666 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -23,9 +23,21 @@ class MemoryBuffer;
 
 namespace elfabi {
 
+enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
+
 /// Attempt to read a binary ELF file from a MemoryBuffer.
 Expected> readELFFile(MemoryBufferRef Buf);
 
+/// Attempt to write a binary ELF stub.
+/// This function determines appropriate ELFType using the passed ELFTarget and
+/// then writes a binary ELF stub to a specified file path.
+///
+/// @param FilePath File path for writing the ELF binary.
+/// @param Stub Source ELFStub to generate a binary ELF stub from.
+/// @param OutputFormat Target ELFType to write binary as.
+Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
+  ELFTarget OutputFormat);
+
 } // end namespace elfabi
 } // end namespace llvm
 

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index cc9a8743cd08..76c637b88827 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -8,11 +8,14 @@
 
 #include "llvm/InterfaceStub/ELFObjHandler.h"
 #include "llvm/InterfaceStub/ELFStub.h"
+#include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 using llvm::MemoryBufferRef;
@@ -38,6 +41,158 @@ struct DynamicEntries {
   Optional GnuHash;
 };
 
+/// This initializes an ELF file header with information specific to a binary
+/// dynamic shared object.
+/// Offsets, indexes, links, etc. for section and program headers are just
+/// zero-initialized as they will be updated elsewhere.
+///
+/// @param ElfHeader Target ELFT::Ehdr to populate.
+/// @param Machine Target architecture (e_machine from ELF specifications).
+template 
+static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine) {
+  memset(&ElfHeader, 0, sizeof(ElfHeader));
+  // ELF identification.
+  ElfHeader.e_ident[EI_MAG0] = ElfMagic[EI_MAG0];
+  ElfHeader.e_ident[EI_MAG1] = ElfMagic[EI_MAG1];
+  ElfHeader.e_ident[EI_MAG2] = ElfMagic[EI_MAG2];
+  ElfHeader.e_ident[EI_MAG3] = ElfMagic[EI_MAG3];
+  ElfHeader.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
+  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+  ElfHeader.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
+  ElfHeader.e_ident[EI_VERSION] = EV_CURRENT;
+  ElfHeader.e_ident[EI_OSABI] = ELFOSABI_NONE;
+
+  // Remainder of ELF header.
+  ElfHeader.e_type = ET_DYN;
+  ElfHeader.e_machine = Machine;
+  ElfHeader.e_version = EV_CURRENT;
+  ElfHeader.e_ehsize = sizeof(typename ELFT::Ehdr);
+  ElfHeader.e_phentsize = sizeof(typename ELFT::Phdr);
+  ElfHeader.e_shentsize = sizeof(typename ELFT::Shdr);
+}
+
+namespace {
+template  struct OutputSection {
+  using Elf_Shdr = typename ELFT::Shdr;
+  std::string Name;
+  Elf_Shdr Shdr;
+  uint64_t Addr;
+  uint64_t Offset;
+  uint64_t Size;
+  uint64_t Align;
+  uint32_t Index;
+  bool NoBits = true;
+};
+
+template 
+struct ContentSection : public OutputSection {
+  T Content;
+  ContentSection() { this->NoBits = false; }
+};
+
+// This class just wraps StringTableBuilder for the purpose of adding a
+// default constructor.
+class ELFStringTableBuilder : public StringTableBuilder {
+public:
+  ELFStringTableBuilder() : StringTableBuilder(StringTableBuilder::ELF) {}
+};
+
+template  class ELFStubBuilder {
+public:
+  using Elf_Ehdr = typename ELFT::Ehdr;
+  using Elf_Shdr = typename ELFT::Shdr;
+  using Elf_Phdr = typename ELFT::Phdr;
+  using Elf_Sym = typename ELFT::Sym;
+  usin

[llvm-branch-commits] [llvm] ae736d2 - Revert "[llvm-elfabi] Emit ELF header and string table sections"

2020-11-23 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-11-23T11:58:51-08:00
New Revision: ae736d295763b05a2047fb64cec821c3d4a63d4d

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

LOG: Revert "[llvm-elfabi] Emit ELF header and string table sections"

This reverts commit 53c5fdd59a5cf7fbb4dcb7a7e84c9c4a40d32a84.

Reason of revert: Some builders failed to build with ld.

Added: 


Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 
llvm/test/tools/llvm-elfabi/fail-file-write-windows.test
llvm/test/tools/llvm-elfabi/fail-file-write.test
llvm/test/tools/llvm-elfabi/output-target-error.test
llvm/test/tools/llvm-elfabi/write-stub.test



diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index cbb9420cb666..1ffd9a614eec 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -23,21 +23,9 @@ class MemoryBuffer;
 
 namespace elfabi {
 
-enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
-
 /// Attempt to read a binary ELF file from a MemoryBuffer.
 Expected> readELFFile(MemoryBufferRef Buf);
 
-/// Attempt to write a binary ELF stub.
-/// This function determines appropriate ELFType using the passed ELFTarget and
-/// then writes a binary ELF stub to a specified file path.
-///
-/// @param FilePath File path for writing the ELF binary.
-/// @param Stub Source ELFStub to generate a binary ELF stub from.
-/// @param OutputFormat Target ELFType to write binary as.
-Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
-  ELFTarget OutputFormat);
-
 } // end namespace elfabi
 } // end namespace llvm
 

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index 76c637b88827..cc9a8743cd08 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -8,14 +8,11 @@
 
 #include "llvm/InterfaceStub/ELFObjHandler.h"
 #include "llvm/InterfaceStub/ELFStub.h"
-#include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 using llvm::MemoryBufferRef;
@@ -41,158 +38,6 @@ struct DynamicEntries {
   Optional GnuHash;
 };
 
-/// This initializes an ELF file header with information specific to a binary
-/// dynamic shared object.
-/// Offsets, indexes, links, etc. for section and program headers are just
-/// zero-initialized as they will be updated elsewhere.
-///
-/// @param ElfHeader Target ELFT::Ehdr to populate.
-/// @param Machine Target architecture (e_machine from ELF specifications).
-template 
-static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine) {
-  memset(&ElfHeader, 0, sizeof(ElfHeader));
-  // ELF identification.
-  ElfHeader.e_ident[EI_MAG0] = ElfMagic[EI_MAG0];
-  ElfHeader.e_ident[EI_MAG1] = ElfMagic[EI_MAG1];
-  ElfHeader.e_ident[EI_MAG2] = ElfMagic[EI_MAG2];
-  ElfHeader.e_ident[EI_MAG3] = ElfMagic[EI_MAG3];
-  ElfHeader.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
-  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
-  ElfHeader.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
-  ElfHeader.e_ident[EI_VERSION] = EV_CURRENT;
-  ElfHeader.e_ident[EI_OSABI] = ELFOSABI_NONE;
-
-  // Remainder of ELF header.
-  ElfHeader.e_type = ET_DYN;
-  ElfHeader.e_machine = Machine;
-  ElfHeader.e_version = EV_CURRENT;
-  ElfHeader.e_ehsize = sizeof(typename ELFT::Ehdr);
-  ElfHeader.e_phentsize = sizeof(typename ELFT::Phdr);
-  ElfHeader.e_shentsize = sizeof(typename ELFT::Shdr);
-}
-
-namespace {
-template  struct OutputSection {
-  using Elf_Shdr = typename ELFT::Shdr;
-  std::string Name;
-  Elf_Shdr Shdr;
-  uint64_t Addr;
-  uint64_t Offset;
-  uint64_t Size;
-  uint64_t Align;
-  uint32_t Index;
-  bool NoBits = true;
-};
-
-template 
-struct ContentSection : public OutputSection {
-  T Content;
-  ContentSection() { this->NoBits = false; }
-};
-
-// This class just wraps StringTableBuilder for the purpose of adding a
-// default constructor.
-class ELFStringTableBuilder : public StringTableBuilder {
-public:
-  ELFStringTableBuilder() : StringTableBuilder(StringTableBuilder::ELF) {}
-};
-
-template  class ELFStubBuilder {
-public:
-  using Elf_Ehdr = typename ELFT::Ehdr;
-  using Elf_Shdr = typename ELFT::Shdr;
-  using Elf_Phdr = typename ELFT::Phdr;
-  using Elf_Sym = typename ELFT::Sym;
-  using Elf_Addr = typename

[llvm-branch-commits] [llvm] cf43308 - [llvm-elfabi] Emit ELF header and string table sections

2020-11-23 Thread Haowei Wu via llvm-branch-commits

Author: Haowei Wu
Date: 2020-11-23T12:18:58-08:00
New Revision: cf4330871844f58075023a9ace9ba0728cf48d57

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

LOG: [llvm-elfabi] Emit ELF header and string table sections

This change serves to create the initial framework for outputting ELF
files from llvm-elfabi.

Differential Revision: https://reviews.llvm.org/D61767

Added: 
llvm/test/tools/llvm-elfabi/fail-file-write-windows.test
llvm/test/tools/llvm-elfabi/fail-file-write.test
llvm/test/tools/llvm-elfabi/output-target-error.test
llvm/test/tools/llvm-elfabi/write-stub.test

Modified: 
llvm/include/llvm/InterfaceStub/ELFObjHandler.h
llvm/lib/InterfaceStub/CMakeLists.txt
llvm/lib/InterfaceStub/ELFObjHandler.cpp
llvm/tools/llvm-elfabi/llvm-elfabi.cpp

Removed: 




diff  --git a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h 
b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
index 1ffd9a614eec..cbb9420cb666 100644
--- a/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/llvm/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -23,9 +23,21 @@ class MemoryBuffer;
 
 namespace elfabi {
 
+enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
+
 /// Attempt to read a binary ELF file from a MemoryBuffer.
 Expected> readELFFile(MemoryBufferRef Buf);
 
+/// Attempt to write a binary ELF stub.
+/// This function determines appropriate ELFType using the passed ELFTarget and
+/// then writes a binary ELF stub to a specified file path.
+///
+/// @param FilePath File path for writing the ELF binary.
+/// @param Stub Source ELFStub to generate a binary ELF stub from.
+/// @param OutputFormat Target ELFType to write binary as.
+Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
+  ELFTarget OutputFormat);
+
 } // end namespace elfabi
 } // end namespace llvm
 

diff  --git a/llvm/lib/InterfaceStub/CMakeLists.txt 
b/llvm/lib/InterfaceStub/CMakeLists.txt
index 4aacebf16cf9..17801999c485 100644
--- a/llvm/lib/InterfaceStub/CMakeLists.txt
+++ b/llvm/lib/InterfaceStub/CMakeLists.txt
@@ -4,6 +4,7 @@ add_llvm_component_library(LLVMInterfaceStub
   TBEHandler.cpp
 
   LINK_COMPONENTS
+  MC
   Object
   Support
 )

diff  --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp 
b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
index cc9a8743cd08..76c637b88827 100644
--- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp
+++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp
@@ -8,11 +8,14 @@
 
 #include "llvm/InterfaceStub/ELFObjHandler.h"
 #include "llvm/InterfaceStub/ELFStub.h"
+#include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ELFTypes.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 using llvm::MemoryBufferRef;
@@ -38,6 +41,158 @@ struct DynamicEntries {
   Optional GnuHash;
 };
 
+/// This initializes an ELF file header with information specific to a binary
+/// dynamic shared object.
+/// Offsets, indexes, links, etc. for section and program headers are just
+/// zero-initialized as they will be updated elsewhere.
+///
+/// @param ElfHeader Target ELFT::Ehdr to populate.
+/// @param Machine Target architecture (e_machine from ELF specifications).
+template 
+static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine) {
+  memset(&ElfHeader, 0, sizeof(ElfHeader));
+  // ELF identification.
+  ElfHeader.e_ident[EI_MAG0] = ElfMagic[EI_MAG0];
+  ElfHeader.e_ident[EI_MAG1] = ElfMagic[EI_MAG1];
+  ElfHeader.e_ident[EI_MAG2] = ElfMagic[EI_MAG2];
+  ElfHeader.e_ident[EI_MAG3] = ElfMagic[EI_MAG3];
+  ElfHeader.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
+  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+  ElfHeader.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
+  ElfHeader.e_ident[EI_VERSION] = EV_CURRENT;
+  ElfHeader.e_ident[EI_OSABI] = ELFOSABI_NONE;
+
+  // Remainder of ELF header.
+  ElfHeader.e_type = ET_DYN;
+  ElfHeader.e_machine = Machine;
+  ElfHeader.e_version = EV_CURRENT;
+  ElfHeader.e_ehsize = sizeof(typename ELFT::Ehdr);
+  ElfHeader.e_phentsize = sizeof(typename ELFT::Phdr);
+  ElfHeader.e_shentsize = sizeof(typename ELFT::Shdr);
+}
+
+namespace {
+template  struct OutputSection {
+  using Elf_Shdr = typename ELFT::Shdr;
+  std::string Name;
+  Elf_Shdr Shdr;
+  uint64_t Addr;
+  uint64_t Offset;
+  uint64_t Size;
+  uint64_t Align;
+  uint32_t Index;
+  bool NoBits = true;
+};
+
+template 
+struct ContentSection : public OutputSection {
+  T Content;
+  ContentSection() { this->NoBits = false; }
+};
+
+// This class just wraps StringTableBuilder for the purpose of ad

[llvm-branch-commits] [clang] 3ce78f5 - [analyzer] Ignore annotations if func is inlined.

2020-12-07 Thread Haowei Wu via llvm-branch-commits

Author: Yu Shan
Date: 2020-12-07T11:28:11-08:00
New Revision: 3ce78f54edcfc881377a9e567715caf2f0be2abc

URL: 
https://github.com/llvm/llvm-project/commit/3ce78f54edcfc881377a9e567715caf2f0be2abc
DIFF: 
https://github.com/llvm/llvm-project/commit/3ce78f54edcfc881377a9e567715caf2f0be2abc.diff

LOG: [analyzer] Ignore annotations if func is inlined.

When we annotating a function header so that it could be used by other
TU, we also need to make sure the function is parsed correctly within
the same TU. So if we can find the function's implementation,
ignore the annotations, otherwise, false positive would occur.
Move the escape by value case to post call and do not escape the handle
if the function is inlined and we have analyzed the handle.

Differential Revision: https://reviews.llvm.org/D91902

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
clang/test/Analysis/fuchsia_handle.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
index d4901eb0abbb..c246a8db3067 100644
--- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -331,11 +331,6 @@ void FuchsiaHandleChecker::checkPreCall(const CallEvent 
&Call,
   return;
 }
   }
-  if (!hasFuchsiaAttr(PVD) &&
-  PVD->getType()->isIntegerType()) {
-// Working around integer by-value escapes.
-State = State->set(Handle, HandleState::getEscaped());
-  }
 }
   }
   C.addTransition(State);
@@ -347,6 +342,10 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent 
&Call,
   if (!FuncDecl)
 return;
 
+  // If we analyzed the function body, then ignore the annotations.
+  if (C.wasInlined)
+return;
+
   ProgramStateRef State = C.getState();
 
   std::vector> Notes;
@@ -417,6 +416,14 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent 
&Call,
 });
 State = State->set(
 Handle, HandleState::getMaybeAllocated(ResultSymbol));
+  } else if (!hasFuchsiaAttr(PVD) &&
+ PVD->getType()->isIntegerType()) {
+// Working around integer by-value escapes.
+// The by-value escape would not be captured in checkPointerEscape.
+// If the function was not analyzed (otherwise wasInlined should be
+// true) and there is no annotation on the handle, we assume the handle
+// is escaped.
+State = State->set(Handle, HandleState::getEscaped());
   }
 }
   }

diff  --git a/clang/test/Analysis/fuchsia_handle.cpp 
b/clang/test/Analysis/fuchsia_handle.cpp
index 911ab7adaaa9..99f0449a4902 100644
--- a/clang/test/Analysis/fuchsia_handle.cpp
+++ b/clang/test/Analysis/fuchsia_handle.cpp
@@ -315,6 +315,45 @@ void checkHandlePtrInStructureLeak() {
   // expected-note@-1 {{Potential leak of handle}}
 }
 
+// Assume this function's declaration that has the release annotation is in one
+// header file while its implementation is in another file. We have to annotate
+// the declaration because it might be used outside the TU.
+// We also want to make sure it is okay to call the function within the same 
TU.
+zx_status_t test_release_handle(zx_handle_t handle ZX_HANDLE_RELEASE) {
+  return zx_handle_close(handle);
+}
+
+void checkReleaseImplementedFunc() {
+  zx_handle_t a, b;
+  zx_channel_create(0, &a, &b);
+  zx_handle_close(a);
+  test_release_handle(b);
+}
+
+void use_handle(zx_handle_t handle) {
+  // Do nothing.
+}
+
+void test_call_by_value() {
+  zx_handle_t a, b;
+  zx_channel_create(0, &a, &b);
+  zx_handle_close(a);
+  use_handle(b);
+  zx_handle_close(b);
+}
+
+void test_call_by_value_leak() {
+  zx_handle_t a, b;
+  zx_channel_create(0, &a, &b); // expected-note {{Handle allocated through 
3rd parameter}}
+  zx_handle_close(a);
+  // Here we are passing handle b as integer value to a function that could be
+  // analyzed by the analyzer, thus the handle should not be considered 
escaped.
+  // After the function 'use_handle', handle b is still tracked and should be
+  // reported leaked.
+  use_handle(b);
+} // expected-warning {{Potential leak of handle}}
+// expected-note@-1 {{Potential leak of handle}}
+
 // RAII
 
 template 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits