реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Непонятки с функцией memcpy
Harvester
сообщение Aug 13 2015, 08:23
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 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?


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 08:29
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Harvester @ Aug 13 2015, 11:23) *
1. Из каких соображений компилятор в 1-м случае поставил функцию побайтного копирования, а во 2-м - пословного?
2. Как сказать компилятору, чтобы он во 2-м случае тоже использовал __rt_memcpy?

1. Руководствуясь типом RFC4357_WRAPPED_KEY_PTR
2. Тут лучше как раз наоборот - чтобы pWrappedKey передавался с корректным выравниванием

То есть виноват тот, кто вызывает RFC4357_KeyUnwrap с некорректным значением pWrappedKey.
Go to the top of the page
 
+Quote Post
Harvester
сообщение Aug 13 2015, 08:37
Сообщение #3


Местный
***

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



Цитата(aaarrr @ Aug 13 2015, 11:29) *
То есть виноват тот, кто вызывает RFC4357_KeyUnwrap с некорректным значением pWrappedKey.

А что делать, если pWrappedKey - указатель на массив во входных данных, который не выровнен по-определению (ну, вот так сложилось исторически).


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 08:40
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Код
UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX,
                         __packed RFC4357_WRAPPED_KEY_PTR pWrappedKey,
                         PUCHAR pUnwrappingKey,
                         PUCHAR pUnwrappedKey)

И так везде. Но лучше бы выровнять.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 13 2015, 08:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я бы __packed под typdef сразу запихал бы...
Go to the top of the page
 
+Quote Post
Harvester
сообщение Aug 13 2015, 09:26
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 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)

И так везде. Но лучше бы выровнять.

Не прокатило sad.gif .
Нашел вот-такой документ: How do the ARM Compilers handle memcpy()?
Попробовал с промежуточным указателем на char - помогло, __rt_memcpy_w превратилась в __rt_memcpy.
Но все-таки логика компилятора мне непонятна. Дело в том, что ниже в функции есть вызов memcpy(pX->ectx.N, pWrappedKey->UKM, 8) - он транслируется в __rt_memcpy без всяких ухищрений.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 09:44
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Harvester @ Aug 13 2015, 12:26) *
Не прокатило sad.gif .

Не прокатило в каком смысле - компилятор __packed не понимает, или все равно оставил __rt_memcpy_w?

Цитата(Harvester @ Aug 13 2015, 12:26) *
Но все-таки логика компилятора мне непонятна. Дело в том, что ниже в функции есть вызов memcpy(pX->ectx.N, pWrappedKey->UKM, 8) - он транслируется в __rt_memcpy без всяких ухищрений.

А какая связь между этим memcpy и первым?
Go to the top of the page
 
+Quote Post
Harvester
сообщение Aug 13 2015, 10:00
Сообщение #8


Местный
***

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



Цитата(aaarrr @ Aug 13 2015, 12:44) *
Не прокатило в каком смысле - компилятор __packed не понимает, или все равно оставил __rt_memcpy_w?


А какая связь между этим memcpy и первым?

1. Оставил __rt_memcpy_w
2. И там и там 2-м параметром используется невыровненный указатель (входной параметр функции)


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 13 2015, 10:08
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Harvester @ Aug 13 2015, 12:26) *
Нашел вот-такой документ: How do the ARM Compilers handle memcpy()?

Кстати, там в примере перед передачей __packed указателя в memcpy() сначала делается явное приведение (void*). Не очень понятно, почему, но возможно, что такой взмах бубном необходим.

Цитата(Harvester @ Aug 13 2015, 13:00) *
2. И там и там 2-м параметром используется невыровненный указатель (входной параметр функции)

Вы бы привели описание типов RFC4357_WRAPPED_KEY_PTR и GOST28147_BCTX_PTR, если это не военная тайна, конечно. Не исключено, что тогда сразу станет ясно, почему по-разному срабатывает memcpy().
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 13 2015, 10:24
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
1. Оставил __rt_memcpy_w

а как вы написали? при передаче или при вызове тип указателя преобразовали?
я бы в объявление RFC4357_WRAPPED_KEY_PTR все же добавил __packed

Go to the top of the page
 
+Quote Post
Harvester
сообщение Aug 13 2015, 10:30
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 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

Какая-то странная мешанина директив.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 10:31
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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. В первом случае компилятор считает указатель выровненным.
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 13 2015, 10:40
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 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) *
Какая-то странная мешанина директив.

Ничего странного. Просто упаковывают структуру разными способами в зависимости от применяемого компилятора.
Go to the top of the page
 
+Quote Post
Harvester
сообщение Aug 13 2015, 10:49
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 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


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 10:58
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Harvester @ Aug 13 2015, 13:49) *
это было первое, что предложили

Нет, первое было:
Код
UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX,
                         __packed RFC4357_WRAPPED_KEY_PTR pWrappedKey,
                         PUCHAR pUnwrappingKey,
                         PUCHAR pUnwrappedKey)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01511 секунд с 7
ELECTRONIX ©2004-2016