[RFC] New info command for win32 native target

Pierre Muller
2002-02-06T10:23:17Z

This patch adds a new win32 native specific command:
"info sel"

This new info command comes in two modes:

--with an expression as argument:
(gdb) info sel exp
will parse the exp as a long value and display the
info returned by GetThreadSelectorEntry API function

--without argument
(gdb) info sel
without any argument will dispaly the info returned
for cs,ds and fs selectors.

Examples:

(gdb) inf sel
Selector 0x001b: "Cs". Execute-readable code segment.
Base address = 0x00000000. Limit = 0xffffffff.
Priviledge level = 3. Page granular.
Selector 0x0023: "Ds". Read-write data segment.
Base address = 0x00000000. Limit = 0xffffffff.
Priviledge level = 3. Page granular.
Selector 0x0038: "Fs". Read-write data segment.
Base address = 0x7ffde000. Limit = 0x00000fff.
Priviledge level = 3. Byte granular.

(gdb) inf sel 0
Selector 0x0000: "0". System selector (Not accessed) Read-only data segment.
Base address = 0x00000000. Limit = 0x00000000.
Priviledge level = 0. Byte granular.

The second example seems to indicate a Selector LDT entry that is totally zeroed.

(gdb) inf sel $fs
Selector 0x0038: "$fs". Read-write data segment.
Base address = 0x7ffde000. Limit = 0x00000fff.
Priviledge level = 3. Byte granular.

Note that the base address of both ds and cs selectors are 0.
Otherwise the ReadProcessMemory and WriteProcessMemory
functions wouldn't work correctly as the arguments should be linear addresses
(which means that the selector base should be added to the address).
This allows to find out where to look for the $fs selector stack
(for inspection of the exception chain for instance).

Note also that I had to base on the Pentium docs rather than on the API docs
to get a reasonable output (especially for the Type field of LDT_ENTRY struct).

Several things could probably be cleaner,
I am waiting for your opinions.

2002-02-06 Pierre Muller <muller@ics.u-strasbg.fr>

* win32-nat.c (display_selector): New function. Displays information
about the information returned by GetThreadSelectorEntry API function.
(display_selectors): New function. Displays the infomation of
the selector given as argument, or of CS, DS ans FS selectors
if no argument is given.
( _initialize_inftarg): Add "sel" info command, with "selector" alias.

Index: win32-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/win32-nat.c,v
retrieving revision 1.47
diff -u -p -r1.47 win32-nat.c
--- win32-nat.c 2002/02/06 09:27:29 1.47
+++ win32-nat.c 2002/02/06 10:11:43
@@ -825,6 +825,93 @@ handle_output_debug_string (struct targe
return gotasig;
}

+static int
+display_selector (HANDLE thread, DWORD sel, char * name)
+{
+ LDT_ENTRY info;
+ if (GetThreadSelectorEntry (thread, sel, &info))
+ {
+ int base, limit;
+ printf ("Selector 0x%04lx: \"%s\". ", sel, name ? name : " ");
+ if ((info.HighWord.Bits.Type & 0x10) == 0)
+ printf("System selector ");
+ if ((info.HighWord.Bits.Type & 0x1) == 0)
+ printf("(Not accessed) ");
+ switch ((info.HighWord.Bits.Type & 0xf) >> 1)
+ {
+ case 0:
+ printf ("Read-only data segment.\n");
+ break;
+ case 1:
+ printf ("Read-write data segment.\n");
+ break;
+ case 2:
+ printf ("Unused segment.\n");
+ break;
+ case 3:
+ printf ("Read-write expand-down data segment.\n");
+ break;
+ case 4:
+ printf ("Execute-only code segment.\n");
+ break;
+ case 5:
+ printf ("Execute-readable code segment.\n");
+ break;
+ case 6:
+ printf ("Execute-only conforming code segment.\n");
+ break;
+ case 7:
+ printf ("Execute-readable conforming segment.\n");
+ break;
+ default:
+ printf("Unknown type 0x%x.\n",info.HighWord.Bits.Type);
+ }
+ base = (info.HighWord.Bits.BaseHi << 24) +
+ (info.HighWord.Bits.BaseMid << 16)
+ + info.BaseLow;
+ limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
+ if (info.HighWord.Bits.Granularity)
+ limit = (limit << 12) | 0xfff;
+ printf ("Base address = 0x%08x. Limit = 0x%08x.\n", base, limit);
+ printf ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
+ if (info.HighWord.Bits.Granularity)
+ printf ("Page granular.\n");
+ else
+ printf ("Byte granular.\n");
+ return 1;
+ }
+ else
+ {
+ printf ("Invalid selector 0x%lx.\n",sel);
+ return 0;
+ }
+}
+
+static void
+display_selectors (char * args, int from_tty)
+{
+ if (!current_thread)
+ {
+ printf ("Impossible to display selectors now.\n");
+ return;
+ }
+ if (!args)
+ {
+ display_selector (current_thread->h,
+ current_thread->context.SegCs, "Cs");
+ display_selector (current_thread->h,
+ current_thread->context.SegDs, "Ds");
+ display_selector (current_thread->h,
+ current_thread->context.SegFs, "Fs");
+ }
+ else
+ {
+ int sel;
+ sel = parse_and_eval_long (args);
+ display_selector (current_thread->h, sel, args);
+ }
+}
+
#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
printf ("gdb: Target exception %s at 0x%08lx\n", x, \
(DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
@@ -1702,6 +1789,9 @@ _initialize_inftarg (void)

add_info ("dll", info_dll_command, "Status of loaded DLLs.");
add_info_alias ("sharedlibrary", "dll", 1);
+
+ add_info ("sel", display_selectors, "Display selectors infos.");
+ add_info_alias ("selector", "sel", 1);

add_target (&child_ops);
}

Pierre Muller
Institut Charles Sadron
6,rue Boussingault
F 67083 STRASBOURG CEDEX (France)
mailto:muller@ics.u-strasbg.fr
Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99