Author: tkreuzer
Date: Wed Dec 24 12:02:47 2008
New Revision: 38330
URL:
http://svn.reactos.org/svn/reactos?rev=38330&view=rev
Log:
rsym64: Fix a bunch bugs, cleanup code. Now it can strip sections at any position, so if
eh_frame is not at the end, we only waste a little address space, and we got plenty of
that.
Modified:
branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c
branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h
Modified: branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.c [iso-8859-1] Wed Dec 24
12:02:47 2008
@@ -318,9 +318,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) \
+ cUWOP * sizeof(UNWIND_CODE) \
@@ -369,14 +366,6 @@
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);
@@ -396,7 +385,7 @@
File->cUWOP = 0;
State.FramePtr = 0;
- p = GetSectionPointer(File, File->eh_frame.idx);
+ p = File->eh_frame.p;
pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
for (; p->Length && (char*)p < pmax; p = NextCIE(p))
{
@@ -444,7 +433,7 @@
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 */
@@ -452,16 +441,24 @@
// 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 = File->SectionHeaders[File->pdata.idx -
1].VirtualAddress +
- File->SectionHeaders[File->pdata.idx -
1].SizeOfRawData;
+ pshp->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
+ File->NewSectionHeaders[i - 1].SizeOfRawData;
pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
- pshp->PointerToRawData = File->SectionHeaders[File->pdata.idx -
1].PointerToRawData +
- File->SectionHeaders[File->pdata.idx -
1].SizeOfRawData;
+ 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);
@@ -470,16 +467,24 @@
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;
@@ -522,7 +527,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;
@@ -534,8 +539,11 @@
void
WriteOutFile(FILE *handle, PFILE_INFO File)
{
- int ret, Size, Pos;
- DWORD Checksum;
+ int ret, Size, Pos = 0;
+ DWORD CheckSum;
+ ULONG i, Alignment;
+
+ Alignment = File->OptionalHeader->FileAlignment;
/* Update section count */
File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
@@ -545,18 +553,60 @@
+ File->xdata.psh->SizeOfRawData;
File->OptionalHeader->SizeOfImage = Size;
- /* Calculate size of file beginning */
- Size = File->SectionHeaders[File->UsedSections].PointerToRawData;
-
/* 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;
@@ -575,11 +625,13 @@
ParsePEHeaders(PFILE_INFO File)
{
DWORD OldChecksum, Checksum;
+ ULONG Alignment, CurrentPos;
int i;
/* 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 -1;
@@ -587,7 +639,9 @@
/* 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");
@@ -596,13 +650,12 @@
/* 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;
+ Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize);
+ Checksum += File->cbInFileSize;
if (Checksum != OldChecksum)
{
fprintf(stderr, "Input file has incorrect PE checksum: 0x%lx (calculated:
0x%lx)\n",
@@ -625,36 +678,64 @@
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;
+ CurrentPos = File->SectionHeaders[0].PointerToRawData;
+// CurrentPos = ROUND_UP(File->HeaderSize, Alignment);
+
+ /* 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;
+ }
+
+ if (File->UseSection[i])
+ {
+ /* Copy section header */
+ File->NewSectionHeaders[File->UsedSections] =
+ File->SectionHeaders[i];
+ /* Fix Offset into File */
+ File->NewSectionHeaders[File->UsedSections].PointerToRawData =
+ File->SectionHeaders[i].PointerToRawData ? CurrentPos : 0;
+ CurrentPos +=
File->NewSectionHeaders[File->UsedSections].SizeOfRawData;
+
+ /* Increase number of used sections */
+ File->UsedSections++;
+ }
+ }
+
+ /* This is the actual size of the new section headers */
+ File->NewSectionHeaderSize =
+ (File->UsedSections+2) * sizeof(IMAGE_SECTION_HEADER);
if (File->eh_frame.idx == -1)
{
Modified: branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/rsym/rsym64.h [iso-8859-1] Wed Dec 24
12:02:47 2008
@@ -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;
@@ -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;