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

 
 
> Непонятки с функцией 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
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
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
Harvester
сообщение Aug 13 2015, 11:21
Сообщение #16


Местный
***

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



Цитата(scifi @ Aug 13 2015, 13:40) *
Ничего странного. Просто упаковывают структуру разными способами в зависимости от применяемого компилятора.

ЧТО директивы делают я понимаю, я просто не могу понять смысла их комбинации:
Код
#if defined(__ICCARM__) || defined(__ICCAVR__)
#pragma pack(ALIGNMENT)            // Если IAR - последующие объявления пакуются по ALIGNMENT (4)
#define __attribute__(...) // ??? возможно это отмена ключевого слова attribute - но зачем?
#endif            

#if !defined(__ARMCC_VERSION)
#pragma pack (push, 4)  // Если не ARMCC, снова приказываем паковать по 4 с сохранением текущего уровня упаковки
#endif
typedef struct GOST28147_BCTX_tag {
...
#if defined(__ICCARM__) || defined(__ICCAVR__)
}__attribute__ ((packed)) GOST28147_BCTX, *GOST28147_BCTX_PTR; // Если IAR - используем (отмененное?) ключевое слово
#else
} GOST28147_BCTX, *GOST28147_BCTX_PTR;

#if !defined(__ARMCC_VERSION)
#pragma pack (pop) // Если не ARMCC - возвращаем уровень упаковки
#endif

#if defined(__ICCARM__) || defined(__ICCAVR__)
#pragma pack()             // Если IAR - ставим уровень упаковки по умолчанию
#endif

Т.е. если я правильно разобрал, в случае компилятора IAR явная упаковка указывается 2 раза, а для других компиляторов - ни одного. Наверное, стоит добавить условие упаковки для ARMCC?

Цитата(aaarrr @ Aug 13 2015, 13:58) *
Нет, первое было:
Код
UCHAR RFC4357_KeyUnwrap(GOST28147_BCTX_PTR pX,
                         __packed RFC4357_WRAPPED_KEY_PTR pWrappedKey,
                         PUCHAR pUnwrappingKey,
                         PUCHAR pUnwrappedKey)

Мне кажется, что с точки зрения языка оба объявления тождественны. Но проверю sm.gif

Хм, забавно.
__packed RFC4357_WRAPPED_KEY_PTR pWrappedKey - ничего не дает, а
__packed RFC4357_WRAPPED_KEY *pWrappedKey выдает ошибку "Error: C2510E: Definition of 'struct RFC4357_WRAPPED_KEY_tag' not '__packed': qualifier ignored". Получается, если параметр функции указан как __packed, то тип должен быть упакован явно.


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


Гуру
******

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



Цитата(Harvester @ Aug 13 2015, 14:21) *
Получается, если параметр функции указан как __packed, то тип должен быть упакован явно.

Да, не умеет он указатели на "абстрактно" упакованные структуры делать, это только для базовых типов проходит.

Остается или "упаковать" typedef или выровнять структуру.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 13 2015, 11:38
Сообщение #18


Гуру
******

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



указатель, а не структуру предлагаютsm.gif ... но все же учитывая историю со 2 структурой, лучше и первую попаковать при объявлении сразу!

А вообще корректно не пакованную структуру пытаться запихать куда-то как пакованную? Или мы просто хотим чтобы он к ней относился как к пакованной, опять же тоже не есть корректно.... ИМХО
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 13 2015, 11:51
Сообщение #19


Гуру
******

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



Цитата(Golikov A. @ Aug 13 2015, 14:38) *
А вообще корректно не пакованную структуру пытаться запихать куда-то как пакованную? Или мы просто хотим чтобы он к ней относился как к пакованной, опять же тоже не есть корректно.... ИМХО

От структуры зависит. Но раз уж не хочет компилятор делать указатель на упакованную структуру на базе описания не упакованной, то и фиг с ним.
Go to the top of the page
 
+Quote Post

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

 


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


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