File: | home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Memory.c |
Warning: | line 127, column 30 Access to field 'NextBlock' results in a dereference of a null pointer (loaded from variable 'PrevBlock') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /** @file | |||
2 | STM memory management | |||
3 | ||||
4 | Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR> | |||
5 | This program and the accompanying materials | |||
6 | are licensed and made available under the terms and conditions of the BSD License | |||
7 | which accompanies this distribution. The full text of the license may be found at | |||
8 | http://opensource.org/licenses/bsd-license.php. | |||
9 | ||||
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |||
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |||
12 | ||||
13 | **/ | |||
14 | ||||
15 | #include "StmInit.h" | |||
16 | #include "PeStm.h" | |||
17 | ||||
18 | void HeapList(int id); | |||
19 | //#define HEAPCHECK | |||
20 | ||||
21 | /** | |||
22 | ||||
23 | This function allocate pages in MSEG. | |||
24 | ||||
25 | @param Pages the requested pages number | |||
26 | ||||
27 | @return pages address | |||
28 | ||||
29 | **/ | |||
30 | ||||
31 | VOIDvoid * | |||
32 | AllocatePages ( | |||
33 | IN UINTN Pages | |||
34 | ) | |||
35 | { | |||
36 | UINT64 Address; | |||
37 | HEAP_HEADER * BlockHeader; | |||
38 | HEAP_HEADER * PrevBlock; | |||
39 | HEAP_HEADER * NewBlock; | |||
40 | BOOLEAN foundBlock; | |||
41 | BOOLEAN endList; | |||
42 | ||||
43 | // implements a first fit algorithm | |||
44 | ||||
45 | // find the first block that fits | |||
46 | ||||
47 | AcquireSpinLock (&mHostContextCommon.MemoryLock); | |||
48 | ||||
49 | Address = mHostContextCommon.HeapFree; // get begining of freelist | |||
50 | ||||
51 | PrevBlock = (HEAP_HEADER *) NULL((void *) 0); | |||
| ||||
52 | BlockHeader = (HEAP_HEADER *)(UINTN)Address; | |||
53 | ||||
54 | foundBlock = FALSE((BOOLEAN)(0==1)); | |||
55 | if(BlockHeader == 0) | |||
56 | { | |||
57 | endList = TRUE((BOOLEAN)(1==1)); // we are totally out of space | |||
58 | } | |||
59 | else | |||
60 | { | |||
61 | endList = FALSE((BOOLEAN)(0==1)); | |||
62 | } | |||
63 | while(!endList) | |||
64 | { | |||
65 | if(BlockHeader->BlockLength >= Pages) | |||
66 | { | |||
67 | foundBlock = TRUE((BOOLEAN)(1==1)); | |||
68 | Address = (UINT64) (UINTN) BlockHeader; // begining of block to return | |||
69 | break; | |||
70 | } | |||
71 | ||||
72 | if(BlockHeader->NextBlock == 0) | |||
73 | { | |||
74 | endList = TRUE((BOOLEAN)(1==1)); | |||
75 | break; | |||
76 | } | |||
77 | PrevBlock = BlockHeader; // remember the previous block; | |||
78 | BlockHeader = BlockHeader->NextBlock; | |||
79 | } | |||
80 | ||||
81 | if(endList
| |||
82 | { | |||
83 | DEBUG((EFI_D_ERROR, "AllocatePages(0x%x) fail - no freeblock of the correct size\n", Pages))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "AllocatePages(0x%x) fail - no freeblock of the correct size\n" , Pages); } } while (((BOOLEAN)(0==1))); | |||
84 | #ifdef HEAPCHECK | |||
85 | // ReleaseSpinLock (&mHostContextCommon.MemoryLock); | |||
86 | HeapList(1); | |||
87 | #endif | |||
88 | ReleaseSpinLock (&mHostContextCommon.MemoryLock); | |||
89 | return NULL((void *) 0); | |||
90 | } | |||
91 | ||||
92 | // found a block that fits - now need to make adjustments | |||
93 | ||||
94 | // cases 1 - first in list == change HeapFree | |||
95 | // 2 - middle of list == change previous pointer | |||
96 | // 3 - released block at end of list == change previous pointer | |||
97 | // subcases - block is completely consumed - need to change pointer in previous block | |||
98 | // - block has leftover space | |||
99 | ||||
100 | //if (mHostContextCommon.HeapBottom + STM_PAGES_TO_SIZE(Pages) > mHostContextCommon.HeapTop) { | |||
101 | // DEBUG ((EFI_D_ERROR, "AllocatePages(%x) fail\n", Pages)); | |||
102 | // ReleaseSpinLock (&mHostContextCommon.MemoryLock); | |||
103 | // //CpuDeadLoop (); | |||
104 | // return NULL; | |||
105 | //} | |||
106 | ||||
107 | // (1) breakup block (if necessary) | |||
108 | // (2) point HeapFree to the new block (or to the next block in the event the current block is consumed | |||
109 | ||||
110 | if(BlockHeader->BlockLength == Pages) | |||
111 | { | |||
112 | NewBlock = (BlockHeader->NextBlock); // get next block in the list | |||
113 | } | |||
114 | else // need to break the block up | |||
115 | { | |||
116 | NewBlock = (HEAP_HEADER *)(UINTN)(Address + ((UINT64)(UINTN)STM_PAGES_TO_SIZE(Pages)( (Pages) << 12))); // second half of block | |||
117 | NewBlock->NextBlock = BlockHeader->NextBlock; | |||
118 | NewBlock->BlockLength = BlockHeader->BlockLength - Pages; | |||
119 | } | |||
120 | ||||
121 | if(BlockHeader == (HEAP_HEADER *)(UINTN) mHostContextCommon.HeapFree) | |||
122 | { | |||
123 | mHostContextCommon.HeapFree = (UINT64) NewBlock; | |||
124 | } | |||
125 | else | |||
126 | { | |||
127 | PrevBlock->NextBlock = NewBlock; | |||
| ||||
128 | } | |||
129 | ||||
130 | //Address = mHostContextCommon.HeapTop - STM_PAGES_TO_SIZE(Pages); | |||
131 | //mHostContextCommon.HeapTop = Address; | |||
132 | #ifdef HEAPCHECK | |||
133 | HeapList(2); | |||
134 | #endif | |||
135 | ReleaseSpinLock (&mHostContextCommon.MemoryLock); | |||
136 | ZeroMem ((VOIDvoid *)(UINTN)Address, STM_PAGES_TO_SIZE (Pages)( (Pages) << 12)); | |||
137 | #ifdef HEAPCHECK | |||
138 | DEBUG((EFI_D_ERROR, "****Allocating 0x%x pages at 0x%016llx - %d Cleared\n", Pages, Address, STM_PAGES_TO_SIZE (Pages)))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "****Allocating 0x%x pages at 0x%016llx - %d Cleared\n" , Pages, Address, ( (Pages) << 12)); } } while (((BOOLEAN )(0==1))); | |||
139 | #endif | |||
140 | return (VOIDvoid *)(UINTN)Address; | |||
141 | } | |||
142 | ||||
143 | /** | |||
144 | ||||
145 | This function free pages in MSEG. | |||
146 | ||||
147 | @param Address pages address | |||
148 | @param Pages pages number | |||
149 | ||||
150 | **/ | |||
151 | VOIDvoid | |||
152 | FreePages ( | |||
153 | IN VOIDvoid *Address, | |||
154 | IN UINTN Pages | |||
155 | ) | |||
156 | { | |||
157 | HEAP_HEADER * CurrentBlock; | |||
158 | HEAP_HEADER * PreviousBlock; | |||
159 | #ifdef HEAPCHECK | |||
160 | DEBUG((EFI_D_ERROR, "****Freeing 0x%x pages at 0x%016llx\n", Pages, (UINTN) Address))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "****Freeing 0x%x pages at 0x%016llx\n" , Pages, (UINTN) Address); } } while (((BOOLEAN)(0==1))); | |||
161 | #endif | |||
162 | AcquireSpinLock (&mHostContextCommon.MemoryLock); | |||
163 | ||||
164 | // (1) Set header | |||
165 | // (2) find place in buffer chain | |||
166 | // (3) coalese(sp?) | |||
167 | ||||
168 | Address = (void *)((UINTN) Address & ~0xfff); // mask out the lower 12 bits | |||
169 | ||||
170 | ((HEAP_HEADER *)Address)->NextBlock = 0L; | |||
171 | ((HEAP_HEADER *)Address)->BlockLength = Pages; | |||
172 | ||||
173 | #ifdef HEAPCHECK | |||
174 | DEBUG((EFI_D_ERROR, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
175 | ((HEAP_HEADER *)Address)->NextBlock,do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
176 | ((HEAP_HEADER *)Address)->BlockLength))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))); | |||
177 | #endif | |||
178 | PreviousBlock = 0L; | |||
179 | CurrentBlock = (HEAP_HEADER *)(UINTN) mHostContextCommon.HeapFree; | |||
180 | ||||
181 | // find where it belongs | |||
182 | while( CurrentBlock != 0L) | |||
183 | { | |||
184 | if((UINTN)CurrentBlock > (UINTN)Address) | |||
185 | { | |||
186 | break; | |||
187 | } | |||
188 | ||||
189 | PreviousBlock = CurrentBlock; | |||
190 | CurrentBlock = CurrentBlock->NextBlock; | |||
191 | } | |||
192 | ||||
193 | //link it in | |||
194 | if(PreviousBlock == 0L) | |||
195 | { | |||
196 | // at beginning of list | |||
197 | ((HEAP_HEADER *)Address)->NextBlock = CurrentBlock; | |||
198 | mHostContextCommon.HeapFree = (UINT64)Address; | |||
199 | } | |||
200 | else | |||
201 | { | |||
202 | // somewhere in list | |||
203 | ((HEAP_HEADER *)Address)->NextBlock = CurrentBlock; | |||
204 | PreviousBlock->NextBlock = (HEAP_HEADER *)Address; | |||
205 | } | |||
206 | #ifdef HEAPCHECK | |||
207 | DEBUG((EFI_D_ERROR, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
208 | ((HEAP_HEADER *)Address)->NextBlock,do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
209 | ((HEAP_HEADER *)Address)->BlockLength))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))); | |||
210 | #endif | |||
211 | // coalesce | |||
212 | ||||
213 | // First check the block after | |||
214 | if(CurrentBlock != 0L) | |||
215 | { | |||
216 | if(((UINT64)Address + STM_PAGES_TO_SIZE(Pages)( (Pages) << 12)) == (UINT64)(UINTN)CurrentBlock) | |||
217 | { | |||
218 | #ifdef HEAPCHECK | |||
219 | DEBUG((EFI_D_ERROR, "Combined with block after\n"))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Combined with block after\n" ); } } while (((BOOLEAN)(0==1))); | |||
220 | #endif | |||
221 | ((HEAP_HEADER *)Address)->NextBlock = CurrentBlock->NextBlock; | |||
222 | ((HEAP_HEADER *)Address)->BlockLength = ((HEAP_HEADER *)Address)->BlockLength + CurrentBlock->BlockLength; | |||
223 | #ifdef HEAPCHECK | |||
224 | DEBUG((EFI_D_ERROR, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
225 | ((HEAP_HEADER *)Address)->NextBlock,do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))) | |||
226 | ((HEAP_HEADER *)Address)->BlockLength))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Address->NextBlock: 0x%016llx Address->BlockLength: 0x%016llx\n" , ((HEAP_HEADER *)Address)->NextBlock, ((HEAP_HEADER *)Address )->BlockLength); } } while (((BOOLEAN)(0==1))); | |||
227 | #endif | |||
228 | } | |||
229 | } | |||
230 | ||||
231 | // then then block before | |||
232 | if(PreviousBlock != 0L) | |||
233 | { | |||
234 | if(((UINT64)PreviousBlock + STM_PAGES_TO_SIZE((UINT64)PreviousBlock->BlockLength)( ((UINT64)PreviousBlock->BlockLength) << 12)) == (UINT64)Address) | |||
235 | { | |||
236 | #ifdef HEAPCHECK | |||
237 | DEBUG((EFI_D_ERROR, "Combined with block before\n"))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "Combined with block before\n" ); } } while (((BOOLEAN)(0==1))); | |||
238 | ||||
239 | DEBUG((EFI_D_ERROR, "PreviousBlock: 0x%016llx BlockLength: 0x%016llx Add: 0x%016llx\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "PreviousBlock: 0x%016llx BlockLength: 0x%016llx Add: 0x%016llx\n" , PreviousBlock, ( ((UINT64)PreviousBlock->BlockLength) << 12), ((HEAP_HEADER*) Address)); } } while (((BOOLEAN)(0==1)) ) | |||
240 | PreviousBlock,do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "PreviousBlock: 0x%016llx BlockLength: 0x%016llx Add: 0x%016llx\n" , PreviousBlock, ( ((UINT64)PreviousBlock->BlockLength) << 12), ((HEAP_HEADER*) Address)); } } while (((BOOLEAN)(0==1)) ) | |||
241 | STM_PAGES_TO_SIZE((UINT64)PreviousBlock->BlockLength),do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "PreviousBlock: 0x%016llx BlockLength: 0x%016llx Add: 0x%016llx\n" , PreviousBlock, ( ((UINT64)PreviousBlock->BlockLength) << 12), ((HEAP_HEADER*) Address)); } } while (((BOOLEAN)(0==1)) ) | |||
242 | ((HEAP_HEADER*) Address)))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, "PreviousBlock: 0x%016llx BlockLength: 0x%016llx Add: 0x%016llx\n" , PreviousBlock, ( ((UINT64)PreviousBlock->BlockLength) << 12), ((HEAP_HEADER*) Address)); } } while (((BOOLEAN)(0==1)) ); | |||
243 | #endif | |||
244 | PreviousBlock->NextBlock = ((HEAP_HEADER *)Address)->NextBlock; | |||
245 | PreviousBlock->BlockLength += ((HEAP_HEADER *) Address)->BlockLength; | |||
246 | } | |||
247 | } | |||
248 | ||||
249 | // if ((UINT64)(UINTN)Address == mHostContextCommon.HeapTop) { | |||
250 | // mHostContextCommon.HeapTop += STM_PAGES_TO_SIZE(Pages); | |||
251 | // } | |||
252 | #ifdef HEAPCHECK | |||
253 | HeapList(3); | |||
254 | #endif | |||
255 | ReleaseSpinLock (&mHostContextCommon.MemoryLock); | |||
256 | return ; | |||
257 | } | |||
258 | ||||
259 | void HeapList(int id) | |||
260 | { | |||
261 | HEAP_HEADER * CurrentBlock = (HEAP_HEADER *)(UINTN) mHostContextCommon.HeapFree; | |||
262 | ||||
263 | DEBUG((EFI_D_ERROR, " ***HeapList %d Start***\n", id))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, " ***HeapList %d Start***\n" , id); } } while (((BOOLEAN)(0==1))); | |||
264 | ||||
265 | while(CurrentBlock != 0L) | |||
266 | { | |||
267 | DEBUG((EFI_D_ERROR, " Block: 0x%llx BlockLength: 0x%x NextBlock: 0x%llx\n", CurrentBlock, CurrentBlock->BlockLength, CurrentBlock->NextBlock))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, " Block: 0x%llx BlockLength: 0x%x NextBlock: 0x%llx\n" , CurrentBlock, CurrentBlock->BlockLength, CurrentBlock-> NextBlock); } } while (((BOOLEAN)(0==1))); | |||
268 | CurrentBlock = CurrentBlock->NextBlock; | |||
269 | } | |||
270 | ||||
271 | DEBUG((EFI_D_ERROR, " ***HeapList %d Done***\n", id))do { if (DebugPrintEnabled ()) { DebugPrint (0x80000000, " ***HeapList %d Done***\n" , id); } } while (((BOOLEAN)(0==1))); | |||
272 | } |