diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-12-15 16:46:01 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-12-15 16:46:01 -0800 |
commit | 8291fd4a435dbb95661e13c5f823498312db4d79 (patch) | |
tree | 0b6546f08826e039fc56afa2ec56aa4b03f12f0d /src | |
parent | 7e9bc12167a0f92a82f3615cedef6f4c818d8c10 (diff) | |
download | binaryen-8291fd4a435dbb95661e13c5f823498312db4d79.tar.gz binaryen-8291fd4a435dbb95661e13c5f823498312db4d79.tar.bz2 binaryen-8291fd4a435dbb95661e13c5f823498312db4d79.zip |
support offsets in relocations
Diffstat (limited to 'src')
-rw-r--r-- | src/s2wasm.h | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h index 9b63666a1..a5e75c9cf 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -40,7 +40,12 @@ private: typedef std::pair<Const*, Name> Addressing; std::vector<Addressing> addressings; // we fix these up - typedef std::pair<std::vector<char>*, Name> Relocation; // the data, and the name whose address we should place there + struct Relocation { + std::vector<char>* data; + Name value; + int offset; + Relocation(std::vector<char>* data, Name value, int offset) : data(data), value(value), offset(offset) {} + }; std::vector<Relocation> relocations; std::set<Name> implementedFunctions; @@ -112,14 +117,14 @@ private: } void skipToSep() { - while (*s && !isspace(*s) && *s != ',' && *s != ')') { + while (*s && !isspace(*s) && *s != ',' && *s != ')' && *s != ':' && *s != '+') { s++; } } Name getStrToSep() { std::string str; - while (*s && !isspace(*s) && *s != ',' && *s != ')' && *s != ':') { + while (*s && !isspace(*s) && *s != ',' && *s != ')' && *s != ':' && *s != '+') { str += *s; s++; } @@ -843,24 +848,32 @@ private: (*(int32_t*)(&(*raw)[0])) = getInt(); } else { // relocation, the address of something - relocations.emplace_back(raw, getStr()); + Name value = getStrToSep(); + int offset = 0; + if (*s == '+') { + s++; + offset = getInt(); + } + relocations.emplace_back(raw, value, offset); } } else if (match(".int64")) { raw->resize(8); (*(int64_t*)(&(*raw)[0])) = getInt(); } else abort_on("data form"); skipWhitespace(); - mustMatch(".size"); - mustMatch(name.str); - mustMatch(","); - size_t seenSize = atoi(getStr().str); // TODO: optimize - assert(seenSize == raw->size()); + size_t size = raw->size(); + if (match(".size")) { + mustMatch(name.str); + mustMatch(","); + size_t seenSize = atoi(getStr().str); // TODO: optimize + assert(seenSize == size); + } while (nextStatic % align) nextStatic++; // assign the address, add to memory staticAddresses[name] = nextStatic; addressSegments[nextStatic] = wasm.memory.segments.size(); - wasm.memory.segments.emplace_back(nextStatic, (const char*)&(*raw)[0], seenSize); - nextStatic += seenSize; + wasm.memory.segments.emplace_back(nextStatic, (const char*)&(*raw)[0], size); + nextStatic += size; } void skipImports() { @@ -882,10 +895,8 @@ private: assert(curr->value.i32 > 0); curr->type = i32; } - for (auto& pair : relocations) { - auto raw = pair.first; - auto name = pair.second; - (*(int32_t*)(&(*raw)[0])) = staticAddresses[name]; + for (auto& relocation : relocations) { + (*(int32_t*)(&(*relocation.data)[0])) = staticAddresses[relocation.value] + relocation.offset; } } |