Пример #1
0
static char *pointer(char *str, char *end, const char **fmt_ptr,
                     const void *arg, int field_width, int precision,
                     int flags)
{
    const char *fmt = *fmt_ptr, *s;

    /* Custom %p suffixes. See XEN_ROOT/docs/misc/printk-formats.txt */
    switch ( fmt[1] )
    {
    case 's': /* Symbol name with offset and size (iff offset != 0) */
    case 'S': /* Symbol name unconditionally with offset and size */
    {
        unsigned long sym_size, sym_offset;
        char namebuf[KSYM_NAME_LEN+1];

        /* Advance parents fmt string, as we have consumed 's' or 'S' */
        ++*fmt_ptr;

        s = symbols_lookup((unsigned long)arg, &sym_size, &sym_offset, namebuf);

        /* If the symbol is not found, fall back to printing the address */
        if ( !s )
            break;

        /* Print symbol name */
        str = string(str, end, s, -1, -1, 0);

        if ( fmt[1] == 'S' || sym_offset != 0 )
        {
            /* Print '+<offset>/<len>' */
            str = number(str, end, sym_offset, 16, -1, -1, SPECIAL|SIGN|PLUS);
            if ( str <= end )
                *str = '/';
            ++str;
            str = number(str, end, sym_size, 16, -1, -1, SPECIAL);
        }

        return str;
    }
    }

    if ( field_width == -1 )
    {
        field_width = 2 * sizeof(void *);
        flags |= ZEROPAD;
    }

    return number(str, end, (unsigned long)arg,
                  16, field_width, precision, flags);
}
Пример #2
0
/* Replace "%s" in format with address, or returns -errno. */
void __print_symbol(const char *fmt, unsigned long address)
{
    const char *name;
    unsigned long offset, size, flags;

    static DEFINE_SPINLOCK(lock);
    static char namebuf[KSYM_NAME_LEN+1];
#define BUFFER_SIZE sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \
			2*(BITS_PER_LONG*3/10) + 1
    static char buffer[BUFFER_SIZE];

    spin_lock_irqsave(&lock, flags);

    name = symbols_lookup(address, &size, &offset, namebuf);

    if (!name)
        snprintf(buffer, BUFFER_SIZE, "???");
    else
        snprintf(buffer, BUFFER_SIZE, "%s+%#lx/%#lx", name, offset, size);

    printk(fmt, buffer);

    spin_unlock_irqrestore(&lock, flags);
}
Пример #3
0
static char *pointer(char *str, char *end, const char **fmt_ptr,
                     const void *arg, int field_width, int precision,
                     int flags)
{
    const char *fmt = *fmt_ptr, *s;

    /* Custom %p suffixes. See XEN_ROOT/docs/misc/printk-formats.txt */
    switch ( fmt[1] )
    {
    case 'h': /* Raw buffer as hex string. */
    {
        const uint8_t *hex_buffer = arg;
        unsigned int i;

        /* Consumed 'h' from the format string. */
        ++*fmt_ptr;

        /* Bound user count from %* to between 0 and 64 bytes. */
        if ( field_width <= 0 )
            return str;
        if ( field_width > 64 )
            field_width = 64;

        for ( i = 0; ; )
        {
            /* Each byte: 2 chars, 0-padded, base 16, no hex prefix. */
            str = number(str, end, hex_buffer[i], 16, 2, -1, ZEROPAD);

            if ( ++i == field_width )
                return str;

            if ( str < end )
                *str = ' ';
            ++str;
        }
    }

    case 's': /* Symbol name with offset and size (iff offset != 0) */
    case 'S': /* Symbol name unconditionally with offset and size */
    {
        unsigned long sym_size, sym_offset;
        char namebuf[KSYM_NAME_LEN+1];

        /* Advance parents fmt string, as we have consumed 's' or 'S' */
        ++*fmt_ptr;

        s = symbols_lookup((unsigned long)arg, &sym_size, &sym_offset, namebuf);

        /* If the symbol is not found, fall back to printing the address */
        if ( !s )
            break;

        /* Print symbol name */
        str = string(str, end, s, -1, -1, 0);

        if ( fmt[1] == 'S' || sym_offset != 0 )
        {
            /* Print '+<offset>/<len>' */
            str = number(str, end, sym_offset, 16, -1, -1, SPECIAL|SIGN|PLUS);
            if ( str < end )
                *str = '/';
            ++str;
            str = number(str, end, sym_size, 16, -1, -1, SPECIAL);
        }

        return str;
    }

    case 'v': /* d<domain-id>v<vcpu-id> from a struct vcpu */
    {
        const struct vcpu *v = arg;

        ++*fmt_ptr;
        if ( str < end )
            *str = 'd';
        str = number(str + 1, end, v->domain->domain_id, 10, -1, -1, 0);
        if ( str < end )
            *str = 'v';
        return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
    }
    }

    if ( field_width == -1 )
    {
        field_width = 2 * sizeof(void *);
        flags |= ZEROPAD;
    }

    return number(str, end, (unsigned long)arg,
                  16, field_width, precision, flags);
}