2 * Copyright (c) 2004 Greg Parker. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "symboltable.h"
27 #include "stringtable.h"
29 SymbolTable::SymbolTable(Image& newImage)
32 // symbol table with single empty symbol, unless replaced by read().
33 mSymbols.push_back(new Symbol(string(""), mImage.sections()[0], 0, 0, 0));
37 void SymbolTable::read(Elf32_Shdr *shdr)
41 vector<Section *>& sections = mImage.sections();
42 Section *section = sections[swap32(shdr->sh_link)];
43 StringTable *strtab = dynamic_cast<StringTable *>(section);
44 Elf32_Sym *sym = (Elf32_Sym *)mContents;
45 Elf32_Sym *end = (Elf32_Sym *)(mContents + mSize);
47 mSymbols.erase(mSymbols.begin(), mSymbols.end());
48 for ( ; sym < end; ++sym) {
49 mSymbols.push_back(new Symbol(mImage, *strtab, sym));
54 // strip all local symbols
55 // strip all globals symbols not mentioned in keep[] (if it exists)
56 void SymbolTable::strip(vector<string> *keep)
58 vector<Symbol *> newSymbols;
59 newSymbols.push_back(new Symbol(string(""), mImage.sections()[0], 0, 0, 0));
60 vector<Symbol *>::iterator iter;
61 for (iter = mSymbols.begin(); iter != mSymbols.end(); ++iter)
64 const string &name = sym->name();
66 if (name == "PealArmStub" || name == "_PealArmStub") {
67 // PealArmStub is special - never strip it
68 newSymbols.push_back(sym);
70 else if (!sym->isGlobal()) {
71 // local symbol - strip it
74 keep->end() == find(keep->begin(), keep->end(), name))
76 // keep list exists, but doesn't have this symbol - strip it
79 newSymbols.push_back(sym);
83 mSymbols = newSymbols;
87 void SymbolTable::addSymbol(Symbol *sym)
89 mSymbols.push_back(sym);
93 void SymbolTable::emit(Elf32_Shdr *shdr, uint8_t *&buf, uint32_t& bufLen)
95 // construct mContents and mSize
96 mSize = mSymbols.size() * sizeof(Elf32_Sym);
97 Elf32_Sym *newContents = (Elf32_Sym *)malloc(mSize);
99 for (unsigned int i = 0; i < mSymbols.size(); i++) {
100 newContents[i] = mSymbols[i]->asElf(mImage);
103 mContents = (uint8_t *)newContents;
105 // set mLink to strtab
106 mLink = find(mImage.sections().begin(), mImage.sections().end(), mImage.strtab()) - mImage.sections().begin();
108 Section::emit(shdr, buf, bufLen);