2014-10-19 13 views
9

Source:Uninitialized garbage on ia64 can be deadlyPułapka unsigned char i IA64 NaT

Na IA64, każdy rejestr 64-bitowy jest faktycznie 65 bitów. Dodatkowy bit nazywany jest "NaT", co oznacza "nie jest rzeczą". Bit jest ustawiony, gdy rejestr nie zawiera poprawnej wartości. Pomyśl o tym jako o liczbie całkowitej zmiennoprzecinkowej NaN na poziomie .

Bit NaT jest najczęściej wybierany z wykonywania spekulacyjnego. Tam jest specjalną formą instrukcji ładunkowej na ia64, która próbuje uzyskać wartość z pamięci, ale jeśli ładowanie się nie powiedzie (ponieważ pamięć jest stronicowana lub adres jest nieprawidłowy), to zamiast podnoszenia błędu strony , wszystko, co się dzieje, polega na tym, że bit NaT zostaje ustawiony, a wykonanie jest kontynuowane.

Wszystkie operacje matematyczne na NaT powodują ponowne pojawienie się NaT.

Artykuł źródłowy zaczął tłumaczyć jak rejestr może skończyć się o nat reprezentację podczas spekulacyjnego załadunku i czyni następującą uwagę:

Bo widzisz, jeśli masz rejestr, którego wartość jest NaT i ty tak bardzo jak oddychać w niewłaściwy sposób (na przykład, spróbuj zapisać jego wartość do pamięci ), procesor podniesie wyjątek STATUS_REG_NAT_CONSUMPTION .

wydaje się od innych odpowiedzi przepełnienia stosu do reprezentacji pułapki,
„Każdy typ (z wyjątkiem unsigned char) może mieć reprezentacje pułapek”.

Ten link mówi, że

gwarancje tylko średnia daje o dostępie niezainicjalizowane Dane są takie, że typ unsigned char ma reprezentacje pułapkę, a że wyściółka ma reprezentacje pułapkę.

Jeśli taki rejestr (rejestr z ustawionym bitem NAT) jest przydzielona do przechowywania niezainicjowanej unsigned char (podobny do fragmentu kodu z raportu defektów poniżej), jak to jest obsługiwane zgodnie z normą ISO C11?

Czy raport o usterkach poniżej wskazuje na ten sam problem i czy został usunięty w ISO C11?

Jeśli nie, w jaki sposób obsługiwany jest ten specjalny przypadek?

Jeśli lwartość wyznacza przedmiot automatycznego czas przechowywania, które mogło być zadeklarowany z klasą pamięci rejestr (nigdy nie miał jej adres wzięte), a obiekt jest niezainicjowany (nie zadeklarował z inicjatora, a nie przypisanie do niej została wykonana przed zastosowaniem ), zachowanie jest niezdefiniowane

ma wyżej dodatek na końcu raportu defekt w sekcji „zmiana dla C1X” obsłużyć ten przypadek?

defect_report

Poniższa funkcja niezdefiniowane zachowanie pod C90, ale wydaje być ściśle zgodne pod C99

int foo(void) { 
     unsigned char uc; 
     return uc + 1 >= 0; 
    } 
+0

@Hasturkun - dzięki za edycję –

+1

TL; DR NaT nie jest w ogóle reprezentacją pułapki. Obejmuje to bit sprzętu, który mówi to lub tamto do sprzętu; ale ten bit nie jest częścią * typu *. Należy do określonej lokalizacji pamięci lub rejestru ze sprzętowego punktu widzenia, ale nie jest tak daleko, jak C. Podobnie jak bit przepełnienia, który może być odwrócony przez operacje arytmetyczne, nie jest częścią żadnej wartości C. Porównaj i kontrastuj z NaN. –

+0

@ n.m - Raport o defekcie wydaje się sugerować, że jest to reprezentacja pułapki? "W przypadku niektórych urządzeń (na przykład Itanium) wartość 8-bitowa może mieć aż 257 różnych wartości (0-255 i wartość" Not a Thing ") .Jednakże, c99 wyraźnie zabrania takiej wartości dla unsigned char." –

Odpowiedz

4

Pierwszą rzeczą, jeśli nie mają widziałem to dla siebie, możesz pobrać ostateczny szkic standardu C11 z here (see also).

Tekst z DR rzeczywiście dodano do sekcji 6.3.2.1 p2, co powoduje, że kod jest nieokreślony zgodnie z C11.

Sekcje w standardach dotyczące reprezentacji pułapek nadal wykluczają możliwość, że unsigned char może mieć reprezentację pułapki - ale to nie ma znaczenia. Należy tutaj zwrócić uwagę na to, że jak wspomniano w zeszłorocznej notatce z DR, ze standardowej perspektywy wcale nie musi się w ogóle angażować w pułapki (są tylko prawdopodobnym mechanizmem, dzięki któremu UB spowodowałoby problem dla ciebie na metalu). Problem dotyczy naprawdę niezainicjowanych automatycznych wartości; zmieniony paragraf rozwiązuje to przez wyjaśnienie, żenie powinno być uważane za zwolnione z ogólnego typu UB, po prostu ze względu na jego specyficzne właściwości specyficzne dla typu (nie przez dodanie większej złożoności do tej właściwości).

Można sobie wyobrazić, że tak jak bity NaT są szczegółem implementacji liczb całkowitych na IA64, brak reprezentacji pułapek jest "szczegółem implementacji" jednego określonego typu w ogólnej rodzinie typów C. Rzeczywisty typ zmiennej jest drugorzędny w stosunku do bardziej ogólnej zasady, że nie powinieneś czuć się bezpiecznie uzyskując dostępu do dowolnej zmiennej niezainicjowanej; dodatek wyjaśnia to pierwszeństwo.

+0

Dzięki, dlaczego wyściółka jest wykluczona/gwarantowana przez standard, aby nie mieć reprezentacji pułapki? –

+0

Wypełnienie nie może mieć odwzorowania pułapki, ponieważ wypełnienie nie jest tak naprawdę danymi? Nie masz dostępu do niego dla siebie; możesz (jeśli kopiujesz) uzyskać dostęp do niego w postaci bajtów. – Leushenko