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;