Rizin
unix-like reverse engineering framework and cli tools
tuklib_physmem.c
Go to the documentation of this file.
1 //
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
12 
13 #include "tuklib_physmem.h"
14 
15 // We want to use Windows-specific code on Cygwin, which also has memory
16 // information available via sysconf(), but on Cygwin 1.5 and older it
17 // gives wrong results (from our point of view).
18 #if defined(_WIN32) || defined(__CYGWIN__)
19 # ifndef _WIN32_WINNT
20 # define _WIN32_WINNT 0x0500
21 # endif
22 # include <windows.h>
23 
24 #elif defined(__OS2__)
25 # define INCL_DOSMISC
26 # include <os2.h>
27 
28 #elif defined(__DJGPP__)
29 # include <dpmi.h>
30 
31 #elif defined(__VMS)
32 # include <lib$routines.h>
33 # include <syidef.h>
34 # include <ssdef.h>
35 
36 #elif defined(AMIGA) || defined(__AROS__)
37 # define __USE_INLINE__
38 # include <proto/exec.h>
39 
40 #elif defined(__QNX__)
41 # include <sys/syspage.h>
42 # include <string.h>
43 
44 #elif defined(TUKLIB_PHYSMEM_AIX)
45 # include <sys/systemcfg.h>
46 
47 #elif defined(TUKLIB_PHYSMEM_SYSCONF)
48 # include <unistd.h>
49 
50 #elif defined(TUKLIB_PHYSMEM_SYSCTL)
51 # ifdef HAVE_SYS_PARAM_H
52 # include <sys/param.h>
53 # endif
54 # include <sys/sysctl.h>
55 
56 // Tru64
57 #elif defined(TUKLIB_PHYSMEM_GETSYSINFO)
58 # include <sys/sysinfo.h>
59 # include <machine/hal_sysinfo.h>
60 
61 // HP-UX
62 #elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
63 # include <sys/param.h>
64 # include <sys/pstat.h>
65 
66 // IRIX
67 #elif defined(TUKLIB_PHYSMEM_GETINVENT_R)
68 # include <invent.h>
69 
70 // This sysinfo() is Linux-specific.
71 #elif defined(TUKLIB_PHYSMEM_SYSINFO)
72 # include <sys/sysinfo.h>
73 #endif
74 
75 
76 extern uint64_t
78 {
79  uint64_t ret = 0;
80 
81 #if defined(_WIN32) || defined(__CYGWIN__)
82  if ((GetVersion() & 0xFF) >= 5) {
83  // Windows 2000 and later have GlobalMemoryStatusEx() which
84  // supports reporting values greater than 4 GiB. To keep the
85  // code working also on older Windows versions, use
86  // GlobalMemoryStatusEx() conditionally.
87  HMODULE kernel32 = GetModuleHandle("kernel32.dll");
88  if (kernel32 != NULL) {
89  typedef BOOL (WINAPI *gmse_type)(LPMEMORYSTATUSEX);
90  gmse_type gmse = (gmse_type)GetProcAddress(
91  kernel32, "GlobalMemoryStatusEx");
92  if (gmse != NULL) {
93  MEMORYSTATUSEX meminfo;
94  meminfo.dwLength = sizeof(meminfo);
95  if (gmse(&meminfo))
96  ret = meminfo.ullTotalPhys;
97  }
98  }
99  }
100 
101  if (ret == 0) {
102  // GlobalMemoryStatus() is supported by Windows 95 and later,
103  // so it is fine to link against it unconditionally. Note that
104  // GlobalMemoryStatus() has no return value.
105  MEMORYSTATUS meminfo;
106  meminfo.dwLength = sizeof(meminfo);
107  GlobalMemoryStatus(&meminfo);
108  ret = meminfo.dwTotalPhys;
109  }
110 
111 #elif defined(__OS2__)
112  unsigned long mem;
113  if (DosQuerySysInfo(QSV_TOTPHYSMEM, QSV_TOTPHYSMEM,
114  &mem, sizeof(mem)) == 0)
115  ret = mem;
116 
117 #elif defined(__DJGPP__)
118  __dpmi_free_mem_info meminfo;
119  if (__dpmi_get_free_memory_information(&meminfo) == 0
120  && meminfo.total_number_of_physical_pages
121  != (unsigned long)-1)
122  ret = (uint64_t)meminfo.total_number_of_physical_pages * 4096;
123 
124 #elif defined(__VMS)
125  int vms_mem;
126  int val = SYI$_MEMSIZE;
127  if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)
128  ret = (uint64_t)vms_mem * 8192;
129 
130 #elif defined(AMIGA) || defined(__AROS__)
131  ret = AvailMem(MEMF_TOTAL);
132 
133 #elif defined(__QNX__)
134  const struct asinfo_entry *entries = SYSPAGE_ENTRY(asinfo);
135  size_t count = SYSPAGE_ENTRY_SIZE(asinfo) / sizeof(struct asinfo_entry);
136  const char *strings = SYSPAGE_ENTRY(strings)->data;
137 
138  for (size_t i = 0; i < count; ++i)
139  if (strcmp(strings + entries[i].name, "ram") == 0)
140  ret += entries[i].end - entries[i].start + 1;
141 
142 #elif defined(TUKLIB_PHYSMEM_AIX)
143  ret = _system_configuration.physmem;
144 
145 #elif defined(TUKLIB_PHYSMEM_SYSCONF)
146  const long pagesize = sysconf(_SC_PAGESIZE);
147  const long pages = sysconf(_SC_PHYS_PAGES);
148  if (pagesize != -1 && pages != -1)
149  // According to docs, pagesize * pages can overflow.
150  // Simple case is 32-bit box with 4 GiB or more RAM,
151  // which may report exactly 4 GiB of RAM, and "long"
152  // being 32-bit will overflow. Casting to uint64_t
153  // hopefully avoids overflows in the near future.
154  ret = (uint64_t)pagesize * (uint64_t)pages;
155 
156 #elif defined(TUKLIB_PHYSMEM_SYSCTL)
157  int name[2] = {
158  CTL_HW,
159 #ifdef HW_PHYSMEM64
160  HW_PHYSMEM64
161 #else
162  HW_PHYSMEM
163 #endif
164  };
165  union {
166  uint32_t u32;
167  uint64_t u64;
168  } mem;
169  size_t mem_ptr_size = sizeof(mem.u64);
170  if (sysctl(name, 2, &mem.u64, &mem_ptr_size, NULL, 0) != -1) {
171  // IIRC, 64-bit "return value" is possible on some 64-bit
172  // BSD systems even with HW_PHYSMEM (instead of HW_PHYSMEM64),
173  // so support both.
174  if (mem_ptr_size == sizeof(mem.u64))
175  ret = mem.u64;
176  else if (mem_ptr_size == sizeof(mem.u32))
177  ret = mem.u32;
178  }
179 
180 #elif defined(TUKLIB_PHYSMEM_GETSYSINFO)
181  // Docs are unclear if "start" is needed, but it doesn't hurt
182  // much to have it.
183  int memkb;
184  int start = 0;
185  if (getsysinfo(GSI_PHYSMEM, (caddr_t)&memkb, sizeof(memkb), &start)
186  != -1)
187  ret = (uint64_t)memkb * 1024;
188 
189 #elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
190  struct pst_static pst;
191  if (pstat_getstatic(&pst, sizeof(pst), 1, 0) != -1)
192  ret = (uint64_t)pst.physical_memory * (uint64_t)pst.page_size;
193 
194 #elif defined(TUKLIB_PHYSMEM_GETINVENT_R)
195  inv_state_t *st = NULL;
196  if (setinvent_r(&st) != -1) {
197  inventory_t *i;
198  while ((i = getinvent_r(st)) != NULL) {
199  if (i->inv_class == INV_MEMORY
200  && i->inv_type == INV_MAIN_MB) {
201  ret = (uint64_t)i->inv_state << 20;
202  break;
203  }
204  }
205 
206  endinvent_r(st);
207  }
208 
209 #elif defined(TUKLIB_PHYSMEM_SYSINFO)
210  struct sysinfo si;
211  if (sysinfo(&si) == 0)
212  ret = (uint64_t)si.totalram * si.mem_unit;
213 #endif
214 
215  return ret;
216 }
si
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type strings(--mime-type and\n" " --mime-encoding)\n") OPT('s'
void * mem
Definition: libc.cpp:91
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage sysinfo
Definition: sflib.h:147
unsigned int uint32_t
Definition: sftypes.h:29
int caddr_t
Definition: sftypes.h:62
unsigned long uint64_t
Definition: sftypes.h:28
Definition: z80asm.h:102
uint64_t tuklib_physmem(void)
Get the amount of physical memory.
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4