Перейти к содержанию
    

RealView Compiler не слушается квалификатора __packed

Компилятор 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...

Но откуда взялся в запакованной структуре явно пэддинг байт (выделен жирным)?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

wchar_t text[sizeof(MANUF_STRING)/2]; /*<-- здесь точно требуется массив из двух байт ?*/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А попробуйте простую кондовую #pragma pack(1) вместо этих многочисленных и совсем уж плохо переносимых __packed

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

wchar_t text[sizeof(MANUF_STRING)/2]; /*<-- здесь точно требуется массив из двух байт ?*/

Там массив из двухбайтовых слов - строка в юникоде.

 

А попробуйте простую кондовую #pragma pack(1) вместо этих многочисленных и совсем уж плохо переносимых __packed

Щаз попробую :)

А эта прагма будет относиться только к сразу следующей за ней структуре, или сразу до конца файла?

 

Эм, попробовал - без результата, лишний нулевой байт остаётся...

 

Хотя с прагмами прикольно - у меня SlickEdit не понимает (__packed), и теперь можно его убрать!

С другой стороны, прагма работает до конца файла, приходится ставить лишнюю pragma pack(), чтобы выравнивание вернулось к состоянию по умолчанию...

 

Проблема решается, если структуре strings добавить квалификатор align(2) - то есть выровнять её в памяти.

Тогда пэддинг не вставляется, и данные генерятся так, как надо.

Но это уже, имхо, костыль для обхода бага...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А эта прагма будет относиться только к сразу следующей за ней структуре, или сразу до конца файла?

До конца, или отменяющей прагмы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оттуда же откуда и следующий за ним 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оттуда же откуда и следующий за ним 0 и все остальные 0 через 1 - из wchar_t.

__packed вообще-то прекрасно работает в RVDS'е.

 

padd здесь ни один компилятор не вставит. Сами подумайте тип wchar - 2 байта.

Какого лешего его размещать с нечетного адреса? А в вашем примере если допустить что выделенный 00 это padd байт, то wchar располагается как раз по нечетному смещению "0x7".

Ноль должен идти уже после 0х53, но никак не до!

В пакованной структуре wchar_t может начинаться с нечётного адреса - на то она и запакованная!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ноль должен идти уже после 0х53, но никак не до!

В пакованной структуре wchar_t может начинаться с нечётного адреса - на то она и запакованная!

В упакованной структуре padding'и отсутствуют как класс. Если предположить что что-то не так с упаковкой (компилер не понял слово __packed), тогда получается неувязочка с нечетным смещением.

 

Ничего подобного - сам стринг должен быть таким:

может какой-то атрибут применен, который перевернул строку в bigendian.

Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sonycman: а данные структуры где смотрите?

 

может какой-то атрибут применен, который перевернул строку в bigendian.

Знаете такой атрибут?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ноль должен идти уже после 0х53, но никак не до!

Ну так переверните его и посмотрите что получится.

swap16( ...->s1.text[ 0 ] );

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну так переверните его и посмотрите что получится.

swap16( ...->s1.text[ 0 ] );

Напишите +2 по результатам отладки, ага.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Напишите +2 по результатам отладки, ага.

Ага, тогда думайте, что это padding дальше и пытайтесь пофиксить его как паддинг.

Мне то что.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может какой-то атрибут применен, который перевернул строку в bigendian.

Я лично считаю, что это не padd byte 100%. и упаковка здесь не при чем.

Весь код перед вами в первом посте.

Тут не переворот, а лишний байт, так как вся структура имеет длину на 1 байт больше, чем должна быть.

 

sonycman: а данные структуры где смотрите?

Смотрю в отладчике, в режиме симулятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...