@@ -193,27 +193,12 @@ void UpdateMemoryUsage() {
193193void UpdateMemoryUsage () {}
194194#endif
195195
196- // Prepare to run instrumented code on the main thread.
197- void InitInstrumentation () {
198- if (hwasan_instrumentation_inited) return ;
199-
200- if (!InitShadow ()) {
201- Printf (" FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n " );
202- DumpProcessMap ();
203- Die ();
204- }
205-
206- InitThreads ();
207- hwasanThreadList ().CreateCurrentThread ();
208-
209- hwasan_instrumentation_inited = 1 ;
210- }
211-
212196} // namespace __hwasan
213197
198+ using namespace __hwasan ;
199+
214200void __sanitizer::BufferedStackTrace::UnwindImpl (
215201 uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
216- using namespace __hwasan ;
217202 Thread *t = GetCurrentThread ();
218203 if (!t) {
219204 // the thread is still being created.
@@ -231,9 +216,85 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
231216 Unwind (max_depth, pc, 0 , context, 0 , 0 , false );
232217}
233218
234- // Interface.
219+ struct hwasan_global {
220+ s32 gv_relptr;
221+ u32 info;
222+ };
223+
224+ static void InitGlobals (const hwasan_global *begin, const hwasan_global *end) {
225+ for (auto *desc = begin; desc != end; ++desc) {
226+ uptr gv = reinterpret_cast <uptr>(desc) + desc->gv_relptr ;
227+ uptr size = desc->info & 0xffffff ;
228+ uptr full_granule_size = RoundDownTo (size, 16 );
229+ u8 tag = desc->info >> 24 ;
230+ TagMemoryAligned (gv, full_granule_size, tag);
231+ if (size % 16 )
232+ TagMemoryAligned (gv + full_granule_size, 16 , size % 16 );
233+ }
234+ }
235235
236- using namespace __hwasan ;
236+ enum { NT_LLVM_HWASAN_GLOBALS = 3 };
237+
238+ struct hwasan_global_note {
239+ s32 begin_relptr;
240+ s32 end_relptr;
241+ };
242+
243+ static void InitGlobalsFromPhdrs (ElfW(Addr) base, const ElfW(Phdr) * phdr,
244+ ElfW(Half) phnum) {
245+ for (; phnum != 0 ; ++phdr, --phnum) {
246+ if (phdr->p_type != PT_NOTE)
247+ continue ;
248+ const char *note = reinterpret_cast <const char *>(base + phdr->p_vaddr );
249+ const char *nend = note + phdr->p_memsz ;
250+ while (note < nend) {
251+ auto *nhdr = reinterpret_cast <const ElfW (Nhdr) *>(note);
252+ const char *name = note + sizeof (ElfW (Nhdr));
253+ const char *desc = name + nhdr->n_namesz ;
254+ if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS ||
255+ internal_strcmp (name, " LLVM" ) != 0 ) {
256+ note = desc + nhdr->n_descsz ;
257+ continue ;
258+ }
259+
260+ auto *global_note = reinterpret_cast <const hwasan_global_note *>(desc);
261+ auto *global_begin = reinterpret_cast <const hwasan_global *>(
262+ note + global_note->begin_relptr );
263+ auto *global_end = reinterpret_cast <const hwasan_global *>(
264+ note + global_note->end_relptr );
265+ InitGlobals (global_begin, global_end);
266+ return ;
267+ }
268+ }
269+ }
270+
271+ static void InitLoadedGlobals () {
272+ dl_iterate_phdr (
273+ [](dl_phdr_info *info, size_t size, void *data) {
274+ InitGlobalsFromPhdrs (info->dlpi_addr , info->dlpi_phdr ,
275+ info->dlpi_phnum );
276+ return 0 ;
277+ },
278+ nullptr );
279+ }
280+
281+ // Prepare to run instrumented code on the main thread.
282+ static void InitInstrumentation () {
283+ if (hwasan_instrumentation_inited) return ;
284+
285+ if (!InitShadow ()) {
286+ Printf (" FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n " );
287+ DumpProcessMap ();
288+ Die ();
289+ }
290+
291+ InitThreads ();
292+ hwasanThreadList ().CreateCurrentThread ();
293+
294+ hwasan_instrumentation_inited = 1 ;
295+ }
296+
297+ // Interface.
237298
238299uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol.
239300
@@ -244,6 +305,17 @@ void __hwasan_init_frames(uptr beg, uptr end) {}
244305void __hwasan_init_static () {
245306 InitShadowGOT ();
246307 InitInstrumentation ();
308+
309+ // In the non-static code path we call dl_iterate_phdr here. But at this point
310+ // libc might not have been initialized enough for dl_iterate_phdr to work.
311+ // Fortunately, since this is a statically linked executable we can use the
312+ // linker-defined symbol __ehdr_start to find the only relevant set of phdrs.
313+ extern ElfW (Ehdr) __ehdr_start;
314+ InitGlobalsFromPhdrs (
315+ 0 ,
316+ reinterpret_cast <const ElfW (Phdr) *>(
317+ reinterpret_cast <const char *>(&__ehdr_start) + __ehdr_start.e_phoff ),
318+ __ehdr_start.e_phnum );
247319}
248320
249321void __hwasan_init () {
@@ -267,6 +339,7 @@ void __hwasan_init() {
267339 DisableCoreDumperIfNecessary ();
268340
269341 InitInstrumentation ();
342+ InitLoadedGlobals ();
270343
271344 // Needs to be called here because flags()->random_tags might not have been
272345 // initialized when InitInstrumentation() was called.
@@ -301,6 +374,18 @@ void __hwasan_init() {
301374 hwasan_inited = 1 ;
302375}
303376
377+ void __hwasan_library_loaded (ElfW(Addr) base, const ElfW(Phdr) * phdr,
378+ ElfW(Half) phnum) {
379+ InitGlobalsFromPhdrs (base, phdr, phnum);
380+ }
381+
382+ void __hwasan_library_unloaded (ElfW(Addr) base, const ElfW(Phdr) * phdr,
383+ ElfW(Half) phnum) {
384+ for (; phnum != 0 ; ++phdr, --phnum)
385+ if (phdr->p_type == PT_LOAD)
386+ TagMemory (base + phdr->p_vaddr , phdr->p_memsz , 0 );
387+ }
388+
304389void __hwasan_print_shadow (const void *p, uptr sz) {
305390 uptr ptr_raw = UntagAddr (reinterpret_cast <uptr>(p));
306391 uptr shadow_first = MemToShadow (ptr_raw);
0 commit comments