You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

memcpy_s.c 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define SECUREC_INLINE_DO_MEMCPY 1
  17. #include "securecutil.h"
  18. #ifndef SECUREC_MEMCOPY_WITH_PERFORMANCE
  19. #define SECUREC_MEMCOPY_WITH_PERFORMANCE 0
  20. #endif
  21. #if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE
  22. #ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE
  23. #define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL
  24. #endif
  25. /*
  26. * Determine whether the address is 8-byte aligned, use static to increase performance
  27. * return 0 is aligned
  28. */
  29. static int SecIsAddrAligned8(const void *addr, const void *zeroAddr)
  30. {
  31. return (int)(((size_t)((const char*)addr - (const char*)zeroAddr)) & 7); /* use 7 to check aligned 8 */
  32. }
  33. #define SECUREC_SMALL_MEM_COPY do { \
  34. if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \
  35. /* use struct assignment */ \
  36. switch (count) { \
  37. case 1: \
  38. *(SecStrBuf1 *)dest = *(const SecStrBuf1 *)src; \
  39. break; \
  40. case 2: \
  41. *(SecStrBuf2 *)dest = *(const SecStrBuf2 *)src; \
  42. break; \
  43. case 3: \
  44. *(SecStrBuf3 *)dest = *(const SecStrBuf3 *)src; \
  45. break; \
  46. case 4: \
  47. *(SecStrBuf4 *)dest = *(const SecStrBuf4 *)src; \
  48. break; \
  49. case 5: \
  50. *(SecStrBuf5 *)dest = *(const SecStrBuf5 *)src; \
  51. break; \
  52. case 6: \
  53. *(SecStrBuf6 *)dest = *(const SecStrBuf6 *)src; \
  54. break; \
  55. case 7: \
  56. *(SecStrBuf7 *)dest = *(const SecStrBuf7 *)src; \
  57. break; \
  58. case 8: \
  59. *(SecStrBuf8 *)dest = *(const SecStrBuf8 *)src; \
  60. break; \
  61. case 9: \
  62. *(SecStrBuf9 *)dest = *(const SecStrBuf9 *)src; \
  63. break; \
  64. case 10: \
  65. *(SecStrBuf10 *)dest = *(const SecStrBuf10 *)src; \
  66. break; \
  67. case 11: \
  68. *(SecStrBuf11 *)dest = *(const SecStrBuf11 *)src; \
  69. break; \
  70. case 12: \
  71. *(SecStrBuf12 *)dest = *(const SecStrBuf12 *)src; \
  72. break; \
  73. case 13: \
  74. *(SecStrBuf13 *)dest = *(const SecStrBuf13 *)src; \
  75. break; \
  76. case 14: \
  77. *(SecStrBuf14 *)dest = *(const SecStrBuf14 *)src; \
  78. break; \
  79. case 15: \
  80. *(SecStrBuf15 *)dest = *(const SecStrBuf15 *)src; \
  81. break; \
  82. case 16: \
  83. *(SecStrBuf16 *)dest = *(const SecStrBuf16 *)src; \
  84. break; \
  85. case 17: \
  86. *(SecStrBuf17 *)dest = *(const SecStrBuf17 *)src; \
  87. break; \
  88. case 18: \
  89. *(SecStrBuf18 *)dest = *(const SecStrBuf18 *)src; \
  90. break; \
  91. case 19: \
  92. *(SecStrBuf19 *)dest = *(const SecStrBuf19 *)src; \
  93. break; \
  94. case 20: \
  95. *(SecStrBuf20 *)dest = *(const SecStrBuf20 *)src; \
  96. break; \
  97. case 21: \
  98. *(SecStrBuf21 *)dest = *(const SecStrBuf21 *)src; \
  99. break; \
  100. case 22: \
  101. *(SecStrBuf22 *)dest = *(const SecStrBuf22 *)src; \
  102. break; \
  103. case 23: \
  104. *(SecStrBuf23 *)dest = *(const SecStrBuf23 *)src; \
  105. break; \
  106. case 24: \
  107. *(SecStrBuf24 *)dest = *(const SecStrBuf24 *)src; \
  108. break; \
  109. case 25: \
  110. *(SecStrBuf25 *)dest = *(const SecStrBuf25 *)src; \
  111. break; \
  112. case 26: \
  113. *(SecStrBuf26 *)dest = *(const SecStrBuf26 *)src; \
  114. break; \
  115. case 27: \
  116. *(SecStrBuf27 *)dest = *(const SecStrBuf27 *)src; \
  117. break; \
  118. case 28: \
  119. *(SecStrBuf28 *)dest = *(const SecStrBuf28 *)src; \
  120. break; \
  121. case 29: \
  122. *(SecStrBuf29 *)dest = *(const SecStrBuf29 *)src; \
  123. break; \
  124. case 30: \
  125. *(SecStrBuf30 *)dest = *(const SecStrBuf30 *)src; \
  126. break; \
  127. case 31: \
  128. *(SecStrBuf31 *)dest = *(const SecStrBuf31 *)src; \
  129. break; \
  130. case 32: \
  131. *(SecStrBuf32 *)dest = *(const SecStrBuf32 *)src; \
  132. break; \
  133. case 33: \
  134. *(SecStrBuf33 *)dest = *(const SecStrBuf33 *)src; \
  135. break; \
  136. case 34: \
  137. *(SecStrBuf34 *)dest = *(const SecStrBuf34 *)src; \
  138. break; \
  139. case 35: \
  140. *(SecStrBuf35 *)dest = *(const SecStrBuf35 *)src; \
  141. break; \
  142. case 36: \
  143. *(SecStrBuf36 *)dest = *(const SecStrBuf36 *)src; \
  144. break; \
  145. case 37: \
  146. *(SecStrBuf37 *)dest = *(const SecStrBuf37 *)src; \
  147. break; \
  148. case 38: \
  149. *(SecStrBuf38 *)dest = *(const SecStrBuf38 *)src; \
  150. break; \
  151. case 39: \
  152. *(SecStrBuf39 *)dest = *(const SecStrBuf39 *)src; \
  153. break; \
  154. case 40: \
  155. *(SecStrBuf40 *)dest = *(const SecStrBuf40 *)src; \
  156. break; \
  157. case 41: \
  158. *(SecStrBuf41 *)dest = *(const SecStrBuf41 *)src; \
  159. break; \
  160. case 42: \
  161. *(SecStrBuf42 *)dest = *(const SecStrBuf42 *)src; \
  162. break; \
  163. case 43: \
  164. *(SecStrBuf43 *)dest = *(const SecStrBuf43 *)src; \
  165. break; \
  166. case 44: \
  167. *(SecStrBuf44 *)dest = *(const SecStrBuf44 *)src; \
  168. break; \
  169. case 45: \
  170. *(SecStrBuf45 *)dest = *(const SecStrBuf45 *)src; \
  171. break; \
  172. case 46: \
  173. *(SecStrBuf46 *)dest = *(const SecStrBuf46 *)src; \
  174. break; \
  175. case 47: \
  176. *(SecStrBuf47 *)dest = *(const SecStrBuf47 *)src; \
  177. break; \
  178. case 48: \
  179. *(SecStrBuf48 *)dest = *(const SecStrBuf48 *)src; \
  180. break; \
  181. case 49: \
  182. *(SecStrBuf49 *)dest = *(const SecStrBuf49 *)src; \
  183. break; \
  184. case 50: \
  185. *(SecStrBuf50 *)dest = *(const SecStrBuf50 *)src; \
  186. break; \
  187. case 51: \
  188. *(SecStrBuf51 *)dest = *(const SecStrBuf51 *)src; \
  189. break; \
  190. case 52: \
  191. *(SecStrBuf52 *)dest = *(const SecStrBuf52 *)src; \
  192. break; \
  193. case 53: \
  194. *(SecStrBuf53 *)dest = *(const SecStrBuf53 *)src; \
  195. break; \
  196. case 54: \
  197. *(SecStrBuf54 *)dest = *(const SecStrBuf54 *)src; \
  198. break; \
  199. case 55: \
  200. *(SecStrBuf55 *)dest = *(const SecStrBuf55 *)src; \
  201. break; \
  202. case 56: \
  203. *(SecStrBuf56 *)dest = *(const SecStrBuf56 *)src; \
  204. break; \
  205. case 57: \
  206. *(SecStrBuf57 *)dest = *(const SecStrBuf57 *)src; \
  207. break; \
  208. case 58: \
  209. *(SecStrBuf58 *)dest = *(const SecStrBuf58 *)src; \
  210. break; \
  211. case 59: \
  212. *(SecStrBuf59 *)dest = *(const SecStrBuf59 *)src; \
  213. break; \
  214. case 60: \
  215. *(SecStrBuf60 *)dest = *(const SecStrBuf60 *)src; \
  216. break; \
  217. case 61: \
  218. *(SecStrBuf61 *)dest = *(const SecStrBuf61 *)src; \
  219. break; \
  220. case 62: \
  221. *(SecStrBuf62 *)dest = *(const SecStrBuf62 *)src; \
  222. break; \
  223. case 63: \
  224. *(SecStrBuf63 *)dest = *(const SecStrBuf63 *)src; \
  225. break; \
  226. case 64: \
  227. *(SecStrBuf64 *)dest = *(const SecStrBuf64 *)src; \
  228. break; \
  229. default: \
  230. break; \
  231. } /* END switch */ \
  232. } else { \
  233. char *tmpDest = (char *)dest; \
  234. const char *tmpSrc = (const char *)src; \
  235. switch (count) { \
  236. case 64: \
  237. *(tmpDest++) = *(tmpSrc++); \
  238. /* fall-through */ /* FALLTHRU */ \
  239. case 63: \
  240. *(tmpDest++) = *(tmpSrc++); \
  241. /* fall-through */ /* FALLTHRU */ \
  242. case 62: \
  243. *(tmpDest++) = *(tmpSrc++); \
  244. /* fall-through */ /* FALLTHRU */ \
  245. case 61: \
  246. *(tmpDest++) = *(tmpSrc++); \
  247. /* fall-through */ /* FALLTHRU */ \
  248. case 60: \
  249. *(tmpDest++) = *(tmpSrc++); \
  250. /* fall-through */ /* FALLTHRU */ \
  251. case 59: \
  252. *(tmpDest++) = *(tmpSrc++); \
  253. /* fall-through */ /* FALLTHRU */ \
  254. case 58: \
  255. *(tmpDest++) = *(tmpSrc++); \
  256. /* fall-through */ /* FALLTHRU */ \
  257. case 57: \
  258. *(tmpDest++) = *(tmpSrc++); \
  259. /* fall-through */ /* FALLTHRU */ \
  260. case 56: \
  261. *(tmpDest++) = *(tmpSrc++); \
  262. /* fall-through */ /* FALLTHRU */ \
  263. case 55: \
  264. *(tmpDest++) = *(tmpSrc++); \
  265. /* fall-through */ /* FALLTHRU */ \
  266. case 54: \
  267. *(tmpDest++) = *(tmpSrc++); \
  268. /* fall-through */ /* FALLTHRU */ \
  269. case 53: \
  270. *(tmpDest++) = *(tmpSrc++); \
  271. /* fall-through */ /* FALLTHRU */ \
  272. case 52: \
  273. *(tmpDest++) = *(tmpSrc++); \
  274. /* fall-through */ /* FALLTHRU */ \
  275. case 51: \
  276. *(tmpDest++) = *(tmpSrc++); \
  277. /* fall-through */ /* FALLTHRU */ \
  278. case 50: \
  279. *(tmpDest++) = *(tmpSrc++); \
  280. /* fall-through */ /* FALLTHRU */ \
  281. case 49: \
  282. *(tmpDest++) = *(tmpSrc++); \
  283. /* fall-through */ /* FALLTHRU */ \
  284. case 48: \
  285. *(tmpDest++) = *(tmpSrc++); \
  286. /* fall-through */ /* FALLTHRU */ \
  287. case 47: \
  288. *(tmpDest++) = *(tmpSrc++); \
  289. /* fall-through */ /* FALLTHRU */ \
  290. case 46: \
  291. *(tmpDest++) = *(tmpSrc++); \
  292. /* fall-through */ /* FALLTHRU */ \
  293. case 45: \
  294. *(tmpDest++) = *(tmpSrc++); \
  295. /* fall-through */ /* FALLTHRU */ \
  296. case 44: \
  297. *(tmpDest++) = *(tmpSrc++); \
  298. /* fall-through */ /* FALLTHRU */ \
  299. case 43: \
  300. *(tmpDest++) = *(tmpSrc++); \
  301. /* fall-through */ /* FALLTHRU */ \
  302. case 42: \
  303. *(tmpDest++) = *(tmpSrc++); \
  304. /* fall-through */ /* FALLTHRU */ \
  305. case 41: \
  306. *(tmpDest++) = *(tmpSrc++); \
  307. /* fall-through */ /* FALLTHRU */ \
  308. case 40: \
  309. *(tmpDest++) = *(tmpSrc++); \
  310. /* fall-through */ /* FALLTHRU */ \
  311. case 39: \
  312. *(tmpDest++) = *(tmpSrc++); \
  313. /* fall-through */ /* FALLTHRU */ \
  314. case 38: \
  315. *(tmpDest++) = *(tmpSrc++); \
  316. /* fall-through */ /* FALLTHRU */ \
  317. case 37: \
  318. *(tmpDest++) = *(tmpSrc++); \
  319. /* fall-through */ /* FALLTHRU */ \
  320. case 36: \
  321. *(tmpDest++) = *(tmpSrc++); \
  322. /* fall-through */ /* FALLTHRU */ \
  323. case 35: \
  324. *(tmpDest++) = *(tmpSrc++); \
  325. /* fall-through */ /* FALLTHRU */ \
  326. case 34: \
  327. *(tmpDest++) = *(tmpSrc++); \
  328. /* fall-through */ /* FALLTHRU */ \
  329. case 33: \
  330. *(tmpDest++) = *(tmpSrc++); \
  331. /* fall-through */ /* FALLTHRU */ \
  332. case 32: \
  333. *(tmpDest++) = *(tmpSrc++); \
  334. /* fall-through */ /* FALLTHRU */ \
  335. case 31: \
  336. *(tmpDest++) = *(tmpSrc++); \
  337. /* fall-through */ /* FALLTHRU */ \
  338. case 30: \
  339. *(tmpDest++) = *(tmpSrc++); \
  340. /* fall-through */ /* FALLTHRU */ \
  341. case 29: \
  342. *(tmpDest++) = *(tmpSrc++); \
  343. /* fall-through */ /* FALLTHRU */ \
  344. case 28: \
  345. *(tmpDest++) = *(tmpSrc++); \
  346. /* fall-through */ /* FALLTHRU */ \
  347. case 27: \
  348. *(tmpDest++) = *(tmpSrc++); \
  349. /* fall-through */ /* FALLTHRU */ \
  350. case 26: \
  351. *(tmpDest++) = *(tmpSrc++); \
  352. /* fall-through */ /* FALLTHRU */ \
  353. case 25: \
  354. *(tmpDest++) = *(tmpSrc++); \
  355. /* fall-through */ /* FALLTHRU */ \
  356. case 24: \
  357. *(tmpDest++) = *(tmpSrc++); \
  358. /* fall-through */ /* FALLTHRU */ \
  359. case 23: \
  360. *(tmpDest++) = *(tmpSrc++); \
  361. /* fall-through */ /* FALLTHRU */ \
  362. case 22: \
  363. *(tmpDest++) = *(tmpSrc++); \
  364. /* fall-through */ /* FALLTHRU */ \
  365. case 21: \
  366. *(tmpDest++) = *(tmpSrc++); \
  367. /* fall-through */ /* FALLTHRU */ \
  368. case 20: \
  369. *(tmpDest++) = *(tmpSrc++); \
  370. /* fall-through */ /* FALLTHRU */ \
  371. case 19: \
  372. *(tmpDest++) = *(tmpSrc++); \
  373. /* fall-through */ /* FALLTHRU */ \
  374. case 18: \
  375. *(tmpDest++) = *(tmpSrc++); \
  376. /* fall-through */ /* FALLTHRU */ \
  377. case 17: \
  378. *(tmpDest++) = *(tmpSrc++); \
  379. /* fall-through */ /* FALLTHRU */ \
  380. case 16: \
  381. *(tmpDest++) = *(tmpSrc++); \
  382. /* fall-through */ /* FALLTHRU */ \
  383. case 15: \
  384. *(tmpDest++) = *(tmpSrc++); \
  385. /* fall-through */ /* FALLTHRU */ \
  386. case 14: \
  387. *(tmpDest++) = *(tmpSrc++); \
  388. /* fall-through */ /* FALLTHRU */ \
  389. case 13: \
  390. *(tmpDest++) = *(tmpSrc++); \
  391. /* fall-through */ /* FALLTHRU */ \
  392. case 12: \
  393. *(tmpDest++) = *(tmpSrc++); \
  394. /* fall-through */ /* FALLTHRU */ \
  395. case 11: \
  396. *(tmpDest++) = *(tmpSrc++); \
  397. /* fall-through */ /* FALLTHRU */ \
  398. case 10: \
  399. *(tmpDest++) = *(tmpSrc++); \
  400. /* fall-through */ /* FALLTHRU */ \
  401. case 9: \
  402. *(tmpDest++) = *(tmpSrc++); \
  403. /* fall-through */ /* FALLTHRU */ \
  404. case 8: \
  405. *(tmpDest++) = *(tmpSrc++); \
  406. /* fall-through */ /* FALLTHRU */ \
  407. case 7: \
  408. *(tmpDest++) = *(tmpSrc++); \
  409. /* fall-through */ /* FALLTHRU */ \
  410. case 6: \
  411. *(tmpDest++) = *(tmpSrc++); \
  412. /* fall-through */ /* FALLTHRU */ \
  413. case 5: \
  414. *(tmpDest++) = *(tmpSrc++); \
  415. /* fall-through */ /* FALLTHRU */ \
  416. case 4: \
  417. *(tmpDest++) = *(tmpSrc++); \
  418. /* fall-through */ /* FALLTHRU */ \
  419. case 3: \
  420. *(tmpDest++) = *(tmpSrc++); \
  421. /* fall-through */ /* FALLTHRU */ \
  422. case 2: \
  423. *(tmpDest++) = *(tmpSrc++); \
  424. /* fall-through */ /* FALLTHRU */ \
  425. case 1: \
  426. *(tmpDest++) = *(tmpSrc++); \
  427. /* fall-through */ /* FALLTHRU */ \
  428. default: \
  429. break; \
  430. } \
  431. } \
  432. } SECUREC_WHILE_ZERO
  433. #endif
  434. /*
  435. * Handling errors
  436. */
  437. static errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count)
  438. {
  439. if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
  440. SECUREC_ERROR_INVALID_RANGE("memcpy_s");
  441. return ERANGE;
  442. }
  443. if (dest == NULL || src == NULL) {
  444. SECUREC_ERROR_INVALID_PARAMTER("memcpy_s");
  445. if (dest != NULL) {
  446. (void)memset(dest, 0, destMax);
  447. return EINVAL_AND_RESET;
  448. }
  449. return EINVAL;
  450. }
  451. if (count > destMax) {
  452. (void)memset(dest, 0, destMax);
  453. SECUREC_ERROR_INVALID_RANGE("memcpy_s");
  454. return ERANGE_AND_RESET;
  455. }
  456. if (dest == src) {
  457. return EOK;
  458. }
  459. if ((dest > src && dest < (const void *)((const unsigned char *)src + count)) || \
  460. (src > dest && src < (void *)((unsigned char *)dest + count))) {
  461. (void)memset(dest, 0, destMax);
  462. SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s");
  463. return EOVERLAP_AND_RESET;
  464. }
  465. /* count == 0 also return EOK */
  466. return EOK;
  467. }
  468. #if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE
  469. /*
  470. * Performance optimization
  471. */
  472. static void SecDoMemcpyOpt(void *dest, const void *src, size_t count)
  473. {
  474. if (count > SECUREC_MEMCOPY_THRESHOLD_SIZE) {
  475. SecDoMemcpy(dest, src, count);
  476. } else {
  477. SECUREC_SMALL_MEM_COPY;
  478. }
  479. return;
  480. }
  481. #endif
  482. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  483. /* fread API in windows will call memcpy_s and pass 0xffffffff to destMax.
  484. * To avoid the failure of fread, we don't check desMax limit.
  485. */
  486. #define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
  487. (dest) != NULL && (src) != NULL && \
  488. (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
  489. #else
  490. #define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
  491. (dest) != NULL && (src) != NULL && \
  492. (destMax) <= SECUREC_MEM_MAX_LEN && \
  493. (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
  494. #endif
  495. /*
  496. * <FUNCTION DESCRIPTION>
  497. * The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest
  498. *
  499. * <INPUT PARAMETERS>
  500. * dest Destination buffer.
  501. * destMax Size of the destination buffer.
  502. * src Buffer to copy from.
  503. * count Number of characters to copy
  504. *
  505. * <OUTPUT PARAMETERS>
  506. * dest buffer is updated.
  507. *
  508. * <RETURN VALUE>
  509. * EOK Success
  510. * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
  511. * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
  512. * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
  513. * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
  514. * and dest != NULL and src != NULL
  515. * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
  516. * count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
  517. * and src != NULL and dest != src
  518. *
  519. * if an error occured, dest will be filled with 0.
  520. * If the source and destination overlap, the behavior of memcpy_s is undefined.
  521. * Use memmove_s to handle overlapping regions.
  522. */
  523. errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count)
  524. {
  525. if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
  526. #if SECUREC_MEMCOPY_WITH_PERFORMANCE
  527. SecDoMemcpyOpt(dest, src, count);
  528. #else
  529. SecDoMemcpy(dest, src, count);
  530. #endif
  531. return EOK;
  532. }
  533. /* meet some runtime violation, return error code */
  534. return SecMemcpyError(dest, destMax, src, count);
  535. }
  536. #if SECUREC_IN_KERNEL
  537. EXPORT_SYMBOL(memcpy_s);
  538. #endif
  539. #if SECUREC_WITH_PERFORMANCE_ADDONS
  540. /*
  541. * Performance optimization
  542. */
  543. errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count)
  544. {
  545. if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
  546. SecDoMemcpyOpt(dest, src, count);
  547. return EOK;
  548. }
  549. /* meet some runtime violation, return error code */
  550. return SecMemcpyError(dest, destMax, src, count);
  551. }
  552. /* trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */
  553. errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count)
  554. {
  555. if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \
  556. count > 0 && \
  557. ((dest > src && (const void *)((const unsigned char *)src + count) <= dest) || \
  558. (src > dest && (void *)((unsigned char *)dest + count) <= src)))) {
  559. SecDoMemcpyOpt(dest, src, count);
  560. return EOK;
  561. }
  562. /* meet some runtime violation, return error code */
  563. return SecMemcpyError(dest, destMax, src, count);
  564. }
  565. #endif