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

Forcer un x86 a rejetter les accès non alignés

7 réponses
Avatar
Marc Boyer
Bonjour,

ma demande n'est pas 100% en charte, mais pas trop loin.

Voilà, j'aimerais savoir comment faire pour forcer un code
C tournant sur x86/linux à générer des interruptions pour les
accès non alignés.

Est-ce qu'il existe une option dans un compilo, ou une instruction
ASM qu'on puisse positionner ?

J'ai tenté un peu de Google, mais sans succès.

Merci,
Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

7 réponses

Avatar
Antoine Leca
En news:, Marc Boyer va escriure:
Voilà, j'aimerais savoir comment faire pour forcer un code
C tournant sur x86/linux à générer des interruptions pour les
accès non alignés.

Est-ce qu'il existe une option dans un compilo, ou une instruction
ASM qu'on puisse positionner ?



Si on fait abstraction de « linux » dans ta demande, en activant le drapeau
AC (contròle d'alignement, bit 18) dans le registre d'état du processeur
(EFLAGS) pour le processus visé, et en activant le drapeau AM (masque de xxx
d'alignenmemnt, bit 18 aussi) dans le registre de contrôle du processeur
(CR0), tout accès non aligné en mode utilisateur dans un processus (DPL3)
doit provoquer sur les 486+ un déroutement de type 18 (dit AF, faute
d'alignement) que le système peut (et doit) traiter comme il faut,
normalement en sommant l'impétrant de recompiler son programme !


Si tu te poses des questions sur le comment faire pour positionner deux bits
de contrôle du processeur sur Linux, en dehors de la réponse évidente qu'il
s'agit d'une opération qui demande d'être root car il faut descendre à DPL0,
je pense qu'il existe des forums plus adaptés pour savoir s'il faut modifier
le noyau, écrire un driver, ou s'il y a d'autres moyens plus mondains.
Idem pour les discussions sur le pourquoi avoir réalisé cette opération n'a
pas d'effet durable (du fait de la propension de certains auteurs du noyau
Linux à croire que ce drapeau ne sert à rien et qu'il peut être
arbitrairement réinitialisé à zéro...)

Si tu te poses des questions sur le comportement que devrait adopter tel ou
tel système d'exploitation en réponse au déroutement d'alignement (doit-on
pénaliser le processus de 200 cycles ou lui envoyer SIGKILL, ou des moyen
termes quelconques doivent-ils être envisagés), je pense là encore qu'il y a
sûrement d'autres groupes...
http://groups.google.com/groups?selm=2t9e7q$ [juin 94]
semble donner à penser qu'une partie était déjà faite sur le Linux de cette
époque, mais que pour la remontée sous forme de signal ou autre il restait
des choses à voir (à l'époque)...


En dehors de Linux, je croyais me souvenir que Minix ou OpenBSD avait un
comportement cohérent à ce niveau et permettait de faire tourner des
processus utilisateurs avec AC=1 (histoire d'assassiner à loisir ou tout
simplement de faciliter les portages); malheureusement il ne m'est pas
possible de remettre la main sur une référence à ce sujet.


Antoine
Avatar
Marc Boyer
On 2008-06-25, Antoine Leca wrote:
En news:, Marc Boyer va escriure:
Voilà, j'aimerais savoir comment faire pour forcer un code
C tournant sur x86/linux à générer des interruptions pour les
accès non alignés.

Est-ce qu'il existe une option dans un compilo, ou une instruction
ASM qu'on puisse positionner ?



Si on fait abstraction de « linux » dans ta demande, en activant le drapeau
AC (contròle d'alignement, bit 18) dans le registre d'état du processeur
(EFLAGS) pour le processus visé, et en activant le drapeau AM (masque de xxx
d'alignenmemnt, bit 18 aussi) dans le registre de contrôle du processeur
(CR0), tout accès non aligné en mode utilisateur dans un processus (DPL3)
doit provoquer sur les 486+ un déroutement de type 18 (dit AF, faute
d'alignement) que le système peut (et doit) traiter comme il faut,
normalement en sommant l'impétrant de recompiler son programme !



Tu as bien gardé en tête que j'étais enseignant, et que le passage
de nos machines de Sparc à x86 m'ennuie sur ce point.

Si tu te poses des questions sur le comment faire pour positionner deux bits
de contrôle du processeur sur Linux, en dehors de la réponse évidente qu'il
s'agit d'une opération qui demande d'être root car il faut descendre à DPL0,
je pense qu'il existe des forums plus adaptés pour savoir s'il faut modifier
le noyau, écrire un driver, ou s'il y a d'autres moyens plus mondains.



Je posais la question ici au cas où.
Les docs Microsoft semblent dirent que c'est gérable au niveau du
compilo (http://msdn.microsoft.com/en-us/library/aa290049.aspx), donc,
je me demandais si un compilo (gcc, icc...) avait cette fonctionnalité.
Visiblement, non.

Et puis il me fallait quelques points d'entrée, que tu me donnes là.

Idem pour les discussions sur le pourquoi avoir réalisé cette opération n'a
pas d'effet durable (du fait de la propension de certains auteurs du noyau
Linux à croire que ce drapeau ne sert à rien et qu'il peut être
arbitrairement réinitialisé à zéro...)



A travailler en effet.

Si tu te poses des questions sur le comportement que devrait adopter tel ou
tel système d'exploitation en réponse au déroutement d'alignement (doit-on
pénaliser le processus de 200 cycles ou lui envoyer SIGKILL, ou des moyen
termes quelconques doivent-ils être envisagés), je pense là encore qu'il y a
sûrement d'autres groupes...
http://groups.google.com/groups?selm=2t9e7q$ [juin 94]
semble donner à penser qu'une partie était déjà faite sur le Linux de cette
époque, mais que pour la remontée sous forme de signal ou autre il restait
des choses à voir (à l'époque)...



Voui, il faut planter le processus utilisateur, mais pas toute
la machine?

En dehors de Linux, je croyais me souvenir que Minix ou OpenBSD avait un
comportement cohérent à ce niveau et permettait de faire tourner des
processus utilisateurs avec AC=1 (histoire d'assassiner à loisir ou tout
simplement de faciliter les portages); malheureusement il ne m'est pas
possible de remettre la main sur une référence à ce sujet.



Tu as écris "OpenBSD", je le recopie, donc Marc Espie devrait surgir
assez vite.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Jean-Marc Bourguet
Marc Boyer writes:

Regarde dans les archives de comp.arch, il y a un an ou deux quelqu'un dans
le meme genre de contexte que toi l'a fait et quelques mois apres est
revenu avec ses conclusions (si j'ai bonne memoire, trop de problemes
pratiques).

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Marc Boyer
On 2008-06-26, Jean-Marc Bourguet wrote:
Marc Boyer writes:

Regarde dans les archives de comp.arch, il y a un an ou deux quelqu'un dans
le meme genre de contexte que toi l'a fait et quelques mois apres est
revenu avec ses conclusions (si j'ai bonne memoire, trop de problemes
pratiques).



En fait, ça n'a pas l'ai si compliqué: j'ai mis la commande magique
dans mon code, et ça fait BOUM.

Tests-C> more acces_non-aligne.c
int main(){
char t[sizeof(double)*2];
double* d= (double*) (t+1);
__asm__("pushfl; popl %eax; orl $0x40000,%eax; pushl %eax; popfl;");
*d= 1.0;
return 0;
}
Tests-C> gcc -W -Wall -pedantic -stdÉ9 acces_non-aligne.c
Tests-C> ./a.out
Bus error (core dumped)

La question, c'est comment forcer les étudiants à mettre ce code
dans leur programme. Est-ce qu'on peut dire à gcc d'ajouter un bout
de code dans le main ?

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Jean-Marc Bourguet
Marc Boyer writes:

On 2008-06-26, Jean-Marc Bourguet wrote:
> Marc Boyer writes:
>
> Regarde dans les archives de comp.arch, il y a un an ou deux quelqu'un dans
> le meme genre de contexte que toi l'a fait et quelques mois apres est
> revenu avec ses conclusions (si j'ai bonne memoire, trop de problemes
> pratiques).

En fait, ça n'a pas l'ai si compliqué: j'ai mis la commande magique
dans mon code, et ça fait BOUM.

Tests-C> more acces_non-aligne.c
int main(){
char t[sizeof(double)*2];
double* d= (double*) (t+1);
__asm__("pushfl; popl %eax; orl $0x40000,%eax; pushl %eax; popfl;");
*d= 1.0;
return 0;
}
Tests-C> gcc -W -Wall -pedantic -stdÉ9 acces_non-aligne.c
Tests-C> ./a.out
Bus error (core dumped)

La question, c'est comment forcer les étudiants à mettre ce code
dans leur programme. Est-ce qu'on peut dire à gcc d'ajouter un bout
de code dans le main ?



Si tu controles la version de gcc, tu dois pouvoir bricoler le code
de start-up.

La vraie question, c'est: est-ce que les libs que tu utilises ne vont
pas crasher...

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Marc Boyer
On 2008-06-26, Jean-Marc Bourguet wrote:
Marc Boyer writes:
On 2008-06-26, Jean-Marc Bourguet wrote:
> Marc Boyer writes:
>
> Regarde dans les archives de comp.arch, il y a un an ou deux quelqu'un dans
> le meme genre de contexte que toi l'a fait et quelques mois apres est
> revenu avec ses conclusions (si j'ai bonne memoire, trop de problemes
> pratiques).

En fait, ça n'a pas l'ai si compliqué: j'ai mis la commande magique
dans mon code, et ça fait BOUM.

Tests-C> more acces_non-aligne.c
int main(){
char t[sizeof(double)*2];
double* d= (double*) (t+1);
__asm__("pushfl; popl %eax; orl $0x40000,%eax; pushl %eax; popfl;");
*d= 1.0;
return 0;
}
Tests-C> gcc -W -Wall -pedantic -stdÉ9 acces_non-aligne.c
Tests-C> ./a.out
Bus error (core dumped)

La question, c'est comment forcer les étudiants à mettre ce code
dans leur programme. Est-ce qu'on peut dire à gcc d'ajouter un bout
de code dans le main ?



Si tu controles la version de gcc, tu dois pouvoir bricoler le code
de start-up.



As-tu un mot clef à me mettre sous la dent pour entamer mes
recherches ?

La vraie question, c'est: est-ce que les libs que tu utilises ne vont
pas crasher...



Se serait marrant...
Mais bon, mes étudiants utilisent les E/S et pas grand chose d'autre.
Je pense pas que ça pose problème. A voir...

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Jean-Marc Bourguet
Marc Boyer writes:

> Si tu controles la version de gcc, tu dois pouvoir bricoler le code
> de start-up.

As-tu un mot clef à me mettre sous la dent pour entamer mes
recherches ?



C'est les fichiers /usr/lib/crt* qui sont a remplacer. Je crois que sous
Linux ils viennent de la libc (tu la recuperes et tu bricoles pour
n'assembler que ces fichiers). Tu dois pouvoir jouer avec les fichiers de
config de gcc (specs, voir l'option --dump-specs) pour faire utiliser ce
que tu veux.

En fait, en jouant avec les specs, il devrait avoir moyen de lier d'office
un fichier qui fait les modifs que tu veux a l'initialisation (en utilisant
la meme section qui execute les constructeurs de variables globales en
C++) sans devoir toucher aux fichiers de la libc.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org