Add weak linkage attributes for stubbing

Add weak linkage attribute to underlying kernel module and filedescriptors
to be able to replace with stub methods together with an example stub
implementation.

Change-Id: I766c51fceede7df16c599bd9f1874e31c264776d
diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp
index 997e12a..0262429 100644
--- a/driver_library/src/ethosu.cpp
+++ b/driver_library/src/ethosu.cpp
@@ -33,8 +33,8 @@
 
 using namespace std;
 
-namespace {
-int eioctl(int fd, unsigned long cmd, void *data = nullptr) {
+namespace EthosU {
+__attribute__((weak)) int eioctl(int fd, unsigned long cmd, void *data = nullptr) {
     int ret = ::ioctl(fd, cmd, data);
     if (ret < 0) {
         throw EthosU::Exception("IOCTL failed");
@@ -43,10 +43,37 @@
     return ret;
 }
 
+__attribute__((weak)) int eopen(const char *pathname, int flags) {
+    int fd = ::open(pathname, flags);
+
+    if (fd < 0) {
+        throw Exception("Failed to open device");
+    }
+
+    return fd;
+}
+
+__attribute__((weak)) int epoll(struct pollfd *fds, nfds_t nfds, int timeout) {
+    return ::poll(fds, nfds, timeout);
+}
+
+__attribute__((weak)) int eclose(int fd) {
+    return ::close(fd);
+}
+__attribute((weak)) void *emmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
+    return ::mmap(addr, length, prot, flags, fd, offset);
+}
+
+__attribute__((weak)) int emunmap(void *addr, size_t length) {
+    return ::munmap(addr, length);
+}
+
+} // namespace EthosU
+
 /****************************************************************************
  * TFL micro helpers
  ****************************************************************************/
-
+namespace {
 size_t getShapeSize(const flatbuffers::Vector<int32_t> *shape) {
     size_t size = 1;
 
@@ -151,16 +178,12 @@
 /****************************************************************************
  * Device
  ****************************************************************************/
-
 Device::Device(const char *device) {
-    fd = open(device, O_RDWR | O_NONBLOCK);
-    if (fd < 0) {
-        throw Exception("Failed to open device");
-    }
+    fd = eopen(device, O_RDWR | O_NONBLOCK);
 }
 
 Device::~Device() {
-    close(fd);
+    eclose(fd);
 }
 
 int Device::ioctl(unsigned long cmd, void *data) {
@@ -189,7 +212,7 @@
     ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
     fd                             = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
 
-    void *d = ::mmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    void *d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     if (d == MAP_FAILED) {
         throw Exception("MMap failed");
     }
@@ -198,7 +221,8 @@
 }
 
 Buffer::~Buffer() {
-    close(fd);
+    emunmap(dataPtr, dataCapacity);
+    eclose(fd);
 }
 
 size_t Buffer::capacity() const {
@@ -263,7 +287,7 @@
 }
 
 Network::~Network() {
-    close(fd);
+    eclose(fd);
 }
 
 int Network::ioctl(unsigned long cmd, void *data) {
@@ -307,7 +331,7 @@
  ****************************************************************************/
 
 Inference::~Inference() {
-    close(fd);
+    eclose(fd);
 }
 
 void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) {
@@ -359,7 +383,7 @@
     pfd.events  = POLLIN | POLLERR;
     pfd.revents = 0;
 
-    int ret = ::poll(&pfd, 1, timeoutSec * 1000);
+    int ret = epoll(&pfd, 1, timeoutSec * 1000);
 
     cout << "Poll. ret=" << ret << ", revents=" << pfd.revents << endl;