]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / EdkIIGlueLib / Library / BasePeCoffGetEntryPointLib / PeCoffGetEntryPoint.c
CommitLineData
3eb9473e 1/*++\r
2\r
2c7e5c2f
HT
3Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials \r
3eb9473e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12\r
13Module Name:\r
14\r
15 PeCoffGetEntryPoint.c\r
16 \r
17Abstract: \r
18\r
19 Pe/Coff loader\r
20\r
21--*/\r
22\r
23#include "EdkIIGlueBase.h"\r
24\r
25/**\r
26 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded\r
27 into system memory with the PE/COFF Loader Library functions.\r
28\r
29 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry\r
30 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then\r
31 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.\r
32 If Pe32Data is NULL, then ASSERT().\r
33 If EntryPoint is NULL, then ASSERT().\r
34\r
35 @param Pe32Data Pointer to the PE/COFF image that is loaded in system memory.\r
36 @param EntryPoint Pointer to entry point to the PE/COFF image to return.\r
37\r
38 @retval RETURN_SUCCESS EntryPoint was returned.\r
39 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.\r
40\r
41**/\r
42RETURN_STATUS\r
43EFIAPI\r
44PeCoffLoaderGetEntryPoint (\r
45 IN VOID *Pe32Data,\r
46 OUT VOID **EntryPoint\r
47 )\r
48{\r
49 EFI_IMAGE_DOS_HEADER *DosHeader;\r
50 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Header;\r
51\r
52 ASSERT (Pe32Data != NULL);\r
53 ASSERT (EntryPoint != NULL);\r
54\r
55 DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
56 if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
57 //\r
58 // DOS image header is present, so read the PE header after the DOS image header.\r
59 //\r
60 Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));\r
61 } else {\r
62 //\r
63 // DOS image header is not present, so PE header is at the image base.\r
64 //\r
65 Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
66 }\r
67\r
68 //\r
69 // Calculate the entry point relative to the start of the image. \r
70 // AddressOfEntryPoint is common for PE32 & PE32+\r
71 //\r
72 *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Header.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
73 return RETURN_SUCCESS;\r
74}\r
75\r
76\r
77/**\r
78 Returns the machine type of a PE/COFF image.\r
79\r
80 Returns the machine type from the PE/COFF image specified by Pe32Data.\r
81 If Pe32Data is NULL, then ASSERT().\r
82\r
83 @param Pe32Data Pointer to the PE/COFF image that is loaded in system\r
84 memory.\r
85\r
86 @return Machine type or zero if not a valid iamge.\r
87\r
88**/\r
89UINT16\r
90EFIAPI\r
91PeCoffLoaderGetMachineType (\r
92 IN VOID *Pe32Data\r
93 )\r
94{\r
95 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
96 EFI_IMAGE_DOS_HEADER *DosHdr;\r
97\r
98 DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
99 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
100 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + DosHdr->e_lfanew);\r
101 } else {\r
102 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data);\r
103 }\r
104\r
105 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
106 return Hdr.Pe32->FileHeader.Machine;\r
107 }\r
108\r
109 return 0x0000;\r
110}\r
111\r
112/**\r
113 Returns a pointer to the PDB file name for a PE/COFF image that has been\r
114 loaded into system memory with the PE/COFF Loader Library functions. \r
115\r
116 Returns the PDB file name for the PE/COFF image specified by Pe32Data. If\r
117 the PE/COFF image specified by Pe32Data is not a valid, then NULL is\r
118 returned. If the PE/COFF image specified by Pe32Data does not contain a\r
119 debug directory entry, then NULL is returned. If the debug directory entry\r
120 in the PE/COFF image specified by Pe32Data does not contain a PDB file name,\r
121 then NULL is returned.\r
122 If Pe32Data is NULL, then ASSERT().\r
123\r
124 @param Pe32Data Pointer to the PE/COFF image that is loaded in system\r
125 memory.\r
126\r
127 @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL\r
128 if it cannot be retrieved.\r
129\r
130**/\r
131VOID *\r
132EFIAPI\r
133PeCoffLoaderGetPdbPointer (\r
134 IN VOID *Pe32Data\r
135 )\r
136{\r
137 EFI_IMAGE_DOS_HEADER *DosHeader;\r
138 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
139 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
140 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
141 UINTN DirCount;\r
142 VOID *CodeViewEntryPointer;\r
143 INTN TEImageAdjust;\r
144 UINT32 NumberOfRvaAndSizes;\r
145 \r
146 ASSERT (Pe32Data != NULL);\r
147\r
148 TEImageAdjust = 0;\r
149 DirectoryEntry = NULL;\r
150 DebugEntry = NULL;\r
151 NumberOfRvaAndSizes = 0;\r
152\r
153 DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
154 if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
155 //\r
156 // DOS image header is present, so read the PE header after the DOS image header.\r
157 //\r
158 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));\r
159 } else {\r
160 //\r
161 // DOS image header is not present, so PE header is at the image base.\r
162 //\r
163 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
164 }\r
165\r
166 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
167 if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
168 DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
169 TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
170 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +\r
171 Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
172 TEImageAdjust);\r
173 }\r
174 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
175 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
176 // \r
177 // Use PE32 offset get Debug Directory Entry\r
178 //\r
179 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
180 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
181 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
182 } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
183 // \r
184 // Use PE32+ offset get Debug Directory Entry\r
185 //\r
186 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
187 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
188 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
189 }\r
190\r
191 if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
192 DirectoryEntry = NULL;\r
193 DebugEntry = NULL;\r
194 }\r
195 } else {\r
196 return NULL;\r
197 }\r
198\r
199 if (DebugEntry == NULL || DirectoryEntry == NULL) {\r
200 return NULL;\r
201 }\r
202\r
203 for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {\r
204 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
205 if (DebugEntry->SizeOfData > 0) {\r
206 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);\r
207 switch (* (UINT32 *) CodeViewEntryPointer) {\r
208 case CODEVIEW_SIGNATURE_NB10:\r
209 return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));\r
210 case CODEVIEW_SIGNATURE_RSDS:\r
211 return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));\r
212 default:\r
213 break;\r
214 }\r
215 }\r
216 }\r
217 }\r
218\r
219 return NULL;\r
220}\r
221\r
222\r