1 //===-- hwasan_globals.cpp ------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of HWAddressSanitizer.
11 // HWAddressSanitizer globals-specific runtime.
12 //===----------------------------------------------------------------------===//
14 #include "hwasan_globals.h"
16 #include "sanitizer_common/sanitizer_array_ref.h"
20 enum { NT_LLVM_HWASAN_GLOBALS
= 3 };
21 struct hwasan_global_note
{
26 // Check that the given library meets the code model requirements for tagged
27 // globals. These properties are not checked at link time so they need to be
28 // checked at runtime.
29 static void CheckCodeModel(ElfW(Addr
) base
, const ElfW(Phdr
) * phdr
,
31 ElfW(Addr
) min_addr
= -1ull, max_addr
= 0;
32 for (unsigned i
= 0; i
!= phnum
; ++i
) {
33 if (phdr
[i
].p_type
!= PT_LOAD
)
35 ElfW(Addr
) lo
= base
+ phdr
[i
].p_vaddr
, hi
= lo
+ phdr
[i
].p_memsz
;
42 if (max_addr
- min_addr
> 1ull << 32) {
43 Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n");
46 if (max_addr
> 1ull << 48) {
47 Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n");
52 ArrayRef
<const hwasan_global
> HwasanGlobalsFor(ElfW(Addr
) base
,
53 const ElfW(Phdr
) * phdr
,
55 // Read the phdrs from this DSO.
56 for (unsigned i
= 0; i
!= phnum
; ++i
) {
57 if (phdr
[i
].p_type
!= PT_NOTE
)
60 const char *note
= reinterpret_cast<const char *>(base
+ phdr
[i
].p_vaddr
);
61 const char *nend
= note
+ phdr
[i
].p_memsz
;
63 // Traverse all the notes until we find a HWASan note.
65 auto *nhdr
= reinterpret_cast<const ElfW(Nhdr
) *>(note
);
66 const char *name
= note
+ sizeof(ElfW(Nhdr
));
67 const char *desc
= name
+ RoundUpTo(nhdr
->n_namesz
, 4);
69 // Discard non-HWASan-Globals notes.
70 if (nhdr
->n_type
!= NT_LLVM_HWASAN_GLOBALS
||
71 internal_strcmp(name
, "LLVM") != 0) {
72 note
= desc
+ RoundUpTo(nhdr
->n_descsz
, 4);
76 // Only libraries with instrumented globals need to be checked against the
77 // code model since they use relocations that aren't checked at link time.
78 CheckCodeModel(base
, phdr
, phnum
);
80 auto *global_note
= reinterpret_cast<const hwasan_global_note
*>(desc
);
81 auto *globals_begin
= reinterpret_cast<const hwasan_global
*>(
82 note
+ global_note
->begin_relptr
);
83 auto *globals_end
= reinterpret_cast<const hwasan_global
*>(
84 note
+ global_note
->end_relptr
);
86 return {globals_begin
, globals_end
};
93 } // namespace __hwasan