diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1531,6 +1531,22 @@ NT_GNU_PROPERTY_TYPE_0 = 5, }; +// Android note types. +enum { + NT_ANDROID_TYPE_IDENT = 1, + NT_ANDROID_TYPE_KUSER = 3, + NT_ANDROID_TYPE_MEMTAG = 4, +}; + +enum { + NT_MEMTAG_LEVEL_NONE = 0, + NT_MEMTAG_LEVEL_ASYNC = 1, + NT_MEMTAG_LEVEL_SYNC = 2, + NT_MEMTAG_LEVEL_MASK = 3, + NT_MEMTAG_HEAP = 4, + NT_MEMTAG_STACK = 8, +}; + // Property types used in GNU_PROPERTY_TYPE_0 notes. enum : unsigned { GNU_PROPERTY_STACK_SIZE = 1, diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -175,6 +175,10 @@ ECase(NT_AMD_PAL_METADATA); // AMDGPU specific notes. (Code Object V3) ECase(NT_AMDGPU_METADATA); + // Android specific notes. + ECase(NT_ANDROID_TYPE_IDENT); + ECase(NT_ANDROID_TYPE_KUSER); + ECase(NT_ANDROID_TYPE_MEMTAG); #undef ECase IO.enumFallback(Value); } diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-async.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-async.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-async.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: ASYNC +# GNU-NEXT: Heap: Enabled +# GNU-NEXT: Stack: Enabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: ASYNC +# LLVM-NEXT: Heap: Enabled +# LLVM-NEXT: Stack: Enabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 0d000000 diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-sync.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-sync.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-all-sync.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: SYNC +# GNU-NEXT: Heap: Enabled +# GNU-NEXT: Stack: Enabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: SYNC +# LLVM-NEXT: Heap: Enabled +# LLVM-NEXT: Stack: Enabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 0e000000 diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-async.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-async.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-async.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: ASYNC +# GNU-NEXT: Heap: Enabled +# GNU-NEXT: Stack: Disabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: ASYNC +# LLVM-NEXT: Heap: Enabled +# LLVM-NEXT: Stack: Disabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 05000000 diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-sync.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-sync.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-heap-sync.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: SYNC +# GNU-NEXT: Heap: Enabled +# GNU-NEXT: Stack: Disabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: SYNC +# LLVM-NEXT: Heap: Enabled +# LLVM-NEXT: Stack: Disabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 06000000 diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-async.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-async.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-async.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: ASYNC +# GNU-NEXT: Heap: Disabled +# GNU-NEXT: Stack: Enabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: ASYNC +# LLVM-NEXT: Heap: Disabled +# LLVM-NEXT: Stack: Enabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 09000000 diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-sync.test b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-sync.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/memtag/aarch64-note-memtag-stack-sync.test @@ -0,0 +1,39 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM + +# GNU: Displaying notes found in: .note.android.memtag +# GNU-NEXT: Owner Data size Description +# GNU-NEXT: Android 0x00000004 NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# GNU-NEXT: Tagging Mode: SYNC +# GNU-NEXT: Heap: Disabled +# GNU-NEXT: Stack: Enabled + +# LLVM: Notes [ +# LLVM-NEXT: NoteSection { +# LLVM-NEXT: Name: .note.android.memtag +# LLVM-NEXT: Offset: 0x40 +# LLVM-NEXT: Size: 0x18 +# LLVM-NEXT: Note { +# LLVM-NEXT: Owner: Android +# LLVM-NEXT: Data size: 0x4 +# LLVM-NEXT: Type: NT_ANDROID_TYPE_MEMTAG (Android memory tagging information) +# LLVM-NEXT: Tagging Mode: SYNC +# LLVM-NEXT: Heap: Disabled +# LLVM-NEXT: Stack: Enabled +# LLVM-NEXT: } +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .note.android.memtag + Type: SHT_NOTE + Notes: + - Name: Android + Type: NT_ANDROID_TYPE_MEMTAG + Desc: 0a000000 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5040,6 +5040,44 @@ return true; } +template +static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType, + ArrayRef Desc) { + // Return true if we were able to pretty-print the note, false otherwise. + switch (NoteType) { + default: + return false; + case ELF::NT_ANDROID_TYPE_MEMTAG: + if (Desc.empty()) + return false; + + OS << " Tagging Mode: "; + switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) { + case NT_MEMTAG_LEVEL_NONE: + OS << "NONE\n"; + break; + case NT_MEMTAG_LEVEL_ASYNC: + OS << "ASYNC\n"; + break; + case NT_MEMTAG_LEVEL_SYNC: + OS << "SYNC\n"; + break; + default: + OS << "Unknown (" << Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + << ")\n"; + break; + } + + OS << " Heap: " + << ((Desc[0] & NT_MEMTAG_HEAP) ? "Enabled\n" : "Disabled\n"); + OS << " Stack: " + << ((Desc[0] & NT_MEMTAG_STACK) ? "Enabled\n" : "Disabled\n"); + break; + } + OS << '\n'; + return true; +} + template static bool printLLVMOMPOFFLOADNote(raw_ostream &OS, uint32_t NoteType, ArrayRef Desc) { @@ -5399,6 +5437,13 @@ "NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION (producing toolchain version)"}, }; +const NoteType AndroidNoteTypes[] = { + {ELF::NT_ANDROID_TYPE_IDENT, "NT_ANDROID_TYPE_IDENT"}, + {ELF::NT_ANDROID_TYPE_KUSER, "NT_ANDROID_TYPE_KUSER"}, + {ELF::NT_ANDROID_TYPE_MEMTAG, + "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"}, +}; + const NoteType CoreNoteTypes[] = { {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"}, {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"}, @@ -5507,6 +5552,8 @@ return FindNote(AMDGPUNoteTypes); if (Name == "LLVMOMPOFFLOAD") return FindNote(LLVMOMPOFFLOADNoteTypes); + if (Name == "Android") + return FindNote(AndroidNoteTypes); if (ELFType == ELF::ET_CORE) return FindNote(CoreNoteTypes); @@ -5657,6 +5704,9 @@ return NoteOrErr.takeError(); } } + } else if (Name == "Android") { + if (printAndroidNote(OS, Type, Descriptor)) + return Error::success(); } if (!Descriptor.empty()) { OS << " description data:"; @@ -7022,6 +7072,44 @@ return true; } +template +static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, + ScopedPrinter &W) { + // Return true if we were able to pretty-print the note, false otherwise. + switch (NoteType) { + default: + return false; + case ELF::NT_ANDROID_TYPE_MEMTAG: + if (Desc.empty()) + return false; + + std::string ModeString; + switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) { + case NT_MEMTAG_LEVEL_NONE: + ModeString = "NONE"; + break; + case NT_MEMTAG_LEVEL_ASYNC: + ModeString = "ASYNC"; + break; + case NT_MEMTAG_LEVEL_SYNC: + ModeString = "SYNC"; + break; + default: + ModeString = + ("Unknown (" + Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + ")") + .str(); + break; + } + W.printString("Tagging Mode", ModeString); + + W.printString("Heap", (Desc[0] & NT_MEMTAG_HEAP) ? "Enabled" : "Disabled"); + W.printString("Stack", + (Desc[0] & NT_MEMTAG_STACK) ? "Enabled" : "Disabled"); + break; + } + return true; +} + template static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, @@ -7124,6 +7212,9 @@ return N.takeError(); } } + } else if (Name == "Android") { + if (printAndroidNoteLLVMStyle(Type, Descriptor, W)) + return Error::success(); } if (!Descriptor.empty()) { W.printBinaryBlock("Description data", Descriptor);