The Pedigree Project 0.1
instrument.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "instrument.h"
21
22extern "C" {
23void __cyg_profile_func_enter(void* func_address, void* call_site)
24 __attribute__((no_instrument_function)) __attribute__((hot));
25
26#define COM1 0x3F8
27#define COM2 0x2F8
28#define COM3 0x3E8
29#define COM4 0x2E8
30
31#ifdef INSTRUMENTATION
32static volatile int g_WrittenFirst = 0;
33#endif
34
35void __cyg_profile_func_enter(void* func_address, void* call_site) {
36#ifdef INSTRUMENTATION
37// NOTE: you cannot call anything in this function, as doing so would
38// re-enter. That means hand-crafted serial writes are necessary.
39#if X64
40 if (UNLIKELY(g_WrittenFirst == 0)) {
41 if (__sync_bool_compare_and_swap(&g_WrittenFirst, 0, 1)) {
42 uint8_t flag = 0;
43 flag |= INSTRUMENT_GLOBAL_LITE;
44 asm volatile("outb %%al, %%dx" ::"d"(COM2), "a"(flag));
45 }
46 }
47
49 record.data.function = reinterpret_cast<uintptr_t>(func_address);
50
51 // Semi-unrolled, all-in-one assembly serial-port write.
52 uintptr_t x = 0;
53 size_t y = 0;
54 asm volatile(
55 "pushf; cli;"
56 ".1:\n"
57 "movq (%0), %%rax;"
58 "outb %%al, %%dx;"
59 "shr $8, %%rax;"
60 "outb %%al, %%dx;"
61 "shr $8, %%rax;"
62 "outb %%al, %%dx;"
63 "shr $8, %%rax;"
64 "outb %%al, %%dx;"
65 "add $4, %0;"
66 "sub $4, %1;"
67 "jnz .1; popf"
68 : "=&r"(x), "=&r"(y)
69 : "d"(COM2), "0"(record.buffer), "1"(sizeof record.buffer)
70 : "rax", "memory");
71#endif
72#endif
73}
74
75} // extern "C"