]> asedeno.scripts.mit.edu Git - peal.git/blob - postlink/symboltable.cc
Greg Parker's Palm Elf Arm Loader (PEAL)
[peal.git] / postlink / symboltable.cc
1 /**********
2  * Copyright (c) 2004 Greg Parker.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
23  **********/
24
25 #include "section.h"
26 #include "symboltable.h"
27 #include "stringtable.h"
28
29 SymbolTable::SymbolTable(Image& newImage)
30     : Section(newImage)
31
32     // symbol table with single empty symbol, unless replaced by read().
33     mSymbols.push_back(new Symbol(string(""), mImage.sections()[0], 0, 0, 0));
34 }
35
36
37 void SymbolTable::read(Elf32_Shdr *shdr)
38
39     Section::read(shdr);
40
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);
46
47     mSymbols.erase(mSymbols.begin(), mSymbols.end());
48     for ( ; sym < end; ++sym) {
49         mSymbols.push_back(new Symbol(mImage, *strtab, sym));
50     }
51 }
52
53
54 // strip all local symbols
55 // strip all globals symbols not mentioned in keep[] (if it exists)
56 void SymbolTable::strip(vector<string> *keep)
57 {
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)
62     {
63         Symbol *sym = *iter;
64         const string &name = sym->name();
65
66         if (name == "PealArmStub"  ||  name == "_PealArmStub") {
67             // PealArmStub is special - never strip it
68             newSymbols.push_back(sym);
69         }
70         else if (!sym->isGlobal()) {
71             // local symbol - strip it
72         } 
73         else if (keep  &&  
74                  keep->end() == find(keep->begin(), keep->end(), name))
75         {
76             // keep list exists, but doesn't have this symbol - strip it
77         } 
78         else {
79             newSymbols.push_back(sym);
80         }
81     }
82
83     mSymbols = newSymbols;
84 }
85
86
87 void SymbolTable::addSymbol(Symbol *sym)
88 {
89     mSymbols.push_back(sym);
90 }
91
92
93 void SymbolTable::emit(Elf32_Shdr *shdr, uint8_t *&buf, uint32_t& bufLen)
94 {
95     // construct mContents and mSize
96     mSize = mSymbols.size() * sizeof(Elf32_Sym);
97     Elf32_Sym *newContents = (Elf32_Sym *)malloc(mSize);
98
99     for (unsigned int i = 0; i < mSymbols.size(); i++) {
100         newContents[i] = mSymbols[i]->asElf(mImage);
101     }
102
103     mContents = (uint8_t *)newContents;
104
105     // set mLink to strtab
106     mLink = find(mImage.sections().begin(), mImage.sections().end(), mImage.strtab()) - mImage.sections().begin();
107
108     Section::emit(shdr, buf, bufLen);
109 }