Bug Summary

File:Source/Core/Core/Src/Boot/ElfReader.cpp
Location:line 203, column 30
Description:Dereference of null pointer

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include <string>
6
7#include "Common.h"
8#include "../Debugger/Debugger_SymbolMap.h"
9#include "../HW/Memmap.h"
10#include "../PowerPC/PPCSymbolDB.h"
11#include "ElfReader.h"
12
13void bswap(Elf32_Word &w) {w = Common::swap32(w);}
14void bswap(Elf32_Half &w) {w = Common::swap16(w);}
15
16static void byteswapHeader(Elf32_Ehdr &ELF_H)
17{
18 bswap(ELF_H.e_type);
19 bswap(ELF_H.e_machine);
20 bswap(ELF_H.e_ehsize);
21 bswap(ELF_H.e_phentsize);
22 bswap(ELF_H.e_phnum);
23 bswap(ELF_H.e_shentsize);
24 bswap(ELF_H.e_shnum);
25 bswap(ELF_H.e_shstrndx);
26 bswap(ELF_H.e_version);
27 bswap(ELF_H.e_entry);
28 bswap(ELF_H.e_phoff);
29 bswap(ELF_H.e_shoff);
30 bswap(ELF_H.e_flags);
31}
32
33static void byteswapSegment(Elf32_Phdr &sec)
34{
35 bswap(sec.p_align);
36 bswap(sec.p_filesz);
37 bswap(sec.p_flags);
38 bswap(sec.p_memsz);
39 bswap(sec.p_offset);
40 bswap(sec.p_paddr);
41 bswap(sec.p_vaddr);
42 bswap(sec.p_type);
43}
44
45static void byteswapSection(Elf32_Shdr &sec)
46{
47 bswap(sec.sh_addr);
48 bswap(sec.sh_addralign);
49 bswap(sec.sh_entsize);
50 bswap(sec.sh_flags);
51 bswap(sec.sh_info);
52 bswap(sec.sh_link);
53 bswap(sec.sh_name);
54 bswap(sec.sh_offset);
55 bswap(sec.sh_size);
56 bswap(sec.sh_type);
57}
58
59ElfReader::ElfReader(void *ptr)
60{
61 base = (char*)ptr;
62 base32 = (u32 *)ptr;
63 header = (Elf32_Ehdr*)ptr;
64 byteswapHeader(*header);
65
66 segments = (Elf32_Phdr *)(base + header->e_phoff);
67 sections = (Elf32_Shdr *)(base + header->e_shoff);
68
69 for (int i = 0; i < GetNumSegments(); i++)
70 {
71 byteswapSegment(segments[i]);
72 }
73
74 for (int i = 0; i < GetNumSections(); i++)
75 {
76 byteswapSection(sections[i]);
77 }
78 entryPoint = header->e_entry;
79}
80
81const char *ElfReader::GetSectionName(int section) const
82{
83 if (sections[section].sh_type == SHT_NULL0)
84 return NULL__null;
85
86 int nameOffset = sections[section].sh_name;
87 char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx);
88
89 if (ptr)
90 return ptr + nameOffset;
91 else
92 return NULL__null;
93}
94
95bool ElfReader::LoadInto(u32 vaddr)
96{
97 DEBUG_LOG(MASTER_LOG,"String section: %i", header->e_shstrndx)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 97, "String section: %i", header->e_shstrndx); } } while
(0)
;
98
99// sectionOffsets = new u32[GetNumSections()];
100// sectionAddrs = new u32[GetNumSections()];
101
102 // Should we relocate?
103 bRelocate = (header->e_type != ET_EXEC);
104
105 if (bRelocate)
106 {
107 DEBUG_LOG(MASTER_LOG,"Relocatable module")do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 107, "Relocatable module"); } } while (0)
;
108 entryPoint += vaddr;
109 }
110 else
111 {
112 DEBUG_LOG(MASTER_LOG,"Prerelocated executable")do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 112, "Prerelocated executable"); } } while (0)
;
113 }
114
115 INFO_LOG(MASTER_LOG,"%i segments:", header->e_phnum)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 115, "%i segments:", header->e_phnum); } } while (0)
;
116
117 // First pass : Get the bits into RAM
118 u32 segmentVAddr[32];
119
120 u32 baseAddress = bRelocate?vaddr:0;
121 for (int i = 0; i < header->e_phnum; i++)
122 {
123 Elf32_Phdr *p = segments + i;
124
125 INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 125, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type
, p->p_vaddr, p->p_filesz, p->p_memsz); } } while (0
)
;
126
127 if (p->p_type == PT_LOAD1)
128 {
129 segmentVAddr[i] = baseAddress + p->p_vaddr;
130 u32 writeAddr = segmentVAddr[i];
131
132 const u8 *src = GetSegmentPtr(i);
133 u8 *dst = Memory::GetPointer(writeAddr);
134 u32 srcSize = p->p_filesz;
135 u32 dstSize = p->p_memsz;
136 u32 *s = (u32*)src;
137 u32 *d = (u32*)dst;
138 for (int j = 0; j < (int)(srcSize + 3) / 4; j++)
139 {
140 *d++ = /*_byteswap_ulong*/(*s++);
141 }
142 if (srcSize < dstSize)
143 {
144 //memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss
145 }
146 INFO_LOG(MASTER_LOG,"Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 146, "Loadable Segment Copied to %08x, size %08x", writeAddr
, p->p_memsz); } } while (0)
;
147 }
148 }
149
150 /*
151 LOG(MASTER_LOG,"%i sections:", header->e_shnum);
152
153 for (int i=0; i<GetNumSections(); i++)
154 {
155 Elf32_Shdr *s = &sections[i];
156 const char *name = GetSectionName(i);
157
158 u32 writeAddr = s->sh_addr + baseAddress;
159 sectionOffsets[i] = writeAddr - vaddr;
160 sectionAddrs[i] = writeAddr;
161
162 if (s->sh_flags & SHF_ALLOC)
163 {
164 LOG(MASTER_LOG,"Data Section found: %s Sitting at %08x, size %08x", name, writeAddr, s->sh_size);
165
166 }
167 else
168 {
169 LOG(MASTER_LOG,"NonData Section found: %s Ignoring (size=%08x) (flags=%08x)", name, s->sh_size, s->sh_flags);
170 }
171 }
172*/
173 INFO_LOG(MASTER_LOG,"Done loading.")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::MASTER_LOG, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/ElfReader.cpp"
, 173, "Done loading."); } } while (0)
;
174 return true;
175}
176
177SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const
178{
179 for (int i = firstSection; i < header->e_shnum; i++)
180 {
181 const char *secname = GetSectionName(i);
182
183 if (secname != NULL__null && strcmp(name, secname) == 0)
184 return i;
185 }
186 return -1;
187}
188
189bool ElfReader::LoadSymbols()
190{
191 bool hasSymbols = false;
192 SectionID sec = GetSectionByName(".symtab");
193 if (sec != -1)
1
Taking true branch
194 {
195 int stringSection = sections[sec].sh_link;
196 const char *stringBase = (const char *)GetSectionDataPtr(stringSection);
197
198 //We have a symbol table!
199 Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec));
200 int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
201 for (int sym = 0; sym < numSymbols; sym++)
2
Assuming 'sym' is < 'numSymbols'
3
Loop condition is true. Entering loop body
202 {
203 int size = Common::swap32(symtab[sym].st_size);
4
Dereference of null pointer
204 if (size == 0)
205 continue;
206
207 // int bind = symtab[sym].st_info >> 4;
208 int type = symtab[sym].st_info & 0xF;
209 int sectionIndex = Common::swap16(symtab[sym].st_shndx);
210 int value = Common::swap32(symtab[sym].st_value);
211 const char *name = stringBase + Common::swap32(symtab[sym].st_name);
212 if (bRelocate)
213 value += sectionAddrs[sectionIndex];
214
215 int symtype = Symbol::SYMBOL_DATA;
216 switch (type)
217 {
218 case STT_OBJECT1:
219 symtype = Symbol::SYMBOL_DATA; break;
220 case STT_FUNC2:
221 symtype = Symbol::SYMBOL_FUNCTION; break;
222 default:
223 continue;
224 }
225 g_symbolDB.AddKnownSymbol(value, size, name, symtype);
226 hasSymbols = true;
227 }
228 }
229 g_symbolDB.Index();
230 return hasSymbols;
231}