mirror of
https://github.com/notwa/mm
synced 2024-11-05 00:39:02 -08:00
shoehorn writing anywhere with lips
This commit is contained in:
parent
e490c712e6
commit
49e51cd6e7
2 changed files with 15 additions and 37 deletions
|
@ -1,6 +1,7 @@
|
|||
require = require "depend"
|
||||
require "boilerplate"
|
||||
require "addrs.init"
|
||||
require "messages"
|
||||
local assemble = require "inject.lips"
|
||||
|
||||
local injection_points = {
|
||||
|
@ -67,12 +68,13 @@ function inject(fn)
|
|||
-- set up a header to handle calling our function and the original
|
||||
local header = header:format(ow_before_addr)
|
||||
|
||||
local inject_words = {}
|
||||
local inject_bytes = {}
|
||||
local length = 0
|
||||
local function add_word(line)
|
||||
-- takes assembled code, up to 4 bytes at a time, as hex strings
|
||||
local function add_word(pos, line)
|
||||
length = length + #line/2
|
||||
table.insert(inject_words, tonumber(line, 16))
|
||||
dprint(("%08X"):format(pos), line)
|
||||
pos = pos % 0x80000000
|
||||
inject_bytes[pos] = tonumber(line, 16)
|
||||
end
|
||||
|
||||
-- offset assembly labels so they work properly, and assemble!
|
||||
|
@ -81,14 +83,15 @@ function inject(fn)
|
|||
assemble(asm_path, add_word, {unsafe=true, offset=true_offset + length})
|
||||
|
||||
printf("length: %i words", length/4)
|
||||
if #inject_words > inject_maxlen then
|
||||
if #inject_bytes > inject_maxlen then
|
||||
print("Assembly too large!")
|
||||
return
|
||||
end
|
||||
|
||||
for i, v in ipairs(inject_words) do
|
||||
W4(inject_addr + (i - 1)*4, v)
|
||||
for pos, val in pairs(inject_bytes) do
|
||||
W1(pos, val)
|
||||
end
|
||||
print_deferred()
|
||||
|
||||
-- finally, write our new jump over the original
|
||||
printf('%08X: %08X', ow_addr, ow_after)
|
||||
|
|
|
@ -473,9 +473,7 @@ function Dumper:init(writer, fn, options)
|
|||
self.options = options or {}
|
||||
self.labels = {}
|
||||
self.commands = {}
|
||||
self.buff = ''
|
||||
self.pos = 0
|
||||
self.size = 0
|
||||
self.pos = options.offset or 0
|
||||
self.lastcommand = nil
|
||||
end
|
||||
|
||||
|
@ -586,7 +584,7 @@ function Lexer:read_number()
|
|||
return self:read_hex()
|
||||
elseif self.chr == '0' and self.chr2:find('%d') then
|
||||
self:nextc()
|
||||
return self:read_octal_number()
|
||||
return self:read_octal()
|
||||
else
|
||||
return self:read_decimal()
|
||||
end
|
||||
|
@ -670,13 +668,11 @@ end
|
|||
function Lexer:lex_string(yield)
|
||||
-- TODO: support escaping
|
||||
if self.chr ~= '"' then
|
||||
print(self.chr, self.ord)
|
||||
self:error("expected opening double quote")
|
||||
end
|
||||
self:nextc()
|
||||
local buff = self:read_chars('[^"\n]')
|
||||
if self.chr ~= '"' then
|
||||
print(self.chr)
|
||||
self:error("expected closing double quote")
|
||||
end
|
||||
self:nextc()
|
||||
|
@ -1347,15 +1343,11 @@ function Parser:parse(asm)
|
|||
end
|
||||
|
||||
function Dumper:error(msg)
|
||||
--error(string.format('%s:%d: Dumper Error: %s', '(code)', self.pos, msg), 2)
|
||||
error(string.format('%s:%d: Error: %s', self.fn, self.line, msg), 2)
|
||||
end
|
||||
|
||||
function Dumper:advance(by)
|
||||
self.pos = self.pos + by
|
||||
if self.pos > self.size then
|
||||
self.size = self.pos
|
||||
end
|
||||
end
|
||||
|
||||
function Dumper:push_instruction(t)
|
||||
|
@ -1457,8 +1449,7 @@ function Dumper:desym(tok)
|
|||
if label == nil then
|
||||
self:error('undefined label')
|
||||
end
|
||||
local offset = self.options.offset or 0
|
||||
return label + offset
|
||||
return label
|
||||
elseif tok[1] == 'LABELREL' then
|
||||
local label = self.labels[tok[2]]
|
||||
if label == nil then
|
||||
|
@ -1540,16 +1531,9 @@ function Dumper:valvar(tok, bits)
|
|||
end
|
||||
|
||||
function Dumper:write(t)
|
||||
-- this is gonna be really slow, but eh, optimization comes last
|
||||
-- should really use a sparse table and fill in the string later
|
||||
for _, b in ipairs(t) do
|
||||
if self.pos >= self.size then
|
||||
error('Internal Error: pos out of range; size too small', 1)
|
||||
end
|
||||
local s = ('%02X'):format(b)
|
||||
local left = self.buff:sub(1, self.pos*2)
|
||||
local right = self.buff:sub(self.pos*2 + 3)
|
||||
self.buff = left..s..right
|
||||
self.writer(self.pos, s)
|
||||
self.pos = self.pos + 1
|
||||
end
|
||||
end
|
||||
|
@ -1583,12 +1567,7 @@ function Dumper:dump_instruction(t)
|
|||
end
|
||||
|
||||
function Dumper:dump()
|
||||
self.pos = 0
|
||||
self.buff = ''
|
||||
for i=1,self.size do
|
||||
self.buff = self.buff..'00'
|
||||
end
|
||||
|
||||
self.pos = self.options.offset or 0
|
||||
for i, t in ipairs(self.commands) do
|
||||
if t.line == nil then
|
||||
error('Internal Error: no line number available')
|
||||
|
@ -1617,10 +1596,6 @@ function Dumper:dump()
|
|||
error('Internal Error: unknown command', 1)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1, self.size*2 - 1, 8 do
|
||||
self.writer(self.buff:sub(i, i + 7))
|
||||
end
|
||||
end
|
||||
|
||||
function assembler.assemble(fn_or_asm, writer, options)
|
||||
|
|
Loading…
Reference in a new issue