ReactOS  0.4.12-dev-432-g3463b2d
rsym64.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "rsym.h"
6 #include "rsym64.h"
7 #include "dwarf2.h"
8 
9 char DoPrint = 0;
11 
12 #define DPRINT if(DoPrint) printf
13 
14 struct {char *name; char regnt;} regs[] =
15 { {"rax", REG_RAX}, {"rdx", REG_RDX}, {"rcx", REG_RCX}, {"rbx", REG_RBX},
16  {"rsi", REG_RSI}, {"rdi", REG_RDI}, {"rbp", REG_RBP}, {"rsp", REG_RSP},
17  {"r8", REG_R8}, {"r9", REG_R9}, {"r10", REG_R10}, {"r11", REG_R11},
18  {"r12", REG_R12}, {"r13", REG_R13}, {"r14", REG_R14}, {"r15", REG_R15},
19  {"xmm0", REG_XMM0}, {"xmm1", REG_XMM1}, {"xmm2", REG_XMM2}, {"xmm3", REG_XMM3},
20  {"xmm4", REG_XMM4}, {"xmm5", REG_XMM5}, {"xmm6", REG_XMM6}, {"xmm7", REG_XMM7},
21  {"xmm8", REG_XMM8}, {"xmm9", REG_XMM9}, {"xmm10",REG_XMM10},{"xmm11",REG_XMM11},
22  {"xmm12",REG_XMM12},{"xmm13",REG_XMM13},{"xmm14",REG_XMM14},{"xmm15",REG_XMM15},
23 // "st0", "st1", "st2", "st3",
24 // "st4", "st5", "st6", "st7",
25 // "mm0", "mm1", "mm2", "mm3",
26 // "mm4", "mm5", "mm6", "mm7"
27 };
28 
31 unsigned long
32 DwDecodeUleb128(unsigned long *pResult, char *pc)
33 {
34  unsigned long ulResult = 0;
35  unsigned long ulShift = 0;
36  unsigned char current;
37  unsigned long ulSize = 0;
38 
39  do
40  {
41  current = pc[ulSize];
42  ulSize++;
43  ulResult |= (current & 0x7f) << ulShift;
44  ulShift += 7;
45  }
46  while (current & 0x80);
47 
48  *pResult = ulResult;
49  return ulSize;
50 }
51 
52 unsigned long
53 DwDecodeSleb128(long *pResult, char *pc)
54 {
55  long lResult = 0;
56  unsigned long ulShift = 0;
57  unsigned char current;
58  unsigned long ulSize = 0;
59 
60  do
61  {
62  current = pc[ulSize];
63  ulSize++;
64  lResult |= (current & 0x7f) << ulShift;
65  ulShift += 7;
66  }
67  while (current & 0x80);
68 
69  if (current & 0x40)
70  lResult |= - (1 << (ulShift));
71 
72  *pResult = lResult;
73 
74  return ulSize;
75 }
76 
77 unsigned long
78 DwDecodeCie(PDW2CIE Cie, char *pc)
79 {
80  Cie->Length = *(ULONG*)pc;
81  Cie->Next = pc + 4 + Cie->Length;
82  Cie->CieId = *(ULONG*)(pc + 4);
83  Cie->Version = pc[8];
84  Cie->AugString = pc + 9;
85  Cie->AugStringLength = strlen(Cie->AugString);
86  pc = Cie->AugString + Cie->AugStringLength + 1;
87  pc += DwDecodeUleb128(&Cie->CodeAlign, pc);
88  pc += DwDecodeSleb128(&Cie->DataAlign, pc);
89  pc += DwDecodeUleb128(&Cie->ReturnAddressRegister, pc);
90  pc += DwDecodeUleb128(&Cie->AugLength, pc);
91  Cie->AugData = pc;
92  pc += Cie->AugLength;
93  Cie->Instructions = pc;
94 
95  return Cie->Length + 4;
96 }
97 
98 unsigned long
99 DwDecodeFde(PDW2FDE Fde, char *pc)
100 {
101  Fde->Length = *(ULONG*)pc;
102  Fde->Next = pc + 4 + Fde->Length;
103  Fde->CiePointer = pc + 4 - *(ULONG*)(pc + 4);
104  Fde->PcBegin = *(ULONG*)(pc + 8);
105  Fde->PcRange = *(ULONG*)(pc + 12);
106  pc += 16;
107  pc += DwDecodeUleb128(&Fde->AugLength, pc);
108  Fde->AugData = pc;
109  Fde->Instructions = Fde->AugData + Fde->AugLength;
110 
111  return Fde->Length + 4;
112 }
113 
114 unsigned long
116 {
117  unsigned char Code;
118  unsigned long Length;
119  unsigned long PrevFramePtr = State->FramePtr;
120 
121  State->Scope = 0;
122  State->IsUwop = 0;
123  State->Code = Code = *pc;
124  Length = 1;
125  if ((Code & 0xc0) == DW_CFA_advance_loc)
126  {
127  State->Code = DW_CFA_advance_loc;
128  State->Location += Code & 0x3f;
129  }
130  else if ((Code & 0xc0) == DW_CFA_offset)
131  {
132  State->Code = DW_CFA_offset;
133  State->Reg = Code & 0x3f;
134  Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + 1);
135  State->Offset *= 8; // fixme data alignment
136  State->IsUwop = 1;
137  }
138  else if ((Code & 0xc0) == DW_CFA_restore)
139  {
140  State->Code = DW_CFA_restore;
141  State->Reg = Code & 0x3f;
142  }
143  else switch (Code)
144  {
145  case DW_CFA_nop:
146  break;
147  case DW_CFA_set_loc:
148  Length = 9; // address
149  State->Location = *(DWORD*)(pc + 1);
150  break;
151  case DW_CFA_advance_loc1:
152  Length = 2;
153  State->Location += pc[1];
154  break;
155  case DW_CFA_advance_loc2:
156  Length = 3;
157 // printf("Found a DW_CFA_advance_loc2 : 0x%lx ->", *(WORD*)(pc + 1));
158  State->Location += *(WORD*)(pc + 1);
159 // printf(" 0x%lx\n", State->Location);
160  break;
161  case DW_CFA_advance_loc4:
162  Length = 5;
163 // printf("Found a DW_CFA_advance_loc4 : 0x%lx ->", *(DWORD*)(pc + 1));
164  State->Location += *(DWORD*)(pc + 1);
165 // printf(" 0x%lx\n", State->Location);
166  break;
168  Length += DwDecodeUleb128(&State->Reg, pc + Length);
169  Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + Length);
170  State->IsUwop = 1;
171  break;
173  Length += DwDecodeUleb128(&State->Reg, pc + Length);
174  Length += DwDecodeSleb128(&State->Offset, pc + Length);
175  State->IsUwop = 1;
176  break;
178  Length += DwDecodeUleb128(&State->Reg, pc + Length);
179  break;
180  case DW_CFA_undefined:
181  Length += DwDecodeUleb128(&State->Reg, pc + Length);
182  break;
183  case DW_CFA_same_value:
184  Length += DwDecodeUleb128(&State->Reg, pc + Length);
185  break;
186  case DW_CFA_register:
187  Length += DwDecodeUleb128(&State->Reg, pc + Length);
188  Length += DwDecodeUleb128(&State->Reg2, pc + Length);
189  break;
191  break;
193  break;
194  case DW_CFA_def_cfa:
195  Length += DwDecodeUleb128(&State->Reg, pc + Length);
196  Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
197  State->IsUwop = 1;
198  break;
200  Length += DwDecodeUleb128(&State->Reg, pc + Length);
201  break;
203  Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
204  State->IsUwop = 1;
205  break;
206  case DW_CFA_def_cfa_sf:
207  Length += DwDecodeUleb128(&State->Reg, pc + Length);
208  Length += DwDecodeSleb128(&State->FramePtr, pc + Length);
209  State->FramePtr *= 8; // data alignment
210  State->IsUwop = 1;
211  break;
213  {
214  unsigned long argsize;
215  printf("Warning, DW_CFA_GNU_args_size is unimplemented\n");
216  Length += DwDecodeUleb128(&argsize, pc + Length);
217  break;
218  }
219  /* PSEH */
220  case 0x21:
221  {
222  unsigned long SehType;
223 
224 // printf("found 0x21 at %lx\n", State->Location);
225  Length += DwDecodeUleb128(&SehType, pc + Length);
226  switch (SehType)
227  {
228  case 1: /* Begin Try */
229  State->TryLevel++;
230  if (State->TryLevel >= 20)
231  {
232  printf("WTF? Trylevel of 20 exceeded...\n");
233  exit(1);
234  }
235  State->SehBlock[State->TryLevel-1].BeginTry = State->Location;
236 // printf("Found begintry at 0x%lx\n", State->Location);
237  State->Scope = 1;
238  break;
239 
240  case 2: /* End Try */
241  State->SehBlock[State->TryLevel-1].EndTry = State->Location;
242  State->Scope = 2;
243  break;
244 
245  case 3: /* Jump target */
246  State->SehBlock[State->TryLevel-1].Target = State->Location;
247  State->Scope = 3;
248  break;
249 
250  case 4: /* SEH End */
251  if (State->TryLevel == 20)
252  {
253  printf("Ooops, end of SEH with trylevel at 0!\n");
254  exit(1);
255  }
256  State->SehBlock[State->TryLevel-1].End = State->Location;
257  State->TryLevel--;
258  State->cScopes++;
259  State->Scope = 0;
260  break;
261 
262  case 5: /* Constant filter */
263  {
264  unsigned long value;
265  Length += DwDecodeUleb128(&value, pc + Length);
266  State->SehBlock[State->TryLevel-1].Handler = value;
267 // printf("Found a constant filter at 0x%lx\n", State->Location);
268  break;
269  }
270 
271  /* These work differently. We are in a new function.
272  * We have to parse a lea opcode to find the adress of
273  * the jump target. This is the reference to find the
274  * appropriate C_SCOPE_TABLE. */
275  case 6: /* Filter func */
276 // printf("Found a filter func at 0x%lx\n", State->Location);
277  break;
278 
279  case 7: /* Finally func */
280  {
281 // printf("Found a finally func at 0x%lx\n", State->Location);
282  break;
283  }
284 
285  default:
286  printf("Found unknow PSEH code 0x%lx\n", SehType);
287  exit(1);
288  }
289  break;
290  }
291  default:
292  fprintf(stderr, "unknown instruction 0x%x at 0x%p\n", Code, pc);
293  exit(1);
294  }
295 
296  State->FramePtrDiff = State->FramePtr - PrevFramePtr;
297  DPRINT("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n",
298  (void*)((ULONG)pc - g_ehframep), Code, State->Location, State->Offset, State->Reg, regs[State->Reg].name);
299  return Length;
300 }
301 
304 ULONG
306 {
307  ULONG cCodes = 0;
308  ULONG AllocSize;
309  UNWIND_CODE Code[3];
310  int i;
311 
312  Code[0].CodeOffset = State->Location - FunctionStart;
313 
314  switch (State->Code)
315  {
316  case DW_CFA_offset:
318  // save register at offset
319  Code[0].OpInfo = regs[State->Reg].regnt;
320  if (State->Offset <= 0x7FFF8)
321  {
322  Code[0].UnwindOp = UWOP_SAVE_NONVOL;
323  Code[1].FrameOffset = State->Offset / 8;
324  cCodes = 2;
325  }
326  else
327  {
328  Code[0].UnwindOp = UWOP_SAVE_NONVOL_FAR;
329  Code[1].FrameOffset = (State->Offset / 8);
330  Code[2].FrameOffset = (State->Offset / 8) >> 16;
331  cCodes = 3;
332  }
333  break;
334 
335  case DW_CFA_def_cfa:
336  //case DW_CFA_def_cfa_register:
338  case DW_CFA_def_cfa_sf:
339  AllocSize = State->FramePtrDiff;
340  if (AllocSize <= 128)
341  {
342  Code[0].UnwindOp = UWOP_ALLOC_SMALL;
343  Code[0].OpInfo = (AllocSize / 8) - 1;
344  cCodes = 1;
345  }
346  else if (AllocSize <= 0x7FFF8)
347  {
348  Code[0].UnwindOp = UWOP_ALLOC_LARGE;
349  Code[0].OpInfo = 0;
350  Code[1].FrameOffset = AllocSize / 8;
351  cCodes = 2;
352  }
353  else // if (AllocSize > 0x7FFF8)
354  {
355  Code[0].UnwindOp = UWOP_ALLOC_LARGE;
356  Code[0].OpInfo = 1;
357  Code[1].FrameOffset = (USHORT)AllocSize;
358  Code[2].FrameOffset = (USHORT)(AllocSize >> 16);
359  cCodes = 3;
360  }
361  break;
362  }
363 
364  if (Info)
365  {
366  /* Move old codes */
367  for (i = Info->CountOfCodes - 1; i >= 0; i--)
368  {
369  Info->UnwindCode[i + cCodes] = Info->UnwindCode[i];
370  }
371 
372  /* Copy new codes */
373  for (i = 0; i < cCodes; i++)
374  {
375  Info->UnwindCode[i] = Code[i];
376  }
377 
378  Info->CountOfCodes += cCodes;
379  }
380 
381  return cCodes;
382 }
383 
384 #define GetxdataSize(cFuncs, cUWOP, cScopes) \
385  ( cFuncs * (sizeof(UNWIND_INFO) + 2 + 4 + 4) \
386  + cUWOP * sizeof(UNWIND_CODE) \
387  + cScopes * sizeof(C_SCOPE_TABLE_ENTRY) )
388 
389 ULONG
391 {
392  ULONG cbSize;
394  char *pInst;
395  ULONG c;
396  DW2CIE Cie;
397 
398  cbSize = 4; // sizeof(UNWIND_INFO);
399  Info->Version = 1;
400  Info->Flags = 0;
401  Info->SizeOfProlog = 0;
402  Info->CountOfCodes = 0;
403  Info->FrameRegister = 0;
404  Info->FrameOffset = 0;
405 
406  /* Decode the CIE */
407  DwDecodeCie(&Cie, pFde->CiePointer);
408 
409  /* Initialize state */
410  State.Location = FunctionStart;
411  State.FramePtr = 0;
412  State.TryLevel = 0;
413  State.cScopes = 0;
414 
415  /* Parse the CIE's initial instructions */
416  pInst = Cie.Instructions;
417  while (pInst < Cie.Next)
418  {
419  pInst += DwExecIntruction(&State, pInst);
420  }
421 
422  /* Parse the FDE instructions */
423  pInst = pFde->Instructions;
424  while (pInst < pFde->Next)
425  {
426  pInst += DwExecIntruction(&State, pInst);
427 
428  if (State.IsUwop)
429  {
430  c = StoreUnwindCodes(Info, &State, FunctionStart);
431  cbSize += c * sizeof(UNWIND_CODE);
432  Info->SizeOfProlog = State.Location - FunctionStart;
433  }
434  }
435  cbSize = ROUND_UP(cbSize, 4);
436 
437  /* Do we have scope table to write? */
438  if (State.cScopes > 0)
439  {
440  unsigned long i;
441  ULONG *pExceptionHandler;
442  PC_SCOPE_TABLE pScopeTable;
443 
444  /* Set flag for exception handler */
445  Info->Flags |= UNW_FLAG_EHANDLER;
446 
447  /* Store address of handler and number of scope tables */
448  pExceptionHandler = (ULONG*)((char*)Info + cbSize);
449  // HACK for testing purpose
450  *pExceptionHandler = FunctionStart; // _C_specific_handler
451 
452  pScopeTable = (PC_SCOPE_TABLE)(pExceptionHandler + 1);
453  pScopeTable->NumEntries = State.cScopes;
454 
455  /* Store the scope table entries */
456  for (i = 0; i < State.cScopes; i++)
457  {
458  pScopeTable->Entry[i].Begin = State.SehBlock[i].BeginTry;
459  pScopeTable->Entry[i].End = State.SehBlock[i].EndTry;
460  pScopeTable->Entry[i].Handler = 1;//State.SehBlock[i].Handler;
461  pScopeTable->Entry[i].Target = State.SehBlock[i].Target;
462  }
463 
464  /* Update size */
465  cbSize += 8 + State.cScopes * sizeof(C_SCOPE_TABLE_ENTRY);
466  }
467 
468  return cbSize;
469 }
470 
471 void
473 {
474  DW2CIEFDE *p;
475  DW2FDE Fde;
476  char *pInst, *pmax;
478 
479  File->cFuncs = 0;
480  File->cScopes = 0;
481  File->cUWOP = 0;
482  State.FramePtr = 0;
483  State.TryLevel = 0;
484 
485  p = File->eh_frame.p;
486  pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
487  for (; p->Length && (char*)p < pmax; p = NextCIE(p))
488  {
489  /* Is this an FDE? */
490  if (p->CiePointer != 0)
491  {
492  File->cFuncs++;
493  DwDecodeFde(&Fde, (char*)p);
494 
495  pInst = Fde.Instructions;
496  while (pInst < Fde.Next)
497  {
498  pInst += DwExecIntruction(&State, pInst);
499  File->cUWOP += StoreUnwindCodes(NULL, &State, 0);
500  File->cScopes += State.Scope ? 1 : 0;
501  }
502  }
503  }
504 
505  return;
506 }
507 
508 int CompFunc(const void *p1, const void *p2)
509 {
510  PRUNTIME_FUNCTION prf1 = (void*)p1, prf2 = (void*)p2;
511  return (prf1->FunctionStart > prf2->FunctionStart ? 1 : -1);
512 }
513 
514 void
516 {
517  DW2CIEFDE *p;
518  DW2FDE Fde;
520  ULONG i, Offset;
521  void * eh_frame;
523  ULONG xdata_va;
524  char *xdata_p;
525  ULONG cbSize;
526  PIMAGE_SECTION_HEADER pshp, pshx;
527  ULONG FileAlignment;
528  char *pmax;
529 
530  FileAlignment = File->OptionalHeader->FileAlignment;
531 
532  /* Get pointer to eh_frame section */
533  eh_frame = File->eh_frame.p;
534  g_ehframep = (ULONG)eh_frame;
535 
536  /* Get sizes */
538 // printf("cFuncs = %ld, cUWOPS = %ld, cScopes = %ld\n",
539 // File->cFuncs, File->cUWOP, File->cScopes);
540 
541  /* Initialize section header for .pdata */
542  i = File->pdata.idx = File->UsedSections;
543  pshp = File->pdata.psh = &File->NewSectionHeaders[i];
544  memcpy(pshp->Name, ".pdata", 7);
545  pshp->Misc.VirtualSize = (File->cFuncs + 1) * sizeof(RUNTIME_FUNCTION);
546  pshp->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
547  File->NewSectionHeaders[i - 1].SizeOfRawData;
548  pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
549  pshp->PointerToRawData = File->NewSectionHeaders[i - 1].PointerToRawData +
550  File->NewSectionHeaders[i - 1].SizeOfRawData;
551  pshp->PointerToRelocations = 0;
552  pshp->PointerToLinenumbers = 0;
553  pshp->NumberOfRelocations = 0;
554  pshp->NumberOfLinenumbers = 0;
557 
558  /* Allocate .pdata buffer */
559  pdata = File->pdata.p = malloc(pshp->SizeOfRawData);
560  memset(File->pdata.p, 0, pshp->SizeOfRawData);
561 
562  /* Init exception data dir */
563  Dir = &File->OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
564  Dir->VirtualAddress = pshp->VirtualAddress;
565  Dir->Size = pshp->Misc.VirtualSize;
566 
567  /* Initialize section header for .xdata */
568  File->xdata.idx = File->pdata.idx + 1;
569  pshx = File->xdata.psh = &File->NewSectionHeaders[File->xdata.idx];
570  memcpy(pshx->Name, ".xdata", 7);
571  pshx->Misc.VirtualSize = GetxdataSize(File->cFuncs, File->cUWOP, File->cScopes);
572  pshx->VirtualAddress = pshp->VirtualAddress + pshp->SizeOfRawData;
573  pshx->SizeOfRawData = ROUND_UP(pshx->Misc.VirtualSize, FileAlignment);
574  pshx->PointerToRawData = pshp->PointerToRawData + pshp->SizeOfRawData;
575  pshx->PointerToRelocations = 0;
576  pshx->PointerToLinenumbers = 0;
577  pshx->NumberOfRelocations = 0;
578  pshx->NumberOfLinenumbers = 0;
581 
582  /* Allocate .xdata buffer */
583  File->xdata.p = malloc(pshx->SizeOfRawData);
584  memset(File->xdata.p, 0, pshx->SizeOfRawData);
585 
586  i = 0;
587  Offset = File->eh_frame.psh->VirtualAddress;
588  xdata_va = pshx->VirtualAddress;
589  xdata_p = File->xdata.p;
590  pmax = (char*)eh_frame + File->eh_frame.psh->Misc.VirtualSize - 100;
591 
592  for (p = eh_frame; p->Length && (char*)p < pmax; p = NextCIE(p))
593  {
594  /* Is this an FDE? */
595  if (p->CiePointer != 0)
596  {
597  DwDecodeFde(&Fde, (char*)p);
598  pdata[i].FunctionStart = Offset + 8 + Fde.PcBegin;
599  pdata[i].FunctionEnd = pdata[i].FunctionStart + Fde.PcRange;
600  pdata[i].UnwindInfo = xdata_va;
601 
602 // printf("%ld: RUNTIME_FUNCTION: {0x%lx, 0x%lx, 0x%lx}\n", i, pdata[i].FunctionStart, pdata[i].FunctionEnd, pdata[i].UnwindInfo);
603 
604  cbSize = StoreUnwindInfo((void*)xdata_p, &Fde, pdata[i].FunctionStart);
605  xdata_va += cbSize;
606  xdata_p += cbSize;
607  i++;
608  }
609  Offset += 4 + p->Length;
610  }
611 
612  /* Sort the RUNTIME_FUNCTIONS */
613  qsort(pdata, i, sizeof(RUNTIME_FUNCTION), CompFunc);
614 
615 }
616 
620 WORD
621 CalculateChecksum(DWORD Start, void *pFile, ULONG cbSize)
622 {
623  WORD *Ptr = pFile;
624  DWORD i;
625  DWORD checksum = Start;
626 
627  for (i = 0; i < (cbSize + 1) / sizeof(WORD); i++)
628  {
629  checksum += Ptr[i];
630  checksum = (checksum + (checksum >> 16)) & 0xffff;
631  }
632 
633  return checksum ;
634 }
635 
636 void
638 {
639  int ret, Size, Pos = 0;
640  DWORD CheckSum;
641  ULONG i, Alignment;
642 
643  Alignment = File->OptionalHeader->FileAlignment;
644 
645  /* Update section count */
646  File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
647 
648  /* Update SizeOfImage */
649  Size = File->xdata.psh->VirtualAddress
650  + File->xdata.psh->SizeOfRawData;
651  File->OptionalHeader->SizeOfImage = Size;
652 
653  /* Recalculate checksum */
654  CheckSum = CalculateChecksum(0, File->FilePtr, File->HeaderSize);
655  for (i = 0; i < File->AllSections; i++)
656  {
657  if (File->UseSection[i])
658  {
659  Size = File->SectionHeaders[i].SizeOfRawData;
660  if (Size)
661  {
662  void *p;
663  p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
665  }
666  }
667  }
668  Size = File->pdata.psh->Misc.VirtualSize;
670  Size = File->xdata.psh->Misc.VirtualSize;
672  CheckSum += File->HeaderSize;
673  CheckSum += File->pdata.psh->Misc.VirtualSize;
674  CheckSum += File->xdata.psh->Misc.VirtualSize;
675  File->OptionalHeader->CheckSum = CheckSum;
676 
677  /* Write file header */
678  Size = File->HeaderSize;
679  ret = fwrite(File->DosHeader, 1, Size, handle);
680  Pos = Size;
681 
682  /* Write Section headers */
683  Size = File->NewSectionHeaderSize;
684  ret = fwrite(File->NewSectionHeaders, 1, Size, handle);
685  Pos += Size;
686 
687  /* Fill up to next alignement */
688  Size = ROUND_UP(Pos, Alignment) - Pos;
689  ret = fwrite(File->AlignBuf, 1, Size, handle);
690  Pos += Size;
691 
692  /* Write sections */
693  for (i = 0; i < File->AllSections; i++)
694  {
695  if (File->UseSection[i])
696  {
697  void *p;
698  Size = File->SectionHeaders[i].SizeOfRawData;
699  if (Size)
700  {
701  p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
702  ret = fwrite(p, 1, Size, handle);
703  Pos += Size;
704  }
705  }
706  }
707 
708  /* Write .pdata section */
709  Size = File->pdata.psh->SizeOfRawData;
710  ret = fwrite(File->pdata.p, 1, Size, handle);
711  Pos += Size;
712 
713  /* Write .xdata section */
714  Size = File->xdata.psh->SizeOfRawData;
715  ret = fwrite(File->xdata.p, 1, Size, handle);
716  Pos += Size;
717 
718 }
719 
720 
721 int
723 {
724  DWORD OldChecksum, Checksum;
725  ULONG Alignment, CurrentPos;
726  int i, j;
727 
728  /* Check if MZ header exists */
729  File->DosHeader = (PIMAGE_DOS_HEADER)File->FilePtr;
730  if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) ||
731  (File->DosHeader->e_lfanew == 0L))
732  {
733  perror("Input file is not a PE image.\n");
734  return -1;
735  }
736 
737  /* Locate PE file header */
738  File->FileHeader = (PIMAGE_FILE_HEADER)(File->FilePtr +
739  File->DosHeader->e_lfanew + sizeof(ULONG));
740 
741  /* Check for x64 image */
742  if (File->FileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
743  {
744  perror("Input file is not an x64 image.\n");
745  return -1;
746  }
747 
748  /* Locate optional header */
749  File->OptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(File->FileHeader + 1);
750 
751  /* Check if checksum is correct */
752  OldChecksum = File->OptionalHeader->CheckSum;
753  File->OptionalHeader->CheckSum = 0;
754  Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize);
755  Checksum += File->cbInFileSize;
756  if ((Checksum & 0xffff) != (OldChecksum & 0xffff))
757  {
758  fprintf(stderr, "Input file has incorrect PE checksum: 0x%lx (calculated: 0x%lx)\n",
759  OldChecksum, Checksum);
760 // return 0;
761  }
762 
763  /* Locate PE section headers */
764  File->SectionHeaders = (PIMAGE_SECTION_HEADER)((char*)File->OptionalHeader
765  + File->FileHeader->SizeOfOptionalHeader);
766 
767  File->HeaderSize = File->DosHeader->e_lfanew
768  + sizeof(ULONG)
769  + sizeof(IMAGE_FILE_HEADER)
770  + File->FileHeader->SizeOfOptionalHeader;
771 
772  if (!File->FileHeader->PointerToSymbolTable)
773  {
774  fprintf(stderr, "No symbol table.\n");
775  return -1;
776  }
777 
778  /* Create some shortcuts */
779  File->ImageBase = File->OptionalHeader->ImageBase;
780  File->Symbols = File->FilePtr + File->FileHeader->PointerToSymbolTable;
781  File->Strings = (char*)File->Symbols + File->FileHeader->NumberOfSymbols * 18;
782 
783  /* Check section names */
784  File->AllSections = File->FileHeader->NumberOfSections;
785  Alignment = File->OptionalHeader->FileAlignment;
786  File->NewSectionHeaders = malloc((File->AllSections+2) * sizeof(IMAGE_SECTION_HEADER));
787  File->UsedSections = 0;
788  File->eh_frame.idx = -1;
789 
790  /* Allocate array of chars, specifiying whether to copy the section */
791  File->UseSection = malloc(File->AllSections);
792 
793  for (i = 0; i < File->AllSections; i++)
794  {
795  char *pName = (char*)File->SectionHeaders[i].Name;
796  File->UseSection[i] = 1;
797 
798  /* Check for long name */
799  if (pName[0] == '/')
800  {
801  unsigned long index = strtoul(pName+1, 0, 10);
802  pName = File->Strings + index;
803 
804  // Hack, simply remove all sections with long names
805  File->UseSection[i] = 0;
806  }
807 
808  /* Chek if we have the eh_frame section */
809  if (strcmp(pName, ".eh_frame") == 0)
810  {
811  File->eh_frame.psh = &File->SectionHeaders[i];
812  File->eh_frame.idx = i;
813  File->eh_frame.p = File->FilePtr + File->eh_frame.psh->PointerToRawData;
814  }
815 
816  /* Increase number of used sections */
817  if (File->UseSection[i])
818  File->UsedSections = i+1;
819 
820  }
821 
822  /* This is the actual size of the new section headers */
823  File->NewSectionHeaderSize =
824  (File->UsedSections+2) * sizeof(IMAGE_SECTION_HEADER);
825 
826  /* Calculate the position to start writing the sections to */
827  CurrentPos = File->HeaderSize + File->NewSectionHeaderSize;
828  CurrentPos = ROUND_UP(CurrentPos, Alignment);
829 
830  /* Create new section headers */
831  for (i = 0, j = 0; i < File->UsedSections; i++)
832  {
833  /* Copy section header */
834  File->NewSectionHeaders[j] = File->SectionHeaders[i];
835 
836  /* Shall we strip the section? */
837  if (File->UseSection[i] == 0)
838  {
839  /* Make it a bss section */
840  File->NewSectionHeaders[j].PointerToRawData = 0;
841  File->NewSectionHeaders[j].SizeOfRawData = 0;
842  File->NewSectionHeaders[j].Characteristics = 0xC0500080;
843  }
844 
845  /* Fix Offset into File */
846  File->NewSectionHeaders[j].PointerToRawData =
847  File->NewSectionHeaders[j].PointerToRawData ? CurrentPos : 0;
848  CurrentPos += File->NewSectionHeaders[j].SizeOfRawData;
849  j++;
850  }
851 
852  if (File->eh_frame.idx == -1)
853  {
854  //fprintf(stderr, "No .eh_frame section found\n");
855  return 0;
856  }
857 
858  return 1;
859 }
860 
861 int main(int argc, char* argv[])
862 {
863  char* pszInFile;
864  char* pszOutFile;
865  FILE_INFO File;
866  FILE* outfile;
867  int ret;
868 
869  if (argc != 3)
870  {
871  fprintf(stderr, "Usage: rsym <exefile> <symfile>\n");
872  exit(1);
873  }
874 
875  pszInFile = convert_path(argv[1]);
876  pszOutFile = convert_path(argv[2]);
877 
878  File.FilePtr = load_file(pszInFile, &File.cbInFileSize);
879  if (!File.FilePtr)
880  {
881  fprintf(stderr, "An error occured loading '%s'\n", pszInFile);
882  exit(1);
883  }
884 
885  ret = ParsePEHeaders(&File);
886  if (ret != 1)
887  {
888  free(File.FilePtr);
889  exit(ret == -1 ? 1 : 0);
890  }
891 
892  File.AlignBuf = malloc(File.OptionalHeader->FileAlignment);
893  memset(File.AlignBuf, 0, File.OptionalHeader->FileAlignment);
894 
896 
897  outfile = fopen(pszOutFile, "wb");
898  if (outfile == NULL)
899  {
900  perror("Cannot open output file");
901  free(File.FilePtr);
902  exit(1);
903  }
904 
906 
907  fclose(outfile);
908 
909  return 0;
910 }
unsigned long PcBegin
Definition: dwarf2.h:807
char * AugData
Definition: dwarf2.h:810
#define DPRINT
Definition: rsym64.c:12
char Version
Definition: dwarf2.h:791
#define REG_R15
Definition: rsym64.h:45
static int argc
Definition: ServiceArgs.c:12
unsigned long Length
Definition: dwarf2.h:804
char * Instructions
Definition: dwarf2.h:799
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
void WriteOutFile(FILE *handle, PFILE_INFO File)
Definition: rsym64.c:637
#define GetxdataSize(cFuncs, cUWOP, cScopes)
Definition: rsym64.c:384
unsigned long AugLength
Definition: dwarf2.h:809
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define REG_R8
Definition: rsym64.h:38
WORD NumberOfRelocations
Definition: pedump.c:293
char * name
Definition: rsym64.c:14
ULONG Target
Definition: rsym64.h:134
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define REG_XMM12
Definition: rsym64.h:59
union _UNWIND_CODE UNWIND_CODE
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
#define free
Definition: debug_ros.c:5
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
char * Next
Definition: dwarf2.h:805
int CompFunc(const void *p1, const void *p2)
Definition: rsym64.c:508
ush Pos
Definition: deflate.h:92
#define REG_RSI
Definition: rsym64.h:36
ULONG ReturnAddressRegister
Definition: dwarf2.h:792
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define REG_R14
Definition: rsym64.h:44
#define REG_XMM5
Definition: rsym64.h:52
#define REG_XMM1
Definition: rsym64.h:48
#define REG_R9
Definition: rsym64.h:39
ULONG AugStringLength
Definition: dwarf2.h:793
#define REG_RDI
Definition: rsym64.h:37
struct _C_SCOPE_TABLE * PC_SCOPE_TABLE
char DoPrint
Definition: rsym64.c:9
static FILE * outfile
Definition: wrjpgcom.c:81
char regnt
Definition: rsym64.c:14
DWORD PointerToRawData
Definition: pedump.c:290
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define REG_R12
Definition: rsym64.h:42
struct TraceInfo Info
#define REG_XMM10
Definition: rsym64.h:57
#define REG_XMM8
Definition: rsym64.h:55
unsigned long PcRange
Definition: dwarf2.h:808
ULONG StoreUnwindCodes(PUNWIND_INFO Info, PDW2CFSTATE State, ULONG FunctionStart)
Definition: rsym64.c:305
#define REG_RAX
Definition: rsym64.h:30
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
char * AugData
Definition: dwarf2.h:796
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define REG_XMM4
Definition: rsym64.h:51
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
union Alignment_ Alignment
smooth NULL
Definition: ftsmooth.c:416
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
#define REG_RCX
Definition: rsym64.h:31
#define REG_R11
Definition: rsym64.h:41
GLuint index
Definition: glext.h:6031
#define REG_RBP
Definition: rsym64.h:35
void GeneratePData(PFILE_INFO File)
Definition: rsym64.c:515
static PROTOCOLDATA * pdata
Definition: protocol.c:157
void CountUnwindData(PFILE_INFO File)
Definition: rsym64.c:472
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define IMAGE_DOS_MAGIC
Definition: pecoff.h:6
#define Code
Definition: deflate.h:80
unsigned long DwExecIntruction(PDW2CFSTATE State, char *pc)
Definition: rsym64.c:115
WORD NumberOfLinenumbers
Definition: pedump.c:294
ULONG CodeAlign
Definition: dwarf2.h:797
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
static LPSTR pName
Definition: security.c:75
DWORD PointerToLinenumbers
Definition: pedump.c:292
unsigned long DwDecodeFde(PDW2FDE Fde, char *pc)
Definition: rsym64.c:99
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define REG_XMM3
Definition: rsym64.h:50
#define REG_XMM15
Definition: rsym64.h:62
struct _IMAGE_FILE_HEADER * PIMAGE_FILE_HEADER
ULONG End
Definition: rsym64.h:132
const GLubyte * c
Definition: glext.h:8905
unsigned short WORD
Definition: ntddk_ex.h:93
#define REG_R10
Definition: rsym64.h:40
#define NextCIE(p)
Definition: dwarf2.h:839
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
#define REG_XMM2
Definition: rsym64.h:49
UCHAR CheckSum(LPSTR p, ULONG Len)
Definition: serial.c:197
char * Instructions
Definition: dwarf2.h:811
int main(int argc, char *argv[])
Definition: rsym64.c:861
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define REG_XMM9
Definition: rsym64.h:56
ULONG g_ehframep
Definition: rsym64.c:10
Definition: partlist.h:32
ULONG CieId
Definition: dwarf2.h:790
struct @3999 regs[]
#define REG_XMM14
Definition: rsym64.h:61
int ret
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1087
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1202
unsigned long DwDecodeCie(PDW2CIE Cie, char *pc)
Definition: rsym64.c:78
WORD CalculateChecksum(DWORD Start, void *pFile, ULONG cbSize)
Definition: rsym64.c:621
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define REG_RBX
Definition: rsym64.h:33
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define REG_XMM6
Definition: rsym64.h:53
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned long DwDecodeUleb128(unsigned long *pResult, char *pc)
Definition: rsym64.c:32
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
enum State_ State
Definition: pofuncs.h:54
#define REG_RDX
Definition: rsym64.h:32
Definition: dwarf2.h:786
char * AugString
Definition: dwarf2.h:794
ULONG Length
Definition: dwarf2.h:788
unsigned short USHORT
Definition: pedump.c:61
ULONG NumEntries
Definition: rsym64.h:139
#define REG_XMM0
Definition: rsym64.h:47
#define IMAGE_SCN_MEM_NOT_PAGED
Definition: ntimage.h:237
C_SCOPE_TABLE_ENTRY Entry[1]
Definition: rsym64.h:140
char * convert_path(char *origpath)
Definition: rcopy.c:11
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
int ParsePEHeaders(PFILE_INFO File)
Definition: rsym64.c:722
ULONG FunctionStart
Definition: rsym64.h:89
struct _IMAGE_OPTIONAL_HEADER64 * PIMAGE_OPTIONAL_HEADER64
ULONG AugLength
Definition: dwarf2.h:795
#define REG_XMM13
Definition: rsym64.h:60
#define c
Definition: ke_i.h:80
ULONG StoreUnwindInfo(PUNWIND_INFO Info, PDW2FDE pFde, ULONG FunctionStart)
Definition: rsym64.c:390
unsigned int ULONG
Definition: retypes.h:1
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define malloc
Definition: debug_ros.c:4
#define REG_XMM7
Definition: rsym64.h:54
#define REG_R13
Definition: rsym64.h:43
#define REG_RSP
Definition: rsym64.h:34
Definition: File.h:15
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
#define REG_XMM11
Definition: rsym64.h:58
#define memset(x, y, z)
Definition: compat.h:39
char * Next
Definition: dwarf2.h:789
unsigned long DwDecodeSleb128(long *pResult, char *pc)
Definition: rsym64.c:53
union _IMAGE_SECTION_HEADER::@1515 Misc
char * CiePointer
Definition: dwarf2.h:806
ULONG Begin
Definition: rsym64.h:131
LONG DataAlign
Definition: dwarf2.h:798
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262
DWORD PointerToRelocations
Definition: pedump.c:291
struct task_struct * current
Definition: linux.c:32
ULONG Handler
Definition: rsym64.h:133
struct _C_SCOPE_TABLE_ENTRY C_SCOPE_TABLE_ENTRY
Definition: dwarf2.h:802
#define printf
Definition: config.h:203