Profile 32-bit app on 64-bit system using INTEL PIN - c

I compiled a C program using -m32 gcc option . I want to profile this program using a Pin tool . My kernel is 64 bit.
I have tried :-
1) pin -t64 <64-bit toolname> -t <32-bit toolname> -- <application>
2) pin -t <32-bit toolname> -- <application>
3) pin -t <64-bit toolname> -- <application>
I have the same .cpp tool file for both the tools compiled differently for 32 bit and 64 bit architectures.
Case 3 invoked an error 'unable to load .. Check the architecture type' .
Cases 1 and 2 , the command was successful but produced some unexpected output , for ex names of images written into a file is empty in this case but contains proper results when executed with a 64-bit application . Which is the correct way to set up the pin tool for this case?

well i found a workaround to compile the 32bit library of pin ( i mean instcount0 ) in 64bit arch.
i did modify the config file related to building the library.
i have pin located in /opt/ so , i edited
/opt/pin-3.0-76991-gcc-linux/source/tools/Config
at line 38
# Define the architecture of the target
# ; TARGET ?= $(HOST_ARCH)
TARGET = ia32
ifeq ($(TARGET),ia32)
BITS := 32
else
BITS := 64
endif
i just changed the target to ia32. works just fine after build .

There are a few caveats to know when starting a program under pin control:
1) The pintool must be compiled in the same architecture than the instrumented program (so, if your program is 32-bit, your pin tool must be 32-bit).
2) Ensure your system is setup to execute 32-bit programs on a 64-bit OS (some linux systems still need ia32-libs and / or need to be prepared for executing 32-bit programs (e.g. sudo dpkg --add-architecture i386)
3) Ensure you have all required libraries for PIN
4) Use pin.sh
Your command should be:
pin -t pintool.so -- <program> <program-options>
If you still have problems it is probably a problem with your pintool code rather than pin itself.
Did you tried one of the simple example (like inscount) on your program ?

Check the version of your PIN binary.
file PIN_DIR/pin
I downloaded PIN kit from this link. My PIN binary is 32-bit. If yours is 64-bit version, you can modify codes that check system architecture in pin.sh, and run
PIN_DIR/pin.sh
That should give you a 32-bit version PIN binary.

Related

Atmel SAM D21 set fuses via ELF file

AVR processors can have their fuses programmed via the ELF file (see http://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.html).
Is there a way to do the same for the SAM D21 ARM-based controller in AtmelStudio 6.2?
According to Atmel, the answer is no:
Question
Is it possible to include fuse information in elf production file for SAMDx devices?
Answer
No it is not possible to include fuse information in elf production file for SAMDx devices. Please see http://atmel.force.com/support/articles/en_US/FAQ/SAMD20-SAMD21-Programming-the-fuses-from-application-code on the recommended procedure to program the fuses from application code.
Your options appear to be:
Program fuses from application code, as Atmel suggests above.
Manually flip bits in the Fuses tab of Atmel Studio's Device Programming tool.
Program the fuses using atprogram.exe:
Question
How to set fuse bits for SAMR21 device using atprogram.exe?
Answer
Refer to the below command for overwriting the fuses bits.
atprogram.exe -t edbg -i SWD -d ATSAMR21G18A write -fs -o 0x804000 --values 0xEFCDAB8967452301
For fuse bit details in the NVM user row refer to Table 8-3. NVM User Row Mapping, SAMR21 datasheet.
Note:
"-o" mentions the offset, NVM user row starts at 0x804000
Reverse the value byte order: for example if 0x123456789ABCDEF has to be written, pass the value as 0xEFCDAB8967452301
Same procedure is applicable for SAM D/L/C Cortex M0+ devices as well.

How to run a C program with no OS on the Raspberry Pi?

I'd like to experiment using the Raspberry Pi for some different low level embedded applications. The only problem is that, unlike the AVR and PIC microcontroller boards available, Raspberry Pi typically runs an OS (like Raspbian) that distributes CPU time across all running programs and makes it impractical for certain real time applications.
I've recently learned that, assuming you have a bootloader like GRUB installed, running a C program on x86 (in the form of a kernel) takes very little actual setup, just an assembly program to call the main function and the actual C code.
Is there a way to achieve this with a Raspberry Pi?
It'd be a great way to learn about low level ARM programming, and it already has a few complex peripherals to mess around with (USB, Ethernet, etc.)
Fully automated minimal bare metal blinker example
Tested on Ubuntu 16.04 host, Raspberry Pi 2.
https://github.com/dwelch67/raspberrypi is the most comprehensive example set I've seen to date (previously mentioned on this now deleted answer), but this is a minimal easy to setup hello world to get you started quickly.
Usage:
Insert SD card on host
Make the image:
./make.sh /dev/mmblck0 p1
Where:
/dev/mmblck0 is the device of the SD card
p1 is the first partition of the device (/dev/mmblck0p1)
Inset SD card on PI
Turn power off and on
GitHub upstream: https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker/tree/d20f0337189641824b3ad5e4a688aa91e13fd764
start.S
.global _start
_start:
mov sp, #0x8000
bl main
hang:
b hang
main.c
#include <stdint.h>
/* This is bad. Anything remotely serious should use timers
* provided by the board. But this makes the code simpler. */
#define BUSY_WAIT __asm__ __volatile__("")
#define BUSY_WAIT_N 0x100000
int main( void ) {
uint32_t i;
/* At the low level, everything is done by writing to magic memory addresses.
The device tree files (dtb / dts), which are provided by hardware vendors,
tell the Linux kernel about those magic values. */
volatile uint32_t * const GPFSEL4 = (uint32_t *)0x3F200010;
volatile uint32_t * const GPFSEL3 = (uint32_t *)0x3F20000C;
volatile uint32_t * const GPSET1 = (uint32_t *)0x3F200020;
volatile uint32_t * const GPCLR1 = (uint32_t *)0x3F20002C;
*GPFSEL4 = (*GPFSEL4 & ~(7 << 21)) | (1 << 21);
*GPFSEL3 = (*GPFSEL3 & ~(7 << 15)) | (1 << 15);
while (1) {
*GPSET1 = 1 << (47 - 32);
*GPCLR1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
*GPCLR1 = 1 << (47 - 32);
*GPSET1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
}
}
ldscript
MEMORY
{
ram : ORIGIN = 0x8000, LENGTH = 0x10000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}
make.sh
#!/usr/bin/env bash
set -e
dev="${1:-/dev/mmcblk0}"
part="${2:-p1}"
part_dev="${dev}${part}"
mnt='/mnt/rpi'
sudo apt-get install binutils-arm-none-eabi gcc-arm-none-eabi
# Generate kernel7.img
arm-none-eabi-as start.S -o start.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c main.c -o main.o
arm-none-eabi-ld start.o main.o -T ldscript -o main.elf
# Get the raw assembly out of the generated elf file.
arm-none-eabi-objcopy main.elf -O binary kernel7.img
# Get the firmware. Those are just magic blobs, likely compiled
# from some Broadcom proprietary C code which we cannot access.
wget -O bootcode.bin https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/bootcode.bin?raw=true
wget -O start.elf https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/start.elf?raw=true
# Prepare the filesystem.
sudo umount "$part_dev"
echo 'start=2048, type=c' | sudo sfdisk "$dev"
sudo mkfs.vfat "$part_dev"
sudo mkdir -p "$mnt"
sudo mount "${part_dev}" "$mnt"
sudo cp kernel7.img bootcode.bin start.elf "$mnt"
# Cleanup.
sync
sudo umount "$mnt"
QEMU friendly bare metal examples
The problem with the blinker is that it is hard to observe LEDs in QEMU: https://raspberrypi.stackexchange.com/questions/56373/is-it-possible-to-get-the-state-of-the-leds-and-gpios-in-a-qemu-emulation-like-t
Here I describe some bare metal QEMU setups that may be of interest: How to make bare metal ARM programs and run them on QEMU? Writing to the UART is the easiest way to get output out from QEMU.
How well QEMU simulates the Raspberry Pi can be partially inferred from: How to emulate Raspberry Pi Raspbian with QEMU? Since even the Linux terminal shows up, it is likely that your baremetal stuff will also work.
Bonus
Here is an x86 example for the curious: How to run a program without an operating system?
While bare metal is possible on the Pi, I would avoid it since Linux is getting so lightweight and handles a whole bunch of stuff for you.
Here's a tutorial to get you started if you want to still learn bare metal stuff: http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/
With all that said, I would just load up your favorite embedded linux distro (RT patched might be preferred based on your requirements) and call it good.
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ is a great tutorial, and as they'll tell you the best quick and dirty way to run code on bare metal is to hijack a linux distro, to do that, just compile to kernel.img (with the appropriate architecture options) and use it to replace the existing one in the linux distro
for just this section of the tutorial you can go to:
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html#pitime
The Pi may be a bit suboptimal for what you are wanting to do, since the SoC design is such that the ARM CPU is a second-class citizen - meaning there are some hoops to jump through to get a bare metal program running on it.
However, you could cheat a bit and use the U-Boot API to give you access to some of the features U-Boot provides but be able to add your own features on the side.

Running qemu on ARM with KVM acceleration

I'm trying to emulate an ARM VM on an ARM host, a cubieboard2 embedded board, by means of qemu. I've compiled qemu from the source code and enabled kvm. Now the problem is that launching qemu-system-arm as follows:
$ /usr/local/bin/qemu-system-arm -M accel=kvm -cpu host -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -sd debian_wheezy-_armhf_standard.qcow2 -append "console=ttyAMA0 root=/dev/mmcblk0p2" -nographic
I have this error:
qemu-system-arm: -M accel=kvm: Unsupported machine type
Use -machine help to list supported machines!
What is wrong in the command I've typed. How to enable kvm?
How about reading this:
https://groups.google.com/forum/#!topic/cubieboard/4EGONZMoIAU
And yes, you are right, as the Cubieboard2 has A15, HYP hypervisor is implemented and KVM should be running in it.
More about HYP mode is covered here:
http://lwn.net/Articles/557132/
there is another way you can see the failing mode (why qemu command failed): execute your command under "strace", and you will be able to clearly see when /dev/kvm is opened, and if it succeed, non-zero fd will be returned after open("/dev/kvm") is called. and before all this - "lsmod" should return a line indicating "kvm.ko" kernel module is running, and if you can read your kernel's config file, there should be a "CONFIG_KVM" embedded within.
-M takes a machine name (eg "vexpress-a15" or "virt"), not a set of suboption=value settings. You want -machine suboption=value,... for that.
("-M name" is a shortcut for "-machine type=name".)
You also need to specify a machine name, either via -machine type=name or -M name, otherwise QEMU will complain that you didn't specify one.

Problems compiling netcat for MIPS in ubuntu

I'm new with this and I am a little messed with it:
I'm trying to compile netcat source code for MIPS in order to deploy it in my router, what I do is:
Download the toolchain for mips: mips-linux-gcc
Download netcat source and expand it to a folder
cd path/to/netcatsource
Execute:
CC=path/to/compiler/mips-linux-gcc ./configure --host=mips-linux
make
The make command works fine and trying the file command over compiled netcat file displays:
file netcat
OUTPUT: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), not stripped
For me everything seems fine, but if I execute ./netcat on my ubuntu box it works, and once I upload it to the router it displays the following error:
# ./netcat
Segmentation fault
This is the /proc/cpuinfo from my router:
# cat /proc/cpuinfo
system type : 963281T_TEF
processor : 0
cpu model : Broadcom4350 V7.5
BogoMIPS : 319.48
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : no
hardware watchpoint : no
ASEs implemented :
shadow register sets : 1
core : 0
VCED exceptions : not available
VCEI exceptions : not available
unaligned exceptions : 1395
Could anyone help me with this?
Regards
(I couldn't add a comment due to, I do not have enough points)
Try to static compile the source code
The problem may be happening because you do not have the necessary libraries on the router, maybe the binary is pointing to ld-linux.so and the router uses ld-uclibc.so. So try static build...
UPDATE
I recomend the buildroot toolchain, which by the way include netcat and many other tools like busybox

Problem with loading compiled c code in R x64 using dyn.load

I recently went from a 32bit laptop to a 64bit desktop (both win7). I just found out that I get an error now when loading dll's using dyn.load. I guess this is a simple mistake and I am overlooking something.
For example, I write this simple c function (foo.c):
void foo( int *x) {*x = *x + 1;}
Then compile it in command prompt:
R CMD SHLIB foo.c
Then in 32bit R I can use it in R:
> dyn.load("foo.dll")
> .C("foo",as.integer(1))
[[1]]
[1] 2
but in 64bit R I get:
> dyn.load("foo.dll")
Error in inDL(x, as.logical(local), as.logical(now), ...) :
unable to load shared object 'C:/Users/Sacha/Documents/R/foo.dll':
LoadLibrary failure: %1 is not a valid Win32 application.
nd.
Edit:
For reference, R CMD can be forced in an architecture by using --arch 64x :
R --arch x64 CMD SHLIB foo.c
Quite clear actually, I knew I was making a rooky mistake:)
My guess is that you are compiling it to a 32 bit target. You need to build it on your 64 bit machine with 64 bit tools. You can't load a 32 bit DLL into a 64 bit process, and vice versa.
what i did is to compile with --arch x64 and --arch 32 once a time and manually put corresponding .dll ( with the same name ) under separate folders src-x64 and src-i386 respectively, these two folders are under the same directory where the folder src is.

Resources