#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
+#include <unistd.h>
#ifndef O_BINARY
#define O_BINARY 0
/* The following definitions are ripped from MinGW W32API headers. We don't
use these headers directly in order to allow compilation on Linux hosts. */
-typedef unsigned char BYTE;
+typedef unsigned char BYTE, *PBYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef int LONG;
+typedef long LONG_PTR;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_NT_SIGNATURE 0x00004550
#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000
-#define FIELD_OFFSET(t,f) ((LONG)&(((t*)0)->f))
+#define FIELD_OFFSET(t,f) ((LONG)(LONG_PTR)&(((t*)0)->f))
#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((unsigned long)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
PIMAGE_DOS_HEADER dos_header;
PIMAGE_NT_HEADERS nt_header;
+static inline WORD dtohs(WORD in)
+{
+ PBYTE in_ptr = (PBYTE)∈
+ return in_ptr[0] | (in_ptr[1] << 8);
+}
+
+static inline WORD htods(WORD in)
+{
+ WORD out;
+ PBYTE out_ptr = (PBYTE)&out;
+ out_ptr[0] = in; out_ptr[1] = in >> 8;
+ return out;
+}
+
+static inline DWORD dtohl(DWORD in)
+{
+ PBYTE in_ptr = (PBYTE)∈
+ return in_ptr[0] | (in_ptr[1] << 8) | (in_ptr[2] << 16) | (in_ptr[3] << 24);
+}
+
+static inline DWORD htodl(DWORD in)
+{
+ DWORD out;
+ PBYTE out_ptr = (PBYTE)&out;
+ out_ptr[0] = in ; out_ptr[1] = in >> 8;
+ out_ptr[2] = in >> 16; out_ptr[3] = in >> 24;
+ return out;
+}
+
void *rva_to_ptr(DWORD rva)
{
PIMAGE_SECTION_HEADER section_header;
unsigned int i;
for (i = 0, section_header = IMAGE_FIRST_SECTION(nt_header);
- i < nt_header->OptionalHeader.NumberOfRvaAndSizes;
+ i < dtohl(nt_header->FileHeader.NumberOfSections);
i++, section_header++)
{
- if (rva >= section_header->VirtualAddress &&
- rva < section_header->VirtualAddress +
- section_header->Misc.VirtualSize)
+ if (rva >= dtohl(section_header->VirtualAddress) &&
+ rva < dtohl(section_header->VirtualAddress) +
+ dtohl(section_header->Misc.VirtualSize))
{
- return buffer + rva - section_header->VirtualAddress +
- section_header->PointerToRawData;
+ return buffer + rva - dtohl(section_header->VirtualAddress) +
+ dtohl(section_header->PointerToRawData);
}
}
{
int fd_in, fd_out;
long len;
+ char hdrbuf[4] = { }, elfhdr[4] = { '\177', 'E', 'L', 'F' };
PIMAGE_SECTION_HEADER section_header;
PIMAGE_DATA_DIRECTORY data_dir;
unsigned int i;
else if (!strcmp(argv[i], "-exports"))
fixup_exports = 1;
else
- { printf("Invalid option: %s\n", argv[i]); return 1; }
+ { fprintf(stderr, "Invalid option: %s\n", argv[i]); return 1; }
}
+ /*
+ * Nothing to do.
+ */
if (fixup_sections == 0 && fixup_exports == 0)
- {
- printf("Nothing to do.\n");
return 0;
- }
/*
* Read the whole file to memory.
fd_in = open(argv[1], O_RDONLY | O_BINARY);
if (fd_in == 0)
{
- printf("Can't open input file.\n");
+ fprintf(stderr, "Can't open input file.\n");
return 1;
}
+ /*
+ * PowerPC ReactOS uses elf, so doesn't need pefixup
+ */
+ len = read(fd_in, hdrbuf, sizeof(elfhdr));
+ if (!memcmp(hdrbuf, elfhdr, sizeof(elfhdr)))
+ return 0;
+
len = lseek(fd_in, 0, SEEK_END);
if (len < sizeof(IMAGE_DOS_HEADER))
{
close(fd_in);
- printf("'%s' isn't a PE image (too short)\n", argv[1]);
+ fprintf(stderr, "'%s' isn't a PE image (too short)\n", argv[1]);
return 1;
}
if (buffer == NULL)
{
close(fd_in);
- printf("Not enough memory available.\n");
+ fprintf(stderr, "Not enough memory available.\n");
return 1;
}
*/
dos_header = (PIMAGE_DOS_HEADER)buffer;
- nt_header = (PIMAGE_NT_HEADERS)(buffer + dos_header->e_lfanew);
-
- if (dos_header->e_magic != IMAGE_DOS_SIGNATURE ||
- nt_header->Signature != IMAGE_NT_SIGNATURE)
+ nt_header = (PIMAGE_NT_HEADERS)(buffer + dtohl(dos_header->e_lfanew));
+
+ if (dtohs(dos_header->e_magic) != IMAGE_DOS_SIGNATURE ||
+ dtohl(nt_header->Signature) != IMAGE_NT_SIGNATURE)
{
- printf("'%s' isn't a PE image (headers %x,%x)\n", argv[1], dos_header->e_magic, nt_header->Signature);
+ fprintf(stderr, "'%s' isn't a PE image (bad headers)\n", argv[1]);
free(buffer);
return 1;
}
{
/* Sort export directory */
data_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
- if (data_dir->Size != 0)
+ if (dtohl(data_dir->Size) != 0)
{
PIMAGE_EXPORT_DIRECTORY export_directory;
DWORD *name_ptr;
WORD *ordinal_ptr;
export_t *exports;
- export_directory = (PIMAGE_EXPORT_DIRECTORY)rva_to_ptr(data_dir->VirtualAddress);
+ export_directory = (PIMAGE_EXPORT_DIRECTORY)rva_to_ptr(dtohl(data_dir->VirtualAddress));
if (export_directory != NULL)
{
- exports = malloc(sizeof(export_t) * export_directory->NumberOfNames);
+ exports = malloc(sizeof(export_t) * dtohl(export_directory->NumberOfNames));
if (exports == NULL)
{
- printf("Not enough memory.\n");
+ fprintf(stderr, "Not enough memory.\n");
free(buffer);
return 1;
}
- name_ptr = (DWORD *)rva_to_ptr(export_directory->AddressOfNames);
- ordinal_ptr = (WORD *)rva_to_ptr(export_directory->AddressOfNameOrdinals);
+ name_ptr = (DWORD *)rva_to_ptr(dtohl(export_directory->AddressOfNames));
+ ordinal_ptr = (WORD *)rva_to_ptr(dtohl(export_directory->AddressOfNameOrdinals));
- for (i = 0; i < export_directory->NumberOfNames; i++)
+ for (i = 0; i < dtohl(export_directory->NumberOfNames); i++)
{
- exports[i].name = name_ptr[i];
- exports[i].ordinal = ordinal_ptr[i];
+ exports[i].name = dtohl(name_ptr[i]);
+ exports[i].ordinal = dtohl(ordinal_ptr[i]);
}
- qsort(exports, export_directory->NumberOfNames, sizeof(export_t),
+ qsort(exports, dtohl(export_directory->NumberOfNames), sizeof(export_t),
export_compare_func);
- for (i = 0; i < export_directory->NumberOfNames; i++)
+ for (i = 0; i < dtohl(export_directory->NumberOfNames); i++)
{
- name_ptr[i] = exports[i].name;
- ordinal_ptr[i] = exports[i].ordinal;
+ name_ptr[i] = htodl(exports[i].name);
+ ordinal_ptr[i] = htodl(exports[i].ordinal);
}
free(exports);
{
/* Update section flags */
for (i = 0, section_header = IMAGE_FIRST_SECTION(nt_header);
- i < nt_header->OptionalHeader.NumberOfRvaAndSizes;
+ i < dtohl(nt_header->OptionalHeader.NumberOfRvaAndSizes);
i++, section_header++)
{
if (!strcmp((char*)section_header->Name, ".text") ||
!strcmp((char*)section_header->Name, ".data") ||
!strcmp((char*)section_header->Name, ".idata") ||
+ !strcmp((char*)section_header->Name, ".rdata") ||
!strcmp((char*)section_header->Name, ".bss"))
{
- section_header->Characteristics |= IMAGE_SCN_MEM_NOT_PAGED;
- section_header->Characteristics &= ~IMAGE_SCN_MEM_DISCARDABLE;
+ section_header->Characteristics |= htodl(IMAGE_SCN_MEM_NOT_PAGED);
+ section_header->Characteristics &= htodl(~IMAGE_SCN_MEM_DISCARDABLE);
}
else if (!strcmp((char*)section_header->Name, "INIT"))
{
- section_header->Characteristics |= IMAGE_SCN_MEM_DISCARDABLE;
+ section_header->Characteristics |= htodl(IMAGE_SCN_MEM_DISCARDABLE);
}
else if (!strcmp((char*)section_header->Name, "PAGE"))
{
- section_header->Characteristics |= IMAGE_SCN_MEM_NOT_PAGED;
+ section_header->Characteristics |= htodl(IMAGE_SCN_MEM_NOT_PAGED);
}
}
}
checksum = (checksum + (checksum >> 16)) & 0xffff;
}
checksum += len;
- nt_header->OptionalHeader.CheckSum = checksum;
+ nt_header->OptionalHeader.CheckSum = htods(checksum);
/* Write the output file */
fd_out = open(argv[1], O_WRONLY | O_BINARY);