1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <elf.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <sys/mman.h>
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include <memory>
27 #include <vector>
28 
29 #include <android-base/file.h>
30 #include <gtest/gtest.h>
31 
32 #include <unwindstack/Elf.h>
33 #include <unwindstack/MapInfo.h>
34 #include <unwindstack/Maps.h>
35 #include <unwindstack/Memory.h>
36 
37 #include "ElfTestUtils.h"
38 #include "MemoryFake.h"
39 
40 namespace unwindstack {
41 
42 class MapInfoCreateMemoryTest : public ::testing::Test {
43  protected:
44   template <typename Ehdr, typename Shdr>
InitElf(int fd,uint64_t file_offset,uint64_t sh_offset,uint8_t class_type)45   static void InitElf(int fd, uint64_t file_offset, uint64_t sh_offset, uint8_t class_type) {
46     std::vector<uint8_t> buffer(20000);
47     memset(buffer.data(), 0, buffer.size());
48 
49     Ehdr ehdr;
50     memset(&ehdr, 0, sizeof(ehdr));
51     memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
52     ehdr.e_ident[EI_CLASS] = class_type;
53     ehdr.e_shoff = sh_offset;
54     ehdr.e_shentsize = sizeof(Shdr) + 100;
55     ehdr.e_shnum = 4;
56     memcpy(&buffer[file_offset], &ehdr, sizeof(ehdr));
57 
58     ASSERT_TRUE(android::base::WriteFully(fd, buffer.data(), buffer.size()));
59   }
60 
SetUp()61   void SetUp() override {
62     std::vector<uint8_t> buffer(12288, 0);
63     memcpy(buffer.data(), ELFMAG, SELFMAG);
64     buffer[EI_CLASS] = ELFCLASS32;
65     ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), 1024));
66 
67     memset(buffer.data(), 0, buffer.size());
68     memcpy(&buffer[0x1000], ELFMAG, SELFMAG);
69     buffer[0x1000 + EI_CLASS] = ELFCLASS64;
70     buffer[0x2000] = 0xff;
71     ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, buffer.data(), buffer.size()));
72 
73     InitElf<Elf32_Ehdr, Elf32_Shdr>(elf32_at_map_.fd, 0x1000, 0x2000, ELFCLASS32);
74     InitElf<Elf64_Ehdr, Elf64_Shdr>(elf64_at_map_.fd, 0x2000, 0x3000, ELFCLASS64);
75 
76     memory_ = new MemoryFake;
77     process_memory_.reset(memory_);
78   }
79 
80   MemoryFake* memory_;
81   std::shared_ptr<Memory> process_memory_;
82 
83   TemporaryFile elf_;
84 
85   TemporaryFile elf_at_1000_;
86 
87   TemporaryFile elf32_at_map_;
88   TemporaryFile elf64_at_map_;
89 };
90 
TEST_F(MapInfoCreateMemoryTest,end_le_start)91 TEST_F(MapInfoCreateMemoryTest, end_le_start) {
92   MapInfo info(nullptr, nullptr, 0x100, 0x100, 0, 0, elf_.path);
93 
94   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
95   ASSERT_TRUE(memory.get() == nullptr);
96 
97   info.set_end(0xff);
98   memory.reset(info.CreateMemory(process_memory_));
99   ASSERT_TRUE(memory.get() == nullptr);
100 
101   // Make sure this test is valid.
102   info.set_end(0x101);
103   memory.reset(info.CreateMemory(process_memory_));
104   ASSERT_TRUE(memory.get() != nullptr);
105   EXPECT_FALSE(info.memory_backed_elf());
106 }
107 
108 // Verify that if the offset is non-zero but there is no elf at the offset,
109 // that the full file is used.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_full_file)110 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) {
111   MapInfo info(nullptr, nullptr, 0x100, 0x200, 0x100, 0, elf_.path);
112 
113   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
114   ASSERT_TRUE(memory.get() != nullptr);
115   EXPECT_FALSE(info.memory_backed_elf());
116   ASSERT_EQ(0x100U, info.elf_offset());
117   EXPECT_EQ(0x100U, info.elf_start_offset());
118 
119   // Read the entire file.
120   std::vector<uint8_t> buffer(1024);
121   ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 1024));
122   ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0);
123   ASSERT_EQ(ELFCLASS32, buffer[EI_CLASS]);
124   for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) {
125     ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
126   }
127 
128   ASSERT_FALSE(memory->ReadFully(1024, buffer.data(), 1));
129 
130   // Now verify the elf start offset is set correctly based on the previous
131   // info.
132   MapInfo prev_info(nullptr, nullptr, 0, 0x100, 0x10, 0, "");
133   info.set_prev_map(&prev_info);
134   info.set_prev_real_map(&prev_info);
135 
136   // No preconditions met, change each one until it should set the elf start
137   // offset to zero.
138   info.set_elf_offset(0);
139   info.set_elf_start_offset(0);
140   info.set_memory_backed_elf(false);
141   memory.reset(info.CreateMemory(process_memory_));
142   ASSERT_TRUE(memory.get() != nullptr);
143   EXPECT_FALSE(info.memory_backed_elf());
144   ASSERT_EQ(0x100U, info.elf_offset());
145   EXPECT_EQ(0x100U, info.elf_start_offset());
146 
147   prev_info.set_offset(0);
148   info.set_elf_offset(0);
149   info.set_elf_start_offset(0);
150   info.set_memory_backed_elf(false);
151   memory.reset(info.CreateMemory(process_memory_));
152   ASSERT_TRUE(memory.get() != nullptr);
153   EXPECT_FALSE(info.memory_backed_elf());
154   ASSERT_EQ(0x100U, info.elf_offset());
155   EXPECT_EQ(0x100U, info.elf_start_offset());
156 
157   prev_info.set_flags(PROT_READ);
158   info.set_elf_offset(0);
159   info.set_elf_start_offset(0);
160   info.set_memory_backed_elf(false);
161   memory.reset(info.CreateMemory(process_memory_));
162   ASSERT_TRUE(memory.get() != nullptr);
163   EXPECT_FALSE(info.memory_backed_elf());
164   ASSERT_EQ(0x100U, info.elf_offset());
165   EXPECT_EQ(0x100U, info.elf_start_offset());
166 
167   prev_info.set_name(info.name());
168   info.set_elf_offset(0);
169   info.set_elf_start_offset(0);
170   info.set_memory_backed_elf(false);
171   memory.reset(info.CreateMemory(process_memory_));
172   ASSERT_TRUE(memory.get() != nullptr);
173   EXPECT_FALSE(info.memory_backed_elf());
174   ASSERT_EQ(0x100U, info.elf_offset());
175   EXPECT_EQ(0U, info.elf_start_offset());
176 }
177 
178 // Verify that if the offset is non-zero and there is an elf at that
179 // offset, that only part of the file is used.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file)180 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) {
181   MapInfo info(nullptr, nullptr, 0x100, 0x200, 0x1000, 0, elf_at_1000_.path);
182 
183   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
184   ASSERT_TRUE(memory.get() != nullptr);
185   EXPECT_FALSE(info.memory_backed_elf());
186   ASSERT_EQ(0U, info.elf_offset());
187   EXPECT_EQ(0x1000U, info.elf_start_offset());
188 
189   // Read the valid part of the file.
190   std::vector<uint8_t> buffer(0x100);
191   ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100));
192   ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0);
193   ASSERT_EQ(ELFCLASS64, buffer[EI_CLASS]);
194   for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) {
195     ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
196   }
197 
198   ASSERT_FALSE(memory->ReadFully(0x100, buffer.data(), 1));
199 }
200 
201 // Verify that if the offset is non-zero and there is an elf at that
202 // offset, that only part of the file is used. Further verify that if the
203 // embedded elf is bigger than the initial map, the new object is larger
204 // than the original map size. Do this for a 32 bit elf and a 64 bit elf.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file_whole_elf32)205 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf32) {
206   MapInfo info(nullptr, nullptr, 0x5000, 0x6000, 0x1000, 0, elf32_at_map_.path);
207 
208   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
209   ASSERT_TRUE(memory.get() != nullptr);
210   EXPECT_FALSE(info.memory_backed_elf());
211   ASSERT_EQ(0U, info.elf_offset());
212   EXPECT_EQ(0x1000U, info.elf_start_offset());
213 
214   // Verify the memory is a valid elf.
215   uint8_t e_ident[SELFMAG + 1];
216   ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG));
217   ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG));
218 
219   // Read past the end of what would normally be the size of the map.
220   ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1));
221 }
222 
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file_whole_elf64)223 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf64) {
224   MapInfo info(nullptr, nullptr, 0x7000, 0x8000, 0x2000, 0, elf64_at_map_.path);
225 
226   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
227   ASSERT_TRUE(memory.get() != nullptr);
228   EXPECT_FALSE(info.memory_backed_elf());
229   ASSERT_EQ(0U, info.elf_offset());
230   EXPECT_EQ(0x2000U, info.elf_start_offset());
231 
232   // Verify the memory is a valid elf.
233   uint8_t e_ident[SELFMAG + 1];
234   ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG));
235   ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG));
236 
237   // Read past the end of what would normally be the size of the map.
238   ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1));
239 }
240 
241 // Verify that device file names will never result in Memory object creation.
TEST_F(MapInfoCreateMemoryTest,check_device_maps)242 TEST_F(MapInfoCreateMemoryTest, check_device_maps) {
243   // Set up some memory so that a valid local memory object would
244   // be returned if the file mapping fails, but the device check is incorrect.
245   std::vector<uint8_t> buffer(1024);
246   uint64_t start = reinterpret_cast<uint64_t>(buffer.data());
247   MapInfo info(nullptr, nullptr, start, start + buffer.size(), 0, 0x8000, "/dev/something");
248 
249   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
250   ASSERT_TRUE(memory.get() == nullptr);
251 }
252 
TEST_F(MapInfoCreateMemoryTest,process_memory)253 TEST_F(MapInfoCreateMemoryTest, process_memory) {
254   MapInfo info(nullptr, nullptr, 0x2000, 0x3000, 0, PROT_READ, "");
255 
256   Elf32_Ehdr ehdr = {};
257   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
258   std::vector<uint8_t> buffer(1024);
259   memcpy(buffer.data(), &ehdr, sizeof(ehdr));
260 
261   // Verify that the the process_memory object is used, so seed it
262   // with memory.
263   for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
264     buffer[i] = i % 256;
265   }
266   memory_->SetMemory(info.start(), buffer.data(), buffer.size());
267 
268   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
269   ASSERT_TRUE(memory.get() != nullptr);
270   EXPECT_TRUE(info.memory_backed_elf());
271 
272   memset(buffer.data(), 0, buffer.size());
273   ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size()));
274   ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
275   for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
276     ASSERT_EQ(i % 256, buffer[i]) << "Failed at byte " << i;
277   }
278 
279   // Try to read outside of the map size.
280   ASSERT_FALSE(memory->ReadFully(buffer.size(), buffer.data(), 1));
281 }
282 
TEST_F(MapInfoCreateMemoryTest,valid_rosegment_zero_offset)283 TEST_F(MapInfoCreateMemoryTest, valid_rosegment_zero_offset) {
284   Maps maps;
285   maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
286   maps.Add(0x1000, 0x2600, 0, PROT_READ, "/only/in/memory.so", 0);
287   maps.Add(0x3000, 0x5000, 0x4000, PROT_READ | PROT_EXEC, "/only/in/memory.so", 0);
288 
289   Elf32_Ehdr ehdr = {};
290   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
291   memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr));
292   memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x1600 - sizeof(ehdr), 0xab);
293 
294   // Set the memory in the r-x map.
295   memory_->SetMemoryBlock(0x3000, 0x2000, 0x5d);
296 
297   MapInfo* map_info = maps.Find(0x3000);
298   ASSERT_TRUE(map_info != nullptr);
299 
300   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
301   ASSERT_TRUE(mem.get() != nullptr);
302   EXPECT_TRUE(map_info->memory_backed_elf());
303   EXPECT_EQ(0x4000UL, map_info->elf_offset());
304   EXPECT_EQ(0x4000UL, map_info->offset());
305   EXPECT_EQ(0U, map_info->elf_start_offset());
306 
307   // Verify that reading values from this memory works properly.
308   std::vector<uint8_t> buffer(0x4000);
309   size_t bytes = mem->Read(0, buffer.data(), buffer.size());
310   ASSERT_EQ(0x1600UL, bytes);
311   ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
312   for (size_t i = sizeof(ehdr); i < bytes; i++) {
313     ASSERT_EQ(0xab, buffer[i]) << "Failed at byte " << i;
314   }
315 
316   bytes = mem->Read(0x4000, buffer.data(), buffer.size());
317   ASSERT_EQ(0x2000UL, bytes);
318   for (size_t i = 0; i < bytes; i++) {
319     ASSERT_EQ(0x5d, buffer[i]) << "Failed at byte " << i;
320   }
321 }
322 
TEST_F(MapInfoCreateMemoryTest,valid_rosegment_non_zero_offset)323 TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) {
324   Maps maps;
325   maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
326   maps.Add(0x1000, 0x2000, 0, PROT_READ, "/only/in/memory.apk", 0);
327   maps.Add(0x2000, 0x3000, 0x1000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
328   maps.Add(0x3000, 0x4000, 0xa000, PROT_READ, "/only/in/memory.apk", 0);
329   maps.Add(0x4000, 0x5000, 0xb000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
330 
331   Elf32_Ehdr ehdr = {};
332   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
333 
334   // Setup an elf at offset 0x1000 in memory.
335   memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr));
336   memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x2000 - sizeof(ehdr), 0x12);
337   memory_->SetMemoryBlock(0x2000, 0x1000, 0x23);
338 
339   // Setup an elf at offset 0x3000 in memory..
340   memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
341   memory_->SetMemoryBlock(0x3000 + sizeof(ehdr), 0x4000 - sizeof(ehdr), 0x34);
342   memory_->SetMemoryBlock(0x4000, 0x1000, 0x43);
343 
344   MapInfo* map_info = maps.Find(0x4000);
345   ASSERT_TRUE(map_info != nullptr);
346 
347   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
348   ASSERT_TRUE(mem.get() != nullptr);
349   EXPECT_TRUE(map_info->memory_backed_elf());
350   EXPECT_EQ(0x1000UL, map_info->elf_offset());
351   EXPECT_EQ(0xb000UL, map_info->offset());
352   EXPECT_EQ(0xa000UL, map_info->elf_start_offset());
353 
354   // Verify that reading values from this memory works properly.
355   std::vector<uint8_t> buffer(0x4000);
356   size_t bytes = mem->Read(0, buffer.data(), buffer.size());
357   ASSERT_EQ(0x1000UL, bytes);
358   ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
359   for (size_t i = sizeof(ehdr); i < bytes; i++) {
360     ASSERT_EQ(0x34, buffer[i]) << "Failed at byte " << i;
361   }
362 
363   bytes = mem->Read(0x1000, buffer.data(), buffer.size());
364   ASSERT_EQ(0x1000UL, bytes);
365   for (size_t i = 0; i < bytes; i++) {
366     ASSERT_EQ(0x43, buffer[i]) << "Failed at byte " << i;
367   }
368 }
369 
TEST_F(MapInfoCreateMemoryTest,valid_single_rx_non_zero_offset)370 TEST_F(MapInfoCreateMemoryTest, valid_single_rx_non_zero_offset) {
371   Maps maps;
372   maps.Add(0x3000, 0x5000, 0xa000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
373 
374   Elf32_Ehdr ehdr = {};
375   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
376 
377   // Setup an elf at offset 0x3000 in memory..
378   memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
379   memory_->SetMemoryBlock(0x3000 + sizeof(ehdr), 0x5000 - sizeof(ehdr), 0x34);
380 
381   MapInfo* map_info = maps.Find(0x3000);
382   ASSERT_TRUE(map_info != nullptr);
383 
384   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
385   ASSERT_TRUE(mem.get() != nullptr);
386   EXPECT_TRUE(map_info->memory_backed_elf());
387   EXPECT_EQ(0UL, map_info->elf_offset());
388   EXPECT_EQ(0xa000UL, map_info->offset());
389   EXPECT_EQ(0xa000UL, map_info->elf_start_offset());
390 
391   // Verify that reading values from this memory works properly.
392   std::vector<uint8_t> buffer(0x3000);
393   size_t bytes = mem->Read(0, buffer.data(), buffer.size());
394   ASSERT_EQ(0x2000UL, bytes);
395   ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
396   for (size_t i = sizeof(ehdr); i < bytes; i++) {
397     ASSERT_EQ(0x34, buffer[i]) << "Failed at byte " << i;
398   }
399 }
400 
TEST_F(MapInfoCreateMemoryTest,rosegment_from_file)401 TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) {
402   Maps maps;
403   maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
404   maps.Add(0x1000, 0x2000, 0x1000, PROT_READ, elf_at_1000_.path, 0);
405   maps.Add(0x2000, 0x3000, 0x2000, PROT_READ | PROT_EXEC, elf_at_1000_.path, 0);
406 
407   MapInfo* map_info = maps.Find(0x2000);
408   ASSERT_TRUE(map_info != nullptr);
409 
410   // Set up the size
411   Elf64_Ehdr ehdr;
412   ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
413   ASSERT_TRUE(android::base::ReadFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
414 
415   // Will not give the elf memory, because the read-only entry does not
416   // extend over the executable segment.
417   std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_));
418   ASSERT_TRUE(memory.get() != nullptr);
419   EXPECT_FALSE(map_info->memory_backed_elf());
420   std::vector<uint8_t> buffer(0x100);
421   EXPECT_EQ(0x2000U, map_info->offset());
422   EXPECT_EQ(0U, map_info->elf_offset());
423   EXPECT_EQ(0U, map_info->elf_start_offset());
424   ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100));
425   EXPECT_EQ(0xffU, buffer[0]);
426 
427   // Now init the elf data enough so that the file memory object will be used.
428   ehdr.e_shoff = 0x4000;
429   ehdr.e_shnum = 1;
430   ehdr.e_shentsize = 0x100;
431   ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
432   ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
433 
434   map_info->set_memory_backed_elf(false);
435   memory.reset(map_info->CreateMemory(process_memory_));
436   EXPECT_FALSE(map_info->memory_backed_elf());
437   EXPECT_EQ(0x2000U, map_info->offset());
438   EXPECT_EQ(0x1000U, map_info->elf_offset());
439   EXPECT_EQ(0x1000U, map_info->elf_start_offset());
440   Elf64_Ehdr ehdr_mem;
441   ASSERT_TRUE(memory->ReadFully(0, &ehdr_mem, sizeof(ehdr_mem)));
442   EXPECT_TRUE(memcmp(&ehdr, &ehdr_mem, sizeof(ehdr)) == 0);
443 }
444 
TEST_F(MapInfoCreateMemoryTest,valid_rosegment_offset_overflow)445 TEST_F(MapInfoCreateMemoryTest, valid_rosegment_offset_overflow) {
446   Maps maps;
447   maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
448   maps.Add(0x1000, 0x2000, 0, PROT_READ, "/only/in/memory.so", 0);
449   maps.Add(0x3000, 0x4000, 0xfffffffffffff000UL, PROT_READ | PROT_EXEC, "/only/in/memory.so", 0);
450 
451   Elf64_Ehdr ehdr = {};
452   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
453   memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr));
454   memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x1000 - sizeof(ehdr), 0xab);
455 
456   // Set the memory in the r-x map.
457   memory_->SetMemoryBlock(0x3000, 0x2000, 0x5d);
458 
459   MapInfo* map_info = maps.Find(0x3000);
460   ASSERT_TRUE(map_info != nullptr);
461 
462   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
463   ASSERT_TRUE(mem.get() != nullptr);
464   EXPECT_TRUE(map_info->memory_backed_elf());
465   EXPECT_EQ(0xfffffffffffff000UL, map_info->elf_offset());
466   EXPECT_EQ(0xfffffffffffff000UL, map_info->offset());
467   EXPECT_EQ(0U, map_info->elf_start_offset());
468 
469   // Verify that reading values from this memory works properly.
470   std::vector<uint8_t> buffer(0x2000);
471   size_t bytes = mem->Read(0xfffffffffffff000UL, buffer.data(), buffer.size());
472   ASSERT_EQ(0x1000UL, bytes);
473   for (size_t i = 0; i < bytes; i++) {
474     ASSERT_EQ(0x5d, buffer[i]) << "Failed at byte " << i;
475   }
476 }
477 
478 }  // namespace unwindstack
479