00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.h"
00017
00018 ElfArchiveFile::ElfArchiveFile()
00019 {
00020 }
00021
00022 ElfArchiveFile::~ElfArchiveFile()
00023 {
00024 }
00025
00026 bool ElfArchiveFile::Load(const char* pName)
00027 {
00028
00029 Elf* elf;
00030
00031 m_filedes = open(pName, O_RDONLY);
00032 if (m_filedes == -1)
00033 {
00034 printf("Could not open %s\n", pName);
00035 return false;
00036 }
00037
00038 elf_version(EV_CURRENT);
00039 m_arf = elf_begin(m_filedes, ELF_C_READ, (Elf*)0);
00040 if (elf_kind(m_arf) != ELF_K_AR)
00041 {
00042 printf("Error - %s is not an archive (.a) file\n", pName);
00043 return false;
00044 }
00045
00046
00047
00048
00049
00050 int iLastOffset = 0;
00051 int iOffset = 0;
00052 unsigned int uNumSyms;
00053 int iIndex = -1;
00054
00055 Elf_Arsym* asym;
00056 asym = elf_getarsym(m_arf, &uNumSyms);
00057 uNumSyms--;
00058 if (asym == 0)
00059 {
00060 printf("Get archive symbol table failed\n");
00061 return false;
00062 }
00063
00064 for (unsigned u=0; u < uNumSyms; u++)
00065 {
00066 iOffset = asym[u].as_off;
00067
00068 if (iOffset == 0) break;
00069 if (iOffset != iLastOffset)
00070 {
00071
00072 iIndex++;
00073 iLastOffset = iOffset;
00074
00075
00076 if (elf_rand(m_arf, iOffset) == 0)
00077 {
00078 printf("Could not seek to offset %d\n", iOffset);
00079 return false;
00080 }
00081 if ((elf = elf_begin(m_filedes, ELF_C_READ, m_arf)) == 0)
00082 {
00083 printf("Could not begin member at offset %d\n", iOffset);
00084 return false;
00085 }
00086 Elf_Arhdr* ahdr;
00087 ahdr = elf_getarhdr(elf);
00088 if (ahdr == 0)
00089 {
00090 printf("Could not get header information "
00091 "for member at offset %d\n", iOffset);
00092 return false;
00093 }
00094
00095 m_FileMap[ahdr->ar_name] = iIndex;
00096
00097 m_FileNames.push_back(ahdr->ar_name);
00098
00099
00100 m_Offsets.push_back(iOffset);
00101 }
00102
00103 m_SymMap[asym[u].as_name] = iIndex;
00104 }
00105
00106
00107
00108
00109 m_Members.reserve(GetNumMembers());
00110
00111 return true;
00112 }
00113
00114 void ElfArchiveFile::UnLoad()
00115 {
00116 for (unsigned u=0; u < m_Members.size(); u++)
00117 {
00118 if (m_Members[u])
00119 {
00120
00121 delete m_Members[u];
00122 }
00123
00124 m_Members.erase(m_Members.begin(), m_Members.end());
00125 }
00126 }
00127
00128 BinaryFile* ElfArchiveFile::GetMember(int i)
00129 {
00130
00131 if (i < 0) return 0;
00132 if (i >= m_FileMap.size()) return 0;
00133
00134
00135 if (i >= m_Members.size() || (m_Members[i] == 0))
00136 {
00137
00138
00139 BinaryFile* pBF = new ElfBinaryFile(true);
00140 if (pBF == 0) return 0;
00141
00142 int iOffset = m_Offsets[i];
00143 if (iOffset == 0) return 0;
00144 if (elf_rand(m_arf, iOffset) != iOffset)
00145 {
00146 return 0;
00147 }
00148 Elf* elf;
00149 if ((elf = elf_begin(m_filedes, ELF_C_READ, m_arf)) == 0)
00150 {
00151 return 0;
00152 }
00153
00154
00155 if (PostLoadMember(pBF, elf) == 0) return 0;
00156 m_Members[i] = pBF;
00157 return pBF;
00158 }
00159
00160 return m_Members[i];
00161 }
00162
00163