Created
October 2, 2014 05:07
-
-
Save Lanchon/c8599c7a4535e8420803 to your computer and use it in GitHub Desktop.
CM11-M10 sdcard.c objdump (i9100)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sdcard: file format elf32-littlearm | |
Disassembly of section .plt: | |
00000f68 <__libc_init@plt-0x14>: | |
f68: e52de004 .word 0xe52de004 | |
f6c: e59fe004 .word 0xe59fe004 | |
f70: e08fe00e .word 0xe08fe00e | |
f74: e5bef008 .word 0xe5bef008 | |
f78: 00003f44 .word 0x00003f44 | |
00000f7c <__libc_init@plt>: | |
f7c: e28fc600 .word 0xe28fc600 | |
f80: e28cca03 .word 0xe28cca03 | |
f84: e5bcff44 .word 0xe5bcff44 | |
00000f88 <__cxa_atexit@plt>: | |
f88: e28fc600 .word 0xe28fc600 | |
f8c: e28cca03 .word 0xe28cca03 | |
f90: e5bcff3c .word 0xe5bcff3c | |
00000f94 <fprintf@plt>: | |
f94: e28fc600 .word 0xe28fc600 | |
f98: e28cca03 .word 0xe28cca03 | |
f9c: e5bcff34 .word 0xe5bcff34 | |
00000fa0 <strcasecmp@plt>: | |
fa0: e28fc600 .word 0xe28fc600 | |
fa4: e28cca03 .word 0xe28cca03 | |
fa8: e5bcff2c .word 0xe5bcff2c | |
00000fac <strlen@plt>: | |
fac: e28fc600 .word 0xe28fc600 | |
fb0: e28cca03 .word 0xe28cca03 | |
fb4: e5bcff24 .word 0xe5bcff24 | |
00000fb8 <hashmapHash@plt>: | |
fb8: e28fc600 .word 0xe28fc600 | |
fbc: e28cca03 .word 0xe28cca03 | |
fc0: e5bcff1c .word 0xe5bcff1c | |
00000fc4 <memcpy@plt>: | |
fc4: e28fc600 .word 0xe28fc600 | |
fc8: e28cca03 .word 0xe28cca03 | |
fcc: e5bcff14 .word 0xe5bcff14 | |
00000fd0 <hashmapRemove@plt>: | |
fd0: e28fc600 .word 0xe28fc600 | |
fd4: e28cca03 .word 0xe28cca03 | |
fd8: e5bcff0c .word 0xe5bcff0c | |
00000fdc <free@plt>: | |
fdc: e28fc600 .word 0xe28fc600 | |
fe0: e28cca03 .word 0xe28cca03 | |
fe4: e5bcff04 .word 0xe5bcff04 | |
00000fe8 <writev@plt>: | |
fe8: e28fc600 .word 0xe28fc600 | |
fec: e28cca03 .word 0xe28cca03 | |
ff0: e5bcfefc .word 0xe5bcfefc | |
00000ff4 <__errno@plt>: | |
ff4: e28fc600 .word 0xe28fc600 | |
ff8: e28cca03 .word 0xe28cca03 | |
ffc: e5bcfef4 .word 0xe5bcfef4 | |
00001000 <memset@plt>: | |
1000: e28fc600 .word 0xe28fc600 | |
1004: e28cca03 .word 0xe28cca03 | |
1008: e5bcfeec .word 0xe5bcfeec | |
0000100c <multiuser_get_app_id@plt>: | |
100c: e28fc600 .word 0xe28fc600 | |
1010: e28cca03 .word 0xe28cca03 | |
1014: e5bcfee4 .word 0xe5bcfee4 | |
00001018 <hashmapContainsKey@plt>: | |
1018: e28fc600 .word 0xe28fc600 | |
101c: e28cca03 .word 0xe28cca03 | |
1020: e5bcfedc .word 0xe5bcfedc | |
00001024 <pthread_mutex_lock@plt>: | |
1024: e28fc600 .word 0xe28fc600 | |
1028: e28cca03 .word 0xe28cca03 | |
102c: e5bcfed4 .word 0xe5bcfed4 | |
00001030 <pthread_mutex_unlock@plt>: | |
1030: e28fc600 .word 0xe28fc600 | |
1034: e28cca03 .word 0xe28cca03 | |
1038: e5bcfecc .word 0xe5bcfecc | |
0000103c <statfs@plt>: | |
103c: e28fc600 .word 0xe28fc600 | |
1040: e28cca03 .word 0xe28cca03 | |
1044: e5bcfec4 .word 0xe5bcfec4 | |
00001048 <__stack_chk_fail@plt>: | |
1048: e28fc600 .word 0xe28fc600 | |
104c: e28cca03 .word 0xe28cca03 | |
1050: e5bcfebc .word 0xe5bcfebc | |
00001054 <rewinddir@plt>: | |
1054: e28fc600 .word 0xe28fc600 | |
1058: e28cca03 .word 0xe28cca03 | |
105c: e5bcfeb4 .word 0xe5bcfeb4 | |
00001060 <readdir@plt>: | |
1060: e28fc600 .word 0xe28fc600 | |
1064: e28cca03 .word 0xe28cca03 | |
1068: e5bcfeac .word 0xe5bcfeac | |
0000106c <__memcpy_chk@plt>: | |
106c: e28fc600 .word 0xe28fc600 | |
1070: e28cca03 .word 0xe28cca03 | |
1074: e5bcfea4 .word 0xe5bcfea4 | |
00001078 <open@plt>: | |
1078: e28fc600 .word 0xe28fc600 | |
107c: e28cca03 .word 0xe28cca03 | |
1080: e5bcfe9c .word 0xe5bcfe9c | |
00001084 <strerror@plt>: | |
1084: e28fc600 .word 0xe28fc600 | |
1088: e28cca03 .word 0xe28cca03 | |
108c: e5bcfe94 .word 0xe5bcfe94 | |
00001090 <close@plt>: | |
1090: e28fc600 .word 0xe28fc600 | |
1094: e28cca03 .word 0xe28cca03 | |
1098: e5bcfe8c .word 0xe5bcfe8c | |
0000109c <access@plt>: | |
109c: e28fc600 .word 0xe28fc600 | |
10a0: e28cca03 .word 0xe28cca03 | |
10a4: e5bcfe84 .word 0xe5bcfe84 | |
000010a8 <opendir@plt>: | |
10a8: e28fc600 .word 0xe28fc600 | |
10ac: e28cca03 .word 0xe28cca03 | |
10b0: e5bcfe7c .word 0xe5bcfe7c | |
000010b4 <closedir@plt>: | |
10b4: e28fc600 .word 0xe28fc600 | |
10b8: e28cca03 .word 0xe28cca03 | |
10bc: e5bcfe74 .word 0xe5bcfe74 | |
000010c0 <rmdir@plt>: | |
10c0: e28fc600 .word 0xe28fc600 | |
10c4: e28cca03 .word 0xe28cca03 | |
10c8: e5bcfe6c .word 0xe5bcfe6c | |
000010cc <unlink@plt>: | |
10cc: e28fc600 .word 0xe28fc600 | |
10d0: e28cca03 .word 0xe28cca03 | |
10d4: e5bcfe64 .word 0xe5bcfe64 | |
000010d8 <malloc@plt>: | |
10d8: e28fc600 .word 0xe28fc600 | |
10dc: e28cca03 .word 0xe28cca03 | |
10e0: e5bcfe5c .word 0xe5bcfe5c | |
000010e4 <__open_2@plt>: | |
10e4: e28fc600 .word 0xe28fc600 | |
10e8: e28cca03 .word 0xe28cca03 | |
10ec: e5bcfe54 .word 0xe5bcfe54 | |
000010f0 <lstat@plt>: | |
10f0: e28fc600 .word 0xe28fc600 | |
10f4: e28cca03 .word 0xe28cca03 | |
10f8: e5bcfe4c .word 0xe5bcfe4c | |
000010fc <truncate@plt>: | |
10fc: e28fc600 .word 0xe28fc600 | |
1100: e28cca03 .word 0xe28cca03 | |
1104: e5bcfe44 .word 0xe5bcfe44 | |
00001108 <utimensat@plt>: | |
1108: e28fc600 .word 0xe28fc600 | |
110c: e28cca03 .word 0xe28cca03 | |
1110: e5bcfe3c .word 0xe5bcfe3c | |
00001114 <strcmp@plt>: | |
1114: e28fc600 .word 0xe28fc600 | |
1118: e28cca03 .word 0xe28cca03 | |
111c: e5bcfe34 .word 0xe5bcfe34 | |
00001120 <rename@plt>: | |
1120: e28fc600 .word 0xe28fc600 | |
1124: e28cca03 .word 0xe28cca03 | |
1128: e5bcfe2c .word 0xe5bcfe2c | |
0000112c <realloc@plt>: | |
112c: e28fc600 .word 0xe28fc600 | |
1130: e28cca03 .word 0xe28cca03 | |
1134: e5bcfe24 .word 0xe5bcfe24 | |
00001138 <calloc@plt>: | |
1138: e28fc600 .word 0xe28fc600 | |
113c: e28cca03 .word 0xe28cca03 | |
1140: e5bcfe1c .word 0xe5bcfe1c | |
00001144 <strtoul@plt>: | |
1144: e28fc600 .word 0xe28fc600 | |
1148: e28cca03 .word 0xe28cca03 | |
114c: e5bcfe14 .word 0xe5bcfe14 | |
00001150 <__strlen_chk@plt>: | |
1150: e28fc600 .word 0xe28fc600 | |
1154: e28cca03 .word 0xe28cca03 | |
1158: e5bcfe0c .word 0xe5bcfe0c | |
0000115c <hashmapGet@plt>: | |
115c: e28fc600 .word 0xe28fc600 | |
1160: e28cca03 .word 0xe28cca03 | |
1164: e5bcfe04 .word 0xe5bcfe04 | |
00001168 <multiuser_get_uid@plt>: | |
1168: e28fc600 .word 0xe28fc600 | |
116c: e28cca03 .word 0xe28cca03 | |
1170: e5bcfdfc .word 0xe5bcfdfc | |
00001174 <mknod@plt>: | |
1174: e28fc600 .word 0xe28fc600 | |
1178: e28cca03 .word 0xe28cca03 | |
117c: e5bcfdf4 .word 0xe5bcfdf4 | |
00001180 <mkdir@plt>: | |
1180: e28fc600 .word 0xe28fc600 | |
1184: e28cca03 .word 0xe28cca03 | |
1188: e5bcfdec .word 0xe5bcfdec | |
0000118c <snprintf@plt>: | |
118c: e28fc600 .word 0xe28fc600 | |
1190: e28cca03 .word 0xe28cca03 | |
1194: e5bcfde4 .word 0xe5bcfde4 | |
00001198 <read@plt>: | |
1198: e28fc600 .word 0xe28fc600 | |
119c: e28cca03 .word 0xe28cca03 | |
11a0: e5bcfddc .word 0xe5bcfddc | |
000011a4 <pread64@plt>: | |
11a4: e28fc600 .word 0xe28fc600 | |
11a8: e28cca03 .word 0xe28cca03 | |
11ac: e5bcfdd4 .word 0xe5bcfdd4 | |
000011b0 <pwrite64@plt>: | |
11b0: e28fc600 .word 0xe28fc600 | |
11b4: e28cca03 .word 0xe28cca03 | |
11b8: e5bcfdcc .word 0xe5bcfdcc | |
000011bc <fdatasync@plt>: | |
11bc: e28fc600 .word 0xe28fc600 | |
11c0: e28cca03 .word 0xe28cca03 | |
11c4: e5bcfdc4 .word 0xe5bcfdc4 | |
000011c8 <fsync@plt>: | |
11c8: e28fc600 .word 0xe28fc600 | |
11cc: e28cca03 .word 0xe28cca03 | |
11d0: e5bcfdbc .word 0xe5bcfdbc | |
000011d4 <write@plt>: | |
11d4: e28fc600 .word 0xe28fc600 | |
11d8: e28cca03 .word 0xe28cca03 | |
11dc: e5bcfdb4 .word 0xe5bcfdb4 | |
000011e0 <umount2@plt>: | |
11e0: e28fc600 .word 0xe28fc600 | |
11e4: e28cca03 .word 0xe28cca03 | |
11e8: e5bcfdac .word 0xe5bcfdac | |
000011ec <mount@plt>: | |
11ec: e28fc600 .word 0xe28fc600 | |
11f0: e28cca03 .word 0xe28cca03 | |
11f4: e5bcfda4 .word 0xe5bcfda4 | |
000011f8 <setgroups@plt>: | |
11f8: e28fc600 .word 0xe28fc600 | |
11fc: e28cca03 .word 0xe28cca03 | |
1200: e5bcfd9c .word 0xe5bcfd9c | |
00001204 <setgid@plt>: | |
1204: e28fc600 .word 0xe28fc600 | |
1208: e28cca03 .word 0xe28cca03 | |
120c: e5bcfd94 .word 0xe5bcfd94 | |
00001210 <setuid@plt>: | |
1210: e28fc600 .word 0xe28fc600 | |
1214: e28cca03 .word 0xe28cca03 | |
1218: e5bcfd8c .word 0xe5bcfd8c | |
0000121c <pthread_mutex_init@plt>: | |
121c: e28fc600 .word 0xe28fc600 | |
1220: e28cca03 .word 0xe28cca03 | |
1224: e5bcfd84 .word 0xe5bcfd84 | |
00001228 <strdup@plt>: | |
1228: e28fc600 .word 0xe28fc600 | |
122c: e28cca03 .word 0xe28cca03 | |
1230: e5bcfd7c .word 0xe5bcfd7c | |
00001234 <hashmapCreate@plt>: | |
1234: e28fc600 .word 0xe28fc600 | |
1238: e28cca03 .word 0xe28cca03 | |
123c: e5bcfd74 .word 0xe5bcfd74 | |
00001240 <getuid@plt>: | |
1240: e28fc600 .word 0xe28fc600 | |
1244: e28cca03 .word 0xe28cca03 | |
1248: e5bcfd6c .word 0xe5bcfd6c | |
0000124c <getgid@plt>: | |
124c: e28fc600 .word 0xe28fc600 | |
1250: e28cca03 .word 0xe28cca03 | |
1254: e5bcfd64 .word 0xe5bcfd64 | |
00001258 <fs_prepare_dir@plt>: | |
1258: e28fc600 .word 0xe28fc600 | |
125c: e28cca03 .word 0xe28cca03 | |
1260: e5bcfd5c .word 0xe5bcfd5c | |
00001264 <umask@plt>: | |
1264: e28fc600 .word 0xe28fc600 | |
1268: e28cca03 .word 0xe28cca03 | |
126c: e5bcfd54 .word 0xe5bcfd54 | |
00001270 <fputs@plt>: | |
1270: e28fc600 .word 0xe28fc600 | |
1274: e28cca03 .word 0xe28cca03 | |
1278: e5bcfd4c .word 0xe5bcfd4c | |
0000127c <pthread_create@plt>: | |
127c: e28fc600 .word 0xe28fc600 | |
1280: e28cca03 .word 0xe28cca03 | |
1284: e5bcfd44 .word 0xe5bcfd44 | |
00001288 <inotify_init@plt>: | |
1288: e28fc600 .word 0xe28fc600 | |
128c: e28cca03 .word 0xe28cca03 | |
1290: e5bcfd3c .word 0xe5bcfd3c | |
00001294 <inotify_add_watch@plt>: | |
1294: e28fc600 .word 0xe28fc600 | |
1298: e28cca03 .word 0xe28cca03 | |
129c: e5bcfd34 .word 0xe5bcfd34 | |
000012a0 <sleep@plt>: | |
12a0: e28fc600 .word 0xe28fc600 | |
12a4: e28cca03 .word 0xe28cca03 | |
12a8: e5bcfd2c .word 0xe5bcfd2c | |
000012ac <hashmapForEach@plt>: | |
12ac: e28fc600 .word 0xe28fc600 | |
12b0: e28cca03 .word 0xe28cca03 | |
12b4: e5bcfd24 .word 0xe5bcfd24 | |
000012b8 <fopen@plt>: | |
12b8: e28fc600 .word 0xe28fc600 | |
12bc: e28cca03 .word 0xe28cca03 | |
12c0: e5bcfd1c .word 0xe5bcfd1c | |
000012c4 <sscanf@plt>: | |
12c4: e28fc600 .word 0xe28fc600 | |
12c8: e28cca03 .word 0xe28cca03 | |
12cc: e5bcfd14 .word 0xe5bcfd14 | |
000012d0 <hashmapPut@plt>: | |
12d0: e28fc600 .word 0xe28fc600 | |
12d4: e28cca03 .word 0xe28cca03 | |
12d8: e5bcfd0c .word 0xe5bcfd0c | |
000012dc <strtok@plt>: | |
12dc: e28fc600 .word 0xe28fc600 | |
12e0: e28cca03 .word 0xe28cca03 | |
12e4: e5bcfd04 .word 0xe5bcfd04 | |
000012e8 <fgets@plt>: | |
12e8: e28fc600 .word 0xe28fc600 | |
12ec: e28cca03 .word 0xe28cca03 | |
12f0: e5bcfcfc .word 0xe5bcfcfc | |
000012f4 <fclose@plt>: | |
12f4: e28fc600 .word 0xe28fc600 | |
12f8: e28cca03 .word 0xe28cca03 | |
12fc: e5bcfcf4 .word 0xe5bcfcf4 | |
00001300 <exit@plt>: | |
1300: e28fc600 .word 0xe28fc600 | |
1304: e28cca03 .word 0xe28cca03 | |
1308: e5bcfcec .word 0xe5bcfcec | |
0000130c <getopt@plt>: | |
130c: e28fc600 .word 0xe28fc600 | |
1310: e28cca03 .word 0xe28cca03 | |
1314: e5bcfce4 .word 0xe5bcfce4 | |
00001318 <setrlimit@plt>: | |
1318: e28fc600 .word 0xe28fc600 | |
131c: e28cca03 .word 0xe28cca03 | |
1320: e5bcfcdc .word 0xe5bcfcdc | |
Disassembly of section .text: | |
00001328 <_start>: | |
1328: e92d4800 push {fp, lr} | |
132c: e28db004 add fp, sp, #4 | |
1330: e24dd010 sub sp, sp, #16 | |
1334: e59f3050 ldr r3, [pc, #80] ; 138c <_start+0x64> | |
1338: e08f3003 add r3, pc, r3 | |
133c: e59f204c ldr r2, [pc, #76] ; 1390 <_start+0x68> | |
1340: e7932002 ldr r2, [r3, r2] | |
1344: e50b2014 str r2, [fp, #-20] | |
1348: e59f2044 ldr r2, [pc, #68] ; 1394 <_start+0x6c> | |
134c: e7932002 ldr r2, [r3, r2] | |
1350: e50b2010 str r2, [fp, #-16] | |
1354: e59f203c ldr r2, [pc, #60] ; 1398 <_start+0x70> | |
1358: e7932002 ldr r2, [r3, r2] | |
135c: e50b200c str r2, [fp, #-12] | |
1360: e1a0200b mov r2, fp | |
1364: e2822004 add r2, r2, #4 | |
1368: e50b2008 str r2, [fp, #-8] | |
136c: e24bc014 sub ip, fp, #20 | |
1370: e51b0008 ldr r0, [fp, #-8] | |
1374: e3a01000 mov r1, #0 | |
1378: e59f201c ldr r2, [pc, #28] ; 139c <_start+0x74> | |
137c: e7933002 ldr r3, [r3, r2] | |
1380: e1a02003 mov r2, r3 | |
1384: e1a0300c mov r3, ip | |
1388: ebfffefb bl f7c <__libc_init@plt> | |
138c: 00003b7c .word 0x00003b7c | |
1390: ffffffe0 .word 0xffffffe0 | |
1394: ffffffe4 .word 0xffffffe4 | |
1398: ffffffe8 .word 0xffffffe8 | |
139c: ffffffec .word 0xffffffec | |
000013a0 <atexit>: | |
13a0: e92d4800 push {fp, lr} | |
13a4: e28db004 add fp, sp, #4 | |
13a8: e24dd008 sub sp, sp, #8 | |
13ac: e50b0008 str r0, [fp, #-8] | |
13b0: e51b0008 ldr r0, [fp, #-8] | |
13b4: e3a01000 mov r1, #0 | |
13b8: e59f3018 ldr r3, [pc, #24] ; 13d8 <atexit+0x38> | |
13bc: e08f3003 add r3, pc, r3 | |
13c0: e1a02003 mov r2, r3 | |
13c4: ebfffeef bl f88 <__cxa_atexit@plt> | |
13c8: e1a03000 mov r3, r0 | |
13cc: e1a00003 mov r0, r3 | |
13d0: e24bd004 sub sp, fp, #4 | |
13d4: e8bd8800 pop {fp, pc} | |
13d8: 00003c3c .word 0x00003c3c | |
000013dc <main>: | |
*/ | |
extern int sdcard_main(int argc, char **argv); | |
int main(int argc, char **argv) { | |
return sdcard_main(argc, argv); | |
13dc: f001 be66 b.w 30ac <sdcard_main> | |
000013e0 <int_hash>: | |
return strcasecmp(keyA, keyB) == 0; | |
} | |
static int int_hash(void *key) { | |
return (int) key; | |
} | |
13e0: 4770 bx lr | |
000013e2 <int_equals>: | |
static bool int_equals(void *keyA, void *keyB) { | |
return keyA == keyB; | |
} | |
13e2: 1a0b subs r3, r1, r0 | |
13e4: 4258 negs r0, r3 | |
13e6: 4158 adcs r0, r3 | |
13e8: 4770 bx lr | |
... | |
000013ec <usage>: | |
quit: | |
exit(1); | |
} | |
static int usage() | |
{ | |
13ec: b508 push {r3, lr} | |
13ee: 4b06 ldr r3, [pc, #24] ; (1408 <usage+0x1c>) | |
ERROR("usage: sdcard [OPTIONS] <source_path> <dest_path>\n" | |
13f0: 4a06 ldr r2, [pc, #24] ; (140c <usage+0x20>) | |
quit: | |
exit(1); | |
} | |
static int usage() | |
{ | |
13f2: 447b add r3, pc | |
ERROR("usage: sdcard [OPTIONS] <source_path> <dest_path>\n" | |
13f4: 4906 ldr r1, [pc, #24] ; (1410 <usage+0x24>) | |
13f6: 5898 ldr r0, [r3, r2] | |
13f8: 2202 movs r2, #2 | |
13fa: 4479 add r1, pc | |
13fc: 30a8 adds r0, #168 ; 0xa8 | |
13fe: f7ff edca blx f94 <fprintf@plt> | |
" -d: derive file permissions based on path\n" | |
" -l: derive file permissions based on legacy internal layout\n" | |
" -s: split derived permissions for pics, av (requires -d or -l)\n" | |
"\n", DEFAULT_NUM_THREADS); | |
return 1; | |
} | |
1402: 2001 movs r0, #1 | |
1404: bd08 pop {r3, pc} | |
1406: bf00 nop | |
1408: 00003ac6 .word 0x00003ac6 | |
140c: fffffff0 .word 0xfffffff0 | |
1410: 000020e2 .word 0x000020e2 | |
00001414 <str_icase_equals>: | |
static int str_hash(void *key) { | |
return hashmapHash(key, strlen(key)); | |
} | |
/** Test if two string keys are equal ignoring case */ | |
static bool str_icase_equals(void *keyA, void *keyB) { | |
1414: b508 push {r3, lr} | |
return strcasecmp(keyA, keyB) == 0; | |
1416: f7ff edc4 blx fa0 <strcasecmp@plt> | |
} | |
141a: f1d0 0001 rsbs r0, r0, #1 | |
141e: bf38 it cc | |
1420: 2000 movcc r0, #0 | |
1422: bd08 pop {r3, pc} | |
00001424 <str_hash>: | |
* position. Used to support things like OBB. */ | |
char* graft_path; | |
size_t graft_pathlen; | |
}; | |
static int str_hash(void *key) { | |
1424: b510 push {r4, lr} | |
1426: 4604 mov r4, r0 | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
1428: f7ff edc0 blx fac <strlen@plt> | |
142c: 4601 mov r1, r0 | |
return hashmapHash(key, strlen(key)); | |
142e: 4620 mov r0, r4 | |
} | |
1430: e8bd 4010 ldmia.w sp!, {r4, lr} | |
char* graft_path; | |
size_t graft_pathlen; | |
}; | |
static int str_hash(void *key) { | |
return hashmapHash(key, strlen(key)); | |
1434: f001 bf30 b.w 3298 <sdcard_main+0x1ec> | |
00001438 <get_node_path_locked>: | |
/* Gets the absolute path to a node into the provided buffer. | |
* | |
* Populates 'buf' with the path and returns the length of the path on success, | |
* or returns -1 if the path is too long for the provided buffer. | |
*/ | |
static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) { | |
1438: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} | |
143c: 460f mov r7, r1 | |
const char* name; | |
size_t namelen; | |
if (node->graft_path) { | |
143e: 6c43 ldr r3, [r0, #68] ; 0x44 | |
1440: b113 cbz r3, 1448 <get_node_path_locked+0x10> | |
name = node->graft_path; | |
namelen = node->graft_pathlen; | |
1442: 6c84 ldr r4, [r0, #72] ; 0x48 | |
1444: 461e mov r6, r3 | |
1446: e003 b.n 1450 <get_node_path_locked+0x18> | |
} else if (node->actual_name) { | |
1448: 6c06 ldr r6, [r0, #64] ; 0x40 | |
144a: 6b84 ldr r4, [r0, #56] ; 0x38 | |
144c: b906 cbnz r6, 1450 <get_node_path_locked+0x18> | |
name = node->actual_name; | |
namelen = node->namelen; | |
} else { | |
name = node->name; | |
144e: 6bc6 ldr r6, [r0, #60] ; 0x3c | |
namelen = node->namelen; | |
} | |
if (bufsize < namelen + 1) { | |
1450: f104 0801 add.w r8, r4, #1 | |
1454: 4542 cmp r2, r8 | |
1456: d203 bcs.n 1460 <get_node_path_locked+0x28> | |
return -1; | |
1458: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff | |
145c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} | |
} | |
ssize_t pathlen = 0; | |
if (node->parent && node->graft_path == NULL) { | |
1460: 6b40 ldr r0, [r0, #52] ; 0x34 | |
1462: b158 cbz r0, 147c <get_node_path_locked+0x44> | |
1464: b963 cbnz r3, 1480 <get_node_path_locked+0x48> | |
pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 2); | |
1466: 3a02 subs r2, #2 | |
1468: 4639 mov r1, r7 | |
146a: 1b12 subs r2, r2, r4 | |
146c: f7ff ffe4 bl 1438 <get_node_path_locked> | |
if (pathlen < 0) { | |
1470: 2800 cmp r0, #0 | |
1472: dbf1 blt.n 1458 <get_node_path_locked+0x20> | |
return -1; | |
} | |
buf[pathlen++] = '/'; | |
1474: 212f movs r1, #47 ; 0x2f | |
1476: 1c45 adds r5, r0, #1 | |
1478: 5439 strb r1, [r7, r0] | |
147a: e002 b.n 1482 <get_node_path_locked+0x4a> | |
if (bufsize < namelen + 1) { | |
return -1; | |
} | |
ssize_t pathlen = 0; | |
147c: 4605 mov r5, r0 | |
147e: e000 b.n 1482 <get_node_path_locked+0x4a> | |
1480: 2500 movs r5, #0 | |
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { | |
__memcpy_src_size_error(); | |
} | |
return __builtin___memcpy_chk(dest, src, copy_amount, d_len); | |
1482: 1978 adds r0, r7, r5 | |
1484: 4631 mov r1, r6 | |
1486: 4642 mov r2, r8 | |
1488: f7ff ed9c blx fc4 <memcpy@plt> | |
} | |
buf[pathlen++] = '/'; | |
} | |
memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */ | |
return pathlen + namelen; | |
148c: 1928 adds r0, r5, r4 | |
} | |
148e: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} | |
00001492 <remove_int_to_null>: | |
hashmapRemove(map, key); | |
free(key); | |
return true; | |
} | |
static bool remove_int_to_null(void *key, void *value, void *context) { | |
1492: 4601 mov r1, r0 | |
1494: b508 push {r3, lr} | |
Hashmap* map = context; | |
hashmapRemove(map, key); | |
1496: 4610 mov r0, r2 | |
1498: f7ff ed9a blx fd0 <hashmapRemove@plt> | |
return true; | |
} | |
149c: 2001 movs r0, #1 | |
149e: bd08 pop {r3, pc} | |
000014a0 <remove_str_to_int>: | |
struct fuse_handler* handler = data; | |
handle_fuse_requests(handler); | |
return NULL; | |
} | |
static bool remove_str_to_int(void *key, void *value, void *context) { | |
14a0: b510 push {r4, lr} | |
14a2: 4604 mov r4, r0 | |
Hashmap* map = context; | |
hashmapRemove(map, key); | |
14a4: 4621 mov r1, r4 | |
14a6: 4610 mov r0, r2 | |
14a8: f7ff ed92 blx fd0 <hashmapRemove@plt> | |
free(key); | |
14ac: 4620 mov r0, r4 | |
14ae: f7ff ed96 blx fdc <free@plt> | |
return true; | |
} | |
14b2: 2001 movs r0, #1 | |
14b4: bd10 pop {r4, pc} | |
... | |
000014b8 <check_caller_access_to_name>: | |
/* Kernel has already enforced everything we returned through | |
* derive_permissions_locked(), so this is used to lock down access | |
* even further, such as enforcing that apps hold sdcard_rw. */ | |
static bool check_caller_access_to_name(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* parent_node, | |
const char* name, int mode, bool has_rw) { | |
14b8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} | |
14bc: 4680 mov r8, r0 | |
14be: 460f mov r7, r1 | |
14c0: 461e mov r6, r3 | |
/* Always block security-sensitive files at root */ | |
if (parent_node && parent_node->perm == PERM_ROOT) { | |
14c2: 4615 mov r5, r2 | |
/* Kernel has already enforced everything we returned through | |
* derive_permissions_locked(), so this is used to lock down access | |
* even further, such as enforcing that apps hold sdcard_rw. */ | |
static bool check_caller_access_to_name(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* parent_node, | |
const char* name, int mode, bool has_rw) { | |
14c4: f89d 401c ldrb.w r4, [sp, #28] | |
/* Always block security-sensitive files at root */ | |
if (parent_node && parent_node->perm == PERM_ROOT) { | |
14c8: b1a2 cbz r2, 14f4 <check_caller_access_to_name+0x3c> | |
14ca: 6993 ldr r3, [r2, #24] | |
14cc: 2b02 cmp r3, #2 | |
14ce: d111 bne.n 14f4 <check_caller_access_to_name+0x3c> | |
if (!strcasecmp(name, "autorun.inf") | |
14d0: 4912 ldr r1, [pc, #72] ; (151c <check_caller_access_to_name+0x64>) | |
14d2: 4630 mov r0, r6 | |
14d4: 4479 add r1, pc | |
14d6: f7ff ed64 blx fa0 <strcasecmp@plt> | |
14da: b1c8 cbz r0, 1510 <check_caller_access_to_name+0x58> | |
|| !strcasecmp(name, ".android_secure") | |
14dc: 4910 ldr r1, [pc, #64] ; (1520 <check_caller_access_to_name+0x68>) | |
14de: 4630 mov r0, r6 | |
14e0: 4479 add r1, pc | |
14e2: f7ff ed5e blx fa0 <strcasecmp@plt> | |
14e6: b198 cbz r0, 1510 <check_caller_access_to_name+0x58> | |
|| !strcasecmp(name, "android_secure")) { | |
14e8: 490e ldr r1, [pc, #56] ; (1524 <check_caller_access_to_name+0x6c>) | |
14ea: 4630 mov r0, r6 | |
14ec: 4479 add r1, pc | |
14ee: f7ff ed58 blx fa0 <strcasecmp@plt> | |
14f2: b168 cbz r0, 1510 <check_caller_access_to_name+0x58> | |
return false; | |
} | |
} | |
/* No additional permissions enforcement */ | |
if (fuse->derive == DERIVE_NONE) { | |
14f4: f8d8 0014 ldr.w r0, [r8, #20] | |
14f8: b160 cbz r0, 1514 <check_caller_access_to_name+0x5c> | |
return true; | |
} | |
/* Root always has access; access for any other UIDs should always | |
* be controlled through packages.list. */ | |
if (hdr->uid == 0) { | |
14fa: 69b9 ldr r1, [r7, #24] | |
14fc: b151 cbz r1, 1514 <check_caller_access_to_name+0x5c> | |
return true; | |
} | |
/* If asking to write, verify that caller either owns the | |
* parent or holds sdcard_rw. */ | |
if (mode & W_OK) { | |
14fe: 9a06 ldr r2, [sp, #24] | |
1500: 0792 lsls r2, r2, #30 | |
1502: d507 bpl.n 1514 <check_caller_access_to_name+0x5c> | |
if (parent_node && hdr->uid == parent_node->uid) { | |
1504: b13d cbz r5, 1516 <check_caller_access_to_name+0x5e> | |
1506: 6a2b ldr r3, [r5, #32] | |
} | |
/* Root always has access; access for any other UIDs should always | |
* be controlled through packages.list. */ | |
if (hdr->uid == 0) { | |
return true; | |
1508: 4299 cmp r1, r3 | |
150a: bf08 it eq | |
150c: 2401 moveq r4, #1 | |
150e: e002 b.n 1516 <check_caller_access_to_name+0x5e> | |
/* Always block security-sensitive files at root */ | |
if (parent_node && parent_node->perm == PERM_ROOT) { | |
if (!strcasecmp(name, "autorun.inf") | |
|| !strcasecmp(name, ".android_secure") | |
|| !strcasecmp(name, "android_secure")) { | |
return false; | |
1510: 4604 mov r4, r0 | |
1512: e000 b.n 1516 <check_caller_access_to_name+0x5e> | |
} | |
} | |
/* No additional permissions enforcement */ | |
if (fuse->derive == DERIVE_NONE) { | |
return true; | |
1514: 2401 movs r4, #1 | |
return has_rw; | |
} | |
/* No extra permissions to enforce */ | |
return true; | |
} | |
1516: 4620 mov r0, r4 | |
1518: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} | |
151c: 00002199 .word 0x00002199 | |
1520: 00002199 .word 0x00002199 | |
1524: 0000219d .word 0x0000219d | |
00001528 <fuse_reply>: | |
hdr.unique = unique; | |
write(fuse->fd, &hdr, sizeof(hdr)); | |
} | |
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len) | |
{ | |
1528: b530 push {r4, r5, lr} | |
152a: b089 sub sp, #36 ; 0x24 | |
152c: 990d ldr r1, [sp, #52] ; 0x34 | |
struct iovec vec[2]; | |
int res; | |
hdr.len = len + sizeof(hdr); | |
hdr.error = 0; | |
hdr.unique = unique; | |
152e: e9cd 2302 strd r2, r3, [sp, #8] | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
1532: 2210 movs r2, #16 | |
{ | |
struct fuse_out_header hdr; | |
struct iovec vec[2]; | |
int res; | |
hdr.len = len + sizeof(hdr); | |
1534: f101 0510 add.w r5, r1, #16 | |
hdr.error = 0; | |
hdr.unique = unique; | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
1538: 9205 str r2, [sp, #20] | |
{ | |
struct fuse_out_header hdr; | |
struct iovec vec[2]; | |
int res; | |
hdr.len = len + sizeof(hdr); | |
153a: 9500 str r5, [sp, #0] | |
hdr.error = 0; | |
153c: 2500 movs r5, #0 | |
hdr.unique = unique; | |
vec[0].iov_base = &hdr; | |
153e: eb0d 0305 add.w r3, sp, r5 | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
vec[1].iov_len = len; | |
1542: 9107 str r1, [sp, #28] | |
hdr.len = len + sizeof(hdr); | |
hdr.error = 0; | |
hdr.unique = unique; | |
vec[0].iov_base = &hdr; | |
1544: 9304 str r3, [sp, #16] | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
vec[1].iov_len = len; | |
res = writev(fuse->fd, vec, 2); | |
1546: 2202 movs r2, #2 | |
hdr.error = 0; | |
hdr.unique = unique; | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
1548: 9b0c ldr r3, [sp, #48] ; 0x30 | |
vec[1].iov_len = len; | |
res = writev(fuse->fd, vec, 2); | |
154a: a904 add r1, sp, #16 | |
hdr.unique = unique; | |
write(fuse->fd, &hdr, sizeof(hdr)); | |
} | |
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len) | |
{ | |
154c: 4c0a ldr r4, [pc, #40] ; (1578 <fuse_reply+0x50>) | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
vec[1].iov_len = len; | |
res = writev(fuse->fd, vec, 2); | |
154e: 6900 ldr r0, [r0, #16] | |
struct fuse_out_header hdr; | |
struct iovec vec[2]; | |
int res; | |
hdr.len = len + sizeof(hdr); | |
hdr.error = 0; | |
1550: 9501 str r5, [sp, #4] | |
hdr.unique = unique; | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
1552: 9306 str r3, [sp, #24] | |
hdr.unique = unique; | |
write(fuse->fd, &hdr, sizeof(hdr)); | |
} | |
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len) | |
{ | |
1554: 447c add r4, pc | |
vec[0].iov_base = &hdr; | |
vec[0].iov_len = sizeof(hdr); | |
vec[1].iov_base = data; | |
vec[1].iov_len = len; | |
res = writev(fuse->fd, vec, 2); | |
1556: f7ff ed48 blx fe8 <writev@plt> | |
if (res < 0) { | |
155a: 42a8 cmp r0, r5 | |
155c: da09 bge.n 1572 <fuse_reply+0x4a> | |
ERROR("*** REPLY FAILED *** %d\n", errno); | |
155e: f7ff ed4a blx ff4 <__errno@plt> | |
1562: 6802 ldr r2, [r0, #0] | |
1564: 4805 ldr r0, [pc, #20] ; (157c <fuse_reply+0x54>) | |
1566: 4906 ldr r1, [pc, #24] ; (1580 <fuse_reply+0x58>) | |
1568: 5820 ldr r0, [r4, r0] | |
156a: 4479 add r1, pc | |
156c: 30a8 adds r0, #168 ; 0xa8 | |
156e: f7ff ed12 blx f94 <fprintf@plt> | |
} | |
} | |
1572: b009 add sp, #36 ; 0x24 | |
1574: bd30 pop {r4, r5, pc} | |
1576: bf00 nop | |
1578: 00003964 .word 0x00003964 | |
157c: fffffff0 .word 0xfffffff0 | |
1580: 0000212e .word 0x0000212e | |
00001584 <release_node_locked>: | |
} | |
static void remove_node_from_parent_locked(struct node* node); | |
static void release_node_locked(struct node* node) | |
{ | |
1584: b510 push {r4, lr} | |
1586: 4604 mov r4, r0 | |
1588: 4b14 ldr r3, [pc, #80] ; (15dc <release_node_locked+0x58>) | |
TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount); | |
if (node->refcount > 0) { | |
158a: 6802 ldr r2, [r0, #0] | |
} | |
static void remove_node_from_parent_locked(struct node* node); | |
static void release_node_locked(struct node* node) | |
{ | |
158c: 447b add r3, pc | |
TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount); | |
if (node->refcount > 0) { | |
158e: b1d2 cbz r2, 15c6 <release_node_locked+0x42> | |
node->refcount--; | |
1590: 1e53 subs r3, r2, #1 | |
1592: 6003 str r3, [r0, #0] | |
if (!node->refcount) { | |
1594: 2b00 cmp r3, #0 | |
1596: d120 bne.n 15da <release_node_locked+0x56> | |
TRACE("DESTROY %p (%s)\n", node, node->name); | |
remove_node_from_parent_locked(node); | |
1598: f000 f826 bl 15e8 <remove_node_from_parent_locked> | |
return __builtin___strncat_chk(dest, src, n, __bos(dest)); | |
} | |
__BIONIC_FORTIFY_INLINE | |
void* memset(void *s, int c, size_t n) { | |
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0)); | |
159c: 21ef movs r1, #239 ; 0xef | |
159e: 6ba2 ldr r2, [r4, #56] ; 0x38 | |
15a0: 6be0 ldr r0, [r4, #60] ; 0x3c | |
15a2: f7ff ed2e blx 1000 <memset@plt> | |
/* TODO: remove debugging - poison memory */ | |
memset(node->name, 0xef, node->namelen); | |
free(node->name); | |
15a6: 6be0 ldr r0, [r4, #60] ; 0x3c | |
15a8: f7ff ed18 blx fdc <free@plt> | |
free(node->actual_name); | |
15ac: 6c20 ldr r0, [r4, #64] ; 0x40 | |
15ae: f7ff ed16 blx fdc <free@plt> | |
15b2: 4620 mov r0, r4 | |
15b4: 21fc movs r1, #252 ; 0xfc | |
15b6: 2250 movs r2, #80 ; 0x50 | |
15b8: f7ff ed22 blx 1000 <memset@plt> | |
memset(node, 0xfc, sizeof(*node)); | |
free(node); | |
15bc: 4620 mov r0, r4 | |
} | |
} else { | |
ERROR("Zero refcnt %p\n", node); | |
} | |
} | |
15be: e8bd 4010 ldmia.w sp!, {r4, lr} | |
/* TODO: remove debugging - poison memory */ | |
memset(node->name, 0xef, node->namelen); | |
free(node->name); | |
free(node->actual_name); | |
memset(node, 0xfc, sizeof(*node)); | |
free(node); | |
15c2: f001 be71 b.w 32a8 <sdcard_main+0x1fc> | |
} | |
} else { | |
ERROR("Zero refcnt %p\n", node); | |
15c6: 4806 ldr r0, [pc, #24] ; (15e0 <release_node_locked+0x5c>) | |
15c8: 4622 mov r2, r4 | |
15ca: 4906 ldr r1, [pc, #24] ; (15e4 <release_node_locked+0x60>) | |
15cc: 5818 ldr r0, [r3, r0] | |
15ce: 4479 add r1, pc | |
15d0: 30a8 adds r0, #168 ; 0xa8 | |
} | |
} | |
15d2: e8bd 4010 ldmia.w sp!, {r4, lr} | |
free(node->actual_name); | |
memset(node, 0xfc, sizeof(*node)); | |
free(node); | |
} | |
} else { | |
ERROR("Zero refcnt %p\n", node); | |
15d6: f001 be6f b.w 32b8 <sdcard_main+0x20c> | |
15da: bd10 pop {r4, pc} | |
15dc: 0000392c .word 0x0000392c | |
15e0: fffffff0 .word 0xfffffff0 | |
15e4: 000020e3 .word 0x000020e3 | |
000015e8 <remove_node_from_parent_locked>: | |
parent->child = node; | |
acquire_node_locked(parent); | |
} | |
static void remove_node_from_parent_locked(struct node* node) | |
{ | |
15e8: b510 push {r4, lr} | |
15ea: 4604 mov r4, r0 | |
if (node->parent) { | |
15ec: 6b42 ldr r2, [r0, #52] ; 0x34 | |
15ee: b18a cbz r2, 1614 <remove_node_from_parent_locked+0x2c> | |
if (node->parent->child == node) { | |
15f0: 6b13 ldr r3, [r2, #48] ; 0x30 | |
15f2: 4283 cmp r3, r0 | |
15f4: d103 bne.n 15fe <remove_node_from_parent_locked+0x16> | |
node->parent->child = node->parent->child->next; | |
15f6: 6ac0 ldr r0, [r0, #44] ; 0x2c | |
15f8: 6310 str r0, [r2, #48] ; 0x30 | |
15fa: e005 b.n 1608 <remove_node_from_parent_locked+0x20> | |
} else { | |
struct node *node2; | |
node2 = node->parent->child; | |
while (node2->next != node) | |
node2 = node2->next; | |
15fc: 4603 mov r3, r0 | |
if (node->parent->child == node) { | |
node->parent->child = node->parent->child->next; | |
} else { | |
struct node *node2; | |
node2 = node->parent->child; | |
while (node2->next != node) | |
15fe: 6ad8 ldr r0, [r3, #44] ; 0x2c | |
1600: 42a0 cmp r0, r4 | |
1602: d1fb bne.n 15fc <remove_node_from_parent_locked+0x14> | |
node2 = node2->next; | |
node2->next = node->next; | |
1604: 6ae1 ldr r1, [r4, #44] ; 0x2c | |
1606: 62d9 str r1, [r3, #44] ; 0x2c | |
} | |
release_node_locked(node->parent); | |
1608: 6b60 ldr r0, [r4, #52] ; 0x34 | |
160a: f7ff ffbb bl 1584 <release_node_locked> | |
node->parent = NULL; | |
160e: 2200 movs r2, #0 | |
1610: 6362 str r2, [r4, #52] ; 0x34 | |
node->next = NULL; | |
1612: 62e2 str r2, [r4, #44] ; 0x2c | |
1614: bd10 pop {r4, pc} | |
00001616 <get_caller_has_rw_locked>: | |
break; | |
} | |
} | |
/* Return if the calling UID holds sdcard_rw. */ | |
static bool get_caller_has_rw_locked(struct fuse* fuse, const struct fuse_in_header *hdr) { | |
1616: b510 push {r4, lr} | |
1618: 4604 mov r4, r0 | |
/* No additional permissions enforcement */ | |
if (fuse->derive == DERIVE_NONE) { | |
161a: 6943 ldr r3, [r0, #20] | |
161c: b153 cbz r3, 1634 <get_caller_has_rw_locked+0x1e> | |
return true; | |
} | |
appid_t appid = multiuser_get_app_id(hdr->uid); | |
161e: 6988 ldr r0, [r1, #24] | |
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid); | |
1620: f504 5483 add.w r4, r4, #4192 ; 0x1060 | |
/* No additional permissions enforcement */ | |
if (fuse->derive == DERIVE_NONE) { | |
return true; | |
} | |
appid_t appid = multiuser_get_app_id(hdr->uid); | |
1624: f7ff ecf2 blx 100c <multiuser_get_app_id@plt> | |
1628: 4601 mov r1, r0 | |
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid); | |
162a: 6960 ldr r0, [r4, #20] | |
} | |
162c: e8bd 4010 ldmia.w sp!, {r4, lr} | |
if (fuse->derive == DERIVE_NONE) { | |
return true; | |
} | |
appid_t appid = multiuser_get_app_id(hdr->uid); | |
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid); | |
1630: f001 be4a b.w 32c8 <sdcard_main+0x21c> | |
} | |
1634: 2001 movs r0, #1 | |
1636: bd10 pop {r4, pc} | |
00001638 <handle_statfs.isra.19>: | |
out.size = res; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
static int handle_statfs(struct fuse* fuse, struct fuse_handler* handler, | |
1638: 4b31 ldr r3, [pc, #196] ; (1700 <handle_statfs.isra.19+0xc8>) | |
163a: 4a32 ldr r2, [pc, #200] ; (1704 <handle_statfs.isra.19+0xcc>) | |
163c: e92d 42f0 stmdb sp!, {r4, r5, r6, r7, r9, lr} | |
1640: f5ad 5d85 sub.w sp, sp, #4256 ; 0x10a0 | |
1644: 447b add r3, pc | |
1646: b086 sub sp, #24 | |
1648: 4689 mov r9, r1 | |
164a: f50d 5185 add.w r1, sp, #4256 ; 0x10a0 | |
164e: 589c ldr r4, [r3, r2] | |
1650: 3114 adds r1, #20 | |
1652: 4607 mov r7, r0 | |
1654: 6823 ldr r3, [r4, #0] | |
1656: 600b str r3, [r1, #0] | |
char path[PATH_MAX]; | |
struct statfs stat; | |
struct fuse_statfs_out out; | |
int res; | |
pthread_mutex_lock(&fuse->lock); | |
1658: f7ff ece4 blx 1024 <pthread_mutex_lock@plt> | |
TRACE("[%d] STATFS\n", handler->token); | |
res = get_node_path_locked(&fuse->root, path, sizeof(path)); | |
165c: a92d add r1, sp, #180 ; 0xb4 | |
165e: f44f 5280 mov.w r2, #4096 ; 0x1000 | |
1662: f107 0020 add.w r0, r7, #32 | |
1666: f7ff fee7 bl 1438 <get_node_path_locked> | |
166a: 4605 mov r5, r0 | |
pthread_mutex_unlock(&fuse->lock); | |
166c: 4638 mov r0, r7 | |
166e: f7ff ece0 blx 1030 <pthread_mutex_unlock@plt> | |
if (res < 0) { | |
1672: 2d00 cmp r5, #0 | |
1674: db34 blt.n 16e0 <handle_statfs.isra.19+0xa8> | |
return -ENOENT; | |
} | |
if (statfs(fuse->root.name, &stat) < 0) { | |
1676: 6df8 ldr r0, [r7, #92] ; 0x5c | |
1678: a916 add r1, sp, #88 ; 0x58 | |
167a: f7ff ece0 blx 103c <statfs@plt> | |
167e: 2800 cmp r0, #0 | |
1680: da04 bge.n 168c <handle_statfs.isra.19+0x54> | |
return -errno; | |
1682: f7ff ecb8 blx ff4 <__errno@plt> | |
1686: 6800 ldr r0, [r0, #0] | |
1688: 4240 negs r0, r0 | |
168a: e02b b.n 16e4 <handle_statfs.isra.19+0xac> | |
} | |
memset(&out, 0, sizeof(out)); | |
168c: ae02 add r6, sp, #8 | |
168e: 2550 movs r5, #80 ; 0x50 | |
1690: 2100 movs r1, #0 | |
1692: 462a mov r2, r5 | |
1694: 4630 mov r0, r6 | |
1696: f7ff ecb4 blx 1000 <memset@plt> | |
out.st.blocks = stat.f_blocks; | |
169a: e9dd 0118 ldrd r0, r1, [sp, #96] ; 0x60 | |
out.st.bfree = stat.f_bfree; | |
169e: e9dd 231a ldrd r2, r3, [sp, #104] ; 0x68 | |
} | |
if (statfs(fuse->root.name, &stat) < 0) { | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
out.st.blocks = stat.f_blocks; | |
16a2: e9cd 0102 strd r0, r1, [sp, #8] | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
16a6: e9dd 011c ldrd r0, r1, [sp, #112] ; 0x70 | |
if (statfs(fuse->root.name, &stat) < 0) { | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
out.st.blocks = stat.f_blocks; | |
out.st.bfree = stat.f_bfree; | |
16aa: e9cd 2304 strd r2, r3, [sp, #16] | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
16ae: e9dd 231e ldrd r2, r3, [sp, #120] ; 0x78 | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
out.st.blocks = stat.f_blocks; | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
16b2: e9c6 0104 strd r0, r1, [r6, #16] | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
16b6: e9dd 0120 ldrd r0, r1, [sp, #128] ; 0x80 | |
} | |
memset(&out, 0, sizeof(out)); | |
out.st.blocks = stat.f_blocks; | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
16ba: e9c6 2306 strd r2, r3, [r6, #24] | |
out.st.ffree = stat.f_ffree; | |
out.st.bsize = stat.f_bsize; | |
16be: 9b17 ldr r3, [sp, #92] ; 0x5c | |
memset(&out, 0, sizeof(out)); | |
out.st.blocks = stat.f_blocks; | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
16c0: e9c6 0108 strd r0, r1, [r6, #32] | |
out.st.bsize = stat.f_bsize; | |
out.st.namelen = stat.f_namelen; | |
out.st.frsize = stat.f_frsize; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
16c4: 4638 mov r0, r7 | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
out.st.bsize = stat.f_bsize; | |
out.st.namelen = stat.f_namelen; | |
out.st.frsize = stat.f_frsize; | |
16c6: 9a25 ldr r2, [sp, #148] ; 0x94 | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
out.st.bsize = stat.f_bsize; | |
out.st.namelen = stat.f_namelen; | |
16c8: 9924 ldr r1, [sp, #144] ; 0x90 | |
out.st.blocks = stat.f_blocks; | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
out.st.bsize = stat.f_bsize; | |
16ca: 62b3 str r3, [r6, #40] ; 0x28 | |
out.st.namelen = stat.f_namelen; | |
out.st.frsize = stat.f_frsize; | |
16cc: 6332 str r2, [r6, #48] ; 0x30 | |
out.st.bfree = stat.f_bfree; | |
out.st.bavail = stat.f_bavail; | |
out.st.files = stat.f_files; | |
out.st.ffree = stat.f_ffree; | |
out.st.bsize = stat.f_bsize; | |
out.st.namelen = stat.f_namelen; | |
16ce: 62f1 str r1, [r6, #44] ; 0x2c | |
out.st.frsize = stat.f_frsize; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
16d0: e9d9 2302 ldrd r2, r3, [r9, #8] | |
16d4: 9600 str r6, [sp, #0] | |
16d6: 9501 str r5, [sp, #4] | |
16d8: f7ff ff26 bl 1528 <fuse_reply> | |
return NO_STATUS; | |
16dc: 2001 movs r0, #1 | |
16de: e001 b.n 16e4 <handle_statfs.isra.19+0xac> | |
pthread_mutex_lock(&fuse->lock); | |
TRACE("[%d] STATFS\n", handler->token); | |
res = get_node_path_locked(&fuse->root, path, sizeof(path)); | |
pthread_mutex_unlock(&fuse->lock); | |
if (res < 0) { | |
return -ENOENT; | |
16e0: f06f 0001 mvn.w r0, #1 | |
out.st.bsize = stat.f_bsize; | |
out.st.namelen = stat.f_namelen; | |
out.st.frsize = stat.f_frsize; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
16e4: f50d 5385 add.w r3, sp, #4256 ; 0x10a0 | |
16e8: 3314 adds r3, #20 | |
16ea: 6819 ldr r1, [r3, #0] | |
16ec: 6822 ldr r2, [r4, #0] | |
16ee: 4291 cmp r1, r2 | |
16f0: d001 beq.n 16f6 <handle_statfs.isra.19+0xbe> | |
16f2: f7ff ecaa blx 1048 <__stack_chk_fail@plt> | |
16f6: b02e add sp, #184 ; 0xb8 | |
16f8: f50d 5d80 add.w sp, sp, #4096 ; 0x1000 | |
16fc: e8bd 82f0 ldmia.w sp!, {r4, r5, r6, r7, r9, pc} | |
1700: 00003874 .word 0x00003874 | |
1704: fffffff4 .word 0xfffffff4 | |
00001708 <handle_readdir.isra.21>: | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler, | |
1708: 4b3b ldr r3, [pc, #236] ; (17f8 <handle_readdir.isra.21+0xf0>) | |
170a: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
170e: 4690 mov r8, r2 | |
1710: 4a3a ldr r2, [pc, #232] ; (17fc <handle_readdir.isra.21+0xf4>) | |
1712: 460f mov r7, r1 | |
1714: 447b add r3, pc | |
1716: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000 | |
171a: b087 sub sp, #28 | |
171c: 4605 mov r5, r0 | |
171e: 5899 ldr r1, [r3, r2] | |
1720: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
1724: 3014 adds r0, #20 | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
1726: f8d8 a000 ldr.w sl, [r8] | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler, | |
172a: 680b ldr r3, [r1, #0] | |
172c: 468b mov fp, r1 | |
172e: 6003 str r3, [r0, #0] | |
struct dirent *de; | |
struct dirhandle *h = id_to_ptr(req->fh); | |
struct node* parent_node; | |
TRACE("[%d] READDIR %p\n", handler->token, h); | |
if (req->offset == 0) { | |
1730: e9d8 2302 ldrd r2, r3, [r8, #8] | |
1734: ea52 0003 orrs.w r0, r2, r3 | |
1738: d103 bne.n 1742 <handle_readdir.isra.21+0x3a> | |
/* rewinddir() might have been called above us, so rewind here too */ | |
TRACE("[%d] calling rewinddir()\n", handler->token); | |
rewinddir(h->d); | |
173a: f8da 0000 ldr.w r0, [sl] | |
173e: f7ff ec8a blx 1054 <rewinddir@plt> | |
skip: | |
de = readdir(h->d); | |
if (!de) { | |
return 0; | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
1742: ac05 add r4, sp, #20 | |
/* rewinddir() might have been called above us, so rewind here too */ | |
TRACE("[%d] calling rewinddir()\n", handler->token); | |
rewinddir(h->d); | |
} | |
skip: | |
de = readdir(h->d); | |
1744: f8da 0000 ldr.w r0, [sl] | |
1748: f7ff ec8a blx 1060 <readdir@plt> | |
if (!de) { | |
174c: 2800 cmp r0, #0 | |
174e: d03e beq.n 17ce <handle_readdir.isra.21+0xc6> | |
return 0; | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */ | |
fde->off = req->offset + 1; | |
1750: eddf 0b27 vldr d16, [pc, #156] ; 17f0 <handle_readdir.isra.21+0xe8> | |
skip: | |
de = readdir(h->d); | |
if (!de) { | |
return 0; | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
1754: 2100 movs r1, #0 | |
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */ | |
fde->off = req->offset + 1; | |
1756: edd8 1b02 vldr d17, [r8, #8] | |
skip: | |
de = readdir(h->d); | |
if (!de) { | |
return 0; | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
175a: f04f 36ff mov.w r6, #4294967295 ; 0xffffffff | |
175e: 6026 str r6, [r4, #0] | |
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */ | |
fde->off = req->offset + 1; | |
fde->type = de->d_type; | |
fde->namelen = strlen(de->d_name); | |
1760: f100 0913 add.w r9, r0, #19 | |
skip: | |
de = readdir(h->d); | |
if (!de) { | |
return 0; | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
1764: 6061 str r1, [r4, #4] | |
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */ | |
fde->off = req->offset + 1; | |
1766: ef31 08a0 vadd.i64 d0, d17, d16 | |
176a: ec53 2b10 vmov r2, r3, d0 | |
176e: ed84 0a02 vstr s0, [r4, #8] | |
1772: 60e3 str r3, [r4, #12] | |
fde->type = de->d_type; | |
1774: 7c83 ldrb r3, [r0, #18] | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
1776: 4648 mov r0, r9 | |
1778: 6163 str r3, [r4, #20] | |
177a: 9103 str r1, [sp, #12] | |
177c: f7ff ec16 blx fac <strlen@plt> | |
fde->namelen = strlen(de->d_name); | |
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
1780: e9d7 2304 ldrd r2, r3, [r7, #16] | |
1784: 4606 mov r6, r0 | |
} | |
fde->ino = FUSE_UNKNOWN_INO; | |
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */ | |
fde->off = req->offset + 1; | |
fde->type = de->d_type; | |
fde->namelen = strlen(de->d_name); | |
1786: 6120 str r0, [r4, #16] | |
1788: 9803 ldr r0, [sp, #12] | |
return 0; | |
} | |
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid) | |
{ | |
if (nid == FUSE_ROOT_ID) { | |
178a: 2b00 cmp r3, #0 | |
178c: bf08 it eq | |
178e: 2a01 cmpeq r2, #1 | |
fde->type = de->d_type; | |
fde->namelen = strlen(de->d_name); | |
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) { | |
1790: 464b mov r3, r9 | |
} | |
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid) | |
{ | |
if (nid == FUSE_ROOT_ID) { | |
return &fuse->root; | |
1792: bf08 it eq | |
1794: f105 0220 addeq.w r2, r5, #32 | |
fde->type = de->d_type; | |
fde->namelen = strlen(de->d_name); | |
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) { | |
1798: 2104 movs r1, #4 | |
179a: 9100 str r1, [sp, #0] | |
179c: 4639 mov r1, r7 | |
179e: 9001 str r0, [sp, #4] | |
17a0: 4628 mov r0, r5 | |
17a2: f7ff fe89 bl 14b8 <check_caller_access_to_name> | |
17a6: 2800 cmp r0, #0 | |
17a8: d0cc beq.n 1744 <handle_readdir.isra.21+0x3c> | |
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { | |
__memcpy_src_size_error(); | |
} | |
return __builtin___memcpy_chk(dest, src, copy_amount, d_len); | |
17aa: 1c72 adds r2, r6, #1 | |
goto skip; | |
} | |
memcpy(fde->name, de->d_name, fde->namelen + 1); | |
fuse_reply(fuse, hdr->unique, fde, | |
FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen)); | |
17ac: 361f adds r6, #31 | |
17ae: 4649 mov r1, r9 | |
17b0: f641 73e8 movw r3, #8168 ; 0x1fe8 | |
17b4: a80b add r0, sp, #44 ; 0x2c | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) { | |
goto skip; | |
} | |
memcpy(fde->name, de->d_name, fde->namelen + 1); | |
fuse_reply(fuse, hdr->unique, fde, | |
17b6: f026 0607 bic.w r6, r6, #7 | |
17ba: f7ff ec58 blx 106c <__memcpy_chk@plt> | |
17be: e9d7 2302 ldrd r2, r3, [r7, #8] | |
17c2: 4628 mov r0, r5 | |
17c4: 9400 str r4, [sp, #0] | |
17c6: 9601 str r6, [sp, #4] | |
17c8: f7ff feae bl 1528 <fuse_reply> | |
FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen)); | |
return NO_STATUS; | |
17cc: 2001 movs r0, #1 | |
} | |
17ce: f50d 5200 add.w r2, sp, #8192 ; 0x2000 | |
17d2: 3214 adds r2, #20 | |
17d4: 6811 ldr r1, [r2, #0] | |
17d6: f8db 3000 ldr.w r3, [fp] | |
17da: 4299 cmp r1, r3 | |
17dc: d001 beq.n 17e2 <handle_readdir.isra.21+0xda> | |
17de: f7ff ec34 blx 1048 <__stack_chk_fail@plt> | |
17e2: b007 add sp, #28 | |
17e4: f50d 5d00 add.w sp, sp, #8192 ; 0x2000 | |
17e8: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
17ec: f3af 8000 nop.w | |
17f0: 00000001 .word 0x00000001 | |
17f4: 00000000 .word 0x00000000 | |
17f8: 000037a4 .word 0x000037a4 | |
17fc: fffffff4 .word 0xfffffff4 | |
00001800 <touch.constprop.26>: | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
} | |
static int touch(char* path, mode_t mode) { | |
1800: b570 push {r4, r5, r6, lr} | |
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) { | |
return __open_2(pathname, flags); | |
} | |
return __open_real(pathname, flags, __builtin_va_arg_pack()); | |
1802: f248 01c2 movw r1, #32962 ; 0x80c2 | |
1806: 4d10 ldr r5, [pc, #64] ; (1848 <touch.constprop.26+0x48>) | |
1808: f44f 72da mov.w r2, #436 ; 0x1b4 | |
180c: 4606 mov r6, r0 | |
180e: f7ff ec34 blx 1078 <open@plt> | |
int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode); | |
if (fd == -1) { | |
1812: 1c41 adds r1, r0, #1 | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
} | |
static int touch(char* path, mode_t mode) { | |
1814: 447d add r5, pc | |
1816: 4604 mov r4, r0 | |
int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode); | |
if (fd == -1) { | |
1818: d112 bne.n 1840 <touch.constprop.26+0x40> | |
if (errno == EEXIST) { | |
181a: f7ff ebec blx ff4 <__errno@plt> | |
181e: 6803 ldr r3, [r0, #0] | |
1820: 2b11 cmp r3, #17 | |
1822: d00f beq.n 1844 <touch.constprop.26+0x44> | |
return 0; | |
} else { | |
ERROR("Failed to open(%s): %s\n", path, strerror(errno)); | |
1824: 6800 ldr r0, [r0, #0] | |
1826: f7ff ec2e blx 1084 <strerror@plt> | |
182a: 4a08 ldr r2, [pc, #32] ; (184c <touch.constprop.26+0x4c>) | |
182c: 4603 mov r3, r0 | |
182e: 4908 ldr r1, [pc, #32] ; (1850 <touch.constprop.26+0x50>) | |
1830: 58a8 ldr r0, [r5, r2] | |
1832: 4632 mov r2, r6 | |
1834: 4479 add r1, pc | |
1836: 30a8 adds r0, #168 ; 0xa8 | |
1838: f7ff ebac blx f94 <fprintf@plt> | |
return -1; | |
183c: 4620 mov r0, r4 | |
183e: bd70 pop {r4, r5, r6, pc} | |
} | |
} | |
close(fd); | |
1840: f7ff ec26 blx 1090 <close@plt> | |
return 0; | |
1844: 2000 movs r0, #0 | |
} | |
1846: bd70 pop {r4, r5, r6, pc} | |
1848: 000036a4 .word 0x000036a4 | |
184c: fffffff0 .word 0xfffffff0 | |
1850: 00001e8d .word 0x00001e8d | |
00001854 <find_file_within.constprop.27>: | |
* the buffer to the path that the file would have, assuming the name were case-sensitive. | |
* | |
* Populates 'buf' with the path and returns the actual name (within 'buf') on success, | |
* or returns NULL if the path is too long for the provided buffer. | |
*/ | |
static char* find_file_within(const char* path, const char* name, | |
1854: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
1858: 460e mov r6, r1 | |
185a: 469b mov fp, r3 | |
185c: 4615 mov r5, r2 | |
185e: 4680 mov r8, r0 | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
1860: f7ff eba4 blx fac <strlen@plt> | |
1864: 4681 mov r9, r0 | |
1866: 4630 mov r0, r6 | |
char* buf, size_t bufsize, int search) | |
{ | |
size_t pathlen = strlen(path); | |
size_t namelen = strlen(name); | |
size_t childlen = pathlen + namelen + 1; | |
1868: f109 0401 add.w r4, r9, #1 | |
* the buffer to the path that the file would have, assuming the name were case-sensitive. | |
* | |
* Populates 'buf' with the path and returns the actual name (within 'buf') on success, | |
* or returns NULL if the path is too long for the provided buffer. | |
*/ | |
static char* find_file_within(const char* path, const char* name, | |
186c: f8df a09c ldr.w sl, [pc, #156] ; 190c <find_file_within.constprop.27+0xb8> | |
1870: f7ff eb9c blx fac <strlen@plt> | |
char* buf, size_t bufsize, int search) | |
{ | |
size_t pathlen = strlen(path); | |
size_t namelen = strlen(name); | |
size_t childlen = pathlen + namelen + 1; | |
1874: 1823 adds r3, r4, r0 | |
1876: 4607 mov r7, r0 | |
char* actual; | |
if (bufsize <= childlen) { | |
1878: f5b3 5f80 cmp.w r3, #4096 ; 0x1000 | |
* the buffer to the path that the file would have, assuming the name were case-sensitive. | |
* | |
* Populates 'buf' with the path and returns the actual name (within 'buf') on success, | |
* or returns NULL if the path is too long for the provided buffer. | |
*/ | |
static char* find_file_within(const char* path, const char* name, | |
187c: 44fa add sl, pc | |
size_t pathlen = strlen(path); | |
size_t namelen = strlen(name); | |
size_t childlen = pathlen + namelen + 1; | |
char* actual; | |
if (bufsize <= childlen) { | |
187e: d240 bcs.n 1902 <find_file_within.constprop.27+0xae> | |
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { | |
__memcpy_src_size_error(); | |
} | |
return __builtin___memcpy_chk(dest, src, copy_amount, d_len); | |
1880: 4641 mov r1, r8 | |
1882: 464a mov r2, r9 | |
1884: 4628 mov r0, r5 | |
return NULL; | |
} | |
memcpy(buf, path, pathlen); | |
buf[pathlen] = '/'; | |
actual = buf + pathlen + 1; | |
1886: 192c adds r4, r5, r4 | |
1888: f7ff eb9c blx fc4 <memcpy@plt> | |
if (bufsize <= childlen) { | |
return NULL; | |
} | |
memcpy(buf, path, pathlen); | |
buf[pathlen] = '/'; | |
188c: 202f movs r0, #47 ; 0x2f | |
188e: 4631 mov r1, r6 | |
1890: f805 0009 strb.w r0, [r5, r9] | |
1894: 1c7a adds r2, r7, #1 | |
1896: 4620 mov r0, r4 | |
1898: f7ff eb94 blx fc4 <memcpy@plt> | |
actual = buf + pathlen + 1; | |
memcpy(actual, name, namelen + 1); | |
if (search && access(buf, F_OK)) { | |
189c: f1bb 0f00 cmp.w fp, #0 | |
18a0: d030 beq.n 1904 <find_file_within.constprop.27+0xb0> | |
18a2: 4628 mov r0, r5 | |
18a4: 2100 movs r1, #0 | |
18a6: f7ff ebfa blx 109c <access@plt> | |
18aa: b358 cbz r0, 1904 <find_file_within.constprop.27+0xb0> | |
struct dirent* entry; | |
DIR* dir = opendir(path); | |
18ac: 4640 mov r0, r8 | |
18ae: f7ff ebfc blx 10a8 <opendir@plt> | |
if (!dir) { | |
18b2: 4605 mov r5, r0 | |
18b4: b9e0 cbnz r0, 18f0 <find_file_within.constprop.27+0x9c> | |
ERROR("opendir %s failed: %s\n", path, strerror(errno)); | |
18b6: f7ff eb9e blx ff4 <__errno@plt> | |
18ba: 6800 ldr r0, [r0, #0] | |
18bc: f7ff ebe2 blx 1084 <strerror@plt> | |
18c0: 4a13 ldr r2, [pc, #76] ; (1910 <find_file_within.constprop.27+0xbc>) | |
18c2: 4603 mov r3, r0 | |
18c4: 4913 ldr r1, [pc, #76] ; (1914 <find_file_within.constprop.27+0xc0>) | |
18c6: f85a 0002 ldr.w r0, [sl, r2] | |
18ca: 4642 mov r2, r8 | |
18cc: 4479 add r1, pc | |
18ce: 30a8 adds r0, #168 ; 0xa8 | |
18d0: f7ff eb60 blx f94 <fprintf@plt> | |
18d4: e016 b.n 1904 <find_file_within.constprop.27+0xb0> | |
return actual; | |
} | |
while ((entry = readdir(dir))) { | |
if (!strcasecmp(entry->d_name, name)) { | |
18d6: f100 0813 add.w r8, r0, #19 | |
18da: 4631 mov r1, r6 | |
18dc: 4640 mov r0, r8 | |
18de: f7ff eb60 blx fa0 <strcasecmp@plt> | |
18e2: b928 cbnz r0, 18f0 <find_file_within.constprop.27+0x9c> | |
18e4: 4620 mov r0, r4 | |
18e6: 4641 mov r1, r8 | |
18e8: 463a mov r2, r7 | |
18ea: f7ff eb6c blx fc4 <memcpy@plt> | |
18ee: e004 b.n 18fa <find_file_within.constprop.27+0xa6> | |
DIR* dir = opendir(path); | |
if (!dir) { | |
ERROR("opendir %s failed: %s\n", path, strerror(errno)); | |
return actual; | |
} | |
while ((entry = readdir(dir))) { | |
18f0: 4628 mov r0, r5 | |
18f2: f7ff ebb6 blx 1060 <readdir@plt> | |
18f6: 2800 cmp r0, #0 | |
18f8: d1ed bne.n 18d6 <find_file_within.constprop.27+0x82> | |
/* we have a match - replace the name, don't need to copy the null again */ | |
memcpy(actual, entry->d_name, namelen); | |
break; | |
} | |
} | |
closedir(dir); | |
18fa: 4628 mov r0, r5 | |
18fc: f7ff ebda blx 10b4 <closedir@plt> | |
1900: e000 b.n 1904 <find_file_within.constprop.27+0xb0> | |
size_t namelen = strlen(name); | |
size_t childlen = pathlen + namelen + 1; | |
char* actual; | |
if (bufsize <= childlen) { | |
return NULL; | |
1902: 2400 movs r4, #0 | |
} | |
} | |
closedir(dir); | |
} | |
return actual; | |
} | |
1904: 4620 mov r0, r4 | |
1906: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
190a: bf00 nop | |
190c: 0000363c .word 0x0000363c | |
1910: fffffff0 .word 0xfffffff0 | |
1914: 00001e0d .word 0x00001e0d | |
00001918 <lookup_node_and_path_by_id_locked.constprop.28>: | |
return 0; | |
} | |
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid) | |
{ | |
if (nid == FUSE_ROOT_ID) { | |
1918: 2b00 cmp r3, #0 | |
191a: bf08 it eq | |
191c: 2a01 cmpeq r2, #1 | |
} else { | |
return id_to_ptr(nid); | |
} | |
} | |
static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid, | |
191e: b510 push {r4, lr} | |
} | |
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid) | |
{ | |
if (nid == FUSE_ROOT_ID) { | |
return &fuse->root; | |
1920: bf0c ite eq | |
1922: f100 0420 addeq.w r4, r0, #32 | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
1926: 4614 movne r4, r2 | |
static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid, | |
char* buf, size_t bufsize) | |
{ | |
struct node* node = lookup_node_by_id_locked(fuse, nid); | |
if (node && get_node_path_locked(node, buf, bufsize) < 0) { | |
1928: b13c cbz r4, 193a <lookup_node_and_path_by_id_locked.constprop.28+0x22> | |
192a: 4620 mov r0, r4 | |
192c: 9902 ldr r1, [sp, #8] | |
192e: f44f 5280 mov.w r2, #4096 ; 0x1000 | |
1932: f7ff fd81 bl 1438 <get_node_path_locked> | |
node = NULL; | |
1936: ea24 74e0 bic.w r4, r4, r0, asr #31 | |
} | |
return node; | |
} | |
193a: 4620 mov r0, r4 | |
193c: bd10 pop {r4, pc} | |
... | |
00001940 <handle_rmdir.isra.16>: | |
return -errno; | |
} | |
return 0; | |
} | |
static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler, | |
1940: 4b2e ldr r3, [pc, #184] ; (19fc <handle_rmdir.isra.16+0xbc>) | |
1942: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} | |
1946: 4616 mov r6, r2 | |
1948: 4a2d ldr r2, [pc, #180] ; (1a00 <handle_rmdir.isra.16+0xc0>) | |
194a: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000 | |
194e: 447b add r3, pc | |
1950: b084 sub sp, #16 | |
1952: 460d mov r5, r1 | |
1954: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
1958: f853 8002 ldr.w r8, [r3, r2] | |
195c: 4604 mov r4, r0 | |
195e: 310c adds r1, #12 | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
parent_path, sizeof(parent_path)); | |
1960: f10d 0a0c add.w sl, sp, #12 | |
return -errno; | |
} | |
return 0; | |
} | |
static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler, | |
1964: f8d8 3000 ldr.w r3, [r8] | |
1968: 600b str r3, [r1, #0] | |
bool has_rw; | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
196a: f7ff eb5c blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
196e: 4629 mov r1, r5 | |
1970: 4620 mov r0, r4 | |
1972: f7ff fe50 bl 1616 <get_caller_has_rw_locked> | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
1976: e9d5 2304 ldrd r2, r3, [r5, #16] | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
197a: 4681 mov r9, r0 | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
197c: f8cd a000 str.w sl, [sp] | |
1980: 4620 mov r0, r4 | |
1982: f7ff ffc9 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1986: 4607 mov r7, r0 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] RMDIR %s @ %llx (%s)\n", handler->token, | |
name, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1988: 4620 mov r0, r4 | |
198a: f7ff eb52 blx 1030 <pthread_mutex_unlock@plt> | |
if (!parent_node || !find_file_within(parent_path, name, | |
198e: b917 cbnz r7, 1996 <handle_rmdir.isra.16+0x56> | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
1990: f06f 0001 mvn.w r0, #1 | |
1994: e023 b.n 19de <handle_rmdir.isra.16+0x9e> | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] RMDIR %s @ %llx (%s)\n", handler->token, | |
name, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !find_file_within(parent_path, name, | |
1996: f50d 5280 add.w r2, sp, #4096 ; 0x1000 | |
199a: 4650 mov r0, sl | |
199c: 4631 mov r1, r6 | |
199e: 320c adds r2, #12 | |
19a0: 2301 movs r3, #1 | |
19a2: f7ff ff57 bl 1854 <find_file_within.constprop.27> | |
19a6: 2800 cmp r0, #0 | |
19a8: d0f2 beq.n 1990 <handle_rmdir.isra.16+0x50> | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
19aa: 2302 movs r3, #2 | |
19ac: 4620 mov r0, r4 | |
19ae: e88d 0208 stmia.w sp, {r3, r9} | |
19b2: 4629 mov r1, r5 | |
19b4: 463a mov r2, r7 | |
19b6: 4633 mov r3, r6 | |
19b8: f7ff fd7e bl 14b8 <check_caller_access_to_name> | |
19bc: b158 cbz r0, 19d6 <handle_rmdir.isra.16+0x96> | |
return -EACCES; | |
} | |
if (rmdir(child_path) < 0) { | |
19be: f50d 5080 add.w r0, sp, #4096 ; 0x1000 | |
19c2: 300c adds r0, #12 | |
19c4: f7ff eb7c blx 10c0 <rmdir@plt> | |
19c8: 2800 cmp r0, #0 | |
19ca: da07 bge.n 19dc <handle_rmdir.isra.16+0x9c> | |
return -errno; | |
19cc: f7ff eb12 blx ff4 <__errno@plt> | |
19d0: 6800 ldr r0, [r0, #0] | |
19d2: 4240 negs r0, r0 | |
19d4: e003 b.n 19de <handle_rmdir.isra.16+0x9e> | |
if (!parent_node || !find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
return -EACCES; | |
19d6: f06f 000c mvn.w r0, #12 | |
19da: e000 b.n 19de <handle_rmdir.isra.16+0x9e> | |
} | |
if (rmdir(child_path) < 0) { | |
return -errno; | |
} | |
return 0; | |
19dc: 2000 movs r0, #0 | |
} | |
19de: f50d 5200 add.w r2, sp, #8192 ; 0x2000 | |
19e2: 320c adds r2, #12 | |
19e4: 6811 ldr r1, [r2, #0] | |
19e6: f8d8 3000 ldr.w r3, [r8] | |
19ea: 4299 cmp r1, r3 | |
19ec: d001 beq.n 19f2 <handle_rmdir.isra.16+0xb2> | |
19ee: f7ff eb2c blx 1048 <__stack_chk_fail@plt> | |
19f2: b004 add sp, #16 | |
19f4: f50d 5d00 add.w sp, sp, #8192 ; 0x2000 | |
19f8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} | |
19fc: 0000356a .word 0x0000356a | |
1a00: fffffff4 .word 0xfffffff4 | |
00001a04 <handle_unlink.isra.15>: | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler, | |
1a04: 4b2e ldr r3, [pc, #184] ; (1ac0 <handle_unlink.isra.15+0xbc>) | |
1a06: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} | |
1a0a: 4616 mov r6, r2 | |
1a0c: 4a2d ldr r2, [pc, #180] ; (1ac4 <handle_unlink.isra.15+0xc0>) | |
1a0e: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000 | |
1a12: 447b add r3, pc | |
1a14: b084 sub sp, #16 | |
1a16: 460d mov r5, r1 | |
1a18: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
1a1c: f853 8002 ldr.w r8, [r3, r2] | |
1a20: 4604 mov r4, r0 | |
1a22: 310c adds r1, #12 | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
parent_path, sizeof(parent_path)); | |
1a24: f10d 0a0c add.w sl, sp, #12 | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler, | |
1a28: f8d8 3000 ldr.w r3, [r8] | |
1a2c: 600b str r3, [r1, #0] | |
bool has_rw; | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
1a2e: f7ff eafa blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1a32: 4629 mov r1, r5 | |
1a34: 4620 mov r0, r4 | |
1a36: f7ff fdee bl 1616 <get_caller_has_rw_locked> | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
1a3a: e9d5 2304 ldrd r2, r3, [r5, #16] | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1a3e: 4681 mov r9, r0 | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
1a40: f8cd a000 str.w sl, [sp] | |
1a44: 4620 mov r0, r4 | |
1a46: f7ff ff67 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1a4a: 4607 mov r7, r0 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] UNLINK %s @ %llx (%s)\n", handler->token, | |
name, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1a4c: 4620 mov r0, r4 | |
1a4e: f7ff eaf0 blx 1030 <pthread_mutex_unlock@plt> | |
if (!parent_node || !find_file_within(parent_path, name, | |
1a52: b917 cbnz r7, 1a5a <handle_unlink.isra.15+0x56> | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
1a54: f06f 0001 mvn.w r0, #1 | |
1a58: e023 b.n 1aa2 <handle_unlink.isra.15+0x9e> | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] UNLINK %s @ %llx (%s)\n", handler->token, | |
name, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !find_file_within(parent_path, name, | |
1a5a: f50d 5280 add.w r2, sp, #4096 ; 0x1000 | |
1a5e: 4650 mov r0, sl | |
1a60: 4631 mov r1, r6 | |
1a62: 320c adds r2, #12 | |
1a64: 2301 movs r3, #1 | |
1a66: f7ff fef5 bl 1854 <find_file_within.constprop.27> | |
1a6a: 2800 cmp r0, #0 | |
1a6c: d0f2 beq.n 1a54 <handle_unlink.isra.15+0x50> | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
1a6e: 2302 movs r3, #2 | |
1a70: 4620 mov r0, r4 | |
1a72: e88d 0208 stmia.w sp, {r3, r9} | |
1a76: 4629 mov r1, r5 | |
1a78: 463a mov r2, r7 | |
1a7a: 4633 mov r3, r6 | |
1a7c: f7ff fd1c bl 14b8 <check_caller_access_to_name> | |
1a80: b158 cbz r0, 1a9a <handle_unlink.isra.15+0x96> | |
return -EACCES; | |
} | |
if (unlink(child_path) < 0) { | |
1a82: f50d 5080 add.w r0, sp, #4096 ; 0x1000 | |
1a86: 300c adds r0, #12 | |
1a88: f7ff eb20 blx 10cc <unlink@plt> | |
1a8c: 2800 cmp r0, #0 | |
1a8e: da07 bge.n 1aa0 <handle_unlink.isra.15+0x9c> | |
return -errno; | |
1a90: f7ff eab0 blx ff4 <__errno@plt> | |
1a94: 6800 ldr r0, [r0, #0] | |
1a96: 4240 negs r0, r0 | |
1a98: e003 b.n 1aa2 <handle_unlink.isra.15+0x9e> | |
if (!parent_node || !find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1)) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
return -EACCES; | |
1a9a: f06f 000c mvn.w r0, #12 | |
1a9e: e000 b.n 1aa2 <handle_unlink.isra.15+0x9e> | |
} | |
if (unlink(child_path) < 0) { | |
return -errno; | |
} | |
return 0; | |
1aa0: 2000 movs r0, #0 | |
} | |
1aa2: f50d 5200 add.w r2, sp, #8192 ; 0x2000 | |
1aa6: 320c adds r2, #12 | |
1aa8: 6811 ldr r1, [r2, #0] | |
1aaa: f8d8 3000 ldr.w r3, [r8] | |
1aae: 4299 cmp r1, r3 | |
1ab0: d001 beq.n 1ab6 <handle_unlink.isra.15+0xb2> | |
1ab2: f7ff eaca blx 1048 <__stack_chk_fail@plt> | |
1ab6: b004 add sp, #16 | |
1ab8: f50d 5d00 add.w sp, sp, #8192 ; 0x2000 | |
1abc: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} | |
1ac0: 000034a6 .word 0x000034a6 | |
1ac4: fffffff4 .word 0xfffffff4 | |
00001ac8 <handle_open.isra.14>: | |
/* Probably O_RDRW, but treat as default to be safe */ | |
return R_OK | W_OK; | |
} | |
} | |
static int handle_open(struct fuse* fuse, struct fuse_handler* handler, | |
1ac8: 4b3c ldr r3, [pc, #240] ; (1bbc <handle_open.isra.14+0xf4>) | |
1aca: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
1ace: 4616 mov r6, r2 | |
1ad0: 4a3b ldr r2, [pc, #236] ; (1bc0 <handle_open.isra.14+0xf8>) | |
1ad2: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020 | |
1ad6: 447b add r3, pc | |
1ad8: b081 sub sp, #4 | |
1ada: 460d mov r5, r1 | |
1adc: f50d 5180 add.w r1, sp, #4096 ; 0x1000 | |
1ae0: 589f ldr r7, [r3, r2] | |
1ae2: 4604 mov r4, r0 | |
1ae4: 311c adds r1, #28 | |
struct fuse_open_out out; | |
struct handle *h; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1ae6: f10d 091c add.w r9, sp, #28 | |
/* Probably O_RDRW, but treat as default to be safe */ | |
return R_OK | W_OK; | |
} | |
} | |
static int handle_open(struct fuse* fuse, struct fuse_handler* handler, | |
1aea: 683b ldr r3, [r7, #0] | |
1aec: 46b8 mov r8, r7 | |
1aee: 600b str r3, [r1, #0] | |
struct node* node; | |
char path[PATH_MAX]; | |
struct fuse_open_out out; | |
struct handle *h; | |
pthread_mutex_lock(&fuse->lock); | |
1af0: f7ff ea98 blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1af4: 4629 mov r1, r5 | |
1af6: 4620 mov r0, r4 | |
1af8: f7ff fd8d bl 1616 <get_caller_has_rw_locked> | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1afc: e9d5 2304 ldrd r2, r3, [r5, #16] | |
char path[PATH_MAX]; | |
struct fuse_open_out out; | |
struct handle *h; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1b00: 4682 mov sl, r0 | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1b02: f8cd 9000 str.w r9, [sp] | |
1b06: 4620 mov r0, r4 | |
1b08: f7ff ff06 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1b0c: 4683 mov fp, r0 | |
TRACE("[%d] OPEN 0%o @ %llx (%s)\n", handler->token, | |
req->flags, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1b0e: 4620 mov r0, r4 | |
1b10: f7ff ea8e blx 1030 <pthread_mutex_unlock@plt> | |
if (!node) { | |
1b14: f1bb 0f00 cmp.w fp, #0 | |
1b18: d038 beq.n 1b8c <handle_open.isra.14+0xc4> | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, | |
open_flags_to_access_mode(req->flags), has_rw)) { | |
1b1a: 6837 ldr r7, [r6, #0] | |
pthread_mutex_unlock(&fuse->lock); | |
return res; | |
} | |
static int open_flags_to_access_mode(int open_flags) { | |
if ((open_flags & O_ACCMODE) == O_RDONLY) { | |
1b1c: f017 0003 ands.w r0, r7, #3 | |
1b20: d004 beq.n 1b2c <handle_open.isra.14+0x64> | |
return R_OK; | |
} else if ((open_flags & O_ACCMODE) == O_WRONLY) { | |
return W_OK; | |
1b22: 2801 cmp r0, #1 | |
1b24: bf14 ite ne | |
1b26: 2306 movne r3, #6 | |
1b28: 2302 moveq r3, #2 | |
1b2a: e000 b.n 1b2e <handle_open.isra.14+0x66> | |
return res; | |
} | |
static int open_flags_to_access_mode(int open_flags) { | |
if ((open_flags & O_ACCMODE) == O_RDONLY) { | |
return R_OK; | |
1b2c: 2304 movs r3, #4 | |
return true; | |
} | |
static bool check_caller_access_to_node(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) { | |
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw); | |
1b2e: e88d 0408 stmia.w sp, {r3, sl} | |
1b32: 4620 mov r0, r4 | |
1b34: 4629 mov r1, r5 | |
1b36: f8db 2034 ldr.w r2, [fp, #52] ; 0x34 | |
1b3a: f8db 303c ldr.w r3, [fp, #60] ; 0x3c | |
1b3e: f7ff fcbb bl 14b8 <check_caller_access_to_name> | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, | |
1b42: b330 cbz r0, 1b92 <handle_open.isra.14+0xca> | |
open_flags_to_access_mode(req->flags), has_rw)) { | |
return -EACCES; | |
} | |
h = malloc(sizeof(*h)); | |
1b44: 2004 movs r0, #4 | |
1b46: f7ff eac8 blx 10d8 <malloc@plt> | |
if (!h) { | |
1b4a: 4606 mov r6, r0 | |
1b4c: b320 cbz r0, 1b98 <handle_open.isra.14+0xd0> | |
if (__builtin_va_arg_pack_len() > 1) { | |
__creat_too_many_args(); // compile time error | |
} | |
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) { | |
return __open_2(pathname, flags); | |
1b4e: 4648 mov r0, r9 | |
1b50: 4639 mov r1, r7 | |
1b52: f7ff eac8 blx 10e4 <__open_2@plt> | |
return -ENOMEM; | |
} | |
TRACE("[%d] OPEN %s\n", handler->token, path); | |
h->fd = open(path, req->flags); | |
if (h->fd < 0) { | |
1b56: 2800 cmp r0, #0 | |
h = malloc(sizeof(*h)); | |
if (!h) { | |
return -ENOMEM; | |
} | |
TRACE("[%d] OPEN %s\n", handler->token, path); | |
h->fd = open(path, req->flags); | |
1b58: 6030 str r0, [r6, #0] | |
if (h->fd < 0) { | |
1b5a: da07 bge.n 1b6c <handle_open.isra.14+0xa4> | |
free(h); | |
1b5c: 4630 mov r0, r6 | |
1b5e: f7ff ea3e blx fdc <free@plt> | |
return -errno; | |
1b62: f7ff ea48 blx ff4 <__errno@plt> | |
1b66: 6803 ldr r3, [r0, #0] | |
1b68: 4258 negs r0, r3 | |
1b6a: e017 b.n 1b9c <handle_open.isra.14+0xd4> | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
1b6c: 2200 movs r2, #0 | |
h->fd = open(path, req->flags); | |
if (h->fd < 0) { | |
free(h); | |
return -errno; | |
} | |
out.fh = ptr_to_id(h); | |
1b6e: a902 add r1, sp, #8 | |
out.open_flags = 0; | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
1b70: 2010 movs r0, #16 | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
1b72: 9203 str r2, [sp, #12] | |
if (h->fd < 0) { | |
free(h); | |
return -errno; | |
} | |
out.fh = ptr_to_id(h); | |
out.open_flags = 0; | |
1b74: 9204 str r2, [sp, #16] | |
out.padding = 0; | |
1b76: 9205 str r2, [sp, #20] | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
1b78: 9001 str r0, [sp, #4] | |
1b7a: 4620 mov r0, r4 | |
1b7c: e9d5 2302 ldrd r2, r3, [r5, #8] | |
1b80: 9100 str r1, [sp, #0] | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
1b82: 9602 str r6, [sp, #8] | |
return -errno; | |
} | |
out.fh = ptr_to_id(h); | |
out.open_flags = 0; | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
1b84: f7ff fcd0 bl 1528 <fuse_reply> | |
return NO_STATUS; | |
1b88: 2001 movs r0, #1 | |
1b8a: e007 b.n 1b9c <handle_open.isra.14+0xd4> | |
TRACE("[%d] OPEN 0%o @ %llx (%s)\n", handler->token, | |
req->flags, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
1b8c: f06f 0001 mvn.w r0, #1 | |
1b90: e004 b.n 1b9c <handle_open.isra.14+0xd4> | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, | |
open_flags_to_access_mode(req->flags), has_rw)) { | |
return -EACCES; | |
1b92: f06f 000c mvn.w r0, #12 | |
1b96: e001 b.n 1b9c <handle_open.isra.14+0xd4> | |
} | |
h = malloc(sizeof(*h)); | |
if (!h) { | |
return -ENOMEM; | |
1b98: f06f 000b mvn.w r0, #11 | |
out.fh = ptr_to_id(h); | |
out.open_flags = 0; | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
1b9c: f50d 5180 add.w r1, sp, #4096 ; 0x1000 | |
1ba0: 311c adds r1, #28 | |
1ba2: 680a ldr r2, [r1, #0] | |
1ba4: f8d8 3000 ldr.w r3, [r8] | |
1ba8: 429a cmp r2, r3 | |
1baa: d001 beq.n 1bb0 <handle_open.isra.14+0xe8> | |
1bac: f7ff ea4c blx 1048 <__stack_chk_fail@plt> | |
1bb0: b009 add sp, #36 ; 0x24 | |
1bb2: f50d 5d80 add.w sp, sp, #4096 ; 0x1000 | |
1bb6: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
1bba: bf00 nop | |
1bbc: 000033e2 .word 0x000033e2 | |
1bc0: fffffff4 .word 0xfffffff4 | |
00001bc4 <handle_opendir.isra.10>: | |
{ | |
TRACE("[%d] FLUSH\n", handler->token); | |
return 0; | |
} | |
static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler, | |
1bc4: 4b32 ldr r3, [pc, #200] ; (1c90 <handle_opendir.isra.10+0xcc>) | |
1bc6: 4a33 ldr r2, [pc, #204] ; (1c94 <handle_opendir.isra.10+0xd0>) | |
1bc8: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} | |
1bcc: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020 | |
1bd0: 447b add r3, pc | |
1bd2: 460f mov r7, r1 | |
1bd4: f50d 5180 add.w r1, sp, #4096 ; 0x1000 | |
1bd8: 4604 mov r4, r0 | |
1bda: 589d ldr r5, [r3, r2] | |
1bdc: 311c adds r1, #28 | |
char path[PATH_MAX]; | |
struct fuse_open_out out; | |
struct dirhandle *h; | |
pthread_mutex_lock(&fuse->lock); | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1bde: f10d 091c add.w r9, sp, #28 | |
{ | |
TRACE("[%d] FLUSH\n", handler->token); | |
return 0; | |
} | |
static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler, | |
1be2: 682b ldr r3, [r5, #0] | |
1be4: 46a8 mov r8, r5 | |
1be6: 600b str r3, [r1, #0] | |
struct node* node; | |
char path[PATH_MAX]; | |
struct fuse_open_out out; | |
struct dirhandle *h; | |
pthread_mutex_lock(&fuse->lock); | |
1be8: f7ff ea1c blx 1024 <pthread_mutex_lock@plt> | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1bec: e9d7 2304 ldrd r2, r3, [r7, #16] | |
1bf0: 4620 mov r0, r4 | |
1bf2: f8cd 9000 str.w r9, [sp] | |
1bf6: f7ff fe8f bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1bfa: 4606 mov r6, r0 | |
TRACE("[%d] OPENDIR @ %llx (%s)\n", handler->token, | |
hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1bfc: 4620 mov r0, r4 | |
1bfe: f7ff ea18 blx 1030 <pthread_mutex_unlock@plt> | |
if (!node) { | |
1c02: 2e00 cmp r6, #0 | |
1c04: d02d beq.n 1c62 <handle_opendir.isra.10+0x9e> | |
return true; | |
} | |
static bool check_caller_access_to_node(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) { | |
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw); | |
1c06: f04f 0a04 mov.w sl, #4 | |
1c0a: 2500 movs r5, #0 | |
1c0c: f8cd a000 str.w sl, [sp] | |
1c10: 4620 mov r0, r4 | |
1c12: 9501 str r5, [sp, #4] | |
1c14: 4639 mov r1, r7 | |
1c16: 6b72 ldr r2, [r6, #52] ; 0x34 | |
1c18: 6bf3 ldr r3, [r6, #60] ; 0x3c | |
1c1a: f7ff fc4d bl 14b8 <check_caller_access_to_name> | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) { | |
1c1e: b318 cbz r0, 1c68 <handle_opendir.isra.10+0xa4> | |
return -EACCES; | |
} | |
h = malloc(sizeof(*h)); | |
1c20: 4650 mov r0, sl | |
1c22: f7ff ea5a blx 10d8 <malloc@plt> | |
if (!h) { | |
1c26: 4606 mov r6, r0 | |
1c28: b308 cbz r0, 1c6e <handle_opendir.isra.10+0xaa> | |
return -ENOMEM; | |
} | |
TRACE("[%d] OPENDIR %s\n", handler->token, path); | |
h->d = opendir(path); | |
1c2a: 4648 mov r0, r9 | |
1c2c: f7ff ea3c blx 10a8 <opendir@plt> | |
1c30: 6030 str r0, [r6, #0] | |
if (!h->d) { | |
1c32: b938 cbnz r0, 1c44 <handle_opendir.isra.10+0x80> | |
free(h); | |
1c34: 4630 mov r0, r6 | |
1c36: f7ff e9d2 blx fdc <free@plt> | |
return -errno; | |
1c3a: f7ff e9dc blx ff4 <__errno@plt> | |
1c3e: 6802 ldr r2, [r0, #0] | |
1c40: 4250 negs r0, r2 | |
1c42: e016 b.n 1c72 <handle_opendir.isra.10+0xae> | |
} | |
out.fh = ptr_to_id(h); | |
1c44: a802 add r0, sp, #8 | |
out.open_flags = 0; | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
1c46: 2110 movs r1, #16 | |
1c48: e9d7 2302 ldrd r2, r3, [r7, #8] | |
1c4c: 9000 str r0, [sp, #0] | |
1c4e: 4620 mov r0, r4 | |
1c50: 9101 str r1, [sp, #4] | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
1c52: 9602 str r6, [sp, #8] | |
1c54: 9503 str r5, [sp, #12] | |
if (!h->d) { | |
free(h); | |
return -errno; | |
} | |
out.fh = ptr_to_id(h); | |
out.open_flags = 0; | |
1c56: 9504 str r5, [sp, #16] | |
out.padding = 0; | |
1c58: 9505 str r5, [sp, #20] | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
1c5a: f7ff fc65 bl 1528 <fuse_reply> | |
return NO_STATUS; | |
1c5e: 2001 movs r0, #1 | |
1c60: e007 b.n 1c72 <handle_opendir.isra.10+0xae> | |
TRACE("[%d] OPENDIR @ %llx (%s)\n", handler->token, | |
hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
1c62: f06f 0001 mvn.w r0, #1 | |
1c66: e004 b.n 1c72 <handle_opendir.isra.10+0xae> | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) { | |
return -EACCES; | |
1c68: f06f 000c mvn.w r0, #12 | |
1c6c: e001 b.n 1c72 <handle_opendir.isra.10+0xae> | |
} | |
h = malloc(sizeof(*h)); | |
if (!h) { | |
return -ENOMEM; | |
1c6e: f06f 000b mvn.w r0, #11 | |
out.fh = ptr_to_id(h); | |
out.open_flags = 0; | |
out.padding = 0; | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
1c72: f50d 5380 add.w r3, sp, #4096 ; 0x1000 | |
1c76: 331c adds r3, #28 | |
1c78: 6819 ldr r1, [r3, #0] | |
1c7a: f8d8 2000 ldr.w r2, [r8] | |
1c7e: 4291 cmp r1, r2 | |
1c80: d001 beq.n 1c86 <handle_opendir.isra.10+0xc2> | |
1c82: f7ff e9e2 blx 1048 <__stack_chk_fail@plt> | |
1c86: b008 add sp, #32 | |
1c88: f50d 5d80 add.w sp, sp, #4096 ; 0x1000 | |
1c8c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} | |
1c90: 000032e8 .word 0x000032e8 | |
1c94: fffffff4 .word 0xfffffff4 | |
00001c98 <fuse_reply_attr>: | |
return NO_STATUS; | |
} | |
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node, | |
const char* path) | |
{ | |
1c98: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} | |
1c9c: b0b7 sub sp, #220 ; 0xdc | |
1c9e: 4681 mov r9, r0 | |
struct fuse_attr_out out; | |
struct stat s; | |
if (lstat(path, &s) < 0) { | |
1ca0: a91c add r1, sp, #112 ; 0x70 | |
return NO_STATUS; | |
} | |
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node, | |
const char* path) | |
{ | |
1ca2: 4614 mov r4, r2 | |
1ca4: 461d mov r5, r3 | |
struct fuse_attr_out out; | |
struct stat s; | |
if (lstat(path, &s) < 0) { | |
1ca6: 983f ldr r0, [sp, #252] ; 0xfc | |
return NO_STATUS; | |
} | |
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node, | |
const char* path) | |
{ | |
1ca8: f8dd 80f8 ldr.w r8, [sp, #248] ; 0xf8 | |
struct fuse_attr_out out; | |
struct stat s; | |
if (lstat(path, &s) < 0) { | |
1cac: f7ff ea20 blx 10f0 <lstat@plt> | |
1cb0: 2800 cmp r0, #0 | |
1cb2: da04 bge.n 1cbe <fuse_reply_attr+0x26> | |
return -errno; | |
1cb4: f7ff e99e blx ff4 <__errno@plt> | |
1cb8: 6803 ldr r3, [r0, #0] | |
1cba: 4258 negs r0, r3 | |
1cbc: e047 b.n 1d4e <fuse_reply_attr+0xb6> | |
} | |
memset(&out, 0, sizeof(out)); | |
1cbe: af02 add r7, sp, #8 | |
return __builtin___strncat_chk(dest, src, n, __bos(dest)); | |
} | |
__BIONIC_FORTIFY_INLINE | |
void* memset(void *s, int c, size_t n) { | |
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0)); | |
1cc0: 2668 movs r6, #104 ; 0x68 | |
1cc2: 2100 movs r1, #0 | |
1cc4: 4632 mov r2, r6 | |
1cc6: 4638 mov r0, r7 | |
1cc8: f7ff e99a blx 1000 <memset@plt> | |
return actual; | |
} | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
1ccc: e9d8 2302 ldrd r2, r3, [r8, #8] | |
attr->size = s->st_size; | |
1cd0: e9dd 0128 ldrd r0, r1, [sp, #160] ; 0xa0 | |
return actual; | |
} | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
1cd4: e9cd 2306 strd r2, r3, [sp, #24] | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
1cd8: e9dd 232c ldrd r2, r3, [sp, #176] ; 0xb0 | |
} | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
1cdc: e9cd 0108 strd r0, r1, [sp, #32] | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
1ce0: 992e ldr r1, [sp, #184] ; 0xb8 | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
1ce2: e9cd 230a strd r2, r3, [sp, #40] ; 0x28 | |
attr->atime = s->st_atime; | |
1ce6: 2300 movs r3, #0 | |
attr->mtime = s->st_mtime; | |
1ce8: 9830 ldr r0, [sp, #192] ; 0xc0 | |
attr->ctime = s->st_ctime; | |
1cea: 9a32 ldr r2, [sp, #200] ; 0xc8 | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
1cec: 930d str r3, [sp, #52] ; 0x34 | |
attr->mtime = s->st_mtime; | |
1cee: 930f str r3, [sp, #60] ; 0x3c | |
attr->ctime = s->st_ctime; | |
1cf0: 9311 str r3, [sp, #68] ; 0x44 | |
attr->atimensec = s->st_atime_nsec; | |
1cf2: 9b2f ldr r3, [sp, #188] ; 0xbc | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
1cf4: 910c str r1, [sp, #48] ; 0x30 | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
1cf6: 9931 ldr r1, [sp, #196] ; 0xc4 | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
1cf8: 900e str r0, [sp, #56] ; 0x38 | |
attr->ctime = s->st_ctime; | |
1cfa: 9210 str r2, [sp, #64] ; 0x40 | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
1cfc: 9833 ldr r0, [sp, #204] ; 0xcc | |
attr->mode = s->st_mode; | |
1cfe: 9a20 ldr r2, [sp, #128] ; 0x80 | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
1d00: 9312 str r3, [sp, #72] ; 0x48 | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
1d02: 9b21 ldr r3, [sp, #132] ; 0x84 | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
1d04: 9113 str r1, [sp, #76] ; 0x4c | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
1d06: f8d8 1020 ldr.w r1, [r8, #32] | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
1d0a: 9014 str r0, [sp, #80] ; 0x50 | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
1d0c: 9316 str r3, [sp, #88] ; 0x58 | |
attr->uid = node->uid; | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
1d0e: f402 73e0 and.w r3, r2, #448 ; 0x1c0 | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
attr->gid = node->gid; | |
1d12: f8d8 0024 ldr.w r0, [r8, #36] ; 0x24 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
1d16: f402 4270 and.w r2, r2, #61440 ; 0xf000 | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
1d1a: 9117 str r1, [sp, #92] ; 0x5c | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
1d1c: 1199 asrs r1, r3, #6 | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
attr->gid = node->gid; | |
1d1e: 9018 str r0, [sp, #96] ; 0x60 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
1d20: ea41 00d3 orr.w r0, r1, r3, lsr #3 | |
1d24: ea40 0c03 orr.w ip, r0, r3 | |
1d28: f8b8 3028 ldrh.w r3, [r8, #40] ; 0x28 | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
1d2c: 9700 str r7, [sp, #0] | |
1d2e: 9601 str r6, [sp, #4] | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
1d30: ea0c 0103 and.w r1, ip, r3 | |
if (lstat(path, &s) < 0) { | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
1d34: 2300 movs r3, #0 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
1d36: ea41 0002 orr.w r0, r1, r2 | |
if (lstat(path, &s) < 0) { | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
1d3a: 220a movs r2, #10 | |
1d3c: e9cd 2302 strd r2, r3, [sp, #8] | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
1d40: 4622 mov r2, r4 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
1d42: 9015 str r0, [sp, #84] ; 0x54 | |
return -errno; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
1d44: 462b mov r3, r5 | |
1d46: 4648 mov r0, r9 | |
1d48: f7ff fbee bl 1528 <fuse_reply> | |
return NO_STATUS; | |
1d4c: 2001 movs r0, #1 | |
} | |
1d4e: b037 add sp, #220 ; 0xdc | |
1d50: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} | |
00001d54 <handle_getattr.isra.5>: | |
} | |
pthread_mutex_unlock(&fuse->lock); | |
return NO_STATUS; /* no reply */ | |
} | |
static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler, | |
1d54: 4b23 ldr r3, [pc, #140] ; (1de4 <handle_getattr.isra.5+0x90>) | |
1d56: 4a24 ldr r2, [pc, #144] ; (1de8 <handle_getattr.isra.5+0x94>) | |
1d58: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} | |
1d5c: f5ad 5d80 sub.w sp, sp, #4096 ; 0x1000 | |
1d60: 447b add r3, pc | |
1d62: b084 sub sp, #16 | |
1d64: 460f mov r7, r1 | |
1d66: f50d 5180 add.w r1, sp, #4096 ; 0x1000 | |
1d6a: f853 8002 ldr.w r8, [r3, r2] | |
1d6e: 4605 mov r5, r0 | |
1d70: 310c adds r1, #12 | |
{ | |
struct node* node; | |
char path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1d72: ac03 add r4, sp, #12 | |
} | |
pthread_mutex_unlock(&fuse->lock); | |
return NO_STATUS; /* no reply */ | |
} | |
static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler, | |
1d74: f8d8 3000 ldr.w r3, [r8] | |
1d78: 600b str r3, [r1, #0] | |
const struct fuse_in_header *hdr, const struct fuse_getattr_in *req) | |
{ | |
struct node* node; | |
char path[PATH_MAX]; | |
pthread_mutex_lock(&fuse->lock); | |
1d7a: f7ff e954 blx 1024 <pthread_mutex_lock@plt> | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1d7e: e9d7 2304 ldrd r2, r3, [r7, #16] | |
1d82: 4628 mov r0, r5 | |
1d84: 9400 str r4, [sp, #0] | |
1d86: f7ff fdc7 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1d8a: 4606 mov r6, r0 | |
TRACE("[%d] GETATTR flags=%x fh=%llx @ %llx (%s)\n", handler->token, | |
req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1d8c: 4628 mov r0, r5 | |
1d8e: f7ff e950 blx 1030 <pthread_mutex_unlock@plt> | |
if (!node) { | |
1d92: b196 cbz r6, 1dba <handle_getattr.isra.5+0x66> | |
return true; | |
} | |
static bool check_caller_access_to_node(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) { | |
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw); | |
1d94: 2004 movs r0, #4 | |
1d96: 2300 movs r3, #0 | |
1d98: e88d 0009 stmia.w sp, {r0, r3} | |
1d9c: 4639 mov r1, r7 | |
1d9e: 4628 mov r0, r5 | |
1da0: 6b72 ldr r2, [r6, #52] ; 0x34 | |
1da2: 6bf3 ldr r3, [r6, #60] ; 0x3c | |
1da4: f7ff fb88 bl 14b8 <check_caller_access_to_name> | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) { | |
1da8: b150 cbz r0, 1dc0 <handle_getattr.isra.5+0x6c> | |
return -EACCES; | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
1daa: e9d7 2302 ldrd r2, r3, [r7, #8] | |
1dae: 4628 mov r0, r5 | |
1db0: 9600 str r6, [sp, #0] | |
1db2: 9401 str r4, [sp, #4] | |
1db4: f7ff ff70 bl 1c98 <fuse_reply_attr> | |
1db8: e004 b.n 1dc4 <handle_getattr.isra.5+0x70> | |
TRACE("[%d] GETATTR flags=%x fh=%llx @ %llx (%s)\n", handler->token, | |
req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
1dba: f06f 0001 mvn.w r0, #1 | |
1dbe: e001 b.n 1dc4 <handle_getattr.isra.5+0x70> | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) { | |
return -EACCES; | |
1dc0: f06f 000c mvn.w r0, #12 | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
} | |
1dc4: f50d 5280 add.w r2, sp, #4096 ; 0x1000 | |
1dc8: 320c adds r2, #12 | |
1dca: 6811 ldr r1, [r2, #0] | |
1dcc: f8d8 3000 ldr.w r3, [r8] | |
1dd0: 4299 cmp r1, r3 | |
1dd2: d001 beq.n 1dd8 <handle_getattr.isra.5+0x84> | |
1dd4: f7ff e938 blx 1048 <__stack_chk_fail@plt> | |
1dd8: b004 add sp, #16 | |
1dda: f50d 5d80 add.w sp, sp, #4096 ; 0x1000 | |
1dde: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} | |
1de2: bf00 nop | |
1de4: 00003158 .word 0x00003158 | |
1de8: fffffff4 .word 0xfffffff4 | |
00001dec <handle_setattr.isra.13>: | |
static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler, | |
1dec: 4b40 ldr r3, [pc, #256] ; (1ef0 <handle_setattr.isra.13+0x104>) | |
1dee: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} | |
1df2: 4614 mov r4, r2 | |
1df4: 4a3f ldr r2, [pc, #252] ; (1ef4 <handle_setattr.isra.13+0x108>) | |
1df6: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020 | |
1dfa: 447b add r3, pc | |
1dfc: 4688 mov r8, r1 | |
1dfe: f50d 5180 add.w r1, sp, #4096 ; 0x1000 | |
1e02: 4606 mov r6, r0 | |
1e04: f853 9002 ldr.w r9, [r3, r2] | |
1e08: 311c adds r1, #28 | |
char path[PATH_MAX]; | |
struct timespec times[2]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1e0a: ad07 add r5, sp, #28 | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
} | |
static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler, | |
1e0c: f8d9 3000 ldr.w r3, [r9] | |
1e10: 600b str r3, [r1, #0] | |
bool has_rw; | |
struct node* node; | |
char path[PATH_MAX]; | |
struct timespec times[2]; | |
pthread_mutex_lock(&fuse->lock); | |
1e12: f7ff e908 blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1e16: 4641 mov r1, r8 | |
1e18: 4630 mov r0, r6 | |
1e1a: f7ff fbfc bl 1616 <get_caller_has_rw_locked> | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1e1e: e9d8 2304 ldrd r2, r3, [r8, #16] | |
struct node* node; | |
char path[PATH_MAX]; | |
struct timespec times[2]; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1e22: 4682 mov sl, r0 | |
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path)); | |
1e24: 9500 str r5, [sp, #0] | |
1e26: 4630 mov r0, r6 | |
1e28: f7ff fd76 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1e2c: 4607 mov r7, r0 | |
TRACE("[%d] SETATTR fh=%llx valid=%x @ %llx (%s)\n", handler->token, | |
req->fh, req->valid, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
1e2e: 4630 mov r0, r6 | |
1e30: f7ff e8fe blx 1030 <pthread_mutex_unlock@plt> | |
if (!node) { | |
1e34: 2f00 cmp r7, #0 | |
1e36: d045 beq.n 1ec4 <handle_setattr.isra.13+0xd8> | |
return true; | |
} | |
static bool check_caller_access_to_node(struct fuse* fuse, | |
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) { | |
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw); | |
1e38: 2302 movs r3, #2 | |
1e3a: 4630 mov r0, r6 | |
1e3c: e88d 0408 stmia.w sp, {r3, sl} | |
1e40: 4641 mov r1, r8 | |
1e42: 6b7a ldr r2, [r7, #52] ; 0x34 | |
1e44: 6bfb ldr r3, [r7, #60] ; 0x3c | |
1e46: f7ff fb37 bl 14b8 <check_caller_access_to_name> | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) { | |
1e4a: 2800 cmp r0, #0 | |
1e4c: d03d beq.n 1eca <handle_setattr.isra.13+0xde> | |
} | |
/* XXX: incomplete implementation on purpose. | |
* chmod/chown should NEVER be implemented.*/ | |
if ((req->valid & FATTR_SIZE) && truncate(path, req->size) < 0) { | |
1e4e: 6820 ldr r0, [r4, #0] | |
1e50: 0703 lsls r3, r0, #28 | |
1e52: d506 bpl.n 1e62 <handle_setattr.isra.13+0x76> | |
1e54: 4628 mov r0, r5 | |
1e56: 6921 ldr r1, [r4, #16] | |
1e58: f7ff e950 blx 10fc <truncate@plt> | |
1e5c: 2800 cmp r0, #0 | |
1e5e: da00 bge.n 1e62 <handle_setattr.isra.13+0x76> | |
1e60: e023 b.n 1eaa <handle_setattr.isra.13+0xbe> | |
* are both set, then set it to the current time. Else, set it to the | |
* time specified in the request. Same goes for mtime. Use utimensat(2) | |
* as it allows ATIME and MTIME to be changed independently, and has | |
* nanosecond resolution which fuse also has. | |
*/ | |
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) { | |
1e62: 6823 ldr r3, [r4, #0] | |
1e64: f013 0f30 tst.w r3, #48 ; 0x30 | |
1e68: d024 beq.n 1eb4 <handle_setattr.isra.13+0xc8> | |
times[0].tv_nsec = UTIME_OMIT; | |
1e6a: 4a20 ldr r2, [pc, #128] ; (1eec <handle_setattr.isra.13+0x100>) | |
times[1].tv_nsec = UTIME_OMIT; | |
if (req->valid & FATTR_ATIME) { | |
1e6c: 06d8 lsls r0, r3, #27 | |
* time specified in the request. Same goes for mtime. Use utimensat(2) | |
* as it allows ATIME and MTIME to be changed independently, and has | |
* nanosecond resolution which fuse also has. | |
*/ | |
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) { | |
times[0].tv_nsec = UTIME_OMIT; | |
1e6e: 9204 str r2, [sp, #16] | |
times[1].tv_nsec = UTIME_OMIT; | |
1e70: 9206 str r2, [sp, #24] | |
if (req->valid & FATTR_ATIME) { | |
1e72: d507 bpl.n 1e84 <handle_setattr.isra.13+0x98> | |
if (req->valid & FATTR_ATIME_NOW) { | |
1e74: 0619 lsls r1, r3, #24 | |
times[0].tv_nsec = UTIME_NOW; | |
} else { | |
times[0].tv_sec = req->atime; | |
1e76: bf57 itett pl | |
1e78: 6a22 ldrpl r2, [r4, #32] | |
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) { | |
times[0].tv_nsec = UTIME_OMIT; | |
times[1].tv_nsec = UTIME_OMIT; | |
if (req->valid & FATTR_ATIME) { | |
if (req->valid & FATTR_ATIME_NOW) { | |
times[0].tv_nsec = UTIME_NOW; | |
1e7a: f06f 4240 mvnmi.w r2, #3221225472 ; 0xc0000000 | |
} else { | |
times[0].tv_sec = req->atime; | |
1e7e: 9203 strpl r2, [sp, #12] | |
times[0].tv_nsec = req->atimensec; | |
1e80: 6ba2 ldrpl r2, [r4, #56] ; 0x38 | |
1e82: 9204 str r2, [sp, #16] | |
} | |
} | |
if (req->valid & FATTR_MTIME) { | |
1e84: 069a lsls r2, r3, #26 | |
1e86: d507 bpl.n 1e98 <handle_setattr.isra.13+0xac> | |
if (req->valid & FATTR_MTIME_NOW) { | |
1e88: 05d9 lsls r1, r3, #23 | |
times[1].tv_nsec = UTIME_NOW; | |
} else { | |
times[1].tv_sec = req->mtime; | |
1e8a: bf57 itett pl | |
1e8c: 6aa1 ldrpl r1, [r4, #40] ; 0x28 | |
times[0].tv_nsec = req->atimensec; | |
} | |
} | |
if (req->valid & FATTR_MTIME) { | |
if (req->valid & FATTR_MTIME_NOW) { | |
times[1].tv_nsec = UTIME_NOW; | |
1e8e: f06f 4140 mvnmi.w r1, #3221225472 ; 0xc0000000 | |
} else { | |
times[1].tv_sec = req->mtime; | |
1e92: 9105 strpl r1, [sp, #20] | |
times[1].tv_nsec = req->mtimensec; | |
1e94: 6be1 ldrpl r1, [r4, #60] ; 0x3c | |
1e96: 9106 str r1, [sp, #24] | |
} | |
} | |
TRACE("[%d] Calling utimensat on %s with atime %ld, mtime=%ld\n", | |
handler->token, path, times[0].tv_sec, times[1].tv_sec); | |
if (utimensat(-1, path, times, 0) < 0) { | |
1e98: 2300 movs r3, #0 | |
1e9a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff | |
1e9e: 4629 mov r1, r5 | |
1ea0: aa03 add r2, sp, #12 | |
1ea2: f7ff e932 blx 1108 <utimensat@plt> | |
1ea6: 2800 cmp r0, #0 | |
1ea8: da04 bge.n 1eb4 <handle_setattr.isra.13+0xc8> | |
return -errno; | |
1eaa: f7ff e8a4 blx ff4 <__errno@plt> | |
1eae: 6800 ldr r0, [r0, #0] | |
1eb0: 4240 negs r0, r0 | |
1eb2: e00c b.n 1ece <handle_setattr.isra.13+0xe2> | |
} | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
1eb4: e9d8 2302 ldrd r2, r3, [r8, #8] | |
1eb8: 4630 mov r0, r6 | |
1eba: 9700 str r7, [sp, #0] | |
1ebc: 9501 str r5, [sp, #4] | |
1ebe: f7ff feeb bl 1c98 <fuse_reply_attr> | |
1ec2: e004 b.n 1ece <handle_setattr.isra.13+0xe2> | |
TRACE("[%d] SETATTR fh=%llx valid=%x @ %llx (%s)\n", handler->token, | |
req->fh, req->valid, hdr->nodeid, node ? node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!node) { | |
return -ENOENT; | |
1ec4: f06f 0001 mvn.w r0, #1 | |
1ec8: e001 b.n 1ece <handle_setattr.isra.13+0xe2> | |
} | |
if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) { | |
return -EACCES; | |
1eca: f06f 000c mvn.w r0, #12 | |
if (utimensat(-1, path, times, 0) < 0) { | |
return -errno; | |
} | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
} | |
1ece: f50d 5380 add.w r3, sp, #4096 ; 0x1000 | |
1ed2: 331c adds r3, #28 | |
1ed4: 681a ldr r2, [r3, #0] | |
1ed6: f8d9 1000 ldr.w r1, [r9] | |
1eda: 428a cmp r2, r1 | |
1edc: d001 beq.n 1ee2 <handle_setattr.isra.13+0xf6> | |
1ede: f7ff e8b4 blx 1048 <__stack_chk_fail@plt> | |
1ee2: b008 add sp, #32 | |
1ee4: f50d 5d80 add.w sp, sp, #4096 ; 0x1000 | |
1ee8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} | |
1eec: 3ffffffe .word 0x3ffffffe | |
1ef0: 000030be .word 0x000030be | |
1ef4: fffffff4 .word 0xfffffff4 | |
00001ef8 <handle_rename.isra.17>: | |
return -errno; | |
} | |
return 0; | |
} | |
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler, | |
1ef8: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
1efc: 4699 mov r9, r3 | |
1efe: 4b8d ldr r3, [pc, #564] ; (2134 <handle_rename.isra.17+0x23c>) | |
1f00: 4615 mov r5, r2 | |
1f02: f5ad 4d80 sub.w sp, sp, #16384 ; 0x4000 | |
1f06: 4688 mov r8, r1 | |
1f08: 4a8b ldr r2, [pc, #556] ; (2138 <handle_rename.isra.17+0x240>) | |
1f0a: b087 sub sp, #28 | |
1f0c: 447b add r3, pc | |
1f0e: f50d 4180 add.w r1, sp, #16384 ; 0x4000 | |
1f12: 3140 adds r1, #64 ; 0x40 | |
1f14: 4604 mov r4, r0 | |
1f16: 589b ldr r3, [r3, r2] | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
old_parent_path, sizeof(old_parent_path)); | |
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir, | |
new_parent_path, sizeof(new_parent_path)); | |
1f18: f50d 5a80 add.w sl, sp, #4096 ; 0x1000 | |
return -errno; | |
} | |
return 0; | |
} | |
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler, | |
1f1c: 680e ldr r6, [r1, #0] | |
1f1e: f50d 4180 add.w r1, sp, #16384 ; 0x4000 | |
1f22: 3114 adds r1, #20 | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
old_parent_path, sizeof(old_parent_path)); | |
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir, | |
new_parent_path, sizeof(new_parent_path)); | |
1f24: f10a 0a14 add.w sl, sl, #20 | |
return -errno; | |
} | |
return 0; | |
} | |
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler, | |
1f28: 681f ldr r7, [r3, #0] | |
1f2a: 9303 str r3, [sp, #12] | |
1f2c: 600f str r7, [r1, #0] | |
char old_child_path[PATH_MAX]; | |
char new_child_path[PATH_MAX]; | |
const char* new_actual_name; | |
int res; | |
pthread_mutex_lock(&fuse->lock); | |
1f2e: f7ff e87a blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
1f32: 4641 mov r1, r8 | |
1f34: 4620 mov r0, r4 | |
1f36: f7ff fb6e bl 1616 <get_caller_has_rw_locked> | |
1f3a: 4683 mov fp, r0 | |
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
old_parent_path, sizeof(old_parent_path)); | |
1f3c: a805 add r0, sp, #20 | |
const char* new_actual_name; | |
int res; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
1f3e: e9d8 2304 ldrd r2, r3, [r8, #16] | |
1f42: 9000 str r0, [sp, #0] | |
1f44: 4620 mov r0, r4 | |
1f46: f7ff fce7 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
old_parent_path, sizeof(old_parent_path)); | |
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir, | |
1f4a: f8cd a000 str.w sl, [sp] | |
const char* new_actual_name; | |
int res; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
1f4e: 4607 mov r7, r0 | |
old_parent_path, sizeof(old_parent_path)); | |
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir, | |
1f50: e9d5 2300 ldrd r2, r3, [r5] | |
1f54: 4620 mov r0, r4 | |
1f56: f7ff fcdf bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
1f5a: 4605 mov r5, r0 | |
new_parent_path, sizeof(new_parent_path)); | |
TRACE("[%d] RENAME %s->%s @ %llx (%s) -> %llx (%s)\n", handler->token, | |
old_name, new_name, | |
hdr->nodeid, old_parent_node ? old_parent_node->name : "?", | |
req->newdir, new_parent_node ? new_parent_node->name : "?"); | |
if (!old_parent_node || !new_parent_node) { | |
1f5c: b917 cbnz r7, 1f64 <handle_rename.isra.17+0x6c> | |
res = -ENOENT; | |
1f5e: f06f 0501 mvn.w r5, #1 | |
1f62: e0c3 b.n 20ec <handle_rename.isra.17+0x1f4> | |
new_parent_path, sizeof(new_parent_path)); | |
TRACE("[%d] RENAME %s->%s @ %llx (%s) -> %llx (%s)\n", handler->token, | |
old_name, new_name, | |
hdr->nodeid, old_parent_node ? old_parent_node->name : "?", | |
req->newdir, new_parent_node ? new_parent_node->name : "?"); | |
if (!old_parent_node || !new_parent_node) { | |
1f64: 2800 cmp r0, #0 | |
1f66: d0fa beq.n 1f5e <handle_rename.isra.17+0x66> | |
res = -ENOENT; | |
goto lookup_error; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK, has_rw)) { | |
1f68: f04f 0c02 mov.w ip, #2 | |
1f6c: f8cd b004 str.w fp, [sp, #4] | |
1f70: f8cd c000 str.w ip, [sp] | |
1f74: 4620 mov r0, r4 | |
1f76: 4641 mov r1, r8 | |
1f78: 463a mov r2, r7 | |
1f7a: 464b mov r3, r9 | |
1f7c: f8cd c008 str.w ip, [sp, #8] | |
1f80: f7ff fa9a bl 14b8 <check_caller_access_to_name> | |
1f84: f8dd c008 ldr.w ip, [sp, #8] | |
1f88: 2800 cmp r0, #0 | |
1f8a: f000 80ad beq.w 20e8 <handle_rename.isra.17+0x1f0> | |
res = -EACCES; | |
goto lookup_error; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK, has_rw)) { | |
1f8e: f8cd c000 str.w ip, [sp] | |
1f92: 4620 mov r0, r4 | |
1f94: f8cd b004 str.w fp, [sp, #4] | |
1f98: 4641 mov r1, r8 | |
1f9a: 462a mov r2, r5 | |
1f9c: 4633 mov r3, r6 | |
1f9e: f7ff fa8b bl 14b8 <check_caller_access_to_name> | |
1fa2: 2800 cmp r0, #0 | |
1fa4: f000 80a0 beq.w 20e8 <handle_rename.isra.17+0x1f0> | |
return node; | |
} | |
static struct node *lookup_child_by_name_locked(struct node *node, const char *name) | |
{ | |
for (node = node->child; node; node = node->next) { | |
1fa8: f8d7 8030 ldr.w r8, [r7, #48] ; 0x30 | |
1fac: e009 b.n 1fc2 <handle_rename.isra.17+0xca> | |
/* use exact string comparison, nodes that differ by case | |
* must be considered distinct even if they refer to the same | |
* underlying file as otherwise operations such as "mv x x" | |
* will not work because the source and target nodes are the same. */ | |
if (!strcmp(name, node->name)) { | |
1fae: 4648 mov r0, r9 | |
1fb0: f8d8 103c ldr.w r1, [r8, #60] ; 0x3c | |
1fb4: f7ff e8ae blx 1114 <strcmp@plt> | |
1fb8: 2800 cmp r0, #0 | |
1fba: f000 80a4 beq.w 2106 <handle_rename.isra.17+0x20e> | |
return node; | |
} | |
static struct node *lookup_child_by_name_locked(struct node *node, const char *name) | |
{ | |
for (node = node->child; node; node = node->next) { | |
1fbe: f8d8 802c ldr.w r8, [r8, #44] ; 0x2c | |
1fc2: f1b8 0f00 cmp.w r8, #0 | |
1fc6: d1f2 bne.n 1fae <handle_rename.isra.17+0xb6> | |
1fc8: e7c9 b.n 1f5e <handle_rename.isra.17+0x66> | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
1fca: f8d8 2000 ldr.w r2, [r8] | |
old_child_path, sizeof(old_child_path)) < 0) { | |
res = -ENOENT; | |
goto lookup_error; | |
} | |
acquire_node_locked(child_node); | |
pthread_mutex_unlock(&fuse->lock); | |
1fce: 4620 mov r0, r4 | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
1fd0: 1c53 adds r3, r2, #1 | |
1fd2: f8c8 3000 str.w r3, [r8] | |
old_child_path, sizeof(old_child_path)) < 0) { | |
res = -ENOENT; | |
goto lookup_error; | |
} | |
acquire_node_locked(child_node); | |
pthread_mutex_unlock(&fuse->lock); | |
1fd6: f7ff e82c blx 1030 <pthread_mutex_unlock@plt> | |
/* Special case for renaming a file where destination is same path | |
* differing only by case. In this case we don't want to look for a case | |
* insensitive match. This allows commands like "mv foo FOO" to work as expected. | |
*/ | |
int search = old_parent_node != new_parent_node | |
|| strcasecmp(old_name, new_name); | |
1fda: 42af cmp r7, r5 | |
1fdc: d107 bne.n 1fee <handle_rename.isra.17+0xf6> | |
1fde: 4648 mov r0, r9 | |
1fe0: 4631 mov r1, r6 | |
1fe2: f7fe efde blx fa0 <strcasecmp@plt> | |
1fe6: 1c03 adds r3, r0, #0 | |
1fe8: bf18 it ne | |
1fea: 2301 movne r3, #1 | |
1fec: e000 b.n 1ff0 <handle_rename.isra.17+0xf8> | |
1fee: 2301 movs r3, #1 | |
if (!(new_actual_name = find_file_within(new_parent_path, new_name, | |
1ff0: f50d 5240 add.w r2, sp, #12288 ; 0x3000 | |
1ff4: 4650 mov r0, sl | |
1ff6: 4631 mov r1, r6 | |
1ff8: 3214 adds r2, #20 | |
1ffa: f7ff fc2b bl 1854 <find_file_within.constprop.27> | |
1ffe: 4681 mov r9, r0 | |
2000: 2800 cmp r0, #0 | |
2002: d068 beq.n 20d6 <handle_rename.isra.17+0x1de> | |
res = -ENOENT; | |
goto io_error; | |
} | |
TRACE("[%d] RENAME %s->%s\n", handler->token, old_child_path, new_child_path); | |
res = rename(old_child_path, new_child_path); | |
2004: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
2008: f50d 5140 add.w r1, sp, #12288 ; 0x3000 | |
200c: 3014 adds r0, #20 | |
200e: 3114 adds r1, #20 | |
2010: f7ff e886 blx 1120 <rename@plt> | |
if (res < 0) { | |
2014: 2800 cmp r0, #0 | |
2016: da04 bge.n 2022 <handle_rename.isra.17+0x12a> | |
res = -errno; | |
2018: f7fe efec blx ff4 <__errno@plt> | |
201c: 6805 ldr r5, [r0, #0] | |
201e: 426d negs r5, r5 | |
2020: e05b b.n 20da <handle_rename.isra.17+0x1e2> | |
goto io_error; | |
} | |
pthread_mutex_lock(&fuse->lock); | |
2022: 4620 mov r0, r4 | |
2024: f7fe effe blx 1024 <pthread_mutex_lock@plt> | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
2028: 4630 mov r0, r6 | |
202a: f7fe efc0 blx fac <strlen@plt> | |
static int rename_node_locked(struct node *node, const char *name, | |
const char* actual_name) | |
{ | |
size_t namelen = strlen(name); | |
int need_actual_name = strcmp(name, actual_name); | |
202e: 4649 mov r1, r9 | |
2030: 4607 mov r7, r0 | |
2032: 4630 mov r0, r6 | |
2034: f7ff e86e blx 1114 <strcmp@plt> | |
/* make the storage bigger without actually changing the name | |
* in case an error occurs part way */ | |
if (namelen > node->namelen) { | |
2038: f8d8 1038 ldr.w r1, [r8, #56] ; 0x38 | |
static int rename_node_locked(struct node *node, const char *name, | |
const char* actual_name) | |
{ | |
size_t namelen = strlen(name); | |
int need_actual_name = strcmp(name, actual_name); | |
203c: 4682 mov sl, r0 | |
/* make the storage bigger without actually changing the name | |
* in case an error occurs part way */ | |
if (namelen > node->namelen) { | |
203e: 428f cmp r7, r1 | |
2040: d918 bls.n 2074 <handle_rename.isra.17+0x17c> | |
char* new_name = realloc(node->name, namelen + 1); | |
2042: f107 0b01 add.w fp, r7, #1 | |
2046: f8d8 003c ldr.w r0, [r8, #60] ; 0x3c | |
204a: 4659 mov r1, fp | |
204c: f7ff e86e blx 112c <realloc@plt> | |
if (!new_name) { | |
2050: 2800 cmp r0, #0 | |
2052: d064 beq.n 211e <handle_rename.isra.17+0x226> | |
return -ENOMEM; | |
} | |
node->name = new_name; | |
2054: f8c8 003c str.w r0, [r8, #60] ; 0x3c | |
if (need_actual_name && node->actual_name) { | |
2058: f1ba 0f00 cmp.w sl, #0 | |
205c: d01d beq.n 209a <handle_rename.isra.17+0x1a2> | |
205e: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40 | |
2062: b140 cbz r0, 2076 <handle_rename.isra.17+0x17e> | |
char* new_actual_name = realloc(node->actual_name, namelen + 1); | |
2064: 4659 mov r1, fp | |
2066: f7ff e862 blx 112c <realloc@plt> | |
if (!new_actual_name) { | |
206a: 2800 cmp r0, #0 | |
206c: d057 beq.n 211e <handle_rename.isra.17+0x226> | |
return -ENOMEM; | |
} | |
node->actual_name = new_actual_name; | |
206e: f8c8 0040 str.w r0, [r8, #64] ; 0x40 | |
2072: e000 b.n 2076 <handle_rename.isra.17+0x17e> | |
} | |
} | |
/* update the name, taking care to allocate storage before overwriting the old name */ | |
if (need_actual_name) { | |
2074: b188 cbz r0, 209a <handle_rename.isra.17+0x1a2> | |
if (!node->actual_name) { | |
2076: f8d8 2040 ldr.w r2, [r8, #64] ; 0x40 | |
207a: b132 cbz r2, 208a <handle_rename.isra.17+0x192> | |
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { | |
__memcpy_src_size_error(); | |
} | |
return __builtin___memcpy_chk(dest, src, copy_amount, d_len); | |
207c: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40 | |
2080: 4649 mov r1, r9 | |
2082: 1c7a adds r2, r7, #1 | |
2084: f7fe ef9e blx fc4 <memcpy@plt> | |
2088: e00e b.n 20a8 <handle_rename.isra.17+0x1b0> | |
node->actual_name = malloc(namelen + 1); | |
208a: 1c78 adds r0, r7, #1 | |
208c: f7ff e824 blx 10d8 <malloc@plt> | |
2090: f8c8 0040 str.w r0, [r8, #64] ; 0x40 | |
if (!node->actual_name) { | |
2094: 2800 cmp r0, #0 | |
2096: d1f1 bne.n 207c <handle_rename.isra.17+0x184> | |
2098: e041 b.n 211e <handle_rename.isra.17+0x226> | |
return -ENOMEM; | |
} | |
} | |
memcpy(node->actual_name, actual_name, namelen + 1); | |
} else { | |
free(node->actual_name); | |
209a: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40 | |
209e: f7fe ef9e blx fdc <free@plt> | |
node->actual_name = NULL; | |
20a2: 2000 movs r0, #0 | |
20a4: f8c8 0040 str.w r0, [r8, #64] ; 0x40 | |
20a8: 4631 mov r1, r6 | |
20aa: 1c7a adds r2, r7, #1 | |
20ac: f8d8 003c ldr.w r0, [r8, #60] ; 0x3c | |
20b0: f7fe ef88 blx fc4 <memcpy@plt> | |
} | |
pthread_mutex_lock(&fuse->lock); | |
res = rename_node_locked(child_node, new_name, new_actual_name); | |
if (!res) { | |
remove_node_from_parent_locked(child_node); | |
20b4: 4640 mov r0, r8 | |
} else { | |
free(node->actual_name); | |
node->actual_name = NULL; | |
} | |
memcpy(node->name, name, namelen + 1); | |
node->namelen = namelen; | |
20b6: f8c8 7038 str.w r7, [r8, #56] ; 0x38 | |
} | |
pthread_mutex_lock(&fuse->lock); | |
res = rename_node_locked(child_node, new_name, new_actual_name); | |
if (!res) { | |
remove_node_from_parent_locked(child_node); | |
20ba: f7ff fa95 bl 15e8 <remove_node_from_parent_locked> | |
ERROR("Zero refcnt %p\n", node); | |
} | |
} | |
static void add_node_to_parent_locked(struct node *node, struct node *parent) { | |
node->parent = parent; | |
20be: f8c8 5034 str.w r5, [r8, #52] ; 0x34 | |
node->next = parent->child; | |
20c2: 6b2b ldr r3, [r5, #48] ; 0x30 | |
20c4: f8c8 302c str.w r3, [r8, #44] ; 0x2c | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
20c8: 6829 ldr r1, [r5, #0] | |
} | |
static void add_node_to_parent_locked(struct node *node, struct node *parent) { | |
node->parent = parent; | |
node->next = parent->child; | |
parent->child = node; | |
20ca: f8c5 8030 str.w r8, [r5, #48] ; 0x30 | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
20ce: 1c48 adds r0, r1, #1 | |
20d0: 6028 str r0, [r5, #0] | |
20d2: 2500 movs r5, #0 | |
20d4: e004 b.n 20e0 <handle_rename.isra.17+0x1e8> | |
*/ | |
int search = old_parent_node != new_parent_node | |
|| strcasecmp(old_name, new_name); | |
if (!(new_actual_name = find_file_within(new_parent_path, new_name, | |
new_child_path, sizeof(new_child_path), search))) { | |
res = -ENOENT; | |
20d6: f06f 0501 mvn.w r5, #1 | |
add_node_to_parent_locked(child_node, new_parent_node); | |
} | |
goto done; | |
io_error: | |
pthread_mutex_lock(&fuse->lock); | |
20da: 4620 mov r0, r4 | |
20dc: f7fe efa2 blx 1024 <pthread_mutex_lock@plt> | |
done: | |
release_node_locked(child_node); | |
20e0: 4640 mov r0, r8 | |
20e2: f7ff fa4f bl 1584 <release_node_locked> | |
20e6: e001 b.n 20ec <handle_rename.isra.17+0x1f4> | |
if (!old_parent_node || !new_parent_node) { | |
res = -ENOENT; | |
goto lookup_error; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK, has_rw)) { | |
res = -EACCES; | |
20e8: f06f 050c mvn.w r5, #12 | |
io_error: | |
pthread_mutex_lock(&fuse->lock); | |
done: | |
release_node_locked(child_node); | |
lookup_error: | |
pthread_mutex_unlock(&fuse->lock); | |
20ec: 4620 mov r0, r4 | |
20ee: f7fe efa0 blx 1030 <pthread_mutex_unlock@plt> | |
return res; | |
} | |
20f2: 9b03 ldr r3, [sp, #12] | |
20f4: f50d 4280 add.w r2, sp, #16384 ; 0x4000 | |
20f8: 3214 adds r2, #20 | |
20fa: 4628 mov r0, r5 | |
20fc: 6812 ldr r2, [r2, #0] | |
20fe: 6819 ldr r1, [r3, #0] | |
2100: 428a cmp r2, r1 | |
2102: d011 beq.n 2128 <handle_rename.isra.17+0x230> | |
2104: e00e b.n 2124 <handle_rename.isra.17+0x22c> | |
if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK, has_rw)) { | |
res = -EACCES; | |
goto lookup_error; | |
} | |
child_node = lookup_child_by_name_locked(old_parent_node, old_name); | |
if (!child_node || get_node_path_locked(child_node, | |
2106: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
210a: 4640 mov r0, r8 | |
210c: 3114 adds r1, #20 | |
210e: f44f 5280 mov.w r2, #4096 ; 0x1000 | |
2112: f7ff f991 bl 1438 <get_node_path_locked> | |
2116: 2800 cmp r0, #0 | |
2118: f6bf af57 bge.w 1fca <handle_rename.isra.17+0xd2> | |
211c: e71f b.n 1f5e <handle_rename.isra.17+0x66> | |
*/ | |
int search = old_parent_node != new_parent_node | |
|| strcasecmp(old_name, new_name); | |
if (!(new_actual_name = find_file_within(new_parent_path, new_name, | |
new_child_path, sizeof(new_child_path), search))) { | |
res = -ENOENT; | |
211e: f06f 050b mvn.w r5, #11 | |
2122: e7dd b.n 20e0 <handle_rename.isra.17+0x1e8> | |
done: | |
release_node_locked(child_node); | |
lookup_error: | |
pthread_mutex_unlock(&fuse->lock); | |
return res; | |
} | |
2124: f7fe ef90 blx 1048 <__stack_chk_fail@plt> | |
2128: b007 add sp, #28 | |
212a: f50d 4d80 add.w sp, sp, #16384 ; 0x4000 | |
212e: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
2132: bf00 nop | |
2134: 00002fac .word 0x00002fac | |
2138: fffffff4 .word 0xfffffff4 | |
213c: 00000000 .word 0x00000000 | |
00002140 <create_node_locked>: | |
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw); | |
} | |
struct node *create_node_locked(struct fuse* fuse, | |
struct node *parent, const char *name, const char* actual_name) | |
{ | |
2140: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
2144: 4607 mov r7, r0 | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
2146: 4610 mov r0, r2 | |
2148: 460d mov r5, r1 | |
214a: 4691 mov r9, r2 | |
214c: 469b mov fp, r3 | |
214e: f7fe ef2e blx fac <strlen@plt> | |
struct node *node; | |
size_t namelen = strlen(name); | |
node = calloc(1, sizeof(struct node)); | |
2152: 2150 movs r1, #80 ; 0x50 | |
2154: 4682 mov sl, r0 | |
2156: 2001 movs r0, #1 | |
2158: f7fe efee blx 1138 <calloc@plt> | |
if (!node) { | |
215c: 4604 mov r4, r0 | |
215e: 2800 cmp r0, #0 | |
2160: f000 80f1 beq.w 2346 <create_node_locked+0x206> | |
return NULL; | |
} | |
node->name = malloc(namelen + 1); | |
2164: f10a 0601 add.w r6, sl, #1 | |
2168: 4630 mov r0, r6 | |
216a: f7fe efb6 blx 10d8 <malloc@plt> | |
216e: 4680 mov r8, r0 | |
2170: 63e0 str r0, [r4, #60] ; 0x3c | |
if (!node->name) { | |
2172: b920 cbnz r0, 217e <create_node_locked+0x3e> | |
free(node); | |
2174: 4620 mov r0, r4 | |
return NULL; | |
2176: 4644 mov r4, r8 | |
if (!node) { | |
return NULL; | |
} | |
node->name = malloc(namelen + 1); | |
if (!node->name) { | |
free(node); | |
2178: f7fe ef30 blx fdc <free@plt> | |
return NULL; | |
217c: e0e3 b.n 2346 <create_node_locked+0x206> | |
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) { | |
__memcpy_src_size_error(); | |
} | |
return __builtin___memcpy_chk(dest, src, copy_amount, d_len); | |
217e: 4649 mov r1, r9 | |
2180: 4632 mov r2, r6 | |
2182: f7fe ef20 blx fc4 <memcpy@plt> | |
} | |
memcpy(node->name, name, namelen + 1); | |
if (strcmp(name, actual_name)) { | |
2186: 4648 mov r0, r9 | |
2188: 4659 mov r1, fp | |
218a: f7fe efc4 blx 1114 <strcmp@plt> | |
218e: b188 cbz r0, 21b4 <create_node_locked+0x74> | |
node->actual_name = malloc(namelen + 1); | |
2190: 4630 mov r0, r6 | |
2192: f7fe efa2 blx 10d8 <malloc@plt> | |
2196: 4681 mov r9, r0 | |
2198: 6420 str r0, [r4, #64] ; 0x40 | |
if (!node->actual_name) { | |
219a: b938 cbnz r0, 21ac <create_node_locked+0x6c> | |
free(node->name); | |
219c: 4640 mov r0, r8 | |
219e: f7fe ef1e blx fdc <free@plt> | |
free(node); | |
21a2: 4620 mov r0, r4 | |
return NULL; | |
21a4: 464c mov r4, r9 | |
memcpy(node->name, name, namelen + 1); | |
if (strcmp(name, actual_name)) { | |
node->actual_name = malloc(namelen + 1); | |
if (!node->actual_name) { | |
free(node->name); | |
free(node); | |
21a6: f7fe ef1a blx fdc <free@plt> | |
return NULL; | |
21aa: e0cc b.n 2346 <create_node_locked+0x206> | |
21ac: 4659 mov r1, fp | |
21ae: 4632 mov r2, r6 | |
21b0: f7fe ef08 blx fc4 <memcpy@plt> | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
21b4: 2300 movs r3, #0 | |
free(node); | |
return NULL; | |
} | |
memcpy(node->actual_name, actual_name, namelen + 1); | |
} | |
node->namelen = namelen; | |
21b6: f8c4 a038 str.w sl, [r4, #56] ; 0x38 | |
return (void *) (uintptr_t) nid; | |
} | |
static inline __u64 ptr_to_id(void *ptr) | |
{ | |
return (__u64) (uintptr_t) ptr; | |
21ba: 60a4 str r4, [r4, #8] | |
21bc: 60e3 str r3, [r4, #12] | |
} | |
memcpy(node->actual_name, actual_name, namelen + 1); | |
} | |
node->namelen = namelen; | |
node->nid = ptr_to_id(node); | |
node->gen = fuse->next_generation++; | |
21be: edd7 0b02 vldr d16, [r7, #8] | |
21c2: eddf 1b63 vldr d17, [pc, #396] ; 2350 <create_node_locked+0x210> | |
21c6: edc4 0b04 vstr d16, [r4, #16] | |
21ca: ef30 08a1 vadd.i64 d0, d16, d17 | |
21ce: ed87 0b02 vstr d0, [r7, #8] | |
static void derive_permissions_locked(struct fuse* fuse, struct node *parent, | |
struct node *node) { | |
appid_t appid; | |
/* By default, each node inherits from its parent */ | |
node->perm = PERM_INHERIT; | |
21d2: 61a3 str r3, [r4, #24] | |
node->userid = parent->userid; | |
21d4: 69e8 ldr r0, [r5, #28] | |
21d6: 61e0 str r0, [r4, #28] | |
node->uid = parent->uid; | |
21d8: 6a29 ldr r1, [r5, #32] | |
21da: 6221 str r1, [r4, #32] | |
node->gid = parent->gid; | |
21dc: 6a6a ldr r2, [r5, #36] ; 0x24 | |
21de: 6262 str r2, [r4, #36] ; 0x24 | |
node->mode = parent->mode; | |
21e0: f8b5 c028 ldrh.w ip, [r5, #40] ; 0x28 | |
21e4: f8a4 c028 strh.w ip, [r4, #40] ; 0x28 | |
if (fuse->derive == DERIVE_NONE) { | |
21e8: 697b ldr r3, [r7, #20] | |
21ea: 2b00 cmp r3, #0 | |
21ec: f000 80a1 beq.w 2332 <create_node_locked+0x1f2> | |
return; | |
} | |
/* Derive custom permissions based on parent and current node */ | |
switch (parent->perm) { | |
21f0: 69a8 ldr r0, [r5, #24] | |
21f2: 1e42 subs r2, r0, #1 | |
21f4: 2a05 cmp r2, #5 | |
21f6: f200 809c bhi.w 2332 <create_node_locked+0x1f2> | |
21fa: e8df f002 tbb [pc, r2] | |
21fe: 0c03 .short 0x0c03 | |
2200: 8c7d7d53 .word 0x8c7d7d53 | |
case PERM_INHERIT: | |
/* Already inherited above */ | |
break; | |
case PERM_LEGACY_PRE_ROOT: | |
/* Legacy internal layout places users at top level */ | |
node->perm = PERM_ROOT; | |
2204: 2202 movs r2, #2 | |
node->userid = strtoul(node->name, NULL, 10); | |
2206: 6be0 ldr r0, [r4, #60] ; 0x3c | |
case PERM_INHERIT: | |
/* Already inherited above */ | |
break; | |
case PERM_LEGACY_PRE_ROOT: | |
/* Legacy internal layout places users at top level */ | |
node->perm = PERM_ROOT; | |
2208: 61a2 str r2, [r4, #24] | |
node->userid = strtoul(node->name, NULL, 10); | |
220a: 2100 movs r1, #0 | |
220c: 220a movs r2, #10 | |
220e: f7fe ef9a blx 1144 <strtoul@plt> | |
2212: 61e0 str r0, [r4, #28] | |
2214: e08d b.n 2332 <create_node_locked+0x1f2> | |
break; | |
case PERM_ROOT: | |
/* Assume masked off by default. */ | |
node->mode = 0770; | |
2216: f44f 76fc mov.w r6, #504 ; 0x1f8 | |
if (!strcasecmp(node->name, "Android")) { | |
221a: 494f ldr r1, [pc, #316] ; (2358 <create_node_locked+0x218>) | |
node->perm = PERM_ROOT; | |
node->userid = strtoul(node->name, NULL, 10); | |
break; | |
case PERM_ROOT: | |
/* Assume masked off by default. */ | |
node->mode = 0770; | |
221c: 8526 strh r6, [r4, #40] ; 0x28 | |
if (!strcasecmp(node->name, "Android")) { | |
221e: 6be6 ldr r6, [r4, #60] ; 0x3c | |
2220: 4479 add r1, pc | |
2222: 4630 mov r0, r6 | |
2224: f7fe eebc blx fa0 <strcasecmp@plt> | |
2228: b908 cbnz r0, 222e <create_node_locked+0xee> | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID; | |
222a: 2103 movs r1, #3 | |
222c: e042 b.n 22b4 <create_node_locked+0x174> | |
node->mode = 0771; | |
} else if (fuse->split_perms) { | |
222e: 7e3b ldrb r3, [r7, #24] | |
2230: 2b00 cmp r3, #0 | |
2232: d07e beq.n 2332 <create_node_locked+0x1f2> | |
if (!strcasecmp(node->name, "DCIM") | |
2234: 4949 ldr r1, [pc, #292] ; (235c <create_node_locked+0x21c>) | |
2236: 4630 mov r0, r6 | |
2238: 4479 add r1, pc | |
223a: f7fe eeb2 blx fa0 <strcasecmp@plt> | |
223e: b128 cbz r0, 224c <create_node_locked+0x10c> | |
|| !strcasecmp(node->name, "Pictures")) { | |
2240: 4947 ldr r1, [pc, #284] ; (2360 <create_node_locked+0x220>) | |
2242: 4630 mov r0, r6 | |
2244: 4479 add r1, pc | |
2246: f7fe eeac blx fa0 <strcasecmp@plt> | |
224a: b910 cbnz r0, 2252 <create_node_locked+0x112> | |
node->gid = AID_SDCARD_PICS; | |
224c: f240 4009 movw r0, #1033 ; 0x409 | |
2250: e026 b.n 22a0 <create_node_locked+0x160> | |
} else if (!strcasecmp(node->name, "Alarms") | |
2252: 4944 ldr r1, [pc, #272] ; (2364 <create_node_locked+0x224>) | |
2254: 4630 mov r0, r6 | |
2256: 4479 add r1, pc | |
2258: f7fe eea2 blx fa0 <strcasecmp@plt> | |
225c: b1f0 cbz r0, 229c <create_node_locked+0x15c> | |
|| !strcasecmp(node->name, "Movies") | |
225e: 4942 ldr r1, [pc, #264] ; (2368 <create_node_locked+0x228>) | |
2260: 4630 mov r0, r6 | |
2262: 4479 add r1, pc | |
2264: f7fe ee9c blx fa0 <strcasecmp@plt> | |
2268: b1c0 cbz r0, 229c <create_node_locked+0x15c> | |
|| !strcasecmp(node->name, "Music") | |
226a: 4940 ldr r1, [pc, #256] ; (236c <create_node_locked+0x22c>) | |
226c: 4630 mov r0, r6 | |
226e: 4479 add r1, pc | |
2270: f7fe ee96 blx fa0 <strcasecmp@plt> | |
2274: b190 cbz r0, 229c <create_node_locked+0x15c> | |
|| !strcasecmp(node->name, "Notifications") | |
2276: 493e ldr r1, [pc, #248] ; (2370 <create_node_locked+0x230>) | |
2278: 4630 mov r0, r6 | |
227a: 4479 add r1, pc | |
227c: f7fe ee90 blx fa0 <strcasecmp@plt> | |
2280: b160 cbz r0, 229c <create_node_locked+0x15c> | |
|| !strcasecmp(node->name, "Podcasts") | |
2282: 493c ldr r1, [pc, #240] ; (2374 <create_node_locked+0x234>) | |
2284: 4630 mov r0, r6 | |
2286: 4479 add r1, pc | |
2288: f7fe ee8a blx fa0 <strcasecmp@plt> | |
228c: b130 cbz r0, 229c <create_node_locked+0x15c> | |
|| !strcasecmp(node->name, "Ringtones")) { | |
228e: 493a ldr r1, [pc, #232] ; (2378 <create_node_locked+0x238>) | |
2290: 4630 mov r0, r6 | |
2292: 4479 add r1, pc | |
2294: f7fe ee84 blx fa0 <strcasecmp@plt> | |
2298: 2800 cmp r0, #0 | |
229a: d14a bne.n 2332 <create_node_locked+0x1f2> | |
node->gid = AID_SDCARD_AV; | |
229c: f240 400a movw r0, #1034 ; 0x40a | |
22a0: 6260 str r0, [r4, #36] ; 0x24 | |
22a2: e046 b.n 2332 <create_node_locked+0x1f2> | |
} | |
} | |
break; | |
case PERM_ANDROID: | |
if (!strcasecmp(node->name, "data")) { | |
22a4: 6be6 ldr r6, [r4, #60] ; 0x3c | |
22a6: 4935 ldr r1, [pc, #212] ; (237c <create_node_locked+0x23c>) | |
22a8: 4630 mov r0, r6 | |
22aa: 4479 add r1, pc | |
22ac: f7fe ee78 blx fa0 <strcasecmp@plt> | |
22b0: b910 cbnz r0, 22b8 <create_node_locked+0x178> | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID_DATA; | |
22b2: 2104 movs r1, #4 | |
22b4: 61a1 str r1, [r4, #24] | |
22b6: e039 b.n 232c <create_node_locked+0x1ec> | |
node->mode = 0771; | |
} else if (!strcasecmp(node->name, "obb")) { | |
22b8: 4931 ldr r1, [pc, #196] ; (2380 <create_node_locked+0x240>) | |
22ba: 4630 mov r0, r6 | |
22bc: 4479 add r1, pc | |
22be: f7fe ee70 blx fa0 <strcasecmp@plt> | |
22c2: b968 cbnz r0, 22e0 <create_node_locked+0x1a0> | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID_OBB; | |
22c4: 2005 movs r0, #5 | |
if (__builtin_constant_p(slen)) { | |
return slen; | |
} | |
#endif /* !defined(__clang__) */ | |
return __strlen_chk(s, bos); | |
22c6: f44f 5180 mov.w r1, #4096 ; 0x1000 | |
node->mode = 0771; | |
22ca: f500 72fa add.w r2, r0, #500 ; 0x1f4 | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID_DATA; | |
node->mode = 0771; | |
} else if (!strcasecmp(node->name, "obb")) { | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID_OBB; | |
22ce: 61a0 str r0, [r4, #24] | |
node->mode = 0771; | |
/* Single OBB directory is always shared */ | |
node->graft_path = fuse->obbpath; | |
22d0: f107 0070 add.w r0, r7, #112 ; 0x70 | |
node->perm = PERM_ANDROID_DATA; | |
node->mode = 0771; | |
} else if (!strcasecmp(node->name, "obb")) { | |
/* App-specific directories inside; let anyone traverse */ | |
node->perm = PERM_ANDROID_OBB; | |
node->mode = 0771; | |
22d4: 8522 strh r2, [r4, #40] ; 0x28 | |
/* Single OBB directory is always shared */ | |
node->graft_path = fuse->obbpath; | |
22d6: 6460 str r0, [r4, #68] ; 0x44 | |
22d8: f7fe ef3a blx 1150 <__strlen_chk@plt> | |
node->graft_pathlen = strlen(fuse->obbpath); | |
22dc: 64a0 str r0, [r4, #72] ; 0x48 | |
22de: e028 b.n 2332 <create_node_locked+0x1f2> | |
} else if (!strcasecmp(node->name, "user")) { | |
22e0: 4928 ldr r1, [pc, #160] ; (2384 <create_node_locked+0x244>) | |
22e2: 4630 mov r0, r6 | |
22e4: 4479 add r1, pc | |
22e6: f7fe ee5c blx fa0 <strcasecmp@plt> | |
22ea: bb10 cbnz r0, 2332 <create_node_locked+0x1f2> | |
/* User directories must only be accessible to system, protected | |
* by sdcard_all. Zygote will bind mount the appropriate user- | |
* specific path. */ | |
node->perm = PERM_ANDROID_USER; | |
22ec: 2106 movs r1, #6 | |
node->gid = AID_SDCARD_ALL; | |
22ee: f240 430b movw r3, #1035 ; 0x40b | |
node->graft_pathlen = strlen(fuse->obbpath); | |
} else if (!strcasecmp(node->name, "user")) { | |
/* User directories must only be accessible to system, protected | |
* by sdcard_all. Zygote will bind mount the appropriate user- | |
* specific path. */ | |
node->perm = PERM_ANDROID_USER; | |
22f2: 61a1 str r1, [r4, #24] | |
node->gid = AID_SDCARD_ALL; | |
22f4: 6263 str r3, [r4, #36] ; 0x24 | |
22f6: e00b b.n 2310 <create_node_locked+0x1d0> | |
node->mode = 0770; | |
} | |
break; | |
case PERM_ANDROID_DATA: | |
case PERM_ANDROID_OBB: | |
appid = (appid_t) hashmapGet(fuse->package_to_appid, node->name); | |
22f8: f507 5783 add.w r7, r7, #4192 ; 0x1060 | |
22fc: 6be1 ldr r1, [r4, #60] ; 0x3c | |
22fe: 6938 ldr r0, [r7, #16] | |
2300: f7fe ef2c blx 115c <hashmapGet@plt> | |
if (appid != 0) { | |
2304: 4601 mov r1, r0 | |
2306: b118 cbz r0, 2310 <create_node_locked+0x1d0> | |
node->uid = multiuser_get_uid(parent->userid, appid); | |
2308: 69e8 ldr r0, [r5, #28] | |
230a: f7fe ef2e blx 1168 <multiuser_get_uid@plt> | |
230e: 6220 str r0, [r4, #32] | |
} | |
node->mode = 0770; | |
2310: f44f 70fc mov.w r0, #504 ; 0x1f8 | |
2314: e00c b.n 2330 <create_node_locked+0x1f0> | |
break; | |
case PERM_ANDROID_USER: | |
/* Root of a secondary user */ | |
node->perm = PERM_ROOT; | |
2316: 2102 movs r1, #2 | |
node->userid = strtoul(node->name, NULL, 10); | |
2318: 6be0 ldr r0, [r4, #60] ; 0x3c | |
} | |
node->mode = 0770; | |
break; | |
case PERM_ANDROID_USER: | |
/* Root of a secondary user */ | |
node->perm = PERM_ROOT; | |
231a: 61a1 str r1, [r4, #24] | |
node->userid = strtoul(node->name, NULL, 10); | |
231c: 220a movs r2, #10 | |
231e: 2100 movs r1, #0 | |
2320: f7fe ef10 blx 1144 <strtoul@plt> | |
node->gid = AID_SDCARD_R; | |
2324: f240 4304 movw r3, #1028 ; 0x404 | |
node->mode = 0770; | |
break; | |
case PERM_ANDROID_USER: | |
/* Root of a secondary user */ | |
node->perm = PERM_ROOT; | |
node->userid = strtoul(node->name, NULL, 10); | |
2328: 61e0 str r0, [r4, #28] | |
node->gid = AID_SDCARD_R; | |
232a: 6263 str r3, [r4, #36] ; 0x24 | |
node->mode = 0771; | |
232c: f240 10f9 movw r0, #505 ; 0x1f9 | |
2330: 8520 strh r0, [r4, #40] ; 0x28 | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
2332: 6822 ldr r2, [r4, #0] | |
ERROR("Zero refcnt %p\n", node); | |
} | |
} | |
static void add_node_to_parent_locked(struct node *node, struct node *parent) { | |
node->parent = parent; | |
2334: 6365 str r5, [r4, #52] ; 0x34 | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
2336: 1c51 adds r1, r2, #1 | |
2338: 6021 str r1, [r4, #0] | |
} | |
} | |
static void add_node_to_parent_locked(struct node *node, struct node *parent) { | |
node->parent = parent; | |
node->next = parent->child; | |
233a: 6b2b ldr r3, [r5, #48] ; 0x30 | |
233c: 62e3 str r3, [r4, #44] ; 0x2c | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
233e: 6828 ldr r0, [r5, #0] | |
} | |
static void add_node_to_parent_locked(struct node *node, struct node *parent) { | |
node->parent = parent; | |
node->next = parent->child; | |
parent->child = node; | |
2340: 632c str r4, [r5, #48] ; 0x30 | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
2342: 1c42 adds r2, r0, #1 | |
2344: 602a str r2, [r5, #0] | |
derive_permissions_locked(fuse, parent, node); | |
acquire_node_locked(node); | |
add_node_to_parent_locked(node, parent); | |
return node; | |
} | |
2346: 4620 mov r0, r4 | |
2348: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
234c: f3af 8000 nop.w | |
2350: 00000001 .word 0x00000001 | |
2354: 00000000 .word 0x00000000 | |
2358: 000014d0 .word 0x000014d0 | |
235c: 000014c0 .word 0x000014c0 | |
2360: 000014b9 .word 0x000014b9 | |
2364: 000014b0 .word 0x000014b0 | |
2368: 000014ab .word 0x000014ab | |
236c: 000014a6 .word 0x000014a6 | |
2370: 000014a0 .word 0x000014a0 | |
2374: 000014a2 .word 0x000014a2 | |
2378: 0000149f .word 0x0000149f | |
237c: 00001491 .word 0x00001491 | |
2380: 00001484 .word 0x00001484 | |
2384: 00001460 .word 0x00001460 | |
00002388 <fuse_reply_entry>: | |
} | |
static int fuse_reply_entry(struct fuse* fuse, __u64 unique, | |
struct node* parent, const char* name, const char* actual_name, | |
const char* path) | |
{ | |
2388: e92d 45f0 stmdb sp!, {r4, r5, r6, r7, r8, sl, lr} | |
238c: 4680 mov r8, r0 | |
238e: ed2d 8b02 vpush {d8} | |
2392: b0bd sub sp, #244 ; 0xf4 | |
struct node* node; | |
struct fuse_entry_out out; | |
struct stat s; | |
if (lstat(path, &s) < 0) { | |
2394: a902 add r1, sp, #8 | |
2396: 9849 ldr r0, [sp, #292] ; 0x124 | |
} | |
static int fuse_reply_entry(struct fuse* fuse, __u64 unique, | |
struct node* parent, const char* name, const char* actual_name, | |
const char* path) | |
{ | |
2398: ec43 2b18 vmov d8, r2, r3 | |
239c: 9d46 ldr r5, [sp, #280] ; 0x118 | |
239e: 9c47 ldr r4, [sp, #284] ; 0x11c | |
struct node* node; | |
struct fuse_entry_out out; | |
struct stat s; | |
if (lstat(path, &s) < 0) { | |
23a0: f7fe eea6 blx 10f0 <lstat@plt> | |
23a4: 2800 cmp r0, #0 | |
23a6: da04 bge.n 23b2 <fuse_reply_entry+0x2a> | |
return -errno; | |
23a8: f7fe ee24 blx ff4 <__errno@plt> | |
23ac: 6801 ldr r1, [r0, #0] | |
23ae: 4248 negs r0, r1 | |
23b0: e078 b.n 24a4 <fuse_reply_entry+0x11c> | |
} | |
pthread_mutex_lock(&fuse->lock); | |
23b2: 4640 mov r0, r8 | |
23b4: f7fe ee36 blx 1024 <pthread_mutex_lock@plt> | |
return node; | |
} | |
static struct node *lookup_child_by_name_locked(struct node *node, const char *name) | |
{ | |
for (node = node->child; node; node = node->next) { | |
23b8: 6b2e ldr r6, [r5, #48] ; 0x30 | |
23ba: e006 b.n 23ca <fuse_reply_entry+0x42> | |
/* use exact string comparison, nodes that differ by case | |
* must be considered distinct even if they refer to the same | |
* underlying file as otherwise operations such as "mv x x" | |
* will not work because the source and target nodes are the same. */ | |
if (!strcmp(name, node->name)) { | |
23bc: 4620 mov r0, r4 | |
23be: 6bf1 ldr r1, [r6, #60] ; 0x3c | |
23c0: f7fe eea8 blx 1114 <strcmp@plt> | |
23c4: 2800 cmp r0, #0 | |
23c6: d05f beq.n 2488 <fuse_reply_entry+0x100> | |
return node; | |
} | |
static struct node *lookup_child_by_name_locked(struct node *node, const char *name) | |
{ | |
for (node = node->child; node; node = node->next) { | |
23c8: 6af6 ldr r6, [r6, #44] ; 0x2c | |
23ca: 2e00 cmp r6, #0 | |
23cc: d1f6 bne.n 23bc <fuse_reply_entry+0x34> | |
23ce: e05f b.n 2490 <fuse_reply_entry+0x108> | |
} | |
pthread_mutex_lock(&fuse->lock); | |
node = acquire_or_create_child_locked(fuse, parent, name, actual_name); | |
if (!node) { | |
pthread_mutex_unlock(&fuse->lock); | |
23d0: 4640 mov r0, r8 | |
23d2: f7fe ee2e blx 1030 <pthread_mutex_unlock@plt> | |
return -ENOMEM; | |
23d6: f06f 000b mvn.w r0, #11 | |
23da: e063 b.n 24a4 <fuse_reply_entry+0x11c> | |
} | |
memset(&out, 0, sizeof(out)); | |
23dc: f10d 0a70 add.w sl, sp, #112 ; 0x70 | |
return __builtin___strncat_chk(dest, src, n, __bos(dest)); | |
} | |
__BIONIC_FORTIFY_INLINE | |
void* memset(void *s, int c, size_t n) { | |
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0)); | |
23e0: 2780 movs r7, #128 ; 0x80 | |
23e2: 2100 movs r1, #0 | |
23e4: 463a mov r2, r7 | |
23e6: 4650 mov r0, sl | |
23e8: f7fe ee0a blx 1000 <memset@plt> | |
return actual; | |
} | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
23ec: e9d6 2302 ldrd r2, r3, [r6, #8] | |
attr->size = s->st_size; | |
23f0: e9dd 450e ldrd r4, r5, [sp, #56] ; 0x38 | |
attr->blocks = s->st_blocks; | |
23f4: e9dd 0112 ldrd r0, r1, [sp, #72] ; 0x48 | |
return actual; | |
} | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
23f8: e9cd 2326 strd r2, r3, [sp, #152] ; 0x98 | |
attr->size = s->st_size; | |
23fc: e9cd 4528 strd r4, r5, [sp, #160] ; 0xa0 | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
2400: 9b16 ldr r3, [sp, #88] ; 0x58 | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
2402: 9d14 ldr r5, [sp, #80] ; 0x50 | |
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node) | |
{ | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
2404: e9cd 012a strd r0, r1, [sp, #168] ; 0xa8 | |
attr->atime = s->st_atime; | |
2408: 2100 movs r1, #0 | |
240a: 912d str r1, [sp, #180] ; 0xb4 | |
240c: 952c str r5, [sp, #176] ; 0xb0 | |
attr->mtime = s->st_mtime; | |
240e: 932e str r3, [sp, #184] ; 0xb8 | |
2410: 912f str r1, [sp, #188] ; 0xbc | |
attr->ctime = s->st_ctime; | |
2412: 9131 str r1, [sp, #196] ; 0xc4 | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
2414: 9d06 ldr r5, [sp, #24] | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
2416: 9a18 ldr r2, [sp, #96] ; 0x60 | |
attr->atimensec = s->st_atime_nsec; | |
2418: 9c15 ldr r4, [sp, #84] ; 0x54 | |
attr->mtimensec = s->st_mtime_nsec; | |
241a: 9817 ldr r0, [sp, #92] ; 0x5c | |
attr->ctimensec = s->st_ctime_nsec; | |
241c: 9919 ldr r1, [sp, #100] ; 0x64 | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
241e: 9b07 ldr r3, [sp, #28] | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
2420: 9535 str r5, [sp, #212] ; 0xd4 | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
2422: 9033 str r0, [sp, #204] ; 0xcc | |
attr->uid = node->uid; | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
2424: f405 70e0 and.w r0, r5, #448 ; 0x1c0 | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
2428: 9134 str r1, [sp, #208] ; 0xd0 | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
242a: 1181 asrs r1, r0, #6 | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
242c: 9336 str r3, [sp, #216] ; 0xd8 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
242e: f405 4570 and.w r5, r5, #61440 ; 0xf000 | |
attr->ino = node->nid; | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
2432: 9230 str r2, [sp, #192] ; 0xc0 | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
2434: ea41 03d0 orr.w r3, r1, r0, lsr #3 | |
attr->size = s->st_size; | |
attr->blocks = s->st_blocks; | |
attr->atime = s->st_atime; | |
attr->mtime = s->st_mtime; | |
attr->ctime = s->st_ctime; | |
attr->atimensec = s->st_atime_nsec; | |
2438: 9432 str r4, [sp, #200] ; 0xc8 | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
243a: 6a32 ldr r2, [r6, #32] | |
attr->gid = node->gid; | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
243c: ea43 0c00 orr.w ip, r3, r0 | |
attr->mtimensec = s->st_mtime_nsec; | |
attr->ctimensec = s->st_ctime_nsec; | |
attr->mode = s->st_mode; | |
attr->nlink = s->st_nlink; | |
attr->uid = node->uid; | |
2440: 9237 str r2, [sp, #220] ; 0xdc | |
attr->gid = node->gid; | |
2442: 6a74 ldr r4, [r6, #36] ; 0x24 | |
2444: 9438 str r4, [sp, #224] ; 0xe0 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
2446: 8d32 ldrh r2, [r6, #40] ; 0x28 | |
2448: ea0c 0402 and.w r4, ip, r2 | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
244c: ea44 0005 orr.w r0, r4, r5 | |
pthread_mutex_unlock(&fuse->lock); | |
return -ENOMEM; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
2450: 240a movs r4, #10 | |
2452: 2500 movs r5, #0 | |
/* Filter requested mode based on underlying file, and | |
* pass through file type. */ | |
int owner_mode = s->st_mode & 0700; | |
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); | |
attr->mode = (attr->mode & S_IFMT) | filtered_mode; | |
2454: 9035 str r0, [sp, #212] ; 0xd4 | |
pthread_mutex_unlock(&fuse->lock); | |
return -ENOMEM; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
2456: e9cd 4522 strd r4, r5, [sp, #136] ; 0x88 | |
out.entry_valid = 10; | |
out.nodeid = node->nid; | |
out.generation = node->gen; | |
pthread_mutex_unlock(&fuse->lock); | |
245a: 4640 mov r0, r8 | |
return -ENOMEM; | |
} | |
memset(&out, 0, sizeof(out)); | |
attr_from_stat(&out.attr, &s, node); | |
out.attr_valid = 10; | |
out.entry_valid = 10; | |
245c: e9cd 4520 strd r4, r5, [sp, #128] ; 0x80 | |
out.nodeid = node->nid; | |
2460: e9d6 2302 ldrd r2, r3, [r6, #8] | |
2464: e9cd 231c strd r2, r3, [sp, #112] ; 0x70 | |
out.generation = node->gen; | |
2468: e9d6 4504 ldrd r4, r5, [r6, #16] | |
246c: e9cd 451e strd r4, r5, [sp, #120] ; 0x78 | |
pthread_mutex_unlock(&fuse->lock); | |
2470: f7fe edde blx 1030 <pthread_mutex_unlock@plt> | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
2474: 4640 mov r0, r8 | |
2476: f8cd a000 str.w sl, [sp] | |
247a: 9701 str r7, [sp, #4] | |
247c: ec53 2b18 vmov r2, r3, d8 | |
2480: f7ff f852 bl 1528 <fuse_reply> | |
return NO_STATUS; | |
2484: 2001 movs r0, #1 | |
2486: e00d b.n 24a4 <fuse_reply_entry+0x11c> | |
return (__u64) (uintptr_t) ptr; | |
} | |
static void acquire_node_locked(struct node* node) | |
{ | |
node->refcount++; | |
2488: 6833 ldr r3, [r6, #0] | |
248a: 1c58 adds r0, r3, #1 | |
248c: 6030 str r0, [r6, #0] | |
248e: e7a5 b.n 23dc <fuse_reply_entry+0x54> | |
{ | |
struct node* child = lookup_child_by_name_locked(parent, name); | |
if (child) { | |
acquire_node_locked(child); | |
} else { | |
child = create_node_locked(fuse, parent, name, actual_name); | |
2490: 4640 mov r0, r8 | |
2492: 4629 mov r1, r5 | |
2494: 4622 mov r2, r4 | |
2496: 9b48 ldr r3, [sp, #288] ; 0x120 | |
2498: f7ff fe52 bl 2140 <create_node_locked> | |
return -errno; | |
} | |
pthread_mutex_lock(&fuse->lock); | |
node = acquire_or_create_child_locked(fuse, parent, name, actual_name); | |
if (!node) { | |
249c: 4606 mov r6, r0 | |
249e: 2800 cmp r0, #0 | |
24a0: d19c bne.n 23dc <fuse_reply_entry+0x54> | |
24a2: e795 b.n 23d0 <fuse_reply_entry+0x48> | |
out.nodeid = node->nid; | |
out.generation = node->gen; | |
pthread_mutex_unlock(&fuse->lock); | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
24a4: b03d add sp, #244 ; 0xf4 | |
24a6: ecbd 8b02 vpop {d8} | |
24aa: e8bd 85f0 ldmia.w sp!, {r4, r5, r6, r7, r8, sl, pc} | |
... | |
000024b0 <handle_lookup.isra.22>: | |
out.attr_valid = 10; | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler, | |
24b0: 4b2d ldr r3, [pc, #180] ; (2568 <handle_lookup.isra.22+0xb8>) | |
24b2: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} | |
24b6: 4615 mov r5, r2 | |
24b8: 4a2c ldr r2, [pc, #176] ; (256c <handle_lookup.isra.22+0xbc>) | |
24ba: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000 | |
24be: 447b add r3, pc | |
24c0: b086 sub sp, #24 | |
24c2: 460f mov r7, r1 | |
24c4: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
24c8: f853 8002 ldr.w r8, [r3, r2] | |
24cc: 4604 mov r4, r0 | |
24ce: 3114 adds r1, #20 | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
parent_path, sizeof(parent_path)); | |
24d0: f10d 0a14 add.w sl, sp, #20 | |
out.attr_valid = 10; | |
fuse_reply(fuse, unique, &out, sizeof(out)); | |
return NO_STATUS; | |
} | |
static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler, | |
24d4: f8d8 3000 ldr.w r3, [r8] | |
24d8: 600b str r3, [r1, #0] | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
24da: f7fe eda4 blx 1024 <pthread_mutex_lock@plt> | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
24de: e9d7 2304 ldrd r2, r3, [r7, #16] | |
24e2: 4620 mov r0, r4 | |
24e4: f8cd a000 str.w sl, [sp] | |
24e8: f7ff fa16 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
24ec: 4606 mov r6, r0 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid, | |
parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
24ee: 4620 mov r0, r4 | |
24f0: f7fe ed9e blx 1030 <pthread_mutex_unlock@plt> | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
24f4: b916 cbnz r6, 24fc <handle_lookup.isra.22+0x4c> | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
24f6: f06f 0001 mvn.w r0, #1 | |
24fa: e025 b.n 2548 <handle_lookup.isra.22+0x98> | |
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid, | |
parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1))) { | |
24fc: f50d 5980 add.w r9, sp, #4096 ; 0x1000 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid, | |
parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
2500: 4650 mov r0, sl | |
child_path, sizeof(child_path), 1))) { | |
2502: f109 0914 add.w r9, r9, #20 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid, | |
parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
2506: 4629 mov r1, r5 | |
2508: 464a mov r2, r9 | |
250a: 2301 movs r3, #1 | |
250c: f7ff f9a2 bl 1854 <find_file_within.constprop.27> | |
2510: 4682 mov sl, r0 | |
2512: 2800 cmp r0, #0 | |
2514: d0ef beq.n 24f6 <handle_lookup.isra.22+0x46> | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK, false)) { | |
2516: 2204 movs r2, #4 | |
2518: 2300 movs r3, #0 | |
251a: e88d 000c stmia.w sp, {r2, r3} | |
251e: 4620 mov r0, r4 | |
2520: 4639 mov r1, r7 | |
2522: 4632 mov r2, r6 | |
2524: 462b mov r3, r5 | |
2526: f7fe ffc7 bl 14b8 <check_caller_access_to_name> | |
252a: b158 cbz r0, 2544 <handle_lookup.isra.22+0x94> | |
return -EACCES; | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
252c: e9d7 2302 ldrd r2, r3, [r7, #8] | |
2530: 4620 mov r0, r4 | |
2532: 9600 str r6, [sp, #0] | |
2534: 9501 str r5, [sp, #4] | |
2536: f8cd a008 str.w sl, [sp, #8] | |
253a: f8cd 900c str.w r9, [sp, #12] | |
253e: f7ff ff23 bl 2388 <fuse_reply_entry> | |
2542: e001 b.n 2548 <handle_lookup.isra.22+0x98> | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK, false)) { | |
return -EACCES; | |
2544: f06f 000c mvn.w r0, #12 | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
2548: f50d 5200 add.w r2, sp, #8192 ; 0x2000 | |
254c: 3214 adds r2, #20 | |
254e: 6811 ldr r1, [r2, #0] | |
2550: f8d8 3000 ldr.w r3, [r8] | |
2554: 4299 cmp r1, r3 | |
2556: d001 beq.n 255c <handle_lookup.isra.22+0xac> | |
2558: f7fe ed76 blx 1048 <__stack_chk_fail@plt> | |
255c: b006 add sp, #24 | |
255e: f50d 5d00 add.w sp, sp, #8192 ; 0x2000 | |
2562: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} | |
2566: bf00 nop | |
2568: 000029fa .word 0x000029fa | |
256c: fffffff4 .word 0xfffffff4 | |
00002570 <handle_mknod.isra.23>: | |
} | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
} | |
static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler, | |
2570: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
2574: 461f mov r7, r3 | |
2576: 4b37 ldr r3, [pc, #220] ; (2654 <handle_mknod.isra.23+0xe4>) | |
2578: 4692 mov sl, r2 | |
257a: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000 | |
257e: 460d mov r5, r1 | |
2580: 4a35 ldr r2, [pc, #212] ; (2658 <handle_mknod.isra.23+0xe8>) | |
2582: b089 sub sp, #36 ; 0x24 | |
2584: 447b add r3, pc | |
2586: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
258a: 4604 mov r4, r0 | |
258c: 311c adds r1, #28 | |
258e: 589e ldr r6, [r3, r2] | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
parent_path, sizeof(parent_path)); | |
2590: f10d 091c add.w r9, sp, #28 | |
} | |
} | |
return fuse_reply_attr(fuse, hdr->unique, node, path); | |
} | |
static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler, | |
2594: 6833 ldr r3, [r6, #0] | |
2596: 600b str r3, [r1, #0] | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
2598: f7fe ed44 blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
259c: 4629 mov r1, r5 | |
259e: 4620 mov r0, r4 | |
25a0: f7ff f839 bl 1616 <get_caller_has_rw_locked> | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
25a4: e9d5 2304 ldrd r2, r3, [r5, #16] | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
25a8: 4683 mov fp, r0 | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
25aa: f8cd 9000 str.w r9, [sp] | |
25ae: 4620 mov r0, r4 | |
25b0: f7ff f9b2 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
25b4: 4680 mov r8, r0 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
25b6: 4620 mov r0, r4 | |
25b8: f7fe ed3a blx 1030 <pthread_mutex_unlock@plt> | |
25bc: 9605 str r6, [sp, #20] | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
25be: f1b8 0f00 cmp.w r8, #0 | |
25c2: d102 bne.n 25ca <handle_mknod.isra.23+0x5a> | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
25c4: f06f 0001 mvn.w r0, #1 | |
25c8: e035 b.n 2636 <handle_mknod.isra.23+0xc6> | |
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1))) { | |
25ca: f50d 5680 add.w r6, sp, #4096 ; 0x1000 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
25ce: 4648 mov r0, r9 | |
child_path, sizeof(child_path), 1))) { | |
25d0: 361c adds r6, #28 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
25d2: 4639 mov r1, r7 | |
25d4: 4632 mov r2, r6 | |
25d6: 2301 movs r3, #1 | |
25d8: f7ff f93c bl 1854 <find_file_within.constprop.27> | |
25dc: 4681 mov r9, r0 | |
25de: 2800 cmp r0, #0 | |
25e0: d0f0 beq.n 25c4 <handle_mknod.isra.23+0x54> | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
25e2: 2302 movs r3, #2 | |
25e4: 4620 mov r0, r4 | |
25e6: e88d 0808 stmia.w sp, {r3, fp} | |
25ea: 4629 mov r1, r5 | |
25ec: 4642 mov r2, r8 | |
25ee: 463b mov r3, r7 | |
25f0: f7fe ff62 bl 14b8 <check_caller_access_to_name> | |
25f4: b1e8 cbz r0, 2632 <handle_mknod.isra.23+0xc2> | |
return -EACCES; | |
} | |
__u32 mode = (req->mode & (~0777)) | 0664; | |
25f6: f8da 0000 ldr.w r0, [sl] | |
25fa: f400 427e and.w r2, r0, #65024 ; 0xfe00 | |
if (mknod(child_path, mode, req->rdev) < 0) { | |
25fe: 4630 mov r0, r6 | |
2600: f442 71da orr.w r1, r2, #436 ; 0x1b4 | |
2604: f8da 2004 ldr.w r2, [sl, #4] | |
2608: f7fe edb4 blx 1174 <mknod@plt> | |
260c: 2800 cmp r0, #0 | |
260e: da04 bge.n 261a <handle_mknod.isra.23+0xaa> | |
return -errno; | |
2610: f7fe ecf0 blx ff4 <__errno@plt> | |
2614: 6803 ldr r3, [r0, #0] | |
2616: 4258 negs r0, r3 | |
2618: e00d b.n 2636 <handle_mknod.isra.23+0xc6> | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
261a: e9d5 2302 ldrd r2, r3, [r5, #8] | |
261e: 4620 mov r0, r4 | |
2620: f8cd 8000 str.w r8, [sp] | |
2624: 9701 str r7, [sp, #4] | |
2626: f8cd 9008 str.w r9, [sp, #8] | |
262a: 9603 str r6, [sp, #12] | |
262c: f7ff feac bl 2388 <fuse_reply_entry> | |
2630: e001 b.n 2636 <handle_mknod.isra.23+0xc6> | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
return -EACCES; | |
2632: f06f 000c mvn.w r0, #12 | |
__u32 mode = (req->mode & (~0777)) | 0664; | |
if (mknod(child_path, mode, req->rdev) < 0) { | |
return -errno; | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
2636: 9b05 ldr r3, [sp, #20] | |
2638: f50d 5100 add.w r1, sp, #8192 ; 0x2000 | |
263c: 311c adds r1, #28 | |
263e: 680a ldr r2, [r1, #0] | |
2640: 6819 ldr r1, [r3, #0] | |
2642: 428a cmp r2, r1 | |
2644: d001 beq.n 264a <handle_mknod.isra.23+0xda> | |
2646: f7fe ed00 blx 1048 <__stack_chk_fail@plt> | |
264a: b009 add sp, #36 ; 0x24 | |
264c: f50d 5d00 add.w sp, sp, #8192 ; 0x2000 | |
2650: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
2654: 00002934 .word 0x00002934 | |
2658: fffffff4 .word 0xfffffff4 | |
0000265c <handle_mkdir.isra.24>: | |
static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler, | |
265c: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
2660: 461d mov r5, r3 | |
2662: f8df 9180 ldr.w r9, [pc, #384] ; 27e4 <handle_mkdir.isra.24+0x188> | |
2666: f5ad 5d40 sub.w sp, sp, #12288 ; 0x3000 | |
266a: b089 sub sp, #36 ; 0x24 | |
266c: 4688 mov r8, r1 | |
266e: 4b5e ldr r3, [pc, #376] ; (27e8 <handle_mkdir.isra.24+0x18c>) | |
2670: f50d 5140 add.w r1, sp, #12288 ; 0x3000 | |
2674: 44f9 add r9, pc | |
2676: 9204 str r2, [sp, #16] | |
2678: 4604 mov r4, r0 | |
267a: 311c adds r1, #28 | |
267c: f859 7003 ldr.w r7, [r9, r3] | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
parent_path, sizeof(parent_path)); | |
2680: f10d 0a1c add.w sl, sp, #28 | |
return -errno; | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler, | |
2684: 683a ldr r2, [r7, #0] | |
2686: 600a str r2, [r1, #0] | |
struct node* parent_node; | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
2688: f7fe eccc blx 1024 <pthread_mutex_lock@plt> | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
268c: 4641 mov r1, r8 | |
268e: 4620 mov r0, r4 | |
2690: f7fe ffc1 bl 1616 <get_caller_has_rw_locked> | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
2694: e9d8 2304 ldrd r2, r3, [r8, #16] | |
char parent_path[PATH_MAX]; | |
char child_path[PATH_MAX]; | |
const char* actual_name; | |
pthread_mutex_lock(&fuse->lock); | |
has_rw = get_caller_has_rw_locked(fuse, hdr); | |
2698: 4683 mov fp, r0 | |
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, | |
269a: f8cd a000 str.w sl, [sp] | |
269e: 4620 mov r0, r4 | |
26a0: f7ff f93a bl 1918 <lookup_node_and_path_by_id_locked.constprop.28> | |
26a4: 4606 mov r6, r0 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
26a6: 4620 mov r0, r4 | |
26a8: f7fe ecc2 blx 1030 <pthread_mutex_unlock@plt> | |
26ac: 9705 str r7, [sp, #20] | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
26ae: b906 cbnz r6, 26b2 <handle_mkdir.isra.24+0x56> | |
26b0: e079 b.n 27a6 <handle_mkdir.isra.24+0x14a> | |
child_path, sizeof(child_path), 1))) { | |
26b2: f50d 5780 add.w r7, sp, #4096 ; 0x1000 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
26b6: 4650 mov r0, sl | |
child_path, sizeof(child_path), 1))) { | |
26b8: 371c adds r7, #28 | |
parent_path, sizeof(parent_path)); | |
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token, | |
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?"); | |
pthread_mutex_unlock(&fuse->lock); | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
26ba: 4629 mov r1, r5 | |
26bc: 463a mov r2, r7 | |
26be: 2301 movs r3, #1 | |
26c0: f7ff f8c8 bl 1854 <find_file_within.constprop.27> | |
26c4: 4682 mov sl, r0 | |
26c6: 2800 cmp r0, #0 | |
26c8: d06d beq.n 27a6 <handle_mkdir.isra.24+0x14a> | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
26ca: 2302 movs r3, #2 | |
26cc: 4620 mov r0, r4 | |
26ce: e88d 0808 stmia.w sp, {r3, fp} | |
26d2: 4641 mov r1, r8 | |
26d4: 4632 mov r2, r6 | |
26d6: 462b mov r3, r5 | |
26d8: f7fe feee bl 14b8 <check_caller_access_to_name> | |
26dc: 2800 cmp r0, #0 | |
26de: d070 beq.n 27c2 <handle_mkdir.isra.24+0x166> | |
return -EACCES; | |
} | |
__u32 mode = (req->mode & (~0777)) | 0775; | |
26e0: 9804 ldr r0, [sp, #16] | |
26e2: 6803 ldr r3, [r0, #0] | |
if (mkdir(child_path, mode) < 0) { | |
26e4: 4638 mov r0, r7 | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
return -EACCES; | |
} | |
__u32 mode = (req->mode & (~0777)) | 0775; | |
26e6: f403 427e and.w r2, r3, #65024 ; 0xfe00 | |
if (mkdir(child_path, mode) < 0) { | |
26ea: f442 7cfe orr.w ip, r2, #508 ; 0x1fc | |
26ee: f04c 0101 orr.w r1, ip, #1 | |
26f2: f7fe ed46 blx 1180 <mkdir@plt> | |
26f6: 2800 cmp r0, #0 | |
26f8: da04 bge.n 2704 <handle_mkdir.isra.24+0xa8> | |
return -errno; | |
26fa: f7fe ec7c blx ff4 <__errno@plt> | |
26fe: 6803 ldr r3, [r0, #0] | |
2700: 4258 negs r0, r3 | |
2702: e060 b.n 27c6 <handle_mkdir.isra.24+0x16a> | |
} | |
/* When creating /Android/data and /Android/obb, mark them as .nomedia */ | |
if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "data")) { | |
2704: 69b1 ldr r1, [r6, #24] | |
2706: 2903 cmp r1, #3 | |
2708: d122 bne.n 2750 <handle_mkdir.isra.24+0xf4> | |
270a: 4938 ldr r1, [pc, #224] ; (27ec <handle_mkdir.isra.24+0x190>) | |
270c: 4628 mov r0, r5 | |
270e: 4479 add r1, pc | |
2710: f7fe ec46 blx fa0 <strcasecmp@plt> | |
2714: b9e0 cbnz r0, 2750 <handle_mkdir.isra.24+0xf4> | |
#else | |
__BIONIC_FORTIFY_INLINE | |
__printflike(3, 4) | |
int snprintf(char *dest, size_t size, const char *format, ...) | |
{ | |
return __builtin___snprintf_chk(dest, size, 0, | |
2716: 4a36 ldr r2, [pc, #216] ; (27f0 <handle_mkdir.isra.24+0x194>) | |
2718: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
271c: 301c adds r0, #28 | |
271e: f44f 5180 mov.w r1, #4096 ; 0x1000 | |
2722: 463b mov r3, r7 | |
2724: 447a add r2, pc | |
2726: f7fe ed32 blx 118c <snprintf@plt> | |
char nomedia[PATH_MAX]; | |
snprintf(nomedia, PATH_MAX, "%s/.nomedia", child_path); | |
if (touch(nomedia, 0664) != 0) { | |
272a: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
272e: 301c adds r0, #28 | |
2730: f7ff f866 bl 1800 <touch.constprop.26> | |
2734: b160 cbz r0, 2750 <handle_mkdir.isra.24+0xf4> | |
ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno)); | |
2736: f7fe ec5e blx ff4 <__errno@plt> | |
273a: 6800 ldr r0, [r0, #0] | |
273c: f7fe eca2 blx 1084 <strerror@plt> | |
2740: 492c ldr r1, [pc, #176] ; (27f4 <handle_mkdir.isra.24+0x198>) | |
2742: 4603 mov r3, r0 | |
2744: f859 0001 ldr.w r0, [r9, r1] | |
2748: 492b ldr r1, [pc, #172] ; (27f8 <handle_mkdir.isra.24+0x19c>) | |
274a: 30a8 adds r0, #168 ; 0xa8 | |
274c: 4479 add r1, pc | |
274e: e025 b.n 279c <handle_mkdir.isra.24+0x140> | |
return -ENOENT; | |
} | |
} | |
if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "obb")) { | |
2750: 69b0 ldr r0, [r6, #24] | |
2752: 2803 cmp r0, #3 | |
2754: d12a bne.n 27ac <handle_mkdir.isra.24+0x150> | |
2756: 4929 ldr r1, [pc, #164] ; (27fc <handle_mkdir.isra.24+0x1a0>) | |
2758: 4628 mov r0, r5 | |
275a: 4479 add r1, pc | |
275c: f7fe ec20 blx fa0 <strcasecmp@plt> | |
2760: bb20 cbnz r0, 27ac <handle_mkdir.isra.24+0x150> | |
2762: 4a27 ldr r2, [pc, #156] ; (2800 <handle_mkdir.isra.24+0x1a4>) | |
2764: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
2768: 301c adds r0, #28 | |
276a: f44f 5180 mov.w r1, #4096 ; 0x1000 | |
276e: f104 0370 add.w r3, r4, #112 ; 0x70 | |
2772: 447a add r2, pc | |
2774: f7fe ed0a blx 118c <snprintf@plt> | |
char nomedia[PATH_MAX]; | |
snprintf(nomedia, PATH_MAX, "%s/.nomedia", fuse->obbpath); | |
if (touch(nomedia, 0664) != 0) { | |
2778: f50d 5000 add.w r0, sp, #8192 ; 0x2000 | |
277c: 301c adds r0, #28 | |
277e: f7ff f83f bl 1800 <touch.constprop.26> | |
2782: b198 cbz r0, 27ac <handle_mkdir.isra.24+0x150> | |
ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno)); | |
2784: f7fe ec36 blx ff4 <__errno@plt> | |
2788: 6800 ldr r0, [r0, #0] | |
278a: f7fe ec7c blx 1084 <strerror@plt> | |
278e: 4a19 ldr r2, [pc, #100] ; (27f4 <handle_mkdir.isra.24+0x198>) | |
2790: 4603 mov r3, r0 | |
2792: 491c ldr r1, [pc, #112] ; (2804 <handle_mkdir.isra.24+0x1a8>) | |
2794: f859 0002 ldr.w r0, [r9, r2] | |
2798: 4479 add r1, pc | |
279a: 30a8 adds r0, #168 ; 0xa8 | |
279c: f50d 5200 add.w r2, sp, #8192 ; 0x2000 | |
27a0: 321c adds r2, #28 | |
27a2: f7fe ebf8 blx f94 <fprintf@plt> | |
return -ENOENT; | |
27a6: f06f 0001 mvn.w r0, #1 | |
27aa: e00c b.n 27c6 <handle_mkdir.isra.24+0x16a> | |
} | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
27ac: e9d8 2302 ldrd r2, r3, [r8, #8] | |
27b0: 4620 mov r0, r4 | |
27b2: 9600 str r6, [sp, #0] | |
27b4: 9501 str r5, [sp, #4] | |
27b6: f8cd a008 str.w sl, [sp, #8] | |
27ba: 9703 str r7, [sp, #12] | |
27bc: f7ff fde4 bl 2388 <fuse_reply_entry> | |
27c0: e001 b.n 27c6 <handle_mkdir.isra.24+0x16a> | |
if (!parent_node || !(actual_name = find_file_within(parent_path, name, | |
child_path, sizeof(child_path), 1))) { | |
return -ENOENT; | |
} | |
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) { | |
return -EACCES; | |
27c2: f06f 000c mvn.w r0, #12 | |
return -ENOENT; | |
} | |
} | |
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path); | |
} | |
27c6: 9905 ldr r1, [sp, #20] | |
27c8: f50d 5240 add.w r2, sp, #12288 ; 0x3000 | |
27cc: 321c adds r2, #28 | |
27ce: 6812 ldr r2, [r2, #0] | |
27d0: 680b ldr r3, [r1, #0] | |
27d2: 429a cmp r2, r3 | |
27d4: d001 beq.n 27da <handle_mkdir.isra.24+0x17e> | |
27d6: f7fe ec38 blx 1048 <__stack_chk_fail@plt> | |
27da: b009 add sp, #36 ; 0x24 | |
27dc: f50d 5d40 add.w sp, sp, #12288 ; 0x3000 | |
27e0: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
27e4: 00002844 .word 0x00002844 | |
27e8: fffffff4 .word 0xfffffff4 | |
27ec: 0000102d .word 0x0000102d | |
27f0: 00001025 .word 0x00001025 | |
27f4: fffffff0 .word 0xfffffff0 | |
27f8: 00001009 .word 0x00001009 | |
27fc: 00000fe6 .word 0x00000fe6 | |
2800: 00000fd7 .word 0x00000fd7 | |
2804: 00000fbd .word 0x00000fbd | |
00002808 <handle_fuse_requests>: | |
} | |
} | |
} | |
static void handle_fuse_requests(struct fuse_handler* handler) | |
{ | |
2808: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
280c: 4606 mov r6, r0 | |
for (;;) { | |
ssize_t len = read(fuse->fd, | |
handler->request_buffer, sizeof(handler->request_buffer)); | |
if (len < 0) { | |
if (errno != EINTR) { | |
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno); | |
280e: f8df 92ac ldr.w r9, [pc, #684] ; 2abc <handle_fuse_requests+0x2b4> | |
continue; | |
} | |
const struct fuse_in_header *hdr = (void*)handler->request_buffer; | |
if (hdr->len != (size_t)len) { | |
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n", | |
2812: f8df a2ac ldr.w sl, [pc, #684] ; 2ac0 <handle_fuse_requests+0x2b8> | |
} | |
continue; | |
} | |
if ((size_t)len < sizeof(struct fuse_in_header)) { | |
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len); | |
2816: f8df b2ac ldr.w fp, [pc, #684] ; 2ac4 <handle_fuse_requests+0x2bc> | |
for (;;) { | |
ssize_t len = read(fuse->fd, | |
handler->request_buffer, sizeof(handler->request_buffer)); | |
if (len < 0) { | |
if (errno != EINTR) { | |
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno); | |
281a: 44f9 add r9, pc | |
} | |
} | |
} | |
static void handle_fuse_requests(struct fuse_handler* handler) | |
{ | |
281c: ed2d 8b02 vpush {d8} | |
2820: b08b sub sp, #44 ; 0x2c | |
struct fuse* fuse = handler->fuse; | |
2822: 6807 ldr r7, [r0, #0] | |
continue; | |
} | |
const struct fuse_in_header *hdr = (void*)handler->request_buffer; | |
if (hdr->len != (size_t)len) { | |
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n", | |
2824: 44fa add sl, pc | |
} | |
} | |
} | |
static void handle_fuse_requests(struct fuse_handler* handler) | |
{ | |
2826: f8df 82a0 ldr.w r8, [pc, #672] ; 2ac8 <handle_fuse_requests+0x2c0> | |
} | |
continue; | |
} | |
if ((size_t)len < sizeof(struct fuse_in_header)) { | |
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len); | |
282a: 44fb add fp, pc | |
} | |
} | |
} | |
static void handle_fuse_requests(struct fuse_handler* handler) | |
{ | |
282c: 44f8 add r8, pc | |
struct fuse* fuse = handler->fuse; | |
for (;;) { | |
ssize_t len = read(fuse->fd, | |
handler->request_buffer, sizeof(handler->request_buffer)); | |
282e: f106 0408 add.w r4, r6, #8 | |
static void handle_fuse_requests(struct fuse_handler* handler) | |
{ | |
struct fuse* fuse = handler->fuse; | |
for (;;) { | |
ssize_t len = read(fuse->fd, | |
2832: 6938 ldr r0, [r7, #16] | |
2834: 4621 mov r1, r4 | |
2836: 4aa0 ldr r2, [pc, #640] ; (2ab8 <handle_fuse_requests+0x2b0>) | |
2838: f7fe ecae blx 1198 <read@plt> | |
handler->request_buffer, sizeof(handler->request_buffer)); | |
if (len < 0) { | |
283c: 1e03 subs r3, r0, #0 | |
283e: da0b bge.n 2858 <handle_fuse_requests+0x50> | |
if (errno != EINTR) { | |
2840: f7fe ebd8 blx ff4 <__errno@plt> | |
2844: 6802 ldr r2, [r0, #0] | |
2846: 2a04 cmp r2, #4 | |
2848: d0f1 beq.n 282e <handle_fuse_requests+0x26> | |
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno); | |
284a: 4da0 ldr r5, [pc, #640] ; (2acc <handle_fuse_requests+0x2c4>) | |
284c: 4649 mov r1, r9 | |
284e: 6803 ldr r3, [r0, #0] | |
2850: f858 0005 ldr.w r0, [r8, r5] | |
2854: 30a8 adds r0, #168 ; 0xa8 | |
2856: e006 b.n 2866 <handle_fuse_requests+0x5e> | |
} | |
continue; | |
} | |
if ((size_t)len < sizeof(struct fuse_in_header)) { | |
2858: 2b27 cmp r3, #39 ; 0x27 | |
285a: d808 bhi.n 286e <handle_fuse_requests+0x66> | |
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len); | |
285c: 489b ldr r0, [pc, #620] ; (2acc <handle_fuse_requests+0x2c4>) | |
285e: 4659 mov r1, fp | |
2860: f858 0000 ldr.w r0, [r8, r0] | |
2864: 30a8 adds r0, #168 ; 0xa8 | |
2866: 6872 ldr r2, [r6, #4] | |
2868: f7fe eb94 blx f94 <fprintf@plt> | |
continue; | |
286c: e7df b.n 282e <handle_fuse_requests+0x26> | |
} | |
const struct fuse_in_header *hdr = (void*)handler->request_buffer; | |
if (hdr->len != (size_t)len) { | |
286e: 68b2 ldr r2, [r6, #8] | |
2870: 429a cmp r2, r3 | |
2872: d009 beq.n 2888 <handle_fuse_requests+0x80> | |
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n", | |
2874: 4c95 ldr r4, [pc, #596] ; (2acc <handle_fuse_requests+0x2c4>) | |
2876: 4651 mov r1, sl | |
2878: f858 0004 ldr.w r0, [r8, r4] | |
287c: 9200 str r2, [sp, #0] | |
287e: 6872 ldr r2, [r6, #4] | |
2880: 30a8 adds r0, #168 ; 0xa8 | |
2882: f7fe eb88 blx f94 <fprintf@plt> | |
handler->token, (size_t)len, hdr->len); | |
continue; | |
2886: e7d2 b.n 282e <handle_fuse_requests+0x26> | |
} | |
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler, | |
const struct fuse_in_header *hdr, const void *data, size_t data_len) | |
{ | |
switch (hdr->opcode) { | |
2888: 68f3 ldr r3, [r6, #12] | |
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n", | |
handler->token, (size_t)len, hdr->len); | |
continue; | |
} | |
const void *data = handler->request_buffer + sizeof(struct fuse_in_header); | |
288a: f106 0230 add.w r2, r6, #48 ; 0x30 | |
size_t data_len = len - sizeof(struct fuse_in_header); | |
__u64 unique = hdr->unique; | |
288e: ed96 8b04 vldr d8, [r6, #16] | |
} | |
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler, | |
const struct fuse_in_header *hdr, const void *data, size_t data_len) | |
{ | |
switch (hdr->opcode) { | |
2892: 1e59 subs r1, r3, #1 | |
2894: 291c cmp r1, #28 | |
2896: f200 8106 bhi.w 2aa6 <handle_fuse_requests+0x29e> | |
289a: e8df f011 tbh [pc, r1, lsl #1] | |
289e: 001d .short 0x001d | |
28a0: 00470022 .word 0x00470022 | |
28a4: 0104004c .word 0x0104004c | |
28a8: 01040104 .word 0x01040104 | |
28ac: 00580051 .word 0x00580051 | |
28b0: 0064005f .word 0x0064005f | |
28b4: 01040069 .word 0x01040069 | |
28b8: 007e0079 .word 0x007e0079 | |
28bc: 00ae0096 .word 0x00ae0096 | |
28c0: 010400b3 .word 0x010400b3 | |
28c4: 010400b8 .word 0x010400b8 | |
28c8: 01040104 .word 0x01040104 | |
28cc: 00f80104 .word 0x00f80104 | |
28d0: 00c900db .word 0x00c900db | |
28d4: 00d300ce .word 0x00d300ce | |
case FUSE_LOOKUP: { /* bytez[] -> entry_out */ | |
const char* name = data; | |
return handle_lookup(fuse, handler, hdr, name); | |
28d8: 4638 mov r0, r7 | |
28da: 4621 mov r1, r4 | |
28dc: f7ff fde8 bl 24b0 <handle_lookup.isra.22> | |
28e0: e0d2 b.n 2a88 <handle_fuse_requests+0x280> | |
static int handle_forget(struct fuse* fuse, struct fuse_handler* handler, | |
const struct fuse_in_header *hdr, const struct fuse_forget_in *req) | |
{ | |
struct node* node; | |
pthread_mutex_lock(&fuse->lock); | |
28e2: 4638 mov r0, r7 | |
28e4: f7fe eb9e blx 1024 <pthread_mutex_lock@plt> | |
node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
28e8: e9d6 2306 ldrd r2, r3, [r6, #24] | |
return 0; | |
} | |
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid) | |
{ | |
if (nid == FUSE_ROOT_ID) { | |
28ec: 2b00 cmp r3, #0 | |
28ee: bf08 it eq | |
28f0: 2a01 cmpeq r2, #1 | |
28f2: d102 bne.n 28fa <handle_fuse_requests+0xf2> | |
return &fuse->root; | |
28f4: f107 0320 add.w r3, r7, #32 | |
28f8: e005 b.n 2906 <handle_fuse_requests+0xfe> | |
pthread_mutex_lock(&fuse->lock); | |
node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup, | |
hdr->nodeid, node ? node->name : "?"); | |
if (node) { | |
28fa: 4613 mov r3, r2 | |
28fc: b91a cbnz r2, 2906 <handle_fuse_requests+0xfe> | |
__u64 n = req->nlookup; | |
while (n--) { | |
release_node_locked(node); | |
} | |
} | |
pthread_mutex_unlock(&fuse->lock); | |
28fe: 4638 mov r0, r7 | |
2900: f7fe eb96 blx 1030 <pthread_mutex_unlock@plt> | |
2904: e793 b.n 282e <handle_fuse_requests+0x26> | |
pthread_mutex_lock(&fuse->lock); | |
node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup, | |
hdr->nodeid, node ? node->name : "?"); | |
if (node) { | |
__u64 n = req->nlookup; | |
2906: e9d6 450c ldrd r4, r5, [r6, #48] ; 0x30 | |
290a: ed9f 8b69 vldr d8, [pc, #420] ; 2ab0 <handle_fuse_requests+0x2a8> | |
290e: e009 b.n 2924 <handle_fuse_requests+0x11c> | |
while (n--) { | |
release_node_locked(node); | |
2910: 4618 mov r0, r3 | |
2912: 9303 str r3, [sp, #12] | |
2914: f7fe fe36 bl 1584 <release_node_locked> | |
2918: ec51 0b18 vmov r0, r1, d8 | |
291c: 9b03 ldr r3, [sp, #12] | |
291e: 1824 adds r4, r4, r0 | |
2920: eb45 0501 adc.w r5, r5, r1 | |
node = lookup_node_by_id_locked(fuse, hdr->nodeid); | |
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup, | |
hdr->nodeid, node ? node->name : "?"); | |
if (node) { | |
__u64 n = req->nlookup; | |
while (n--) { | |
2924: ea54 0105 orrs.w r1, r4, r5 | |
2928: d1f2 bne.n 2910 <handle_fuse_requests+0x108> | |
292a: e7e8 b.n 28fe <handle_fuse_requests+0xf6> | |
return handle_forget(fuse, handler, hdr, req); | |
} | |
case FUSE_GETATTR: { /* getattr_in -> attr_out */ | |
const struct fuse_getattr_in *req = data; | |
return handle_getattr(fuse, handler, hdr, req); | |
292c: 4638 mov r0, r7 | |
292e: 4621 mov r1, r4 | |
2930: f7ff fa10 bl 1d54 <handle_getattr.isra.5> | |
2934: e0a8 b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_SETATTR: { /* setattr_in -> attr_out */ | |
const struct fuse_setattr_in *req = data; | |
return handle_setattr(fuse, handler, hdr, req); | |
2936: 4638 mov r0, r7 | |
2938: 4621 mov r1, r4 | |
293a: f7ff fa57 bl 1dec <handle_setattr.isra.13> | |
293e: e0a3 b.n 2a88 <handle_fuse_requests+0x280> | |
// case FUSE_READLINK: | |
// case FUSE_SYMLINK: | |
case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */ | |
const struct fuse_mknod_in *req = data; | |
const char *name = ((const char*) data) + sizeof(*req); | |
return handle_mknod(fuse, handler, hdr, req, name); | |
2940: 4638 mov r0, r7 | |
2942: 4621 mov r1, r4 | |
2944: f106 0340 add.w r3, r6, #64 ; 0x40 | |
2948: f7ff fe12 bl 2570 <handle_mknod.isra.23> | |
294c: e09c b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */ | |
const struct fuse_mkdir_in *req = data; | |
const char *name = ((const char*) data) + sizeof(*req); | |
return handle_mkdir(fuse, handler, hdr, req, name); | |
294e: 4638 mov r0, r7 | |
2950: 4621 mov r1, r4 | |
2952: f106 0338 add.w r3, r6, #56 ; 0x38 | |
2956: f7ff fe81 bl 265c <handle_mkdir.isra.24> | |
295a: e095 b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_UNLINK: { /* bytez[] -> */ | |
const char* name = data; | |
return handle_unlink(fuse, handler, hdr, name); | |
295c: 4638 mov r0, r7 | |
295e: 4621 mov r1, r4 | |
2960: f7ff f850 bl 1a04 <handle_unlink.isra.15> | |
2964: e090 b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_RMDIR: { /* bytez[] -> */ | |
const char* name = data; | |
return handle_rmdir(fuse, handler, hdr, name); | |
2966: 4638 mov r0, r7 | |
2968: 4621 mov r1, r4 | |
296a: f7fe ffe9 bl 1940 <handle_rmdir.isra.16> | |
296e: e08b b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_RENAME: { /* rename_in, oldname, newname -> */ | |
const struct fuse_rename_in *req = data; | |
const char *old_name = ((const char*) data) + sizeof(*req); | |
2970: f106 0538 add.w r5, r6, #56 ; 0x38 | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
2974: 9203 str r2, [sp, #12] | |
2976: 4628 mov r0, r5 | |
2978: f7fe eb18 blx fac <strlen@plt> | |
const char *new_name = old_name + strlen(old_name) + 1; | |
297c: 1c41 adds r1, r0, #1 | |
return handle_rename(fuse, handler, hdr, req, old_name, new_name); | |
297e: 9a03 ldr r2, [sp, #12] | |
} | |
case FUSE_RENAME: { /* rename_in, oldname, newname -> */ | |
const struct fuse_rename_in *req = data; | |
const char *old_name = ((const char*) data) + sizeof(*req); | |
const char *new_name = old_name + strlen(old_name) + 1; | |
2980: 186b adds r3, r5, r1 | |
return handle_rename(fuse, handler, hdr, req, old_name, new_name); | |
2982: 4638 mov r0, r7 | |
2984: 9300 str r3, [sp, #0] | |
2986: 4621 mov r1, r4 | |
2988: 462b mov r3, r5 | |
298a: f7ff fab5 bl 1ef8 <handle_rename.isra.17> | |
298e: e07b b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
// case FUSE_LINK: | |
case FUSE_OPEN: { /* open_in -> open_out */ | |
const struct fuse_open_in *req = data; | |
return handle_open(fuse, handler, hdr, req); | |
2990: 4638 mov r0, r7 | |
2992: 4621 mov r1, r4 | |
2994: f7ff f898 bl 1ac8 <handle_open.isra.14> | |
2998: e076 b.n 2a88 <handle_fuse_requests+0x280> | |
static int handle_read(struct fuse* fuse, struct fuse_handler* handler, | |
const struct fuse_in_header* hdr, const struct fuse_read_in* req) | |
{ | |
struct handle *h = id_to_ptr(req->fh); | |
__u64 unique = hdr->unique; | |
__u32 size = req->size; | |
299a: 6c32 ldr r2, [r6, #64] ; 0x40 | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
299c: 6b33 ldr r3, [r6, #48] ; 0x30 | |
const struct fuse_in_header* hdr, const struct fuse_read_in* req) | |
{ | |
struct handle *h = id_to_ptr(req->fh); | |
__u64 unique = hdr->unique; | |
__u32 size = req->size; | |
__u64 offset = req->offset; | |
299e: e9d6 010e ldrd r0, r1, [r6, #56] ; 0x38 | |
* overlaps the request buffer and will clobber data in the request. This | |
* saves us 128KB per request handler thread at the cost of this scary comment. */ | |
TRACE("[%d] READ %p(%d) %u@%llu\n", handler->token, | |
h, h->fd, size, offset); | |
if (size > sizeof(handler->read_buffer)) { | |
29a2: f5b2 3f00 cmp.w r2, #131072 ; 0x20000 | |
29a6: d80d bhi.n 29c4 <handle_fuse_requests+0x1bc> | |
return -EINVAL; | |
} | |
res = pread64(h->fd, handler->read_buffer, size, offset); | |
29a8: f106 0508 add.w r5, r6, #8 | |
29ac: e9cd 0100 strd r0, r1, [sp] | |
29b0: 4629 mov r1, r5 | |
29b2: 6818 ldr r0, [r3, #0] | |
29b4: f7fe ebf6 blx 11a4 <pread64@plt> | |
if (res < 0) { | |
29b8: 2800 cmp r0, #0 | |
29ba: da00 bge.n 29be <handle_fuse_requests+0x1b6> | |
29bc: e033 b.n 2a26 <handle_fuse_requests+0x21e> | |
return -errno; | |
} | |
fuse_reply(fuse, unique, handler->read_buffer, res); | |
29be: 9500 str r5, [sp, #0] | |
29c0: 9001 str r0, [sp, #4] | |
29c2: e05b b.n 2a7c <handle_fuse_requests+0x274> | |
* saves us 128KB per request handler thread at the cost of this scary comment. */ | |
TRACE("[%d] READ %p(%d) %u@%llu\n", handler->token, | |
h, h->fd, size, offset); | |
if (size > sizeof(handler->read_buffer)) { | |
return -EINVAL; | |
29c4: f06f 0015 mvn.w r0, #21 | |
29c8: e062 b.n 2a90 <handle_fuse_requests+0x288> | |
struct handle *h = id_to_ptr(req->fh); | |
int res; | |
TRACE("[%d] WRITE %p(%d) %u@%llu\n", handler->token, | |
h, h->fd, req->size, req->offset); | |
res = pwrite64(h->fd, buffer, req->size, req->offset); | |
29ca: e9d6 010e ldrd r0, r1, [r6, #56] ; 0x38 | |
29ce: 6b35 ldr r5, [r6, #48] ; 0x30 | |
29d0: 6c32 ldr r2, [r6, #64] ; 0x40 | |
29d2: e9cd 0100 strd r0, r1, [sp] | |
29d6: f106 0158 add.w r1, r6, #88 ; 0x58 | |
29da: 6828 ldr r0, [r5, #0] | |
29dc: f7fe ebe8 blx 11b0 <pwrite64@plt> | |
if (res < 0) { | |
29e0: 2800 cmp r0, #0 | |
29e2: da00 bge.n 29e6 <handle_fuse_requests+0x1de> | |
29e4: e01f b.n 2a26 <handle_fuse_requests+0x21e> | |
return -errno; | |
} | |
out.size = res; | |
29e6: a90a add r1, sp, #40 ; 0x28 | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
29e8: 2408 movs r4, #8 | |
h, h->fd, req->size, req->offset); | |
res = pwrite64(h->fd, buffer, req->size, req->offset); | |
if (res < 0) { | |
return -errno; | |
} | |
out.size = res; | |
29ea: f841 0d18 str.w r0, [r1, #-24]! | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
29ee: 4638 mov r0, r7 | |
29f0: e9d6 2304 ldrd r2, r3, [r6, #16] | |
29f4: 9100 str r1, [sp, #0] | |
29f6: 9401 str r4, [sp, #4] | |
29f8: e043 b.n 2a82 <handle_fuse_requests+0x27a> | |
const void* buffer = (const __u8*)data + sizeof(*req); | |
return handle_write(fuse, handler, hdr, req, buffer); | |
} | |
case FUSE_STATFS: { /* getattr_in -> attr_out */ | |
return handle_statfs(fuse, handler, hdr); | |
29fa: 4638 mov r0, r7 | |
29fc: 4621 mov r1, r4 | |
29fe: f7fe fe1b bl 1638 <handle_statfs.isra.19> | |
2a02: e041 b.n 2a88 <handle_fuse_requests+0x280> | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
2a04: 6b35 ldr r5, [r6, #48] ; 0x30 | |
const struct fuse_in_header* hdr, const struct fuse_release_in* req) | |
{ | |
struct handle *h = id_to_ptr(req->fh); | |
TRACE("[%d] RELEASE %p(%d)\n", handler->token, h, h->fd); | |
close(h->fd); | |
2a06: 6828 ldr r0, [r5, #0] | |
2a08: f7fe eb42 blx 1090 <close@plt> | |
2a0c: e01e b.n 2a4c <handle_fuse_requests+0x244> | |
} | |
static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler, | |
const struct fuse_in_header* hdr, const struct fuse_fsync_in* req) | |
{ | |
int is_data_sync = req->fsync_flags & 1; | |
2a0e: 6bb2 ldr r2, [r6, #56] ; 0x38 | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
2a10: 6b33 ldr r3, [r6, #48] ; 0x30 | |
struct handle *h = id_to_ptr(req->fh); | |
int res; | |
TRACE("[%d] FSYNC %p(%d) is_data_sync=%d\n", handler->token, | |
h, h->fd, is_data_sync); | |
res = is_data_sync ? fdatasync(h->fd) : fsync(h->fd); | |
2a12: 07d1 lsls r1, r2, #31 | |
2a14: 6818 ldr r0, [r3, #0] | |
2a16: d502 bpl.n 2a1e <handle_fuse_requests+0x216> | |
2a18: f7fe ebd0 blx 11bc <fdatasync@plt> | |
2a1c: e001 b.n 2a22 <handle_fuse_requests+0x21a> | |
2a1e: f7fe ebd4 blx 11c8 <fsync@plt> | |
if (res < 0) { | |
2a22: 2800 cmp r0, #0 | |
2a24: da33 bge.n 2a8e <handle_fuse_requests+0x286> | |
return -errno; | |
2a26: f7fe eae6 blx ff4 <__errno@plt> | |
2a2a: 6802 ldr r2, [r0, #0] | |
2a2c: 4250 negs r0, r2 | |
2a2e: e02b b.n 2a88 <handle_fuse_requests+0x280> | |
return handle_flush(fuse, handler, hdr); | |
} | |
case FUSE_OPENDIR: { /* open_in -> open_out */ | |
const struct fuse_open_in *req = data; | |
return handle_opendir(fuse, handler, hdr, req); | |
2a30: 4638 mov r0, r7 | |
2a32: 4621 mov r1, r4 | |
2a34: f7ff f8c6 bl 1bc4 <handle_opendir.isra.10> | |
2a38: e026 b.n 2a88 <handle_fuse_requests+0x280> | |
} | |
case FUSE_READDIR: { | |
const struct fuse_read_in *req = data; | |
return handle_readdir(fuse, handler, hdr, req); | |
2a3a: 4638 mov r0, r7 | |
2a3c: 4621 mov r1, r4 | |
2a3e: f7fe fe63 bl 1708 <handle_readdir.isra.21> | |
2a42: e021 b.n 2a88 <handle_fuse_requests+0x280> | |
}; | |
}; | |
static inline void *id_to_ptr(__u64 nid) | |
{ | |
return (void *) (uintptr_t) nid; | |
2a44: 6b35 ldr r5, [r6, #48] ; 0x30 | |
const struct fuse_in_header* hdr, const struct fuse_release_in* req) | |
{ | |
struct dirhandle *h = id_to_ptr(req->fh); | |
TRACE("[%d] RELEASEDIR %p\n", handler->token, h); | |
closedir(h->d); | |
2a46: 6828 ldr r0, [r5, #0] | |
2a48: f7fe eb34 blx 10b4 <closedir@plt> | |
free(h); | |
2a4c: 4628 mov r0, r5 | |
2a4e: f7fe eac6 blx fdc <free@plt> | |
2a52: e01c b.n 2a8e <handle_fuse_requests+0x286> | |
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n", | |
handler->token, req->major, req->minor, req->max_readahead, req->flags); | |
out.major = FUSE_KERNEL_VERSION; | |
out.minor = FUSE_KERNEL_MINOR_VERSION; | |
out.max_readahead = req->max_readahead; | |
2a54: 6bb2 ldr r2, [r6, #56] ; 0x38 | |
{ | |
struct fuse_init_out out; | |
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n", | |
handler->token, req->major, req->minor, req->max_readahead, req->flags); | |
out.major = FUSE_KERNEL_VERSION; | |
2a56: 2007 movs r0, #7 | |
out.minor = FUSE_KERNEL_MINOR_VERSION; | |
2a58: 240d movs r4, #13 | |
out.max_readahead = req->max_readahead; | |
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES; | |
out.max_background = 32; | |
2a5a: 2120 movs r1, #32 | |
{ | |
struct fuse_init_out out; | |
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n", | |
handler->token, req->major, req->minor, req->max_readahead, req->flags); | |
out.major = FUSE_KERNEL_VERSION; | |
2a5c: 9004 str r0, [sp, #16] | |
out.minor = FUSE_KERNEL_MINOR_VERSION; | |
out.max_readahead = req->max_readahead; | |
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES; | |
2a5e: 2328 movs r3, #40 ; 0x28 | |
struct fuse_init_out out; | |
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n", | |
handler->token, req->major, req->minor, req->max_readahead, req->flags); | |
out.major = FUSE_KERNEL_VERSION; | |
out.minor = FUSE_KERNEL_MINOR_VERSION; | |
2a60: 9405 str r4, [sp, #20] | |
out.max_readahead = req->max_readahead; | |
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES; | |
out.max_background = 32; | |
out.congestion_threshold = 32; | |
out.max_write = MAX_WRITE; | |
2a62: f44f 2580 mov.w r5, #262144 ; 0x40000 | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
2a66: a804 add r0, sp, #16 | |
2a68: 2418 movs r4, #24 | |
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n", | |
handler->token, req->major, req->minor, req->max_readahead, req->flags); | |
out.major = FUSE_KERNEL_VERSION; | |
out.minor = FUSE_KERNEL_MINOR_VERSION; | |
out.max_readahead = req->max_readahead; | |
2a6a: 9206 str r2, [sp, #24] | |
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES; | |
2a6c: 9307 str r3, [sp, #28] | |
out.max_background = 32; | |
2a6e: f8ad 1020 strh.w r1, [sp, #32] | |
out.congestion_threshold = 32; | |
2a72: f8ad 1022 strh.w r1, [sp, #34] ; 0x22 | |
out.max_write = MAX_WRITE; | |
2a76: 9509 str r5, [sp, #36] ; 0x24 | |
fuse_reply(fuse, hdr->unique, &out, sizeof(out)); | |
2a78: 9000 str r0, [sp, #0] | |
2a7a: 9401 str r4, [sp, #4] | |
2a7c: 4638 mov r0, r7 | |
2a7e: ec53 2b18 vmov r2, r3, d8 | |
2a82: f7fe fd51 bl 1528 <fuse_reply> | |
2a86: e6d2 b.n 282e <handle_fuse_requests+0x26> | |
int res = handle_fuse_request(fuse, handler, hdr, data, data_len); | |
/* We do not access the request again after this point because the underlying | |
* buffer storage may have been reused while processing the request. */ | |
if (res != NO_STATUS) { | |
2a88: 2801 cmp r0, #1 | |
2a8a: d101 bne.n 2a90 <handle_fuse_requests+0x288> | |
2a8c: e6cf b.n 282e <handle_fuse_requests+0x26> | |
// case FUSE_SETXATTR: | |
// case FUSE_GETXATTR: | |
// case FUSE_LISTXATTR: | |
// case FUSE_REMOVEXATTR: | |
case FUSE_FLUSH: { | |
return handle_flush(fuse, handler, hdr); | |
2a8e: 2000 movs r0, #0 | |
} | |
static void fuse_status(struct fuse *fuse, __u64 unique, int err) | |
{ | |
struct fuse_out_header hdr; | |
hdr.len = sizeof(hdr); | |
2a90: 2210 movs r2, #16 | |
hdr.error = err; | |
2a92: 9005 str r0, [sp, #20] | |
} | |
static void fuse_status(struct fuse *fuse, __u64 unique, int err) | |
{ | |
struct fuse_out_header hdr; | |
hdr.len = sizeof(hdr); | |
2a94: 9204 str r2, [sp, #16] | |
hdr.error = err; | |
hdr.unique = unique; | |
write(fuse->fd, &hdr, sizeof(hdr)); | |
2a96: eb0d 0102 add.w r1, sp, r2 | |
static void fuse_status(struct fuse *fuse, __u64 unique, int err) | |
{ | |
struct fuse_out_header hdr; | |
hdr.len = sizeof(hdr); | |
hdr.error = err; | |
hdr.unique = unique; | |
2a9a: ed8d 8b06 vstr d8, [sp, #24] | |
write(fuse->fd, &hdr, sizeof(hdr)); | |
2a9e: 6938 ldr r0, [r7, #16] | |
2aa0: f7fe eb98 blx 11d4 <write@plt> | |
2aa4: e6c3 b.n 282e <handle_fuse_requests+0x26> | |
} | |
default: { | |
TRACE("[%d] NOTIMPL op=%d uniq=%llx nid=%llx\n", | |
handler->token, hdr->opcode, hdr->unique, hdr->nodeid); | |
return -ENOSYS; | |
2aa6: f06f 0025 mvn.w r0, #37 ; 0x25 | |
2aaa: e7f1 b.n 2a90 <handle_fuse_requests+0x288> | |
2aac: f3af 8000 nop.w | |
2ab0: ffffffff .word 0xffffffff | |
2ab4: ffffffff .word 0xffffffff | |
2ab8: 00040050 .word 0x00040050 | |
2abc: 00000f54 .word 0x00000f54 | |
2ac0: 00000f90 .word 0x00000f90 | |
2ac4: 00000f69 .word 0x00000f69 | |
2ac8: 0000268c .word 0x0000268c | |
2acc: fffffff0 .word 0xfffffff0 | |
00002ad0 <run>: | |
return 1; | |
} | |
static int run(const char* source_path, const char* dest_path, uid_t uid, | |
gid_t gid, gid_t write_gid, int num_threads, derive_t derive, | |
bool split_perms) { | |
2ad0: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
2ad4: 4699 mov r9, r3 | |
2ad6: f8df 4530 ldr.w r4, [pc, #1328] ; 3008 <run+0x538> | |
2ada: f5ad 5dcc sub.w sp, sp, #6528 ; 0x1980 | |
2ade: b087 sub sp, #28 | |
2ae0: 4617 mov r7, r2 | |
2ae2: f8df 3528 ldr.w r3, [pc, #1320] ; 300c <run+0x53c> | |
2ae6: 468a mov sl, r1 | |
2ae8: 447c add r4, pc | |
} | |
return __open_real(pathname, flags, __builtin_va_arg_pack()); | |
2aea: f8df b524 ldr.w fp, [pc, #1316] ; 3010 <run+0x540> | |
2aee: 4606 mov r6, r0 | |
2af0: f50d 51cc add.w r1, sp, #6528 ; 0x1980 | |
2af4: f854 8003 ldr.w r8, [r4, r3] | |
2af8: f50d 50ce add.w r0, sp, #6592 ; 0x19c0 | |
2afc: 3008 adds r0, #8 | |
2afe: 3114 adds r1, #20 | |
2b00: 6805 ldr r5, [r0, #0] | |
2b02: 44fb add fp, pc | |
2b04: f8d8 2000 ldr.w r2, [r8] | |
char opts[256]; | |
int res; | |
struct fuse fuse; | |
/* cleanup from previous instance, if necessary */ | |
umount2(dest_path, 2); | |
2b08: 4650 mov r0, sl | |
return 1; | |
} | |
static int run(const char* source_path, const char* dest_path, uid_t uid, | |
gid_t gid, gid_t write_gid, int num_threads, derive_t derive, | |
bool split_perms) { | |
2b0a: 600a str r2, [r1, #0] | |
char opts[256]; | |
int res; | |
struct fuse fuse; | |
/* cleanup from previous instance, if necessary */ | |
umount2(dest_path, 2); | |
2b0c: 2102 movs r1, #2 | |
2b0e: f7fe eb68 blx 11e0 <umount2@plt> | |
2b12: 2102 movs r1, #2 | |
2b14: 4658 mov r0, fp | |
2b16: f7fe eab0 blx 1078 <open@plt> | |
fd = open("/dev/fuse", O_RDWR); | |
if (fd < 0){ | |
2b1a: 2800 cmp r0, #0 | |
2b1c: f8cd 800c str.w r8, [sp, #12] | |
2b20: 9002 str r0, [sp, #8] | |
2b22: da12 bge.n 2b4a <run+0x7a> | |
ERROR("cannot open fuse device: %s\n", strerror(errno)); | |
2b24: f8df a4ec ldr.w sl, [pc, #1260] ; 3014 <run+0x544> | |
2b28: f7fe ea64 blx ff4 <__errno@plt> | |
2b2c: 6800 ldr r0, [r0, #0] | |
2b2e: f7fe eaaa blx 1084 <strerror@plt> | |
2b32: f8df 14e4 ldr.w r1, [pc, #1252] ; 3018 <run+0x548> | |
2b36: 4602 mov r2, r0 | |
2b38: f854 000a ldr.w r0, [r4, sl] | |
return -1; | |
2b3c: f04f 3aff mov.w sl, #4294967295 ; 0xffffffff | |
/* cleanup from previous instance, if necessary */ | |
umount2(dest_path, 2); | |
fd = open("/dev/fuse", O_RDWR); | |
if (fd < 0){ | |
ERROR("cannot open fuse device: %s\n", strerror(errno)); | |
2b40: 4479 add r1, pc | |
2b42: 30a8 adds r0, #168 ; 0xa8 | |
2b44: f7fe ea26 blx f94 <fprintf@plt> | |
2b48: e24c b.n 2fe4 <run+0x514> | |
2b4a: f8df 24d0 ldr.w r2, [pc, #1232] ; 301c <run+0x54c> | |
return -1; | |
} | |
snprintf(opts, sizeof(opts), | |
2b4e: f10d 0818 add.w r8, sp, #24 | |
2b52: f44f 7180 mov.w r1, #256 ; 0x100 | |
2b56: 9b02 ldr r3, [sp, #8] | |
2b58: e88d 0280 stmia.w sp, {r7, r9} | |
2b5c: 4640 mov r0, r8 | |
2b5e: 447a add r2, pc | |
2b60: f7fe eb14 blx 118c <snprintf@plt> | |
"fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d", | |
fd, uid, gid); | |
res = mount("/dev/fuse", dest_path, "fuse", MS_NOSUID | MS_NODEV, opts); | |
2b64: f8df 24b8 ldr.w r2, [pc, #1208] ; 3020 <run+0x550> | |
2b68: 4651 mov r1, sl | |
2b6a: 2306 movs r3, #6 | |
2b6c: f8cd 8000 str.w r8, [sp] | |
2b70: 4658 mov r0, fp | |
2b72: 447a add r2, pc | |
2b74: f7fe eb3a blx 11ec <mount@plt> | |
if (res < 0) { | |
2b78: f1b0 0a00 subs.w sl, r0, #0 | |
2b7c: da0d bge.n 2b9a <run+0xca> | |
ERROR("cannot mount fuse filesystem: %s\n", strerror(errno)); | |
2b7e: f7fe ea3a blx ff4 <__errno@plt> | |
2b82: 6800 ldr r0, [r0, #0] | |
2b84: f7fe ea7e blx 1084 <strerror@plt> | |
2b88: f8df 1488 ldr.w r1, [pc, #1160] ; 3014 <run+0x544> | |
2b8c: 4602 mov r2, r0 | |
2b8e: 5860 ldr r0, [r4, r1] | |
2b90: f8df 1490 ldr.w r1, [pc, #1168] ; 3024 <run+0x554> | |
2b94: 30a8 adds r0, #168 ; 0xa8 | |
2b96: 4479 add r1, pc | |
2b98: e03e b.n 2c18 <run+0x148> | |
goto error; | |
} | |
res = setgroups(sizeof(kGroups) / sizeof(kGroups[0]), kGroups); | |
2b9a: f8df 148c ldr.w r1, [pc, #1164] ; 3028 <run+0x558> | |
2b9e: 2001 movs r0, #1 | |
2ba0: 4479 add r1, pc | |
2ba2: f7fe eb2a blx 11f8 <setgroups@plt> | |
if (res < 0) { | |
2ba6: f1b0 0a00 subs.w sl, r0, #0 | |
2baa: da0d bge.n 2bc8 <run+0xf8> | |
ERROR("cannot setgroups: %s\n", strerror(errno)); | |
2bac: f7fe ea22 blx ff4 <__errno@plt> | |
2bb0: 6800 ldr r0, [r0, #0] | |
2bb2: f7fe ea68 blx 1084 <strerror@plt> | |
2bb6: 4602 mov r2, r0 | |
2bb8: f8df 0458 ldr.w r0, [pc, #1112] ; 3014 <run+0x544> | |
2bbc: f8df 146c ldr.w r1, [pc, #1132] ; 302c <run+0x55c> | |
2bc0: 5820 ldr r0, [r4, r0] | |
2bc2: 4479 add r1, pc | |
2bc4: 30a8 adds r0, #168 ; 0xa8 | |
2bc6: e027 b.n 2c18 <run+0x148> | |
goto error; | |
} | |
res = setgid(gid); | |
2bc8: 4648 mov r0, r9 | |
2bca: f7fe eb1c blx 1204 <setgid@plt> | |
if (res < 0) { | |
2bce: f1b0 0a00 subs.w sl, r0, #0 | |
2bd2: da0d bge.n 2bf0 <run+0x120> | |
ERROR("cannot setgid: %s\n", strerror(errno)); | |
2bd4: f7fe ea0e blx ff4 <__errno@plt> | |
2bd8: 6800 ldr r0, [r0, #0] | |
2bda: f7fe ea54 blx 1084 <strerror@plt> | |
2bde: f8df 3434 ldr.w r3, [pc, #1076] ; 3014 <run+0x544> | |
2be2: 4602 mov r2, r0 | |
2be4: f8df 1448 ldr.w r1, [pc, #1096] ; 3030 <run+0x560> | |
2be8: 58e0 ldr r0, [r4, r3] | |
2bea: 4479 add r1, pc | |
2bec: 30a8 adds r0, #168 ; 0xa8 | |
2bee: e013 b.n 2c18 <run+0x148> | |
goto error; | |
} | |
res = setuid(uid); | |
2bf0: 4638 mov r0, r7 | |
2bf2: f7fe eb0e blx 1210 <setuid@plt> | |
if (res < 0) { | |
2bf6: f1b0 0a00 subs.w sl, r0, #0 | |
2bfa: da10 bge.n 2c1e <run+0x14e> | |
ERROR("cannot setuid: %s\n", strerror(errno)); | |
2bfc: f7fe e9fa blx ff4 <__errno@plt> | |
2c00: 6800 ldr r0, [r0, #0] | |
2c02: f7fe ea40 blx 1084 <strerror@plt> | |
2c06: f8df c40c ldr.w ip, [pc, #1036] ; 3014 <run+0x544> | |
2c0a: 4602 mov r2, r0 | |
2c0c: f8df 1424 ldr.w r1, [pc, #1060] ; 3034 <run+0x564> | |
2c10: f854 000c ldr.w r0, [r4, ip] | |
2c14: 4479 add r1, pc | |
2c16: 30a8 adds r0, #168 ; 0xa8 | |
2c18: f7fe e9bc blx f94 <fprintf@plt> | |
goto error; | |
2c1c: e1df b.n 2fde <run+0x50e> | |
return child; | |
} | |
static void fuse_init(struct fuse *fuse, int fd, const char *source_path, | |
gid_t write_gid, derive_t derive, bool split_perms) { | |
pthread_mutex_init(&fuse->lock, NULL); | |
2c1e: f60d 1718 addw r7, sp, #2328 ; 0x918 | |
2c22: 2100 movs r1, #0 | |
2c24: 4638 mov r0, r7 | |
fuse->split_perms = split_perms; | |
fuse->write_gid = write_gid; | |
memset(&fuse->root, 0, sizeof(fuse->root)); | |
fuse->root.nid = FUSE_ROOT_ID; /* 1 */ | |
fuse->root.refcount = 2; | |
2c26: f04f 0802 mov.w r8, #2 | |
return child; | |
} | |
static void fuse_init(struct fuse *fuse, int fd, const char *source_path, | |
gid_t write_gid, derive_t derive, bool split_perms) { | |
pthread_mutex_init(&fuse->lock, NULL); | |
2c2a: f7fe eaf8 blx 121c <pthread_mutex_init@plt> | |
fuse->fd = fd; | |
2c2e: 9802 ldr r0, [sp, #8] | |
fuse->next_generation = 0; | |
2c30: 2100 movs r1, #0 | |
fuse->derive = derive; | |
fuse->split_perms = split_perms; | |
2c32: f50d 53ce add.w r3, sp, #6592 ; 0x19c0 | |
gid_t write_gid, derive_t derive, bool split_perms) { | |
pthread_mutex_init(&fuse->lock, NULL); | |
fuse->fd = fd; | |
fuse->next_generation = 0; | |
fuse->derive = derive; | |
2c36: 617d str r5, [r7, #20] | |
fuse->split_perms = split_perms; | |
2c38: 330c adds r3, #12 | |
static void fuse_init(struct fuse *fuse, int fd, const char *source_path, | |
gid_t write_gid, derive_t derive, bool split_perms) { | |
pthread_mutex_init(&fuse->lock, NULL); | |
fuse->fd = fd; | |
2c3a: 6138 str r0, [r7, #16] | |
fuse->next_generation = 0; | |
2c3c: 2000 movs r0, #0 | |
2c3e: e9c7 0102 strd r0, r1, [r7, #8] | |
fuse->derive = derive; | |
fuse->split_perms = split_perms; | |
fuse->write_gid = write_gid; | |
2c42: f50d 51ce add.w r1, sp, #6592 ; 0x19c0 | |
pthread_mutex_init(&fuse->lock, NULL); | |
fuse->fd = fd; | |
fuse->next_generation = 0; | |
fuse->derive = derive; | |
fuse->split_perms = split_perms; | |
2c46: 781a ldrb r2, [r3, #0] | |
fuse->write_gid = write_gid; | |
2c48: 6808 ldr r0, [r1, #0] | |
return __builtin___strncat_chk(dest, src, n, __bos(dest)); | |
} | |
__BIONIC_FORTIFY_INLINE | |
void* memset(void *s, int c, size_t n) { | |
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0)); | |
2c4a: 2100 movs r1, #0 | |
pthread_mutex_init(&fuse->lock, NULL); | |
fuse->fd = fd; | |
fuse->next_generation = 0; | |
fuse->derive = derive; | |
fuse->split_perms = split_perms; | |
2c4c: 763a strb r2, [r7, #24] | |
2c4e: 2250 movs r2, #80 ; 0x50 | |
fuse->write_gid = write_gid; | |
2c50: 61f8 str r0, [r7, #28] | |
2c52: f60d 1038 addw r0, sp, #2360 ; 0x938 | |
2c56: f7fe e9d4 blx 1000 <memset@plt> | |
memset(&fuse->root, 0, sizeof(fuse->root)); | |
fuse->root.nid = FUSE_ROOT_ID; /* 1 */ | |
2c5a: 2100 movs r1, #0 | |
2c5c: 2001 movs r0, #1 | |
2c5e: e9c7 010a strd r0, r1, [r7, #40] ; 0x28 | |
size_t bos = __bos(s); | |
#if !defined(__clang__) | |
// Compiler doesn't know destination size. Don't call __strlen_chk | |
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { | |
return __builtin_strlen(s); | |
2c62: 4630 mov r0, r6 | |
fuse->root.refcount = 2; | |
2c64: f8c7 8020 str.w r8, [r7, #32] | |
2c68: f7fe e9a0 blx fac <strlen@plt> | |
fuse->root.namelen = strlen(source_path); | |
2c6c: 65b8 str r0, [r7, #88] ; 0x58 | |
fuse->root.name = strdup(source_path); | |
2c6e: 4630 mov r0, r6 | |
2c70: f7fe eada blx 1228 <strdup@plt> | |
fuse->root.userid = 0; | |
fuse->root.uid = AID_ROOT; | |
/* Set up root node for various modes of operation */ | |
switch (derive) { | |
2c74: 2d01 cmp r5, #1 | |
memset(&fuse->root, 0, sizeof(fuse->root)); | |
fuse->root.nid = FUSE_ROOT_ID; /* 1 */ | |
fuse->root.refcount = 2; | |
fuse->root.namelen = strlen(source_path); | |
fuse->root.name = strdup(source_path); | |
2c76: 65f8 str r0, [r7, #92] ; 0x5c | |
fuse->root.userid = 0; | |
fuse->root.uid = AID_ROOT; | |
/* Set up root node for various modes of operation */ | |
switch (derive) { | |
2c78: d00d beq.n 2c96 <run+0x1c6> | |
2c7a: d302 bcc.n 2c82 <run+0x1b2> | |
2c7c: 4545 cmp r5, r8 | |
2c7e: d160 bne.n 2d42 <run+0x272> | |
2c80: e03b b.n 2cfa <run+0x22a> | |
case DERIVE_NONE: | |
/* Traditional behavior that treats entire device as being accessible | |
* to sdcard_rw, and no permissions are derived. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0775; | |
2c82: f240 16fd movw r6, #509 ; 0x1fd | |
/* Set up root node for various modes of operation */ | |
switch (derive) { | |
case DERIVE_NONE: | |
/* Traditional behavior that treats entire device as being accessible | |
* to sdcard_rw, and no permissions are derived. */ | |
fuse->root.perm = PERM_ROOT; | |
2c86: f8c7 8038 str.w r8, [r7, #56] ; 0x38 | |
fuse->root.mode = 0775; | |
fuse->root.gid = AID_SDCARD_RW; | |
2c8a: f506 72fd add.w r2, r6, #506 ; 0x1fa | |
switch (derive) { | |
case DERIVE_NONE: | |
/* Traditional behavior that treats entire device as being accessible | |
* to sdcard_rw, and no permissions are derived. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0775; | |
2c8e: f8a7 6048 strh.w r6, [r7, #72] ; 0x48 | |
fuse->root.gid = AID_SDCARD_RW; | |
2c92: 647a str r2, [r7, #68] ; 0x44 | |
2c94: e055 b.n 2d42 <run+0x272> | |
case DERIVE_LEGACY: | |
/* Legacy behavior used to support internal multiuser layout which | |
* places user_id at the top directory level, with the actual roots | |
* just below that. Shared OBB path is also at top level. */ | |
fuse->root.perm = PERM_LEGACY_PRE_ROOT; | |
fuse->root.mode = 0771; | |
2c96: f240 11f9 movw r1, #505 ; 0x1f9 | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2c9a: 4ae7 ldr r2, [pc, #924] ; (3038 <run+0x568>) | |
case DERIVE_LEGACY: | |
/* Legacy behavior used to support internal multiuser layout which | |
* places user_id at the top directory level, with the actual roots | |
* just below that. Shared OBB path is also at top level. */ | |
fuse->root.perm = PERM_LEGACY_PRE_ROOT; | |
fuse->root.mode = 0771; | |
2c9c: f8a7 1048 strh.w r1, [r7, #72] ; 0x48 | |
fuse->root.gid = AID_SDCARD_R; | |
2ca0: f240 4004 movw r0, #1028 ; 0x404 | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2ca4: 49e5 ldr r1, [pc, #916] ; (303c <run+0x56c>) | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/obb", source_path); | |
2ca6: f107 0a70 add.w sl, r7, #112 ; 0x70 | |
/* Legacy behavior used to support internal multiuser layout which | |
* places user_id at the top directory level, with the actual roots | |
* just below that. Shared OBB path is also at top level. */ | |
fuse->root.perm = PERM_LEGACY_PRE_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
2caa: 6478 str r0, [r7, #68] ; 0x44 | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2cac: 447a add r2, pc | |
2cae: f44f 7080 mov.w r0, #256 ; 0x100 | |
break; | |
case DERIVE_LEGACY: | |
/* Legacy behavior used to support internal multiuser layout which | |
* places user_id at the top directory level, with the actual roots | |
* just below that. Shared OBB path is also at top level. */ | |
fuse->root.perm = PERM_LEGACY_PRE_ROOT; | |
2cb2: 63bd str r5, [r7, #56] ; 0x38 | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2cb4: 4479 add r1, pc | |
2cb6: f507 5583 add.w r5, r7, #4192 ; 0x1060 | |
2cba: f7fe eabc blx 1234 <hashmapCreate@plt> | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
2cbe: 49e0 ldr r1, [pc, #896] ; (3040 <run+0x570>) | |
2cc0: 4ae0 ldr r2, [pc, #896] ; (3044 <run+0x574>) | |
* places user_id at the top directory level, with the actual roots | |
* just below that. Shared OBB path is also at top level. */ | |
fuse->root.perm = PERM_LEGACY_PRE_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2cc2: 6128 str r0, [r5, #16] | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
2cc4: 2080 movs r0, #128 ; 0x80 | |
2cc6: 4479 add r1, pc | |
2cc8: 447a add r2, pc | |
2cca: f7fe eab4 blx 1234 <hashmapCreate@plt> | |
2cce: 4ade ldr r2, [pc, #888] ; (3048 <run+0x578>) | |
2cd0: 4633 mov r3, r6 | |
2cd2: f44f 5180 mov.w r1, #4096 ; 0x1000 | |
2cd6: 6168 str r0, [r5, #20] | |
2cd8: 4650 mov r0, sl | |
2cda: 447a add r2, pc | |
2cdc: f7fe ea56 blx 118c <snprintf@plt> | |
snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/obb", source_path); | |
fs_prepare_dir(fuse->obbpath, 0775, getuid(), getgid()); | |
2ce0: f7fe eaae blx 1240 <getuid@plt> | |
2ce4: 4680 mov r8, r0 | |
2ce6: f7fe eab2 blx 124c <getgid@plt> | |
2cea: f240 11fd movw r1, #509 ; 0x1fd | |
2cee: 4603 mov r3, r0 | |
2cf0: 4642 mov r2, r8 | |
2cf2: 4650 mov r0, sl | |
2cf4: f7fe eab0 blx 1258 <fs_prepare_dir@plt> | |
2cf8: e023 b.n 2d42 <run+0x272> | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2cfa: 49d4 ldr r1, [pc, #848] ; (304c <run+0x57c>) | |
case DERIVE_UNIFIED: | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
2cfc: f240 4304 movw r3, #1028 ; 0x404 | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d00: 4ad3 ldr r2, [pc, #844] ; (3050 <run+0x580>) | |
2d02: f44f 7080 mov.w r0, #256 ; 0x100 | |
fs_prepare_dir(fuse->obbpath, 0775, getuid(), getgid()); | |
break; | |
case DERIVE_UNIFIED: | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
2d06: 63bd str r5, [r7, #56] ; 0x38 | |
fuse->root.mode = 0771; | |
2d08: f240 15f9 movw r5, #505 ; 0x1f9 | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d0c: 4479 add r1, pc | |
case DERIVE_UNIFIED: | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
2d0e: 647b str r3, [r7, #68] ; 0x44 | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d10: 447a add r2, pc | |
break; | |
case DERIVE_UNIFIED: | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
2d12: f8a7 5048 strh.w r5, [r7, #72] ; 0x48 | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d16: f7fe ea8e blx 1234 <hashmapCreate@plt> | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
2d1a: 49ce ldr r1, [pc, #824] ; (3054 <run+0x584>) | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d1c: f507 5583 add.w r5, r7, #4192 ; 0x1060 | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
2d20: 4acd ldr r2, [pc, #820] ; (3058 <run+0x588>) | |
/* Unified multiuser layout which places secondary user_id under | |
* /Android/user and shared OBB path under /Android/obb. */ | |
fuse->root.perm = PERM_ROOT; | |
fuse->root.mode = 0771; | |
fuse->root.gid = AID_SDCARD_R; | |
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals); | |
2d22: 6128 str r0, [r5, #16] | |
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals); | |
2d24: 2080 movs r0, #128 ; 0x80 | |
2d26: 4479 add r1, pc | |
2d28: 447a add r2, pc | |
2d2a: f7fe ea84 blx 1234 <hashmapCreate@plt> | |
2d2e: 4acb ldr r2, [pc, #812] ; (305c <run+0x58c>) | |
2d30: f44f 5180 mov.w r1, #4096 ; 0x1000 | |
2d34: 6168 str r0, [r5, #20] | |
2d36: 4633 mov r3, r6 | |
2d38: f107 0070 add.w r0, r7, #112 ; 0x70 | |
2d3c: 447a add r2, pc | |
2d3e: f7fe ea26 blx 118c <snprintf@plt> | |
#if !defined(__clang__) | |
if (__builtin_constant_p(mode)) { | |
if ((mode & 0777) != mode) { | |
__umask_invalid_mode(); | |
} | |
return __umask_real(mode); | |
2d42: 2000 movs r0, #0 | |
static int ignite_fuse(struct fuse* fuse, int num_threads) | |
{ | |
struct fuse_handler* handlers; | |
int i; | |
handlers = malloc(num_threads * sizeof(struct fuse_handler)); | |
2d44: 4daf ldr r5, [pc, #700] ; (3004 <run+0x534>) | |
2d46: f7fe ea8e blx 1264 <umask@plt> | |
2d4a: f50d 53ce add.w r3, sp, #6592 ; 0x19c0 | |
2d4e: 1d1e adds r6, r3, #4 | |
2d50: 46a8 mov r8, r5 | |
2d52: 6832 ldr r2, [r6, #0] | |
2d54: fb05 f002 mul.w r0, r5, r2 | |
2d58: f7fe e9be blx 10d8 <malloc@plt> | |
if (!handlers) { | |
2d5c: 4606 mov r6, r0 | |
2d5e: b988 cbnz r0, 2d84 <run+0x2b4> | |
ERROR("cannot allocate storage for threads\n"); | |
2d60: 49ac ldr r1, [pc, #688] ; (3014 <run+0x544>) | |
} | |
fuse_init(&fuse, fd, source_path, write_gid, derive, split_perms); | |
umask(0); | |
res = ignite_fuse(&fuse, num_threads); | |
2d62: f06f 0a0b mvn.w sl, #11 | |
struct fuse_handler* handlers; | |
int i; | |
handlers = malloc(num_threads * sizeof(struct fuse_handler)); | |
if (!handlers) { | |
ERROR("cannot allocate storage for threads\n"); | |
2d66: 48be ldr r0, [pc, #760] ; (3060 <run+0x590>) | |
2d68: 5861 ldr r1, [r4, r1] | |
2d6a: 4478 add r0, pc | |
2d6c: 31a8 adds r1, #168 ; 0xa8 | |
2d6e: f7fe ea80 blx 1270 <fputs@plt> | |
2d72: e134 b.n 2fde <run+0x50e> | |
return -ENOMEM; | |
} | |
for (i = 0; i < num_threads; i++) { | |
handlers[i].fuse = fuse; | |
2d74: 51f1 str r1, [r6, r7] | |
" -s: split derived permissions for pics, av (requires -d or -l)\n" | |
"\n", DEFAULT_NUM_THREADS); | |
return 1; | |
} | |
static int run(const char* source_path, const char* dest_path, uid_t uid, | |
2d76: 19f2 adds r2, r6, r7 | |
2d78: f507 2780 add.w r7, r7, #262144 ; 0x40000 | |
return -ENOMEM; | |
} | |
for (i = 0; i < num_threads; i++) { | |
handlers[i].fuse = fuse; | |
handlers[i].token = i; | |
2d7c: 6055 str r5, [r2, #4] | |
2d7e: 3758 adds r7, #88 ; 0x58 | |
if (!handlers) { | |
ERROR("cannot allocate storage for threads\n"); | |
return -ENOMEM; | |
} | |
for (i = 0; i < num_threads; i++) { | |
2d80: 3501 adds r5, #1 | |
2d82: e003 b.n 2d8c <run+0x2bc> | |
{ | |
struct fuse_handler* handlers; | |
int i; | |
handlers = malloc(num_threads * sizeof(struct fuse_handler)); | |
if (!handlers) { | |
2d84: 2700 movs r7, #0 | |
2d86: f60d 1118 addw r1, sp, #2328 ; 0x918 | |
2d8a: 463d mov r5, r7 | |
ERROR("cannot allocate storage for threads\n"); | |
return -ENOMEM; | |
} | |
for (i = 0; i < num_threads; i++) { | |
2d8c: f50d 50ce add.w r0, sp, #6592 ; 0x19c0 | |
2d90: 1d03 adds r3, r0, #4 | |
2d92: 681a ldr r2, [r3, #0] | |
2d94: 4295 cmp r5, r2 | |
2d96: dbed blt.n 2d74 <run+0x2a4> | |
handlers[i].token = i; | |
} | |
/* When deriving permissions, this thread is used to process inotify events, | |
* otherwise it becomes one of the FUSE handlers. */ | |
i = (fuse->derive == DERIVE_NONE) ? 1 : 0; | |
2d98: 694f ldr r7, [r1, #20] | |
for (; i < num_threads; i++) { | |
pthread_t thread; | |
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]); | |
2d9a: f8df 92c8 ldr.w r9, [pc, #712] ; 3064 <run+0x594> | |
handlers[i].token = i; | |
} | |
/* When deriving permissions, this thread is used to process inotify events, | |
* otherwise it becomes one of the FUSE handlers. */ | |
i = (fuse->derive == DERIVE_NONE) ? 1 : 0; | |
2d9e: f1d7 0501 rsbs r5, r7, #1 | |
2da2: bf38 it cc | |
2da4: 2500 movcc r5, #0 | |
for (; i < num_threads; i++) { | |
pthread_t thread; | |
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]); | |
2da6: 44f9 add r9, pc | |
" -s: split derived permissions for pics, av (requires -d or -l)\n" | |
"\n", DEFAULT_NUM_THREADS); | |
return 1; | |
} | |
static int run(const char* source_path, const char* dest_path, uid_t uid, | |
2da8: fb08 6805 mla r8, r8, r5, r6 | |
2dac: 2700 movs r7, #0 | |
2dae: e015 b.n 2ddc <run+0x30c> | |
/* When deriving permissions, this thread is used to process inotify events, | |
* otherwise it becomes one of the FUSE handlers. */ | |
i = (fuse->derive == DERIVE_NONE) ? 1 : 0; | |
for (; i < num_threads; i++) { | |
pthread_t thread; | |
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]); | |
2db0: eb07 0308 add.w r3, r7, r8 | |
2db4: a805 add r0, sp, #20 | |
2db6: 2100 movs r1, #0 | |
2db8: 464a mov r2, r9 | |
2dba: f507 2780 add.w r7, r7, #262144 ; 0x40000 | |
2dbe: f7fe ea5e blx 127c <pthread_create@plt> | |
2dc2: 3758 adds r7, #88 ; 0x58 | |
if (res) { | |
2dc4: 4603 mov r3, r0 | |
2dc6: b140 cbz r0, 2dda <run+0x30a> | |
ERROR("failed to start thread #%d, error=%d\n", i, res); | |
2dc8: 4e92 ldr r6, [pc, #584] ; (3014 <run+0x544>) | |
2dca: 462a mov r2, r5 | |
2dcc: 49a6 ldr r1, [pc, #664] ; (3068 <run+0x598>) | |
2dce: 59a0 ldr r0, [r4, r6] | |
2dd0: 4479 add r1, pc | |
2dd2: 30a8 adds r0, #168 ; 0xa8 | |
2dd4: f7fe e8de blx f94 <fprintf@plt> | |
2dd8: e0fe b.n 2fd8 <run+0x508> | |
} | |
/* When deriving permissions, this thread is used to process inotify events, | |
* otherwise it becomes one of the FUSE handlers. */ | |
i = (fuse->derive == DERIVE_NONE) ? 1 : 0; | |
for (; i < num_threads; i++) { | |
2dda: 3501 adds r5, #1 | |
2ddc: f50d 51ce add.w r1, sp, #6592 ; 0x19c0 | |
2de0: 1d08 adds r0, r1, #4 | |
2de2: 6803 ldr r3, [r0, #0] | |
2de4: 429d cmp r5, r3 | |
2de6: dbe3 blt.n 2db0 <run+0x2e0> | |
ERROR("failed to start thread #%d, error=%d\n", i, res); | |
goto quit; | |
} | |
} | |
if (fuse->derive == DERIVE_NONE) { | |
2de8: f60d 1518 addw r5, sp, #2328 ; 0x918 | |
2dec: 696a ldr r2, [r5, #20] | |
2dee: b912 cbnz r2, 2df6 <run+0x326> | |
handle_fuse_requests(&handlers[0]); | |
2df0: 4630 mov r0, r6 | |
2df2: f7ff fd09 bl 2808 <handle_fuse_requests> | |
static void watch_package_list(struct fuse* fuse) { | |
struct inotify_event *event; | |
char event_buf[512]; | |
int nfd = inotify_init(); | |
2df6: f7fe ea48 blx 1288 <inotify_init@plt> | |
if (nfd < 0) { | |
2dfa: f1b0 0800 subs.w r8, r0, #0 | |
2dfe: da0b bge.n 2e18 <run+0x348> | |
ERROR("inotify_init failed: %s\n", strerror(errno)); | |
2e00: 4d84 ldr r5, [pc, #528] ; (3014 <run+0x544>) | |
2e02: f7fe e8f8 blx ff4 <__errno@plt> | |
2e06: 6800 ldr r0, [r0, #0] | |
2e08: f7fe e93c blx 1084 <strerror@plt> | |
2e0c: 4997 ldr r1, [pc, #604] ; (306c <run+0x59c>) | |
2e0e: 4602 mov r2, r0 | |
2e10: 5960 ldr r0, [r4, r5] | |
2e12: 4479 add r1, pc | |
2e14: 30a8 adds r0, #168 ; 0xa8 | |
2e16: e0c6 b.n 2fa6 <run+0x4d6> | |
} | |
static int read_package_list(struct fuse *fuse) { | |
pthread_mutex_lock(&fuse->lock); | |
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid); | |
2e18: f505 5683 add.w r6, r5, #4192 ; 0x1060 | |
static void watch_package_list(struct fuse* fuse) { | |
struct inotify_event *event; | |
char event_buf[512]; | |
int nfd = inotify_init(); | |
if (nfd < 0) { | |
2e1c: 2700 movs r7, #0 | |
} | |
static int read_package_list(struct fuse *fuse) { | |
pthread_mutex_lock(&fuse->lock); | |
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid); | |
2e1e: f106 0910 add.w r9, r6, #16 | |
return; | |
} | |
bool active = false; | |
while (1) { | |
if (!active) { | |
2e22: 2f00 cmp r7, #0 | |
2e24: f040 80a6 bne.w 2f74 <run+0x4a4> | |
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF); | |
2e28: 4f91 ldr r7, [pc, #580] ; (3070 <run+0x5a0>) | |
if (res == -1) { | |
if (errno == ENOENT || errno == EACCES) { | |
/* Framework may not have created yet, sleep and retry */ | |
ERROR("missing packages.list; retrying\n"); | |
2e2a: f8df a248 ldr.w sl, [pc, #584] ; 3074 <run+0x5a4> | |
} | |
bool active = false; | |
while (1) { | |
if (!active) { | |
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF); | |
2e2e: 447f add r7, pc | |
if (res == -1) { | |
if (errno == ENOENT || errno == EACCES) { | |
/* Framework may not have created yet, sleep and retry */ | |
ERROR("missing packages.list; retrying\n"); | |
2e30: 44fa add sl, pc | |
} | |
bool active = false; | |
while (1) { | |
if (!active) { | |
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF); | |
2e32: 4640 mov r0, r8 | |
2e34: 4639 mov r1, r7 | |
2e36: f44f 6280 mov.w r2, #1024 ; 0x400 | |
2e3a: f7fe ea2c blx 1294 <inotify_add_watch@plt> | |
if (res == -1) { | |
2e3e: 3001 adds r0, #1 | |
2e40: d11c bne.n 2e7c <run+0x3ac> | |
if (errno == ENOENT || errno == EACCES) { | |
2e42: f7fe e8d8 blx ff4 <__errno@plt> | |
2e46: 6802 ldr r2, [r0, #0] | |
2e48: 4972 ldr r1, [pc, #456] ; (3014 <run+0x544>) | |
2e4a: 2a02 cmp r2, #2 | |
2e4c: f854 b001 ldr.w fp, [r4, r1] | |
2e50: d002 beq.n 2e58 <run+0x388> | |
2e52: 6803 ldr r3, [r0, #0] | |
2e54: 2b0d cmp r3, #13 | |
2e56: d108 bne.n 2e6a <run+0x39a> | |
/* Framework may not have created yet, sleep and retry */ | |
ERROR("missing packages.list; retrying\n"); | |
2e58: 4650 mov r0, sl | |
2e5a: f10b 01a8 add.w r1, fp, #168 ; 0xa8 | |
2e5e: f7fe ea08 blx 1270 <fputs@plt> | |
sleep(3); | |
2e62: 2003 movs r0, #3 | |
2e64: f7fe ea1c blx 12a0 <sleep@plt> | |
2e68: e7e3 b.n 2e32 <run+0x362> | |
continue; | |
} else { | |
ERROR("inotify_add_watch failed: %s\n", strerror(errno)); | |
2e6a: 6800 ldr r0, [r0, #0] | |
2e6c: f7fe e90a blx 1084 <strerror@plt> | |
2e70: 4981 ldr r1, [pc, #516] ; (3078 <run+0x5a8>) | |
2e72: 4602 mov r2, r0 | |
2e74: f10b 00a8 add.w r0, fp, #168 ; 0xa8 | |
2e78: 4479 add r1, pc | |
2e7a: e094 b.n 2fa6 <run+0x4d6> | |
hashmapRemove(map, key); | |
return true; | |
} | |
static int read_package_list(struct fuse *fuse) { | |
pthread_mutex_lock(&fuse->lock); | |
2e7c: 4628 mov r0, r5 | |
2e7e: f7fe e8d2 blx 1024 <pthread_mutex_lock@plt> | |
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid); | |
2e82: f8d9 0000 ldr.w r0, [r9] | |
2e86: 497d ldr r1, [pc, #500] ; (307c <run+0x5ac>) | |
2e88: 4602 mov r2, r0 | |
2e8a: 4479 add r1, pc | |
2e8c: f7fe ea0e blx 12ac <hashmapForEach@plt> | |
hashmapForEach(fuse->appid_with_rw, remove_int_to_null, fuse->appid_with_rw); | |
2e90: 6970 ldr r0, [r6, #20] | |
2e92: 497b ldr r1, [pc, #492] ; (3080 <run+0x5b0>) | |
2e94: 4602 mov r2, r0 | |
2e96: 4479 add r1, pc | |
2e98: f7fe ea08 blx 12ac <hashmapForEach@plt> | |
FILE* file = fopen(kPackagesListFile, "r"); | |
2e9c: 4979 ldr r1, [pc, #484] ; (3084 <run+0x5b4>) | |
2e9e: 4638 mov r0, r7 | |
2ea0: 4479 add r1, pc | |
2ea2: f7fe ea0a blx 12b8 <fopen@plt> | |
if (!file) { | |
2ea6: 4607 mov r7, r0 | |
2ea8: 2800 cmp r0, #0 | |
2eaa: d151 bne.n 2f50 <run+0x480> | |
ERROR("failed to open package list: %s\n", strerror(errno)); | |
2eac: 4e59 ldr r6, [pc, #356] ; (3014 <run+0x544>) | |
2eae: f7fe e8a2 blx ff4 <__errno@plt> | |
2eb2: 6800 ldr r0, [r0, #0] | |
2eb4: f7fe e8e6 blx 1084 <strerror@plt> | |
2eb8: 59a7 ldr r7, [r4, r6] | |
2eba: 4602 mov r2, r0 | |
2ebc: 4972 ldr r1, [pc, #456] ; (3088 <run+0x5b8>) | |
2ebe: 37a8 adds r7, #168 ; 0xa8 | |
2ec0: 4479 add r1, pc | |
2ec2: 4638 mov r0, r7 | |
2ec4: f7fe e866 blx f94 <fprintf@plt> | |
pthread_mutex_unlock(&fuse->lock); | |
2ec8: 4628 mov r0, r5 | |
2eca: f7fe e8b2 blx 1030 <pthread_mutex_unlock@plt> | |
} | |
/* Watch above will tell us about any future changes, so | |
* read the current state. */ | |
if (read_package_list(fuse) == -1) { | |
ERROR("read_package_list failed: %s\n", strerror(errno)); | |
2ece: f7fe e892 blx ff4 <__errno@plt> | |
2ed2: 6800 ldr r0, [r0, #0] | |
2ed4: f7fe e8d6 blx 1084 <strerror@plt> | |
2ed8: 496c ldr r1, [pc, #432] ; (308c <run+0x5bc>) | |
2eda: 4602 mov r2, r0 | |
2edc: 4638 mov r0, r7 | |
2ede: 4479 add r1, pc | |
2ee0: e061 b.n 2fa6 <run+0x4d6> | |
while (fgets(buf, sizeof(buf), file) != NULL) { | |
char package_name[512]; | |
int appid; | |
char gids[512]; | |
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) { | |
2ee2: f50d 6ae3 add.w sl, sp, #1816 ; 0x718 | |
2ee6: a8c6 add r0, sp, #792 ; 0x318 | |
2ee8: f8cd a000 str.w sl, [sp] | |
2eec: 4659 mov r1, fp | |
2eee: f50d 62a3 add.w r2, sp, #1304 ; 0x518 | |
2ef2: ab05 add r3, sp, #20 | |
2ef4: f7fe e9e6 blx 12c4 <sscanf@plt> | |
2ef8: 2803 cmp r0, #3 | |
2efa: d12c bne.n 2f56 <run+0x486> | |
char* package_name_dup = strdup(package_name); | |
2efc: f50d 60a3 add.w r0, sp, #1304 ; 0x518 | |
2f00: f7fe e992 blx 1228 <strdup@plt> | |
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid); | |
2f04: 9a05 ldr r2, [sp, #20] | |
char package_name[512]; | |
int appid; | |
char gids[512]; | |
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) { | |
char* package_name_dup = strdup(package_name); | |
2f06: 4601 mov r1, r0 | |
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid); | |
2f08: f8d9 0000 ldr.w r0, [r9] | |
2f0c: f7fe e9e0 blx 12d0 <hashmapPut@plt> | |
char* token = strtok(gids, ","); | |
2f10: 495f ldr r1, [pc, #380] ; (3090 <run+0x5c0>) | |
2f12: 4650 mov r0, sl | |
while (token != NULL) { | |
if (strtoul(token, NULL, 10) == fuse->write_gid) { | |
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1); | |
break; | |
} | |
token = strtok(NULL, ","); | |
2f14: f8df a17c ldr.w sl, [pc, #380] ; 3094 <run+0x5c4> | |
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) { | |
char* package_name_dup = strdup(package_name); | |
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid); | |
char* token = strtok(gids, ","); | |
2f18: 4479 add r1, pc | |
2f1a: f7fe e9e0 blx 12dc <strtok@plt> | |
while (token != NULL) { | |
if (strtoul(token, NULL, 10) == fuse->write_gid) { | |
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1); | |
break; | |
} | |
token = strtok(NULL, ","); | |
2f1e: 44fa add sl, pc | |
2f20: e013 b.n 2f4a <run+0x47a> | |
char* package_name_dup = strdup(package_name); | |
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid); | |
char* token = strtok(gids, ","); | |
while (token != NULL) { | |
if (strtoul(token, NULL, 10) == fuse->write_gid) { | |
2f22: 2100 movs r1, #0 | |
2f24: 220a movs r2, #10 | |
2f26: f7fe e90e blx 1144 <strtoul@plt> | |
2f2a: 69e9 ldr r1, [r5, #28] | |
2f2c: 4288 cmp r0, r1 | |
2f2e: d108 bne.n 2f42 <run+0x472> | |
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1); | |
2f30: f50d 53cc add.w r3, sp, #6528 ; 0x1980 | |
2f34: 9905 ldr r1, [sp, #20] | |
2f36: 330c adds r3, #12 | |
2f38: 2201 movs r2, #1 | |
2f3a: 6818 ldr r0, [r3, #0] | |
2f3c: f7fe e9c8 blx 12d0 <hashmapPut@plt> | |
2f40: e009 b.n 2f56 <run+0x486> | |
break; | |
} | |
token = strtok(NULL, ","); | |
2f42: 2000 movs r0, #0 | |
2f44: 4651 mov r1, sl | |
2f46: f7fe e9ca blx 12dc <strtok@plt> | |
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) { | |
char* package_name_dup = strdup(package_name); | |
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid); | |
char* token = strtok(gids, ","); | |
while (token != NULL) { | |
2f4a: 2800 cmp r0, #0 | |
2f4c: d1e9 bne.n 2f22 <run+0x452> | |
2f4e: e002 b.n 2f56 <run+0x486> | |
while (fgets(buf, sizeof(buf), file) != NULL) { | |
char package_name[512]; | |
int appid; | |
char gids[512]; | |
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) { | |
2f50: f8df b144 ldr.w fp, [pc, #324] ; 3098 <run+0x5c8> | |
2f54: 44fb add fp, pc | |
} | |
// Compiler can prove, at compile time, that the passed in size | |
// is always <= the actual object size. Don't call __fgets_chk | |
if (__builtin_constant_p(size) && (size <= (int) bos)) { | |
return __fgets_real(dest, size, stream); | |
2f56: a8c6 add r0, sp, #792 ; 0x318 | |
2f58: f44f 7100 mov.w r1, #512 ; 0x200 | |
2f5c: 463a mov r2, r7 | |
2f5e: f7fe e9c4 blx 12e8 <fgets@plt> | |
pthread_mutex_unlock(&fuse->lock); | |
return -1; | |
} | |
char buf[512]; | |
while (fgets(buf, sizeof(buf), file) != NULL) { | |
2f62: 2800 cmp r0, #0 | |
2f64: d1bd bne.n 2ee2 <run+0x412> | |
} | |
TRACE("read_package_list: found %d packages, %d with write_gid\n", | |
hashmapSize(fuse->package_to_appid), | |
hashmapSize(fuse->appid_with_rw)); | |
fclose(file); | |
2f66: 4638 mov r0, r7 | |
* read the current state. */ | |
if (read_package_list(fuse) == -1) { | |
ERROR("read_package_list failed: %s\n", strerror(errno)); | |
return; | |
} | |
active = true; | |
2f68: 2701 movs r7, #1 | |
} | |
TRACE("read_package_list: found %d packages, %d with write_gid\n", | |
hashmapSize(fuse->package_to_appid), | |
hashmapSize(fuse->appid_with_rw)); | |
fclose(file); | |
2f6a: f7fe e9c4 blx 12f4 <fclose@plt> | |
pthread_mutex_unlock(&fuse->lock); | |
2f6e: 4628 mov r0, r5 | |
2f70: f7fe e85e blx 1030 <pthread_mutex_unlock@plt> | |
} | |
active = true; | |
} | |
int event_pos = 0; | |
int res = read(nfd, event_buf, sizeof(event_buf)); | |
2f74: f50d 7a8c add.w sl, sp, #280 ; 0x118 | |
2f78: 4640 mov r0, r8 | |
2f7a: 4651 mov r1, sl | |
2f7c: f44f 7200 mov.w r2, #512 ; 0x200 | |
2f80: f7fe e90a blx 1198 <read@plt> | |
if (res < (int) sizeof(*event)) { | |
2f84: 280f cmp r0, #15 | |
2f86: dc11 bgt.n 2fac <run+0x4dc> | |
if (errno == EINTR) | |
2f88: f7fe e834 blx ff4 <__errno@plt> | |
2f8c: 6802 ldr r2, [r0, #0] | |
2f8e: 2a04 cmp r2, #4 | |
2f90: f43f af47 beq.w 2e22 <run+0x352> | |
continue; | |
ERROR("failed to read inotify event: %s\n", strerror(errno)); | |
2f94: 6800 ldr r0, [r0, #0] | |
2f96: f7fe e876 blx 1084 <strerror@plt> | |
2f9a: 4602 mov r2, r0 | |
2f9c: 481d ldr r0, [pc, #116] ; (3014 <run+0x544>) | |
2f9e: 493f ldr r1, [pc, #252] ; (309c <run+0x5cc>) | |
2fa0: 5820 ldr r0, [r4, r0] | |
2fa2: 4479 add r1, pc | |
2fa4: 30a8 adds r0, #168 ; 0xa8 | |
2fa6: f7fd eff6 blx f94 <fprintf@plt> | |
2faa: e00e b.n 2fca <run+0x4fa> | |
active = true; | |
} | |
int event_pos = 0; | |
int res = read(nfd, event_buf, sizeof(event_buf)); | |
if (res < (int) sizeof(*event)) { | |
2fac: 2300 movs r3, #0 | |
return; | |
} | |
while (res >= (int) sizeof(*event)) { | |
int event_size; | |
event = (struct inotify_event *) (event_buf + event_pos); | |
2fae: eb0a 0103 add.w r1, sl, r3 | |
TRACE("inotify event: %08x\n", event->mask); | |
if ((event->mask & IN_IGNORED) == IN_IGNORED) { | |
2fb2: 684a ldr r2, [r1, #4] | |
/* Previously watched file was deleted, probably due to move | |
* that swapped in new data; re-arm the watch and read. */ | |
active = false; | |
} | |
event_size = sizeof(*event) + event->len; | |
2fb4: 68c9 ldr r1, [r1, #12] | |
TRACE("inotify event: %08x\n", event->mask); | |
if ((event->mask & IN_IGNORED) == IN_IGNORED) { | |
/* Previously watched file was deleted, probably due to move | |
* that swapped in new data; re-arm the watch and read. */ | |
active = false; | |
2fb6: f412 4f00 tst.w r2, #32768 ; 0x8000 | |
2fba: bf18 it ne | |
2fbc: 2700 movne r7, #0 | |
} | |
event_size = sizeof(*event) + event->len; | |
2fbe: 3110 adds r1, #16 | |
res -= event_size; | |
2fc0: 1a40 subs r0, r0, r1 | |
event_pos += event_size; | |
2fc2: 185b adds r3, r3, r1 | |
continue; | |
ERROR("failed to read inotify event: %s\n", strerror(errno)); | |
return; | |
} | |
while (res >= (int) sizeof(*event)) { | |
2fc4: 280f cmp r0, #15 | |
2fc6: dcf2 bgt.n 2fae <run+0x4de> | |
2fc8: e72b b.n 2e22 <run+0x352> | |
handle_fuse_requests(&handlers[0]); | |
} else { | |
watch_package_list(fuse); | |
} | |
ERROR("terminated prematurely\n"); | |
2fca: 4812 ldr r0, [pc, #72] ; (3014 <run+0x544>) | |
2fcc: 5821 ldr r1, [r4, r0] | |
2fce: 4834 ldr r0, [pc, #208] ; (30a0 <run+0x5d0>) | |
2fd0: 31a8 adds r1, #168 ; 0xa8 | |
2fd2: 4478 add r0, pc | |
2fd4: f7fe e94c blx 1270 <fputs@plt> | |
/* don't bother killing all of the other threads or freeing anything, | |
* should never get here anyhow */ | |
quit: | |
exit(1); | |
2fd8: 2001 movs r0, #1 | |
2fda: f7fe e992 blx 1300 <exit@plt> | |
/* we do not attempt to umount the file system here because we are no longer | |
* running as the root user */ | |
error: | |
close(fd); | |
2fde: 9802 ldr r0, [sp, #8] | |
2fe0: f7fe e856 blx 1090 <close@plt> | |
return res; | |
} | |
2fe4: 9b03 ldr r3, [sp, #12] | |
2fe6: f50d 52cc add.w r2, sp, #6528 ; 0x1980 | |
2fea: 3214 adds r2, #20 | |
2fec: 4650 mov r0, sl | |
2fee: 6812 ldr r2, [r2, #0] | |
2ff0: 6819 ldr r1, [r3, #0] | |
2ff2: 428a cmp r2, r1 | |
2ff4: d001 beq.n 2ffa <run+0x52a> | |
2ff6: f7fe e828 blx 1048 <__stack_chk_fail@plt> | |
2ffa: b067 add sp, #412 ; 0x19c | |
2ffc: f50d 5dc0 add.w sp, sp, #6144 ; 0x1800 | |
3000: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
3004: 00040058 .word 0x00040058 | |
3008: 000023d0 .word 0x000023d0 | |
300c: fffffff4 .word 0xfffffff4 | |
3010: 00000cdf .word 0x00000cdf | |
3014: fffffff0 .word 0xfffffff0 | |
3018: 00000cab .word 0x00000cab | |
301c: 00000caa .word 0x00000caa | |
3020: 00000ce2 .word 0x00000ce2 | |
3024: 00000cc3 .word 0x00000cc3 | |
3028: 00000938 .word 0x00000938 | |
302c: 00000cb9 .word 0x00000cb9 | |
3030: 00000ca7 .word 0x00000ca7 | |
3034: 00000c90 .word 0x00000c90 | |
3038: ffffe765 .word 0xffffe765 | |
303c: ffffe76d .word 0xffffe76d | |
3040: ffffe717 .word 0xffffe717 | |
3044: ffffe717 .word 0xffffe717 | |
3048: 00000bdd .word 0x00000bdd | |
304c: ffffe715 .word 0xffffe715 | |
3050: ffffe701 .word 0xffffe701 | |
3054: ffffe6b7 .word 0xffffe6b7 | |
3058: ffffe6b7 .word 0xffffe6b7 | |
305c: 00000b82 .word 0x00000b82 | |
3060: 00000b63 .word 0x00000b63 | |
3064: 000002fb .word 0x000002fb | |
3068: 00000b22 .word 0x00000b22 | |
306c: 00000b06 .word 0x00000b06 | |
3070: 00000b03 .word 0x00000b03 | |
3074: 00000b1c .word 0x00000b1c | |
3078: 00000af5 .word 0x00000af5 | |
307c: ffffe613 .word 0xffffe613 | |
3080: ffffe5f9 .word 0xffffe5f9 | |
3084: 00000aeb .word 0x00000aeb | |
3088: 00000acd .word 0x00000acd | |
308c: 00000ae7 .word 0x00000ae7 | |
3090: 00000aab .word 0x00000aab | |
3094: 00000aa5 .word 0x00000aa5 | |
3098: 00000a5a .word 0x00000a5a | |
309c: 00000a41 .word 0x00000a41 | |
30a0: 00000a33 .word 0x00000a33 | |
000030a4 <start_handler>: | |
} | |
} | |
} | |
static void* start_handler(void* data) | |
{ | |
30a4: b508 push {r3, lr} | |
struct fuse_handler* handler = data; | |
handle_fuse_requests(handler); | |
30a6: f7ff fbaf bl 2808 <handle_fuse_requests> | |
... | |
000030ac <sdcard_main>: | |
close(fd); | |
return res; | |
} | |
int sdcard_main(int argc, char **argv) | |
{ | |
30ac: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} | |
int res; | |
const char *source_path = NULL; | |
const char *dest_path = NULL; | |
uid_t uid = 0; | |
gid_t gid = 0; | |
gid_t write_gid = AID_SDCARD_RW; | |
30b0: f240 33f7 movw r3, #1015 ; 0x3f7 | |
close(fd); | |
return res; | |
} | |
int sdcard_main(int argc, char **argv) | |
{ | |
30b4: f8df b1b0 ldr.w fp, [pc, #432] ; 3268 <sdcard_main+0x1bc> | |
30b8: b08b sub sp, #44 ; 0x2c | |
uid_t uid = 0; | |
gid_t gid = 0; | |
gid_t write_gid = AID_SDCARD_RW; | |
int num_threads = DEFAULT_NUM_THREADS; | |
derive_t derive = DERIVE_NONE; | |
bool split_perms = false; | |
30ba: 2600 movs r6, #0 | |
const char *source_path = NULL; | |
const char *dest_path = NULL; | |
uid_t uid = 0; | |
gid_t gid = 0; | |
gid_t write_gid = AID_SDCARD_RW; | |
int num_threads = DEFAULT_NUM_THREADS; | |
30bc: f04f 0a02 mov.w sl, #2 | |
bool split_perms = false; | |
int i; | |
struct rlimit rlim; | |
int opt; | |
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) { | |
30c0: 4f6a ldr r7, [pc, #424] ; (326c <sdcard_main+0x1c0>) | |
const char *dest_path = NULL; | |
uid_t uid = 0; | |
gid_t gid = 0; | |
gid_t write_gid = AID_SDCARD_RW; | |
int num_threads = DEFAULT_NUM_THREADS; | |
derive_t derive = DERIVE_NONE; | |
30c2: 46b1 mov r9, r6 | |
close(fd); | |
return res; | |
} | |
int sdcard_main(int argc, char **argv) | |
{ | |
30c4: 44fb add fp, pc | |
30c6: 9006 str r0, [sp, #24] | |
30c8: 9107 str r1, [sp, #28] | |
int res; | |
const char *source_path = NULL; | |
const char *dest_path = NULL; | |
uid_t uid = 0; | |
gid_t gid = 0; | |
30ca: 4634 mov r4, r6 | |
gid_t write_gid = AID_SDCARD_RW; | |
30cc: 9305 str r3, [sp, #20] | |
int sdcard_main(int argc, char **argv) | |
{ | |
int res; | |
const char *source_path = NULL; | |
const char *dest_path = NULL; | |
uid_t uid = 0; | |
30ce: 4635 mov r5, r6 | |
bool split_perms = false; | |
int i; | |
struct rlimit rlim; | |
int opt; | |
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) { | |
30d0: 447f add r7, pc | |
30d2: e03e b.n 3152 <sdcard_main+0xa6> | |
switch (opt) { | |
30d4: 3864 subs r0, #100 ; 0x64 | |
30d6: 2813 cmp r0, #19 | |
30d8: d86a bhi.n 31b0 <sdcard_main+0x104> | |
30da: e8df f000 tbb [pc, r0] | |
30de: 6935 .short 0x6935 | |
30e0: 69691469 .word 0x69691469 | |
30e4: 69386969 .word 0x69386969 | |
30e8: 69696969 .word 0x69696969 | |
30ec: 0a293369 .word 0x0a293369 | |
30f0: 1e69 .short 0x1e69 | |
case 'u': | |
uid = strtoul(optarg, NULL, 10); | |
30f2: 4d5f ldr r5, [pc, #380] ; (3270 <sdcard_main+0x1c4>) | |
30f4: 220a movs r2, #10 | |
30f6: f85b 1005 ldr.w r1, [fp, r5] | |
30fa: 6808 ldr r0, [r1, #0] | |
30fc: 2100 movs r1, #0 | |
30fe: f7fe e822 blx 1144 <strtoul@plt> | |
3102: 4605 mov r5, r0 | |
break; | |
3104: e025 b.n 3152 <sdcard_main+0xa6> | |
case 'g': | |
gid = strtoul(optarg, NULL, 10); | |
3106: 4c5a ldr r4, [pc, #360] ; (3270 <sdcard_main+0x1c4>) | |
3108: 2100 movs r1, #0 | |
310a: f85b 2004 ldr.w r2, [fp, r4] | |
310e: 6810 ldr r0, [r2, #0] | |
3110: 220a movs r2, #10 | |
3112: f7fe e818 blx 1144 <strtoul@plt> | |
3116: 4604 mov r4, r0 | |
break; | |
3118: e01b b.n 3152 <sdcard_main+0xa6> | |
case 'w': | |
write_gid = strtoul(optarg, NULL, 10); | |
311a: f8df e154 ldr.w lr, [pc, #340] ; 3270 <sdcard_main+0x1c4> | |
311e: 2100 movs r1, #0 | |
3120: f85b 200e ldr.w r2, [fp, lr] | |
3124: 6810 ldr r0, [r2, #0] | |
3126: 220a movs r2, #10 | |
3128: f7fe e80c blx 1144 <strtoul@plt> | |
312c: 9005 str r0, [sp, #20] | |
break; | |
312e: e010 b.n 3152 <sdcard_main+0xa6> | |
case 't': | |
num_threads = strtoul(optarg, NULL, 10); | |
3130: 484f ldr r0, [pc, #316] ; (3270 <sdcard_main+0x1c4>) | |
3132: 2100 movs r1, #0 | |
3134: 220a movs r2, #10 | |
3136: f85b 3000 ldr.w r3, [fp, r0] | |
313a: 6818 ldr r0, [r3, #0] | |
313c: f7fe e802 blx 1144 <strtoul@plt> | |
3140: 4682 mov sl, r0 | |
break; | |
3142: e006 b.n 3152 <sdcard_main+0xa6> | |
break; | |
case 'l': | |
derive = DERIVE_LEGACY; | |
break; | |
case 's': | |
split_perms = true; | |
3144: 2601 movs r6, #1 | |
break; | |
3146: e004 b.n 3152 <sdcard_main+0xa6> | |
break; | |
case 't': | |
num_threads = strtoul(optarg, NULL, 10); | |
break; | |
case 'd': | |
derive = DERIVE_UNIFIED; | |
3148: f04f 0902 mov.w r9, #2 | |
314c: e001 b.n 3152 <sdcard_main+0xa6> | |
break; | |
case 'l': | |
derive = DERIVE_LEGACY; | |
314e: f04f 0901 mov.w r9, #1 | |
bool split_perms = false; | |
int i; | |
struct rlimit rlim; | |
int opt; | |
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) { | |
3152: 9806 ldr r0, [sp, #24] | |
3154: 463a mov r2, r7 | |
3156: 9907 ldr r1, [sp, #28] | |
3158: f7fe e8d8 blx 130c <getopt@plt> | |
315c: 1c43 adds r3, r0, #1 | |
315e: d1b9 bne.n 30d4 <sdcard_main+0x28> | |
default: | |
return usage(); | |
} | |
} | |
for (i = optind; i < argc; i++) { | |
3160: 4a44 ldr r2, [pc, #272] ; (3274 <sdcard_main+0x1c8>) | |
int sdcard_main(int argc, char **argv) | |
{ | |
int res; | |
const char *source_path = NULL; | |
const char *dest_path = NULL; | |
3162: 2700 movs r7, #0 | |
} | |
int sdcard_main(int argc, char **argv) | |
{ | |
int res; | |
const char *source_path = NULL; | |
3164: 46b8 mov r8, r7 | |
default: | |
return usage(); | |
} | |
} | |
for (i = optind; i < argc; i++) { | |
3166: f85b 0002 ldr.w r0, [fp, r2] | |
316a: 6803 ldr r3, [r0, #0] | |
316c: e027 b.n 31be <sdcard_main+0x112> | |
char* arg = argv[i]; | |
316e: 9807 ldr r0, [sp, #28] | |
3170: f850 0023 ldr.w r0, [r0, r3, lsl #2] | |
if (!source_path) { | |
3174: f1b8 0f00 cmp.w r8, #0 | |
3178: d01d beq.n 31b6 <sdcard_main+0x10a> | |
source_path = arg; | |
} else if (!dest_path) { | |
317a: b1f7 cbz r7, 31ba <sdcard_main+0x10e> | |
dest_path = arg; | |
} else if (!uid) { | |
317c: b935 cbnz r5, 318c <sdcard_main+0xe0> | |
uid = strtoul(arg, NULL, 10); | |
317e: 4629 mov r1, r5 | |
3180: 220a movs r2, #10 | |
3182: 9304 str r3, [sp, #16] | |
3184: f7fd efde blx 1144 <strtoul@plt> | |
3188: 4605 mov r5, r0 | |
318a: e006 b.n 319a <sdcard_main+0xee> | |
} else if (!gid) { | |
318c: b93c cbnz r4, 319e <sdcard_main+0xf2> | |
gid = strtoul(arg, NULL, 10); | |
318e: 4621 mov r1, r4 | |
3190: 220a movs r2, #10 | |
3192: 9304 str r3, [sp, #16] | |
3194: f7fd efd6 blx 1144 <strtoul@plt> | |
3198: 4604 mov r4, r0 | |
319a: 9b04 ldr r3, [sp, #16] | |
319c: e00e b.n 31bc <sdcard_main+0x110> | |
} else { | |
ERROR("too many arguments\n"); | |
319e: f8df c0d8 ldr.w ip, [pc, #216] ; 3278 <sdcard_main+0x1cc> | |
31a2: 4836 ldr r0, [pc, #216] ; (327c <sdcard_main+0x1d0>) | |
31a4: f85b 100c ldr.w r1, [fp, ip] | |
31a8: 4478 add r0, pc | |
31aa: 31a8 adds r1, #168 ; 0xa8 | |
31ac: f7fe e860 blx 1270 <fputs@plt> | |
return usage(); | |
31b0: f7fe f91c bl 13ec <usage> | |
31b4: e054 b.n 3260 <sdcard_main+0x1b4> | |
} | |
for (i = optind; i < argc; i++) { | |
char* arg = argv[i]; | |
if (!source_path) { | |
source_path = arg; | |
31b6: 4680 mov r8, r0 | |
31b8: e000 b.n 31bc <sdcard_main+0x110> | |
} else if (!dest_path) { | |
dest_path = arg; | |
31ba: 4607 mov r7, r0 | |
default: | |
return usage(); | |
} | |
} | |
for (i = optind; i < argc; i++) { | |
31bc: 3301 adds r3, #1 | |
31be: 9906 ldr r1, [sp, #24] | |
31c0: 428b cmp r3, r1 | |
31c2: dbd4 blt.n 316e <sdcard_main+0xc2> | |
ERROR("too many arguments\n"); | |
return usage(); | |
} | |
} | |
if (!source_path) { | |
31c4: f1b8 0f00 cmp.w r8, #0 | |
31c8: d105 bne.n 31d6 <sdcard_main+0x12a> | |
ERROR("no source path specified\n"); | |
31ca: 4b2b ldr r3, [pc, #172] ; (3278 <sdcard_main+0x1cc>) | |
31cc: 482c ldr r0, [pc, #176] ; (3280 <sdcard_main+0x1d4>) | |
31ce: f85b 1003 ldr.w r1, [fp, r3] | |
31d2: 4478 add r0, pc | |
31d4: e7e9 b.n 31aa <sdcard_main+0xfe> | |
return usage(); | |
} | |
if (!dest_path) { | |
31d6: b92f cbnz r7, 31e4 <sdcard_main+0x138> | |
ERROR("no dest path specified\n"); | |
31d8: 4927 ldr r1, [pc, #156] ; (3278 <sdcard_main+0x1cc>) | |
31da: 482a ldr r0, [pc, #168] ; (3284 <sdcard_main+0x1d8>) | |
31dc: f85b 1001 ldr.w r1, [fp, r1] | |
31e0: 4478 add r0, pc | |
31e2: e7e2 b.n 31aa <sdcard_main+0xfe> | |
return usage(); | |
} | |
if (!uid || !gid) { | |
31e4: b105 cbz r5, 31e8 <sdcard_main+0x13c> | |
31e6: b92c cbnz r4, 31f4 <sdcard_main+0x148> | |
ERROR("uid and gid must be nonzero\n"); | |
31e8: 4a23 ldr r2, [pc, #140] ; (3278 <sdcard_main+0x1cc>) | |
31ea: 4827 ldr r0, [pc, #156] ; (3288 <sdcard_main+0x1dc>) | |
31ec: f85b 1002 ldr.w r1, [fp, r2] | |
31f0: 4478 add r0, pc | |
31f2: e7da b.n 31aa <sdcard_main+0xfe> | |
return usage(); | |
} | |
if (num_threads < 1) { | |
31f4: f1ba 0f00 cmp.w sl, #0 | |
31f8: dc06 bgt.n 3208 <sdcard_main+0x15c> | |
ERROR("number of threads must be at least 1\n"); | |
31fa: f8df e07c ldr.w lr, [pc, #124] ; 3278 <sdcard_main+0x1cc> | |
31fe: 4823 ldr r0, [pc, #140] ; (328c <sdcard_main+0x1e0>) | |
3200: f85b 100e ldr.w r1, [fp, lr] | |
3204: 4478 add r0, pc | |
3206: e7d0 b.n 31aa <sdcard_main+0xfe> | |
return usage(); | |
} | |
if (split_perms && derive == DERIVE_NONE) { | |
3208: b14e cbz r6, 321e <sdcard_main+0x172> | |
320a: f1b9 0f00 cmp.w r9, #0 | |
320e: d106 bne.n 321e <sdcard_main+0x172> | |
ERROR("cannot split permissions without deriving\n"); | |
3210: f8df c064 ldr.w ip, [pc, #100] ; 3278 <sdcard_main+0x1cc> | |
3214: 481e ldr r0, [pc, #120] ; (3290 <sdcard_main+0x1e4>) | |
3216: f85b 100c ldr.w r1, [fp, ip] | |
321a: 4478 add r0, pc | |
321c: e7c5 b.n 31aa <sdcard_main+0xfe> | |
return usage(); | |
} | |
rlim.rlim_cur = 8192; | |
321e: f44f 5300 mov.w r3, #8192 ; 0x2000 | |
rlim.rlim_max = 8192; | |
if (setrlimit(RLIMIT_NOFILE, &rlim)) { | |
3222: 2007 movs r0, #7 | |
3224: a908 add r1, sp, #32 | |
if (split_perms && derive == DERIVE_NONE) { | |
ERROR("cannot split permissions without deriving\n"); | |
return usage(); | |
} | |
rlim.rlim_cur = 8192; | |
3226: 9308 str r3, [sp, #32] | |
rlim.rlim_max = 8192; | |
3228: 9309 str r3, [sp, #36] ; 0x24 | |
if (setrlimit(RLIMIT_NOFILE, &rlim)) { | |
322a: f7fe e876 blx 1318 <setrlimit@plt> | |
322e: b150 cbz r0, 3246 <sdcard_main+0x19a> | |
ERROR("Error setting RLIMIT_NOFILE, errno = %d\n", errno); | |
3230: f7fd eee0 blx ff4 <__errno@plt> | |
3234: 6802 ldr r2, [r0, #0] | |
3236: 4810 ldr r0, [pc, #64] ; (3278 <sdcard_main+0x1cc>) | |
3238: 4916 ldr r1, [pc, #88] ; (3294 <sdcard_main+0x1e8>) | |
323a: f85b 0000 ldr.w r0, [fp, r0] | |
323e: 4479 add r1, pc | |
3240: 30a8 adds r0, #168 ; 0xa8 | |
3242: f7fd eea8 blx f94 <fprintf@plt> | |
} | |
res = run(source_path, dest_path, uid, gid, write_gid, num_threads, derive, split_perms); | |
3246: 9b05 ldr r3, [sp, #20] | |
3248: 4640 mov r0, r8 | |
324a: f8cd 9008 str.w r9, [sp, #8] | |
324e: 4639 mov r1, r7 | |
3250: 9603 str r6, [sp, #12] | |
3252: 462a mov r2, r5 | |
3254: e88d 0408 stmia.w sp, {r3, sl} | |
3258: 4623 mov r3, r4 | |
325a: f7ff fc39 bl 2ad0 <run> | |
return res < 0 ? 1 : 0; | |
325e: 0fc0 lsrs r0, r0, #31 | |
} | |
3260: b00b add sp, #44 ; 0x2c | |
3262: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} | |
3266: bf00 nop | |
3268: 00001df4 .word 0x00001df4 | |
326c: 0000094d .word 0x0000094d | |
3270: fffffff8 .word 0xfffffff8 | |
3274: fffffffc .word 0xfffffffc | |
3278: fffffff0 .word 0xfffffff0 | |
327c: 00000881 .word 0x00000881 | |
3280: 0000086b .word 0x0000086b | |
3284: 00000877 .word 0x00000877 | |
3288: 0000087f .word 0x0000087f | |
328c: 00000888 .word 0x00000888 | |
3290: 00000898 .word 0x00000898 | |
3294: 0000089f .word 0x0000089f | |
3298: 46c04778 .word 0x46c04778 | |
329c: e59fc000 .word 0xe59fc000 | |
32a0: e08cf00f .word 0xe08cf00f | |
32a4: ffffdd10 .word 0xffffdd10 | |
32a8: 46c04778 .word 0x46c04778 | |
32ac: e59fc000 .word 0xe59fc000 | |
32b0: e08cf00f .word 0xe08cf00f | |
32b4: ffffdd24 .word 0xffffdd24 | |
32b8: 46c04778 .word 0x46c04778 | |
32bc: e59fc000 .word 0xe59fc000 | |
32c0: e08cf00f .word 0xe08cf00f | |
32c4: ffffdccc .word 0xffffdccc | |
32c8: 46c04778 .word 0x46c04778 | |
32cc: e59fc000 .word 0xe59fc000 | |
32d0: e08cf00f .word 0xe08cf00f | |
32d4: ffffdd40 .word 0xffffdd40 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment