public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* A gdb pretty print for CHAR16 question. Need some gdb help.
@ 2021-07-15  5:15 Andrew Fish
  2021-07-15 19:53 ` Andrew Fish
  0 siblings, 1 reply; 2+ messages in thread
From: Andrew Fish @ 2021-07-15  5:15 UTC (permalink / raw)
  To: edk2-devel-groups-io

[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]

I’ve been watching the Le Tour replays and playing around with gdb scripts. I was trying to figure out how to do stuff I know how to do in lldb. 

For lldb I have Pretty Printer and for CHAR16 things like this:

CHAR16 gChar    = L'X';
CHAR16 gStr[]   = L"1234567890\x23f3"; 
CHAR16 *gStrPtr = gStr;      

For lldb I get:
L’X’
L”1234567890⏳”
(CHAR16 *)L”1234567890⏳”

The default for gdb is:
(gdb) p /r gChar
$8 = 88
(gdb) p /r gStr
$9 = {49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 9203, 0}
(gdb) p /r gStrPtr
$10 = (CHAR16 *) 0x100008030 <gStr>

I’ve figured out how to teach GDB to pretty print CHAR16, but I can’t figure out how to hook CHAR16 * or CHAR16 {}?

This is what I’ve got (vs what gdb does for char):
$1 = 88 'X'
$2 = L'X'
 
$3 = "1234567890"
$4 = {L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'0', L'⏳', L'\x00'}
 
$5 = 0x100008058 <Str> "1234567890"
$6 = (CHAR16 *) 0x100008030 <gStr>

This is the script...
$ cat CHAR16.py
import gdb

from gdb.printing import register_pretty_printer
from gdb.printing import RegexpCollectionPrettyPrinter


class CHAR16_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        if int(self.val) < 0x20:
            return f"L'\\x{int(self.val):02x}'"
        else:
            return f"L'{chr(self.val):s}'"


def build_pretty_printer():
    pp = RegexpCollectionPrettyPrinter("EFI")
    pp.add_printer('CHAR16', '^CHAR16$', CHAR16_PrettyPrinter)
    return pp


register_pretty_printer(None, build_pretty_printer(), replace=True)

$ cat CHAR16.c
#include <stdio.h>

///
/// 2-byte Character.  Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short      CHAR16;

CHAR16 gChar    = L'X';
CHAR16 gChar2   = L'\x23f3';
CHAR16 gStr[]   = L"1234567890\x23f3"; 
CHAR16 *gStrPtr = gStr;      

char Char       = 'X';
char Str[]      = "1234567890";
char *StrPtr    = Str;

int
main(int argc, char **argv)
{
  printf ("hello world!\n");
  return 0;
}

$ cat CHAR16.sh
gcc -fshort-wchar -g CHAR16.c
gdb  -ex "source CHAR16.py" -ex "p Char" -ex "p gChar" -ex "shell echo ' '" -ex "p Str" -ex "p gStr" -ex "shell echo ' '" -ex "p StrPtr" -ex "p gStrPtr”

Given the above example you should be able to experiment with just the code in this email to figure out how to get CHAR16 working. No edk2 or EFI knowledge required, in case you have a friend who is good with gdb pretty print?

If you have CHAR16.sh, CHAR16.c, and CHAR16.py you can just run ./CHAR16.sh and it will print out the results for char and CHAR16 if you modify the CHAR16.py gdb Python script it will show you the results. 

Thanks,

Andrew Fish





[-- Attachment #2.1: Type: text/html, Size: 10824 bytes --]

[-- Attachment #2.2: CHAR16.py --]
[-- Type: text/x-python-script, Size: 614 bytes --]

#!/usr/bin/python3

import gdb

from gdb.printing import register_pretty_printer
from gdb.printing import RegexpCollectionPrettyPrinter


class CHAR16_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        if int(self.val) < 0x20:
            return f"L'\\x{int(self.val):02x}'"
        else:
            return f"L'{chr(self.val):s}'"


def build_pretty_printer():
    pp = RegexpCollectionPrettyPrinter("EFI")
    pp.add_printer('CHAR16', '^CHAR16$', CHAR16_PrettyPrinter)
    return pp


register_pretty_printer(None, build_pretty_printer(), replace=True)

[-- Attachment #2.3: CHAR16.c --]
[-- Type: application/octet-stream, Size: 507 bytes --]

#include <stdio.h>

///
/// 2-byte Character.  Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short      CHAR16;

CHAR16 gChar    = L'X';
CHAR16 gChar2   = L'\x23f3';
CHAR16 gStr[]   = L"1234567890\x23f3"; 
CHAR16 *gStrPtr = gStr;      

char Char       = 'X';
char Str[]      = "1234567890";
char *StrPtr    = Str;

int
main(int argc, char **argv)
{
  printf ("hello world!\n");
  return 0;
}

[-- Attachment #2.4: CHAR16.sh --]
[-- Type: application/octet-stream, Size: 206 bytes --]

/opt/brew/bin/gcc-11 -fshort-wchar -g CHAR16.c
gdb  -ex "source CHAR16.py" -ex "p Char" -ex "p gChar" -ex "shell echo ' '" -ex "p Str" -ex "p gStr" -ex "shell echo ' '" -ex "p StrPtr" -ex "p gStrPtr" a.out

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-07-15 19:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-15  5:15 A gdb pretty print for CHAR16 question. Need some gdb help Andrew Fish
2021-07-15 19:53 ` Andrew Fish

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox