xref: /aosp_15_r20/external/lz4/tests/freestanding.c (revision 27162e4e17433d5aa7cb38e7b6a433a09405fc7f)
1*27162e4eSAndroid Build Coastguard Worker // Basic test for LZ4_FREESTANDING
2*27162e4eSAndroid Build Coastguard Worker 
3*27162e4eSAndroid Build Coastguard Worker // $ gcc -ffreestanding -nostdlib freestanding.c && ./a.out || echo $?
4*27162e4eSAndroid Build Coastguard Worker 
5*27162e4eSAndroid Build Coastguard Worker // $ strace ./a.out
6*27162e4eSAndroid Build Coastguard Worker // execve("./a.out", ["./a.out"], 0x7fffaf5fa580 /* 22 vars */) = 0
7*27162e4eSAndroid Build Coastguard Worker // brk(NULL)                               = 0x56536f4fe000
8*27162e4eSAndroid Build Coastguard Worker // arch_prctl(0x3001 /* ARCH_??? */, 0x7fffc9e74950) = -1 EINVAL (Invalid argument)
9*27162e4eSAndroid Build Coastguard Worker // mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd5c9c2b000
10*27162e4eSAndroid Build Coastguard Worker // access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
11*27162e4eSAndroid Build Coastguard Worker // arch_prctl(ARCH_SET_FS, 0x7fd5c9c2bc40) = 0
12*27162e4eSAndroid Build Coastguard Worker // set_tid_address(0x7fd5c9c2bf10)         = 381
13*27162e4eSAndroid Build Coastguard Worker // set_robust_list(0x7fd5c9c2bf20, 24)     = 0
14*27162e4eSAndroid Build Coastguard Worker // rseq(0x7fd5c9c2c5e0, 0x20, 0, 0x53053053) = 0
15*27162e4eSAndroid Build Coastguard Worker // mprotect(0x56536ea63000, 4096, PROT_READ) = 0
16*27162e4eSAndroid Build Coastguard Worker // exit(0)                                 = ?
17*27162e4eSAndroid Build Coastguard Worker // +++ exited with 0 +++
18*27162e4eSAndroid Build Coastguard Worker 
19*27162e4eSAndroid Build Coastguard Worker // $ ltrace ./a.out
20*27162e4eSAndroid Build Coastguard Worker // +++ exited (status 0) +++
21*27162e4eSAndroid Build Coastguard Worker 
22*27162e4eSAndroid Build Coastguard Worker #include <stddef.h>
23*27162e4eSAndroid Build Coastguard Worker #include <stdint.h>
24*27162e4eSAndroid Build Coastguard Worker 
25*27162e4eSAndroid Build Coastguard Worker #if defined(__cplusplus)
26*27162e4eSAndroid Build Coastguard Worker #  define EXTERN_C extern "C"
27*27162e4eSAndroid Build Coastguard Worker #else
28*27162e4eSAndroid Build Coastguard Worker #  define EXTERN_C
29*27162e4eSAndroid Build Coastguard Worker #endif
30*27162e4eSAndroid Build Coastguard Worker 
31*27162e4eSAndroid Build Coastguard Worker 
32*27162e4eSAndroid Build Coastguard Worker #if !defined(__x86_64__) || !defined(__linux__)
main(int argc,char ** argv)33*27162e4eSAndroid Build Coastguard Worker int main(int argc, char** argv) { return 0; }
34*27162e4eSAndroid Build Coastguard Worker #else
35*27162e4eSAndroid Build Coastguard Worker 
36*27162e4eSAndroid Build Coastguard Worker static void MY_exit(int exitCode);
37*27162e4eSAndroid Build Coastguard Worker static void MY_abort(void);
38*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memmove(void *dst, const void *src, size_t n);
39*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memcpy(void * __restrict__ dst, const void * __restrict__ src, size_t n);
40*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memset(void *s, int c, size_t n);
41*27162e4eSAndroid Build Coastguard Worker EXTERN_C int memcmp(const void *s1, const void *s2, size_t n);
42*27162e4eSAndroid Build Coastguard Worker 
43*27162e4eSAndroid Build Coastguard Worker // LZ4/HC basic freestanding setup
44*27162e4eSAndroid Build Coastguard Worker #define LZ4_FREESTANDING 1
45*27162e4eSAndroid Build Coastguard Worker #define LZ4_memmove(dst, src, size) memmove((dst),(src),(size))
46*27162e4eSAndroid Build Coastguard Worker #define LZ4_memcpy(dst, src, size)  memcpy((dst),(src),(size))
47*27162e4eSAndroid Build Coastguard Worker #define LZ4_memset(p,v,s)           memset((p),(v),(s))
48*27162e4eSAndroid Build Coastguard Worker 
49*27162e4eSAndroid Build Coastguard Worker #include "../lib/lz4.c"
50*27162e4eSAndroid Build Coastguard Worker #include "../lib/lz4hc.c"
51*27162e4eSAndroid Build Coastguard Worker 
52*27162e4eSAndroid Build Coastguard Worker // Test for LZ4
test_lz4(const uint8_t * srcData,int srcSize)53*27162e4eSAndroid Build Coastguard Worker static void test_lz4(const uint8_t* srcData, int srcSize) {
54*27162e4eSAndroid Build Coastguard Worker     // Compress
55*27162e4eSAndroid Build Coastguard Worker     static uint8_t compressBuffer[1024 * 1024];
56*27162e4eSAndroid Build Coastguard Worker     const int compressedSize = LZ4_compress_default(
57*27162e4eSAndroid Build Coastguard Worker         (const char*) srcData,
58*27162e4eSAndroid Build Coastguard Worker         (char*) compressBuffer,
59*27162e4eSAndroid Build Coastguard Worker         srcSize,
60*27162e4eSAndroid Build Coastguard Worker         sizeof(compressBuffer)
61*27162e4eSAndroid Build Coastguard Worker     );
62*27162e4eSAndroid Build Coastguard Worker     if (compressedSize <= 0) {
63*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
64*27162e4eSAndroid Build Coastguard Worker     }
65*27162e4eSAndroid Build Coastguard Worker 
66*27162e4eSAndroid Build Coastguard Worker     // Decompress
67*27162e4eSAndroid Build Coastguard Worker     static uint8_t decompressBuffer[1024 * 1024];
68*27162e4eSAndroid Build Coastguard Worker     const int decompressedSize = LZ4_decompress_safe(
69*27162e4eSAndroid Build Coastguard Worker         (const char*) compressBuffer,
70*27162e4eSAndroid Build Coastguard Worker         (char*) decompressBuffer,
71*27162e4eSAndroid Build Coastguard Worker         compressedSize,
72*27162e4eSAndroid Build Coastguard Worker         sizeof(decompressBuffer)
73*27162e4eSAndroid Build Coastguard Worker     );
74*27162e4eSAndroid Build Coastguard Worker     if (decompressedSize <= 0) {
75*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
76*27162e4eSAndroid Build Coastguard Worker     }
77*27162e4eSAndroid Build Coastguard Worker 
78*27162e4eSAndroid Build Coastguard Worker     // Verify
79*27162e4eSAndroid Build Coastguard Worker     if (decompressedSize != srcSize) {
80*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
81*27162e4eSAndroid Build Coastguard Worker     }
82*27162e4eSAndroid Build Coastguard Worker     if (memcmp(srcData, decompressBuffer, srcSize) != 0) {
83*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
84*27162e4eSAndroid Build Coastguard Worker     }
85*27162e4eSAndroid Build Coastguard Worker }
86*27162e4eSAndroid Build Coastguard Worker 
87*27162e4eSAndroid Build Coastguard Worker 
88*27162e4eSAndroid Build Coastguard Worker // Test for LZ4HC
test_lz4hc(const uint8_t * srcData,int srcSize)89*27162e4eSAndroid Build Coastguard Worker static void test_lz4hc(const uint8_t* srcData, int srcSize) {
90*27162e4eSAndroid Build Coastguard Worker     // Compress
91*27162e4eSAndroid Build Coastguard Worker     static uint8_t compressBuffer[1024 * 1024];
92*27162e4eSAndroid Build Coastguard Worker     const int compressedSize = LZ4_compress_HC(
93*27162e4eSAndroid Build Coastguard Worker         (const char*) srcData,
94*27162e4eSAndroid Build Coastguard Worker         (char*) compressBuffer,
95*27162e4eSAndroid Build Coastguard Worker         srcSize,
96*27162e4eSAndroid Build Coastguard Worker         sizeof(compressBuffer),
97*27162e4eSAndroid Build Coastguard Worker         LZ4HC_CLEVEL_DEFAULT
98*27162e4eSAndroid Build Coastguard Worker     );
99*27162e4eSAndroid Build Coastguard Worker     if (compressedSize <= 0) {
100*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
101*27162e4eSAndroid Build Coastguard Worker     }
102*27162e4eSAndroid Build Coastguard Worker 
103*27162e4eSAndroid Build Coastguard Worker     // Decompress
104*27162e4eSAndroid Build Coastguard Worker     static uint8_t decompressBuffer[1024 * 1024];
105*27162e4eSAndroid Build Coastguard Worker     const int decompressedSize = LZ4_decompress_safe(
106*27162e4eSAndroid Build Coastguard Worker         (const char*) compressBuffer,
107*27162e4eSAndroid Build Coastguard Worker         (char*) decompressBuffer,
108*27162e4eSAndroid Build Coastguard Worker         compressedSize,
109*27162e4eSAndroid Build Coastguard Worker         sizeof(decompressBuffer)
110*27162e4eSAndroid Build Coastguard Worker     );
111*27162e4eSAndroid Build Coastguard Worker     if (decompressedSize <= 0) {
112*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
113*27162e4eSAndroid Build Coastguard Worker     }
114*27162e4eSAndroid Build Coastguard Worker 
115*27162e4eSAndroid Build Coastguard Worker     // Verify
116*27162e4eSAndroid Build Coastguard Worker     if (decompressedSize != srcSize) {
117*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
118*27162e4eSAndroid Build Coastguard Worker     }
119*27162e4eSAndroid Build Coastguard Worker     if (memcmp(srcData, decompressBuffer, srcSize) != 0) {
120*27162e4eSAndroid Build Coastguard Worker         MY_exit(__LINE__);
121*27162e4eSAndroid Build Coastguard Worker     }
122*27162e4eSAndroid Build Coastguard Worker }
123*27162e4eSAndroid Build Coastguard Worker 
124*27162e4eSAndroid Build Coastguard Worker 
test(void)125*27162e4eSAndroid Build Coastguard Worker static void test(void) {
126*27162e4eSAndroid Build Coastguard Worker     // First 256 bytes of lz4/README.md
127*27162e4eSAndroid Build Coastguard Worker     static const uint8_t README_md[] = {
128*27162e4eSAndroid Build Coastguard Worker         0x4c, 0x5a, 0x34, 0x20, 0x2d, 0x20, 0x45, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x6c, 0x79, 0x20,
129*27162e4eSAndroid Build Coastguard Worker         0x66, 0x61, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
130*27162e4eSAndroid Build Coastguard Worker         0x0a, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
131*27162e4eSAndroid Build Coastguard Worker         0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
132*27162e4eSAndroid Build Coastguard Worker         0x3d, 0x0a, 0x0a, 0x4c, 0x5a, 0x34, 0x20, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x73, 0x73, 0x6c, 0x65,
133*27162e4eSAndroid Build Coastguard Worker         0x73, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x61,
134*27162e4eSAndroid Build Coastguard Worker         0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2c, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
135*27162e4eSAndroid Build Coastguard Worker         0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20,
136*27162e4eSAndroid Build Coastguard Worker         0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3e, 0x20, 0x35, 0x30, 0x30, 0x20, 0x4d, 0x42, 0x2f, 0x73,
137*27162e4eSAndroid Build Coastguard Worker         0x20, 0x70, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x2c, 0x0a, 0x73, 0x63, 0x61, 0x6c, 0x61,
138*27162e4eSAndroid Build Coastguard Worker         0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x63,
139*27162e4eSAndroid Build Coastguard Worker         0x6f, 0x72, 0x65, 0x73, 0x20, 0x43, 0x50, 0x55, 0x2e, 0x0a, 0x49, 0x74, 0x20, 0x66, 0x65, 0x61,
140*27162e4eSAndroid Build Coastguard Worker         0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65,
141*27162e4eSAndroid Build Coastguard Worker         0x6c, 0x79, 0x20, 0x66, 0x61, 0x73, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2c,
142*27162e4eSAndroid Build Coastguard Worker         0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x6d,
143*27162e4eSAndroid Build Coastguard Worker         0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x47, 0x42, 0x2f, 0x73, 0x20, 0x70, 0x65, 0x72,
144*27162e4eSAndroid Build Coastguard Worker     };
145*27162e4eSAndroid Build Coastguard Worker 
146*27162e4eSAndroid Build Coastguard Worker     static const uint8_t* srcData = README_md;
147*27162e4eSAndroid Build Coastguard Worker     static const int      srcSize = (int) sizeof(README_md);
148*27162e4eSAndroid Build Coastguard Worker     test_lz4  (srcData, srcSize);
149*27162e4eSAndroid Build Coastguard Worker     test_lz4hc(srcData, srcSize);
150*27162e4eSAndroid Build Coastguard Worker }
151*27162e4eSAndroid Build Coastguard Worker 
152*27162e4eSAndroid Build Coastguard Worker 
153*27162e4eSAndroid Build Coastguard Worker // low level syscall
154*27162e4eSAndroid Build Coastguard Worker #define SYS_exit (60)
155*27162e4eSAndroid Build Coastguard Worker 
os_syscall1(long n,long a1)156*27162e4eSAndroid Build Coastguard Worker static __inline long os_syscall1(long n, long a1) {
157*27162e4eSAndroid Build Coastguard Worker     register long rax __asm__ ("rax") = n;
158*27162e4eSAndroid Build Coastguard Worker     register long rdi __asm__ ("rdi") = a1;
159*27162e4eSAndroid Build Coastguard Worker     __asm__ __volatile__ ("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory");
160*27162e4eSAndroid Build Coastguard Worker     return rax;
161*27162e4eSAndroid Build Coastguard Worker }
162*27162e4eSAndroid Build Coastguard Worker 
MY_exit(int exitCode)163*27162e4eSAndroid Build Coastguard Worker static void MY_exit(int exitCode) {
164*27162e4eSAndroid Build Coastguard Worker     (void) os_syscall1(SYS_exit, exitCode);
165*27162e4eSAndroid Build Coastguard Worker     __builtin_unreachable();  // suppress "warning: 'noreturn' function does return"
166*27162e4eSAndroid Build Coastguard Worker }
167*27162e4eSAndroid Build Coastguard Worker 
MY_abort(void)168*27162e4eSAndroid Build Coastguard Worker static void MY_abort(void) {
169*27162e4eSAndroid Build Coastguard Worker     MY_exit(-1);
170*27162e4eSAndroid Build Coastguard Worker }
171*27162e4eSAndroid Build Coastguard Worker 
172*27162e4eSAndroid Build Coastguard Worker // https://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/baselib---assert-fail-1.html
__assert_fail(const char * assertion,const char * file,unsigned int line,const char * function)173*27162e4eSAndroid Build Coastguard Worker void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) {
174*27162e4eSAndroid Build Coastguard Worker     MY_abort();
175*27162e4eSAndroid Build Coastguard Worker }
176*27162e4eSAndroid Build Coastguard Worker 
177*27162e4eSAndroid Build Coastguard Worker 
178*27162e4eSAndroid Build Coastguard Worker // GCC requires memcpy, memmove, memset and memcmp.
179*27162e4eSAndroid Build Coastguard Worker // https://gcc.gnu.org/onlinedocs/gcc/Standards.html
180*27162e4eSAndroid Build Coastguard Worker // > GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp.
memmove(void * dst,const void * src,size_t n)181*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memmove(void *dst, const void *src, size_t n) {
182*27162e4eSAndroid Build Coastguard Worker     uint8_t* d = (uint8_t*) dst;
183*27162e4eSAndroid Build Coastguard Worker     const uint8_t* s = (const uint8_t*) src;
184*27162e4eSAndroid Build Coastguard Worker 
185*27162e4eSAndroid Build Coastguard Worker     if (d > s) {
186*27162e4eSAndroid Build Coastguard Worker         d += n;
187*27162e4eSAndroid Build Coastguard Worker         s += n;
188*27162e4eSAndroid Build Coastguard Worker         while (n--) {
189*27162e4eSAndroid Build Coastguard Worker             *--d = *--s;
190*27162e4eSAndroid Build Coastguard Worker         }
191*27162e4eSAndroid Build Coastguard Worker     } else {
192*27162e4eSAndroid Build Coastguard Worker         while (n--) {
193*27162e4eSAndroid Build Coastguard Worker             *d++ = *s++;
194*27162e4eSAndroid Build Coastguard Worker         }
195*27162e4eSAndroid Build Coastguard Worker     }
196*27162e4eSAndroid Build Coastguard Worker     return dst;
197*27162e4eSAndroid Build Coastguard Worker }
198*27162e4eSAndroid Build Coastguard Worker 
memcpy(void * __restrict__ dst,const void * __restrict__ src,size_t n)199*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memcpy(void * __restrict__ dst, const void * __restrict__ src, size_t n) {
200*27162e4eSAndroid Build Coastguard Worker     return memmove(dst, src, n);
201*27162e4eSAndroid Build Coastguard Worker }
202*27162e4eSAndroid Build Coastguard Worker 
memset(void * s,int c,size_t n)203*27162e4eSAndroid Build Coastguard Worker EXTERN_C void *memset(void *s, int c, size_t n) {
204*27162e4eSAndroid Build Coastguard Worker     uint8_t* p = (uint8_t*) s;
205*27162e4eSAndroid Build Coastguard Worker     while (n--) {
206*27162e4eSAndroid Build Coastguard Worker         *p++ = (uint8_t) c;
207*27162e4eSAndroid Build Coastguard Worker     }
208*27162e4eSAndroid Build Coastguard Worker     return s;
209*27162e4eSAndroid Build Coastguard Worker }
210*27162e4eSAndroid Build Coastguard Worker 
memcmp(const void * s1,const void * s2,size_t n)211*27162e4eSAndroid Build Coastguard Worker EXTERN_C int memcmp(const void *s1, const void *s2, size_t n) {
212*27162e4eSAndroid Build Coastguard Worker     const uint8_t* p1 = (const uint8_t*) s1;
213*27162e4eSAndroid Build Coastguard Worker     const uint8_t* p2 = (const uint8_t*) s2;
214*27162e4eSAndroid Build Coastguard Worker     while (n--) {
215*27162e4eSAndroid Build Coastguard Worker         const uint8_t c1 = *p1++;
216*27162e4eSAndroid Build Coastguard Worker         const uint8_t c2 = *p2++;
217*27162e4eSAndroid Build Coastguard Worker         if (c1 < c2) {
218*27162e4eSAndroid Build Coastguard Worker             return -1;
219*27162e4eSAndroid Build Coastguard Worker         } else if (c1 > c2) {
220*27162e4eSAndroid Build Coastguard Worker             return 1;
221*27162e4eSAndroid Build Coastguard Worker         }
222*27162e4eSAndroid Build Coastguard Worker     }
223*27162e4eSAndroid Build Coastguard Worker     return 0;
224*27162e4eSAndroid Build Coastguard Worker }
225*27162e4eSAndroid Build Coastguard Worker 
226*27162e4eSAndroid Build Coastguard Worker 
227*27162e4eSAndroid Build Coastguard Worker //
_start(void)228*27162e4eSAndroid Build Coastguard Worker EXTERN_C void _start(void) {
229*27162e4eSAndroid Build Coastguard Worker     test();
230*27162e4eSAndroid Build Coastguard Worker     MY_exit(0);
231*27162e4eSAndroid Build Coastguard Worker }
232*27162e4eSAndroid Build Coastguard Worker 
main(int argc,char ** argv)233*27162e4eSAndroid Build Coastguard Worker int main(int argc, char** argv) {
234*27162e4eSAndroid Build Coastguard Worker     test();
235*27162e4eSAndroid Build Coastguard Worker     MY_exit(0);
236*27162e4eSAndroid Build Coastguard Worker     return 0;
237*27162e4eSAndroid Build Coastguard Worker }
238*27162e4eSAndroid Build Coastguard Worker #endif
239