1
2 #include <l4/l4re_vfs/vfs.h>
3 #include <l4/sys/kdebug.h>
4 #include <l4/re/env>
5
6 using namespace L4Re::Vfs;
7 using cxx::Ref_ptr;
8
9 #define L4RE_CALL(call...) \
10 extern "C" attribute_hidden call; \
11 extern "C" attribute_hidden call
12
13 extern "C" attribute_hidden int _dl_open(char const *path, int flags, int mode);
14 extern "C" attribute_hidden int _dl_close(int fd);
15 extern "C" attribute_hidden L4Re::Vfs::Ops *__rtld_l4re_env_posix_vfs_ops;
16
17 #define L4RE_VFS __rtld_l4re_env_posix_vfs_ops
18
19 static inline
20 void
_dl_convert_stat(struct stat * buf,struct stat64 const & s)21 _dl_convert_stat(struct stat *buf, struct stat64 const &s)
22 {
23 buf->st_dev = s.st_dev;
24 buf->st_ino = s.st_ino;
25 buf->st_mode = s.st_mode;
26 buf->st_nlink = s.st_nlink;
27 buf->st_uid = s.st_uid;
28 buf->st_gid = s.st_gid;
29 buf->st_size = s.st_size;
30 }
31
L4RE_CALL(int _dl_stat (const char * p,struct stat * buf))32 L4RE_CALL(int _dl_stat(const char *p, struct stat *buf))
33 {
34 Ref_ptr<File> f;
35 int res = L4RE_VFS->get_root()->openat(p, 0, 0, &f);
36
37 if (res < 0)
38 return res;
39
40 struct stat64 s;
41 res = f->fstat64(&s);
42
43 if (res < 0)
44 return res;
45
46 _dl_convert_stat(buf, s);
47 return res;
48 }
49
50
L4RE_CALL(int _dl_fstat (int fd,struct stat * buf))51 L4RE_CALL(int _dl_fstat(int fd, struct stat *buf))
52 {
53 Ref_ptr<File> f = L4RE_VFS->get_file(fd);
54
55 if (!f)
56 return -EBADF;
57
58 struct stat64 s;
59 int res = f->fstat64(&s);
60
61 if (res < 0)
62 return res;
63
64 _dl_convert_stat(buf, s);
65 return res;
66 }
67
68
L4RE_CALL(int _dl_read (int fd,void * buf,size_t len))69 L4RE_CALL(int _dl_read(int fd, void *buf, size_t len))
70 {
71 Ref_ptr<File> f = L4RE_VFS->get_file(fd);
72
73 if (!f)
74 return -EBADF;
75
76 struct iovec v;
77 v.iov_len = len;
78 v.iov_base = buf;
79 #if 0
80 outstring("### DL: read: "); outhex32(fd); outstring("\n");
81 #endif
82 int res = f->readv(&v, 1);
83 return res;
84 };
85
86
L4RE_CALL(int _dl_close (int fd))87 L4RE_CALL(int _dl_close(int fd))
88 {
89 Ref_ptr<File> f = L4RE_VFS->free_fd(fd);
90 if (!f)
91 return -EBADF;
92
93 f->unlock_all_locks();
94 return 0;
95 }
96
97
L4RE_CALL(int _dl_open (char const * path,int flags,int mode))98 L4RE_CALL(int _dl_open(char const *path, int flags, int mode))
99 { //outstring("### DL: open: '"); outstring(path); outstring ("'\n");
100 #if 0
101 if (!_dl_init_auxvp())
102 return -L4_ENOSYS;
103 return __rtld_l4re_env_posix_vfs_ops->open(path, flags, mode);
104 #endif
105
106 Ref_ptr<File> f;
107 int res = L4RE_VFS->get_root()->openat(path, flags, mode, &f);
108
109 if (res < 0)
110 return res;
111
112 int fd = L4RE_VFS->alloc_fd(f);
113
114 return fd;
115 }
116
L4RE_CALL(int _dl_write (int fd,char const * str,size_t len))117 L4RE_CALL(int _dl_write(int fd, char const *str, size_t len))
118 {
119 Ref_ptr<File> f = L4RE_VFS->get_file(fd);
120
121 if (!f)
122 return -EBADF;
123
124 struct iovec v;
125 v.iov_len = len;
126 v.iov_base = (char*)str;
127
128 if (len <= 0)
129 return 0;
130
131 int res = f->writev(&v, 1);
132 return res;
133 }
134
135
136
L4RE_CALL(int _dl_mprotect (void const * addr,size_t len,int prot))137 L4RE_CALL(int _dl_mprotect(void const *addr, size_t len, int prot))
138 {
139 return L4RE_VFS->mprotect((void *)addr, len, prot);
140 }
141
142
143
144
L4RE_CALL(int _dl_munmap (void * start,size_t len))145 L4RE_CALL(int _dl_munmap(void *start, size_t len))
146 {
147 return L4RE_VFS->munmap(start, len);
148 }
149
L4RE_CALL(void * _dl_mmap (void * start,size_t len,int prot,int flags,int fd,off_t offset))150 L4RE_CALL(void *_dl_mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset))
151 {
152 #if 0
153 outstring("### DL: _dl_mmap(");
154 outhex32((int)start); outstring(", ");
155 outhex32((int)len); outstring(", ");
156 outhex32((int)prot); outstring(", ");
157 outhex32((int)flags); outstring(", ");
158 outhex32((int)fd); outstring(", ");
159 outhex32((int)offset); outstring("); from=");
160 outhex32((int)__builtin_return_address(0)); outstring("\n");
161 #endif
162 void *resptr;
163 int res = L4RE_VFS->mmap2(start, len, prot, flags, fd, offset >> 12, &resptr);
164 if (res >= 0)
165 return resptr;
166 else
167 return MAP_FAILED;
168 }
169