Author: tkreuzer
Date: Wed Dec 24 18:20:47 2008
New Revision: 38341
URL:
http://svn.reactos.org/svn/reactos?rev=38341&view=rev
Log:
Initial x64 SEH support for rsym64. Together with the x64 SEH macros, it (partly) creates
the needed tables. It has also revealed that there is something broken with
DW_CFA_advance_loc4.
Modified:
branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h
branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c
branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h
Modified: branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h [iso-8859-1] Wed Dec 24
18:20:47 2008
@@ -812,6 +812,15 @@
char *Instructions;
} DW2FDE, *PDW2FDE;
+typedef struct _SEHBLOCK
+{
+ unsigned long BeginTry;
+ unsigned long EndTry;
+ unsigned long Target;
+ unsigned long Handler;
+ unsigned long End;
+} SEHBLOCK, *PSEHBLOCK;
+
typedef struct _CFSTATE
{
unsigned long Location;
@@ -823,6 +832,9 @@
long Offset;
unsigned long IsUwop;
unsigned long Scope;
+ unsigned long cScopes;
+ unsigned long TryLevel;
+ SEHBLOCK SehBlock[20];
} DW2CFSTATE, *PDW2CFSTATE;
#define NextCIE(p) ((void*)((char*)p + p->Length + 4))
Modified: branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c [iso-8859-1] Wed Dec 24
18:20:47 2008
@@ -154,11 +154,15 @@
break;
case DW_CFA_advance_loc2:
Length = 3;
+// printf("Found a DW_CFA_advance_loc2 : 0x%lx ->", *(WORD*)(pc +
1));
State->Location += *(WORD*)(pc + 1);
+// printf(" 0x%lx\n", State->Location);
break;
case DW_CFA_advance_loc4:
Length = 5;
+// printf("Found a DW_CFA_advance_loc4 : 0x%lx ->", *(DWORD*)(pc
+ 1));
State->Location += *(DWORD*)(pc + 1);
+// printf(" 0x%lx\n", State->Location);
break;
case DW_CFA_offset_extended:
Length += DwDecodeUleb128(&State->Reg, pc + Length);
@@ -212,19 +216,78 @@
Length += DwDecodeUleb128(&argsize, pc + Length);
break;
}
- /* PSEH types */
- case 0x1c:
- printf("found 1c at %lx\n", State->Location);
- State->Scope = 1;
- break;
- case 0x1d:
- printf("found 1d at %lx\n", State->Location);
- State->Scope = 2;
- break;
- case 0x1e:
- printf("found 1e at %lx\n", State->Location);
- State->Scope = 3;
- break;
+ /* PSEH */
+ case 0x21:
+ {
+ unsigned long SehType;
+
+// printf("found 0x21 at %lx\n", State->Location);
+ Length += DwDecodeUleb128(&SehType, pc + Length);
+ switch (SehType)
+ {
+ case 1: /* Begin Try */
+ State->TryLevel++;
+ if (State->TryLevel >= 20)
+ {
+ printf("WTF? Trylevel of 20 exceeded...\n");
+ exit(1);
+ }
+ State->SehBlock[State->TryLevel-1].BeginTry =
State->Location;
+// printf("Found begintry at 0x%lx\n", State->Location);
+ State->Scope = 1;
+ break;
+
+ case 2: /* End Try */
+ State->SehBlock[State->TryLevel-1].EndTry =
State->Location;
+ State->Scope = 2;
+ break;
+
+ case 3: /* Jump target */
+ State->SehBlock[State->TryLevel-1].Target =
State->Location;
+ State->Scope = 3;
+ break;
+
+ case 4: /* SEH End */
+ if (State->TryLevel == 20)
+ {
+ printf("Ooops, end of SEH with trylevel at 0!\n");
+ exit(1);
+ }
+ State->SehBlock[State->TryLevel-1].End = State->Location;
+ State->TryLevel--;
+ State->cScopes++;
+ State->Scope = 0;
+ break;
+
+ case 5: /* Constant filter */
+ {
+ unsigned long value;
+ Length += DwDecodeUleb128(&value, pc + Length);
+ State->SehBlock[State->TryLevel-1].Handler = value;
+// printf("Found a constant filter at 0x%lx\n",
State->Location);
+ break;
+ }
+
+ /* These work differently. We are in a new function.
+ * We have to parse a lea opcode to find the adress of
+ * the jump target. This is the reference to find the
+ * appropriate C_SCOPE_TABLE. */
+ case 6: /* Filter func */
+// printf("Found a filter func at 0x%lx\n",
State->Location);
+ break;
+
+ case 7: /* Finally func */
+ {
+// printf("Found a finally func at 0x%lx\n",
State->Location);
+ break;
+ }
+
+ default:
+ printf("Found unknow PSEH code 0x%lx\n", SehType);
+ exit(1);
+ }
+ break;
+ }
default:
fprintf(stderr, "unknown instruction 0x%x at 0x%p\n", Code, pc);
exit(1);
@@ -346,6 +409,8 @@
/* Initialize state */
State.Location = FunctionStart;
State.FramePtr = 0;
+ State.TryLevel = 0;
+ State.cScopes = 0;
/* Parse the CIE's initial instructions */
pInst = Cie.Instructions;
@@ -368,6 +433,37 @@
}
}
cbSize = ROUND_UP(cbSize, 4);
+
+ /* Do we have scope table to write? */
+ if (State.cScopes > 0)
+ {
+ unsigned long i;
+ ULONG *pExceptionHandler;
+ PC_SCOPE_TABLE pScopeTable;
+
+ /* Set flag for exception handler */
+ Info->Flags |= UNW_FLAG_EHANDLER;
+
+ /* Store address of handler and number of scope tables */
+ pExceptionHandler = (ULONG*)((char*)Info + cbSize);
+ // HACK for testing purpose
+ *pExceptionHandler = FunctionStart; // _C_specific_handler
+
+ pScopeTable = (PC_SCOPE_TABLE)(pExceptionHandler + 1);
+ pScopeTable->NumEntries = State.cScopes;
+
+ /* Store the scope table entries */
+ for (i = 0; i < State.cScopes; i++)
+ {
+ pScopeTable->Entry[i].Begin = State.SehBlock[i].BeginTry;
+ pScopeTable->Entry[i].End = State.SehBlock[i].EndTry;
+ pScopeTable->Entry[i].Handler = 1;//State.SehBlock[i].Handler;
+ pScopeTable->Entry[i].Target = State.SehBlock[i].Target;
+ }
+
+ /* Update size */
+ cbSize += 8 + State.cScopes * sizeof(C_SCOPE_TABLE_ENTRY);
+ }
return cbSize;
}
@@ -384,6 +480,7 @@
File->cScopes = 0;
File->cUWOP = 0;
State.FramePtr = 0;
+ State.TryLevel = 0;
p = File->eh_frame.p;
pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
Modified: branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h [iso-8859-1] Wed Dec 24
18:20:47 2008
@@ -132,7 +132,7 @@
typedef struct _C_SCOPE_TABLE
{
ULONG NumEntries;
- C_SCOPE_TABLE_ENTRY Table[1];
+ C_SCOPE_TABLE_ENTRY Entry[1];
} C_SCOPE_TABLE, *PC_SCOPE_TABLE;