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