1 // TODO: Investigate these failures
2 // XFAIL: asan, tsan, ubsan
3 
4 // The other libunwind tests don't test internal interfaces, so the include path
5 // is a little wonky.
6 #include "../src/config.h"
7 
8 // Only run this test under supported configurations.
9 
10 #if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) &&                                 \
11     defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
12 
13 #include <link.h>
14 #include <stdio.h>
15 
16 // This file defines several of the data structures needed here,
17 // and includes FrameHeaderCache.hpp as well.
18 #include "../src/AddressSpace.hpp"
19 
20 #define kBaseAddr 0xFFF000
21 #define kTextSegmentLength 0xFF
22 
23 using namespace libunwind;
24 
25 int main(int, char**) {
26   FrameHeaderCache FHC;
27   struct dl_phdr_info PInfo;
28   memset(&PInfo, 0, sizeof(PInfo));
29   // The cache itself should only care about these two fields--they
30   // tell the cache to invalidate or not; everything else is handled
31   // by AddressSpace.hpp.
32   PInfo.dlpi_adds = 6;
33   PInfo.dlpi_subs = 7;
34 
35   UnwindInfoSections UIS;
36   UIS.dso_base = kBaseAddr;
37   UIS.text_segment_length = kTextSegmentLength;
38   dl_iterate_cb_data CBData;
39   // Unused by the cache.
40   CBData.addressSpace = nullptr;
41   CBData.sects = &UIS;
42   CBData.targetAddr = kBaseAddr + 1;
43 
44   // Nothing present, shouldn't find.
45   if (FHC.find(&PInfo, 0, &CBData))
46     abort();
47   FHC.add(&UIS);
48   // Just added. Should find.
49   if (!FHC.find(&PInfo, 0, &CBData))
50     abort();
51   // Cache is invalid. Shouldn't find.
52   PInfo.dlpi_adds++;
53   if (FHC.find(&PInfo, 0, &CBData))
54     abort();
55 
56   FHC.add(&UIS);
57   CBData.targetAddr = kBaseAddr - 1;
58   // Shouldn't find something outside of the addresses.
59   if (FHC.find(&PInfo, 0, &CBData))
60     abort();
61   // Add enough things to the cache that the entry is evicted.
62   for (int i = 0; i < 9; i++) {
63     UIS.dso_base = kBaseAddr + (kTextSegmentLength * i);
64     FHC.add(&UIS);
65   }
66   CBData.targetAddr = kBaseAddr;
67   // Should have been evicted.
68   if (FHC.find(&PInfo, 0, &CBData))
69     abort();
70   return 0;
71 }
72 
73 #else
74 int main(int, char**) { return 0;}
75 #endif
76