]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/whereami.c
1 // (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz)
2 // https://github.com/gpakosz/whereami
4 // in case you want to #include "whereami.c" in a larger compilation unit
5 #if !defined(WHEREAMI_H)
13 #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
17 #if !defined(WAI_MALLOC)
18 #define WAI_MALLOC(size) malloc(size)
21 #if !defined(WAI_FREE)
22 #define WAI_FREE(p) free(p)
25 #if !defined(WAI_REALLOC)
26 #define WAI_REALLOC(p, size) realloc(p, size)
31 #define WAI_NOINLINE __declspec(noinline)
32 #elif defined(__GNUC__)
33 #define WAI_NOINLINE __attribute__((noinline))
35 #error unsupported compiler
40 #define WAI_RETURN_ADDRESS() _ReturnAddress()
41 #elif defined(__GNUC__)
42 #define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
44 #error unsupported compiler
49 #define WIN32_LEAN_AND_MEAN
51 #pragma warning(push, 3)
54 //#include <intrin.h> // not required and doesn't exist in old mingw environments
59 static int WAI_PREFIX(getModulePath_
)(HMODULE module
, char* out
, int capacity
, int* dirname_length
)
61 wchar_t buffer1
[MAX_PATH
];
62 wchar_t buffer2
[MAX_PATH
];
69 int length_
, length__
;
71 size
= GetModuleFileNameW(module
, buffer1
, sizeof(buffer1
) / sizeof(buffer1
[0]));
75 else if (size
== (DWORD
)(sizeof(buffer1
) / sizeof(buffer1
[0])))
82 path_
= (wchar_t*)WAI_REALLOC(path
, sizeof(wchar_t) * size_
* 2);
87 size
= GetModuleFileNameW(module
, path
, size_
);
89 while (size
== size_
);
97 if (!_wfullpath(buffer2
, path
, MAX_PATH
))
99 length_
= (int)wcslen(buffer2
);
100 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, out
, capacity
, NULL
, NULL
);
103 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, NULL
, 0, NULL
, NULL
);
107 if (length__
<= capacity
&& dirname_length
)
111 for (i
= length__
- 1; i
>= 0; --i
)
134 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
136 return WAI_PREFIX(getModulePath_
)(NULL
, out
, capacity
, dirname_length
);
139 // GetModuleHandleEx() is not available on old mingw environments. We don't need getModulePath() yet.
140 // Sacrifice it for the time being to improve backwards compatibility
143 int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
148 #if defined(_MSC_VER)
149 #pragma warning(push)
150 #pragma warning(disable: 4054)
152 if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
153 #if defined(_MSC_VER)
157 length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
164 #elif defined(__linux__)
169 // #include <limits.h> // not all linux distributions define PATH_MAX in limits.h because it depends on the filesystem. Therefore use...
170 #include <linux/limits.h>
171 #ifndef __STDC_FORMAT_MACROS
172 #define __STDC_FORMAT_MACROS
174 #include <inttypes.h>
176 #if !defined(WAI_PROC_SELF_EXE)
177 #define WAI_PROC_SELF_EXE "/proc/self/exe"
181 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
183 char buffer
[PATH_MAX
];
184 char* resolved
= NULL
;
189 resolved
= realpath(WAI_PROC_SELF_EXE
, buffer
);
193 length
= (int)strlen(resolved
);
194 if (length
<= capacity
)
196 memcpy(out
, resolved
, length
);
202 for (i
= length
- 1; i
>= 0; --i
)
219 #if !defined(WAI_PROC_SELF_MAPS_RETRY)
220 #define WAI_PROC_SELF_MAPS_RETRY 5
223 #if !defined(WAI_PROC_SELF_MAPS)
224 #define WAI_PROC_SELF_MAPS "/proc/self/maps"
227 #if defined(__ANDROID__) || defined(ANDROID)
229 #include <sys/mman.h>
234 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
240 for (i
= 0; i
< WAI_PROC_SELF_MAPS_RETRY
; ++i
)
242 maps
= fopen(WAI_PROC_SELF_MAPS
, "r");
248 char buffer
[PATH_MAX
< 1024 ? 1024 : PATH_MAX
];
252 uint32_t major
, minor
;
256 if (!fgets(buffer
, sizeof(buffer
), maps
))
259 if (sscanf(buffer
, "%" PRIx64
"-%" PRIx64
" %s %" PRIx64
" %x:%x %u %s\n", &low
, &high
, perms
, &offset
, &major
, &minor
, &inode
, path
) == 8)
261 uint64_t addr
= (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS();
262 if (low
<= addr
&& addr
<= high
)
266 resolved
= realpath(path
, buffer
);
270 length
= (int)strlen(resolved
);
271 #if defined(__ANDROID__) || defined(ANDROID)
273 &&buffer
[length
- 1] == 'k'
274 &&buffer
[length
- 2] == 'p'
275 &&buffer
[length
- 3] == 'a'
276 &&buffer
[length
- 4] == '.')
278 int fd
= open(path
, O_RDONLY
);
282 begin
= (char*)mmap(0, offset
, PROT_READ
, MAP_SHARED
, fd
, 0);
285 while (p
>= begin
) // scan backwards
287 if (*((uint32_t*)p
) == 0x04034b50UL
) // local file header found
289 uint16_t length_
= *((uint16_t*)(p
+ 26));
291 if (length
+ 2 + length_
< (int)sizeof(buffer
))
293 memcpy(&buffer
[length
], "!/", 2);
294 memcpy(&buffer
[length
+ 2], p
+ 30, length_
);
295 length
+= 2 + length_
;
304 munmap(begin
, offset
);
308 if (length
<= capacity
)
310 memcpy(out
, resolved
, length
);
316 for (i
= length
- 1; i
>= 0; --i
)
341 #elif defined(__APPLE__)
343 #define _DARWIN_BETTER_REALPATH
344 #include <mach-o/dyld.h>
351 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
353 char buffer1
[PATH_MAX
];
354 char buffer2
[PATH_MAX
];
355 char* path
= buffer1
;
356 char* resolved
= NULL
;
361 uint32_t size
= (uint32_t)sizeof(buffer1
);
362 if (_NSGetExecutablePath(path
, &size
) == -1)
364 path
= (char*)WAI_MALLOC(size
);
365 if (!_NSGetExecutablePath(path
, &size
))
369 resolved
= realpath(path
, buffer2
);
373 length
= (int)strlen(resolved
);
374 if (length
<= capacity
)
376 memcpy(out
, resolved
, length
);
382 for (i
= length
- 1; i
>= 0; --i
)
404 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
406 char buffer
[PATH_MAX
];
407 char* resolved
= NULL
;
414 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
416 resolved
= realpath(info
.dli_fname
, buffer
);
420 length
= (int)strlen(resolved
);
421 if (length
<= capacity
)
423 memcpy(out
, resolved
, length
);
429 for (i
= length
- 1; i
>= 0; --i
)
447 #elif defined(__QNXNTO__)
455 #if !defined(WAI_PROC_SELF_EXE)
456 #define WAI_PROC_SELF_EXE "/proc/self/exefile"
460 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
462 char buffer1
[PATH_MAX
];
463 char buffer2
[PATH_MAX
];
464 char* resolved
= NULL
;
465 FILE* self_exe
= NULL
;
470 self_exe
= fopen(WAI_PROC_SELF_EXE
, "r");
474 if (!fgets(buffer1
, sizeof(buffer1
), self_exe
))
477 resolved
= realpath(buffer1
, buffer2
);
481 length
= (int)strlen(resolved
);
482 if (length
<= capacity
)
484 memcpy(out
, resolved
, length
);
490 for (i
= length
- 1; i
>= 0; --i
)
510 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
512 char buffer
[PATH_MAX
];
513 char* resolved
= NULL
;
520 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
522 resolved
= realpath(info
.dli_fname
, buffer
);
526 length
= (int)strlen(resolved
);
527 if (length
<= capacity
)
529 memcpy(out
, resolved
, length
);
535 for (i
= length
- 1; i
>= 0; --i
)
553 #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
554 defined(__FreeBSD_kernel__) || defined(__NetBSD__)
559 #include <sys/types.h>
560 #include <sys/sysctl.h>
564 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
566 char buffer1
[PATH_MAX
];
567 char buffer2
[PATH_MAX
];
568 char* path
= buffer1
;
569 char* resolved
= NULL
;
574 int mib
[4] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PATHNAME
, -1 };
575 size_t size
= sizeof(buffer1
);
577 if (sysctl(mib
, (u_int
)(sizeof(mib
) / sizeof(mib
[0])), path
, &size
, NULL
, 0) != 0)
580 resolved
= realpath(path
, buffer2
);
584 length
= (int)strlen(resolved
);
585 if (length
<= capacity
)
587 memcpy(out
, resolved
, length
);
593 for (i
= length
- 1; i
>= 0; --i
)
615 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
617 char buffer
[PATH_MAX
];
618 char* resolved
= NULL
;
625 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
627 resolved
= realpath(info
.dli_fname
, buffer
);
631 length
= (int)strlen(resolved
);
632 if (length
<= capacity
)
634 memcpy(out
, resolved
, length
);
640 for (i
= length
- 1; i
>= 0; --i
)
660 #error unsupported platform