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=4075... ============================================================================== --- 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=trun... ============================================================================== --- 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... ============================================================================== --- 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=407... ============================================================================== --- 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=trun... ============================================================================== --- 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=trun... ============================================================================== --- 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