cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

libc.c (3491B)


      1/*
      2 * Copyright (c) 2013 Kevin Wolf <kwolf@redhat.com>
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a copy
      5 * of this software and associated documentation files (the "Software"), to deal
      6 * in the Software without restriction, including without limitation the rights
      7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 * copies of the Software, and to permit persons to whom the Software is
      9 * furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 * THE SOFTWARE.
     21 */
     22
     23#include "libc.h"
     24
     25void* memcpy(void *dest, const void *src, int n)
     26{
     27    char *d = dest;
     28    const char *s = src;
     29
     30    while (n--) {
     31        *d++ = *s++;
     32    }
     33
     34    return dest;
     35}
     36
     37static void print_char(char c)
     38{
     39    outb(0xe9, c);
     40}
     41
     42static void print_str(char *s)
     43{
     44    while (*s) {
     45        print_char(*s++);
     46    }
     47}
     48
     49static void print_num(uint64_t value, int base)
     50{
     51    char digits[] = "0123456789abcdef";
     52    char buf[32] = { 0 };
     53    int i = sizeof(buf) - 2;
     54
     55    do {
     56        buf[i--] = digits[value % base];
     57        value /= base;
     58    } while (value);
     59
     60    print_str(&buf[i + 1]);
     61}
     62
     63void printf(const char *fmt, ...)
     64{
     65    va_list ap;
     66    uint64_t val;
     67    char *str;
     68    int base;
     69    int has_long;
     70    int alt_form;
     71
     72    va_start(ap, fmt);
     73
     74    for (; *fmt; fmt++) {
     75        if (*fmt != '%') {
     76            print_char(*fmt);
     77            continue;
     78        }
     79        fmt++;
     80
     81        if (*fmt == '#') {
     82            fmt++;
     83            alt_form = 1;
     84        } else {
     85            alt_form = 0;
     86        }
     87
     88        if (*fmt == 'l') {
     89            fmt++;
     90            if (*fmt == 'l') {
     91                fmt++;
     92                has_long = 2;
     93            } else {
     94                has_long = 1;
     95            }
     96        } else {
     97            has_long = 0;
     98        }
     99
    100        switch (*fmt) {
    101        case 'x':
    102        case 'p':
    103            base = 16;
    104            goto convert_number;
    105        case 'd':
    106        case 'i':
    107        case 'u':
    108            base = 10;
    109            goto convert_number;
    110        case 'o':
    111            base = 8;
    112            goto convert_number;
    113
    114        convert_number:
    115            switch (has_long) {
    116            case 0:
    117                val = va_arg(ap, unsigned int);
    118                break;
    119            case 1:
    120                val = va_arg(ap, unsigned long);
    121                break;
    122            case 2:
    123                val = va_arg(ap, unsigned long long);
    124                break;
    125            }
    126
    127            if (alt_form && base == 16) {
    128                print_str("0x");
    129            }
    130
    131            print_num(val, base);
    132            break;
    133
    134        case 's':
    135            str = va_arg(ap, char*);
    136            print_str(str);
    137            break;
    138        case '%':
    139            print_char(*fmt);
    140            break;
    141        default:
    142            print_char('%');
    143            print_char(*fmt);
    144            break;
    145        }
    146    }
    147
    148    va_end(ap);
    149}
    150
    151