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