1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 | #include "resolve.h"
#include <iostream>
#include <vector>
#define FOUND_ALL_DEF 0
#define MULTI_DEF 1
#define NO_DEF 2
// this script is for Task2, Task3, Task4, Task5
std::string errSymName;
int callResolveSymbols(std::vector<ObjectFile> &allObjects);
void resolveSymbols(std::vector<ObjectFile> &allObjects) {
int ret = callResolveSymbols(allObjects);
if (ret == MULTI_DEF) {
std::cerr << "multiple definition for symbol " << errSymName << std::endl;
abort();
} else if (ret == NO_DEF) {
std::cerr << "undefined reference for symbol " << errSymName << std::endl;
abort();
}
}
/* bind each undefined reference (reloc entry) to the exact valid symbol table entry
* Throw correct errors when a reference is not bound to definition,
* or there is more than one definition.
*/
int callResolveSymbols(std::vector<ObjectFile> &allObjects)
{
/* Your code here */
// if found multiple definition, set the errSymName to problematic symbol name and return MULTIDEF;
// if no definition is found, set the errSymName to problematic symbol name and return NODEF;
std::unordered_map<std::string, Symbol*> StrongMap;
std::unordered_map<std::string, Symbol*> WeakMap;
/*
Strong:
- Mul-Def: ERROR! (task3)
- ok: add into mapping
Weak:
- Strong Exists: attach to Strong (task4)
- No Strong: All use itself (task5)
No Signal:
- Error! (task2)
*/
// Multi-Def
for (auto &obj : allObjects)
{
for (auto &sym : obj.symbolTable) // symbol
{
if (sym.bind == STB_GLOBAL && sym.index != SHN_UNDEF && sym.index != SHN_COMMON)
{
// Strong & Global itself, need to consider Multi-Conflicts
if (StrongMap.find(sym.name) != StrongMap.end())
{
// conflict
errSymName = sym.name;
return MULTI_DEF;
}
// no conflict, then add current mapping
StrongMap[sym.name] = &sym;
}
else if (sym.bind == STB_GLOBAL && sym.index == SHN_COMMON)
{
// Global but Weak, put into WeakClass at first
WeakMap[sym.name] = &sym;
}
}
}
// Attach weak symbols to strong symbols if they exist
for (auto &pair : WeakMap)
{
auto symName = pair.first;
if (StrongMap.find(symName) != StrongMap.end()) {
// find StrongOne, then attach
pair.second->value = StrongMap[symName]->value;
pair.second->index = StrongMap[symName]->index;
}
}
// Now both Strong and Weak can be utilized
// None-Def
for (auto &obj : allObjects)
{
for (auto &re : obj.relocTable) // symbol
{
std::string symName = re.sym->name;
if (StrongMap.find(symName) != StrongMap.end()) {
re.sym = StrongMap[symName];
}
else if (WeakMap.find(symName) != WeakMap.end()) {
re.sym = WeakMap[symName];
}
else {
errSymName = symName;
return NO_DEF;
}
}
}
return FOUND_ALL_DEF;
}
|