[ros-diffs] [tkreuzer] 40759: Merge from amd64-branch: 37291, 3730, 37305, 37320, 37329, 37462, 37895, 38129, 38330, 38331, 38341, 38947, 38973, 39072, 39114, 39121, 40605 Implement rsym64 (Timo Kreuzer)

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Fri May 1 14:31:03 CEST 2009


Author: tkreuzer
Date: Fri May  1 16:31:02 2009
New Revision: 40759

URL: http://svn.reactos.org/svn/reactos?rev=40759&view=rev
Log:
Merge from amd64-branch:
37291, 3730, 37305, 37320, 37329, 37462, 37895, 38129, 38330, 38331, 38341, 38947, 38973, 39072, 39114, 39121, 40605
Implement rsym64 (Timo Kreuzer)

Added:
    trunk/reactos/tools/rsym/dwarf2.h
      - copied, changed from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h
    trunk/reactos/tools/rsym/rsym64.c
      - copied, changed from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c
    trunk/reactos/tools/rsym/rsym64.h
      - copied, changed from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h
Modified:
    trunk/reactos/tools/raddr2line.c
    trunk/reactos/tools/rsym/rsym.c   (props changed)
    trunk/reactos/tools/rsym/rsym.h   (contents, props changed)
    trunk/reactos/tools/rsym/rsym.mak   (contents, props changed)
    trunk/reactos/tools/rsym/rsym_common.c   (props changed)

Modified: trunk/reactos/tools/raddr2line.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/raddr2line.c?rev=40759&r1=40758&r2=40759&view=diff
==============================================================================
--- trunk/reactos/tools/raddr2line.c [iso-8859-1] (original)
+++ trunk/reactos/tools/raddr2line.c [iso-8859-1] Fri May  1 16:31:02 2009
@@ -18,8 +18,8 @@
 
 size_t fixup_offset ( size_t ImageBase, size_t offset )
 {
-	if ( offset >= ImageBase )
-		offset -= ImageBase;
+//	if ( offset >= ImageBase )
+//		offset -= ImageBase;
 	return offset;
 }
 

Copied: trunk/reactos/tools/rsym/dwarf2.h (from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h)
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/dwarf2.h?p2=trunk/reactos/tools/rsym/dwarf2.h&p1=branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h&r1=37291&r2=40759&rev=40759&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/dwarf2.h [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/dwarf2.h [iso-8859-1] Fri May  1 16:31:02 2009
@@ -802,27 +802,39 @@
 
 typedef struct
 {
-    ULONG Length;
+    unsigned long Length;
     char *Next;
     char *CiePointer;
-    ULONG PcBegin;
-    ULONG PcRange;
-    ULONG AugLength;
+    unsigned long PcBegin;
+    unsigned long PcRange;
+    unsigned long AugLength;
     char *AugData;
     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
 {
-    ULONG Location;
-    ULONG Code;
-    ULONG Reg;
-    ULONG Reg2;
-    ULONG FramePtr;
-    ULONG FramePtrDiff;
-    ULONG Offset;
-    ULONG IsUwop;
-    ULONG Scope;
+    unsigned long Location;
+    unsigned long Code;
+    unsigned long Reg;
+    unsigned long Reg2;
+    long FramePtr;
+    long FramePtrDiff;
+    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))

Propchange: trunk/reactos/tools/rsym/rsym.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri May  1 16:31:02 2009
@@ -1,0 +1,1 @@
+/branches/ros-amd64-bringup/reactos/tools/rsym/rsym.c:37291,37302,37305,37320,37329,37462,37895,38129,38330-38331,38341,38947,38973,39072,39114,39121,40605

Modified: trunk/reactos/tools/rsym/rsym.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/rsym.h?rev=40759&r1=40758&r2=40759&view=diff
==============================================================================
--- trunk/reactos/tools/rsym/rsym.h [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/rsym.h [iso-8859-1] Fri May  1 16:31:02 2009
@@ -14,9 +14,26 @@
 #define IMAGE_DIRECTORY_ENTRY_BASERELOC	5
 
 #define IMAGE_SCN_TYPE_NOLOAD     0x00000002
+#define IMAGE_SCN_TYPE_NO_PAD     0x00000008
+#define IMAGE_SCN_CNT_CODE        0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080
+#define IMAGE_SCN_LNK_OTHER       0x00000100
+#define IMAGE_SCN_LNK_INFO        0x00000200
 #define IMAGE_SCN_LNK_REMOVE      0x00000800
+#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000
+#define IMAGE_SCN_GPREL           0x00008000
+#define IMAGE_SCN_MEM_PURGEABLE   0x00020000
+#define IMAGE_SCN_MEM_LOCKED      0x00040000
+#define IMAGE_SCN_MEM_PRELOAD     0x00080000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED  0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED   0x08000000
+#define IMAGE_SCN_MEM_SHARED      0x10000000
+#define IMAGE_SCN_MEM_EXECUTE     0x20000000
 #define IMAGE_SCN_MEM_READ        0x40000000
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_WRITE       0x80000000
 
 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
 

Propchange: trunk/reactos/tools/rsym/rsym.h
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri May  1 16:31:02 2009
@@ -1,0 +1,1 @@
+/branches/ros-amd64-bringup/reactos/tools/rsym/rsym.h:37291,37302,37305,37320,37329,37462,37895,38129,38330-38331,38341,38947,38973,39072,39114,39121,40605

Modified: trunk/reactos/tools/rsym/rsym.mak
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/rsym.mak?rev=40759&r1=40758&r2=40759&view=diff
==============================================================================
--- trunk/reactos/tools/rsym/rsym.mak [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/rsym.mak [iso-8859-1] Fri May  1 16:31:02 2009
@@ -18,9 +18,15 @@
 RSYM_TARGET = \
 	$(RSYM_OUT_)rsym$(EXEPOSTFIX)
 
+ifeq ($(ARCH),amd64)
+RSYM_SOURCES = \
+	$(RSYM_BASE_)rsym64.c \
+	$(RSYM_BASE_)rsym_common.c
+else
 RSYM_SOURCES = \
 	$(RSYM_BASE_)rsym.c \
 	$(RSYM_BASE_)rsym_common.c
+endif
 
 RSYM_OBJECTS = \
 	$(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.c=.o))
@@ -44,6 +50,10 @@
 	$(ECHO_CC)
 	${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@
 
+$(RSYM_INT_)rsym64.o: $(RSYM_BASE_)rsym64.c | $(RSYM_INT)
+	$(ECHO_CC)
+	${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@
+
 $(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.c | $(RSYM_INT)
 	$(ECHO_CC)
 	${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@

Propchange: trunk/reactos/tools/rsym/rsym.mak
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri May  1 16:31:02 2009
@@ -1,0 +1,1 @@
+/branches/ros-amd64-bringup/reactos/tools/rsym/rsym.mak:37291,37302,37305,37320,37329,37462,37895,38129,38330-38331,38341,38947,38973,39072,39114,39121,40605

Copied: trunk/reactos/tools/rsym/rsym64.c (from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c)
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/rsym64.c?p2=trunk/reactos/tools/rsym/rsym64.c&p1=branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c&r1=37291&r2=40759&rev=40759&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/rsym64.c [iso-8859-1] Fri May  1 16:31:02 2009
@@ -5,6 +5,11 @@
 #include "rsym.h"
 #include "rsym64.h"
 #include "dwarf2.h"
+
+char DoPrint = 0;
+ULONG g_ehframep;
+
+#define DPRINT if(DoPrint) printf
 
 struct {char *name; char regnt;} regs[] =
 { {"rax", REG_RAX}, {"rdx", REG_RDX}, {"rcx", REG_RCX}, {"rbx", REG_RBX},
@@ -35,7 +40,7 @@
 	{
 		current = pc[ulSize];
 		ulSize++;
-		ulResult |= current & 0x7f << ulShift;
+		ulResult |= (current & 0x7f) << ulShift;
 		ulShift += 7;
 	}
 	while (current & 0x80);
@@ -56,7 +61,7 @@
 	{
 		current = pc[ulSize];
 		ulSize++;
-		lResult |= current & 0x7f << ulShift;
+		lResult |= (current & 0x7f) << ulShift;
 		ulShift += 7;
 	}
 	while (current & 0x80);
@@ -87,7 +92,7 @@
     pc += Cie->AugLength;
     Cie->Instructions = pc;
 
-    return Cie->Length;
+    return Cie->Length + 4;
 }
 
 unsigned long
@@ -103,7 +108,7 @@
     Fde->AugData = pc;
     Fde->Instructions = Fde->AugData + Fde->AugLength;
 
-    return Fde->Length;
+    return Fde->Length + 4;
 }
 
 unsigned long
@@ -126,7 +131,7 @@
     {
         State->Code = DW_CFA_offset;
         State->Reg = Code & 0x3f;
-        Length += DwDecodeUleb128(&State->Offset, pc + 1);
+        Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + 1);
         State->Offset *= 8; // fixme data alignment
         State->IsUwop = 1;
     }
@@ -149,15 +154,24 @@
             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);
-            Length += DwDecodeUleb128(&State->Offset, pc + Length);
+            Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + Length);
+            State->IsUwop = 1;
+            break;
+        case DW_CFA_offset_extended_sf:
+            Length += DwDecodeUleb128(&State->Reg, pc + Length);
+            Length += DwDecodeSleb128(&State->Offset, pc + Length);
             State->IsUwop = 1;
             break;
         case DW_CFA_restore_extended:
@@ -179,37 +193,109 @@
             break;
         case DW_CFA_def_cfa:
             Length += DwDecodeUleb128(&State->Reg, pc + Length);
-            Length += DwDecodeUleb128(&State->FramePtr, pc + Length);
+            Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
             State->IsUwop = 1;
             break;
         case DW_CFA_def_cfa_register:
             Length += DwDecodeUleb128(&State->Reg, pc + Length);
             break;
         case DW_CFA_def_cfa_offset:
-            Length += DwDecodeUleb128(&State->FramePtr, pc + Length);
+            Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
             State->IsUwop = 1;
             break;
         case DW_CFA_def_cfa_sf:
             Length += DwDecodeUleb128(&State->Reg, pc + Length);
-            Length += DwDecodeSleb128((LONG*)&State->FramePtr, pc + Length);
+            Length += DwDecodeSleb128(&State->FramePtr, pc + Length);
             State->FramePtr *= 8; // data alignment
             State->IsUwop = 1;
             break;
-        /* PSEH types */
-        case 0x1c:
-            State->Scope = 1;
-            break;
-        case 0x1d:
-            State->Scope = 2;
-            break;
+        case DW_CFA_GNU_args_size:
+        {
+            unsigned long argsize;
+            printf("Warning, DW_CFA_GNU_args_size is unimplemented\n");
+            Length += DwDecodeUleb128(&argsize, pc + Length);
+            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);
     }
     
     State->FramePtrDiff = State->FramePtr - PrevFramePtr;
-    
-//printf("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n", pc, code, State->Location, State->Offset, State->Reg, regnames_64[State->Reg]);
+    DPRINT("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n", 
+        (void*)((ULONG)pc - g_ehframep), Code, State->Location, State->Offset, State->Reg, regs[State->Reg].name);
     return Length;
 }
 
@@ -268,8 +354,8 @@
             {
                 Code[0].UnwindOp = UWOP_ALLOC_LARGE;
                 Code[0].OpInfo = 1;
-                Code[1].FrameOffset = (AllocSize / 8);
-                Code[2].FrameOffset = (AllocSize / 8) >> 16;
+                Code[1].FrameOffset = (USHORT)AllocSize;
+                Code[2].FrameOffset = (USHORT)(AllocSize >> 16);
                 cCodes = 3;
             }
             break;
@@ -294,9 +380,6 @@
 
     return cCodes;
 }
-
-#define GetSectionPointer(Info, i) \
-    ((void*)(Info->FilePtr + Info->SectionHeaders[i].PointerToRawData))
 
 #define GetxdataSize(cFuncs, cUWOP, cScopes) \
     ( cFuncs * (sizeof(UNWIND_INFO) + 2 + 4 + 4) \
@@ -326,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;
@@ -346,16 +431,39 @@
             cbSize += c * sizeof(UNWIND_CODE);
             Info->SizeOfProlog = State.Location - FunctionStart;
         }
-//        else if
-        // if is scope
-            // if is first scope
-                // align 4
-                // emit gcc_specific handler
-                // create pointer to C_SCOPE_TABLE
-            // 
-
     }
     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;
 }
@@ -365,16 +473,18 @@
 {
     DW2CIEFDE *p;
     DW2FDE Fde;
-    char *pInst;
+    char *pInst, *pmax;
     DW2CFSTATE State;
 
     File->cFuncs = 0;
     File->cScopes = 0;
     File->cUWOP = 0;
     State.FramePtr = 0;
-
-    p = GetSectionPointer(File, File->eh_frame.idx);
-    for (; p->Length; p = NextCIE(p))
+    State.TryLevel = 0;
+
+    p = File->eh_frame.p;
+    pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
+    for (; p->Length && (char*)p < pmax; p = NextCIE(p))
     {
         /* Is this an FDE? */
         if (p->CiePointer != 0)
@@ -415,25 +525,37 @@
     ULONG cbSize;
     PIMAGE_SECTION_HEADER pshp, pshx;
     ULONG FileAlignment;
+    char *pmax;
 
     FileAlignment = File->OptionalHeader->FileAlignment;
 
     /* Get pointer to eh_frame section */
-    eh_frame = GetSectionPointer(File, File->eh_frame.idx);
+    eh_frame = File->eh_frame.p;
+    g_ehframep = (ULONG)eh_frame;
 
     /* Get sizes */
     CountUnwindData(File);
 //    printf("cFuncs = %ld, cUWOPS = %ld, cScopes = %ld\n", 
 //        File->cFuncs, File->cUWOP, File->cScopes);
 
-    /* Allocate .pdata buffer */
-    File->pdata.idx = File->UsedSections;
-    pshp = File->pdata.psh = &File->SectionHeaders[File->pdata.idx];
+    /* Initialize section header for .pdata */
+    i = File->pdata.idx = File->UsedSections;
+    pshp = File->pdata.psh = &File->NewSectionHeaders[i];
     memcpy(pshp->Name, ".pdata", 7);
     pshp->Misc.VirtualSize = (File->cFuncs + 1) * sizeof(RUNTIME_FUNCTION);
-//    pshp->VirtualAddress = 
+    pshp->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
+                           File->NewSectionHeaders[i - 1].SizeOfRawData;
     pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
-//    pshp->PointerToRawData = 
+    pshp->PointerToRawData = File->NewSectionHeaders[i - 1].PointerToRawData +
+                           File->NewSectionHeaders[i - 1].SizeOfRawData;
+    pshp->PointerToRelocations = 0;
+    pshp->PointerToLinenumbers = 0;
+    pshp->NumberOfRelocations = 0;
+    pshp->NumberOfLinenumbers = 0;
+    pshp->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
+                            IMAGE_SCN_CNT_INITIALIZED_DATA;
+
+    /* Allocate .pdata buffer */
     pdata = File->pdata.p = malloc(pshp->SizeOfRawData);
     memset(File->pdata.p, pshp->SizeOfRawData, 0);
 
@@ -442,22 +564,32 @@
     Dir->VirtualAddress = pshp->VirtualAddress;
     Dir->Size = pshp->Misc.VirtualSize;
 
-    /* Allocate .xdata buffer */
+    /* Initialize section header for .xdata */
     File->xdata.idx = File->pdata.idx + 1;
-    pshx = File->xdata.psh = &File->SectionHeaders[File->xdata.idx];
+    pshx = File->xdata.psh = &File->NewSectionHeaders[File->xdata.idx];
     memcpy(pshx->Name, ".xdata", 7);
     pshx->Misc.VirtualSize = GetxdataSize(File->cFuncs, File->cUWOP, File->cScopes);
     pshx->VirtualAddress = pshp->VirtualAddress + pshp->SizeOfRawData;
     pshx->SizeOfRawData = ROUND_UP(pshx->Misc.VirtualSize, FileAlignment);
     pshx->PointerToRawData = pshp->PointerToRawData + pshp->SizeOfRawData;
+    pshx->PointerToRelocations = 0;
+    pshx->PointerToLinenumbers = 0;
+    pshx->NumberOfRelocations = 0;
+    pshx->NumberOfLinenumbers = 0;
+    pshx->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
+                            IMAGE_SCN_CNT_INITIALIZED_DATA;
+
+    /* Allocate .xdata buffer */
     File->xdata.p = malloc(pshx->SizeOfRawData);
-    memset(File->pdata.p, pshx->SizeOfRawData, 0);
+    memset(File->xdata.p, pshx->SizeOfRawData, 0);
 
     i = 0;
     Offset = File->eh_frame.psh->VirtualAddress;
     xdata_va = pshx->VirtualAddress;
     xdata_p = File->xdata.p;
-    for (p = eh_frame; p->Length; p = NextCIE(p))
+    pmax = (char*)eh_frame + File->eh_frame.psh->Misc.VirtualSize - 100;
+
+    for (p = eh_frame; p->Length && (char*)p < pmax; p = NextCIE(p))
     {
         /* Is this an FDE? */
         if (p->CiePointer != 0)
@@ -492,7 +624,7 @@
     DWORD i;
     DWORD checksum = Start;
 
-    for (i = 0; i < (cbSize + 1) / sizeof(WORD); i += 1)
+    for (i = 0; i < (cbSize + 1) / sizeof(WORD); i++)
     {
         checksum += Ptr[i];
         checksum = (checksum + (checksum >> 16)) & 0xffff;
@@ -504,24 +636,74 @@
 void
 WriteOutFile(FILE *handle, PFILE_INFO File)
 {
-    int ret, Size, Pos;
-    DWORD Checksum;
-
-    /* Correct section count */
+    int ret, Size, Pos = 0;
+    DWORD CheckSum;
+    ULONG i, Alignment;
+
+    Alignment = File->OptionalHeader->FileAlignment;
+
+    /* Update section count */
     File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
 
-    /* Calculate size of file beginning */
-    Size = File->SectionHeaders[File->UsedSections].PointerToRawData;
+    /* Update SizeOfImage */
+    Size = File->xdata.psh->VirtualAddress
+           + File->xdata.psh->SizeOfRawData;
+    File->OptionalHeader->SizeOfImage = Size;
 
     /* Recalculate checksum */
-    Checksum = CalculateChecksum(0, File->FilePtr, Size);
-    Checksum = CalculateChecksum(Checksum, File->pdata.p, File->pdata.psh->Misc.VirtualSize);
-    Checksum = CalculateChecksum(Checksum, File->xdata.p, File->xdata.psh->Misc.VirtualSize);
-    File->OptionalHeader->CheckSum = Checksum + Size + File->pdata.psh->Misc.VirtualSize;
-
-    /* Write file beginning */
+    CheckSum = CalculateChecksum(0, File->FilePtr, File->HeaderSize);
+    for (i = 0; i < File->AllSections; i++)
+    {
+        if (File->UseSection[i])
+        {
+            Size = File->SectionHeaders[i].SizeOfRawData;
+            if (Size)
+            {
+                void *p;
+                p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
+                CheckSum = CalculateChecksum(CheckSum, p, Size);
+            }
+        }
+    }
+    Size = File->pdata.psh->Misc.VirtualSize;
+    CheckSum = CalculateChecksum(CheckSum, File->pdata.p, Size);
+    Size = File->xdata.psh->Misc.VirtualSize;
+    CheckSum = CalculateChecksum(CheckSum, File->xdata.p, Size);
+    CheckSum += File->HeaderSize;
+    CheckSum += File->pdata.psh->Misc.VirtualSize;
+    CheckSum += File->xdata.psh->Misc.VirtualSize;
+    File->OptionalHeader->CheckSum = CheckSum;
+
+    /* Write file header */
+    Size = File->HeaderSize;
     ret = fwrite(File->DosHeader, 1, Size, handle);
     Pos = Size;
+
+    /* Write Section headers */
+    Size = File->NewSectionHeaderSize;
+    ret = fwrite(File->NewSectionHeaders, 1, Size, handle);
+    Pos += Size;
+
+    /* Fill up to next alignement */
+    Size = ROUND_UP(Pos, Alignment) - Pos;
+    ret = fwrite(File->AlignBuf, 1, Size, handle);
+    Pos += Size;
+
+    /* Write sections */
+    for (i = 0; i < File->AllSections; i++)
+    {
+        if (File->UseSection[i])
+        {
+            void *p;
+            Size = File->SectionHeaders[i].SizeOfRawData;
+            if (Size)
+            {
+                p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
+                ret = fwrite(p, 1, Size, handle);
+                Pos += Size;
+            }
+        }
+    }
 
     /* Write .pdata section */
     Size = File->pdata.psh->SizeOfRawData;
@@ -540,35 +722,38 @@
 ParsePEHeaders(PFILE_INFO File)
 {
     DWORD OldChecksum, Checksum;
-    int i;
+    ULONG Alignment, CurrentPos;
+    int i, j;
 
     /* Check if MZ header exists  */
     File->DosHeader = (PIMAGE_DOS_HEADER)File->FilePtr;
-    if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) || File->DosHeader->e_lfanew == 0L)
+    if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) || 
+        (File->DosHeader->e_lfanew == 0L))
     {
         perror("Input file is not a PE image.\n");
-        return 0;
+        return -1;
     }
 
     /* Locate PE file header  */
     File->FileHeader = (PIMAGE_FILE_HEADER)(File->FilePtr + 
-                                     File->DosHeader->e_lfanew + sizeof(ULONG));
+                               File->DosHeader->e_lfanew + sizeof(ULONG));
+
+    /* Check for x64 image */
     if (File->FileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
     {
         perror("Input file is not an x64 image.\n");
-        return 0;
+        return -1;
     }
 
     /* Locate optional header */
     File->OptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(File->FileHeader + 1);
-    File->ImageBase = File->OptionalHeader->ImageBase;
 
     /* Check if checksum is correct */
     OldChecksum = File->OptionalHeader->CheckSum;
     File->OptionalHeader->CheckSum = 0;
-    Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize)
-               + File->cbInFileSize;
-    if (Checksum != OldChecksum)
+    Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize);
+    Checksum += File->cbInFileSize;
+    if ((Checksum & 0xffff) != (OldChecksum & 0xffff))
     {
         fprintf(stderr, "Input file has incorrect PE checksum: 0x%lx (calculated: 0x%lx)\n",
             OldChecksum, Checksum);
@@ -587,38 +772,81 @@
     if (!File->FileHeader->PointerToSymbolTable)
     {
         fprintf(stderr, "No symbol table.\n");
-        return 0;
-    }
-
+        return -1;
+    }
+
+    /* Create some shortcuts */
+    File->ImageBase = File->OptionalHeader->ImageBase;
     File->Symbols = File->FilePtr + File->FileHeader->PointerToSymbolTable;
     File->Strings = (char*)File->Symbols + File->FileHeader->NumberOfSymbols * 18;
 
     /* Check section names */
     File->AllSections = File->FileHeader->NumberOfSections;
+    Alignment = File->OptionalHeader->FileAlignment;
+    File->NewSectionHeaders = malloc((File->AllSections+2) * sizeof(IMAGE_SECTION_HEADER));
+    File->UsedSections = 0;
     File->eh_frame.idx = -1;
+
+    /* Allocate array of chars, specifiying wheter to copy the section */
+    File->UseSection = malloc(File->AllSections);
+
     for (i = 0; i < File->AllSections; i++)
     {
         char *pName = (char*)File->SectionHeaders[i].Name;
+        File->UseSection[i] = 1;
 
         /* Check for long name */
         if (pName[0] == '/')
         {
             unsigned long index = strtoul(pName+1, 0, 10);
             pName = File->Strings + index;
-        }
-        else
-        {
-            /* Mark last section with a short name */
-            File->UsedSections = i + 1;
-        }
-
+            
+            // Hack, simply remove all sections with long names
+            File->UseSection[i] = 0;
+        }
+
+        /* Chek if we have the eh_frame section */
         if (strcmp(pName, ".eh_frame") == 0)
         {
+            File->eh_frame.psh = &File->SectionHeaders[i];
             File->eh_frame.idx = i;
-            File->eh_frame.psh = &File->SectionHeaders[i];
-            File->eh_frame.p = GetSectionPointer(File, i);
-        }
-
+            File->eh_frame.p = File->FilePtr + File->eh_frame.psh->PointerToRawData;
+        }
+        
+        /* Increase number of used sections */
+        if (File->UseSection[i])
+            File->UsedSections = i+1;
+
+    }
+
+    /* This is the actual size of the new section headers */
+    File->NewSectionHeaderSize = 
+        (File->UsedSections+2) * sizeof(IMAGE_SECTION_HEADER);
+
+    /* Calculate the position to start writing the sections to */
+    CurrentPos = File->HeaderSize + File->NewSectionHeaderSize;
+    CurrentPos = ROUND_UP(CurrentPos, Alignment);
+
+    /* Create new section headers */
+    for (i = 0, j = 0; i < File->UsedSections; i++)
+    {
+        /* Copy section header */
+        File->NewSectionHeaders[j] = File->SectionHeaders[i];
+
+        /* Shall we strip the section? */
+        if (File->UseSection[i] == 0)
+        {
+            /* Make it a bss section */
+            File->NewSectionHeaders[j].PointerToRawData = 0;
+            File->NewSectionHeaders[j].SizeOfRawData = 0;
+            File->NewSectionHeaders[j].Characteristics = 0xC0500080;
+        }
+
+        /* Fix Offset into File */
+        File->NewSectionHeaders[j].PointerToRawData =
+              File->NewSectionHeaders[j].PointerToRawData ? CurrentPos : 0;
+        CurrentPos += File->NewSectionHeaders[j].SizeOfRawData;
+        j++;
     }
 
     if (File->eh_frame.idx == -1)
@@ -636,6 +864,7 @@
     char* pszOutFile;
     FILE_INFO File;
     FILE* outfile;
+    int ret;
 
     if (argc != 3)
     {
@@ -653,10 +882,11 @@
         exit(1);
     }
 
-    if (!ParsePEHeaders(&File))
+    ret = ParsePEHeaders(&File);
+    if (ret != 1)
     {
         free(File.FilePtr);
-        exit(1);
+        exit(ret == -1 ? 1 : 0);
     }
 
     File.AlignBuf = malloc(File.OptionalHeader->FileAlignment);

Copied: trunk/reactos/tools/rsym/rsym64.h (from r37291, branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h)
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/rsym64.h?p2=trunk/reactos/tools/rsym/rsym64.h&p1=branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h&r1=37291&r2=40759&rev=40759&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/rsym64.h [iso-8859-1] Fri May  1 16:31:02 2009
@@ -97,6 +97,13 @@
     USHORT FrameOffset;
 } UNWIND_CODE, *PUNWIND_CODE;
 
+enum
+{
+    UNW_FLAG_EHANDLER  = 0x01,
+    UNW_FLAG_UHANDLER  = 0x02,
+    UNW_FLAG_CHAININFO = 0x03,
+};
+
 typedef struct _UNWIND_INFO
 {
     UBYTE Version:3;
@@ -125,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;
 
 
@@ -148,11 +155,14 @@
     PIMAGE_FILE_HEADER FileHeader;
     PIMAGE_OPTIONAL_HEADER64 OptionalHeader;
     PIMAGE_SECTION_HEADER SectionHeaders;
+    PIMAGE_SECTION_HEADER NewSectionHeaders;
+    ULONG NewSectionHeaderSize;
     PIMAGE_BASE_RELOCATION Relocations;
     void *Symbols;
     char *Strings;
     ULONG64 ImageBase;
     ULONG HeaderSize;
+    char *UseSection;
 
     /* Sections */
     ULONG AllSections;

Propchange: trunk/reactos/tools/rsym/rsym_common.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri May  1 16:31:02 2009
@@ -1,0 +1,1 @@
+/branches/ros-amd64-bringup/reactos/tools/rsym/rsym_common.c:37291,37302,37305,37320,37329,37462,37895,38129,38330-38331,38341,38947,38973,39072,39114,39121,40605



More information about the Ros-diffs mailing list