1b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma/* libunwind - a platform-independent unwind library
2b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
3b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaThis file is part of libunwind.
4b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
5b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaPermission is hereby granted, free of charge, to any person obtaining
6b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaa copy of this software and associated documentation files (the
7b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma"Software"), to deal in the Software without restriction, including
8b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmawithout limitation the rights to use, copy, modify, merge, publish,
9b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmadistribute, sublicense, and/or sell copies of the Software, and to
10b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmapermit persons to whom the Software is furnished to do so, subject to
11b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmathe following conditions:
12b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
13b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaThe above copyright notice and this permission notice shall be
14b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaincluded in all copies or substantial portions of the Software.
15b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
16b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
24b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#include "_UCD_lib.h"
25b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#include "_UCD_internal.h"
26b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
27b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaint
28b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
29b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma		 int write, void *arg)
30b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma{
31b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (write)
32b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
33e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala      Debug(0, "write is not supported\n");
34b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      return -UNW_EINVAL;
35b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    }
36b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
37b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  struct UCD_info *ui = arg;
38b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
39b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  unw_word_t addr_last = addr + sizeof(*val)-1;
40b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  coredump_phdr_t *phdr;
41b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  unsigned i;
42b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  for (i = 0; i < ui->phdrs_count; i++)
43b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
44b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      phdr = &ui->phdrs[i];
45b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz)
46b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	{
47b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	  goto found;
48b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	}
49b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    }
50e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala  Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr);
51b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  return -UNW_EINVAL;
52b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
53b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma found: ;
54b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
556ed1db2ddc6a987e44c0f9e15e73eeac33074880Arun Sharma  const char *filename UNUSED;
56b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  off_t fileofs;
57b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  int fd;
58b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (addr_last >= phdr->p_vaddr + phdr->p_filesz)
59b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
60b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      /* This part of mapped address space is not present in coredump file */
61b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      /* Do we have it in the backup file? */
62b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      if (phdr->backing_fd < 0)
63b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma        {
64e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala          Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n",
65e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala				i, (unsigned long long)addr
66b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma			);
67b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma          return -UNW_EINVAL;
68b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma        }
69b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      filename = phdr->backing_filename;
70b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      fileofs = addr - phdr->p_vaddr;
71b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      fd = phdr->backing_fd;
72b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      goto read;
73b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    }
74b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
75b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  filename = ui->coredump_filename;
76b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  fileofs = phdr->p_offset + (addr - phdr->p_vaddr);
77b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  fd = ui->coredump_fd;
78b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma read:
79b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (lseek(fd, fileofs, SEEK_SET) != fileofs)
80b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    goto read_error;
81b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (read(fd, val, sizeof(*val)) != sizeof(*val))
82b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    goto read_error;
83b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
84e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala  Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n",
85b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	(unsigned long long)(*val),
86b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	(unsigned long long)addr,
87b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	(unsigned long long)fileofs
88b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  );
89b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  return 0;
90b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
91b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma read_error:
92e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala  Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n",
93b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	(unsigned long long)addr,
94b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	(unsigned long long)fileofs,
95b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma	filename
96b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  );
97b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  return -UNW_EINVAL;
98b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma}
99