|
Непонятки с функцией memcpy |
|
|
|
Aug 13 2015, 08:23
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Добрый день. Процессор ARM11, компилятор ADS 1.2 Имеется следующая функция: Код UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX, RFC4357_WRAPPED_KEY_PTR pWrappedKey, PUCHAR pUnwrappingKey, PUCHAR pUnwrappedKey) { UCHAR kd[32]; UCHAR ke[32];
/* calc diversified key */ memcpy(kd, pUnwrappingKey, 32); ... /* decrypt key */ memcpy(ke, pWrappedKey->KEY, 32); ... } Во время второго вызова memcpy() возникает исключение Misaligned. И действительно, перед вызовом функции R1 = 010CF0BA. Из листинга видно, что при первом вызове вызывается функция __rt_memcpy, а при втором - __rt_memcpy_w. Собственно, вопросы: 1. Из каких соображений компилятор в 1-м случае поставил функцию побайтного копирования, а во 2-м - пословного? 2. Как сказать компилятору, чтобы он во 2-м случае тоже использовал __rt_memcpy?
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Aug 13 2015, 08:37
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(aaarrr @ Aug 13 2015, 11:29)  То есть виноват тот, кто вызывает RFC4357_KeyUnwrap с некорректным значением pWrappedKey. А что делать, если pWrappedKey - указатель на массив во входных данных, который не выровнен по-определению (ну, вот так сложилось исторически).
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Aug 13 2015, 09:26
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(aaarrr @ Aug 13 2015, 11:40)  Код UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX, __packed RFC4357_WRAPPED_KEY_PTR pWrappedKey, PUCHAR pUnwrappingKey, PUCHAR pUnwrappedKey) И так везде. Но лучше бы выровнять. Не прокатило  . Нашел вот-такой документ: How do the ARM Compilers handle memcpy()? Попробовал с промежуточным указателем на char - помогло, __rt_memcpy_w превратилась в __rt_memcpy. Но все-таки логика компилятора мне непонятна. Дело в том, что ниже в функции есть вызов memcpy(pX->ectx.N, pWrappedKey->UKM, 8) - он транслируется в __rt_memcpy без всяких ухищрений.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Aug 13 2015, 09:44
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Harvester @ Aug 13 2015, 12:26)  Не прокатило  . Не прокатило в каком смысле - компилятор __packed не понимает, или все равно оставил __rt_memcpy_w? Цитата(Harvester @ Aug 13 2015, 12:26)  Но все-таки логика компилятора мне непонятна. Дело в том, что ниже в функции есть вызов memcpy(pX->ectx.N, pWrappedKey->UKM, 8) - он транслируется в __rt_memcpy без всяких ухищрений. А какая связь между этим memcpy и первым?
|
|
|
|
|
Aug 13 2015, 10:00
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(aaarrr @ Aug 13 2015, 12:44)  Не прокатило в каком смысле - компилятор __packed не понимает, или все равно оставил __rt_memcpy_w?
А какая связь между этим memcpy и первым? 1. Оставил __rt_memcpy_w 2. И там и там 2-м параметром используется невыровненный указатель (входной параметр функции)
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Aug 13 2015, 10:08
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Harvester @ Aug 13 2015, 12:26)  Кстати, там в примере перед передачей __packed указателя в memcpy() сначала делается явное приведение (void*). Не очень понятно, почему, но возможно, что такой взмах бубном необходим. Цитата(Harvester @ Aug 13 2015, 13:00)  2. И там и там 2-м параметром используется невыровненный указатель (входной параметр функции) Вы бы привели описание типов RFC4357_WRAPPED_KEY_PTR и GOST28147_BCTX_PTR, если это не военная тайна, конечно. Не исключено, что тогда сразу станет ясно, почему по-разному срабатывает memcpy().
|
|
|
|
|
Aug 13 2015, 10:30
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(scifi @ Aug 13 2015, 13:08)  Кстати, там в примере перед передачей __packed указателя в memcpy() сначала делается явное приведение (void*). Не очень понятно, почему, но возможно, что такой взмах бубном необходим. Действительно, проверю. Цитата(scifi @ Aug 13 2015, 13:08)  Вы бы привели описание типов RFC4357_WRAPPED_KEY_PTR и GOST28147_BCTX_PTR, если это не военная тайна, конечно. Не исключено, что тогда сразу станет ясно, почему по-разному срабатывает memcpy(). Да не вопрос. Код typedef struct RFC4357_WRAPPED_KEY_tag { UCHAR UKM[8]; UCHAR KEY[GOST28147_KEY_SIZE]; ULONG CRC; } RFC4357_WRAPPED_KEY, *RFC4357_WRAPPED_KEY_PTR; Код #if defined(__ICCARM__) || defined(__ICCAVR__) // IAR #pragma pack(ALIGNMENT) // IAR #define __attribute__(...) // IAR #endif
#if !defined(__ARMCC_VERSION) #pragma pack (push, 4) #endif ... typedef struct GOST28147_BCTX_tag { GOST28147_CTX ectx; ULONG cbInbuf; UCHAR buf[GOST28147_BLOCK_SIZE]; ULONG KeyMeshingBlocks; GOST28147_KM_PROC KeyMeshingProc; ULONG KeyMeshingBlocksRemain; UCHAR BufferedKey[GOST28147_KEY_SIZE]; #if defined(__ICCARM__) || defined(__ICCAVR__) }__attribute__ ((packed)) GOST28147_BCTX, *GOST28147_BCTX_PTR; #else } GOST28147_BCTX, *GOST28147_BCTX_PTR; #endif //
#if !defined(__ARMCC_VERSION) #pragma pack (pop) #endif
#if defined(__ICCARM__) || defined(__ICCAVR__) // IAR #pragma pack() // IAR #endif // IAR Какая-то странная мешанина директив.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Aug 13 2015, 10:31
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Harvester @ Aug 13 2015, 13:00)  1. Оставил __rt_memcpy_w 2. И там и там 2-м параметром используется невыровненный указатель (входной параметр функции) 1. Если структура объявлена как Код typedef struct { } RFC4357_WRAPPED_KEY, *RFC4357_WRAPPED_KEY_PTR; то вполне возможно такое поведение. Тогда надо: Код UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX, __packed RFC4357_WRAPPED_KEY *pWrappedKey, PUCHAR pUnwrappingKey, PUCHAR pUnwrappedKey) 2. В первом случае компилятор считает указатель выровненным.
|
|
|
|
|
Aug 13 2015, 10:40
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Harvester @ Aug 13 2015, 12:26)  Но все-таки логика компилятора мне непонятна. Дело в том, что ниже в функции есть вызов memcpy(pX->ectx.N, pWrappedKey->UKM, 8) - он транслируется в __rt_memcpy без всяких ухищрений. После того, как вы привели объявление типа, стало понятно. Дело в том, что pX уже упакованный, так как указывает на упакованную структуру (см. объявление соответствующего типа). Цитата(Harvester @ Aug 13 2015, 13:30)  Какая-то странная мешанина директив. Ничего странного. Просто упаковывают структуру разными способами в зависимости от применяемого компилятора.
|
|
|
|
|
Aug 13 2015, 10:49
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(aaarrr @ Aug 13 2015, 13:31)  1. Если структура объявлена как Код typedef struct { } RFC4357_WRAPPED_KEY, *RFC4357_WRAPPED_KEY_PTR; то вполне возможно такое поведение. Тогда надо: Код UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX, __packed RFC4357_WRAPPED_KEY *pWrappedKey, PUCHAR pUnwrappingKey, PUCHAR pUnwrappedKey) Именно это не прокатило - компилятор оставил __rt_memcpy_w (это было первое, что предложили).
Сообщение отредактировал Harvester - Aug 13 2015, 10:50
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|