Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

accès non alignés

12 réponses
Avatar
Manuel Pégourié-Gonnard
Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?

L'idée étant de pouvoir exécuter du code sur une de ces plateformes
(soit directement si on trouve du matos abordable, soit en l'émulant si
c'est possible) pour tester sa portabilité.

Merci d'avance !

--
Manuel Pégourié-Gonnard

10 réponses

1 2
Avatar
Erwan David
Manuel Pégourié-Gonnard écrivait :

Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.


--
Les simplifications c'est trop compliqué
Avatar
JKB
Le Mon, 21 Oct 2013 13:55:44 +0200,
Erwan David écrivait :
Manuel Pégourié-Gonnard écrivait :



Bonjour,

Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



MIPS, Alpha (mais c'est mort) et en règle générale les processeurs
RISC qui aiment assez les BUS ERROR.

Sur x86, j'ai souvenir d'avoir vu un bout de code assembleur
permettant de "sigbusser" comme un sparc (gcc). Il suffisait d'exécuter la
séquence au début du programme.

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
=> http://loubardes.de-charybde-en-scylla.fr
Avatar
Jean-Marc Bourguet
JKB writes:

Le Mon, 21 Oct 2013 13:55:44 +0200,
Erwan David écrivait :
Manuel Pégourié-Gonnard écrivait :



Bonjour,

Bonjour,

Je suis désolé de poster ici une question qui n'est que margi nalement en
lien avec le langage C, mais comme il s'agit de portabilité qui es t un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mém oire ne
respectant pas certaines conditions d'alignement (par exemple, accà ¨s à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouen t ?



sparc, 68000 je crois.



MIPS, Alpha (mais c'est mort) et en règle générale les pr ocesseurs
RISC qui aiment assez les BUS ERROR.

Sur x86, j'ai souvenir d'avoir vu un bout de code assembleur
permettant de "sigbusser" comme un sparc (gcc). Il suffisait
d'exécuter la séquence au début du programme.



Il y a bien un mode qui permet de faire ca. De memoire, il etait
impossible a utiliser en pratique parce que la lib standard et les
autres lib de l'OS utilisent les acces non alignes donc foirent
joyeusement meme si ton code n'a pas de probleme.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
espie
In article ,
Erwan David wrote:
Manuel Pégourié-Gonnard écrivait :

Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



Pour les 68000, il faut du vrai 68000 de base. Il me semble qu'il y a de
quoi gerer les acces non alignes des le 6820...

Si tu veux de la portabilite, utilise uint_least32_t. Lui, il est *garanti*
par la norme (et il vaut exactement uint32_t si ce dernier existe).
Avatar
Bruno Ducrot
On 2013-10-21, Jean-Marc Bourguet wrote:
JKB writes:

Le Mon, 21 Oct 2013 13:55:44 +0200,
Erwan David écrivait :
Manuel Pégourié-Gonnard écrivait :



Bonjour,

Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



MIPS, Alpha (mais c'est mort) et en règle générale les processeurs
RISC qui aiment assez les BUS ERROR.

Sur x86, j'ai souvenir d'avoir vu un bout de code assembleur
permettant de "sigbusser" comme un sparc (gcc). Il suffisait
d'exécuter la séquence au début du programme.





Il faut armer le bit 18 du registre eflags. Une telle séquence peut
être (sous gcc, ou sous clang) :

__asm__("pushfnorl $0x40000,(%esp)npopf");


Il y a bien un mode qui permet de faire ca. De memoire, il etait
impossible a utiliser en pratique parce que la lib standard et les
autres lib de l'OS utilisent les acces non alignes donc foirent
joyeusement meme si ton code n'a pas de probleme.




On peut aussi désactiver cette fonctionalité avant appel
à certaines bibliothèques, en désarmant ce bit :

__asm__("pushfnandl $0xfffbffff,(%esp)npopf");

Pour un x86_64, il suffit de remplacer %esp par %rsp, et
de pas oublier que l'on récupère sur la pile le registre
rflags (64 bits) et non plus eflags (32 bits).

Pour armer :
__asm__("pushfnorl $0x40000,(%rsp)npopf");

et pour désarmer :
__asm__("pushfnandl $0xfffffffffffbffff,(%rsp)npopf");

Bien sûr, ce genre de pratique ne vaut que si l'on a pas un
bon vieux sparc sous la main, et que l'on désire vérifié
qu'un bout de code sera correct d'un point de vue alignement.

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Avatar
Antoine Leca
Bruno Ducrot écrivit :
On 2013-10-21, Jean-Marc Bourguet wrote:
JKB writes:
Sur x86, j'ai souvenir d'avoir vu un bout de code assembleur
permettant de "sigbusser" comme un sparc (gcc). Il suffisait
d'exécuter la séquence au début du programme.





Il faut armer le bit 18 du registre eflags. Une telle séquence peut
être (sous gcc, ou sous clang) :

__asm__("pushfnorl $0x40000,(%esp)npopf");



Il faut aussi que le processeur soit dans le mode où cela a un effet,
c'est-à-dire que le bit 18 (AM, même place) du registre CR0 soit armé.

En toute logique, pour un système normal le bit CR0.AM devrait être
désarmé, sinon c'est trop facile pour du code utilisateur de créer un
piège système imparable (ou à tout le moins de forcer un détour par
l'INT 0x17 à chaque accès mémoire). Et tout aussi logiquement, l'accès à
CR0 est réservé au système (ring 0, kernel, etc.)


Antoine
Avatar
Alexandre Bacquart
On 10/21/2013 01:55 PM, Erwan David wrote:
Manuel Pégourié-Gonnard écrivait :

Bonjour,

Je suis désolé de poster ici une question qui n'est que marginalement en
lien avec le langage C, mais comme il s'agit de portabilité qui est un
des objectifs du C, et que la question ne se poserait pas dans d'autres
langages...

Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



De mémoire, le 68000 génère une exception quand cela se produit. Le
système, s'il le souhaite, peut détourner le vecteur d'interruption
correspondant et faire les corrections nécessaires pour que cela
fonctionne de manière transparente. C'est plus lent (interruption +
accès multiples), mais c'est possible et c'est donc un problème
logiciel. Après, tout dépend de l'implémentation et de ses objectifs
(stabilité ou efficacité), etc...


--
Alexandre
Avatar
Bruno Ducrot
On 2013-10-23, Antoine Leca wrote:
Bruno Ducrot écrivit :
On 2013-10-21, Jean-Marc Bourguet wrote:
JKB writes:
Sur x86, j'ai souvenir d'avoir vu un bout de code assembleur
permettant de "sigbusser" comme un sparc (gcc). Il suffisait
d'exécuter la séquence au début du programme.





Il faut armer le bit 18 du registre eflags. Une telle séquence peut
être (sous gcc, ou sous clang) :

__asm__("pushfnorl $0x40000,(%esp)npopf");



Il faut aussi que le processeur soit dans le mode où cela a un effet,
c'est-à-dire que le bit 18 (AM, même place) du registre CR0 soit armé.

En toute logique, pour un système normal le bit CR0.AM devrait être
désarmé, sinon c'est trop facile pour du code utilisateur de créer un
piège système imparable (ou à tout le moins de forcer un détour par
l'INT 0x17 à chaque accès mémoire).



Pas pour tous les process. Uniquement pour ceux qui auront
armé le bit AM du registre EFLAGS.

En ce cas, l'interruption logicielle aura pour unique conséquence
l'envoie d'un sig bus au process fautif, si effectivement
l'OS aura pris soin d'armé le bit AM du registre CR0, ce qui est
d'ailleurs le cas sous FreeBSD et Linux.

Et tout aussi logiquement, l'accès à
CR0 est réservé au système (ring 0, kernel, etc.)




Et heureusement.

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Avatar
Antoine Leca
Alexandre Bacquart écrivit :
Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



De mémoire, le 68000 génère une exception quand cela se produit. Le
système, s'il le souhaite, peut détourner le vecteur d'interruption
correspondant et faire les corrections nécessaires pour que cela
fonctionne de manière transparente.



De mémoire (c'est trèèèèès loin pour moi) le 68000 de base ne sait pas
reprendre complètement une instruction interrompue, ce qui complique
notablement ce genre de procédure. Avec un 68010, par contre, ce doit
être possible (et long, et pas souvent implanté dans le système).


Antoine
Avatar
espie
In article <l4o8fr$59l$,
Antoine Leca wrote:
Alexandre Bacquart écrivit :
Qu'y a-t-il comme architecture courante où les accès mémoire ne
respectant pas certaines conditions d'alignement (par exemple, accès à
un uint32_t pas aligné sur une frontière de 4 octets (oui, je sais,
uint32_t c'est pas portable, c'était pour l'exemple)) échouent ?



sparc, 68000 je crois.



De mémoire, le 68000 génère une exception quand cela se produit. Le
système, s'il le souhaite, peut détourner le vecteur d'interruption
correspondant et faire les corrections nécessaires pour que cela
fonctionne de manière transparente.



De mémoire (c'est trèèèèès loin pour moi) le 68000 de base ne sait pas
reprendre complètement une instruction interrompue, ce qui complique
notablement ce genre de procédure. Avec un 68010, par contre, ce doit
être possible (et long, et pas souvent implanté dans le système).



Oui, ca me rappelle egalement des choses. Je suis a peu pres certain que
tu as raison.
1 2