1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: lib/rossym/fromfile.c 5 * PURPOSE: Creating rossym info from a file 6 * 7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) 8 */ 9 10 #include <precomp.h> 11 12 #define NDEBUG 13 #include <debug.h> 14 15 #define SYMBOL_SIZE 18 16 17 extern NTSTATUS RosSymStatus; 18 19 BOOLEAN 20 RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) 21 { 22 IMAGE_DOS_HEADER DosHeader; 23 IMAGE_NT_HEADERS NtHeaders; 24 PIMAGE_SECTION_HEADER SectionHeaders; 25 unsigned SectionIndex; 26 unsigned SymbolTable, NumSymbols; 27 28 /* Load DOS header */ 29 if (! RosSymSeekFile(FileContext, 0)) 30 { 31 werrstr("Could not rewind file\n"); 32 return FALSE; 33 } 34 if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER))) 35 { 36 werrstr("Failed to read DOS header %x\n", RosSymStatus); 37 return FALSE; 38 } 39 if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader)) 40 { 41 werrstr("Image doesn't have a valid DOS header\n"); 42 return FALSE; 43 } 44 45 /* Load NT headers */ 46 if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew)) 47 { 48 werrstr("Failed seeking to NT headers\n"); 49 return FALSE; 50 } 51 if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS))) 52 { 53 werrstr("Failed to read NT headers\n"); 54 return FALSE; 55 } 56 if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders)) 57 { 58 werrstr("Image doesn't have a valid PE header\n"); 59 return FALSE; 60 } 61 62 SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable; 63 NumSymbols = NtHeaders.FileHeader.NumberOfSymbols; 64 65 if (!NumSymbols) 66 { 67 werrstr("Image doesn't have debug symbols\n"); 68 return FALSE; 69 } 70 71 DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols); 72 73 /* Load section headers */ 74 if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) - 75 (char *) &NtHeaders + DosHeader.e_lfanew)) 76 { 77 werrstr("Failed seeking to section headers\n"); 78 return FALSE; 79 } 80 DPRINT("Alloc section headers\n"); 81 SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections 82 * sizeof(IMAGE_SECTION_HEADER)); 83 if (NULL == SectionHeaders) 84 { 85 werrstr("Failed to allocate memory for %u section headers\n", 86 NtHeaders.FileHeader.NumberOfSections); 87 return FALSE; 88 } 89 if (! RosSymReadFile(FileContext, SectionHeaders, 90 NtHeaders.FileHeader.NumberOfSections 91 * sizeof(IMAGE_SECTION_HEADER))) 92 { 93 RosSymFreeMem(SectionHeaders); 94 werrstr("Failed to read section headers\n"); 95 return FALSE; 96 } 97 98 // Convert names to ANSI_STRINGs 99 for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; 100 SectionIndex++) 101 { 102 ANSI_STRING astr; 103 if (SectionHeaders[SectionIndex].Name[0] != '/') { 104 DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name); 105 astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME); 106 memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME); 107 astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME; 108 astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME); 109 } else { 110 UNICODE_STRING intConv; 111 NTSTATUS Status; 112 ULONG StringOffset; 113 114 if (!RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1)) 115 goto freeall; 116 Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset); 117 RtlFreeUnicodeString(&intConv); 118 if (!NT_SUCCESS(Status)) goto freeall; 119 if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset)) 120 goto freeall; 121 astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE); 122 if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE)) 123 goto freeall; 124 astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE); 125 astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE; 126 DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer); 127 } 128 *ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr; 129 } 130 131 DPRINT("Done with sections\n"); 132 Pe *pe = RosSymAllocMem(sizeof(*pe)); 133 pe->fd = FileContext; 134 pe->e2 = peget2; 135 pe->e4 = peget4; 136 pe->e8 = peget8; 137 pe->nsections = NtHeaders.FileHeader.NumberOfSections; 138 pe->sect = SectionHeaders; 139 pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase; 140 pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage; 141 pe->codestart = NtHeaders.OptionalHeader.BaseOfCode; 142 pe->datastart = NtHeaders.OptionalHeader.BaseOfData; 143 pe->loadsection = loaddisksection; 144 *RosSymInfo = dwarfopen(pe); 145 146 return TRUE; 147 148 freeall: 149 for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; 150 SectionIndex++) 151 RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex])); 152 RosSymFreeMem(SectionHeaders); 153 154 return FALSE; 155 } 156 157 /* EOF */ 158