For example, in C, I have something like this declared:
extern char _binary_res_txt_start[];
It came from this command:
ld -r -b binary -o binary.o res.txt
How can I get a Ptr
in Haskell that points there? If it were a function, I'd do something like foreign import ccall "&exp" a_exp :: FunPtr (Double -> Double)
, but I don't think that works for variables.
The foreign import
syntax works for variables too, as long as you use &
. You can then use peekCString
or packCString
to read it (or peekCStringLen
or packCStringLen
if it's not null-terminated but you know its length). Here's a full example:
printf 'foo\0bar' > res.txt
ld -r -b binary -o binary.o res.txt
extern char _binary_res_txt_start[];
extern char _binary_res_txt_end[];
import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr
foreign import ccall "&_binary_res_txt_start" txt_start :: Ptr CChar
foreign import ccall "&_binary_res_txt_end" txt_end :: Ptr CChar
main = do
str <- peekCStringLen (txt_start, txt_end `minusPtr` txt_start)
print str
"foo\NULbar"
Note that while ld -b binary
also produces a _binary_res_txt_size
symbol, it's no longer useful now that ASLR is a thing. See Why doesn't a linked binary file's _size symbol work correctly? for details on that.