lscpu
echo "================================================="
cat /proc/cpuinfo
Architecture: aarch64 Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 1 Vendor ID: ARM Model: 4 Model name: Cortex-A53 Stepping: r0p4 CPU max MHz: 1200.0000 CPU min MHz: 600.0000 BogoMIPS: 38.40 Flags: fp asimd evtstrm crc32 cpuid ================================================= processor : 0 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 2 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 3 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4
This is example_foo.c:
int foo(int a, int b)
{
return a + b;
}
cc -c -o example_foo.o example_foo.c -O2
These are machine codes for add and sub:
0: 0b010000 add w0, w0, w1 --------------------------------------- 0: 4b010000 sub w0, w0, w1
Let’s mmap example_foo.o
object file and run some code from it:
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
typedef int foo_t(int, int);
int main()
{
int fd;
struct stat fs;
assert((fd = open("example_foo.o", O_RDONLY)) != -1);
assert(fstat(fd, &fs) == 0);
long pagesize = sysconf(_SC_PAGESIZE);
size_t roundedSize = (fs.st_size + (pagesize - 1)) & ~(pagesize - 1);
printf("File size is %zu\n"
"Page size is %ld\n"
"Bytes to mmap %zu\n",
fs.st_size, pagesize, roundedSize);
void *reg = mmap(NULL, roundedSize,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE,
fd, 0);
assert(reg != MAP_FAILED);
printf("Mapped file at address %p\n", reg);
/* 0x40 is an offset to .text section inside object file where
* foo is defined
*/
foo_t *foo = (foo_t *)((char *)reg + 0x40);
int result = foo(42, 23);
printf("The result before write should be (42 + 23) = %d\n", result);
/* sub instruction starts with 0x4b, due to little endianness
* we need to modify 4th byte to turn add into sub
*/
*((char *)reg + 0x40 + 3) = 0x4b;
result = foo(42, 23);
printf("The result after write should be (42 - 23) = %d\n", result);
assert(munmap(reg, roundedSize) == 0);
return 0;
}
: File size is 1016 : Page size is 4096 : Bytes to mmap 4096 : Mapped file at address 0xffffb27a6000 : The result before write should be (42 + 23) = 65 : The result after write should be (42 - 23) = 19