Skip to content

Commit baee589

Browse files
author
전상현
committed
[100_System] ELF파서 최적화
1 parent d8d968d commit baee589

File tree

5 files changed

+131
-101
lines changed

5 files changed

+131
-101
lines changed

Src/100_System/100_SystemA.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
</ItemGroup>
291291
<ItemGroup>
292292
<ClCompile Include="ELFParser.cpp" />
293+
<ClCompile Include="ELFParserT.cpp" />
293294
<ClCompile Include="Environment.cpp" />
294295
<ClCompile Include="EnvironmentT.cpp" />
295296
<ClCompile Include="EnvironmentT_Win.cpp" />

Src/100_System/100_SystemW.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
</ItemGroup>
291291
<ItemGroup>
292292
<ClCompile Include="ELFParser.cpp" />
293+
<ClCompile Include="ELFParserT.cpp" />
293294
<ClCompile Include="Environment.cpp" />
294295
<ClCompile Include="EnvironmentT.cpp" />
295296
<ClCompile Include="EnvironmentT_Win.cpp" />

Src/100_System/ELFParser.cpp

Lines changed: 60 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,200 +2,165 @@
22
#include "ELFParser.h"
33
#include "Log.h"
44
#include "FileSystem.h"
5+
#include "KernelObject.h"
56

67
namespace core
78
{
8-
//////////////////////////////////////////////////////////////////////////
9-
CELFParser::CELFParser(void)
10-
: m_strFilePath()
11-
, m_mapSection64()
12-
{
13-
14-
}
9+
static LPCSTR g_pszFileVersionName = "FileVersion";
10+
static LPCSTR g_pszProductVersionName = "ProductVersion";
1511

1612
//////////////////////////////////////////////////////////////////////////
17-
#define READ_BIN_FROM_FILE(TARGET) \
18-
{\
19-
size_t tRead = fread(&TARGET, 1, sizeof(TARGET), pFile);\
20-
if( tRead != sizeof(TARGET) )\
21-
throw exception_format("ELF %s read failure, try:%lu, read:%lu", #TARGET, sizeof(TARGET), tRead);\
22-
}
23-
24-
//////////////////////////////////////////////////////////////////////////
25-
ECODE CELFParser::Parse(const char* pszFilePath)
13+
CELFParser::CELFParser(void)
14+
: m_mapSection64()
2615
{
27-
FILE* pFile = NULL;
28-
29-
try
30-
{
31-
pFile = fopenA(pszFilePath, "rb");
32-
if( NULL == pFile )
33-
throw exception_format("file open failure, %s", pszFilePath);
34-
35-
ST_ELF_IDENTITY stIdentity = { 0, };
36-
READ_BIN_FROM_FILE(stIdentity);
37-
38-
if( 0x7F != stIdentity.ei_magic[0]
39-
|| 'E' != stIdentity.ei_magic[1]
40-
|| 'L' != stIdentity.ei_magic[2]
41-
|| 'F' != stIdentity.ei_magic[3] )
42-
throw exception_format("ELF magic is not matched");
43-
44-
ECODE nRet = EC_SUCCESS;
45-
if( 1 == stIdentity.ei_class )
46-
nRet = Parse32Bit(pFile, stIdentity);
47-
48-
if( 2 == stIdentity.ei_class )
49-
nRet = Parse64Bit(pFile, stIdentity);
50-
51-
if( EC_SUCCESS != nRet )
52-
throw exception_format("ELF parsing failure, %d", nRet);
53-
54-
fclose(pFile);
55-
}
56-
catch (std::exception& e)
57-
{
58-
e; // Declaration to resolve unused variable warning
59-
//Log_Error("%s", e.what());
60-
if( pFile )
61-
fclose(pFile);
62-
return EC_INTERNAL_ERROR;
63-
}
64-
65-
m_strFilePath = pszFilePath;
66-
return EC_SUCCESS;
6716
}
6817

6918
//////////////////////////////////////////////////////////////////////////
70-
ECODE CELFParser::QueryELFVersion(const char* pszSectioName, ST_VERSIONINFO& stVersionInfo)
19+
ECODE CELFParser::QueryVersion(HANDLE hFile, const char* pszSectionName, ST_VERSIONINFO& stVersionInfo)
7120
{
7221
ECODE nRet = EC_SUCCESS;
73-
FILE* pFile = NULL;
7422
try
7523
{
76-
CELFSectionHeader64It iter = m_mapSection64.find(pszSectioName);
24+
CELFSectionHeader64It iter = m_mapSection64.find(pszSectionName);
7725

7826
nRet = EC_NO_DATA;
7927
if( iter == m_mapSection64.end() )
8028
throw exception_format("VersionInfo section is not found");
8129

8230
const ST_ELF_SECTION_HEADER64& shVersionInfo = iter->second;
8331

84-
nRet = EC_INVALID_FILE;
85-
pFile = fopenA(m_strFilePath.c_str(), "rb");
86-
if( NULL == pFile )
87-
throw exception_format("File(%s) open failure", m_strFilePath.c_str());
88-
89-
fseek(pFile, (long)shVersionInfo.sh_offset, SEEK_SET);
32+
SetFilePointer(hFile, (long)shVersionInfo.sh_offset, FILE_BEGIN_);
9033

9134
int nVersion[4];
9235
const size_t tVersionStructSize = sizeof(nVersion);
9336
if( (shVersionInfo.sh_size > 0) && (shVersionInfo.sh_size%tVersionStructSize > 0) )
9437
throw exception_format("Section VersionInfo size is not matched, try:%lu, stored:%lu", sizeof(nVersion), shVersionInfo.sh_size);
9538

96-
size_t tRead = fread(nVersion, 1, sizeof(nVersion), pFile);
97-
if( tRead != sizeof(nVersion) )
98-
throw exception_format("VersionInfo section read failure, try:%lu, read:%lu", sizeof(nVersion), tRead);
39+
DWORD dwReadSize = 0;
40+
if( !ReadFile(hFile, nVersion, sizeof(nVersion), &dwReadSize) )
41+
throw exception_format("VersionInfo section read failure, try:%lu, read:%lu", sizeof(nVersion), dwReadSize);
9942

10043
stVersionInfo.dwMajor = nVersion[0];
10144
stVersionInfo.dwMinor = nVersion[1];
10245
stVersionInfo.dwPatch = nVersion[2];
10346
stVersionInfo.dwBuild = nVersion[3];
104-
fclose(pFile);
10547
}
10648
catch (std::exception& e)
10749
{
108-
e; // Declaration to resolve unused variable warning
109-
//Log_Error("%s", e.what()); // skip for unexpected console output, caused by ConsolFramework
110-
if( pFile )
111-
fclose(pFile);
50+
Log_Debug("%s", e.what());
11251
return nRet;
11352
}
11453

11554
return EC_SUCCESS;
11655
}
11756

11857
//////////////////////////////////////////////////////////////////////////
119-
ECODE CELFParser::QueryFileVersion(ST_VERSIONINFO& stVersionInfo)
58+
ECODE CELFParser::QueryFileVersion(ST_VERSIONINFO& outVersionInfo)
12059
{
121-
return QueryELFVersion("FileVersion", stVersionInfo);
60+
auto iter = m_mapVersionInfo.find(g_pszFileVersionName);
61+
if (iter == m_mapVersionInfo.end())
62+
return EC_NO_DATA;
63+
64+
outVersionInfo = iter->second;
65+
return EC_SUCCESS;
12266
}
12367

12468
//////////////////////////////////////////////////////////////////////////
125-
ECODE CELFParser::QueryProductVersion(ST_VERSIONINFO& stVersionInfo)
69+
ECODE CELFParser::QueryProductVersion(ST_VERSIONINFO& outVersionInfo)
12670
{
127-
return QueryELFVersion("ProductVersion", stVersionInfo);
71+
auto iter = m_mapVersionInfo.find(g_pszProductVersionName);
72+
if (iter == m_mapVersionInfo.end())
73+
return EC_NO_DATA;
74+
75+
outVersionInfo = iter->second;
76+
return EC_SUCCESS;
12877
}
12978

13079
//////////////////////////////////////////////////////////////////////////
131-
ECODE CELFParser::Parse32Bit(FILE* pFile, const ST_ELF_IDENTITY& stIdentity)
80+
ECODE CELFParser::Parse32Bit(HANDLE hFile, const ST_ELF_IDENTITY& stIdentity)
13281
{
82+
DWORD dwRead = 0;
83+
13384
ST_ELF_HEADER32 stHeader = { 0, };
134-
READ_BIN_FROM_FILE(stHeader);
85+
if (!ReadFile(hFile, &stHeader, sizeof(stHeader), &dwRead))
86+
return EC_READ_FAILURE;
13587

13688
return EC_SUCCESS;
13789
}
13890

13991
//////////////////////////////////////////////////////////////////////////
140-
ECODE CELFParser::Parse64Bit(FILE* pFile, const ST_ELF_IDENTITY& stIdentity)
92+
ECODE CELFParser::Parse64Bit(HANDLE hFile, const ST_ELF_IDENTITY& stIdentity)
14193
{
94+
ECODE nRet = EC_SUCCESS;
14295
try
14396
{
97+
DWORD dwRead = 0;
98+
14499
ST_ELF_HEADER64 stHeader = { 0, };
145-
READ_BIN_FROM_FILE(stHeader);
100+
nRet = EC_READ_FAILURE;
101+
if (!ReadFile(hFile, &stHeader, sizeof(stHeader), &dwRead))
102+
throw exception_format(TEXT("Reading ELF header has failed."));
146103

147-
fseek(pFile, (long)stHeader.e_phoff, SEEK_SET);
104+
SetFilePointer(hFile, (long)stHeader.e_phoff, FILE_BEGIN_);
148105
std::vector<ST_ELF_PROGRAM_HEADER64> vecPHTable;
149106
size_t i;
150107
for(i=0; i<stHeader.e_phnum; i++)
151108
{
152109
ST_ELF_PROGRAM_HEADER64 stPH;
153-
READ_BIN_FROM_FILE(stPH);
110+
nRet = EC_READ_FAILURE;
111+
if (!ReadFile(hFile, &stPH, sizeof(stPH), &dwRead))
112+
throw exception_format(TEXT("Reading ELF PH has failed."));
154113

155114
vecPHTable.push_back(stPH);
156115
}
157116

158-
fseek(pFile, (long)stHeader.e_shoff, SEEK_SET);
117+
SetFilePointer(hFile, (long)stHeader.e_shoff, FILE_BEGIN_);
159118
std::vector<ST_ELF_SECTION_HEADER64> vecSHTable;
160119
for(i=0; i<stHeader.e_shnum; i++)
161120
{
162-
ST_ELF_SECTION_HEADER64 stPH;
163-
READ_BIN_FROM_FILE(stPH);
121+
ST_ELF_SECTION_HEADER64 stSH;
122+
nRet = EC_READ_FAILURE;
123+
if (!ReadFile(hFile, &stSH, sizeof(stSH), &dwRead))
124+
throw exception_format(TEXT("Reading ELF SH has failed."));
164125

165-
vecSHTable.push_back(stPH);
126+
vecSHTable.push_back(stSH);
166127
}
167128

168129
std::vector<char> vecStringTable;
130+
nRet = EC_INVALID_DATA;
169131
if( vecSHTable.size() < stHeader.e_shstrndx )
170132
throw exception_format("Invalid ELF string table index");
171133

134+
nRet = EC_INVALID_DATA;
172135
if( SHT_STRTAB != vecSHTable[stHeader.e_shstrndx].sh_type )
173136
throw exception_format("Invalid ELF string table location");
174137

175138
{
176139
const ST_ELF_SECTION_HEADER64& shStringTable = vecSHTable[stHeader.e_shstrndx];
177-
fseek(pFile, (long)shStringTable.sh_offset, SEEK_SET);
140+
SetFilePointer(hFile, (long)shStringTable.sh_offset, FILE_BEGIN_);
178141
vecStringTable.resize((size_t)shStringTable.sh_size);
179-
fread(&vecStringTable[0], (size_t)shStringTable.sh_size, 1, pFile);
142+
143+
nRet = EC_READ_FAILURE;
144+
if (!ReadFile(hFile, &vecStringTable[0], (size_t)shStringTable.sh_size, &dwRead))
145+
throw exception_format("Reading ELF string table has failed");
180146
}
181147

182148
for(i=0; i<vecSHTable.size(); i++)
183149
{
184150
const ST_ELF_SECTION_HEADER64& curSectionHeader = vecSHTable[i];
185-
if( vecStringTable.size() <= curSectionHeader.sh_name )
186-
m_mapSection64.insert(std::make_pair("InvalidName", curSectionHeader));
187-
else
151+
if(curSectionHeader.sh_name < vecStringTable.size())
188152
{
189153
std::string strName = &vecStringTable[curSectionHeader.sh_name];
190154
m_mapSection64.insert(std::make_pair(strName, curSectionHeader));
191155
}
156+
else
157+
m_mapSection64.insert(std::make_pair("InvalidName", curSectionHeader));
192158
}
193159
}
194160
catch (std::exception& e)
195161
{
196-
e; // Declaration to resolve unused variable warning
197-
//Log_Error("%s", e.what());
198-
return EC_INTERNAL_ERROR;
162+
Log_Debug("%s", e.what());
163+
return nRet;
199164
}
200165

201166
return EC_SUCCESS;

Src/100_System/ELFParser.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,21 +238,23 @@ namespace core
238238
typedef std::map<std::string, ST_ELF_SECTION_HEADER64> CELFSectionHeader64;
239239
typedef std::map<std::string, ST_ELF_SECTION_HEADER64>::iterator CELFSectionHeader64It;
240240

241-
std::string m_strFilePath;
241+
std::map<std::string, ST_VERSIONINFO> m_mapVersionInfo;
242+
242243
CELFSectionHeader64 m_mapSection64;
243244

244245
public:
245246
CELFParser(void);
246247

247248
ECODE Parse(const char* pszFilePath);
248-
ECODE QueryFileVersion(ST_VERSIONINFO& stVersionInfo);
249-
ECODE QueryProductVersion(ST_VERSIONINFO& stVersionInfo);
249+
ECODE Parse(const wchar_t* pszFilePath);
250+
ECODE QueryFileVersion(ST_VERSIONINFO& outVersionInfo);
251+
ECODE QueryProductVersion(ST_VERSIONINFO& outVersionInfo);
250252

251253
private:
252-
ECODE Parse32Bit(FILE* pFile, const ST_ELF_IDENTITY& stIdentity);
253-
ECODE Parse64Bit(FILE* pFile, const ST_ELF_IDENTITY& stIdentity);
254+
ECODE Parse32Bit(HANDLE hFile, const ST_ELF_IDENTITY& stIdentity);
255+
ECODE Parse64Bit(HANDLE hFile, const ST_ELF_IDENTITY& stIdentity);
254256

255-
ECODE QueryELFVersion(const char* pszSectioName, ST_VERSIONINFO& stVersionInfo);
257+
ECODE QueryVersion(HANDLE hFile, const char* pszSectioName, ST_VERSIONINFO& stVersionInfo);
256258

257259
};
258260

Src/100_System/ELFParserT.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "stdafx.h"
2+
#include "ELFParser.h"
3+
#include "Log.h"
4+
#include "FileSystem.h"
5+
#include "KernelObject.h"
6+
7+
namespace core
8+
{
9+
static LPCSTR g_pszFileVersionName = "FileVersion";
10+
static LPCSTR g_pszProductVersionName = "ProductVersion";
11+
12+
//////////////////////////////////////////////////////////////////////////
13+
ECODE CELFParser::Parse(LPCTSTR pszFilePath)
14+
{
15+
HANDLE hFile = NULL;
16+
17+
try
18+
{
19+
hFile = CreateFile(pszFilePath, GENERIC_READ_, OPEN_ALWAYS_, 0);
20+
if (NULL == hFile)
21+
throw exception_format(TEXT("ELF File:%s open failure, %s"), pszFilePath);
22+
23+
DWORD dwReadSize = 0;
24+
ST_ELF_IDENTITY stIdentity = { 0, };
25+
if (!ReadFile(hFile, &stIdentity, sizeof(stIdentity), &dwReadSize))
26+
throw exception_format(TEXT("ELF header reading failure, read:%u"), dwReadSize);
27+
28+
if (0x7F != stIdentity.ei_magic[0]
29+
|| 'E' != stIdentity.ei_magic[1]
30+
|| 'L' != stIdentity.ei_magic[2]
31+
|| 'F' != stIdentity.ei_magic[3])
32+
throw exception_format("ELF magic is not matched");
33+
34+
ECODE nRet = EC_NO_DATA;
35+
if (1 == stIdentity.ei_class)
36+
nRet = Parse32Bit(hFile, stIdentity);
37+
if (2 == stIdentity.ei_class)
38+
nRet = Parse64Bit(hFile, stIdentity);
39+
if (EC_SUCCESS != nRet)
40+
throw exception_format("ELF parsing failure, %d", nRet);
41+
42+
ST_VERSIONINFO stVersion;
43+
if (EC_SUCCESS == QueryVersion(hFile, g_pszFileVersionName, stVersion))
44+
m_mapVersionInfo.insert(std::make_pair(g_pszFileVersionName, stVersion));
45+
46+
if (EC_SUCCESS == QueryVersion(hFile, g_pszProductVersionName, stVersion))
47+
m_mapVersionInfo.insert(std::make_pair(g_pszProductVersionName, stVersion));
48+
49+
CloseFile(hFile);
50+
}
51+
catch (std::exception& e)
52+
{
53+
Log_Debug("%s", e.what());
54+
if (hFile)
55+
CloseFile(hFile);
56+
return EC_INTERNAL_ERROR;
57+
}
58+
59+
return EC_SUCCESS;
60+
}
61+
}

0 commit comments

Comments
 (0)