1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

Prevent early_fmt code from triggering Go's allocator

When converting strings to []byte so that they can be used with the tty
io.Writer interface Go calls a runtime method called
"stringtoslicebyte". If the input length exceeds a particular size then
this method will allocate a new []byte and copy the data into it. This
obviously causes our kernel to crash.

To fix this, all early_fmt functions have been changed to iterate any
string arguments and output them to the active TTY one byte at a time.
This commit is contained in:
Achilleas Anagnostopoulos 2017-05-12 08:00:18 +01:00
parent d7028cee00
commit 6d3c463ee8

View File

@ -7,7 +7,7 @@ var (
errWrongArgType = []byte("%!(WRONGTYPE)")
errNoVerb = []byte("%!(NOVERB)")
errExtraArg = []byte("%!(EXTRA)")
padding = []byte{' '}
padding = byte(' ')
trueValue = []byte("true")
falseValue = []byte("false")
)
@ -62,7 +62,9 @@ func Printf(format string, args ...interface{}) {
}
if blockStart < blockEnd {
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
for i := blockStart; i < blockEnd; i++ {
hal.ActiveTerminal.WriteByte(format[i])
}
}
// Scan til we hit the format character
@ -109,7 +111,9 @@ func Printf(format string, args ...interface{}) {
}
if blockStart != blockEnd {
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
for i := blockStart; i < blockEnd; i++ {
hal.ActiveTerminal.WriteByte(format[i])
}
}
// Check for unused args
@ -139,23 +143,25 @@ func fmtBool(v interface{}) {
// padding specified by padLen. This function uses hal.ActiveTerminal for its
// output.
func fmtString(v interface{}, padLen int) {
var sval []byte
switch castedVal := v.(type) {
case string:
sval = []byte(castedVal)
fmtRepeat(padding, padLen-len(castedVal))
for i := 0; i < len(castedVal); i++ {
hal.ActiveTerminal.WriteByte(castedVal[i])
}
case []byte:
sval = castedVal
fmtRepeat(padding, padLen-len(castedVal))
hal.ActiveTerminal.Write(castedVal)
default:
hal.ActiveTerminal.Write(errWrongArgType)
return
}
}
for pad := padLen - len(sval); pad > 0; pad-- {
hal.ActiveTerminal.Write(padding)
// fmtRepeat writes count bytes with value ch to the hal.ActiveTerminal.
func fmtRepeat(ch byte, count int) {
for i := 0; i < count; i++ {
hal.ActiveTerminal.WriteByte(ch)
}
hal.ActiveTerminal.Write(sval)
}
// fmtInt prints out a formatted version of v in the requested base, applying the