1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[llvm-readobj] Add support for decoding FreeBSD ELF notes

The current support only printed coredump notes, but most binaries also
contain notes. This change adds names for four FreeBSD-specific notes and
pretty-prints three of them:

NT_FREEBSD_ABI_TAG:
This note holds a 32-bit (decimal) integer containing the value of the
__FreeBSD_version macro, which is defined in crt1.o and will hold a value
such as 1300076 for a binary build on a FreeBSD 13 system.

NT_FREEBSD_ARCH_TAG:
A string containing the value of the build-time MACHINE_ARCH

NT_FREEBSD_FEATURE_CTL: A 32-bit flag that indicates to the kernel that
the binary wants certain bevahiour. Examples include setting
NT_FREEBSD_FCTL_ASLR_DISABLE which tells the kernel to disable ASLR.

After this change llvm-readobj also no longer decodes coredump-only
FreeBSD notes in non-coredump files. I've also converted the
note-freebsd.s test to use yaml2obj instead of llvm-mc.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D74393
This commit is contained in:
Alex Richardson 2021-02-09 16:46:29 +00:00
parent 458893076b
commit 9d4a31c573
6 changed files with 382 additions and 98 deletions

View File

@ -1516,6 +1516,24 @@ enum : unsigned {
GNU_PROPERTY_X86_FEATURE_2_XSAVEC = 1 << 9,
};
// FreeBSD note types.
enum {
NT_FREEBSD_ABI_TAG = 1,
NT_FREEBSD_NOINIT_TAG = 2,
NT_FREEBSD_ARCH_TAG = 3,
NT_FREEBSD_FEATURE_CTL = 4,
};
// NT_FREEBSD_FEATURE_CTL values (see FreeBSD's sys/sys/elf_common.h).
enum {
NT_FREEBSD_FCTL_ASLR_DISABLE = 0x00000001,
NT_FREEBSD_FCTL_PROTMAX_DISABLE = 0x00000002,
NT_FREEBSD_FCTL_STKGAP_DISABLE = 0x00000004,
NT_FREEBSD_FCTL_WXNEEDED = 0x00000008,
NT_FREEBSD_FCTL_LA48 = 0x00000010,
NT_FREEBSD_FCTL_ASG_DISABLE = 0x00000020,
};
// FreeBSD core note types.
enum {
NT_FREEBSD_THRMISC = 7,

View File

@ -138,6 +138,11 @@ void ScalarEnumerationTraits<ELFYAML::ELF_NT>::enumeration(
ECase(NT_GNU_BUILD_ID);
ECase(NT_GNU_GOLD_VERSION);
ECase(NT_GNU_PROPERTY_TYPE_0);
// FreeBSD note types.
ECase(NT_FREEBSD_ABI_TAG);
ECase(NT_FREEBSD_NOINIT_TAG);
ECase(NT_FREEBSD_ARCH_TAG);
ECase(NT_FREEBSD_FEATURE_CTL);
// FreeBSD core note types.
ECase(NT_FREEBSD_THRMISC);
ECase(NT_FREEBSD_PROCSTAT_PROC);

View File

@ -0,0 +1,145 @@
## Test that note values are interpreted correctly for FreeBSD core files.
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-readelf --notes %t.o | FileCheck %s --check-prefix=GNU --strict-whitespace
# RUN: llvm-readobj --notes %t.o | FileCheck %s --check-prefix=LLVM --strict-whitespace
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_CORE
Sections:
- Name: .note.foo
Type: SHT_NOTE
Notes:
- Name: FreeBSD
Type: NT_FREEBSD_THRMISC
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_PROC
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_FILES
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_VMMAP
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_GROUPS
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_UMASK
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_RLIMIT
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_OSREL
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_PSSTRINGS
- Name: FreeBSD
Type: NT_FREEBSD_PROCSTAT_AUXV
- Name: FreeBSD
Type: 0x12345
- Name: .note.bar
Type: SHT_NOTE
Notes:
- Name: FreeBSD
Desc: 'aabbccddeeff'
Type: NT_PRPSINFO
ProgramHeaders:
- Type: PT_NOTE
FirstSec: .note.foo
LastSec: .note.foo
- Type: PT_NOTE
FirstSec: .note.bar
LastSec: .note.bar
# GNU: Displaying notes found at file offset 0x000000b0 with length 0x000000dc:
# GNU-NEXT: Owner Data size Description
# GNU-NEXT: FreeBSD 0x00000000 NT_THRMISC (thrmisc structure)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_PROC (proc data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_FILES (files data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_VMMAP (vmmap data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_GROUPS (groups data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_UMASK (umask data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_RLIMIT (rlimit data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_OSREL (osreldate data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_PSSTRINGS (ps_strings data)
# GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_AUXV (auxv data)
# GNU-NEXT: FreeBSD 0x00000000 Unknown note type: (0x00012345)
# GNU-EMPTY:
# GNU-NEXT: Displaying notes found at file offset 0x0000018c with length 0x0000001c:
# GNU-NEXT: Owner Data size Description
# GNU-NEXT: FreeBSD 0x00000006 NT_PRPSINFO (prpsinfo structure)
# GNU-NEXT: description data: aa bb cc dd ee ff
# GNU-EMPTY:
# LLVM: Notes [
# LLVM-NEXT: NoteSection {
# LLVM-NEXT: Name: <?>
# LLVM-NEXT: Offset: 0xB0
# LLVM-NEXT: Size: 0xDC
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_THRMISC (thrmisc structure)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_PROC (proc data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_FILES (files data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_VMMAP (vmmap data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_GROUPS (groups data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_UMASK (umask data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_RLIMIT (rlimit data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_OSREL (osreldate data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_PSSTRINGS (ps_strings data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: NT_PROCSTAT_AUXV (auxv data)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x0
# LLVM-NEXT: Type: Unknown (0x00012345)
# LLVM-NEXT: }
# LLVM-NEXT: }
# LLVM-NEXT: NoteSection {
# LLVM-NEXT: Name: <?>
# LLVM-NEXT: Offset: 0x18C
# LLVM-NEXT: Size: 0x1C
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x6
# LLVM-NEXT: Type: NT_PRPSINFO (prpsinfo structure)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: AABBCCDD EEFF |......|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: }
# LLVM-NEXT: ]

View File

@ -1,89 +0,0 @@
// REQUIRES: x86-registered-target
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
// RUN: llvm-readobj --notes %t.o | FileCheck %s --check-prefix=LLVM
// RUN: llvm-readelf --notes %t.o | FileCheck %s --check-prefix=GNU
// GNU: Displaying notes found in: .note.foo
// GNU-NEXT: Owner Data size Description
// GNU-NEXT: FreeBSD 0x00000000 NT_THRMISC (thrmisc structure)
// GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_PROC (proc data)
// GNU-EMPTY:
// GNU-NEXT: Displaying notes found in: .note.bar
// GNU-NEXT: Owner Data size Description
// GNU-NEXT: FreeBSD 0x00000000 NT_PROCSTAT_FILES (files data)
// GNU-EMPTY:
// GNU-NEXT: Displaying notes found in: .note.baz
// GNU-NEXT: Owner Data size Description
// GNU-NEXT: FreeBSD 0x0000001c Unknown note type: (0x00000003)
// GNU-NEXT: description data: 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74 00 00
// GNU-EMPTY:
// LLVM: Notes [
// LLVM-NEXT: NoteSection {
// LLVM-NEXT: Name: .note.foo
// LLVM-NEXT: Offset:
// LLVM-NEXT: Size:
// LLVM-NEXT: Note {
// LLVM-NEXT: Owner: FreeBSD
// LLVM-NEXT: Data size: 0x0
// LLVM-NEXT: Type: NT_THRMISC (thrmisc structure)
// LLVM-NEXT: }
// LLVM-NEXT: Note {
// LLVM-NEXT: Owner: FreeBSD
// LLVM-NEXT: Data size: 0x0
// LLVM-NEXT: Type: NT_PROCSTAT_PROC (proc data)
// LLVM-NEXT: }
// LLVM-NEXT: }
// LLVM-NEXT: NoteSection {
// LLVM-NEXT: Name: .note.bar
// LLVM-NEXT: Offset: 0x68
// LLVM-NEXT: Size: 0x14
// LLVM-NEXT: Note {
// LLVM-NEXT: Owner: FreeBSD
// LLVM-NEXT: Data size: 0x0
// LLVM-NEXT: Type: NT_PROCSTAT_FILES (files data)
// LLVM-NEXT: }
// LLVM-NEXT: }
// LLVM-NEXT: NoteSection {
// LLVM-NEXT: Name: .note.baz
// LLVM-NEXT: Offset: 0x7C
// LLVM-NEXT: Size: 0x30
// LLVM-NEXT: Note {
// LLVM-NEXT: Owner: FreeBSD
// LLVM-NEXT: Data size: 0x1C
// LLVM-NEXT: Type: Unknown (0x00000003)
// LLVM-NEXT: Description data (
// LLVM-NEXT: 0000: 4C6F7265 6D206970 73756D20 646F6C6F |Lorem ipsum dolo|
// LLVM-NEXT: 0010: 72207369 7420616D 65740000 |r sit amet..|
// LLVM-NEXT: )
// LLVM-NEXT: }
// LLVM-NEXT: }
// LLVM-NEXT: ]
.section ".note.foo", "a"
.align 4
.long 8 /* namesz */
.long 0 /* descsz */
.long 7 /* type = NT_FREEBSD_THRMISC */
.asciz "FreeBSD"
.long 8 /* namesz */
.long 0 /* descsz */
.long 8 /* type = NT_FREEBSD_PROC */
.asciz "FreeBSD"
.section ".note.bar", "a"
.align 4
.long 8 /* namesz */
.long 0 /* descsz */
.long 9 /* type = NT_FREEBSD_FILES */
.asciz "FreeBSD"
.section ".note.baz", "a"
.align 4
.long 8 /* namesz */
.long end - begin /* descsz */
.long 3 /* type */
.asciz "FreeBSD"
begin:
.asciz "Lorem ipsum dolor sit amet"
.align 4
end:

View File

@ -0,0 +1,128 @@
## Test that note values are interpreted correctly for FreeBSD executables.
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-readelf --notes %t.o | FileCheck %s --check-prefixes=GNU --strict-whitespace
# RUN: llvm-readobj --notes %t.o | FileCheck %s --check-prefix=LLVM --strict-whitespace
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_RISCV
Sections:
- Name: .note.tag
Type: SHT_NOTE
AddressAlign: 0x0000000000000004
Notes:
- Name: FreeBSD
Desc: '6CD61300'
Type: NT_FREEBSD_ABI_TAG
- Name: FreeBSD
Desc: '6C' # Invalid data (should be 4 bytes)
Type: NT_FREEBSD_ABI_TAG
- Name: FreeBSD
Desc: '61617263683634'
Type: NT_FREEBSD_ARCH_TAG
- Name: FreeBSD
Desc: 'FFFFFFFF'
Type: NT_FREEBSD_FEATURE_CTL
- Name: FreeBSD
Desc: '00' # Invalid data (should be 4 bytes)
Type: NT_FREEBSD_FEATURE_CTL
- Name: FreeBSD
Desc: '00000000'
Type: NT_FREEBSD_NOINIT_TAG
- Name: FreeBSD
Desc: '616263646566'
Type: 0xabcdef
- Name: FreeBSD
Desc: '616263646566'
Type: NT_FREEBSD_PROCSTAT_RLIMIT # Only valid for coredumps.
# GNU: Displaying notes found in: .note.tag
# GNU-NEXT: Owner Data size Description
# GNU-NEXT: FreeBSD 0x00000004 NT_FREEBSD_ABI_TAG (ABI version tag)
# GNU-NEXT: ABI tag: 1300076
# GNU-NEXT: FreeBSD 0x00000001 NT_FREEBSD_ABI_TAG (ABI version tag)
# GNU-NEXT: description data: 6c
# GNU-NEXT: FreeBSD 0x00000007 NT_FREEBSD_ARCH_TAG (architecture tag)
# GNU-NEXT: Arch tag: aarch64
# GNU-NEXT: FreeBSD 0x00000004 NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)
# GNU-NEXT: Feature flags: ASLR_DISABLE PROTMAX_DISABLE STKGAP_DISABLE WXNEEDED LA48 ASG_DISABLE (0xFFFFFFFF)
# GNU-NEXT: FreeBSD 0x00000001 NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)
# GNU-NEXT: description data: 00
# GNU-NEXT: FreeBSD 0x00000004 NT_FREEBSD_NOINIT_TAG (no .init tag)
# GNU-NEXT: description data: 00 00 00 00
# GNU-NEXT: FreeBSD 0x00000006 Unknown note type: (0x00abcdef)
# GNU-NEXT: description data: 61 62 63 64 65 66
## NT_FREEBSD_PROCSTAT_RLIMIT is only a valid type for coredumps and should therefore not be decoded.
## Note: Binutils prints NT_PROCSTAT_RLIMIT, but this seems incorrect
# GNU-NEXT: FreeBSD 0x00000006 Unknown note type: (0x0000000d)
# GNU-NEXT: description data: 61 62 63 64 65 66
# GNU-EMPTY:
# LLVM: Notes [
# LLVM-NEXT: NoteSection {
# LLVM-NEXT: Name: .note.tag
# LLVM-NEXT: Offset: 0x40
# LLVM-NEXT: Size: 0xCC
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x4
# LLVM-NEXT: Type: NT_FREEBSD_ABI_TAG (ABI version tag)
# LLVM-NEXT: ABI tag: 1300076
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x1
# LLVM-NEXT: Type: NT_FREEBSD_ABI_TAG (ABI version tag)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: 6C |l|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x7
# LLVM-NEXT: Type: NT_FREEBSD_ARCH_TAG (architecture tag)
# LLVM-NEXT: Arch tag: aarch64
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x4
# LLVM-NEXT: Type: NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)
# LLVM-NEXT: Feature flags: ASLR_DISABLE PROTMAX_DISABLE STKGAP_DISABLE WXNEEDED LA48 ASG_DISABLE (0xFFFFFFFF)
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x1
# LLVM-NEXT: Type: NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: 00 |.|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x4
# LLVM-NEXT: Type: NT_FREEBSD_NOINIT_TAG (no .init tag)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: 00000000 |....|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x6
# LLVM-NEXT: Type: Unknown (0x00abcdef)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: 61626364 6566 |abcdef|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: Note {
# LLVM-NEXT: Owner: FreeBSD
# LLVM-NEXT: Data size: 0x6
# LLVM-NEXT: Type: Unknown (0x0000000d)
# LLVM-NEXT: Description data (
# LLVM-NEXT: 0000: 61626364 6566 |abcdef|
# LLVM-NEXT: )
# LLVM-NEXT: }
# LLVM-NEXT: }
# LLVM-NEXT:]

View File

@ -4908,6 +4908,53 @@ static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,
return true;
}
static const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = {
{"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE},
{"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE},
{"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE},
{"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED},
{"LA48", NT_FREEBSD_FCTL_LA48},
{"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE},
};
struct FreeBSDNote {
std::string Type;
std::string Value;
};
template <typename ELFT>
static Optional<FreeBSDNote>
getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) {
if (IsCore)
return None; // No pretty-printing yet.
switch (NoteType) {
case ELF::NT_FREEBSD_ABI_TAG:
if (Desc.size() != 4)
return None;
return FreeBSDNote{
"ABI tag",
utostr(support::endian::read32<ELFT::TargetEndianness>(Desc.data()))};
case ELF::NT_FREEBSD_ARCH_TAG:
return FreeBSDNote{"Arch tag", toStringRef(Desc).str()};
case ELF::NT_FREEBSD_FEATURE_CTL: {
if (Desc.size() != 4)
return None;
unsigned Value =
support::endian::read32<ELFT::TargetEndianness>(Desc.data());
std::string FlagsStr;
raw_string_ostream OS(FlagsStr);
printFlags(Value, makeArrayRef(FreeBSDFeatureCtlFlags), OS);
if (OS.str().empty())
OS << "0x" << utohexstr(Value);
else
OS << "(0x" << utohexstr(Value) << ")";
return FreeBSDNote{"Feature flags", OS.str()};
}
default:
return None;
}
}
struct AMDNote {
std::string Type;
std::string Value;
@ -5057,7 +5104,7 @@ static const NoteType GNUNoteTypes[] = {
{ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
};
static const NoteType FreeBSDNoteTypes[] = {
static const NoteType FreeBSDCoreNoteTypes[] = {
{ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
{ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
{ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
@ -5071,6 +5118,14 @@ static const NoteType FreeBSDNoteTypes[] = {
{ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
};
static const NoteType FreeBSDNoteTypes[] = {
{ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"},
{ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"},
{ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"},
{ELF::NT_FREEBSD_FEATURE_CTL,
"NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"},
};
static const NoteType AMDNoteTypes[] = {
{ELF::NT_AMD_AMDGPU_HSA_METADATA,
"NT_AMD_AMDGPU_HSA_METADATA (HSA Metadata)"},
@ -5161,8 +5216,17 @@ StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {
StringRef Name = Note.getName();
if (Name == "GNU")
return FindNote(GNUNoteTypes);
if (Name == "FreeBSD")
return FindNote(FreeBSDNoteTypes);
if (Name == "FreeBSD") {
if (ELFType == ELF::ET_CORE) {
// FreeBSD also places the generic core notes in the FreeBSD namespace.
StringRef Result = FindNote(FreeBSDCoreNoteTypes);
if (!Result.empty())
return Result;
return FindNote(CoreNoteTypes);
} else {
return FindNote(FreeBSDNoteTypes);
}
}
if (Name == "AMD")
return FindNote(AMDNoteTypes);
if (Name == "AMDGPU")
@ -5179,12 +5243,13 @@ static void printNotesHelper(
llvm::function_ref<void(Optional<StringRef>, typename ELFT::Off,
typename ELFT::Addr)>
StartNotesFn,
llvm::function_ref<Error(const typename ELFT::Note &)> ProcessNoteFn,
llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn,
llvm::function_ref<void()> FinishNotesFn) {
const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE;
ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());
if (Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) {
if (!IsCoreFile && !Sections.empty()) {
for (const typename ELFT::Shdr &S : Sections) {
if (S.sh_type != SHT_NOTE)
continue;
@ -5193,7 +5258,7 @@ static void printNotesHelper(
Error Err = Error::success();
size_t I = 0;
for (const typename ELFT::Note Note : Obj.notes(S, Err)) {
if (Error E = ProcessNoteFn(Note))
if (Error E = ProcessNoteFn(Note, IsCoreFile))
Dumper.reportUniqueWarning(
"unable to read note with index " + Twine(I) + " from the " +
describe(Obj, S) + ": " + toString(std::move(E)));
@ -5224,7 +5289,7 @@ static void printNotesHelper(
Error Err = Error::success();
size_t Index = 0;
for (const typename ELFT::Note Note : Obj.notes(P, Err)) {
if (Error E = ProcessNoteFn(Note))
if (Error E = ProcessNoteFn(Note, IsCoreFile))
Dumper.reportUniqueWarning("unable to read note with index " +
Twine(Index) +
" from the PT_NOTE segment with index " +
@ -5262,7 +5327,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
OS << " Owner Data size \tDescription\n";
};
auto ProcessNote = [&](const Elf_Note &Note) -> Error {
auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
StringRef Name = Note.getName();
ArrayRef<uint8_t> Descriptor = Note.getDesc();
Elf_Word Type = Note.getType();
@ -5283,6 +5348,12 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
if (Name == "GNU") {
if (printGNUNote<ELFT>(OS, Type, Descriptor))
return Error::success();
} else if (Name == "FreeBSD") {
if (Optional<FreeBSDNote> N =
getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
OS << " " << N->Type << ": " << N->Value << '\n';
return Error::success();
}
} else if (Name == "AMD") {
const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
if (!N.Type.empty()) {
@ -6531,7 +6602,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
auto EndNotes = [&] { NoteScope.reset(); };
auto ProcessNote = [&](const Elf_Note &Note) -> Error {
auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
DictScope D2(W, "Note");
StringRef Name = Note.getName();
ArrayRef<uint8_t> Descriptor = Note.getDesc();
@ -6554,6 +6625,12 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
if (Name == "GNU") {
if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W))
return Error::success();
} else if (Name == "FreeBSD") {
if (Optional<FreeBSDNote> N =
getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
W.printString(N->Type, N->Value);
return Error::success();
}
} else if (Name == "AMD") {
const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
if (!N.Type.empty()) {