|
RealView Compiler не слушается квалификатора __packed, и вставляет padding byte... |
|
|
|
Jun 24 2009, 16:18
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Компилятор RealView 4.0.0.524 из пакета MDK3.70. C++. Что-то не слушается меня компилер, то ли я не так пишу, то ли багу нашёл. Исходник: Код #define USB_STRING_DESCRIPTOR_TYPE 3 #define MANUF_STRING L"Sonycman Production" #define PROD_STRING L"Sonycman Mass Storage Drive" #define SERIAL_STRING L"123456789ABC"
typedef __packed struct { byte length; byte descriptor_type; word languageID; } USB_STRING_ID_DESCRIPTOR;
typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(MANUF_STRING)/2]; } USB_STRING1_DESCRIPTOR;
typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(PROD_STRING)/2]; } USB_STRING2_DESCRIPTOR;
typedef __packed struct { byte length; byte descriptor_type; wchar_t text[sizeof(SERIAL_STRING)/2]; } USB_STRING3_DESCRIPTOR;
typedef __packed struct { USB_STRING_ID_DESCRIPTOR s0; USB_STRING1_DESCRIPTOR s1; USB_STRING2_DESCRIPTOR s2; USB_STRING3_DESCRIPTOR s3; } USB_STRING_DESCRIPTOR; и инициализация: Код const USB_STRING_DESCRIPTOR CUSB::strings = { sizeof(USB_STRING_ID_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, 0x409, //language ID sizeof(USB_STRING1_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, MANUF_STRING, sizeof(USB_STRING2_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, PROD_STRING, sizeof(USB_STRING3_DESCRIPTOR), USB_STRING_DESCRIPTOR_TYPE, SERIAL_STRING }; Так вот, члену strings присваиваются такие данные: 0x080046f9: 04 03 09 04 2a 03 00 53 00 6f 00 6e 00... Но откуда взялся в запакованной структуре явно пэддинг байт (выделен жирным)?!
|
|
|
|
|
Jun 24 2009, 16:47
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(forever failure @ Jun 24 2009, 20:41)  wchar_t text[sizeof(MANUF_STRING)/2]; /*<-- здесь точно требуется массив из двух байт ?*/ Там массив из двухбайтовых слов - строка в юникоде. Цитата(zltigo @ Jun 24 2009, 20:43)  А попробуйте простую кондовую #pragma pack(1) вместо этих многочисленных и совсем уж плохо переносимых __packed Щаз попробую  А эта прагма будет относиться только к сразу следующей за ней структуре, или сразу до конца файла? Эм, попробовал - без результата, лишний нулевой байт остаётся... Хотя с прагмами прикольно - у меня SlickEdit не понимает (__packed), и теперь можно его убрать! С другой стороны, прагма работает до конца файла, приходится ставить лишнюю pragma pack(), чтобы выравнивание вернулось к состоянию по умолчанию... Проблема решается, если структуре strings добавить квалификатор align(2) - то есть выровнять её в памяти. Тогда пэддинг не вставляется, и данные генерятся так, как надо. Но это уже, имхо, костыль для обхода бага...
|
|
|
|
|
Jun 24 2009, 18:09
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(sonycman @ Jun 24 2009, 19:18)  0x080046f9: 04 03 09 04 2a 03 00 53 00 6f 00 6e 00... Но откуда взялся в запакованной структуре явно пэддинг байт (выделен жирным)?! Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t. __packed вообще-то прекрасно работает в RVDS'е. padd здесь ни один компилятор не вставит. Сами подумайте тип wchar - 2 байта. Какого лешего его размещать с нечетного адреса? А в вашем примере если допустить что выделенный 00 это padd байт, то wchar располагается как раз по нечетному смещению "0x7".
|
|
|
|
|
Jun 24 2009, 18:18
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(defunct @ Jun 24 2009, 22:09)  Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t. Ничего подобного - сам стринг должен быть таким: Код 53 00 6f 00 6e 00... RVDS 2.2 создает корректную структуру (в плюсовом режиме правда не смотрел): Код 0x0000a4c4 04 03 09 04 2A 03 53 00 6F 00 6E 00 79 00 63 00 ....*.S.o.n.y.c. 0x0000a4d4 6D 00 61 00 6E 00 20 00 50 00 72 00 6F 00 64 00 m.a.n. .P.r.o.d.
|
|
|
|
|
Jun 24 2009, 18:26
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(sonycman @ Jun 24 2009, 21:21)  Ноль должен идти уже после 0х53, но никак не до! В пакованной структуре wchar_t может начинаться с нечётного адреса - на то она и запакованная! В упакованной структуре padding'и отсутствуют как класс. Если предположить что что-то не так с упаковкой (компилер не понял слово __packed), тогда получается неувязочка с нечетным смещением. Цитата Ничего подобного - сам стринг должен быть таким: может какой-то атрибут применен, который перевернул строку в bigendian. Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем.
|
|
|
|
|
Jun 24 2009, 20:42
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(defunct @ Jun 24 2009, 22:26)  может какой-то атрибут применен, который перевернул строку в bigendian. Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем. Весь код перед вами в первом посте. Тут не переворот, а лишний байт, так как вся структура имеет длину на 1 байт больше, чем должна быть. Цитата(aaarrr @ Jun 24 2009, 22:28)  sonycman: а данные структуры где смотрите? Смотрю в отладчике, в режиме симулятора.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|