replace function offset with source code line number in output of "adb dumpsys meminfo --unreachable" - memory-leaks

To find memory leaks of the native C code of my app I run the following command
adb shell dumpsys meminfo --unreachable $(adb shell pidof com.mycompany.myapp)
I get the following output
6 bytes unreachable at ee1551b0
and 654 similar unreachable bytes in 109 allocations
contents:
ee1551b0: 31 2e 30 2e 30 00 1.0.0.
#00 pc 000421e4 /apex/com.android.runtime/lib/bionic/libc.so (malloc +68)
#01 pc 00126670 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction7 +80)
#02 pc 0011d2b9 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so
#03 pc 0011d025 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction6 +165)
#04 pc 0011e82c /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction5 +892)
#05 pc 00120ea7 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so
#06 pc 0012091c /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so
#07 pc 00120144 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so
#08 pc 0011eebe /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so
#09 pc 0011e6d4 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction4 +548)
#10 pc 00121924 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction3 +68)
#11 pc 00121743 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction2 +99)
#12 pc 001221c9 /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (myCfunction1 +409)
#13 pc 00121f4d /data/app/~~XX==/com.mycompany.myapp-W6-xx==/lib/x86/mylib.so (Java_com_mycompany_myapp_myjavaclass_myjavamethod +333)
I'm looking for a simple way to replace offset functions (+333, +409, +99, ...) by line numbers of the source code.
I do this kind of stuff by using ndk-stack on tombstone files. Perhaps there is a tool able to decipher the output of 'dumpsys meminfo --unreachable'.

I've found a simple solution.
I attach the debugger to the process, set a breakpoint and move to the lldb console of android studio.
To set a breapoint to a given offset after a function, I enter the command given here
https://stackoverflow.com/a/23250892/9459302
For instance
b -a (void*()(void, size_t)) myCfunction1 +400
where (void*(*)(void*, size_t)) is the prototype of myCfunction1

Related

How can I get the port of my Rflink (Arduino Mega) to show in /dev on my Raspberry pi 3?

I bought a RFlink Gateway from Nodo-shop.nl, the the RFLink 433.42 Somfy RTS version, to use with Domoticz on a RPI. I had Nodo to solder the components of my Rflink, so there should not be any problem on this end :)
I connected it to my MacbookAir, and followed the instructions on Domoticz wiki to upload the firmware into the RFlink. It apparently uploaded the firmware successfully.
Then I updated and upgraded my RPI (Linux raspberrypi 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l GNU/Linux) and hooked it up to my Raspberry Pi 3 .
I tried to identify the port with Dmesg. If the Arduino Mega is detected, I cannot see the ttyAMCO or ttyUSB everyone is referring to in various posts.
Here is the output of the dmesg command:
[3902580.423329] usb 1-1.1.2: new full-speed USB device number 9 using dwc_otg [3902580.568650] usb 1-1.1.2: New USB device found, idVendor=2341, idProduct=0042, bcdDevice= 0.01 [3902580.568671] usb 1-1.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220 [3902580.568685] usb 1-1.1.2: Manufacturer: Arduino (www.arduino.cc) [3902580.568699] usb 1-1.1.2: SerialNumber: 55037313237351714260
I also tried to look for the port using this command ls /dev | grep tty*. I can only see these ports : ttyXX, ttyAMA0 and ttyprintk. But no sign of the port of my RFlink Gateway.
When I use this command lsusb, it shows it recognizes the Arduino:
Bus 001 Device 009: ID 2341:0042 Arduino SA Mega 2560 R3 (CDC ACM).
I read tons of posts on the internet but I did not find any answer to my problem.
I even bought a power supply for my Arduino Mega as some wrote that it may not get enough power from the RPI's USB. But I still have the same problem...
What I'm not doing right ? Or what am I not looking at ?
Thank you for your help
Sorry, bit late but it might be useful to someone else...
It might well be the /dev/ttyAMA0 you found - it depends what else you've got on there.
listing by id should identify it definitively though:
$ ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 Mar 18 2021 usb-0658_0200_12345678-9012-3456-7890-123456789012-if00 -> ../../ttyACM1
lrwxrwxrwx 1 root root 13 Mar 18 2021 usb-Arduino__www.arduino.cc__0042_55639313533351509150-if00 -> ../../ttyACM0
So, in my case it's on /dev/ttyACM0.
If you've got multiple USB serial adapters, reboot the pi with them all plugged in to get the default mapping (I've seen hotplugged AMA0 and AMA1 swap after a reboot).

Load binary into stm32f103c8t6 with OpenOCD and arm-none-eabi-gdb

I tried to load binary that is compiled from rust code, but it doesn't work.
First, I downloaded Rust code from https://github.com/rust-embedded/discovery.
Then, I built it.
# I am in the `src/05-led-roulette` directory
rustup target add thumbv7m-none-eabi
cargo build --target thumbv7m-none-eabi
It was successfully compiled.
After that, I successfully connected with stm32f103c8t6 using OpenOCD.
Then, I run this command.
arm-none-eabi-gdb -q target/thumbv7m-none-eabi/debug/led-roulette
But it seemed like it didn't finish reading.
Reading symbols from target/thumbv7m-none-eabi/debug/led-roulette...
(gdb)
(not done?!)
After that, I tried loadcommand, but it returned following sentences.
Start address 0x0, load size 0
Transfer rate: 0 bits in <1 sec.
I have no idea about why it doesn't work.
Please help me.
First see if your binary is good, then try telnet, then gdb. Rust also multiplies the odds of failure, so start with something simple:
so.s
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.thumb_func
reset:
ldr r0,some_addr
ldr r1,[r0]
add r1,r1,#1
str r1,[r0]
b .
.align
some_addr: .word 0x20000000
build it
arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objdump -D so.elf
arm-none-eabi-objdump -D so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 :
8000008: 4802 ldr r0, [pc, #8] ; (8000014 <some_addr>)
800000a: 6801 ldr r1, [r0, #0]
800000c: 3101 adds r1, #1
800000e: 6001 str r1, [r0, #0]
8000010: e7fe b.n 8000010 <reset+0x8>
8000012: 46c0 nop ; (mov r8, r8)
08000014 <some_addr>:
8000014: 20000000 andcs r0, r0, r0
for small programs (Read the st documentation) this can be based at address 0x08000000 or 0x00000000 for this part. 0x08000000 is preferred. The vector table must be first in this case ignore the disassembly just look at the values
8000000: 20001000 andcs r1, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
The 0x08000009 is the reset address ORRed with one. so 0x08000008 | 1 is 0x08000009. So that will at least boot and try to fetch code without a fault.
This code simply reads the word at address 0x20000000 and increments it, sram is not affected by a reset so we can keep resetting and seeing that value increment.
using whatever configs you have and interface, I combine the openocd one for the st part into a single file and carry that with the project along with ones for the various interfaces (stlinks of different versions and jlink).
openocd -f jlink.cfg -f target.cfg
Open On-Chip Debugger 0.9.0 (2019-04-28-23:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : JLink SWD mode enabled
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : J-Link caps 0x88ea5833
Info : J-Link hw version 70000
Info : J-Link hw type J-Link
Info : J-Link max mem block 15344
Info : J-Link configuration
Info : USB-Address: 0x0
Info : Kickstart power on JTAG-pin 19: 0x0
Info : Vref = 3.300 TCK = 1 TDI = 1 TDO = 1 TMS = 1 SRST = 1 TRST = 1
Info : J-Link JTAG Interface ready
Info : clock speed 1000 kHz
Info : SWD IDCODE 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
If you don't see the watchpoints line if it returns to the console, it didn't work.
In another window
telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>
Now let's stop the chip and write our program. The psr, pc, etc values may be different depending than mine depending on what you had running.
> reset halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000010 msp: 0x20001000
> flash write_image erase so.elf
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file so.elf in 0.437883s (2.284 KiB/s)
Let's read it and see that it is there, should match the words from the disassembly
> mdw 0x08000000 20
0x08000000: 20001000 08000009 5000f04f 31016801 e7fe6001 ffffffff ffffffff ffffffff
0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
0x08000040: ffffffff ffffffff ffffffff ffffffff
Assume this is random garbage and that is fine so long as we see it increment.
> mdw 0x20000000
0x20000000: 2e006816
> reset
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000012 msp: 0x20001000
> mdw 0x20000000
0x20000000: 2e006817
So the value incremented if you do a reset, then do a halt (not a reset halt in one command) then dump that memory location it should keep incrementing every time.
Now you can choose to take the gdb path (I don't have a use for gdb so don't have one installed) with this binary or examine your rust binary by first examining the vector table to see it is correct, without at least the reset vector being correct then you will fault and not run any code on the processor. Can flash it using telnet or you can try gdb.
If gdb is having a problem with the file then perhaps you are using the wrong file. or the file is incorrectly built. did you try a simple program in that repository? can you make a minimal program from that repository, an empty entry function or an infinite loop or a counter that counts forever?
Is this truly a gdb problem? Is this an openocd problem? Is this a Rust tools problem? Is this a Rust binary problem? Is this a bug in the docs and you are pointing gdb at the wrong file problem? If the above works then openocd works, binutils at least works, the debugger/hardware works, it eliminates those and then becomes is this a rust thing, a gdb thing, using the wrong file thing, or something else?
After connecting openocd with the board don't forget to connect the debugger
arm-none-eabi-gdb with openocd.
> arm-none-eabi-gdb -se target/thumbv7em-none-eabi/release/your_binary
(gdb) target remote localhost:3333
If all is OK in the terminal console where openocd is running you will see the message:
accepting 'gdb' connection on tcp/3333`
and you should be able to start debugging.
To optimize connection setup you may create/update the .gdbinit file with the content:
target remote localhost:3333

Compiling driver for ARMv7 vs ARMv5

I've managed to compile a driver for an ARM based device, but the driver crashed when I try to load it.
here is the output from cpuinfo:
Processor : ARMv7 Processor rev 2 (v7l)
BogoMIPS : 999.42
Features : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x3
CPU part : 0xc08
CPU revision : 2
Here is the uname -r output
2.6.37
modinfo driver.ko
filename: cp210x.ko
description: Silicon Labs CP210x RS232 serial adaptor driver
license: GPL
vermagic: 2.6.37 mod_unload ARMv7
vermagic: 2.6.37 mod_unload modversions ARMv5
parm: debug:Enable verbose debugging messages
As you can I've added an extra vermagic (2.6.37 mod_unload ARMv7) so it will match the target system.
So if I understand this correct, I've compiled this module for an ARMv5 cpu, while the target is v7. Could this be the cause of the device driver crashing?
The device has this driver, but its embedded into an other driver package from the hw producer. This package also load some drivers that we cannot use. This driver package is not load, but I guess this indicate that this driver should work on this hardware some how.
here is the crash log
modprobe cp210x.ko
Unable to handle kernel NULL pointer dereference at virtual address 0000000a
pgd = ca1fc000
[0000000a] *pgd=870dd031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
last sysfs file: /sys/kernel/uevent_seqnum
Modules linked in: dahdi_dummy dahdi cmemk syslink ipt_MASQUERADE nf_nat iptable_filter ip_tables ipt_LOG xt_state nf_conntrack_ftp nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_recent xt_mac xt_limit work_led reset_button ipv6
CPU: 0 Not tainted (2.6.37 #1)
PC is at sys_init_module+0xfe0/0x1460
LR is at sys_init_module+0xe7c/0x1460
pc : [<c00836e8>] lr : [<c0083584>] psr: 20000013
sp : cc5e9ed0 ip : bf3828dc fp : cc5e8000
r10: bf385ca8 r9 : cf3bcb4e r8 : 000000c5
r7 : 00000027 r6 : bf382544 r5 : bf38266c r4 : bf385ca8
r3 : 00000000 r2 : c7c9f000 r1 : 0000000a r0 : 0000000a
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 8a1fc019 DAC: 00000015
Process modprobe (pid: 2676, stack limit = 0xcc5e82e8)
Stack: (0xcc5e9ed0 to 0xcc5ea000)
9ec0: bf382544 00000001 000ac048 bf382550
9ee0: 000000c5 cf3bd5a4 cf3b8000 000055f4 cf3bd20c cf3bd128 cf3bc2a0 c7c9f000
9f00: 0000266c 000028dc 00000000 00000000 00000017 00000018 00000010 0000000d
9f20: 00000009 00000000 6e72656b 00006c65 00000000 00000000 00000000 00000000
9f40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9f60: 00000000 00000000 c9a19540 00000000 ca2403c0 00000006 c9a19540 00000000
9f80: ca2403c0 000055f4 00000000 00000006 00000080 c0037c28 cc5e8000 00000000
9fa0: 00000001 c0037a80 000055f4 00000000 000ac998 000055f4 000ac048 000ac978
9fc0: 000055f4 00000000 00000006 00000080 000ac008 000ac028 000ac998 00000001
9fe0: bebaf968 bebaf958 00017764 40214740 60000010 000ac998 c1e38bcc 03de8ad9
[<c00836e8>] (sys_init_module+0xfe0/0x1460) from [<c0037a80>] (ret_fast_syscall+0x0/0x30)
Code: e7923103 e1a03133 e3130001 15963128 (17d33000)
---[ end trace 6e8943127db36208 ]---
Segmentation fault
I hade to change the cp210x.c file and comment out where there was any use of mutex. this was the only place:
static void cp210x_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
usb_serial_generic_close(port);
/* mutex_lock(&port->serial->disc_mutex);*/
if (!port->serial->disconnected)
cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE);
/* mutex_unlock(&port->serial->disc_mutex);*/
}
Are you trying to load a kernel module that was compiled for one kernel into another kernel? Linux modules (what you call drivers) are only supposed to be loaded into the kernel that they were compiled for. Even the same version of the kernel with different configuration or compiler settings could render the module incompatible. So playing with version magic is very dangerous.
The reason your driver is crashing is because it is trying to access kernel data structures using incorrect layout, so it is not actually reading the attributes it thinks it should be reading.
Changing architecture from ARMv7 to ARMv5 is very drastic configuration change that will completely change the memory layout of kernel data structures.
Unlike some other operating systems like Windows, Linux does not have an abstraction layer or fixed memory layouts that let you load the same loadable module into different versions of the kernel.

Cannot see "Waiting for connection from remote gdb..."

I'm now configuring kgdb with a target pc and a host pc.
These 2 PCs are connected via serial cable.
The host PC has USB-to-Serial cable which is ttyUSB0.
And the target PC has conventional serial port which is ttyS0.
The target PC's BIOS has serial console redirection option so I turned it off.
The Kernel of target PC is built with the following options.
1) CONFIG_HAVE_ARCH_KGDB = y
2) CONFIG_KGDB = y
3) CONFIG_KGDB_SERIAL_CONSOLE = y
And the following is the line of grub.cfg
linux /vmlinuz ro PROMPT_NO nmi_watchdog=1 kgdbwait kgdb8250=/dev/ttyS0,9600,kgdboc=/dev/ttyS0,9600 quiet
I have grub2 installed in this target PC.
I was expecting "Waiting for connection from remote gdb..." message.
But it does boot normally without any message.
After booting I checked the /sys/module/kgdboc/parameters/kgdboc and it was empty.

tslib not creating device

I am trying to embed tslib on an ARM system, in order to use a touchscreen device ; I already installed it successfully but unfortunately I can't retrieve all my notes to do it again. x)
I cross-compiled the libraries files, and I put them into /usr/lib ; I have created the conf file /etc/ts.conf and I have exported the good environment variables :
export TSLIB_TSDEVICE="/dev/event2"
export TSLIB_CONFFILE="/etc/ts.conf"
Here is my problem : tslib doesn't seem to create the event device when I plug the device in. And here is the result of *ts_calibrate* : ts_open: No such file or directory
I think it tries to open /dev/event2 which doesn't exist because it has not been created by tslib.
Any ideas ?
Thanks
What kind of kernel + userspace do you have ? device file creation is usually
the job of kernel hotplug + udev or mdev.
In any case, tslib is not supposed to create device file. You have two options :
creating the device manually, provided your busybox contains the mknod utility :
mknod event2 c 13 66
where 66 is the minor number, it should be one more than the minor number for event1.
launching mdev -s and see if the content of your /dev directory change
find out why the vent device is not detected / created : please post the output of uname -a, and dmesg after boot.
Do you need to mknod the /dev/event2 yourself? Are you positive your library makes the device node?
Actually mknod is not available on our busybox. Nothing changed when launching mdev -s, I already tryed that. :/
Here is the result of uname : Linux MYNAME 2.6.24.4 #3 Fri Dec 2 16:54:41 CET 2011 armv4l unknown (MYNAME is just the system name, I replaced it for privacy reason ;) )
And dmesg :
<6>usb 1-1.3: new high speed USB device using str8100-ehci and address 23
<6>usb 1-1.3: configuration #1 chosen from 1 choice
<6>hub 1-1.3:1.0: USB hub found
<6>hub 1-1.3:1.0: 4 ports detected
<6>usb 1-1.3.2: new high speed USB device using str8100-ehci and address 24
<6>usb 1-1.3.2: configuration #1 chosen from 1 choice
<6>udlfb: DisplayLink AT-7 - serial #200694
<6>udlfb: vid_17e9&pid_02fc&rev_0104 driver's dlfb_data struct at c1031000
<6>udlfb: console enable=0
<6>udlfb: fb_defio enable=0
<6>udlfb: vendor descriptor length:23 data:23 5f 01 0021 00 04 04 07 00 01
<4>udlfb: DL chip limited to 1500000 pixel modes
<4>dlfb_alloc_urb_list
<4>dlfb_release_urb_work : INIT_DELAYED_WORK dlfb_release_urb_work
<4>dlfb_release_urb_work : after INIT_DELAYED_WORK
<4>usb_fill_bulk_urb
<4>usb_fill_bulk_urb end
<4>dlfb_release_urb_work : INIT_DELAYED_WORK dlfb_release_urb_work
<4>dlfb_release_urb_work : after INIT_DELAYED_WORK
<4>usb_fill_bulk_urb
<4>usb_fill_bulk_urb end
<4>dlfb_release_urb_work : INIT_DELAYED_WORK dlfb_release_urb_work
<4>dlfb_release_urb_work : after INIT_DELAYED_WORK
<4>usb_fill_bulk_urb
<4>usb_fill_bulk_urb end
<4>dlfb_release_urb_work : INIT_DELAYED_WORK dlfb_release_urb_work
<4>dlfb_release_urb_work : after INIT_DELAYED_WORK
<4>usb_fill_bulk_urb
<4>usb_fill_bulk_urb end
<4>dlb_alloc_urb_list : before sema_init
<4>dlb_alloc_urb_list : after sema_init
<5>udlfb: allocated 4 65024 byte urbs
<4>dlfb_setup_modes
<4>dlfb_get_edid
<4>dlfb_is_valid_mode
<6>udlfb: 800x480 valid mode
<4>udlfb: Reallocating framebuffer. Addresses will change!
<4>dlfb_ops_check_var
<4>dlfb_is_valid_mode
<6>udlfb: 800x480 valid mode
<5>udlfb: set_par mode 800x480
<4>dlfb_set_video_mode
<4>dlfb_get_urb end
<4>dlfb_set_vid_cmds
<4>dlfb_submit_urb
<4>dlfb_submit_urb : after usb_submit_urb ret=0
<4>dlfb_set_video_mode end
<4>dlfb_urb_completion
<4>up release_urb_work !!!
<4>dlfb_urb_completion end
<4>dlfb_handle_damage
<4>dlfb_get_urb end
<4>dlfb_submit_urb
<4>dlfb_submit_urb : after usb_submit_urb ret=0
<6>udlfb: DisplayLink USB device /dev/fb1 attached. 800x480 resolution. Using 1504K framebuffer memory
<4>dlfb_urb_completion
<4>up release_urb_work !!!
<4>dlfb_urb_completion end
<6>usb 1-1.3.3: new full speed USB device using str8100-ehci and address 25
<3>usb 1-1.3.3: device descriptor read/64, error -32
<3>usb 1-1.3.3: device descriptor read/64, error -32
<6>usb 1-1.3.3: new full speed USB device using str8100-ehci and address 26
<3>usb 1-1.3.3: device descriptor read/64, error -32
<3>usb 1-1.3.3: device descriptor read/64, error -32
<6>usb 1-1.3.3: new full speed USB device using str8100-ehci and address 27
<3>usb 1-1.3.3: device not accepting address 27, error -32
<6>usb 1-1.3.3: new full speed USB device using str8100-ehci and address 28
<3>usb 1-1.3.3: device not accepting address 28, error -32
<6>usb 1-1.3: USB disconnect, address 23
<6>usb 1-1.3.2: USB disconnect, address 24
<6>udlfb: USB disconnect starting
<4>dlfb_free_framebuffer_work
<4>udlfb: fb_info for /dev/fb1 has been freed
<4>dlfb_free
<5>udlfb: Waiting for completes and freeing all render urbs
<4>udlfb: freeing dlfb_data c1031000
<6>usb 1-1: USB disconnect, address 12
<6>usb 1-1: new high speed USB device using str8100-ehci and address 29
<6>usb 1-1: configuration #1 chosen from 1 choice
<6>hub 1-1:1.0: USB hub found
<6>hub 1-1:1.0: 4 ports detected
tslib doesn't create an input device; your touchscreen's device driver does. tslib uses it and you can call ts_read() to get filtered samples. There are X11 and Qt5 wrappers that do this. That's the way it always was.
As of version 1.3 of tslib, there is tslib/tools/ts_uinput that you can use to create an input device to point your environment to, see tslib's project page.
As of now, there is tslib-1.3-rc1 if you want to test this.

Resources