1+ #include < sys/stat.h>
2+ #include < sys/mman.h>
3+ #include " ElfUtils.h"
4+ #include < fcntl.h>
5+ #include < unistd.h>
6+
7+ bool ElfOpen (const std::string& fullModulePath, std::function<void (ElfPack libMap)> callback)
8+ {
9+ int libFd = open (fullModulePath.c_str (), O_RDONLY);
10+
11+ if (libFd < 0 )
12+ return false ;
13+
14+ struct stat libStats;
15+
16+ if (fstat (libFd, &libStats) != 0 )
17+ {
18+ close (libFd);
19+ return false ;
20+ }
21+
22+ ElfPack libMap;
23+
24+ libMap.baseV = mmap (NULL , libStats.st_size , PROT_READ, MAP_SHARED, libFd, 0 );
25+
26+ if (libMap.res == -1 )
27+ {
28+ close (libFd);
29+ return false ;
30+ }
31+
32+ callback (libMap);
33+
34+ munmap (libMap.baseV , libStats.st_size );
35+
36+ close (libFd);
37+ return true ;
38+ }
39+
40+ Elf32_Shdr* ElfSectionByIndex (ElfPack libMap, unsigned int sectionIdx)
41+ {
42+ if ((sectionIdx < libMap.header ->e_shnum ) == false )
43+ return nullptr ;
44+
45+ Elf32_Shdr* libElfSections = (Elf32_Shdr*)(libMap.base + libMap.header ->e_shoff );
46+
47+ return libElfSections + sectionIdx;
48+ }
49+
50+ void ElfForEachSection (ElfPack libMap, std::function<bool (Elf32_Shdr* pCurrentSection)> callback)
51+ {
52+ Elf32_Shdr* libElfSections = (Elf32_Shdr*)(libMap.base + libMap.header ->e_shoff );
53+
54+ for (int i = 0 ; i < libMap.header ->e_shnum ; i++)
55+ {
56+ if (callback (libElfSections + i) == false )
57+ break ;
58+ }
59+ }
60+
61+ Elf32_Shdr* ElfLookupSection (ElfPack libMap, uint32_t sectionType)
62+ {
63+ Elf32_Shdr* secHeader = nullptr ;
64+
65+ ElfForEachSection (libMap, [&](Elf32_Shdr* currSection){
66+ if (currSection->sh_type != sectionType)
67+ return true ;
68+
69+ secHeader = currSection;
70+
71+ return false ;
72+ });
73+
74+ return secHeader;
75+ }
76+
77+ Elf32_Shdr* ElfGetSymbolSection (ElfPack libMap)
78+ {
79+ Elf32_Shdr* result = nullptr ;
80+
81+ result = ElfLookupSection (libMap, SHT_SYMTAB);
82+
83+ if (result)
84+ return result;
85+
86+ result = ElfLookupSection (libMap, SHT_DYNSYM);
87+
88+ if (result)
89+ return result;
90+
91+ return result;
92+ }
93+
94+ bool ElfForEachSymbol (ElfPack libMap, std::function<bool (Elf32_Sym* pCurrentSym, const char * pCurrSymName)> callback)
95+ {
96+ Elf32_Shdr* symTable = ElfGetSymbolSection (libMap);
97+
98+ if (symTable == nullptr )
99+ return false ;
100+
101+ Elf32_Shdr* strTable = ElfSectionByIndex (libMap, symTable->sh_link );
102+
103+ if (strTable == nullptr )
104+ return false ;
105+
106+ const char * elfStrBlob = (const char *)(libMap.base + strTable->sh_offset );
107+
108+ int nSyms = symTable->sh_size / sizeof (Elf32_Sym);
109+ Elf32_Sym* symEntry = (Elf32_Sym*)(libMap.base + symTable->sh_offset );
110+ Elf32_Sym* symEnd = symEntry + nSyms;
111+
112+ for (Elf32_Sym* sym = symEntry; sym < symEnd; sym++)
113+ {
114+ if ((ELF32_ST_BIND (sym->st_info ) & (STT_FUNC | STB_GLOBAL)) == 0 )
115+ continue ;
116+
117+ if (callback (sym, elfStrBlob + sym->st_name ) == false )
118+ break ;
119+ }
120+
121+ return true ;
122+ }
123+
124+ bool ElfLookupSymbol (ElfPack libMap, const std::string& symbolName, uint64_t * outSymbolOff)
125+ {
126+ Elf32_Sym* result = nullptr ;
127+ if (ElfForEachSymbol (libMap, [&](Elf32_Sym* currSym, const char * currSymName){
128+ if (strcmp (currSymName, symbolName.c_str ()))
129+ return true ;
130+
131+ result = currSym;
132+
133+ return false ;
134+ }) == false )
135+ return false ;
136+
137+ if (outSymbolOff && result)
138+ *outSymbolOff = result->st_value ;
139+
140+ return result != nullptr ;
141+ }
0 commit comments