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"
18 enum { NT_LLVM_HWASAN_GLOBALS
= 3 };
19 struct hwasan_global_note
{
24 // Check that the given library meets the code model requirements for tagged
25 // globals. These properties are not checked at link time so they need to be
26 // checked at runtime.
27 static void CheckCodeModel(ElfW(Addr
) base
, const ElfW(Phdr
) * phdr
,
29 ElfW(Addr
) min_addr
= -1ull, max_addr
= 0;
30 for (unsigned i
= 0; i
!= phnum
; ++i
) {
31 if (phdr
[i
].p_type
!= PT_LOAD
)
33 ElfW(Addr
) lo
= base
+ phdr
[i
].p_vaddr
, hi
= lo
+ phdr
[i
].p_memsz
;
40 if (max_addr
- min_addr
> 1ull << 32) {
41 Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n");
44 if (max_addr
> 1ull << 48) {
45 Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n");
50 ArrayRef
<const hwasan_global
> HwasanGlobalsFor(ElfW(Addr
) base
,
51 const ElfW(Phdr
) * phdr
,
53 // Read the phdrs from this DSO.
54 for (unsigned i
= 0; i
!= phnum
; ++i
) {
55 if (phdr
[i
].p_type
!= PT_NOTE
)
58 const char *note
= reinterpret_cast<const char *>(base
+ phdr
[i
].p_vaddr
);
59 const char *nend
= note
+ phdr
[i
].p_memsz
;
61 // Traverse all the notes until we find a HWASan note.
63 auto *nhdr
= reinterpret_cast<const ElfW(Nhdr
) *>(note
);
64 const char *name
= note
+ sizeof(ElfW(Nhdr
));
65 const char *desc
= name
+ RoundUpTo(nhdr
->n_namesz
, 4);
67 // Discard non-HWASan-Globals notes.
68 if (nhdr
->n_type
!= NT_LLVM_HWASAN_GLOBALS
||
69 internal_strcmp(name
, "LLVM") != 0) {
70 note
= desc
+ RoundUpTo(nhdr
->n_descsz
, 4);
74 // Only libraries with instrumented globals need to be checked against the
75 // code model since they use relocations that aren't checked at link time.
76 CheckCodeModel(base
, phdr
, phnum
);
78 auto *global_note
= reinterpret_cast<const hwasan_global_note
*>(desc
);
79 auto *globals_begin
= reinterpret_cast<const hwasan_global
*>(
80 note
+ global_note
->begin_relptr
);
81 auto *globals_end
= reinterpret_cast<const hwasan_global
*>(
82 note
+ global_note
->end_relptr
);
84 return {globals_begin
, globals_end
};
91 } // namespace __hwasan